Revert "Workaround for regex engine limitation"
[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_format_selection_video(self):
186         formats = [
187             {'format_id': 'dash-video-low', 'ext': 'mp4', 'preference': 1, 'acodec': 'none'},
188             {'format_id': 'dash-video-high', 'ext': 'mp4', 'preference': 2, 'acodec': 'none'},
189             {'format_id': 'vid', 'ext': 'mp4', 'preference': 3},
190         ]
191         info_dict = {'formats': formats, 'extractor': 'test'}
192
193         ydl = YDL({'format': 'bestvideo'})
194         ydl.process_ie_result(info_dict.copy())
195         downloaded = ydl.downloaded_info_dicts[0]
196         self.assertEqual(downloaded['format_id'], 'dash-video-high')
197
198         ydl = YDL({'format': 'worstvideo'})
199         ydl.process_ie_result(info_dict.copy())
200         downloaded = ydl.downloaded_info_dicts[0]
201         self.assertEqual(downloaded['format_id'], 'dash-video-low')
202
203     def test_youtube_format_selection(self):
204         order = [
205             '38', '37', '46', '22', '45', '35', '44', '18', '34', '43', '6', '5', '36', '17', '13',
206             # Apple HTTP Live Streaming
207             '96', '95', '94', '93', '92', '132', '151',
208             # 3D
209             '85', '84', '102', '83', '101', '82', '100',
210             # Dash video
211             '138', '137', '248', '136', '247', '135', '246',
212             '245', '244', '134', '243', '133', '242', '160',
213             # Dash audio
214             '141', '172', '140', '139', '171',
215         ]
216
217         for f1id, f2id in zip(order, order[1:]):
218             f1 = YoutubeIE._formats[f1id].copy()
219             f1['format_id'] = f1id
220             f2 = YoutubeIE._formats[f2id].copy()
221             f2['format_id'] = f2id
222
223             info_dict = {'formats': [f1, f2], 'extractor': 'youtube'}
224             ydl = YDL()
225             yie = YoutubeIE(ydl)
226             yie._sort_formats(info_dict['formats'])
227             ydl.process_ie_result(info_dict)
228             downloaded = ydl.downloaded_info_dicts[0]
229             self.assertEqual(downloaded['format_id'], f1id)
230
231             info_dict = {'formats': [f2, f1], 'extractor': 'youtube'}
232             ydl = YDL()
233             yie = YoutubeIE(ydl)
234             yie._sort_formats(info_dict['formats'])
235             ydl.process_ie_result(info_dict)
236             downloaded = ydl.downloaded_info_dicts[0]
237             self.assertEqual(downloaded['format_id'], f1id)
238
239     def test_add_extra_info(self):
240         test_dict = {
241             'extractor': 'Foo',
242         }
243         extra_info = {
244             'extractor': 'Bar',
245             'playlist': 'funny videos',
246         }
247         YDL.add_extra_info(test_dict, extra_info)
248         self.assertEqual(test_dict['extractor'], 'Foo')
249         self.assertEqual(test_dict['playlist'], 'funny videos')
250
251     def test_prepare_filename(self):
252         info = {
253             'id': '1234',
254             'ext': 'mp4',
255             'width': None,
256         }
257         def fname(templ):
258             ydl = YoutubeDL({'outtmpl': templ})
259             return ydl.prepare_filename(info)
260         self.assertEqual(fname('%(id)s.%(ext)s'), '1234.mp4')
261         self.assertEqual(fname('%(id)s-%(width)s.%(ext)s'), '1234-NA.mp4')
262         # Replace missing fields with 'NA'
263         self.assertEqual(fname('%(uploader_date)s-%(id)s.%(ext)s'), 'NA-1234.mp4')
264
265
266 if __name__ == '__main__':
267     unittest.main()