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
, compat_urllib_error
16 from youtube_dl
.extractor
import YoutubeIE
17 from youtube_dl
.extractor
.common
import InfoExtractor
18 from youtube_dl
.postprocessor
.common
import PostProcessor
19 from youtube_dl
.utils
import ExtractorError
, match_filter_func
21 TEST_URL
= 'http://localhost/sample.mp4'
25 def __init__(self
, *args
, **kwargs
):
26 super(YDL
, self
).__init
__(*args
, **kwargs
)
27 self
.downloaded_info_dicts
= []
30 def process_info(self
, info_dict
):
31 self
.downloaded_info_dicts
.append(info_dict
)
33 def to_screen(self
, msg
):
37 def _make_result(formats
, **kwargs
):
41 'title': 'testttitle',
42 'extractor': 'testex',
48 class TestFormatSelection(unittest
.TestCase
):
49 def test_prefer_free_formats(self
):
50 # Same resolution => download webm
52 ydl
.params
['prefer_free_formats'] = True
54 {'ext': 'webm', 'height': 460, 'url': TEST_URL}
,
55 {'ext': 'mp4', 'height': 460, 'url': TEST_URL}
,
57 info_dict
= _make_result(formats
)
59 yie
._sort
_formats
(info_dict
['formats'])
60 ydl
.process_ie_result(info_dict
)
61 downloaded
= ydl
.downloaded_info_dicts
[0]
62 self
.assertEqual(downloaded
['ext'], 'webm')
64 # Different resolution => download best quality (mp4)
66 ydl
.params
['prefer_free_formats'] = True
68 {'ext': 'webm', 'height': 720, 'url': TEST_URL}
,
69 {'ext': 'mp4', 'height': 1080, 'url': TEST_URL}
,
71 info_dict
['formats'] = formats
73 yie
._sort
_formats
(info_dict
['formats'])
74 ydl
.process_ie_result(info_dict
)
75 downloaded
= ydl
.downloaded_info_dicts
[0]
76 self
.assertEqual(downloaded
['ext'], 'mp4')
78 # No prefer_free_formats => prefer mp4 and flv for greater compatibility
80 ydl
.params
['prefer_free_formats'] = False
82 {'ext': 'webm', 'height': 720, 'url': TEST_URL}
,
83 {'ext': 'mp4', 'height': 720, 'url': TEST_URL}
,
84 {'ext': 'flv', 'height': 720, 'url': TEST_URL}
,
86 info_dict
['formats'] = formats
88 yie
._sort
_formats
(info_dict
['formats'])
89 ydl
.process_ie_result(info_dict
)
90 downloaded
= ydl
.downloaded_info_dicts
[0]
91 self
.assertEqual(downloaded
['ext'], 'mp4')
94 ydl
.params
['prefer_free_formats'] = False
96 {'ext': 'flv', 'height': 720, 'url': TEST_URL}
,
97 {'ext': 'webm', 'height': 720, 'url': TEST_URL}
,
99 info_dict
['formats'] = formats
101 yie
._sort
_formats
(info_dict
['formats'])
102 ydl
.process_ie_result(info_dict
)
103 downloaded
= ydl
.downloaded_info_dicts
[0]
104 self
.assertEqual(downloaded
['ext'], 'flv')
106 def test_format_selection(self
):
108 {'format_id': '35', 'ext': 'mp4', 'preference': 1, 'url': TEST_URL}
,
109 {'format_id': 'example-with-dashes', 'ext': 'webm', 'preference': 1, 'url': TEST_URL}
,
110 {'format_id': '45', 'ext': 'webm', 'preference': 2, 'url': TEST_URL}
,
111 {'format_id': '47', 'ext': 'webm', 'preference': 3, 'url': TEST_URL}
,
112 {'format_id': '2', 'ext': 'flv', 'preference': 4, 'url': TEST_URL}
,
114 info_dict
= _make_result(formats
)
116 ydl
= YDL({'format': '20/47'}
)
117 ydl
.process_ie_result(info_dict
.copy())
118 downloaded
= ydl
.downloaded_info_dicts
[0]
119 self
.assertEqual(downloaded
['format_id'], '47')
121 ydl
= YDL({'format': '20/71/worst'}
)
122 ydl
.process_ie_result(info_dict
.copy())
123 downloaded
= ydl
.downloaded_info_dicts
[0]
124 self
.assertEqual(downloaded
['format_id'], '35')
127 ydl
.process_ie_result(info_dict
.copy())
128 downloaded
= ydl
.downloaded_info_dicts
[0]
129 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')
136 ydl
= YDL({'format': '3gp/40/mp4'}
)
137 ydl
.process_ie_result(info_dict
.copy())
138 downloaded
= ydl
.downloaded_info_dicts
[0]
139 self
.assertEqual(downloaded
['format_id'], '35')
141 ydl
= YDL({'format': 'example-with-dashes'}
)
142 ydl
.process_ie_result(info_dict
.copy())
143 downloaded
= ydl
.downloaded_info_dicts
[0]
144 self
.assertEqual(downloaded
['format_id'], 'example-with-dashes')
146 def test_format_selection_audio(self
):
148 {'format_id': 'audio-low', 'ext': 'webm', 'preference': 1, 'vcodec': 'none', 'url': TEST_URL}
,
149 {'format_id': 'audio-mid', 'ext': 'webm', 'preference': 2, 'vcodec': 'none', 'url': TEST_URL}
,
150 {'format_id': 'audio-high', 'ext': 'flv', 'preference': 3, 'vcodec': 'none', 'url': TEST_URL}
,
151 {'format_id': 'vid', 'ext': 'mp4', 'preference': 4, 'url': TEST_URL}
,
153 info_dict
= _make_result(formats
)
155 ydl
= YDL({'format': 'bestaudio'}
)
156 ydl
.process_ie_result(info_dict
.copy())
157 downloaded
= ydl
.downloaded_info_dicts
[0]
158 self
.assertEqual(downloaded
['format_id'], 'audio-high')
160 ydl
= YDL({'format': 'worstaudio'}
)
161 ydl
.process_ie_result(info_dict
.copy())
162 downloaded
= ydl
.downloaded_info_dicts
[0]
163 self
.assertEqual(downloaded
['format_id'], 'audio-low')
166 {'format_id': 'vid-low', 'ext': 'mp4', 'preference': 1, 'url': TEST_URL}
,
167 {'format_id': 'vid-high', 'ext': 'mp4', 'preference': 2, 'url': TEST_URL}
,
169 info_dict
= _make_result(formats
)
171 ydl
= YDL({'format': 'bestaudio/worstaudio/best'}
)
172 ydl
.process_ie_result(info_dict
.copy())
173 downloaded
= ydl
.downloaded_info_dicts
[0]
174 self
.assertEqual(downloaded
['format_id'], 'vid-high')
176 def test_format_selection_audio_exts(self
):
178 {'format_id': 'mp3-64', 'ext': 'mp3', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'}
,
179 {'format_id': 'ogg-64', 'ext': 'ogg', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'}
,
180 {'format_id': 'aac-64', 'ext': 'aac', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'}
,
181 {'format_id': 'mp3-32', 'ext': 'mp3', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'}
,
182 {'format_id': 'aac-32', 'ext': 'aac', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'}
,
185 info_dict
= _make_result(formats
)
186 ydl
= YDL({'format': 'best'}
)
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'], 'aac-64')
193 ydl
= YDL({'format': 'mp3'}
)
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'], 'mp3-64')
200 ydl
= YDL({'prefer_free_formats': True}
)
202 ie
._sort
_formats
(info_dict
['formats'])
203 ydl
.process_ie_result(copy
.deepcopy(info_dict
))
204 downloaded
= ydl
.downloaded_info_dicts
[0]
205 self
.assertEqual(downloaded
['format_id'], 'ogg-64')
207 def test_format_selection_video(self
):
209 {'format_id': 'dash-video-low', 'ext': 'mp4', 'preference': 1, 'acodec': 'none', 'url': TEST_URL}
,
210 {'format_id': 'dash-video-high', 'ext': 'mp4', 'preference': 2, 'acodec': 'none', 'url': TEST_URL}
,
211 {'format_id': 'vid', 'ext': 'mp4', 'preference': 3, 'url': TEST_URL}
,
213 info_dict
= _make_result(formats
)
215 ydl
= YDL({'format': 'bestvideo'}
)
216 ydl
.process_ie_result(info_dict
.copy())
217 downloaded
= ydl
.downloaded_info_dicts
[0]
218 self
.assertEqual(downloaded
['format_id'], 'dash-video-high')
220 ydl
= YDL({'format': 'worstvideo'}
)
221 ydl
.process_ie_result(info_dict
.copy())
222 downloaded
= ydl
.downloaded_info_dicts
[0]
223 self
.assertEqual(downloaded
['format_id'], 'dash-video-low')
226 {'format_id': 'vid-vcodec-dot', 'ext': 'mp4', 'preference': 1, 'vcodec': 'avc1.123456', 'acodec': 'none', 'url': TEST_URL}
,
228 info_dict
= _make_result(formats
)
230 ydl
= YDL({'format': 'bestvideo[vcodec=avc1.123456]'}
)
231 ydl
.process_ie_result(info_dict
.copy())
232 downloaded
= ydl
.downloaded_info_dicts
[0]
233 self
.assertEqual(downloaded
['format_id'], 'vid-vcodec-dot')
235 def test_youtube_format_selection(self
):
237 '38', '37', '46', '22', '45', '35', '44', '18', '34', '43', '6', '5', '17', '36', '13',
238 # Apple HTTP Live Streaming
239 '96', '95', '94', '93', '92', '132', '151',
241 '85', '84', '102', '83', '101', '82', '100',
243 '137', '248', '136', '247', '135', '246',
244 '245', '244', '134', '243', '133', '242', '160',
246 '141', '172', '140', '171', '139',
249 def format_info(f_id
):
250 info
= YoutubeIE
._formats
[f_id
].copy()
252 # XXX: In real cases InfoExtractor._parse_mpd_formats() fills up 'acodec'
253 # and 'vcodec', while in tests such information is incomplete since
254 # commit a6c2c24479e5f4827ceb06f64d855329c0a6f593
255 # test_YoutubeDL.test_youtube_format_selection is broken without
257 if 'acodec' in info
and 'vcodec' not in info
:
258 info
['vcodec'] = 'none'
259 elif 'vcodec' in info
and 'acodec' not in info
:
260 info
['acodec'] = 'none'
262 info
['format_id'] = f_id
263 info
['url'] = 'url:' + f_id
265 formats_order
= [format_info(f_id
) for f_id
in order
]
267 info_dict
= _make_result(list(formats_order
), extractor
='youtube')
268 ydl
= YDL({'format': 'bestvideo+bestaudio'}
)
270 yie
._sort
_formats
(info_dict
['formats'])
271 ydl
.process_ie_result(info_dict
)
272 downloaded
= ydl
.downloaded_info_dicts
[0]
273 self
.assertEqual(downloaded
['format_id'], '137+141')
274 self
.assertEqual(downloaded
['ext'], 'mp4')
276 info_dict
= _make_result(list(formats_order
), extractor
='youtube')
277 ydl
= YDL({'format': 'bestvideo[height>=999999]+bestaudio/best'}
)
279 yie
._sort
_formats
(info_dict
['formats'])
280 ydl
.process_ie_result(info_dict
)
281 downloaded
= ydl
.downloaded_info_dicts
[0]
282 self
.assertEqual(downloaded
['format_id'], '38')
284 info_dict
= _make_result(list(formats_order
), extractor
='youtube')
285 ydl
= YDL({'format': 'bestvideo/best,bestaudio'}
)
287 yie
._sort
_formats
(info_dict
['formats'])
288 ydl
.process_ie_result(info_dict
)
289 downloaded_ids
= [info
['format_id'] for info
in ydl
.downloaded_info_dicts
]
290 self
.assertEqual(downloaded_ids
, ['137', '141'])
292 info_dict
= _make_result(list(formats_order
), extractor
='youtube')
293 ydl
= YDL({'format': '(bestvideo[ext=mp4],bestvideo[ext=webm])+bestaudio'}
)
295 yie
._sort
_formats
(info_dict
['formats'])
296 ydl
.process_ie_result(info_dict
)
297 downloaded_ids
= [info
['format_id'] for info
in ydl
.downloaded_info_dicts
]
298 self
.assertEqual(downloaded_ids
, ['137+141', '248+141'])
300 info_dict
= _make_result(list(formats_order
), extractor
='youtube')
301 ydl
= YDL({'format': '(bestvideo[ext=mp4],bestvideo[ext=webm])[height<=720]+bestaudio'}
)
303 yie
._sort
_formats
(info_dict
['formats'])
304 ydl
.process_ie_result(info_dict
)
305 downloaded_ids
= [info
['format_id'] for info
in ydl
.downloaded_info_dicts
]
306 self
.assertEqual(downloaded_ids
, ['136+141', '247+141'])
308 info_dict
= _make_result(list(formats_order
), extractor
='youtube')
309 ydl
= YDL({'format': '(bestvideo[ext=none]/bestvideo[ext=webm])+bestaudio'}
)
311 yie
._sort
_formats
(info_dict
['formats'])
312 ydl
.process_ie_result(info_dict
)
313 downloaded_ids
= [info
['format_id'] for info
in ydl
.downloaded_info_dicts
]
314 self
.assertEqual(downloaded_ids
, ['248+141'])
316 for f1
, f2
in zip(formats_order
, formats_order
[1:]):
317 info_dict
= _make_result([f1
, f2
], extractor
='youtube')
318 ydl
= YDL({'format': 'best/bestvideo'}
)
320 yie
._sort
_formats
(info_dict
['formats'])
321 ydl
.process_ie_result(info_dict
)
322 downloaded
= ydl
.downloaded_info_dicts
[0]
323 self
.assertEqual(downloaded
['format_id'], f1
['format_id'])
325 info_dict
= _make_result([f2
, f1
], extractor
='youtube')
326 ydl
= YDL({'format': 'best/bestvideo'}
)
328 yie
._sort
_formats
(info_dict
['formats'])
329 ydl
.process_ie_result(info_dict
)
330 downloaded
= ydl
.downloaded_info_dicts
[0]
331 self
.assertEqual(downloaded
['format_id'], f1
['format_id'])
333 def test_invalid_format_specs(self
):
334 def assert_syntax_error(format_spec
):
335 ydl
= YDL({'format': format_spec}
)
336 info_dict
= _make_result([{'format_id': 'foo', 'url': TEST_URL}
])
337 self
.assertRaises(SyntaxError, ydl
.process_ie_result
, info_dict
)
339 assert_syntax_error('bestvideo,,best')
340 assert_syntax_error('+bestaudio')
341 assert_syntax_error('bestvideo+')
342 assert_syntax_error('/')
344 def test_format_filtering(self
):
346 {'format_id': 'A', 'filesize': 500, 'width': 1000}
,
347 {'format_id': 'B', 'filesize': 1000, 'width': 500}
,
348 {'format_id': 'C', 'filesize': 1000, 'width': 400}
,
349 {'format_id': 'D', 'filesize': 2000, 'width': 600}
,
350 {'format_id': 'E', 'filesize': 3000}
,
352 {'format_id': 'G', 'filesize': 1000000}
,
355 f
['url'] = 'http://_/'
357 info_dict
= _make_result(formats
)
359 ydl
= YDL({'format': 'best[filesize<3000]'}
)
360 ydl
.process_ie_result(info_dict
)
361 downloaded
= ydl
.downloaded_info_dicts
[0]
362 self
.assertEqual(downloaded
['format_id'], 'D')
364 ydl
= YDL({'format': 'best[filesize<=3000]'}
)
365 ydl
.process_ie_result(info_dict
)
366 downloaded
= ydl
.downloaded_info_dicts
[0]
367 self
.assertEqual(downloaded
['format_id'], 'E')
369 ydl
= YDL({'format': 'best[filesize <= ? 3000]'}
)
370 ydl
.process_ie_result(info_dict
)
371 downloaded
= ydl
.downloaded_info_dicts
[0]
372 self
.assertEqual(downloaded
['format_id'], 'F')
374 ydl
= YDL({'format': 'best [filesize = 1000] [width>450]'}
)
375 ydl
.process_ie_result(info_dict
)
376 downloaded
= ydl
.downloaded_info_dicts
[0]
377 self
.assertEqual(downloaded
['format_id'], 'B')
379 ydl
= YDL({'format': 'best [filesize = 1000] [width!=450]'}
)
380 ydl
.process_ie_result(info_dict
)
381 downloaded
= ydl
.downloaded_info_dicts
[0]
382 self
.assertEqual(downloaded
['format_id'], 'C')
384 ydl
= YDL({'format': '[filesize>?1]'}
)
385 ydl
.process_ie_result(info_dict
)
386 downloaded
= ydl
.downloaded_info_dicts
[0]
387 self
.assertEqual(downloaded
['format_id'], 'G')
389 ydl
= YDL({'format': '[filesize<1M]'}
)
390 ydl
.process_ie_result(info_dict
)
391 downloaded
= ydl
.downloaded_info_dicts
[0]
392 self
.assertEqual(downloaded
['format_id'], 'E')
394 ydl
= YDL({'format': '[filesize<1MiB]'}
)
395 ydl
.process_ie_result(info_dict
)
396 downloaded
= ydl
.downloaded_info_dicts
[0]
397 self
.assertEqual(downloaded
['format_id'], 'G')
399 ydl
= YDL({'format': 'all[width>=400][width<=600]'}
)
400 ydl
.process_ie_result(info_dict
)
401 downloaded_ids
= [info
['format_id'] for info
in ydl
.downloaded_info_dicts
]
402 self
.assertEqual(downloaded_ids
, ['B', 'C', 'D'])
404 ydl
= YDL({'format': 'best[height<40]'}
)
406 ydl
.process_ie_result(info_dict
)
407 except ExtractorError
:
409 self
.assertEqual(ydl
.downloaded_info_dicts
, [])
412 class TestYoutubeDL(unittest
.TestCase
):
413 def test_subtitles(self
):
414 def s_formats(lang
, autocaption
=False):
417 'url': 'http://localhost/video.%s.%s' % (lang
, ext
),
418 '_auto': autocaption
,
419 } for ext
in ['vtt', 'srt', 'ass']]
420 subtitles
= dict((l
, s_formats(l
)) for l
in ['en', 'fr', 'es'])
421 auto_captions
= dict((l
, s_formats(l
, True)) for l
in ['it', 'pt', 'es'])
425 'url': 'http://localhost/video.mp4',
426 'subtitles': subtitles
,
427 'automatic_captions': auto_captions
,
431 def get_info(params
={}):
432 params
.setdefault('simulate', True)
434 ydl
.report_warning
= lambda *args
, **kargs
: None
435 return ydl
.process_video_result(info_dict
, download
=False)
438 self
.assertFalse(result
.get('requested_subtitles'))
439 self
.assertEqual(result
['subtitles'], subtitles
)
440 self
.assertEqual(result
['automatic_captions'], auto_captions
)
442 result
= get_info({'writesubtitles': True}
)
443 subs
= result
['requested_subtitles']
444 self
.assertTrue(subs
)
445 self
.assertEqual(set(subs
.keys()), set(['en']))
446 self
.assertTrue(subs
['en'].get('data') is None)
447 self
.assertEqual(subs
['en']['ext'], 'ass')
449 result
= get_info({'writesubtitles': True, 'subtitlesformat': 'foo/srt'}
)
450 subs
= result
['requested_subtitles']
451 self
.assertEqual(subs
['en']['ext'], 'srt')
453 result
= get_info({'writesubtitles': True, 'subtitleslangs': ['es', 'fr', 'it']}
)
454 subs
= result
['requested_subtitles']
455 self
.assertTrue(subs
)
456 self
.assertEqual(set(subs
.keys()), set(['es', 'fr']))
458 result
= get_info({'writesubtitles': True, 'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']}
)
459 subs
= result
['requested_subtitles']
460 self
.assertTrue(subs
)
461 self
.assertEqual(set(subs
.keys()), set(['es', 'pt']))
462 self
.assertFalse(subs
['es']['_auto'])
463 self
.assertTrue(subs
['pt']['_auto'])
465 result
= get_info({'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']}
)
466 subs
= result
['requested_subtitles']
467 self
.assertTrue(subs
)
468 self
.assertEqual(set(subs
.keys()), set(['es', 'pt']))
469 self
.assertTrue(subs
['es']['_auto'])
470 self
.assertTrue(subs
['pt']['_auto'])
472 def test_add_extra_info(self
):
478 'playlist': 'funny videos',
480 YDL
.add_extra_info(test_dict
, extra_info
)
481 self
.assertEqual(test_dict
['extractor'], 'Foo')
482 self
.assertEqual(test_dict
['playlist'], 'funny videos')
484 def test_prepare_filename(self
):
492 ydl
= YoutubeDL({'outtmpl': templ}
)
493 return ydl
.prepare_filename(info
)
494 self
.assertEqual(fname('%(id)s.%(ext)s'), '1234.mp4')
495 self
.assertEqual(fname('%(id)s-%(width)s.%(ext)s'), '1234-NA.mp4')
496 # Replace missing fields with 'NA'
497 self
.assertEqual(fname('%(uploader_date)s-%(id)s.%(ext)s'), 'NA-1234.mp4')
499 def test_format_note(self
):
501 self
.assertEqual(ydl
._format
_note
({}), '')
502 assertRegexpMatches(self
, ydl
._format
_note
({
506 def test_postprocessors(self
):
507 filename
= 'post-processor-testfile.mp4'
508 audiofile
= filename
+ '.mp3'
510 class SimplePP(PostProcessor
):
512 with open(audiofile
, 'wt') as f
:
514 return [info
['filepath']], info
516 def run_pp(params
, PP
):
517 with open(filename
, 'wt') as f
:
519 ydl
= YoutubeDL(params
)
520 ydl
.add_post_processor(PP())
521 ydl
.post_process(filename
, {'filepath': filename}
)
523 run_pp({'keepvideo': True}
, SimplePP
)
524 self
.assertTrue(os
.path
.exists(filename
), '%s doesn\'t exist' % filename
)
525 self
.assertTrue(os
.path
.exists(audiofile
), '%s doesn\'t exist' % audiofile
)
529 run_pp({'keepvideo': False}
, SimplePP
)
530 self
.assertFalse(os
.path
.exists(filename
), '%s exists' % filename
)
531 self
.assertTrue(os
.path
.exists(audiofile
), '%s doesn\'t exist' % audiofile
)
534 class ModifierPP(PostProcessor
):
536 with open(info
['filepath'], 'wt') as f
:
540 run_pp({'keepvideo': False}
, ModifierPP
)
541 self
.assertTrue(os
.path
.exists(filename
), '%s doesn\'t exist' % filename
)
544 def test_match_filter(self
):
545 class FilterYDL(YDL
):
546 def __init__(self
, *args
, **kwargs
):
547 super(FilterYDL
, self
).__init
__(*args
, **kwargs
)
548 self
.params
['simulate'] = True
550 def process_info(self
, info_dict
):
551 super(YDL
, self
).process_info(info_dict
)
553 def _match_entry(self
, info_dict
, incomplete
):
554 res
= super(FilterYDL
, self
)._match
_entry
(info_dict
, incomplete
)
556 self
.downloaded_info_dicts
.append(info_dict
)
565 'filesize': 10 * 1024,
573 'description': 'foo',
574 'filesize': 5 * 1024,
576 videos
= [first
, second
]
578 def get_videos(filter_
=None):
579 ydl
= FilterYDL({'match_filter': filter_}
)
581 ydl
.process_ie_result(v
, download
=True)
582 return [v
['id'] for v
in ydl
.downloaded_info_dicts
]
585 self
.assertEqual(res
, ['1', '2'])
591 return 'Video id is not 1'
593 self
.assertEqual(res
, ['1'])
595 f
= match_filter_func('duration < 30')
597 self
.assertEqual(res
, ['2'])
599 f
= match_filter_func('description = foo')
601 self
.assertEqual(res
, ['2'])
603 f
= match_filter_func('description =? foo')
605 self
.assertEqual(res
, ['1', '2'])
607 f
= match_filter_func('filesize > 5KiB')
609 self
.assertEqual(res
, ['1'])
611 def test_playlist_items_selection(self
):
614 'title': compat_str(i
),
616 } for i
in range(1, 5)]
621 'extractor': 'test:playlist',
622 'extractor_key': 'test:playlist',
623 'webpage_url': 'http://example.com',
628 # make a copy because the dictionary can be modified
629 ydl
.process_ie_result(playlist
.copy())
630 return [int(v
['id']) for v
in ydl
.downloaded_info_dicts
]
633 self
.assertEqual(result
, [1, 2, 3, 4])
635 result
= get_ids({'playlistend': 10}
)
636 self
.assertEqual(result
, [1, 2, 3, 4])
638 result
= get_ids({'playlistend': 2}
)
639 self
.assertEqual(result
, [1, 2])
641 result
= get_ids({'playliststart': 10}
)
642 self
.assertEqual(result
, [])
644 result
= get_ids({'playliststart': 2}
)
645 self
.assertEqual(result
, [2, 3, 4])
647 result
= get_ids({'playlist_items': '2-4'}
)
648 self
.assertEqual(result
, [2, 3, 4])
650 result
= get_ids({'playlist_items': '2,4'}
)
651 self
.assertEqual(result
, [2, 4])
653 result
= get_ids({'playlist_items': '10'}
)
654 self
.assertEqual(result
, [])
656 def test_urlopen_no_file_protocol(self
):
657 # see https://github.com/rg3/youtube-dl/issues/8227
659 self
.assertRaises(compat_urllib_error
.URLError
, ydl
.urlopen
, 'file:///etc/passwd')
661 def test_do_not_override_ie_key_in_url_transparent(self
):
664 class Foo1IE(InfoExtractor
):
665 _VALID_URL
= r
'foo1:'
667 def _real_extract(self
, url
):
669 '_type': 'url_transparent',
674 class Foo2IE(InfoExtractor
):
675 _VALID_URL
= r
'foo2:'
677 def _real_extract(self
, url
):
684 class Foo3IE(InfoExtractor
):
685 _VALID_URL
= r
'foo3:'
687 def _real_extract(self
, url
):
688 return _make_result([{'url': TEST_URL}
])
690 ydl
.add_info_extractor(Foo1IE(ydl
))
691 ydl
.add_info_extractor(Foo2IE(ydl
))
692 ydl
.add_info_extractor(Foo3IE(ydl
))
693 ydl
.extract_info('foo1:')
694 downloaded
= ydl
.downloaded_info_dicts
[0]
695 self
.assertEqual(downloaded
['url'], TEST_URL
)
698 if __name__
== '__main__':