test_InfoExtractor.py 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  1. #!/usr/bin/env python
  2. from __future__ import unicode_literals
  3. # Allow direct execution
  4. import io
  5. import os
  6. import sys
  7. import unittest
  8. sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  9. from test.helper import FakeYDL, expect_dict, expect_value, http_server_port
  10. from youtube_dl.compat import compat_etree_fromstring, compat_http_server
  11. from youtube_dl.extractor.common import InfoExtractor
  12. from youtube_dl.extractor import YoutubeIE, get_info_extractor
  13. from youtube_dl.utils import encode_data_uri, strip_jsonp, ExtractorError, RegexNotFoundError
  14. import threading
  15. TEAPOT_RESPONSE_STATUS = 418
  16. TEAPOT_RESPONSE_BODY = "<h1>418 I'm a teapot</h1>"
  17. class InfoExtractorTestRequestHandler(compat_http_server.BaseHTTPRequestHandler):
  18. def log_message(self, format, *args):
  19. pass
  20. def do_GET(self):
  21. if self.path == '/teapot':
  22. self.send_response(TEAPOT_RESPONSE_STATUS)
  23. self.send_header('Content-Type', 'text/html; charset=utf-8')
  24. self.end_headers()
  25. self.wfile.write(TEAPOT_RESPONSE_BODY.encode())
  26. else:
  27. assert False
  28. class DummyIE(InfoExtractor):
  29. pass
  30. class TestInfoExtractor(unittest.TestCase):
  31. def setUp(self):
  32. self.ie = DummyIE(FakeYDL())
  33. def test_ie_key(self):
  34. self.assertEqual(get_info_extractor(YoutubeIE.ie_key()), YoutubeIE)
  35. def test_html_search_regex(self):
  36. html = '<p id="foo">Watch this <a href="http://www.youtube.com/watch?v=BaW_jenozKc">video</a></p>'
  37. search = lambda re, *args: self.ie._html_search_regex(re, html, *args)
  38. self.assertEqual(search(r'<p id="foo">(.+?)</p>', 'foo'), 'Watch this video')
  39. def test_opengraph(self):
  40. ie = self.ie
  41. html = '''
  42. <meta name="og:title" content='Foo'/>
  43. <meta content="Some video's description " name="og:description"/>
  44. <meta property='og:image' content='http://domain.com/pic.jpg?key1=val1&amp;key2=val2'/>
  45. <meta content='application/x-shockwave-flash' property='og:video:type'>
  46. <meta content='Foo' property=og:foobar>
  47. <meta name="og:test1" content='foo > < bar'/>
  48. <meta name="og:test2" content="foo >//< bar"/>
  49. <meta property=og-test3 content='Ill-formatted opengraph'/>
  50. <meta property=og:test4 content=unquoted-value/>
  51. '''
  52. self.assertEqual(ie._og_search_title(html), 'Foo')
  53. self.assertEqual(ie._og_search_description(html), 'Some video\'s description ')
  54. self.assertEqual(ie._og_search_thumbnail(html), 'http://domain.com/pic.jpg?key1=val1&key2=val2')
  55. self.assertEqual(ie._og_search_video_url(html, default=None), None)
  56. self.assertEqual(ie._og_search_property('foobar', html), 'Foo')
  57. self.assertEqual(ie._og_search_property('test1', html), 'foo > < bar')
  58. self.assertEqual(ie._og_search_property('test2', html), 'foo >//< bar')
  59. self.assertEqual(ie._og_search_property('test3', html), 'Ill-formatted opengraph')
  60. self.assertEqual(ie._og_search_property(('test0', 'test1'), html), 'foo > < bar')
  61. self.assertRaises(RegexNotFoundError, ie._og_search_property, 'test0', html, None, fatal=True)
  62. self.assertRaises(RegexNotFoundError, ie._og_search_property, ('test0', 'test00'), html, None, fatal=True)
  63. self.assertEqual(ie._og_search_property('test4', html), 'unquoted-value')
  64. def test_html_search_meta(self):
  65. ie = self.ie
  66. html = '''
  67. <meta name="a" content="1" />
  68. <meta name='b' content='2'>
  69. <meta name="c" content='3'>
  70. <meta name=d content='4'>
  71. <meta property="e" content='5' >
  72. <meta content="6" name="f">
  73. '''
  74. self.assertEqual(ie._html_search_meta('a', html), '1')
  75. self.assertEqual(ie._html_search_meta('b', html), '2')
  76. self.assertEqual(ie._html_search_meta('c', html), '3')
  77. self.assertEqual(ie._html_search_meta('d', html), '4')
  78. self.assertEqual(ie._html_search_meta('e', html), '5')
  79. self.assertEqual(ie._html_search_meta('f', html), '6')
  80. self.assertEqual(ie._html_search_meta(('a', 'b', 'c'), html), '1')
  81. self.assertEqual(ie._html_search_meta(('c', 'b', 'a'), html), '3')
  82. self.assertEqual(ie._html_search_meta(('z', 'x', 'c'), html), '3')
  83. self.assertRaises(RegexNotFoundError, ie._html_search_meta, 'z', html, None, fatal=True)
  84. self.assertRaises(RegexNotFoundError, ie._html_search_meta, ('z', 'x'), html, None, fatal=True)
  85. def test_search_json_ld_realworld(self):
  86. # https://github.com/ytdl-org/youtube-dl/issues/23306
  87. expect_dict(
  88. self,
  89. self.ie._search_json_ld(r'''<script type="application/ld+json">
  90. {
  91. "@context": "http://schema.org/",
  92. "@type": "VideoObject",
  93. "name": "1 On 1 With Kleio",
  94. "url": "https://www.eporner.com/hd-porn/xN49A1cT3eB/1-On-1-With-Kleio/",
  95. "duration": "PT0H12M23S",
  96. "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"],
  97. "contentUrl": "https://gvideo.eporner.com/xN49A1cT3eB/xN49A1cT3eB.mp4",
  98. "embedUrl": "https://www.eporner.com/embed/xN49A1cT3eB/1-On-1-With-Kleio/",
  99. "image": "https://static-eu-cdn.eporner.com/thumbs/static4/7/78/780/780814/9_360.jpg",
  100. "width": "1920",
  101. "height": "1080",
  102. "encodingFormat": "mp4",
  103. "bitrate": "6617kbps",
  104. "isFamilyFriendly": "False",
  105. "description": "Kleio Valentien",
  106. "uploadDate": "2015-12-05T21:24:35+01:00",
  107. "interactionStatistic": {
  108. "@type": "InteractionCounter",
  109. "interactionType": { "@type": "http://schema.org/WatchAction" },
  110. "userInteractionCount": 1120958
  111. }, "aggregateRating": {
  112. "@type": "AggregateRating",
  113. "ratingValue": "88",
  114. "ratingCount": "630",
  115. "bestRating": "100",
  116. "worstRating": "0"
  117. }, "actor": [{
  118. "@type": "Person",
  119. "name": "Kleio Valentien",
  120. "url": "https://www.eporner.com/pornstar/kleio-valentien/"
  121. }]}
  122. </script>''', None),
  123. {
  124. 'title': '1 On 1 With Kleio',
  125. 'description': 'Kleio Valentien',
  126. 'url': 'https://gvideo.eporner.com/xN49A1cT3eB/xN49A1cT3eB.mp4',
  127. 'timestamp': 1449347075,
  128. 'duration': 743.0,
  129. 'view_count': 1120958,
  130. 'width': 1920,
  131. 'height': 1080,
  132. })
  133. def test_download_json(self):
  134. uri = encode_data_uri(b'{"foo": "blah"}', 'application/json')
  135. self.assertEqual(self.ie._download_json(uri, None), {'foo': 'blah'})
  136. uri = encode_data_uri(b'callback({"foo": "blah"})', 'application/javascript')
  137. self.assertEqual(self.ie._download_json(uri, None, transform_source=strip_jsonp), {'foo': 'blah'})
  138. uri = encode_data_uri(b'{"foo": invalid}', 'application/json')
  139. self.assertRaises(ExtractorError, self.ie._download_json, uri, None)
  140. self.assertEqual(self.ie._download_json(uri, None, fatal=False), None)
  141. def test_parse_html5_media_entries(self):
  142. # inline video tag
  143. expect_dict(
  144. self,
  145. self.ie._parse_html5_media_entries(
  146. 'https://127.0.0.1/video.html',
  147. r'<html><video src="/vid.mp4" /></html>', None)[0],
  148. {
  149. 'formats': [{
  150. 'url': 'https://127.0.0.1/vid.mp4',
  151. }],
  152. })
  153. # from https://www.r18.com/
  154. # with kpbs in label
  155. expect_dict(
  156. self,
  157. self.ie._parse_html5_media_entries(
  158. 'https://www.r18.com/',
  159. r'''
  160. <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">
  161. <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">
  162. <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">
  163. <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">
  164. <p>Your browser does not support the video tag.</p>
  165. </video>
  166. ''', None)[0],
  167. {
  168. 'formats': [{
  169. 'url': 'https://awscc3001.r18.com/litevideo/freepv/m/mgm/mgmr105/mgmr105_sm_w.mp4',
  170. 'ext': 'mp4',
  171. 'format_id': '300kbps',
  172. 'height': 240,
  173. 'tbr': 300,
  174. }, {
  175. 'url': 'https://awscc3001.r18.com/litevideo/freepv/m/mgm/mgmr105/mgmr105_dm_w.mp4',
  176. 'ext': 'mp4',
  177. 'format_id': '1000kbps',
  178. 'height': 480,
  179. 'tbr': 1000,
  180. }, {
  181. 'url': 'https://awscc3001.r18.com/litevideo/freepv/m/mgm/mgmr105/mgmr105_dmb_w.mp4',
  182. 'ext': 'mp4',
  183. 'format_id': '1500kbps',
  184. 'height': 740,
  185. 'tbr': 1500,
  186. }],
  187. 'thumbnail': '//pics.r18.com/digital/amateur/mgmr105/mgmr105jp.jpg'
  188. })
  189. # from https://www.csfd.cz/
  190. # with width and height
  191. expect_dict(
  192. self,
  193. self.ie._parse_html5_media_entries(
  194. 'https://www.csfd.cz/',
  195. r'''
  196. <video width="770" height="328" preload="none" controls poster="https://img.csfd.cz/files/images/film/video/preview/163/344/163344118_748d20.png?h360" >
  197. <source src="https://video.csfd.cz/files/videos/157/750/157750813/163327358_eac647.mp4" type="video/mp4" width="640" height="360">
  198. <source src="https://video.csfd.cz/files/videos/157/750/157750813/163327360_3d2646.mp4" type="video/mp4" width="1280" height="720">
  199. <source src="https://video.csfd.cz/files/videos/157/750/157750813/163327356_91f258.mp4" type="video/mp4" width="1920" height="1080">
  200. <source src="https://video.csfd.cz/files/videos/157/750/157750813/163327359_962b4a.webm" type="video/webm" width="640" height="360">
  201. <source src="https://video.csfd.cz/files/videos/157/750/157750813/163327361_6feee0.webm" type="video/webm" width="1280" height="720">
  202. <source src="https://video.csfd.cz/files/videos/157/750/157750813/163327357_8ab472.webm" type="video/webm" width="1920" height="1080">
  203. <track src="https://video.csfd.cz/files/subtitles/163/344/163344115_4c388b.srt" type="text/x-srt" kind="subtitles" srclang="cs" label="cs">
  204. </video>
  205. ''', None)[0],
  206. {
  207. 'formats': [{
  208. 'url': 'https://video.csfd.cz/files/videos/157/750/157750813/163327358_eac647.mp4',
  209. 'ext': 'mp4',
  210. 'width': 640,
  211. 'height': 360,
  212. }, {
  213. 'url': 'https://video.csfd.cz/files/videos/157/750/157750813/163327360_3d2646.mp4',
  214. 'ext': 'mp4',
  215. 'width': 1280,
  216. 'height': 720,
  217. }, {
  218. 'url': 'https://video.csfd.cz/files/videos/157/750/157750813/163327356_91f258.mp4',
  219. 'ext': 'mp4',
  220. 'width': 1920,
  221. 'height': 1080,
  222. }, {
  223. 'url': 'https://video.csfd.cz/files/videos/157/750/157750813/163327359_962b4a.webm',
  224. 'ext': 'webm',
  225. 'width': 640,
  226. 'height': 360,
  227. }, {
  228. 'url': 'https://video.csfd.cz/files/videos/157/750/157750813/163327361_6feee0.webm',
  229. 'ext': 'webm',
  230. 'width': 1280,
  231. 'height': 720,
  232. }, {
  233. 'url': 'https://video.csfd.cz/files/videos/157/750/157750813/163327357_8ab472.webm',
  234. 'ext': 'webm',
  235. 'width': 1920,
  236. 'height': 1080,
  237. }],
  238. 'subtitles': {
  239. 'cs': [{'url': 'https://video.csfd.cz/files/subtitles/163/344/163344115_4c388b.srt'}]
  240. },
  241. 'thumbnail': 'https://img.csfd.cz/files/images/film/video/preview/163/344/163344118_748d20.png?h360'
  242. })
  243. # from https://tamasha.com/v/Kkdjw
  244. # with height in label
  245. expect_dict(
  246. self,
  247. self.ie._parse_html5_media_entries(
  248. 'https://tamasha.com/v/Kkdjw',
  249. r'''
  250. <video crossorigin="anonymous">
  251. <source src="https://s-v2.tamasha.com/statics/videos_file/19/8f/Kkdjw_198feff8577d0057536e905cce1fb61438dd64e0_n_240.mp4" type="video/mp4" label="AUTO" res="0"/>
  252. <source src="https://s-v2.tamasha.com/statics/videos_file/19/8f/Kkdjw_198feff8577d0057536e905cce1fb61438dd64e0_n_240.mp4" type="video/mp4"
  253. label="240p" res="240"/>
  254. <source src="https://s-v2.tamasha.com/statics/videos_file/20/00/Kkdjw_200041c66f657fc967db464d156eafbc1ed9fe6f_n_144.mp4" type="video/mp4"
  255. label="144p" res="144"/>
  256. </video>
  257. ''', None)[0],
  258. {
  259. 'formats': [{
  260. 'url': 'https://s-v2.tamasha.com/statics/videos_file/19/8f/Kkdjw_198feff8577d0057536e905cce1fb61438dd64e0_n_240.mp4',
  261. }, {
  262. 'url': 'https://s-v2.tamasha.com/statics/videos_file/19/8f/Kkdjw_198feff8577d0057536e905cce1fb61438dd64e0_n_240.mp4',
  263. 'ext': 'mp4',
  264. 'format_id': '240p',
  265. 'height': 240,
  266. }, {
  267. 'url': 'https://s-v2.tamasha.com/statics/videos_file/20/00/Kkdjw_200041c66f657fc967db464d156eafbc1ed9fe6f_n_144.mp4',
  268. 'ext': 'mp4',
  269. 'format_id': '144p',
  270. 'height': 144,
  271. }]
  272. })
  273. # from https://www.directvnow.com
  274. # with data-src
  275. expect_dict(
  276. self,
  277. self.ie._parse_html5_media_entries(
  278. 'https://www.directvnow.com',
  279. r'''
  280. <video id="vid1" class="header--video-masked active" muted playsinline>
  281. <source data-src="https://cdn.directv.com/content/dam/dtv/prod/website_directvnow-international/videos/DTVN_hdr_HBO_v3.mp4" type="video/mp4" />
  282. </video>
  283. ''', None)[0],
  284. {
  285. 'formats': [{
  286. 'ext': 'mp4',
  287. 'url': 'https://cdn.directv.com/content/dam/dtv/prod/website_directvnow-international/videos/DTVN_hdr_HBO_v3.mp4',
  288. }]
  289. })
  290. # from https://www.directvnow.com
  291. # with data-src
  292. expect_dict(
  293. self,
  294. self.ie._parse_html5_media_entries(
  295. 'https://www.directvnow.com',
  296. r'''
  297. <video id="vid1" class="header--video-masked active" muted playsinline>
  298. <source data-src="https://cdn.directv.com/content/dam/dtv/prod/website_directvnow-international/videos/DTVN_hdr_HBO_v3.mp4" type="video/mp4" />
  299. </video>
  300. ''', None)[0],
  301. {
  302. 'formats': [{
  303. 'url': 'https://cdn.directv.com/content/dam/dtv/prod/website_directvnow-international/videos/DTVN_hdr_HBO_v3.mp4',
  304. 'ext': 'mp4',
  305. }]
  306. })
  307. # from https://www.klarna.com/uk/
  308. # with data-video-src
  309. expect_dict(
  310. self,
  311. self.ie._parse_html5_media_entries(
  312. 'https://www.directvnow.com',
  313. r'''
  314. <video loop autoplay muted class="responsive-video block-kl__video video-on-medium">
  315. <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" />
  316. </video>
  317. ''', None)[0],
  318. {
  319. 'formats': [{
  320. 'url': 'https://www.klarna.com/uk/wp-content/uploads/sites/11/2019/01/KL062_Smooth3_0_DogWalking_5s_920x080_.mp4',
  321. 'ext': 'mp4',
  322. }],
  323. })
  324. def test_extract_jwplayer_data_realworld(self):
  325. # from http://www.suffolk.edu/sjc/
  326. expect_dict(
  327. self,
  328. self.ie._extract_jwplayer_data(r'''
  329. <script type='text/javascript'>
  330. jwplayer('my-video').setup({
  331. file: 'rtmp://192.138.214.154/live/sjclive',
  332. fallback: 'true',
  333. width: '95%',
  334. aspectratio: '16:9',
  335. primary: 'flash',
  336. mediaid:'XEgvuql4'
  337. });
  338. </script>
  339. ''', None, require_title=False),
  340. {
  341. 'id': 'XEgvuql4',
  342. 'formats': [{
  343. 'url': 'rtmp://192.138.214.154/live/sjclive',
  344. 'ext': 'flv'
  345. }]
  346. })
  347. # from https://www.pornoxo.com/videos/7564/striptease-from-sexy-secretary/
  348. expect_dict(
  349. self,
  350. self.ie._extract_jwplayer_data(r'''
  351. <script type="text/javascript">
  352. jwplayer("mediaplayer").setup({
  353. 'videoid': "7564",
  354. 'width': "100%",
  355. 'aspectratio': "16:9",
  356. 'stretching': "exactfit",
  357. 'autostart': 'false',
  358. 'flashplayer': "https://t04.vipstreamservice.com/jwplayer/v5.10/player.swf",
  359. '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",
  360. 'image': "https://t03.vipstreamservice.com/thumbs/pxo-full/2009-12/14/a4b2157147afe5efa93ce1978e0265289c193874e02597.flv-full-13.jpg",
  361. '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",
  362. 'logo.hide': true,
  363. 'skin': "https://t04.vipstreamservice.com/jwplayer/skin/modieus-blk.zip",
  364. 'plugins': "https://t04.vipstreamservice.com/jwplayer/dock/dockableskinnableplugin.swf",
  365. 'dockableskinnableplugin.piclink': "/index.php?key=ajax-videothumbsn&vid=7564&data=2009-12--14--4b2157147afe5efa93ce1978e0265289c193874e02597.flv--17370",
  366. 'controlbar': 'bottom',
  367. 'modes': [
  368. {type: 'flash', src: 'https://t04.vipstreamservice.com/jwplayer/v5.10/player.swf'}
  369. ],
  370. 'provider': 'http'
  371. });
  372. //noinspection JSAnnotator
  373. invideo.setup({
  374. adsUrl: "/banner-iframe/?zoneId=32",
  375. adsUrl2: "",
  376. autostart: false
  377. });
  378. </script>
  379. ''', 'dummy', require_title=False),
  380. {
  381. 'thumbnail': 'https://t03.vipstreamservice.com/thumbs/pxo-full/2009-12/14/a4b2157147afe5efa93ce1978e0265289c193874e02597.flv-full-13.jpg',
  382. 'formats': [{
  383. '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',
  384. 'ext': 'flv'
  385. }]
  386. })
  387. # from http://www.indiedb.com/games/king-machine/videos
  388. expect_dict(
  389. self,
  390. self.ie._extract_jwplayer_data(r'''
  391. <script>
  392. 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) {
  393. videoAnalytics("play");
  394. }).once("complete", function(event) {
  395. videoAnalytics("completed");
  396. });
  397. </script>
  398. ''', 'dummy'),
  399. {
  400. 'title': 'king machine trailer 1',
  401. 'thumbnail': 'http://media.indiedb.com/cache/images/games/1/50/49678/thumb_620x2000/king-machine-trailer.mp4.jpg',
  402. 'formats': [{
  403. 'url': 'http://cdn.dbolical.com/cache/videos/games/1/50/49678/encode_mp4/king-machine-trailer.mp4',
  404. 'height': 360,
  405. 'ext': 'mp4'
  406. }, {
  407. 'url': 'http://cdn.dbolical.com/cache/videos/games/1/50/49678/encode720p_mp4/king-machine-trailer.mp4',
  408. 'height': 720,
  409. 'ext': 'mp4'
  410. }]
  411. })
  412. def test_parse_m3u8_formats(self):
  413. _TEST_CASES = [
  414. (
  415. # https://github.com/ytdl-org/youtube-dl/issues/11507
  416. # http://pluzz.francetv.fr/videos/le_ministere.html
  417. 'pluzz_francetv_11507',
  418. 'http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/master.m3u8?caption=2017%2F16%2F156589847-1492488987.m3u8%3Afra%3AFrancais&audiotrack=0%3Afra%3AFrancais',
  419. [{
  420. 'url': 'http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/index_0_av.m3u8?null=0',
  421. 'manifest_url': 'http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/master.m3u8?caption=2017%2F16%2F156589847-1492488987.m3u8%3Afra%3AFrancais&audiotrack=0%3Afra%3AFrancais',
  422. 'ext': 'mp4',
  423. 'format_id': '180',
  424. 'protocol': 'm3u8',
  425. 'acodec': 'mp4a.40.2',
  426. 'vcodec': 'avc1.66.30',
  427. 'tbr': 180,
  428. 'width': 256,
  429. 'height': 144,
  430. }, {
  431. 'url': 'http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/index_1_av.m3u8?null=0',
  432. 'manifest_url': 'http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/master.m3u8?caption=2017%2F16%2F156589847-1492488987.m3u8%3Afra%3AFrancais&audiotrack=0%3Afra%3AFrancais',
  433. 'ext': 'mp4',
  434. 'format_id': '303',
  435. 'protocol': 'm3u8',
  436. 'acodec': 'mp4a.40.2',
  437. 'vcodec': 'avc1.66.30',
  438. 'tbr': 303,
  439. 'width': 320,
  440. 'height': 180,
  441. }, {
  442. 'url': 'http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/index_2_av.m3u8?null=0',
  443. 'manifest_url': 'http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/master.m3u8?caption=2017%2F16%2F156589847-1492488987.m3u8%3Afra%3AFrancais&audiotrack=0%3Afra%3AFrancais',
  444. 'ext': 'mp4',
  445. 'format_id': '575',
  446. 'protocol': 'm3u8',
  447. 'acodec': 'mp4a.40.2',
  448. 'vcodec': 'avc1.66.30',
  449. 'tbr': 575,
  450. 'width': 512,
  451. 'height': 288,
  452. }, {
  453. 'url': 'http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/index_3_av.m3u8?null=0',
  454. 'manifest_url': 'http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/master.m3u8?caption=2017%2F16%2F156589847-1492488987.m3u8%3Afra%3AFrancais&audiotrack=0%3Afra%3AFrancais',
  455. 'ext': 'mp4',
  456. 'format_id': '831',
  457. 'protocol': 'm3u8',
  458. 'acodec': 'mp4a.40.2',
  459. 'vcodec': 'avc1.77.30',
  460. 'tbr': 831,
  461. 'width': 704,
  462. 'height': 396,
  463. }, {
  464. 'url': 'http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/index_4_av.m3u8?null=0',
  465. 'manifest_url': 'http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/master.m3u8?caption=2017%2F16%2F156589847-1492488987.m3u8%3Afra%3AFrancais&audiotrack=0%3Afra%3AFrancais',
  466. 'ext': 'mp4',
  467. 'protocol': 'm3u8',
  468. 'format_id': '1467',
  469. 'acodec': 'mp4a.40.2',
  470. 'vcodec': 'avc1.77.30',
  471. 'tbr': 1467,
  472. 'width': 1024,
  473. 'height': 576,
  474. }]
  475. ),
  476. (
  477. # https://github.com/ytdl-org/youtube-dl/issues/11995
  478. # http://teamcoco.com/video/clueless-gamer-super-bowl-for-honor
  479. 'teamcoco_11995',
  480. 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/main.m3u8',
  481. [{
  482. 'url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/hls/CONAN_020217_Highlight_show-audio-160k_v4.m3u8',
  483. 'manifest_url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/main.m3u8',
  484. 'ext': 'mp4',
  485. 'format_id': 'audio-0-Default',
  486. 'protocol': 'm3u8',
  487. 'vcodec': 'none',
  488. }, {
  489. 'url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/hls/CONAN_020217_Highlight_show-audio-64k_v4.m3u8',
  490. 'manifest_url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/main.m3u8',
  491. 'ext': 'mp4',
  492. 'format_id': 'audio-1-Default',
  493. 'protocol': 'm3u8',
  494. 'vcodec': 'none',
  495. }, {
  496. 'url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/hls/CONAN_020217_Highlight_show-audio-64k_v4.m3u8',
  497. 'manifest_url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/main.m3u8',
  498. 'ext': 'mp4',
  499. 'format_id': '71',
  500. 'protocol': 'm3u8',
  501. 'acodec': 'mp4a.40.5',
  502. 'vcodec': 'none',
  503. 'tbr': 71,
  504. }, {
  505. 'url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/hls/CONAN_020217_Highlight_show-400k_v4.m3u8',
  506. 'manifest_url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/main.m3u8',
  507. 'ext': 'mp4',
  508. 'format_id': '413',
  509. 'protocol': 'm3u8',
  510. 'acodec': 'none',
  511. 'vcodec': 'avc1.42001e',
  512. 'tbr': 413,
  513. 'width': 400,
  514. 'height': 224,
  515. }, {
  516. 'url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/hls/CONAN_020217_Highlight_show-400k_v4.m3u8',
  517. 'manifest_url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/main.m3u8',
  518. 'ext': 'mp4',
  519. 'format_id': '522',
  520. 'protocol': 'm3u8',
  521. 'acodec': 'none',
  522. 'vcodec': 'avc1.42001e',
  523. 'tbr': 522,
  524. 'width': 400,
  525. 'height': 224,
  526. }, {
  527. 'url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/hls/CONAN_020217_Highlight_show-1m_v4.m3u8',
  528. 'manifest_url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/main.m3u8',
  529. 'ext': 'mp4',
  530. 'format_id': '1205',
  531. 'protocol': 'm3u8',
  532. 'acodec': 'none',
  533. 'vcodec': 'avc1.4d001e',
  534. 'tbr': 1205,
  535. 'width': 640,
  536. 'height': 360,
  537. }, {
  538. 'url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/hls/CONAN_020217_Highlight_show-2m_v4.m3u8',
  539. 'manifest_url': 'http://ak.storage-w.teamcococdn.com/cdn/2017-02/98599/ed8f/main.m3u8',
  540. 'ext': 'mp4',
  541. 'format_id': '2374',
  542. 'protocol': 'm3u8',
  543. 'acodec': 'none',
  544. 'vcodec': 'avc1.4d001f',
  545. 'tbr': 2374,
  546. 'width': 1024,
  547. 'height': 576,
  548. }]
  549. ),
  550. (
  551. # https://github.com/ytdl-org/youtube-dl/issues/12211
  552. # http://video.toggle.sg/en/series/whoopie-s-world/ep3/478601
  553. 'toggle_mobile_12211',
  554. 'http://cdnapi.kaltura.com/p/2082311/sp/208231100/playManifest/protocol/http/entryId/0_89q6e8ku/format/applehttp/tags/mobile_sd/f/a.m3u8',
  555. [{
  556. 'url': 'http://k.toggle.sg/fhls/p/2082311/sp/208231100/serveFlavor/entryId/0_89q6e8ku/v/2/pv/1/flavorId/0_sa2ntrdg/name/a.mp4/index.m3u8',
  557. 'manifest_url': 'http://cdnapi.kaltura.com/p/2082311/sp/208231100/playManifest/protocol/http/entryId/0_89q6e8ku/format/applehttp/tags/mobile_sd/f/a.m3u8',
  558. 'ext': 'mp4',
  559. 'format_id': 'audio-English',
  560. 'protocol': 'm3u8',
  561. 'language': 'eng',
  562. 'vcodec': 'none',
  563. }, {
  564. 'url': 'http://k.toggle.sg/fhls/p/2082311/sp/208231100/serveFlavor/entryId/0_89q6e8ku/v/2/pv/1/flavorId/0_r7y0nitg/name/a.mp4/index.m3u8',
  565. 'manifest_url': 'http://cdnapi.kaltura.com/p/2082311/sp/208231100/playManifest/protocol/http/entryId/0_89q6e8ku/format/applehttp/tags/mobile_sd/f/a.m3u8',
  566. 'ext': 'mp4',
  567. 'format_id': 'audio-Undefined',
  568. 'protocol': 'm3u8',
  569. 'language': 'und',
  570. 'vcodec': 'none',
  571. }, {
  572. 'url': 'http://k.toggle.sg/fhls/p/2082311/sp/208231100/serveFlavor/entryId/0_89q6e8ku/v/2/pv/1/flavorId/0_qlk9hlzr/name/a.mp4/index.m3u8',
  573. 'manifest_url': 'http://cdnapi.kaltura.com/p/2082311/sp/208231100/playManifest/protocol/http/entryId/0_89q6e8ku/format/applehttp/tags/mobile_sd/f/a.m3u8',
  574. 'ext': 'mp4',
  575. 'format_id': '155',
  576. 'protocol': 'm3u8',
  577. 'tbr': 155.648,
  578. 'width': 320,
  579. 'height': 180,
  580. }, {
  581. 'url': 'http://k.toggle.sg/fhls/p/2082311/sp/208231100/serveFlavor/entryId/0_89q6e8ku/v/2/pv/1/flavorId/0_oefackmi/name/a.mp4/index.m3u8',
  582. 'manifest_url': 'http://cdnapi.kaltura.com/p/2082311/sp/208231100/playManifest/protocol/http/entryId/0_89q6e8ku/format/applehttp/tags/mobile_sd/f/a.m3u8',
  583. 'ext': 'mp4',
  584. 'format_id': '502',
  585. 'protocol': 'm3u8',
  586. 'tbr': 502.784,
  587. 'width': 480,
  588. 'height': 270,
  589. }, {
  590. 'url': 'http://k.toggle.sg/fhls/p/2082311/sp/208231100/serveFlavor/entryId/0_89q6e8ku/v/12/pv/1/flavorId/0_vyg9pj7k/name/a.mp4/index.m3u8',
  591. 'manifest_url': 'http://cdnapi.kaltura.com/p/2082311/sp/208231100/playManifest/protocol/http/entryId/0_89q6e8ku/format/applehttp/tags/mobile_sd/f/a.m3u8',
  592. 'ext': 'mp4',
  593. 'format_id': '827',
  594. 'protocol': 'm3u8',
  595. 'tbr': 827.392,
  596. 'width': 640,
  597. 'height': 360,
  598. }, {
  599. 'url': 'http://k.toggle.sg/fhls/p/2082311/sp/208231100/serveFlavor/entryId/0_89q6e8ku/v/12/pv/1/flavorId/0_50n4psvx/name/a.mp4/index.m3u8',
  600. 'manifest_url': 'http://cdnapi.kaltura.com/p/2082311/sp/208231100/playManifest/protocol/http/entryId/0_89q6e8ku/format/applehttp/tags/mobile_sd/f/a.m3u8',
  601. 'ext': 'mp4',
  602. 'format_id': '1396',
  603. 'protocol': 'm3u8',
  604. 'tbr': 1396.736,
  605. 'width': 854,
  606. 'height': 480,
  607. }]
  608. ),
  609. (
  610. # http://www.twitch.tv/riotgames/v/6528877
  611. 'twitch_vod',
  612. 'https://usher.ttvnw.net/vod/6528877?allow_source=true&allow_audio_only=true&allow_spectre=true&player=twitchweb&nauth=%7B%22user_id%22%3Anull%2C%22vod_id%22%3A6528877%2C%22expires%22%3A1492887874%2C%22chansub%22%3A%7B%22restricted_bitrates%22%3A%5B%5D%7D%2C%22privileged%22%3Afalse%2C%22https_required%22%3Afalse%7D&nauthsig=3e29296a6824a0f48f9e731383f77a614fc79bee',
  613. [{
  614. 'url': 'https://vod.edgecast.hls.ttvnw.net/e5da31ab49_riotgames_15001215120_261543898/audio_only/index-muted-HM49I092CC.m3u8',
  615. 'manifest_url': 'https://usher.ttvnw.net/vod/6528877?allow_source=true&allow_audio_only=true&allow_spectre=true&player=twitchweb&nauth=%7B%22user_id%22%3Anull%2C%22vod_id%22%3A6528877%2C%22expires%22%3A1492887874%2C%22chansub%22%3A%7B%22restricted_bitrates%22%3A%5B%5D%7D%2C%22privileged%22%3Afalse%2C%22https_required%22%3Afalse%7D&nauthsig=3e29296a6824a0f48f9e731383f77a614fc79bee',
  616. 'ext': 'mp4',
  617. 'format_id': 'Audio Only',
  618. 'protocol': 'm3u8',
  619. 'acodec': 'mp4a.40.2',
  620. 'vcodec': 'none',
  621. 'tbr': 182.725,
  622. }, {
  623. 'url': 'https://vod.edgecast.hls.ttvnw.net/e5da31ab49_riotgames_15001215120_261543898/mobile/index-muted-HM49I092CC.m3u8',
  624. 'manifest_url': 'https://usher.ttvnw.net/vod/6528877?allow_source=true&allow_audio_only=true&allow_spectre=true&player=twitchweb&nauth=%7B%22user_id%22%3Anull%2C%22vod_id%22%3A6528877%2C%22expires%22%3A1492887874%2C%22chansub%22%3A%7B%22restricted_bitrates%22%3A%5B%5D%7D%2C%22privileged%22%3Afalse%2C%22https_required%22%3Afalse%7D&nauthsig=3e29296a6824a0f48f9e731383f77a614fc79bee',
  625. 'ext': 'mp4',
  626. 'format_id': 'Mobile',
  627. 'protocol': 'm3u8',
  628. 'acodec': 'mp4a.40.2',
  629. 'vcodec': 'avc1.42C00D',
  630. 'tbr': 280.474,
  631. 'width': 400,
  632. 'height': 226,
  633. }, {
  634. 'url': 'https://vod.edgecast.hls.ttvnw.net/e5da31ab49_riotgames_15001215120_261543898/low/index-muted-HM49I092CC.m3u8',
  635. 'manifest_url': 'https://usher.ttvnw.net/vod/6528877?allow_source=true&allow_audio_only=true&allow_spectre=true&player=twitchweb&nauth=%7B%22user_id%22%3Anull%2C%22vod_id%22%3A6528877%2C%22expires%22%3A1492887874%2C%22chansub%22%3A%7B%22restricted_bitrates%22%3A%5B%5D%7D%2C%22privileged%22%3Afalse%2C%22https_required%22%3Afalse%7D&nauthsig=3e29296a6824a0f48f9e731383f77a614fc79bee',
  636. 'ext': 'mp4',
  637. 'format_id': 'Low',
  638. 'protocol': 'm3u8',
  639. 'acodec': 'mp4a.40.2',
  640. 'vcodec': 'avc1.42C01E',
  641. 'tbr': 628.347,
  642. 'width': 640,
  643. 'height': 360,
  644. }, {
  645. 'url': 'https://vod.edgecast.hls.ttvnw.net/e5da31ab49_riotgames_15001215120_261543898/medium/index-muted-HM49I092CC.m3u8',
  646. 'manifest_url': 'https://usher.ttvnw.net/vod/6528877?allow_source=true&allow_audio_only=true&allow_spectre=true&player=twitchweb&nauth=%7B%22user_id%22%3Anull%2C%22vod_id%22%3A6528877%2C%22expires%22%3A1492887874%2C%22chansub%22%3A%7B%22restricted_bitrates%22%3A%5B%5D%7D%2C%22privileged%22%3Afalse%2C%22https_required%22%3Afalse%7D&nauthsig=3e29296a6824a0f48f9e731383f77a614fc79bee',
  647. 'ext': 'mp4',
  648. 'format_id': 'Medium',
  649. 'protocol': 'm3u8',
  650. 'acodec': 'mp4a.40.2',
  651. 'vcodec': 'avc1.42C01E',
  652. 'tbr': 893.387,
  653. 'width': 852,
  654. 'height': 480,
  655. }, {
  656. 'url': 'https://vod.edgecast.hls.ttvnw.net/e5da31ab49_riotgames_15001215120_261543898/high/index-muted-HM49I092CC.m3u8',
  657. 'manifest_url': 'https://usher.ttvnw.net/vod/6528877?allow_source=true&allow_audio_only=true&allow_spectre=true&player=twitchweb&nauth=%7B%22user_id%22%3Anull%2C%22vod_id%22%3A6528877%2C%22expires%22%3A1492887874%2C%22chansub%22%3A%7B%22restricted_bitrates%22%3A%5B%5D%7D%2C%22privileged%22%3Afalse%2C%22https_required%22%3Afalse%7D&nauthsig=3e29296a6824a0f48f9e731383f77a614fc79bee',
  658. 'ext': 'mp4',
  659. 'format_id': 'High',
  660. 'protocol': 'm3u8',
  661. 'acodec': 'mp4a.40.2',
  662. 'vcodec': 'avc1.42C01F',
  663. 'tbr': 1603.789,
  664. 'width': 1280,
  665. 'height': 720,
  666. }, {
  667. 'url': 'https://vod.edgecast.hls.ttvnw.net/e5da31ab49_riotgames_15001215120_261543898/chunked/index-muted-HM49I092CC.m3u8',
  668. 'manifest_url': 'https://usher.ttvnw.net/vod/6528877?allow_source=true&allow_audio_only=true&allow_spectre=true&player=twitchweb&nauth=%7B%22user_id%22%3Anull%2C%22vod_id%22%3A6528877%2C%22expires%22%3A1492887874%2C%22chansub%22%3A%7B%22restricted_bitrates%22%3A%5B%5D%7D%2C%22privileged%22%3Afalse%2C%22https_required%22%3Afalse%7D&nauthsig=3e29296a6824a0f48f9e731383f77a614fc79bee',
  669. 'ext': 'mp4',
  670. 'format_id': 'Source',
  671. 'protocol': 'm3u8',
  672. 'acodec': 'mp4a.40.2',
  673. 'vcodec': 'avc1.100.31',
  674. 'tbr': 3214.134,
  675. 'width': 1280,
  676. 'height': 720,
  677. }]
  678. ),
  679. (
  680. # http://www.vidio.com/watch/165683-dj_ambred-booyah-live-2015
  681. # EXT-X-STREAM-INF tag with NAME attribute that is not defined
  682. # in HLS specification
  683. 'vidio',
  684. 'https://www.vidio.com/videos/165683/playlist.m3u8',
  685. [{
  686. 'url': 'https://cdn1-a.production.vidio.static6.com/uploads/165683/dj_ambred-4383-b300.mp4.m3u8',
  687. 'manifest_url': 'https://www.vidio.com/videos/165683/playlist.m3u8',
  688. 'ext': 'mp4',
  689. 'format_id': '270p 3G',
  690. 'protocol': 'm3u8',
  691. 'tbr': 300,
  692. 'width': 480,
  693. 'height': 270,
  694. }, {
  695. 'url': 'https://cdn1-a.production.vidio.static6.com/uploads/165683/dj_ambred-4383-b600.mp4.m3u8',
  696. 'manifest_url': 'https://www.vidio.com/videos/165683/playlist.m3u8',
  697. 'ext': 'mp4',
  698. 'format_id': '360p SD',
  699. 'protocol': 'm3u8',
  700. 'tbr': 600,
  701. 'width': 640,
  702. 'height': 360,
  703. }, {
  704. 'url': 'https://cdn1-a.production.vidio.static6.com/uploads/165683/dj_ambred-4383-b1200.mp4.m3u8',
  705. 'manifest_url': 'https://www.vidio.com/videos/165683/playlist.m3u8',
  706. 'ext': 'mp4',
  707. 'format_id': '720p HD',
  708. 'protocol': 'm3u8',
  709. 'tbr': 1200,
  710. 'width': 1280,
  711. 'height': 720,
  712. }]
  713. ),
  714. (
  715. # https://github.com/ytdl-org/youtube-dl/issues/18923
  716. # https://www.ted.com/talks/boris_hesser_a_grassroots_healthcare_revolution_in_africa
  717. 'ted_18923',
  718. 'http://hls.ted.com/talks/31241.m3u8',
  719. [{
  720. 'url': 'http://hls.ted.com/videos/BorisHesser_2018S/audio/600k.m3u8?nobumpers=true&uniqueId=76011e2b',
  721. 'format_id': '600k-Audio',
  722. 'vcodec': 'none',
  723. }, {
  724. 'url': 'http://hls.ted.com/videos/BorisHesser_2018S/audio/600k.m3u8?nobumpers=true&uniqueId=76011e2b',
  725. 'format_id': '68',
  726. 'vcodec': 'none',
  727. }, {
  728. 'url': 'http://hls.ted.com/videos/BorisHesser_2018S/video/64k.m3u8?nobumpers=true&uniqueId=76011e2b',
  729. 'format_id': '163',
  730. 'acodec': 'none',
  731. 'width': 320,
  732. 'height': 180,
  733. }, {
  734. 'url': 'http://hls.ted.com/videos/BorisHesser_2018S/video/180k.m3u8?nobumpers=true&uniqueId=76011e2b',
  735. 'format_id': '481',
  736. 'acodec': 'none',
  737. 'width': 512,
  738. 'height': 288,
  739. }, {
  740. 'url': 'http://hls.ted.com/videos/BorisHesser_2018S/video/320k.m3u8?nobumpers=true&uniqueId=76011e2b',
  741. 'format_id': '769',
  742. 'acodec': 'none',
  743. 'width': 512,
  744. 'height': 288,
  745. }, {
  746. 'url': 'http://hls.ted.com/videos/BorisHesser_2018S/video/450k.m3u8?nobumpers=true&uniqueId=76011e2b',
  747. 'format_id': '984',
  748. 'acodec': 'none',
  749. 'width': 512,
  750. 'height': 288,
  751. }, {
  752. 'url': 'http://hls.ted.com/videos/BorisHesser_2018S/video/600k.m3u8?nobumpers=true&uniqueId=76011e2b',
  753. 'format_id': '1255',
  754. 'acodec': 'none',
  755. 'width': 640,
  756. 'height': 360,
  757. }, {
  758. 'url': 'http://hls.ted.com/videos/BorisHesser_2018S/video/950k.m3u8?nobumpers=true&uniqueId=76011e2b',
  759. 'format_id': '1693',
  760. 'acodec': 'none',
  761. 'width': 853,
  762. 'height': 480,
  763. }, {
  764. 'url': 'http://hls.ted.com/videos/BorisHesser_2018S/video/1500k.m3u8?nobumpers=true&uniqueId=76011e2b',
  765. 'format_id': '2462',
  766. 'acodec': 'none',
  767. 'width': 1280,
  768. 'height': 720,
  769. }]
  770. ),
  771. ]
  772. for m3u8_file, m3u8_url, expected_formats in _TEST_CASES:
  773. with io.open('./test/testdata/m3u8/%s.m3u8' % m3u8_file,
  774. mode='r', encoding='utf-8') as f:
  775. formats = self.ie._parse_m3u8_formats(
  776. f.read(), m3u8_url, ext='mp4')
  777. self.ie._sort_formats(formats)
  778. expect_value(self, formats, expected_formats, None)
  779. def test_parse_mpd_formats(self):
  780. _TEST_CASES = [
  781. (
  782. # https://github.com/ytdl-org/youtube-dl/issues/13919
  783. # Also tests duplicate representation ids, see
  784. # https://github.com/ytdl-org/youtube-dl/issues/15111
  785. 'float_duration',
  786. 'http://unknown/manifest.mpd', # mpd_url
  787. None, # mpd_base_url
  788. [{
  789. 'manifest_url': 'http://unknown/manifest.mpd',
  790. 'ext': 'm4a',
  791. 'format_id': '318597',
  792. 'format_note': 'DASH audio',
  793. 'protocol': 'http_dash_segments',
  794. 'acodec': 'mp4a.40.2',
  795. 'vcodec': 'none',
  796. 'tbr': 61.587,
  797. }, {
  798. 'manifest_url': 'http://unknown/manifest.mpd',
  799. 'ext': 'mp4',
  800. 'format_id': '318597',
  801. 'format_note': 'DASH video',
  802. 'protocol': 'http_dash_segments',
  803. 'acodec': 'none',
  804. 'vcodec': 'avc1.42001f',
  805. 'tbr': 318.597,
  806. 'width': 340,
  807. 'height': 192,
  808. }, {
  809. 'manifest_url': 'http://unknown/manifest.mpd',
  810. 'ext': 'mp4',
  811. 'format_id': '638590',
  812. 'format_note': 'DASH video',
  813. 'protocol': 'http_dash_segments',
  814. 'acodec': 'none',
  815. 'vcodec': 'avc1.42001f',
  816. 'tbr': 638.59,
  817. 'width': 512,
  818. 'height': 288,
  819. }, {
  820. 'manifest_url': 'http://unknown/manifest.mpd',
  821. 'ext': 'mp4',
  822. 'format_id': '1022565',
  823. 'format_note': 'DASH video',
  824. 'protocol': 'http_dash_segments',
  825. 'acodec': 'none',
  826. 'vcodec': 'avc1.4d001f',
  827. 'tbr': 1022.565,
  828. 'width': 688,
  829. 'height': 384,
  830. }, {
  831. 'manifest_url': 'http://unknown/manifest.mpd',
  832. 'ext': 'mp4',
  833. 'format_id': '2046506',
  834. 'format_note': 'DASH video',
  835. 'protocol': 'http_dash_segments',
  836. 'acodec': 'none',
  837. 'vcodec': 'avc1.4d001f',
  838. 'tbr': 2046.506,
  839. 'width': 1024,
  840. 'height': 576,
  841. }, {
  842. 'manifest_url': 'http://unknown/manifest.mpd',
  843. 'ext': 'mp4',
  844. 'format_id': '3998017',
  845. 'format_note': 'DASH video',
  846. 'protocol': 'http_dash_segments',
  847. 'acodec': 'none',
  848. 'vcodec': 'avc1.640029',
  849. 'tbr': 3998.017,
  850. 'width': 1280,
  851. 'height': 720,
  852. }, {
  853. 'manifest_url': 'http://unknown/manifest.mpd',
  854. 'ext': 'mp4',
  855. 'format_id': '5997485',
  856. 'format_note': 'DASH video',
  857. 'protocol': 'http_dash_segments',
  858. 'acodec': 'none',
  859. 'vcodec': 'avc1.640032',
  860. 'tbr': 5997.485,
  861. 'width': 1920,
  862. 'height': 1080,
  863. }]
  864. ), (
  865. # https://github.com/ytdl-org/youtube-dl/pull/14844
  866. 'urls_only',
  867. 'http://unknown/manifest.mpd', # mpd_url
  868. None, # mpd_base_url
  869. [{
  870. 'manifest_url': 'http://unknown/manifest.mpd',
  871. 'ext': 'mp4',
  872. 'format_id': 'h264_aac_144p_m4s',
  873. 'format_note': 'DASH video',
  874. 'protocol': 'http_dash_segments',
  875. 'acodec': 'mp4a.40.2',
  876. 'vcodec': 'avc3.42c01e',
  877. 'tbr': 200,
  878. 'width': 256,
  879. 'height': 144,
  880. }, {
  881. 'manifest_url': 'http://unknown/manifest.mpd',
  882. 'ext': 'mp4',
  883. 'format_id': 'h264_aac_240p_m4s',
  884. 'format_note': 'DASH video',
  885. 'protocol': 'http_dash_segments',
  886. 'acodec': 'mp4a.40.2',
  887. 'vcodec': 'avc3.42c01e',
  888. 'tbr': 400,
  889. 'width': 424,
  890. 'height': 240,
  891. }, {
  892. 'manifest_url': 'http://unknown/manifest.mpd',
  893. 'ext': 'mp4',
  894. 'format_id': 'h264_aac_360p_m4s',
  895. 'format_note': 'DASH video',
  896. 'protocol': 'http_dash_segments',
  897. 'acodec': 'mp4a.40.2',
  898. 'vcodec': 'avc3.42c01e',
  899. 'tbr': 800,
  900. 'width': 640,
  901. 'height': 360,
  902. }, {
  903. 'manifest_url': 'http://unknown/manifest.mpd',
  904. 'ext': 'mp4',
  905. 'format_id': 'h264_aac_480p_m4s',
  906. 'format_note': 'DASH video',
  907. 'protocol': 'http_dash_segments',
  908. 'acodec': 'mp4a.40.2',
  909. 'vcodec': 'avc3.42c01e',
  910. 'tbr': 1200,
  911. 'width': 856,
  912. 'height': 480,
  913. }, {
  914. 'manifest_url': 'http://unknown/manifest.mpd',
  915. 'ext': 'mp4',
  916. 'format_id': 'h264_aac_576p_m4s',
  917. 'format_note': 'DASH video',
  918. 'protocol': 'http_dash_segments',
  919. 'acodec': 'mp4a.40.2',
  920. 'vcodec': 'avc3.42c01e',
  921. 'tbr': 1600,
  922. 'width': 1024,
  923. 'height': 576,
  924. }, {
  925. 'manifest_url': 'http://unknown/manifest.mpd',
  926. 'ext': 'mp4',
  927. 'format_id': 'h264_aac_720p_m4s',
  928. 'format_note': 'DASH video',
  929. 'protocol': 'http_dash_segments',
  930. 'acodec': 'mp4a.40.2',
  931. 'vcodec': 'avc3.42c01e',
  932. 'tbr': 2400,
  933. 'width': 1280,
  934. 'height': 720,
  935. }, {
  936. 'manifest_url': 'http://unknown/manifest.mpd',
  937. 'ext': 'mp4',
  938. 'format_id': 'h264_aac_1080p_m4s',
  939. 'format_note': 'DASH video',
  940. 'protocol': 'http_dash_segments',
  941. 'acodec': 'mp4a.40.2',
  942. 'vcodec': 'avc3.42c01e',
  943. 'tbr': 4400,
  944. 'width': 1920,
  945. 'height': 1080,
  946. }]
  947. ), (
  948. # https://github.com/ytdl-org/youtube-dl/issues/20346
  949. # Media considered unfragmented even though it contains
  950. # Initialization tag
  951. 'unfragmented',
  952. 'https://v.redd.it/hw1x7rcg7zl21/DASHPlaylist.mpd', # mpd_url
  953. 'https://v.redd.it/hw1x7rcg7zl21', # mpd_base_url
  954. [{
  955. 'url': 'https://v.redd.it/hw1x7rcg7zl21/audio',
  956. 'manifest_url': 'https://v.redd.it/hw1x7rcg7zl21/DASHPlaylist.mpd',
  957. 'ext': 'm4a',
  958. 'format_id': 'AUDIO-1',
  959. 'format_note': 'DASH audio',
  960. 'container': 'm4a_dash',
  961. 'acodec': 'mp4a.40.2',
  962. 'vcodec': 'none',
  963. 'tbr': 129.87,
  964. 'asr': 48000,
  965. }, {
  966. 'url': 'https://v.redd.it/hw1x7rcg7zl21/DASH_240',
  967. 'manifest_url': 'https://v.redd.it/hw1x7rcg7zl21/DASHPlaylist.mpd',
  968. 'ext': 'mp4',
  969. 'format_id': 'VIDEO-2',
  970. 'format_note': 'DASH video',
  971. 'container': 'mp4_dash',
  972. 'acodec': 'none',
  973. 'vcodec': 'avc1.4d401e',
  974. 'tbr': 608.0,
  975. 'width': 240,
  976. 'height': 240,
  977. 'fps': 30,
  978. }, {
  979. 'url': 'https://v.redd.it/hw1x7rcg7zl21/DASH_360',
  980. 'manifest_url': 'https://v.redd.it/hw1x7rcg7zl21/DASHPlaylist.mpd',
  981. 'ext': 'mp4',
  982. 'format_id': 'VIDEO-1',
  983. 'format_note': 'DASH video',
  984. 'container': 'mp4_dash',
  985. 'acodec': 'none',
  986. 'vcodec': 'avc1.4d401e',
  987. 'tbr': 804.261,
  988. 'width': 360,
  989. 'height': 360,
  990. 'fps': 30,
  991. }]
  992. )
  993. ]
  994. for mpd_file, mpd_url, mpd_base_url, expected_formats in _TEST_CASES:
  995. with io.open('./test/testdata/mpd/%s.mpd' % mpd_file,
  996. mode='r', encoding='utf-8') as f:
  997. formats = self.ie._parse_mpd_formats(
  998. compat_etree_fromstring(f.read().encode('utf-8')),
  999. mpd_base_url=mpd_base_url, mpd_url=mpd_url)
  1000. self.ie._sort_formats(formats)
  1001. expect_value(self, formats, expected_formats, None)
  1002. def test_parse_f4m_formats(self):
  1003. _TEST_CASES = [
  1004. (
  1005. # https://github.com/ytdl-org/youtube-dl/issues/14660
  1006. 'custom_base_url',
  1007. 'http://api.new.livestream.com/accounts/6115179/events/6764928/videos/144884262.f4m',
  1008. [{
  1009. 'manifest_url': 'http://api.new.livestream.com/accounts/6115179/events/6764928/videos/144884262.f4m',
  1010. 'ext': 'flv',
  1011. 'format_id': '2148',
  1012. 'protocol': 'f4m',
  1013. 'tbr': 2148,
  1014. 'width': 1280,
  1015. 'height': 720,
  1016. }]
  1017. ),
  1018. ]
  1019. for f4m_file, f4m_url, expected_formats in _TEST_CASES:
  1020. with io.open('./test/testdata/f4m/%s.f4m' % f4m_file,
  1021. mode='r', encoding='utf-8') as f:
  1022. formats = self.ie._parse_f4m_formats(
  1023. compat_etree_fromstring(f.read().encode('utf-8')),
  1024. f4m_url, None)
  1025. self.ie._sort_formats(formats)
  1026. expect_value(self, formats, expected_formats, None)
  1027. def test_parse_xspf(self):
  1028. _TEST_CASES = [
  1029. (
  1030. 'foo_xspf',
  1031. 'https://example.org/src/foo_xspf.xspf',
  1032. [{
  1033. 'id': 'foo_xspf',
  1034. 'title': 'Pandemonium',
  1035. 'description': 'Visit http://bigbrother404.bandcamp.com',
  1036. 'duration': 202.416,
  1037. 'formats': [{
  1038. 'manifest_url': 'https://example.org/src/foo_xspf.xspf',
  1039. 'url': 'https://example.org/src/cd1/track%201.mp3',
  1040. }],
  1041. }, {
  1042. 'id': 'foo_xspf',
  1043. 'title': 'Final Cartridge (Nichico Twelve Remix)',
  1044. 'description': 'Visit http://bigbrother404.bandcamp.com',
  1045. 'duration': 255.857,
  1046. 'formats': [{
  1047. 'manifest_url': 'https://example.org/src/foo_xspf.xspf',
  1048. 'url': 'https://example.org/%E3%83%88%E3%83%A9%E3%83%83%E3%82%AF%E3%80%80%EF%BC%92.mp3',
  1049. }],
  1050. }, {
  1051. 'id': 'foo_xspf',
  1052. 'title': 'Rebuilding Nightingale',
  1053. 'description': 'Visit http://bigbrother404.bandcamp.com',
  1054. 'duration': 287.915,
  1055. 'formats': [{
  1056. 'manifest_url': 'https://example.org/src/foo_xspf.xspf',
  1057. 'url': 'https://example.org/src/track3.mp3',
  1058. }, {
  1059. 'manifest_url': 'https://example.org/src/foo_xspf.xspf',
  1060. 'url': 'https://example.com/track3.mp3',
  1061. }]
  1062. }]
  1063. ),
  1064. ]
  1065. for xspf_file, xspf_url, expected_entries in _TEST_CASES:
  1066. with io.open('./test/testdata/xspf/%s.xspf' % xspf_file,
  1067. mode='r', encoding='utf-8') as f:
  1068. entries = self.ie._parse_xspf(
  1069. compat_etree_fromstring(f.read().encode('utf-8')),
  1070. xspf_file, xspf_url=xspf_url, xspf_base_url=xspf_url)
  1071. expect_value(self, entries, expected_entries, None)
  1072. for i in range(len(entries)):
  1073. expect_dict(self, entries[i], expected_entries[i])
  1074. def test_response_with_expected_status_returns_content(self):
  1075. # Checks for mitigations against the effects of
  1076. # <https://bugs.python.org/issue15002> that affect Python 3.4.1+, which
  1077. # manifest as `_download_webpage`, `_download_xml`, `_download_json`,
  1078. # or the underlying `_download_webpage_handle` returning no content
  1079. # when a response matches `expected_status`.
  1080. httpd = compat_http_server.HTTPServer(
  1081. ('127.0.0.1', 0), InfoExtractorTestRequestHandler)
  1082. port = http_server_port(httpd)
  1083. server_thread = threading.Thread(target=httpd.serve_forever)
  1084. server_thread.daemon = True
  1085. server_thread.start()
  1086. (content, urlh) = self.ie._download_webpage_handle(
  1087. 'http://127.0.0.1:%d/teapot' % port, None,
  1088. expected_status=TEAPOT_RESPONSE_STATUS)
  1089. self.assertEqual(content, TEAPOT_RESPONSE_BODY)
  1090. if __name__ == '__main__':
  1091. unittest.main()