Last active
January 9, 2022 00:45
-
-
Save Palisand/f02e8bba23918b2d4a87958287ad2c4b to your computer and use it in GitHub Desktop.
An old gif_to_mp4 python script written fresh outta college
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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