La foret rouge
Published on

자주 쓰는 FFmpeg 명령어

Authors
  • avatar
    Name
    Shin Juyong

FFmpeg은 오디오와 비디오 등의 미디어를 다양하게 다룰 수 있는 솔루션입니다1. 영상을 녹화하거나, 변환할 수 있고, 특정 필터를 적용하거나, 자르고, 붙이고, 빨리감기 등등... 굉장히 할 수 있는 게 많죠. 하지만 기능이 많다는건 초보자가 사용하기 쉽지 않다는 뜻이기도 합니다.

그래서 이번 글에서는 제가 주로 사용하는 (1) 용량을 줄여 보관하기 (2) README.md 등에 포함하기여서 그와 관련된 명령어를 소개합니다.

설치

일단 가장 먼저 설치입니다.

# macOS
brew install ffmpeg

# Ubuntu
sudo apt install ffmpeg

# Windows
choco install ffmpeg

참고로 여기서 Windows는 Chocolatey로 설치하는 방법을 적어뒀는데, 맥의 brew나 우분투의 apt, snap 같이 CLI 환경에서 편하게 설치할 수 있어서 좋습니다.

파일 정보 확인

hevc 같은 최신 코덱을 사용하면 보편적으로 쓰이는 같은 화질의 h264 영상에 비해 용량을 더 줄일 수 있다는 장점이 있습니다. 하지만 아직 충분히 보편화되지는 않아 호환이 안되는 환경이 존재한다는 단점이 있습니다. 아래와 같은 상황처럼요.

ffmpeg
ffmpeg

이 파일의 정보를 FFmpeg으로 확인해봅시다.

➜ ffmpeg -i input.mp4
# ...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  # ...
  Duration: 00:00:13.10, start: 0.000000, bitrate: 9083 kb/s
  Stream #0:0[0x1](und): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv, bt709, progressive), 1920x1080, 9075 kb/s, 60 fps, 60 tbr, 15360 tbn (default)
  # ...
  • -i input.mp4: 입력 파일의 경로입니다. 다른 폴더에 있을 경우 상대 경로 또는 절대 경로 입력도 가능합니다.

Input > Stream #0:0을 보면 Video: hevc (Main) (hvc1 ...이라고 나옵니다.

인코딩

그러면 재생이 가능하도록 h264로 인코딩을 하기 전에 먼저 제 컴퓨터에서 사용 가능한 h264 인코더가 어떤 것이 있는지부터 봅시다.

➜ ffmpeg -h encoder=h264 | grep AVOptions
# ...
libx264 AVOptions:
libx264rgb AVOptions:
h264_videotoolbox AVOptions:

3개가 나왔는데, 이 중 libx264는 CPU를 사용하는 인코더이고, h264_videotoolbox는 mac의 GPU를 사용하는 인코더입니다. 만약 데스크탑에서 nvidia의 그래픽 카드를 사용하는 분이시면 h264_nvenc가 보일 것입니다. 각 인코더에서 사용 가능한 자세한 설정값을 알아보고 싶다면 인코더를 정확히 명시해주면 됩니다.

➜ ffmpeg -h encoder=libx264

그러면 이제 본격적으로 h264로 인코딩을 해봅시다. 사용할 명령어는 다음과 같습니다.

➜ ffmpeg -i input.mp4 -c:v libx264 -crf 0 output.mp4
  • -c:v libx264: codec:video를 나타냅니다. 위에서 인코더에 대해 얘기했는데, 여기서는 CPU를 사용하는 libx264를 사용했습니다.
    그래픽 카드는 없을 수도 있지만 CPU는 모든 컴퓨터에 다 있으니까요..!
  • -crf 0: 압축률을 설정하는 파라미터입니다. 0으로 하면 거의 원본에 가깝게 인코딩을 합니다.
  • output.mp4: 출력 파일 경로입니다.

용량 줄이기

위에서 압축률에 대한 얘기를 잠깐 했는데, 영상은 꽤나 용량이 큽니다. 초당 30장의 사진을 수 백, 수 천 초동안 재생하는 파일이니까요. 영화나 드라마를 제공하는 OTT 플랫폼에서는 고화질 영상이 중요하겠지만, 제 경우에는 그렇지 않습니다. 영상이 너무 고화질인 경우 어딘가에 제출을 해야될 때 용량 제한에 걸리거나, 프로젝트 발표 때 화상 회의 플랫폼을 통해 시연해야 하는 영상의 경우 대역폭 문제로 영상이 끊기듯 재생되는 문제도 있을 수 있기 때문입니다.

그래서 이런 경우에 영상의 용량을 줄이는데, (1) 비트레이트를 낮추거나 (2) 영상 크기를 리사이징하는 방법을 사용합니다.

리사이즈

인코딩 시 출력된 콘솔 로그입니다. Input/Output Stream을 보면 1920x1080 픽셀(우리가 흔히 말하는 FHD)으로 나옵니다.

➜ ffmpeg -i input.mp4 -c:v libx264 -crf 0 output.mp4
# ...
Output #0, mp4, to 'output.mp4':
  # ...
  Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080, q=2-31, 60 fps, 15360 tbn (default)

이를 1280x720(HD)으로 줄여봅시다.

➜ ffmpeg -i input.mp4 -c:v libx264 -crf 0 -vf "scale=-1:720" output.mp4
# ...
Output #0, mp4, to 'output.mp4':
  # ...
  Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1280x720, q=2-31, 60 fps, 15360 tbn (default)
  # ...

ls -alh *.mp4
Permissions Size User Date Modified Name
.rw-r--r--   15M refo  7 Apr 12:30   input.mp4
.rw-r--r--@ 7.0M refo  7 Apr 13:28   output.mp4
  • -vf "scale=-1:720": 비디오(v)에 필터(f)를 적용합니다.
    • scale 필터를 사용하고 너비(w):높이(h) 형식으로 파라미터를 입력합니다. 만약 둘 중 하나를 -1로 입력하면 원본 영상 비율에 맞게 자동으로 계산됩니다.

영상의 크기를 줄여서 용량도 15MB에서 7MB로 줄어든 것을 볼 수 있습니다.

비트레이트 낮추기

비트레이트(bit rate)란 초당 비트 전송률을 나타낸다고 하면 똑같이 어렵죠..ㅎ 쉽게 말하자면 1초당 용량입니다2. 아까 영상은 사진이 1초당 30장이 모여있는 파일이라고 했습니다. 사진 한 장 한 장의 용량이 줄어들면 전체 영상의 용량도 줄어들겠죠. 유튜브는 HD 영상의 비트레이트로 5Mbps를 권장합니다3. 하지만 제가 사용하는 용도에는 조금 더 낮춰도 괜찮았습니다.

이전 리사이징의 결과 파일 정보를 다시 봅시다.

➜ ffmpeg -i output.mp4
# ...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output.mp4':
  # ...
  Duration: 00:00:13.12, start: 0.000000, bitrate: 4243 kb/s

4,200kbps가 나오네요. 이 파일을 2,500kbps 수준으로 낮춰봅시다. 방법은 크게 두 가지가 있습니다.

압축률 설정

FFmpeg 문서를 보면 -crf 옵션을 사용해 화질을 조절할 수 있다고 나옵니다4. 위에서 사용했던 것처럼 0을 사용하면 거의 원본에 가깝고, 기본값은 23, 최악은 51이라고 하며, 0이 아니라 17이나 18 정도로만 사용해도 '눈으로 보기에 거의 손실이 없는' 수준이라고 합니다. 그러면 -crf 17로 한 번 비교해보겠습니다.

➜ ffmpeg -i output.mp4 -c:v libx264 -crf 17 output_crf17.mp4

-crf 17으로 하니 700Kbps 정도가 되는데, 2500Kbps 정도가 나오도록 값을 조금 수정해보죠.

➜ ffmpeg -i output.mp4 -c:v libx264 -crf 5 output_crf5.mp4

비트레이트 명시

위 경우처럼 의도한 비트레이트가 있다면 -crf 값을 바꿔가면서 하는게 아니라 -b:v 2500k와 같은 옵션을 사용할 수 있습니다.

➜ ffmpeg -i output.mp4 -c:v libx264 -b:v 2500k output_bv2500k.mp4

결과적으로 원본 input.mp4에서 리사이즈를 해서 용량을 절반 정도로 줄인 output.mp4를 만들었고, 거기서 비트레이트를 조절해서 output_bv2500k.mp4, output_crf3.mp4와 같이 또 절반 정도로 줄일 수 있었습니다.

ls -alh
Permissions Size User Date Modified Name
.rw-r--r--@  15M refo  7 Apr 12:30   input.mp4
.rw-r--r--@ 7.0M refo  7 Apr 14:37   output.mp4
.rw-r--r--  3.2M refo 13 Apr 10:14   output_bv2500k.mp4
.rw-r--r--@ 3.9M refo 13 Apr 09:55   output_crf3.mp4

영상 자르기

영상의 일부만 사용해야 될 때가 있습니다. 제 경우에는 프로젝트 README에 포함할 화면 녹화를 할 때 실제 동작을 보여주는 전후로 녹화 시작/종료 버튼을 누르러 마우스를 옮기는 과정이 몇 초 되지는 않지만 포함시키기는 별로여서 자르는 편입니다. 다음은 영상의 2초부터 11초까지 9초짜리로 자르는 예시입니다.

➜ ffmpeg -i output.mp4 -c:v libx264 -ss 00:00:02 -to 00:11:00 output_trim.mp4
  • -ss HH:MM:SS: 시작 시간입니다. 0초부터 이 시간까지의 영상이 잘립니다(사라집니다). 0초부터 사용할 때는 없어도 됩니다.
  • -t HH:MM:SS: 지속 시간입니다. 시작 시간부터 이 시간동안의 영상이 출력됩니다.
  • -to HH:MM:SS: 종료 시간입니다. 이 시간부터 영상 끝까지가 잘립니다. 영상 끝까지 사용할 때는 없어도 됩니다.

제 경우에는 -ss-to를 조합해서 주로 사용합니다.

➜ ffmpeg -i output.mp4
# ...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output.mp4':
  # ...
  Duration: 00:00:13.12, start: 0.000000, bitrate: 4243 kb/s
  # ...

➜ ffmpeg -i output_trim.mp4
# ...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output_trim.mp4':
  # ...
  Duration: 00:00:11.12, start: 0.000000, bitrate: 455 kb/s
  # ...

영상 빨리감기

영상 재생이 너무 느려 조금 빨리 재생해야 할 때가 있을 수도 있습니다. 영상을 2배속으로 재생하는 명령은 다음과 같습니다.

➜ ffmpeg -i output.mp4 -c:v libx264 \
  -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" \
  -map "[v]" -map "[a]" \
  output_ff.mp4

재생시간이 절반이 된 것을 확인할 수 있습니다.

➜ ffmpeg -i output.mp4
# ...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output.mp4':
  # ...
  Duration: 00:00:13.12, start: 0.000000, bitrate: 4243 kb/s
  # ...

➜ ffmpeg -i output_ff.mp4
# ...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output_ff.mp4':
  # ...
  Duration: 00:00:06.60, start: 0.000000, bitrate: 415 kb/s
  # ...

GIF 만들기

영상을 사용해 GIF 파일을 만들 수 있습니다. 영상 자르기를 설명할 때 README에 포함한다고 했는데 보통 README에는 영상을 포함하기보다는 GIF 파일을 포함하는 편이고, 이 때 빨리감기도 주로 같이 사용하는 편입니다.

➜ ffmpeg -i output_ff.mp4 -r 15 -loop 0 output.gif
  • -r 15: 초당 프레임 수입니다. GIF에서는 이 숫자가 높아질수록 원본 영상(30fps)처럼 부드러워 보이지만, 영상보다 용량이 더 커질 수도 있습니다.
  • -loop 0: 무한 반복합니다.
ffmpeg

Footnotes

  1. FFmpeg. "ffmpeg Documentation." ffmpeg.org. https://ffmpeg.org/ffmpeg.html (accessed Apr. 07, 2024).

  2. Wikipedia. "Bit rate." Wikipedia. https://en.wikipedia.org/wiki/Bit_rate (accessed Apr. 07, 2024).

  3. YouTube. "YouTube 권장 업로드 인코딩 설정." YouTube 고객센터. https://support.google.com/youtube/answer/1722171?hl=ko#zippy=%2C비트-전송률 (accessed Apr. 07, 2024).

  4. FFmpeg. "H.264 Video Encoding Guide." ffmpeg.org. https://trac.ffmpeg.org/wiki/Encode/H.264#a1.ChooseaCRFvalue (accessed Apr. 07, 2024).