aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--youtube_dl/PostProcessor.py75
-rw-r--r--youtube_dl/__init__.py3
2 files changed, 57 insertions, 21 deletions
diff --git a/youtube_dl/PostProcessor.py b/youtube_dl/PostProcessor.py
index 79a0d7928..3d1093731 100644
--- a/youtube_dl/PostProcessor.py
+++ b/youtube_dl/PostProcessor.py
@@ -57,19 +57,17 @@ class PostProcessor(object):
"""
return information # by default, do nothing
+class FFmpegPostProcessorError(BaseException):
+ def __init__(self, message):
+ self.message = message
+
class AudioConversionError(BaseException):
def __init__(self, message):
self.message = message
-class FFmpegExtractAudioPP(PostProcessor):
- def __init__(self, downloader=None, preferredcodec=None, preferredquality=None, keepvideo=False, nopostoverwrites=False):
+class FFmpegPostProcessor(PostProcessor):
+ def __init__(self,downloader=None):
PostProcessor.__init__(self, downloader)
- if preferredcodec is None:
- preferredcodec = 'best'
- self._preferredcodec = preferredcodec
- self._preferredquality = preferredquality
- self._keepvideo = keepvideo
- self._nopostoverwrites = nopostoverwrites
self._exes = self.detect_executables()
@staticmethod
@@ -83,6 +81,34 @@ class FFmpegExtractAudioPP(PostProcessor):
programs = ['avprobe', 'avconv', 'ffmpeg', 'ffprobe']
return dict((program, executable(program)) for program in programs)
+ def run_ffmpeg(self, path, out_path, opts):
+ if not self._exes['ffmpeg'] and not self._exes['avconv']:
+ raise FFmpegPostProcessorError('ffmpeg or avconv not found. Please install one.')
+ cmd = ([self._exes['avconv'] or self._exes['ffmpeg'], '-y', '-i', encodeFilename(path)]
+ + opts +
+ [encodeFilename(self._ffmpeg_filename_argument(out_path))])
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ stdout,stderr = p.communicate()
+ if p.returncode != 0:
+ msg = stderr.strip().split('\n')[-1]
+ raise FFmpegPostProcessorError(msg)
+
+ def _ffmpeg_filename_argument(self, fn):
+ # ffmpeg broke --, see https://ffmpeg.org/trac/ffmpeg/ticket/2127 for details
+ if fn.startswith(u'-'):
+ return u'./' + fn
+ return fn
+
+class FFmpegExtractAudioPP(FFmpegPostProcessor):
+ def __init__(self, downloader=None, preferredcodec=None, preferredquality=None, keepvideo=False, nopostoverwrites=False):
+ FFmpegPostProcessor.__init__(self, downloader)
+ if preferredcodec is None:
+ preferredcodec = 'best'
+ self._preferredcodec = preferredcodec
+ self._preferredquality = preferredquality
+ self._keepvideo = keepvideo
+ self._nopostoverwrites = nopostoverwrites
+
def get_audio_codec(self, path):
if not self._exes['ffprobe'] and not self._exes['avprobe']: return None
try:
@@ -108,14 +134,11 @@ class FFmpegExtractAudioPP(PostProcessor):
acodec_opts = []
else:
acodec_opts = ['-acodec', codec]
- cmd = ([self._exes['avconv'] or self._exes['ffmpeg'], '-y', '-i', encodeFilename(path), '-vn']
- + acodec_opts + more_opts +
- [encodeFilename(self._ffmpeg_filename_argument(out_path))])
- p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- stdout,stderr = p.communicate()
- if p.returncode != 0:
- msg = stderr.strip().split('\n')[-1]
- raise AudioConversionError(msg)
+ opts = ['-vn'] + acodec_opts + more_opts
+ try:
+ FFmpegPostProcessor.run_ffmpeg(self, path, out_path, opts)
+ except FFmpegPostProcessorError as err:
+ raise AudioConversionError(err.message)
def run(self, information):
path = information['filepath']
@@ -203,9 +226,19 @@ class FFmpegExtractAudioPP(PostProcessor):
information['filepath'] = new_path
return information
- def _ffmpeg_filename_argument(self, fn):
- # ffmpeg broke --, see https://ffmpeg.org/trac/ffmpeg/ticket/2127 for details
- if fn.startswith(u'-'):
- return u'./' + fn
- return fn
+class FFmpegVideoConvertor(FFmpegPostProcessor):
+ def __init__(self, downloader=None,preferedformat=None):
+ FFmpegPostProcessor.__init__(self,downloader)
+ self._preferedformat=preferedformat
+ def run(self, information):
+ path = information['filepath']
+ prefix, sep, ext = path.rpartition(u'.')
+ outpath = prefix + sep + self._preferedformat
+ if not self._preferedformat or information['format'] == self._preferedformat:
+ return information
+ self._downloader.to_screen(u'['+'ffmpeg'+'] Converting video from %s to %s, Destination: ' % (information['format'], self._preferedformat) +outpath)
+ self.run_ffmpeg(path, outpath, [])
+ information['filepath'] = outpath
+ information['format'] = self._preferedformat
+ return information
diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py
index d7ab0f086..0d9053db3 100644
--- a/youtube_dl/__init__.py
+++ b/youtube_dl/__init__.py
@@ -455,6 +455,9 @@ def _real_main():
if opts.extractaudio:
fd.add_post_processor(FFmpegExtractAudioPP(preferredcodec=opts.audioformat, preferredquality=opts.audioquality, keepvideo=opts.keepvideo, nopostoverwrites=opts.nopostoverwrites))
+ if opts.format:
+ fd.add_post_processor(FFmpegVideoConvertor(preferedformat=opts.format))
+
# Update version
if opts.update_self:
update_self(fd.to_screen, opts.verbose, sys.argv[0])