From d28b5171541aaef568372a78384d6a5c862b2369 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Sun, 26 Oct 2014 16:31:52 +0100 Subject: [PATCH] [YoutubeDL] Output avconv/ffmpeg versions if -v is given --- youtube_dl/YoutubeDL.py | 16 ++++++++++--- youtube_dl/postprocessor/__init__.py | 12 ++++++---- youtube_dl/postprocessor/ffmpeg.py | 34 +++++++++++++++++++++++----- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index 242affb5b..ecf426e37 100755 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -62,7 +62,7 @@ from .utils import ( from .cache import Cache from .extractor import get_info_extractor, gen_extractors from .downloader import get_suitable_downloader -from .postprocessor import FFmpegMergerPP +from .postprocessor import FFmpegMergerPP, FFmpegPostProcessor from .version import __version__ @@ -1311,8 +1311,18 @@ class YoutubeDL(object): sys.exc_clear() except: pass - self._write_string('[debug] Python version %s - %s' % - (platform.python_version(), platform_name()) + '\n') + self._write_string('[debug] Python version %s - %s\n' % ( + platform.python_version(), platform_name())) + + exe_versions = FFmpegPostProcessor.get_versions() + exe_str = ', '.join( + '%s %s' % (exe, v) + for exe, v in sorted(exe_versions.items()) + if v + ) + if not exe_str: + exe_str = 'none' + self._write_string('[debug] exe versions: %s\n' % exe_str) proxy_map = {} for handler in self._opener.handlers: diff --git a/youtube_dl/postprocessor/__init__.py b/youtube_dl/postprocessor/__init__.py index 15aa0daa9..6ac67cbae 100644 --- a/youtube_dl/postprocessor/__init__.py +++ b/youtube_dl/postprocessor/__init__.py @@ -1,24 +1,26 @@ from .atomicparsley import AtomicParsleyPP from .ffmpeg import ( + FFmpegPostProcessor, FFmpegAudioFixPP, + FFmpegEmbedSubtitlePP, + FFmpegExtractAudioPP, FFmpegMergerPP, FFmpegMetadataPP, FFmpegVideoConvertor, - FFmpegExtractAudioPP, - FFmpegEmbedSubtitlePP, ) from .xattrpp import XAttrMetadataPP from .execafterdownload import ExecAfterDownloadPP __all__ = [ 'AtomicParsleyPP', + 'ExecAfterDownloadPP', 'FFmpegAudioFixPP', + 'FFmpegEmbedSubtitlePP', + 'FFmpegExtractAudioPP', 'FFmpegMergerPP', 'FFmpegMetadataPP', + 'FFmpegPostProcessor', 'FFmpegVideoConvertor', - 'FFmpegExtractAudioPP', - 'FFmpegEmbedSubtitlePP', 'XAttrMetadataPP', - 'ExecAfterDownloadPP', ] diff --git a/youtube_dl/postprocessor/ffmpeg.py b/youtube_dl/postprocessor/ffmpeg.py index 6f010a9c7..867e75d80 100644 --- a/youtube_dl/postprocessor/ffmpeg.py +++ b/youtube_dl/postprocessor/ffmpeg.py @@ -1,4 +1,5 @@ import os +import re import subprocess import sys import time @@ -18,6 +19,23 @@ 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 @@ -25,22 +43,26 @@ class FFmpegPostProcessorError(PostProcessingError): class FFmpegPostProcessor(PostProcessor): def __init__(self, downloader=None, deletetempfiles=False): PostProcessor.__init__(self, downloader) - self._exes = self.detect_executables() + self._versions = self.get_versions() self._deletetempfiles = deletetempfiles @staticmethod - def detect_executables(): + def get_versions(): programs = ['avprobe', 'avconv', 'ffmpeg', 'ffprobe'] - return dict((program, check_executable(program, ['-version'])) for program in programs) + return dict((program, get_version(program)) for program in programs) def _get_executable(self): if self._downloader.params.get('prefer_ffmpeg', False): - return self._exes['ffmpeg'] or self._exes['avconv'] + prefs = ('ffmpeg', 'avconv') else: - return self._exes['avconv'] or self._exes['ffmpeg'] + prefs = ('avconv', 'ffmpeg') + for p in prefs: + if self._versions[p]: + return p + return None def _uses_avconv(self): - return self._get_executable() == self._exes['avconv'] + return self._get_executable() == 'avconv' def run_ffmpeg_multiple_files(self, input_paths, out_path, opts): if not self._get_executable():