Fix https://github.com/yt-dlp/yt-dlp/issues/8363 by manually adding metadata during ffmpeg split chapters execution

This commit is contained in:
danilovsergei 2023-10-16 22:35:04 -07:00 committed by GitHub
parent 4e38e2ae9d
commit bb9ec9a24d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1046,6 +1046,20 @@ def _ffmpeg_args_for_chapter(self, number, chapter, info):
destination, destination,
['-ss', str(chapter['start_time']), ['-ss', str(chapter['start_time']),
'-t', str(chapter['end_time'] - chapter['start_time'])]) '-t', str(chapter['end_time'] - chapter['start_time'])])
# FFmpeg adds metadata about all chapters from parent file to all split m4a files.
# This is incorrect since there must be only single chapter in each file after split.
# Such behavior confuses players who think multiple chapters present
def _set_out_opts(self, ext, chapter_title):
if ext == 'm4a':
return [
*self.stream_copy_opts(),
# For m4a ffmpeg copies all available parent track chapters to split tracks metadata
# And such behavior confuses players
# Wipe parent track metadata from split tracks and fill out only title
'-metadata', 'title={}'.format(chapter_title),
'-map_metadata','-1']
else:
return self.stream_copy_opts()
@PostProcessor._restrict_to(images=False) @PostProcessor._restrict_to(images=False)
def run(self, info): def run(self, info):
@ -1061,7 +1075,8 @@ def run(self, info):
self.to_screen('Splitting video by chapters; %d chapters found' % len(chapters)) self.to_screen('Splitting video by chapters; %d chapters found' % len(chapters))
for idx, chapter in enumerate(chapters): for idx, chapter in enumerate(chapters):
destination, opts = self._ffmpeg_args_for_chapter(idx + 1, chapter, info) destination, opts = self._ffmpeg_args_for_chapter(idx + 1, chapter, info)
self.real_run_ffmpeg([(in_file, opts)], [(destination, self.stream_copy_opts())]) out_file_opts = self._set_out_opts(info['ext'], chapter['title'])
self.real_run_ffmpeg([(in_file, opts)], [(destination, out_file_opts)])
if in_file != info['filepath']: if in_file != info['filepath']:
self._delete_downloaded_files(in_file, msg=None) self._delete_downloaded_files(in_file, msg=None)
return [], info return [], info