Skip to content

Commit

Permalink
[core] Warn if lack of ffmpeg alters format selection (#9805)
Browse files Browse the repository at this point in the history
Authored by: seproDev, pukkandan
  • Loading branch information
seproDev authored May 4, 2024
1 parent bec9a59 commit 96da952
Showing 1 changed file with 33 additions and 22 deletions.
55 changes: 33 additions & 22 deletions yt_dlp/YoutubeDL.py
Original file line number Diff line number Diff line change
Expand Up @@ -2136,6 +2136,11 @@ def _filter(f):

def _check_formats(self, formats):
for f in formats:
working = f.get('__working')
if working is not None:
if working:
yield f
continue
self.to_screen('[info] Testing format %s' % f['format_id'])
path = self.get_output_path('temp')
if not self._ensure_dir_exists(f'{path}/'):
Expand All @@ -2152,33 +2157,44 @@ def _check_formats(self, formats):
os.remove(temp_file.name)
except OSError:
self.report_warning('Unable to delete temporary file "%s"' % temp_file.name)
f['__working'] = success
if success:
yield f
else:
self.to_screen('[info] Unable to download format %s. Skipping...' % f['format_id'])

def _select_formats(self, formats, selector):
return list(selector({
'formats': formats,
'has_merged_format': any('none' not in (f.get('acodec'), f.get('vcodec')) for f in formats),
'incomplete_formats': (all(f.get('vcodec') == 'none' for f in formats) # No formats with video
or all(f.get('acodec') == 'none' for f in formats)), # OR, No formats with audio
}))

def _default_format_spec(self, info_dict, download=True):
download = download and not self.params.get('simulate')

This comment has been minimized.

Copy link
@dirkf

dirkf May 4, 2024

Contributor

I would have omitted this line.

Per the relevant issue discussion it's an accidental oversight that the simulate parameter affects the default format selection and that behaviour should be corrected.

In case users of the API rely on the historic behaviour when download is falsy, that can be left in place, as it's always truthy in the CLI (at least it is upstream).

This comment has been minimized.

Copy link
@bashonly

bashonly May 4, 2024

Member

#9843 is still open; we are planning to deal with it in a separate PR

This comment has been minimized.

Copy link
@seproDev

seproDev May 4, 2024

Author Member

This commit was only for adding the warning if ffmpeg missing causes the format selection to differ. As such, the behaviour was left unchanged.

This comment has been minimized.

Copy link
@dirkf

dirkf May 4, 2024

Contributor

Thanks for the clarification.

prefer_best = download and (
self.params['outtmpl']['default'] == '-'
or info_dict.get('is_live') and not self.params.get('live_from_start'))

def can_merge():
merger = FFmpegMergerPP(self)
return merger.available and merger.can_merge()

prefer_best = (
not self.params.get('simulate')
and download
and (
not can_merge()
or info_dict.get('is_live') and not self.params.get('live_from_start')
or self.params['outtmpl']['default'] == '-'))
compat = (
prefer_best
or self.params.get('allow_multiple_audio_streams', False)
or 'format-spec' in self.params['compat_opts'])

return (
'best/bestvideo+bestaudio' if prefer_best
else 'bestvideo*+bestaudio/best' if not compat
else 'bestvideo+bestaudio/best')
if not prefer_best and download and not can_merge():
prefer_best = True
formats = self._get_formats(info_dict)
evaluate_formats = lambda spec: self._select_formats(formats, self.build_format_selector(spec))
if evaluate_formats('b/bv+ba') != evaluate_formats('bv*+ba/b'):
self.report_warning('ffmpeg not found. The downloaded format may not be the best available. '
'Installing ffmpeg is strongly recommended: https://github.com/yt-dlp/yt-dlp#dependencies')

compat = (self.params.get('allow_multiple_audio_streams')
or 'format-spec' in self.params['compat_opts'])

return ('best/bestvideo+bestaudio' if prefer_best
else 'bestvideo+bestaudio/best' if compat
else 'bestvideo*+bestaudio/best')

def build_format_selector(self, format_spec):
def syntax_error(note, start):
Expand Down Expand Up @@ -2928,12 +2944,7 @@ def is_wellformed(f):
self.write_debug(f'Default format spec: {req_format}')
format_selector = self.build_format_selector(req_format)

formats_to_download = list(format_selector({
'formats': formats,
'has_merged_format': any('none' not in (f.get('acodec'), f.get('vcodec')) for f in formats),
'incomplete_formats': (all(f.get('vcodec') == 'none' for f in formats) # No formats with video
or all(f.get('acodec') == 'none' for f in formats)), # OR, No formats with audio
}))
formats_to_download = self._select_formats(formats, format_selector)
if interactive_format_selection and not formats_to_download:
self.report_error('Requested format is not available', tb=False, is_error=False)
continue
Expand Down

0 comments on commit 96da952

Please sign in to comment.