#!/bin/bash
# input arguments
OUTPUT_VIDEO_ENCODER=$1 # only x264 is available at the moment
VIDEO_RESOLUTION=$2 # entering the width is sufficient
VIDEO_BITRATE=$3 # pick a smaller bitrate
OUTPUT_AUDIO_ENCODER=$4 # only vorbis is available at the moment
AUDIO_QUALITY=$5 # For vorbis a value of 20 here corresponds with ~90 kbps (which should be sufficient)
OUTPUT_CONTAINER=$6 # only matroska available at the moment
WORK=work_tmp
CURRENT=$(pwd)
TEMP="${CURRENT}/${WORK}"
[[ ! -d ${TEMP} ]] && mkdir "${TEMP}"
# collects output encoding settings from a configuration file
# for now just use some pre-written settings.
# mencoder filter settings and x264 settings
ENCODEX264_1="-ovc x264 -x264encopts threads=auto:bitrate=${VIDEO_BITRATE}:subq=4:bframes=3:b_pyramid:weight_b:turbo=1:pass=1"
ENCODEX264_2="-ovc x264 -x264encopts threads=auto:bitrate=${VIDEO_BITRATE}:subq=6:frameref=6:partitions=all:8x8dct:me=umh:bframes=3:b_pyramid:weight_b:pass=2"
FILTER_1="-vf scale=${VIDEO_RESOLUTION}:-2,pullup,pp=md,softskip,harddup"
FILTER_2="${FILTER_1}"
# ffmpeg vorbis setting
ENCODE_VORBIS="-acodec vorbis -ar 44100 -aq ${AUDIO_QUALITY} -ac 2"
# Demuxing the file
ls -1 *{mkv,avi,mp4,ogm,vob} 2>/dev/null | while read INPUT
do
# declare variables
VIDS=0; AUDS=0; SUBS=0; EXTRACTION=""; TRACKS=0; TITLE=""; MUX="";
declare -a TRACKTYPE VIDEOFPS FRAMERATE_MENCODER VIDEOAR AUDIOTYPE AUDIOLANG SUBTYPE SUBLANG
# Collecting Info
mplayer ${INPUT} -endpos 0 -ao null -vo null 2>/dev/null 1>log </dev/null
EXT_TMP=$(cat log | grep "format detected" | cut -f 1 -d " ")
case ${EXT_TMP} in
Matroska)
EXT="mkv";;
AVI)
EXT="avi";;
libavformat)
EXT=$(echo ${INPUT##*.});;
esac
# Demuxing
case ${EXT} in
mkv)
TITLE=${INPUT/.mkv/}
echo ${TITLE}
TRACKS=$(grep "Track ID [0-9]*" log | wc -l)
for ID in $(seq 1 ${TRACKS})
do
i=$((ID-1))
TRACK=$(grep "Track ID ${ID}" log)
TRACKTYPE[$i]=$(echo ${TRACK} | egrep -o "(video|audio|subtitles)")
case ${TRACKTYPE[$i]} in
video)
VIDEOTYPE[$VIDS]=$(echo ${TRACK} | egrep -o "video \([A-Z1-9_/]*" | sed -e 's/^.*(//g') ## storing video encoder information
## for multiple video tracks we'll have play each to find out the frame rates
VID=$(echo ${TRACK} | egrep -o "vid [0-9]*" | sed -e 's/vid //g')
mplayer ${INPUT} -endpos 0 -ao null -vo null -vid ${VID} 2>/dev/null 1>log1 </dev/null
VIDEOFPS[$VIDS]=$(cat log1 | egrep -o " [0-9.]* fps" | grep -o "[0-9.]*") # grabbing the frame rate # this may not be robust
case ${VIDEOFPS[$VIDS]} in
23.976*)
FRAMERATE_MENCODER[$VIDS]="24000/1001"
VIDEOFPS[$VIDS]="23.976024";;
29.97*)
FRAMERATE_MENCODER[$VIDS]="30000/1001"
VIDEOFPS[$VIDS]="29.970030";;
25*)
FRAMERATE_MENCODER[$VIDS]="25";;
esac
VIDEOAR[$VIDS]=$(cat log1 | egrep -o "Aspect is 1[0-9.]*" | egrep -o "1[0-9.]*")
echo "The video is encoded with ${VIDEOTYPE[$VIDS]}"
echo "The video has a framerate of ${VIDEOFPS[$VIDS]}"
echo "The video has an aspect ratio of ${VIDEOAR[$VIDS]}"
VIDS=$((VIDS+1))
VIDEOTRACK="${TEMP}/${TITLE}_${VIDS}.video"
EXTRACTION="${EXTRACTION} ${ID}:${VIDEOTRACK}"
;;
audio)
AUDIOTYPE[$AUDS]=$(echo ${TRACK} | egrep -o "audio \([A-Z1-9_/]*" | sed -e 's/^.*(//g')
AUDIOLANG[$AUDS]=$(echo ${TRACK} | egrep -o "alang [a-z]*" | sed -e 's/alang //g') ## storing audio encoder information
echo "The audio is encoded with ${AUDIOTYPE[$AUDS]}"
echo "The audio language is ${AUDIOLANG[$AUDS]}"
AUDS=$((AUDS+1))
AUDIOTRACK="${TEMP}/${TITLE}_${AUDS}.audio"
EXTRACTION="${EXTRACTION} ${ID}:${AUDIOTRACK}"
;;
subtitles)
SUBTYPE[$SUBS]=$(echo ${TRACK} | egrep -o "subtitles \([A-Z1-9_/]*" | sed -e 's/^.*(//g')
SUBLANG[$SUBS]=$(echo ${TRACK} | egrep -o "slang [a-z]*" | sed -e 's/slang //g') ## storing subtitle information
echo "The subtitle is ${SUBTYPE[$SUBS]}"
echo "The subtitle language is ${SUBLANG[$SUBS]}"
SUBS=$((SUBS+1))
SUBTRACK="${TEMP}/${TITLE}_${SUBS}.subtitles"
EXTRACTION="${EXTRACTION} ${ID}:${SUBTRACK}"
;;
esac
done
mkvextract tracks ${INPUT} ${EXTRACTION} </dev/null
;;
avi)
echo "Under Construction" ;;
mp4)
echo "Under Construction" ;;
ogm)
echo "Under Construction" ;;
vob)
echo "Under Construction" ;;
esac
## Transcoding the video tracks
for VIDEOID in $(seq 1 ${VIDS})
do
i=$((VIDEOID-1))
VIDEOTRACK="${TEMP}/${TITLE}_${VIDEOID}.video"
if [ -f "${VIDEOTRACK}" ]; then
case ${OUTPUT_VIDEO_ENCODER} in
x264)
TMP1=$(echo ${VIDEOTRACK/.video/.264})
TMP2=$(echo ${VIDEOTRACK/.video/.mp4})
echo "The VIDEO output is ${TMP2}"
[[ ! -f "${TMP2}" ]] && \
mencoder ${VIDEOTRACK} ${FILTER_1} -nosound ${ENCODEX264_1} -ofps ${FRAMERATE_MENCODER[$i]} -of rawvideo -o ${TMP1} </dev/null && \
mencoder ${VIDEOTRACK} ${FILTER_2} -nosound ${ENCODEX264_2} -ofps ${FRAMERATE_MENCODER[$i]} -of rawvideo -o ${TMP1} </dev/null && \
MP4Box -fps ${VIDEOFPS[$i]} -add ${TMP1} ${TMP2} </dev/null
cp "${TMP2}" "${VIDEOTRACK}"
rm "${TMP1}" "${TMP2}" 2>/dev/null
;;
xvid)
echo "Under Construction"
;;
esac
fi
done
## Transcoding the audio tracks
for AUDIOID in $(seq 1 ${AUDS})
do
i=$((AUDIOID-1))
AUDIOTRACK="${TEMP}/${TITLE}_${AUDIOID}.audio"
if [ -f "${AUDIOTRACK}" ]; then
case ${OUTPUT_AUDIO_ENCODER} in
vorbis)
TMP1=$(echo ${AUDIOTRACK/.audio/.ogg})
[[ ! -f "${TMP1}" ]] && \
ffmpeg -i ${AUDIOTRACK} ${ENCODE_VORBIS} ${TMP1} </dev/null
cp "${TMP1}" "${AUDIOTRACK}" 2>/dev/null
rm "${TMP1}"
;;
mp3)
echo "Under Construction"
esac
fi
done
# Muxing Everything Back together
VIDS=0; AUDS=0; SUBS=0;
OUTPUT="${TITLE}_new.${EXT}"
case ${OUTPUT_CONTAINER} in
matroska)
for TRACKID in $(seq 1 ${TRACKS})
do
i=$((TRACKID-1))
case ${TRACKTYPE[$i]} in
video)
j=$(echo ${VIDS})
VIDS=$((VIDS+1))
VIDEOTRACK="${TEMP}/${TITLE}_${VIDS}.video"
if [ -f "${VIDEOTRACK}" ]; then
if [ ${j} -eq 0 ]; then
MUX="${MUX} --default-track -1"
fi
MUX="${MUX} --default-duration -1:${VIDEOFPS[$j]}fps --aspect-ratio -1:${VIDEOAR[$j]} ${VIDEOTRACK}"
fi
;;
audio)
j=$(echo ${AUDS})
AUDS=$((AUDS+1))
AUDIOTRACK="${TEMP}/${TITLE}_${AUDS}.audio"
if [ -f "${AUDIOTRACK}" ]; then
if [ ${j} -eq 0 ]; then
MUX="${MUX} --default-track 0"
fi
MUX="${MUX} --language 0:${AUDIOLANG[$j]} ${AUDIOTRACK}"
fi
;;
subtitles)
j=$(echo ${SUBS})
SUBS=$((SUBS+1))
SUBTRACK="${TEMP}/${TITLE}_${SUBS}.subtitles"
if [ -f "${SUBTRACK}" ]; then
if [ ${j} -eq 0 ]; then
MUX="${MUX} --default-track 0"
fi
MUX="${MUX} --language 0:${SUBLANG[$j]} ${SUBTRACK}"
fi
;;
esac
done
echo ${MUX}
mkvmerge -o ${OUTPUT} ${MUX} </dev/null
;;
avi)
echo "Under Construction"
esac
## Clean up
rm "${TEMP}"/* -fr
rm divx2*
rm log log1
done