DVD 光碟上的视频文件通常以 .VOB 格式保存在 VIDEO_TS 目录中,由于一些系统只能读取 1GB 以下的 VOB 文件,因此,为了保证最大兼容性,视频通常会被切割成 1GB 大小的多个 VOB 文件。

对于只有一个 VOB 文件的光盘,可以不做处理直接转换(ffmpeg 会采用默认的最优化配置完成视频的格式转换):

$ ffmpeg -i VTS_01_1.VOB output.mp4

多 vob 文件时,就要参照以下步骤转换:

第一步 合并多个 vob 文件

光盘 VIDEO_TS 目录中通常有多个 *.vob 格式的视频文件。转换前首先要把它们合成为一个 output.vob 文件:

$ cat *.VOB > output.vob

第二步 识别 vob 信息

$ ffmpeg -i output.vob

Input #0, mpeg, from 'output.vob':
  Duration: 01:08:50.98, start: 0.287267, bitrate: 6469 kb/s
    Stream #0:0[0x1bf]: Data: dvd_nav_packet
    Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, bt470bg, top first), 720x576 [SAR 16:15 DAR 4:3], 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:2[0x80]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s
    Stream #0:3[0x81]: Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s
    Stream #0:4[0x20]: Subtitle: dvd_subtitle
    Stream #0:5[0x21]: Subtitle: dvd_subtitle

从输出的信息可以看出来,0:0 是 DVD 的菜单,0:1 是视频部分,0:20:3是音频部分,0:40:5 是字幕。

进一步识别视频信息

由于 ffmpeg 只会用几秒的时间对视频的头文件解析,从而知道视频中包含哪些文件。不幸的是,VOB 这种格式没有头文件,因此只读几秒钟是无法获取 VOB 文件的完整文件信息的。这时候就需要指定参数,让 ffmpeg 读取视频的一部分,从而获取完成的文件信息:

$ ffmpeg -analyzeduration 100M -probesize 100M -i output.vob

可以根据情况调整数值

开始转换

为了让转码后的视频更完整,我决定将两个音轨和两个字幕都集成进去

$ ffmpeg -i output.vob -preset superfast -crf 21 \
    -c:a ac3 \
    -c:s copy \
    -map 0:1 -map 0:2 -map 0:3 -map 0:4 -map 0:5 \
    output.mkv

-c:a-codec:a 的简写,冒号后面的 aaudio 音频的简写,ssubtitle 的简写。这个参数用来指定视频、音频、字幕所采用的编码器,copy 表示沿用源视频的编码器。

-map 用来指定参与转码的资源编号,即第二步识别出来的视频信息。

Tips

在不指定任何解码器时,ffmpeg 会使用 libx264 转码视频,转出的视频文件大小是源文件的 16% 左右,清晰度很高,但转码时间很长。

如果希望快点完成转码,则可以指定 -preset-crf 两个参数来调谐。

我个人用下面的参数设置就能达到速度和质量比较理想的平衡,转码后的文件是源文件尺寸的 40% 左右:

$ ffmpeg -i output.vob -preset superfast -crf 18 output.mp4

-crf 参数的设置范围是 0~50,数值越小代表清晰度越高,建议值域为 18~28。

使用 -c:s copy 参数可以把光盘中的字幕复制到视频里。

Reference