Search code examples
iosvideoyoutubempmovieplayercontroller

YouTube : This video contains content from vevo?


I am trying to play a YouTube video in my application. Everything works fine. However, when I try to watch a video that contains content from Vevo, it fails.

I had also tried to pass el=vevo in get_video_info:

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";
}

When I use url its not playing. Is there any solution?


Solution

  • get_video_info works only for the videos which are allowed to be viewed as embedded videos in other websites. I struggled a lot with get_video_info but could find any solution for vevo. however I was able to make it work by retrieving the actual video page, in actual video page you have to grab player version and hit url (specified in code) to grab the streams links and actual signatures.

    youtube might change this in future but today following solutions is working great for me.

    Its c# you should know how to convert it into object-C, entry point of following code is ExtractUrls function and remember to pass it html of video page.

    e.g. html content of 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();
    }
    

    credit goes to comments under this code project artical