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