import os import subprocess def render_final_video( background, audio, subtitles, output, crf=23, preset="ultrafast" ): if not os.path.exists(background): raise FileNotFoundError( f"Background file not found: {background}" ) if not os.path.exists(audio): raise FileNotFoundError( f"Audio file not found: {audio}" ) if not os.path.exists(subtitles): raise FileNotFoundError( f"Subtitle file not found: {subtitles}" ) print("=" * 60) print("AVAILABLE FONTS") print("=" * 60) if os.path.exists("fonts"): for f in os.listdir("fonts"): print(f) print("=" * 60) print("FINAL RENDER START") print("=" * 60) print("BACKGROUND :", background) print("AUDIO :", audio) print("SUBTITLE :", subtitles) print("OUTPUT :", output) vf_filter = ( #"drawbox=" #"x=0:y=0:" #"w=iw:h=ih:" #"color=black@0.20:" #"t=fill," f"ass={subtitles}:fontsdir=fonts" ) cmd = [ "ffmpeg", "-y", "-stream_loop", "-1", "-i", background, "-i", audio, "-vf", vf_filter, "-map", "0:v", "-map", "1:a", "-c:v", "libx264", "-preset", preset, "-crf", str(crf), "-pix_fmt", "yuv420p", "-movflags", "+faststart", "-c:a", "aac", "-b:a", "192k", "-shortest", output ] print("\nFFMPEG COMMAND:\n") print(" ".join(cmd)) print() result = subprocess.run( cmd, capture_output=True, text=True ) print("=" * 60) print("STDOUT") print("=" * 60) print(result.stdout) print("=" * 60) print("STDERR") print("=" * 60) print(result.stderr) result.check_returncode() if not os.path.exists(output): raise Exception( "Output video was not generated" ) probe = subprocess.run( [ "ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", output ], capture_output=True, text=True ) duration = probe.stdout.strip() print("=" * 60) print("FINAL VIDEO DURATION") print("=" * 60) print(duration) size_mb = ( os.path.getsize(output) / 1024 / 1024 ) print("=" * 60) print("FINAL VIDEO SIZE") print("=" * 60) print( f"{size_mb:.2f} MB" ) print("=" * 60) print("FINAL RENDER SUCCESS") print("=" * 60) return output