mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-30 22:25:19 +00:00 
			
		
		
		
	[YoutubeDL] format spec: Fix handling of '+' with '/'
'bestvideo+bestaudio/best' was incorrectly interpreted as 'bestvideo+(bestaudio/best)', so it would fail if 'bestaudio' doesn't exist instead of falling back to 'best'.
This commit is contained in:
		| @@ -245,6 +245,14 @@ class TestFormatSelection(unittest.TestCase): | |||||||
|         self.assertEqual(downloaded['format_id'], '137+141') |         self.assertEqual(downloaded['format_id'], '137+141') | ||||||
|         self.assertEqual(downloaded['ext'], 'mp4') |         self.assertEqual(downloaded['ext'], 'mp4') | ||||||
|  |  | ||||||
|  |         info_dict = _make_result(list(formats_order), extractor='youtube') | ||||||
|  |         ydl = YDL({'format': 'bestvideo[height>=999999]+bestaudio/best'}) | ||||||
|  |         yie = YoutubeIE(ydl) | ||||||
|  |         yie._sort_formats(info_dict['formats']) | ||||||
|  |         ydl.process_ie_result(info_dict) | ||||||
|  |         downloaded = ydl.downloaded_info_dicts[0] | ||||||
|  |         self.assertEqual(downloaded['format_id'], '38') | ||||||
|  |  | ||||||
|         info_dict = _make_result(list(formats_order), extractor='youtube') |         info_dict = _make_result(list(formats_order), extractor='youtube') | ||||||
|         ydl = YDL({'format': '(bestvideo[ext=mp4],bestvideo[ext=webm])+bestaudio'}) |         ydl = YDL({'format': '(bestvideo[ext=mp4],bestvideo[ext=webm])+bestaudio'}) | ||||||
|         yie = YoutubeIE(ydl) |         yie = YoutubeIE(ydl) | ||||||
|   | |||||||
| @@ -931,7 +931,7 @@ class YoutubeDL(object): | |||||||
|                 else: |                 else: | ||||||
|                     filter_parts.append(string) |                     filter_parts.append(string) | ||||||
|  |  | ||||||
|         def _parse_format_selection(tokens, endwith=[]): |         def _parse_format_selection(tokens, inside_merge=False, inside_choice=False, inside_group=False): | ||||||
|             selectors = [] |             selectors = [] | ||||||
|             current_selector = None |             current_selector = None | ||||||
|             for type, string, start, _, _ in tokens: |             for type, string, start, _, _ in tokens: | ||||||
| @@ -941,18 +941,23 @@ class YoutubeDL(object): | |||||||
|                 elif type in [tokenize.NAME, tokenize.NUMBER]: |                 elif type in [tokenize.NAME, tokenize.NUMBER]: | ||||||
|                     current_selector = FormatSelector(SINGLE, string, []) |                     current_selector = FormatSelector(SINGLE, string, []) | ||||||
|                 elif type == tokenize.OP: |                 elif type == tokenize.OP: | ||||||
|                     if string in endwith: |                     if string == ')': | ||||||
|  |                         if not inside_group: | ||||||
|  |                             # ')' will be handled by the parentheses group | ||||||
|  |                             tokens.restore_last_token() | ||||||
|                         break |                         break | ||||||
|                     elif string == ')': |                     elif inside_merge and string in ['/', ',']: | ||||||
|                         # ')' will be handled by the parentheses group |  | ||||||
|                         tokens.restore_last_token() |                         tokens.restore_last_token() | ||||||
|                         break |                         break | ||||||
|                     if string == ',': |                     elif inside_choice and string == ',': | ||||||
|  |                         tokens.restore_last_token() | ||||||
|  |                         break | ||||||
|  |                     elif string == ',': | ||||||
|                         selectors.append(current_selector) |                         selectors.append(current_selector) | ||||||
|                         current_selector = None |                         current_selector = None | ||||||
|                     elif string == '/': |                     elif string == '/': | ||||||
|                         first_choice = current_selector |                         first_choice = current_selector | ||||||
|                         second_choice = _parse_format_selection(tokens, [',']) |                         second_choice = _parse_format_selection(tokens, inside_choice=True) | ||||||
|                         current_selector = None |                         current_selector = None | ||||||
|                         selectors.append(FormatSelector(PICKFIRST, (first_choice, second_choice), [])) |                         selectors.append(FormatSelector(PICKFIRST, (first_choice, second_choice), [])) | ||||||
|                     elif string == '[': |                     elif string == '[': | ||||||
| @@ -963,12 +968,12 @@ class YoutubeDL(object): | |||||||
|                     elif string == '(': |                     elif string == '(': | ||||||
|                         if current_selector: |                         if current_selector: | ||||||
|                             raise syntax_error('Unexpected "("', start) |                             raise syntax_error('Unexpected "("', start) | ||||||
|                         current_selector = FormatSelector(GROUP, _parse_format_selection(tokens, [')']), []) |                         group = _parse_format_selection(tokens, inside_group=True) | ||||||
|  |                         current_selector = FormatSelector(GROUP, group, []) | ||||||
|                     elif string == '+': |                     elif string == '+': | ||||||
|                         video_selector = current_selector |                         video_selector = current_selector | ||||||
|                         audio_selector = _parse_format_selection(tokens, [',']) |                         audio_selector = _parse_format_selection(tokens, inside_merge=True) | ||||||
|                         current_selector = None |                         current_selector = FormatSelector(MERGE, (video_selector, audio_selector), []) | ||||||
|                         selectors.append(FormatSelector(MERGE, (video_selector, audio_selector), [])) |  | ||||||
|                     else: |                     else: | ||||||
|                         raise syntax_error('Operator not recognized: "{0}"'.format(string), start) |                         raise syntax_error('Operator not recognized: "{0}"'.format(string), start) | ||||||
|                 elif type == tokenize.ENDMARKER: |                 elif type == tokenize.ENDMARKER: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jaime Marquínez Ferrándiz
					Jaime Marquínez Ferrándiz