#!/usr/bin/env python3.9 import argparse import json import logging import subprocess import sys from pathlib import Path import typing def parse_args(argv: list[str]): arger = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) arger.add_argument("video_path", type=Path, help="Video path") arger.add_argument("save_path", nargs="?", type=Path, help="Output path") if len(argv) == 0: arger.print_help() exit(1) return arger.parse_args(argv) def ffprobe(video_path: Path) -> dict: proc = subprocess.run( [ "ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", str(video_path), ], check=True, capture_output=True, ) return json.loads(proc.stdout) def clean_video(video_path: Path, save_path: Path) -> Path: media_info = ffprobe(video_path) # check if the first video stream has hevc codec if media_info["streams"][0]["codec_name"] == "hevc": logging.info(f"Video codec is hevc, adding hvc1 tag") extra_args = ["-tag:v", "hvc1"] else: extra_args = [] # fmt: off args = [ 'ffmpeg', '-i', str(video_path), '-c:v', 'copy', # '-movflags', '+faststart', '-map_metadata', '-1', *extra_args, '-c:a', 'copy', '-y', str(save_path), ] # fmt: on logging.info(f"calling ffmpeg with {args=}") subprocess.run(args, check=True) return save_path def main(): logging.basicConfig(level=logging.INFO) args = parse_args(sys.argv[1:]) save_path: typing.Optional[Path] = args.save_path if save_path and save_path.resolve().is_dir(): save_path = save_path / args.video_path.name if save_path is None: save_path = args.video_path.with_suffix(".clean.mp4") clean_video(video_path=args.video_path, save_path=save_path) if __name__ == "__main__": main()