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

标签 bash video ffmpeg

我在 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 文件。具体来说,我有两个问题:
  • 上面的代码显示了我从用于测试代码的输入文件中手动检查的特定秒数。我需要根据上面的时间自动化代码。
  • 将输出文件命名为与输入文件相同,但添加“_1”后缀

  • 总之,我有一个输入文件的目录,长度在 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/

    相关文章:

    linux - Bash 脚本缺少 ']' 错误

    python - 如何通过python命令使用python2.7?

    python - 在opencv + python中处理帧时实时流被延迟

    php - 为什么我不能在 MAMP 环境中使用 shell_exec 执行 ffmpeg?

    node.js - 如何使用 Node fluent-ffmpeg 向视频添加音频?

    ffmpeg - 转换 Chrome 生成的 webm 视频很慢

    Bash - 为什么这种情况没有做我认为应该做的事情?

    bash - 使用--line-buffer选项时,gnu并行抑制ssh和scp的输出

    video - 获取生成缩略图的第二个

    ios - 从服务器视频 url swift 中提取缩略图