Diff of /trunk/tubetutor/ffmpeg.py [r8] .. [r9]  Maximize  Restore

Switch to side-by-side view

--- a/trunk/tubetutor/ffmpeg.py
+++ b/trunk/tubetutor/ffmpeg.py
@@ -19,224 +19,233 @@
 proc_ffmpeg=None
 
 if platform.system() == "Linux":
-	grabber="-video_size 1920x1080 -f x11grab -framerate 20 -i :0.0"
+    grabber="-video_size 1920x1080 -f x11grab -framerate 20 -i :0.0 -f pulse -i 1"
 else:
-	grabber="-f gdigrab -framerate 20 -i desktop"
+    grabber="-f gdigrab -framerate 20 -i desktop"
 
 #
 # The following helper functions will retrieve the pathnames for the ffmpeg tools
 #
 def get_cmd_ffmpeg():
-	subdir=os.path.join(os.path.dirname(sys.argv[0]), "ffmpeg")
-	if os.path.exists(subdir):
-		return os.path.join(subdir, "ffmpeg.exe")
-	return "ffmpeg"
+    subdir=os.path.join(os.path.dirname(sys.argv[0]), "ffmpeg -loglevel verbose")
+    if os.path.exists(subdir):
+        return os.path.join(subdir, "ffmpeg.exe -loglevel verbose")
+    return "ffmpeg -loglevel verbose"
 
 def get_cmd_ffprobe():
-	subdir=os.path.join(os.path.dirname(sys.argv[0]), "ffmpeg")
-	if os.path.exists(subdir):
-		return os.path.join(subdir, "ffprobe.exe")
-	return "ffprobe"
+    subdir=os.path.join(os.path.dirname(sys.argv[0]), "ffmpeg")
+    if os.path.exists(subdir):
+        return os.path.join(subdir, "ffprobe.exe")
+    return "ffprobe"
 
 def get_cmd_convert():
-	subdir=os.path.join(os.path.dirname(sys.argv[0]), "imagemagick")
-	if os.path.exists(subdir):
-		return os.path.join(subdir, "convert.exe")
-	return "convert"
+    subdir=os.path.join(os.path.dirname(sys.argv[0]), "imagemagick")
+    if os.path.exists(subdir):
+        return os.path.join(subdir, "convert.exe")
+    return "convert"
 
 def is_recording():
-	return proc_ffmpeg != None
+    return proc_ffmpeg != None
 
 def convert_image(input, output, params):
-	global font
-	cmd = get_cmd_convert()
-	cmd += " " + input
-	cmd += " " + params
-	cmd += " " + output
-	print ("====================================================")
-	print ("cmd: %s" % cmd)
-	p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
-	(out, error) = p.communicate()
-	print("output:\n%s" % out)
-	print("error:\n%s" % error)
+    global font
+    cmd = get_cmd_convert()
+    cmd += " " + input
+    cmd += " " + params
+    cmd += " " + output
+    print ("====================================================")
+    print ("cmd: %s" % cmd)
+    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
+    (out, error) = p.communicate()
+    if p.returncode != 0:
+        raise Exception('error: command failed: %s' % cmd)
+    print("output:\n%s" % out)
+    print("error:\n%s" % error)
 
 def start(filename, params):
-	global proc_ffmpeg
-
-	# Kill remaining ffmpeg instances
-	stop()
-	# execute ffmpeg cmd
-	cmd = get_cmd_ffmpeg()
-	cmd += " " + params
-	cmd += " " + filename
-	print ("====================================================")
-	print ("cmd: %s" % cmd)
-	if platform.system() == "Linux":
-		proc_ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
-	else:
-		proc_ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
+    global proc_ffmpeg
+
+    # Kill remaining ffmpeg instances
+    stop()
+    # execute ffmpeg cmd
+    cmd = get_cmd_ffmpeg()
+    cmd += " " + params
+    cmd += " " + filename
+    print ("====================================================")
+    print ("cmd: %s" % cmd)
+    if platform.system() == "Linux":
+        proc_ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
+    else:
+        proc_ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
 
 def record(filename, resolution=""):
-	if resolution != "":
-		start(filename, " %s -y -vf scale=%s -v:q 1" % (grabber, resolution))
-	else:
-		start(filename, " %s -y -v:q 1" % (grabber))
+    if resolution != "":
+        start(filename, " %s -y -vf scale=%s -v:q 1" % (grabber, resolution))
+    else:
+        start(filename, " %s -y -v:q 1" % (grabber))
 
 def stop():
-	global proc_ffmpeg
-	# Kill remaining ffmpeg instances
-	if proc_ffmpeg:
-		try:
-			ctypes.windll.kernel32.TerminateProcess(int(proc_ffmpeg._handle), -1)
-		except:
-			os.killpg(os.getpgid(proc_ffmpeg.pid), signal.SIGTERM)
-		proc_ffmpeg.kill()
-		proc_ffmpeg=None
-		
+    global proc_ffmpeg
+    # Kill remaining ffmpeg instances
+    if proc_ffmpeg:
+        try:
+            ctypes.windll.kernel32.TerminateProcess(int(proc_ffmpeg._handle), -1)
+        except:
+            os.killpg(os.getpgid(proc_ffmpeg.pid), signal.SIGTERM)
+        proc_ffmpeg.kill()
+        proc_ffmpeg=None
+        
 def video_duration(filename):
-	cmd = get_cmd_ffprobe()
-	cmd += " -i %s" % filename
-	cmd += " -show_entries format=duration"
-	print ("====================================================")
-	print ("cmd: %s" % cmd)
-	p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
-	(output, error) = p.communicate()
-	print("duration output: %s - %s" % (output, error))
-	durations = re.findall(r'duration=[0-9.]*', str(output))
-	for d in durations:
-		duration = d.split("=")[1]
-		print("duration string: %s" % duration)
-		print("duration: %f" % float(duration))
-		return float(duration)
+    cmd = get_cmd_ffprobe()
+    cmd += " -i %s" % filename
+    cmd += " -show_entries format=duration"
+    print ("====================================================")
+    print ("cmd: %s" % cmd)
+    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
+    (output, error) = p.communicate()
+    if p.returncode != 0:
+        raise Exception('error: command failed: %s' % cmd)
+    print("duration output: %s - %s" % (output, error))
+    durations = re.findall(r'duration=[0-9.]*', str(output))
+    for d in durations:
+        duration = d.split("=")[1]
+        print("duration string: %s" % duration)
+        print("duration: %f" % float(duration))
+        return float(duration)
 
 def wait():
-	global proc_ffmpeg
-	if proc_ffmpeg:
-		(out, error) = proc_ffmpeg.communicate()
-		print("output:\n%s" % out)
-		print("error:\n%s" % error)
-		proc_ffmpeg = None
+    global proc_ffmpeg
+    if proc_ffmpeg:
+        (out, error) = proc_ffmpeg.communicate()
+        print("output:\n%s" % out)
+        print("error:\n%s" % error)
+        proc_ffmpeg = None
 
 class renderer:
-	pconcat=""
-	nconcat=0
-	vidfilter=[]
-	vidresolution=""
-	lastfilename=""
-	tmppath=""
-	framerate=20
-	qfilter=" -v:q 1 "
-
-	def __init__(self):
-		self.tmppath = os.path.join("videos", "tmp")
-		self.framerate = 20
-		
-	def add_text(self, filename, duration=5):
-		f = open(filename, "r")
-		if f:
-			content = f.read()
-			f.close()
-		if content.replace("\n", "") == "":
-			return
-
-		params = " -scale %s!" % self.vidresolution.replace(":", "x")
-		params += " -font %s -weight 500 -pointsize 75" % font
-		params += " -draw \"gravity northwest fill white text 100,650 '%s'\"" % content
-		params += " -scale %s!" % self.vidresolution.replace(":", "x")
-		image = os.path.splitext(filename)[0] + ".png"
-		convert_image(os.path.join("media", "back.png"), image, params)
-		self.add_image(image, duration)
-		return content
-	
-	def add_image(self, filename, duration=5, fadein=True):
-		print(self.tmppath)
-		tmpimage = os.path.join(self.tmppath, os.path.basename(filename) + ".png")
-		tmpfilename = os.path.join(self.tmppath, os.path.basename(filename) + ".mkv")
-		params = " -scale %s!" % self.vidresolution.replace(":", "x")
-		convert_image(filename, tmpimage, params)
-
-		params = " -y -loop 1 -t %d -i %s" % (duration, tmpimage)
-		if fadein:
-			params += " -filter_complex \"fade=in:0:d=1[v];[v]fade=out:st=%f:d=2\"" % ((duration-2))
-		else:
-			params += " -filter_complex \"fade=out:st=%f:d=1\"" % ((duration-3))
-		params += self.qfilter
-		start(tmpfilename, params)
-		wait()
-
-		self.pconcat += " -i %s" % (tmpfilename)
-		self.nconcat+=1
-	
-	def add_video(self, filename):
-		# fade video temporarily
-		tmpfilename = os.path.join(self.tmppath, "add_" + os.path.basename(filename))
-		(w,h) = self.vidresolution.split(":")
-		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)
-		params += self.qfilter
-		start(tmpfilename, params)
-		wait()
-		
-		self.pconcat += " -i %s" % (tmpfilename)
-		self.nconcat+=1
-
-	def speedup(self, filename, pts=0.7):
-		params = " -i %s -y -filter:v \"setpts=%f*PTS\"" % (self.lastfilename, pts)
-		params += self.qfilter
-		self.lastfilename = filename
-		start(filename, params)
-		wait()
-
-	def mux(self, filename, audiofile):
-		duration = video_duration(self.lastfilename)
-		params = " -i %s -i %s -y" % (self.lastfilename, audiofile)
-		params += " -t %d" % (int(duration)+1)
-		params += " -af \"afade=out:st=%f:d=3\"" % (duration-3.0)
-		params += " -map 0:v:0 -map 1:a:0"
-		params += self.qfilter
-		self.lastfilename = filename
-		start(filename, params)
-		wait()
-
-	def filter(self, filter):
-		self.vidfilter = filter
-
-	def resolution(self, resolution):
-		self.vidresolution = resolution
-
-	def concat(self, filename, audio=False):
-		if self.lastfilename != "":
-			self.nconcat += 1
-			self.pconcat = "-i %s %s " % (self.lastfilename, self.pconcat)
-
-		if audio:
-			a=1
-		else:
-			a=0
-		if len(self.vidfilter) > 0:
-			params = self.pconcat + " -y -filter_complex \"concat=n=%d:v=1:a=%d,%s\"" % (a, self.nconcat, ",".join(self.vidfilter))
-		else:
-			params = self.pconcat + " -y -filter_complex concat=n=%d:v=1:a=%d" % (self.nconcat, a)
-		self.lastfilename = filename
-		params += self.qfilter
-		start(filename, params)
-		wait()
-
-	def filename(self, filename):
-		self.lastfilename = filename
-
-	def framerate(self, framerate):
-		self.framerate = framerate
-
-	def tmppath(self, path):
-		self.tmppath = path
-
-	def process(self, filename, param):
-		print("process %s -> %s" % (self.lastfilename, filename))
-		params = " -y -i %s %s " % (self.lastfilename, param)
-		self.lastfilename = filename
-		params += self.qfilter
-		start(filename, params)
-		wait()
-		
-		
-
+    pconcat=""
+    nconcat=0
+    vidfilter=[]
+    vidresolution=""
+    lastfilename=""
+    tmppath=""
+    framerate=20
+    qfilter=" -v:q 1 "
+
+    def __init__(self):
+        self.tmppath = os.path.join("videos", "tmp")
+        self.framerate = 20
+        
+    def add_text(self, filename, duration=5):
+        f = open(filename, "r")
+        if f:
+            content = f.read()
+            f.close()
+        if content.replace("\n", "") == "":
+            return
+
+        params = " -scale %s!" % self.vidresolution.replace(":", "x")
+        params += " -font %s -weight 500 -pointsize 75" % font
+        params += " -draw \"gravity northwest fill white text 100,650 '%s'\"" % content
+        params += " -scale %s!" % self.vidresolution.replace(":", "x")
+        image = os.path.splitext(filename)[0] + ".png"
+        convert_image(os.path.join("media", "back.png"), image, params)
+        self.add_image(image, duration)
+        return content
+    
+    def add_image(self, filename, duration=5, fadein=True):
+        print("*** add_image(%s, %d, %s)" % (filename, duration, fadein))
+        tmpimage = os.path.join(self.tmppath, os.path.basename(filename) + ".png")
+        tmpfilename = os.path.join(self.tmppath, os.path.basename(filename) + ".mkv")
+        params = " -scale %s!" % self.vidresolution.replace(":", "x")
+        convert_image(filename, tmpimage, params)
+
+        params = " -y -loop 1 -t %d -i %s" % (duration, tmpimage)
+        # add silent audio
+        params += " -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -shortest"
+        if fadein:
+            params += " -filter_complex \"fade=in:0:d=1[v];[v]fade=out:st=%f:d=2\"" % ((duration-2))
+        else:
+            params += " -filter_complex \"fade=out:st=%f:d=1\"" % ((duration-3))
+        params += self.qfilter
+        start(tmpfilename, params)
+        wait()
+
+        self.pconcat += " -i %s" % (tmpfilename)
+        self.nconcat+=1
+    
+    def add_video(self, filename):
+        print("*** add_video(%s)" % (filename))
+        # fade video temporarily
+        tmpfilename = os.path.join(self.tmppath, "add_" + os.path.basename(filename))
+        (w,h) = self.vidresolution.split(":")
+        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)
+        params += self.qfilter
+        start(tmpfilename, params)
+        wait()
+        
+        self.pconcat += " -i %s" % (tmpfilename)
+        self.nconcat+=1
+
+    def speedup(self, filename, pts=0.7):
+        print("*** speedup(%s, %f)" % (filename, pts))
+        params = " -i %s -y -filter:v \"setpts=%f*PTS\"" % (self.lastfilename, pts)
+        params += self.qfilter
+        self.lastfilename = filename
+        start(filename, params)
+        wait()
+
+    def mux(self, filename, audiofile):
+        print("*** mux(%s, %s)" % (filename, audiofile))
+        duration = video_duration(self.lastfilename)
+        params = " -i %s -i %s -y" % (self.lastfilename, audiofile)
+        params += " -t %d" % (int(duration)+1)
+        params += " -filter_complex \"[0:a][1:a]amerge,afade=out:st=%f:d=3\"" % (duration-3.0)
+        params += " -map 0:v:0 -map 1:a:0"
+        params += self.qfilter
+        self.lastfilename = filename
+        start(filename, params)
+        wait()
+
+    def filter(self, filter):
+        self.vidfilter = filter
+
+    def resolution(self, resolution):
+        self.vidresolution = resolution
+
+    def concat(self, filename, audio=False):
+        if self.lastfilename != "":
+            self.nconcat += 1
+            self.pconcat = "-i %s %s " % (self.lastfilename, self.pconcat)
+
+        if audio:
+            a=1
+        else:
+            a=0
+        if len(self.vidfilter) > 0:
+            params = self.pconcat + " -y -filter_complex \"concat=n=%d:v=1:a=%d,%s\"" % (a, self.nconcat, ",".join(self.vidfilter))
+        else:
+            params = self.pconcat + " -y -filter_complex concat=n=%d:v=1:a=%d" % (self.nconcat, a)
+        self.lastfilename = filename
+        params += self.qfilter
+        start(filename, params)
+        wait()
+
+    def filename(self, filename):
+        self.lastfilename = filename
+
+    def framerate(self, framerate):
+        self.framerate = framerate
+
+    def tmppath(self, path):
+        self.tmppath = path
+
+    def process(self, filename, param):
+        print("process %s -> %s" % (self.lastfilename, filename))
+        params = " -y -i %s %s " % (self.lastfilename, param)
+        self.lastfilename = filename
+        params += self.qfilter
+        start(filename, params)
+        wait()
+        
+
+