a/trunk/tubetutor/ffmpeg.py | b/trunk/tubetutor/ffmpeg.py | ||
---|---|---|---|
... |
... |
||
5 | # <script path>/ffmpeg |
5 | # <script path>/ffmpeg |
6 | # |
6 | # |
7 | # Otherwise, the windows search path is used |
7 | # Otherwise, the windows search path is used |
8 | # |
8 | # |
9 | import subprocess |
9 | import subprocess |
10 | import ctypes |
10 | import platform |
11 | import ctypes |
||
12 | import signal |
||
11 | import sys |
13 | import sys |
12 | import os |
14 | import os |
13 | import re |
15 | import re |
14 | 16 | ||
15 | #font="Arial" |
17 | #font="Arial" |
16 | font=os.path.join("media", "Roboto-Regular.ttf") |
18 | font=os.path.join("media", "Roboto-Regular.ttf") |
17 | proc_ffmpeg=None |
19 | proc_ffmpeg=None |
18 | 20 | ||
21 | if platform.system() == "Linux": |
||
22 | grabber="-video_size 1920x1080 -f x11grab -framerate 20 -i :0.0" |
||
23 | else: |
||
24 | grabber="-f gdigrab -framerate 20 -i desktop" |
||
25 | |||
19 | # |
26 | # |
20 | # 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 |
21 | # |
28 | # |
22 | def get_cmd_ffmpeg(): |
29 | def get_cmd_ffmpeg(): |
23 | subdir=os.path.join(os.path.dirname(sys.argv[0]), "ffmpeg") |
30 | subdir=os.path.join(os.path.dirname(sys.argv[0]), "ffmpeg") |
24 | if os.path.exists(subdir): |
31 | if os.path.exists(subdir): |
25 | return os.path.join(subdir, "ffmpeg.exe") |
32 | return os.path.join(subdir, "ffmpeg.exe") |
26 | return "ffmpeg.exe" |
33 | return "ffmpeg" |
27 | 34 | ||
28 | def get_cmd_ffprobe(): |
35 | def get_cmd_ffprobe(): |
29 | subdir=os.path.join(os.path.dirname(sys.argv[0]), "ffmpeg") |
36 | subdir=os.path.join(os.path.dirname(sys.argv[0]), "ffmpeg") |
30 | if os.path.exists(subdir): |
37 | if os.path.exists(subdir): |
31 | return os.path.join(subdir, "ffprobe.exe") |
38 | return os.path.join(subdir, "ffprobe.exe") |
32 | return "ffprobe.exe" |
39 | return "ffprobe" |
33 | 40 | ||
34 | def get_cmd_convert(): |
41 | def get_cmd_convert(): |
35 | subdir=os.path.join(os.path.dirname(sys.argv[0]), "imagemagick") |
42 | subdir=os.path.join(os.path.dirname(sys.argv[0]), "imagemagick") |
36 | if os.path.exists(subdir): |
43 | if os.path.exists(subdir): |
37 | return os.path.join(subdir, "convert.exe") |
44 | return os.path.join(subdir, "convert.exe") |
38 | return "convert.exe" |
45 | return "convert" |
39 | 46 | ||
40 | def is_recording(): |
47 | def is_recording(): |
41 | return proc_ffmpeg != None |
48 | return proc_ffmpeg != None |
42 | 49 | ||
43 | def convert_image(input, output, params): |
50 | def convert_image(input, output, params): |
... |
... |
||
46 | cmd += " " + input |
53 | cmd += " " + input |
47 | cmd += " " + params |
54 | cmd += " " + params |
48 | cmd += " " + output |
55 | cmd += " " + output |
49 | print ("====================================================") |
56 | print ("====================================================") |
50 | print ("cmd: %s" % cmd) |
57 | print ("cmd: %s" % cmd) |
51 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=False) |
58 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) |
52 | (out, error) = p.communicate() |
59 | (out, error) = p.communicate() |
53 | print("output:\n%s" % out) |
60 | print("output:\n%s" % out) |
54 | print("error:\n%s" % error) |
61 | print("error:\n%s" % error) |
55 | 62 | ||
56 | def start(filename, params): |
63 | def start(filename, params): |
... |
... |
||
62 | cmd = get_cmd_ffmpeg() |
69 | cmd = get_cmd_ffmpeg() |
63 | cmd += " " + params |
70 | cmd += " " + params |
64 | cmd += " " + filename |
71 | cmd += " " + filename |
65 | print ("====================================================") |
72 | print ("====================================================") |
66 | print ("cmd: %s" % cmd) |
73 | print ("cmd: %s" % cmd) |
67 | proc_ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=False) |
74 | if platform.system() == "Linux": |
75 | proc_ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid) |
||
76 | else: |
||
77 | proc_ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) |
||
68 | 78 | ||
69 | def record(filename, resolution=""): |
79 | def record(filename, resolution=""): |
70 | if resolution != "": |
80 | if resolution != "": |
71 | start(filename, " -f gdigrab -framerate 20 -i desktop -y -vf scale=%s -v:q 1" % (resolution)) |
81 | start(filename, " %s -y -vf scale=%s -v:q 1" % (grabber, resolution)) |
72 | else: |
82 | else: |
73 | start(filename, " -f gdigrab -framerate 20 -i desktop -y -v:q 1") |
83 | start(filename, " %s -y -v:q 1" % (grabber)) |
74 | 84 | ||
75 | def stop(): |
85 | def stop(): |
76 | global proc_ffmpeg |
86 | global proc_ffmpeg |
77 | # Kill remaining ffmpeg instances |
87 | # Kill remaining ffmpeg instances |
78 | if proc_ffmpeg: |
88 | if proc_ffmpeg: |
79 | ctypes.windll.kernel32.TerminateProcess(int(proc_ffmpeg._handle), -1) |
89 | try: |
90 | ctypes.windll.kernel32.TerminateProcess(int(proc_ffmpeg._handle), -1) |
||
91 | except: |
||
92 | os.killpg(os.getpgid(proc_ffmpeg.pid), signal.SIGTERM) |
||
80 | proc_ffmpeg.kill() |
93 | proc_ffmpeg.kill() |
81 | proc_ffmpeg=None |
94 | proc_ffmpeg=None |
82 | 95 | ||
83 | def video_duration(filename): |
96 | def video_duration(filename): |
84 | cmd = get_cmd_ffprobe() |
97 | cmd = get_cmd_ffprobe() |
85 | cmd += " -i %s" % filename |
98 | cmd += " -i %s" % filename |
86 | cmd += " -show_entries format=duration" |
99 | cmd += " -show_entries format=duration" |
87 | print ("====================================================") |
100 | print ("====================================================") |
88 | print ("cmd: %s" % cmd) |
101 | print ("cmd: %s" % cmd) |
89 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=False) |
102 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) |
90 | (output, error) = p.communicate() |
103 | (output, error) = p.communicate() |
91 | print("duration output: %s - %s" % (output, error)) |
104 | print("duration output: %s - %s" % (output, error)) |
92 | durations = re.findall(r'duration=[0-9.]*', str(output)) |
105 | durations = re.findall(r'duration=[0-9.]*', str(output)) |
93 | for d in durations: |
106 | for d in durations: |
94 | duration = d.split("=")[1] |
107 | duration = d.split("=")[1] |
... |
... |
||
150 | self.pconcat += " -i %s" % (tmpfilename) |
163 | self.pconcat += " -i %s" % (tmpfilename) |
151 | self.nconcat+=1 |
164 | self.nconcat+=1 |
152 | 165 | ||
153 | def add_video(self, filename): |
166 | def add_video(self, filename): |
154 | # fade video temporarily |
167 | # fade video temporarily |
155 | tmpfilename = os.path.join(self.tmppath, os.path.basename(filename)) |
168 | tmpfilename = os.path.join(self.tmppath, "add_" + os.path.basename(filename)) |
156 | (w,h) = self.vidresolution.split(":") |
169 | (w,h) = self.vidresolution.split(":") |
157 | 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) |
170 | 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) |
158 | params += self.qfilter |
171 | params += self.qfilter |
159 | start(tmpfilename, params) |
172 | start(tmpfilename, params) |
160 | wait() |
173 | wait() |
... |
... |
||
212 | 225 | ||
213 | def tmppath(self, path): |
226 | def tmppath(self, path): |
214 | self.tmppath = path |
227 | self.tmppath = path |
215 | 228 | ||
216 | def process(self, filename, param): |
229 | def process(self, filename, param): |
230 | print("process %s -> %s" % (self.lastfilename, filename)) |
||
217 | params = " -y -i %s %s " % (self.lastfilename, param) |
231 | params = " -y -i %s %s " % (self.lastfilename, param) |
218 | self.lastfilename = filename |
232 | self.lastfilename = filename |
219 | params += self.qfilter |
233 | params += self.qfilter |
220 | start(filename, params) |
234 | start(filename, params) |
221 | wait() |
235 | wait() |