最近打算把我电脑上的一些视频文件转换成x264格式的mp4,从而实现和平板&电脑间的共享。由于WinMEncoder对高清视频有些力不从心,便用MeGui实现视频转换。MeGui本身还算比较容易上手,但是它有一个问题,那就是无法像WinMencoder那样根据设置的规则实现批量转换,需要对每一个文件进行设置,如果文件较多便会觉得很累,容易出错。
MeGui本身就是一个Gui,具体转换的工作还是靠外部程序实现的,它主要是生成外部命令行所需要的参数。而其中参数主要有两种——avs脚本和命令行参数。对于那些转换视频的老手来说,自然可以手动编写avs脚本,并手动配置相应命令行参数,写一个批处理文件即可实现批量转换,但对于我这种门外汉来说几乎是不可能任务。我的实现方案是:
PS:本文只是给了一个通用的方案,使用该方案也需要较强的动手能力和一定的编程经验。由于转换任务配置有很大差异,我这里并没有给出一个可以直接使用的傻瓜程序,请不要留言索求程序,具体根据自己的配置参数来实现。
由于视频文件较大,这里我用网上下的一个flv短片演示这一过程。
转换完后,可以通过Job项查看该转换过程结果了哪几步,
这里由于我是采用的二次编码,因此有两次视频转换,其总共分四步:
Job项写得比较简单,从中我们看不出具体的调用了那些外部程序,参数是啥,详细信息需要进一步查看日志:
下面我们来一一分析这些过程,并将其转换为命令行。
第一步:分离出音频文件
其中高亮部分表示的是通过R:\1\MeGUI\tools\eac3to\neroAacEnc.exe -ignorelength -q 0.5 -if - -of "R:\2\3.m4a"命令,分离出"3.m4a"音频文件。
NeroAAC的参数说明可以参考这个地址:http://wiki.hydrogenaudio.org/index.php?title=NeroAAC。 它的输入参数是一个wav格式文件,当输入为-的时候表示stdin中获取。从这里的参数来看是通过stdin中获取wav数据的。从日志中我们无法看出是如何将视频格式转换为wav并输出到stdin中共neroaac调用的,但能发现图中所示的一个脚本:
LoadPlugin("R:\1\MeGUI\tools\ffms\ffms2.dll")
FFAudioSource("R:\2\3.flv")
Normalize()
return last
这个脚本的功能就是将音频信息转换为wav格式,如何执行的这个脚本,在日志中并没有找到相应的外挂命令行,可能是MeGUI自己的内部实现,不过可以通过dshow2wav.exe(在http://sourceforge.net/projects/direct264/下载)来实现,它的命令格式如下:dshow2wav.exe "audio.avs"(PS:不要单独在控制台执行这个命令,大量非法输出会把控制台挂死)其中它的输入参数"audio.avs"就是我将前面的脚本保存成的avs文件。
综上所述,最终的组合命令如下:
dshow2wav.exe "audio.avs" | R:\1\MeGUI\tools\eac3to\neroAacEnc.exe -ignorelength -q 0.5 -if - -of "R:\2\3.m4a"
执行完这个命令行,就可以获取音频文件"3.m4a"了。
注: 有时dshow2wav.exe无法正确解析出wav文件来,这时可以试一下wavi这个程序,不过它不支持输出到stdout,需要中间有个临时wav文件。不过这个程序是开源的,有空的话我改一下这个程序。
第二步:第一次视频转换
从它的日志类型-任务命令行(前面的那个转换音频的日志类型是CommandLine,表示是一个组合的命令行),这一步命令行化就比较简单了,直接将它的命令行执行输出即可:
"R:\1\MeGUI\tools\x264\avs4x264mod.exe" --tune animation --pass 1 --bitrate 1000 --stats "R:\2\3.stats" --keyint 150 --sar 1:1 --output NUL "R:\2\3.avs"
这里有一个avs脚本作为输入参数,它是MeGUI自动生成的,内容如下:
DirectShowSource("R:\2\3.flv", fps=15.000, audio=false, convertfps=true).AssumeFPS(15.000)
#deinterlace
#crop
#resize
#denoise
ConvertToYV12()
第三步:第二次视频转换
这一步也是直接执行命令行:
"R:\1\MeGUI\tools\x264\avs4x264mod.exe" --tune animation --pass 2 --bitrate 1000 --stats "R:\2\3.stats" --keyint 150 --sar 1:1 --output "R:\2\3.264" "R:\2\3.avs"
这个里面的输入脚本和前面一样,就不多介绍了。执行完这一步后,就生成了视频文件"3.avs"。
第四步:混流
这一步也是直接执行命令行:
"R:\1\MeGUI\tools\mp4box\mp4box.exe" -add "R:\2\3.264:fps=15" -add "R:\2\3.m4a#trackID=1" -tmp "R:\\2" -new "R:\2\3-混合文件.mp4"
执行这个命令行后,就生成了我们要的mp4文件了。
综合:
最后把这四步综合起来,形成一个批处理文件:
R:\1\direct264\dshow2wav.exe "audio.avs" | R:\1\MeGUI\tools\eac3to\neroAacEnc.exe -ignorelength -q 0.5 -if - -of "R:\2\3.m4a"
"R:\1\MeGUI\tools\x264\avs4x264mod.exe" --tune animation --pass 1 --bitrate 1000 --stats "R:\2\3.stats" --keyint 150 --sar 1:1 --output NUL "R:\2\3.avs"
"R:\1\MeGUI\tools\x264\avs4x264mod.exe" --tune animation --pass 2 --bitrate 1000 --stats "R:\2\3.stats" --keyint 150 --sar 1:1 --output "R:\2\3.264" "R:\2\3.avs"
"R:\1\MeGUI\tools\mp4box\mp4box.exe" -add "R:\2\3.264:fps=15" -add "R:\2\3.m4a#trackID=1" -tmp "R:\\2" -new "R:\2\3-混合文件.mp4"
del *.stats
del *.m4a
del *.ffindex
del *.264
del *.mbtree
PS: 由于删除临时文件的命令行在日志中找不到,这里是我根据我的命令的输出加入的,根据命令不同,输出的临时文件也会有所不同。
其中用到了两个输入脚本audio.avs和3.avs,这些都是MeGui创建的:
Auido.avs
LoadPlugin("R:\1\MeGUI\tools\ffms\ffms2.dll")
FFAudioSource("R:\2\3.flv")
Normalize()
return last
3.avs
DirectShowSource("R:\2\3.flv", fps=15.000, audio=false, convertfps=true).AssumeFPS(15.000)
#deinterlace
#crop
#resize
#denoise
ConvertToYV12()
到了这一步后,我们已经成功实现纯命令行转换视频了,直接执行这个批处理文件就可以获取转换后的mp4文件了。下一步就是把这些命令行应用到其它视频文件中,以实现批量转换的目的。
我的批量转换方式实现比较简单:写了一个程序导入所有待转换的文件,然后每次转换前直接把输入和输出文件(上面脚本中标红的部分)的命令行在bat和avs脚本中替换,调用bat文件获取转换输出。
由于转换任务配置有很大差异,所以我这里的分析过程还是手动完成的,因此并不能给出一个通用的批量转换。实际上,如果能实现一个智能分析日志的的功能,把我这里的分析过程自动化,是可以实现直接根据MeGui日志自动批量转换的。我最开始本打算实现一下的,后来发现如果要弄一个比较完善的版本还有些工作量,就没弄了,等闲下来时再看看。