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;

  

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM