直播电视HLS协议分析及实现3---URL相对地址拼接
来源:互联网 发布:彩票双色球数据分析 编辑:程序博客网 时间:2024/05/16 20:53
上一篇文章中获取segment地址列表的时候,出现了url相对地址,那么是如何转化为绝对url地址的呢?下面先来了解一些概念:
URL可以看做是URI的一个子集,上面的意思放在URL的范畴上可以做如下解释:
1.就是如果想用相对路径来表示URL,则该URL与其父URL应该是同一种方法(例如:都是http,或都是ftp),否则需要用绝对路径来表示。
2.如果相对路径表示的URL是以反斜杠开头的,[这段的英文有点绕,看的不是太清楚]则取其父URL第一个相同数量反斜杠位置的左侧部分[连续多个反斜杠?貌似http里面很少看到],加上相对路径表示URL,组成完整的URL。
例如:页面中的有一个URL是 /info/test.html ,它的父链是http://www.example.com/index.html,则这个相对URL的完整链接是:http://www.example.com/info/test.html。
3.如果相对路径表示的URL不是以反斜杠开头,则移除该URL父链的最后一个部分,拼接上该相对路径表示的URL,组成完整的URL。
例如:页面中有一个URL是 test.html ,父链是http://www.example.com/info/index.html,则完整链接是http://www.example.com/info/test.html。
另外如果URL是 ../test.html,父链是http://www.example.com/info/index.html,则完整链接是http://www.example.com/test.html。这个和UNIX文件系统是的表示是一样的。
好了除此之外,还需要注意另外一种情况:
如果html头部有 <base>标记,例如:<base href="http://www.example.com/info/" />则该页面上的基准URL都以此为准,不考虑其父链的情况。说了这么多,如何用c代码来实现呢?这里列出ffmpeg中的相关函数,整理如下:
void ff_make_absolute_url(char *buf, int size, const char *base, const char *rel){ char *sep, *path_query; /* Absolute path, relative to the current server */ if (base && strstr(base, "://") && rel[0] == '/') { if (base != buf) av_strlcpy(buf, base, size); sep = strstr(buf, "://"); if (sep) { /* Take scheme from base url */ if (rel[1] == '/') sep[1] = '\0'; else { /* Take scheme and host from base url */ sep += 3; sep = strchr(sep, '/'); if (sep) *sep = '\0'; } } av_strlcat(buf, rel, size); return; } /* If rel actually is an absolute url, just copy it */ if (!base || strstr(rel, "://") || rel[0] == '/') { av_strlcpy(buf, rel, size); return; } if (base != buf) av_strlcpy(buf, base, size); /* Strip off any query string from base */ path_query = strchr(buf, '?'); if (path_query != NULL) *path_query = '\0'; /* Is relative path just a new query part? */ if (rel[0] == '?') { av_strlcat(buf, rel, size); return; } /* Remove the file name from the base url */ sep = strrchr(buf, '/'); if (sep) sep[1] = '\0'; else buf[0] = '\0'; while (av_strstart(rel, "../", NULL) && sep) { /* Remove the path delimiter at the end */ sep[0] = '\0'; sep = strrchr(buf, '/'); /* If the next directory name to pop off is "..", break here */ if (!strcmp(sep ? &sep[1] : buf, "..")) { /* Readd the slash we just removed */ av_strlcat(buf, "/", size); break; } /* Cut off the directory name */ if (sep) sep[1] = '\0'; else buf[0] = '\0'; rel += 3; } av_strlcat(buf, rel, size);}
其中有一些字符串的拼接函数,是ffmpeg封装的标注string的函数,如果想运行这段代码,可以参照下面的例子,分别对应上面提到的三种情况:
/** * make absolute url from ffmpeg project * */#include <stdio.h>#include <stdint.h> /* for intptr_t */#include <string.h> /* for string */int av_strstart(const char *str, const char *pfx, const char **ptr){ while (*pfx && *pfx == *str) { pfx++; str++; } if (!*pfx && ptr) *ptr = str; return !*pfx;}size_t av_strlcpy(char *dst, const char *src, size_t size){ size_t len = 0; while (++len < size && *src) *dst++ = *src++; if (len <= size) *dst = 0; return len + strlen(src) - 1;}size_t av_strlcat(char *dst, const char *src, size_t size){ size_t len = strlen(dst); if (size <= len + 1) return len + strlen(src); return len + av_strlcpy(dst + len, src, size - len);}/** * make absolute url */void ff_make_absolute_url(char *buf, int size, const char *base, const char *rel){ char *sep, *path_query; /* Absolute path, relative to the current server */ if (base && strstr(base, "://") && rel[0] == '/') { if (base != buf) av_strlcpy(buf, base, size); sep = strstr(buf, "://"); if (sep) { /* Take scheme from base url */ if (rel[1] == '/') sep[1] = '\0'; else { /* Take scheme and host from base url */ sep += 3; sep = strchr(sep, '/'); if (sep) *sep = '\0'; } } av_strlcat(buf, rel, size); return; } /* If rel actually is an absolute url, just copy it */ if (!base || strstr(rel, "://") || rel[0] == '/') { av_strlcpy(buf, rel, size); return; } if (base != buf) av_strlcpy(buf, base, size); /* Strip off any query string from base */ path_query = strchr(buf, '?'); if (path_query != NULL) *path_query = '\0'; /* Is relative path just a new query part? */ if (rel[0] == '?') { av_strlcat(buf, rel, size); return; } /* Remove the file name from the base url */ sep = strrchr(buf, '/'); if (sep) sep[1] = '\0'; else buf[0] = '\0'; while (av_strstart(rel, "../", NULL) && sep) { /* Remove the path delimiter at the end */ sep[0] = '\0'; sep = strrchr(buf, '/'); /* If the next directory name to pop off is "..", break here */ if (!strcmp(sep ? &sep[1] : buf, "..")) { /* Readd the slash we just removed */ av_strlcat(buf, "/", size); break; } /* Cut off the directory name */ if (sep) sep[1] = '\0'; else buf[0] = '\0'; rel += 3; } av_strlcat(buf, rel, size);}/** * main test */void main(void){ char dst1[1024]; char dst2[1024]; char dst3[1024]; char base1[] = "http://www.example.com/index.html"; char ref1[] = "/info/test.html"; ff_make_absolute_url(dst1, sizeof(dst1), base1, ref1); printf("---------------------------------------------\n"); printf("%s\n", base1); printf("%s\n", ref1); printf("%s\n", dst1); printf("---------------------------------------------\n"); char base2[] = "http://www.example.com/info/index.html"; char ref2[] = "test.html"; ff_make_absolute_url(dst2, sizeof(dst2), base2, ref2); printf("%s\n", base2); printf("%s\n", ref2); printf("%s\n", dst2); printf("---------------------------------------------\n"); char base3[] = "http://www.example.com/info/index.html"; char ref3[] = "../test.html"; ff_make_absolute_url(dst3, sizeof(dst3), base3, ref3); printf("%s\n", base3); printf("%s\n", ref3); printf("%s\n", dst3); printf("---------------------------------------------\n"); return;}
运行结果是
--------------------------------------------- http://www.example.com/index.html /info/test.html http://www.example.com/info/test.html --------------------------------------------- http://www.example.com/info/index.html test.html http://www.example.com/info/test.html --------------------------------------------- http://www.example.com/info/index.html ../test.html http://www.example.com/test.html ---------------------------------------------
与上文提到的结果是一致的,当然实际的HLS URL的情况复杂一点,但是原理是一致的。
本文参考了:
作者:yihucha166 网址:http://blog.csdn.net/yihucha166/article/details/4388735
- 直播电视HLS协议分析及实现3---URL相对地址拼接
- 直播电视HLS协议分析及实现4---安卓手机电视apk演示版
- 直播电视HLS协议分析及实现2---协议实例分析
- 直播电视HLS协议分析及实现1---相关开源工程代码
- 网络直播电视之寻找直播地址
- 【HLS】【转】HTTP Live Streaming直播(iOS直播)技术分析与实现
- URL地址的拼接
- 直播协议的选择:RTMP vs. HLS
- 直播协议的选择:RTMP vs. HLS
- HLS协议实现
- HLS协议实现
- HLS协议实现
- HLS协议实现
- 网络电视在线直播地址大全
- 网络直播电视之寻找直播地址(上)
- 网络直播电视之寻找直播地址(下)
- 基于HLS(HTTP Live Streaming)的视频直播分析与实现
- 关于实现HLS直播的一些探究
- 自行车租凭移动开发
- apt命令使用
- win7下IIS的安装和配置 图文教程
- 一些大牛的blog
- iPhone开发中为UINavigationBar设置背景图片方法
- 直播电视HLS协议分析及实现3---URL相对地址拼接
- 美国联邦政府电子政务架构(FEA)
- Java程序员从笨鸟到菜鸟之(五十)细谈Hibernate(一)hibernate基本概念和体系结构
- 反向 Ajax,第 1 部分: Comet 简介
- dos批处理文件之adb push
- ubuntu 11.04下android开发环境的搭建!
- Java程序员从笨鸟到菜鸟之(五十一)细谈Hibernate(二)开发第一个hibernate基本详解
- SlidingDrawer--抽屉效果
- IOS开发(48)之由init、loadView、viewDidLoad、viewDidUnload、dealloc的关系说起