mirror of
https://github.com/ytdl-org/youtube-dl.git
synced 2024-11-25 19:52:11 +00:00
Allow merging formats (closes #1612)
Multiple formats can be requested using `-f 137+139`, each one is downloaded and then the two are merged with ffmpeg.
This commit is contained in:
parent
a7c26e7338
commit
6350728be2
2 changed files with 47 additions and 6 deletions
|
@ -508,3 +508,11 @@ class FFmpegMetadataPP(FFmpegPostProcessor):
|
||||||
os.remove(encodeFilename(filename))
|
os.remove(encodeFilename(filename))
|
||||||
os.rename(encodeFilename(temp_filename), encodeFilename(filename))
|
os.rename(encodeFilename(temp_filename), encodeFilename(filename))
|
||||||
return True, info
|
return True, info
|
||||||
|
|
||||||
|
|
||||||
|
class FFmpegMergerPP(FFmpegPostProcessor):
|
||||||
|
def run(self, info):
|
||||||
|
filename = info['filepath']
|
||||||
|
args = ['-c', 'copy']
|
||||||
|
self.run_ffmpeg_multiple_files(info['__files_to_merge'], filename, args)
|
||||||
|
return True, info
|
||||||
|
|
|
@ -51,9 +51,11 @@ from .utils import (
|
||||||
write_json_file,
|
write_json_file,
|
||||||
write_string,
|
write_string,
|
||||||
YoutubeDLHandler,
|
YoutubeDLHandler,
|
||||||
|
prepend_extension,
|
||||||
)
|
)
|
||||||
from .extractor import get_info_extractor, gen_extractors
|
from .extractor import get_info_extractor, gen_extractors
|
||||||
from .downloader import get_suitable_downloader
|
from .downloader import get_suitable_downloader
|
||||||
|
from .PostProcessor import FFmpegMergerPP
|
||||||
from .version import __version__
|
from .version import __version__
|
||||||
|
|
||||||
|
|
||||||
|
@ -704,6 +706,16 @@ class YoutubeDL(object):
|
||||||
# the first that is available, starting from left
|
# the first that is available, starting from left
|
||||||
req_formats = req_format.split('/')
|
req_formats = req_format.split('/')
|
||||||
for rf in req_formats:
|
for rf in req_formats:
|
||||||
|
if re.match(r'.+?\+.+?', rf) is not None:
|
||||||
|
# Two formats have been requested like '137+139'
|
||||||
|
format_1, format_2 = rf.split('+')
|
||||||
|
formats_info = (self.select_format(format_1, formats),
|
||||||
|
self.select_format(format_2, formats))
|
||||||
|
if all(formats_info):
|
||||||
|
selected_format = {'requested_formats': formats_info}
|
||||||
|
else:
|
||||||
|
selected_format = None
|
||||||
|
else:
|
||||||
selected_format = self.select_format(rf, formats)
|
selected_format = self.select_format(rf, formats)
|
||||||
if selected_format is not None:
|
if selected_format is not None:
|
||||||
formats_to_download = [selected_format]
|
formats_to_download = [selected_format]
|
||||||
|
@ -880,10 +892,27 @@ class YoutubeDL(object):
|
||||||
success = True
|
success = True
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
fd = get_suitable_downloader(info_dict)(self, self.params)
|
def dl(name, info):
|
||||||
|
fd = get_suitable_downloader(info)(self, self.params)
|
||||||
for ph in self._progress_hooks:
|
for ph in self._progress_hooks:
|
||||||
fd.add_progress_hook(ph)
|
fd.add_progress_hook(ph)
|
||||||
success = fd.download(filename, info_dict)
|
return fd.download(name, info)
|
||||||
|
if info_dict.get('requested_formats') is not None:
|
||||||
|
downloaded = []
|
||||||
|
success = True
|
||||||
|
for f in info_dict['requested_formats']:
|
||||||
|
new_info = dict(info_dict)
|
||||||
|
new_info.update(f)
|
||||||
|
fname = self.prepare_filename(new_info)
|
||||||
|
fname = prepend_extension(fname, 'f%s' % f['format_id'])
|
||||||
|
downloaded.append(fname)
|
||||||
|
partial_success = dl(fname, new_info)
|
||||||
|
success = success and partial_success
|
||||||
|
info_dict['__postprocessors'] = [FFmpegMergerPP(self)]
|
||||||
|
info_dict['__files_to_merge'] = downloaded
|
||||||
|
else:
|
||||||
|
# Just a single file
|
||||||
|
success = dl(filename, info_dict)
|
||||||
except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err:
|
except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err:
|
||||||
self.report_error(u'unable to download video data: %s' % str(err))
|
self.report_error(u'unable to download video data: %s' % str(err))
|
||||||
return
|
return
|
||||||
|
@ -940,7 +969,11 @@ class YoutubeDL(object):
|
||||||
info = dict(ie_info)
|
info = dict(ie_info)
|
||||||
info['filepath'] = filename
|
info['filepath'] = filename
|
||||||
keep_video = None
|
keep_video = None
|
||||||
for pp in self._pps:
|
pps_chain = []
|
||||||
|
if ie_info.get('__postprocessors') is not None:
|
||||||
|
pps_chain.extend(ie_info['__postprocessors'])
|
||||||
|
pps_chain.extend(self._pps)
|
||||||
|
for pp in pps_chain:
|
||||||
try:
|
try:
|
||||||
keep_video_wish, new_info = pp.run(info)
|
keep_video_wish, new_info = pp.run(info)
|
||||||
if keep_video_wish is not None:
|
if keep_video_wish is not None:
|
||||||
|
|
Loading…
Reference in a new issue