2P by GN⁺ 4시간전 | ★ favorite | 댓글 1개
  • 오디오와 비디오를 인코딩·디코딩·트랜스코딩하고 스트리밍할 수 있는 FFmpeg 프레임워크의 구조와 사용법을 다룸
  • ffmpeg, ffplay, ffprobe 등 명령줄 도구와 libavcodec, libavformat, libavfilter 등 핵심 라이브러리의 역할을 구체적으로 설명
  • AVFormatContext, AVCodecContext, AVPacket, AVFrame을 중심으로 한 스트림 분석과 디코딩 절차를 단계별로 구현
  • meson/ninja 빌드 시스템을 이용해 예제 코드를 자동으로 다운로드·컴파일하고, 샘플 미디어 파일을 분석해 결과를 출력
  • FFmpeg의 내부 동작 원리와 디코딩 파이프라인 이해를 위한 실습형 입문 자료로 활용 가능

FFmpeg 패키지 구성

  • FFmpeg은 다양한 오디오·비디오 포맷을 인코딩, 디코딩, 트랜스코딩하고 네트워크를 통해 스트리밍할 수 있는 도구와 라이브러리 모음으로 구성됨
  • FFmpeg 도구

    • ffmpeg: 명령줄 기반 멀티미디어 포맷 변환 도구
    • ffplay: SDL과 FFmpeg 라이브러리를 기반으로 한 간단한 미디어 플레이어
    • ffprobe: 멀티미디어 스트림을 분석하는 도구
  • FFmpeg 라이브러리

    • libavformat: 입출력 및 muxing/demuxing 기능 제공
    • libavcodec: 인코딩/디코딩 기능 제공
    • libavfilter: 그래프 기반 필터를 통한 원시 미디어 처리
    • libavdevice: 입력/출력 장치 지원
    • libavutil: 공통 멀티미디어 유틸리티 제공
    • libswresample: 오디오 리샘플링, 샘플 포맷 변환, 오디오 믹싱 지원
    • libswscale: 색상 변환 및 이미지 스케일링 기능
    • libpostproc: 비디오 후처리(디블로킹, 노이즈 필터 등) 기능

FFmpeg 간단 플레이어

  • 기본적인 FFmpeg 사용 방식은 멀티미디어 스트림을 demux하여 오디오와 비디오 스트림으로 분리하고, 이를 raw 오디오/비디오 데이터로 디코딩하는 과정
  • 주요 구조체

    • AVFormatContext: 스트림의 동기화, 메타데이터, muxing을 관리하는 상위 구조체
    • AVStream: 연속적인 오디오 또는 비디오 스트림
    • AVCodec: 데이터 인코딩 및 디코딩 방식 정의
    • AVPacket: 스트림 내 인코딩된 데이터
    • AVFrame: 디코딩된 원시 비디오 프레임 또는 오디오 샘플
  • 스트림 분석 및 demux 과정

    • avformat_alloc_context()AVFormatContext 메모리 할당
    • avformat_open_input()으로 멀티미디어 파일 열기
    • avformat_find_stream_info()로 파일 내 스트림 정보 분석
    • 각 스트림의 시간 기반(time base), 프레임레이트, 시작 시간, 길이, 타입, FourCC 코드를 출력
    • avformat_close_input()으로 파일 닫기 및 메모리 해제
  • 코덱 탐색 및 초기화

    • avcodec_find_decoder()AVStream의 코덱 ID에 맞는 디코더 탐색
    • 비디오 스트림의 경우 해상도(width, height), 오디오 스트림의 경우 채널 수와 샘플레이트 출력
    • avcodec_alloc_context3()AVCodecContext 생성
    • avcodec_parameters_to_context()로 스트림의 코덱 파라미터를 디코더 컨텍스트에 적용
    • avcodec_open2()로 디코더 열기
  • 패킷 읽기 및 디코딩

    • AVPacketAVFrame 구조체를 각각 인코딩된 패킷디코딩된 프레임 저장용으로 할당
    • av_read_frame()으로 입력 파일에서 패킷을 순차적으로 읽음
    • 패킷의 stream_index를 통해 어떤 스트림에서 왔는지 식별
    • 선택된 비디오 스트림(first_video_stream_index)의 패킷만 디코더로 전송
    • avcodec_send_packet()으로 패킷을 디코더에 전달
    • avcodec_receive_frame()으로 디코딩된 프레임을 반복적으로 수신
    • 각 프레임의 번호, 타입(I/P/B), 포맷, PTS, 키프레임 여부 출력
    • av_packet_unref()으로 패킷 메모리 재활용
    • 모든 처리가 끝나면 av_packet_free(), av_frame_free(), avcodec_free_context(), avformat_close_input()으로 메모리 해제
  • 실행 및 결과 예시

    • 예제 코드는 GitHub 저장소에서 제공
    • mesonninja를 이용해 빌드 가능 (pip3 install meson ninja)
    • meson setup build 실행 시 FFmpeg 자동 다운로드 및 설정
    • ninja -C build로 빌드 후 ./build/ffmpeg-101 sample.mp4로 실행
    • 실행 결과는 파일 포맷, 스트림 정보(비디오/오디오), 코덱, 해상도, 샘플레이트, 각 패킷의 PTS 및 디코딩된 프레임 정보 출력
  • 출력 예시 요약

    • 비디오 스트림: H.264 (avc1), 해상도 206x80, 프레임레이트 30fps
    • 오디오 스트림: AAC (mp4a), 2채널, 44.1kHz
    • 각 패킷의 PTS프레임 타입(I/P) 이 순차적으로 표시되며, 디코딩 과정이 콘솔에 출력됨

빌드 및 실행 환경

  • 필요 도구: Python, pip, meson, ninja
  • 설치 명령: pip3 install meson ninja
  • 빌드 절차

    • 예제 압축 파일을 ffmpeg-101 폴더에 추출
    • meson setup build 실행
    • ninja -C build로 빌드
    • ./build/ffmpeg-101 sample.mp4로 실행
    • FFmpeg이 시스템에 설치되어 있지 않으면 자동으로 다운로드 및 구성
Hacker News 의견들
  • FFmpeg과 libav의 내부 동작을 깊이 이해하고 싶은 사람에게 Leandro Moreira의 튜토리얼을 강력히 추천함
    개인적으로 지금까지 본 것 중 가장 완전하고 명확한 설명임
    FFmpeg-libav 튜토리얼 링크

    • 이 튜토리얼이 정말 도움이 됨. 고마움
    • 원문에 있던 명령어들은 별로 흥미롭지 않았는데, 이 튜토리얼은 훨씬 실용적으로 보임
  • 벌써 ffmpeg 101이라니 놀라움. ffmpeg 8이 나온 게 어제 같은 느낌임

    • 잠자는 사이에 에이전트가 코드 푸시, 승인, 릴리스까지 다 해버린 결과 같음
  • 또 다른 가이드를 공유함
    HN의 관련 가이드 링크

  • FFmpeg, 정말 사랑하는 도구

  • 훌륭한 ffmpeg 입문 자료였음. 감사함

  • ffmpeg은 진정한 슈퍼파워
    나는 여러 영상 조각을 하나의 재생 가능한 형태로 조립할 때 항상 사용함