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.

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