]> jfr.im git - yt-dlp.git/blob - test/test_InfoExtractor.py
[ie/youtube] Fix comments extraction (#9775)
[yt-dlp.git] / test / test_InfoExtractor.py
1 #!/usr/bin/env python3
2
3 # Allow direct execution
4 import os
5 import sys
6 import unittest
7
8 sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
9
10
11 import http.server
12 import threading
13
14 from test.helper import FakeYDL, expect_dict, expect_value, http_server_port
15 from yt_dlp.compat import compat_etree_fromstring
16 from yt_dlp.extractor import YoutubeIE, get_info_extractor
17 from yt_dlp.extractor.common import InfoExtractor
18 from yt_dlp.utils import (
19 ExtractorError,
20 RegexNotFoundError,
21 encode_data_uri,
22 strip_jsonp,
23 )
24
25 TEAPOT_RESPONSE_STATUS = 418
26 TEAPOT_RESPONSE_BODY = "<h1>418 I'm a teapot</h1>"
27
28
29 class InfoExtractorTestRequestHandler(http.server.BaseHTTPRequestHandler):
30 def log_message(self, format, *args):
31 pass
32
33 def do_GET(self):
34 if self.path == '/teapot':
35 self.send_response(TEAPOT_RESPONSE_STATUS)
36 self.send_header('Content-Type', 'text/html; charset=utf-8')
37 self.end_headers()
38 self.wfile.write(TEAPOT_RESPONSE_BODY.encode())
39 else:
40 assert False
41
42
43 class DummyIE(InfoExtractor):
44 def _sort_formats(self, formats, field_preference=[]):
45 self._downloader.sort_formats(
46 {'formats': formats, '_format_sort_fields': field_preference})
47
48
49 class TestInfoExtractor(unittest.TestCase):
50 def setUp(self):
51 self.ie = DummyIE(FakeYDL())
52
53 def test_ie_key(self):
54 self.assertEqual(get_info_extractor(YoutubeIE.ie_key()), YoutubeIE)
55
56 def test_html_search_regex(self):
57 html = '<p id="foo">Watch this <a href="http://www.youtube.com/watch?v=BaW_jenozKc">video</a></p>'
58 search = lambda re, *args: self.ie._html_search_regex(re, html, *args)
59 self.assertEqual(search(r'<p id="foo">(.+?)</p>', 'foo'), 'Watch this video')
60
61 def test_opengraph(self):
62 ie = self.ie
63 html = '''
64 <meta name="og:title" content='Foo'/>
65 <meta content="Some video's description " name="og:description"/>
66 <meta property='og:image' content='http://domain.com/pic.jpg?key1=val1&amp;key2=val2'/>
67 <meta content='application/x-shockwave-flash' property='og:video:type'>
68 <meta content='Foo' property=og:foobar>
69 <meta name="og:test1" content='foo > < bar'/>
70 <meta name="og:test2" content="foo >//< bar"/>
71 <meta property=og-test3 content='Ill-formatted opengraph'/>
72 <meta property=og:test4 content=unquoted-value/>
73 '''
74 self.assertEqual(ie._og_search_title(html), 'Foo')
75 self.assertEqual(ie._og_search_description(html), 'Some video\'s description ')
76 self.assertEqual(ie._og_search_thumbnail(html), 'http://domain.com/pic.jpg?key1=val1&key2=val2')
77 self.assertEqual(ie._og_search_video_url(html, default=None), None)
78 self.assertEqual(ie._og_search_property('foobar', html), 'Foo')
79 self.assertEqual(ie._og_search_property('test1', html), 'foo > < bar')
80 self.assertEqual(ie._og_search_property('test2', html), 'foo >//< bar')
81 self.assertEqual(ie._og_search_property('test3', html), 'Ill-formatted opengraph')
82 self.assertEqual(ie._og_search_property(('test0', 'test1'), html), 'foo > < bar')
83 self.assertRaises(RegexNotFoundError, ie._og_search_property, 'test0', html, None, fatal=True)
84 self.assertRaises(RegexNotFoundError, ie._og_search_property, ('test0', 'test00'), html, None, fatal=True)
85 self.assertEqual(ie._og_search_property('test4', html), 'unquoted-value')
86
87 def test_html_search_meta(self):
88 ie = self.ie
89 html = '''
90 <meta name="a" content="1" />
91 <meta name='b' content='2'>
92 <meta name="c" content='3'>
93 <meta name=d content='4'>
94 <meta property="e" content='5' >
95 <meta content="6" name="f">
96 '''
97
98 self.assertEqual(ie._html_search_meta('a', html), '1')
99 self.assertEqual(ie._html_search_meta('b', html), '2')
100 self.assertEqual(ie._html_search_meta('c', html), '3')
101 self.assertEqual(ie._html_search_meta('d', html), '4')
102 self.assertEqual(ie._html_search_meta('e', html), '5')
103 self.assertEqual(ie._html_search_meta('f', html), '6')
104 self.assertEqual(ie._html_search_meta(('a', 'b', 'c'), html), '1')
105 self.assertEqual(ie._html_search_meta(('c', 'b', 'a'), html), '3')
106 self.assertEqual(ie._html_search_meta(('z', 'x', 'c'), html), '3')
107 self.assertRaises(RegexNotFoundError, ie._html_search_meta, 'z', html, None, fatal=True)
108 self.assertRaises(RegexNotFoundError, ie._html_search_meta, ('z', 'x'), html, None, fatal=True)
109
110 def test_search_json_ld_realworld(self):
111 _TESTS = [
112 # https://github.com/ytdl-org/youtube-dl/issues/23306
113 (
114 r'''<script type="application/ld+json">
115 {
116 "@context": "http://schema.org/",
117 "@type": "VideoObject",
118 "name": "1 On 1 With Kleio",
119 "url": "https://www.eporner.com/hd-porn/xN49A1cT3eB/1-On-1-With-Kleio/",
120 "duration": "PT0H12M23S",
121 "thumbnailUrl": ["https://static-eu-cdn.eporner.com/thumbs/static4/7/78/780/780814/9_360.jpg", "https://imggen.eporner.com/780814/1920/1080/9.jpg"],
122 "contentUrl": "https://gvideo.eporner.com/xN49A1cT3eB/xN49A1cT3eB.mp4",
123 "embedUrl": "https://www.eporner.com/embed/xN49A1cT3eB/1-On-1-With-Kleio/",
124 "image": "https://static-eu-cdn.eporner.com/thumbs/static4/7/78/780/780814/9_360.jpg",
125 "width": "1920",
126 "height": "1080",
127 "encodingFormat": "mp4",
128 "bitrate": "6617kbps",
129 "isFamilyFriendly": "False",
130 "description": "Kleio Valentien",
131 "uploadDate": "2015-12-05T21:24:35+01:00",
132 "interactionStatistic": {
133 "@type": "InteractionCounter",
134 "interactionType": { "@type": "http://schema.org/WatchAction" },
135 "userInteractionCount": 1120958
136 }, "aggregateRating": {
137 "@type": "AggregateRating",
138 "ratingValue": "88",
139 "ratingCount": "630",
140 "bestRating": "100",
141 "worstRating": "0"
142 }, "actor": [{
143 "@type": "Person",
144 "name": "Kleio Valentien",
145 "url": "https://www.eporner.com/pornstar/kleio-valentien/"
146 }]}
147 </script>''',
148 {
149 'title': '1 On 1 With Kleio',
150 'description': 'Kleio Valentien',
151 'url': 'https://gvideo.eporner.com/xN49A1cT3eB/xN49A1cT3eB.mp4',
152 'timestamp': 1449347075,
153 'duration': 743.0,
154 'view_count': 1120958,
155 'width': 1920,
156 'height': 1080,
157 },
158 {},
159 ),
160 (
161 r'''<script type="application/ld+json">
162 {
163 "@context": "https://schema.org",
164 "@graph": [
165 {
166 "@type": "NewsArticle",
167 "mainEntityOfPage": {
168 "@type": "WebPage",
169 "@id": "https://www.ant1news.gr/Society/article/620286/symmoria-anilikon-dikigoros-thymaton-ithelan-na-toys-apoteleiosoyn"
170 },
171 "headline": "Συμμορία ανηλίκων – δικηγόρος θυμάτων: ήθελαν να τους αποτελειώσουν",
172 "name": "Συμμορία ανηλίκων – δικηγόρος θυμάτων: ήθελαν να τους αποτελειώσουν",
173 "description": "Τα παιδιά δέχθηκαν την επίθεση επειδή αρνήθηκαν να γίνουν μέλη της συμμορίας, ανέφερε ο Γ. Ζαχαρόπουλος.",
174 "image": {
175 "@type": "ImageObject",
176 "url": "https://ant1media.azureedge.net/imgHandler/1100/a635c968-be71-447c-bf9c-80d843ece21e.jpg",
177 "width": 1100,
178 "height": 756 },
179 "datePublished": "2021-11-10T08:50:00+03:00",
180 "dateModified": "2021-11-10T08:52:53+03:00",
181 "author": {
182 "@type": "Person",
183 "@id": "https://www.ant1news.gr/",
184 "name": "Ant1news",
185 "image": "https://www.ant1news.gr/images/logo-e5d7e4b3e714c88e8d2eca96130142f6.png",
186 "url": "https://www.ant1news.gr/"
187 },
188 "publisher": {
189 "@type": "Organization",
190 "@id": "https://www.ant1news.gr#publisher",
191 "name": "Ant1news",
192 "url": "https://www.ant1news.gr",
193 "logo": {
194 "@type": "ImageObject",
195 "url": "https://www.ant1news.gr/images/logo-e5d7e4b3e714c88e8d2eca96130142f6.png",
196 "width": 400,
197 "height": 400 },
198 "sameAs": [
199 "https://www.facebook.com/Ant1news.gr",
200 "https://twitter.com/antennanews",
201 "https://www.youtube.com/channel/UC0smvAbfczoN75dP0Hw4Pzw",
202 "https://www.instagram.com/ant1news/"
203 ]
204 },
205
206 "keywords": "μαχαίρωμα,συμμορία ανηλίκων,ΕΙΔΗΣΕΙΣ,ΕΙΔΗΣΕΙΣ ΣΗΜΕΡΑ,ΝΕΑ,Κοινωνία - Ant1news",
207
208
209 "articleSection": "Κοινωνία"
210 }
211 ]
212 }
213 </script>''',
214 {
215 'timestamp': 1636523400,
216 'title': 'md5:91fe569e952e4d146485740ae927662b',
217 },
218 {'expected_type': 'NewsArticle'},
219 ),
220 (
221 r'''<script type="application/ld+json">
222 {"url":"/vrtnu/a-z/het-journaal/2021/het-journaal-het-journaal-19u-20211231/",
223 "name":"Het journaal 19u",
224 "description":"Het journaal 19u van vrijdag 31 december 2021.",
225 "potentialAction":{"url":"https://vrtnu.page.link/pfVy6ihgCAJKgHqe8","@type":"ShareAction"},
226 "mainEntityOfPage":{"@id":"1640092242445","@type":"WebPage"},
227 "publication":[{
228 "startDate":"2021-12-31T19:00:00.000+01:00",
229 "endDate":"2022-01-30T23:55:00.000+01:00",
230 "publishedBy":{"name":"een","@type":"Organization"},
231 "publishedOn":{"url":"https://www.vrt.be/vrtnu/","name":"VRT NU","@type":"BroadcastService"},
232 "@id":"pbs-pub-3a7ec233-da95-4c1e-9b2b-cf5fdfebcbe8",
233 "@type":"BroadcastEvent"
234 }],
235 "video":{
236 "name":"Het journaal - Aflevering 365 (Seizoen 2021)",
237 "description":"Het journaal 19u van vrijdag 31 december 2021. Bekijk aflevering 365 van seizoen 2021 met VRT NU via de site of app.",
238 "thumbnailUrl":"//images.vrt.be/width1280/2021/12/31/80d5ed00-6a64-11ec-b07d-02b7b76bf47f.jpg",
239 "expires":"2022-01-30T23:55:00.000+01:00",
240 "hasPart":[
241 {"name":"Explosie Turnhout","startOffset":70,"@type":"Clip"},
242 {"name":"Jaarwisseling","startOffset":440,"@type":"Clip"},
243 {"name":"Natuurbranden Colorado","startOffset":1179,"@type":"Clip"},
244 {"name":"Klimaatverandering","startOffset":1263,"@type":"Clip"},
245 {"name":"Zacht weer","startOffset":1367,"@type":"Clip"},
246 {"name":"Financiële balans","startOffset":1383,"@type":"Clip"},
247 {"name":"Club Brugge","startOffset":1484,"@type":"Clip"},
248 {"name":"Mentale gezondheid bij topsporters","startOffset":1575,"@type":"Clip"},
249 {"name":"Olympische Winterspelen","startOffset":1728,"@type":"Clip"},
250 {"name":"Sober oudjaar in Nederland","startOffset":1873,"@type":"Clip"}
251 ],
252 "duration":"PT34M39.23S",
253 "uploadDate":"2021-12-31T19:00:00.000+01:00",
254 "@id":"vid-9457d0c6-b8ac-4aba-b5e1-15aa3a3295b5",
255 "@type":"VideoObject"
256 },
257 "genre":["Nieuws en actua"],
258 "episodeNumber":365,
259 "partOfSeries":{"name":"Het journaal","@id":"222831405527","@type":"TVSeries"},
260 "partOfSeason":{"name":"Seizoen 2021","@id":"961809365527","@type":"TVSeason"},
261 "@context":"https://schema.org","@id":"961685295527","@type":"TVEpisode"}</script>
262 ''',
263 {
264 'chapters': [
265 {"title": "Explosie Turnhout", "start_time": 70, "end_time": 440},
266 {"title": "Jaarwisseling", "start_time": 440, "end_time": 1179},
267 {"title": "Natuurbranden Colorado", "start_time": 1179, "end_time": 1263},
268 {"title": "Klimaatverandering", "start_time": 1263, "end_time": 1367},
269 {"title": "Zacht weer", "start_time": 1367, "end_time": 1383},
270 {"title": "Financiële balans", "start_time": 1383, "end_time": 1484},
271 {"title": "Club Brugge", "start_time": 1484, "end_time": 1575},
272 {"title": "Mentale gezondheid bij topsporters", "start_time": 1575, "end_time": 1728},
273 {"title": "Olympische Winterspelen", "start_time": 1728, "end_time": 1873},
274 {"title": "Sober oudjaar in Nederland", "start_time": 1873, "end_time": 2079.23}
275 ],
276 'title': 'Het journaal - Aflevering 365 (Seizoen 2021)'
277 }, {}
278 ),
279 (
280 # test multiple thumbnails in a list
281 r'''
282 <script type="application/ld+json">
283 {"@context":"https://schema.org",
284 "@type":"VideoObject",
285 "thumbnailUrl":["https://www.rainews.it/cropgd/640x360/dl/img/2021/12/30/1640886376927_GettyImages.jpg"]}
286 </script>''',
287 {
288 'thumbnails': [{'url': 'https://www.rainews.it/cropgd/640x360/dl/img/2021/12/30/1640886376927_GettyImages.jpg'}],
289 },
290 {},
291 ),
292 (
293 # test single thumbnail
294 r'''
295 <script type="application/ld+json">
296 {"@context":"https://schema.org",
297 "@type":"VideoObject",
298 "thumbnailUrl":"https://www.rainews.it/cropgd/640x360/dl/img/2021/12/30/1640886376927_GettyImages.jpg"}
299 </script>''',
300 {
301 'thumbnails': [{'url': 'https://www.rainews.it/cropgd/640x360/dl/img/2021/12/30/1640886376927_GettyImages.jpg'}],
302 },
303 {},
304 )
305 ]
306 for html, expected_dict, search_json_ld_kwargs in _TESTS:
307 expect_dict(
308 self,
309 self.ie._search_json_ld(html, None, **search_json_ld_kwargs),
310 expected_dict
311 )
312
313 def test_download_json(self):
314 uri = encode_data_uri(b'{"foo": "blah"}', 'application/json')
315 self.assertEqual(self.ie._download_json(uri, None), {'foo': 'blah'})
316 uri = encode_data_uri(b'callback({"foo": "blah"})', 'application/javascript')
317 self.assertEqual(self.ie._download_json(uri, None, transform_source=strip_jsonp), {'foo': 'blah'})
318 uri = encode_data_uri(b'{"foo": invalid}', 'application/json')
319 self.assertRaises(ExtractorError, self.ie._download_json, uri, None)
320 self.assertEqual(self.ie._download_json(uri, None, fatal=False), None)
321
322 def test_parse_html5_media_entries(self):
323 # inline video tag
324 expect_dict(
325 self,
326 self.ie._parse_html5_media_entries(
327 'https://127.0.0.1/video.html',
328 r'<html><video src="/vid.mp4" /></html>', None)[0],
329 {
330 'formats': [{
331 'url': 'https://127.0.0.1/vid.mp4',
332 }],
333 })
334
335 # from https://www.r18.com/
336 # with kpbs in label
337 expect_dict(
338 self,
339 self.ie._parse_html5_media_entries(
340 'https://www.r18.com/',
341 r'''
342 <video id="samplevideo_amateur" class="js-samplevideo video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" width="400" height="225" poster="//pics.r18.com/digital/amateur/mgmr105/mgmr105jp.jpg">
343 <source id="video_source" src="https://awscc3001.r18.com/litevideo/freepv/m/mgm/mgmr105/mgmr105_sm_w.mp4" type="video/mp4" res="240" label="300kbps">
344 <source id="video_source" src="https://awscc3001.r18.com/litevideo/freepv/m/mgm/mgmr105/mgmr105_dm_w.mp4" type="video/mp4" res="480" label="1000kbps">
345 <source id="video_source" src="https://awscc3001.r18.com/litevideo/freepv/m/mgm/mgmr105/mgmr105_dmb_w.mp4" type="video/mp4" res="740" label="1500kbps">
346 <p>Your browser does not support the video tag.</p>
347 </video>
348 ''', None)[0],
349 {
350 'formats': [{
351 'url': 'https://awscc3001.r18.com/litevideo/freepv/m/mgm/mgmr105/mgmr105_sm_w.mp4',
352 'ext': 'mp4',
353 'format_id': '300kbps',
354 'height': 240,
355 'tbr': 300,
356 }, {
357 'url': 'https://awscc3001.r18.com/litevideo/freepv/m/mgm/mgmr105/mgmr105_dm_w.mp4',
358 'ext': 'mp4',
359 'format_id': '1000kbps',
360 'height': 480,
361 'tbr': 1000,
362 }, {
363 'url': 'https://awscc3001.r18.com/litevideo/freepv/m/mgm/mgmr105/mgmr105_dmb_w.mp4',
364 'ext': 'mp4',
365 'format_id': '1500kbps',
366 'height': 740,
367 'tbr': 1500,
368 }],
369 'thumbnail': '//pics.r18.com/digital/amateur/mgmr105/mgmr105jp.jpg'
370 })
371
372 # from https://www.csfd.cz/
373 # with width and height
374 expect_dict(
375 self,
376 self.ie._parse_html5_media_entries(
377 'https://www.csfd.cz/',
378 r'''
379 <video width="770" height="328" preload="none" controls poster="https://img.csfd.cz/files/images/film/video/preview/163/344/163344118_748d20.png?h360" >
380 <source src="https://video.csfd.cz/files/videos/157/750/157750813/163327358_eac647.mp4" type="video/mp4" width="640" height="360">
381 <source src="https://video.csfd.cz/files/videos/157/750/157750813/163327360_3d2646.mp4" type="video/mp4" width="1280" height="720">
382 <source src="https://video.csfd.cz/files/videos/157/750/157750813/163327356_91f258.mp4" type="video/mp4" width="1920" height="1080">
383 <source src="https://video.csfd.cz/files/videos/157/750/157750813/163327359_962b4a.webm" type="video/webm" width="640" height="360">
384 <source src="https://video.csfd.cz/files/videos/157/750/157750813/163327361_6feee0.webm" type="video/webm" width="1280" height="720">
385 <source src="https://video.csfd.cz/files/videos/157/750/157750813/163327357_8ab472.webm" type="video/webm" width="1920" height="1080">
386 <track src="https://video.csfd.cz/files/subtitles/163/344/163344115_4c388b.srt" type="text/x-srt" kind="subtitles" srclang="cs" label="cs">
387 </video>
388 ''', None)[0],
389 {
390 'formats': [{
391 'url': 'https://video.csfd.cz/files/videos/157/750/157750813/163327358_eac647.mp4',
392 'ext': 'mp4',
393 'width': 640,
394 'height': 360,
395 }, {
396 'url': 'https://video.csfd.cz/files/videos/157/750/157750813/163327360_3d2646.mp4',
397 'ext': 'mp4',
398 'width': 1280,
399 'height': 720,
400 }, {
401 'url': 'https://video.csfd.cz/files/videos/157/750/157750813/163327356_91f258.mp4',
402 'ext': 'mp4',
403 'width': 1920,
404 'height': 1080,
405 }, {
406 'url': 'https://video.csfd.cz/files/videos/157/750/157750813/163327359_962b4a.webm',
407 'ext': 'webm',
408 'width': 640,
409 'height': 360,
410 }, {
411 'url': 'https://video.csfd.cz/files/videos/157/750/157750813/163327361_6feee0.webm',
412 'ext': 'webm',
413 'width': 1280,
414 'height': 720,
415 }, {
416 'url': 'https://video.csfd.cz/files/videos/157/750/157750813/163327357_8ab472.webm',
417 'ext': 'webm',
418 'width': 1920,
419 'height': 1080,
420 }],
421 'subtitles': {
422 'cs': [{'url': 'https://video.csfd.cz/files/subtitles/163/344/163344115_4c388b.srt'}]
423 },
424 'thumbnail': 'https://img.csfd.cz/files/images/film/video/preview/163/344/163344118_748d20.png?h360'
425 })
426
427 # from https://tamasha.com/v/Kkdjw
428 # with height in label
429 expect_dict(
430 self,
431 self.ie._parse_html5_media_entries(
432 'https://tamasha.com/v/Kkdjw',
433 r'''
434 <video crossorigin="anonymous">
435 <source src="https://s-v2.tamasha.com/statics/videos_file/19/8f/Kkdjw_198feff8577d0057536e905cce1fb61438dd64e0_n_240.mp4" type="video/mp4" label="AUTO" res="0"/>
436 <source src="https://s-v2.tamasha.com/statics/videos_file/19/8f/Kkdjw_198feff8577d0057536e905cce1fb61438dd64e0_n_240.mp4" type="video/mp4"
437 label="240p" res="240"/>
438 <source src="https://s-v2.tamasha.com/statics/videos_file/20/00/Kkdjw_200041c66f657fc967db464d156eafbc1ed9fe6f_n_144.mp4" type="video/mp4"
439 label="144p" res="144"/>
440 </video>
441 ''', None)[0],
442 {
443 'formats': [{
444 'url': 'https://s-v2.tamasha.com/statics/videos_file/19/8f/Kkdjw_198feff8577d0057536e905cce1fb61438dd64e0_n_240.mp4',
445 }, {
446 'url': 'https://s-v2.tamasha.com/statics/videos_file/19/8f/Kkdjw_198feff8577d0057536e905cce1fb61438dd64e0_n_240.mp4',
447 'ext': 'mp4',
448 'format_id': '240p',
449 'height': 240,
450 }, {
451 'url': 'https://s-v2.tamasha.com/statics/videos_file/20/00/Kkdjw_200041c66f657fc967db464d156eafbc1ed9fe6f_n_144.mp4',
452 'ext': 'mp4',
453 'format_id': '144p',
454 'height': 144,
455 }]
456 })
457
458 # from https://www.directvnow.com
459 # with data-src
460 expect_dict(
461 self,
462 self.ie._parse_html5_media_entries(
463 'https://www.directvnow.com',
464 r'''
465 <video id="vid1" class="header--video-masked active" muted playsinline>
466 <source data-src="https://cdn.directv.com/content/dam/dtv/prod/website_directvnow-international/videos/DTVN_hdr_HBO_v3.mp4" type="video/mp4" />
467 </video>
468 ''', None)[0],
469 {
470 'formats': [{
471 'ext': 'mp4',
472 'url': 'https://cdn.directv.com/content/dam/dtv/prod/website_directvnow-international/videos/DTVN_hdr_HBO_v3.mp4',
473 }]
474 })
475
476 # from https://www.directvnow.com
477 # with data-src
478 expect_dict(
479 self,
480 self.ie._parse_html5_media_entries(
481 'https://www.directvnow.com',
482 r'''
483 <video id="vid1" class="header--video-masked active" muted playsinline>
484 <source data-src="https://cdn.directv.com/content/dam/dtv/prod/website_directvnow-international/videos/DTVN_hdr_HBO_v3.mp4" type="video/mp4" />
485 </video>
486 ''', None)[0],
487 {
488 'formats': [{
489 'url': 'https://cdn.directv.com/content/dam/dtv/prod/website_directvnow-international/videos/DTVN_hdr_HBO_v3.mp4',
490 'ext': 'mp4',
491 }]
492 })
493
494 # from https://www.klarna.com/uk/
495 # with data-video-src
496 expect_dict(
497 self,
498 self.ie._parse_html5_media_entries(
499 'https://www.directvnow.com',
500 r'''
501 <video loop autoplay muted class="responsive-video block-kl__video video-on-medium">
502 <source src="" data-video-desktop data-video-src="https://www.klarna.com/uk/wp-content/uploads/sites/11/2019/01/KL062_Smooth3_0_DogWalking_5s_920x080_.mp4" type="video/mp4" />
503 </video>
504 ''', None)[0],
505 {
506 'formats': [{
507 'url': 'https://www.klarna.com/uk/wp-content/uploads/sites/11/2019/01/KL062_Smooth3_0_DogWalking_5s_920x080_.mp4',
508 'ext': 'mp4',
509 }],
510 })
511
512 # from https://0000.studio/
513 # with type attribute but without extension in URL
514 expect_dict(
515 self,
516 self.ie._parse_html5_media_entries(
517 'https://0000.studio',
518 r'''
519 <video src="https://d1ggyt9m8pwf3g.cloudfront.net/protected/ap-northeast-1:1864af40-28d5-492b-b739-b32314b1a527/archive/clip/838db6a7-8973-4cd6-840d-8517e4093c92"
520 controls="controls" type="video/mp4" preload="metadata" autoplay="autoplay" playsinline class="object-contain">
521 </video>
522 ''', None)[0],
523 {
524 'formats': [{
525 'url': 'https://d1ggyt9m8pwf3g.cloudfront.net/protected/ap-northeast-1:1864af40-28d5-492b-b739-b32314b1a527/archive/clip/838db6a7-8973-4cd6-840d-8517e4093c92',
526 'ext': 'mp4',
527 }],
528 })
529
530 def test_extract_jwplayer_data_realworld(self):
531 # from http://www.suffolk.edu/sjc/
532 expect_dict(
533 self,
534 self.ie._extract_jwplayer_data(r'''
535 <script type='text/javascript'>
536 jwplayer('my-video').setup({
537 file: 'rtmp://192.138.214.154/live/sjclive',
538 fallback: 'true',
539 width: '95%',
540 aspectratio: '16:9',
541 primary: 'flash',
542 mediaid:'XEgvuql4'
543 });
544 </script>
545 ''', None, require_title=False),
546 {
547 'id': 'XEgvuql4',
548 'formats': [{
549 'url': 'rtmp://192.138.214.154/live/sjclive',
550 'ext': 'flv'
551 }]
552 })
553
554 # from https://www.pornoxo.com/videos/7564/striptease-from-sexy-secretary/
555 expect_dict(
556 self,
557 self.ie._extract_jwplayer_data(r'''
558 <script type="text/javascript">
559 jwplayer("mediaplayer").setup({
560 'videoid': "7564",
561 'width': "100%",
562 'aspectratio': "16:9",
563 'stretching': "exactfit",
564 'autostart': 'false',
565 'flashplayer': "https://t04.vipstreamservice.com/jwplayer/v5.10/player.swf",
566 'file': "https://cdn.pornoxo.com/key=MF+oEbaxqTKb50P-w9G3nA,end=1489689259,ip=104.199.146.27/ip=104.199.146.27/speed=6573765/buffer=3.0/2009-12/4b2157147afe5efa93ce1978e0265289c193874e02597.flv",
567 'image': "https://t03.vipstreamservice.com/thumbs/pxo-full/2009-12/14/a4b2157147afe5efa93ce1978e0265289c193874e02597.flv-full-13.jpg",
568 'filefallback': "https://cdn.pornoxo.com/key=9ZPsTR5EvPLQrBaak2MUGA,end=1489689259,ip=104.199.146.27/ip=104.199.146.27/speed=6573765/buffer=3.0/2009-12/m_4b2157147afe5efa93ce1978e0265289c193874e02597.mp4",
569 'logo.hide': true,
570 'skin': "https://t04.vipstreamservice.com/jwplayer/skin/modieus-blk.zip",
571 'plugins': "https://t04.vipstreamservice.com/jwplayer/dock/dockableskinnableplugin.swf",
572 'dockableskinnableplugin.piclink': "/index.php?key=ajax-videothumbsn&vid=7564&data=2009-12--14--4b2157147afe5efa93ce1978e0265289c193874e02597.flv--17370",
573 'controlbar': 'bottom',
574 'modes': [
575 {type: 'flash', src: 'https://t04.vipstreamservice.com/jwplayer/v5.10/player.swf'}
576 ],
577 'provider': 'http'
578 });
579 //noinspection JSAnnotator
580 invideo.setup({
581 adsUrl: "/banner-iframe/?zoneId=32",
582 adsUrl2: "",
583 autostart: false
584 });
585 </script>
586 ''', 'dummy', require_title=False),
587 {
588 'thumbnail': 'https://t03.vipstreamservice.com/thumbs/pxo-full/2009-12/14/a4b2157147afe5efa93ce1978e0265289c193874e02597.flv-full-13.jpg',
589 'formats': [{
590 'url': 'https://cdn.pornoxo.com/key=MF+oEbaxqTKb50P-w9G3nA,end=1489689259,ip=104.199.146.27/ip=104.199.146.27/speed=6573765/buffer=3.0/2009-12/4b2157147afe5efa93ce1978e0265289c193874e02597.flv',
591 'ext': 'flv'
592 }]
593 })
594
595 # from http://www.indiedb.com/games/king-machine/videos
596 expect_dict(
597 self,
598 self.ie._extract_jwplayer_data(r'''
599 <script>
600 jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/\/www.indiedb.com\/","displaytitle":false,"autostart":false,"repeat":false,"title":"king machine trailer 1","sharing":{"link":"http:\/\/www.indiedb.com\/games\/king-machine\/videos\/king-machine-trailer-1","code":"<iframe width=\"560\" height=\"315\" src=\"http:\/\/www.indiedb.com\/media\/iframe\/1522983\" frameborder=\"0\" allowfullscreen><\/iframe><br><a href=\"http:\/\/www.indiedb.com\/games\/king-machine\/videos\/king-machine-trailer-1\">king machine trailer 1 - Indie DB<\/a>"},"related":{"file":"http:\/\/rss.indiedb.com\/media\/recommended\/1522983\/feed\/rss.xml","dimensions":"160x120","onclick":"link"},"sources":[{"file":"http:\/\/cdn.dbolical.com\/cache\/videos\/games\/1\/50\/49678\/encode_mp4\/king-machine-trailer.mp4","label":"360p SD","default":"true"},{"file":"http:\/\/cdn.dbolical.com\/cache\/videos\/games\/1\/50\/49678\/encode720p_mp4\/king-machine-trailer.mp4","label":"720p HD"}],"image":"http:\/\/media.indiedb.com\/cache\/images\/games\/1\/50\/49678\/thumb_620x2000\/king-machine-trailer.mp4.jpg","advertising":{"client":"vast","tag":"http:\/\/ads.intergi.com\/adrawdata\/3.0\/5205\/4251742\/0\/1013\/ADTECH;cors=yes;width=560;height=315;referring_url=http:\/\/www.indiedb.com\/games\/king-machine\/videos\/king-machine-trailer-1;content_url=http:\/\/www.indiedb.com\/games\/king-machine\/videos\/king-machine-trailer-1;media_id=1522983;title=king+machine+trailer+1;device=__DEVICE__;model=__MODEL__;os=Windows+OS;osversion=__OSVERSION__;ua=__UA__;ip=109.171.17.81;uniqueid=1522983;tags=__TAGS__;number=58cac25928151;time=1489683033"},"width":620,"height":349}).once("play", function(event) {
601 videoAnalytics("play");
602 }).once("complete", function(event) {
603 videoAnalytics("completed");
604 });
605 </script>
606 ''', 'dummy'),
607 {
608 'title': 'king machine trailer 1',
609 'thumbnail': 'http://media.indiedb.com/cache/images/games/1/50/49678/thumb_620x2000/king-machine-trailer.mp4.jpg',
610 'formats': [{
611 'url': 'http://cdn.dbolical.com/cache/videos/games/1/50/49678/encode_mp4/king-machine-trailer.mp4',
612 'height': 360,
613 'ext': 'mp4'
614 }, {
615 'url': 'http://cdn.dbolical.com/cache/videos/games/1/50/49678/encode720p_mp4/king-machine-trailer.mp4',
616 'height': 720,
617 'ext': 'mp4'
618 }]
619 })
620
621 def test_parse_m3u8_formats(self):
622 _TEST_CASES = [
623 (
624 # https://github.com/ytdl-org/youtube-dl/issues/11995
625 # http://teamcoco.com/video/clueless-gamer-super-bowl-for-honor
626 'img_bipbop_adv_example_fmp4',
627 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
628 [{
629 'format_id': 'aud1-English',
630 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/a1/prog_index.m3u8',
631 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
632 'language': 'en',
633 'ext': 'mp4',
634 'protocol': 'm3u8_native',
635 'audio_ext': 'mp4',
636 }, {
637 'format_id': 'aud2-English',
638 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/a2/prog_index.m3u8',
639 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
640 'language': 'en',
641 'ext': 'mp4',
642 'protocol': 'm3u8_native',
643 'audio_ext': 'mp4',
644 }, {
645 'format_id': 'aud3-English',
646 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/a3/prog_index.m3u8',
647 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
648 'language': 'en',
649 'ext': 'mp4',
650 'protocol': 'm3u8_native',
651 'audio_ext': 'mp4',
652 }, {
653 'format_id': '530',
654 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v2/prog_index.m3u8',
655 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
656 'ext': 'mp4',
657 'protocol': 'm3u8_native',
658 'width': 480,
659 'height': 270,
660 'vcodec': 'avc1.640015',
661 }, {
662 'format_id': '561',
663 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v2/prog_index.m3u8',
664 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
665 'ext': 'mp4',
666 'protocol': 'm3u8_native',
667 'width': 480,
668 'height': 270,
669 'vcodec': 'avc1.640015',
670 }, {
671 'format_id': '753',
672 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v2/prog_index.m3u8',
673 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
674 'ext': 'mp4',
675 'protocol': 'm3u8_native',
676 'width': 480,
677 'height': 270,
678 'vcodec': 'avc1.640015',
679 }, {
680 'format_id': '895',
681 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v3/prog_index.m3u8',
682 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
683 'ext': 'mp4',
684 'protocol': 'm3u8_native',
685 'width': 640,
686 'height': 360,
687 'vcodec': 'avc1.64001e',
688 }, {
689 'format_id': '926',
690 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v3/prog_index.m3u8',
691 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
692 'ext': 'mp4',
693 'protocol': 'm3u8_native',
694 'width': 640,
695 'height': 360,
696 'vcodec': 'avc1.64001e',
697 }, {
698 'format_id': '1118',
699 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v3/prog_index.m3u8',
700 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
701 'ext': 'mp4',
702 'protocol': 'm3u8_native',
703 'width': 640,
704 'height': 360,
705 'vcodec': 'avc1.64001e',
706 }, {
707 'format_id': '1265',
708 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v4/prog_index.m3u8',
709 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
710 'ext': 'mp4',
711 'protocol': 'm3u8_native',
712 'width': 768,
713 'height': 432,
714 'vcodec': 'avc1.64001e',
715 }, {
716 'format_id': '1295',
717 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v4/prog_index.m3u8',
718 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
719 'ext': 'mp4',
720 'protocol': 'm3u8_native',
721 'width': 768,
722 'height': 432,
723 'vcodec': 'avc1.64001e',
724 }, {
725 'format_id': '1487',
726 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v4/prog_index.m3u8',
727 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
728 'ext': 'mp4',
729 'protocol': 'm3u8_native',
730 'width': 768,
731 'height': 432,
732 'vcodec': 'avc1.64001e',
733 }, {
734 'format_id': '2168',
735 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v5/prog_index.m3u8',
736 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
737 'ext': 'mp4',
738 'protocol': 'm3u8_native',
739 'width': 960,
740 'height': 540,
741 'vcodec': 'avc1.640020',
742 }, {
743 'format_id': '2198',
744 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v5/prog_index.m3u8',
745 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
746 'ext': 'mp4',
747 'protocol': 'm3u8_native',
748 'width': 960,
749 'height': 540,
750 'vcodec': 'avc1.640020',
751 }, {
752 'format_id': '2390',
753 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v5/prog_index.m3u8',
754 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
755 'ext': 'mp4',
756 'protocol': 'm3u8_native',
757 'width': 960,
758 'height': 540,
759 'vcodec': 'avc1.640020',
760 }, {
761 'format_id': '3168',
762 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v6/prog_index.m3u8',
763 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
764 'ext': 'mp4',
765 'protocol': 'm3u8_native',
766 'width': 1280,
767 'height': 720,
768 'vcodec': 'avc1.640020',
769 }, {
770 'format_id': '3199',
771 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v6/prog_index.m3u8',
772 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
773 'ext': 'mp4',
774 'protocol': 'm3u8_native',
775 'width': 1280,
776 'height': 720,
777 'vcodec': 'avc1.640020',
778 }, {
779 'format_id': '3391',
780 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v6/prog_index.m3u8',
781 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
782 'ext': 'mp4',
783 'protocol': 'm3u8_native',
784 'width': 1280,
785 'height': 720,
786 'vcodec': 'avc1.640020',
787 }, {
788 'format_id': '4670',
789 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v7/prog_index.m3u8',
790 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
791 'ext': 'mp4',
792 'protocol': 'm3u8_native',
793 'width': 1920,
794 'height': 1080,
795 'vcodec': 'avc1.64002a',
796 }, {
797 'format_id': '4701',
798 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v7/prog_index.m3u8',
799 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
800 'ext': 'mp4',
801 'protocol': 'm3u8_native',
802 'width': 1920,
803 'height': 1080,
804 'vcodec': 'avc1.64002a',
805 }, {
806 'format_id': '4893',
807 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v7/prog_index.m3u8',
808 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
809 'ext': 'mp4',
810 'protocol': 'm3u8_native',
811 'width': 1920,
812 'height': 1080,
813 'vcodec': 'avc1.64002a',
814 }, {
815 'format_id': '6170',
816 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v8/prog_index.m3u8',
817 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
818 'ext': 'mp4',
819 'protocol': 'm3u8_native',
820 'width': 1920,
821 'height': 1080,
822 'vcodec': 'avc1.64002a',
823 }, {
824 'format_id': '6200',
825 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v8/prog_index.m3u8',
826 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
827 'ext': 'mp4',
828 'protocol': 'm3u8_native',
829 'width': 1920,
830 'height': 1080,
831 'vcodec': 'avc1.64002a',
832 }, {
833 'format_id': '6392',
834 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v8/prog_index.m3u8',
835 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
836 'ext': 'mp4',
837 'protocol': 'm3u8_native',
838 'width': 1920,
839 'height': 1080,
840 'vcodec': 'avc1.64002a',
841 }, {
842 'format_id': '7968',
843 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v9/prog_index.m3u8',
844 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
845 'ext': 'mp4',
846 'protocol': 'm3u8_native',
847 'width': 1920,
848 'height': 1080,
849 'vcodec': 'avc1.64002a',
850 }, {
851 'format_id': '7998',
852 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v9/prog_index.m3u8',
853 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
854 'ext': 'mp4',
855 'protocol': 'm3u8_native',
856 'width': 1920,
857 'height': 1080,
858 'vcodec': 'avc1.64002a',
859 }, {
860 'format_id': '8190',
861 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/v9/prog_index.m3u8',
862 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8',
863 'ext': 'mp4',
864 'protocol': 'm3u8_native',
865 'width': 1920,
866 'height': 1080,
867 'vcodec': 'avc1.64002a',
868 }],
869 {}
870 ),
871 (
872 'bipbop_16x9',
873 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8',
874 [{
875 'format_id': 'bipbop_audio-BipBop Audio 2',
876 'format_index': None,
877 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/alternate_audio_aac/prog_index.m3u8',
878 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8',
879 'language': 'eng',
880 'ext': 'mp4',
881 'protocol': 'm3u8_native',
882 'preference': None,
883 'quality': None,
884 'vcodec': 'none',
885 'audio_ext': 'mp4',
886 'video_ext': 'none',
887 }, {
888 'format_id': '41',
889 'format_index': None,
890 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear0/prog_index.m3u8',
891 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8',
892 'tbr': 41.457,
893 'ext': 'mp4',
894 'fps': None,
895 'protocol': 'm3u8_native',
896 'preference': None,
897 'quality': None,
898 'vcodec': 'none',
899 'acodec': 'mp4a.40.2',
900 'audio_ext': 'mp4',
901 'video_ext': 'none',
902 'abr': 41.457,
903 }, {
904 'format_id': '263',
905 'format_index': None,
906 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear1/prog_index.m3u8',
907 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8',
908 'tbr': 263.851,
909 'ext': 'mp4',
910 'fps': None,
911 'protocol': 'm3u8_native',
912 'preference': None,
913 'quality': None,
914 'width': 416,
915 'height': 234,
916 'vcodec': 'avc1.4d400d',
917 'acodec': 'mp4a.40.2',
918 'video_ext': 'mp4',
919 'audio_ext': 'none',
920 }, {
921 'format_id': '577',
922 'format_index': None,
923 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear2/prog_index.m3u8',
924 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8',
925 'tbr': 577.61,
926 'ext': 'mp4',
927 'fps': None,
928 'protocol': 'm3u8_native',
929 'preference': None,
930 'quality': None,
931 'width': 640,
932 'height': 360,
933 'vcodec': 'avc1.4d401e',
934 'acodec': 'mp4a.40.2',
935 'video_ext': 'mp4',
936 'audio_ext': 'none',
937 }, {
938 'format_id': '915',
939 'format_index': None,
940 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear3/prog_index.m3u8',
941 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8',
942 'tbr': 915.905,
943 'ext': 'mp4',
944 'fps': None,
945 'protocol': 'm3u8_native',
946 'preference': None,
947 'quality': None,
948 'width': 960,
949 'height': 540,
950 'vcodec': 'avc1.4d401f',
951 'acodec': 'mp4a.40.2',
952 'video_ext': 'mp4',
953 'audio_ext': 'none',
954 }, {
955 'format_id': '1030',
956 'format_index': None,
957 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear4/prog_index.m3u8',
958 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8',
959 'tbr': 1030.138,
960 'ext': 'mp4',
961 'fps': None,
962 'protocol': 'm3u8_native',
963 'preference': None,
964 'quality': None,
965 'width': 1280,
966 'height': 720,
967 'vcodec': 'avc1.4d401f',
968 'acodec': 'mp4a.40.2',
969 'video_ext': 'mp4',
970 'audio_ext': 'none',
971 }, {
972 'format_id': '1924',
973 'format_index': None,
974 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear5/prog_index.m3u8',
975 'manifest_url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8',
976 'tbr': 1924.009,
977 'ext': 'mp4',
978 'fps': None,
979 'protocol': 'm3u8_native',
980 'preference': None,
981 'quality': None,
982 'width': 1920,
983 'height': 1080,
984 'vcodec': 'avc1.4d401f',
985 'acodec': 'mp4a.40.2',
986 'video_ext': 'mp4',
987 'audio_ext': 'none',
988 }],
989 {
990 'en': [{
991 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/subtitles/eng/prog_index.m3u8',
992 'ext': 'vtt',
993 'protocol': 'm3u8_native'
994 }, {
995 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/subtitles/eng_forced/prog_index.m3u8',
996 'ext': 'vtt',
997 'protocol': 'm3u8_native'
998 }],
999 'fr': [{
1000 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/subtitles/fra/prog_index.m3u8',
1001 'ext': 'vtt',
1002 'protocol': 'm3u8_native'
1003 }, {
1004 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/subtitles/fra_forced/prog_index.m3u8',
1005 'ext': 'vtt',
1006 'protocol': 'm3u8_native'
1007 }],
1008 'es': [{
1009 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/subtitles/spa/prog_index.m3u8',
1010 'ext': 'vtt',
1011 'protocol': 'm3u8_native'
1012 }, {
1013 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/subtitles/spa_forced/prog_index.m3u8',
1014 'ext': 'vtt',
1015 'protocol': 'm3u8_native'
1016 }],
1017 'ja': [{
1018 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/subtitles/jpn/prog_index.m3u8',
1019 'ext': 'vtt',
1020 'protocol': 'm3u8_native'
1021 }, {
1022 'url': 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/subtitles/jpn_forced/prog_index.m3u8',
1023 'ext': 'vtt',
1024 'protocol': 'm3u8_native'
1025 }],
1026 }
1027 ),
1028 ]
1029
1030 for m3u8_file, m3u8_url, expected_formats, expected_subs in _TEST_CASES:
1031 with open('./test/testdata/m3u8/%s.m3u8' % m3u8_file, encoding='utf-8') as f:
1032 formats, subs = self.ie._parse_m3u8_formats_and_subtitles(
1033 f.read(), m3u8_url, ext='mp4')
1034 self.ie._sort_formats(formats)
1035 expect_value(self, formats, expected_formats, None)
1036 expect_value(self, subs, expected_subs, None)
1037
1038 def test_parse_mpd_formats(self):
1039 _TEST_CASES = [
1040 (
1041 # https://github.com/ytdl-org/youtube-dl/issues/13919
1042 # Also tests duplicate representation ids, see
1043 # https://github.com/ytdl-org/youtube-dl/issues/15111
1044 'float_duration',
1045 'http://unknown/manifest.mpd', # mpd_url
1046 None, # mpd_base_url
1047 [{
1048 'manifest_url': 'http://unknown/manifest.mpd',
1049 'ext': 'm4a',
1050 'format_id': '318597',
1051 'format_note': 'DASH audio',
1052 'protocol': 'http_dash_segments',
1053 'acodec': 'mp4a.40.2',
1054 'vcodec': 'none',
1055 'tbr': 61.587,
1056 }, {
1057 'manifest_url': 'http://unknown/manifest.mpd',
1058 'ext': 'mp4',
1059 'format_id': '318597',
1060 'format_note': 'DASH video',
1061 'protocol': 'http_dash_segments',
1062 'acodec': 'none',
1063 'vcodec': 'avc1.42001f',
1064 'tbr': 318.597,
1065 'width': 340,
1066 'height': 192,
1067 }, {
1068 'manifest_url': 'http://unknown/manifest.mpd',
1069 'ext': 'mp4',
1070 'format_id': '638590',
1071 'format_note': 'DASH video',
1072 'protocol': 'http_dash_segments',
1073 'acodec': 'none',
1074 'vcodec': 'avc1.42001f',
1075 'tbr': 638.59,
1076 'width': 512,
1077 'height': 288,
1078 }, {
1079 'manifest_url': 'http://unknown/manifest.mpd',
1080 'ext': 'mp4',
1081 'format_id': '1022565',
1082 'format_note': 'DASH video',
1083 'protocol': 'http_dash_segments',
1084 'acodec': 'none',
1085 'vcodec': 'avc1.4d001f',
1086 'tbr': 1022.565,
1087 'width': 688,
1088 'height': 384,
1089 }, {
1090 'manifest_url': 'http://unknown/manifest.mpd',
1091 'ext': 'mp4',
1092 'format_id': '2046506',
1093 'format_note': 'DASH video',
1094 'protocol': 'http_dash_segments',
1095 'acodec': 'none',
1096 'vcodec': 'avc1.4d001f',
1097 'tbr': 2046.506,
1098 'width': 1024,
1099 'height': 576,
1100 }, {
1101 'manifest_url': 'http://unknown/manifest.mpd',
1102 'ext': 'mp4',
1103 'format_id': '3998017',
1104 'format_note': 'DASH video',
1105 'protocol': 'http_dash_segments',
1106 'acodec': 'none',
1107 'vcodec': 'avc1.640029',
1108 'tbr': 3998.017,
1109 'width': 1280,
1110 'height': 720,
1111 }, {
1112 'manifest_url': 'http://unknown/manifest.mpd',
1113 'ext': 'mp4',
1114 'format_id': '5997485',
1115 'format_note': 'DASH video',
1116 'protocol': 'http_dash_segments',
1117 'acodec': 'none',
1118 'vcodec': 'avc1.640032',
1119 'tbr': 5997.485,
1120 'width': 1920,
1121 'height': 1080,
1122 }],
1123 {},
1124 ), (
1125 # https://github.com/ytdl-org/youtube-dl/pull/14844
1126 'urls_only',
1127 'http://unknown/manifest.mpd', # mpd_url
1128 None, # mpd_base_url
1129 [{
1130 'manifest_url': 'http://unknown/manifest.mpd',
1131 'ext': 'mp4',
1132 'format_id': 'h264_aac_144p_m4s',
1133 'format_note': 'DASH video',
1134 'protocol': 'http_dash_segments',
1135 'acodec': 'mp4a.40.2',
1136 'vcodec': 'avc3.42c01e',
1137 'tbr': 200,
1138 'width': 256,
1139 'height': 144,
1140 }, {
1141 'manifest_url': 'http://unknown/manifest.mpd',
1142 'ext': 'mp4',
1143 'format_id': 'h264_aac_240p_m4s',
1144 'format_note': 'DASH video',
1145 'protocol': 'http_dash_segments',
1146 'acodec': 'mp4a.40.2',
1147 'vcodec': 'avc3.42c01e',
1148 'tbr': 400,
1149 'width': 424,
1150 'height': 240,
1151 }, {
1152 'manifest_url': 'http://unknown/manifest.mpd',
1153 'ext': 'mp4',
1154 'format_id': 'h264_aac_360p_m4s',
1155 'format_note': 'DASH video',
1156 'protocol': 'http_dash_segments',
1157 'acodec': 'mp4a.40.2',
1158 'vcodec': 'avc3.42c01e',
1159 'tbr': 800,
1160 'width': 640,
1161 'height': 360,
1162 }, {
1163 'manifest_url': 'http://unknown/manifest.mpd',
1164 'ext': 'mp4',
1165 'format_id': 'h264_aac_480p_m4s',
1166 'format_note': 'DASH video',
1167 'protocol': 'http_dash_segments',
1168 'acodec': 'mp4a.40.2',
1169 'vcodec': 'avc3.42c01e',
1170 'tbr': 1200,
1171 'width': 856,
1172 'height': 480,
1173 }, {
1174 'manifest_url': 'http://unknown/manifest.mpd',
1175 'ext': 'mp4',
1176 'format_id': 'h264_aac_576p_m4s',
1177 'format_note': 'DASH video',
1178 'protocol': 'http_dash_segments',
1179 'acodec': 'mp4a.40.2',
1180 'vcodec': 'avc3.42c01e',
1181 'tbr': 1600,
1182 'width': 1024,
1183 'height': 576,
1184 }, {
1185 'manifest_url': 'http://unknown/manifest.mpd',
1186 'ext': 'mp4',
1187 'format_id': 'h264_aac_720p_m4s',
1188 'format_note': 'DASH video',
1189 'protocol': 'http_dash_segments',
1190 'acodec': 'mp4a.40.2',
1191 'vcodec': 'avc3.42c01e',
1192 'tbr': 2400,
1193 'width': 1280,
1194 'height': 720,
1195 }, {
1196 'manifest_url': 'http://unknown/manifest.mpd',
1197 'ext': 'mp4',
1198 'format_id': 'h264_aac_1080p_m4s',
1199 'format_note': 'DASH video',
1200 'protocol': 'http_dash_segments',
1201 'acodec': 'mp4a.40.2',
1202 'vcodec': 'avc3.42c01e',
1203 'tbr': 4400,
1204 'width': 1920,
1205 'height': 1080,
1206 }],
1207 {},
1208 ), (
1209 # https://github.com/ytdl-org/youtube-dl/issues/20346
1210 # Media considered unfragmented even though it contains
1211 # Initialization tag
1212 'unfragmented',
1213 'https://v.redd.it/hw1x7rcg7zl21/DASHPlaylist.mpd', # mpd_url
1214 'https://v.redd.it/hw1x7rcg7zl21', # mpd_base_url
1215 [{
1216 'url': 'https://v.redd.it/hw1x7rcg7zl21/audio',
1217 'manifest_url': 'https://v.redd.it/hw1x7rcg7zl21/DASHPlaylist.mpd',
1218 'ext': 'm4a',
1219 'format_id': 'AUDIO-1',
1220 'format_note': 'DASH audio',
1221 'container': 'm4a_dash',
1222 'acodec': 'mp4a.40.2',
1223 'vcodec': 'none',
1224 'tbr': 129.87,
1225 'asr': 48000,
1226
1227 }, {
1228 'url': 'https://v.redd.it/hw1x7rcg7zl21/DASH_240',
1229 'manifest_url': 'https://v.redd.it/hw1x7rcg7zl21/DASHPlaylist.mpd',
1230 'ext': 'mp4',
1231 'format_id': 'VIDEO-2',
1232 'format_note': 'DASH video',
1233 'container': 'mp4_dash',
1234 'acodec': 'none',
1235 'vcodec': 'avc1.4d401e',
1236 'tbr': 608.0,
1237 'width': 240,
1238 'height': 240,
1239 'fps': 30,
1240 }, {
1241 'url': 'https://v.redd.it/hw1x7rcg7zl21/DASH_360',
1242 'manifest_url': 'https://v.redd.it/hw1x7rcg7zl21/DASHPlaylist.mpd',
1243 'ext': 'mp4',
1244 'format_id': 'VIDEO-1',
1245 'format_note': 'DASH video',
1246 'container': 'mp4_dash',
1247 'acodec': 'none',
1248 'vcodec': 'avc1.4d401e',
1249 'tbr': 804.261,
1250 'width': 360,
1251 'height': 360,
1252 'fps': 30,
1253 }],
1254 {},
1255 ), (
1256 'subtitles',
1257 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1258 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/',
1259 [{
1260 'format_id': 'audio=128001',
1261 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1262 'ext': 'm4a',
1263 'tbr': 128.001,
1264 'asr': 48000,
1265 'format_note': 'DASH audio',
1266 'container': 'm4a_dash',
1267 'vcodec': 'none',
1268 'acodec': 'mp4a.40.2',
1269 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1270 'fragment_base_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/dash/',
1271 'protocol': 'http_dash_segments',
1272 'audio_ext': 'm4a',
1273 'video_ext': 'none',
1274 'abr': 128.001,
1275 }, {
1276 'format_id': 'video=100000',
1277 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1278 'ext': 'mp4',
1279 'width': 336,
1280 'height': 144,
1281 'tbr': 100,
1282 'format_note': 'DASH video',
1283 'container': 'mp4_dash',
1284 'vcodec': 'avc1.4D401F',
1285 'acodec': 'none',
1286 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1287 'fragment_base_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/dash/',
1288 'protocol': 'http_dash_segments',
1289 'video_ext': 'mp4',
1290 'audio_ext': 'none',
1291 'vbr': 100,
1292 }, {
1293 'format_id': 'video=326000',
1294 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1295 'ext': 'mp4',
1296 'width': 562,
1297 'height': 240,
1298 'tbr': 326,
1299 'format_note': 'DASH video',
1300 'container': 'mp4_dash',
1301 'vcodec': 'avc1.4D401F',
1302 'acodec': 'none',
1303 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1304 'fragment_base_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/dash/',
1305 'protocol': 'http_dash_segments',
1306 'video_ext': 'mp4',
1307 'audio_ext': 'none',
1308 'vbr': 326,
1309 }, {
1310 'format_id': 'video=698000',
1311 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1312 'ext': 'mp4',
1313 'width': 844,
1314 'height': 360,
1315 'tbr': 698,
1316 'format_note': 'DASH video',
1317 'container': 'mp4_dash',
1318 'vcodec': 'avc1.4D401F',
1319 'acodec': 'none',
1320 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1321 'fragment_base_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/dash/',
1322 'protocol': 'http_dash_segments',
1323 'video_ext': 'mp4',
1324 'audio_ext': 'none',
1325 'vbr': 698,
1326 }, {
1327 'format_id': 'video=1493000',
1328 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1329 'ext': 'mp4',
1330 'width': 1126,
1331 'height': 480,
1332 'tbr': 1493,
1333 'format_note': 'DASH video',
1334 'container': 'mp4_dash',
1335 'vcodec': 'avc1.4D401F',
1336 'acodec': 'none',
1337 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1338 'fragment_base_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/dash/',
1339 'protocol': 'http_dash_segments',
1340 'video_ext': 'mp4',
1341 'audio_ext': 'none',
1342 'vbr': 1493,
1343 }, {
1344 'format_id': 'video=4482000',
1345 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1346 'ext': 'mp4',
1347 'width': 1688,
1348 'height': 720,
1349 'tbr': 4482,
1350 'format_note': 'DASH video',
1351 'container': 'mp4_dash',
1352 'vcodec': 'avc1.4D401F',
1353 'acodec': 'none',
1354 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1355 'fragment_base_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/dash/',
1356 'protocol': 'http_dash_segments',
1357 'video_ext': 'mp4',
1358 'audio_ext': 'none',
1359 'vbr': 4482,
1360 }],
1361 {
1362 'en': [
1363 {
1364 'ext': 'mp4',
1365 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1366 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
1367 'fragment_base_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/dash/',
1368 'protocol': 'http_dash_segments',
1369 }
1370 ]
1371 },
1372 )
1373 ]
1374
1375 for mpd_file, mpd_url, mpd_base_url, expected_formats, expected_subtitles in _TEST_CASES:
1376 with open('./test/testdata/mpd/%s.mpd' % mpd_file, encoding='utf-8') as f:
1377 formats, subtitles = self.ie._parse_mpd_formats_and_subtitles(
1378 compat_etree_fromstring(f.read().encode()),
1379 mpd_base_url=mpd_base_url, mpd_url=mpd_url)
1380 self.ie._sort_formats(formats)
1381 expect_value(self, formats, expected_formats, None)
1382 expect_value(self, subtitles, expected_subtitles, None)
1383
1384 def test_parse_ism_formats(self):
1385 _TEST_CASES = [
1386 (
1387 'sintel',
1388 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1389 [{
1390 'format_id': 'audio-128',
1391 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1392 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1393 'ext': 'isma',
1394 'tbr': 128,
1395 'asr': 48000,
1396 'vcodec': 'none',
1397 'acodec': 'AACL',
1398 'protocol': 'ism',
1399 'audio_channels': 2,
1400 '_download_params': {
1401 'stream_type': 'audio',
1402 'duration': 8880746666,
1403 'timescale': 10000000,
1404 'width': 0,
1405 'height': 0,
1406 'fourcc': 'AACL',
1407 'codec_private_data': '1190',
1408 'sampling_rate': 48000,
1409 'channels': 2,
1410 'bits_per_sample': 16,
1411 'nal_unit_length_field': 4
1412 },
1413 }, {
1414 'format_id': 'video-100',
1415 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1416 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1417 'ext': 'ismv',
1418 'width': 336,
1419 'height': 144,
1420 'tbr': 100,
1421 'vcodec': 'AVC1',
1422 'acodec': 'none',
1423 'protocol': 'ism',
1424 '_download_params': {
1425 'stream_type': 'video',
1426 'duration': 8880746666,
1427 'timescale': 10000000,
1428 'width': 336,
1429 'height': 144,
1430 'fourcc': 'AVC1',
1431 'codec_private_data': '00000001674D401FDA0544EFFC2D002CBC40000003004000000C03C60CA80000000168EF32C8',
1432 'channels': 2,
1433 'bits_per_sample': 16,
1434 'nal_unit_length_field': 4
1435 },
1436 }, {
1437 'format_id': 'video-326',
1438 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1439 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1440 'ext': 'ismv',
1441 'width': 562,
1442 'height': 240,
1443 'tbr': 326,
1444 'vcodec': 'AVC1',
1445 'acodec': 'none',
1446 'protocol': 'ism',
1447 '_download_params': {
1448 'stream_type': 'video',
1449 'duration': 8880746666,
1450 'timescale': 10000000,
1451 'width': 562,
1452 'height': 240,
1453 'fourcc': 'AVC1',
1454 'codec_private_data': '00000001674D401FDA0241FE23FFC3BC83BA44000003000400000300C03C60CA800000000168EF32C8',
1455 'channels': 2,
1456 'bits_per_sample': 16,
1457 'nal_unit_length_field': 4
1458 },
1459 }, {
1460 'format_id': 'video-698',
1461 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1462 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1463 'ext': 'ismv',
1464 'width': 844,
1465 'height': 360,
1466 'tbr': 698,
1467 'vcodec': 'AVC1',
1468 'acodec': 'none',
1469 'protocol': 'ism',
1470 '_download_params': {
1471 'stream_type': 'video',
1472 'duration': 8880746666,
1473 'timescale': 10000000,
1474 'width': 844,
1475 'height': 360,
1476 'fourcc': 'AVC1',
1477 'codec_private_data': '00000001674D401FDA0350BFB97FF06AF06AD1000003000100000300300F1832A00000000168EF32C8',
1478 'channels': 2,
1479 'bits_per_sample': 16,
1480 'nal_unit_length_field': 4
1481 },
1482 }, {
1483 'format_id': 'video-1493',
1484 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1485 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1486 'ext': 'ismv',
1487 'width': 1126,
1488 'height': 480,
1489 'tbr': 1493,
1490 'vcodec': 'AVC1',
1491 'acodec': 'none',
1492 'protocol': 'ism',
1493 '_download_params': {
1494 'stream_type': 'video',
1495 'duration': 8880746666,
1496 'timescale': 10000000,
1497 'width': 1126,
1498 'height': 480,
1499 'fourcc': 'AVC1',
1500 'codec_private_data': '00000001674D401FDA011C3DE6FFF0D890D871000003000100000300300F1832A00000000168EF32C8',
1501 'channels': 2,
1502 'bits_per_sample': 16,
1503 'nal_unit_length_field': 4
1504 },
1505 }, {
1506 'format_id': 'video-4482',
1507 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1508 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1509 'ext': 'ismv',
1510 'width': 1688,
1511 'height': 720,
1512 'tbr': 4482,
1513 'vcodec': 'AVC1',
1514 'acodec': 'none',
1515 'protocol': 'ism',
1516 '_download_params': {
1517 'stream_type': 'video',
1518 'duration': 8880746666,
1519 'timescale': 10000000,
1520 'width': 1688,
1521 'height': 720,
1522 'fourcc': 'AVC1',
1523 'codec_private_data': '00000001674D401FDA01A816F97FFC1ABC1AB440000003004000000C03C60CA80000000168EF32C8',
1524 'channels': 2,
1525 'bits_per_sample': 16,
1526 'nal_unit_length_field': 4
1527 },
1528 }],
1529 {
1530 'eng': [
1531 {
1532 'ext': 'ismt',
1533 'protocol': 'ism',
1534 'url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1535 'manifest_url': 'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/Manifest',
1536 '_download_params': {
1537 'stream_type': 'text',
1538 'duration': 8880746666,
1539 'timescale': 10000000,
1540 'fourcc': 'TTML',
1541 'codec_private_data': ''
1542 }
1543 }
1544 ]
1545 },
1546 ),
1547 (
1548 'ec-3_test',
1549 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1550 [{
1551 'format_id': 'audio_deu-127',
1552 'url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1553 'manifest_url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1554 'ext': 'isma',
1555 'tbr': 127,
1556 'asr': 48000,
1557 'vcodec': 'none',
1558 'acodec': 'AACL',
1559 'protocol': 'ism',
1560 'language': 'deu',
1561 'audio_channels': 2,
1562 '_download_params': {
1563 'stream_type': 'audio',
1564 'duration': 370000000,
1565 'timescale': 10000000,
1566 'width': 0,
1567 'height': 0,
1568 'fourcc': 'AACL',
1569 'language': 'deu',
1570 'codec_private_data': '1190',
1571 'sampling_rate': 48000,
1572 'channels': 2,
1573 'bits_per_sample': 16,
1574 'nal_unit_length_field': 4
1575 },
1576 }, {
1577 'format_id': 'audio_deu_1-224',
1578 'url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1579 'manifest_url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1580 'ext': 'isma',
1581 'tbr': 224,
1582 'asr': 48000,
1583 'vcodec': 'none',
1584 'acodec': 'EC-3',
1585 'protocol': 'ism',
1586 'language': 'deu',
1587 'audio_channels': 6,
1588 '_download_params': {
1589 'stream_type': 'audio',
1590 'duration': 370000000,
1591 'timescale': 10000000,
1592 'width': 0,
1593 'height': 0,
1594 'fourcc': 'EC-3',
1595 'language': 'deu',
1596 'codec_private_data': '00063F000000AF87FBA7022DFB42A4D405CD93843BDD0700200F00',
1597 'sampling_rate': 48000,
1598 'channels': 6,
1599 'bits_per_sample': 16,
1600 'nal_unit_length_field': 4
1601 },
1602 }, {
1603 'format_id': 'video_deu-23',
1604 'url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1605 'manifest_url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1606 'ext': 'ismv',
1607 'width': 384,
1608 'height': 216,
1609 'tbr': 23,
1610 'vcodec': 'AVC1',
1611 'acodec': 'none',
1612 'protocol': 'ism',
1613 'language': 'deu',
1614 '_download_params': {
1615 'stream_type': 'video',
1616 'duration': 370000000,
1617 'timescale': 10000000,
1618 'width': 384,
1619 'height': 216,
1620 'fourcc': 'AVC1',
1621 'language': 'deu',
1622 'codec_private_data': '000000016742C00CDB06077E5C05A808080A00000300020000030009C0C02EE0177CC6300F142AE00000000168CA8DC8',
1623 'channels': 2,
1624 'bits_per_sample': 16,
1625 'nal_unit_length_field': 4
1626 },
1627 }, {
1628 'format_id': 'video_deu-403',
1629 'url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1630 'manifest_url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1631 'ext': 'ismv',
1632 'width': 400,
1633 'height': 224,
1634 'tbr': 403,
1635 'vcodec': 'AVC1',
1636 'acodec': 'none',
1637 'protocol': 'ism',
1638 'language': 'deu',
1639 '_download_params': {
1640 'stream_type': 'video',
1641 'duration': 370000000,
1642 'timescale': 10000000,
1643 'width': 400,
1644 'height': 224,
1645 'fourcc': 'AVC1',
1646 'language': 'deu',
1647 'codec_private_data': '00000001674D4014E98323B602D4040405000003000100000300320F1429380000000168EAECF2',
1648 'channels': 2,
1649 'bits_per_sample': 16,
1650 'nal_unit_length_field': 4
1651 },
1652 }, {
1653 'format_id': 'video_deu-680',
1654 'url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1655 'manifest_url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1656 'ext': 'ismv',
1657 'width': 640,
1658 'height': 360,
1659 'tbr': 680,
1660 'vcodec': 'AVC1',
1661 'acodec': 'none',
1662 'protocol': 'ism',
1663 'language': 'deu',
1664 '_download_params': {
1665 'stream_type': 'video',
1666 'duration': 370000000,
1667 'timescale': 10000000,
1668 'width': 640,
1669 'height': 360,
1670 'fourcc': 'AVC1',
1671 'language': 'deu',
1672 'codec_private_data': '00000001674D401EE981405FF2E02D4040405000000300100000030320F162D3800000000168EAECF2',
1673 'channels': 2,
1674 'bits_per_sample': 16,
1675 'nal_unit_length_field': 4
1676 },
1677 }, {
1678 'format_id': 'video_deu-1253',
1679 'url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1680 'manifest_url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1681 'ext': 'ismv',
1682 'width': 640,
1683 'height': 360,
1684 'tbr': 1253,
1685 'vcodec': 'AVC1',
1686 'acodec': 'none',
1687 'protocol': 'ism',
1688 'vbr': 1253,
1689 'language': 'deu',
1690 '_download_params': {
1691 'stream_type': 'video',
1692 'duration': 370000000,
1693 'timescale': 10000000,
1694 'width': 640,
1695 'height': 360,
1696 'fourcc': 'AVC1',
1697 'language': 'deu',
1698 'codec_private_data': '00000001674D401EE981405FF2E02D4040405000000300100000030320F162D3800000000168EAECF2',
1699 'channels': 2,
1700 'bits_per_sample': 16,
1701 'nal_unit_length_field': 4
1702 },
1703 }, {
1704 'format_id': 'video_deu-2121',
1705 'url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1706 'manifest_url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1707 'ext': 'ismv',
1708 'width': 768,
1709 'height': 432,
1710 'tbr': 2121,
1711 'vcodec': 'AVC1',
1712 'acodec': 'none',
1713 'protocol': 'ism',
1714 'language': 'deu',
1715 '_download_params': {
1716 'stream_type': 'video',
1717 'duration': 370000000,
1718 'timescale': 10000000,
1719 'width': 768,
1720 'height': 432,
1721 'fourcc': 'AVC1',
1722 'language': 'deu',
1723 'codec_private_data': '00000001674D401EECA0601BD80B50101014000003000400000300C83C58B6580000000168E93B3C80',
1724 'channels': 2,
1725 'bits_per_sample': 16,
1726 'nal_unit_length_field': 4
1727 },
1728 }, {
1729 'format_id': 'video_deu-3275',
1730 'url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1731 'manifest_url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1732 'ext': 'ismv',
1733 'width': 1280,
1734 'height': 720,
1735 'tbr': 3275,
1736 'vcodec': 'AVC1',
1737 'acodec': 'none',
1738 'protocol': 'ism',
1739 'language': 'deu',
1740 '_download_params': {
1741 'stream_type': 'video',
1742 'duration': 370000000,
1743 'timescale': 10000000,
1744 'width': 1280,
1745 'height': 720,
1746 'fourcc': 'AVC1',
1747 'language': 'deu',
1748 'codec_private_data': '00000001674D4020ECA02802DD80B501010140000003004000000C83C60C65800000000168E93B3C80',
1749 'channels': 2,
1750 'bits_per_sample': 16,
1751 'nal_unit_length_field': 4
1752 },
1753 }, {
1754 'format_id': 'video_deu-5300',
1755 'url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1756 'manifest_url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1757 'ext': 'ismv',
1758 'width': 1920,
1759 'height': 1080,
1760 'tbr': 5300,
1761 'vcodec': 'AVC1',
1762 'acodec': 'none',
1763 'protocol': 'ism',
1764 'language': 'deu',
1765 '_download_params': {
1766 'stream_type': 'video',
1767 'duration': 370000000,
1768 'timescale': 10000000,
1769 'width': 1920,
1770 'height': 1080,
1771 'fourcc': 'AVC1',
1772 'language': 'deu',
1773 'codec_private_data': '00000001674D4028ECA03C0113F2E02D4040405000000300100000030320F18319600000000168E93B3C80',
1774 'channels': 2,
1775 'bits_per_sample': 16,
1776 'nal_unit_length_field': 4
1777 },
1778 }, {
1779 'format_id': 'video_deu-8079',
1780 'url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1781 'manifest_url': 'https://smstr01.dmm.t-online.de/smooth24/smoothstream_m1/streaming/sony/9221438342941275747/636887760842957027/25_km_h-Trailer-9221571562372022953_deu_20_1300k_HD_H_264_ISMV.ism/Manifest',
1782 'ext': 'ismv',
1783 'width': 1920,
1784 'height': 1080,
1785 'tbr': 8079,
1786 'vcodec': 'AVC1',
1787 'acodec': 'none',
1788 'protocol': 'ism',
1789 'language': 'deu',
1790 '_download_params': {
1791 'stream_type': 'video',
1792 'duration': 370000000,
1793 'timescale': 10000000,
1794 'width': 1920,
1795 'height': 1080,
1796 'fourcc': 'AVC1',
1797 'language': 'deu',
1798 'codec_private_data': '00000001674D4028ECA03C0113F2E02D4040405000000300100000030320F18319600000000168E93B3C80',
1799 'channels': 2,
1800 'bits_per_sample': 16,
1801 'nal_unit_length_field': 4
1802 },
1803 }],
1804 {},
1805 ),
1806 ]
1807
1808 for ism_file, ism_url, expected_formats, expected_subtitles in _TEST_CASES:
1809 with open('./test/testdata/ism/%s.Manifest' % ism_file, encoding='utf-8') as f:
1810 formats, subtitles = self.ie._parse_ism_formats_and_subtitles(
1811 compat_etree_fromstring(f.read().encode()), ism_url=ism_url)
1812 self.ie._sort_formats(formats)
1813 expect_value(self, formats, expected_formats, None)
1814 expect_value(self, subtitles, expected_subtitles, None)
1815
1816 def test_parse_f4m_formats(self):
1817 _TEST_CASES = [
1818 (
1819 # https://github.com/ytdl-org/youtube-dl/issues/14660
1820 'custom_base_url',
1821 'http://api.new.livestream.com/accounts/6115179/events/6764928/videos/144884262.f4m',
1822 [{
1823 'manifest_url': 'http://api.new.livestream.com/accounts/6115179/events/6764928/videos/144884262.f4m',
1824 'ext': 'flv',
1825 'format_id': '2148',
1826 'protocol': 'f4m',
1827 'tbr': 2148,
1828 'width': 1280,
1829 'height': 720,
1830 }]
1831 ),
1832 ]
1833
1834 for f4m_file, f4m_url, expected_formats in _TEST_CASES:
1835 with open('./test/testdata/f4m/%s.f4m' % f4m_file, encoding='utf-8') as f:
1836 formats = self.ie._parse_f4m_formats(
1837 compat_etree_fromstring(f.read().encode()),
1838 f4m_url, None)
1839 self.ie._sort_formats(formats)
1840 expect_value(self, formats, expected_formats, None)
1841
1842 def test_parse_xspf(self):
1843 _TEST_CASES = [
1844 (
1845 'foo_xspf',
1846 'https://example.org/src/foo_xspf.xspf',
1847 [{
1848 'id': 'foo_xspf',
1849 'title': 'Pandemonium',
1850 'description': 'Visit http://bigbrother404.bandcamp.com',
1851 'duration': 202.416,
1852 'formats': [{
1853 'manifest_url': 'https://example.org/src/foo_xspf.xspf',
1854 'url': 'https://example.org/src/cd1/track%201.mp3',
1855 }],
1856 }, {
1857 'id': 'foo_xspf',
1858 'title': 'Final Cartridge (Nichico Twelve Remix)',
1859 'description': 'Visit http://bigbrother404.bandcamp.com',
1860 'duration': 255.857,
1861 'formats': [{
1862 'manifest_url': 'https://example.org/src/foo_xspf.xspf',
1863 'url': 'https://example.org/%E3%83%88%E3%83%A9%E3%83%83%E3%82%AF%E3%80%80%EF%BC%92.mp3',
1864 }],
1865 }, {
1866 'id': 'foo_xspf',
1867 'title': 'Rebuilding Nightingale',
1868 'description': 'Visit http://bigbrother404.bandcamp.com',
1869 'duration': 287.915,
1870 'formats': [{
1871 'manifest_url': 'https://example.org/src/foo_xspf.xspf',
1872 'url': 'https://example.org/src/track3.mp3',
1873 }, {
1874 'manifest_url': 'https://example.org/src/foo_xspf.xspf',
1875 'url': 'https://example.com/track3.mp3',
1876 }]
1877 }]
1878 ),
1879 ]
1880
1881 for xspf_file, xspf_url, expected_entries in _TEST_CASES:
1882 with open('./test/testdata/xspf/%s.xspf' % xspf_file, encoding='utf-8') as f:
1883 entries = self.ie._parse_xspf(
1884 compat_etree_fromstring(f.read().encode()),
1885 xspf_file, xspf_url=xspf_url, xspf_base_url=xspf_url)
1886 expect_value(self, entries, expected_entries, None)
1887 for i in range(len(entries)):
1888 expect_dict(self, entries[i], expected_entries[i])
1889
1890 def test_response_with_expected_status_returns_content(self):
1891 # Checks for mitigations against the effects of
1892 # <https://bugs.python.org/issue15002> that affect Python 3.4.1+, which
1893 # manifest as `_download_webpage`, `_download_xml`, `_download_json`,
1894 # or the underlying `_download_webpage_handle` returning no content
1895 # when a response matches `expected_status`.
1896
1897 httpd = http.server.HTTPServer(
1898 ('127.0.0.1', 0), InfoExtractorTestRequestHandler)
1899 port = http_server_port(httpd)
1900 server_thread = threading.Thread(target=httpd.serve_forever)
1901 server_thread.daemon = True
1902 server_thread.start()
1903
1904 (content, urlh) = self.ie._download_webpage_handle(
1905 'http://127.0.0.1:%d/teapot' % port, None,
1906 expected_status=TEAPOT_RESPONSE_STATUS)
1907 self.assertEqual(content, TEAPOT_RESPONSE_BODY)
1908
1909 def test_search_nextjs_data(self):
1910 data = '<script id="__NEXT_DATA__" type="application/json">{"props":{}}</script>'
1911 self.assertEqual(self.ie._search_nextjs_data(data, None), {'props': {}})
1912 self.assertEqual(self.ie._search_nextjs_data('', None, fatal=False), {})
1913 self.assertEqual(self.ie._search_nextjs_data('', None, default=None), None)
1914 self.assertEqual(self.ie._search_nextjs_data('', None, default={}), {})
1915 with self.assertRaises(DeprecationWarning):
1916 self.assertEqual(self.ie._search_nextjs_data('', None, default='{}'), {})
1917
1918
1919 if __name__ == '__main__':
1920 unittest.main()