]>
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
17 from youtube_dl
.utils
import match_filter_func
19 TEST_URL
= 'http://localhost/sample.mp4'
23 def __init__(self
, *args
, **kwargs
):
24 super(YDL
, self
).__init
__(*args
, **kwargs
)
25 self
.downloaded_info_dicts
= []
28 def process_info(self
, info_dict
):
29 self
.downloaded_info_dicts
.append(info_dict
)
31 def to_screen(self
, msg
):
35 def _make_result(formats
, **kwargs
):
39 'title': 'testttitle',
40 'extractor': 'testex',
46 class TestFormatSelection(unittest
.TestCase
):
47 def test_prefer_free_formats(self
):
48 # Same resolution => download webm
50 ydl
.params
['prefer_free_formats'] = True
52 {'ext': 'webm', 'height': 460, 'url': TEST_URL
},
53 {'ext': 'mp4', 'height': 460, 'url': TEST_URL
},
55 info_dict
= _make_result(formats
)
57 yie
._sort
_formats
(info_dict
['formats'])
58 ydl
.process_ie_result(info_dict
)
59 downloaded
= ydl
.downloaded_info_dicts
[0]
60 self
.assertEqual(downloaded
['ext'], 'webm')
62 # Different resolution => download best quality (mp4)
64 ydl
.params
['prefer_free_formats'] = True
66 {'ext': 'webm', 'height': 720, 'url': TEST_URL
},
67 {'ext': 'mp4', 'height': 1080, 'url': TEST_URL
},
69 info_dict
['formats'] = formats
71 yie
._sort
_formats
(info_dict
['formats'])
72 ydl
.process_ie_result(info_dict
)
73 downloaded
= ydl
.downloaded_info_dicts
[0]
74 self
.assertEqual(downloaded
['ext'], 'mp4')
76 # No prefer_free_formats => prefer mp4 and flv for greater compatibility
78 ydl
.params
['prefer_free_formats'] = False
80 {'ext': 'webm', 'height': 720, 'url': TEST_URL
},
81 {'ext': 'mp4', 'height': 720, 'url': TEST_URL
},
82 {'ext': 'flv', 'height': 720, 'url': TEST_URL
},
84 info_dict
['formats'] = formats
86 yie
._sort
_formats
(info_dict
['formats'])
87 ydl
.process_ie_result(info_dict
)
88 downloaded
= ydl
.downloaded_info_dicts
[0]
89 self
.assertEqual(downloaded
['ext'], 'mp4')
92 ydl
.params
['prefer_free_formats'] = False
94 {'ext': 'flv', 'height': 720, 'url': TEST_URL
},
95 {'ext': 'webm', 'height': 720, 'url': TEST_URL
},
97 info_dict
['formats'] = formats
99 yie
._sort
_formats
(info_dict
['formats'])
100 ydl
.process_ie_result(info_dict
)
101 downloaded
= ydl
.downloaded_info_dicts
[0]
102 self
.assertEqual(downloaded
['ext'], 'flv')
104 def test_format_selection(self
):
106 {'format_id': '35', 'ext': 'mp4', 'preference': 1, 'url': TEST_URL
},
107 {'format_id': '45', 'ext': 'webm', 'preference': 2, 'url': TEST_URL
},
108 {'format_id': '47', 'ext': 'webm', 'preference': 3, 'url': TEST_URL
},
109 {'format_id': '2', 'ext': 'flv', 'preference': 4, 'url': TEST_URL
},
111 info_dict
= _make_result(formats
)
113 ydl
= YDL({'format': '20/47'})
114 ydl
.process_ie_result(info_dict
.copy())
115 downloaded
= ydl
.downloaded_info_dicts
[0]
116 self
.assertEqual(downloaded
['format_id'], '47')
118 ydl
= YDL({'format': '20/71/worst'})
119 ydl
.process_ie_result(info_dict
.copy())
120 downloaded
= ydl
.downloaded_info_dicts
[0]
121 self
.assertEqual(downloaded
['format_id'], '35')
124 ydl
.process_ie_result(info_dict
.copy())
125 downloaded
= ydl
.downloaded_info_dicts
[0]
126 self
.assertEqual(downloaded
['format_id'], '2')
128 ydl
= YDL({'format': 'webm/mp4'})
129 ydl
.process_ie_result(info_dict
.copy())
130 downloaded
= ydl
.downloaded_info_dicts
[0]
131 self
.assertEqual(downloaded
['format_id'], '47')
133 ydl
= YDL({'format': '3gp/40/mp4'})
134 ydl
.process_ie_result(info_dict
.copy())
135 downloaded
= ydl
.downloaded_info_dicts
[0]
136 self
.assertEqual(downloaded
['format_id'], '35')
138 def test_format_selection_audio(self
):
140 {'format_id': 'audio-low', 'ext': 'webm', 'preference': 1, 'vcodec': 'none', 'url': TEST_URL
},
141 {'format_id': 'audio-mid', 'ext': 'webm', 'preference': 2, 'vcodec': 'none', 'url': TEST_URL
},
142 {'format_id': 'audio-high', 'ext': 'flv', 'preference': 3, 'vcodec': 'none', 'url': TEST_URL
},
143 {'format_id': 'vid', 'ext': 'mp4', 'preference': 4, 'url': TEST_URL
},
145 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')
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')
158 {'format_id': 'vid-low', 'ext': 'mp4', 'preference': 1, 'url': TEST_URL
},
159 {'format_id': 'vid-high', 'ext': 'mp4', 'preference': 2, 'url': TEST_URL
},
161 info_dict
= _make_result(formats
)
163 ydl
= YDL({'format': 'bestaudio/worstaudio/best'})
164 ydl
.process_ie_result(info_dict
.copy())
165 downloaded
= ydl
.downloaded_info_dicts
[0]
166 self
.assertEqual(downloaded
['format_id'], 'vid-high')
168 def test_format_selection_audio_exts(self
):
170 {'format_id': 'mp3-64', 'ext': 'mp3', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
171 {'format_id': 'ogg-64', 'ext': 'ogg', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
172 {'format_id': 'aac-64', 'ext': 'aac', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
173 {'format_id': 'mp3-32', 'ext': 'mp3', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'},
174 {'format_id': 'aac-32', 'ext': 'aac', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'},
177 info_dict
= _make_result(formats
)
178 ydl
= YDL({'format': 'best'})
180 ie
._sort
_formats
(info_dict
['formats'])
181 ydl
.process_ie_result(copy
.deepcopy(info_dict
))
182 downloaded
= ydl
.downloaded_info_dicts
[0]
183 self
.assertEqual(downloaded
['format_id'], 'aac-64')
185 ydl
= YDL({'format': 'mp3'})
187 ie
._sort
_formats
(info_dict
['formats'])
188 ydl
.process_ie_result(copy
.deepcopy(info_dict
))
189 downloaded
= ydl
.downloaded_info_dicts
[0]
190 self
.assertEqual(downloaded
['format_id'], 'mp3-64')
192 ydl
= YDL({'prefer_free_formats': True})
194 ie
._sort
_formats
(info_dict
['formats'])
195 ydl
.process_ie_result(copy
.deepcopy(info_dict
))
196 downloaded
= ydl
.downloaded_info_dicts
[0]
197 self
.assertEqual(downloaded
['format_id'], 'ogg-64')
199 def test_format_selection_video(self
):
201 {'format_id': 'dash-video-low', 'ext': 'mp4', 'preference': 1, 'acodec': 'none', 'url': TEST_URL
},
202 {'format_id': 'dash-video-high', 'ext': 'mp4', 'preference': 2, 'acodec': 'none', 'url': TEST_URL
},
203 {'format_id': 'vid', 'ext': 'mp4', 'preference': 3, 'url': TEST_URL
},
205 info_dict
= _make_result(formats
)
207 ydl
= YDL({'format': 'bestvideo'})
208 ydl
.process_ie_result(info_dict
.copy())
209 downloaded
= ydl
.downloaded_info_dicts
[0]
210 self
.assertEqual(downloaded
['format_id'], 'dash-video-high')
212 ydl
= YDL({'format': 'worstvideo'})
213 ydl
.process_ie_result(info_dict
.copy())
214 downloaded
= ydl
.downloaded_info_dicts
[0]
215 self
.assertEqual(downloaded
['format_id'], 'dash-video-low')
217 def test_youtube_format_selection(self
):
219 '38', '37', '46', '22', '45', '35', '44', '18', '34', '43', '6', '5', '36', '17', '13',
220 # Apple HTTP Live Streaming
221 '96', '95', '94', '93', '92', '132', '151',
223 '85', '84', '102', '83', '101', '82', '100',
225 '137', '248', '136', '247', '135', '246',
226 '245', '244', '134', '243', '133', '242', '160',
228 '141', '172', '140', '171', '139',
231 for f1id
, f2id
in zip(order
, order
[1:]):
232 f1
= YoutubeIE
._formats
[f1id
].copy()
233 f1
['format_id'] = f1id
234 f1
['url'] = 'url:' + f1id
235 f2
= YoutubeIE
._formats
[f2id
].copy()
236 f2
['format_id'] = f2id
237 f2
['url'] = 'url:' + f2id
239 info_dict
= _make_result([f1
, f2
], extractor
='youtube')
240 ydl
= YDL({'format': 'best/bestvideo'})
242 yie
._sort
_formats
(info_dict
['formats'])
243 ydl
.process_ie_result(info_dict
)
244 downloaded
= ydl
.downloaded_info_dicts
[0]
245 self
.assertEqual(downloaded
['format_id'], f1id
)
247 info_dict
= _make_result([f2
, f1
], extractor
='youtube')
248 ydl
= YDL({'format': 'best/bestvideo'})
250 yie
._sort
_formats
(info_dict
['formats'])
251 ydl
.process_ie_result(info_dict
)
252 downloaded
= ydl
.downloaded_info_dicts
[0]
253 self
.assertEqual(downloaded
['format_id'], f1id
)
255 def test_format_filtering(self
):
257 {'format_id': 'A', 'filesize': 500, 'width': 1000},
258 {'format_id': 'B', 'filesize': 1000, 'width': 500},
259 {'format_id': 'C', 'filesize': 1000, 'width': 400},
260 {'format_id': 'D', 'filesize': 2000, 'width': 600},
261 {'format_id': 'E', 'filesize': 3000},
263 {'format_id': 'G', 'filesize': 1000000},
266 f
['url'] = 'http://_/'
268 info_dict
= _make_result(formats
)
270 ydl
= YDL({'format': 'best[filesize<3000]'})
271 ydl
.process_ie_result(info_dict
)
272 downloaded
= ydl
.downloaded_info_dicts
[0]
273 self
.assertEqual(downloaded
['format_id'], 'D')
275 ydl
= YDL({'format': 'best[filesize<=3000]'})
276 ydl
.process_ie_result(info_dict
)
277 downloaded
= ydl
.downloaded_info_dicts
[0]
278 self
.assertEqual(downloaded
['format_id'], 'E')
280 ydl
= YDL({'format': 'best[filesize <= ? 3000]'})
281 ydl
.process_ie_result(info_dict
)
282 downloaded
= ydl
.downloaded_info_dicts
[0]
283 self
.assertEqual(downloaded
['format_id'], 'F')
285 ydl
= YDL({'format': 'best [filesize = 1000] [width>450]'})
286 ydl
.process_ie_result(info_dict
)
287 downloaded
= ydl
.downloaded_info_dicts
[0]
288 self
.assertEqual(downloaded
['format_id'], 'B')
290 ydl
= YDL({'format': 'best [filesize = 1000] [width!=450]'})
291 ydl
.process_ie_result(info_dict
)
292 downloaded
= ydl
.downloaded_info_dicts
[0]
293 self
.assertEqual(downloaded
['format_id'], 'C')
295 ydl
= YDL({'format': '[filesize>?1]'})
296 ydl
.process_ie_result(info_dict
)
297 downloaded
= ydl
.downloaded_info_dicts
[0]
298 self
.assertEqual(downloaded
['format_id'], 'G')
300 ydl
= YDL({'format': '[filesize<1M]'})
301 ydl
.process_ie_result(info_dict
)
302 downloaded
= ydl
.downloaded_info_dicts
[0]
303 self
.assertEqual(downloaded
['format_id'], 'E')
305 ydl
= YDL({'format': '[filesize<1MiB]'})
306 ydl
.process_ie_result(info_dict
)
307 downloaded
= ydl
.downloaded_info_dicts
[0]
308 self
.assertEqual(downloaded
['format_id'], 'G')
311 class TestYoutubeDL(unittest
.TestCase
):
312 def test_subtitles(self
):
313 def s_formats(lang
, autocaption
=False):
316 'url': 'http://localhost/video.%s.%s' % (lang
, ext
),
317 '_auto': autocaption
,
318 } for ext
in ['vtt', 'srt', 'ass']]
319 subtitles
= dict((l
, s_formats(l
)) for l
in ['en', 'fr', 'es'])
320 auto_captions
= dict((l
, s_formats(l
, True)) for l
in ['it', 'pt', 'es'])
324 'url': 'http://localhost/video.mp4',
325 'subtitles': subtitles
,
326 'automatic_captions': auto_captions
,
330 def get_info(params
={}):
331 params
.setdefault('simulate', True)
333 ydl
.report_warning
= lambda *args
, **kargs
: None
334 return ydl
.process_video_result(info_dict
, download
=False)
337 self
.assertFalse(result
.get('requested_subtitles'))
338 self
.assertEqual(result
['subtitles'], subtitles
)
339 self
.assertEqual(result
['automatic_captions'], auto_captions
)
341 result
= get_info({'writesubtitles': True})
342 subs
= result
['requested_subtitles']
343 self
.assertTrue(subs
)
344 self
.assertEqual(set(subs
.keys()), set(['en']))
345 self
.assertTrue(subs
['en'].get('data') is None)
346 self
.assertEqual(subs
['en']['ext'], 'ass')
348 result
= get_info({'writesubtitles': True, 'subtitlesformat': 'foo/srt'})
349 subs
= result
['requested_subtitles']
350 self
.assertEqual(subs
['en']['ext'], 'srt')
352 result
= get_info({'writesubtitles': True, 'subtitleslangs': ['es', 'fr', 'it']})
353 subs
= result
['requested_subtitles']
354 self
.assertTrue(subs
)
355 self
.assertEqual(set(subs
.keys()), set(['es', 'fr']))
357 result
= get_info({'writesubtitles': True, 'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']})
358 subs
= result
['requested_subtitles']
359 self
.assertTrue(subs
)
360 self
.assertEqual(set(subs
.keys()), set(['es', 'pt']))
361 self
.assertFalse(subs
['es']['_auto'])
362 self
.assertTrue(subs
['pt']['_auto'])
364 result
= get_info({'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']})
365 subs
= result
['requested_subtitles']
366 self
.assertTrue(subs
)
367 self
.assertEqual(set(subs
.keys()), set(['es', 'pt']))
368 self
.assertTrue(subs
['es']['_auto'])
369 self
.assertTrue(subs
['pt']['_auto'])
371 def test_add_extra_info(self
):
377 'playlist': 'funny videos',
379 YDL
.add_extra_info(test_dict
, extra_info
)
380 self
.assertEqual(test_dict
['extractor'], 'Foo')
381 self
.assertEqual(test_dict
['playlist'], 'funny videos')
383 def test_prepare_filename(self
):
391 ydl
= YoutubeDL({'outtmpl': templ
})
392 return ydl
.prepare_filename(info
)
393 self
.assertEqual(fname('%(id)s.%(ext)s'), '1234.mp4')
394 self
.assertEqual(fname('%(id)s-%(width)s.%(ext)s'), '1234-NA.mp4')
395 # Replace missing fields with 'NA'
396 self
.assertEqual(fname('%(uploader_date)s-%(id)s.%(ext)s'), 'NA-1234.mp4')
398 def test_format_note(self
):
400 self
.assertEqual(ydl
._format
_note
({}), '')
401 assertRegexpMatches(self
, ydl
._format
_note
({
405 def test_postprocessors(self
):
406 filename
= 'post-processor-testfile.mp4'
407 audiofile
= filename
+ '.mp3'
409 class SimplePP(PostProcessor
):
411 with open(audiofile
, 'wt') as f
:
413 return [info
['filepath']], info
415 def run_pp(params
, PP
):
416 with open(filename
, 'wt') as f
:
418 ydl
= YoutubeDL(params
)
419 ydl
.add_post_processor(PP())
420 ydl
.post_process(filename
, {'filepath': filename
})
422 run_pp({'keepvideo': True}, SimplePP
)
423 self
.assertTrue(os
.path
.exists(filename
), '%s doesn\'t exist' % filename
)
424 self
.assertTrue(os
.path
.exists(audiofile
), '%s doesn\'t exist' % audiofile
)
428 run_pp({'keepvideo': False}, SimplePP
)
429 self
.assertFalse(os
.path
.exists(filename
), '%s exists' % filename
)
430 self
.assertTrue(os
.path
.exists(audiofile
), '%s doesn\'t exist' % audiofile
)
433 class ModifierPP(PostProcessor
):
435 with open(info
['filepath'], 'wt') as f
:
439 run_pp({'keepvideo': False}, ModifierPP
)
440 self
.assertTrue(os
.path
.exists(filename
), '%s doesn\'t exist' % filename
)
443 def test_match_filter(self
):
444 class FilterYDL(YDL
):
445 def __init__(self
, *args
, **kwargs
):
446 super(FilterYDL
, self
).__init
__(*args
, **kwargs
)
447 self
.params
['simulate'] = True
449 def process_info(self
, info_dict
):
450 super(YDL
, self
).process_info(info_dict
)
452 def _match_entry(self
, info_dict
, incomplete
):
453 res
= super(FilterYDL
, self
)._match
_entry
(info_dict
, incomplete
)
455 self
.downloaded_info_dicts
.append(info_dict
)
464 'filesize': 10 * 1024,
472 'description': 'foo',
473 'filesize': 5 * 1024,
475 videos
= [first
, second
]
477 def get_videos(filter_
=None):
478 ydl
= FilterYDL({'match_filter': filter_
})
480 ydl
.process_ie_result(v
, download
=True)
481 return [v
['id'] for v
in ydl
.downloaded_info_dicts
]
484 self
.assertEqual(res
, ['1', '2'])
490 return 'Video id is not 1'
492 self
.assertEqual(res
, ['1'])
494 f
= match_filter_func('duration < 30')
496 self
.assertEqual(res
, ['2'])
498 f
= match_filter_func('description = foo')
500 self
.assertEqual(res
, ['2'])
502 f
= match_filter_func('description =? foo')
504 self
.assertEqual(res
, ['1', '2'])
506 f
= match_filter_func('filesize > 5KiB')
508 self
.assertEqual(res
, ['1'])
511 if __name__
== '__main__':