diff --git a/app/dl_formats.py b/app/dl_formats.py index 961ca1c9..51bfc67e 100644 --- a/app/dl_formats.py +++ b/app/dl_formats.py @@ -2,6 +2,7 @@ AUDIO_FORMATS = ("m4a", "mp3", "opus", "wav") + def get_format(format: str, quality: str) -> str: """ Returns format for download @@ -37,7 +38,13 @@ def get_format(format: str, quality: str) -> str: vres = f"[height<={quality}]" if quality != "best" else "" vcombo = vres + vfmt - return f"bestvideo{vcombo}+bestaudio{afmt}/best{vcombo}" + # iOS has strict requirements for video files, requiring h264 or h265 + # video codec and aac audio codec in MP4 container. This format string + # attempts to get the fully compatible formats first, then the h264/h265 + # video codec with any M4A audio codec (because audio is faster to + # convert if needed), and falls back to getting the best available MP4 + # file. + return f"bestvideo[vcodec~='^((he|a)vc|h26[45])']{vres}+bestaudio[acodec=aac]/bestvideo[vcodec~='^((he|a)vc|h26[45])']{vres}+bestaudio{afmt}/bestvideo{vcombo}+bestaudio{afmt}/best{vcombo}" raise Exception(f"Unkown format {format}") @@ -55,29 +62,41 @@ def get_opts(format: str, quality: str, ytdl_opts: dict) -> dict: Returns: ytdl_opts: Extra options """ - + opts = copy.deepcopy(ytdl_opts) postprocessors = [] if format in AUDIO_FORMATS: - postprocessors.append({ - "key": "FFmpegExtractAudio", - "preferredcodec": format, - "preferredquality": 0 if quality == "best" else quality, - }) - - #Audio formats without thumbnail + postprocessors.append( + { + "key": "FFmpegExtractAudio", + "preferredcodec": format, + "preferredquality": 0 if quality == "best" else quality, + } + ) + + # Audio formats without thumbnail if format not in ("wav") and "writethumbnail" not in opts: opts["writethumbnail"] = True - postprocessors.append({"key": "FFmpegThumbnailsConvertor", "format": "jpg", "when": "before_dl"}) + postprocessors.append( + { + "key": "FFmpegThumbnailsConvertor", + "format": "jpg", + "when": "before_dl", + } + ) postprocessors.append({"key": "FFmpegMetadata"}) postprocessors.append({"key": "EmbedThumbnail"}) - + if format == "thumbnail": opts["skip_download"] = True opts["writethumbnail"] = True - postprocessors.append({"key": "FFmpegThumbnailsConvertor", "format": "jpg", "when": "before_dl"}) - - opts["postprocessors"] = postprocessors + (opts["postprocessors"] if "postprocessors" in opts else []) + postprocessors.append( + {"key": "FFmpegThumbnailsConvertor", "format": "jpg", "when": "before_dl"} + ) + + opts["postprocessors"] = postprocessors + ( + opts["postprocessors"] if "postprocessors" in opts else [] + ) return opts