Skip to content

Instantly share code, notes, and snippets.

@jotson
Created February 12, 2016 08:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jotson/8b6af012cb911ad909a7 to your computer and use it in GitHub Desktop.
Save jotson/8b6af012cb911ad909a7 to your computer and use it in GitHub Desktop.
Python script for converting a movie to an animated GIF using ffmpeg and ImageMagick
#!/usr/bin/python3
import os
import sys
import subprocess
import optparse
import datetime
import re
import shutil
def printOutput(string):
'''
Pretty print multi-line string
'''
for line in string.splitlines():
print(' >> {}'.format(line.decode('utf8')))
def runCommand(command):
p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout
while True and p:
line = p.readline()
if not line:
break
printOutput(line)
def printOutput(string):
'''
Pretty print multi-line string
'''
for line in string.splitlines():
print(' >> {}'.format(line.decode('utf8')))
if __name__ == '__main__':
parser = optparse.OptionParser(usage="Usage: %prog [options] video-file")
parser.add_option("-s", "--start", dest="start", action="store", type='string', help="Start time")
parser.add_option("-d", "--duration", dest="duration", action="store", type='string', help="Duration")
parser.add_option("--fps", dest="fps", action="store", type='string', help="FPS")
parser.add_option("--colors", dest="colors", action="store", type='string', help="Number of colors")
parser.add_option("--resize", dest="resize", action="store", type='string', help="Size wxh")
parser.add_option("--mono", dest="mono", action="store_true", help="Monochrome")
parser.add_option("--gray", dest="gray", action="store_true", help="Grayscale")
(options, args) = parser.parse_args()
if len(args) == 0:
print('Missing file')
print('Try -h or --help for help')
sys.exit(1)
video = args[0]
print("Extracting frames from %s..." % video)
if not os.path.exists(video):
print("File not found")
sys.exit(1)
command = ['ffmpeg']
if args:
command.extend(['-i', video]);
if options.start:
command.extend(['-ss', options.start])
if options.duration:
command.extend(['-t', options.duration])
fps = ''
try:
fps = subprocess.check_output(['ffmpeg', '-i', video], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
fps = e.output
pass
if options.fps:
fps = options.fps
else:
fps = fps.decode('utf-8');
match = re.search('(\d\d) fps', fps)
if match is None:
print('FPS not found')
sys.exit(1)
fps = match.group(1)
command.extend(['-r', fps])
WORKING_DIR = '/tmp/gif-frames'
if os.path.exists(WORKING_DIR):
shutil.rmtree(WORKING_DIR)
os.mkdir(WORKING_DIR)
command.extend([WORKING_DIR + '/frame-%03d.png']);
runCommand(command)
delay = str(100/int(fps))
print("Making GIF animation @ %s FPS..." % fps)
output = os.path.splitext(video)[0] + '.gif'
command = ['convert']
command.extend(['-delay', delay])
if options.colors:
command.extend(['-colors', options.colors])
if options.mono:
command.extend(['-monochrome'])
if options.gray:
command.extend(['-colorspace', 'gray'])
if options.resize:
command.extend(['-resize', options.resize])
command.extend([WORKING_DIR + '/*.png', output])
runCommand(command)
size = os.path.getsize(output) / 1000000
print("Created %s (%0.1f MB)" % (output, size))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment