Created
February 12, 2016 08:26
-
-
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
This file contains 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
#!/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