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