6

I am trying to play youtube video in my application. everything works fine. but when i am trying to watch video that contains content from youtube. it fails.

I researched found one think that you should encrypt and decrypt signature and add this to the URL?

I dont know how to decrypt signature in IOS?

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?

Sunny Shah
  • 12,990
  • 9
  • 50
  • 86
  • Why are you using an undocumented part of the YouTube API and expecting any kind of consistency? `s` could be anything at all, even worthless. – CodaFi Mar 30 '14 at 12:01
  • Because i want to play all the types of video of the youtube within my app. i am not finding any way. so i am doing google and i came at point. i know apple will not accept. but i want to show my client. – Sunny Shah Mar 30 '14 at 12:56
  • Are you sure you can't do this with the real YouTube API? – CodaFi Mar 30 '14 at 13:08
  • i dont have idea i am getting this type of (http://r7---sn-cvh7zn7r)url using third party library and when i am playing with this url it sometimes work and sometime not(Error YouTube : This video contains content from vevo?). – Sunny Shah Mar 30 '14 at 15:14
  • @CodaFi No, you can’t get the URLs of the videos with the official YouTube API. – 0xced Dec 22 '15 at 08:35

3 Answers3

6

You can't just use get_video_info data alone, you also need to download the main video page in order to see which html5player-XXXXX.js javascript file is loaded. This will dictate which permutations are needed. See http://www.jwz.org/hacks/youtubedown (written in Perl) as an example -- skip to the section that says "This is not crypto or a hash, just a character-rearrangement cipher. Total security through obscurity. Total dick move.", which is a sentiment I heartily concur with.

Stuart Caie
  • 2,803
  • 14
  • 15
3

The XCDYouTubeKit library does this with a very simple API for you to use.

NSString *videoIdentifier = @"uuZE_IRwLNI";
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:videoIdentifier completionHandler:^(XCDYouTubeVideo *video, NSError *error) {
    if (video)
    {
        // All URLs, with decrypted signature, are available in the `video.streamURLs` dictionary
    }
    else
    {
        // Handle error
    }
}];

Disclaimer: I’m the author of XCDYouTubeKit.

0xced
  • 25,219
  • 10
  • 103
  • 255
-1

A little shameless self promotion, I spent the last few weeks figuring out how the alternative JavaScript and perl versions of software did this, initially used JavaScriptCore to accomplish it, but decided I wanted a pure obj-C sample, so I made one myself. There is exhaustive commenting on how it all works in the main file.

https://github.com/lechium/yourTube/blob/master/yourTube/KBYourTube.m

KBYourTube *tube = [[KBYourTube alloc] init];
NSArray *streamArray = [tube getVideoStreamsForID:@"_7nYuyfkjCk"];

Will return

 {
"fallback_host" = "tc.v20.cache6.googlevideo.com";
format = "720p MP4";
itag = 22;
quality = hd720;
s = "771171A2777DE13D6CE5320C210DCCA29F018FC6DBA.A7630D3C26F2F70EEFEB25889E1A1B8805EC0616616";
title = "Lil+Wayne+-+She+Will+ft.+Drake";
type = "video%2Fmp4%3B+codecs%3D%22avc1.64001F%2C+mp4a.40.2%22";
url = "https://r15---sn-bvvbax-2iml.googlevideo.com/videoplayback?nh=EAI&fexp=9416126%2C9420452%2C9422596%2C9423662%2C9424859&ipbits=0&mime=video%2Fmp4&ratebypass=yes&itag=22&upn=8XDeh70fkMI&expire=1450776595&mt=1450754946&sparams=dur%2Cid%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cnh%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cupn%2Cexpire&key=yt6&id=o-AF5K6y8liVQ1S9iLjUHOcIBdnb4a8g-rgcFwGc0wuidq&mn=sn-bvvbax-2iml&mm=31&ms=au&mv=m&source=youtube&pl=16&dur=323.895&lmt=1417236324599143&ip=xx&requiressl=yes&sver=3&signature=671A2777DE73D6CE5320C210DCCA29F018FC1DBA.A7630D3C26F2F70EEFEB25889E1A1B8805EC0616&title=Lil+Wayne+-+She+Will+ft.+Drake";
},

This should be able to fully supplant any way you are currently getting details about a video for download / playback purposes and takes care of the signature deciphering for you. You could also pretty easily modify the code to JUST use it for signature deciphering (but you would need to take care to use the proper timestamp value when using get_video_info).