Skip to content

Instantly share code, notes, and snippets.

@euskadi31
Forked from dzuelke/mkv2m4v.sh
Created July 27, 2011 12:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save euskadi31/1109264 to your computer and use it in GitHub Desktop.
Save euskadi31/1109264 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"
@PodFicus
Copy link

How to improve this code to deal with .mkv that contain more than one audio track?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment