![Скрипт для нарезки видео на основе списка редактирования](https://rvso.com/image/1313321/%D0%A1%D0%BA%D1%80%D0%B8%D0%BF%D1%82%20%D0%B4%D0%BB%D1%8F%20%D0%BD%D0%B0%D1%80%D0%B5%D0%B7%D0%BA%D0%B8%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D0%BD%D0%B0%20%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%B5%20%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%20%D1%80%D0%B5%D0%B4%D0%B0%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F.png)
У меня есть куча видеозаписей игр моей футбольной команды за сезон, и я поручил каждому из своих товарищей по команде посмотреть одну игру и записать временные интервалы, в которые происходили наиболее яркие моменты.
Теперь вместо того, чтобы вырезать все это вручную, я хочу написать скрипт, который сделает это за меня. Я знаком с shell-скриптингом, python и ruby.
Кто-нибудь из вас знает хорошие инструменты для редактирования видео, которые могут помочь автоматизировать эту задачу? Я надеялся, что смогу поместить интервалы в простой входной файл, который мои товарищи по команде смогут использовать.
решение1
Для этого вам понадобится FFmpeg (скачатьстатическая сборка) и Баш.
Создайте список точек входа и выхода в формате CSV, например:
00:01:00,00:02:00
00:03:00,00:03:02
…
Затем вы можете запустить следующий Bash-скрипт, чтобы разрезать видео на отдельные части:
#!/usr/bin/env bash
if [[ $# -ne 2 ]]; then
echo "Usage: $0 <input> <editList>"
exit 1
fi
inputFile=$1
editFile=$2
inputFileBase="${inputFile%.*}"
extension="${inputFile##*.}"
cnt=0
while IFS=, read -r start end; do
suffix="$(printf "%05d" $cnt)"
outfile="${inputFileBase}-${suffix}.${extension}"
ffmpeg -nostdin -ss "$start" -i "$inputFile" -to "$end" -c copy -map 0 "$outfile"
cnt=$((cnt+1))
done < "$editFile"
Сохраните этот файл как cut.sh
(или как-то похоже), затем запустите:
chmod +x cut.sh
./cut.sh /path/to/input.mp4 /path/to/editList.csv
Он скопирует видео- и аудиопотоки в выходные файлы, последовательно пронумерованные с суффиксом 00001
и 00002
т. д.
Старый ответ ниже…
Я когда-то написал скрипт Ruby, который делает именно это. Вам нужен Ruby ≥1.9.2 (например, черезРВМ) и последняя версияFFmpegустановлен (см.здесьо том, как установить из исходного кода).
Мой скрипт доступен здесь:
video-extract.rb
Вам необходимо предоставить ему список входных данных в формате CSV с правками, содержащий, что наиболее важно, следующие столбцы:
- префикс (может быть пустым)
- идентификатор видео (какой-то порядковый номер)
- имя входного файла
- точка входа в
HH:MM:SS.ms
или секунд - длина редактирования в
HH:MM:SS.ms
секундах
Например (обратите внимание, что Out
столбец не используется):
- Затем настройте переменные в заголовке скрипта. Самое главное, измените
COPY
наtrue
, если вы хотите получить копию потока битов и не перекодировать. Также измените индекс столбцов CSV и разделитель CSV.
Не стесняйтесь улучшать скрипт или предлагать изменения (особенно если вы уже знаете Ruby). Я использовал этот скрипт очень часто и пока не сталкивался с проблемами. Единственное, чего не хватает, так это надлежащей поддержки звука — он просто копирует аудиопоток, что может сработать или не сработать в вашем случае. В случае проблем сообщите об этом.
Если вам нужно рассчитать разницу между точкой входа и точкой выхода, вы можете сделать это с помощью этого небольшого скрипта Ruby, основанного наэтот Stack Overflow Вопросы и ответы:
require "Time"
def time_diff(time1_str, time2_str)
t = Time.at( Time.parse(time2_str) - Time.parse(time1_str) )
(t - t.gmt_offset).strftime("%H:%M:%S.%L")
end
ins, outs, diffs = File.open("ins.txt"), File.open("outs.txt"), File.new("diffs.txt", "w")
inlines, outlines = [], []
ins.each { |l| inlines << l }
outs.each { |l| outlines << l }
inlines.zip(outlines).each { |ins, outs| diffs.puts time_diff(ins, outs) }
diffs.close
Вы просто создаете файл с именем ins.txt
и outs.txt
где каждая строка соответствует точке входа и выхода (см. скриншот выше). Разница будет записана в diffs.txt
. Вот и все.
решение2
MEncoder — ваш друг. Это отличный инструмент для скриптовых операций с видео. Я часто использую его для создания видеофайлов из отдельных кадров.
Я нашел этот скрипт на Perl, который может сделать именно то, что вам нужно:Video Cutter V2: Нарезка видео с помощью Mencoder
решение3
Пытатьсяffmpeg.
Например:
ffmpeg -i original.mpg -ss 20 -t 30 newmovie.mpg
Откроется исходный видеофайл ( -i original.mpg
), пропустит первые 20 секунд ( -ss 20
), а затем сохранит 30 секунд ( -t 30
) в новый фильм под названиемnewmovie.mpg