1. 程式人生 > >HLS學習(五)HLSDownloader原始碼分析(4)解析Master PlayList

HLS學習(五)HLSDownloader原始碼分析(4)解析Master PlayList

解析Master PlayList

    PlayList就是m3u8檔案或者索引檔案,Master PlayList也叫一級索引檔案。

解析Master PlayList的過程如下:

1、計算Master PlayList中URL的數量,每一個URL指向一個Media PlayList

2、根據URL的數量,分配Media PlayList的記憶體(Master PlayList中有一個Media PlayList陣列)

3、解析出Master PlayList中的URL,然後格式化(把不規則的路徑格式化成標準的HTTP型別的URL),並放入 Media PlayList的URL欄位中

4、解析出Master PlayList中的bitRate欄位,放入Media PlayList的bitRate欄位中

// 處理Master PlayList
int handle_hls_master_playlist(struct hls_master_playlist *ma)
{
	// 分析PlayList中URL的數量
    ma->count = get_link_count(ma->source);
	
	// 為分配Media PlayList的記憶體
    ma->media_playlist = new hls_media_playlist[ma->count];//(hls_media_playlist *)malloc(sizeof(struct hls_media_playlist) * ma->count);
    
	// 解析Master PlayList中的URL
	if (master_playlist_get_links(ma)) {
        MSG_ERROR("Could not parse links. Exiting.\n");
        return 1;
    }

    for (int i = 0; i < ma->count; i++) {
        ma->media_playlist[i].bitrate = 0;
    }

	// 解析Master PlayList中的bitRate
    if (master_playlist_get_bitrate(ma)) {
        MSG_ERROR("Could not parse bitrate. Exiting.\n");
        return 1;
    }
    return 0;
}

Master PlayList示例:

#EXTM3U #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1064000 1000kbps.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=564000 500kbps.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=282000 250kbps.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2128000 2000kbps.m3u8      bandwidth指定視訊的位元率;      PROGRAM-ID無需關注;
     每個#EXT-X-STREAM-INF的下一行就是二級index檔案的路徑,路徑可以是絕對路徑也可以是相對路徑;      客戶端可以自己判斷目前的網路頻寬,來決定播放哪一個視訊流

獲取URL的數量

// 獲取URL的數量
static int get_link_count(char *src)
{
    int linkcount = 0;

	// 除去以#開頭的行和空白行,剩下的都是URL行
    while (src != NULL) {
        if (*src == '#'||*src=='\n') {
            src = next_line(src);
            continue;
        }
        if (*src == '\0') {
            break;
        }
        linkcount++;
        src = next_line(src);
    }

    return linkcount;
}


解析URL

// 解析URL
// 解析出來的URL填入Media PlayList中的URL欄位
static int master_playlist_get_links(struct hls_master_playlist *ma)
{
    struct hls_media_playlist *me = ma->media_playlist;
    char *src = ma->source;

	// 分配記憶體
    for (int i = 0; i < ma->count; i++) {
        me[i].url = (char *)malloc(strlen(src));
    }

	// 讀取URL
    for (int i = 0; i < ma->count; i++) {
        while (src != NULL) {
            if (*src == '#' || *src == '\n') {
                src = next_line(src);
                continue;
            }
            if (*src == '\0') {
                goto finish;
            }
            if (sscanf(src, "%[^\n]", me[i].url) == 1) {
                src = next_line(src);
                break;
            }
        }
    }

finish:
    for (int i = 0; i < ma->count; i++) {
        extend_url(&me[i].url, ma->url); // 格式化URL
    }
    return 0;
}


解析位元率

// 解析Master PlayList中的bitRate
static int master_playlist_get_bitrate(struct hls_master_playlist *ma)
{
    struct hls_media_playlist *me = ma->media_playlist;

    char *src = ma->source;

	// BANDWIDTH欄位就表示位元率
    for (int i = 0; i < ma->count && src; i++) {
        if ((src = strstr(src, "BANDWIDTH="))) {
            if ((sscanf(src, "BANDWIDTH=%u", &me[i].bitrate)) == 1) {
                src++;
                continue;
            }
        }
    }
    return 0;
}


      #EXTM3U #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1064000 1000kbps.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=564000 500kbps.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=282000 250kbps.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2128000 2000kbps.m3u8      bandwidth指定視訊的位元率;      PROGRAM-ID無需關注;      每個#EXT-X-STREAM-INF的下一行就是二級index檔案的路徑,路徑可以是絕對路徑也可以是相對路徑;      客戶端可以自己判斷目前的網路頻寬,來決定播放哪一個視訊流