我在 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 文件。具体来说,我有两个问题:
总之,我有一个输入文件的目录,长度在 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
非常感谢您提前。
最佳答案
制作是单行的并不能提高可读性。
所以,你正在做的是:
#!/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
s 告诉你发生了什么。至于输出文件的变量:
${file%.mp4}_1.mp4
可能会。所以,这意味着:
#!/bin/bash
for file in *.mp4; do
outputfile=${file%.mp4}_1.mp4
echo "Doing $file -> $outputfile"
# the ffmpeg command
done
关于bash - ffmpeg 从大型视频 bash 中选择子剪辑并创建输出文件名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51106599/