本篇文章更新時間:2026/03/22
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知或向一介資男的 LINE 社群反應。
如果本站內容對你有幫助,歡迎贊助支持 。
內容目錄
FFmpeg 101:從零開始理解 FFmpeg 的架構與解碼流程
編輯前言:如果你曾想直接使用 FFmpeg 讀取、解析或解碼影音檔,卻發現 API 如迷宮般複雜,這篇文章將是一次非常友善的入門導航。本文靈感來源自 FFmpeg 101。
核心觀點 (Key Takeaways)
- FFmpeg 不只是指令工具,它同時是一組強大且模組化的多媒體處理函式庫。
- 解碼流程其實由一連串清楚的步驟組成:讀檔 → 找串流 → 選 codec → 餵 packet → 收 frame。
- FFmpeg 的核心資料結構 (AVFormatContext、AVPacket、AVFrame…) 才是理解 API 的關鍵。
深入解析
這篇原文其實做了一件對初學者非常友善的事:它不是教你「如何用 ffmpeg 指令」,而是帶你看見 FFmpeg 在底層是如何把一個 mp4 解析並解碼成影格。
作者從兩個層次開場:工具與函式庫。
- 工具層:如 ffmpeg、ffplay、ffprobe,負責轉檔、播放、檢測。
- 函式庫層:如 libavformat、libavcodec、libswscale,這些才是開發者真正會在程式中使用的部分。
原文一句話:FFmpeg 的工具是包裝,真正的核心能力來自各個 library。
接著作者用一個「最小可行播放器」示範 FFmpeg 的典型工作流程:
1. 讀檔與解析容器格式:AVFormatContext
這個結構負責:
- 打開檔案
- 解析容器(例如 MP4 裡有幾個 stream)
- 找出每個 stream 的 metadata(Frame rate、codec、duration…)
這部分主要透過:
avformat_open_inputavformat_find_stream_info
2. 找出每條 Stream 該用哪個 Codec
每個 AVStream 裡會記錄 codec_id,然後我們用:
avcodec_find_decoder
找到對應的解碼器,如 H.264、AAC。
作者也提到一個實用細節:你也可以自己寫 codec,只要註冊 FFCodec 即可。
3. 建立解碼器上下文:AVCodecContext
流程是:
avcodec_alloc_context3avcodec_parameters_to_contextavcodec_open2
這裡最重要的觀念是:
解碼器會被視為一個 FIFO:你送進去 packet,它吐出 frame。
4. Demux packet,送進解碼器
使用:
av_read_frame拿到 AVPacketavcodec_send_packet丟給 decoderavcodec_receive_frame拿 AVFrame
這段是 FFmpeg 初學者最容易卡住的地方,因為解碼器並不是「你送一個 packet 就一定吐一個 frame」,編碼特性(如 B frame)會讓解碼器的 queue 更複雜。
原文也提供了清楚的 pseudo event log,讓人能理解解碼器的運作節奏。
筆者心得與啟發
讀完這篇文章,我最大的感想是:FFmpeg 看似龐大,其實邏輯非常一致。真正複雜的不是 API,而是影音編碼本身。
我特別喜歡作者從架構切入,而不是直接給一堆 code。因為當我理解:
- AVFormatContext 負責容器
- AVStream 描述每條流
- AVCodecContext 是真正的解碼器實體
- AVPacket 是被 demux 出來的一小塊編碼資料
- AVFrame 是最後輸出的 raw data
之後整個 FFmpeg API 就變得親切許多。
如果你正在寫播放器、處理影像資料或需要從程式端理解 FFmpeg,我會非常推薦從這篇開始。理解底層資料流動後,你會發現許多網路教學的誤用或錯誤假設,也更能自己 debug FFmpeg 程式。
最後我認為最重要的啟示是:寫 FFmpeg 不是在「呼叫函式」,而是在理解一條資料在系統中的流動過程。當你把 FFmpeg 當成一個 pipeline 而非工具箱,它就自然變得更加易懂了。
