Замена кадров по образцу в видео (ffmpeg)

Материал из rrv-wiki
Перейти к навигации Перейти к поиску


=Скрипт для ffmpeg

#!/bin/bash

# Скрипт ищет файлы кадры по образцу и накладывает на них картинку.
# Требовалось закрыть часть одного из планов в видео, т.к. там появился лишний предмет
# В целом слегка модифицировав скрипт, можно заменять черные кадры     

# Исходный видео файл
FILE="./2021-12-22_08-10-14.mp4"

# Образец
TEMPLATE_FILE="out0030.jpg"

# Кадр наложения
OVER_FILE="out0031.png"

# Лог файл
LOGFILE="./file.log"

# Обработанный файл
OUTFILE="./out.mp4"

# Подготовка
# Тут мы сравниваем часть кадра с такой же частью образца (там неподвижная часть фона, вам придется задать свои координаты)
# Кадры которые совпадают с образцом записываются в лог файл
# blackframe=80:32 определяет точность совпадения, с этим параметром можно поиграться
# Можно так же создать видео файл (не null) и посмотреть результат, совпадающие кадры должны быть черными
ffmpeg -i ${FILE} -i ${TEMPLATE_FILE} -filter_complex "[0:v]crop=400:175:120:750[a];[1:v]crop=400:175:120:750[b];[a][b]blend=difference,blackframe=80:32" -v info -f null - 2>${LOGFILE}

# Создание шаблона замены
# Обрабатываем лог файл, находим номера начала и окончания совпадающих кадров 
# и создаем файл фильтра для ffmpeg с диапазонами в которых требуется наложить изображение на видео
# цикл от 1 до 60 требуется для того, что бы отфильтровать пропуски, когда один или несколько кадров (до 60 ) определился как не совпадающий, т.к.
# В этом видео сцены меняются не реже чем раз в 7 сек, а в секунду проходит 25 кадров. В общем с этим параметром надо поиграть.
cat ${LOGFILE} \
| grep "^\[Parsed_blackf" \
| awk '{print $4}' \
| awk 'BEGIN{FS=":"; getline; k=$2; j=k;printf("[0:v][1:v]overlay=0:0:enable=")}{ f=0; for (i = 1; i < 60; i++){if (j + i ==$2){f=1; break;}}; if (f == 1){j=j+1}else{printf("between(n\\,"k"\\,"j")+"); k=$2-1; j=k}}END{print("between(n\\,"k"\\,"j")");}' \
> filter_complex.txt

# Замена файлов
# тут выполняется замена в соответствии со скриптом фильтра (./filter_complex.txt)
ffmpeg -i ${FILE} -i ${OVER_FILE} -filter_complex_script ./filter_complex.txt ${OUTFILE}