ffmpeg从大型视频bash中选择子剪辑并创建输出文件名

ffmpeg从大型视频bash中选择子剪辑并创建输出文件名,bash,video,ffmpeg,Bash,Video,Ffmpeg,我正在Mac终端上使用bash命令。对于目录中的每个250.mp4文件,我需要创建一个新的输出文件,从每个输入文件中提取4个子唇:第一个子唇(从第二个10到20)、第二个子唇(在输入文件的33%阶段为10秒)、第三个子唇(在输入文件的66%阶段为10秒)和第四个子唇(输入文件结束前30秒开始的10秒)。每个输入文件的长度不同,约为10-15分钟 我尝试使用一个inputfile,以下bash脚本可以工作: #!/bin/bash for file in *.mp4; do ffmpeg -i "

我正在Mac终端上使用bash命令。对于目录中的每个250.mp4文件,我需要创建一个新的输出文件,从每个输入文件中提取4个子唇:第一个子唇(从第二个10到20)、第二个子唇(在输入文件的33%阶段为10秒)、第三个子唇(在输入文件的66%阶段为10秒)和第四个子唇(输入文件结束前30秒开始的10秒)。每个输入文件的长度不同,约为10-15分钟

我尝试使用一个inputfile,以下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文件上循环。具体来说,我有两个问题:

  • 上面的代码显示了我从用于测试代码的输入文件中手动检查的特定秒数。我需要根据上面的计时自动执行代码
  • 将输出文件命名为与输入文件相同的名称,但添加“\u 1”后缀
  • 总之,我有一个输入文件长度在10-15分钟之间的目录:

    inputfile1.mp4
    inputfile2.mp4
    inputfile3.mp4
    .......
    inputfile250.mp4
    
    我想要相同的目录,同时包含inputfiles和outputfiles:

    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
    。正如Header所指出的,这将有效地在所有不同的文件上循环。但是,由于您正在写入固定的文件名(
    outputfile.mp4
    ),因此只剩下一个outputfile:循环中最后一个mp4的缩短版本

    因此,如果您将输出写入不同的文件,您将看到,实际上,对所有输入文件执行
    ffmpeg

    如果不确定循环,请尝试插入
    echo
    s来告诉您发生了什么

    至于输出文件的变量:
    ${file%.mp4}\u 1.mp4
    可能就可以了

    因此,这意味着:

    #!/bin/bash
    for file in *.mp4; do
        outputfile=${file%.mp4}_1.mp4
        echo "Doing $file -> $outputfile"
        # the ffmpeg command
    done
    

    “我不知道如何在250个mp4文件上循环。你认为文件*.mp4的
    在做什么?也许你需要
    cd/path/to/mp4Files/
    在脚本的顶部?“我希望输入文件和输出文件在同一个目录下”。将新文件保存到工作目录,然后在for循环完成后将其移回主目录。顺便说一句,非常好地使用了
    ffmpeg
    选项。祝你好运。谢谢@Ljm!是的,我知道循环的作用。我的问题有两个:秒问题,尚未解决,以及输出文件名,已解决!再次感谢。让我们看看如果其他用户能给我一些关于秒数问题的提示