#!/bin/sh ## ## SCRIPT NAME: ffmpeg_monitorAndAudio_MovieCapture.sh ## ##+####### ## PURPOSE: ## This script fruns the 'ffmpeg' command after being provided with ## about 15 'ffmpeg' parameters passed to this script. ## ## This shell script is meant to be issued from the Tk GUI 'wrapper' script ## --- 'monitorAndAudio_MovieCapture_ffmpeg_FrontEnd.tk'. ## That Tk script is to get parameters for the 'ffmpeg' command --- for the ## purpose of recording the monitor screen and audio from a computer ## into a movie file. ## ## The 'ffmpeg' parameters are passed into this script via *positional* ## parameters in the order indicated below. ## ## Having the 'ffmpeg' call in a shell script instead of embedded in the ## Tk script facilitates testing and debugging. For example, this ## script can be tested independently of the Tk script. ('ffmpeg' ## is very sensitive to the order of the input parameters, as well ## as sensitive to the container-video-audio formats selected --- ## as evidenced by the many appeals for help on internet forums.) ## ##+###### ## INPUTS: ## ## Here are example default parameters for 'ffmpeg' from the Tk script, ## preceded by the variable names used in the Tk script: ## ## Var01: VIDEOsize "800x600" ## Var02: VIDEOoffset "+10,30" ## Var03: VIDEOsource ":0.0" ## Var04: VIDEOformat "x11grab" ## Var05: VIDEOrate "25" ## Var06: VIDEOcodec "libx264" ## Var07: VIDEOotherParms "-vpre /usr/share/ffmpeg/libx264-lossless_ultrafast.ffpreset" ## Var08: AUDIOformat "alsa" ## Var09: AUDIOinterface "pulse" ## Var10: AUDIOchannels "1" ## Var11: AUDIOcodec "pcm_s16le" ## Var12: AUDIOotherParms "-ar 22050 -ab 96k" ## Var13: Nthreads "1" ## Var14: CONTAINERformat "matroska" ## Var15: ENTRYfilename "$outDIR/$env(USER)_screen_capture_movie.mkv" ## ## In this script, we will put those parameters in shell script variables ## using the same variable names as above --- except that we will ## use 'OUTfile' instead of 'ENTRYfilename' and 'CONTAINfmt' instead of ## 'CONTAINERformat'. ## ##+######################################################################### ## REFERENCE: http://ubuntuforums.org/archive/index.php/t-1392026.html ## "HOWTO: Proper Screencasting on Linux" (as seen in 2011) ## ## "...we capture audio from pulse (pulseaudio sound server) and encode it ## to *'lossless'* raw PCM with 2 audio channels (stereo). Then, we grab a ## video stream from x11 at a frame rate of 30 and a size of 1024×768 ## from the display :0.0 and encode it to *'lossless'* h264 using libx264. ## ... The resulting streams will be muxed in a Matroska container (.mkv)." ##+######################################################################### ## MAINTENANCE HISTORY: ## Started by: Blaise Montandon 2014may29 ## Updated by: Blaise Montandon 2014may30 Added the 'CONTAINfmt' variable. ## Re-ordered the 'ffmpeg' parms to ## avoid the MISLEADING error message: ## Unknown decoder 'libx264' ##+######################################################################### ## FOR TESTING: (to show statements as they execute) # set -x VIDEOsize="$1" VIDEOoffset="$2" VIDEOsource="$3" VIDEOformat="$4" VIDEOrate="$5" VIDEOcodec="$6" VIDEOotherParms="$7" AUDIOformat="$8" AUDIOinterface="$9" AUDIOchannels="$10" AUDIOcodec="$11" AUDIOotherParms="$12" Nthreads="$13" CONTAINfmt="$14" OUTfile="$15" ## FOR TESTING of this script without the Tk wrapper: ## (For stand-alone testing, change 'if test 1 = 0' to 'if test 1 = 1'.) if test 1 = 0 then VIDEOsize="800x600" # VIDEOsize="1024x768" VIDEOoffset="+10,30" # VIDEOoffset="+0,0" VIDEOsource=":0.0" VIDEOformat="x11grab" VIDEOrate="25" # VIDEOrate="30" VIDEOcodec="libx264" # VIDEOcodec="xvid" # VIDEOcodec="libvpx" # VIDEOcodec="mpeg1video" # VIDEOcodec="flv" VIDEOotherParms="-vpre /usr/share/ffmpeg/libx264-lossless_ultrafast.ffpreset" # VIDEOotherParms="" AUDIOformat="alsa" # AUDIOformat="oss" AUDIOinterface="pulse" # AUDIOinterface="hw:0,0" # AUDIOinterface="/dev/dsp" AUDIOchannels="1" # AUDIOchannels="2" AUDIOcodec="pcm_s16le" # AUDIOcodec="libmp3lame" # AUDIOcodec="libfaac" # AUDIOcodec "vorbis" AUDIOotherParms="-ar 22050 -ab 96k" # AUDIOotherParms="-ar 44100 -ab 128k" Nthreads="1" # Nthreads="2" # Nthreads="0" ## auto-detect, max CPUs (not advisable?) CONTAINfmt="matroska" # CONTAINfmt="mpeg4" # CONTAINfmt="mpeg" # CONTAINfmt="flv" # CONTAINfmt="avi" # CONTAINfmt="webm" OUTfile="/tmp/${USER}_screen_capture_movie.mkv" fi ## FOR TESTING: # echo "OUTfile: $OUTfile" ## Simply exit if there is no output filename passed to this script. if test "$OUTfile" = "" then exit fi ##+########################################################## ## Prepare to use the filename to hold the movie. ## Make sure we start with a new (empty) output file. ##+########################################################## rm -f "$OUTfile" ##+####################################################### ## Call on the 'ffmpeg' command, which puts the movie ## in file "$OUTfile". ## ## We run ffmpeg in an 'xterm' so that we can see its messages ## and the user can stop the recording by opening the xterm ## window and typing 'q' in the window. ## ## We could move the 'xterm' call into the calling Tk script. ## ## We do not use '&' to run this process in the background, ## but the Tk script that calls this script issues the call ## as a background process, rather than foreground. ##+####################################################### ## FOR TESTING: (to show statements as they execute) # set -x xterm -bg black -fg white -hold -geometry 90x48+100+100 -e ffmpeg \ -f $VIDEOformat -r $VIDEOrate -s $VIDEOsize -i ${VIDEOsource}$VIDEOoffset \ -f $AUDIOformat -ac $AUDIOchannels -i $AUDIOinterface \ -vcodec $VIDEOcodec $VIDEOotherParms \ -acodec $AUDIOcodec $AUDIOotherParms \ -threads $Nthreads "$OUTfile" ## The following order of parameters (all video, then all audio) gave ## the puzzling error message: Unknown decoder 'libx264' ## ## (Puzzling because I knew that the 'libx264' coder was available, ## because another order of the parameters in a different script worked. ## This is proof that 'ffmpeg' can give VERY MISLEADING error messages.) ## ## ffmpeg -f $VIDEOformat -r $VIDEOrate -s $VIDEOsize \ ## -i ${VIDEOsource}$VIDEOoffset -vcodec $VIDEOcodec $VIDEOotherParms \ ## -f $AUDIOformat -i $AUDIOinterface -ac $AUDIOchannels -acodec $AUDIOcodec \ ## -threads $Nthreads "$OUTfile" ## ## It appears that 'ffmpeg' parameters should be grouped such that ## ALL the 'input' parameters (video AND audio) are to be specified BEFORE ## the 'output' (in particular, codec) parameters.