在iOS开发中,播放视频通常有两种方式,一种是使用MPMoviePlayerController(需要导入MediaPlayer.Framework),还有一种是使用AVPlayer。关于这两个类的区别可以参考http://stackoverflow.com/questions/8146942/avplayer-and-mpmovieplayercontroller-differences,简而言之就是MPMoviePlayerController使用更简单,功能不如AVPlayer强大,而AVPlayer使用稍微麻烦点,不过功能更加强大。这篇博客主要介绍下AVPlayer的基本使用,由于博主也是刚刚接触,所以有问题大家直接指出~

  在开发中,单纯使用AVPlayer类是无法显示视频的,要将视频层添加至AVPlayerLayer中,这样才能将视频显示出来,所以先在ViewController的@interface中添加以下属性

@property (nonatomic ,strong) AVPlayer *player;
@property (nonatomic ,strong) AVPlayerItem *playerItem;@property (nonatomic ,weak) IBOutlet PlayerView *playerView;

其中playerView继承自UIView,不过重写了set和get方法,用于将player添加至playerView的AVPlayerLayer中,这样才能顺利将视频显示出来

在PlayerView.h中声明一个AVPlayer对象,由于默认的layer是CALayer,而AVPlayer只能添加至AVPlayerLayer中,所以我们改变一下layerClass,这样PlayerView的默认layer就变了,之后我们可以把在viewController中初始化的AVPlayer对象赋给AVPlayerLayer的player属性。

 PlayerView.h 

 @property (nonatomic ,strong) AVPlayer *player;

 PlayerView.m

+ (Class)layerClass {return [AVPlayerLayer class];
}- (AVPlayer *)player {return [(AVPlayerLayer *)[self layer] player];
}- (void)setPlayer:(AVPlayer *)player {[(AVPlayerLayer *)[self layer] setPlayer:player];
}

然后在viewDidLoad中执行初始化:

NSURL *videoUrl = [NSURL URLWithString:@"http://www.jxvdy.com/file/upload/201405/05/18-24-58-42-627.mp4"];
self.playerItem = [AVPlayerItem playerItemWithURL:videoUrl];
[self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];// 监听status属性
[self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];// 监听loadedTimeRanges属性
self.player = [AVPlayer playerWithPlayerItem:self.playerItem];[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotificationobject:self.playerItem];

先将在线视频链接存放在videoUrl中,然后初始化playerItem,playerItem是管理资源的对象(A player item manages the presentation state of an asset with which it is associated. A player item contains player item tracks—instances of AVPlayerItemTrack—that correspond to the tracks in the asset.)

然后监听playerItem的status和loadedTimeRange属性,status有三种状态:

AVPlayerStatusUnknown,

AVPlayerStatusReadyToPlay,

AVPlayerStatusFailed

当status等于AVPlayerStatusReadyToPlay时代表视频已经可以播放了,我们就可以调用play方法播放了。

loadedTimeRange属性代表已经缓冲的进度,监听此属性可以在UI中更新缓冲进度,也是很有用的一个属性。

最后添加一个通知,用于监听视频是否已经播放完毕,然后实现KVO的方法:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {AVPlayerItem *playerItem = (AVPlayerItem *)object;if ([keyPath isEqualToString:@"status"]) {if ([playerItem status] == AVPlayerStatusReadyToPlay) {NSLog(@"AVPlayerStatusReadyToPlay");self.stateButton.enabled = YES;CMTime duration = self.playerItem.duration;// 获取视频总长度CGFloat totalSecond = playerItem.duration.value / playerItem.duration.timescale;// 转换成秒_totalTime = [self convertTime:totalSecond];// 转换成播放时间[self customVideoSlider:duration];// 自定义UISlider外观NSLog(@"movie total duration:%f",CMTimeGetSeconds(duration));[self monitoringPlayback:self.playerItem];// 监听播放状态} else if ([playerItem status] == AVPlayerStatusFailed) {NSLog(@"AVPlayerStatusFailed");}} else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {NSTimeInterval timeInterval = [self availableDuration];// 计算缓冲进度NSLog(@"Time Interval:%f",timeInterval);CMTime duration = self.playerItem.duration;CGFloat totalDuration = CMTimeGetSeconds(duration);[self.videoProgress setProgress:timeInterval / totalDuration animated:YES];}
}- (NSTimeInterval)availableDuration {NSArray *loadedTimeRanges = [[self.playerView.player currentItem] loadedTimeRanges];CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域float startSeconds = CMTimeGetSeconds(timeRange.start);float durationSeconds = CMTimeGetSeconds(timeRange.duration);NSTimeInterval result = startSeconds + durationSeconds;// 计算缓冲总进度return result;
}- (NSString *)convertTime:(CGFloat)second{NSDate *d = [NSDate dateWithTimeIntervalSince1970:second];NSDateFormatter *formatter = [[NSDateFormatter alloc] init];if (second/3600 >= 1) {[formatter setDateFormat:@"HH:mm:ss"];} else {[formatter setDateFormat:@"mm:ss"];}NSString *showtimeNew = [formatter stringFromDate:d];return showtimeNew;
}

此方法主要对status和loadedTimeRanges属性做出响应,status状态变为AVPlayerStatusReadyToPlay时,说明视频已经可以播放了,这时我们可以获取一些视频的信息,包含视频长度等,把播放按钮设备enabled,点击就可以调用play方法播放视频了。在AVPlayerStatusReadyToPlay的底部还有个monitoringPlayback方法:

- (void)monitoringPlayback:(AVPlayerItem *)playerItem {self.playbackTimeObserver = [self.playerView.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time) {CGFloat currentSecond = playerItem.currentTime.value/playerItem.currentTime.timescale;// 计算当前在第几秒
        [self updateVideoSlider:currentSecond];NSString *timeString = [self convertTime:currentSecond];self.timeLabel.text = [NSString stringWithFormat:@"%@/%@",timeString,_totalTime];}];
}

monitoringPlayback用于监听每秒的状态,- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block;此方法就是关键,interval参数为响应的间隔时间,这里设为每秒都响应,queue是队列,传NULL代表在主线程执行。可以更新一个UI,比如进度条的当前时间等。

  作为播放器,除了播放,暂停等功能外。还有一个必不可少的功能,那就是显示当前播放进度,还有缓冲的区域,我的思路是这样,用UIProgressView显示缓冲的可播放区域,用UISlider显示当前正在播放的进度,当然这里要对UISlider做一些自定义,代码如下:

- (void)customVideoSlider:(CMTime)duration {self.videoSlider.maximumValue = CMTimeGetSeconds(duration);UIGraphicsBeginImageContextWithOptions((CGSize){ 1, 1 }, NO, 0.0f);UIImage *transparentImage = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();[self.videoSlider setMinimumTrackImage:transparentImage forState:UIControlStateNormal];[self.videoSlider setMaximumTrackImage:transparentImage forState:UIControlStateNormal];
}

这样UISlider就只有中间的ThumbImage了,而ThumbImage左右的颜色都变成透明的了,仅仅是用于显示当前的播放时间。UIProgressView则用于显示当前缓冲的区域,不做任何自定义的修改,在StoryBoard看起来是这样的:

把UISlider添加至UIProgressView上面,运行起来的效果就变成了这样:

这样基本的缓冲功能就做好了,当然还有一些功能没做,比如音量大小,滑动屏幕快进快退等,大家有时间可以自己做着玩儿下~ 最后的效果如下:

最后附上demo链接:https://github.com/mzds/AVPlayerDemo

转载于:https://www.cnblogs.com/mzds/p/3711867.html

AVPlayer的基本使用相关推荐

  1. [iOS]调和 pop 手势导致 AVPlayer 播放卡顿

    作者 NewPan 关注 2017.07.15 14:24* 字数 3110 阅读 749评论 8喜欢 17 声明:我为这个框架写了四篇文章: 第一篇:[iOS]UINavigationControl ...

  2. iOS: ios视频播放(MPMediaPlayerController,AVPlayer,AVPlayerViewcontroller、ffmpeg-AVPlayer)...

    介绍: 和音频播放一样,ios也提供个很多的API.如mediaPlayer.framework下的MPMediaPlayerController.AVFounditon.framework下的AVP ...

  3. AVPlayer支持VSFilter啦, 也就支持字幕啦

    2019独角兽企业重金招聘Python工程师标准>>> 哈哈, 以前研究dshow的时候, 研究过VSFilter, 在以dshow为基础的播放器中(比如暴风, 射手等等...), ...

  4. AVPlayer播放视频

    2019独角兽企业重金招聘Python工程师标准>>> // //  ViewController.m //  04-AVPlayer播放视频 // //  Created by鹿微 ...

  5. AVPlayer 之avcore模块

    2019独角兽企业重金招聘Python工程师标准>>> avcore模块介绍 avcore事实上它只是一个对外的c++类接口, 目前基于windows实现. 在avcore中, av ...

  6. boost avplayer

    from  http://avplayer.org/ 开源了许多代码, 可以看看其中需要的部分. http, avbot: rip && xmpp p2p 播放器

  7. linux p2p视频播放器,avplayer: 一个基于FFmpeg、libtorrent的P2P播放器实现.

    一直以来, 在多媒体播放器这块, 即使目前有许多开源的播放器项目, 但要写一个播放器仍然是件非常困难的事, 如果在windows上你有可能需要熟悉DShow, 另外的话, 你需要学习一堆开源项目(比如 ...

  8. iOS AVPlayer 简单应用

    //1 AVPlayerViewController *avvc = [[AVPlayerViewController alloc] init]; //2 avvc.player = [[AVPlay ...

  9. android ios av tv,iOS使用AVPlayer制作战旗TvDEMO OC版

    在视频教学中看到一个别人写的战旗TvDEMO写得很好,于是自己动手试着制作一个. 效果如下图所示 主界面 竖屏播放 横屏播放 点击出现工具栏 视频播放使用的是AVPlayer,具体的使用方式如下 // ...

  10. iOS开发:AVPlayer实现流音频边播边存

    1. AVPlayer简介AVPlayer存在于AVFoundation中,可以播放视频和音频,可以理解为一个随身听AVPlayer的关联类:AVAsset:一个抽象类,不能直接使用,代表一个要播放的 ...

最新文章

  1. 获取JSON格式的树形
  2. poj-1159 Palindrome **
  3. Ueditor1.4.3上传视频IE下无法播放的问题
  4. 【Linux】一步一步学Linux——wget命令(192)
  5. 反射获取成员变量并使用【应用】
  6. 个人IOCP服务器例子解说
  7. 数据结构-链表的删除和添加
  8. iptables的连接追踪机制和nf_conntrack调优
  9. 洛谷——P1320 压缩技术(续集版)
  10. 遥感软件_遥感软件的可持续发展
  11. 跨平台iOS自动化测试工具——tidevice安装及使用
  12. dell服务器系统备份软件,使用 AlienRespawn 备份 Alienware 电脑的系统
  13. 数据库设计4-概念结构设计
  14. iphone中按Home键退出程序
  15. 【TypeError: Descriptors cannot not be created directly. 】解决方法
  16. 旋转体体积和平行截面的面积求体积
  17. 流畅的python 14章可迭代的对象、迭代器 和生成器
  18. C语言之时间复杂度空间复杂度
  19. 想要专升本你不得不看的全干货_吐血整理_专升本_计算机文化基础(五)
  20. 区块链“不可能三角难题”解决了

热门文章

  1. SDWebImage 加载网络图片不能显示
  2. C#跨平台开发桌面程序(Avalonia)
  3. 数据解读 | 离开互联网大厂的年轻人都去了哪儿?
  4. 【毕业设计】python+opencv+深度学习实现二维码识别
  5. 计算机 桌面黑屏怎么办,计算机桌面黑屏怎么办
  6. python简单爬虫手机号_使用Python编写多线程爬虫抓取邮箱与手机号(2)
  7. Python 日期和时间day12
  8. 光源基础(4)——如何选择光源及各种打光结构
  9. 【猜凶手,猜名次,杨辉三角】经典小学奥数的代码逻辑是什么?
  10. 使用 Moco 搭建一个模拟服务器