转载地址:http://www.tuicool.com/articles/3qaUnqF
最近的一个项目涉及到视频播放,在一段时间的“技术调研”之后完成的项目的完整编码和测试。回过头看时,发现自己在所谓的“技术调研”阶段简直是在乱撞,毫无章法。因此总结一文于此。以备后查。
脑洞开一下
和拍照相仿,都是需要一个主题,也就是要表现什么。同样,调研的主体要明确。比如说,要研究视频播放。那么,思维发散开来,视频播放涉及到哪些东西?(参考但并不仅限于下图)
终于,开始进入正题。
As A …
作为一个视频播放的工具,要能播放视频(能够同时支持音频更好)。那么:
- 视频来自哪里呢:要么是本地资源,要么是网络资源、流媒体一类。
- 能支持什么格式:mp4?m3u8?wav?mp3?
(PS: 打印audiovisualMIMETypes属性查看AVPlayer支持哪些格式:
“audio/aacp”,
“audio/mpeg3”,
“audio/mp3”,
“audio/x-caf”,
“audio/mpeg”,
“audio/x-mpeg3”,
“audio/wav”,
“audio/scpls”,
“audio/mp4”,
“audio/x-mpg”,
“audio/x-wav”,
“audio/x-aiff”,
“audio/x-m4p”,
“audio/x-scpls”,
“audio/x-mpegurl”,
“audio/x-aac”,
“audio/3gpp”,
“audio/basic”,
“audio/x-m4a”,
“audio/x-mpeg”,
“audio/wave”,
“audio/x-m4r”,
“audio/x-mp3”,
“audio/AMR”,
“audio/aiff”,
“audio/3gpp2”,
“audio/aac”,
“audio/mpg”,
“audio/mpegurl”,
“audio/x-m4b”,“video/3gpp2”,
“video/quicktime”,
“video/mp4”,
“video/avi”,
“video/x-m4v”,
“video/3gpp”,“text/vtt”,
“application/mp4”,
“application/x-mpegurl”
“application/vnd.apple.mpegurl”)
- 播放的场景:在应用中前台播放?扔到后台去了是自动暂停还是继续播放?
- 对于单一资源而言,要能够:
- 播放/暂停;
- 改变播放进度;
- 音量控制;
- 全屏显示;
- ……
- 对于多个资源而言,可能需要:
- 视频队列的播放;
- 视频间的切换;
- 视频浏览;
- ……
如何实现
在iOS中,怎么实现这个播放视频的功能?
1.需要系统的什么类库:
- MediaPlayer.framework中的MPMoviePlayerController来实现的确简单,几句代码就够了,而且支持本地视频和网络视频,但是对于界面的自定义不强。pass掉。(在iOS9开始被标记为了弃用,改用AVPlayerViewController了。)
- AVFoundation。AVPlayer存在于其中。它更接近底层,所以灵活性也更强。但是,AVPlayer本身并没有view属性,如果要显示必须创建一个播放器层AVPlayerLayer用于展示。
```
// DPlayerLayerView.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface DPlayerLayerView : UIView
@property (nonatomic, strong) AVPlayer *player;
-(void)setVideoFillMode:(NSString *)fillMode;
@end
```
```
// DPlayerLayerView.m
#import "DPlayerLayerView.h"
@implementation DPlayerLayerView
+(Class)layerClass
{
return [AVPlayerLayer class];
}
// 单纯使用AVPlayer类是无法显示视频的,要将视频层添加至AVPlayerLayer中,这样才能将视频显示出来。
-(AVPlayer *)player
{
return [(AVPlayerLayer *)[self layer] player];
}
-(void)setPlayer:(AVPlayer *)player
{
[(AVPlayerLayer *)[self layer] setPlayer:player];
}
// 指定video在player layer的bounds内如何显示。(默认是AVLayerVideoGravityResizeAspect)
/* 可选项:
* AVLayerVideoGravityResizeAspect,保证宽高比,在layer的bounds内正常显示;
* AVLayerVideoGravityResizeAspectFill,保证宽高比,填充满layer的bounds;
* AVLayerVideoGravityResize,拉伸来填满layer的bounds。
*/
-(void)setVideoFillMode:(NSString *)fillMode
{
AVPlayerLayer *playerLayer = (AVPlayerLayer *)[self layer];
playerLayer.videoGravity = fillMode;
}
@end
```
- AVKit。iOS8以来的新秀。用来代替MPMoviePlayerViewController。基于AVFoundation。它提供了视频播放的UI,又可以播放任何来自AVFoundation的
AVPlayer
对象。(由于项目需要支持iOS7,所以,只能忍痛割爱T_T)
2.API
之前把AVPlayer类中的方法梳理了一遍,在这里,AVPlayerItem和AVURLAsset时间允许的话也应该整理一下。比如AVPlayerItem中的cancelPendingSeeks
和AVAsset中的cancelLoading
,就帮我解决了一个困扰很久的问题。API就在那儿,不近不远。你看到了,就找到了光明;看不到,就继续在黑暗中摸索。
3.来自苹果的demo
这就是苹果赠予开发者的彩蛋啊。在网络上茫茫如海的资料中,官网demo永远是那个指引的灯塔,是经常让你感慨“原来可以这么写这么简单”的存在。
视频播放相关的demo有:
- MoviePlayer;
- AVPlayerDemo;
- AVLoupe。
(PS:Xcode自带的Document其实很好用,Command + Shift + 数字0,调出来就可以直接搜索,可加标签,可看demo,和Dash的差别就是不能在这里看收藏的代码段,但是可以在Utility View中看啊~)
4.其他教程
能够在接触一个事物/模块的初期看到一篇通俗易懂、条理清晰的教程也是个幸运的事。以下列出几篇从中受益匪浅的,以此感谢各位作者。
http://www.cnblogs.com/kenshincui/p/4186022.html
https://www.shinobicontrols.com/blog/ios8-day-by-day-day-26-avkit
Trick or treat?
除了上面列出的基本功能外,还有一些可能现在不是必须、但很常见的功能点。比如:
- 获取视频的缩略图;
- 清理缩略图的缓存;
- 资源的缓存;
- 本地视频资源的播放;
- 清理已下载资源的缓存;
- 资源队列;
- 跳到指定位置开始播放;
- 网络状况切换时的处理;
- 限制带宽的情况下,对于码流和清晰度的支持(一般来说,如果是IM的宽带,在网上只能看不超过128kbps的视频,超过128kbps的视频只能等视频缓冲才能顺利观看。);
- ……
其他相关
对于视频有以上的问题需要考虑,那么其他相关的呢?比如:
- 音频的播放?AVPlayer本身可以播放mp3等格式的音频;同属AVFoundation中的
AVAudioPlayer
也可以播放音频,但仅限于本地文件。 - 在音频/视频播放时,对于耳机的支持?
- 尤其是视频的播放时,对于AirPlay的支持?
- ……
总结
本文并没有很详细的列出在处理视频播放时具体的API,更多的是想给之后类似的“技术调研”提供一种思考的模式,不至于上来就一头乱撞。实现一个功能不难,通过实现功能来训练自己的思维能力,才能让自己更有效率的提升吧。