Files
Upscale/utils/upcale.py
2026-03-19 18:16:12 +01:00

116 lines
2.8 KiB
Python

import os
import sys
import subprocess
from utils.mediainfo import get_framerate
MAX_INPUT_WIDTH = '720'
def _re_encode(
source_video: str,
temp_out_video: str,
input_aspect: str = "16:9"
):
"""
Re-Encodes the source video to avoid nasty video bugs
:param source_video: Video Input
:type source_video: str
:param input_aspect: Aspect Ratio of Video
:type input_aspect: str
"""
fps = get_framerate(source_video)
vf_filter = f"fps={fps},scale=-1:min({MAX_INPUT_WIDTH}\\,ih)"
cmd = [
"ffmpeg", "-v", "quiet", "-stats",
"-i", source_video,
"-c:v", "ffv1",
"-level", "3",
"-vf", vf_filter,
"-aspect", input_aspect,
"-pix_fmt", "yuv420p",
"-color_primaries", "1",
"-color_trc", "1",
"-colorspace", "1",
"-an",
"-sn",
"-map_metadata", "-1",
temp_out_video
]
try:
subprocess.run(cmd, check=True)
except subprocess.CalledProcessError as e:
print(f"\nffmpeg failed with error code {e.returncode} at _re_encode()", file=sys.stderr)
sys.exit(e.returncode)
def _upscale(
upscale_output: str,
input_aspect: str = "16:9"
):
print('Started Upscale')
vapoursynth_script = os.path.join('utils', 'vs-realesrgan.vpy')
try:
# First process (vspipe)
vspipe = subprocess.Popen(
[
"vspipe",
"-c", "y4m",
vapoursynth_script,
"-"
],
stdout=subprocess.PIPE
)
# Second process (ffmpeg), reading from vspipe
ffmpeg = subprocess.Popen(
[
"ffmpeg",
"-v", "quiet", "-stats",
"-f", "yuv4mpegpipe",
"-i", "-",
"-c:v", "hevc_nvenc",
"-qp", "5",
"-aspect", input_aspect,
upscale_output
],
stdin=vspipe.stdout
)
# Important: allow vspipe to receive SIGPIPE if ffmpeg exits
vspipe.stdout.close()
ffmpeg.wait()
vspipe.wait()
if ffmpeg.returncode != 0:
raise subprocess.CalledProcessError(ffmpeg.returncode, "ffmpeg")
except subprocess.CalledProcessError as e:
print(f"\nffmpeg failed with error code {e.returncode}", file=sys.stderr)
sys.exit(e.returncode)
def upscale(
source_video: str,
upscaled_video_output: str,
input_aspect: str,
):
if os.path.exists(upscaled_video_output):
print('Skipped Upscale')
return
temp_out_video = os.path.join('1-Temp', 'source.mkv')
_re_encode(source_video, temp_out_video, input_aspect)
_upscale(upscaled_video_output, input_aspect)
# Remove Temp Files
os.remove(temp_out_video)
os.remove(f'{temp_out_video}.ffindex')