Skip to content

FFmpeg에 대해서 알아보자

Seungheon Han edited this page Dec 1, 2024 · 1 revision

실시간 스트리밍 서비스 프로젝트에서 실시간 썸네일 이미지 제공녹화 기능 제공 기능을 구현해야 했습니다.

저희 팀은 FFmpeg을 사용하여 실시간 스트림 영상과 오디오를 저장하기로 결정했고, 생소한 기술이기 때문에 FFmpeg에 대해 학습한 정리하고자 합니다.

1️⃣ FFmepg 이란?

비디오, 오디오, 이미지를 쉽게 인코딩 (Encoding)디코딩 (Decoding)먹싱 (Muxing)디먹싱 (Demuxing)등 처리 할 수 있도록 도움을 주는 멀티미디어 프레임워크

FFmpeg을 사용하는 이유

  • 영상 및 오디오 압축 알고리즘은 매우 다양하고 복잡하여 이를 모두 직접 구현하는 것은 현실적으로 어렵다.
  • FFmpeg은 오픈소스 프로젝트로, 전 세계 개발자들이 협력하여 다양한 영상 및 오디오 코덱, 파일 포맷을 지원한다.
  • 이러한 강점으로 FFmpeg은 멀티미디어 계의 필수 도구로 자리 잡았으며, 멀티미디어 파일을 다루는데 있어서 선택이 아닌 필수라는 말도 있다.

2️⃣ FFmpeg을 다루면서 알아야 할 멀티미디어 용어

인코딩

  • 문서의 용량을 줄이기 위해 ZIP 프로그램을 사용하는 것처럼, 동영상이나 이미지의 용량을 줄이기 위해 전용 압축 알고리즘으로 데이터를 압축하는 과정
  • 예를 들어, 곰인코더와 같은 프로그램이 동영상 인코딩을 수행

디코딩

  • 압축된 데이터를 해제하는 과정으로, 동영상을 재생하기 위해 압축된 영상과 오디오 데이터를 복원하는 작업
  • 동영상 재생 프로그램 (예: 곰플레이어, KMP 플레이어)은 내부적으로 FFmpeg을 사용하여 디코딩을 수행하며, 해제된 데이터를 UI로 출력

먹싱

  • 여러 개의 입력 데이터를 하나로 합치는 과정
  • 정지 영상 장면(1개의 프레임)들과 오디오가 인코딩된 후 하나의 동영상 파일(예: AVI, MKV, MOV)로 결합되는 과정

디먹싱

  • 합쳐진 데이터를 다시 여러 출력으로 분리하는 과정
  • 동영상 파일에서 정지 영상 장면(1개의 프레임)과 오디오를 각각 분리해내는 작업

코덱 (COder + DECoder)

  • 음성 또는 영상의 신호를 디지털 신호로 변환하는 코더와 그 반대로 변환시켜 주는 디코더를 통틀어 부르는 용어
  • 위에서 작성한 인코딩과 디코딩을 해주는 알고리즘을 의미
  • 손실 압축과 무손실 압축이 있다.

코덱 종류

  • H.264/AVC : 높은 호환성과 좋은 압축률
  • H.265/HEVC : 같은 품질에서 약 50% 더 높은 압축률
  • VP9 : google이 개발, youtube에서 주로 사용
  • AAC: 높은 음질과 효율적인 압축
  • MP3: 후속 표준
  • Opus: 다양한 프로파일 지원

컨테이너

  • 다양한 데이터 스트림을 하나의 파일로 포장하는 형식
  • 각 스트림은 서로 다른 코덱으로 인코딩될 수 있다.
  • 주요 컨테이너 포맷은 우리가 흔히 아는 확장자이다
    • MP4 (.mp4)
    • Matroska (.mkv)
    • AVI (.avi)
    • MOV (.mov)

비트레이트 (Bitrate)

  • 초당 처리되는 데이터양을 의미.
  • 고정 비트레이트(CBR)와 가변 비트레이트(VBR)가 있음.
  • 비트레이트가 높을수록 품질은 좋아지지만 파일 크기가 커진다.

해상도 (Resolution)

  • 영상의 가로x세로 픽셀 수입니다
  • 보통 1920x1080(Full HD), 3840x2160(4K) 등으로 표현합니다
  • 해상도가 높을수록 더 선명하지만 처리 부하가 증가합니다

프레임 레이트 (Framerate)

  • 초당 표시되는 이미지 수
  • 보통 24fps, 30fps, 60fps
  • 프레임레이트가 높을수록 부드럽지만 데이터 양이 증가합니다.

3️⃣ FFmpeg 옵션 정리

기본 입출력

-i [input]      # 입력 파일 지정
-f [format]     # 강제 입출력 형식 지정
-y              # 출력 파일 덮어쓰기
-n              # 출력 파일 덮어쓰기 방지

비디오 관련

-c:v [codec]    # 비디오 코덱 지정 (예: libx264, libx265)
-b:v [bitrate]  # 비디오 비트레이트 설정 (예: 1M, 2M)
-r [fps]        # 프레임레이트 설정
-s [size]       # 해상도 설정 (예: 1920x1080)
-aspect [ratio] # 화면비 설정 (예: 16:9)

오디오 관련

-c:a [codec]    # 오디오 코덱 지정 (예: aac, mp3)
-b:a [bitrate]  # 오디오 비트레이트 설정 (예: 128k, 192k)
-ar [rate]      # 오디오 샘플레이트 설정
-ac [channels]  # 오디오 채널 수 설정

인코딩 품질 관련

-crf [0-51]     # 영상 품질 설정 (낮을수록 고품질)
-preset [value] # 인코딩 속도 설정 (ultrafast ~ veryslow)
-profile:v      # 비디오 프로파일 설정
-level          # 인코딩 레벨 설정

필터 관련

-vf             # 비디오 필터 설정
-af             # 오디오 필터 설정
-filter_complex # 복잡한 필터 그래프 설정

디버깅

-v [level]      # 로그 레벨 설정
-report         # 로그 파일 생성
-debug          # 디버그 정보 출력

4️⃣ SDP 란?

해상도나 형식, 코덱, 암호화 등의 멀티미디어 컨텐츠의 연결을 설명하기 위한 메타데이터. 디바이스 간의 미디어를 공유하기 위한 연결 정보 포맷을 제공. 세션의 속성, 미디어 유형, 인코딩 방식 등을 정의.

  • webRTC에서 SDP는 미디어 스트림, 네트워크 주소 및 코덱 정보를 포함한, 두 Peer간의 통신 세션 매개 변수를 정하는데 사용된다.
  • 미디어 스트림을 주고받기 위해서 webRTC의 피어간 공유하는 세션 정보를 담은 SDP 오퍼를 생성하고, 다른 피어에게 전달한다.
  • 수신 피어는 SDP오퍼를 분석하고 수신할 수 있는 미디어 유형과 연결할 수 있는 네트워크 주소가 포함된 SDP응답을 반환한다.

SDP 파일의 주요 구성 요소

v=0                     # 프로토콜 버전
o=- 0 0 IN IP4 127.0.0.1  # 세션 생성자 정보
s=Streaming Test       # 세션 이름
c=IN IP4 127.0.0.1     # 연결 정보
t=0 0                  # 세션 시간 정보
m=video 5000 RTP/AVP 96  # 미디어 설명
a=rtpmap:96 H264/90000   # RTP 페이로드 포맷

FFmepg에서 SDP를 사용하는 이유

주로 라이브 스트리밍 미디어 처리에서 sdp를 사용하게 된다. 왜 사용할까?

  1. 실시간 스트리밍 시에 스트리밍 참가자들간의 통신방법을 정의하고, 미디어 형식, 코덱, 전송 프로토콜 등의 정보를 공유하기 위해서
  2. 송신자와 수신자 간의 지원가능한 미디어 형식을 맞추고, 최적의 코덱과 설정을 선택하기 위해서

참고자료

[01) FFmpeg 이란?](https://wikidocs.net/78484)

[ffmpeg - 동영상 파일 형식/코덱/해상도 변환, 특정 시간대의 비디오 자르기](https://wikidocs.net/237717#google_vignette)

[Documentation](https://www.ffmpeg.org/documentation.html)

[SDP는 무엇인가](https://berom.tistory.com/43)

👥 팀 강점

🧑‍💻 개발 일지

📌 ALL

📌 FE

📌 BE

💥 트러블 슈팅

📌 FE

📌 BE

🤔 고민

📚 학습 정리

📌 김광현

📌 백지연

📌 전희선

📌 한승헌

🤝 회의록

🗒️ 데일리 스크럼

💬 팀 회고


👨‍👩‍👧‍👦 소개

🌱 문화

🔨 기술 스택

⚙️ 서비스 아키텍쳐

🚧 CI/CD

🌊 Flow

💭 6주를 보내면서

Clone this wiki locally