Как зациклить видео с плавным переходом
Разработал инструкцию по тому, как делать бесшовные зацикленные видео с мягким переходом звука и изображения при помощи инструмента ffmpeg
1. Такие видео подходят для коротких видеороликов (shorts) и анимированных фонов для веб-сайтов.
Отдельно, можно ознакомиться с примером зацикленного видео, полученного в результате применения инструкции.
Инструкция
Для удобства будем использовать операционную систему Linux, но данная схема работает и в других операционных системах (Microsoft Windows, MacOS) для которых есть дистрибутив2 ffmpeg
.
При помощи фильтра volumedetect
определяем максимальную громкость видео для последующей корректировки звука.
ffmpeg -i input.mp4 -af "volumedetect" -vn -sn -dn -f null /dev/null
Вывод на экран.
...
[Parsed_volumedetect_0 @ 0x61f1feced740] max_volume: -27.6 dB
...
Где,
input.mp4
- исходный видеофайл;max_volume: -27.6 dB
- максимальная громкость в децибелах.
Создаём bash-скрипт loop_video.sh
с правом на запуск chmod +x loop_video.sh
.
loop_video.sh
# ./loop_video.sh 5 27.6 input_video.mp4 output_video.mp4
FADE_DURATION_IN_SECONDS=$1
INCREASE_BY_DB=$2
INPUT_VIDEO=$3
OUTPUT_VIDEO=$4
echo "Fade duration in seconds: $FADE_DURATION_IN_SECONDS"
echo "Increase by dB: $INCREASE_BY_DB"
echo "Input video: $INPUT_VIDEO"
echo "Output video: $OUTPUT_VIDEO"
DURATION_IN_SECONDS=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $INPUT_VIDEO)
DURATION_WITHOUT_FADE_DURATION_IN_SECONDS=$(echo "$DURATION_IN_SECONDS-$FADE_DURATION_IN_SECONDS" | bc)
DELAYS_IN_SECONDS=$(echo "$DURATION_IN_SECONDS-$FADE_DURATION_IN_SECONDS-$FADE_DURATION_IN_SECONDS" | bc)
DELAYS_IN_MS=$(echo "$DELAYS_IN_SECONDS*1000" | bc)
ffmpeg \
-i $INPUT_VIDEO \
-filter_complex \
"[0:v]fade=type=in:alpha=1:duration=$FADE_DURATION_IN_SECONDS[v]; \
[v]fade=type=out:alpha=1:start_time=$DURATION_WITHOUT_FADE_DURATION_IN_SECONDS:duration=$FADE_DURATION_IN_SECONDS[v]; \
[v]trim=start=0:duration=$FADE_DURATION_IN_SECONDS[v1]; \
[v]trim=start=$FADE_DURATION_IN_SECONDS:duration=32767[v2]; \
[v1]setpts=PTS-STARTPTS+(($DELAYS_IN_SECONDS)/TB)[v1]; \
[v2]setpts=PTS-STARTPTS-(0/TB)[v2]; \
[v2][v1]overlay[vout]; \
[0:a]atrim=start=0:duration=$FADE_DURATION_IN_SECONDS[a1]; \
[a1]afade=type=in:duration=$FADE_DURATION_IN_SECONDS[a1]; \
[0:a]atrim=start=$FADE_DURATION_IN_SECONDS:duration=32767[a2]; \
[a2]afade=type=out:start_time=$DURATION_WITHOUT_FADE_DURATION_IN_SECONDS:duration=$FADE_DURATION_IN_SECONDS[a2]; \
[a1]adelay=delays=$DELAYS_IN_MS:all=1[a1]; \
[a2]asetpts=PTS-STARTPTS-(0/TB)[a2]; \
[a2][a1]amix=dropout_transition=0:normalize=0[aout]; \
[aout]volume=${INCREASE_BY_DB}dB[aout]" \
-map [vout] \
-map [aout] \
$OUTPUT_VIDEO
Запустив скрипт, конвертируем обычного видео в зацикленное.
./loop_video.sh 5 27.6 input.mp4 output.mp4
Где,
5
- время плавного перехода в секундах между концом и началом видео;27.6
- величина усиления громкости в децибелах; равняетсяmax_volume
, но без знака минус-
;input.mp4
- исходный видеофайл;output.mp4
- результирующий видеофайл с зацикленным видео.
Подробную документацию по ffmpeg
, фильтрам и сопутствующим инструментам можно найти в официальной документации3. Дополнительную информацию по работе со звуком можно получить в официальной Wiki4.