diff options
author | pukkandan <pukkandan.ytdlp@gmail.com> | 2022-01-13 16:31:08 +0530 |
---|---|---|
committer | pukkandan <pukkandan.ytdlp@gmail.com> | 2022-01-13 16:32:23 +0530 |
commit | 3b603dbdf139efe187f961dbe8b1b24ba16ae194 (patch) | |
tree | 6378839c98d78b6dda8015a85e7034f9b8935668 /yt_dlp/postprocessor/ffmpeg.py | |
parent | 5df1ac92bd85a02696f61a194d9a3a9e1ca34cfc (diff) | |
download | hypervideo-pre-3b603dbdf139efe187f961dbe8b1b24ba16ae194.tar.lz hypervideo-pre-3b603dbdf139efe187f961dbe8b1b24ba16ae194.tar.xz hypervideo-pre-3b603dbdf139efe187f961dbe8b1b24ba16ae194.zip |
Add option `--concat-playlist`
Closes #1855, related: #382
Diffstat (limited to 'yt_dlp/postprocessor/ffmpeg.py')
-rw-r--r-- | yt_dlp/postprocessor/ffmpeg.py | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/yt_dlp/postprocessor/ffmpeg.py b/yt_dlp/postprocessor/ffmpeg.py index 43c1b276d..213de0ecf 100644 --- a/yt_dlp/postprocessor/ffmpeg.py +++ b/yt_dlp/postprocessor/ffmpeg.py @@ -1123,3 +1123,48 @@ class FFmpegThumbnailsConvertorPP(FFmpegPostProcessor): if not has_thumbnail: self.to_screen('There aren\'t any thumbnails to convert') return files_to_delete, info + + +class FFmpegConcatPP(FFmpegPostProcessor): + def __init__(self, downloader, only_multi_video=False): + self._only_multi_video = only_multi_video + super().__init__(downloader) + + def concat_files(self, in_files, out_file): + if len(in_files) == 1: + os.replace(in_files[0], out_file) + return + + codecs = [traverse_obj(self.get_metadata_object(file), ('streams', ..., 'codec_name')) for file in in_files] + if len(set(map(tuple, codecs))) > 1: + raise PostProcessingError( + 'The files have different streams/codecs and cannot be concatenated. ' + 'Either select different formats or --recode-video them to a common format') + super().concat_files(in_files, out_file) + + @PostProcessor._restrict_to(images=False) + def run(self, info): + if not info.get('entries') or self._only_multi_video and info['_type'] != 'multi_video': + return [], info + elif None in info['entries']: + raise PostProcessingError('Aborting concatenation because some downloads failed') + elif any(len(entry) > 1 for entry in traverse_obj(info, ('entries', ..., 'requested_downloads')) or []): + raise PostProcessingError('Concatenation is not supported when downloading multiple separate formats') + + in_files = traverse_obj(info, ('entries', ..., 'requested_downloads', 0, 'filepath')) + if not in_files: + self.to_screen('There are no files to concatenate') + return [], info + + ie_copy = self._downloader._playlist_infodict(info) + exts = [traverse_obj(entry, ('requested_downloads', 0, 'ext'), 'ext') for entry in info['entries']] + ie_copy['ext'] = exts[0] if len(set(exts)) == 1 else 'mkv' + out_file = self._downloader.prepare_filename(ie_copy, 'pl_video') + + self.concat_files(in_files, out_file) + + info['requested_downloads'] = [{ + 'filepath': out_file, + 'ext': ie_copy['ext'], + }] + return in_files, info |