from argparse import ArgumentParser import os, subprocess def delete_if_exists(path): if os.path.exists(path) and os.path.isfile(path): os.remove(path) def run_ffmpeg(ffmpeg_args): ffmpeg_args.insert(0, "ffmpeg") ffmpeg_args = [str(arg) for arg in ffmpeg_args] print(" ".join(ffmpeg_args)) result = subprocess.run(ffmpeg_args, capture_output=True, text=True) if result.stdout: print(result.stdout) if result.stderr: print(result.stderr) def extract_subs(input_file): subs_path = "subs.ssa" delete_if_exists(subs_path) run_ffmpeg(["-i", input_file, "-map", "0:s:0", subs_path]) return subs_path def create_gif(input_file, subs_path, start_time, duration, width, height, framerate): subs_arg = f"subtitles={subs_path}," if subs_path else "" ffmpeg_args = ["-i", input_file, "-ss", start_time, "-vf", f"{subs_arg}scale={width}:{height}"] if duration: ffmpeg_args.append("-t") ffmpeg_args.append(duration) if framerate: ffmpeg_args.append("-r") ffmpeg_args.append(framerate) output_path = f"{os.path.splitext(input_file)[0]}.gif" delete_if_exists(output_path) ffmpeg_args.append(output_path) run_ffmpeg(ffmpeg_args) if __name__ == '__main__': parser = ArgumentParser(prog="ffmpeg-gif", description="A tool for converting a video file with subs to a gif") parser.add_argument("-i", "--input_file", required=True, type=str) parser.add_argument("-ss", "--start_time", default="00:00:00", type=str) parser.add_argument("-t", "--duration", type=str) parser.add_argument("-x", "--width", default=640, type=int) parser.add_argument("-y", "--height", default=360, type=int) parser.add_argument("-r", "--framerate", default=10, type=int) parser.add_argument("-s", "--subs", action="store_true") args = parser.parse_args() subs = None if args.subs: subs = extract_subs(args.input_file) create_gif(args.input_file, subs, args.start_time, args.duration, args.width, args.height, args.framerate)