4 điểm bởi GN⁺ 2026-03-23 | 1 bình luận | Chia sẻ qua WhatsApp
  • Trình bày cấu trúc và cách sử dụng của framework FFmpeg để mã hóa, giải mã, chuyển mã và phát trực tuyến âm thanh và video
  • Giải thích cụ thể vai trò của các công cụ dòng lệnh như ffmpeg, ffplay, ffprobe và các thư viện cốt lõi như libavcodec, libavformat, libavfilter
  • Triển khai từng bước quy trình phân tích luồng và giải mã xoay quanh AVFormatContext, AVCodecContext, AVPacket, AVFrame
  • Sử dụng hệ thống build meson/ninja để tự động tải xuống và biên dịch mã ví dụ, đồng thời phân tích các tệp media mẫu và in kết quả
  • Có thể dùng như tài liệu nhập môn thiên về thực hành để hiểu nguyên lý hoạt động bên trong và pipeline giải mã của FFmpeg

Cấu thành gói FFmpeg

  • FFmpegbộ công cụ và thư viện có thể mã hóa, giải mã, chuyển mã nhiều định dạng âm thanh·video khác nhau và phát trực tuyến qua mạng
  • Công cụ FFmpeg

    • ffmpeg: công cụ chuyển đổi định dạng multimedia dựa trên dòng lệnh
    • ffplay: trình phát media đơn giản dựa trên SDL và các thư viện FFmpeg
    • ffprobe: công cụ phân tích luồng multimedia
  • Thư viện FFmpeg

    • libavformat: cung cấp chức năng nhập/xuất và muxing/demuxing
    • libavcodec: cung cấp chức năng mã hóa/giải mã
    • libavfilter: xử lý media thô thông qua bộ lọc dựa trên đồ thị
    • libavdevice: hỗ trợ thiết bị nhập/xuất
    • libavutil: cung cấp các tiện ích multimedia dùng chung
    • libswresample: hỗ trợ resampling âm thanh, chuyển đổi định dạng mẫu và trộn âm thanh
    • libswscale: chức năng chuyển đổi màu sắc và scale hình ảnh
    • libpostproc: chức năng hậu xử lý video (deblocking, bộ lọc nhiễu, v.v.)

Trình phát FFmpeg đơn giản

  • Cách sử dụng FFmpeg cơ bản là demux luồng multimedia để tách thành luồng âm thanh và video, sau đó giải mã thành dữ liệu âm thanh/video thô
  • Các cấu trúc chính

    • AVFormatContext: cấu trúc cấp cao quản lý đồng bộ hóa luồng, metadata và muxing
    • AVStream: luồng âm thanh hoặc video liên tục
    • AVCodec: định nghĩa phương thức mã hóa và giải mã dữ liệu
    • AVPacket: dữ liệu đã mã hóa trong luồng
    • AVFrame: khung hình video thô hoặc mẫu âm thanh đã giải mã
  • Quy trình phân tích luồng và demux

    • Cấp phát bộ nhớ cho AVFormatContext bằng avformat_alloc_context()
    • Mở tệp multimedia bằng avformat_open_input()
    • Phân tích thông tin luồng trong tệp bằng avformat_find_stream_info()
    • In ra time base, frame rate, thời gian bắt đầu, độ dài, loại, mã FourCC của từng luồng
    • Đóng tệp và giải phóng bộ nhớ bằng avformat_close_input()
  • Tìm codec và khởi tạo

    • Tìm decoder phù hợp với codec ID của AVStream bằng avcodec_find_decoder()
    • Với luồng video thì in độ phân giải (width, height), với luồng âm thanh thì in số kênh và sample rate
    • Tạo AVCodecContext bằng avcodec_alloc_context3()
    • Áp dụng tham số codec của luồng vào decoder context bằng avcodec_parameters_to_context()
    • Mở decoder bằng avcodec_open2()
  • Đọc packet và giải mã

    • Cấp phát các cấu trúc AVPacketAVFrame lần lượt để lưu packet đã mã hóaframe đã giải mã
    • Đọc tuần tự packet từ tệp đầu vào bằng av_read_frame()
    • Xác định packet đến từ luồng nào thông qua stream_index của packet
    • Chỉ gửi các packet của luồng video được chọn (first_video_stream_index) tới decoder
    • Chuyển packet tới decoder bằng avcodec_send_packet()
    • Nhận lặp lại các frame đã giải mã bằng avcodec_receive_frame()
    • In ra số thứ tự, loại (I/P/B), định dạng, PTS, có phải keyframe hay không của từng frame
    • Tái sử dụng bộ nhớ packet bằng av_packet_unref()
    • Khi hoàn tất mọi xử lý, giải phóng bộ nhớ bằng av_packet_free(), av_frame_free(), avcodec_free_context(), avformat_close_input()
  • Ví dụ chạy và kết quả

    • Mã ví dụ được cung cấp trong kho lưu trữ GitHub
    • Có thể build bằng mesonninja (pip3 install meson ninja)
    • Chạy meson setup build để FFmpeg tự động được tải xuống và cấu hình
    • Sau khi build bằng ninja -C build, chạy bằng ./build/ffmpeg-101 sample.mp4
    • Kết quả chạy sẽ in ra định dạng tệp, thông tin luồng (video/audio), codec, độ phân giải, sample rate, PTS của từng packet và thông tin frame đã giải mã
  • Tóm tắt ví dụ đầu ra

    • Luồng video: H.264 (avc1), độ phân giải 206x80, frame rate 30fps
    • Luồng âm thanh: AAC (mp4a), 2 kênh, 44.1kHz
    • PTSloại frame (I/P) của từng packet được hiển thị tuần tự, và quá trình giải mã được in ra trên console

Môi trường build và chạy

  • Công cụ cần thiết: Python, pip, meson, ninja
  • Lệnh cài đặt: pip3 install meson ninja
  • Quy trình build

    • Giải nén tệp ví dụ vào thư mục ffmpeg-101
    • Chạy meson setup build
    • Build bằng ninja -C build
    • Chạy bằng ./build/ffmpeg-101 sample.mp4
    • Nếu FFmpeg chưa được cài đặt trên hệ thống, nó sẽ tự động được tải xuống và cấu hình

1 bình luận

 
GN⁺ 2026-03-23
Ý kiến trên Hacker News
  • Rất khuyến nghị tutorial của Leandro Moreira cho những ai muốn hiểu sâu cách FFmpeg và libav hoạt động bên trong
    Cá nhân mình thấy đây là phần giải thích đầy đủ và rõ ràng nhất từng đọc cho đến nay
    Link tutorial FFmpeg-libav

    • Tutorial này thực sự rất hữu ích. Cảm ơn
    • Các lệnh trong bài gốc không mấy thú vị, nhưng tutorial này có vẻ thực tế hơn nhiều
  • Thật ngạc nhiên khi đã là ffmpeg 101 rồi. Cảm giác như ffmpeg 8 mới ra mắt ngày hôm qua

    • Có vẻ như đây là kết quả của việc agent đã push code, phê duyệt và phát hành hết trong lúc mình ngủ
  • Chia sẻ thêm một hướng dẫn khác
    Link hướng dẫn liên quan trên HN

  • FFmpeg đúng là một công cụ mình rất yêu thích

  • Đây là tài liệu nhập môn ffmpeg rất tuyệt. Cảm ơn

  • ffmpeg đúng là một siêu năng lực
    Mình luôn dùng nó khi cần ghép nhiều đoạn video thành một dạng có thể phát được