1. AVPlayer
AVPlayer 是一个用来播放基于时间的视听媒体的控制器对象(一个队播放和资源时间相隔信息进行管理的对象,而非一个视图或窗口控制器).
AVPlayer支持播放从本地, 分步下载或通过HTTP Live Streaming协议得到的流媒体, 并在多种播放场景中播放这些视频资源.
开发者通过AVPlayer框架提供的应用程序接口来开发控制播放基于时间的媒体的用户界面.
AVPlayer只管理一个单独资源的播放, 但是框架还体用了AVPlayer的一个子类AVQueuePlayer, 通过它可以
管理一个资源队列
AVPlayer是一个不可见组件,对于播放MP3, ACC等音频文件, 没有可视化界面不会有什么问题, 但是对于想MP4等视频类文件就会给用户非常差的体验, 而要将视频资源导出到用户界面的目标位置, 需要使用AVPlayerLayer类.
2. AVPlayerLayer
AVPlayerLayer构建于Core Animation之上(AVPlayerLayer扩展了Core Animation的CALayer), 是AV Foundation中能找到的位数不多的可视化组件.
说白了就是AVPlayer没有显示界面的能力,靠AVPlayerLayer来显示界面。
AVPlayerLayer开发者可以自定义的只有一个属性: videoGravity
video gravity 总共有三个不同的值:
- AVLayerVideoGravityResizeAspect: 会在承载层的范围内缩放视频大小来保存视频的原始宽高比例,最常用
- AVLayerVideoGravityAspectFill: 保留视频的宽高比,并使其通过缩放填满层的范围区域,通常会导致视频图片被部分裁剪
- AVLayerVideoGravityResize: 会将视频内容拉伸来匹配承载层的范围.这是最不常用的模式, 因为它通常会导致图片扭曲
3. AVPlayerItem
视频的播放就是使用AVPlayer来播放AVAsset.
通过AVAsset 可以找到一些用来获取数据的方法和属性,(如创建日期, 元数据, 时长等信息). 但无法获取当前时间,也不能够在媒体中查找特定位置.这是因为AVAsset模型只包含媒体资源的静态信息, 这些不变的属性用来描述对象的静态状态. 这意味着仅使用AVAsset对象是无法实现播放功能的.
当我们需要对一个资源及其相关曲目进行播放时, 首先需要通过AVPlayerItemTrack和 AVPlayerItemTrack类构建相应的动态内容.
- AVPlayerItem会建立媒体资源动态视角的数据模型,并保存AVPlayer在播放资源时的呈现状态
- AVPlayerItem由一个或多个媒体曲目组成, 由AVPlayerItemTrack类建立模型
- AVPlayerItemTrack实例用于表示播放器条目中的类型同一的媒体流,比如音频或视频
- AVPlayerItem中的曲目直接与基础AVAsset中的AVAssetTrack实例相对应
以下是最简单的视频播放器代码
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"视频播放 ";
NSURL *url = [[NSBundle mainBundle]URLForResource:@"hubblecast.m4v" withExtension:nil];
self.set = [AVAsset assetWithURL:url];
self.item = [[AVPlayerItem alloc]initWithAsset:self.set];
self.player = [AVPlayer playerWithPlayerItem:self.item];
self.layer = [AVPlayerLayer playerLayerWithPlayer:self.player];
self.layer.frame = self.view.frame;
[self.view.layer addSublayer:self.layer];
[self.item addObserver:self forKeyPath:@"status" options:0 context:&PlayerItemStatusContext];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if (context == &PlayerItemStatusContext) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.item removeObserver:self forKeyPath:@"status"];
NSLog(@"self.item.status=%ld",(long)self.item.status);
if (self.item.status == AVPlayerItemStatusReadyToPlay) {
[self.player play];
} else {
}
});
}
}