-
Notifications
You must be signed in to change notification settings - Fork 3
/
videos_to_gif.py
executable file
·117 lines (90 loc) · 3.41 KB
/
videos_to_gif.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/python
import sys, os, re, subprocess, shutil, yaml, pysrt
from PIL import Image, ImageFont, ImageDraw
from slugify import slugify
directory = "screenshots"
gif_dir = "gifs"
font = ImageFont.truetype("font/DejaVuSansCondensed-BoldOblique.ttf", 14)
def striptags(data):
# I'm a bad person, don't ever do this.
# Only okay, because of how basic the tags are.
p = re.compile(r'<.*?>')
return p.sub('', data)
def drawText(draw, x, y, text, font):
# black outline
draw.text((x-1, y),text,(0,0,0),font=font)
draw.text((x+1, y),text,(0,0,0),font=font)
draw.text((x, y-1),text,(0,0,0),font=font)
draw.text((x, y+1),text,(0,0,0),font=font)
# white text
draw.text((x, y),text,(255,255,255),font=font)
def makeGif(video, starts, ends, strings, output):
if not os.path.exists(gif_dir):
os.makedirs(gif_dir)
for index in range(0, len(starts)):
if not os.path.exists(directory):
os.makedirs(directory)
string = strings[index]
start = starts[index]
end = ends[index]
text = striptags(string).split("\n")
subprocess.call(['avconv', '-i', video, '-vf', 'scale=w=400:h=-1', '-r', '15', '-ss', start, '-t', end, os.path.join(directory, 'image-%05d.png')])
file_names = sorted((fn for fn in os.listdir(directory)))
images = []
for f in file_names:
image = Image.open(os.path.join(directory,f))
draw = ImageDraw.Draw(image)
# reddit tells me this patten sucks, but I like it
try:
image_size
except NameError:
image_size = image.size
# multiple lines in text
if len(text) == 2:
# at most 2?
text_size = font.getsize(text[0])
x = (image_size[0]/2) - (text_size[0]/2)
y = image_size[1] - (2*text_size[1]) - 5 # padding
drawText(draw, x, y, text[0], font)
text_size = font.getsize(text[1])
x = (image_size[0]/2) - (text_size[0]/2)
y += text_size[1]
drawText(draw, x, y, text[1], font)
else:
text_size = font.getsize(text[0])
x = (image_size[0]/2) - (text_size[0]/2)
y = image_size[1] - text_size[1] - 5 # padding
drawText(draw, x, y, text[0], font)
image.save(os.path.join(directory,f))
subprocess.call(["convert", '-loop', '0', os.path.join(directory, '*.png'), os.path.join(gif_dir, "temp"+str(index)+".gif")])
shutil.rmtree(directory)
subprocess.call(["convert", '-loop', '0', os.path.join(gif_dir, '*.gif'), output])
shutil.rmtree(gif_dir)
def generateAllGifs():
stream = file('files.yml', 'r')
data = yaml.load(stream)
if "outpath" in data:
outpath = data["outpath"]
else:
outpath = ""
for file_data in data["files"]:
video_file_path = file_data["video"]
sub_file_path = file_data["subs"]
if "encoding" in file_data:
sub_encoding = file_data["encoding"]
else:
sub_encoding = "utf-8"
subs = pysrt.open(sub_file_path, encoding=sub_encoding)
# generate a gif for every line of dialogue
for sub in subs:
# 00:00:00,000 => 00:00:00.000
start = str(sub.start).replace(',', '.')
end = str(sub.end - sub.start).replace(',', '.')
gif_filename = os.path.join(outpath, slugify(sub.text) + ".gif")
if os.path.isfile(gif_filename):
next
else:
print "generating " + gif_filename + "..."
makeGif(video_file_path, start, end, sub.text, gif_filename)
if __name__ == '__main__':
generateAllGifs()