Skip to content

Instantly share code, notes, and snippets.

@bmatherly
Last active August 29, 2015 13:56
Show Gist options
  • Save bmatherly/9085903 to your computer and use it in GitHub Desktop.
Save bmatherly/9085903 to your computer and use it in GitHub Desktop.
Normalize media files.
#!/bin/bash
declare SRC=""
declare DST=""
declare -i USE_TIME=0
declare -r WIDTH=1280
declare -r HEIGHT=720
declare -r RATE="60000/1001"
declare -r EXT=".mov"
function print_help()
{
cat <<EOM
-------------------------------------------------------------------------------
Usage: $(basename $0) [-t] input output
-h Print [h]elp and exit.
-t Rename output files with modification [t]ime
Input and output may be specified as either a file or directory.
* If input is a file, it will be normalized to the output file.
* If input is a directory, all files inside the directory will be
normalized and stored in the output directory.
In all cases, an appropriate file extension is added.
-------------------------------------------------------------------------------
EOM
}
function parse_args()
{
while getopts "hi:o:t" opt
do
case $opt in
h) print_help; exit 0;;
i) echo $opt; SRC=$OPTARG;;
o) echo $opt; DST=$OPTARG;;
t) USE_TIME=1;;
*) echo "unknown arg: $opt"; print_help; exit 1;;
esac
done
shift $(($OPTIND - 1))
SRC=$1
DST=$2
}
function get_destination_filename()
{
local srcname=$1
local dstname=""
if [ $USE_TIME -eq 1 ]; then
dstname=`date -r "$srcname" "+%Y-%m-%d-%H%M%S"`
else
# Clean the name of spaces and strage characters
dstname=`echo $srcname | tr ' ' '_' | tr -d '[{}(),\!]' | tr -d "\'" | tr '[A-Z]' '[a-z]' | sed 's/_-_/_/g'`
# Strip the extension
dstname=${dstname%.*}
dstname=${dstname##*/}
fi
echo $dstname$EXT
}
function normalize_file()
{
local src_file="$1"
local dst_file="$2"
local vf=""
local filters=""
# Get information about the video
vidinfo=`ffmpeg -i "$src_file" -vframes 1 -vf "showinfo" -an -f rawvideo -y /dev/null 2>&1 | grep --max-count=1 showinfo`
structure=`echo "$vidinfo" | sed "s/.* i:\([A-Z]*\).*/\1/" | tr -d "[:space:]"`
iw=`echo "$vidinfo" | sed "s/.* s:\([1-9][0-9]*\)x\([0-9]*\).*/\1/" | tr -d "[:space:]"`
ih=`echo "$vidinfo" | sed "s/.* s:\([1-9][0-9]*\)x\([0-9]*\).*/\2/" | tr -d "[:space:]"`
# Deinterlace if necessary
if [ "$structure" != "P" ]; then
echo "Source is Interlaced"
if [ "$filters" != "" ]; then
filters=$filters","
fi
# Duplicate frames
filters=$filters"yadif=1:-1:0"
else
echo "Source is Progressive"
fi
# Scale if necessary
if [ "$iw" != $WIDTH -o "$ih" != $HEIGHT ]; then
echo "Scale $iw x $ih -> $WIDTH x $HEIGHT"
if [ "$filters" != "" ]; then
filters=$filters","
fi
filters=$filters"scale=(iw*sar)*min($WIDTH/(iw*sar)\,$HEIGHT/ih):ih*min($WIDTH/(iw*sar)\,$HEIGHT/ih)"
filters=$filters","
# Add bars if AR does not match. Has no effect when they do match.
filters=$filters"pad=$WIDTH:$HEIGHT:($WIDTH-iw*min($WIDTH/iw\,$HEIGHT/ih))/2:($HEIGHT-ih*min($WIDTH/iw\,$HEIGHT/ih))/2"
fi
if [ "$filters" ]; then
filters='-vf "'"$filters"'"'
fi
cmd="ionice -c3 nice -19 ffmpeg -i \"$src_file\" -sn $filters -r $RATE -vcodec dnxhd -vb 220000k -pix_fmt yuv422p -threads 3 -acodec pcm_s16le -ac 2 -ar 48000 \"$dst_file\""
echo "About to run command:"
echo "$cmd"
eval "$cmd"
# Make sure the normalize succeeded.
if [ -f "$dst_file" ]; then
touch -r "$src_file" "$dst_file"
else
echo "Normalize Failed"
exit 7
fi
}
parse_args "$@"
# Sanity checking, to make sure everything is in order.
if [ -z "$SRC" -o -z "$DST" ]; then
print_help
exit 1
elif [ -f "$SRC" ]; then
# Normalize a single file
srcfile=$SRC
dstfile=$(get_destination_filename "$srcfile")
echo "Normalize $srcfile to $dstfile"
normalize_file "$srcfile" "$dstfile"
elif [ -d "$SRC" ]; then
# Normalize all files in a directory
if [ ! -d "$DST" ]; then
echo "Destination directory does not exist: $DST"
exit 2
fi
shopt -s nullglob
for srcfile in $SRC/*
do
dstfile=$DST/$(get_destination_filename "$srcfile")
echo "Normalize $srcfile to $dstfile"
normalize_file "$srcfile" "$dstfile"
done
else
echo "$SRC is not a file or directory"
print_help
exit 2
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment