Chinaunix首页 | 论坛 | 博客
  • 博客访问: 523023
  • 博文数量: 86
  • 博客积分: 1076
  • 博客等级: 准尉
  • 技术积分: 1018
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-02 19:15
文章分类

全部博文(86)

文章存档

2013年(15)

2012年(69)

2011年(2)

分类: Android平台

2013-05-07 16:48:55

    上一篇文章中获取segment地址列表的时候,出现了url相对地址,那么是如何转化为绝对url地址的呢?下面先来了解一些概念:

    URL
可以看做是URI的一个子集,上面的意思放在URL的范畴上可以做如下解释:

    1. 就是如果想用相对路径来表示URL,则该URL与其父URL应该是同一种方法(例如:都是http,或都是ftp),否则需要用绝对路径来表示。

 

    2. 如果相对路径表示的URL是以反斜杠开头的,[这段的英文有点绕,看的不是太清楚]则取其父URL第一个相同数量反斜杠位置的左侧部分[连续多个反斜杠?貌似http里面很少看到],加上相对路径表示URL,组成完整的URL

    例如:页面中的有一个URL /info/test.html ,它的父链是 ,则这个相对URL的完整链接是:

 

    3. 如果相对路径表示的URL不是以反斜杠开头,则移除该URL父链的最后一个部分,拼接上该相对路径表示的URL,组成完整的URL

    例如:页面中有一个URL test.html ,父链是,则完整链接是

    另外如果URL ../test.html,父链是,则完整链接是。这个和UNIX文件系统是的表示是一样的。

    好了 除此之外,还需要注意另外一种情况:

    如果html头部 标记,例如:则该页面上的基准URL都以此为准,不考虑其父链的情况。

   说了这么多,如何用c代码来实现呢?这里列出ffmpeg中的相关函数,整理如下:

点击(此处)折叠或打开

  1. void ff_make_absolute_url(char *buf, int size, const char *base,
  2.                           const char *rel)
  3. {
  4.     char *sep, *path_query;
  5.     /* Absolute path, relative to the current server */
  6.     if (base && strstr(base, "://") && rel[0] == '/') {
  7.         if (base != buf)
  8.             av_strlcpy(buf, base, size);
  9.         sep = strstr(buf, "://");
  10.         if (sep) {
  11.             /* Take scheme from base url */
  12.             if (rel[1] == '/')
  13.                 sep[1] = '\0';
  14.             else {
  15.                 /* Take scheme and host from base url */
  16.                 sep += 3;
  17.                 sep = strchr(sep, '/');
  18.                 if (sep)
  19.                     *sep = '\0';
  20.             }
  21.         }
  22.         av_strlcat(buf, rel, size);
  23.         return;
  24.     }
  25.     /* If rel actually is an absolute url, just copy it */
  26.     if (!base || strstr(rel, "://") || rel[0] == '/') {
  27.         av_strlcpy(buf, rel, size);
  28.         return;
  29.     }
  30.     if (base != buf)
  31.         av_strlcpy(buf, base, size);

  32.     /* Strip off any query string from base */
  33.     path_query = strchr(buf, '?');
  34.     if (path_query != NULL)
  35.         *path_query = '\0';

  36.     /* Is relative path just a new query part? */
  37.     if (rel[0] == '?') {
  38.         av_strlcat(buf, rel, size);
  39.         return;
  40.     }

  41.     /* Remove the file name from the base url */
  42.     sep = strrchr(buf, '/');
  43.     if (sep)
  44.         sep[1] = '\0';
  45.     else
  46.         buf[0] = '\0';
  47.     while (av_strstart(rel, "../", NULL) && sep) {
  48.         /* Remove the path delimiter at the end */
  49.         sep[0] = '\0';
  50.         sep = strrchr(buf, '/');
  51.         /* If the next directory name to pop off is "..", break here */
  52.         if (!strcmp(sep ? &sep[1] : buf, "..")) {
  53.             /* Readd the slash we just removed */
  54.             av_strlcat(buf, "/", size);
  55.             break;
  56.         }
  57.         /* Cut off the directory name */
  58.         if (sep)
  59.             sep[1] = '\0';
  60.         else
  61.             buf[0] = '\0';
  62.         rel += 3;
  63.     }
  64.     av_strlcat(buf, rel, size);
  65. }


    其中有一些字符串的拼接函数,是ffmpeg封装的标注string的函数,如果想运行这段代码,可以参照下面的例子,分别对应上面提到的三种情况:

点击(此处)折叠或打开

  1. /**
  2.  * make absolute url from ffmpeg project
  3.  *
  4.  */
  5. #include <stdio.h>
  6. #include <stdint.h>        /* for intptr_t */
  7. #include <string.h>        /* for string */

  8. int av_strstart(const char *str, const char *pfx, const char **ptr)
  9. {
  10.     while (*pfx && *pfx == *str) {
  11.         pfx++;
  12.         str++;
  13.     }
  14.     if (!*pfx && ptr)
  15.         *ptr = str;
  16.     return !*pfx;
  17. }

  18. size_t av_strlcpy(char *dst, const char *src, size_t size)
  19. {
  20.     size_t len = 0;
  21.     while (++len < size && *src)
  22.         *dst++ = *src++;
  23.     if (len <= size)
  24.         *dst = 0;
  25.     return len + strlen(src) - 1;
  26. }

  27. size_t av_strlcat(char *dst, const char *src, size_t size)
  28. {
  29.     size_t len = strlen(dst);
  30.     if (size <= len + 1)
  31.         return len + strlen(src);
  32.     return len + av_strlcpy(dst + len, src, size - len);
  33. }

  34. /**
  35.  * make absolute url
  36.  */
  37. void ff_make_absolute_url(char *buf, int size, const char *base,
  38.                           const char *rel)
  39. {
  40.     char *sep, *path_query;
  41.     /* Absolute path, relative to the current server */
  42.     if (base && strstr(base, "://") && rel[0] == '/') {
  43.         if (base != buf)
  44.             av_strlcpy(buf, base, size);
  45.         sep = strstr(buf, "://");
  46.         if (sep) {
  47.             /* Take scheme from base url */
  48.             if (rel[1] == '/')
  49.                 sep[1] = '\0';
  50.             else {
  51.                 /* Take scheme and host from base url */
  52.                 sep += 3;
  53.                 sep = strchr(sep, '/');
  54.                 if (sep)
  55.                     *sep = '\0';
  56.             }
  57.         }
  58.         av_strlcat(buf, rel, size);
  59.         return;
  60.     }
  61.     /* If rel actually is an absolute url, just copy it */
  62.     if (!base || strstr(rel, "://") || rel[0] == '/') {
  63.         av_strlcpy(buf, rel, size);
  64.         return;
  65.     }
  66.     if (base != buf)
  67.         av_strlcpy(buf, base, size);

  68.     /* Strip off any query string from base */
  69.     path_query = strchr(buf, '?');
  70.     if (path_query != NULL)
  71.         *path_query = '\0';

  72.     /* Is relative path just a new query part? */
  73.     if (rel[0] == '?') {
  74.         av_strlcat(buf, rel, size);
  75.         return;
  76.     }

  77.     /* Remove the file name from the base url */
  78.     sep = strrchr(buf, '/');
  79.     if (sep)
  80.         sep[1] = '\0';
  81.     else
  82.         buf[0] = '\0';
  83.     while (av_strstart(rel, "../", NULL) && sep) {
  84.         /* Remove the path delimiter at the end */
  85.         sep[0] = '\0';
  86.         sep = strrchr(buf, '/');
  87.         /* If the next directory name to pop off is "..", break here */
  88.         if (!strcmp(sep ? &sep[1] : buf, "..")) {
  89.             /* Readd the slash we just removed */
  90.             av_strlcat(buf, "/", size);
  91.             break;
  92.         }
  93.         /* Cut off the directory name */
  94.         if (sep)
  95.             sep[1] = '\0';
  96.         else
  97.             buf[0] = '\0';
  98.         rel += 3;
  99.     }
  100.     av_strlcat(buf, rel, size);
  101. }

  102. /**
  103.  * main test
  104.  */
  105. void main(void)
  106. {
  107.     char dst1[1024];
  108.     char dst2[1024];
  109.     char dst3[1024];
  110.     
  111.     char base1[] = "";
  112.     char ref1[] = "/info/test.html";
  113.     ff_make_absolute_url(dst1, sizeof(dst1), base1, ref1);
  114.     printf("---------------------------------------------\n");
  115.     printf("%s\n", base1);
  116.     printf("%s\n", ref1);
  117.     printf("%s\n", dst1);
  118.     printf("---------------------------------------------\n");
  119.     
  120.     char base2[] = "index.html";
  121.     char ref2[] = "test.html";
  122.     ff_make_absolute_url(dst2, sizeof(dst2), base2, ref2);
  123.     printf("%s\n", base2);
  124.     printf("%s\n", ref2);
  125.     printf("%s\n", dst2);
  126.     printf("---------------------------------------------\n");
  127.     
  128.     char base3[] = "index.html";
  129.     char ref3[] = "../test.html";
  130.     ff_make_absolute_url(dst3, sizeof(dst3), base3, ref3);
  131.     printf("%s\n", base3);
  132.     printf("%s\n", ref3);
  133.     printf("%s\n", dst3);
  134.     printf("---------------------------------------------\n");
  135.     
  136.     return;
  137. }

   
运行结果是

  1. ---------------------------------------------
  2. http://www.example.com/index.html
  3. /info/test.html
  4. http://www.example.com/info/test.html
  5. ---------------------------------------------
  6. http://www.example.com/info/index.html
  7. test.html
  8. http://www.example.com/info/test.html
  9. ---------------------------------------------
  10. http://www.example.com/info/index.html
  11. ../test.html
  12. http://www.example.com/test.html
  13. ---------------------------------------------

    与上文提到的结果是一致的,当然实际的HLS URL的情况复杂一点,但是原理是一致的。

    本文参考了:
    作者:      网址:http://blog.csdn.net/yihucha166/article/details/4388735



阅读(3453) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

jgfntu2013-05-07 17:25:59

感觉CU的源代码编辑器显示效果不佳啊,本来好好的C代码,被显示的,唉。。。