资料介绍
AVPlayer:可以理解为播放器对象,灵活性好,可以高度化的自定义UI,但它本身不能显示视频,显示需要另一个类AVPlayerLayer来显示,继承于CALayer,下面是摘自官方的一段介绍:
AVPlayer works equally well with local and remote media files.
You can display the visual content of items played by an instance of AVPlayer in a CoreAnimation layer of class AVPlayerLayer.
You can observe the status of a player using key-value observing.
主要是说它支持本地/网络媒体播放,需要CoreAnimation下的AVPlayerLayer来显示视频,我们可以通过KVO监听player的播放状态。
AVPlayerItem:存有相关媒体信息的类,一个视频资源对应一个AVPlayerItem对象,当你需要循环播放多个视频资源时也需创建多个AVPlayerItem对象。建议大家可以多看看官方的英文文档解释(题外话)。
An AVPlayerItem represents the presentation state of an asset that’s played by an AVPlayer object, and lets you observe that state.
AVAsset:主要用于获取多媒体信息,可以理解为一个抽象类,不能直接使用,操作针对它的子类AVURLAsset,根据你视频的url创建一个包含视频媒体信息的AVURLAsset对象。
CMTime:还会用到这个媒体时间相关的类,如有不明白可以看之前一个帖子的解释。
层级关系:
基于以上几个类就能实现视频的基本功能了,例如暂停、播放,快进、后退、显示播放/缓冲进度。然后UI层面,层级很简单,XLVideoPlayer继承于UIView,上面我们说到显示视频需要AVPlayerLayer,我们将AVPlayerLayer加到view的layer上。
下面贴出主要的代码,初始化AVPlayer对象
- (AVPlayerLayer *)playerLayer {
if (!_playerLayer) {
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
_playerLayer.backgroundColor = kPlayerBackgroundColor;
_playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;//视频填充模式
}
return _playerLayer;
}
- (AVPlayer *)player{
if (!_player) {
AVPlayerItem *playerItem = [self getAVPlayItem];
self.playerItem = playerItem;
_player = [AVPlayer playerWithPlayerItem:playerItem];
[self addProgressObserver];
[self addObserverToPlayerItem:playerItem];
}
return _player;
}
//initialize AVPlayerItem
- (AVPlayerItem *)getAVPlayItem{
NSAssert(self.videoUrl != nil, @“必须先传入视频url!!!”);
if ([self.videoUrl rangeOfString:@“http”].location != NSNotFound) {
AVPlayerItem *playerItem=[AVPlayerItem playerItemWithURL:[NSURL URLWithString:[self.videoUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
return playerItem;
}else{
AVAsset *movieAsset = [[AVURLAsset alloc]initWithURL:[NSURL fileURLWithPath:self.videoUrl] options:nil];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:movieAsset];
return playerItem;
}
}
同时我们注册KVO,监控视频播放过程,这可以获取视频的播放进度。AVPlayer有一个属性currentItem是AVPlayerItem类型,表示当前播放的视频对象。
#pragma mark - monitor video playing course
-(void)addProgressObserver{
//get current playerItem object
AVPlayerItem *playerItem = self.player.currentItem;
__weak typeof(self) weakSelf = self;
//Set once per second
[self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
float current = CMTimeGetSeconds(time);
float total = CMTimeGetSeconds([playerItem duration]);
weakSelf.progressLabel.text = [weakSelf timeFormatted:current];
if (current) {
// NSLog(@“%f”, current / total);
weakSelf.slider.value = current / total;
if (weakSelf.slider.value == 1) { //complete block
if (weakSelf.completedPlayingBlock) {
weakSelf.completedPlayingBlock(weakSelf);
}else { //finish and loop playback
weakSelf.playOrPauseBtn.selected = NO;
[weakSelf showOrHidenBar];
CMTime currentCMTime = CMTimeMake(0, 1);
[weakSelf.player seekToTime:currentCMTime completionHandler:^(BOOL finished) {
weakSelf.slider.value = 0.0f;
}];
}
}
}
}];
}
以及监听AVPlayerItem对象的status/loadedTimeRanges属性变化,status对应播放状态,loadedTimeRanges网络缓冲状态,当loadedTimeRanges的改变时,每缓冲一部分数据就会更新此属性,可以获得本次缓冲加载的视频范围(包含起始时间、本次网络加载时长)
#pragma mark - PlayerItem (status,loadedTimeRanges)
-(void)addObserverToPlayerItem:(AVPlayerItem *)playerItem{
//监控状态属性,注意AVPlayer也有一个status属性,通过监控它的status也可以获得播放状态
[playerItem addObserver:self forKeyPath:@“status” options:NSKeyValueObservingOptionNew context:nil];
//network loading progress
[playerItem addObserver:self forKeyPath:@“loadedTimeRanges” options:NSKeyValueObservingOptionNew context:nil];
}
在这获取视频的总时长,网络的视频缓冲进度,做相应的显示。
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
AVPlayerItem *playerItem = object;
if ([keyPath isEqualToString:@“status”]) {
AVPlayerStatus status = [[change objectForKey:@“new”] intValue];
if(status == AVPlayerStatusReadyToPlay){
self.totalDuration = CMTimeGetSeconds(playerItem.duration);
self.totalDurationLabel.text = [self timeFormatted:self.totalDuration];
}
}else if([keyPath isEqualToString:@“loadedTimeRanges”]){
NSArray *array = playerItem.loadedTimeRanges;
CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次缓冲时间范围
float startSeconds = CMTimeGetSeconds(timeRange.start);
float durationSeconds = CMTimeGetSeconds(timeRange.duration);
NSTimeInterval totalBuffer = startSeconds + durationSeconds;//缓冲总长度
self.slider.middleValue = totalBuffer / CMTimeGetSeconds(playerItem.duration);
// NSLog(@“totalBuffer:%.2f”,totalBuffer);
//remove loading animation
if (self.slider.middleValue 《= self.slider.value) {
self.activityIndicatorView.center = self.center;
[self addSubview:self.activityIndicatorView];
[self.activityIndicatorView startAnimating];
}else {
[self.activityIndicatorView removeFromSuperview];
}
}
}
下面这部分是定位视频的某个位置播放,也就是快进后退。
这里需要注意的是在用户拖拽slider的过程中需要先暂停,否则手动改变进度和播放的进度会有冲突,用户拖拽完毕再去播放视频。
- (void)finishChange {
_inOperation = NO;
[self hiden];
CMTime currentCMTime = CMTimeMake(self.slider.value * self.totalDuration, 1);
[self.player seekToTime:currentCMTime completionHandler:^(BOOL finished) {
[self.player play];
self.playOrPauseBtn.selected = YES;
}];
}
- labview超快自定义控件制作和普通自定义控件制作 11次下载
- labview自定义控件 16次下载
- 自定义视图组件教程案例 14次下载
- Labview自定义右键快捷菜单功能实用小技巧 26次下载
- 精美的TF自定义控件源文件合集 31次下载
- 串口屏LUA教程10-自定义串口指令
- Xilinx基本自定义OpenRISC系统硬件教程 93次下载
- 如何在LabVIEW中实现自定义控件 48次下载
- LCD1602自定义显示字符及汉字 85次下载
- 自定义fifo接口控制器 1次下载
- 1602自定义字符 1次下载
- 自定义函数测试学习工程
- 基于SOPC的MPEG-4视频播放器
- matlab自定义函数调用的方法
- CSF文件播放器
- TSMaster 自定义 LIN 调度表编程指导 389次阅读
- 基于YOLOv8实现自定义姿态评估模型训练 2397次阅读
- 博途用户自定义库的使用 634次阅读
- 添加自定义属性控制fridaserver启动和停止 1350次阅读
- 什么是自定义序列 1028次阅读
- 自定义特性能做什么? 700次阅读
- FreeRTOS|自定义裁剪 1193次阅读
- 基于AWTK和AWPLC开发自定义功能块 818次阅读
- 如何自定义函数或局部脚本 1305次阅读
- 如何在Vivado中更改自定义的Interface 2658次阅读
- 三种自定义弹窗UI组件封装的实现 2887次阅读
- 如何给EOS账号设置自定义权限 1414次阅读
- erlang如何自定义_ERLANG环境搭建 1467次阅读
- springmvc 自定义拦截器实现未登录用户的拦截 2481次阅读
- LCD1602自定义点阵字符详解 1.3w次阅读
下载排行
本周
- 1电子电路原理第七版PDF电子教材免费下载
- 0.00 MB | 1490次下载 | 免费
- 2单片机典型实例介绍
- 18.19 MB | 93次下载 | 1 积分
- 3S7-200PLC编程实例详细资料
- 1.17 MB | 27次下载 | 1 积分
- 4笔记本电脑主板的元件识别和讲解说明
- 4.28 MB | 18次下载 | 4 积分
- 5开关电源原理及各功能电路详解
- 0.38 MB | 10次下载 | 免费
- 6基于AT89C2051/4051单片机编程器的实验
- 0.11 MB | 4次下载 | 免费
- 7基于单片机和 SG3525的程控开关电源设计
- 0.23 MB | 3次下载 | 免费
- 8基于单片机的红外风扇遥控
- 0.23 MB | 3次下载 | 免费
本月
- 1OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234313次下载 | 免费
- 2PADS 9.0 2009最新版 -下载
- 0.00 MB | 66304次下载 | 免费
- 3protel99下载protel99软件下载(中文版)
- 0.00 MB | 51209次下载 | 免费
- 4LabView 8.0 专业版下载 (3CD完整版)
- 0.00 MB | 51043次下载 | 免费
- 5555集成电路应用800例(新编版)
- 0.00 MB | 33562次下载 | 免费
- 6接口电路图大全
- 未知 | 30320次下载 | 免费
- 7Multisim 10下载Multisim 10 中文版
- 0.00 MB | 28588次下载 | 免费
- 8开关电源设计实例指南
- 未知 | 21539次下载 | 免费
总榜
- 1matlab软件下载入口
- 未知 | 935053次下载 | 免费
- 2protel99se软件下载(可英文版转中文版)
- 78.1 MB | 537791次下载 | 免费
- 3MATLAB 7.1 下载 (含软件介绍)
- 未知 | 420026次下载 | 免费
- 4OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234313次下载 | 免费
- 5Altium DXP2002下载入口
- 未知 | 233046次下载 | 免费
- 6电路仿真软件multisim 10.0免费下载
- 340992 | 191183次下载 | 免费
- 7十天学会AVR单片机与C语言视频教程 下载
- 158M | 183277次下载 | 免费
- 8proe5.0野火版下载(中文版免费下载)
- 未知 | 138039次下载 | 免费
评论
查看更多