解析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文件的路径,路径可以是绝对路径也可以是相对路径;
客户端可以自己判断目前的网络带宽,来决定播放哪一个视频流