X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=youtube_dl%2Fpostprocessor%2Fffmpeg.py;h=f3f2743c078db157c187114760fbf65f6587e662;hb=8c25f81beea169c9d6540eea1a6f71dc045da6ed;hp=867e75d80c36c2db91fc0f25ec16972d41ef1882;hpb=d28b5171541aaef568372a78384d6a5c862b2369;p=youtube-dl diff --git a/youtube_dl/postprocessor/ffmpeg.py b/youtube_dl/postprocessor/ffmpeg.py index 867e75d80..f3f2743c0 100644 --- a/youtube_dl/postprocessor/ffmpeg.py +++ b/youtube_dl/postprocessor/ffmpeg.py @@ -1,5 +1,4 @@ import os -import re import subprocess import sys import time @@ -7,11 +6,14 @@ import time from .common import AudioConversionError, PostProcessor -from ..utils import ( - check_executable, +from ..compat import ( compat_subprocess_get_DEVNULL, +) +from ..utils import ( encodeArgument, encodeFilename, + get_exe_version, + is_outdated_version, PostProcessingError, prepend_extension, shell_quote, @@ -19,23 +21,6 @@ from ..utils import ( ) -def get_version(executable): - """ Returns the version of the specified executable, - or False if the executable is not present """ - try: - out, err = subprocess.Popen( - [executable, '-version'], - stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() - except OSError: - return False - firstline = out.partition(b'\n')[0].decode('ascii', 'ignore') - m = re.search(r'version\s+([0-9._-a-zA-Z]+)', firstline) - if not m: - return u'present' - else: - return m.group(1) - - class FFmpegPostProcessorError(PostProcessingError): pass @@ -46,12 +31,25 @@ class FFmpegPostProcessor(PostProcessor): self._versions = self.get_versions() self._deletetempfiles = deletetempfiles + def check_version(self): + if not self._executable: + raise FFmpegPostProcessorError(u'ffmpeg or avconv not found. Please install one.') + + REQUIRED_VERSION = '1.0' + if is_outdated_version( + self._versions[self._executable], REQUIRED_VERSION): + warning = u'Your copy of %s is outdated, update %s to version %s or newer if you encounter any errors.' % ( + self._executable, self._executable, REQUIRED_VERSION) + if self._downloader: + self._downloader.report_warning(warning) + @staticmethod def get_versions(): programs = ['avprobe', 'avconv', 'ffmpeg', 'ffprobe'] - return dict((program, get_version(program)) for program in programs) + return dict((p, get_exe_version(p, args=['-version'])) for p in programs) - def _get_executable(self): + @property + def _executable(self): if self._downloader.params.get('prefer_ffmpeg', False): prefs = ('ffmpeg', 'avconv') else: @@ -61,17 +59,27 @@ class FFmpegPostProcessor(PostProcessor): return p return None + @property + def _probe_executable(self): + if self._downloader.params.get('prefer_ffmpeg', False): + prefs = ('ffprobe', 'avprobe') + else: + prefs = ('avprobe', 'ffprobe') + for p in prefs: + if self._versions[p]: + return p + return None + def _uses_avconv(self): - return self._get_executable() == 'avconv' + return self._executable == 'avconv' def run_ffmpeg_multiple_files(self, input_paths, out_path, opts): - if not self._get_executable(): - raise FFmpegPostProcessorError(u'ffmpeg or avconv not found. Please install one.') + self.check_version() files_cmd = [] for path in input_paths: files_cmd.extend(['-i', encodeFilename(path, True)]) - cmd = ([self._get_executable(), '-y'] + files_cmd + cmd = ([self._executable, '-y'] + files_cmd + [encodeArgument(o) for o in opts] + [encodeFilename(self._ffmpeg_filename_argument(out_path), True)]) @@ -107,11 +115,12 @@ class FFmpegExtractAudioPP(FFmpegPostProcessor): self._nopostoverwrites = nopostoverwrites def get_audio_codec(self, path): - if not self._exes['ffprobe'] and not self._exes['avprobe']: + + if not self._probe_executable: raise PostProcessingError(u'ffprobe or avprobe not found. Please install one.') try: cmd = [ - self._exes['avprobe'] or self._exes['ffprobe'], + self._probe_executable, '-show_streams', encodeFilename(self._ffmpeg_filename_argument(path), True)] handle = subprocess.Popen(cmd, stderr=compat_subprocess_get_DEVNULL(), stdout=subprocess.PIPE) @@ -204,14 +213,14 @@ class FFmpegExtractAudioPP(FFmpegPostProcessor): if self._nopostoverwrites and os.path.exists(encodeFilename(new_path)): self._downloader.to_screen(u'[youtube] Post-process file %s exists, skipping' % new_path) else: - self._downloader.to_screen(u'[' + self._get_executable() + '] Destination: ' + new_path) + self._downloader.to_screen(u'[' + self._executable + '] Destination: ' + new_path) self.run_ffmpeg(path, new_path, acodec, more_opts) except: etype,e,tb = sys.exc_info() if isinstance(e, AudioConversionError): msg = u'audio conversion failed: ' + e.msg else: - msg = u'error running ' + self._get_executable() + msg = u'error running ' + self._executable raise PostProcessingError(msg) # Try to update the date time for extracted audio file.