Friday, February 11, 2011

Audio/Video

处理视频,Windows 下有很多图形界面的工具,由于涉及到视频、音频、字幕...参数太多,图形界面太
复杂,想告诉别人处理过程还得截图,此时 Linux commandline 的优势出来了,用起来比图形界面简单易懂。
如果不压片,只是合并、截取之类简单需求,就可以在 Linux 下处理;要压片就只好用 Windows megui:


1. K-Lite_Codec_Pack_902_Full.exe
2. Microsoft .NET Framework 3.5
3. Avisynth
4. MeGUI
5. MkvToolnix
6. tsMuxeR


区分 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)

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


H.264/MPEG-4 AVC/MPEG-4 part 10,对cpu等硬件要求较高。

DVD .vob,MPEG-2 + ac3、dts
Blu-ray Disc 蓝光盘、录制的视频,扩展名为 .ts .m2ts
iphone 能支持多种视频,支持 H.264,能看高清电影

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

还有两个format平时压片尽量别用,商业味太浓,处理起来麻烦:

.rm RV40 + cook
.wmv .asf wmv3 + wmav2


视频操作先考虑专用工具,比如 mkvtollnix, mp4box,实在不行再用 ffmpeg,以前一直用 mencoder,
后来发现ffmpeg问题少些,以后陆续转移到ffmpeg上来。但 mencoder 依旧好用,有时候 ffmpeg 无法正确
提取 audio,用 mencoder 就可以。man mencoder 很有挑战性,和 mplayer 一起,参数多,跨度大,
这个熟练后,man 什么都不怕了。

生成的视频 linux mplayer 总能很好的播放,所以一定要到Windows下去验证,最好直接mount一个NTFS,
把生成的视频直接放上面。无论什么方法,转换后的视频质量都会低于原质量。



1. 处理 mkv 用 mkvtoolnix

$ sudo yum install mkvtoolnix

生成一个mkv:

$ mkvmerge foo.avi -o out.mkv
$ file out.mkv
out.mkv: Matroska data

截取一段mkv:

$ 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

out-002.mkv 就是想要的,码率保持的很好,Linux mplayer、Windows Kmplayer 都能正常播放。目前命令行
无法直接截取第二段,windows 图形界面能够做到。可以在第二个文件split完成后手动中断 mkvmerge进程。


PBS 纪录片 《Prohibition》用 Windows kmplayer 由于库版本低无法播放,但 Linux 库版本高能播放,
mount Windows 分区,然后在 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.mkv

合并mkv:

$ mkvmerge 1.mkv + 2.mkv -o out.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)


可见,有2条音轨,3种字幕,但不知道哪个是粤语,可以用 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

压片人 Metadata 有注释,要第1条 audio Cantonese、前两个中文字幕chs cht:

$ mkvmerge -a 2 -s 4,5 花样年华.2000.98.min.mkv -o out.mkv

也可以用 $ mplayer -v -novideo 花样年华.2000.98min.mkv 找出 -aid,听听哪个是粤语:

$ mplayer -aid 0 花样年华.2000.98min.mkv
$ mplayer -aid 1 花样年华.2000.98min.mkv



去掉所有字幕:

$ mkvmerge -S 霸王别姬.1993.mkv -o 霸王别姬.1993.out.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 2:foo.aac 3:3.srt 4:4.srt 5:5.srt

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


如果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 后再放到Window上。
封装 srt 软字幕。过后还可以extract、delete。

$ 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



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


内嵌硬字幕:

$ MP4Box -add "中国残留孤儿归国记.avi" -add "中国残留孤儿归国记.srt" "中国残留孤儿归国记.mp4"


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

extract Video:

$ ffmpeg -i River.Elegy.1988.mpeg -an -vcodec copy river.avi

extract Audio:

$ ffmpeg -i River.Elegy.1988.mpeg -vn -acodec copy river.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

mp3 bitrate 不要小于64kbps,否则声音失真。

extract Video and Audio:

$ ffmpeg -ss 01:05:08 -t 600 -i in.avi -vcodec copy -acodec copy -o out.avi
$ mencoder in.avi -ovc copy -oac copy -ss 01:05:08 -endpos 600 -o out.avi


将片尾曲提取出来,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

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


电视录制的一个 .ts 视频,两条音轨,想提取其中一条。但 tsMuxer 无法识别两条音轨,
ffmpeg、megui 也都只能提取出部分,无法正常播放。用 mencoder:

$ mplayer -identify "[PTS]美味纵贯现.2013.ts" >> c
$ less c

Playing [PTS]美味纵贯现.2013.ts.

libavformat version 53.21.0 (external)
Mismatching header version 53.19.0
TS file format detected.
PROGRAM_ID=1 (0x01), PMT_PID: 2000(0x7D0)
PROGRAM_ID=1 (0x01), PMT_PID: 2000(0x7D0)
PROGRAM_ID=1 (0x01), PMT_PID: 2000(0x7D0)
PROGRAM_ID=1 (0x01), PMT_PID: 2000(0x7D0)
PROGRAM_ID=1 (0x01), PMT_PID: 2000(0x7D0)
PROGRAM_ID=1 (0x01), PMT_PID: 2000(0x7D0)
PROGRAM_ID=1 (0x01), PMT_PID: 2000(0x7D0)
PROGRAM_ID=1 (0x01), PMT_PID: 2000(0x7D0)
PROGRAM_ID=1 (0x01), PMT_PID: 2000(0x7D0)
VIDEO H264(pid=2001) AUDIO AAC LATM(pid=2003) NO SUBS (yet)! PROGRAM N. 1
ID_VIDEO_ID=2001
ID_AUDIO_ID=2003
ID_AID_2003_LANG=eng
ID_AUDIO_ID=2002
ID_AID_2002_LANG=eng
FPS seems to be: 29.970030

...

选第一条音轨,-aid 2002

$ mencoder "[PTS]美味纵贯现.2013.ts" -ovc copy -aid 2002 -oac mp3lame -lameopts cbr:br=128:aq=0:mode=2
-of rawaudio -o food.mp3


从 wmv 提取音频:

$ ffmpeg -i 打开记忆.wmv -vn -acodec copy -f asf 打开记忆.wma


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


BluRay 原盘 .ts .m2ts,在 Windows 下无法直接用 Kmplayer 观看,Linux Smplayer 虽然能看,
但是外挂字幕无法显示。

先到 Windows 下用 tsMuxerGUI.exe 把 .ts 视频和音频都提取出来,然后用 mkvmerge 合并:

原盘: [NHK][道兰]早稻田大学和北大学生之间的对话.ts

提取出来两个文件:

[NHK][道兰]早稻田大学和北大学生之间的对话.mpv
[NHK][道兰]早稻田大学和北大学生之间的对话.aac

$ mkvmerge "[NHK][道兰]早稻田大学和北大学生之间的对话.mpv" "[NHK][道兰]早稻田大学和北大学生之间的对话.aac"
-o "[NHK][道兰]早稻田大学和北大学生之间的对话.mkv"


合并视频:

先用cat,mkvmerge、mp4box,要注意的是 ffmpeg 不能合并,要用 mencoder。
合并 flv 直接用 Windows flvbind,而有些视频的参数不同,无法合并。



$ cat 1.avi 2.avi 3.avi >> 1987红楼梦.avi
$ cat 龙应台-01.mp3 龙应台-02.mp3 龙应台对话.mp3 >> 龍應台.北大.從鄉愁到美麗島.73min.24s.2010.08.01.mp3


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

$ cat 史上最牛50进球.avi 十大门将愚蠢失误.avi >> temp.avi

生成的temp.avi合并成功了,但无法前后拖动,用mencoder -forceidx 加上 idx 就好了

$ mencoder temp.avi -ovc copy -oac copy -forceidx -o out.avi
$ mencoder 寻找林昭的灵魂.2004.上.mpg 寻找林昭的灵魂.2004.下.mpg -ovc copy -oac copy
-of mpeg -mpegopts format=mpeg1 -o 寻找林昭的灵魂.2004.mpg

如果mount一个Windows NTFS,想把cat生成的文件放在Windows机器上,直接 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 或 cat 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 保持多音轨。


现在只想要第二条音轨,由于 out.vob 视频有缺陷,用 mkvmerge 会报错,用 ffmpeg 提取 video。

$ MP4Box -add out.vob out.mp4
$ MP4Box -info out.mp4
* Movie Info *

Timescale 600 - Duration 03:34:19.920
Fragmented File no - 3 track(s)
File Brand isom - version 1
Created: GMT Sat Apr 20 02:43:31 2013

File has no MPEG4 IOD/OD

Track # 1 Info - TrackID 1 - TimeScale 30000 - Duration 03:34:19.913
Media Info: Language "Undetermined" - Type "vide:mp4v" - 385412 samples
Visual Track layout: x=0 y=0 width=352 height=240
MPEG-4 Config: Visual Stream - ObjectTypeIndication 0x6a
Visual Size 352 x 240
Self-synchronized

Track # 2 Info - TrackID 2 - TimeScale 48000 - Duration 03:34:19.920
Media Info: Language "Undetermined" - Type "soun:mp4a" - 535830 samples
MPEG-4 Config: Audio Stream - ObjectTypeIndication 0x6b
MPEG-1 Audio - 2 Channel(s) - SampleRate 48000 - Layer 2
Synchronized on stream 1
Track # 3 Info - TrackID 3 - TimeScale 48000 - Duration 03:34:19.920
Media Info: Language "Undetermined" - Type "soun:mp4a" - 535830 samples
MPEG-4 Config: Audio Stream - ObjectTypeIndication 0x6b
MPEG-1 Audio - 1 Channel(s) - SampleRate 48000 - Layer 2
Synchronized on stream 1

extract audio:

$ MP4Box -raw 3 out.mp4

extract video:

$ ffmpeg -i file.mp4 -an -vcodec copy result.mp4



    西游记前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,但进程仍旧继续执行,视频转换进度在不断增加。


从视频截取图片,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


经验就是: 压片时最好别压成 .rm .wmv,自身质量一般,想进行合并操作太麻烦了。
即使压成 .rm,codec 也别用 RV40 + Cook,drop frame 太多了
尽量用 MPEG-4/x264 + ac3/aac/mp3

2.《让子弹飞》是个双音轨的 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

其它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 让子弹飞 了!

No comments:

Post a Comment