一、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;