iOS 处理HLS视频流
一、HLS介绍
HLS是苹果主导的音视频传输协议,其主要的格式是一个索引文件(M3U8)+ ts分片的视频文件。
HLS的优势是iOS系统天然支持,通过Http 80传输,规避了常规的防火墙问题。
视频的分片方便服务器CDN对视频文件分发缓存。
HLS支持视频点播和直播,直播的延时可能达到10s。
二、HLS协议内容
完整的HLS协议包含,视频加密标准(MPEG4、H264)、音频加密标准(AAC、MP3);
视频封装标准 TS
视频如何切片 M3U8
视频如何传输 M3U8索引描述ts流分片
对于客户端来说,常见的就是对HLS协议的利用
M3U8描述格式:
通过苹果的 https://developer.apple.com/streaming/examples/advanced-stream-ts.html 在线视频,可以抓包看到
#EXTM3U #EXT-X-VERSION:6 #EXT-X-INDEPENDENT-SEGMENTS #EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=2218327,BANDWIDTH=2227464,CODECS="avc1.640020,mp4a.40.2",RESOLUTION=960x540,FRAME-RATE=60.000,CLOSED-CAPTIONS="cc1",AUDIO="aud1",SUBTITLES="sub1" v5/prog_index.m3u8 #EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=8144656,BANDWIDTH=8178040,CODECS="avc1.64002a,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=60.000,CLOSED-CAPTIONS="cc1",AUDIO="aud1",SUBTITLES="sub1" v9/prog_index.m3u8 #EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=6307144,BANDWIDTH=6453202,CODECS="avc1.64002a,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=60.000,CLOSED-CAPTIONS="cc1",AUDIO="aud1",SUBTITLES="sub1" v8/prog_index.m3u8 #EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=4775338,BANDWIDTH=5054232,CODECS="avc1.64002a,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=60.000,CLOSED-CAPTIONS="cc1",AUDIO="aud1",SUBTITLES="sub1" v7/prog_index.m3u8 #EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=3240596,BANDWIDTH=3289288,CODECS="avc1.640020,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=60.000,CLOSED-CAPTIONS="cc1",AUDIO="aud1",SUBTITLES="sub1" v6/prog_index.m3u8 #EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=1292926,BANDWIDTH=1296989,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=768x432,FRAME-RATE=30.000,CLOSED-CAPTIONS="cc1",AUDIO="aud1",SUBTITLES="sub1" v4/prog_index.m3u8 #EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=914722,BANDWIDTH=922242,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,FRAME-RATE=30.000,CLOSED-CAPTIONS="cc1",AUDIO="aud1",SUBTITLES="sub1" v3/prog_index.m3u8 #EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=541239,BANDWIDTH=553010,CODECS="avc1.640015,mp4a.40.2",RESOLUTION=480x270,FRAME-RATE=30.000,CLOSED-CAPTIONS="cc1",AUDIO="aud1",SUBTITLES="sub1" v2/prog_index.m3u8
HLS协议是一个文本协议,一个M3U8中通过不同的Tag来描述,视频的内容
参考:https://tools.ietf.org/html/rfc8216
这篇文章写的比较清楚,https://www.cnblogs.com/jimodetiantang/p/9133564.html
三、HLS在iOS上面的的应用
1)如果仅仅是播放,那就比较简单,直接使用AVPlayer接口就可以了
AVPlayer加载AVPlayerItem的结构,这个对象通过对本地音视频文件或者远程视频文件的封装的到
AVURLAsset通过对M3U8播放地址对封装,可以的到一个远程对Asset,穿入到AVPlayer中,可以自动下载播放
可以很方便看到,这个封装中可以传入对应对Cookie
类似这种,下面的URL是Mp4文件,如果换成M3U8也可以播放的
NSURL *assetUrl = [NSURL URLWithString:@"http://flv2.bn.netease.com/videolib3/1606/23/RiTxE9164/SD/RiTxE9164-mobile.mp4"]; AVAsset *asset = [AVAsset assetWithURL:assetUrl]; AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset]; self.player = [AVPlayer playerWithPlayerItem:item];
2)HLS的下载解析
通过上面的例子,可以的到一个AVUrlAsset,这个asset除了用来播放之外,还可以用来下载
可以初始化为一个DownloadTask,然后跟普通的下载一样,放入NSUrlSession中
类似下面的代码
NSURL *assetURL = [NSURL URLWithString:@"STREAMING_HOST/video/hls/3729170.m3u8"]; AVURLAsset *hlsAsset = [AVURLAsset assetWithURL:assetURL]; urlSessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"assetDowloadConfigIdentifier"]; avAssetDownloadSession = [AVAssetDownloadURLSession sessionWithConfiguration:urlSessionConfiguration assetDownloadDelegate:self delegateQueue:[NSOperationQueue mainQueue]]; // Download movie avAssetDownloadTask = [avAssetDownloadSession assetDownloadTaskWithURLAsset:hlsAsset assetTitle:@"downloadedMedia" assetArtworkData:nil options:nil]; //@{AVAssetDownloadTaskMinimumRequiredMediaBitrateKey : @(300000)} [avAssetDownloadTask resume];
当下载完毕之后,会回调
在这里,会在本地会生成一个movpkg的文件夹,也就是MOV打包文件
在这个文件夹中,包含一个一个M3U8的描述文件,和多个frag视频分片
这里的分片有可能是加密的,如果是加密的,需要通过M3U8中 ,指定key的url,下载到key,并且通过M3U8解析到IV
通过Key和IV,使用AES CBC 解析的到解密后到视频文件。
TS流本身可以直接通过二进制到方式追加,追加之后还是可以直接播放的。
如果,要进行合并,可以使用ffmpeg 的命令行进行ts流合并
四、附加
这里的下载回调,建议不通过来处理成功的逻辑,因为这里处理成功的逻辑时,拿不到本地文件的下载路径
/* Sent as the last message related to a specific task. Error may be * nil, which implies that no error occurred and this task is complete. */ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error;