forked from SpikeAI/2019-07-15_CNS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
deck.py
112 lines (99 loc) · 4.61 KB
/
deck.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
__author__ = "Laurent Perrinet INT - CNRS"
__licence__ = 'GPL licence'
import os
################################################################################
class Slide:
def __init__(self, contents=[], subtitles=[], fontsizes=[],
type='text', color='white', bg_color='black', duration=1):
self.type = type
self.subtitles = subtitles
self.duration = duration
self.contents = contents
self.fontsizes = fontsizes
self.color = color
self.bg_color = bg_color
################################################################################
# http://zulko.github.io/moviepy/ref/VideoClip/VideoClip.html
from moviepy.editor import VideoFileClip, ImageClip, TextClip, CompositeVideoClip, ColorClip
################################################################################
class Deck:
def __init__(self,
videoname = "2020-09-10_video-abstract", fps=6, do_gif=True,
figpath = 'figures',
H=500, W=800, border_ratio=.12):
self.W = W
self.H = H
self.H_fig, self.W_fig = int(H-H*border_ratio), int(W-W*border_ratio)
self.videoname = videoname
self.do_gif = do_gif
if self.do_gif: self.gifname = videoname + ".gif"
self.figpath = figpath
self.fps = fps
self.txt_opts = dict(font="Open-Sans-Regular", align='center',
color='white',
size=(W,H), method='caption')
#self.txt_opts = dict(fontsize=65, bg_color='white', align='center', **opt_st)
self.sub_opts = dict(font="Open-Sans-SemiBold", fontsize=30, align='South',
#bg_color='white',
color='orange',
size=(W,H), method='caption')
def compositing(self, slides):
t = 0
clips = []
for slide in slides:
# contains figures or text
if len(slide.contents)>0:
# background
clip = ColorClip(color=(0, 0, 0), size=(self.W, self.H))
clip = clip.set_start(t).set_duration(slide.duration)
clips.append(clip)
sub_duration = slide.duration / len(slide.contents)
for i_, content in enumerate(slide.contents):
if slide.type == 'text':
if len(slide.fontsizes)==0:
fontsize = 35 # default
elif len(slide.fontsizes)==1:
fontsize = slide.fontsizes
else:
fontsize = slide.fontsizes[i_]
clip = TextClip(content, bg_color=slide.bg_color,
fontsize=fontsize, **self.txt_opts)
else:
# drawing the list of figures
clip = ImageClip(os.path.join(self.figpath, content))
# time
clip = clip.set_start(t).set_duration(sub_duration)
# space
clip = clip.resize(height=self.H_fig, width=self.W_fig)
clip = clip.set_pos(("center", "top"))
clips.append(clip)
t += sub_duration
if len(slide.subtitles)>0:
# overlaying subtitles
t -= slide.duration # be kind, rewind
sub_duration = slide.duration / len(slide.subtitles)
for subtitle in slide.subtitles:
sub = TextClip(subtitle, **self.sub_opts)
# time
sub = sub.set_start(t).set_duration(sub_duration)
# space
sub = sub.resize(height=self.H_fig, width=self.W_fig)
sub = sub.set_pos('center')
#sub = sub.on_color(size=(clip.w + sub.w, sub.h-10),
# color=(0,0,0), pos=(6,'center'), col_opacity=0.6)
clips.append(sub)
t += sub_duration
else:
print('/!\ no subtitle', slide.contents)
return clips
def compiling(self, clips):
# Compostiting all clips
video = CompositeVideoClip(clips)
print('Writing', self.videoname + '.mp4')
video.write_videofile(self.videoname + '.mp4', fps=self.fps)
if self.do_gif:
print('Writing', self.gifname)
video.write_gif(self.gifname, fps=self.fps)
from pygifsicle import optimize
optimize(self.gifname)
print('Done')