首页 文章

大多数视频都没有从YouTube获取VideoUrl

提问于
浏览

2 回答

  • 1

    从YouTube检索videoUrl的网址为 https://www.youtube.com/get_video_info?video_id=/*videoId*/&el=vevo&el=embedded&asv=3&sts=15902

    以下是如何通过videoId获取videoUrl . Lua代码:

    -- string.explode(string, separator)
    function string.explode(p, d)
      local t, i
      t={}
      i=0
      if(#p == 1) then return {p} end
        while true do
          l=string.find(p,d,i,true)
          if l~=nil then
            table.insert(t, string.sub(p,i,l-1))
            i=l+1
          else
            table.insert(t, string.sub(p,i))
            break
          end
        end
      return t
    end
    
    -- string.begin_with
    function string.begin_with(str, sub_str)
       return string.find(str, sub_str)==1
    end
    
    -- string.url_decode
    function string.url_decode(str)
      str = string.gsub (str, "+", " ")
      str = string.gsub (str, "%%(%x%x)", function(h) return string.char(tonumber(h,16)) end)
      str = string.gsub (str, "\r\n", "\n")
      return str
    end
    
    -- string.url_query_parameter_map
    function string.url_query_parameter_map(str)
        local params_kv = {}
        for k,v in pairs(string.explode(str, "&")) do
            local eqmark_idx = string.find(v, "=")
            if eqmark_idx ~= nil and eqmark_idx > 1 and eqmark_idx < string.len(v) then
                local param_name = string.sub(v, 1, eqmark_idx-1)
                local param_value = string.sub(v, eqmark_idx+1)
                param_name = string.url_decode(param_name)
                param_value = string.url_decode(param_value)
                --print (param_name .." => " .. param_value)
                params_kv[param_name] = param_value
            else
                params_kv[string.url_decode(v)] = ""
            end
        end
        return params_kv
    end
    
    function string.ytb_sig_charswap(str, pos)
        local c1 = string.sub(str,1,1)
        local pos2 = (pos-1)%string.len(str)+1--lua has index begun at 1!
        local c2 = string.sub(str,pos2,pos2)
    
        return c2..string.sub(str,2,pos2-1)..c1..string.sub(str,pos2+1)
    end
    
    -- string.ytb_sig_decrypt
    function string.ytb_sig_decrypt(str)
        local sig = str
        sig = string.sub(sig, 3)
        sig = string.reverse(sig)
        sig = string.sub(sig, 4)
        sig = string.ytb_sig_charswap(sig, 10)
        sig = string.sub(sig, 4)
        sig = string.ytb_sig_charswap(sig, 44)
        sig = string.sub(sig, 4)
        sig = string.reverse(sig)
        sig = string.ytb_sig_charswap(sig, 24)
        return sig
    end
    
    --local s = "YFRHVIIsjrkkiGDtqKXrh847DI5GKDKokWjjgougGDLanT2rw92V6cuXY5BfPGMsaLwgGUYV76wr1T6W"
    --print(string.ytb_sig_decrypt(s))
    
    -- define the parser function
    -- return: number of video resource, table of video resources, failed reason text.
    parse = function (s)
        local params_kv = string.url_query_parameter_map(s)
        -- print(params_kv["fmt_list"]);
        local fmt_list, fmt_stream = params_kv["fmt_list"],  params_kv["url_encoded_fmt_stream_map"]
        local reason, rental_bar = params_kv["reason"], params_kv["ypc_video_rental_bar_text"]
    
        if (fmt_list == nil or fmt_stream == nil) then
            local reason_text = "reason="
            if (reason ~= nil) then 
                reason_text = reason_text .. reason
            elseif (rental_bar ~= nil) then 
                reason_text = reason_text .. rental_bar
            else 
                reason_text = "reason=This video cannot be played for some unknown reason(unexpected)"
            end
            return 0, {}, reason_text
        end
    
        print(fmt_list)
        --local fmt_infos = {}
        --for k,v in pairs(string.explode(fmt_list, ",")) do
        --  local fmt_info = string.explode(v, "/")
        --  local v_itag, v_reso = fmt_info[1], fmt_info[2] 
        --  fmt_infos[v_itag]=v_reso
        --  print (v_itag.." => "..v_reso)
        --end
    
        local stream_n, stream_infos = 0, {}
        for k,v in pairs(string.explode(fmt_stream, ",")) do
            local s_info = string.url_query_parameter_map(v)
            local v_itag, v_url, v_s, v_sig = s_info["itag"], s_info["url"], s_info["s"], s_info["sig"]
            --print (v_itag.." => "..v_url)
            --print ((v_s or "nil").." ~ "..(v_sig or "nil"))
            if (string.find(v_url, "signature=") ~= nil) then
                v_url = v_url
            elseif (v_sig ~= nil) then
                v_url = v_url.."&signature="..v_sig
            elseif (v_s ~= nil) then
                v_url = v_url.."&signature="..string.ytb_sig_decrypt(v_s)
            else
                v_url = v_url
            end
            stream_infos[v_itag] = v_url
            stream_n=stream_n+1
            print (v_itag.." => "..v_url)
        end
    
        return stream_n, stream_infos, ""
    end
    
    -- multiple return values:
    -- the first one is script version number.
    -- the second one is remote YouTube URL for fetching, with one parameter placeholder "%s".
    -- the third one is the parser entry function object.
    return "14.3.5", "https://www.youtube.com/get_video_info?video_id=%s&el=vevo&el=embedded&asv=3&sts=15902", parse
    

    您可以将其“翻译”为Objective-C代码 .

    希望这可以帮助 .

  • -2

    这种类型的视频只能在嵌入真实网站时播放 . 我们不会通过API公开这些列表 .

    这篇博文还有一些细节:

    http://apiblog.youtube.com/2011/12/understanding-playback-restrictions.html

相关问题