#!/bin/sh ## ## SCRIPT NAME: ffmpeg_webcamAndAudio_MovieCapture.sh ## ##+####### ## PURPOSE: ## This script runs the 'ffmpeg' command after being provided with ## about 14 'ffmpeg' parameters passed to this script. ## ## This shell script is meant to be issued from the Tk GUI 'wrapper' ## script --- 'webcamAndAudio_MovieCapture_ffmpeg_FrontEnd.tk'. ## That Tk script is to get parameters for the 'ffmpeg' command --- ## for the purpose of recording the webcam 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: VIDEOsource "/dev/video0" ## Var03: VIDEOformat "video4linux2" ## Var04: VIDEOrate "25" ## Var05: VIDEOcodec "libx264" ## Var06: VIDEOotherParms "-vpre /usr/share/ffmpeg/libx264-lossless_ultrafast.ffpreset" ## Var07: AUDIOformat "alsa" ## Var08: AUDIOinterface "pulse" ## Var09: AUDIOchannels "1" ## Var10: AUDIOcodec "pcm_s16le" ## Var11: AUDIOotherParms "-ar 22050 -ab 96k" ## Var12: Nthreads "1" ## Var13: CONTAINERformat "matroska" ## Var14: ENTRYfilename "$outDIR/$env(USER)_webcam_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 2014jun02 Started based on the shell script ## 'ffmpeg_monitorAndAudio_MovieCapture.sh'. ## Updated by: Blaise Montandon 2014 ##+######################################################################### ## FOR TESTING: (to show statements as they execute) # set -x VIDEOsize="$1" VIDEOsource="$2" VIDEOformat="$3" VIDEOrate="$4" VIDEOcodec="$5" VIDEOotherParms="$6" AUDIOformat="$7" AUDIOinterface="$8" AUDIOchannels="$9" AUDIOcodec="$10" AUDIOotherParms="$11" Nthreads="$12" CONTAINfmt="$13" OUTfile="$14" ## 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" # VIDEOsource="/dev/video1" VIDEOsource="/dev/video0" VIDEOformat="video4linux2" # VIDEOformat="video4linux" VIDEOrate="25" # VIDEOrate="30" VIDEOcodec="libx264" # VIDEOcodec="mpeg4" # VIDEOcodec="mpeg2video" # VIDEOcodec="mpeg1video" # VIDEOcodec="flv" # VIDEOcodec="libvpx" # VIDEOcodec="xvid" VIDEOotherParms="-vpre /usr/share/ffmpeg/libx264-lossless_ultrafast.ffpreset" # VIDEOotherParms="" AUDIOformat="alsa" # AUDIOformat="oss" AUDIOinterface="pulse" # AUDIOinterface="hw:2,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}_webcam_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. ##+############################################################### ## If you have another webcam applicaton running, such as 'Cheese', ## you may get the following error: ## [video4linux2 @ 0x892f700]Cannot find a proper format. ## It apparently 'ties up' the specified device --- in this case, ## /dev/video0. ################################################################## ## If you specify the wrong input device, you may get the following ## error: ## [video4linux2 @ 0x9fd4700]Cannot open video device /dev/video1 : ## No such file or directory ## /dev/video1: I/O error occurred ################################################################## ## 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 \ -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 -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.