HLS學習(四)HLSDownloader原始碼分析(3)總體流程
阿新 • • 發佈:2019-02-04
總體流程
下載一個媒體檔案的流程
1、初始化
2、根據URL下載m3u8檔案(即PlayList檔案)
3、判斷m3u8檔案的型別,是Master PlayList還是Media PlayList
4、如果是Master PlayList,那麼分析這個PlayList的內容,並選擇一個合適的Media PlayList,注意這一步只是分析Master PlayList的內容,並沒有下載Media PlayList
5、處理Media PlayList,因為步驟3下載的可能就是一個Media PlayList,因此,在處理之前先把舊的內容釋放掉,然後重新下載Media PlayList,再分析Media PlayList裡面的內容
6、Media PlayList分析完成之後,就得到TS媒體檔案的資訊了
7、根據TS媒體檔案資訊,下載TS檔案
8、清理
程式碼實現
// 下載一個視訊 HRESULT HLSDownloader::download_hls_video(std::string surl,std::string filename,bool livestreaming){ curl_global_init(CURL_GLOBAL_ALL); av_register_all(); // ffmpge的函式,註冊所有的編解碼器 const char * url = surl.c_str(); char *hlsfile_source; struct hls_media_playlist media_playlist; // 從伺服器上下載m3u8檔案(Master PlayList或者Media PlayList) if (get_data_from_url(url, &hlsfile_source, NULL, STRING,m_strUserAgent) == 0) { Log(LogID_MMHLSDownloader, LogLevel_Error, __FUNCTION__, ""); MSG_ERROR("No result from server.\n"); return E_FAIL; } // 獲取m3u8檔案的型別(是Master PlayList還是Media PlayList) int playlist_type = get_playlist_type(hlsfile_source); // 如果是Master PlayList if (playlist_type == MASTER_PLAYLIST) { struct hls_master_playlist master_playlist; master_playlist.source = hlsfile_source; master_playlist.url = strdup(url); // 讀取Master PlayList中的內容並分析 if (handle_hls_master_playlist(&master_playlist)) { return E_FAIL; } int max = 0; for (int i = 0; i < master_playlist.count; i++) { if (master_playlist.media_playlist[i].bitrate > master_playlist.media_playlist[max].bitrate) { max = i; } } int quality_choice = max; // 選取一個Media PlayList media_playlist = master_playlist.media_playlist[quality_choice]; master_playlist_cleanup(&master_playlist); } else if (playlist_type == MEDIA_PLAYLIST) { // 如果是Media PlayList media_playlist.bitrate = 0; media_playlist.url = strdup(url); } else { return E_FAIL; } // 處理Media PlayList if (handle_hls_media_playlist(&media_playlist,m_strUserAgent)) { return E_FAIL; } if (media_playlist.encryption) { Log(LogID_MMHLSDownloader, LogLevel_Info, __FUNCTION__, "HLS Stream is %s encrypted.", media_playlist.encryptiontype == ENC_AES128 ? "AES-128" : "SAMPLE-AES"); } Log(LogID_MMHLSDownloader, LogLevel_Info, __FUNCTION__, "Media Playlist parsed successfully"); // 下載HLS視訊 if (download_hls(&media_playlist,livestreaming,m_iMaxSize,filename.c_str(),m_strUserAgent,true)) { Log(LogID_MMHLSDownloader, LogLevel_Error, __FUNCTION__, "Download HLS Failed"); return E_FAIL; } media_playlist_cleanup(&media_playlist); curl_global_cleanup(); return S_OK; }