test_InfoExtractor.py 98 KB

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