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