Jul 18, 2013

Shell script: Converting DTS/AC3 audio to AAC

I have been using HandBrake to transcode movie files for reasons. One of the reasons was the audio codecs. iDevices and Raspberry Pi cannot perform hardware accelerated DTS/AC3 audio decoding due to license issues.

With HandBrake, I couldn't find a way to convert only audio but not video. What I wanted was not touching the video for quality reason and convert only the audio to AAC or MP3.

I found several people posted how to do that for MKV container format. From those scripts I made my own script that converts audio tracks. I don't know how to manipulate AVI or other container formats yet but most of cases MKV seems to be enough.

This script is faster than transcoding both video and audio because this converts only audio not video. And since it doesn't touch the video, the video quality wouldn't be affected as well.

I believe as long as you use Raspberry Pi, you wouldn't need to transcode video. But if you are using iDevices, you may need to transcode audio and video both.

You will need to install two packages.
sudo apt-get install mkvtoolnix ffmpeg
Now here is the script:
#!/bin/sh
mkv_input=$1
if [ ! -f "$mkv_input" ]; then
        echo "*** File not found: $mkv_input ***"
fi

DIRNAME=/usr/bin/dirname
BASENAME=/usr/bin/basename
WC=/usr/bin/wc
DATE=/bin/date
GREP=/bin/grep
HEAD=/usr/bin/head
TAIL=/usr/bin/tail
CUT=/usr/bin/cut
AVCONV=/usr/bin/avconv
MKVINFO=/usr/bin/mkvinfo
MKVEXTRACT=/usr/bin/mkvextract
MKVMERGE=/usr/bin/mkvmerge

filename_only=`$BASENAME "$mkv_input" .mkv`
dirname_only=`$DIRNAME "$mkv_input"`

trackCount=`$MKVINFO "$mkv_input" | $GREP track\ ID | $WC -l`
echo "[`$DATE`] $trackCount tracks are found from $mkv_input..."
echo "[`$DATE`] This script will generate temporary files on the way and you may want to remove them by yourself..."

trackId=0
while [ $trackId -lt $trackCount ]
do
        trackNum=`expr $trackId + 1`
        mkv_output=$dirname_only/$filename_only.$trackId.mkv
        audio_org=$dirname_only/_tmp_audio.$trackId.org
        audio_new=$dirname_only/_tmp_audio.$trackId.aac

        if [ -f "$mkv_output" ]; then
                echo "[`$DATE`] Already converted file found: $mkv_output"
                trackId=`expr $trackId + 1`
                continue;
        fi

        srcAudio=`$MKVINFO "$mkv_input" | $GREP Codec\ ID | $HEAD -$trackNum | $TAIL -1 | $GREP -e "\(DTS\|AC3\)" | $CUT -d ":" -f 2`
        if [ "$srcAudio" = "" ]; then
                trackId=`expr $trackId + 1`
                continue
        fi
        echo "[`$DATE`] Audio track found at $trackId: $srcAudio"

        echo "[`$DATE`] Extracting audio to a file: $audio_org ..."
        $MKVEXTRACT tracks "$mkv_input" $trackId:"$audio_org"
        if [ ! -f "$audio_org" ]; then
                echo "[`$DATE`] *** Audio track extraction failed ***"
                trackId=`expr $trackId + 1`
                continue
        fi

        echo "[`$DATE`] Converting extracted audio to AAC: $audio_new ..."
        $AVCONV -i "$audio_org" -strict experimental -acodec 'aac' -ac '2' -pass '1' -y "$audio_new"
        if [ ! -f "$audio_new" ]; then
                echo "[`$DATE`] *** Audio converting failed ***"
                trackId=`expr $trackId + 1`
                continue
        fi

        echo "[`$DATE`] Merging new audio into MKV: $mkv_output ..."
        $MKVMERGE -o "$mkv_output" -A "$mkv_input" "$audio_new"
        if [ ! -f "$mkv_output" ]; then
                echo "[`$DATE`] *** Merging failed ***"
        fi

        trackId=`expr $trackId + 1`
done

echo "[`$DATE`] Done"
As you can see it generates temporary files on the way. You will need to manually remove them or you will need to modify the script by yourself. I just don't like any scripts to remove anything for safety reasons.

3 comments:

Unknown said...

I've been hunting for a script like this for ages but I'm on Windows is there anyway I can get this to work with python on Windows 8.1?

Anonymous said...

You may refer to this step by step guide to convert DTS/AC3 to AAC, MP3, WAV, WMA, M4A, RA, AU etc at http://www.idealshare.net/audio-converter/convert-ac3-to-aac-wav-aiff-flac-m4a-wma-mp3.html

Anonymous said...

Thanks for the script, works really well, where is the tmp directory located?