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

解决方法

从YouTube检索videoUrl的网址是https://www.youtube.com/get_video_info?video_id=/*videoId*/\u0026amp;el=vevo\u0026amp;el=embedded\u0026amp;asv=3\u0026amp;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,l-1))
        i=l+1
      else
        table.insert(t,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)
    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,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代码.

希望这可以帮助.

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...