ffmpeg 以 10 秒的速度从视频中提取子剪辑; 30%; 60%;视频的最后 30 秒
ffmpeg extract subclips from video at 10s; 30%; 60%; last 30s of a video
我正在 Mac 终端上编写 Bash 命令。为了能够使用循环,我想提取不同输入文件 .mp4 视频的 4 个子剪辑:第一个子剪辑(从第二个 10 到第二个 20)、第二个子剪辑(从输入文件的 33% 阶段开始的 10 秒)、第三个子剪辑(10 秒,从输入文件的 66% 处开始),以及第 4 个子剪辑(10 秒,从输入文件结束前 30 秒开始)。
到目前为止,我只知道如何让它在固定时间(即秒)下工作,但这些仅对应于我的第一个视频(我有 +200):
#!/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" ${file%.mp4}_1.mp4; done
对于第一个子剪辑,我总是想要从第二个 10 到 20,所以我可以保持原样,但是对于第二个到第四个子剪辑,我需要一些公式,但不知道是哪些。有什么建议吗?
感谢您的宝贵时间
首先你需要获取视频时长(以秒为单位):
DURATION=$(ffmpeg -i $file 2>&1 | grep "Duration" | awk '{print }' | sed 's/\..*//g' | awk '{split(, a, ":"); print 3600*a[1] + 60*a[2] + a[3]}')
在此命令中,您查询 ffmpeg 的视频持续时间并通过搜索 "Duration" 关键字(grep)解析结果,获取时间字段(awk),丢弃厘秒(sed)并解析将 H:M:S 字符串转换为秒数 (awk)。
然后,您可以计算所需的间隔:
START1=10
END1=20
START2=$(($DURATION*33/100))
END2=$(($START2+10))
START3=$(($DURATION*66/100))
END3=$(($START3+10))
START4=$(($DURATION-30))
END4=$(($START4+10))
你需要完整的秒数,所以使用 bash 方法 returns 整数是一个很好的方法。
您应该确保您的视频至少持续 30 秒。
现在,您可以使用适当的时间替换来启动您的命令:
#!/bin/bash
for file in *.mp4
do
DURATION=$(ffmpeg -i $file 2>&1 | grep "Duration" | awk '{print }' | sed 's/\..*//g' | awk '{split(, a, ":"); print 3600*a[1] + 60*a[2] + a[3]}')
START1=10
END1=20
START2=$(($DURATION*33/100))
END2=$(($START2+10))
START3=$(($DURATION*66/100))
END3=$(($START3+10))
START4=$(($DURATION-30))
END4=$(($START4+10))
ffmpeg -i "$file" -vf "select='between(t, $START1, $END1) + between(t, $START2, $END2) + between(t, $START3, $END3) + between(t, $START4, $END4)', setpts=N/FRAME_RATE/TB" -qscale 0 -af "aselect='between(t, $START1, $END1) + between(t, $START2, $END2) + between(t, $START3, $END3) + between(t, $START4, $END4)', asetpts=N/SR/TB" ${file%.mp4}_1.mp4
done
我正在 Mac 终端上编写 Bash 命令。为了能够使用循环,我想提取不同输入文件 .mp4 视频的 4 个子剪辑:第一个子剪辑(从第二个 10 到第二个 20)、第二个子剪辑(从输入文件的 33% 阶段开始的 10 秒)、第三个子剪辑(10 秒,从输入文件的 66% 处开始),以及第 4 个子剪辑(10 秒,从输入文件结束前 30 秒开始)。
到目前为止,我只知道如何让它在固定时间(即秒)下工作,但这些仅对应于我的第一个视频(我有 +200):
#!/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" ${file%.mp4}_1.mp4; done
对于第一个子剪辑,我总是想要从第二个 10 到 20,所以我可以保持原样,但是对于第二个到第四个子剪辑,我需要一些公式,但不知道是哪些。有什么建议吗?
感谢您的宝贵时间
首先你需要获取视频时长(以秒为单位):
DURATION=$(ffmpeg -i $file 2>&1 | grep "Duration" | awk '{print }' | sed 's/\..*//g' | awk '{split(, a, ":"); print 3600*a[1] + 60*a[2] + a[3]}')
在此命令中,您查询 ffmpeg 的视频持续时间并通过搜索 "Duration" 关键字(grep)解析结果,获取时间字段(awk),丢弃厘秒(sed)并解析将 H:M:S 字符串转换为秒数 (awk)。
然后,您可以计算所需的间隔:
START1=10
END1=20
START2=$(($DURATION*33/100))
END2=$(($START2+10))
START3=$(($DURATION*66/100))
END3=$(($START3+10))
START4=$(($DURATION-30))
END4=$(($START4+10))
你需要完整的秒数,所以使用 bash 方法 returns 整数是一个很好的方法。
您应该确保您的视频至少持续 30 秒。
现在,您可以使用适当的时间替换来启动您的命令:
#!/bin/bash
for file in *.mp4
do
DURATION=$(ffmpeg -i $file 2>&1 | grep "Duration" | awk '{print }' | sed 's/\..*//g' | awk '{split(, a, ":"); print 3600*a[1] + 60*a[2] + a[3]}')
START1=10
END1=20
START2=$(($DURATION*33/100))
END2=$(($START2+10))
START3=$(($DURATION*66/100))
END3=$(($START3+10))
START4=$(($DURATION-30))
END4=$(($START4+10))
ffmpeg -i "$file" -vf "select='between(t, $START1, $END1) + between(t, $START2, $END2) + between(t, $START3, $END3) + between(t, $START4, $END4)', setpts=N/FRAME_RATE/TB" -qscale 0 -af "aselect='between(t, $START1, $END1) + between(t, $START2, $END2) + between(t, $START3, $END3) + between(t, $START4, $END4)', asetpts=N/SR/TB" ${file%.mp4}_1.mp4
done