You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
12 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
  1. #!/usr/bin/env python
  2. from __future__ import unicode_literals
  3. # Allow direct execution
  4. import os
  5. import sys
  6. import unittest
  7. sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  8. import copy
  9. from test.helper import FakeYDL, assertRegexpMatches
  10. from youtube_dl import YoutubeDL
  11. from youtube_dl.extractor import YoutubeIE
  12. class YDL(FakeYDL):
  13. def __init__(self, *args, **kwargs):
  14. super(YDL, self).__init__(*args, **kwargs)
  15. self.downloaded_info_dicts = []
  16. self.msgs = []
  17. def process_info(self, info_dict):
  18. self.downloaded_info_dicts.append(info_dict)
  19. def to_screen(self, msg):
  20. self.msgs.append(msg)
  21. def _make_result(formats, **kwargs):
  22. res = {
  23. 'formats': formats,
  24. 'id': 'testid',
  25. 'title': 'testttitle',
  26. 'extractor': 'testex',
  27. }
  28. res.update(**kwargs)
  29. return res
  30. class TestFormatSelection(unittest.TestCase):
  31. def test_prefer_free_formats(self):
  32. # Same resolution => download webm
  33. ydl = YDL()
  34. ydl.params['prefer_free_formats'] = True
  35. formats = [
  36. {'ext': 'webm', 'height': 460, 'url': 'x'},
  37. {'ext': 'mp4', 'height': 460, 'url': 'y'},
  38. ]
  39. info_dict = _make_result(formats)
  40. yie = YoutubeIE(ydl)
  41. yie._sort_formats(info_dict['formats'])
  42. ydl.process_ie_result(info_dict)
  43. downloaded = ydl.downloaded_info_dicts[0]
  44. self.assertEqual(downloaded['ext'], 'webm')
  45. # Different resolution => download best quality (mp4)
  46. ydl = YDL()
  47. ydl.params['prefer_free_formats'] = True
  48. formats = [
  49. {'ext': 'webm', 'height': 720, 'url': 'a'},
  50. {'ext': 'mp4', 'height': 1080, 'url': 'b'},
  51. ]
  52. info_dict['formats'] = formats
  53. yie = YoutubeIE(ydl)
  54. yie._sort_formats(info_dict['formats'])
  55. ydl.process_ie_result(info_dict)
  56. downloaded = ydl.downloaded_info_dicts[0]
  57. self.assertEqual(downloaded['ext'], 'mp4')
  58. # No prefer_free_formats => prefer mp4 and flv for greater compatibility
  59. ydl = YDL()
  60. ydl.params['prefer_free_formats'] = False
  61. formats = [
  62. {'ext': 'webm', 'height': 720, 'url': '_'},
  63. {'ext': 'mp4', 'height': 720, 'url': '_'},
  64. {'ext': 'flv', 'height': 720, 'url': '_'},
  65. ]
  66. info_dict['formats'] = formats
  67. yie = YoutubeIE(ydl)
  68. yie._sort_formats(info_dict['formats'])
  69. ydl.process_ie_result(info_dict)
  70. downloaded = ydl.downloaded_info_dicts[0]
  71. self.assertEqual(downloaded['ext'], 'mp4')
  72. ydl = YDL()
  73. ydl.params['prefer_free_formats'] = False
  74. formats = [
  75. {'ext': 'flv', 'height': 720, 'url': '_'},
  76. {'ext': 'webm', 'height': 720, 'url': '_'},
  77. ]
  78. info_dict['formats'] = formats
  79. yie = YoutubeIE(ydl)
  80. yie._sort_formats(info_dict['formats'])
  81. ydl.process_ie_result(info_dict)
  82. downloaded = ydl.downloaded_info_dicts[0]
  83. self.assertEqual(downloaded['ext'], 'flv')
  84. def test_format_limit(self):
  85. formats = [
  86. {'format_id': 'meh', 'url': 'http://example.com/meh', 'preference': 1},
  87. {'format_id': 'good', 'url': 'http://example.com/good', 'preference': 2},
  88. {'format_id': 'great', 'url': 'http://example.com/great', 'preference': 3},
  89. {'format_id': 'excellent', 'url': 'http://example.com/exc', 'preference': 4},
  90. ]
  91. info_dict = _make_result(formats)
  92. ydl = YDL()
  93. ydl.process_ie_result(info_dict)
  94. downloaded = ydl.downloaded_info_dicts[0]
  95. self.assertEqual(downloaded['format_id'], 'excellent')
  96. ydl = YDL({'format_limit': 'good'})
  97. assert ydl.params['format_limit'] == 'good'
  98. ydl.process_ie_result(info_dict.copy())
  99. downloaded = ydl.downloaded_info_dicts[0]
  100. self.assertEqual(downloaded['format_id'], 'good')
  101. ydl = YDL({'format_limit': 'great', 'format': 'all'})
  102. ydl.process_ie_result(info_dict.copy())
  103. self.assertEqual(ydl.downloaded_info_dicts[0]['format_id'], 'meh')
  104. self.assertEqual(ydl.downloaded_info_dicts[1]['format_id'], 'good')
  105. self.assertEqual(ydl.downloaded_info_dicts[2]['format_id'], 'great')
  106. self.assertTrue('3' in ydl.msgs[0])
  107. ydl = YDL()
  108. ydl.params['format_limit'] = 'excellent'
  109. ydl.process_ie_result(info_dict.copy())
  110. downloaded = ydl.downloaded_info_dicts[0]
  111. self.assertEqual(downloaded['format_id'], 'excellent')
  112. def test_format_selection(self):
  113. formats = [
  114. {'format_id': '35', 'ext': 'mp4', 'preference': 1, 'url': '_'},
  115. {'format_id': '45', 'ext': 'webm', 'preference': 2, 'url': '_'},
  116. {'format_id': '47', 'ext': 'webm', 'preference': 3, 'url': '_'},
  117. {'format_id': '2', 'ext': 'flv', 'preference': 4, 'url': '_'},
  118. ]
  119. info_dict = _make_result(formats)
  120. ydl = YDL({'format': '20/47'})
  121. ydl.process_ie_result(info_dict.copy())
  122. downloaded = ydl.downloaded_info_dicts[0]
  123. self.assertEqual(downloaded['format_id'], '47')
  124. ydl = YDL({'format': '20/71/worst'})
  125. ydl.process_ie_result(info_dict.copy())
  126. downloaded = ydl.downloaded_info_dicts[0]
  127. self.assertEqual(downloaded['format_id'], '35')
  128. ydl = YDL()
  129. ydl.process_ie_result(info_dict.copy())
  130. downloaded = ydl.downloaded_info_dicts[0]
  131. self.assertEqual(downloaded['format_id'], '2')
  132. ydl = YDL({'format': 'webm/mp4'})
  133. ydl.process_ie_result(info_dict.copy())
  134. downloaded = ydl.downloaded_info_dicts[0]
  135. self.assertEqual(downloaded['format_id'], '47')
  136. ydl = YDL({'format': '3gp/40/mp4'})
  137. ydl.process_ie_result(info_dict.copy())
  138. downloaded = ydl.downloaded_info_dicts[0]
  139. self.assertEqual(downloaded['format_id'], '35')
  140. def test_format_selection_audio(self):
  141. formats = [
  142. {'format_id': 'audio-low', 'ext': 'webm', 'preference': 1, 'vcodec': 'none', 'url': '_'},
  143. {'format_id': 'audio-mid', 'ext': 'webm', 'preference': 2, 'vcodec': 'none', 'url': '_'},
  144. {'format_id': 'audio-high', 'ext': 'flv', 'preference': 3, 'vcodec': 'none', 'url': '_'},
  145. {'format_id': 'vid', 'ext': 'mp4', 'preference': 4, 'url': '_'},
  146. ]
  147. info_dict = _make_result(formats)
  148. ydl = YDL({'format': 'bestaudio'})
  149. ydl.process_ie_result(info_dict.copy())
  150. downloaded = ydl.downloaded_info_dicts[0]
  151. self.assertEqual(downloaded['format_id'], 'audio-high')
  152. ydl = YDL({'format': 'worstaudio'})
  153. ydl.process_ie_result(info_dict.copy())
  154. downloaded = ydl.downloaded_info_dicts[0]
  155. self.assertEqual(downloaded['format_id'], 'audio-low')
  156. formats = [
  157. {'format_id': 'vid-low', 'ext': 'mp4', 'preference': 1, 'url': '_'},
  158. {'format_id': 'vid-high', 'ext': 'mp4', 'preference': 2, 'url': '_'},
  159. ]
  160. info_dict = _make_result(formats)
  161. ydl = YDL({'format': 'bestaudio/worstaudio/best'})
  162. ydl.process_ie_result(info_dict.copy())
  163. downloaded = ydl.downloaded_info_dicts[0]
  164. self.assertEqual(downloaded['format_id'], 'vid-high')
  165. def test_format_selection_audio_exts(self):
  166. formats = [
  167. {'format_id': 'mp3-64', 'ext': 'mp3', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
  168. {'format_id': 'ogg-64', 'ext': 'ogg', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
  169. {'format_id': 'aac-64', 'ext': 'aac', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
  170. {'format_id': 'mp3-32', 'ext': 'mp3', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'},
  171. {'format_id': 'aac-32', 'ext': 'aac', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'},
  172. ]
  173. info_dict = _make_result(formats)
  174. ydl = YDL({'format': 'best'})
  175. ie = YoutubeIE(ydl)
  176. ie._sort_formats(info_dict['formats'])
  177. ydl.process_ie_result(copy.deepcopy(info_dict))
  178. downloaded = ydl.downloaded_info_dicts[0]
  179. self.assertEqual(downloaded['format_id'], 'aac-64')
  180. ydl = YDL({'format': 'mp3'})
  181. ie = YoutubeIE(ydl)
  182. ie._sort_formats(info_dict['formats'])
  183. ydl.process_ie_result(copy.deepcopy(info_dict))
  184. downloaded = ydl.downloaded_info_dicts[0]
  185. self.assertEqual(downloaded['format_id'], 'mp3-64')
  186. ydl = YDL({'prefer_free_formats': True})
  187. ie = YoutubeIE(ydl)
  188. ie._sort_formats(info_dict['formats'])
  189. ydl.process_ie_result(copy.deepcopy(info_dict))
  190. downloaded = ydl.downloaded_info_dicts[0]
  191. self.assertEqual(downloaded['format_id'], 'ogg-64')
  192. def test_format_selection_video(self):
  193. formats = [
  194. {'format_id': 'dash-video-low', 'ext': 'mp4', 'preference': 1, 'acodec': 'none', 'url': '_'},
  195. {'format_id': 'dash-video-high', 'ext': 'mp4', 'preference': 2, 'acodec': 'none', 'url': '_'},
  196. {'format_id': 'vid', 'ext': 'mp4', 'preference': 3, 'url': '_'},
  197. ]
  198. info_dict = _make_result(formats)
  199. ydl = YDL({'format': 'bestvideo'})
  200. ydl.process_ie_result(info_dict.copy())
  201. downloaded = ydl.downloaded_info_dicts[0]
  202. self.assertEqual(downloaded['format_id'], 'dash-video-high')
  203. ydl = YDL({'format': 'worstvideo'})
  204. ydl.process_ie_result(info_dict.copy())
  205. downloaded = ydl.downloaded_info_dicts[0]
  206. self.assertEqual(downloaded['format_id'], 'dash-video-low')
  207. def test_youtube_format_selection(self):
  208. order = [
  209. '38', '37', '46', '22', '45', '35', '44', '18', '34', '43', '6', '5', '36', '17', '13',
  210. # Apple HTTP Live Streaming
  211. '96', '95', '94', '93', '92', '132', '151',
  212. # 3D
  213. '85', '84', '102', '83', '101', '82', '100',
  214. # Dash video
  215. '137', '248', '136', '247', '135', '246',
  216. '245', '244', '134', '243', '133', '242', '160',
  217. # Dash audio
  218. '141', '172', '140', '171', '139',
  219. ]
  220. for f1id, f2id in zip(order, order[1:]):
  221. f1 = YoutubeIE._formats[f1id].copy()
  222. f1['format_id'] = f1id
  223. f1['url'] = 'url:' + f1id
  224. f2 = YoutubeIE._formats[f2id].copy()
  225. f2['format_id'] = f2id
  226. f2['url'] = 'url:' + f2id
  227. info_dict = _make_result([f1, f2], extractor='youtube')
  228. ydl = YDL()
  229. yie = YoutubeIE(ydl)
  230. yie._sort_formats(info_dict['formats'])
  231. ydl.process_ie_result(info_dict)
  232. downloaded = ydl.downloaded_info_dicts[0]
  233. self.assertEqual(downloaded['format_id'], f1id)
  234. info_dict = _make_result([f2, f1], extractor='youtube')
  235. ydl = YDL()
  236. yie = YoutubeIE(ydl)
  237. yie._sort_formats(info_dict['formats'])
  238. ydl.process_ie_result(info_dict)
  239. downloaded = ydl.downloaded_info_dicts[0]
  240. self.assertEqual(downloaded['format_id'], f1id)
  241. def test_add_extra_info(self):
  242. test_dict = {
  243. 'extractor': 'Foo',
  244. }
  245. extra_info = {
  246. 'extractor': 'Bar',
  247. 'playlist': 'funny videos',
  248. }
  249. YDL.add_extra_info(test_dict, extra_info)
  250. self.assertEqual(test_dict['extractor'], 'Foo')
  251. self.assertEqual(test_dict['playlist'], 'funny videos')
  252. def test_prepare_filename(self):
  253. info = {
  254. 'id': '1234',
  255. 'ext': 'mp4',
  256. 'width': None,
  257. }
  258. def fname(templ):
  259. ydl = YoutubeDL({'outtmpl': templ})
  260. return ydl.prepare_filename(info)
  261. self.assertEqual(fname('%(id)s.%(ext)s'), '1234.mp4')
  262. self.assertEqual(fname('%(id)s-%(width)s.%(ext)s'), '1234-NA.mp4')
  263. # Replace missing fields with 'NA'
  264. self.assertEqual(fname('%(uploader_date)s-%(id)s.%(ext)s'), 'NA-1234.mp4')
  265. def test_format_note(self):
  266. ydl = YoutubeDL()
  267. self.assertEqual(ydl._format_note({}), '')
  268. assertRegexpMatches(self, ydl._format_note({
  269. 'vbr': 10,
  270. }), '^\s*10k$')
  271. if __name__ == '__main__':
  272. unittest.main()