| a/trunk/tubetutor/ffmpeg.py | b/trunk/tubetutor/ffmpeg.py | ||
|---|---|---|---|
... |
... |
||
| 17 | #font="Arial" |
17 | #font="Arial" |
| 18 | font=os.path.join("media", "Roboto-Regular.ttf") |
18 | font=os.path.join("media", "Roboto-Regular.ttf") |
| 19 | proc_ffmpeg=None |
19 | proc_ffmpeg=None |
| 20 | 20 | ||
| 21 | if platform.system() == "Linux": |
21 | if platform.system() == "Linux": |
| 22 | grabber="-video_size 1920x1080 -f x11grab -framerate 20 -i :0.0" |
22 | grabber="-video_size 1920x1080 -f x11grab -framerate 20 -i :0.0 -f pulse -i 1" |
| 23 | else: |
23 | else: |
| 24 | grabber="-f gdigrab -framerate 20 -i desktop" |
24 | grabber="-f gdigrab -framerate 20 -i desktop" |
| 25 | 25 | ||
| 26 | # |
26 | # |
| 27 | # The following helper functions will retrieve the pathnames for the ffmpeg tools |
27 | # The following helper functions will retrieve the pathnames for the ffmpeg tools |
| 28 | # |
28 | # |
| 29 | def get_cmd_ffmpeg(): |
29 | def get_cmd_ffmpeg(): |
| 30 | subdir=os.path.join(os.path.dirname(sys.argv[0]), "ffmpeg") |
30 | subdir=os.path.join(os.path.dirname(sys.argv[0]), "ffmpeg -loglevel verbose") |
| 31 | if os.path.exists(subdir): |
31 | if os.path.exists(subdir): |
| 32 | return os.path.join(subdir, "ffmpeg.exe") |
32 | return os.path.join(subdir, "ffmpeg.exe -loglevel verbose") |
| 33 | return "ffmpeg" |
33 | return "ffmpeg -loglevel verbose" |
| 34 | 34 | ||
| 35 | def get_cmd_ffprobe(): |
35 | def get_cmd_ffprobe(): |
| 36 | subdir=os.path.join(os.path.dirname(sys.argv[0]), "ffmpeg") |
36 | subdir=os.path.join(os.path.dirname(sys.argv[0]), "ffmpeg") |
| 37 | if os.path.exists(subdir): |
37 | if os.path.exists(subdir): |
| 38 | return os.path.join(subdir, "ffprobe.exe") |
38 | return os.path.join(subdir, "ffprobe.exe") |
... |
... |
||
| 55 | cmd += " " + output |
55 | cmd += " " + output |
| 56 | print ("====================================================") |
56 | print ("====================================================") |
| 57 | print ("cmd: %s" % cmd) |
57 | print ("cmd: %s" % cmd) |
| 58 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) |
58 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) |
| 59 | (out, error) = p.communicate() |
59 | (out, error) = p.communicate() |
| 60 | if p.returncode != 0: |
||
| 61 | raise Exception('error: command failed: %s' % cmd) |
||
| 60 | print("output:\n%s" % out) |
62 | print("output:\n%s" % out) |
| 61 | print("error:\n%s" % error) |
63 | print("error:\n%s" % error) |
| 62 | 64 | ||
| 63 | def start(filename, params): |
65 | def start(filename, params): |
| 64 | global proc_ffmpeg |
66 | global proc_ffmpeg |
... |
... |
||
| 99 | cmd += " -show_entries format=duration" |
101 | cmd += " -show_entries format=duration" |
| 100 | print ("====================================================") |
102 | print ("====================================================") |
| 101 | print ("cmd: %s" % cmd) |
103 | print ("cmd: %s" % cmd) |
| 102 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) |
104 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) |
| 103 | (output, error) = p.communicate() |
105 | (output, error) = p.communicate() |
| 106 | if p.returncode != 0: |
||
| 107 | raise Exception('error: command failed: %s' % cmd) |
||
| 104 | print("duration output: %s - %s" % (output, error)) |
108 | print("duration output: %s - %s" % (output, error)) |
| 105 | durations = re.findall(r'duration=[0-9.]*', str(output)) |
109 | durations = re.findall(r'duration=[0-9.]*', str(output)) |
| 106 | for d in durations: |
110 | for d in durations: |
| 107 | duration = d.split("=")[1] |
111 | duration = d.split("=")[1] |
| 108 | print("duration string: %s" % duration) |
112 | print("duration string: %s" % duration) |
... |
... |
||
| 147 | convert_image(os.path.join("media", "back.png"), image, params) |
151 | convert_image(os.path.join("media", "back.png"), image, params) |
| 148 | self.add_image(image, duration) |
152 | self.add_image(image, duration) |
| 149 | return content |
153 | return content |
| 150 | 154 | ||
| 151 | def add_image(self, filename, duration=5, fadein=True): |
155 | def add_image(self, filename, duration=5, fadein=True): |
| 152 | print(self.tmppath) |
156 | print("*** add_image(%s, %d, %s)" % (filename, duration, fadein)) |
| 153 | tmpimage = os.path.join(self.tmppath, os.path.basename(filename) + ".png") |
157 | tmpimage = os.path.join(self.tmppath, os.path.basename(filename) + ".png") |
| 154 | tmpfilename = os.path.join(self.tmppath, os.path.basename(filename) + ".mkv") |
158 | tmpfilename = os.path.join(self.tmppath, os.path.basename(filename) + ".mkv") |
| 155 | params = " -scale %s!" % self.vidresolution.replace(":", "x") |
159 | params = " -scale %s!" % self.vidresolution.replace(":", "x") |
| 156 | convert_image(filename, tmpimage, params) |
160 | convert_image(filename, tmpimage, params) |
| 157 | 161 | ||
| 158 | params = " -y -loop 1 -t %d -i %s" % (duration, tmpimage) |
162 | params = " -y -loop 1 -t %d -i %s" % (duration, tmpimage) |
| 163 | # add silent audio |
||
| 164 | params += " -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -shortest" |
||
| 159 | if fadein: |
165 | if fadein: |
| 160 | params += " -filter_complex \"fade=in:0:d=1[v];[v]fade=out:st=%f:d=2\"" % ((duration-2)) |
166 | params += " -filter_complex \"fade=in:0:d=1[v];[v]fade=out:st=%f:d=2\"" % ((duration-2)) |
| 161 | else: |
167 | else: |
| 162 | params += " -filter_complex \"fade=out:st=%f:d=1\"" % ((duration-3)) |
168 | params += " -filter_complex \"fade=out:st=%f:d=1\"" % ((duration-3)) |
| 163 | params += self.qfilter |
169 | params += self.qfilter |
... |
... |
||
| 166 | 172 | ||
| 167 | self.pconcat += " -i %s" % (tmpfilename) |
173 | self.pconcat += " -i %s" % (tmpfilename) |
| 168 | self.nconcat+=1 |
174 | self.nconcat+=1 |
| 169 | 175 | ||
| 170 | def add_video(self, filename): |
176 | def add_video(self, filename): |
| 177 | print("*** add_video(%s)" % (filename)) |
||
| 171 | # fade video temporarily |
178 | # fade video temporarily |
| 172 | tmpfilename = os.path.join(self.tmppath, "add_" + os.path.basename(filename)) |
179 | tmpfilename = os.path.join(self.tmppath, "add_" + os.path.basename(filename)) |
| 173 | (w,h) = self.vidresolution.split(":") |
180 | (w,h) = self.vidresolution.split(":") |
| 174 | params = " -y -i %s -filter_complex \"scale=-1:%s[v];[v]crop=%s:0:0[v];[v]fade=in:0:10\"" % (filename, h, self.vidresolution) |
181 | params = " -y -i %s -filter_complex \"scale=-1:%s[v];[v]crop=%s:0:0[v];[v]fade=in:0:10\"" % (filename, h, self.vidresolution) |
| 175 | params += self.qfilter |
182 | params += self.qfilter |
... |
... |
||
| 178 | 185 | ||
| 179 | self.pconcat += " -i %s" % (tmpfilename) |
186 | self.pconcat += " -i %s" % (tmpfilename) |
| 180 | self.nconcat+=1 |
187 | self.nconcat+=1 |
| 181 | 188 | ||
| 182 | def speedup(self, filename, pts=0.7): |
189 | def speedup(self, filename, pts=0.7): |
| 190 | print("*** speedup(%s, %f)" % (filename, pts)) |
||
| 183 | params = " -i %s -y -filter:v \"setpts=%f*PTS\"" % (self.lastfilename, pts) |
191 | params = " -i %s -y -filter:v \"setpts=%f*PTS\"" % (self.lastfilename, pts) |
| 184 | params += self.qfilter |
192 | params += self.qfilter |
| 185 | self.lastfilename = filename |
193 | self.lastfilename = filename |
| 186 | start(filename, params) |
194 | start(filename, params) |
| 187 | wait() |
195 | wait() |
| 188 | 196 | ||
| 189 | def mux(self, filename, audiofile): |
197 | def mux(self, filename, audiofile): |
| 198 | print("*** mux(%s, %s)" % (filename, audiofile)) |
||
| 190 | duration = video_duration(self.lastfilename) |
199 | duration = video_duration(self.lastfilename) |
| 191 | params = " -i %s -i %s -y" % (self.lastfilename, audiofile) |
200 | params = " -i %s -i %s -y" % (self.lastfilename, audiofile) |
| 192 | params += " -t %d" % (int(duration)+1) |
201 | params += " -t %d" % (int(duration)+1) |
| 193 | params += " -af \"afade=out:st=%f:d=3\"" % (duration-3.0) |
202 | params += " -filter_complex \"[0:a][1:a]amerge,afade=out:st=%f:d=3\"" % (duration-3.0) |
| 194 | params += " -map 0:v:0 -map 1:a:0" |
203 | params += " -map 0:v:0 -map 1:a:0" |
| 195 | params += self.qfilter |
204 | params += self.qfilter |
| 196 | self.lastfilename = filename |
205 | self.lastfilename = filename |
| 197 | start(filename, params) |
206 | start(filename, params) |
| 198 | wait() |
207 | wait() |
... |
... |
||
| 236 | self.lastfilename = filename |
245 | self.lastfilename = filename |
| 237 | params += self.qfilter |
246 | params += self.qfilter |
| 238 | start(filename, params) |
247 | start(filename, params) |
| 239 | wait() |
248 | wait() |
| 240 | 249 | ||
| 241 | 250 | ||
| 242 | 251 |