diff --git a/yt_dlp/postprocessor/ffmpeg.py b/yt_dlp/postprocessor/ffmpeg.py index a5ed6d184..0b18e8774 100644 --- a/yt_dlp/postprocessor/ffmpeg.py +++ b/yt_dlp/postprocessor/ffmpeg.py @@ -86,13 +86,18 @@ def get_versions_and_features(downloader=None): @staticmethod def get_versions(downloader=None): - return FFmpegPostProcessor.get_version_and_features(downloader)[0] + return FFmpegPostProcessor.get_versions_and_features(downloader)[0] + + _version_cache, _features_cache = {}, {} def _determine_executables(self): programs = ['avprobe', 'avconv', 'ffmpeg', 'ffprobe'] def get_ffmpeg_version(path, prog): - out = _get_exe_version_output(path, ['-bsfs']) + if path in self._version_cache: + self._versions[path], self._features = self._version_cache[path], self._features_cache.get(path, {}) + return + out = _get_exe_version_output(path, ['-bsfs'], to_screen=self.write_debug) ver = detect_exe_version(out) if out else False if ver: regexs = [ @@ -104,13 +109,13 @@ def get_ffmpeg_version(path, prog): mobj = re.match(regex, ver) if mobj: ver = mobj.group(1) - self._versions[prog] = ver + self._versions[prog] = self._version_cache[path] = ver if prog != 'ffmpeg' or not out: return mobj = re.search(r'(?m)^\s+libavformat\s+(?:[0-9. ]+)\s+/\s+(?P[0-9. ]+)', out) lavf_runtime_version = mobj.group('runtime').replace(' ', '') if mobj else None - self._features = { + self._features = self._features_cache[path] = { 'fdk': '--enable-libfdk-aac' in out, 'setts': 'setts' in out.splitlines(), 'needs_adtstoasc': is_outdated_version(lavf_runtime_version, '57.56.100', False), @@ -148,26 +153,15 @@ def get_ffmpeg_version(path, prog): self._paths[basename] = location self._versions = {} - for p in programs: - get_ffmpeg_version(self._paths[p], p) - + executables = {'basename': ('ffmpeg', 'avconv'), 'probe_basename': ('ffprobe', 'avprobe')} if prefer_ffmpeg is False: - prefs = ('avconv', 'ffmpeg') - else: - prefs = ('ffmpeg', 'avconv') - for p in prefs: - if self._versions[p]: - self.basename = p - break - - if prefer_ffmpeg is False: - prefs = ('avprobe', 'ffprobe') - else: - prefs = ('ffprobe', 'avprobe') - for p in prefs: - if self._versions[p]: - self.probe_basename = p - break + executables = {k: v[::-1] for k, v in executables.items()} + for var, prefs in executables.items(): + for p in prefs: + get_ffmpeg_version(self._paths[p], p) + if self._versions[p]: + setattr(self, var, p) + break if self.basename == 'avconv': self.deprecation_warning( diff --git a/yt_dlp/utils.py b/yt_dlp/utils.py index 08e30d18f..62a1800d4 100644 --- a/yt_dlp/utils.py +++ b/yt_dlp/utils.py @@ -2713,7 +2713,9 @@ def check_executable(exe, args=[]): return exe -def _get_exe_version_output(exe, args): +def _get_exe_version_output(exe, args, *, to_screen=None): + if to_screen: + to_screen(f'Checking exe version: {shell_quote([exe] + args)}') try: # STDIN should be redirected too. On UNIX-like systems, ffmpeg triggers # SIGTTOU if yt-dlp is run in the background.