FFmpeg로 비디오 크로스 페이드를 수행하는 효율적인 방법은 무엇입니까?


11

FFmpeg에서는 두 개의 비디오 컨텐츠간에 크로스 페이드를 수행하는 것이 실제로 매우 복잡합니다. 오디오와 같은 "크로스 페이드"필터는 없습니다.

효율적인 방법은 무엇입니까?


좋은 자체 답변 질문!
JakeGould

이 답변은 더 많은지지를 얻어야합니다 ... Mark, 오디오에 크로스 페이딩을 추가했다면 당신을 영원히 사랑합니다 ...
Merc

방법을 알아 내 자마자 추가하겠습니다. 오디오 크로스 페이드가 간단하다고 생각합니다. 간단한 필터가 있다고 생각하십시오.
Mark Gerolimatos

[0:a][1:a] acrossfade=d=1 [audio]필터에 추가 한 다음 -map "[audio]" 명령에 추가 하면 효과가있었습니다. 원한다면 테스트를 해보고 답변을 업데이트하십시오!
Merc

답변:


17

TL; DR 버전 :

이 예제는 두 비디오 클립의 해상도, 프레임 속도 등이 같다고 가정 할 때 비디오 만 수행합니다. 그러면 fadeoutclip과 fadeinclip 사이에 1 초 페이드가 생성됩니다. 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

먼저 트림 필터를 사용하여 두 스트림을 두 조각으로 나눕니다 . 내용과 크로스 페이드 섹션. 페이드 아웃은 내용과 페이드 섹션으로 나뉘고 페이드 인은 페이드 섹션과 내용으로 나뉩니다. 총 4 개의 섹션.

엄밀히 말하면, 우리가하지 않는 것이 참고 우리가 단지 두 개의 비디오 클립을 시간에 밖으로 페이드 인 페이드를 지정할 수 있습니다 : 밖으로 크로스 페이드 섹션을 휴식. 그러나 이렇게함으로써 우리는 :

  • GUI 비디오 편집기에서 일반적으로 사용되는 방법론을 따르십시오
  • overlay필터 사용의 복잡성을 피하십시오
  • 솔루션이 가능한 일반적인지 확인하십시오 (예 : 재사용 가능한 코드).
  • 필요에 따라 크로스 페이드 섹션을 사전 처리하고 사후 처리 할 수 ​​있습니다 (여기서는 안 됨).

이 4 개의 섹션은 각각 시작 시간 (초), 종료 시간 (초) 및 신비한 setpts=PTS-STARTPTS필터를 지정합니다 .이 필터 는 기본적으로 각 비디오 서브 클립을 0 초에서 시작합니다. 다시 합성 할 때 매우 중요합니다.

s=0지정자는 중복이며 해당 지정에 대한 setpts필터 s=0는 중복입니다. 그러나 필터 컴플렉스를 중단하지 않고 시작 시간을 0에서 변경할 수 있도록 둘 다 중복 지정됩니다. 또한 두 번째 컨텐츠 클립이 끝까지 실행되므로 e=부분 (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지정 하여 알파 (투명도) 채널을 두 페이드 섹션에 추가합니다 . 실제로 알파 채널을 제공하는 모든 형식을 사용할 수 있습니다.

이 필터에서 다음 우리가 페이드 아웃 하나를 지정하고, 하나의 페이드 subcomplex.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필터 는 필터 컴플렉스에 사용 가능한 버퍼 공간이 있는지 확인합니다. 놀랍게도 이것이 기본값이 아닙니다. 이렇게하지 않으면 위 단계의 출력이 아래의 오버레이 필터를 오버런하면 crossfade가 실패 할 수 있습니다. 네, 지금 무슨 생각하는지 알아요 실제로 FFMPEG 버그 입니다.

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

이제 두 페이드 섹션을 오버레이합니다 . 두 크로스 페이드 섹션의 크기를 동일하게 하여 오버레이 필터가 사용하는 다소 불쾌한 옵션 에 대해 걱정할 필요가 없습니다.

    [fadeoutfifo][fadeinfifo]overlay[crossfade];

마지막으로 concat 필터를 사용하여 세 개의 세그먼트 정렬합니다 .

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

이제 출력 패드를 비디오 소스로 매핑하십시오.

잊지 마세요 픽셀 형식으로 무엇을 일반적으로 사용을 (일반적으로 설정 yuv420p), 크로스 페이드 섹션으로 설정 한 것으로 yuv420출력 채널에! (우리가 지정하지 않았으므로 오버레이 인수를 사용할 수 있습니다) 물론 WANT yuv420이면 괜찮습니다 :-)

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

그런 다음 나중에이 Q & A 범위를 벗어난 오디오를 다시 결합 할 수 있습니다.


1
최신 ffmpeg에서는 ..가 trim=start=0:end=9아니라 trim=st=0:e=9,..
Merc Merc

그러나 진지하게, 이것은 내가 본 FFMPEG에 대한 가장 좋은 대답이어야하며 가장 명확한 ffmpeg 설명이어야합니다.
Merc

남자, 내 머리에 갈거야 :-) 소품 주셔서 감사합니다!
Mark Gerolimatos

걱정 마. = 트림 특히 함께 답을 업데이트하십시오 = 지금으로 = 0을 시작 그것을 수행하는 최신는 FFmpeg하지 작업
용병

최신 ffmpeg 버전은 Filter setpts has an unconnected output스크립트에 대해 다음과 같은 오류를 발생 시킵니다. 트림 매개 변수를 시작 및 종료로 변경했습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.