[MEncoder-users] Ripping dvd to mp4
Erik Slagter
erik at slagter.name
Mon Mar 24 13:34:26 CET 2008
Hi,
I want to be able to rip dvd's and play them on my PS3 (and also other
future, standards-compliant hardware devices, so this rules out ogg,
matroska etc.)
The nasty thing is that I also want exactly 1 subtitle track included.
Without subtitling it is actually very simple to rip a dvd...
I also found out that mp4 does support (soft) subtitling but most
devices do not render them, so I will need to render the subtitles in
the video stream :-(
Also the audio and video need to remain in sync (of course) wich rules
out solutions that use elementary streams without a/v sync compensation.
As far as I know there is only one combination of programs and options
that can do this (see attached script), which works fairly well. It uses
the command line versions of x264 and faac to achieve maximum
flexibility. The audio and video frames are passed using named pipes so
there are no huge intermediate files. The stdin-stdout pipes are only
there to keep all processes running while there is still input to be
processed, no data is passed through them. It adds chapter info to the
mp4 file although the PS3 doesn't use it :-(
I was wondering whether someone knows other (simpler) solutions as well.
Native subtitling rendering support in ffmpeg and mencoder would the
best solution of course, but that's not reality.
==============================================
#!/bin/sh
audiolang="en"
sublang="nl"
if [ $# -lt 1 ]
then
dvd=$PWD
else
dvd="$1"
fi
if [ ! -d "$dvd" ]
then
echo "not a directory: $1"
exit
fi
vpipe1="dvd2avc1.y4m"
apipe1="dvd2avc1.apipe"
title=$(mplayer -identify -frames 0 -dvd-device $dvd dvd:// 2>&1 |
egrep "ID_DVD_TITLE_[0-9]+_LENGTH=" |
sort '-t=' -g -r -k 2 |
head -1 | \
perl -n -e '($_) = m/ID_DVD_TITLE_([0-9]+)_LENGTH/; print $_')
echo "Main title: $title"
chapters=$(mplayer -identify -frames 0 -dvd-device $dvd dvd://${title}
2>&1 |
perl -n -e 'if(/^CHAPTERS: /) { s/^CHAPTERS: //; s/,/ /g; print
$_; last; }')
echo "Chapters in this title: $chapters"
aid=$(mplayer -identify -frames 0 -dvd-device $dvd dvd://${title} 2>&1 |
egrep "ID_AID_[0-9]+_LANG=${audiolang}" |
sort -g |
head -1 | \
perl -n -e '($_) = m/ID_AID_([0-9]+)_LANG/; print $_')
echo "Audio id: $aid"
sid=$(mplayer -identify -frames 0 -dvd-device $dvd dvd:// 2>&1 | \
perl -n -e "if(/ID_SID_[0-9]+_LANG=${sublang}/) { (\$a) =
m/ID_SID_([0-9])+_LANG/; printf \"%s\n\", \$a; }")
echo "Sub id: $sid"
avc="dvd.264"
aac="dvd.aac"
mp4="dvd.mp4"
chap="dvd.chap"
rm "$vpipe1" "$apipe1" 2> /dev/null
mknod "$vpipe1" p
mknod "$apipe1" p
rm "$chap" 2> /dev/null
for chapter in $chapters
do
echo "$chapter $chapter" >> $chap
done
mplayer -noconsolecontrols -nocache -vf-clr -benchmark -slang nl -sid
"$sid" -aid "$aid" \
-vo "yuv4mpeg:interlaced:file=$vpipe1" -ao
"pcm:waveheader:file=$apipe1:fast" \
-dvd-device $dvd dvd://$title 1>&2 /dev/null | \
x264 --bframes 16 --b-pyramid --ref 4 --interlaced --crf 20 \
--trellis 1 --nr 1000 --level 41 \
--threads 2 --direct none --subme 5 -o "$avc" "$vpipe1" | \
(faac --mpeg-vers 4 -b 192 -o "$aac" "$apipe1" 2> /dev/null)
rm "$vpipe1" "$apipe1" 2> /dev/null
MP4Box -lang en -new "$mp4" -add "$avc" -add "$aac" -chap "$chap" -isma
More information about the MEncoder-users
mailing list