ffmpeg выбирает подклипы из большого видео-bash и создает имена выходных файлов - PullRequest
0 голосов
/ 29 июня 2018

Я использую команду bash на Mac Terminal. Для каждого из 250 файлов .mp4 в каталоге мне нужно создать новый выходной файл, который извлекает 4 субклипа из каждого входного файла: 1-й субклип (со второго 10 до 20), 2-й субклип (10 секунд на этапе 33% входного файла) 3-й субклип (10 секунд при 66% входного файла) и 4-й субклип (10 секунд, начинающихся за 30 секунд до конца входного файла). Каждый входной файл имеет разную длину около 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. В частности, у меня есть 2 вопроса:

  1. Приведенный выше код показывает конкретные секунды, которые я проверял вручную из файла ввода, который использовал для проверки кода. Мне нужно автоматизировать код в соответствии с указанными выше временами.
  2. Назовите выходной файл так же, как входной файл, но добавив суффикс "_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

Заранее большое спасибо.

1 Ответ

0 голосов
/ 29 июня 2018

Создание в одну строку не улучшает читаемость.

Итак, что вы делаете:

#!/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 для каждого файла в каталоге. Это, как указал Шелтер, эффективно перебирает все разные файлы. Но, поскольку вы пишете с фиксированным именем файла (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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...