자주 쓰는 FFmpeg 명령어들

7 분 소요

2020/12/13

FFmpeg는 동영상 관련 처리를 할 때 많이 사용하는 오픈소스 소프트웨어입니다. 동영상 플레이어인 Movist나 팟플레이어도 내부적으로 사용하는 걸로 알려져 있습니다. 요즘은 동영상 추출이나 스트리밍, 다운로드 등에서도 자주 사용하지요.

그런데 GUI 화면을 보면서 설정하는 게 아니라 옵션을 키보드로 입력해서 사용하는 방식이라 사용법이 조금 까다롭습니다. 하지만 한 번 익혀두면 이래저래 유용하게 일괄 처리하는데 편리합니다. 그런 편리한 FFmpeg 명령어 중에 개인적으로 종종 사용하는 것을 정리해 보았습니다.

명령어는 Mac OS를 기준으로 설명합니다.

설치하기

brew를 사용해서 설치하는 것이 일반적입니다. 설치 방법은 다른 좋은 글이 많으니 검색해 보세요.

alias 설정

FFmpeg를 그냥 사용할 수도 있지만, 다음처럼 alias를 사용해서 공통 옵션을 설정해두면 조금 더 편리합니다.

alias ffmpegu='ffmpeg -hide_banner -loglevel info -stats -analyzeduration 10M -probesize 50M -user_agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15" -allowed_extensions ALL -protocol_whitelist "file,http,https,tcp,tls,crypto" '

-hide_banner -loglevel info -stats는 실행할 때 나오는 FFmpeg 정보를 숨기고 로그 레벨은 info, 진행 상황 정보는 출력하겠다는 내용입니다. -loglevel warning이나 -loglevel error로 바꾸면 어떤 이상이 생겼을 때만 로그가 출력되어서 조금 더 화면이 깔끔해집니다.

-analyzeduration 10M -probesize 50M는 입력 파일을 분석할 버퍼를 설정하는 옵션입니다. 이 옵션을 사용하면 초반에 음성 트랙이 여러 개이거나 비디오 ID가 바뀌는 경우도 정상적으로 처리할 수 있게 됩니다.

-user_agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15"는 마치 브라우저에서 보는 것처럼 유저 정보를 서버에 보내고 싶을 때 사용합니다. 가끔 이 정보를 확인하기도 하므로 미리 추가해 둡시다.

-allowed_extensions ALL -protocol_whitelist "file,http,https,tcp,tls,crypto"는 보안상 기본적으로 사용하지 못하게 하는 프로토콜이나 확장 기능을 사용할 수 있도록 하는 옵션입니다. 파일 목록으로 합치기 등등의 기능을 사용하려면 필요한 옵션입니다.

이 내용을 .zshrc.bashrc에 추가해 두면 앞으로 설명하는 명령어 예문에서 ffmpeg 대신에 ffmpegu를 사용하면 됩니다.

인코딩

아마도 FFmpeg를 사용하는 가장 주된 목적은 인코딩이겠지요. FFmpeg가 지원하는 인코딩 코덱은 ffmpeg -encoders로 확인 가능한데 그중에서도 요즘 자주 쓰이는 MP4로 인코딩하는 명령어 예를 가지고 살펴 봅시다. FFmpeg 옵션은 지정 순서가 무척 중요해서 순서를 잘못 지정하면 에러가 발생하기도 하니 주의해야 합니다.

# 입력 파일을 디인터페이스해서 1280x720 해상도인 mp4로 저장하기
ffmpeg -fflags +discardcorrupt -i '입력 파일' -vf "yadif=0:-1:0,scale=1280:720" -c:v libx264 -preset:v veryfast -crf 22 -movflags +faststart -c:a aac -b:a 160k '출력 파일.mp4'

-fflags +discardcorrupt는 입력 파일에 있는 깨진 패킷은 무시하겠다는 옵션입니다. 불안정한 인터넷 상태나 저장 실패 때문에 손상된 파일을 처리할 때 유용합니다. 이런 옵션은 FFmpeg 공식 도움말에서 확인 가능합니다.

-i '입력 파일'input을 지정하는 옵션입니다. 변환할 원본 파일 경로를 지정하면 됩니다.

-vf "yadif=0:-1:0,scale=1280:720" 이 옵션은 디인터레이스(yadif=0:-1:0), 해상도 변환(scale=1280:720)을 실시하는 video filter를 지정하는 부분입니다. 더욱 자세한 내용은 도움말 참조하세요.

-c:v libx264 -preset:v veryfast -crf 22는 libx264 인코더로 영상을 mpeg-4 코덱으로 인코딩하겠다는 옵션입니다. crf 22로 화질을 정하고(숫자가 작을수록 고화질, 고용량) preset:v veryfast으로 인코딩 시간과 압축 효율을 결정합니다. 경험상 veryfast가 일반적인 사용에 적당합니다.

-movflags +faststart는 MP4 영상의 크기, 재생 시간 같은 메타 정보가 든 moov atom을 파일 첫부분으로 옮겨서 스트리밍 등으로 볼 때 빠르게 재생할 수 있도록 만들어 주는 옵션입니다.

--c:a aac -b:a 160k 옵션은 음성 코덱 지정 부분으로 aac 코덱으로 인코딩한다는 의미입니다. 비트레이트로 160k를 지정했는데 보다 고음질을 원하면 256k 등을 지정하면 됩니다.

복잡해 보이지만 FFmpeg는 이렇게 영상 관련 옵션, 음성 관련 옵션을 조합해서 사용하는 것이 기본 방식입니다.

일부분 자르기

# 영상을 00:01:00~00:03:00(2분간) 잘라서 저장하기
ffmpeg -ss 00:01:00 -i "in.ts" -to 00:02:00 -c copy "cut.ts"

-ss 00:01:00은 영상 자르기 시작점을 지정하는 옵션입니다. ss 뒤에 오는 숫자는 시:분:초 형식입니다. 따라서 1분이 시작점이 됩니다.

-to 00:02:00은 시작점으로부터 얼마나 영상을 자를지 지정하는 옵션입니다. -to 뒤에 오는 시간은 영상 전체의 플레이 시간이 아니라 시작점으로부터 재생 시간(2분)이라는 점에 주의해야 합니다. 따라서 위 예제에서는 영상의 1분부터 3분 사이의 2분간(00:02:00)을 cut.ts라는 이름으로 저장하겠다는 뜻이 됩니다.

영상을 프레임 단위로 이미지 저장하기

# 초당 10 프레임 단위로 디인터페이스, 720 해상도로 변환한 jpg 파일 저장하기
FPS=10 ffmpeg -i "in.ts" -vf "yadif=0:-1:0,scale=1280:720,fps=${FPS}" -qscale:v 2 "thumb_%04d.jpg"

영상에 어떤 내용이 들어 있는지 빠르게 훑어 보고 싶거나 프레임 단위로 확인해 보고 싶을 때 유용한 명령어입니다.

-vf "yadif=0:-1:0,scale=1280:720,fps=${FPS}"에서 앞의 두 옵션은 인코딩 옵션 때 본 것과 같습니다. fps 옵션이 초당 몇 프레임을 추출할지 지정하는 값인데, 여기서는 환경변수 옵션 FPS에 10을 지정해서 사용했습니다. -vf "yadif=0:-1:0,scale=1280:720,fps=10" 처럼 직접 숫자를 지정할 수도 있지만 이렇게 상황에 따라 바뀔 수도 있는 값은 변수를 사용하는 것이 조금 더 편리합니다.

` -qscale:v 2`는 jpg 파일 화질을 지정하는 옵션입니다. 숫자가 클수록 화질이 떨어지는데 2~5 값을 추천합니다.

"thumb_%04d.jpg"는 출력할 파일명을 지정하는 옵션입니다. 추출한 프레임이 thumb_0001.jpg, thumb_0002.jpg, thumb_0003.jpg… 식으로 자동으로 번호순서대로 저장됩니다.

영상 파일 간편 합치기

ffmpeg -i "concat:in1.mp4|in2.mp4" -c copy "out.mp4"

재인코딩 없이 두 영상을 하나로 합쳐서 저장하는 명령어입니다. in1.mp4와 in2.mp4가 입력 파일, out.mp4가 출력 파일이 됩니다. 입력의 두 파일은 같은 해상도, 같은 코덱을 사용해야 합니다.

음성 파일에 섬네일을 지정해서 영상 파일 만들기

ffmpeg -loop 1 -i "thumb.jpg" -i "in.aac" -c:v libx264 -tune stillimage -acodec copy -pix_fmt yuv420p -shortest "out.mp4"

유튜브 등에 음성을 올릴 때 사용할 수 있는 방법입니다. thumb.jpg라는 이미지를 이용해서 in.aac 음성 파일이 재생이 끝날 때까지 같은 이미지가 계속 출력되는 mp4 영상 파일을 작성할 수 있습니다.

영상 회전하기

# 90도 회전
ffmpeg -i "in.mp4" -metadata:s:v "rotate=90" -c copy "out.mp4"

어쩌다 보니 옆으로 누워서 출력되는 영상을 회전시키고 싶을 때 사용하는 명령어입니다. 위 옵션을 사용하면 재인코딩 없이 90도 각도로 회전시킬 수 있습니다. 90에 회전시키고 싶은 각도 값을 지정하면 됩니다.

다른 영상과 음성을 합쳐서 새로운 파일로 저장하기

ffmpeg -stream_loop -1 -i "video.mp4" -i "audio.aac" -c copy -shortest -map 0:v:0 -map 1:a:0 -y "out.mp4"

기존에 존재하는 영상에 있는 음성을 좀 더 고음질 음성으로 교체하거나, 음성 출력 시간 동안 영상을 반복 재생하는 영상을 만들고 싶을 때 유용한 명령어입니다.

자막 파일을 내장하는 MP4 파일 만들기

ffmpeg -i "in.mp4" -i "sub.srt" -map 0:v:0 -c:v copy -map 0:a:0 -c:a copy -map 1 -c:s:0 mov_text -metadata:s:s:0 title=srt -metadata:s:s:0 language=kor "out.mp4"

-map 옵션은 여러 입력 파일이 있을 때 사용하는 옵션입니다. -map 입력 인덱스:스트림 종류:스트림 인덱스 형식으로 지정하는데 자세한 내용은 위키를 참조하기 바랍니다. 복잡하지만 익숙해지면 활용법이 무궁무진한 옵션입니다.

-map 0:v:0 -c:v copy -map 0:a:0 -c:a copy은 0번 입력 파일(in.mp4)에서 영상과 음성을 복사해서 0번 출력(out.mp4)으로 보낸다는 의미입니다.

-map 1 -c:s:0 mov_text -metadata:s:s:0 title=srt -metadata:s:s:0 language=kor은 1번 입력 파일(sub.srt)에서 자막을 복사해서 0번 출력(out.mp4)으로 보낸다는 의미입니다. FFmpeg는 srt 형식 자막을 지원합니다.

번외편: Nvidia 하드웨어 인코딩 사용하기

ffmpeg -y -hide_banner -analyzeduration 30M -probesize 100M -fflags +discardcorrupt  -i "in.ts" -vf "yadif=0:-1:0,scale=1280:720" -map 0:v:0 -c:v h264_nvenc -preset:v fast -rc constqp -qp 29.5 -profile:v high -movflags +faststart -map 0:a:0 -c:a:0 aac -b:a:0 160k -metadata:s:a:0 title="Audio#1"  "out.mp4"

맥에서는 더이상 사용할 수 없는 Nvidia이지만 윈도나 리눅스라면 이런 방식으로 하드웨어 인코딩을 사용할 수 있습니다. 하드웨어 인코딩은 CPU 인코딩에 비해 훨씬 빠르게 인코딩할 수 있는데 사용하는 그래픽 카드 성능에 따라 10배 이상 차이가 나기도 합니다. 훨씬 다양한 옵션이 존재하므로 자세한 내용은 검색해 보세요.

해당 인코더를 사용하려면 공식 홈페이지에서 배포하는 파일이 아니라 직접 빌드해서 사용해야 합니다.

정리

이렇게 간단히 상황에 따라 유용한 FFmpeg 명령어를 살펴 보았습니다. 더욱 자세한 내용은 공식 사이트나 위키 페이지를 참조하세요.

댓글남기기