From 4aafb9a5e7e1728bf728a3f8c572cfa4454a6771 Mon Sep 17 00:00:00 2001 From: Rob Date: Tue, 27 Jun 2017 23:19:29 -0700 Subject: [PATCH] Adding Audio and Visual converter for ffmpeg. --- youtube_dl/postprocessor/__init__.py | 2 ++ youtube_dl/postprocessor/ffmpeg.py | 54 ++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/youtube_dl/postprocessor/__init__.py b/youtube_dl/postprocessor/__init__.py index 3ea518399..734bb8b9b 100644 --- a/youtube_dl/postprocessor/__init__.py +++ b/youtube_dl/postprocessor/__init__.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals from .embedthumbnail import EmbedThumbnailPP from .ffmpeg import ( FFmpegPostProcessor, + FFmpegAVConvertorPP, FFmpegEmbedSubtitlePP, FFmpegExtractAudioPP, FFmpegFixupStretchedPP, @@ -25,6 +26,7 @@ def get_postprocessor(key): __all__ = [ 'EmbedThumbnailPP', 'ExecAfterDownloadPP', + 'FFmpegAVConvertorPP', 'FFmpegEmbedSubtitlePP', 'FFmpegExtractAudioPP', 'FFmpegFixupM3u8PP', diff --git a/youtube_dl/postprocessor/ffmpeg.py b/youtube_dl/postprocessor/ffmpeg.py index f021ea8fd..9c3630bf1 100644 --- a/youtube_dl/postprocessor/ffmpeg.py +++ b/youtube_dl/postprocessor/ffmpeg.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals import io import os +import shutil import subprocess import time import re @@ -319,9 +320,10 @@ class FFmpegExtractAudioPP(FFmpegPostProcessor): class FFmpegVideoConvertorPP(FFmpegPostProcessor): - def __init__(self, downloader=None, preferedformat=None): + def __init__(self, downloader=None, preferedformat=None, outpath=None): super(FFmpegVideoConvertorPP, self).__init__(downloader) self._preferedformat = preferedformat + self._outpath = outpath def run(self, information): path = information['filepath'] @@ -331,16 +333,56 @@ class FFmpegVideoConvertorPP(FFmpegPostProcessor): options = [] if self._preferedformat == 'avi': options.extend(['-c:v', 'libxvid', '-vtag', 'XVID']) - prefix, sep, ext = path.rpartition('.') - outpath = prefix + sep + self._preferedformat - self._downloader.to_screen('[' + 'ffmpeg' + '] Converting video from %s to %s, Destination: ' % (information['ext'], self._preferedformat) + outpath) - self.run_ffmpeg(path, outpath, options) - information['filepath'] = outpath + if not self._outpath: + prefix, sep, ext = path.rpartition('.') + self._outpath = prefix + sep + self._preferedformat + self._downloader.to_screen('[' + 'ffmpeg' + '] Converting video from %s to %s, Destination: ' % (information['ext'], self._preferedformat) + self._outpath) + self.run_ffmpeg(path, self._outpath, options) + information['filepath'] = self._outpath information['format'] = self._preferedformat information['ext'] = self._preferedformat return [path], information +class FFmpegAVConvertorPP(FFmpegPostProcessor): + def __init__(self, downloader=None, preferedvformat=None, preferedaformat=None, preferredquality=None): + super(FFmpegAVConvertorPP, self).__init__(downloader) + self._downloader = downloader + self._preferedaformat = preferedaformat + self._preferedvformat = preferedvformat + self._preferredquality = preferredquality + + def run(self, information): + path = information['filepath'] + paths_to_remove = [] + prefix, sep, ext = path.rpartition('.') + tmp_file = prefix + '.tmp' + sep + self._preferedvformat + if ext != self._preferedvformat: + tmp_file = prefix + '.tmp' + sep + self._preferedvformat + vc = FFmpegVideoConvertorPP(downloader=self._downloader, + preferedformat=self._preferedvformat, + outpath=tmp_file) + path_list, information = vc.run(information) + paths_to_remove.append(path_list[0]) + elif self.get_audio_codec(path) != self._preferedaformat: + information['filepath'] = tmp_file + shutil.move(path, tmp_file) + else: + self._downloader.to_screen('[ffmpeg] Not converting video file %s - ' + 'already is in target format %s:%s' % + (path, self._preferedvformat, self._preferedaformat)) + return [], information + + path = information['filepath'] + if self.get_audio_codec(path) != self._preferedaformat: + output = prefix + sep + self._preferedvformat + aformat = self._preferedaformat + quality = self._preferredquality + 'k' + self.run_ffmpeg(path, output, ['-c:v', 'copy', '-c:a', aformat, '-b:a', quality]) + paths_to_remove.append(path) + return paths_to_remove, information + + class FFmpegEmbedSubtitlePP(FFmpegPostProcessor): def run(self, information): if information['ext'] not in ('mp4', 'webm', 'mkv'):