Skip to content

Instantly share code, notes, and snippets.

@Palisand
Last active January 9, 2022 00:45
Show Gist options
  • Save Palisand/f02e8bba23918b2d4a87958287ad2c4b to your computer and use it in GitHub Desktop.
Save Palisand/f02e8bba23918b2d4a87958287ad2c4b to your computer and use it in GitHub Desktop.
An old gif_to_mp4 python script written fresh outta college
"""
gif_to_mp4
Converts GIFs from an input directory to MP4s or a single GIF file to an MP4
and stores them in the same directory if an output location is not specified.
Also, generates a preview image if desired.
Usage:
gif_to_mp4.py <input_file_or_directory> [-o=<output_directory>]
gif_to_mp4.py prev <input_file_or_directory> [-o=<output_directory>] [-p=<output_directory>]
gif_to_mp4.py (-h | --help)
Options:
-h --help Show this screen
-o=<output_directory> Specify output directory for converted file(s) (defaults to input location)
-p=<output_directory> Specify output directory for preview image(s) (defaults to input location)
"""
import os
import sys
import subprocess
from docopt import docopt
def generate_preview_image(vfpath, outdir, time_at=0, width=None, height=None):
"""
Captures and stores the first frame of a video file (MP4 expected) as a JPG
:param vfpath: the path of the video file to be extracted
:param outdir: an existing output directory (default '')
:param time_at: time in video at which to extract (default 0)
:param width: width of image to output (default None)
:param height: height of image to output (default None)
:return: None
"""
filename = os.path.splitext(os.path.basename(vfpath))[0] + '.jpg'
fout = outdir + '/' + filename if outdir else os.path.dirname(vfpath) + '/' + filename
if width and height:
subprocess.call(['ffmpeg', '-ss', str(time_at), '-i', vfpath, '-vframes', '1',
'-s', str(height) + 'x' + str(width), '-f', 'image2', fout])
else:
subprocess.call(['ffmpeg', '-ss', str(time_at), '-i', vfpath, '-vframes', '1',
'-f', 'image2', fout])
def convert_file(fpath, outdir, gen_prev, prevdir):
"""
Converts a GIF to an MP4 and stores the file in the same directory or specified directory
:param fpath: the path of the file to be converted
:param outdir: an existing output directory
:return: None
"""
if fpath.endswith(".gif"):
filename = os.path.splitext(os.path.basename(fpath))[0] + '.mp4'
fout = outdir + '/' + filename if outdir else os.path.dirname(fpath) + '/' + filename
subprocess.call(['ffmpeg', '-i', fpath, '-pix_fmt', 'yuv420p',
'-vf', 'scale=trunc(iw/2)*2:trunc(ih/2)*2', fout])
if gen_prev:
generate_preview_image(fout, prevdir)
else:
sys.exit(fpath + ": Not a GIF")
def convert_dir(dir_, outdir, gen_prev, prevdir):
"""
Converts any GIFs found within a specified directory to MP4s
and stores the files in the same directory or specified directory
:param dir_: the path of the directory containing files to be converted
:param outdir: an existing output directory
:return: None
"""
files = [dir_ + '/' + f for f in os.listdir(dir_) if f.endswith('.gif')]
if files:
for f in files:
filename = os.path.splitext(os.path.basename(f))[0] + '.mp4'
fout = outdir + '/' + filename if outdir else dir_ + '/' + filename
subprocess.call(['ffmpeg', '-i', f, '-pix_fmt', 'yuv420p',
'-vf', 'scale=trunc(iw/2)*2:trunc(ih/2)*2', fout])
if gen_prev:
generate_preview_image(fout, prevdir)
else:
sys.exit(dir_ + ": No GIFs found")
# TODO: Check for possible loss of transparency
def main(dir_or_file, outdir, gen_prev, prevdir):
if os.path.isfile(dir_or_file):
convert_file(dir_or_file, outdir, gen_prev, prevdir)
elif os.path.isdir(dir_or_file):
convert_dir(dir_or_file, outdir, gen_prev, prevdir)
else:
sys.exit("Unknown Error")
if __name__ == '__main__':
args = docopt(__doc__)
in_, out_, prev_, pout_ = args["<input_file_or_directory>"], args["-o"], args["prev"], args["-p"]
in_ = os.path.abspath(in_)
if not os.path.exists(in_):
sys.exit(in_ + ": No such file or directory")
if out_:
out_ = os.path.abspath(out_)
if not os.path.exists(out_) or not os.path.isdir(out_):
sys.exit(out_ + ": No such directory")
if pout_:
pout_ = os.path.abspath(pout_)
if not os.path.exists(pout_) or not os.path.isdir(pout_):
sys.exit(pout_ + ": No such directory")
main(in_, out_, prev_, pout_)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment