feat: completed with all features
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import argparse
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def resolve_path(value: str) -> Path:
|
||||
return Path(value).expanduser().resolve()
|
||||
|
||||
|
||||
def run(command: list[str]) -> None:
|
||||
print("Running:", " ".join(command))
|
||||
subprocess.run(command, check=True)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Replace a video's original audio with a new voiceover audio file."
|
||||
)
|
||||
parser.add_argument("--video", required=True, help="Input video file, for example input/tutorial.mp4")
|
||||
parser.add_argument("--audio", required=True, help="Input voiceover audio file, for example output/voiceover.wav")
|
||||
parser.add_argument("--output", required=True, help="Output MP4 file, for example output/final_video.mp4")
|
||||
parser.add_argument(
|
||||
"--reencode-video",
|
||||
action="store_true",
|
||||
help="Re-encode video with H.264 instead of copying. Use only if the copied output has playback issues.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
video_file = resolve_path(args.video)
|
||||
audio_file = resolve_path(args.audio)
|
||||
output_file = resolve_path(args.output)
|
||||
|
||||
if not video_file.exists():
|
||||
raise FileNotFoundError(f"Video not found: {video_file}")
|
||||
if not audio_file.exists():
|
||||
raise FileNotFoundError(f"Audio not found: {audio_file}")
|
||||
|
||||
output_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
video_codec_args = ["-c:v", "libx264", "-preset", "medium", "-crf", "18"] if args.reencode_video else ["-c:v", "copy"]
|
||||
|
||||
command = [
|
||||
"ffmpeg", "-y",
|
||||
"-i", str(video_file),
|
||||
"-i", str(audio_file),
|
||||
"-map", "0:v:0", # video from first input
|
||||
"-map", "1:a:0", # audio from second input only, so original video audio is muted/removed
|
||||
*video_codec_args,
|
||||
"-c:a", "aac",
|
||||
"-b:a", "192k",
|
||||
"-movflags", "+faststart",
|
||||
str(output_file),
|
||||
]
|
||||
run(command)
|
||||
print(f"Done: {output_file}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user