]>
Raphaƫl G. Git Repositories - youtubedl/blob - test/test_YoutubeDL.py
3 from __future__
import unicode_literals
5 # Allow direct execution
9 sys
.path
.insert(0, os
.path
.dirname(os
.path
.dirname(os
.path
.abspath(__file__
))))
13 from test
.helper
import FakeYDL
, assertRegexpMatches
14 from youtube_dl
import YoutubeDL
15 from youtube_dl
.extractor
import YoutubeIE
16 from youtube_dl
.postprocessor
.common
import PostProcessor
20 def __init__(self
, *args
, **kwargs
):
21 super(YDL
, self
).__init
__(*args
, **kwargs
)
22 self
.downloaded_info_dicts
= []
25 def process_info(self
, info_dict
):
26 self
.downloaded_info_dicts
.append(info_dict
)
28 def to_screen(self
, msg
):
32 def _make_result(formats
, **kwargs
):
36 'title': 'testttitle',
37 'extractor': 'testex',
43 class TestFormatSelection(unittest
.TestCase
):
44 def test_prefer_free_formats(self
):
45 # Same resolution => download webm
47 ydl
.params
['prefer_free_formats'] = True
49 {'ext': 'webm', 'height': 460, 'url': 'x'},
50 {'ext': 'mp4', 'height': 460, 'url': 'y'},
52 info_dict
= _make_result(formats
)
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'], 'webm')
59 # Different resolution => download best quality (mp4)
61 ydl
.params
['prefer_free_formats'] = True
63 {'ext': 'webm', 'height': 720, 'url': 'a'},
64 {'ext': 'mp4', 'height': 1080, 'url': 'b'},
66 info_dict
['formats'] = formats
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')
73 # No prefer_free_formats => prefer mp4 and flv for greater compatibility
75 ydl
.params
['prefer_free_formats'] = False
77 {'ext': 'webm', 'height': 720, 'url': '_'},
78 {'ext': 'mp4', 'height': 720, 'url': '_'},
79 {'ext': 'flv', 'height': 720, 'url': '_'},
81 info_dict
['formats'] = formats
83 yie
._sort
_formats
(info_dict
['formats'])
84 ydl
.process_ie_result(info_dict
)
85 downloaded
= ydl
.downloaded_info_dicts
[0]
86 self
.assertEqual(downloaded
['ext'], 'mp4')
89 ydl
.params
['prefer_free_formats'] = False
91 {'ext': 'flv', 'height': 720, 'url': '_'},
92 {'ext': 'webm', 'height': 720, 'url': '_'},
94 info_dict
['formats'] = formats
96 yie
._sort
_formats
(info_dict
['formats'])
97 ydl
.process_ie_result(info_dict
)
98 downloaded
= ydl
.downloaded_info_dicts
[0]
99 self
.assertEqual(downloaded
['ext'], 'flv')
101 def test_format_limit(self
):
103 {'format_id': 'meh', 'url': 'http://example.com/meh', 'preference': 1},
104 {'format_id': 'good', 'url': 'http://example.com/good', 'preference': 2},
105 {'format_id': 'great', 'url': 'http://example.com/great', 'preference': 3},
106 {'format_id': 'excellent', 'url': 'http://example.com/exc', 'preference': 4},
108 info_dict
= _make_result(formats
)
111 ydl
.process_ie_result(info_dict
)
112 downloaded
= ydl
.downloaded_info_dicts
[0]
113 self
.assertEqual(downloaded
['format_id'], 'excellent')
115 ydl
= YDL({'format_limit': 'good'})
116 assert ydl
.params
['format_limit'] == 'good'
117 ydl
.process_ie_result(info_dict
.copy())
118 downloaded
= ydl
.downloaded_info_dicts
[0]
119 self
.assertEqual(downloaded
['format_id'], 'good')
121 ydl
= YDL({'format_limit': 'great', 'format': 'all'})
122 ydl
.process_ie_result(info_dict
.copy())
123 self
.assertEqual(ydl
.downloaded_info_dicts
[0]['format_id'], 'meh')
124 self
.assertEqual(ydl
.downloaded_info_dicts
[1]['format_id'], 'good')
125 self
.assertEqual(ydl
.downloaded_info_dicts
[2]['format_id'], 'great')
126 self
.assertTrue('3' in ydl
.msgs
[0])
129 ydl
.params
['format_limit'] = 'excellent'
130 ydl
.process_ie_result(info_dict
.copy())
131 downloaded
= ydl
.downloaded_info_dicts
[0]
132 self
.assertEqual(downloaded
['format_id'], 'excellent')
134 def test_format_selection(self
):
136 {'format_id': '35', 'ext': 'mp4', 'preference': 1, 'url': '_'},
137 {'format_id': '45', 'ext': 'webm', 'preference': 2, 'url': '_'},
138 {'format_id': '47', 'ext': 'webm', 'preference': 3, 'url': '_'},
139 {'format_id': '2', 'ext': 'flv', 'preference': 4, 'url': '_'},
141 info_dict
= _make_result(formats
)
143 ydl
= YDL({'format': '20/47'})
144 ydl
.process_ie_result(info_dict
.copy())
145 downloaded
= ydl
.downloaded_info_dicts
[0]
146 self
.assertEqual(downloaded
['format_id'], '47')
148 ydl
= YDL({'format': '20/71/worst'})
149 ydl
.process_ie_result(info_dict
.copy())
150 downloaded
= ydl
.downloaded_info_dicts
[0]
151 self
.assertEqual(downloaded
['format_id'], '35')
154 ydl
.process_ie_result(info_dict
.copy())
155 downloaded
= ydl
.downloaded_info_dicts
[0]
156 self
.assertEqual(downloaded
['format_id'], '2')
158 ydl
= YDL({'format': 'webm/mp4'})
159 ydl
.process_ie_result(info_dict
.copy())
160 downloaded
= ydl
.downloaded_info_dicts
[0]
161 self
.assertEqual(downloaded
['format_id'], '47')
163 ydl
= YDL({'format': '3gp/40/mp4'})
164 ydl
.process_ie_result(info_dict
.copy())
165 downloaded
= ydl
.downloaded_info_dicts
[0]
166 self
.assertEqual(downloaded
['format_id'], '35')
168 def test_format_selection_audio(self
):
170 {'format_id': 'audio-low', 'ext': 'webm', 'preference': 1, 'vcodec': 'none', 'url': '_'},
171 {'format_id': 'audio-mid', 'ext': 'webm', 'preference': 2, 'vcodec': 'none', 'url': '_'},
172 {'format_id': 'audio-high', 'ext': 'flv', 'preference': 3, 'vcodec': 'none', 'url': '_'},
173 {'format_id': 'vid', 'ext': 'mp4', 'preference': 4, 'url': '_'},
175 info_dict
= _make_result(formats
)
177 ydl
= YDL({'format': 'bestaudio'})
178 ydl
.process_ie_result(info_dict
.copy())
179 downloaded
= ydl
.downloaded_info_dicts
[0]
180 self
.assertEqual(downloaded
['format_id'], 'audio-high')
182 ydl
= YDL({'format': 'worstaudio'})
183 ydl
.process_ie_result(info_dict
.copy())
184 downloaded
= ydl
.downloaded_info_dicts
[0]
185 self
.assertEqual(downloaded
['format_id'], 'audio-low')
188 {'format_id': 'vid-low', 'ext': 'mp4', 'preference': 1, 'url': '_'},
189 {'format_id': 'vid-high', 'ext': 'mp4', 'preference': 2, 'url': '_'},
191 info_dict
= _make_result(formats
)
193 ydl
= YDL({'format': 'bestaudio/worstaudio/best'})
194 ydl
.process_ie_result(info_dict
.copy())
195 downloaded
= ydl
.downloaded_info_dicts
[0]
196 self
.assertEqual(downloaded
['format_id'], 'vid-high')
198 def test_format_selection_audio_exts(self
):
200 {'format_id': 'mp3-64', 'ext': 'mp3', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
201 {'format_id': 'ogg-64', 'ext': 'ogg', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
202 {'format_id': 'aac-64', 'ext': 'aac', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
203 {'format_id': 'mp3-32', 'ext': 'mp3', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'},
204 {'format_id': 'aac-32', 'ext': 'aac', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'},
207 info_dict
= _make_result(formats
)
208 ydl
= YDL({'format': 'best'})
210 ie
._sort
_formats
(info_dict
['formats'])
211 ydl
.process_ie_result(copy
.deepcopy(info_dict
))
212 downloaded
= ydl
.downloaded_info_dicts
[0]
213 self
.assertEqual(downloaded
['format_id'], 'aac-64')
215 ydl
= YDL({'format': 'mp3'})
217 ie
._sort
_formats
(info_dict
['formats'])
218 ydl
.process_ie_result(copy
.deepcopy(info_dict
))
219 downloaded
= ydl
.downloaded_info_dicts
[0]
220 self
.assertEqual(downloaded
['format_id'], 'mp3-64')
222 ydl
= YDL({'prefer_free_formats': True})
224 ie
._sort
_formats
(info_dict
['formats'])
225 ydl
.process_ie_result(copy
.deepcopy(info_dict
))
226 downloaded
= ydl
.downloaded_info_dicts
[0]
227 self
.assertEqual(downloaded
['format_id'], 'ogg-64')
229 def test_format_selection_video(self
):
231 {'format_id': 'dash-video-low', 'ext': 'mp4', 'preference': 1, 'acodec': 'none', 'url': '_'},
232 {'format_id': 'dash-video-high', 'ext': 'mp4', 'preference': 2, 'acodec': 'none', 'url': '_'},
233 {'format_id': 'vid', 'ext': 'mp4', 'preference': 3, 'url': '_'},
235 info_dict
= _make_result(formats
)
237 ydl
= YDL({'format': 'bestvideo'})
238 ydl
.process_ie_result(info_dict
.copy())
239 downloaded
= ydl
.downloaded_info_dicts
[0]
240 self
.assertEqual(downloaded
['format_id'], 'dash-video-high')
242 ydl
= YDL({'format': 'worstvideo'})
243 ydl
.process_ie_result(info_dict
.copy())
244 downloaded
= ydl
.downloaded_info_dicts
[0]
245 self
.assertEqual(downloaded
['format_id'], 'dash-video-low')
247 def test_youtube_format_selection(self
):
249 '38', '37', '46', '22', '45', '35', '44', '18', '34', '43', '6', '5', '36', '17', '13',
250 # Apple HTTP Live Streaming
251 '96', '95', '94', '93', '92', '132', '151',
253 '85', '84', '102', '83', '101', '82', '100',
255 '137', '248', '136', '247', '135', '246',
256 '245', '244', '134', '243', '133', '242', '160',
258 '141', '172', '140', '171', '139',
261 for f1id
, f2id
in zip(order
, order
[1:]):
262 f1
= YoutubeIE
._formats
[f1id
].copy()
263 f1
['format_id'] = f1id
264 f1
['url'] = 'url:' + f1id
265 f2
= YoutubeIE
._formats
[f2id
].copy()
266 f2
['format_id'] = f2id
267 f2
['url'] = 'url:' + f2id
269 info_dict
= _make_result([f1
, f2
], extractor
='youtube')
272 yie
._sort
_formats
(info_dict
['formats'])
273 ydl
.process_ie_result(info_dict
)
274 downloaded
= ydl
.downloaded_info_dicts
[0]
275 self
.assertEqual(downloaded
['format_id'], f1id
)
277 info_dict
= _make_result([f2
, f1
], extractor
='youtube')
280 yie
._sort
_formats
(info_dict
['formats'])
281 ydl
.process_ie_result(info_dict
)
282 downloaded
= ydl
.downloaded_info_dicts
[0]
283 self
.assertEqual(downloaded
['format_id'], f1id
)
285 def test_format_filtering(self
):
287 {'format_id': 'A', 'filesize': 500, 'width': 1000},
288 {'format_id': 'B', 'filesize': 1000, 'width': 500},
289 {'format_id': 'C', 'filesize': 1000, 'width': 400},
290 {'format_id': 'D', 'filesize': 2000, 'width': 600},
291 {'format_id': 'E', 'filesize': 3000},
293 {'format_id': 'G', 'filesize': 1000000},
296 f
['url'] = 'http://_/'
298 info_dict
= _make_result(formats
)
300 ydl
= YDL({'format': 'best[filesize<3000]'})
301 ydl
.process_ie_result(info_dict
)
302 downloaded
= ydl
.downloaded_info_dicts
[0]
303 self
.assertEqual(downloaded
['format_id'], 'D')
305 ydl
= YDL({'format': 'best[filesize<=3000]'})
306 ydl
.process_ie_result(info_dict
)
307 downloaded
= ydl
.downloaded_info_dicts
[0]
308 self
.assertEqual(downloaded
['format_id'], 'E')
310 ydl
= YDL({'format': 'best[filesize <= ? 3000]'})
311 ydl
.process_ie_result(info_dict
)
312 downloaded
= ydl
.downloaded_info_dicts
[0]
313 self
.assertEqual(downloaded
['format_id'], 'F')
315 ydl
= YDL({'format': 'best [filesize = 1000] [width>450]'})
316 ydl
.process_ie_result(info_dict
)
317 downloaded
= ydl
.downloaded_info_dicts
[0]
318 self
.assertEqual(downloaded
['format_id'], 'B')
320 ydl
= YDL({'format': 'best [filesize = 1000] [width!=450]'})
321 ydl
.process_ie_result(info_dict
)
322 downloaded
= ydl
.downloaded_info_dicts
[0]
323 self
.assertEqual(downloaded
['format_id'], 'C')
325 ydl
= YDL({'format': '[filesize>?1]'})
326 ydl
.process_ie_result(info_dict
)
327 downloaded
= ydl
.downloaded_info_dicts
[0]
328 self
.assertEqual(downloaded
['format_id'], 'G')
330 ydl
= YDL({'format': '[filesize<1M]'})
331 ydl
.process_ie_result(info_dict
)
332 downloaded
= ydl
.downloaded_info_dicts
[0]
333 self
.assertEqual(downloaded
['format_id'], 'E')
335 ydl
= YDL({'format': '[filesize<1MiB]'})
336 ydl
.process_ie_result(info_dict
)
337 downloaded
= ydl
.downloaded_info_dicts
[0]
338 self
.assertEqual(downloaded
['format_id'], 'G')
340 def test_subtitles(self
):
341 def s_formats(lang
, autocaption
=False):
344 'url': 'http://localhost/video.%s.%s' % (lang
, ext
),
345 '_auto': autocaption
,
346 } for ext
in ['vtt', 'srt', 'ass']]
347 subtitles
= dict((l
, s_formats(l
)) for l
in ['en', 'fr', 'es'])
348 auto_captions
= dict((l
, s_formats(l
, True)) for l
in ['it', 'pt', 'es'])
352 'url': 'http://localhost/video.mp4',
353 'subtitles': subtitles
,
354 'automatic_captions': auto_captions
,
358 def get_info(params
={}):
359 params
.setdefault('simulate', True)
361 ydl
.report_warning
= lambda *args
, **kargs
: None
362 return ydl
.process_video_result(info_dict
, download
=False)
365 self
.assertFalse(result
.get('requested_subtitles'))
366 self
.assertEqual(result
['subtitles'], subtitles
)
367 self
.assertEqual(result
['automatic_captions'], auto_captions
)
369 result
= get_info({'writesubtitles': True})
370 subs
= result
['requested_subtitles']
371 self
.assertTrue(subs
)
372 self
.assertEqual(set(subs
.keys()), set(['en']))
373 self
.assertTrue(subs
['en'].get('data') is None)
374 self
.assertEqual(subs
['en']['ext'], 'ass')
376 result
= get_info({'writesubtitles': True, 'subtitlesformat': 'foo/srt'})
377 subs
= result
['requested_subtitles']
378 self
.assertEqual(subs
['en']['ext'], 'srt')
380 result
= get_info({'writesubtitles': True, 'subtitleslangs': ['es', 'fr', 'it']})
381 subs
= result
['requested_subtitles']
382 self
.assertTrue(subs
)
383 self
.assertEqual(set(subs
.keys()), set(['es', 'fr']))
385 result
= get_info({'writesubtitles': True, 'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']})
386 subs
= result
['requested_subtitles']
387 self
.assertTrue(subs
)
388 self
.assertEqual(set(subs
.keys()), set(['es', 'pt']))
389 self
.assertFalse(subs
['es']['_auto'])
390 self
.assertTrue(subs
['pt']['_auto'])
392 result
= get_info({'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']})
393 subs
= result
['requested_subtitles']
394 self
.assertTrue(subs
)
395 self
.assertEqual(set(subs
.keys()), set(['es', 'pt']))
396 self
.assertTrue(subs
['es']['_auto'])
397 self
.assertTrue(subs
['pt']['_auto'])
399 def test_add_extra_info(self
):
405 'playlist': 'funny videos',
407 YDL
.add_extra_info(test_dict
, extra_info
)
408 self
.assertEqual(test_dict
['extractor'], 'Foo')
409 self
.assertEqual(test_dict
['playlist'], 'funny videos')
411 def test_prepare_filename(self
):
419 ydl
= YoutubeDL({'outtmpl': templ
})
420 return ydl
.prepare_filename(info
)
421 self
.assertEqual(fname('%(id)s.%(ext)s'), '1234.mp4')
422 self
.assertEqual(fname('%(id)s-%(width)s.%(ext)s'), '1234-NA.mp4')
423 # Replace missing fields with 'NA'
424 self
.assertEqual(fname('%(uploader_date)s-%(id)s.%(ext)s'), 'NA-1234.mp4')
426 def test_format_note(self
):
428 self
.assertEqual(ydl
._format
_note
({}), '')
429 assertRegexpMatches(self
, ydl
._format
_note
({
433 def test_postprocessors(self
):
434 filename
= 'post-processor-testfile.mp4'
435 audiofile
= filename
+ '.mp3'
437 class SimplePP(PostProcessor
):
439 with open(audiofile
, 'wt') as f
:
445 with open(filename
, 'wt') as f
:
447 ydl
= YoutubeDL(params
)
448 ydl
.add_post_processor(SimplePP())
449 ydl
.post_process(filename
, {'filepath': filename
})
451 run_pp({'keepvideo': True})
452 self
.assertTrue(os
.path
.exists(filename
), '%s doesn\'t exist' % filename
)
453 self
.assertTrue(os
.path
.exists(audiofile
), '%s doesn\'t exist' % audiofile
)
457 run_pp({'keepvideo': False})
458 self
.assertFalse(os
.path
.exists(filename
), '%s exists' % filename
)
459 self
.assertTrue(os
.path
.exists(audiofile
), '%s doesn\'t exist' % audiofile
)
463 if __name__
== '__main__':