ffmpeg在10s时从视频中提取子剪辑; 30%; 60%;视频的最后30秒

时间:2018-07-01 07:40:30

标签: bash video ffmpeg mp4

我正在Mac终端上编写Bash命令。为了能够使用循环,我想提取不同输入文件.mp4视频的4个子剪辑:第一个子剪辑(从第二个10到20),第二个子剪辑(从输入文件的33%阶段开始10秒),第三个子剪辑(从输入文件的66%开始10秒)和第4个子剪辑(从输入文件结束前30秒开始10秒)。

到目前为止,我只知道如何使其以固定的时间(即秒)运行,但是这些仅对应于我的第一个视频(我有+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,所以我可以保持原样,但是对于第二个到第4个子剪辑,我需要一些公式,但是不知道哪个公式。有什么建议吗?

感谢您的时间

1 个答案:

答案 0 :(得分:0)

首先,您需要获取以秒为单位的视频时长:

DURATION=$(ffmpeg -i $file 2>&1 | grep "Duration" | awk '{print $2}' | sed 's/\..*//g' | awk '{split($1, 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方法是一个不错的方法。

您应该确保视频至少持续30秒。

现在,您可以使用适当的时间替换来启动命令了:

#!/bin/bash

for file in *.mp4
do
    DURATION=$(ffmpeg -i $file 2>&1 | grep "Duration" | awk '{print $2}' | sed 's/\..*//g' | awk '{split($1, 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