mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-21 20:46:36 -05:00
YoutubeIE: new algo for length 86 (fixes #1156)
Now is using the same length as the flash player used for age protected videos, but the algorithm is different, so now for age protected videos it first tries to use the old algo.
This commit is contained in:
parent
05afc96b73
commit
75952c6e3d
3 changed files with 35 additions and 6 deletions
|
@ -17,9 +17,9 @@
|
||||||
# 87 - vflART1Nf 2013/07/24
|
# 87 - vflART1Nf 2013/07/24
|
||||||
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$^&*()_-+={[]}|:;?/>.<",
|
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$^&*()_-+={[]}|:;?/>.<",
|
||||||
"tyuioplkjhgfdsazxcv<nm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$^&*()_-+={[]}|:;?/>"),
|
"tyuioplkjhgfdsazxcv<nm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$^&*()_-+={[]}|:;?/>"),
|
||||||
# 86 - vfl_ymO4Z 2013/06/27
|
# 86 - vflm_D8eE 2013/07/31
|
||||||
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<",
|
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<",
|
||||||
"ertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!/#$%^&*()_-+={[|};?@"),
|
">.1}|[{=+-_)(*&^%$#@!MNBVCXZASDFGHJK<POIUYTREW509876L432/mnbvcxzasdfghjklpoiuytre"),
|
||||||
# 85 - vflSAFCP9 2013/07/19
|
# 85 - vflSAFCP9 2013/07/19
|
||||||
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?/>.<",
|
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?/>.<",
|
||||||
"ertyuiqplkjhgfdsazx$vbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#<%^&*()_-+={[};?/c"),
|
"ertyuiqplkjhgfdsazx$vbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#<%^&*()_-+={[};?/c"),
|
||||||
|
@ -40,6 +40,12 @@
|
||||||
"Z?;}[{=+-(*&^%$#@!MNBVCXRASDFGHKLPOIUYT/EWQ0q87659321mnbvcxzasdfghjkl4oiuytrewp"),
|
"Z?;}[{=+-(*&^%$#@!MNBVCXRASDFGHKLPOIUYT/EWQ0q87659321mnbvcxzasdfghjkl4oiuytrewp"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
tests_age_gate = [
|
||||||
|
# 86 - vflqinMWD
|
||||||
|
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<",
|
||||||
|
"ertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!/#$%^&*()_-+={[|};?@"),
|
||||||
|
]
|
||||||
|
|
||||||
def find_matching(wrong, right):
|
def find_matching(wrong, right):
|
||||||
idxs = [wrong.index(c) for c in right]
|
idxs = [wrong.index(c) for c in right]
|
||||||
return compress(idxs)
|
return compress(idxs)
|
||||||
|
@ -90,6 +96,8 @@ def genall(tests):
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
print(genall(tests))
|
print(genall(tests))
|
||||||
|
print(u' Age gate:')
|
||||||
|
print(genall(tests_age_gate))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -10,7 +10,9 @@
|
||||||
from youtube_dl.extractor.youtube import YoutubeIE
|
from youtube_dl.extractor.youtube import YoutubeIE
|
||||||
from helper import FakeYDL
|
from helper import FakeYDL
|
||||||
|
|
||||||
sig = YoutubeIE(FakeYDL())._decrypt_signature
|
ie = YoutubeIE(FakeYDL())
|
||||||
|
sig = ie._decrypt_signature
|
||||||
|
sig_age_gate = ie._decrypt_signature_age_gate
|
||||||
|
|
||||||
class TestYoutubeSig(unittest.TestCase):
|
class TestYoutubeSig(unittest.TestCase):
|
||||||
def test_92(self):
|
def test_92(self):
|
||||||
|
@ -35,7 +37,7 @@ def test_87(self):
|
||||||
|
|
||||||
def test_86(self):
|
def test_86(self):
|
||||||
wrong = "qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<"
|
wrong = "qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<"
|
||||||
right = "ertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!/#$%^&*()_-+={[|};?@"
|
right = ">.1}|[{=+-_)(*&^%$#@!MNBVCXZASDFGHJK<POIUYTREW509876L432/mnbvcxzasdfghjklpoiuytre"
|
||||||
self.assertEqual(sig(wrong), right)
|
self.assertEqual(sig(wrong), right)
|
||||||
|
|
||||||
def test_85(self):
|
def test_85(self):
|
||||||
|
@ -67,6 +69,11 @@ def test_79(self):
|
||||||
wrong = "qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKHGFDSAZXCVBNM!@#$%^&*(-+={[};?/"
|
wrong = "qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKHGFDSAZXCVBNM!@#$%^&*(-+={[};?/"
|
||||||
right = "Z?;}[{=+-(*&^%$#@!MNBVCXRASDFGHKLPOIUYT/EWQ0q87659321mnbvcxzasdfghjkl4oiuytrewp"
|
right = "Z?;}[{=+-(*&^%$#@!MNBVCXRASDFGHKLPOIUYT/EWQ0q87659321mnbvcxzasdfghjkl4oiuytrewp"
|
||||||
self.assertEqual(sig(wrong), right)
|
self.assertEqual(sig(wrong), right)
|
||||||
|
|
||||||
|
def test_86_age_gate(self):
|
||||||
|
wrong = "qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<"
|
||||||
|
right = "ertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!/#$%^&*()_-+={[|};?@"
|
||||||
|
self.assertEqual(sig_age_gate(wrong), right)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -286,7 +286,7 @@ def _decrypt_signature(self, s):
|
||||||
elif len(s) == 87:
|
elif len(s) == 87:
|
||||||
return s[4:23] + s[86] + s[24:85]
|
return s[4:23] + s[86] + s[24:85]
|
||||||
elif len(s) == 86:
|
elif len(s) == 86:
|
||||||
return s[2:63] + s[82] + s[64:82] + s[63]
|
return s[83:85] + s[26] + s[79:46:-1] + s[85] + s[45:36:-1] + s[30] + s[35:30:-1] + s[46] + s[29:26:-1] + s[82] + s[25:1:-1]
|
||||||
elif len(s) == 85:
|
elif len(s) == 85:
|
||||||
return s[2:8] + s[0] + s[9:21] + s[65] + s[22:65] + s[84] + s[66:82] + s[21]
|
return s[2:8] + s[0] + s[9:21] + s[65] + s[22:65] + s[84] + s[66:82] + s[21]
|
||||||
elif len(s) == 84:
|
elif len(s) == 84:
|
||||||
|
@ -303,6 +303,16 @@ def _decrypt_signature(self, s):
|
||||||
else:
|
else:
|
||||||
raise ExtractorError(u'Unable to decrypt signature, key length %d not supported; retrying might work' % (len(s)))
|
raise ExtractorError(u'Unable to decrypt signature, key length %d not supported; retrying might work' % (len(s)))
|
||||||
|
|
||||||
|
def _decrypt_signature_age_gate(self, s):
|
||||||
|
# The videos with age protection use another player, so the algorithms
|
||||||
|
# can be different.
|
||||||
|
if len(s) == 86:
|
||||||
|
return s[2:63] + s[82] + s[64:82] + s[63]
|
||||||
|
else:
|
||||||
|
# Fallback to the other algortihms
|
||||||
|
self._decrypt_signature(s)
|
||||||
|
|
||||||
|
|
||||||
def _get_available_subtitles(self, video_id):
|
def _get_available_subtitles(self, video_id):
|
||||||
self.report_video_subtitles_download(video_id)
|
self.report_video_subtitles_download(video_id)
|
||||||
request = compat_urllib_request.Request('http://video.google.com/timedtext?hl=en&type=list&v=%s' % video_id)
|
request = compat_urllib_request.Request('http://video.google.com/timedtext?hl=en&type=list&v=%s' % video_id)
|
||||||
|
@ -611,7 +621,11 @@ def _real_extract(self, url):
|
||||||
parts_sizes = u'.'.join(compat_str(len(part)) for part in s.split('.'))
|
parts_sizes = u'.'.join(compat_str(len(part)) for part in s.split('.'))
|
||||||
self.to_screen(u'encrypted signature length %d (%s), itag %s, %s' %
|
self.to_screen(u'encrypted signature length %d (%s), itag %s, %s' %
|
||||||
(len(s), parts_sizes, url_data['itag'][0], player))
|
(len(s), parts_sizes, url_data['itag'][0], player))
|
||||||
signature = self._decrypt_signature(url_data['s'][0])
|
encrypted_sig = url_data['s'][0]
|
||||||
|
if age_gate:
|
||||||
|
signature = self._decrypt_signature_age_gate(encrypted_sig)
|
||||||
|
else:
|
||||||
|
signature = self._decrypt_signature(encrypted_sig)
|
||||||
url += '&signature=' + signature
|
url += '&signature=' + signature
|
||||||
if 'ratebypass' not in url:
|
if 'ratebypass' not in url:
|
||||||
url += '&ratebypass=yes'
|
url += '&ratebypass=yes'
|
||||||
|
|
Loading…
Reference in a new issue