Skip to content
This repository has been archived by the owner on Jul 12, 2020. It is now read-only.

Signature problem with some videos #9

Closed
Animis09 opened this issue Jun 24, 2013 · 82 comments
Closed

Signature problem with some videos #9

Animis09 opened this issue Jun 24, 2013 · 82 comments
Labels

Comments

@Animis09
Copy link

The download is forbidden for some videos because of the signature.

Example: http://www.youtube.com/watch?v=ghQvZ9IID2A

@jeckman
Copy link
Owner

jeckman commented Jun 24, 2013

Confirmed - doesn't download either directly or through the proxy. Not sure what the difference is between this and other videos which work

@Animis09
Copy link
Author

The download doesn't work when the video has the attribute use_cipher_signature=true

@Animis09 Animis09 reopened this Jun 24, 2013
@jeckman
Copy link
Owner

jeckman commented Jun 24, 2013

Can you remove the attribute use_cipher_signature or set it to false, or will that just render the token invalid?

@jeckman
Copy link
Owner

jeckman commented Jun 24, 2013

Interesting, there is a DecryptYouTubeCypher function here http://www.codingforums.com/showthread.php?p=1342470 which might be of interest

@ghost ghost assigned jeckman Jun 24, 2013
@Animis09
Copy link
Author

It's generated by the page get_video_info?video_id= and it can't be modified. In fact, if this variable is set to true then the value of the signature must be recalculated. Moreover, the parameter is no longer $sig but $s .

// Code
$avail_formats[$i]['url'] = urldecode($url) . '&signature=' . (isset($sig) ? $sig : decrypt($s));

@Animis09
Copy link
Author

Thank you but I have already tried this function and it doesn't work.

@jeckman
Copy link
Owner

jeckman commented Jun 24, 2013

Have you tried http://rg3.github.com/youtube-dl/ to see if they have solved it? Might be able to port over their solution if they handle these videos better

@jeckman
Copy link
Owner

jeckman commented Jun 24, 2013

Not certain it is the same issue but see ytdl-org/youtube-dl#897 looks like they have encountered this

@JanetGreen
Copy link

I had some issues with it as well, and not being able to access stuff. I found a decent alternative with the torch browser though. It has some kind of media grabber built in, and it has worked on all the streaming video sites I tried.

@ghost
Copy link

ghost commented Feb 22, 2014

Hello, I've been working with this source closely, and here is what I've found.

When downloading videos that contain copyrights, vevo, or even audio soundtracks, it won't work.
To get a step closer, add this element after the video ID: &el=vevo (vevo obviously). However when gathering the links, it's missing the &signature=, so it will not give you the file (403).

We need to find the new signature with a less-complicated solution.
attribute use_cipher_signature=true is when it's not a classic file, and will need the special &sig.

@barthmania
Copy link

Hi,

Yes there is a problem for the Vevo videos, the signature isn't the same, they are using a JS file to modify it...

Example for this video : https://www.youtube.com/watch?v=6Cp6mKbRTQY

The JS is : http://s.ytimg.com/yts/jsbin/html5player-ima-vflrGwWV9.js
Look at the bz() function.

Last week I was able to download this videos, but they have modifed it and I don't know how to do now.

Thanks in advance.

@jeckman
Copy link
Owner

jeckman commented Feb 26, 2014

See my comment above and link to ytdl-org/youtube-dl#897

The http://rg3.github.com/youtube-dl/ looks to have encountered this and found a workaround - anyone have time to take what they have learned on that project and apply it here?

@ghost
Copy link

ghost commented Mar 2, 2014

Confirmed, I would like to point out that youtube-dl works 100% with Vevo, I'll try to convert the patch to PHP.


Wow, youtube-dl is an amazing source, it's very flexible and has many options..

@bitnol
Copy link
Contributor

bitnol commented Mar 2, 2014

I have used youtube-dl and youtube-downloader both. After some analysis I found the actual algo for decrypting the ciphered signature.

Check this link: http://stackoverflow.com/questions/21510857/best-approach-to-decode-youtube-cipher-signature-using-php-or-js/21700294#21700294

@wilsonschu
Copy link

I found this one is much clear and easy:
https://github.com/soimort/you-get/blob/develop/src/you_get/extractor/youtube.py
(from https://github.com/soimort/you-get)

Here are the basic steps:

  • Crawl YouTube playback page source(for example, http://www.youtube.com/watch?v=6Cp6mKbRTQY) to find the "ytplayer.config" which is a json object
  • in the json object, find ['args']['url_encoded_fmt_stream_map'] which is similar to the one in video_info
  • if 'url' in 'url_encoded_fmt_stream_map' has "s=..." then it has a ciphered signature
  • also find ['assets']['js'] in json. it's the html5player:
    //s.ytimg.com/yts/jsbin/html5player-ima-en_US-vflWnCYSF.js
  • Get the javascript source for the html5player:
    http://s.ytimg.com/yts/jsbin/html5player-ima-en_US-vflWnCYSF.js
  • find the decipher functions in javascript by matching regex '\w+.sig||(\w+)(\w+.\w+)' (in this example, to find the function name "WD" in "if(e.sig||e.s){var g=e.sig||WD(e.s);"):
function WD(a){a=a.split("");a=a.reverse();a=a.slice(1);a=a.reverse();a=a.slice(3);a=XD(a,19);a=a.reverse();a=XD(a,35);a=XD(a,61);a=a.slice(2);return a.join("")}
function XD(a,b){var c=a[0];a[0]=a[b%a.length];a[b]=c;return a}
  • (note: the algorithm is changed comparing to what Akhileshgup found 15 days ago)
  • convert the javascript codes to your own language, like python, c or php
  • sample ciphered
s=558D58CA687B9BD6B4C7E22FDB1C07395679C758489.0203EF29F3E3BD1E7A32567C9F02FE09035C837676
  • deciphered
sig=738C53090EF20F9C76523A7E1DB3E3F927E3020.984857C97659370C1BDFD2E7C4B6DB9B786AC852
  • these are converted functions in php
function WD($a){$a=str_split($a);$a=array_reverse($a);$a=array_slice($a,1);$a=array_reverse($a);$a=array_slice($a,3);$a=XD($a,19);$a=array_reverse($a);$a=XD($a,35);$a=XD($a,61);$a=array_slice($a,2);return implode($a);}
function XD($a,$b){$c=$a[0];$a[0]=$a[$b%count($a)];$a[$b]=$c;return $a;}
  • this is the php converting code:
function js2php($f) {
  $f = preg_replace('/\$/', '_', $f);
  $f = preg_replace('/\}/', ';}', $f);
  $f = preg_replace('/var\s+/', '', $f);
  $f = preg_replace('/(\w+).join\(""\)/', 'implode(${1})', $f);
  $f = preg_replace('/(\w+).length/', 'count(${1})', $f);
  $f = preg_replace('/(\w+).reverse\(\)/', 'array_reverse(${1})', $f);
  $f = preg_replace('/(\w+).slice\((\d+)\)/', 'array_slice(\$${1},${2})', $f);
  $f = preg_replace('/(\w+).split\(""\)/', 'str_split(${1})', $f);
  $f = preg_replace('/\((\w+)\)/', '(\$${1})', $f);
  $f = preg_replace('/\[(\w+)/', '[\$${1}', $f);
  $f = preg_replace('/\((\w+,\d+)\)/', '(\$${1})', $f);
  $f = preg_replace('/\((\w+),(\w+)\)/', '(\$${1},\$${2})', $f);
  $f = preg_replace('/(\w+)([=\[;])/', '\$${1}${2}', $f);
  $f = preg_replace('/\$(\d+)/', '${1}', $f);
  #echo $f . "\n";
  return $f;
}
$f1='function WD(a){a=a.split("");a=a.reverse();a=a.slice(1);a=a.reverse();a=a.slice(3);a=XD(a,19);a=a.reverse();a=XD(a,35);a=XD(a,61);a=a.slice(2);return a.join("")}';
$f2='function XD(a,b){var c=a[0];a[0]=a[b%a.length];a[b]=c;return a}';
$s='558D58CA687B9BD6B4C7E22FDB1C07395679C758489.0203EF29F3E3BD1E7A32567C9F02FE09035C837676';
$code = '$a= "' . $s . '";' . js2php($f1) . js2php($f2) . '$sig=WD($a); return $sig;';
$signature = eval($code);
echo 'decipered:' . $signature;
  • these are converted functions in Python:
def WD(a):
  a=list(a);a=a[::-1];a=a[1:];a=a[::-1];a=a[3:];a=XD(a,19);a=a[::-1];a=XD(a,35);a=XD(a,61);a=a[2:];return "".join(a)
global XD
def XD(a,b):
  c=a[0];a[0]=a[b%len(a)];a[b]=c;return a
sig=WD(s)
  • use the converted code to decipher the signature
  • use the deciphered signature to change "s=..." to "signature=..." in download url

@wilsonschu
Copy link

Just found out that youtube changed the function today. In js console:

function fE(a){a=a.split("");a=a.slice(2);a=a.reverse();a=gE(a,39);a=gE(a,43);return a.join("")}
function gE(a,b){var c=a[0];a[0]=a[b%a.length];a[b]=c;return a}
//test a ciphered signature:
fE('28282AFC11ADF6D6D2C9CA541913FE0D50E359538C.5B3EF2AD526CBCEB7C973C092A6632738707A330')
//deciphered result:
"333A7078372366A290C379C7BECBC625DA2FE3B0.C855953E05D0EF319145AC9C2D6D6FDA11CFA282"

but the above php js2php routine still works.

@simplyi
Copy link

simplyi commented Mar 20, 2014

@wilsonschu thank you very much for this very detailed description. I tried your approach but js2php code fails on line
$f = preg_replace('/[(\w+)/', '[$${1}', $f);

do you know how to fix it?

if I use the JavaScript only. for Example:
fE('28282AFC11ADF6D6D2C9CA541913FE0D50E359538C.5B3EF2AD526CBCEB7C973C092A6632738707A330')

and display new signature with javascript alert, then it works... I get deciphered signature displayed... the video still does not play :(

@simplyi
Copy link

simplyi commented Mar 20, 2014

@wilsonschu do I add the diciphered signature to a URL from url_encoded_fmt_stream_map ? do I need to urldecode any of the parameters? I get the signature, replace s= with signature= but video still does not play.... I checked functions from html5player javascript and they are correct. They are exactly the same as in your example:

function fE(a){a=a.split("");a=a.slice(2);a=a.reverse();a=gE(a,39);a=gE(a,43);return a.join("")}
function gE(a,b){var c=a[0];a[0]=a[b%a.length];a[b]=c;return a}

@wilsonschu
Copy link

Somehow the website display removes some ""s.
I changed the tag to ``` it's now showing the correct code:

function js2php($f) {
$f = preg_replace('/$/', '', $f);
$f = preg_replace('/}/', ';}', $f);
$f = preg_replace('/var\s+/', '', $f);
$f = preg_replace('/(\w+).join("")/', 'implode(${1})', $f);
$f = preg_replace('/(\w+).length/', 'count(${1})', $f);
$f = preg_replace('/(\w+).reverse()/', 'array_reverse(${1})', $f);
$f = preg_replace('/(\w+).slice((\d+))/', 'array_slice($${1},${2})', $f);
$f = preg_replace('/(\w+).split("")/', 'str_split(${1})', $f);
$f = preg_replace('/((\w+))/', '($${1})', $f);
$f = preg_replace('/[(\w+)/', '[$${1}', $f);
$f = preg_replace('/((\w+,\s
\d+))/', '($${1})', $f);
$f = preg_replace('/((\w+),\s_(\w+))/', '($${1},$${2})', $f);
$f = preg_replace('/(\w+)([=[;])/', '$${1}${2}', $f);
$f = preg_replace('/$(\d+)/', '${1}', $f);
#echo $f . "\n";
return $f;
}

On Wed, Mar 19, 2014 at 5:40 PM, simplyi [email protected] wrote:

@wilsonschu https://github.com/wilsonschu thank you very much for this
very detailed description. I tried your approach but js2php code fails on
line
$f = preg_replace('/[(\w+)/', '[$${1}', $f);

do you know how to fix it?

if I use the JavaScript only. for Example:

fE('28282AFC11ADF6D6D2C9CA541913FE0D50E359538C.5B3EF2AD526CBCEB7C973C092A6632738707A330')

and display new signature with javascript alert, then it works... I get
deciphered signature displayed... the video still does not play :(


Reply to this email directly or view it on GitHubhttps://github.com//issues/9#issuecomment-38124488
.

@simplyi
Copy link

simplyi commented Mar 20, 2014

@wilsonschu You are the man! It is working!!!

@simplyi
Copy link

simplyi commented Mar 20, 2014

@wilsonschu the url_encoded_fmt_stream_map contains urls to videos of different quality. But these urls and all its parameters like "s" for example are all stored in url_encoded_fmt_stream_map as one string. How to I properly split them into a map of = ?.... So I can then do the decipher of each signature of each url? Every time I request url_encoded_fmt_stream_map it comes back from Youtube shuffled and because there are multiple "url" and multiple "s" php functions like parse_str and parse_url do not help.... Do you have piece of code that parses out urls and their respected "s" into a separate array? out of url_encoded_fmt_stream_map.

@wilsonschu
Copy link

parse_str($videoinfo);
if ($status =='fail') {
// need to deal with ciphered signature
die('need to call play back source');
}
if ($status != 'ok') {
//wrong video_info
die('invalid video_info');
}

if (isset($url_encoded_fmt_stream_map)) {
$fmts = explode(',', $url_encoded_fmt_stream_map);
} else {
$fmts = array();
}

$videos = array();
foreach ($fmts as $fmt) {
parse_str($fmt, $video);
if ($video) {
$videos[] = $video;
}
}

print_r($videos);

On Wed, Mar 19, 2014 at 10:34 PM, simplyi [email protected] wrote:

@wilsonschu https://github.com/wilsonschu the
url_encoded_fmt_stream_map contains urls to videos of different quality.
But these urls and all its parameters like "s" for example are all stored
in url_encoded_fmt_stream_map as one string. How to I properly split them
into a map of = ?.... So I can then do the decipher of each signature of
each url? Every time I request url_encoded_fmt_stream_map it comes back
from Youtube shuffled and because there are multiple "url" and multiple "s"
php functions like parse_str and parse_url do not help.... Do you have
piece of code that parses out urls and their respected "s" into a separate
array? out of url_encoded_fmt_stream_map.


Reply to this email directly or view it on GitHubhttps://github.com//issues/9#issuecomment-38136654
.

@jeckman
Copy link
Owner

jeckman commented Mar 20, 2014

Can one of you please make this into a pull request?

@simplyi
Copy link

simplyi commented Mar 20, 2014

Sorry @jeckman I am very new to gihub interface and do not know how to do it :(

@simplyi
Copy link

simplyi commented Mar 20, 2014

@wilsonschu with the functions I am getting from html5player(listing below) I am able to play most of youtube videos.

function fE(a){a=a.split("");a=a.slice(2);a=a.reverse();a=gE(a,39);a=gE(a,43);return a.join("")}
function gE(a,b){var c=a[0];a[0]=a[b%a.length];a[b]=c;return a}

However this does not help with velvo content. Using the above two functions I get the deciphered signature but video still does not download..... I tried using youtube-dl as command like tool and it works great. I wonder if it is possible to convert part of their code that deals with velvo content into php. I have just emailed them.. or maybe use youtube-dl to extract list of video urls with correct deciphered signature that will work.

@bitnol
Copy link
Contributor

bitnol commented Nov 12, 2014

@pmesco longer? I didn't get you.

@bitnol
Copy link
Contributor

bitnol commented Nov 12, 2014

@pmesco you are welcome to discuss on my email id: [email protected]

@mega94
Copy link

mega94 commented Nov 12, 2014

I understand you gave the link to the script you created? or google translator I with emphasis to translate =)

@paulwscom
Copy link
Contributor

@bitnol i mean your api will last longer cause i really need it on my project

@paulwscom
Copy link
Contributor

@bitnol
Copy link
Contributor

bitnol commented Nov 13, 2014

@pmesco Very interesting... it's using GAE and its working for cipher also :)

@paulwscom
Copy link
Contributor

@bitnol your api not working now, it shows "New html5player id found. Please wait while we update our algo list."

@bitnol
Copy link
Contributor

bitnol commented Nov 13, 2014

@pmesco yeah fixed that: check this ciper video: http://www.genyoutube.com/?vid=UxxajLWwzqY

@paulwscom
Copy link
Contributor

@bitnol wow, its very interesting, you have much format

@bitnol
Copy link
Contributor

bitnol commented Nov 13, 2014

I really need code contribution from fellows who are interested. Today its broke because of new method of decryption introduced in js.

@paulwscom
Copy link
Contributor

@bitnol Where can we contribute for that?

@VileTung
Copy link

Apparently it's possible to rely on regex, because while @bitnol his api wasn't working, mine is (without modifications or code changes). Please don't get me wrong, I don't want to be rude or insult someone. But why is your code closed source? I'm willing to share my code, however I don't know how Github works (and don't want people to hit & run).

@paulwscom
Copy link
Contributor

@VileTung Then share it to us

@bitnol
Copy link
Contributor

bitnol commented Nov 13, 2014

Sharing is great. And I am also sharing the decryption algo.
I am not alone the one who working on it. So without other's concern it is not possible to share the base code :(

@bitnol
Copy link
Contributor

bitnol commented Nov 14, 2014

I like to report here a content theft by a Github fellow pmesco [Paul Mikki Escorido] [[email protected]]. He stole my script [ http://www.genyoutube.com ] and uploaded in his server [ http://ytd.wapmon.com/index3.html ] and using it without permission. Other Fellows please make a note of this data theft while having any contact with him.

@jeckman
Copy link
Owner

jeckman commented Nov 14, 2014

Closing this whole thread as won't fix. The whole conversation no longer has anything to do with this actual project.

When someone wants to issue a pull request to include cipher videos in YouTube-Downloader I'll be glad to reopen the issue and evaluate the pull request.

@webdesignerart
Copy link

Is private video Problem solved? Anyone have any idea about it? Plz share.

@paulwscom
Copy link
Contributor

@bitnol what i have stolen on you? script of your api? oh come on dude, anyone can make script for your api. The point is you dont give the actual script.

@bitnol
Copy link
Contributor

bitnol commented Nov 14, 2014

@pmesco You are using my code on your site without permission, its illegal. Remove that code.

@paulwscom
Copy link
Contributor

@bitnol Hello bro :) how are you feeling today? Still a baby sitter? Ok bro i will remove your code on my server, and for your information, im not interested to use your script, i only like the design.

@bitnol
Copy link
Contributor

bitnol commented Nov 14, 2014

@pmesco Atleast you accepted.
If you not cease and desist, your Hosting provider will act on you for
copyright issue. I already reported them.

On Sat, Nov 15, 2014 at 3:04 AM, pmesco [email protected] wrote:

@bitnol https://github.com/bitnol Ahm ok sure. And for your
information, im not interested to use your script, i only like the design.


Reply to this email directly or view it on GitHub
#9 (comment)
.

Regards,
Akhilesh Chandra Gupta.
www.bitnol.com
www.gitnol.com

@paulwscom
Copy link
Contributor

@bitnol script removed :) and thanks for reporting, do you think it bothered me?

@webdesignerart
Copy link

@VileTung Can you share with me your working code example plz. From a week still i didn't get any solution for youtube cypher signatured video.

@jeckman jeckman removed their assignment Nov 14, 2014
Repository owner locked and limited conversation to collaborators Nov 14, 2014
@jeckman
Copy link
Owner

jeckman commented Nov 14, 2014

Locking the thread. If y'all want to go use bitnol's API feel free, but none of this is actually adding value to the YouTube-Downloader project at this point.

Personally I have no interest in making this work with Cypher signed videos. If someone else does and has code to share, please open a new issue with a pull request.

nyctef added a commit to nyctef/hosed that referenced this issue Apr 6, 2015
doesn't work for some videos, should probably delegate to youtube-dl

see jeckman/YouTube-Downloader#9
DmitriyLyalyuev referenced this issue Jan 27, 2016
Right URL handling and parse short URLs for Video ID thanks @DmitriyLyalyuev
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests