我在 Debian 服务器上有大约 300 个视频,存储方式如下:
/mediaroot/1/m32.mp4
/mediaroot/2/m421.mp4
/mediaroot/n/mx.mp4
它们都需要去隔行,我想用 FFmpeg 来做。
在另一个有用的鞋底的帮助下,我通过以下步骤达到了某种程度上可以接受的结果:
- 提取音频
转码视频,示例
ffmpeg -y -i m148.mp4 -pix_fmt yuv420p -an -pass 1 -passlogfile m148.x600.1351896878.log -an -vcodec libx264 -b:v 600k -preset medium -tune film -threads 0 m148.x600.1351896878.mp4 ffmpeg -y -i m148.mp4 -pix_fmt yuv420p -an -pass 2 -passlogfile m148.x600.1351896878.log -an -vcodec libx264 -b:v 600k -preset medium -tune film -threads 0 m148.x600.1351896878.video.mp4
将新视频与步骤 1 中提取的音频混合在一起。
使用 qt-faststart 移动原子
ffmpeg/qt-faststart m148.x600.1351896878.mp4 m148.x600.1351896878.atom.mp4
我的问题是:如何让它自动去隔行并替换所有视频?
答案1
要去隔行,请使用YADIF过滤器。只需-filter:v yadif
在命令行中的某位后面添加即可-i input.mp4
。
您不需要提取音频然后重新复用。如果您通过添加-acodec copy
到编码命令中提出要求,FFMPEG 愿意将源音频从输入流复制到输出。同样,它需要出现在-i input.mp4
选项之后,也许-f container
也出现在选项之后。我倾向于将其放在所有视频选项之后,这只是个人风格的问题。
至于替换输入文件,这一点应该很清楚:您编码到临时输出文件,然后如果成功,您的脚本会显示类似mv /tmp/whatever.mp4 input.mp4
.
答案2
编写一个简单的 shell 脚本 - 您基本上已经完成了所有操作,只需将它们放在“一个屋檐下”(在一个脚本文件中)即可。
#!/bin/bash
# loop over all arguments to the script - place each single
# one into variable f (further referenced to by $f) and execute
# the commands in the loop
for f in "$@"; do
# create new variable holding filename without the extension
n=${m%.mp4}
# commands you mentioned above go here, you only need to
# replace the strings that correspond to actual filename
# with "$f" or "$n". Use the quotes around in case your
# filenames contained spaces. e.g.:
ffmpeg -y -i "$f" -pix_fmt yuv420p -an -pass 1 -passlogfile "$n".x600.1351896878.log -an -vcodec libx264 -b:v 600k -preset medium -tune film -threads 0 "$n".x600.1351896878.mp4
ffmpeg -y -i "$f" -pix_fmt yuv420p -an -pass 2 -passlogfile "$n".x600.1351896878.log -an -vcodec libx264 -b:v 600k -preset medium -tune film -threads 0 "$n".x600.1351896878.video.mp4
# more commands...
done
然后使用要转换的文件名作为参数运行脚本:
script.sh file1.mp4 /another/directory/file2/mp4 ...
您需要使其可执行:chmod a+x script.sh
或通过 shell 解释器显式运行它:bash script.sh ...