2010年3月31日 星期三

linuxer


处理视频,Windows 下有很多图形界面的工具,由于涉及到视频、音频、字幕...参数太多,图形界面太
复杂,想告诉别人处理过程还得截图,此时 Linux commandline 的优势出来了,用起来比图形界面简单易懂。

区分 video format 和 codec。avi mkv mp4 都属于format,被称为container,里面包含video、audio、
sub,对应有 vcodec、acodec、scodec。

Windows 为了方便普通用户,把文件的扩展名用类似 format 的名字来表示,有的就是 format 名字本身。
因此Windows下想知道视频的format就看扩展名:
.avi .mp4 .rm .vob 和其format名相同
.mpg format名是 mpeg
.mkv format名是 matroska

当然用扩展名也有坏处,比如一个a.rar可能无法解压,因为这个a.rar是由一个电脑新手把a.txt直接改
名成a.rar的;或者下了一个.torrent无法下载,实际是制作人把.torrent压缩成了zip,然后又改名成.torrent。
Linux 下就没这类问题,解压不了就用file命令看一下真正的format,然后用相应的工具处理。把foo.avi改名
为foo,也照样能用 $ mplayer foo 播放。

通常文件扩展名就代表文件的format,但由于用户可以任意修改扩展名,所以拿来一个新文件,无法确
定a.avi 就是 avi format,普通用户在这里会被误导。

这里也看出来 Windows 那一套机制都是给傻瓜用户用的,方便却糊里糊涂;Linux 是给大学生用的,不
方便但是有利于培养思考能力。有些国家连计算机系的大学生都普及 Windows,就可以知道这个国家没有原
创技术,也不崇尚创新,大学都是衙门,不是培养人才之地。

查看 format 和 codec:
$ ffmpeg -formats|less
$ ffmpeg -codecs|less

file 命令看 format 和 codec:
$ file *
foo.DAT: RIFF (little-endian) data, wrapped MPEG-1 (CDXA)
foo.mpg: RIFF (little-endian) data, wrapped MPEG-1 (CDXA)
foo.vob: MPEG sequence, v2, program multiplex
foo.wmv: Microsoft ASF
foo.asf: Microsoft ASF
foo.rm: RealMedia file
foo.mkv: Matroska data
foo.mp4: ISO Media, MPEG v4 system, version 1
foo.m4v: ISO Media, MPEG v4 system, iTunes AVC-LC
foo.mov: ISO Media, Apple QuickTime movie
foo.flv: Macromedia Flash Video
foo.ts: MPEG transport stream data
foo.avi: RIFF (little-endian) data, AVI, 640 x 480, 25.00 fps, video: XviD, audio: MPEG-1 Layer 3 (stereo, 44100 Hz)
foo1.avi: RIFF (little-endian) data, AVI, 640 x 480, 30.00 fps, video: H.264 X.264 or H.264, audio: MPEG-1 Layer 3 (stereo, 22050 Hz)
foo2.avi: RIFF (little-endian) data, AVI, 352 x 256, 30.00 fps, video: DivX 5, audio: MPEG-1 Layer 3 (stereo, 44100 Hz)
foo3.avi: RIFF (little-endian) data, AVI, 640 x 480, 30.00 fps, video: Motion JPEG, audio: uLaw (mono, 8000 Hz)

常见 format: avi mkv mp4 vob mpg mov wmv rm ...
常见 vcodec: MPEG-1 MPEG-2 MPEG-4 H.264 wmv3 RV40...
常见 acodec: AAC ac3 libmp3lame wmav2 cook ...

其中 H.264 是最流行的 vcodec,也叫 MPEG-4 AVC、MPEG-4 part 10,对cpu等硬件要求较高,目前高
清用 H.264、MPEG-2 的最多。

DVD 电影扩展名为 .vob,MPEG-2 + ac3、dts,vbitrate: 7Mbps
720P、1080P 高清电影扩展名多为 .mkv .mp4,H.264 + ac3、dts,vbitrate: 5Mbps、10Mbps
Blu-ray Disc 蓝光盘电影扩展名多为 .ts .m2ts H.264、MPEG-2 + ac3、dts,vbitrate: 36Mbps
手机等掌上设备: mp4,MPEG-4
iphone 主要支持的format: mp4 mov m4v,优势是支持 H.264,也就是能看高清电影

.mov 多用来做高清1080P的电影预告片: True.Grit.2010.12.25.1080P.预告片.mov


想起了一个MM征友,说要找有品味的,比如平时谈论的是苹果五代,而不是五袋苹果的人。显然我是没
品味的那种,因为我平时只喜欢谈论五袋苹果,不喜欢谈论苹果五代。

还有两个format平时压片尽量别用,因为它们商业味太浓,处理起来特别麻烦,尽量别用:
.rm RV40 + cook
.wmv .asf wmv3 + wmav2

视频操作先考虑专用工具,比如 mkvtollnix, mp4box,实在不行再用 ffmpeg,以前一直用 mencoder,
后来发现ffmpeg问题少些,以后陆续转移到ffmpeg上来。虽然mencoder毛病很多,但由于ffmpeg无法合并视
频,所以不能完全舍弃 mencoder。man mencoder 很有挑战性,和 mplayer 一起,参数多,跨度大,这个
熟练后,在 man 什么都不怕了。

生成的视频 linux mplayer 总能很好的播放,所以一定要到Windows下去验证,最好直接mount一个NTFS,
把生成的视频直接放上面。转换会有很多问题,比如转换后参数没有保持默认:bitrate被降低、视频的长宽
比例DAR被改变、生成的视频信息封装不完整导致 file 无法识别...
$ file out.mp4
out.mp4: data

还有就是,无论什么方法,转换后的视频质量都会低于原质量,因此普通质量的视频无需转换,只转换
蓝光、1080P、720P 的视频。

1. 处理 mkv 用 mkvtoolnix
$ sudo yum install mkvtoolnix

生成一个mkv:
$ mkvmerge foo.avi -o out.mkv
$ file out.mkv
out.mkv: Matroska data

截取一段mkv。一个720P高清视频 Lin.mkv,H.264 vcodec:
$ mkvmerge Lin.mkv --split timecodes:00:36:51,01:11:00 -o out.mkv
生成3个mkv文件:
out-001.mkv
out-002.mkv
out-003.mkv
第二个就是想要的,码率会有很小的损失,Linux 下mplayer 或 Windows 下 Kmplayer 都能正常播放。
目前无法直接截取第二段,可以在第二个文件split完成后手动中断mkvmerge进程。
虽然 ffmpeg 能直接截取第二段,但操作H.264特别慢,而且不好控制,还不如直接来。

PBS 纪录片 Prohibition 用 Windows kmplayer 由于库版本低无法播放,但 Linux 库版本高能播放,
在 Linux 下做个截取的过程就能在 Windows 下播放了:
$ ffmpeg -i PBS.Prohibition.1of3.A.Nation.of.Drunkards.2011.HDTV.x264.AAC.MVGroup.Forum.mkv
Duration: 01:33:51.77, start: 0.000000, bitrate: N/A
Stream #0.0(eng): Video: h264, yuv420p, 1280x720 [PAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 1k tbn, 59.94 tbc
Stream #0.1(eng): Audio: aac, 48000 Hz, 5.1, s16
At least one output file must be specified

$ mkvmerge PBS.Prohibition.1of3.A.Nation.of.Drunkards.2011.HDTV.x264.AAC.MVGroup.Forum.mkv
--split timecodes:01:33:49
-o PBS.Prohibition.1of3.A.Nation.of.Drunkards.2011.HDTV.x264.AAC.MVGroup.Forum.out.mkv

生成的文件能用 Windows kmplayer 正常播放了。

合并mkv:
$ mkvmerge 1.mkv + 2.mkv -o out.mkv

港片国粤双语,只保留粤语: ffmpeg -i 看视频参数
$ ffmpeg -i 花样年华.2000.98min.mkv
......
Duration: 01:38:51.47, start: 0.000000, bitrate: N/A
Stream #0.0: Video: h264, yuv420p, 668x480 [PAR 5760:4739 DAR 8016:4739], PAR 203:167 DAR 203:120, 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc
Metadata:
title : Source:R1-US-DVD9 CRITERION COLLECTION
Stream #0.1: Audio: aac, 48000 Hz, stereo, s16
Metadata:
title : Cantonese
Stream #0.2: Audio: aac, 48000 Hz, stereo, s16
Metadata:
title : Mandarin
Stream #0.3(chi): Subtitle: 0x0000
Metadata:
title : chs
Stream #0.4(chi): Subtitle: 0x0000
Metadata:
title : cht
Stream #0.5(eng): Subtitle: 0x0000
Metadata:
title : eng

可见,有2条音轨,3种字幕。要第1条audio Cantonese、前两个中文字幕chs cht。

也可以用 $ mplayer -v -novideo 花样年华.2000.98min.mkv 找出 -aid 音轨号,听听验证一下:
$ mplayer -aid 0 花样年华.2000.98min.mkv
$ mplayer -aid 1 花样年华.2000.98min.mkv

$ mkvmerge -i 花样年华.2000.98min.mkv
File '花样年华.2000.98min.mkv': container: Matroska
Track ID 1: video (V_MPEG4/ISO/AVC)
Track ID 2: audio (A_AAC)
Track ID 3: audio (A_AAC)
Track ID 4: subtitles (S_TEXT/UTF8)
Track ID 5: subtitles (S_TEXT/UTF8)
Track ID 6: subtitles (S_TEXT/UTF8)

$ mkvmerge -a 2 -s 4,5 花样年华.2000.98.min.mkv -o out.mkv
out.mkv 确实就是粤语,码率损失很少,容量减少了约30MB。

一个视频一般只关心 Video、Audio、Subtitle 3个方面,mkvmerge -i 把这3类信息统一用一串
Track ID 表示出来了,只要从这3个方面考虑,就很容易却别这些 TID 了。

欧美大片想让字幕默认eng,可惜 --default-track 设置后 Windows Kmplayer 还是默认中文chs,
按照 chs eng 字母顺序来,google 说有些视频播放器 ignore default flag。

普通话国产电影,去掉所有字幕:
$ mkvmerge -S 霸王别姬.1993.mkv -o 霸王别姬.1993.out.mkv

从mkv提取字幕:

$ mplayer -v -novideo foo.mkv 发现是英简繁三种字幕
$ mkvmerge -i foo.mkv
File 'foo.mkv': container: Matroska
Track ID 1: video (V_MPEG4/ISO/AVC)
Track ID 2: audio (A_AAC)
Track ID 3: subtitles (S_TEXT/UTF8)
Track ID 4: subtitles (S_TEXT/UTF8)
Track ID 5: subtitles (S_TEXT/UTF8)

$ mkvextract tracks foo.mkv 3:3.srt 4:4.srt 5:5.srt

生成的文件为utf8编码,中文没有乱码,完全正常。

提取《大话西游之仙履奇缘》的两条音轨:
$ ffmpeg -i A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv
Input #0, matroska, from 'A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv':
Metadata:
doctype : matroska
Duration: 01:39:44.06, start: 0.000000, bitrate: 640 kb/s
Stream #0.0(chi): Video: h264, yuv420p, 1280x720, PAR 1:1 DAR 16:9, 24 fps, 24 tbr, 1k tbn, 48 tbc
Metadata:
title : A.Chinese.Odyssey.Part.Two.Cinderella.1994.x264.720p.2AUDiO.DTS.AC3.BDRiP-CHD
Stream #0.1(chi): Audio: dca, 48000 Hz, 6 channels, s16
Metadata:
title : Cantonese, DTS 5.1 @ 768Kbps
Stream #0.2(chi): Audio: ac3, 48000 Hz, 5.1, s16, 640 kb/s
Metadata:
title : Mandarin, AC3 5.1 @ 640Kbps

$ mkvmerge -i A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv
File 'A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv': container: Matroska
Track ID 1: video (V_MPEG4/ISO/AVC)
Track ID 2: audio (A_DTS)
Track ID 3: audio (A_AC3)
$ sudo mkvextract tracks A.Chinese.Odyssey.Part.Two.Cinderella.1994.blu-ray.x264.720P.2AUDIO.DTS-CHD.mkv 2:Cantonese.dts 3:Mandarin.ac3

如果mount上一个Windows硬盘,把生成的字幕文件放在Windows上,由于换行符的差别,生成的文件在 Windows
上,整个文件就是一行。而在 linux 下对 Windows 上的 3.srt 执行 $ sudo unix2dos 3.srt 会报错。
因此要把生成的 3.srt 4.srt 5.srt 放在 Linux 上,执行 $ unix2dos 3.srt 4.srt 5.srt 后再放到Windows
上。 往视频里封装srt字幕:

软字幕,过后还可以extract、delete。man mkvmerge 末尾有example,中文字幕要存为 utf-8 。

封装单个字幕:
$ mkvmerge 新上海滩.1996.avi --language 0:chi 新上海滩.1996.chs.srt -o 新上海滩.1996.mkv

封装多个字幕:
$ mkvmerge foo.avi --language 0:chi foo.chs.srt --language 0:eng foo.eng.srt -o out.mkv

subtitleeditor 处理字幕文件:
$ sudo yum install subtitleeditor

调节固定秒数:
打开subtitleeditor,File --> Open sub 后,Ctrl+a全选,Timings --> Add 100 Milliseconds
反操作就是下面的 Remove 100 Milliseconds
如果整体调节50ms就选 Timings -> Move Subtitles 自己填数字

2. 处理 mp4 用 MP4Box,它隶属于 gpac
$ sudo yum install gpac
$ man mp4box 注意命令是 MP4Box,不是 mp4box

生成mp4:
$ MP4Box -add in.avi out.mp4
$ file out.mp4
out.mp4: ISO Media, MPEG v4 system, version 1

截一段mp4:
$ MP4Box -add in.mp4 out.mp4 -splitx 60:186

合并mp4:
$ MP4Box -cat 1.mp4 -cat 2.mp4 out.mp4

内嵌字幕生成mp4: 一个avi、srt,将srt嵌入到avi中,无法提取
$ MP4Box -add "中国残留孤儿归国记.avi" -add "中国残留孤儿归国记.srt" "中国残留孤儿归国记.mp4"

3. 上面两个不行了再考虑用ffmpeg,ffmpeg 不行了用mencoder。
比如 .wmv .mpg .flv 上面两个工具都不认、codec 转换。man ffmpeg、man mencoder
ffmpeg、mencoder 参数顺序很重要。

截一段avi出来: vcodec 不变
$ ffmpeg -ss 01:05:08 -t 600 -i in.avi -vcodec copy -acodec copy -o out.avi
有时ffmpeg 截取的开始时间不准,就用 mencoder:
$ mencoder in.avi -ovc copy -oac copy -ss 01:05:08 -endpos 600 -o out.avi

一个1080p的h264视频太大,降成720p:
$ ffmpeg -i Journey.to.the.Edge.of.the.Universe.2008.Bluray.1080p.AC3.Audio.x264-CHD-002.mkv
Duration: 00:29:15.52, start: 0.000000, bitrate: 448 kb/s
Stream #0.0(eng): Video: h264, yuv420p, 1920x1080, PAR 1:1 DAR 16:9, 29.97 fps, 30 tbr, 1k tbn, 59.94 tbc
Metadata:
title : Journey.to.the.Edge.of.the.Universe.2008.Bluray.1080p.AC3.Audio.x264-CHD
Stream #0.1(eng): Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
Metadata:
title : AC3 5.1 channels, 448kbps
At least one output file must be specified

$ ffmpeg -i Journey.to.the.Edge.of.the.Universe.2008.Bluray.1080p.AC3.Audio.x264-CHD-002.mkv
-vcodec mpeg4 -b 4000k -maxrate 4200k -bufsize 1000k -r 29.97 -s hd720 -aspect 16:9 -acodec copy
-f matroska Journey.to.the.Edge.of.the.Universe.2008.720p.mkv

$ ffmpeg -i Journey.to.the.Edge.of.the.Universe.2008.720p.mkv
Duration: 00:29:15.52, start: 0.000000, bitrate: 448 kb/s
Stream #0.0(eng): Video: mpeg4, yuv420p, 1280x720 [PAR 1:1 DAR 16:9], 29.97 fps, 29.92 tbr, 1k tbn, 2997 tbc
Metadata:
title : Journey.to.the.Edge.of.the.Universe.2008.Bluray.1080p.AC3.Audio.x264-CHD
Stream #0.1(eng): Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
Metadata:
title : AC3 5.1 channels, 448kbps
At least one output file must be specified

参数保持的很好,Windows 下播放完全正常。

wmv to avi: 只转换vcodec,其它参数尽量不变,ffmpeg -i 看wmv参数
$ ffmpeg -i 打开记忆.wmv
......
Duration: 02:31:53.32, start: 2.000000, bitrate: 560 kb/s
Stream #0.0: Audio: wmav2, 44100 Hz, 2 channels, s16, 64 kb/s
Stream #0.1: Video: wmv3, yuv420p, 640x480, 30 tbr, 1k tbn, 1k tbc
At least one output file must be specified

$ ffmpeg -i 打开记忆.wmv -vcodec mpeg4 -b 560k -maxrate 660k -bufsize 1000k -r 30
-acodec libmp3lame -ab 64k -ac 2 -f avi 打开记忆.avi

直接 -acodec copy 没有声音,ffmpeg 处理 acodec wmav2 有问题。
mp3 bitrate 不要小于64k,否则声音失真;

将片尾曲提取出来,ffmpeg 多音轨用 -map:
$ ffmpeg -i OCEANS.2010.Bluray.720p.x264.AC3.2Audio-CHD.mkv
......
Duration: 01:44:00.25, start: 0.000000, bitrate: 1280 kb/s
Stream #0.0(eng): Video: h264, yuv420p, 1280x536, PAR 1:1 DAR 160:67, 23.98 fps, 24 tbr, 1k tbn, 47.95 tbc
Stream #0.1: Audio: ac3, 48000 Hz, 5.1, s16, 640 kb/s
Stream #0.2: Audio: ac3, 48000 Hz, 5.1, s16, 640 kb/s
At least one output file must be specified

$ ffmpeg -i OCEANS.2010.Bluray.720p.x264.AC3.2Audio-CHD.mkv
-map 0:1 -acodec copy japanese.ac3 -map 0:2 -acodec copy france.ac3

0:1 0:2 就是 Stream #0.1 Stream #0.2

目标硬盘是mount上的NTFS,结果提取一段时间报错,不让同时write,同时 mount 假死,中断操作后,
mount 立刻恢复了。把目标ac3 同时 write 到本机目录就不影响mount了。


从视频中提取mp3:
$ ffmpeg -ss 00:00:00 -t 286 -i 日本通商的150年.avi -vn -acodec copy "加古隆 - JAPANデビュー.mp3"

$ mencoder 日本通商的150年.avi -ovc copy -oac mp3lame -lameopts cbr:br=128:aq=0:mode=2
-of rawaudio -o "加古隆 - JAPANデビュー.mp3" -ss 00:00:00 -endpos 286

从 wmv 提取音频:
$ ffmpeg -i 打开记忆.wmv -vn -acodec copy -f asf 打开记忆.wma

多音轨视频 VTS_01_7.vob,改变其音频参数,同时不丢失音轨:
$ ffmpeg -i VTS_01_7.vob
......
Input #0, mpeg, from 'VTS_01_7.vob':
Duration: 00:05:22.94, start: 7416.780544, bitrate: 6930 kb/s
Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s
Stream #0.2[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s
At least one output file must be specified

-ac 5.1,现设定 -ac 2
$ ffmpeg -i VTS_01_7.vob -map 0:0 -vcodec copy -map 0:1 -acodec ac3 -ab 384k -ar 48000 -ac 2 VTS.vob
-map 0:2 -acodec ac3 -ab 384k -ar 48000 -ac 2 -newaudio
$ ffmpeg -i VTS.vob
......
Input #0, mpeg, from 'VTS.vob':
Duration: 00:05:22.94, start: 0.500000, bitrate: 6885 kb/s
Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x80]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s
Stream #0.2[0x81]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s
At least one output file must be specified

加 -map 时位置很重要,下面的方式虽然也行但会损失音质:

$ ffmpeg -i VTS_01_7.vob -map 0:0 -vcodec copy -map 0:1 -acodec ac3 -ab 384k -ar 48000 -ac 2
-map 0:2 -acodec ac3 -ab 384k -ar 48000 -ac 2 VTS.vob -newaudio

$ ffmpeg -i VTS.vob
Input #0, mpeg, from 'VTS.vob':
Duration: 00:03:15.89, start: 0.500000, bitrate: 6900 kb/s
Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x80]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s
Stream #0.2[0x1c0]: Audio: mp2, 48000 Hz, 2 channels, s16, 384 kb/s
At least one output file must be specified

audio 0.2 变成 mp2 了。


ac3 aac wma mp3 互转: lame 不认 wma
$ ffmpeg -i 打开记忆.wma -vn -f mp3 打开记忆.mp3
$ ffmpeg -i 打开记忆.mp3 -vn -f asf 打开记忆.wma
$ ffmpeg -i 阿里山.ac3 -vn -acodec libmp3lame -ab 320k -ac 2 -f mp3 阿里山.mp3
ac3 to mp3 要指定 -ac,虽然默认是1,但不指定不行,是个bug

$ ffmpeg -formats|less 发现 ffmpeg 无法生成ape,生成ape用mac

wav to ape:
$ mac foo.wav foo.ape -c4000

wv to wav:
$ sox Kill.Bill.Vol.1.wv Kill.Bill.Vol.1.wav

wav ape flac 互转:
$ ffmpeg -i "酒井法子 - 碧いうさぎ.wav" -vn -f flac "酒井法子 - 碧いうさぎ.flac"

截取[mp3|wav|flac]:
$ ffmpeg -ss 00:02:05 -t 300 -i 打开记忆.mp3 -vn -acodec copy cut.mp3


合并视频:

先用cat,mkvmerge、mp4box,要注意的是 ffmpeg 不能合并,要用 mencoder。
$ cat 1.avi 2.avi 3.avi >> 1987红楼梦.avi
$ cat 龙应台-01.mp3 龙应台-02.mp3 龙应台对话.mp3 >> 龍應台.北大.從鄉愁到美麗島.73min.24s.2010.08.01.mp3

cat 有些avi可以,比如一个 DVD iso 种各个vob参数都一样,就可以直接用cat,但多数format都不能用cat,
rm、mkv、mp4 从来没cat成功过。cat 成功与否和format关系很大,没发现和codec有关,avi h264一样合并
成功过。

$ cat 史上最牛50进球.avi 十大门将愚蠢失误.avi >> temp.avi
生成的temp.avi合并成功了,但无法前后拖动,用mencoder -forceidx 加上 idx 就好了
$ mencoder temp.avi -ovc copy -oac copy -forceidx -o out.avi

如果mount一个Windows NTFS,想把cat生成的文件放在Windows机器上,那要用root执行,sudo 不行:
$ sudo cat 1.avi 2.avi >> /mnt/win/out.avi
bash: out.avi: Permission denied

sudo 只对cat起作用,cat 操作升级为root,然后bash 负责 >> 操作,bash 没有被sudo提升权限。
sudo 涉及redirection时,用 bash -c 或 tee
$ sudo bash -c 'cat VTS_01_7.vob "孙燕姿 - 遇见.vob" >> /mnt/win/out.avi'
$ cat VTS_01_7.vob "孙燕姿 - 遇见.vob" | sudo tee /mnt/win/out.avi
看到 pipe | 不禁想到了上ftp站点在线看电影:
$ lftp web:123@*.*.*.*
> cat 日俄战争.mp4 |mplayer -

一个双音轨的 DVD 文件 a.iso,把里面的文件合并成一个:
$ sudo mount ~/a.iso /mnt/temp -o loop
$ ls -lR /mnt/temp
/mnt/temp:
total 4
dr-xr-xr-x 2 4294967295 4294967295 40 2009-05-30 19:11 AUDIO_TS
dr-xr-xr-x 2 4294967295 4294967295 456 2009-05-30 19:11 VIDEO_TS

/mnt/temp/AUDIO_TS:
total 0

/mnt/temp/VIDEO_TS:
total 2454804
-r--r--r-- 1 4294967295 4294967295 8192 2009-05-30 18:41 VIDEO_TS.BUP
-r--r--r-- 1 4294967295 4294967295 8192 2009-05-30 18:41 VIDEO_TS.IFO
-r--r--r-- 1 4294967295 4294967295 133120 2009-05-30 19:11 VTS_01_0.BUP
-r--r--r-- 1 4294967295 4294967295 133120 2009-05-30 18:41 VTS_01_0.IFO
-r--r--r-- 1 4294967295 4294967295 39340032 2009-05-30 19:11 VTS_01_0.VOB
-r--r--r-- 1 4294967295 4294967295 1073565696 2009-05-30 19:11 VTS_01_1.VOB
-r--r--r-- 1 4294967295 4294967295 1073565696 2009-05-30 19:11 VTS_01_2.VOB
-r--r--r-- 1 4294967295 4294967295 326965248 2009-05-30 19:11 VTS_01_3.VOB

$ cat VTS_01_1.VOB VTS_01_2.VOB VTS_01_3.VOB >> out.vob
OK了,out.vob 保持多音轨。


西游记前25集,6张 DVD .iso 文件,国粤双语,每个 .iso 里有4集,用电脑看不方便,想单独提取出来。
发现.iso中每一集都分为两个vob,就先合并,然后抛弃粤语音轨。
.iso 在Windows上,直接 cat 不行,要用 bash -c

$ sudo bash -c "cat VTS_01_1.VOB VTS_01_2.VOB >> 18.mkv"
$ sudo bash -c "cat VTS_02_1.VOB VTS_02_2.VOB >> 19.mkv"
$ sudo bash -c "cat VTS_03_1.VOB VTS_03_2.VOB >> 20.mkv"
$ sudo bash -c "cat VTS_04_1.VOB VTS_04_2.VOB >> 21.mkv"

$ sudo mkvmerge 18.vob -o 18.mkv
$ sudo mkvmerge 19.vob -o 19.mkv
$ sudo mkvmerge 20.vob -o 20.mkv
$ sudo mkvmerge 21.vob -o 21.mkv

$ sudo mkvmerge -a 2 18.mkv -o 西游记18.mkv
$ sudo mkvmerge -a 2 18.mkv -o 西游记19.mkv
$ sudo mkvmerge -a 2 18.mkv -o 西游记20.mkv
$ sudo mkvmerge -a 2 18.mkv -o 西游记21.mkv

由于同时开的mkvmerge太多,频繁写入硬盘,使得4个对应mkvmerge的进程都处于了D状态:

$ top

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1087 root 20 0 0 0 0 S 7.0 0.0 25:42.83 cifsd
1121 root 20 0 90852 22m 9284 S 1.7 2.3 85:36.64 Xorg
22116 cngrid 20 0 65308 18m 12m S 1.3 1.8 1:06.17 gnome-terminal
25334 root 20 0 38012 9268 2260 D 0.7 0.9 0:49.12 mkvmerge
25380 root 20 0 38300 10m 3456 D 0.7 1.1 0:48.66 mkvmerge
25424 root 20 0 37768 9024 2260 D 0.7 0.9 0:48.24 mkvmerge
25429 root 20 0 37296 10m 2372 D 0.7 1.0 0:57.04 mkvmerge
......

man top 说是 uninterruptible sleep,但进程仍旧继续执行,视频转换进度在不断增加。


合并mpg:

$ file *.mpg
寻找.2004.上.mpg: RIFF (little-endian) data, wrapped MPEG-1 (CDXA)
寻找.2004.下.mpg: RIFF (little-endian) data, wrapped MPEG-1 (CDXA)

$ ffmpeg -i 寻找.2004.上.mpg
......
Input #0, mpeg, from '寻找.2004.上.mpg':
Duration: 01:07:03.01, start: 0.351433, bitrate: 1410 kb/s
Stream #0.0[0x1e0]: Video: mpeg1video, yuv420p, 352x288 [PAR 178:163 DAR 1958:1467], 1150 kb/s, 25 fps, 25 tbr, 90k tbn, 25 tbc
Stream #0.1[0x1c0]: Audio: mp2, 44100 Hz, 2 channels, s16, 224 kb/s
At least one output file must be specified

$ mkvmerge -i 寻找.2004.上.mpg
File '寻找.2004.上.mpg': unsupported container: RIFF CDXA

mkvmerge 不认

$ MP4Box -cat 寻找.2004.上.mpg -cat 寻找.2004.下.mpg 寻找.2004.mp4

成功合并,bitrate 保持的很好。用mencoder也成功了,bitrate 保持的都很好:

$ mencoder 寻找.2004.上.mpg 寻找.2004.下.mpg -ovc copy -oac copy
-of mpeg -mpegopts format=mpeg1 -o out.mpg


to dvd:
$ ffmpeg -i foo.avi -target dvd out.vob

to psp:
$ ffmpeg -i foo.avi -r 29.97 -b 564k -ar 24000 -ab 64k -s 368x208 -f psp out.mp4

有时生成的文件播放时图像变窄或变宽,即 Display Aspect Ratio 失调,可以用 -aspect 指定。

从视频截取图片,1 fps:
$ ffmpeg -i foo.avi -r 1 -f image2 foo-%04d.jpeg

将一堆图片合成avi,0.5 fps: 如果图片名不规律就用mencoder
$ ls|grep .png$ >> list
$ mencoder mf://@list -mf type=png -ovc lavc -lavcopts mbd=2:trell -fps 0.5 -o out.avi

从视频中截取一段,生成 Animation gif:
$ ffmpeg -ss 00:10:00 -t 10 -i source.avi -pix_fmt rgb24 -s 360x240 out.gif

1. 合并两个rm: 只为管理方便,其它参数不动
合并成mkv,由于ffmpeg 把视频转化成 mkv 后,file 无法识别format,还是用 mkvmerge。

$ mkvmerge -i 38度線A.rmvb
File '38度線A.rmvb': container: RealMedia
Track ID 0: audio (cook)
Track ID 1: video (RV40)

$ mkvmerge 38度線A.rmvb -o 38度線A.mkv
$ mkvmerge -i 38度線A.mkv
File '38度線A.mkv': container: Matroska
Track ID 1: audio (A_REAL/COOK)
Track ID 2: video (V_REAL/RV40)

Windows下Kmplayer播放 38度線A.mkv 只有图像没有声音,mkvmerge 对 acodec cook 没处理好。
用 ffmpeg 把audio提取出来转化成mp3,然后用mkvmerge封装mp3:

$ ffmpeg -i 38度線A.rmvb -vn -acodec libmp3lame -ab 128k 38度線A.mp3
$ mkvmerge -A 38度線A.rmvb 38度線A.mp3 -o 38度線A.mkv

可以了。38度線B.rmvb -> 38度線B.mkv
$ mkvmerge 38度線A.mkv + 38度線B.mkv -o 38度線.2002.160min.mkv
$ mkvmerge -i 38度線.2002.160min.mkv
File '38度線.2002.160min.mkv': container: Matroska
Track ID 1: video (V_REAL/RV40)
Track ID 2: audio (A_MPEG/L3)

可见,acodec 变成mp3了,但 vcodec 仍是real,也就是说,要想看这个mkv文件,仍需要有real decodec。
这个例子也说明一个视频的扩展名、format只是形式,codec才是关键。


再合并两个rm: 辛亥双十.1.rmvb 辛亥双十.2.rmvb

和上面一样,先提取出mp3,再合并。但 辛亥双十.2.rmvb 质量不行,无法用 mkvmerge直接转换成mkv:

$ mkvmerge -A 辛亥双十.2.rmvb 辛亥双十.2.mp3 -o 辛亥双十.2.mkv
mkvmerge v3.3.0 ('Language') built on Mar 29 2010 18:15:52
'辛亥双十.2.rmvb': Using the RealMedia demultiplexer.
'辛亥双十.2.mp3': Using the MP2/MP3 demultiplexer.
Warning: '辛亥双十.2.mp3': Skipping 33 bytes at the beginning (no valid MP3 header found).
'辛亥双十.2.rmvb' track 1: Using the video output module (FourCC: RV40).
'辛亥双十.2.mp3' track 0: Using the MPEG audio output module.
The file '辛亥双十.2.mkv' has been opened for writing.
Warning: '辛亥双十.2.rmvb': File contains fewer frames than expected or is corrupt after frame 46566.
Progress: 100%
The cue entries (the index) are being written...
Muxing took 43 seconds.

没有转换完全,Warning 说有frame corrupt。用 ffmpeg 把vcodec转化为 mpeg4 试试:

$ ffmpeg -i 辛亥双十.2.rmvb -vcodec mpeg4 -b 600k -acodec libmp3lame -ab 96k -ac 2
-s 352x240 -r 12 辛亥双十.2.avi

转换过程中 drop 很多frame,导致生成的avi audio/video 不同步,要先做同步:
Windows 用Kmplayer 可以调整: 播放 -> 音频/视频同步 -> 重新同步音频 - 0.5 秒,试几下就行了。

mplayer -delay 也可以找到所需同步时间,一点一点尝试
$ mplayer -delay 1 辛亥双十.2.avi
$ mplayer -delay 2 辛亥双十.2.avi
$ mplayer -delay 3 辛亥双十.2.avi
......

但经过验证,-delay 的时间只是估计值,还要经过1、2秒钟的调整才行,最后找到audio需要延迟4500ms

$ sudo mkvmerge -i 辛亥双十.2.avi
File '辛亥双十.2.avi': container: AVI
Track ID 0: video (FMP4)
Track ID 1: audio (MP3)

$ mkvmerge -y 1:4500 辛亥双十.2.avi -o 辛亥双十.2.mkv

同样,辛亥双十.1.rmvb 也要转换为 MPEG-4/mp3/辛亥双十.1.avi,然后 mkvmerge 成 辛亥双十.1.mkv。

$ mkvmerge 辛亥双十.1.mkv + 辛亥双十.2.mkv -o 辛亥双十.1981.120min.mkv

合并成功了。网上有个 x264 版本,也是460MB左右,H.264 比 MPEG-4 高效,就不共享这个了。

经验就是: 压片时最好别压成 .rm .wmv,自身质量很一般,想进行合并操作太麻烦了。
即使压成 .rm,codec 也别用 RV40 + Cook,drop frame 太多了
即使压成 .wmv,codec 也别用 wmv + wma
推荐用 MPEG-4 + mp3,或者 H.264 + mp3

2. 合并7个flv: 参数类型都相同,文件很小,都在5MB左右
$ file *.flv
01.flv: Macromedia Flash Video
02.flv: Macromedia Flash Video
......
07.flv: Macromedia Flash Video

$ ffmpeg -i 01.flv
......
Duration: 00:05:53.55, start: 0.000000, bitrate: 113 kb/s
Stream #0.0: Video: h264, yuv420p, 320x240 [PAR 1:1 DAR 4:3], 49 kb/s, 18 tbr, 1k tbn, 36 tbc
Stream #0.1: Audio: aac, 22050 Hz, stereo, s16, 64 kb/s
At least one output file must be specified

cat不行,mkvmerge、MP4Box 不认,先用ffmpeg转成mp4,然后用MP4Box合并:
$ ffmpeg -i 01.flv -vcodec libx264 -vpre normal -b 49k -acodec aac -strict experimental
-ab 64k -ac 2 -ar 22050 -s 320x240 -r 18 01.mp4

$ MP4Box -cat 01.mp4 -cat 02.mp4 -cat 03.mp4 -cat 04.mp4 -cat 05.mp4 -cat 06.mp4 -cat 07.mp4 out.mp4

3. 合并两个多音轨的vob:

$ file "孙燕姿 - 遇见.vob" VTS_01_7.vob
孙燕姿 - 遇见.vob: MPEG sequence, v2, program multiplex
VTS_01_7.vob: MPEG sequence, v2, program multiplex

$ ffmpeg -i "孙燕姿 - 遇见.vob" -i VTS_01_7.vob
......
Input #0, mpeg, from '孙燕姿 - 遇见.vob':
Duration: 00:03:40.86, start: 786.008633, bitrate: 5120 kb/s
Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 4225 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x80]: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s
Stream #0.2[0x81]: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s
[mpeg2video @ 0x918c3a0]mpeg_decode_postinit() failure
[mpeg @ 0x918b070]max_analyze_duration reached
Input #1, mpeg, from 'VTS_01_7.vob':
Duration: 00:05:22.94, start: 7416.780544, bitrate: 6930 kb/s
Stream #1.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #1.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s
Stream #1.2[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s
At least one output file must be specified

两个视频vcodec都是MPEG-2,都是双音轨,acodec 都是ac3。似乎一致,看能否合并:

$ mkvmerge "孙燕姿 - 遇见.vob" + VTS_01_7.vob -o out.vob
mkvmerge v3.3.0 ('Language') built on Mar 29 2010 18:15:52
'孙燕姿 - 遇见.vob': Using the MPEG PS demultiplexer.
'VTS_01_7.vob': Using the MPEG PS demultiplexer.
'孙燕姿 - 遇见.vob' track 0: Using the MPEG-1/2 video output module.
'孙燕姿 - 遇见.vob' track 1: Using the AC3 output module.
'孙燕姿 - 遇见.vob' track 2: Using the AC3 output module.
'VTS_01_7.vob' track 0: Using the MPEG-1/2 video output module.
'VTS_01_7.vob' track 1: Using the AC3 output module.
'VTS_01_7.vob' track 2: Using the AC3 output module.
No append mapping was given for the file no. 1 ('VTS_01_7.vob'). A default mapping of 1:0:0:0,1:1:0:1,1:2:0:2 will be used instead. Please keep that in mind if mkvmerge aborts with an error message regarding invalid '--append-to' options.
Error: The track number 1 from the file 'VTS_01_7.vob' cannot be appended to the track number 1 from the file '孙燕姿 - 遇见.vob'. The track parameters do not match.

无法合并,Error 说两个视频的第一条音轨的参数不同,回头细看真是不同: 一个是 stereo,另一个是 5.1。
把 VTS_01_7.vob 的audio channel 数目降成2个再合并:

$ ffmpeg -i VTS_01_7.vob -vcodec copy -acodec ac3 -ab 384k -ar 48000 -ac 2 VTS.vob

VTS.vob 只有第一条音轨,另一条丢失。

$ mkvmerge "孙燕姿 - 遇见.vob" + VTS.vob -o final.vob

合并成功了。
$ ffmpeg -i
Duration: 00:09:04.43, start: 0.000000, bitrate: 5110 kb/s
Stream #0.0: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 4726 kb/s, 59.94 fps, 30 tbr, 1k tbn, 59.94 tbc
Stream #0.1: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s
Stream #0.2: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s
At least one output file must be specified

final.vob中,前段 "孙燕姿 - 遇见.vob" 两条音轨都有,后段 VTS.vob 也被添加了一条没有声音的新音轨。
vbitrate 取低的192k。不足之处是前段画面的长宽变化了,后段正常。看各自的 Display Aspect Ratio,
即DAR,分别是 16:9 和 4:3 ,一个视频的 aspect ratio 只有一个,只能将就点了。

若想保持 VTS_01_7.vob 的2条音轨就用map:

$ ffmpeg -i VTS_01_7.vob -map 0:0 -vcodec copy -map 0:1 -acodec ac3 -ab 384k -ar 48000 -ac 2 VTS.vob
-map 0:2 -acodec ac3 -ab 384k -ar 48000 -ac 2 -newaudio

$ ffmpeg -i VTS.vob
......
Input #0, mpeg, from 'VTS.vob':
Duration: 00:05:22.94, start: 0.500000, bitrate: 6885 kb/s
Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x80]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s
Stream #0.2[0x81]: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s
At least one output file must be specified

参数保持的很好,合并:
$ mkvmerge "孙燕姿 - 遇见.vob" + VTS.vob -o final.mkv
$ ffmpeg -i final.mkv
......
Input #0, matroska, from 'final.mkv':
Metadata:
doctype : matroska
Duration: 00:09:04.43, start: 0.000000, bitrate: 5110 kb/s
Stream #0.0: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 4726 kb/s, 59.94 fps, 30 tbr, 1k tbn, 59.94 tbc
Stream #0.1: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s
Stream #0.2: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s
At least one output file must be specified

成功了,播放正常,音轨切换也正常,想保持vob format就用mencoder。

再看一个audio:

$ file Eagles.Hotel.California.Original.1994.Live.vob
Eagles.Hotel.California.Original.1994.Live.vob: MPEG sequence, v2, program multiplex

$ ffmpeg -i Eagles.Hotel.California.Original.1994.Live.vob
......
Input #0, mpeg, from 'Eagles.Hotel.California.Original.1994.Live.vob':
Duration: 00:06:59.12, start: 666.818967, bitrate: 7584 kb/s
Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 6000 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0xa0]: Audio: pcm_s16be, 48000 Hz, 2 channels, s16, 1536 kb/s
Stream #0.2[0x8a]: Audio: dca, 48000 Hz, 5.1, s16, 1536 kb/s
Stream #0.3[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
At least one output file must be specified

第一条音轨无法播放,把后两条音轨提取出来,其中0.2显示dca的不认识,先用.wav代替:

$ ffmpeg -i Eagles.Hotel.California.Original.1994.Live.vob -vn -map 0:2 -acodec copy 02.wav
-map 0:3 -acodec copy 03.ac3

$ file 02.wav 03.ac3
02.wav: RIFF (little-endian) data, WAVE audio, 6 channels 48000 Hz
03.ac3: Sendmail frozen configuration - version \304\024\320\274*$nG\273\257\221\213\020\0256\346XQ\273

两个文件 Windows 千千都能正常播放,google 知道dca就是decoding dts 的,libdca是开源的,
$ locate libdca 可以找到 .so

发现 VTS_01_7.vob 和 Eagles.Hotel.California.Original.1994.Live.vob 都有一条 ac3 5.1 audio,
现把它们合并,最终视频只有 ac3 5.1 这一条音轨:

$ ffmpeg -i VTS_01_7.vob -i Eagles.Hotel.California.Original.1994.Live.vob
......
Input #0, mpeg, from 'VTS_01_7.vob':
Duration: 00:05:22.94, start: 7416.780544, bitrate: 6930 kb/s
Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s
Stream #0.2[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s
[mpeg @ 0x96ee4e0]max_analyze_duration reached
Input #1, mpeg, from 'Eagles.Hotel.California.Original.1994.Live.vob':
Duration: 00:06:59.12, start: 666.818967, bitrate: 7584 kb/s
Stream #1.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 6000 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #1.1[0xa0]: Audio: pcm_s16be, 48000 Hz, 2 channels, s16, 1536 kb/s
Stream #1.2[0x8a]: Audio: dca, 48000 Hz, 5.1, s16, 1536 kb/s
Stream #1.3[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
At least one output file must be specified

$ mkvmerge -i VTS_01_7.vob
File 'VTS_01_7.vob': container: MPEG 2 program stream (PS)
Track ID 0: video (MPEG-2)
Track ID 1: audio (AC3)
Track ID 2: audio (AC3)

$ mkvmerge -i Eagles.Hotel.California.Original.1994.Live.vob
File 'Eagles.Hotel.California.Original.1994.Live.vob': container: MPEG 2 program stream (PS)
Track ID 0: video (MPEG-2)
Track ID 1: audio (AC3)
Track ID 2: audio (DTS)

$ mkvmerge -a 2 VTS_01_7.vob -a 1 Eagles.Hotel.California.Original.1994.Live.vob -o out.mkv
合并失败,用 mencoder:

$ mplayer -v -novideo 找到对应的 audio number 分别为 128、129
$ mencoder VTS_01_7.vob -aid 128 Eagles.Hotel.California.Original.1994.Live.vob -aid 129
-ovc copy -oac copy -of mpeg -mpegopts format=dvd -o out.vob

合并成功,播放正常,原来两个视频的DAR就不同,所以会有一个视频长宽比例失调,可以用 -aspect 指定。
参数也正常:

$ file out.vob
out.vob: MPEG sequence, v2, program multiplex

$ ffmpeg -i out.vob
Input #0, mpeg, from 'out.vob':
Duration: 00:11:58.41, start: 0.233367, bitrate: 5201 kb/s
Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s
At least one output file must be specified

继续尝试把 ac3 5.1 和 dts 5.1 合并,没成功。对于两个不同的codec,合并不成功很正常。

4.《让子弹飞》是个双音轨的 DVD 一共7个vob,两条音轨都是国语,都有 A/V 不同步的现象,而且每个vob
A/V 不同步程度还不同,有的差1s,有的差0.5s。现在把片源 A/V 同步,都是普通话,只留一个音轨,合并
成一个普通视频文件。先分别把vob转化成mkv,然后合并:
$ mkvmerge -i VTS_01_1.VOB
Track ID 0: video (MPEG-2)
Track ID 1: audio (AC3)
Track ID 2: audio (AC3)

mplayer -delay 分别试试就可以知道延迟的秒数:
$ mplayer -delay 0.5 VTS_01_1.VOB
$ mplayer -delay 1 VTS_01_1.VOB
...

$ mkvmerge -a 1 -y 0:800 VTS_01_1.VOB -o out1.mkv
mkvmerge v3.3.0 ('Language') built on Mar 29 2010 18:15:52
'VTS_01_1.VOB': Using the MPEG PS demultiplexer.
'VTS_01_1.VOB': Processing the following files as well: VTS_01_2.VOB, VTS_01_3.VOB, VTS_01_4.VOB, VTS_01_5.VOB, VTS_01_6.VOB, VTS_01_7.VOB
'VTS_01_1.VOB' track 0: Using the MPEG-1/2 video output module.
'VTS_01_1.VOB' track 1: Using the AC3 output module.
The file 'out1.mkv' has been opened for writing.
Progress: 1%

由shell信息知道 mkvmerge 想把这7个VOB一起处理,在这是不行的,因为每个VOB A/V 延迟秒数不同,
所以先中断进程。建个文件夹,把其它6个VOB放进去,一个一个的分别处理:

$ mkvmerge -a 1 -y 0:1000 VTS_01_1.VOB -o out1.mkv

out1.mkv 比 VTS_01_1.VOB 小了30MB,小于1GB,可以分别把生成的7个mkv文件放115上给别人共享了:)
网上一个视频如果是双语的,只要不超过1030MB 就确定可以下来,只保留一条原声,转换后就小于1GB了。

其它6个VOB类似处理,每个vob的同步时间的调整都要尽量精确,因为一旦错了一个,后面的都会跟着错。可
以在处理完前3个VOB之后,合并一下看看效果,如果不行就重新调教时间,提前发现问题。依次调教的秒数:

$ mkvmerge -a 1 -y 0:300 VTS_01_2.VOB -o out2.mkv
$ mkvmerge -a 1 -y 0:300 VTS_01_3.VOB -o out3.mkv
$ mkvmerge -a 1 -y 0:300 VTS_01_4.VOB -o out4.mkv
$ mkvmerge -a 1 -y 0:100 VTS_01_5.VOB -o out5.mkv
$ mkvmerge -a 1 VTS_01_7.VOB -o out7.mkv

其中 VTS_01_6.VOB 无法处理
$ mkvmerge -a 1 -y 0:300 VTS_01_6.VOB -o out6.mkv
mkvmerge v3.3.0 ('Language') built on Mar 29 2010 18:15:52
'VTS_01_6.VOB': Using the MPEG PS demultiplexer.
'VTS_01_6.VOB' track 0: Using the MPEG-4 part 10 ES video output module.
'VTS_01_6.VOB' track 1: Using the AC3 output module.
The file 'out6.mkv' has been opened for writing.
Warning: 'VTS_01_6.VOB' track 1: This AC3 track contains 1155 bytes of non-AC3 data which were skipped. The audio/video synchronization may have been lost.
Error: 'VTS_01_6.VOB' track 0: mkvmerge encountered broken or unparsable data in this AVC/h.264 video track. Either your file is damaged (which mkvmerge cannot cope with yet) or this is a bug in mkvmerge itself. The error message was:
end-of-file

处理前5个VOB时也会有那个Warning,但是没有Error,始终能继续处理,看下 VTS_01_6.VOB 确实和别的不同:
$ mkvmerge -i VTS_01_6.VOB
File 'VTS_01_6.VOB': container: MPEG 2 program stream (PS)
Track ID 0: video (AVC/h.264)
Track ID 1: audio (AC3)
Track ID 2: audio (AC3)

video那行显示是 AVC/h.264,ffmpeg -i 显示是MPEG-2,Windows Kmplayer 也显示是 MPEG-2。
用 ffmpeg 转化成 dvd format 看能否修复这个VOB:

$ ffmpeg -i VTS_01_6.VOB
......
Input #0, mpeg, from 'VTS_01_6.VOB':
Duration: 00:20:35.93, start: 6180.812544, bitrate: 6949 kb/s
Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 32:27 DAR 16:9], 6050 kb/s, 33.01 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s
Stream #0.2[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s
......

音轨只要第一条
$ ffmpeg -i VTS_01_6.VOB -map 0:0 -map 0:1 -vcodec copy -acodec copy -target dvd mid.vob
$ mkvmerge -i mid.vob 发现没修复过来,又试几个参数都不行:

$ ffmpeg -i VTS_01_6.VOB -map 0:0 -map 0:1 -vcodec copy -acodec copy -f dvd mid.vob
$ ffmpeg -i VTS_01_6.VOB -map 0:0 -map 0:2 ......
......

只好 mencoder 试试:
$ mplayer -v -novideo VTS_01_6.VOB 找到 -aid audio number,要第一条音轨 -aid 128
$ mencoder VTS_01_6.VOB -ovc copy -oac copy -aid 128 -of mpeg -mpegopts format=dvd -o mid.vob
$ mkvmerge -i mid.vob
File 'mid.vob': container: MPEG 2 program stream (PS)
Track ID 0: video (MPEG-2)
Track ID 1: audio (AC3)

正确识别为 MPEG-2 了,ffmpeg -i 发现码率保持的也很好。

$ mkvmerge -y 0:1150 mid.vob -o out6.mkv
$ mkvmerge out1.mkv + out2.mkv + out3.mkv + out4.mkv + out5.mkv + out6.mkv + out7.mkv
-o 让子弹飞.2010.mkv

终于得到 MPEG-2 + 6 Mbps 让子弹飞.2010.mkv 了!