Compare commits

...

6 Commits

Author SHA1 Message Date
danilovsergei
097c54c36a
Merge 523c7e1d44 into 4b5eec0aaa 2024-11-25 08:30:42 +05:30
Jakob Kruse
4b5eec0aaa
[ie/chaturbate] Fix support for non-public streams (#11624)
Fix bug in 720b3dc453

Closes #11623
Authored by: jkruse
2024-11-24 22:20:30 +00:00
sergeidanilov
523c7e1d44 Fixed comments and added more supported formats 2023-11-12 23:40:55 -08:00
sergeidanilov
fc46f24dc5 fix pull request lint comments
cleaned up implementation and comments
2023-10-25 23:18:49 -07:00
danilovsergei
c29caf1739
Merge branch 'yt-dlp:master' into split-chapters-metadata-m4a-fix 2023-10-25 23:04:21 -07:00
danilovsergei
bb9ec9a24d
Fix https://github.com/yt-dlp/yt-dlp/issues/8363 by manually adding metadata during ffmpeg split chapters execution 2023-10-16 22:35:04 -07:00
2 changed files with 37 additions and 9 deletions

View File

@ -59,16 +59,15 @@ def _extract_from_api(self, video_id, tld):
'Accept': 'application/json', 'Accept': 'application/json',
}, fatal=False, impersonate=True) or {} }, fatal=False, impersonate=True) or {}
status = response.get('room_status')
if status != 'public':
if error := self._ERROR_MAP.get(status):
raise ExtractorError(error, expected=True)
self.report_warning('Falling back to webpage extraction')
return None
m3u8_url = response.get('url') m3u8_url = response.get('url')
if not m3u8_url: if not m3u8_url:
self.raise_geo_restricted() status = response.get('room_status')
if error := self._ERROR_MAP.get(status):
raise ExtractorError(error, expected=True)
if status == 'public':
self.raise_geo_restricted()
self.report_warning(f'Got status "{status}" from API; falling back to webpage extraction')
return None
return { return {
'id': video_id, 'id': video_id,

View File

@ -1048,6 +1048,34 @@ def _ffmpeg_args_for_chapter(self, number, chapter, info):
['-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'])])
# Extends opts with chapter specific metadata for the supported formats.
#
# Tested and supported on opus, m4a, webm and mp4.
def _set_metadata_arg(self, opts, ext, key, value):
if ext == 'opus':
# opus file requires a stream to keep title, artist etc metadata.
# FFmpegMetadataPP already set metadata and created that stream.
# Futher metadata updates should be set on the stream(:s)
# -metadata will do nothing and needs to be -metadata:s
opts.extend(['-metadata:s', f'{key}={value}'])
elif ext in ['m4a', 'webm', 'mp4']:
opts.extend(['-metadata', f'{key}={value}'])
# 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, track_number):
out_opts = [*self.stream_copy_opts()]
out_opts.extend(['-map_metadata', '0'])
# exclude chapters metadata but keep everything else
out_opts.extend(['-map_chapters', '-1'])
# replace global title with chapter specific title in split files
if chapter_title:
self._set_metadata_arg(out_opts, ext, "title", chapter_title)
self._set_metadata_arg(out_opts, ext, "track", track_number)
return out_opts
@PostProcessor._restrict_to(images=False) @PostProcessor._restrict_to(images=False)
def run(self, info): def run(self, info):
self._fixup_chapters(info) self._fixup_chapters(info)
@ -1062,7 +1090,8 @@ def run(self, info):
self.to_screen(f'Splitting video by chapters; {len(chapters)} chapters found') self.to_screen(f'Splitting video by chapters; {len(chapters)} chapters found')
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.get('title', ''), str(idx + 1))
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