YouTube:此视频包含来自vevo的内容?

时间:2014-03-02 08:15:20

标签: ios video youtube mpmovieplayercontroller

我正在尝试在我的应用中播放YouTube视频。一切正常。但是,当我尝试观看包含Vevo内容的视频时,它会失败。

我还尝试在get_video_info中传递el=vevo

http://www.youtube.com/get_video_info?video_id=uuZE_IRwLNI&el=vevo&ps=default&eurl=&gl=US&hl=en

stream

 {
    "fallback_host" = "tc.v12.cache7.googlevideo.com";
    itag = 22;
    quality = hd720;
    s = "8E6E5D13EB65FB653B173B94CB0BCC3A20853F5EDE8.5E2E87DF33EEDE165FEA90109D3C7D5DADA06B6BB60";
    type = "video/mp4; codecs=\"avc1.64001F, mp4a.40.2\"";
    url = "http://r7---sn-cvh7zn7r.googlevideo.com/videoplayback?pcm2fr=yes&sver=3&expire=1393773646&itag=22&id=bae644fc84702cd2&upn=SjZd81MudQs&sparams=gcr%2Cid%2Cip%2Cipbits%2Citag%2Cpcm2fr%2Cratebypass%2Csource%2Cupn%2Cexpire&ms=au&gcr=in&mt=1393747698&source=youtube&ratebypass=yes&ipbits=0&fexp=935620%2C919120%2C912523%2C932288%2C914084%2C916626%2C937417%2C937416%2C913434%2C932289%2C936910%2C936913%2C902907&mv=m&key=yt5&ip=103.250.162.79";
}

当我使用url时,它没有播放。有没有解决方案?

3 个答案:

答案 0 :(得分:7)

get_video_info仅适用于允许在其他网站中被视为嵌入视频的视频。我使用get_video_info进行了很多努力,但是可以找到任何针对vevo的解决方案。但是我能够通过检索实际的视频页面使其工作,在实际的视频页面中你必须获取播放器版本并点击url(在代码中指定)来获取流链接和实际签名。

youtube将来可能会改变这一点,但今天以下解决方案对我来说非常有用。

它的c#你应该知道如何将它转换为object-C,下面代码的入口点是ExtractUrls函数,并记得将它传递给html的视频页面。

e.g。 html内容http://www.youtube.com/watch?v=J5iS3tULXMQ&nomobile=1

private static List<string> ExtractUrls(string html)
{
    string Player_Version = Regex.Match(html, @"""\\/\\/s.ytimg.com\\/yts\\/jsbin\\/html5player-(.+?)\.js""").Groups[1].ToString();
    string Player_Code = new WebClient().DownloadString("http://s.ytimg.com/yts/jsbin/" + "html5player-" + Player_Version + ".js");

    html = Uri.UnescapeDataString( Regex.Match(html, @"""url_encoded_fmt_stream_map"":\s+""(.+?)""", RegexOptions.Singleline).Groups[1].ToString());

    var Streams = Regex.Matches(html, @"(^url=|(\\u0026url=|,url=))(.+?)(\\u0026|,|$)");
    var Signatures = Regex.Matches(html, @"(^s=|(\\u0026s=|,s=))(.+?)(\\u0026|,|$)");
    List<string> urls = new List<string>();

    for (int i = 0; i < Streams.Count - 1; i++)
    {
        string URL = Streams[i].Groups[3].ToString();
        if (Signatures.Count > 0)
        {
            string Sign = Sign_Decipher(Signatures[i].Groups[3].ToString(), Player_Code);
            URL += "&signature=" + Sign;
        }
        urls.Add(URL.Trim());
    }

    return urls;
}

public static string Sign_Decipher(string s, string Code)
{
    string Function_Name = Regex.Match(Code, @"signature=(\w+)\(\w+\)").Groups[1].ToString();
    var Function_Match = Regex.Match(Code, "function " + Function_Name + @"\((\w+)\)\{(.+?)\}",RegexOptions.Singleline);
    string Var = Function_Match.Groups[1].ToString();
    string Decipher = Function_Match.Groups[2].ToString();
    var Lines = Decipher.Split(';');

    for (int i = 0; i < Lines.Length; i++)
    {
        string Line = Lines[i].Trim();
        if (Regex.IsMatch(Line, Var + "=" + Var + @"\.reverse\(\)"))
        {
            char[] charArray = s.ToCharArray();
            Array.Reverse(charArray);
            s = new string(charArray);
        }
        else if (Regex.IsMatch(Line, Var + "=" + Var + @"\.slice\(\d+\)"))
        {
            s = Slice(s, Convert.ToInt32(Regex.Match(Line, Var + "=" + Var + @"\.slice\((\d+)\)").Groups[1].ToString()));
        }
        else if (Regex.IsMatch(Line, Var + @"=\w+\(" + Var + @",\d+\)"))
        {
            s = Swap(s, Convert.ToInt32(Regex.Match(Line, Var + @"=\w+\(" + Var + @",(\d+)\)").Groups[1].ToString()));
        }
        else if (Regex.IsMatch(Line, Var + @"\[0\]=" + Var + @"\[\d+%" + Var + @"\.length\]"))
        {
            s = Swap(s, Convert.ToInt32(Regex.Match(Line, Var + @"\[0\]=" + Var + @"\[(\d+)%" + Var + @"\.length\]").Groups[1].ToString()));
        }
    }

    return s;
}

private static string Slice(string Input, int Length)
{
    return Input.Substring(Length, Input.Length - 1);
}

private static string Swap(string Input, int Position)
{
    var Str = new StringBuilder(Input);
    var SwapChar = Str[Position];
    Str[Position] = Str[0];
    Str[0] = SwapChar;
    return Str.ToString();
}

归功于this code project artical

下的评论

答案 1 :(得分:1)

YouTube视频网址应包含签名(包含在's'字段中),要使用此网址,您需要先解密签名并将其添加到网址。

签名解密器可以在视频的网页上找到(即youtube.com/watch?v=VIDEO_ID)。

我无法提供更多信息,因为它违反了YouTube服务条款:)。

答案 2 :(得分:1)

某些视频应用了域级白名单或黑名单。这是由内容所有者自行决定的。

如果存在白名单或黑名单,并且无法确定嵌入网站的域(可能是因为在您的本机应用程序中没有真正的引用域),则默认行为是阻止播放。

此博客文章还有一些细节:http://apiblog.youtube.com/2011/12/understanding-playback-restrictions.html

该特定视频只有在嵌入真实网站的真实网站上才能播放,因为域白/黑名单的工作方式。而且,我们不会通过API公开这些列表。这是一个长期的功能要求