10

В FFmpeg на самом деле довольно сложно сделать перекрестное затухание между двумя частями видеоконтента. Нет фильтра «перекрестного затухания», как для аудио.

Какой эффективный способ сделать это?

1 ответ1

16

TL; версия DR:

В этом примере выполняется только видео, при условии, что оба видеоклипа имеют одинаковое разрешение, частоту кадров и т.д. Это создаст 1-секундное замирание между fadeoutclip и fadeinclip. Предположим, что fadeoutclip длится 10 секунд. Обратите внимание, что это отформатировано для ясности: это действительно одна строка кода.

ffmpeg -i fadeoutclip.mp4 -i fadeinclip.mp4 -an \
-filter_complex "\
    [0:v]trim=start=0:end=9,setpts=PTS-STARTPTS[firstclip]; \
    [1:v]trim=start=1,setpts=PTS-STARTPTS[secondclip]; \
    [0:v]trim=start=9:end=10,setpts=PTS-STARTPTS[fadeoutsrc]; \
    [1:v]trim=start=0:end=1,setpts=PTS-STARTPTS[fadeinsrc]; \
    [fadeinsrc]format=pix_fmts=yuva420p, \
                fade=t=in:st=0:d=1:alpha=1[fadein]; \
    [fadeoutsrc]format=pix_fmts=yuva420p, \
                fade=t=out:st=0:d=1:alpha=1[fadeout]; \
    [fadein]fifo[fadeinfifo]; \
    [fadeout]fifo[fadeoutfifo]; \
    [fadeoutfifo][fadeinfifo]overlay[crossfade]; \
    [firstclip][crossfade][secondclip]concat=n=3[output] \
    " \
-map "[output]" <add in encoding part here>

"Что за черт?"Версия:

Вот объяснение того, что это было все:

Спецификация ввода ... очевидно

ffmpeg -i fadeoutclip.mp4 -i fadeinclip.mp4 -an

Создание filter_complex: при условии, что вы уже понимаете комплексы фильтров:

-filter_complex

Сначала мы разбиваем два потока на два, используя фильтр обрезки: содержимое и секцию перекрестного затухания. Затухание разбивается на раздел контента и затухания, а затухание - на раздел затухания и контент. Всего четыре раздела.

Обратите внимание, что, строго говоря, нам не нужно разбивать участки перекрестного затухания: мы МОЖЕМ просто указать время затухания и затухания для двух видеоклипов. Однако, делая это, мы:

  • следуйте методологии, обычно используемой графическими редакторами GUI
  • избегать разочаровывающей сложности использования overlay фильтра
  • убедитесь, что решение является как можно более общим (т. е. повторно используемый код)
  • позволяют нам предварительно обрабатывать и постобрабатывать участок кроссфейдера по мере необходимости (здесь не делается)

Каждый из этих четырех разделов определяет: время начала (секунды), время окончания (секунды) и загадочный setpts=PTS-STARTPTS, который, по сути, запускает каждый видеоклип с 0 секунд. Это будет жизненно важно при их перекомпоновке.

Обратите внимание, что спецификаторы s=0 являются избыточными, а фильтр setpts для s=0 также избыточен. Тем не менее, оба указываются с избыточностью, чтобы позволить стартовое время изменить с 0, не нарушая комплекс фильтра. Кроме того, второй клип контента выполняется до конца, поэтому e= part (end =) не указана.

    [0:v]trim=s=0:e=9,setpts=PTS-STARTPTS[firstclip];
    [1:v]trim=s=1,setpts=PTS-STARTPTS[secondclip];
    [0:v]trim=s=9:e=10,setpts=PTS-STARTPTS[fadeoutsrc];
    [1:v]trim=s=0:e=1,setpts=PTS-STARTPTS[fadeinsrc];

Далее мы указываем постепенное появление и постепенное исчезновение: сначала мы добавляем альфа-канал (прозрачность) в обе секции постепенного изменения, указав формат пикселя yuva420p. Вы можете использовать любой формат, который обеспечивает альфа-канал.

Далее в этом подкомплексе фильтра мы указываем один для постепенного исчезновения и один для постепенного появления. alpha=1 означает, что само видео не потемнеет, только "прозрачность" "исчезнет". st означает начало, d означает продолжительность.

    [fadeinsrc]format=pix_fmts=yuva420p,      
                fade=t=in:st=0:d=1:alpha=1[fadein];
    [fadeoutsrc]format=pix_fmts=yuva420p,
                fade=t=out:st=0:d=1:alpha=1[fadeout];

Что это ?: Фильтр fifo гарантирует наличие буферного пространства в комплексе фильтров. Удивительно, но это не по умолчанию. Если вы этого не сделаете, кроссфейд может потерпеть неудачу, если выходной сигнал вышеприведенного каскада превысит нижний фильтр наложения. Да, я знаю, о чем ты сейчас думаешь. Это действительно ошибка FFMPEG.

    [fadein]fifo[fadeinfifo];
    [fadeout]fifo[fadeoutfifo];

Теперь наложите две секции затухания: убедившись, что две секции перекрестного затухания имеют одинаковый размер, нам не нужно беспокоиться о довольно неприятных опциях, которые принимает фильтр наложения (и поэтому мы их здесь игнорируем):

    [fadeoutfifo][fadeinfifo]overlay[crossfade];

Наконец, мы выстраиваем наши три сегмента, используя фильтр concat.

    [firstclip][crossfade][secondclip]concat=n=3[output]

А теперь сопоставьте выходную панель как источник видео.

НЕ ЗАБУДЬТЕ установить формат пикселя в ТО, ЧТО ВЫ НОРМАЛЬНО ИСПОЛЬЗУЕТЕ (обычно это yuv420p), так как секция кроссфейдера установит его в yuv420 на выходном канале! (поскольку мы не указали это, вы можете использовать аргументы оверлея) Конечно, если вы ХОТИТЕ yuv420 , то все в порядке :-)

-map "[output]" <add your normal encoding part here>

После этого вы можете позже рекомбинировать звук (за рамками этого вопроса).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .