我在Mac终端上使用bash命令。对于目录中的250个.mp4文件中的每个文件,我需要创建一个新的输出文件,该文件从每个输入文件中提取4个子剪辑:第一个子剪辑(从第二个10到20),第二个子剪辑(在输入文件的33%阶段为10秒) ,第3个子剪辑(在输入文件的66%处为10秒)和第4个子剪辑(在输入文件结束前30秒开始为10秒)。每个输入文件的长度大约为10-15分钟。
我尝试了一个输入文件,以下bash脚本有效:
#!/bin/bash
for file in *.mp4; do ffmpeg -i "$file" -vf "select='between(t, 10, 20) + between(t, 197, 207) + between(t, 393, 403) + between(t, 570,580)',
setpts=N/FRAME_RATE/TB" -qscale 0 -af "aselect='between(t, 10, 20) +
between(t, 197, 207) + between(t, 393, 403) + between(t, 570, 580)',
asetpts=N/SR/TB" outputfile.mp4; done
但是,我不知道如何在250个mp4文件中循环播放。具体来说,我有2个问题:
总而言之,我有一个目录,其中输入文件的长度在10-15分钟之间:
inputfile1.mp4
inputfile2.mp4
inputfile3.mp4
.......
inputfile250.mp4
我想将输入文件和输出文件放在同一目录:
inputfile1.mp4
inputfile1_1.mp4 #this is 40 seconds long
inputfile2.mp4
inputfile2_1.mp4 #this is 40 seconds long
inputfile3.mp4
inputfile3_1.mp4 #this is 40 seconds long
.......
inputfile250.mp4
inputfile250_1.mp4 #this is 40 seconds long
非常感谢您。
答案 0 :(得分:0)
单线执行不会提高可读性。
所以,您正在做的是:
#!/bin/bash
for file in *.mp4; do
ffmpeg -i "$file" \
-vf "select='between(t, 10, 20) \
+ between(t, 197, 207) + between(t, 393, 403) \
+ between(t, 570,580)', \
setpts=N/FRAME_RATE/TB" \
-qscale 0 \
-af "aselect='between(t, 10, 20) \
+ between(t, 197, 207) \
+ between(t, 393, 403) \
+ between(t, 570, 580)', \
asetpts=N/SR/TB" \
outputfile.mp4
done
要详细介绍:
for file in *.mp4; do
这意味着,您将对目录中的每个文件执行ffmpeg
。正如Shelter指出的那样,这有效地循环了所有不同的文件。但是,由于您正在写入固定的文件名(outputfile.mp4
),因此仅保留一个输出文件:循环中最后一个mp4的简化版本。
因此,如果将输出写入不同的文件,则会看到实际上ffmpeg
对所有输入文件都已执行。
如果不确定循环,请尝试插入echo
来告诉您发生了什么情况。
关于输出文件的变量:${file%.mp4}_1.mp4
可能会做。
所以,这意味着:
#!/bin/bash
for file in *.mp4; do
outputfile=${file%.mp4}_1.mp4
echo "Doing $file -> $outputfile"
# the ffmpeg command
done