diff options
Diffstat (limited to 'yt_dlp/postprocessor/ffmpeg.py')
-rw-r--r-- | yt_dlp/postprocessor/ffmpeg.py | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/yt_dlp/postprocessor/ffmpeg.py b/yt_dlp/postprocessor/ffmpeg.py index a8635c1d1..7d0452dbc 100644 --- a/yt_dlp/postprocessor/ffmpeg.py +++ b/yt_dlp/postprocessor/ffmpeg.py @@ -10,6 +10,7 @@ import json from .common import AudioConversionError, PostProcessor +from ..compat import compat_str from ..utils import ( encodeArgument, encodeFilename, @@ -769,3 +770,40 @@ class FFmpegSubtitlesConvertorPP(FFmpegPostProcessor): } return sub_filenames, info + + +class FFmpegSplitChaptersPP(FFmpegPostProcessor): + + def _prepare_filename(self, number, chapter, info): + info = info.copy() + info.update({ + 'section_number': number, + 'section_title': chapter.get('title'), + 'section_start': chapter.get('start_time'), + 'section_end': chapter.get('end_time'), + }) + return self._downloader.prepare_filename(info, 'chapter') + + def _ffmpeg_args_for_chapter(self, number, chapter, info): + destination = self._prepare_filename(number, chapter, info) + if not self._downloader._ensure_dir_exists(encodeFilename(destination)): + return + + chapter['_filename'] = destination + self.to_screen('Chapter %03d; Destination: %s' % (number, destination)) + return ( + destination, + ['-ss', compat_str(chapter['start_time']), + '-to', compat_str(chapter['end_time'])]) + + def run(self, info): + chapters = info.get('chapters') or [] + if not chapters: + self.report_warning('There are no tracks to extract') + return [], info + + self.to_screen('Splitting video by chapters; %d chapters found' % len(chapters)) + for idx, chapter in enumerate(chapters): + destination, opts = self._ffmpeg_args_for_chapter(idx + 1, chapter, info) + self.real_run_ffmpeg([(info['filepath'], opts)], [(destination, ['-c', 'copy'])]) + return [], info |