Skip to content

Instantly share code, notes, and snippets.

@dzuelke
Forked from innerfence/mkv2m4v.sh
Created October 22, 2010 22:07
Show Gist options
  • Save dzuelke/641476 to your computer and use it in GitHub Desktop.
Save dzuelke/641476 to your computer and use it in GitHub Desktop.
Convert .mkv video to iPad compatible .m4v without re-encoding
#!/bin/bash
#
# mkv2m4v inputfile.mkv
#
# Given an MKV container with H.264 video & AC3 or DTS audio, converts
# quickly to an iPad-compatible MP4 container without re-encoding the
# video (so it must already be in an iPad-compatible resolution); the
# audio is downmixed to stereo with Dynamic Range Compression.
#
ME=$(basename $0)
usage() {
echo "usage: ${ME} inputfile.mkv" 1>&2
exit 1
}
message() {
echo ${ME}: "$@"
}
error() {
message "$@" 1>&2
exit 1
}
checkdep() {
[ ! -z $(which "$@") ] || error "Can't find dependency:" "$@"
}
# brew install mkvtoolnix
checkdep mkvmerge
checkdep mkvinfo
checkdep mkvextract
# brew install a52dec
checkdep a52dec
# brew install libdca
checkdep dcadec
# brew install faac
checkdep faac
# brew install gpac
checkdep MP4Box
INFILE=$1
shift
if [ "${INFILE}" == "" ]; then
usage
fi
if [ ! -r $INFILE ]; then
error "Can't read $INFILE"
fi
DESTDIR=$(dirname $INFILE)
INFILE_BASE=$(basename $INFILE)
BASE=$DESTDIR/${INFILE_BASE%.*}
message "Analyzing Matroska ..."
mkvmerge -i ${INFILE} > ${BASE}.tid
echo ""
AUDTID=$(grep A_AC3 ${BASE}.tid | perl -ne '/(\d+)/ and print $1')
AVCTID=$(grep AVC ${BASE}.tid | perl -ne '/(\d+)/ and print $1')
if [ "${AUDTID}" == "" ]; then
AUDTID=$(grep A_DTS ${BASE}.tid | perl -ne '/(\d+)/ and print $1')
if [ "${AUDTID}" == "" ]; then
error "Couldn't find AC3 or DTS stream, check track info in ${BASE}.tid"
else
AUDIO="DTS"
AUDIODEC="dcadec"
fi
else
AUDIO="AC3"
AUDIODEC="a52dec"
fi
if [ "${AVCTID}" == "" ]; then
error "Couldn't find AVC stream, check track info in ${BASE}.tid"
fi
message "Demultiplexing Matroska ..."
mkvextract tracks ${INFILE} "${AUDTID}:${BASE}.${AUDIO}" "${AVCTID}:${BASE}.264"
echo ""
message "Downmixing ${AUDIO} ..."
${AUDIODEC} -o wav ${BASE}.${AUDIO} > ${BASE}.wav
echo ""
message "Encoding audio for MP4 ..."
faac -b 96 --mpeg-vers 4 -o ${BASE}.aac ${BASE}.wav
echo ""
message "Creating MP4 container ..."
MP4Box -inter 0 -add ${BASE}.264:fps=`LANG=en mkvinfo ${INFILE} | grep "Track number: $AVCTID" -A 15 | awk '/[0-9.]\ fps/ { print $6 }' | awk -F\( '{ print $2 }' | tail -1` -add ${BASE}.aac ${BASE}.m4v
echo ""
message "Cleaning up ..."
rm ${BASE}.{tid,264,wav,aac}
rm ${BASE}.${AUDIO}
echo ""
message "Done, output file: ${BASE}.m4v"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment