User Tools

Site Tools


copy_dvd

Copying / transcoding a DVD with ffmpeg

  • First, copy the DVD to a hard drive

For unencrypted DVDs:

  • Use VLC to check which are the correct files. In the example below, they are VTS_01_1.VOB to VTS_01_3.VOB.
  • Define a few variables
dvd_folder=Desktop/MetaMecano-VIDEO_TS
out=Desktop/MetaMecano-DVD.mkv

* send to ffmpeg for rewrapping or transcoding

time cat "$dvd_folder"/VTS_01_[123].VOB \
| ffmpeg -r 25 -fflags +genpts -analyzeduration 1G -probesize 1G -i - \
  -map 0:v -map 0:a -map 0:s -c copy -r 25 \
  "$out"

To copy all subtitles, use

-map 0:v -map 0:a -map 0:s -c copy

Using just

-map 0 -c copy

doesn't work because of

Stream #0:0[0x1bf]: Data: dvd_nav_packet :
  [matroska @ 0x7f7f6e875400] Only audio, video, and subtitles are supported for Matroska.
  Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument)

Or to copy only the first subtitle track, use :

-c:v copy -c:a copy -c:s copy

More options

vob_opt=(-probesize 1G -analyzeduration 1G -r 25 -fflags +genpts)
h264_opt=(-c:v libx264 -tune film -pix_fmt yuv420p -profile:v high -level 4.0 -preset fast -crf 18)
filter_opt=(-filter:v "yadif=0:-1:0, scale=iw*sar:ih:flags=lanczos, setsar=1")
col_opt=(-colorspace bt470bg -color_primaries bt470bg -color_trc gamma28)
keyframes_opt=(-g 25)
audio_opt=(-c:a aac -b:a 160k)
test="-t 120" # 120 seconds for testing

then

ffmpeg "${vob_opt[@]}" -i "$in" $test "${col_opt[@]}" "${h264_opt[@]}" "${keyframes_opt[@]}" "${filter_opt[@]}" "${audio_opt[@]}" "$out"

Check if the DVD uses CSS copy protection

  • Try playing single .VOB files in VLC.
  • Or use check-dvd-css.pl with one of the .VOB files :
check-dvd-css.pl
#!/usr/bin/perl
 
my $VERSION=0.1;
 
my $sector_size = 2048;
my $count       = 1000;
 
use strict;
use autodie;
 
 
my $file = shift;
die "Not found: $file\n" unless (-f $file);
 
if (-s $file < $count * $sector_size) {
	$count = int( (-s $file)/$sector_size );
	warn "File too small. Checking $count sectors only ($file)\n";
}
 
my $protected = 0;
 
open my $fh, '<:raw', $file;
 
for (my $s=0; $s<$count; $s++) {
	my $bytes_read = read($fh, my $sector, $sector_size);
	die "Got $bytes_read but expected $sector_size from $file\n" unless ($bytes_read == $sector_size);
 
	my @bytes = unpack("C*", $sector);
	if ( ($bytes[ ($bytes[13] & 7)+20 ] & 48) != 0 ) {
		$protected++;
	}
}
 
if ($protected) {
	print "CSS-protected (on $protected of $count sectors) : $file\n";
} else {
	print "NOT protected : $file\n";
}

Extract subtitles

List content with lsdvd -x. From the output, select the VTS index for the movie, and select the index of the wanted subtitle track.

vtsid=2    # "Title: 02, [...] VTS: 02" will use VTS_02_0.IFO
subid=0    # "Subtitle: 01" : 1st subtitle track is index 0
mencoder -dvd-device VIDEO_TS dvd://1 -nosound -ovc 'copy' -o /dev/null -ifo VIDEO_TS/VTS_0${vtid}_0.IFO -sid $subid -vobsubout vobsubs-$subid

(See also https://www.rigacci.org/wiki/doku.php/doc/appunti/linux/video/vobcopy)

/docs/dokuwiki/data/pages/copy_dvd.txt · Last modified: 2021-12-26 14:54:08 by mi