Skip to content

Instantly share code, notes, and snippets.

@harlo
Last active August 29, 2015 14:12
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 harlo/9d821ecb9c8ce92c3e2b to your computer and use it in GitHub Desktop.
Save harlo/9d821ecb9c8ce92c3e2b to your computer and use it in GitHub Desktop.
threading together some screenshot pngs to video
def get_image_info(data):
"""
FROM http://markasread.net/post/17551554979/get-image-size-info-using-pure-python-code
Return (content_type, width, height) for a given img file content
no requirements
"""
import struct
data = str(data)
size = len(data)
height = -1
width = -1
content_type = ''
# handle GIFs
if (size >= 10) and data[:6] in ('GIF87a', 'GIF89a'):
# Check to see if content_type is correct
content_type = 'image/gif'
w, h = struct.unpack("<HH", data[6:10])
width = int(w)
height = int(h)
# See PNG 2. Edition spec (http://www.w3.org/TR/PNG/)
# Bytes 0-7 are below, 4-byte chunk length, then 'IHDR'
# and finally the 4-byte width, height
elif ((size >= 24) and data.startswith('\211PNG\r\n\032\n')
and (data[12:16] == 'IHDR')):
content_type = 'image/png'
w, h = struct.unpack(">LL", data[16:24])
width = int(w)
height = int(h)
# Maybe this is for an older PNG version.
elif (size >= 16) and data.startswith('\211PNG\r\n\032\n'):
# Check to see if we have the right content type
content_type = 'image/png'
w, h = struct.unpack(">LL", data[8:16])
width = int(w)
height = int(h)
# handle JPEGs
elif (size >= 2) and data.startswith('\377\330'):
content_type = 'image/jpeg'
jpeg = StringIO(data)
jpeg.read(2)
b = jpeg.read(1)
try:
while (b and ord(b) != 0xDA):
while (ord(b) != 0xFF): b = jpeg.read
while (ord(b) == 0xFF): b = jpeg.read(1)
if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
jpeg.read(3)
h, w = struct.unpack(">HH", jpeg.read(4))
break
else:
jpeg.read(int(struct.unpack(">H", jpeg.read(2))[0])-2)
b = jpeg.read(1)
width = int(w)
height = int(h)
except struct.error:
pass
except ValueError:
pass
return content_type, width, height
import os
from sys import argv, exit
def images_to_vid(in_folder, out_file=None, img_sentenel=None, vid_type=None, frame_rate=None):
if not os.path.exists(in_folder):
print "%s does not exist!" % in_folder
return False
if img_sentenel is None:
img_sentenel = "screenshot_"
img_info = None
import re
for _, _, files in os.walk(in_folder):
files = [f for f in files if re.match(re.compile("^%s" % img_sentenel), f) is not None]
try:
files = sorted(files, key=lambda f: int(f.split(img_sentenel)[1].split('.')[0]))
except Exception as e:
print e
return False
for f in files:
if re.match(re.compile("^%s" % img_sentenel), f):
from get_image_info import get_image_info
with open(f, 'rb') as img:
img_info = get_image_info(img.read())
break
if img_info is None:
print "no info for any images in folder"
return False
sequence_start = None
try:
sequence_start = "-start_number %d " % int(files[0].split(img_sentenel)[1].split('.')[0])
except Exception as e:
print e
img_type = None
if img_info[0] == "image/png":
img_type = "png"
if img_info[0] == "image/jpeg":
img_type = "jpg"
if img_type is None:
print "cannot determine image type"
return False
if out_file is None:
from time import time
out_file = "images_to_vid_%d" % time()
if vid_type is None:
vid_type = "mp4"
if frame_rate is None:
frame_rate = 2
mapping = {
'r' : frame_rate,
'is' : img_sentenel,
'is' : "{0}%05d.{1}".format(img_sentenel, img_type),
'vw' : img_info[1],
'vh' : img_info[2],
'of' : "%s.%s" % (out_file, vid_type),
'ss' : "" if sequence_start is None else sequence_start
}
from fabric.api import settings, local
with settings(warn_only=True):
ffmpeg_cmd = "ffmpeg -y -r %(r)d %(ss)s-i %(is)s -s %(vw)dx%(vh)d -c:v libx264 -crf 23 -pix_fmt yuv420p %(of)s" % mapping
res = local(ffmpeg_cmd, capture=True)
print res
return True
return False
if __name__ == "__main__":
if len(argv) < 2:
print "usage: images_to_vid.py in_folder [out_file, vid_type, frame_rate]"
exit(-1)
out_file = None if len(argv) < 3 else argv[2]
frame_rate = None if len(argv) < 4 else int(argv[3])
vid_type = None if len(argv) < 5 else argv[4]
img_sentenel = None if len(argv) < 6 else argv[5]
this_dir = os.getcwd()
os.chdir(argv[1])
res = images_to_vid(argv[1], out_file=out_file, img_sentenel=img_sentenel, vid_type=vid_type, frame_rate=frame_rate)
os.chdir(this_dir)
if res:
exit(0)
exit(-1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment