用批处理+FFMPEG处理保存老DV文件

十几年前用DV录了一些东西,当时把所有的Raw文件简单压成成品后,就把源文件刻了DVD保存,谁让当时硬盘空间也很宝贵呢!这十几年过去了,爸妈清理房子的时候发现了这一堆历史见证需要清理,拖着到了杭州,我又带回了广州。

看了下,当时是720p的视频,画质也一般。但想了想,还是把源文件备份到NAS上(谁让现在硬盘这么大),然后重新压制一份尽量接近原清晰度的视频吧。

原始的视频当时是用一个工具从DV录像带导出的,所以是n多个avi文件。工具选定了FFMPEG,打算直接压。但碰到了几个问题。

首先是查找FFMPEG怎样支持多源文件。文件太多几十个,全部在命令行输入不合适。找了下,https://www.google.com/search?q=ffmpeg+cancat&oq=ffmpeg+cancat&aqs=chrome..69i57j0l7.8326j0j9&sourceid=chrome&ie=UTF-8 这里有提到了办法。

ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.wav

但这里的例子是直接合并视频,我要的是输入多个avi,然后做编码。所以想试一试用这种引入外部文件列表的方法来解决输入文件的问题。

mylist.txt的文件格式如下。按照例子的建议,在Windows下可以用批处理一键生成mylist.txt。

# this is a comment
file '/path/to/file1.wav'
file '/path/to/file2.wav'
file '/path/to/file3.wav'
(for %i in (*.wav) do @echo file '%i') > mylist.txt

但生成之后呢,FFMPEG报错,说文件名不对。看来看去,原来是文件名中包含有’(单引号),不认文件。当时DV导出的软件自动加入了日期和时间。文件名都是这样的

dad'20060318 11.32.32.avi
dad'20060318 11.33.08.avi

那没办法了,只能先改文件名。那肯定得借助批处理了对吧。批处理没学过,但觉得不难。结果真写起来发现坑真的很多。。。。具体过程就不费笔墨了。参考了很多个文章之后,最终把文件名改名和FFMPEG编码加在一起写了一个批处理程序如下:

@echo off
setlocal enabledelayedexpansion 
::延迟变量。BAT文件按行之行,一次一行。不加的话变量值很可能不正确。

for /F "tokens=*" %%i in ('dir /o:n /B *.avi') do (
:: /F 是文件
:: "token=*" 是在文件名有空格时可以正常工作
:: dir /o:n 按文件名顺序,/B按简略文件名
:: 注意这里用两个百分号。命令行执行for用一个就行
echo %%i 
set o=%%i
:: 这里是坑了很久的地方。直接用%%i进行计算,变量值不更新或者取不到。于是设间接变量
set n=!o:'=_!
:: 坑的地方。原来按教程写的是n=%o:'=_%,怎么都不对,把o改成%oo或者!o!也不对。直到找到一个完整例子,看到他用的是两边的叹号。终于对了。
echo !n!
:: 延迟变量一定要用两个!!扩起来。
move "!o!" "!n!"
:: 改名命令文件名扩起来,不然文件名有空格会出错
)
(for %%i in (*.avi) do @echo file '%%i') > mylist.txt
:: FFMPEG的例子
ffmpeg -f concat -safe 0 -i mylist.txt -acodec aac -vcodec h264 output.mp4
:: 这么指定输入,然后直接编码证明是可以的。偷懒用了最简单的命令行。-safe 0如果不加的话,FFMPEG会抱文件名有隐患,不执行。
del mylist.txt

虽然花了好几个小时做这个。但现在觉得心情很舒适。一点点基础,加一点点学习,加一点点思考,解决一点点的问题。创业不都是这样的吗?

用批处理+FFMPEG处理保存老DV文件