1
0
.dotfiles/home/bin/video2gif

129 lines
4.0 KiB
Python
Executable File

#!/usr/bin/env python3
"""video2gif: convert a video into a GIF image using ffmpeg.
Usage: video2gif input_video.mp4
# produces video2gif.gif output of the first 5 seconds from the video
Command line options and their defaults:
--time, -t = 00:00:00
The time offset to seek into the video before starting the GIF,
default is "00:00:00", this value can be an integer number of seconds too
like "190"
--length, -l = 5
The number of seconds to convert into a GIF, default is 5, usually 10
or fewer is a good length for a GIF.
--width, -w = 480
The max width for the output GIF to be scaled down to. 480 is a good
default, smaller or bigger and you'll trade off file size for resolution.
--fps = 10
Set the FPS setting in ffmpeg for the GIF, 10 is a good default.
--output, -o = video2gif.gif
Name a different output file for the GIF image.
--Kirsle
https://www.kirsle.net/
"""
import argparse
import sys
import os
import os.path
import subprocess
import tempfile
# Test for required programs.
if subprocess.call("which ffmpeg >/dev/null 2>&1", shell=True) != 0:
print("You require ffmpeg to use this script, install the ffmpeg package and try again")
sys.exit(1)
def main():
# Command line options for this script. Run `video2gif --help` for automatic
# documentation.
parser = argparse.ArgumentParser(description="video2gif: convert a video into a GIF image")
parser.add_argument("--time", "-t",
help="Time skip in the video, in 00:00:00 format or as an integer number of seconds, default is 0.",
type=str,
default="00:00:00",
)
parser.add_argument("--length", "-l",
help="Number of seconds of video to go into the GIF, beginning at the --time option."
"Usually use a value <= 10 seconds. Default is 5.",
type=str,
default="5",
)
parser.add_argument("--fps",
help="Set a custom FPS value for the output GIF, default is 10",
type=str,
default="10",
)
parser.add_argument("--width", "-w",
help="Set a target width for the output GIF image, default is 480",
type=str,
default="480",
)
parser.add_argument("--output", "-o",
help="Output file name, default is video2gif.gif",
type=str,
default="video2gif.gif",
)
parser.add_argument("input",
help="Input file, a video to convert into a GIF",
)
# Parse the command line arguments.
args = parser.parse_args()
# We need a temporary file to hold the video palette.
palette_fh = tempfile.NamedTemporaryFile(
suffix=".png",
delete=False,
)
palette_file = palette_fh.name # file path like "/tmp/tmpabccdd.png"
palette_fh.close() # we're not the ones writing to it so close the file
print("Temporary palette file is:", palette_file)
# 1. create the palette from the original video file
subprocess.call([
"ffmpeg",
"-y", # yes, force overwrite the named temporary file
"-ss", args.time,
"-t", args.length,
"-i", args.input,
"-vf", "fps={fps},scale={width}:-1:flags=lanczos,palettegen".format(
fps=args.fps,
width=args.width,
),
palette_file,
])
# 2. create the GIF from the original video file and the temp palette.
subprocess.call([
"ffmpeg",
"-ss", args.time,
"-t", args.length,
"-i", args.input,
"-i", palette_file,
"-filter_complex", "fps={fps},scale={width}:-1:flags=lanczos[x];[x][1:v]paletteuse".format(
fps=args.fps,
width=args.width,
),
args.output,
])
# clean up the temporary palette file
os.unlink(palette_file)
# the following condition is only true when this python script is being run
# as a script directly (not when imported as a module in another program)
if __name__ == "__main__":
main()
# vim:expandtab