test_InfoExtractor.py 99 KB

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