- กล่าวถึงโครงสร้างและวิธีใช้งานของเฟรมเวิร์ก FFmpeg ที่สามารถเข้ารหัส ถอดรหัส แปลงรหัส และสตรีมเสียงกับวิดีโอได้
- อธิบายบทบาทของเครื่องมือบรรทัดคำสั่งอย่าง ffmpeg, ffplay, ffprobe และไลบรารีหลักอย่าง libavcodec, libavformat, libavfilter อย่างเป็นรูปธรรม
- ลงมือทำกระบวนการวิเคราะห์สตรีมและถอดรหัสแบบเป็นขั้นตอน โดยมี AVFormatContext, AVCodecContext, AVPacket, AVFrame เป็นแกนหลัก
- ใช้ระบบบิลด์ meson/ninja เพื่อดาวน์โหลดและคอมไพล์โค้ดตัวอย่างโดยอัตโนมัติ พร้อมวิเคราะห์ไฟล์มีเดียตัวอย่างและแสดงผลลัพธ์
- ใช้เป็นสื่อเริ่มต้นเชิงปฏิบัติสำหรับทำความเข้าใจหลักการทำงานภายในและ pipeline การถอดรหัสของ FFmpeg ได้
องค์ประกอบแพ็กเกจ FFmpeg
- FFmpeg ประกอบด้วยชุดเครื่องมือและไลบรารีสำหรับเข้ารหัส ถอดรหัส แปลงรหัสฟอร์แมตเสียงและวิดีโอหลากหลายชนิด รวมถึงสตรีมผ่านเครือข่าย
-
เครื่องมือ FFmpeg
- ffmpeg: เครื่องมือแปลงฟอร์แมตมัลติมีเดียผ่านบรรทัดคำสั่ง
- ffplay: มีเดียเพลเยอร์อย่างง่ายที่สร้างบน SDL และไลบรารี FFmpeg
- ffprobe: เครื่องมือสำหรับวิเคราะห์สตรีมมัลติมีเดีย
-
ไลบรารี FFmpeg
- libavformat: ให้ความสามารถด้านอินพุต/เอาต์พุตและ muxing/demuxing
- libavcodec: ให้ความสามารถด้านการเข้ารหัส/ถอดรหัส
- libavfilter: ประมวลผลมีเดียดิบผ่านตัวกรองแบบกราฟ
- libavdevice: รองรับอุปกรณ์อินพุต/เอาต์พุต
- libavutil: ให้ยูทิลิตีมัลติมีเดียทั่วไป
- libswresample: รองรับการรีแซมเปิลเสียง การแปลงรูปแบบตัวอย่าง และการมิกซ์เสียง
- libswscale: ความสามารถด้านการแปลงสีและการสเกลภาพ
- libpostproc: ความสามารถด้านการประมวลผลวิดีโอภายหลัง (deblocking, noise filter ฯลฯ)
เพลเยอร์อย่างง่ายด้วย FFmpeg
- วิธีใช้งาน FFmpeg พื้นฐานคือการ demux สตรีมมัลติมีเดียเพื่อแยกเป็นสตรีมเสียงและวิดีโอ แล้วจึงถอดรหัสเป็นข้อมูลเสียง/วิดีโอแบบ raw
-
โครงสร้างหลัก
- AVFormatContext: โครงสร้างระดับบนที่จัดการการซิงก์ Metadata และ muxing ของสตรีม
- AVStream: สตรีมเสียงหรือวิดีโอแบบต่อเนื่อง
- AVCodec: นิยามวิธีการเข้ารหัสและถอดรหัสข้อมูล
- AVPacket: ข้อมูลที่ถูกเข้ารหัสภายในสตรีม
- AVFrame: เฟรมวิดีโอดิบหรือชุดตัวอย่างเสียงที่ถอดรหัสแล้ว
-
กระบวนการวิเคราะห์สตรีมและ demux
- จัดสรรหน่วยความจำสำหรับ AVFormatContext ด้วย
avformat_alloc_context()
- เปิดไฟล์มัลติมีเดียด้วย
avformat_open_input()
- วิเคราะห์ข้อมูลสตรีมภายในไฟล์ด้วย
avformat_find_stream_info()
- แสดง time base, frame rate, เวลาเริ่มต้น, ความยาว, ประเภท, และ โค้ด FourCC ของแต่ละสตรีม
- ปิดไฟล์และคืนหน่วยความจำด้วย
avformat_close_input()
-
การค้นหาและเริ่มต้น codec
- ค้นหาตัวถอดรหัสที่ตรงกับ codec ID ของ AVStream ด้วย
avcodec_find_decoder()
- สำหรับสตรีมวิดีโอ แสดงความละเอียด (width, height); สำหรับสตรีมเสียง แสดงจำนวนช่องและ sample rate
- สร้าง AVCodecContext ด้วย
avcodec_alloc_context3()
- นำพารามิเตอร์ codec ของสตรีมไปใช้กับ decoder context ด้วย
avcodec_parameters_to_context()
- เปิดตัวถอดรหัสด้วย
avcodec_open2()
-
การอ่านแพ็กเก็ตและถอดรหัส
- จัดสรรโครงสร้าง
AVPacket และ AVFrame เพื่อเก็บแพ็กเก็ตที่เข้ารหัสแล้วและเฟรมที่ถอดรหัสแล้วตามลำดับ
- อ่านแพ็กเก็ตจากไฟล์อินพุตตามลำดับด้วย
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 repository
- บิลด์ได้ด้วย meson และ ninja (
pip3 install meson ninja)
- เมื่อรัน
meson setup build จะดาวน์โหลดและตั้งค่า FFmpeg อัตโนมัติ
- หลังบิลด์ด้วย
ninja -C build ให้รันด้วย ./build/ffmpeg-101 sample.mp4
- ผลลัพธ์การรันจะแสดงฟอร์แมตไฟล์ ข้อมูลสตรีม (วิดีโอ/เสียง) codec ความละเอียด sample rate ค่า PTS ของแต่ละแพ็กเก็ต และข้อมูลเฟรมที่ถอดรหัสแล้ว
-
สรุปตัวอย่างเอาต์พุต
- สตรีมวิดีโอ: H.264 (avc1), ความละเอียด 206x80, frame rate 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 ไว้ในระบบ ระบบจะดาวน์โหลดและตั้งค่าให้อัตโนมัติ
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ขอแนะนำอย่างยิ่ง บทแนะนำของ Leandro Moreira สำหรับคนที่อยากเข้าใจการทำงานภายในของ FFmpeg และ libav แบบลึกซึ้ง
สำหรับผม นี่คือคำอธิบายที่ครบถ้วนและชัดเจนที่สุดเท่าที่เคยเห็นมา
ลิงก์บทแนะนำ FFmpeg-libav
น่าตกใจที่ตอนนี้ถึงขั้น ffmpeg 101 แล้ว รู้สึกเหมือน ffmpeg 8 เพิ่งออกเมื่อวานนี้เอง
มีการแชร์คู่มืออีกอันหนึ่ง
ลิงก์คู่มือที่เกี่ยวข้องบน HN
FFmpeg เป็น เครื่องมือที่รักมาก จริง ๆ
เป็นบทนำ ffmpeg ที่ยอดเยี่ยมมาก ขอบคุณ
ffmpeg คือ ซูเปอร์พาวเวอร์ ที่แท้จริง
ผมใช้มันเสมอเวลาต้อง ประกอบ ชิ้นส่วนวิดีโอหลาย ๆ ชิ้นให้เป็นรูปแบบที่เล่นได้