ytdl-sub/src/ytdl_sub/cli/parsers/cli_to_sub.py
Jesse Bannon ed55f3a3f7
[FEATURE] cli-to-sub argument to convert yt-dlp args to ytdl-sub (#1376)
Example usage:
```
$ ytdl-sub cli-to-sub -S vcodec:h264,res:480,acodec:m4a
ytdl_options:
  format_sort:
  - vcodec:h264
  - res:480
  - acodec:m4a
```
2025-11-06 21:05:18 -08:00

64 lines
1.6 KiB
Python

from typing import List
import yt_dlp
import yt_dlp.options
from ytdl_sub.utils.logger import Logger
from ytdl_sub.utils.yaml import dump_yaml
logger = Logger.get()
# pylint: disable=missing-function-docstring
##############################################################
# --- BEGIN ----
# Copy of https://github.com/yt-dlp/yt-dlp/blob/master/devscripts/cli_to_api.py
create_parser = yt_dlp.options.create_parser
def parse_patched_options(opts):
patched_parser = create_parser()
patched_parser.defaults.update(
{
"ignoreerrors": False,
"retries": 0,
"fragment_retries": 0,
"extract_flat": False,
"concat_playlist": "never",
"update_self": False,
}
)
yt_dlp.options.create_parser = lambda: patched_parser
try:
return yt_dlp.parse_options(opts)
finally:
yt_dlp.options.create_parser = create_parser
default_opts = parse_patched_options([]).ydl_opts
def cli_to_api(opts, cli_defaults=False):
opts = (yt_dlp.parse_options if cli_defaults else parse_patched_options)(opts).ydl_opts
diff = {k: v for k, v in opts.items() if default_opts[k] != v}
if "postprocessors" in diff:
diff["postprocessors"] = [
pp for pp in diff["postprocessors"] if pp not in default_opts["postprocessors"]
]
return diff
# --- END ----
##############################################################
def print_cli_to_sub(args: List[str]) -> None:
api_args = cli_to_api(args)
if not api_args:
logger.info("Does not resolve to any yt-dlp args")
return
print(dump_yaml({"ytdl_options": api_args}))