1
0
mirror of https://github.com/l1ving/youtube-dl synced 2025-02-13 19:02:52 +08:00

[postprocessor/ffmpeg] use json output format for ffprobe

This commit is contained in:
Dr. PO 2017-08-23 03:46:59 +08:00
parent 37d9af306a
commit c6bc6b95bf

View File

@ -1,6 +1,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import io import io
import json
import os import os
import subprocess import subprocess
import time import time
@ -9,9 +10,6 @@ import re
from .common import AudioConversionError, PostProcessor from .common import AudioConversionError, PostProcessor
from ..compat import (
compat_subprocess_get_DEVNULL,
)
from ..utils import ( from ..utils import (
encodeArgument, encodeArgument,
encodeFilename, encodeFilename,
@ -151,28 +149,31 @@ class FFmpegPostProcessor(PostProcessor):
def probe_executable(self): def probe_executable(self):
return self._paths[self.probe_basename] return self._paths[self.probe_basename]
def get_audio_codec(self, path): def run_ffprobe_json(self, path, opts):
if not self.probe_available: if not self.probe_available:
raise PostProcessingError('ffprobe or avprobe not found. Please install one.') raise PostProcessingError('ffprobe or avprobe not found. Please install one.')
try:
cmd = [ # json output format is available since ffmpeg 0.9 and avconv 9_beta1
encodeFilename(self.probe_executable, True), # don't need another check_version() for ffprobe
encodeArgument('-show_streams'), self.check_version()
encodeFilename(self._ffmpeg_filename_argument(path), True)]
options = ['-of', 'json'] + opts
cmd = ([encodeFilename(self.probe_executable, True)] +
[encodeArgument(o) for o in options] +
[encodeFilename(self._ffmpeg_filename_argument(path), True)])
if self._downloader.params.get('verbose', False): if self._downloader.params.get('verbose', False):
self._downloader.to_screen('[debug] %s command line: %s' % (self.basename, shell_quote(cmd))) self._downloader.to_screen('[debug] %s command line: %s' % (self.probe_basename, shell_quote(cmd)))
handle = subprocess.Popen(cmd, stderr=compat_subprocess_get_DEVNULL(), stdout=subprocess.PIPE, stdin=subprocess.PIPE) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
output = handle.communicate()[0] stdout, stderr = p.communicate()
if handle.wait() != 0: if p.returncode != 0:
return None return {}
except (IOError, OSError): return json.loads(stdout.decode('utf-8', 'replace'))
return None
audio_codec = None def get_audio_codec(self, path):
for line in output.decode('ascii', 'ignore').split('\n'): streams_info = self.run_ffprobe_json(path, ['-show_streams'])
if line.startswith('codec_name='): for stream in streams_info.get('streams', []):
audio_codec = line.split('=')[1].strip() if 'audio' == stream.get('codec_type'):
elif line.strip() == 'codec_type=audio' and audio_codec is not None: return stream.get('codec_name')
return audio_codec
return None return None
def run_ffmpeg_multiple_files(self, input_paths, out_path, opts): def run_ffmpeg_multiple_files(self, input_paths, out_path, opts):