FFmpeg 사용법: 터미널에서 영상과 오디오 다루기
개발을 하다 보면 영상이나 오디오 파일을 다뤄야 할 때가 종종 있죠. 프론트엔드에서 업로드된 영상의 포맷을 바꿔야 하거나, 데모 영상에서 오디오만 뽑아야 하거나, API 문서에 넣을 GIF를 만들어야 할 때처럼요. 이럴 때 GUI 편집 프로그램을 열기엔 너무 거창하고 간단한 커맨드 하나로 해결하고 싶을 때가 있는데요.
FFmpeg은 바로 그런 상황에서 빛나는 도구입니다. 터미널에서 한 줄이면 영상 포맷을 변환하고, 오디오를 추출하고, 영상을 자르고 합칠 수 있거든요. 이번 글에서는 FFmpeg의 기본 개념부터 실전에서 자주 쓰는 명령어까지 차근차근 살펴보겠습니다.
FFmpeg이란
FFmpeg은 영상과 오디오를 녹화하고 변환하고 스트리밍할 수 있는 오픈소스 멀티미디어 프레임워크입니다. 2000년에 첫 릴리스된 이후 25년이 넘도록 꾸준히 개발되어 왔고, 거의 모든 멀티미디어 포맷을 지원해서 “멀티미디어의 스위스 군용 칼”이라고도 불립니다.
YouTube나 Netflix, VLC 미디어 플레이어 같은 유명 서비스 내부에서도 FFmpeg이 쓰이고 있을 정도로 업계 표준 도구라고 할 수 있는데요. FFmpeg을 설치하면 세 가지 커맨드라인 도구가 함께 설치됩니다.
ffmpeg은 멀티미디어 파일을 변환하고 처리하는 핵심 도구입니다.
포맷 변환이나 인코딩, 필터 적용 등 대부분의 작업이 이 명령어로 이루어지죠.
ffprobe는 미디어 파일의 정보를 분석해주는 도구로 영상의 해상도나 코덱, 비트레이트 같은 메타데이터를 확인할 때 씁니다.
ffplay는 간단한 미디어 플레이어인데 별도의 프로그램 없이 터미널에서 바로 영상이나 오디오를 재생할 수 있어서 변환 결과를 빠르게 확인하기 좋습니다.
설치
macOS에서는 Homebrew로 간편하게 설치할 수 있습니다.
brew install ffmpeg
Ubuntu/Debian 계열 리눅스에서는 apt를 사용합니다.
sudo apt update
sudo apt install ffmpeg
Windows에서는 공식 사이트(https://ffmpeg.org/download.html)에서 빌드를 다운로드하거나 Chocolatey 또는 Scoop 같은 패키지 매니저로 설치할 수 있습니다.
# Chocolatey
choco install ffmpeg
# Scoop
scoop install ffmpeg
설치가 잘 됐는지 확인해볼까요?
$ ffmpeg -version
ffmpeg version 8.0.1 Copyright (c) 2000-2025 the FFmpeg developers
built with Apple clang version 17.0.0 (clang-1700.6.3.2)
버전 정보가 출력되면 정상적으로 설치된 겁니다.
FFmpeg 명령어의 기본 구조
FFmpeg 명령어는 기본적으로 이런 형태를 따릅니다.
ffmpeg [전역 옵션] [입력 옵션] -i 입력파일 [출력 옵션] 출력파일
-i 플래그 뒤에 입력 파일을 지정하고 맨 끝에 출력 파일을 적습니다.
입력과 출력 사이에 여러 옵션을 넣어서 변환 방법을 지정하는 구조인데요.
가장 간단한 예시로, MP4 파일을 WebM 포맷으로 변환해보겠습니다.
$ ffmpeg -i input.mp4 output.webm
이 한 줄이면 FFmpeg이 입력 파일의 코덱을 분석하고, 출력 파일 확장자에 맞는 코덱으로 자동 인코딩합니다.
출력 파일이 이미 존재하면 덮어쓸지 물어보는데 -y 옵션을 추가하면 묻지 않고 바로 덮어씁니다.
스크립트에서 쓸 때 유용하죠.
ffprobe로 미디어 정보 확인
영상을 처리하기 전에 원본 파일의 정보부터 확인하는 습관을 들이면 좋습니다.
ffprobe를 사용하면 파일의 코덱, 해상도, 비트레이트, 길이 같은 메타데이터를 한눈에 파악할 수 있거든요.
$ ffprobe sample.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'sample.mp4':
Duration: 00:00:10.00, start: 0.000000, bitrate: 195 kb/s
Stream #0:0: Video: h264 (High), yuv420p, 1280x720, 116 kb/s, 30 fps
Stream #0:1: Audio: aac (LC), 44100 Hz, mono, 69 kb/s
이 출력을 보면 10초짜리 H.264 영상에 AAC 오디오가 들어 있고, 해상도가 1280x720이라는 걸 바로 알 수 있습니다.
프로그래밍에서 파싱하기 쉬운 JSON 형식으로도 출력할 수 있는데요.
$ ffprobe -v quiet -print_format json -show_format -show_streams sample.mp4
{
"streams": [
{
"codec_name": "h264",
"codec_type": "video",
"width": 1280,
"height": 720,
"r_frame_rate": "30/1",
"duration": "10.000000",
"bit_rate": "116084"
},
{
"codec_name": "aac",
"codec_type": "audio",
"sample_rate": "44100",
"channels": 1,
"duration": "10.000000",
"bit_rate": "69247"
}
],
"format": {
"duration": "10.000000",
"size": "244149",
"bit_rate": "195319"
}
}
-v quiet는 FFmpeg의 배너 출력을 숨기고 -show_format과 -show_streams는 각각 파일 포맷 정보와 스트림 정보를 표시합니다.
CI/CD 파이프라인에서 영상 메타데이터를 자동으로 검증하거나 업로드된 파일의 스펙을 체크할 때 이 JSON 출력이 아주 유용합니다.
포맷 변환
FFmpeg으로 가장 많이 하는 작업이 포맷 변환입니다. 앞서 봤듯이 출력 파일의 확장자만 바꾸면 FFmpeg이 알아서 적절한 코덱을 선택해주는데요.
# MP4 → WebM
$ ffmpeg -i input.mp4 output.webm
# MP4 → AVI
$ ffmpeg -i input.mp4 output.avi
# WAV → MP3
$ ffmpeg -i input.wav output.mp3
코덱을 직접 지정하고 싶을 때는 -c:v (비디오 코덱)와 -c:a (오디오 코덱) 옵션을 사용합니다.
예를 들어 H.264 영상을 H.265(HEVC)로 변환하면 화질은 비슷하게 유지하면서 파일 크기를 크게 줄일 수 있습니다.
$ ffmpeg -i input.mp4 -c:v libx265 -c:a aac output_h265.mp4
반대로 코덱을 바꾸지 않고 컨테이너 포맷만 바꾸고 싶다면 -c copy를 사용합니다.
재인코딩 없이 스트림을 그대로 복사하기 때문에 속도가 매우 빠르고 화질 손실도 없습니다.
$ ffmpeg -i input.mp4 -c copy output.mkv
영상에서 오디오 추출
영상 파일에서 오디오 트랙만 뽑아내고 싶을 때가 있는데요.
-vn 옵션을 사용하면 비디오 스트림을 제외하고 오디오만 추출할 수 있습니다.
$ ffmpeg -i sample.mp4 -vn -c:a libmp3lame -q:a 2 output.mp3
-vn은 “video none”의 약자로 비디오를 빼겠다는 뜻입니다.
-c:a libmp3lame은 오디오 코덱으로 LAME MP3 인코더를 사용하겠다는 의미이고 -q:a 2는 VBR(가변 비트레이트) 품질을 지정합니다.
품질 값은 0(최고)부터 9(최저)까지인데 2 정도면 충분한 품질이에요.
AAC 포맷으로 추출하고 싶다면 이렇게 합니다.
$ ffmpeg -i input.mp4 -vn -c:a aac -b:a 192k output.aac
비슷한 원리로 -an 옵션을 쓰면 오디오를 제외하고 영상만 추출할 수 있습니다.
$ ffmpeg -i input.mp4 -an -c:v copy output_no_audio.mp4
영상 자르기
긴 영상에서 특정 구간만 잘라내는 것도 자주 하는 작업입니다.
-ss로 시작 시간을, -t로 길이를 지정하면 됩니다.
$ ffmpeg -i sample.mp4 -ss 00:00:02 -t 5 -c copy trimmed.mp4
이 명령은 2초 지점부터 5초 동안의 구간을 잘라냅니다.
-c copy를 함께 사용했기 때문에 재인코딩 없이 빠르게 처리되죠.
길이 대신 끝나는 시간을 지정하고 싶다면 -t 대신 -to를 쓰면 됩니다.
# 1분 30초부터 2분 45초까지
$ ffmpeg -i input.mp4 -ss 00:01:30 -to 00:02:45 -c copy clip.mp4
참고로 -ss의 위치가 성능에 영향을 미치는데요.
-i 앞에 놓으면 해당 시간까지 빠르게 탐색(seek)한 뒤 디코딩을 시작하고, -i 뒤에 놓으면 처음부터 디코딩하면서 해당 시간까지 건너뜁니다.
긴 영상에서 뒷부분을 잘라낼 때는 -i 앞에 놓는 게 훨씬 빠릅니다.
# 빠른 방식 (-ss를 -i 앞에)
$ ffmpeg -ss 01:30:00 -i long_video.mp4 -t 60 -c copy clip.mp4
영상 크기 변경
영상의 해상도를 변경할 때는 -vf scale 필터를 사용합니다.
-vf는 “video filter”의 약자인데요.
$ ffmpeg -i sample.mp4 -vf scale=640:360 -c:v libx264 -c:a copy resized.mp4
이렇게 하면 원본 1280x720 영상이 640x360으로 줄어듭니다.
너비만 지정하고 높이는 비율에 맞게 자동 계산하고 싶다면 -1을 사용합니다.
# 너비 640, 높이는 자동
$ ffmpeg -i input.mp4 -vf scale=640:-1 resized.mp4
# 높이 480, 너비는 자동
$ ffmpeg -i input.mp4 -vf scale=-1:480 resized.mp4
특정 코덱은 해상도 값이 2의 배수여야 하는 경우가 있는데, 그럴 때는 -2를 쓰면 가장 가까운 짝수로 맞춰줍니다.
$ ffmpeg -i input.mp4 -vf scale=640:-2 resized.mp4
썸네일 추출
영상의 특정 시점에서 이미지를 한 장 뽑아내는 것도 간단합니다.
$ ffmpeg -i sample.mp4 -ss 00:00:03 -vframes 1 thumbnail.jpg
-ss 00:00:03으로 3초 지점을 지정하고, -vframes 1로 한 프레임만 추출합니다.
일정 간격으로 여러 장의 이미지를 추출하고 싶다면 fps 필터를 사용합니다.
# 1초마다 한 장씩 추출
$ ffmpeg -i input.mp4 -vf fps=1 frames/frame_%04d.jpg
# 10초마다 한 장씩 추출
$ ffmpeg -i input.mp4 -vf fps=1/10 frames/frame_%04d.jpg
%04d는 0001, 0002처럼 4자리 숫자로 파일명을 매기겠다는 뜻입니다.
GIF 만들기
데모 영상이나 튜토리얼을 GIF로 만들어야 할 때가 있죠.
가장 단순한 방법은 그냥 확장자를 .gif로 바꾸는 건데요.
$ ffmpeg -i sample.mp4 output.gif
이렇게 하면 동작은 하지만 파일 크기가 꽤 커집니다. 예를 들어 238KB짜리 MP4 파일이 7.5MB짜리 GIF가 돼버리거든요 😅
파일 크기를 줄이면서 색상 품질도 유지하려면 팔레트 최적화를 사용하는 게 좋습니다.
$ ffmpeg -i sample.mp4 \
-vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
palette.gif
명령이 좀 길어 보이지만 하는 일은 명확합니다.
fps=10으로 초당 프레임을 10으로 줄이고, scale=320:-1로 너비를 320px로 조정합니다.
lanczos는 고품질 리사이즈 알고리즘이고, palettegen과 paletteuse가 영상에 최적화된 256색 팔레트를 생성해서 적용하는 부분입니다.
같은 영상으로 비교하면 단순 변환은 7.5MB, 팔레트 최적화는 465KB로 파일 크기가 약 16분의 1로 줄어듭니다.
재생 속도 변경
영상의 재생 속도를 바꾸려면 비디오와 오디오 필터를 함께 적용해야 합니다. 2배속으로 빠르게 재생하는 영상을 만들어볼까요?
$ ffmpeg -i sample.mp4 -vf "setpts=0.5*PTS" -af "atempo=2.0" fast.mp4
setpts=0.5*PTS는 비디오의 프레젠테이션 타임스탬프를 절반으로 줄여서 2배속으로 만드는 필터입니다.
atempo=2.0은 오디오의 재생 속도를 2배로 올리는데, 피치(음높이)는 유지해줍니다.
느리게 재생하고 싶다면 값을 반대로 설정하면 됩니다.
# 0.5배속 (슬로모션)
$ ffmpeg -i input.mp4 -vf "setpts=2.0*PTS" -af "atempo=0.5" slow.mp4
atempo 필터는 0.5에서 2.0 사이 값만 지원하기 때문에 4배속을 만들려면 필터를 체이닝해야 합니다.
# 4배속
$ ffmpeg -i input.mp4 -vf "setpts=0.25*PTS" -af "atempo=2.0,atempo=2.0" fast4x.mp4
여러 파일 합치기
짧은 클립 여러 개를 하나로 이어 붙이려면 concat 디먹서를 사용합니다. 먼저 합칠 파일 목록을 텍스트 파일로 만들어야 하는데요.
file 'clip1.mp4'
file 'clip2.mp4'
file 'clip3.mp4'
그다음 이 목록을 입력으로 넘기면 됩니다.
$ ffmpeg -f concat -safe 0 -i filelist.txt -c copy merged.mp4
-f concat은 concat 디먹서를 사용하겠다는 뜻이고 -safe 0은 절대 경로를 허용하는 옵션입니다.
-c copy로 재인코딩 없이 빠르게 합칠 수 있지만 모든 클립의 코덱과 해상도가 같아야 한다는 조건이 있습니다.
자주 쓰는 옵션 정리
FFmpeg에는 옵션이 정말 많지만, 실제로 자주 사용하는 것은 한정되어 있습니다.
-i— 입력 파일 지정-y— 출력 파일이 이미 존재하면 묻지 않고 덮어쓰기-c:v— 비디오 코덱 지정 (libx264, libx265, libvpx-vp9 등)-c:a— 오디오 코덱 지정 (aac, libmp3lame, libopus 등)-c copy— 재인코딩 없이 스트림 복사-vn— 비디오 스트림 제외-an— 오디오 스트림 제외-ss— 시작 시간 (00:01:30 또는 90)-t— 처리할 길이 (초 단위 또는 HH:MM:SS)-to— 종료 시간-vf— 비디오 필터 (scale, fps, setpts 등)-af— 오디오 필터 (atempo, volume 등)-b:v— 비디오 비트레이트 (예: 2M, 5000k)-b:a— 오디오 비트레이트 (예: 192k, 320k)-r— 프레임 레이트 (예: 30, 60)-vframes— 추출할 비디오 프레임 수
마치며
FFmpeg은 처음에는 옵션이 많아서 복잡해 보일 수 있지만, 기본 구조인 ffmpeg -i 입력 [옵션] 출력 패턴만 기억하면 대부분의 작업을 해낼 수 있습니다.
포맷 변환, 오디오 추출, 영상 자르기, GIF 만들기처럼 개발 중에 흔히 마주치는 멀티미디어 작업을 터미널에서 빠르게 처리할 수 있다는 점이 FFmpeg의 가장 큰 매력이에요.
터미널에서 HTTP 호출이 필요할 때 curl 사용법이 유용하듯이, 멀티미디어 파일을 다룰 때는 FFmpeg이 든든한 도구가 되어줄 겁니다. 이미지 처리도 터미널에서 해결하고 싶다면 libvips CLI 사용법을 함께 알아두면 좋고요. 코드로 영상을 만드는 것에 관심이 있다면 Remotion으로 React 코드로 영상 만들기도 재미있는 선택지입니다.
이 글에서 다룬 내용은 FFmpeg이 제공하는 기능의 극히 일부에 불과합니다. 필터 그래프를 활용한 고급 영상 편집이나 실시간 스트리밍, 하드웨어 가속 인코딩까지 더 깊은 주제가 많으니 공식 문서를 참고하면서 하나씩 탐색해보시길 바랍니다.
더 자세한 내용은 FFmpeg 공식 문서를 참고하세요.
This work is licensed under
CC BY 4.0