]>
Raphaƫl G. Git Repositories - youtubedl/blob - test/test_YoutubeDL.py
a13c09ef40c7d8c101c86b471cae142ada9ccd7c
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
.compat
import compat_str
16 from youtube_dl
.extractor
import YoutubeIE
17 from youtube_dl
.postprocessor
.common
import PostProcessor
18 from youtube_dl
.utils
import match_filter_func
20 TEST_URL
= 'http://localhost/sample.mp4'
24 def __init__(self
, *args
, **kwargs
):
25 super(YDL
, self
).__init
__(*args
, **kwargs
)
26 self
.downloaded_info_dicts
= []
29 def process_info(self
, info_dict
):
30 self
.downloaded_info_dicts
.append(info_dict
)
32 def to_screen(self
, msg
):
36 def _make_result(formats
, **kwargs
):
40 'title': 'testttitle',
41 'extractor': 'testex',
47 class TestFormatSelection(unittest
.TestCase
):
48 def test_prefer_free_formats(self
):
49 # Same resolution => download webm
51 ydl
.params
['prefer_free_formats'] = True
53 {'ext': 'webm', 'height': 460, 'url': TEST_URL
},
54 {'ext': 'mp4', 'height': 460, 'url': TEST_URL
},
56 info_dict
= _make_result(formats
)
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'], 'webm')
63 # Different resolution => download best quality (mp4)
65 ydl
.params
['prefer_free_formats'] = True
67 {'ext': 'webm', 'height': 720, 'url': TEST_URL
},
68 {'ext': 'mp4', 'height': 1080, 'url': TEST_URL
},
70 info_dict
['formats'] = formats
72 yie
._sort
_formats
(info_dict
['formats'])
73 ydl
.process_ie_result(info_dict
)
74 downloaded
= ydl
.downloaded_info_dicts
[0]
75 self
.assertEqual(downloaded
['ext'], 'mp4')
77 # No prefer_free_formats => prefer mp4 and flv for greater compatibility
79 ydl
.params
['prefer_free_formats'] = False
81 {'ext': 'webm', 'height': 720, 'url': TEST_URL
},
82 {'ext': 'mp4', 'height': 720, 'url': TEST_URL
},
83 {'ext': 'flv', 'height': 720, 'url': TEST_URL
},
85 info_dict
['formats'] = formats
87 yie
._sort
_formats
(info_dict
['formats'])
88 ydl
.process_ie_result(info_dict
)
89 downloaded
= ydl
.downloaded_info_dicts
[0]
90 self
.assertEqual(downloaded
['ext'], 'mp4')
93 ydl
.params
['prefer_free_formats'] = False
95 {'ext': 'flv', 'height': 720, 'url': TEST_URL
},
96 {'ext': 'webm', 'height': 720, 'url': TEST_URL
},
98 info_dict
['formats'] = formats
100 yie
._sort
_formats
(info_dict
['formats'])
101 ydl
.process_ie_result(info_dict
)
102 downloaded
= ydl
.downloaded_info_dicts
[0]
103 self
.assertEqual(downloaded
['ext'], 'flv')
105 def test_format_selection(self
):
107 {'format_id': '35', 'ext': 'mp4', 'preference': 1, 'url': TEST_URL
},
108 {'format_id': '45', 'ext': 'webm', 'preference': 2, 'url': TEST_URL
},
109 {'format_id': '47', 'ext': 'webm', 'preference': 3, 'url': TEST_URL
},
110 {'format_id': '2', 'ext': 'flv', 'preference': 4, 'url': TEST_URL
},
112 info_dict
= _make_result(formats
)
114 ydl
= YDL({'format': '20/47'})
115 ydl
.process_ie_result(info_dict
.copy())
116 downloaded
= ydl
.downloaded_info_dicts
[0]
117 self
.assertEqual(downloaded
['format_id'], '47')
119 ydl
= YDL({'format': '20/71/worst'})
120 ydl
.process_ie_result(info_dict
.copy())
121 downloaded
= ydl
.downloaded_info_dicts
[0]
122 self
.assertEqual(downloaded
['format_id'], '35')
125 ydl
.process_ie_result(info_dict
.copy())
126 downloaded
= ydl
.downloaded_info_dicts
[0]
127 self
.assertEqual(downloaded
['format_id'], '2')
129 ydl
= YDL({'format': 'webm/mp4'})
130 ydl
.process_ie_result(info_dict
.copy())
131 downloaded
= ydl
.downloaded_info_dicts
[0]
132 self
.assertEqual(downloaded
['format_id'], '47')
134 ydl
= YDL({'format': '3gp/40/mp4'})
135 ydl
.process_ie_result(info_dict
.copy())
136 downloaded
= ydl
.downloaded_info_dicts
[0]
137 self
.assertEqual(downloaded
['format_id'], '35')
139 def test_format_selection_audio(self
):
141 {'format_id': 'audio-low', 'ext': 'webm', 'preference': 1, 'vcodec': 'none', 'url': TEST_URL
},
142 {'format_id': 'audio-mid', 'ext': 'webm', 'preference': 2, 'vcodec': 'none', 'url': TEST_URL
},
143 {'format_id': 'audio-high', 'ext': 'flv', 'preference': 3, 'vcodec': 'none', 'url': TEST_URL
},
144 {'format_id': 'vid', 'ext': 'mp4', 'preference': 4, 'url': TEST_URL
},
146 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')
153 ydl
= YDL({'format': 'worstaudio'})
154 ydl
.process_ie_result(info_dict
.copy())
155 downloaded
= ydl
.downloaded_info_dicts
[0]
156 self
.assertEqual(downloaded
['format_id'], 'audio-low')
159 {'format_id': 'vid-low', 'ext': 'mp4', 'preference': 1, 'url': TEST_URL
},
160 {'format_id': 'vid-high', 'ext': 'mp4', 'preference': 2, 'url': TEST_URL
},
162 info_dict
= _make_result(formats
)
164 ydl
= YDL({'format': 'bestaudio/worstaudio/best'})
165 ydl
.process_ie_result(info_dict
.copy())
166 downloaded
= ydl
.downloaded_info_dicts
[0]
167 self
.assertEqual(downloaded
['format_id'], 'vid-high')
169 def test_format_selection_audio_exts(self
):
171 {'format_id': 'mp3-64', 'ext': 'mp3', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
172 {'format_id': 'ogg-64', 'ext': 'ogg', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
173 {'format_id': 'aac-64', 'ext': 'aac', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
174 {'format_id': 'mp3-32', 'ext': 'mp3', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'},
175 {'format_id': 'aac-32', 'ext': 'aac', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'},
178 info_dict
= _make_result(formats
)
179 ydl
= YDL({'format': 'best'})
181 ie
._sort
_formats
(info_dict
['formats'])
182 ydl
.process_ie_result(copy
.deepcopy(info_dict
))
183 downloaded
= ydl
.downloaded_info_dicts
[0]
184 self
.assertEqual(downloaded
['format_id'], 'aac-64')
186 ydl
= YDL({'format': 'mp3'})
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'], 'mp3-64')
193 ydl
= YDL({'prefer_free_formats': True})
195 ie
._sort
_formats
(info_dict
['formats'])
196 ydl
.process_ie_result(copy
.deepcopy(info_dict
))
197 downloaded
= ydl
.downloaded_info_dicts
[0]
198 self
.assertEqual(downloaded
['format_id'], 'ogg-64')
200 def test_format_selection_video(self
):
202 {'format_id': 'dash-video-low', 'ext': 'mp4', 'preference': 1, 'acodec': 'none', 'url': TEST_URL
},
203 {'format_id': 'dash-video-high', 'ext': 'mp4', 'preference': 2, 'acodec': 'none', 'url': TEST_URL
},
204 {'format_id': 'vid', 'ext': 'mp4', 'preference': 3, 'url': TEST_URL
},
206 info_dict
= _make_result(formats
)
208 ydl
= YDL({'format': 'bestvideo'})
209 ydl
.process_ie_result(info_dict
.copy())
210 downloaded
= ydl
.downloaded_info_dicts
[0]
211 self
.assertEqual(downloaded
['format_id'], 'dash-video-high')
213 ydl
= YDL({'format': 'worstvideo'})
214 ydl
.process_ie_result(info_dict
.copy())
215 downloaded
= ydl
.downloaded_info_dicts
[0]
216 self
.assertEqual(downloaded
['format_id'], 'dash-video-low')
218 def test_youtube_format_selection(self
):
220 '38', '37', '46', '22', '45', '35', '44', '18', '34', '43', '6', '5', '36', '17', '13',
221 # Apple HTTP Live Streaming
222 '96', '95', '94', '93', '92', '132', '151',
224 '85', '84', '102', '83', '101', '82', '100',
226 '137', '248', '136', '247', '135', '246',
227 '245', '244', '134', '243', '133', '242', '160',
229 '141', '172', '140', '171', '139',
232 for f1id
, f2id
in zip(order
, order
[1:]):
233 f1
= YoutubeIE
._formats
[f1id
].copy()
234 f1
['format_id'] = f1id
235 f1
['url'] = 'url:' + f1id
236 f2
= YoutubeIE
._formats
[f2id
].copy()
237 f2
['format_id'] = f2id
238 f2
['url'] = 'url:' + f2id
240 info_dict
= _make_result([f1
, f2
], extractor
='youtube')
241 ydl
= YDL({'format': 'best/bestvideo'})
243 yie
._sort
_formats
(info_dict
['formats'])
244 ydl
.process_ie_result(info_dict
)
245 downloaded
= ydl
.downloaded_info_dicts
[0]
246 self
.assertEqual(downloaded
['format_id'], f1id
)
248 info_dict
= _make_result([f2
, f1
], extractor
='youtube')
249 ydl
= YDL({'format': 'best/bestvideo'})
251 yie
._sort
_formats
(info_dict
['formats'])
252 ydl
.process_ie_result(info_dict
)
253 downloaded
= ydl
.downloaded_info_dicts
[0]
254 self
.assertEqual(downloaded
['format_id'], f1id
)
256 def test_format_filtering(self
):
258 {'format_id': 'A', 'filesize': 500, 'width': 1000},
259 {'format_id': 'B', 'filesize': 1000, 'width': 500},
260 {'format_id': 'C', 'filesize': 1000, 'width': 400},
261 {'format_id': 'D', 'filesize': 2000, 'width': 600},
262 {'format_id': 'E', 'filesize': 3000},
264 {'format_id': 'G', 'filesize': 1000000},
267 f
['url'] = 'http://_/'
269 info_dict
= _make_result(formats
)
271 ydl
= YDL({'format': 'best[filesize<3000]'})
272 ydl
.process_ie_result(info_dict
)
273 downloaded
= ydl
.downloaded_info_dicts
[0]
274 self
.assertEqual(downloaded
['format_id'], 'D')
276 ydl
= YDL({'format': 'best[filesize<=3000]'})
277 ydl
.process_ie_result(info_dict
)
278 downloaded
= ydl
.downloaded_info_dicts
[0]
279 self
.assertEqual(downloaded
['format_id'], 'E')
281 ydl
= YDL({'format': 'best[filesize <= ? 3000]'})
282 ydl
.process_ie_result(info_dict
)
283 downloaded
= ydl
.downloaded_info_dicts
[0]
284 self
.assertEqual(downloaded
['format_id'], 'F')
286 ydl
= YDL({'format': 'best [filesize = 1000] [width>450]'})
287 ydl
.process_ie_result(info_dict
)
288 downloaded
= ydl
.downloaded_info_dicts
[0]
289 self
.assertEqual(downloaded
['format_id'], 'B')
291 ydl
= YDL({'format': 'best [filesize = 1000] [width!=450]'})
292 ydl
.process_ie_result(info_dict
)
293 downloaded
= ydl
.downloaded_info_dicts
[0]
294 self
.assertEqual(downloaded
['format_id'], 'C')
296 ydl
= YDL({'format': '[filesize>?1]'})
297 ydl
.process_ie_result(info_dict
)
298 downloaded
= ydl
.downloaded_info_dicts
[0]
299 self
.assertEqual(downloaded
['format_id'], 'G')
301 ydl
= YDL({'format': '[filesize<1M]'})
302 ydl
.process_ie_result(info_dict
)
303 downloaded
= ydl
.downloaded_info_dicts
[0]
304 self
.assertEqual(downloaded
['format_id'], 'E')
306 ydl
= YDL({'format': '[filesize<1MiB]'})
307 ydl
.process_ie_result(info_dict
)
308 downloaded
= ydl
.downloaded_info_dicts
[0]
309 self
.assertEqual(downloaded
['format_id'], 'G')
312 class TestYoutubeDL(unittest
.TestCase
):
313 def test_subtitles(self
):
314 def s_formats(lang
, autocaption
=False):
317 'url': 'http://localhost/video.%s.%s' % (lang
, ext
),
318 '_auto': autocaption
,
319 } for ext
in ['vtt', 'srt', 'ass']]
320 subtitles
= dict((l
, s_formats(l
)) for l
in ['en', 'fr', 'es'])
321 auto_captions
= dict((l
, s_formats(l
, True)) for l
in ['it', 'pt', 'es'])
325 'url': 'http://localhost/video.mp4',
326 'subtitles': subtitles
,
327 'automatic_captions': auto_captions
,
331 def get_info(params
={}):
332 params
.setdefault('simulate', True)
334 ydl
.report_warning
= lambda *args
, **kargs
: None
335 return ydl
.process_video_result(info_dict
, download
=False)
338 self
.assertFalse(result
.get('requested_subtitles'))
339 self
.assertEqual(result
['subtitles'], subtitles
)
340 self
.assertEqual(result
['automatic_captions'], auto_captions
)
342 result
= get_info({'writesubtitles': True})
343 subs
= result
['requested_subtitles']
344 self
.assertTrue(subs
)
345 self
.assertEqual(set(subs
.keys()), set(['en']))
346 self
.assertTrue(subs
['en'].get('data') is None)
347 self
.assertEqual(subs
['en']['ext'], 'ass')
349 result
= get_info({'writesubtitles': True, 'subtitlesformat': 'foo/srt'})
350 subs
= result
['requested_subtitles']
351 self
.assertEqual(subs
['en']['ext'], 'srt')
353 result
= get_info({'writesubtitles': True, 'subtitleslangs': ['es', 'fr', 'it']})
354 subs
= result
['requested_subtitles']
355 self
.assertTrue(subs
)
356 self
.assertEqual(set(subs
.keys()), set(['es', 'fr']))
358 result
= get_info({'writesubtitles': True, 'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']})
359 subs
= result
['requested_subtitles']
360 self
.assertTrue(subs
)
361 self
.assertEqual(set(subs
.keys()), set(['es', 'pt']))
362 self
.assertFalse(subs
['es']['_auto'])
363 self
.assertTrue(subs
['pt']['_auto'])
365 result
= get_info({'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']})
366 subs
= result
['requested_subtitles']
367 self
.assertTrue(subs
)
368 self
.assertEqual(set(subs
.keys()), set(['es', 'pt']))
369 self
.assertTrue(subs
['es']['_auto'])
370 self
.assertTrue(subs
['pt']['_auto'])
372 def test_add_extra_info(self
):
378 'playlist': 'funny videos',
380 YDL
.add_extra_info(test_dict
, extra_info
)
381 self
.assertEqual(test_dict
['extractor'], 'Foo')
382 self
.assertEqual(test_dict
['playlist'], 'funny videos')
384 def test_prepare_filename(self
):
392 ydl
= YoutubeDL({'outtmpl': templ
})
393 return ydl
.prepare_filename(info
)
394 self
.assertEqual(fname('%(id)s.%(ext)s'), '1234.mp4')
395 self
.assertEqual(fname('%(id)s-%(width)s.%(ext)s'), '1234-NA.mp4')
396 # Replace missing fields with 'NA'
397 self
.assertEqual(fname('%(uploader_date)s-%(id)s.%(ext)s'), 'NA-1234.mp4')
399 def test_format_note(self
):
401 self
.assertEqual(ydl
._format
_note
({}), '')
402 assertRegexpMatches(self
, ydl
._format
_note
({
406 def test_postprocessors(self
):
407 filename
= 'post-processor-testfile.mp4'
408 audiofile
= filename
+ '.mp3'
410 class SimplePP(PostProcessor
):
412 with open(audiofile
, 'wt') as f
:
414 return [info
['filepath']], info
416 def run_pp(params
, PP
):
417 with open(filename
, 'wt') as f
:
419 ydl
= YoutubeDL(params
)
420 ydl
.add_post_processor(PP())
421 ydl
.post_process(filename
, {'filepath': filename
})
423 run_pp({'keepvideo': True}, SimplePP
)
424 self
.assertTrue(os
.path
.exists(filename
), '%s doesn\'t exist' % filename
)
425 self
.assertTrue(os
.path
.exists(audiofile
), '%s doesn\'t exist' % audiofile
)
429 run_pp({'keepvideo': False}, SimplePP
)
430 self
.assertFalse(os
.path
.exists(filename
), '%s exists' % filename
)
431 self
.assertTrue(os
.path
.exists(audiofile
), '%s doesn\'t exist' % audiofile
)
434 class ModifierPP(PostProcessor
):
436 with open(info
['filepath'], 'wt') as f
:
440 run_pp({'keepvideo': False}, ModifierPP
)
441 self
.assertTrue(os
.path
.exists(filename
), '%s doesn\'t exist' % filename
)
444 def test_match_filter(self
):
445 class FilterYDL(YDL
):
446 def __init__(self
, *args
, **kwargs
):
447 super(FilterYDL
, self
).__init
__(*args
, **kwargs
)
448 self
.params
['simulate'] = True
450 def process_info(self
, info_dict
):
451 super(YDL
, self
).process_info(info_dict
)
453 def _match_entry(self
, info_dict
, incomplete
):
454 res
= super(FilterYDL
, self
)._match
_entry
(info_dict
, incomplete
)
456 self
.downloaded_info_dicts
.append(info_dict
)
465 'filesize': 10 * 1024,
473 'description': 'foo',
474 'filesize': 5 * 1024,
476 videos
= [first
, second
]
478 def get_videos(filter_
=None):
479 ydl
= FilterYDL({'match_filter': filter_
})
481 ydl
.process_ie_result(v
, download
=True)
482 return [v
['id'] for v
in ydl
.downloaded_info_dicts
]
485 self
.assertEqual(res
, ['1', '2'])
491 return 'Video id is not 1'
493 self
.assertEqual(res
, ['1'])
495 f
= match_filter_func('duration < 30')
497 self
.assertEqual(res
, ['2'])
499 f
= match_filter_func('description = foo')
501 self
.assertEqual(res
, ['2'])
503 f
= match_filter_func('description =? foo')
505 self
.assertEqual(res
, ['1', '2'])
507 f
= match_filter_func('filesize > 5KiB')
509 self
.assertEqual(res
, ['1'])
511 def test_playlist_items_selection(self
):
514 'title': compat_str(i
),
516 } for i
in range(1, 5)]
521 'extractor': 'test:playlist',
522 'extractor_key': 'test:playlist',
523 'webpage_url': 'http://example.com',
528 # make a copy because the dictionary can be modified
529 ydl
.process_ie_result(playlist
.copy())
530 return [int(v
['id']) for v
in ydl
.downloaded_info_dicts
]
533 self
.assertEqual(result
, [1, 2, 3, 4])
535 result
= get_ids({'playlistend': 10})
536 self
.assertEqual(result
, [1, 2, 3, 4])
538 result
= get_ids({'playlistend': 2})
539 self
.assertEqual(result
, [1, 2])
541 result
= get_ids({'playliststart': 10})
542 self
.assertEqual(result
, [])
544 result
= get_ids({'playliststart': 2})
545 self
.assertEqual(result
, [2, 3, 4])
547 result
= get_ids({'playlist_items': '2-4'})
548 self
.assertEqual(result
, [2, 3, 4])
550 result
= get_ids({'playlist_items': '2,4'})
551 self
.assertEqual(result
, [2, 4])
553 result
= get_ids({'playlist_items': '10'})
554 self
.assertEqual(result
, [])
557 if __name__
== '__main__':