Initial MaterialSub release
Derived from pengchujin/jzsub at 222a90265d2a8797ca258eb1a980cee0863a8311; preserve the upstream MIT license and attribution.
This commit is contained in:
Executable
+101
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Run MaterialSub dependency and font checks before a long download."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import shutil
|
||||
import sys
|
||||
from typing import Any, Sequence
|
||||
|
||||
import burn_subtitles as burn
|
||||
|
||||
|
||||
def assess(*, font: str, allow_missing_font: bool, youtube: bool) -> tuple[int, dict[str, Any]]:
|
||||
if sys.version_info < (3, 10):
|
||||
return 2, {
|
||||
"complete": False,
|
||||
"stage": "dependency_required",
|
||||
"error": "Python 3.10 or newer is required",
|
||||
}
|
||||
yt_dlp = shutil.which("yt-dlp")
|
||||
if not yt_dlp:
|
||||
return 2, {
|
||||
"complete": False,
|
||||
"stage": "dependency_required",
|
||||
"error": "yt-dlp was not found in PATH",
|
||||
}
|
||||
try:
|
||||
ffmpeg, ffprobe = burn._required_executables()
|
||||
burn._require_libass_subtitles_filter(ffmpeg)
|
||||
except burn.BurnError as exc:
|
||||
return 2, {
|
||||
"complete": False,
|
||||
"stage": "dependency_required",
|
||||
"error": str(exc),
|
||||
}
|
||||
|
||||
warnings: list[str] = []
|
||||
if youtube and not shutil.which("deno"):
|
||||
warnings.append(
|
||||
"Deno was not found; current yt-dlp may expose fewer YouTube formats"
|
||||
)
|
||||
installed = burn._font_installed(font)
|
||||
if installed is False and not allow_missing_font:
|
||||
return 3, {
|
||||
"complete": False,
|
||||
"stage": "font_decision_required",
|
||||
"font": font,
|
||||
"font_installed": False,
|
||||
"substitution_allowed": False,
|
||||
"instruction": (
|
||||
"Install the requested font, or rerun preflight and the final burn "
|
||||
"with --allow-missing-font to accept libass substitution"
|
||||
),
|
||||
"warnings": warnings,
|
||||
}
|
||||
if installed is False:
|
||||
warnings.append(f"Font {font!r} is missing; libass substitution was accepted")
|
||||
elif installed is None:
|
||||
warnings.append(f"Could not verify whether font {font!r} is installed")
|
||||
return 0, {
|
||||
"complete": True,
|
||||
"stage": "preflight_complete",
|
||||
"font": font,
|
||||
"font_installed": installed,
|
||||
"substitution_allowed": bool(installed is False and allow_missing_font),
|
||||
"executables": {
|
||||
"yt_dlp": yt_dlp,
|
||||
"ffmpeg": ffmpeg,
|
||||
"ffprobe": ffprobe,
|
||||
},
|
||||
"warnings": warnings,
|
||||
}
|
||||
|
||||
|
||||
def _parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(description="Check MaterialSub dependencies before downloading.")
|
||||
parser.add_argument("--font", default="MiSans")
|
||||
parser.add_argument("--allow-missing-font", action="store_true")
|
||||
parser.add_argument("--youtube", action="store_true")
|
||||
return parser
|
||||
|
||||
|
||||
def main(argv: Sequence[str] | None = None) -> int:
|
||||
args = _parser().parse_args(argv)
|
||||
font = args.font.strip()
|
||||
if not font:
|
||||
print(json.dumps({"complete": False, "error": "font cannot be empty"}))
|
||||
return 2
|
||||
exit_code, result = assess(
|
||||
font=font,
|
||||
allow_missing_font=args.allow_missing_font,
|
||||
youtube=args.youtube,
|
||||
)
|
||||
print(json.dumps(result, ensure_ascii=False, sort_keys=True))
|
||||
return exit_code
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user