test_YoutubeDL.py 10.0 KB

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