117 lines
3 KiB
Python
Executable file
117 lines
3 KiB
Python
Executable file
#!/usr/bin/env nix-shell
|
|
#!nix-shell -i python3 -p python3 ffmpeg-full
|
|
from subprocess import run
|
|
import mimetypes
|
|
import os.path
|
|
import re
|
|
import sys
|
|
|
|
|
|
def lavfi_escape(parameter):
|
|
return (
|
|
parameter.replace("'", "\\'")
|
|
.replace(":", "\:")
|
|
.replace("\\'", "\\\\\\'")
|
|
.replace("[", "\[")
|
|
.replace("]", "\]")
|
|
.replace(",", "\,")
|
|
)
|
|
|
|
|
|
infile = sys.argv[1]
|
|
try:
|
|
timeout = sys.argv[2]
|
|
except IndexError:
|
|
timeout = 1800
|
|
# the system default font
|
|
# if the font name does not include this but the resulting fqn does, it is treated as missing
|
|
default_font = "Roboto"
|
|
|
|
res = run(
|
|
[
|
|
"ffmpeg",
|
|
"-hide_banner",
|
|
"-t",
|
|
str(timeout),
|
|
"-f",
|
|
"lavfi",
|
|
"-i",
|
|
"nullsrc=16x16",
|
|
"-filter:v",
|
|
f"subtitles={lavfi_escape(infile)}",
|
|
"-f",
|
|
"null",
|
|
"-",
|
|
],
|
|
capture_output=True,
|
|
)
|
|
|
|
if res.returncode != 0:
|
|
print("ffmpeg failed")
|
|
print(f"stdout: {res.stdout.decode('utf-8')}")
|
|
print(f"stderr: {res.stderr.decode('utf-8')}")
|
|
sys.exit(1)
|
|
|
|
if res.stdout != b"":
|
|
print(f"Got Stdout: {res.stdout.decode('utf-8')}")
|
|
|
|
substitutions = []
|
|
fonts = []
|
|
|
|
for line in res.stderr.decode("utf-8").splitlines():
|
|
substitution = re.match(
|
|
"^\[Parsed_subtitles_0 @ 0x[0-9a-f]*\] Glyph .* not found, selecting one more font for \((.*), ([0-9]{1,3}), ([0-9]{1,3})\)",
|
|
line,
|
|
)
|
|
fontselect = re.match(
|
|
"^\[Parsed_subtitles_0 @ 0x[0-9a-f]*\] fontselect: \((.*), ([0-9]{1,3}), ([0-9]{1,3})\) -> (.*), ([0-9]*), (.*)",
|
|
line,
|
|
)
|
|
if substitution is not None:
|
|
substitutions.append(
|
|
(
|
|
substitution.group(1),
|
|
int(substitution.group(2)),
|
|
int(substitution.group(3)),
|
|
)
|
|
)
|
|
if fontselect is not None:
|
|
font = {
|
|
"name": fontselect.group(1),
|
|
"weight": int(fontselect.group(2)),
|
|
"italic": int(fontselect.group(3)),
|
|
"path": fontselect.group(4),
|
|
#'?': fontselect.group(5),
|
|
"fqn": fontselect.group(6),
|
|
}
|
|
if font["name"] == "":
|
|
continue
|
|
|
|
if (font["name"], font["weight"], font["italic"]) in substitutions:
|
|
print(
|
|
f"Font {font['name']} lacks glyph support which lead to the substitution by {font['fqn']}, not including substitution font"
|
|
)
|
|
continue
|
|
|
|
if default_font in font["fqn"] and not default_font in font["name"]:
|
|
print(
|
|
f"Font {font['name']} could not be found (based on {font['fqn']} looking like the default font)"
|
|
)
|
|
sys.exit(1)
|
|
|
|
fonts.append(font)
|
|
|
|
command = ["mkvmerge", "-q", "-o", f"{os.path.splitext(infile)[0]}.mks", infile]
|
|
|
|
for font in fonts:
|
|
command.extend(
|
|
[
|
|
"--attachment-mime-type",
|
|
mimetypes.guess_type(font["path"])[0] or "font/sfnt",
|
|
"--attach-file",
|
|
font["path"],
|
|
]
|
|
)
|
|
|
|
run(command, check=True)
|