iOS技术程序员iOS分享世界

iOS流媒体开发之一:总结系统提供的接口

2016-06-30  本文已影响5811人  张云龙

尊重知识,转发请注明出处:iOS流媒体开发之一:总结系统提供的接口
<small> 本文参考了博文部分内容:AVPlayer 本地、网络视频播放相关 </small>


最近独立完成了公司的一个电视直播和电台直播的流媒体类项目,目前完成了第一版,已经上线,开发过程中收获很多,准备写一个流媒体系列博客总结和分享我的一些感悟。第一篇很简单,主要是总结下系统提供的常用的音视频开发接口,属于可以百度或者Google到一大堆资料的东西,几个不支持流媒体播放的接口就不说了,一方面很简单,另一方面大多数项目用不到。了解这些技术的小伙伴就忽略吧,我这里只是简单的总结下,没有太多技术含量和价值。

预告

后续会分享有关自定义视频播放器M3U8下载M3U8回看等比较有难度的技术点,当然也不是随便百度或者Google下就可以找到的东西,我就把这些技术点献给简书吧。这里主要总结M3U8直播类的音视频技术,至于MP4、3GP等等这些点播类的播放源都很简单,无论下载还是播放都很容易实现,就不浪费简书的服务器硬盘了。最近时间很紧,并且有一些技术点还需要继续改进和优化,争取尽快整理出比较靠谱的东西给大家。


MPMoviePlayerController

AVPlayer

真机运行图如下:


AVPlayer播放M3U8效果.png

控制台输出结果
开始:0.000000,持续:0.325000,总时间:0.325000 视频的加载进度是:%inf 准备播放 开始:0.000000,持续:18.203000,总时间:18.203000 视频的加载进度是:%12.227365 开始:0.000000,持续:35.108000,总时间:35.108000 视频的加载进度是:%23.582833 开始:0.000000,持续:43.119000,总时间:43.119000 视频的加载进度是:%28.964002 开始:0.000000,持续:46.068000,总时间:46.068000 视频的加载进度是:%30.944912 开始:0.000000,持续:62.160000,总时间:62.160000 视频的加载进度是:%41.754270 开始:0.000000,持续:73.283000,总时间:73.283000 视频的加载进度是:%49.225840 开始:0.000000,持续:80.064000,总时间:80.064000 视频的加载进度是:%53.780790 开始:0.000000,持续:94.298000,总时间:94.298000 视频的加载进度是:%63.342088 开始:0.000000,持续:101.682000,总时间:101.682000 视频的加载进度是:%68.302087 开始:0.000000,持续:106.977000,总时间:106.977000 视频的加载进度是:%71.858858 开始:0.000000,持续:117.775000,总时间:117.775000 视频的加载进度是:%79.112117 开始:0.000000,持续:132.172000,总时间:132.172000 视频的加载进度是:%88.782906 开始:0.000000,持续:148.871000,总时间:148.871000 视频的加载进度是:%100.000000
从控制台输出的结果可以很清楚的看到视频加载的进度,这里有几点需要注意
1、只有播放状态变成AVPlayerItemStatusReadyToPlay时才可以获取视频播放的总时间,提前获取无效; 2、我们判断缓冲进度是靠比较视频总时长self.total和已经缓冲的总时间durationSeconds作比较,如果二者相等即达到100%视频则加载完成,这里需要注意,有时这2个值在浮点数下不一定相同,有可能出现99.990836%这样的情况,但是视频实际上已经加载完成,如果我们硬性的凭借100%判断会出现有的视频永远加载不完的假象,因此在判断的时候应该设置一个误差值,比如缓冲进度>99.95%就认为是加载完成了,具体数值可以根据项目自行设定一个合理的误差; 3、这里显示的所有数据,比如视频的总时长、进度都是点播类播放源,非M3U8,M3U8是直播无法获取总时长数据,开始时间和缓冲时间等数据也没有参考价值,项目中的直播视频也不会涉及到这些。

2、获取AVPlayer当前的播放进度

    CMTime ctime = self.avPlayer.currentTime;
    CGFloat currentTimeSec = ctime.value / ctime.timescale;

有了当前的播放进度,视频的进度条功能就可以完成,很简单,这里就不赘述了。

3、关于AVPlayer播放卡顿时如何获取此时的状态也是我遇到的难题,因为AVPlayer并没有给出这种状态,有人说根据AVPlayer的rate是1还是0判断,经测试这个方法不靠谱,即使卡顿时rate有时还是1,文章开头连接的博文给出了一种解决办法,可以参考下,这里大家有什么好的方法欢迎留言,感激不尽。

    self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(upadte)];
    [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

实现update方法

- (void)upadte
{
NSTimeInterval current = CMTimeGetSeconds(self.avPlayer.currentTime);

if (current!=self.lastTime) {
    //没有卡顿
    NSLog(@"没有卡顿");
}else{
    //卡顿了
    NSLog(@"卡顿了");
}
self.lastTime = current;
}

AVPlayerViewController


尾巴

这里只总结了MPMoviePlayerController、AVPlayer、AVPlayerViewController3个开发流媒体常用的接口,在开发中如何选择呢,我总结了一些经验,仅供参考。
1、如果是纯音频的流媒体项目,并且最低支持的版本在iOS9以下,使用MPMoviePlayerController最合适,音频不需要考虑MPMoviePlayerController本身自定义的界面,只需要播放声音,界面我们自己布局就可以了,并且获取播放的各种状态也要比其余两种方便。
2、有视频需求的流媒体项目,如果只是简单的视频需求可以使用MPMoviePlayerController,如果要深度自定义视频播放器,建议使用AVPlayerViewController,用法和AVPlayer基本是一样的,但是AVPlayerViewController的好处是可以在后续方便的实现画中画功能,后续苹果在更新时接口时也会为AVPlayerViewController提供更多有用方便的方法和属性,方便开发者使用。

上一篇下一篇

猜你喜欢

热点阅读