[postprocessor/ffmpeg] fallback to ffmpeg/avconv for audio codec detection(closes #681)

This commit is contained in:
Remita Amine 2019-01-24 20:23:04 +01:00
parent 118afcf52f
commit eb35b163ad

View File

@ -9,9 +9,6 @@
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,
@ -165,27 +162,45 @@ def probe_executable(self):
return self._paths[self.probe_basename] return self._paths[self.probe_basename]
def get_audio_codec(self, path): def get_audio_codec(self, path):
if not self.probe_available: if not self.probe_available and not self.available:
raise PostProcessingError('ffprobe or avprobe not found. Please install one.') raise PostProcessingError('ffprobe/avprobe and ffmpeg/avconv not found. Please install one.')
try: try:
if self.probe_available:
cmd = [ cmd = [
encodeFilename(self.probe_executable, True), encodeFilename(self.probe_executable, True),
encodeArgument('-show_streams'), encodeArgument('-show_streams')]
encodeFilename(self._ffmpeg_filename_argument(path), True)] else:
cmd = [
encodeFilename(self.executable, True),
encodeArgument('-i')]
cmd.append(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(
handle = subprocess.Popen(cmd, stderr=compat_subprocess_get_DEVNULL(), stdout=subprocess.PIPE, stdin=subprocess.PIPE) '[debug] %s command line: %s' % (self.basename, shell_quote(cmd)))
output = handle.communicate()[0] handle = subprocess.Popen(
if handle.wait() != 0: cmd, stderr=subprocess.PIPE,
stdout=subprocess.PIPE, stdin=subprocess.PIPE)
stdout_data, stderr_data = handle.communicate()
expected_ret = 0 if self.probe_available else 1
if handle.wait() != expected_ret:
return None return None
except (IOError, OSError): except (IOError, OSError):
return None return None
output = (stdout_data if self.probe_available else stderr_data).decode('ascii', 'ignore')
if self.probe_available:
audio_codec = None audio_codec = None
for line in output.decode('ascii', 'ignore').split('\n'): for line in output.split('\n'):
if line.startswith('codec_name='): if line.startswith('codec_name='):
audio_codec = line.split('=')[1].strip() audio_codec = line.split('=')[1].strip()
elif line.strip() == 'codec_type=audio' and audio_codec is not None: elif line.strip() == 'codec_type=audio' and audio_codec is not None:
return audio_codec return audio_codec
else:
# Stream #FILE_INDEX:STREAM_INDEX[STREAM_ID](LANGUAGE): CODEC_TYPE: CODEC_NAME
mobj = re.search(
r'Stream\s*#\d+:\d+(?:\[0x[0-9a-f]+\])?(?:\([a-z]{3}\))?:\s*Audio:\s*([0-9a-z]+)',
output)
if mobj:
return mobj.group(1)
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):