Created
August 6, 2022 17:32
-
-
Save Grub4K/e3315a752c2d39c005322741d3d967f0 to your computer and use it in GitHub Desktop.
Doctor Who audio synced intro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import subprocess | |
from collections import namedtuple | |
from pathlib import Path | |
Timewarp = namedtuple("Timewarp", ["start", "end", "rate"]) | |
def font_filter(stream: str, text: str): | |
return ":".join( | |
[ | |
f"[{stream}]drawtext=fontfile=roboto.ttf", | |
f"text='{text}'", | |
"fontcolor=white", | |
"bordercolor=black", | |
"borderw=5", | |
"x=(w-text_w)/2", | |
f"y=10[{stream}]", | |
] | |
) | |
def create_intro( | |
input_file: Path, | |
output_file: Path, | |
start_time: float, | |
comparison=False, | |
): | |
command = ["ffmpeg", "-hide_banner", "-v", "error", "-stats", "-y"] | |
command.extend(["-i", str(input_file)]) | |
filters = [ | |
f"[0:v]trim={start_time}:duration=42.5,setpts=PTS-STARTPTS[intro]", | |
] | |
timewarps = [ | |
Timewarp(0, 8, 0.75), | |
Timewarp(8, 23, 0.9), | |
Timewarp(23, 26, 0.6), | |
Timewarp(26, 29.7, 1.2), | |
Timewarp(29.7, 34.8, 0.8), | |
Timewarp(34.8, 36, 1.75), | |
Timewarp(36, 42, 1), | |
] | |
parts = "".join(f"[part{part}]" for part, _ in enumerate(timewarps)) | |
filters.append(f"[intro]split={len(timewarps)}{parts}") | |
for part_num, timewarp in enumerate(timewarps): | |
filter_data = [ | |
f"[part{part_num}]trim={timewarp.start}:{timewarp.end}", | |
"setpts=PTS-STARTPTS", | |
f"setpts={timewarp.rate}*PTS[part{part_num}]", | |
] | |
filters.append(",".join(filter_data)) | |
filters.append(f"{parts}concat=n={len(timewarps)},setpts=PTS-STARTPTS[vout]") | |
filters.append(f"[0:a]atrim={start_time}:duration=37.5,asetpts=PTS-STARTPTS[aout]") | |
if comparison: | |
filters.append( | |
f"[0:v]trim={start_time}:duration=37.5,setpts=PTS-STARTPTS[vout_top]" | |
) | |
if Path("roboto.ttf").exists(): | |
filters.extend( | |
[ | |
font_filter("vout_top", "Original"), | |
font_filter("vout", "Audio synced"), | |
] | |
) | |
filters.append( | |
"[vout_top][vout]vstack[vout]", | |
) | |
# Theoretically not needed, but I messed up so here is the fix | |
filters.append( | |
"[vout]fps=23.98,setpts=PTS-STARTPTS,trim=0.7:37.5,setpts=PTS-STARTPTS[vout]" | |
) | |
filters.append("[aout]atrim=0.7:37.5,asetpts=PTS-STARTPTS[aout]") | |
command.extend(["-filter_complex", ";".join(filters)]) | |
command.extend(["-map", "[vout]"]) | |
command.extend(["-map", "[aout]"]) | |
command.extend([str(output_file)]) | |
subprocess.run(command) | |
def main(): | |
import argparse | |
parser = argparse.ArgumentParser( | |
prog="dw_intro.py", | |
description="Creates a timewarped Doctor Who intro synced with the audio. " | |
+ "Designed to be used with Season 9 Episode 3. ", | |
epilog="Be careful using this, it might break.", | |
) | |
parser.add_argument( | |
"-i", | |
"--input", | |
type=Path, | |
required=True, | |
help="the input file from which to take the intro.", | |
) | |
parser.add_argument( | |
"-o", | |
"--output", | |
type=Path, | |
help="the output file. Defaults to either `synced.mp4` or `comparison.mp4`", | |
) | |
parser.add_argument( | |
"-s", | |
"--start", | |
type=float, | |
default=185.3, | |
help="the time in seconds at which the intro starts. Defaults to 185.3s", | |
) | |
parser.add_argument( | |
"-c", | |
"--comparison", | |
action="store_true", | |
help="create a comparison instead of only the synced intro", | |
) | |
args = parser.parse_args() | |
if args.output is None: | |
args.output = Path("comparison.mp4" if args.comparison else "synced.mp4") | |
create_intro(args.input, args.output, args.start, args.comparison) | |
if __name__ == "__main__": | |
try: | |
main() | |
except KeyboardInterrupt: | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment