From 42fac496e059414a150fafa828c249357113e868 Mon Sep 17 00:00:00 2001 From: bashonly Date: Fri, 30 May 2025 16:20:23 -0500 Subject: [PATCH 1/3] [utils] `parse_codecs`: Handle IAMF formats Authored by: bashonly --- yt_dlp/utils/_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yt_dlp/utils/_utils.py b/yt_dlp/utils/_utils.py index 20aa341ca..c89f50a51 100644 --- a/yt_dlp/utils/_utils.py +++ b/yt_dlp/utils/_utils.py @@ -3040,7 +3040,7 @@ def parse_codecs(codecs_str): elif parts[:2] == ['vp9', '2']: hdr = 'HDR10' elif parts[0] in ('flac', 'mp4a', 'opus', 'vorbis', 'mp3', 'aac', 'ac-4', - 'ac-3', 'ec-3', 'eac3', 'dtsc', 'dtse', 'dtsh', 'dtsl'): + 'ac-3', 'ec-3', 'eac3', 'dtsc', 'dtse', 'dtsh', 'dtsl', 'iamf'): acodec = acodec or full_codec elif parts[0] in ('stpp', 'wvtt'): scodec = scodec or full_codec From 9a221819d4289c849dd0244edf88de1ae8b13897 Mon Sep 17 00:00:00 2001 From: bashonly Date: Fri, 30 May 2025 18:37:37 -0500 Subject: [PATCH 2/3] [ie/youtube] Deprioritize IAMF formats Authored by: bashonly --- yt_dlp/extractor/youtube/_video.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yt_dlp/extractor/youtube/_video.py b/yt_dlp/extractor/youtube/_video.py index 3d4bdfd56..afbb34fcf 100644 --- a/yt_dlp/extractor/youtube/_video.py +++ b/yt_dlp/extractor/youtube/_video.py @@ -3477,8 +3477,8 @@ def build_fragments(f): 'width': int_or_none(fmt.get('width')), 'language': join_nonempty(language_code, 'desc' if is_descriptive else '') or None, 'language_preference': PREFERRED_LANG_VALUE if is_original else 5 if is_default else -10 if is_descriptive else -1, - # Strictly de-prioritize damaged and 3gp formats - 'preference': -10 if is_damaged else -2 if itag == '17' else None, + # Strictly de-prioritize damaged, 3gp and iamf formats + 'preference': -10 if is_damaged else -2 if itag in ('17', '773') else None, } mime_mobj = re.match( r'((?:[^/]+)/(?:[^;]+))(?:;\s*codecs="([^"]+)")?', fmt.get('mimeType') or '') From 19ed787130be632e977a64d4fc706f618f441e94 Mon Sep 17 00:00:00 2001 From: bashonly Date: Fri, 18 Jul 2025 13:40:07 -0500 Subject: [PATCH 3/3] return `container` and block merging Authored by: bashonly --- yt_dlp/YoutubeDL.py | 11 ++++++++++- yt_dlp/extractor/youtube/_video.py | 2 +- yt_dlp/utils/_utils.py | 5 ++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py index ea6264a0d..707578f0d 100644 --- a/yt_dlp/YoutubeDL.py +++ b/yt_dlp/YoutubeDL.py @@ -3452,6 +3452,7 @@ def correct_ext(filename, ext=new_ext): merger = FFmpegMergerPP(self) downloaded = [] + should_merge = True if dl_filename is not None: self.report_file_already_downloaded(dl_filename) elif fd: @@ -3469,12 +3470,20 @@ def correct_ext(filename, ext=new_ext): 'You have requested merging of multiple formats ' 'while also allowing unplayable formats to be downloaded. ' 'The formats won\'t be merged to prevent data corruption.') + should_merge = False elif not merger.available: msg = 'You have requested merging of multiple formats but ffmpeg is not installed' if not self.params.get('ignoreerrors'): self.report_error(f'{msg}. Aborting due to --abort-on-error') return self.report_warning(f'{msg}. The formats won\'t be merged') + should_merge = False + elif any(f.get('container') == 'iamf' for f in info_dict['requested_formats']): + self.report_warning( + 'You have requested merging of multiple formats ' + 'but one of the formats is an IAMF audio format. ' + 'The formats won\'t be merged to prevent data loss.') + should_merge = False if temp_filename == '-': reason = ('using a downloader other than ffmpeg' if FFmpegFD.can_merge_formats(info_dict, self.params) @@ -3500,7 +3509,7 @@ def correct_ext(filename, ext=new_ext): info_dict['__real_download'] = info_dict['__real_download'] or real_download success = success and partial_success - if downloaded and merger.available and not self.params.get('allow_unplayable_formats'): + if downloaded and should_merge: info_dict['__postprocessors'].append(merger) info_dict['__files_to_merge'] = downloaded # Even if there were no downloads, it is being merged only now diff --git a/yt_dlp/extractor/youtube/_video.py b/yt_dlp/extractor/youtube/_video.py index afbb34fcf..2bcf8d967 100644 --- a/yt_dlp/extractor/youtube/_video.py +++ b/yt_dlp/extractor/youtube/_video.py @@ -3489,7 +3489,7 @@ def build_fragments(f): itags[itag].add(('https', dct.get('language'))) stream_ids.append(stream_id) single_stream = 'none' in (dct.get('acodec'), dct.get('vcodec')) - if single_stream and dct.get('ext'): + if single_stream and dct.get('ext') and not dct.get('container'): dct['container'] = dct['ext'] + '_dash' if (all_formats or 'dashy' in format_types) and dct['filesize']: diff --git a/yt_dlp/utils/_utils.py b/yt_dlp/utils/_utils.py index c89f50a51..7e8acc824 100644 --- a/yt_dlp/utils/_utils.py +++ b/yt_dlp/utils/_utils.py @@ -3024,7 +3024,7 @@ def parse_codecs(codecs_str): return {} split_codecs = list(filter(None, map( str.strip, codecs_str.strip().strip(',').split(',')))) - vcodec, acodec, scodec, hdr = None, None, None, None + vcodec, acodec, scodec, hdr, container = None, None, None, None, None for full_codec in split_codecs: full_codec = re.sub(r'^([^.]+)', lambda m: m.group(1).lower(), full_codec) parts = re.sub(r'0+(?=\d)', '', full_codec).split('.') @@ -3042,6 +3042,8 @@ def parse_codecs(codecs_str): elif parts[0] in ('flac', 'mp4a', 'opus', 'vorbis', 'mp3', 'aac', 'ac-4', 'ac-3', 'ec-3', 'eac3', 'dtsc', 'dtse', 'dtsh', 'dtsl', 'iamf'): acodec = acodec or full_codec + if parts[0] == 'iamf': + container = 'iamf' elif parts[0] in ('stpp', 'wvtt'): scodec = scodec or full_codec else: @@ -3052,6 +3054,7 @@ def parse_codecs(codecs_str): 'acodec': acodec or 'none', 'dynamic_range': hdr, **({'scodec': scodec} if scodec is not None else {}), + **({'container': container} if container is not None else {}), } elif len(split_codecs) == 2: return {