用awk下载YouTube视频

来源:互联网 发布:社交网络电影讲的什么 编辑:IT博客网 时间:2019/10/18 03:00

    上次用gawk搭配curl实现了下载优酷视频,相比较而言,YouTube虽然影响要大于优酷,但从程序的实做而言,YouTube要简单的多。


    程序依然是读取需要下载的列表文件tube,格式应该是这样:



     在Cygwin下运行看起来是这样的:



      下面是代码:

  1. #! /usr/local/bin/gawk -f
  2. ################################################################################
  3. #一个从youtube上下载flash视频的程序
  4. #
  5. #Author: ChangHailong
  6. #E-mail: hailongchang@163.com
  7. #
  8. #Date: 2008/10/11
  9. ################################################################################
  10. BEGIN{
  11.     BINMODE = 3
  12. }
  13. {
  14.     filename = $2
  15.     vid = parse_url($1)
  16.     get_vid_info(vid,VID_INFO)
  17.     download_video(VID_INFO["request"],filename)
  18.     print "/nthe " NR " file has been downloaded/n"
  19. }
  20. ################################################################################
  21. #parse_url(url)用来从输入的网址信息中提取我们关心的信息
  22. #url通常具有类似下面这样的形式:http://www.youtube.com/watch?v=vkDAKke56n
  23. #这个函数就是能够将视频信息vkDAKke56n网址中提取出来
  24. ################################################################################
  25. function parse_url(url)
  26. {
  27.     gsub(/http://///,"",url)
  28.     gsub(/www/./,"",url)
  29.     gsub(/youtube/.com//watch/?v=/,"",url)
  30.     
  31.     if((p = index(url,"&")) > 0)
  32.     url = substr(url, 1, p-1)
  33.     return url
  34. }
  35. ################################################################################
  36. #
  37. ################################################################################
  38. function get_vid_info(vid, VID_INFO)
  39. {
  40.     InetFile = "/inet/tcp/0/www.youtube.com/80"
  41.     Request = "GET /watch?v=" vid " HTTP/1.1/r/n"
  42.     Request = Request "Host: www.youtube.com/r/n/r/n"
  43.     print Request |& InetFile
  44.     while((InetFile |& getline) >0)
  45.     {
  46.        if (match($0, /"video_id""([^"]+)".+"t": "([^"]+)"/, info_matches)) 
  47.        {
  48.             VID_INFO["request"] = "video_id=" info_matches[1] "&t=" info_matches[2]
  49.             close(InetFile)
  50.             return
  51.        }
  52.        else
  53.        continue
  54.     }
  55.    close(InetFile)
  56.    return
  57. }
  58. ################################################################################
  59. function get_header_info(Inet,Request,HEADER_INFO)
  60. {
  61.     delete HEADER_INFO
  62.     OLD_RS=RS
  63.     print Request |& InetFile
  64.     if (Inet |& getline > 0) 
  65.     {
  66.         HEADER_INFO["_status"] = $2
  67.     }
  68.     else 
  69.     {
  70.         print "I can not redirect net address for you. Quitting!"
  71.         exit 1
  72.     }
  73.     RS="/r/n"
  74.     while ((Inet |& getline) > 0) 
  75.     {
  76.         if (match($0, /([^:]+): (.+)/, matches)) 
  77.     {
  78.             HEADER_INFO[matches[1]] = matches[2]
  79.         }
  80.         else 
  81.     { 
  82.         break 
  83.     }
  84.     }
  85.     RS = OLD_RS
  86. }
  87. ################################################################################
  88. function download_video(req,filename)
  89. {
  90.     InetFile = "/inet/tcp/0/www.youtube.com/80"
  91.     Request = "GET /get_video?" req " HTTP/1.1/r/n"
  92.     Request = Request "Host: www.youtube.com/r/n/r/n"
  93. #    RS=OLD_RS
  94.     Loop = 0
  95.     do
  96.     {
  97.     get_header_info(InetFile,Request,HEADER_INFO)
  98.     if ("Location" in HEADER_INFO) 
  99.     { 
  100.         #close www.youtube.com
  101.             close(InetFile)
  102.             parse_location(HEADER_INFO["Location"], GOOGLE_VIDEO)
  103.             InetFile = GOOGLE_VIDEO["InetFile"]
  104.             Request  = "GET " GOOGLE_VIDEO["Request"" HTTP/1.1/r/n"
  105.             Request  = Request "Host: " GOOGLE_VIDEO["Host""/r/n/r/n"
  106.             if (InetFile == ""
  107.         {
  108.                 print "I can not download flv for you, please check your vid"
  109.                 return
  110.             }       
  111.         }
  112.     Loop++
  113.     }while (("Location" in HEADER_INFO) && Loop < 5)
  114.     filename=filename".flv"
  115.     save_file(InetFile,filename,HEADER_INFO)
  116.     close(InetFile)
  117.     return
  118. }
  119. ################################################################################
  120. function parse_location(location, GOOGLE_VIDEO) {
  121.     if (match(location, /http:////([^//]+)(//.+)/, mat)) {
  122.         GOOGLE_VIDEO["InetFile"] = "/inet/tcp/0/" mat[1] "/80"
  123.         GOOGLE_VIDEO["Host"]     = mat[1]
  124.     GOOGLE_VIDEO["Request"]  = mat[2]
  125.     }
  126.     else {
  127.         GOOGLE_VIDEO["InetFile"] = ""
  128.         GOOGLE_VIDEO["Host"]     = ""
  129.         GOOGLE_VIDEO["Request"]  = ""
  130.     }
  131. }
  132. ################################################################################
  133. function save_file(InetFile,filename,HEADER_INFO)
  134. {
  135.     OLD_RS  = RS
  136.     OLD_ORS = ORS
  137.     ORS = ""
  138.     print "" > filename
  139.     RS = "@"
  140.     has_read = 0
  141.     printf("The %d flv file has %10d bytes. I have downloaded:            bytes",NR,HEADER_INFO["Content-Length"]);
  142.     printf(" /b/b/b/b/b/b/b/b/b/b/b/b/b/b/b/b/b/b");
  143.     while ((InetFile |& getline) > 0)
  144.     {
  145.     has_read += length($0 RT)
  146.     printf("%10d/b/b/b/b/b/b/b/b/b/b",has_read)
  147.     print $0 RT >> filename
  148.     }
  149.     printf("%10d/b/b/b/b/b/b/b/b/b/b",has_read)
  150.     RS  = OLD_RS
  151.     ORS = OLD_ORS
  152.     return
  153. }
  154. ################################################################################