Over-The-Shoulder Manual DVDRiP
I decided to make an OTS example of my DVD ripping, as most geeks that have seen my rips wonder how I did it—now I don’t have to repeat myself over and over.
Tools
- dvdbackup (part of the dvd-create tool set) — To get the data off the DVD and remove the CSS encryption. I used the Fink package.
- x264 — For encoding the H.264 stream. I got this from the ffmpegX suite.
- FAAC — For encoding the AAC audio, which gives better quality per bit than MP3s. I used the Fink package.
- ffmpeg — Demuxer and decoder. I got this from the ffmpegX suite.
- mp4box (part of the gpac project) — Muxer. I got this from the ffmpegX suite.
- BTMKT — BitTorrent metainfo file creator.
Steps
Set Up Workspace
ckastorff@wide:~ $ cd monty-python/
ckastorff@wide:~/monty-python $
Ripped DVD to Hard Drive
First, I found the device node for my DVD—this part will change depending on the OS. In OS X’s case, I went to Disk Utility and found the device name by viewing extra info on the Volume. The device name was /dev/disk1. I then unmounted the DVD so that dvdbackup wouldn’t have any issues.
libdvdread: Using libdvdcss version 1.2.9 for DVD access
libdvdread: Attempting to retrieve all CSS keys
libdvdread: This can take a _long_ time, please be patient
libdvdread: Get key for /VIDEO_TS/VIDEO_TS.VOB at 0x000001c0
libdvdread: Elapsed time 0
libdvdread: Get key for /VIDEO_TS/VTS_01_0.VOB at 0x000022c0
libdvdread: Elapsed time 0
libdvdread: Get key for /VIDEO_TS/VTS_01_1.VOB at 0x0002fe3a
libdvdread: Elapsed time 0
libdvdread: Get key for /VIDEO_TS/VTS_02_0.VOB at 0x0028ab40
libdvdread: Elapsed time 0
libdvdread: Get key for /VIDEO_TS/VTS_02_1.VOB at 0x0028ab60
libdvdread: Elapsed time 0
libdvdread: Found 2 VTS's
libdvdread: Elapsed time 0
While waiting on that, I talked on IRC.
<jordgubbe> still hunting for stuff to delete.
<jordgubbe> :)
<encryptio> coo
<jordgubbe> you?
<jordgubbe> :P
<encryptio> copying things from irc to put in the dvd ripping over-the-shoulder tutorial
<encryptio> you'll be famous!
Strip and Join
I checked, with VLC, which VOBs are the actual movie—turns out only VTS_01_0.VOB was not. I removed it and the IFO and BUP files, as I won’t be needing them.
ckastorff@wide:~/monty-python/dvdrip/VIDEO_TS $ ls
VTS_01_1.VOB VTS_01_2.VOB VTS_01_3.VOB VTS_01_4.VOB VTS_01_5.VOB
I then joined the VOBs into a single VOB so that ffmpeg would have an easier time dealing with the file, then killed the split files.
ckastorff@wide:~/monty-python/dvdrip/VIDEO_TS $ rm VTS_*
Transcoded the Audio Track
First, I needed to know which track I wanted to get. I got info on the file with ffmpeg...
FFmpeg version CVS, Copyright (c) 2000-2004 Fabrice Bellard
Mac OSX universal build for ffmpegX
configuration: --enable-memalign-hack --enable-mp3lame --enable-gpl --disable-vhook
--disable-ffplay --disable-ffserver --enable-a52 --enable-xvid --enable-faac --enable-faad
--enable-amr_nb --enable-amr_wb --enable-pthreads --enable-x264
libavutil version: 49.0.0
libavcodec version: 51.9.0
libavformat version: 50.4.0
built on Apr 15 2006 04:58:19, gcc: 4.0.1 (Apple Computer, Inc. build 5250)
Input #0, mpeg, from 'joined.vob':
Duration: 00:31:33.9, start: 0.041500, bitrate: 21358 kb/s
Stream #0.0[0x1e0], 29.97 fps(r): Video: mpeg2video, yuv420p, 720x480, 9800 kb/s
Stream #0.1[0x84]: Audio: ac3, 48000 Hz, stereo, 192 kb/s
Stream #0.2[0x83]: Audio: ac3, 48000 Hz, stereo, 192 kb/s
Stream #0.3[0x82]: Audio: ac3, 48000 Hz, stereo, 192 kb/s
Stream #0.4[0x81]: Audio: ac3, 48000 Hz, 5:1, 448 kb/s
Stream #0.5[0x80]: Audio: ac3, 48000 Hz, stereo, 192 kb/s
Stream #0.6[0x26]: Subtitle: dvdsub
Stream #0.7[0x25]: Subtitle: dvdsub
Stream #0.8[0x24]: Subtitle: dvdsub
Stream #0.9[0x23]: Subtitle: dvdsub
Stream #0.10[0x22]: Subtitle: dvdsub
Stream #0.11[0x21]: Subtitle: dvdsub
Must supply at least one output file
Now I knew the audio tracks were on tracks #0.1, #0.2, #0.3, #0.4, and #0.5. After a little trial and error, I found that that 5.1 track (#0.4) was the correct track—the others were commentaries by various people, and #0.5 was a french track. I decoded that track to a wav file.
<<snip>
Input #0, mpeg, from 'joined.vob':
<<snip>>
Output #0, wav, to 'out.wav':
Stream #0.0: Audio: pcm_s16le, 48000 Hz, stereo, 1536 kb/s
Stream mapping:
Stream #0.4 -> #0.0 [sync #0.0]
Press [q] to stop encoding
size= 1036614kB time=5528.6 bitrate=1536.0kbits/s
video:0kB audio:1036614kB global headers:0kB muxing overhead 0.000004%
Then I encoded it into the AAC track I needed, with a slightly higher bitrate than it would normally output.
Freeware Advanced Audio Coder
FAAC 1.24+ (Sep 7 2007) UNSTABLE
Quantization quality: 133
Bandwidth: 19960 Hz
Object type: Low Complexity(MPEG-2) + M/S
Container format: Transport Stream (ADTS)
Encoding out.wav to out.aac
frame | bitrate | elapsed/estim | play/CPU | ETA
259155/259155 (100%)| 141.6 | 269.1/269.1 | 20.55x | 0.0
Transcoded the Video Track
First, I needed to know what bitrate I was supposed to use—I knew my target size was 690MiB, and the audio was already taking up 93.3MiB. I went to my bot for advice:
<boobs> encryptio: 905.216 kbps
There were small black borders around the image in the DVD, something I wanted to remove—so I used ffmpeg’s -crop* options to remove them, finding the values via trial and error. I then encoded the first pass.
-cropbottom 8 -s 720x400 -r 30000/1001 - | x264 -I 100 -b 5 --b-pyramid --ref 5 -A all --weightb \
--me umh --merange 24 --subme 7 --b-rdo --mixed-refs --bime --8x8dct --trellis 2 --qcomp 0.9 \
--bitrate 905 --threads 2 --fps 30000/1001 --pass 1 -o video.mp4 - 720x400
<<snip>>
Output #0, yuv4mpegpipe, to 'pipe:':
Stream #0.0, 29.97 fps(c): Video: rawvideo, yuv420p, 720x400, q=2-31, 200 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Press [q] to stop encoding
frame=165699 q=0.0 Lsize=69904266kB time=5528.8 bitrate=103576.4kbits/s
video:0kB audio:0kB global headers:0kB muxing overhead inf%
x264 [info]: slice I:2413 Avg QP:21.44 size: 24789 PSNR Mean Y:44.91 U:49.18 V:49.71 Avg:45.76 Global:43.84
x264 [info]: slice P:86723 Avg QP:23.70 size: 5043 PSNR Mean Y:42.30 U:46.64 V:47.34 Avg:43.26 Global:41.95
x264 [info]: slice B:76563 Avg QP:24.51 size: 1512 PSNR Mean Y:45.05 U:51.49 V:52.11 Avg:46.06 Global:41.80
x264 [info]: mb I I16..4: 18.7% 68.5% 12.9%
x264 [info]: mb P I16..4: 2.9% 6.6% 0.6% P16..4: 45.4% 11.0% 4.0% 0.2% 0.1% skip:29.3%
x264 [info]: mb B I16..4: 0.3% 0.7% 0.1% B16..8: 28.4% 0.9% 1.3% direct: 2.0% skip:66.5%
x264 [info]: final ratefactor: 21.91
x264 [info]: 8x8 transform intra:65.8% inter:72.1%
x264 [info]: ref P 71.5% 11.9% 8.7% 4.0% 3.9%
x264 [info]: ref B 72.2% 12.8% 8.3% 3.6% 3.0%
x264 [info]: PSNR Mean Y:43.605 U:48.922 V:49.579 Avg:44.589 Global:41.902 kb/s:886.83
encoded 165699 frames, 7.02 fps, 888.17 kb/s
While waiting on that, I noticed I had made a mistake. The movie wasn’t 90 minutes long, it was slightly longer: 92 minutes. So I took the new length into account, calculated my new bitrate, and continued with the second pass.
<boobs> encryptio: 884.127912024313 kbps
-cropbottom 8 -s 720x400 -r 30000/1001 - | x264 -I 100 -b 5 --b-pyramid --ref 5 -A all --weightb \
--me umh --merange 24 --subme 7 --b-rdo --mixed-refs --bime --8x8dct --trellis 2 --qcomp 0.9 \
--bitrate 884 --threads 2 --fps 30000/1001 --pass 3 -o video.mp4 - 720x400
<<snip>>
Press [q] to stop encoding
frame=165699 q=0.0 Lsize=69904266kB time=5528.8 bitrate=103576.4kbits/s
video:0kB audio:0kB global headers:0kB muxing overhead inf%
x264 [info]: slice I:2413 Avg QP:21.37 size: 25698 PSNR Mean Y:45.04 U:49.30 V:49.83 Avg:45.88 Global:44.09
x264 [info]: slice P:86723 Avg QP:23.63 size: 5031 PSNR Mean Y:42.43 U:46.75 V:47.43 Avg:43.38 Global:42.24
x264 [info]: slice B:76563 Avg QP:24.67 size: 1473 PSNR Mean Y:45.01 U:51.62 V:52.22 Avg:46.02 Global:42.09
x264 [info]: mb I I16..4: 18.4% 68.7% 12.9%
x264 [info]: mb P I16..4: 2.7% 6.9% 0.7% P16..4: 37.9% 11.1% 4.1% 0.2% 0.1% skip:36.3%
x264 [info]: mb B I16..4: 0.3% 0.7% 0.1% B16..8: 28.8% 0.9% 1.3% direct: 1.9% skip:66.0%
x264 [info]: 8x8 transform intra:67.4% inter:75.2%
x264 [info]: ref P 68.0% 12.3% 10.3% 5.0% 4.5%
x264 [info]: ref B 74.2% 10.6% 8.5% 3.8% 3.0%
x264 [info]: PSNR Mean Y:43.664 U:49.037 V:49.676 Avg:44.640 Global:42.188 kb/s:884.13
encoded 165699 frames, 7.92 fps, 885.46 kb/s
And the third and final pass...
-cropbottom 8 -s 720x400 -r 30000/1001 - | x264 -I 100 -b 5 --b-pyramid --ref 5 -A all --weightb \
--me umh --merange 24 --subme 7 --b-rdo --mixed-refs --bime --8x8dct --trellis 2 --qcomp 0.9 \
--bitrate 884 --threads 2 --fps 30000/1001 --pass 2 -o video.mp4 - 720x400
<<snip>>
Press [q] to stop encoding
frame=165699 q=0.0 Lsize=69904266kB time=5528.8 bitrate=103576.4kbits/s
video:0kB audio:0kB global headers:0kB muxing overhead inf%
x264 [info]: slice I:2413 Avg QP:21.31 size: 25755 PSNR Mean Y:45.05 U:49.32 V:49.85 Avg:45.89 Global:44.15
x264 [info]: slice P:86723 Avg QP:23.60 size: 5031 PSNR Mean Y:42.44 U:46.75 V:47.44 Avg:43.39 Global:42.27
x264 [info]: slice B:76563 Avg QP:24.55 size: 1470 PSNR Mean Y:45.02 U:51.63 V:52.23 Avg:46.03 Global:42.12
x264 [info]: mb I I16..4: 18.1% 69.1% 12.8%
x264 [info]: mb P I16..4: 2.7% 6.9% 0.7% P16..4: 38.0% 11.1% 4.2% 0.2% 0.1% skip:36.1%
x264 [info]: mb B I16..4: 0.3% 0.7% 0.1% B16..8: 28.8% 0.9% 1.4% direct: 1.9% skip:65.9%
x264 [info]: 8x8 transform intra:67.3% inter:75.2%
x264 [info]: ref P 68.0% 12.4% 10.2% 4.9% 4.4%
x264 [info]: ref B 73.9% 10.7% 8.5% 3.8% 3.0%
x264 [info]: PSNR Mean Y:43.670 U:49.041 V:49.690 Avg:44.645 Global:42.221 kb/s:884.09
encoded 165699 frames, 7.05 fps, 885.42 kb/s
Mux Video and Audio Tracks for Final File
Here, there was an odd error—the original VOBs indicated that the frame rate was 29.97 fps, but the actual frame rate was 29.971 fps. This caused a small delay on the order of a tenth of a second by the end of the movie. I had to demux the video track from its mp4 container and force its frame rate to the improper, but working frame rate.
Extracting MPEG-4 AVC-H264 stream to h264
And here’s the mux...
AVC-H264 import - frame size 720 x 400 at 29.971 FPS
Adjusting AVC SizeLength to 16 bits
Import results: 165699 samples - Slices: 4826 I 173446 P 153126 B - 1 SEI - 4270 IDR
Stream uses B-slice references - max frame delay 2
AAC import - sample rate 48000 - MPEG-2 audio - 2 channels
Saving to muxed.mp4: 0.500 secs Interleaving
Make a Torrent for Other People That Own the Movie to Travel With
I would never advocate piracy!
ckastorff@wide:~/monty-python $ btmkt -private http://ann/url monty*