Categories
FFmpeg

FFmpeg으로 비디오 위에 비디오를 오버레이 (overlay) 하기

FFmpeg 으로 비디오 위에 다른 비디오를 오버레이 (overlay) 해 보자.

오버레이 효과를 위해서 overlay 필터를 사용한다.

1. 첫번째 예제

다음 명령을 살펴보자.

ffmpeg -i main.mp4 -i over.mp4 -filter_complex “[0:v][1:v]overlay=x=0:y=0[v]” output.mp4

이 명령은 over.mp4 의 비디오 스트림을 main.mp4 의 비디오 스트림 위에 오버레이 한다.

overlay 필터의 x 옵션은 메인 (main) 비디오 안에서 오버레이 비디오의 가로 위치를 지정한다.

overlay 필터의 y 옵션은 메인 비디오 안에서 오버레이 비디오의 세로 위치를 지정한다.

over.mp4 비디오는 main.mp4 비디오의 (0, 0) 위치에 오버레이 된다.

오버레이 했을 때 위에 있는 비디오를 오버레이 비디오 라고 부르고 아래에 있는 비디오를 메인 비디오 라고 부른다.

오버레이 비디오의 위치가 (x, y) 라는 말은 오버레이 비디오의 좌측 상단 꼭지점이 메인 비디오의 (x, y) 위치에 놓인다는 것을 의미한다.

2. shortest 옵션

메인 비디오와 오버레이 비디오의 재생 시간이 다를 때 shortest 옵션을 사용한다.

shortest 옵션을 1 로 지정하면 재생 시간이 짧은 비디오가 끝날 때 오버레이 작업이 끝난다. 완성된 출력 스트림의 재생 시간은 짧은 비디오의 재생 시간과 같게 된다.

ffmpeg -i main.mp4 -i over.mp4 -filter_complex “[0:v][1:v]overlay=x=0:y=0:shortest=1[v]” output.mp4

shortest 옵션의 기본값은 0 이다.

3. 임의의 위치에 오버레이하기

오버레이 비디오를 메인 비디오의 우측 상단에 오버레이 해보자.

ffmpeg -i main.mp4 -i over.mp4 -filter_complex “[0:v][1:v]overlay=x=W-w:y=0[v]” output.mp4

x 옵션의 값을 W-w 로 지정했다. W 는 메인 비디오의 가로 크기이고 w 는 오버레이 비디오의 가로 크기이다.

메인 비디오의 가로 크기는 1920 픽셀이고 오버레이 비디오의 가로 크기는 400 픽셀이라고 가정해 보자. 이 경우에 오버레이 비디오의 가로 위치는 1520 (1920 – 400) 이 된다.

오버레이 비디오의 위치는 (1520, 0) 이 된다.

오버레이 비디오를 메인 비디오의 우측 하단에 오버레이 해보자.

ffmpeg -i main.mp4 -i over.mp4 -filter_complex “[0:v][1:v]overlay=x=W-w:y=H-h[v]” output.mp4

y 옵션의 값을 H-h 로 지정했다. H 는 메인 비디오의 세로 크기이고 h 는 오버레이 비디오의 세로 크기이다.

메인 비디오의 세로 크기는 1080 픽셀이고 오버레이 비디오의 세로 크기는 300 픽셀이라고 가정해 보자. 이 경우에 오버레이 비디오의 세로 위치는 780 (1080 – 300) 이 된다.

오버레이 비디오의 위치는 (1520, 780) 이 된다.

Categories
FFmpeg

FFmpeg의 필터그래프, 체인, 필터의 개념과 상호관계

FFmpeg의 필터그래프, 체인, 필터 등의 개념과 상호관계를 살펴본다.

1. 필터그래프, 체인, 필터

FFmpeg 의 필터그래프 (filtergraph) 는 체인 (chain) 과 필터 (filter) 로 구성된다.

각 체인은 세미콜론 (;) 으로 구분된다.

-vf [in]scale=640:480[mid];[mid]fps=25[out]

2개의 체인이 사용되었다.

각 필터는 콤마 (,) 로 구분된다.

-vf scale=640:480,fps=25

scale 필터와 fps 필터가 콤마로 구분되어 있다.

2. 스트림 지정의 생략

아래 명령은 “[in]” 스트림에 scale 필터를 적용하여 “[out]” 스트림을 생성한다.

ffmpeg -i input.mp4 -vf [in]scale=640:480[out] output.mp4

“[in]” 스트림 지정을 생략하면 앞에 있는 스트림을 지정한 것으로 간주된다.

ffmpeg -i input.mp4 -vf scale=640:480[out] output.mp4

“[out]” 스트림 지정을 생략하면 뒤에 올 스트림을 지정한 것으로 간주된다.

ffmpeg -i input.mp4 -vf [in]scale=640:480 output.mp4

스트림 지정을 모두 생략할 수도 있다.

ffmpeg -i input.mp4 -vf scale=640:480 output.mp4

3. 체인이 2개 이상일 때 스트림 지정 생략

아래 명령을 살펴보자.

ffmpeg -i input.mp4 -vf [in]scale=640:480[mid];[mid]fps=25[out] output.mp4

“[in]” 스트림에 scale 필터를 적용하여 “[mid]” 라는 중간 스트림을 생성한다. “[mid]” 스트림에 fps 필터를 적용하여 “[out]” 스트림을 생성한다.

중간 스트림의 지정을 생략할 수 있다.

ffmpeg -i input.mp4 -vf [in]scale=640:480,fps=25[out] output.mp4

체인의 개수는 1개가 된다. 각 필터는 콤마로 구분한다.

“[in]” 스트림 또는 “[out]” 스트림의 지정을 생략할 수 있다. 2개 모두 지정하지 않는 것도 가능하다.

ffmpeg -i input.mp4 -vf scale=640:480,fps=25 output.mp4

Categories
FFmpeg

FFmpeg 으로 동영상의 비디오 해상도 변경하기

FFmpeg 으로 동영상의 비디오 해상도를 변경하는 방법을 알아보자.

1. scale 필터

비디오 해상도를 변경할 때는 scale 필터를 쓴다.

ffmpeg -i input.mp4 -vf scale=w=640:h=480 output.mp4

w 옵션은 동영상의 가로 크기를 픽셀 단위로 지정한다.

h 옵션은 동영상의 세로 크기를 픽셀 단위로 지정한다.

2. 동영상 품질의 유지

해상도를 변경하면서 동영상의 품질을 최대한 유지하는 방법을 알아보자.

ffmpeg -i input.mp4 -vf scale=w=640:h=480 -preset slow -crf 18 output.mp4

-preset 옵션은 인코딩 속도를 지정할 때 쓴다. 속도가 느릴수록 동영상의 품질이 좋아진다.

-crf 옵션의 값은 0 ~ 51 범위 안에서 지정한다. 값이 작을수록 동영상의 품질이 좋아진다. 기본값은 23 이다. 17 또는 18 로 지정하면 무손실에 근접한 정도의 품질을 얻을 수 있다.

CRF 는 고정 비율 인자 (Constant Rate Factor) 를 의미한다.

3. 가로세로 비율의 유지

원래의 가로세로 비율 (aspect ratio) 을 유지하면서 비디오 해상도를 변경해 보자.

입력 파일인 input.mp4 의 비디오 해상도가 1920×1080 이라고 하자.

ffmpeg -i input.mp4 -vf scale=w=800:h=-1 output.mp4

가로 크기를 800 으로 지정하고 세로 크기는 -1 로 지정했다. 세로 크기는 원래의 가로세로 비율에 따라 자동으로 계산되어 다시 지정된다. 실제의 세로 크기는 450 이 된다.

ffmpeg -i input.mp4 -vf scale=w=-1:h=600 output.mp4

가로 크기를 -1 로 지정하고 세로 크기는 600 으로 지정했다. 가로 크기는 원래의 가로세로 비율에 따라 자동으로 계산되어 다시 지정된다. 실제의 가로 크기는 1067 이 된다.

Categories
FFmpeg

FFmpeg으로 여러 동영상을 연결하는 2가지 방법

ffmpeg 명령으로 여러 동영상을 연결하는 방법을 알아보자.

1. concat 필터를 이용한 방법

concat 필터를 이용해서 여러 동영상을 연결해 보자.

다음 ffmpeg 명령은 3개의 동영상을 연결하여 하나의 새로운 동영상을 생성한다.

ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 \
  -filter_complex "[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[v][a]" \
  -map "[v]" -map "[a]" output.mp4

명령에서 중요한 몇몇 부분들을 살펴보자.

[0:v][0:a] 부분은 첫번째 입력 파일의 비디오 스트림과 오디오 스트림을 가리킨다. 이러한 부분을 세그먼트라고 한다.

[1:v][1:a] 부분은 두번째 입력 파일의 비디오 스트림과 오디오 스트림을 가리킨다.

[2:v][2:a] 부분은 세번째 입력 파일의 비디오 스트림과 오디오 스트림을 가리킨다.

concat 필터에는 3가지 옵션이 있다.

n=3

n 옵션은 세그먼트의 개수를 지정한다.

v=1

v 옵션은 출력 비디오 스트림의 개수를 지정한다. 이것은 각 세그먼트의 비디오 스트림 개수와 일치해야 한다.

a=1

a 옵션은 출력 오디오 스트림의 개수를 지정한다. 이것은 각 세그먼트의 오디오 스트림 개수와 일치해야 한다.

[v] 는 출력 비디오 스트림의 이름이다.

[a] 는 출력 오디오 스트림의 이름이다.

-map “[v]” -map “[a]” output.mp4

출력 비디오 스트림과 출력 오디오 스트림을 매핑한다. 최종 결과물은 output.mp4 파일로 저장된다.

2. cat 명령을 이용한 방법

cat 명령과 중간 (intermediate) 동영상을 이용해서 여러 동영상을 연결해 보자.

중간 동영상으로는 TS (Transport Stream) 포맷의 동영상이 주로 사용된다.

연결할 동영상 중 하나를 TS 포맷으로 변환한다.

ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts inter1.ts

명령에서 중요한 부분들을 살펴보자.

-bsf:v h264_mp4toannexb

비트스트림(bitstream) 필터로 h264_mp4toannexb 를 지정한다.

-f mpegts inter1.ts

파일 포맷을 mpegts 로 지정한다. 최종 결과물은 inter1.ts 파일로 저장된다.

나머지 동영상들도 마찬가지 방법으로 변환한다.

ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts inter2.ts
ffmpeg -i input3.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts inter3.ts

변환된 3개의 동영상을 cat 명령으로 연결한다.

cat inter1.ts inter2.ts inter3.ts > inter-all.ts

ts 파일을 mp4 파일로 변환한다.

ffmpeg -i inter-all.ts -c:v libx264 -c:a libfdk_aac output.mp4