Shell script to trim a video clip with avconv, ffmpeg or mencoder

2 Jan 2015 avconv, Bash, ffmpeg, Linux, mencoder, videography Trackback

This script is an updated version of the Shell script to trim a video with mencoder or ffmpeg.

Main difference are:

Adds support for and defaults to avconv (but still supports ffmpeg and mencoder ).

(but still supports and ). Uses simpler code to calculate clip duration from start/stop times.

Accepts period ( . ) in addition to colon ( : ) as the HH:MM:SS separator in start/stop times. Dots are much quicker to type, which is nice when creating lots of clips.

Here's the script:

#!/bin/bash Usage() { cat << EOF Usage examples: $(basename $0) video.avi 00:30:00 00:40:00 $(basename $0) video.avi 00.30.00 00.40.00 Optionally, can also provide '-a', '-f' or '-m' as the 4th arg to force avconv, ffmpeg or mencoder. EOF } if [ "$#" -lt "3" ]; then Usage exit 1 else InFile=$1 StartTime=$2 StopTime=$3 fi CheckInput() { if ! [ -r $InFile ]; then echo "ERROR: input file \"$InFile\" not readable" exit 1 fi for time in StartTime StopTime; do if [ "$(echo ${!time} | grep -Eo "(:|\.)" | wc -l)" -ne "2" ]; then echo "ERROR: check $time time format, expecting cols or dots e.g.:" echo "00:20:00 or 00.20.00" exit 1 fi if [ "$(echo ${!time} | sed -r 's/(:|\.)//g' | wc -c)" -ne "7" ]; then echo "ERROR: check $time time format, expecting six numeric digits, e.g.:" echo "00:20:00 or 00.20.00" exit 1 fi done start=$(echo "$StartTime" | sed -r 's/(:|\.)//g') stopt=$(echo "$StopTime" | sed -r 's/(:|\.)//g') if [ "$start" -ge "$stopt" ]; then echo "ERROR: stop time must be later than start time. I got:" echo " start = $StartTime" echo " stop = $StopTime" exit 1 fi } CalcDuration() { # NOTE: won't work with clips longer than 24 hours. Never had # one of those, so not an issue, but if this changes, switch # to date handling as in the calc-duration script. time1="$(echo $StartTime | sed 's/\./:/g')" time2="$(echo $StopTime | sed 's/\./:/g')" date1="$(date +%F)" date2="$(date +%F)" time1sec=$(date --date="$date1 $time1" +%s) time2sec=$(date --date="$date2 $time2" +%s) secdiff=$(( $time2sec-$time1sec )) h=$(( secdiff / 3600 )) m=$(( ( secdiff / 60 ) % 60 )) s=$(( secdiff % 60 )) Duration=$(printf "%02d:%02d:%02d

" $h $m $s) } ConstructFileName() { ext=$(echo "$InFile" | egrep -io "\.[a-z0-9]{2,4}$") main=$(echo "$InFile" | sed "s/$ext$//") OutFile=$main.trim.$start-$stopt$ext } aTrim() { avconv=$(which avconv) if [ -x "$avconv" ]; then echo "INFO: using avconv.." avconv -i $InFile -ss $time1 -t $Duration -codec copy -threads auto $OutFile echo "==================================================" echo "command used was:" echo "avconv -i $InFile -ss $time1 -t $Duration -codec copy -threads auto $OutFile" exit 0 else echo "ERROR: avconv not available.." fi } fTrim() { ffmpeg=$(which ffmpeg) if [ -x "$ffmpeg" ]; then echo "INFO: using ffmpeg.." ffmpeg -i $InFile -ss $time1 -t $Duration -vcodec copy -acodec copy $OutFile echo "==================================================" echo "command used was:" echo "ffmpeg -i $InFile -ss $time1 -t $Duration -vcodec copy -acodec copy $OutFile" exit 0 else echo "ERROR: ffmpeg not available.." fi } mTrim() { mencoder=$(which mencoder) if [ -x "$mencoder" ]; then echo "INFO: using mencoder.." mencoder -ss $time1 -endpos $Duration -oac mp3lame -ovc copy $InFile -o $OutFile echo "==================================================" echo "command used was:" echo "mencoder -ss $time1 -endpos $Duration -oac mp3lame -ovc copy $InFile -o $OutFile" exit 0 else echo "ERROR: mencoder not available.." fi } echo -e "

checking input.." CheckInput echo "all good" echo -e "

calculating duration from start/stop times.." CalcDuration echo "clip duration is $Duration" echo -e "

constructing file name for output.." ConstructFileName echo "trimmed video will be saved as $OutFile" echo -e "

trimming video.." echo "==================================================" if [ "$4" == "-a" ]; then aTrim elif [ "$4" == "-f" ]; then fTrim elif [ "$4" == "-m" ]; then mTrim else aTrim fTrim mTrim fi