Я хочу разрезать видео на 10-минутные части, как это.
ffmpeg -i video.mp4 -ss 00:00:00 -t 00:10:00 -c copy 01.mp4
ffmpeg -i video.mp4 -ss 00:10:00 -t 00:10:00 -c copy 02.mp4
ffmpeg -i video.mp4 -ss 00:20:00 -t 00:10:00 -c copy 03.mp4
С for
ним будет так.
for i in `seq 10`; do ffmpeg -i video.mp4 -ss 00:${i}0:00 -t 00:10:00 -c copy ${i].mp4; done;
Но это работает только если продолжительность меньше часа. Как преобразовать число в формат времени в оболочке bash?
решение1
BASH не так уж плох для этой проблемы. Вам просто нужно использовать очень мощную, но недоиспользуемую date
команду.
for i in {1..10}; do
hrmin=$(date -u -d@$(($i * 10 * 60)) +"%H:%M")
outfile=${hrmin/:/-}.mp4
ffmpeg -i video.mp4 -ss ${hrmin}:00 -t 00:10:00 -c copy ${outfile}
done
date
Объяснение команды
date
с -d
флагами позволяет вам установитькоторыйдата, которую вы хотите отобразить (вместо текущей даты и времени, которые являются значениями по умолчанию). В этом случае я устанавливаю время UNIX, добавляя символ @
перед целым числом. Целое число в этом случае — это время с десятиминутными приращениями (вычисляется встроенным калькулятором BASH: $((...))
).
Символ +
говорит date
о том, что вы хотите указать формат отображения результатов. В нашем случае нас интересуют только часы ( %H
) и минуты ( %M
).
И наконец, -u
is для отображения времени UTC вместо местного. Это важно в данном случае, поскольку мы указали время как UTC, когда дали ему время UNIX (время UNIX всегда как UTC). Числа, скорее всего, не будут начинаться с 0, если вы не укажете -u
.
Объяснение замены переменных в BASH
Команда date
дала нам как раз то, что нам было нужно. Но двоеточия в имени файла могут быть проблематичными/нестандартными. Поэтому мы заменяем ':' на '-'. Это можно сделать командой sed
или cut
или tr
, но поскольку это такая простая задача, зачем порождать новую подоболочку, если BASH может это сделать?
Здесь мы используем простую подстановку выражений BASH. Для этого переменная должна быть заключена в фигурные скобки ( ${hrmin}
), а затем использована стандартная нотация с косой чертой. Первая строка после первой косой черты — это шаблон поиска. Вторая строка после второй косой черты — это подстановка.
Подстановку переменных BASH и многое другое можно найти на сайтеhttp://tldp.org/LDP/abs/html/parameter-substitution.html.
решение2
Это немного сложнее, но вы можете сделать это в bash достаточно легко. Пример ниже для 2-часового видео, вы можете установить ограничения ( n<=11
) соответственно:
k=0;
i=00;
for ((n=0;n<=11;n++)); do
if [ $i -ge 60 ]; then
let k++; i=00;
fi;
ffmpeg -i video.mp4 -ss 0$k:$i:00 -t 00:10:00 -c copy $k$i.mp4;
let i+=10;
done
Вы можете увидеть, что это делает, добавив echo
к ffmpeg
строке:
echo "ffmpeg -i video.mp4 -ss 0$k:$i:00 -t 00:10:00 -c copy $k$i.mp4";
который напечатает:
ffmpeg -i video.mp4 -ss 00:00:00 -t 00:10:00 -c copy 000.mp4
ffmpeg -i video.mp4 -ss 00:10:00 -t 00:10:00 -c copy 010.mp4
ffmpeg -i video.mp4 -ss 00:20:00 -t 00:10:00 -c copy 020.mp4
ffmpeg -i video.mp4 -ss 00:30:00 -t 00:10:00 -c copy 030.mp4
ffmpeg -i video.mp4 -ss 00:40:00 -t 00:10:00 -c copy 040.mp4
ffmpeg -i video.mp4 -ss 00:50:00 -t 00:10:00 -c copy 050.mp4
ffmpeg -i video.mp4 -ss 01:00:00 -t 00:10:00 -c copy 100.mp4
ffmpeg -i video.mp4 -ss 01:10:00 -t 00:10:00 -c copy 110.mp4
ffmpeg -i video.mp4 -ss 01:20:00 -t 00:10:00 -c copy 120.mp4
ffmpeg -i video.mp4 -ss 01:30:00 -t 00:10:00 -c copy 130.mp4
ffmpeg -i video.mp4 -ss 01:40:00 -t 00:10:00 -c copy 140.mp4
ffmpeg -i video.mp4 -ss 01:50:00 -t 00:10:00 -c copy 150.mp4
решение3
Это простая математика: цифра часа — $((i%3600)
, минут — $((i/60%60))
, секунд — $((i%60))
. Чтобы добавить начальный ноль там, где это необходимо, простой трюк — добавить 100, а затем удалить начальный 1
. Сделайте то же самое с именем файла, если вы хотите избежать начальных нулей.
for i in $(seq 10); do
minutes=$((i / 60 % 60 + 100)); minutes=${minutes#1}
seconds=$((i%60)); seconds=${seconds#1}
i=$((i+100)); i=${i#1}
ffmpeg -i video.mp4 -ss $((i%3600):$minutes:$seconds -t 00:10:00 -c copy ${i}.mp4
done
решение4
Я обнаружил, что ffmpeg принимает в качестве формата временной метки не только [ЧЧ:ММ:СС], но и простые секунды.
https://trac.ffmpeg.org/wiki/Seeking%20with%20FFmpeg
Поэтому я могу написать вот так.
for i in `seq 10`; do ffmpeg -i video.mp4 -ss $((i*10*60)) -t 00:10:00 -c copy ${i].mp4; done;