mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2025-12-14 04:05:16 +00:00
Merge remote-tracking branch 'origin' into yt-live-from-start-range
This commit is contained in:
@@ -917,8 +917,6 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
|
||||
'acodec': 'mp4a.40.2',
|
||||
'video_ext': 'mp4',
|
||||
'audio_ext': 'none',
|
||||
'vbr': 263.851,
|
||||
'abr': 0,
|
||||
}, {
|
||||
'format_id': '577',
|
||||
'format_index': None,
|
||||
@@ -936,8 +934,6 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
|
||||
'acodec': 'mp4a.40.2',
|
||||
'video_ext': 'mp4',
|
||||
'audio_ext': 'none',
|
||||
'vbr': 577.61,
|
||||
'abr': 0,
|
||||
}, {
|
||||
'format_id': '915',
|
||||
'format_index': None,
|
||||
@@ -955,8 +951,6 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
|
||||
'acodec': 'mp4a.40.2',
|
||||
'video_ext': 'mp4',
|
||||
'audio_ext': 'none',
|
||||
'vbr': 915.905,
|
||||
'abr': 0,
|
||||
}, {
|
||||
'format_id': '1030',
|
||||
'format_index': None,
|
||||
@@ -974,8 +968,6 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
|
||||
'acodec': 'mp4a.40.2',
|
||||
'video_ext': 'mp4',
|
||||
'audio_ext': 'none',
|
||||
'vbr': 1030.138,
|
||||
'abr': 0,
|
||||
}, {
|
||||
'format_id': '1924',
|
||||
'format_index': None,
|
||||
@@ -993,8 +985,6 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
|
||||
'acodec': 'mp4a.40.2',
|
||||
'video_ext': 'mp4',
|
||||
'audio_ext': 'none',
|
||||
'vbr': 1924.009,
|
||||
'abr': 0,
|
||||
}],
|
||||
{
|
||||
'en': [{
|
||||
|
||||
@@ -630,6 +630,7 @@ class TestYoutubeDL(unittest.TestCase):
|
||||
self.assertEqual(test_dict['playlist'], 'funny videos')
|
||||
|
||||
outtmpl_info = {
|
||||
'id': '1234',
|
||||
'id': '1234',
|
||||
'ext': 'mp4',
|
||||
'width': None,
|
||||
@@ -668,7 +669,7 @@ class TestYoutubeDL(unittest.TestCase):
|
||||
for (name, got), expect in zip((('outtmpl', out), ('filename', fname)), expected):
|
||||
if callable(expect):
|
||||
self.assertTrue(expect(got), f'Wrong {name} from {tmpl}')
|
||||
else:
|
||||
elif expect is not None:
|
||||
self.assertEqual(got, expect, f'Wrong {name} from {tmpl}')
|
||||
|
||||
# Side-effects
|
||||
@@ -754,20 +755,23 @@ class TestYoutubeDL(unittest.TestCase):
|
||||
test('%(ext)c', 'm')
|
||||
test('%(id)d %(id)r', "1234 '1234'")
|
||||
test('%(id)r %(height)r', "'1234' 1080")
|
||||
test('%(title5)a %(height)a', (R"'\xe1\xe9\xed \U0001d400' 1080", None))
|
||||
test('%(ext)s-%(ext|def)d', 'mp4-def')
|
||||
test('%(width|0)04d', '0000')
|
||||
test('%(width|0)04d', '0')
|
||||
test('a%(width|b)d', 'ab', outtmpl_na_placeholder='none')
|
||||
|
||||
FORMATS = self.outtmpl_info['formats']
|
||||
sanitize = lambda x: x.replace(':', ':').replace('"', """).replace('\n', ' ')
|
||||
|
||||
# Custom type casting
|
||||
test('%(formats.:.id)l', 'id 1, id 2, id 3')
|
||||
test('%(formats.:.id)#l', ('id 1\nid 2\nid 3', 'id 1 id 2 id 3'))
|
||||
test('%(ext)l', 'mp4')
|
||||
test('%(formats.:.id) 18l', ' id 1, id 2, id 3')
|
||||
test('%(formats)j', (json.dumps(FORMATS), sanitize(json.dumps(FORMATS))))
|
||||
test('%(formats)#j', (json.dumps(FORMATS, indent=4), sanitize(json.dumps(FORMATS, indent=4))))
|
||||
test('%(formats)j', (json.dumps(FORMATS), None))
|
||||
test('%(formats)#j', (
|
||||
json.dumps(FORMATS, indent=4),
|
||||
json.dumps(FORMATS, indent=4).replace(':', ':').replace('"', """).replace('\n', ' ')
|
||||
))
|
||||
test('%(title5).3B', 'á')
|
||||
test('%(title5)U', 'áéí 𝐀')
|
||||
test('%(title5)#U', 'a\u0301e\u0301i\u0301 𝐀')
|
||||
@@ -792,8 +796,8 @@ class TestYoutubeDL(unittest.TestCase):
|
||||
test('%(title|%)s %(title|%%)s', '% %%')
|
||||
test('%(id+1-height+3)05d', '00158')
|
||||
test('%(width+100)05d', 'NA')
|
||||
test('%(formats.0) 15s', ('% 15s' % FORMATS[0], '% 15s' % sanitize(str(FORMATS[0]))))
|
||||
test('%(formats.0)r', (repr(FORMATS[0]), sanitize(repr(FORMATS[0]))))
|
||||
test('%(formats.0) 15s', ('% 15s' % FORMATS[0], None))
|
||||
test('%(formats.0)r', (repr(FORMATS[0]), None))
|
||||
test('%(height.0)03d', '001')
|
||||
test('%(-height.0)04d', '-001')
|
||||
test('%(formats.-1.id)s', FORMATS[-1]['id'])
|
||||
@@ -805,7 +809,7 @@ class TestYoutubeDL(unittest.TestCase):
|
||||
out = json.dumps([{'id': f['id'], 'height.:2': str(f['height'])[:2]}
|
||||
if 'height' in f else {'id': f['id']}
|
||||
for f in FORMATS])
|
||||
test('%(formats.:.{id,height.:2})j', (out, sanitize(out)))
|
||||
test('%(formats.:.{id,height.:2})j', (out, None))
|
||||
test('%(formats.:.{id,height}.id)l', ', '.join(f['id'] for f in FORMATS))
|
||||
test('%(.{id,title})j', ('{"id": "1234"}', '{"id": "1234"}'))
|
||||
|
||||
|
||||
@@ -12,19 +12,62 @@ import math
|
||||
from yt_dlp.jsinterp import JS_Undefined, JSInterpreter
|
||||
|
||||
|
||||
class NaN:
|
||||
pass
|
||||
|
||||
|
||||
class TestJSInterpreter(unittest.TestCase):
|
||||
def _test(self, code, ret, func='f', args=()):
|
||||
self.assertEqual(JSInterpreter(code).call_function(func, *args), ret)
|
||||
def _test(self, jsi_or_code, expected, func='f', args=()):
|
||||
if isinstance(jsi_or_code, str):
|
||||
jsi_or_code = JSInterpreter(jsi_or_code)
|
||||
got = jsi_or_code.call_function(func, *args)
|
||||
if expected is NaN:
|
||||
self.assertTrue(math.isnan(got), f'{got} is not NaN')
|
||||
else:
|
||||
self.assertEqual(got, expected)
|
||||
|
||||
def test_basic(self):
|
||||
jsi = JSInterpreter('function f(){;}')
|
||||
self.assertEqual(repr(jsi.extract_function('f')), 'F<f>')
|
||||
self.assertEqual(jsi.call_function('f'), None)
|
||||
self._test(jsi, None)
|
||||
|
||||
self._test('function f(){return 42;}', 42)
|
||||
self._test('function f(){42}', None)
|
||||
self._test('var f = function(){return 42;}', 42)
|
||||
|
||||
def test_add(self):
|
||||
self._test('function f(){return 42 + 7;}', 49)
|
||||
self._test('function f(){return 42 + undefined;}', NaN)
|
||||
self._test('function f(){return 42 + null;}', 42)
|
||||
|
||||
def test_sub(self):
|
||||
self._test('function f(){return 42 - 7;}', 35)
|
||||
self._test('function f(){return 42 - undefined;}', NaN)
|
||||
self._test('function f(){return 42 - null;}', 42)
|
||||
|
||||
def test_mul(self):
|
||||
self._test('function f(){return 42 * 7;}', 294)
|
||||
self._test('function f(){return 42 * undefined;}', NaN)
|
||||
self._test('function f(){return 42 * null;}', 0)
|
||||
|
||||
def test_div(self):
|
||||
jsi = JSInterpreter('function f(a, b){return a / b;}')
|
||||
self._test(jsi, NaN, args=(0, 0))
|
||||
self._test(jsi, NaN, args=(JS_Undefined, 1))
|
||||
self._test(jsi, float('inf'), args=(2, 0))
|
||||
self._test(jsi, 0, args=(0, 3))
|
||||
|
||||
def test_mod(self):
|
||||
self._test('function f(){return 42 % 7;}', 0)
|
||||
self._test('function f(){return 42 % 0;}', NaN)
|
||||
self._test('function f(){return 42 % undefined;}', NaN)
|
||||
|
||||
def test_exp(self):
|
||||
self._test('function f(){return 42 ** 2;}', 1764)
|
||||
self._test('function f(){return 42 ** undefined;}', NaN)
|
||||
self._test('function f(){return 42 ** null;}', 1)
|
||||
self._test('function f(){return undefined ** 42;}', NaN)
|
||||
|
||||
def test_calc(self):
|
||||
self._test('function f(a){return 2*a+1;}', 7, args=[3])
|
||||
|
||||
@@ -95,16 +138,15 @@ class TestJSInterpreter(unittest.TestCase):
|
||||
''', [20, 20, 30, 40, 50])
|
||||
|
||||
def test_builtins(self):
|
||||
jsi = JSInterpreter('function f() { return NaN }')
|
||||
self.assertTrue(math.isnan(jsi.call_function('f')))
|
||||
self._test('function f() { return NaN }', NaN)
|
||||
|
||||
def test_date(self):
|
||||
self._test('function f() { return new Date("Wednesday 31 December 1969 18:01:26 MDT") - 0; }', 86000)
|
||||
|
||||
jsi = JSInterpreter('function f(dt) { return new Date(dt) - 0; }')
|
||||
self.assertEqual(jsi.call_function('f', 'Wednesday 31 December 1969 18:01:26 MDT'), 86000)
|
||||
self.assertEqual(jsi.call_function('f', '12/31/1969 18:01:26 MDT'), 86000) # m/d/y
|
||||
self.assertEqual(jsi.call_function('f', '1 January 1970 00:00:00 UTC'), 0)
|
||||
self._test(jsi, 86000, args=['Wednesday 31 December 1969 18:01:26 MDT'])
|
||||
self._test(jsi, 86000, args=['12/31/1969 18:01:26 MDT']) # m/d/y
|
||||
self._test(jsi, 0, args=['1 January 1970 00:00:00 UTC'])
|
||||
|
||||
def test_call(self):
|
||||
jsi = JSInterpreter('''
|
||||
@@ -112,8 +154,8 @@ class TestJSInterpreter(unittest.TestCase):
|
||||
function y(a) { return x() + (a?a:0); }
|
||||
function z() { return y(3); }
|
||||
''')
|
||||
self.assertEqual(jsi.call_function('z'), 5)
|
||||
self.assertEqual(jsi.call_function('y'), 2)
|
||||
self._test(jsi, 5, func='z')
|
||||
self._test(jsi, 2, func='y')
|
||||
|
||||
def test_if(self):
|
||||
self._test('''
|
||||
@@ -160,9 +202,9 @@ class TestJSInterpreter(unittest.TestCase):
|
||||
default:x=0;
|
||||
} return x }
|
||||
''')
|
||||
self.assertEqual(jsi.call_function('f', 1), 7)
|
||||
self.assertEqual(jsi.call_function('f', 3), 6)
|
||||
self.assertEqual(jsi.call_function('f', 5), 0)
|
||||
self._test(jsi, 7, args=[1])
|
||||
self._test(jsi, 6, args=[3])
|
||||
self._test(jsi, 0, args=[5])
|
||||
|
||||
def test_switch_default(self):
|
||||
jsi = JSInterpreter('''
|
||||
@@ -175,9 +217,9 @@ class TestJSInterpreter(unittest.TestCase):
|
||||
case 1: x+=1;
|
||||
} return x }
|
||||
''')
|
||||
self.assertEqual(jsi.call_function('f', 1), 2)
|
||||
self.assertEqual(jsi.call_function('f', 5), 11)
|
||||
self.assertEqual(jsi.call_function('f', 9), 14)
|
||||
self._test(jsi, 2, args=[1])
|
||||
self._test(jsi, 11, args=[5])
|
||||
self._test(jsi, 14, args=[9])
|
||||
|
||||
def test_try(self):
|
||||
self._test('function f() { try{return 10} catch(e){return 5} }', 10)
|
||||
@@ -305,12 +347,12 @@ class TestJSInterpreter(unittest.TestCase):
|
||||
|
||||
def test_char_code_at(self):
|
||||
jsi = JSInterpreter('function f(i){return "test".charCodeAt(i)}')
|
||||
self.assertEqual(jsi.call_function('f', 0), 116)
|
||||
self.assertEqual(jsi.call_function('f', 1), 101)
|
||||
self.assertEqual(jsi.call_function('f', 2), 115)
|
||||
self.assertEqual(jsi.call_function('f', 3), 116)
|
||||
self.assertEqual(jsi.call_function('f', 4), None)
|
||||
self.assertEqual(jsi.call_function('f', 'not_a_number'), 116)
|
||||
self._test(jsi, 116, args=[0])
|
||||
self._test(jsi, 101, args=[1])
|
||||
self._test(jsi, 115, args=[2])
|
||||
self._test(jsi, 116, args=[3])
|
||||
self._test(jsi, None, args=[4])
|
||||
self._test(jsi, 116, args=['not_a_number'])
|
||||
|
||||
def test_bitwise_operators_overflow(self):
|
||||
self._test('function f(){return -524999584 << 5}', 379882496)
|
||||
|
||||
@@ -62,7 +62,12 @@ _SIG_TESTS = [
|
||||
'https://s.ytimg.com/yts/jsbin/html5player-en_US-vflKjOTVq/html5player.js',
|
||||
'312AA52209E3623129A412D56A40F11CB0AF14AE.3EE09501CB14E3BCDC3B2AE808BF3F1D14E7FBF12',
|
||||
'112AA5220913623229A412D56A40F11CB0AF14AE.3EE0950FCB14EEBCDC3B2AE808BF331D14E7FBF3',
|
||||
)
|
||||
),
|
||||
(
|
||||
'https://www.youtube.com/s/player/6ed0d907/player_ias.vflset/en_US/base.js',
|
||||
'2aq0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpzEICs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
|
||||
'AOq0QJ8wRAIgXmPlOPSBkkUs1bYFYlJCfe29xx8j7v1pDL2QwbdV96sCIEzpWqMGkFR20CFOg51Tp-7vj_EMu-m37KtXJoOySqa0',
|
||||
),
|
||||
]
|
||||
|
||||
_NSIG_TESTS = [
|
||||
@@ -150,6 +155,14 @@ _NSIG_TESTS = [
|
||||
'https://www.youtube.com/s/player/cfa9e7cb/player_ias.vflset/en_US/base.js',
|
||||
'aCi3iElgd2kq0bxVbQ', 'QX1y8jGb2IbZ0w',
|
||||
),
|
||||
(
|
||||
'https://www.youtube.com/s/player/8c7583ff/player_ias.vflset/en_US/base.js',
|
||||
'1wWCVpRR96eAmMI87L', 'KSkWAVv1ZQxC3A',
|
||||
),
|
||||
(
|
||||
'https://www.youtube.com/s/player/b7910ca8/player_ias.vflset/en_US/base.js',
|
||||
'_hXMCwMt9qE310D', 'LoZMgkkofRMCZQ',
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
@@ -226,7 +239,7 @@ def n_sig(jscode, sig_input):
|
||||
|
||||
|
||||
make_sig_test = t_factory(
|
||||
'signature', signature, re.compile(r'.*-(?P<id>[a-zA-Z0-9_-]+)(?:/watch_as3|/html5player)?\.[a-z]+$'))
|
||||
'signature', signature, re.compile(r'.*(?:-|/player/)(?P<id>[a-zA-Z0-9_-]+)(?:/.+\.js|(?:/watch_as3|/html5player)?\.[a-z]+)$'))
|
||||
for test_spec in _SIG_TESTS:
|
||||
make_sig_test(*test_spec)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user