#!/bin/sh ## ## SCRIPT: movieFilePROPERTIES_ffmpeg-i.sh ## ##+####### ## PURPOSE: ## This script runs the 'ffmpeg -i' command on a filename which is provided ## to this script as its only argument. ## ## This script is meant to return several lines selected from the output ## of 'ffmpeg -i'. The lines are to be sent to standard out. ## ## Those selected lines are to provide the 'properties' of a movie file. ## Example lines to be extracted: ## ## Input #0, mpeg, from 'ParkingTechnique2_320x240_12sec_MPEG1-MP2.mpeg': ## Duration: N/A, start: 0.602367, bitrate: N/A ## Stream #0.0[0x1e0]: Video: mpeg1video, yuv420p, 320x240 [PAR 178:163 DAR 712:489], 500 kb/s, 29.97 tbr, 90k tbn, 29.97 tbc ## Stream #0.1[0x1c0]: Audio: mp2, 44100 Hz, mono, s16, 96 kb/s ## ##+######### ## CALLED BY: ## This shell script is meant to be called from the Tk GUI 'wrapper' ## script --- 'movieClipCropEtc_ffmpeg_FrontEnd.tk' --- when the ## user requests the PROPERTIES of an input or output movie file. ## ##+###### ## METHOD: ## It would be nice to simply call 'ffmpeg -i' via a Tcl 'exec' command ## in the Tk script. However, the 'ffmpeg -i' command throws an error ## when output is not directed to a recognized media file type --- ## and all text output goes to 'stderr' not 'stdout'. ## ## Sample output follows: ## ## $ ffmpeg -i ParkingTechnique2_320x240_12sec_MPEG1-MP2.mpeg ## FFmpeg version SVN-r19352-4:0.5+svn20090706-2ubuntu2.3, Copyright (c) 2000-2009 Fabrice Bellard, et al. ## configuration: --extra-version=4:0.5+svn20090706-2ubuntu2.3 --prefix=/usr --enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --disable-stripping --disable-vhook --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --extra-cflags=-I/build/buildd/ffmpeg-0.5+svn20090706/debian/include --enable-shared --disable-static ## libavutil 49.15. 0 / 49.15. 0 ## libavcodec 52.20. 0 / 52.20. 0 ## libavformat 52.31. 0 / 52.31. 0 ## libavdevice 52. 1. 0 / 52. 1. 0 ## libavfilter 0. 4. 0 / 0. 4. 0 ## libswscale 0. 7. 1 / 0. 7. 1 ## libpostproc 51. 2. 0 / 51. 2. 0 ## built on Mar 31 2011 18:50:18, gcc: 4.4.1 ## Input #0, mpeg, from 'ParkingTechnique2_320x240_12sec_MPEG1-MP2.mpeg': ## Duration: N/A, start: 0.602367, bitrate: N/A ## Stream #0.0[0x1e0]: Video: mpeg1video, yuv420p, 320x240 [PAR 178:163 DAR 712:489], 500 kb/s, 29.97 tbr, 90k tbn, 29.97 tbc ## Stream #0.1[0x1c0]: Audio: mp2, 44100 Hz, mono, s16, 96 kb/s ## At least one output file must be specified ## ## NOTE: The information we want is between the 'built on' line and the ## ending error message line: 'At least one output file must be specified'. ## ## There does not appear to be a way to direct these information messages and ## the ending error message to 'stdout' (even with '2>&1') in such a way that ## the Tk script does not detect an error. When Tk detects the error return code, ## there does not seem to be a way to pass 'stdout' to the Tk script. ## ## So we call on this 'external' shell script from the Tk script, ## to do the dirty work of extracting the desired lines from ## the stderr output and pass the lines back to the Tk script ## without throwing an error that would prevent the Tk script ## from accepting the lines sent to stdout. ## ## We use '2>&1' to pipe the output of 'ffmpeg -i' to a small ## 'awk' program that extracts the desired lines --- between ## the 'built on' line and the 'At least one ...' line. ## ## Since we let the output of 'awk' go to 'stdout', that becomes ## the output from this script that will be captured in the Tk script. ## ## NOTE: Piping the output of 'ffmpeg -i 2>&1' to ## egrep 'Input|Duration|Stream' ## might work, but it may miss some output for some kinds of media/movie files. ## ##+######### ## REFERENCE: ## http://www.commandlinefu.com/commands/view/2207/get-video-information-with-ffmpeg ## 2009-05-18 ## TOPIC: Get video information with ffmpeg ## ## $ ffmpeg -i filename.flv ## ## I used an flv in my example, but it'll work on any file ffmpeg supports. ## ## It says it wants an output file [the 'At least one output' error message], ## but it tells what you want to know without one [without specifying an ## output file]. ## ## Also see: ## http://stackoverflow.com/questions/11400248/using-ffmpeg-to-get-video-info-why-do-i-need-to-specify-an-output-file ## http://www.techanswerguy.com/2012/03/redirecting-ffmpeg-output-performing.html ## https://groups.google.com/forum/#!msg/nodejs/7KakLQR50_w/yEVW1-kA-boJ ## http://www.computerhope.com/forum/index.php?topic=110250.0 ########################################################################## ## Started: 2014jun17 Based on a similar PROPERTIES script from the ## feNautilusScripts system at www.freedomenv.com. ## But that script uses temporary files and the ## 'grep' and 'tail' commands instead of 'awk'. ## Changed: 2014 ########################################################################### ## FOR TESTING: (show statements as they execute) # set -x ######################################### ## Get the filename passed to this script. ######################################### FILENAME="$1" ## FOR TESTING: # FILENAME="$HOME/TESTfilesMOVIES/mpeg/ParkingTechnique2_320x240_12sec_MPEG1-MP2.mpeg" ######################################### ## Pass a heading to stdout. ######################################### echo "\ 'ffmpeg -i' output: ################## " ######################################################################## ## Pass the output of 'ffmpeg -i "$FILENAME"' to a small awk' program ## that extracts the properties of the movie file. ######################################################################## ## CAUTION: Single-quotes in comment lines of an awk script cause syntax ## errors --- like braces in comment lines cause errors in ## Tcl-Tk scripts. ## Use double-quotes instead. ######################################################################## ffmpeg -i "$FILENAME" 2>&1 | awk ' BEGIN { KEEP=0; ## KEEP is a flag. It will be set to 1 when we encounter the "built on" rec. } { ################################################ ## Hold the first 12 characters of this record, ## whose contents are in $0. ################################################ FIELD1=substr($0,1,12) ######################################################################### ## If KEEP=0 and this rec does not contain the string "built on", skip ## this rec (read the next one). We want to read to the "built on" rec. ######################################################################### if ( FIELD1 !~ "built on" && KEEP==0) next ######################################################################### ## If this rec contains the string "built on", set KEEP=1 and ## read the next rec. ######################################################################### if ( FIELD1 ~ "built on" && KEEP==0) { KEEP=1 next } ######################################################################### ## If this rec contains the string "At least one" (as in ## "At least one output file must be specified"), exit. ######################################################################### if ( FIELD1 ~ "At least one") {exit} ######################################################################### ## If we get here, this is a record we want. Print it. ######################################################################### print $0 }' ## END OF the awk script.