diff options
| author | Jaime Marquínez Ferrándiz <jaime.marquinez.ferrandiz@gmail.com> | 2015-06-30 19:45:42 +0200 | 
|---|---|---|
| committer | Jaime Marquínez Ferrándiz <jaime.marquinez.ferrandiz@gmail.com> | 2015-06-30 19:50:17 +0200 | 
| commit | cf2ac6df6896dac4d23918867bb86fac1e1088d9 (patch) | |
| tree | e70ddc44a5dafe9a1b13c1c9aacd27e51da27d71 | |
| parent | 0130afb76e5cb6f470f39f127c8d09eea3e82d0d (diff) | |
[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'.
| -rw-r--r-- | test/test_YoutubeDL.py | 8 | ||||
| -rwxr-xr-x | youtube_dl/YoutubeDL.py | 25 | 
2 files changed, 23 insertions, 10 deletions
diff --git a/test/test_YoutubeDL.py b/test/test_YoutubeDL.py index 6f374d7ea..1e4aaa559 100644 --- a/test/test_YoutubeDL.py +++ b/test/test_YoutubeDL.py @@ -246,6 +246,14 @@ class TestFormatSelection(unittest.TestCase):          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')          ydl = YDL({'format': '(bestvideo[ext=mp4],bestvideo[ext=webm])+bestaudio'})          yie = YoutubeIE(ydl)          yie._sort_formats(info_dict['formats']) diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index e5b46f87e..5deb4848e 100755 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -931,7 +931,7 @@ class YoutubeDL(object):                  else:                      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 = []              current_selector = None              for type, string, start, _, _ in tokens: @@ -941,18 +941,23 @@ class YoutubeDL(object):                  elif type in [tokenize.NAME, tokenize.NUMBER]:                      current_selector = FormatSelector(SINGLE, string, [])                  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 -                    elif string == ')': -                        # ')' will be handled by the parentheses group +                    elif inside_merge and string in ['/', ',']:                          tokens.restore_last_token()                          break -                    if string == ',': +                    elif inside_choice and string == ',': +                        tokens.restore_last_token() +                        break +                    elif string == ',':                          selectors.append(current_selector)                          current_selector = None                      elif string == '/':                          first_choice = current_selector -                        second_choice = _parse_format_selection(tokens, [',']) +                        second_choice = _parse_format_selection(tokens, inside_choice=True)                          current_selector = None                          selectors.append(FormatSelector(PICKFIRST, (first_choice, second_choice), []))                      elif string == '[': @@ -963,12 +968,12 @@ class YoutubeDL(object):                      elif string == '(':                          if current_selector:                              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 == '+':                          video_selector = current_selector -                        audio_selector = _parse_format_selection(tokens, [',']) -                        current_selector = None -                        selectors.append(FormatSelector(MERGE, (video_selector, audio_selector), [])) +                        audio_selector = _parse_format_selection(tokens, inside_merge=True) +                        current_selector = FormatSelector(MERGE, (video_selector, audio_selector), [])                      else:                          raise syntax_error('Operator not recognized: "{0}"'.format(string), start)                  elif type == tokenize.ENDMARKER:  | 
