iOS 处理HLS视频流

Posted doudouyoutang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;

  

  

  

以上是关于iOS 处理HLS视频流的主要内容,如果未能解决你的问题,请参考以下文章

AVPlayerLayer 不在 iOS 11 中渲染离线 HLS 视频

IOS - 比特率文件视频 hls

在播放 iOS 时从 HLS 流(视频)中提取/录制音频

在 iOS 上捕获/分割视频并通过 HLS 重新加入会导致音频丢失

在 iOS 13 上,AVPlayer 会为此 HLS 视频选择仅音频流。我可以控制这种行为,而是让它加载视频+音频吗?

在 iOS SDK - AVPlayer 中手动选择视频质量的 HLS 流?