diff options
author | Lauren N. Liberda <laura@selfisekai.rocks> | 2022-08-04 02:42:12 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-04 06:12:12 +0530 |
commit | fc61aff41beae0063b306dd9d74cc4ff27f0eff7 (patch) | |
tree | 9207f5e28f69a3b53980653e00ff3c1e927fc27a /yt_dlp/utils.py | |
parent | fe0918bb65c828ec81ce904cece58d450c117eba (diff) | |
download | hypervideo-pre-fc61aff41beae0063b306dd9d74cc4ff27f0eff7.tar.lz hypervideo-pre-fc61aff41beae0063b306dd9d74cc4ff27f0eff7.tar.xz hypervideo-pre-fc61aff41beae0063b306dd9d74cc4ff27f0eff7.zip |
Determine merge container better (See desc) (#1482)
* Determine the container early. Closes #4069
* Use codecs instead of just file extensions
* Obey `--prefer-free-formats`
* Allow fallbacks in `--merge-output`
Authored by: pukkandan, selfisekai
Diffstat (limited to 'yt_dlp/utils.py')
-rw-r--r-- | yt_dlp/utils.py | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/yt_dlp/utils.py b/yt_dlp/utils.py index c3ccb3a78..d405ed3e3 100644 --- a/yt_dlp/utils.py +++ b/yt_dlp/utils.py @@ -3456,6 +3456,46 @@ def parse_codecs(codecs_str): return {} +def get_compatible_ext(*, vcodecs, acodecs, vexts, aexts, preferences=None): + assert len(vcodecs) == len(vexts) and len(acodecs) == len(aexts) + + allow_mkv = not preferences or 'mkv' in preferences + + if allow_mkv and max(len(acodecs), len(vcodecs)) > 1: + return 'mkv' # TODO: any other format allows this? + + # TODO: All codecs supported by parse_codecs isn't handled here + COMPATIBLE_CODECS = { + 'mp4': { + 'av1', 'hevc', 'avc1', 'mp4a', # fourcc (m3u8, mpd) + 'h264', 'aacl', # Set in ISM + }, + 'webm': { + 'av1', 'vp9', 'vp8', 'opus', 'vrbs', + 'vp9x', 'vp8x', # in the webm spec + }, + } + + sanitize_codec = functools.partial(try_get, getter=lambda x: x.split('.')[0].replace('0', '')) + vcodec, acodec = sanitize_codec(vcodecs[0]), sanitize_codec(acodecs[0]) + + for ext in preferences or COMPATIBLE_CODECS.keys(): + codec_set = COMPATIBLE_CODECS.get(ext, set()) + if ext == 'mkv' or codec_set.issuperset((vcodec, acodec)): + return ext + + COMPATIBLE_EXTS = ( + {'mp3', 'mp4', 'm4a', 'm4p', 'm4b', 'm4r', 'm4v', 'ismv', 'isma', 'mov'}, + {'webm'}, + ) + for ext in preferences or vexts: + current_exts = {ext, *vexts, *aexts} + if ext == 'mkv' or current_exts == {ext} or any( + ext_sets.issuperset(current_exts) for ext_sets in COMPATIBLE_EXTS): + return ext + return 'mkv' if allow_mkv else preferences[-1] + + def urlhandle_detect_ext(url_handle): getheader = url_handle.headers.get |