iOS视频流开发(2)—视频播放
承上篇,本篇文章主要介绍iOS视频播放需要用到的类。以及他们的使用场景和开发中遇到的问题。
MPMoviePlayerViewController
MP简介
iOS提供MPMoviePlayerController类进行播放,支持流媒体和文件播放。MPMoviePlayerController足够强大,几乎不用写几行代码就能完成一个播放器。视频内容会渲染到他的View上,这个View可以移动、缩放,放在任何用户想放的地方,而在缩放移动的过程中视频都可以正常的播放,完全不受影响。
通常我们在ipad上会做这样的小窗播放功能,让用户可以边看视频边看电子书或者浏览网页。
MP支持的格式
- MPMoviePlayerController既支持本地视频文件的播放也支持流媒体(HTTP Live Streaming)
- MPMoviePlayerController因为使用的是硬解码,所以支持的文件格式只有以H264为编码格式的MP4、MOV、M4V、M2V、3GP等。
- MPMoviePlayerController支持大多数音频编码。
- 其他格式的解码比如rmvb,可以考虑第三方解码框架ffmpeg。ffmpeg等第三方解码框架使用的是软解码,所以手机的发热和耗电非常的恐怖,如非必要,不要使用。
- 视频格式的相关知识的详细介绍:iOS视频流开发(1)—视频基础知识
MP开发注意事项
由于MPMoviePlayerViewController的初始化方法做了大量工作,例如设置URL、自动播放、添加点击Done完成的监控等。所以尽可能重用,而不要频繁的销毁重新创建,重用一个MPMoviePlayerViewController非常简单,将新的播放地址设置过去就可以了
MPMoviePlayerViewController进入全屏播放模式的时候,一定要监听他的stop状态,并进行处理,继续播放或者退出全屏。否则一直停在全屏模式下。
MPMoviePlayerViewController是一个很复杂的视图结构,我们有时候需要对播放器添加一些控件。我建议不要在MPMoviePlayerViewController上修改,因为MP在iOS4、5、6、7上的视图结构都不一样,添加自定义控件非常容易出问题。那需求又必须让我们加入自定义的控件怎么办呢?这个时候我们就需要用到AVPlayer了。
AVPlayer
AVPlayer简介
当需要自定义播放器的样式时,我们可以使用AVPlayer。AVPlayer在AVFoundation框架中,相比MPMoviePlayerController它更加接近于底层。由于AVPlayer是作用在layer上,效率会比MP高一些。
AVPlayer播放
AVPlayer本身并不能显示视频。他通过创建一个播放器层AVPlayerLayer用于展示视频,播放器层继承于CALayer,有了AVPlayerLayer之后,将AVPlayerLayer添加到控制器视图的layer中即可。相比MP直接传入一个URL,AVPlayer播放的时候略微复杂一些,需要用到以下数据结构:
AVURLAsset:AVAsset的子类,可以根据一个URL路径创建一个包含媒体信息的AVURLAsset对象。
AVPlayerItem:一个媒体资源管理对象,管理者视频的一些基本信息和状态,一个AVPlayerItem对应着一个视频资源。
AVPlayer获取播放状态
- 视频加载状态
通过KVO监听AVPlayerItem的status属性来获得。当AVPlayerItem的status属性为AVPlayerStatusReadyToPlay时,表明视频加载完成。 - 视频缓冲状态
同样,通过KVO监听AVPlayerItem的loadedTimeRanges属性来获得。视频每缓冲一部分这个属性数据就会被更新,当loadedTimeRanges的值改变时可以获得本次缓冲加载的视频范围,包含起始时间、本次加载时长),这样一来就可以实时获得缓冲情况。 - 播放进度状态
通过AVPlayer的- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block方法获得播放进度,这个方法会在设定的时间间隔内定时更新播放进度。
AVQueuePlayer
AVQueuePlayer用于列表播放,虽然AVPlayer通过监听播放状态也可以做到视频结束后的自动切换,但是使用AVQueuePlayer加载会快很多。应该是AVFoundation框架对AVQueuePlayer进行了优化,排队的视频会进行预加载。
iOS视频播放:
iOS提供MPMoviePlayerController这个类有个非常难用的点,就是他的频播放状态和视频加载状态都是通过Notification通知状态变化,而不是通过block或者delegate。在实际使用中稍微不注意就会出问题,尤其是在视频列表中。如果苹果的工程师不是脑子进水的话,为什么这样设计呢?
我认为之所以这样设计的原因是,无论MPMoviePlayerController还是AVPlayer,都只是一个外壳,他们内部都是用了一个同一个CoreMedia的播放组件,这个播放组件是全局单例。包括iOS浏览器使用的播放器(浏览器的播放器以plugin的形式嵌入)都是使用的这个播放内核。所以理论上也就不可能在一部iOS设备上同时播放两个视频,一个播放另一个必然停止,无论它是网页还是本地。那么Notification这样的应用程序级的通知方式似乎比block或者delegate这样类级别的方式更合理。
大家可以试试,看看用原生播放器能否做到一个iOS设备上同时播放两个视频。
iOS视频流开发(2)—视频播放的更多相关文章
- iOS视频流开发(2) — 视频播放
iOS视频流开发(2) — 视频播放 承上篇,本篇文章主要介绍iOS视频播放需要用到的类.以及他们的使用场景和开发中遇到的问题. MPMoviePlayerViewController MP简介 i ...
- iOS视频流开发(1)—视频基本概念
iOS视频流开发(1)-视频基本概念 手机比PC的优势除了便携外,她最重要特点就是可以快速方便的创作多媒体作品.照片分享,语音输入,视频录制,地理位置.一个成功的手机APP从产品形态上都有这其中的一项 ...
- [iOS 视频流开发-获得视频帧处理]
调用视频流所使用框架:<Foundation/Foundation.h> 必须定义的参数: 1.AVCaptureDevice(捕获设备:前置.后置摄像头等) 2.AVCaptureInp ...
- 浅谈iOS视频开发
浅谈iOS视频开发 这段时间对视频开发进行了一些了解,在这里和大家分享一下我自己觉得学习步骤和资料,希望对那些对视频感兴趣的朋友有些帮助. 一.iOS系统自带播放器 要了解iOS视频开发,首先我们从 ...
- iOS 视频开发学习
原文:浅谈iOS视频开发 这段时间对视频开发进行了一些了解,在这里和大家分享一下我自己觉得学习步骤和资料,希望对那些对视频感兴趣的朋友有些帮助. 一.iOS系统自带播放器 要了解iOS视频开发,首先我 ...
- 中文 iOS/Mac 开发博客列表
中文 iOS/Mac 开发博客列表 博客地址 RSS地址 OneV's Den http://onevcat.com/atom.xml 一只魔法师的工坊 http://blog.ibireme.com ...
- Unity iOS混合开发界面切换思路
Unity iOS混合开发界面切换思路 最近有很多博友QQ 私信 或则 留言联系我,请教iOS和Unity界面之前相互切换的问题,源代码就不私下发你们了,界面跳转功能的代码我直接贴到下面好了,顺带说i ...
- ios新手开发——toast提示和旋转图片加载框
不知不觉自学ios已经四个月了,从OC语法到app开发,过程虽然枯燥无味,但是结果还是挺有成就感的,在此分享我的ios开发之路中的小小心得~废话不多说,先上我们今天要实现的效果图: 有过一点做APP经 ...
- iOS常用开发技巧
iOS开发过程中,总有那么一些个小问题让人纠结,它们不会让程序崩溃,但是会让人崩溃.除此之外,还将分享一些细节现在我通过自己的总结以及从其他地方的引用,来总结一下一些常见小问题. 本篇长期更新,多积累 ...
随机推荐
- SQL将Null转化为0
使用ifnull() ) ; 使用判断 public function getGold($table,$querry,$start,$end,$status,$field) { $gold = Db: ...
- UVA11401-Triangle Counting-递推
给出一个数字n,计算从1到n能组成几个不同的三角形. n的范围是10^6,大概就是递推吧.从F[i-1]到F[i]可以线性求出.要注意结果超出int. #include <cstdio> ...
- Json 转 dynamic
直接上代码: var model = JsonConvert.DeserializeObject<dynamic>("{\"ResponseResult\": ...
- BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】
题目分析: 很无聊的一道题目.首先区间内单点对应异或值的询问容易想到trie树.由于题目在树上进行,case1将路径分成两段,然后dfs的时候顺便可持久化trie树做询问.case2维护dfs序,对d ...
- 趣谈生成函数 =v=
趣谈生成函数 =v= 今天luyouqi在洛谷随机跳题rand出来一道生成函数板子题,然后我给做了(雾 发现小伙伴们还不会生成函数,于是我试着写这篇生成函数简介.(其实我也不怎么会生成函数这么高级的东 ...
- java匹配竖线的错误警示
String s1 = "|"; // 输出 | System.out.println(s1); String s2 = s1.replaceAll("|",& ...
- 洛谷P4843 清理雪道
题意:给你DAG,求最小路径边覆盖.路径可重. 解:首先可以想到边转点,发现有n²条边,果断超时. 有源汇有上下界最小流. 建图:每条边都建立一条边,流量限制为[1, 1]. 源点向每个点连边,因为都 ...
- linux提取指定列字符并打印所有内容(awk)
假设有文件长如下样子: CHROM POS ID REF ALT QUAL FILTER INFO FORMAT samplename 1 3552 ...
- 洛谷 P1282 多米诺骨牌("01"背包)
传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 参考资料: [1]:https://blog.csdn.net/Darost/artic ...
- MySQL基本命令行
登陆:mysql –h localhost –u 用户名 –p mysql –u 用户名 –p (默认连接localhost服务器) 服务器中可以有多个库,库中可以有多个表.数据库的名字无法修改 ...