ffmprovisr: ชุดสูตรสำหรับสร้างคำสั่ง FFmpeg ได้ง่ายขึ้น
(amiaopensource.github.io)- ffmprovisr เป็นเว็บไซต์ช่วยสร้างคำสั่ง สำหรับผู้ใช้ที่รู้สึกว่าการเขียนคำสั่ง FFmpeg ยาก โดยให้เลือกงานแล้วดูคำสั่งตัวอย่างพร้อมคำอธิบายของแต่ละแฟล็กได้
- สูตรต่าง ๆ แยกองค์ประกอบอย่าง ไฟล์อินพุต, โค้ดेक, ฟิลเตอร์, การแมปสตรีม และคอนเทนเนอร์เอาต์พุต โดยเน้น
ffmpeg,ffplay,ffprobeเป็นหลัก - ขอบเขตที่ครอบคลุมกว้าง ตั้งแต่ รีแรป/ทรานส์โค้ด ไปจนถึงการตัด·ต่อ, ซับไตเติล·ลายน้ำ, ธัมบ์เนล·GIF, ไฟล์ทดสอบ, เมทาดาทา·เช็กซัม·รายงาน QCTools
- ไม่มีระบบค้นหาในตัว แต่มีคำแนะนำให้กางสูตรทั้งหมดแล้วใช้การค้นหาของเบราว์เซอร์เพื่อหา คีย์เวิร์ด ที่ต้องการ
- นอกจาก FFmpeg แล้ว ยังครอบคลุมเครื่องมืออย่าง CDDA ripping, ImageMagick,
flacจึงใช้เป็นชุดคำสั่งภาคปฏิบัติสำหรับ เวิร์กโฟลว์การอนุรักษ์ดิจิทัล ได้
สิ่งที่ ffmprovisr มีให้
- ffmprovisr ลดภาระที่ต้องประกอบคำสั่ง FFmpeg เอง โดยให้คำสั่งตัวอย่างตามงานและคำอธิบายออปชัน
- ผู้ใช้กดปุ่มงานเพื่อไปยังคำสั่งเดี่ยวหรือรายการคำสั่งที่เกี่ยวข้อง จากนั้นตรวจดูคำสั่งตัวอย่างและการทำงานของแต่ละแฟล็กได้
- ตัวหน้าเว็บไม่มีฟีเจอร์ค้นหา และแนะนำให้เปิดสูตรทั้งหมดแล้วใช้
ctrl+fหรือcmd+fเพื่อค้นหาด้วยเบราว์เซอร์ - เชื่อมโยงแหล่งอ้างอิงพื้นฐานอย่าง เว็บไซต์ทางการ ของ FFmpeg, installation instructions ของ Reto Kromer, Command Line Crash Course, และ explainshell.com
- ไลเซนส์คือ Creative Commons Attribution 4.0 International License
วิธีพื้นฐานในการอ่านคำสั่ง FFmpeg
- หลังติดตั้ง FFmpeg แล้ว เรียกใช้งานได้โดยพิมพ์
ffmpegใน command prompt - โดยทั่วไปคำสั่งประกอบด้วย คู่ของแฟล็กและค่า
- ใน
-i input_file.extนั้น-iคือแฟล็กที่ระบุไฟล์อินพุต และinput_file.extคือไฟล์เป้าหมาย - ใน
-c:v proresนั้น-c:vระบุการเข้ารหัสสตรีมวิดีโอ และproresคือโค้ดেকที่จะใช้
- ใน
- ชื่อไฟล์เอาต์พุตจะอยู่ท้ายคำสั่ง และระบุด้วยชื่อไฟล์โดยไม่ต้องมีแฟล็กเอาต์พุตแยกต่างหาก
ffmpegบันทึกวิดีโอ ส่วนffplayเล่นวิดีโอที่สร้างขึ้นได้โดยไม่บันทึก- ตัวอย่างการบันทึก SMPTE bars คือ
ffmpeg -f lavfi -i smptebars=size=640x480 -t 5 output_file - ตัวอย่างการเล่น SMPTE bars คือ
ffplay -f lavfi smptebars=size=640x480 - ตัวอย่าง FFmpeg ต้องมี
-i, ระยะเวลาบันทึก-t 5, และไฟล์เอาต์พุต แต่ตัวอย่าง FFplay ไม่ต้องมี-i
- ตัวอย่างการบันทึก SMPTE bars คือ
เช็กพอยต์เพื่อลดข้อผิดพลาด
- ต้องตรวจสอบว่าไฟล์เอาต์พุตเปิดได้ เล่นได้ และมีภาพกับเสียงตรงตามที่ตั้งใจหรือไม่
- นามสกุลเอาต์พุตต้องตรงกับโค้ดекที่ตั้งใจใช้ และบางนามสกุลทำให้ FFmpeg ใช้ค่าเริ่มต้นเป็นโค้ดекบางตัว
- เช่น
.mp4อาจถูกตั้งค่าเริ่มต้นให้เข้ารหัสเป็น H.264
- เช่น
"Error: No such file or directory"อาจเกิดจากไดเรกทอรีผิด, พิมพ์ผิด, ขาดช่องว่าง, หรือแฟล็กติดกันผิดตำแหน่ง- หากต้องการย้ายไปโฟลเดอร์ Downloads บน macOS ให้ใช้
cd $HOME/Downloads - หากคำสั่งที่คัดลอก·วางดูถูกต้องแต่ยังเกิดข้อผิดพลาด แนะนำให้พิมพ์ใหม่เองโดยตรงในบรรทัดคำสั่ง
- หากต้องการย้ายไปโฟลเดอร์ Downloads บน macOS ให้ใช้
"Could not find tag for codec"เกิดขึ้นเมื่อพยายามรีแรปไฟล์ที่มีโค้ดекเสียง·วิดีโอไม่เข้ากันกับนามสกุลเอาต์พุต- สามารถทรานส์โค้ดเป็นโค้ดекที่เหมาะสมก่อน หรือเอา
-c copyออกเมื่อมั่นใจว่านามสกุลจะเข้ารหัสอัตโนมัติเป็นโค้ดекที่ถูกต้อง
- สามารถทรานส์โค้ดเป็นโค้ดекที่เหมาะสมก่อน หรือเอา
"Killed"อาจปรากฏเมื่อไฟล์เกินความจุหน่วยความจำของเซิร์ฟเวอร์- บนเซิร์ฟเวอร์ระยะไกล แก้ได้ด้วยการเพิ่มความจุหน่วยความจำ
- บนเซิร์ฟเวอร์โลคัล ควรรักษาเวอร์ชัน FFmpeg ให้เป็นรุ่นล่าสุด และหลีกเลี่ยงการรันพร้อมกับโปรแกรมอื่นที่ใช้หน่วยความจำมาก
- หากระหว่างใช้ฟิลเตอร์มีข้อความ
"Error splitting argument list: option not found"ให้ตรวจสอบ การใช้เครื่องหมายคำพูด และรูปแบบ filtergraph - ฟิลเตอร์ต้องมีการเข้ารหัสสตรีมใหม่ ดังนั้นอาจเกิดปัญหาได้หากใช้ร่วมกับ
-c copyซึ่งคัดลอกสตรีมไฟล์โดยตรง
Filtergraph, การแมปสตรีม, โค้ดекเริ่มต้น
- เมื่อต้องรันงานแบตช์ FFmpeg ภายในลูป สามารถใส่
-nostdinก่อนอินพุตเพื่อแทนที่พฤติกรรมเริ่มต้นของการโต้ตอบผ่าน standard input ได้- ตัวอย่าง:
ffmpeg -nostdin -i input_file ...
- ตัวอย่าง:
- FFmpeg ตั้งค่า ค่าเริ่มต้นของโค้ดекและพารามิเตอร์โค้ดек ให้โดยอัตโนมัติตามรูปแบบไฟล์เอาต์พุต
.avi: ออดิโอmp3, วิดีโอmpeg4.mkv: ออดิโอac3, วิดีโอ H.264.mov: ออดิโอ AAC, วิดีโอ H.264.mp4: ออดิโอ AAC, วิดีโอ H.264.mpg: ออดิโอmp2, วิดีโอmpeg1video.mxf: ออดิโอpcm_s16le, วิดีโอmpeg2video.wav: ออดิโอpcm_s16le
- Filtergraph คือชุดของชื่อฟิลเตอร์และออปชันที่ตามหลัง
-vfหรือ-af-vfเป็น alias ของ-filter:v- ตัวอย่างฟิลเตอร์วิดีโอคือ
hflipและตัวอย่างฟิลเตอร์เสียงคือamerge - เชื่อมฟิลเตอร์หลายตัวด้วยคอมมา และแยกเชนฟิลเตอร์หลายชุดด้วยเซมิโคลอน
-vf "fieldmatch,yadif,decimate"เป็นเชนฟิลเตอร์หนึ่งชุดที่ใช้สำหรับกระบวนการ inverse telecine- หากมีอินพุตหรือเอาต์พุตมากกว่าหนึ่งรายการ ต้องใช้
-filter_complexแทน-vf - ต้องใช้เครื่องหมายคำพูดแบบตรง และหลีกเลี่ยงเครื่องหมายคำพูดแบบโค้ง
- การแมปสตรีม กำหนดว่าจะรวมสตรีมใดจากไฟล์อินพุตไว้ในเอาต์พุต ไม่ว่าจะเป็นวิดีโอ, ออดิโอ, ซับไตเติล, ข้อมูล หรือสตรีมแนบ
- FFmpeg รู้จักประเภทสตรีม
a,v,s,d,t -map 0:vเลือกสตรีมวิดีโอทั้งหมดจากไฟล์อินพุตไฟล์แรก-map 0:3เลือกสตรีมที่สี่จากไฟล์อินพุตไฟล์แรก-map 0:a:2เลือกสตรีมเสียงที่สามจากไฟล์อินพุตไฟล์แรก- หากไม่ระบุการแมป ค่าเริ่มต้นสำหรับไฟล์วิดีโอคือดึงเฉพาะวิดีโอ 1 สตรีมและออดิโอ 1 สตรีมไปเป็นเอาต์พุต
- หากต้องการแมปสตรีมทั้งหมด ให้ใช้
-map 0 - หากเติม
?เช่น-map 0:a?จะทำให้ไฟล์ที่ไม่มีออดิโอระหว่างการประมวลผลแบบแบตช์ดำเนินต่อได้โดยไม่เกิดข้อผิดพลาด
- FFmpeg รู้จักประเภทสตรีม
การเปลี่ยนคอนเทนเนอร์และการแปลงรหัส
- การ rewrap ไฟล์ทำได้ด้วย
ffmpeg -i input_file.ext -c copy -map 0 output_file.ext- ย้ายข้อมูลวิดีโอ·เสียง·ซับไตเติลภายในไปยังรูปแบบคอนเทนเนอร์อื่นโดยไม่เปลี่ยนแปลงข้อมูลเหล่านั้น
- การ rewrap เรียกอีกอย่างว่า remuxing หรือ re-multiplexing
- ต้องใช้
-map 0เพื่อเก็บสตรีมทั้งหมดไว้ได้ เช่น แทร็กเสียงหลายแทร็ก - คอนเทนเนอร์บางชนิดรองรับได้เฉพาะการเข้ารหัสสตรีมบางแบบ จึงอาจ rewrap โดยไม่เข้ารหัสใหม่ไม่ได้
- การสร้าง Broadcast WAV ใช้
-write_bext 1และ-metadata field_name='Content'เพื่อบันทึก BEXT chunk และเมทาดาทาที่เกี่ยวข้อง- ฟิลด์ที่ใช้บ่อยคือ
description,originator,originator_reference,origination_date,origination_time,coding_history,IARL - ฟิลด์เมทาดาทา BWF มีข้อจำกัดจำนวนอักขระ โดย
OriginatorReferenceยาวได้สูงสุด 32 ตัวอักษร
- ฟิลด์ที่ใช้บ่อยคือ
- เมื่อ rewrap วิดีโอ codec DV เป็นไฟล์
.dvให้ใช้-f rawvideo -c:v copyเพื่อหลีกเลี่ยงการลบเมทาดาทาแหล่งที่มาในสตรีม DV โดยไม่ตั้งใจ - ตัวอย่างการแปลงรหัส Apple ProRes LT คือ
-c:v prores -profile:v 1 -vf yadif -c:a pcm_s16le- โปรไฟล์ ProRes 422 แยกเป็น
0Proxy,1LT,2Standard,3HQ - คอนเทนเนอร์ ProRes ที่ FFmpeg รองรับคือ QuickTime
.mov, Matroska.mkv, MXF.mxf
- โปรไฟล์ ProRes 422 แยกเป็น
- ตัวอย่างการแปลงรหัส H.264 คือ
-c:v libx264 -pix_fmt yuv420p -c:a aac- ค่าเริ่มต้นของ
libx264คือ presetmediumและ CRF 23 -pix_fmt yuv420pระบุ chroma subsampling 4:2:0 เพื่อความเข้ากันได้กับ QuickTime และเครื่องเล่นส่วนใหญ่ที่ไม่ได้อิง FFmpeg- สำหรับการปรับให้เหมาะกับการสตรีม ให้เพิ่ม
-movflags +faststart - ตัวอย่างคุณภาพที่สูงขึ้นคือ
-preset veryslow -crf 18และ CRF 18 มักถือว่า “สูญเสียคุณภาพทางสายตาน้อยจนมองไม่เห็น”
- ค่าเริ่มต้นของ
- การเข้ารหัส H.264/H.265 บน Nvidia GPU ใช้
h264_nvencหรือhevc_nvenc- ฮาร์ดแวร์ fixed-function ของ Nvidia อาจมีประสิทธิภาพมากกว่าการเข้ารหัสด้วย CPU ถึง 10 เท่า แต่การปรับคุณภาพที่บิตเรตต่ำต้องใช้พารามิเตอร์มากขึ้น
- HEVC ถูกอธิบายว่าเป็น codec ที่มีประสิทธิภาพมากกว่าและรองรับบน GPU ตั้งแต่ราวปี 2015 เป็นต้นมา
- การแปลงรหัส H.265/HEVC ใช้
-c:v libx265 -pix_fmt yuv420p -c:a copy- ค่าเริ่มต้นของ
libx265คือ presetmediumและ CRF 28 - CRF 28 ของ H.265 เทียบเท่ากับ CRF 23 ของ H.264 และขนาดไฟล์อาจลดลงเหลือประมาณครึ่งหนึ่ง
- ค่าเริ่มต้นของ
- ตัวอย่างแบบ lossless เพื่อการเก็บรักษาคือคำสั่งที่ใส่ FFV1 Version 3 ลงในคอนเทนเนอร์ Matroska และสร้าง
framemd5ของอินพุตไปพร้อมกัน-map 0แมปสตรีมทั้งหมด-dnยกเว้นสตรีมข้อมูลที่ Matroska ไม่อนุญาต-slicecrc 1เพิ่มข้อมูล CRC เพื่อให้ decoder ตรวจพบ slice ที่เสียหายได้-f framemd5 -anสร้าง checksum MD5 แยกตามเฟรมวิดีโอ
การเปลี่ยนคุณสมบัติวิดีโอ·เสียง
- สูตรเปลี่ยนอัตราส่วนภาพใช้ฟิลเตอร์ padding
- เมื่อทำ 4:3 ให้เป็น 16:9 ให้ใช้ pillarbox
- เมื่อทำ 16:9 ให้เป็น 4:3 ให้ใช้ letterbox
- วิดีโอที่ไม่มีเสียงสามารถใช้
-anแทน-c:a copyได้
- ตัวอย่างการแปลง SD เป็น HD ใช้ฟิลเตอร์สามตัวคือ
colormatrix=bt601:bt709,scale=1440:1080:flags=lanczos,pad=1920:1080:240:0- เปลี่ยนค่าสัมประสิทธิ์ความสว่างจาก Rec. 601 เป็น Rec. 709
- การสเกลแบบ Lanczos ช้ากว่า bilinear ที่เป็นค่าเริ่มต้น แต่ให้ผลลัพธ์ดีกว่า
- แนะนำให้ deinterlace แหล่งวิดีโอแบบ interlaced ด้วย
yadifก่อนสเกล
- อัตราส่วนภาพที่ใช้แสดงผลสามารถเปลี่ยนในระดับคอนเทนเนอร์ได้ด้วยตัวเลือกอย่าง
-aspect 4:3- เมื่อใช้ร่วมกับ
-c:v copyจะส่งผลต่ออัตราส่วนภาพที่บันทึกในคอนเทนเนอร์ ไม่ใช่อัตราส่วนภาพในเฟรมที่เข้ารหัสไว้
- เมื่อใช้ร่วมกับ
- การแปลง color space ใช้ฟิลเตอร์
colormatrix=src:dst- ค่าที่อนุญาตรวมถึง
bt601,smpte170m,bt470bg,bt709,bt2020 - การฝังเมทาดาทา color space ใช้
-color_primaries,-color_trc,-colorspace - ต้องระวัง เพราะสามารถติดแท็ก Rec.709 ให้กับไฟล์ที่เป็น Rec.601 จริงได้
- แท็กเมทาดาทาถูกบันทึกโดย
libx264หรือlibx265จึงเพิ่มโดยไม่เข้ารหัสใหม่ไม่ได้
- ค่าที่อนุญาตรวมถึง
- การเปลี่ยนความเร็วใช้
setptsและatempoร่วมกัน- ตัวอย่างคือการสร้างสำเนาแบบ PAL ที่เปลี่ยน 24fps เป็น 25fps โดยยังรักษา pitch ของเสียงไว้
- การทำ fade ใช้ฟิลเตอร์
fadeและafadeและเนื่องจากใช้ฟิลเตอร์จึงต้องเข้ารหัสวิดีโอและเสียงใหม่ - การแยกเสียงใช้
-c:a copy -vnเพื่อแยกสตรีมเสียงออกมาแบบไม่สูญเสียคุณภาพโดยไม่มีวิดีโอ - การรวมแทร็กเสียงสองแทร็กใช้
amergeและ-filter_complex- อาจมีประโยชน์กับกระบวนการถัดไปที่คาดหวังแทร็กเสียงเดียว เช่น คำบรรยายอัตโนมัติของ YouTube
- เพื่อยืนยันแทร็กที่ต้องการ แนะนำให้รัน
ffprobeก่อนเขียนสคริปต์
- การวิเคราะห์และปรับระดับความดังใช้ฟิลเตอร์
loudnorm- เอาต์พุต JSON สามารถใช้เป็นค่าอินพุตสำหรับการปรับระดับแบบ 2-pass ได้
- อธิบายว่าค่าเริ่มต้นสอดคล้องกับระดับความดังเป้าหมายที่ PBS แนะนำ
- 1-pass เร็วกว่า แต่แม่นยำน้อยกว่า 2-pass
- ยังมีสูตรสำหรับ CD pre-emphasis, RIAA equalization, การ resampling เสียง และการบังคับตีความ WAV 192kHz เป็น 96kHz ด้วย
การตัด การต่อ และเซกเมนต์
- เมื่อต่อไฟล์ที่มีสเปกทางเทคนิคเดียวกัน ให้ใช้ concat demuxer
ffmpeg -f concat -i mylist.txt -c copy output_file- ไฟล์ที่จะรวมต้องใช้ codec และสเปกทางเทคนิคเดียวกัน และต้องพรีวิวไฟล์ผลลัพธ์เสมอ
- หากต้องการใช้ path แบบ absolute ให้เพิ่ม
-safe 0
- เมื่อต่อไฟล์ต่างรูปแบบหรือ codec ให้ใช้ฟิลเตอร์
concatและ-filter_complex- ไฟล์อินพุตอาจต่างกันได้ทั้งคอนเทนเนอร์, codec, chroma subsampling, frame rate ฯลฯ
- ตัวอย่างพื้นฐานจะทำงานได้ถูกต้องเฉพาะกรณีที่มีความละเอียดเท่ากัน
- หาก frame rate ต่างกัน เอาต์พุตอาจกลายเป็น variable frame rate
- หากความละเอียดต่างกัน ให้ปรับให้ตรงกันด้วย
scaleก่อน concat และเมื่อต่อ SD กับ HD อาจทำ pillarbox ให้ SD ได้
- การแบ่งไฟล์จัดการด้วย segment muxer
-segment_time 60สร้างเซกเมนต์ยาวสูงสุดช่วงละ 60 วินาที%03dสร้างชื่อไฟล์เป็นตัวเลข 3 หลักที่เติมศูนย์นำหน้า
- การ trim โดยไม่เข้ารหัสใหม่ใช้
-ss,-to,-t,-c copy,-map 0- codec แบบ interframe เช่น H.264 อาจเริ่มที่จุดใกล้ที่สุดตาม i-frame
-sseof -5คือวิธีคัดลอกจากช่วง 5 วินาทีก่อนจบไฟล์
- การลบความเงียบช่วงต้นของไฟล์เสียงใช้
silenceremove=start_threshold=-57dB:start_duration=1:start_periods=1-57dBถูกเสนอว่าเป็นระดับที่เหมาะสมเมื่อต้องคำนึงถึงเสียงฮิสจากระบบแอนะล็อก- เนื่องจากใช้ฟิลเตอร์ เสียงจึงถูกเข้ารหัสใหม่
- การลบความเงียบช่วงท้ายของไฟล์เสียงทำตามลำดับ
areverse,silenceremove,areverse- เนื่องจาก
silenceremoveเหมาะกับการลบความเงียบช่วงต้นมากกว่า จึงกลับเสียงก่อนแล้วค่อยกลับคืน
- เนื่องจาก
การประมวลผลวิดีโอแบบอินเทอร์เลซ
- เมื่อสร้างไฟล์เข้าถึง HD H.264 จากแหล่ง SD NTSC ให้ใช้
yadif,scale,pad,format=yuv420pร่วมกันyadifเป็นฟิลเตอร์ดีอินเทอร์เลซscale=1440:1080:flags=lanczosปรับภาพเป็น 1440x1080pad=1920:1080:(ow-iw)/2:(oh-ih)/2เติม padding ให้อินพุต 4:3 พอดีกับเฟรมเอาต์พุต 16:9
- ตัวอย่างดีอินเทอร์เลซทั่วไปคือ
-vf "yadif,format=yuv420p"format=yuv420pระบุ chroma subsampling แบบ 4:2:0 เพื่อความเข้ากันได้ในการเล่น H.264- นอกจาก
yadifแล้ว FFmpeg ยังมี deinterlacer อย่างbwdif,w3fdif,kerndeint,nnedi
- การดีอินเทอร์เลซที่แยก field เป็นเฟรมใช้
idet,bwdif,format=yuv420p- มักใช้เพื่อรักษา cadence ทางภาพของแหล่งที่มาในวิดีโออินเทอร์เลซที่มีการเคลื่อนไหวมาก
idetตรวจจับลำดับ field- โดยค่าเริ่มต้น
bwdifจะส่งออกหนึ่งเฟรมต่อหนึ่ง field
- inverse telecine ใช้
fieldmatch,yadif,decimate- ย้อนกลับ 3:2 pulldown เพื่อกู้วิดีโออินเทอร์เลซ 29.97fps กลับเป็นเฟรมเรต 24fps ของแหล่งฟิล์มต้นฉบับ
- เมื่อนำไปใช้กับไฟล์ 29.97i เฟรมเรตเอาต์พุตจริงจะเป็น 23.976fps
- การเปลี่ยนลำดับ field ใช้
setfield=tffหรือsetfield=bff- เนื่องจากใช้ฟิลเตอร์วิดีโอ จึงไม่สามารถใช้
-c copyได้และต้องเข้ารหัสใหม่
- เนื่องจากใช้ฟิลเตอร์วิดีโอ จึงไม่สามารถใช้
- การตรวจสอบรูปแบบอินเทอร์เลซทำได้ด้วย
ffmpeg -i input_file -filter:v idet -f null -เพื่อวิเคราะห์โดยไม่มีไฟล์เอาต์พุต
ลายน้ำ ซับไตเติล ภาพย่อ GIF
- ลายน้ำข้อความสร้างด้วยฟิลเตอร์
drawtext- ระบุตัวเลือก
fontfile,fontsize,text,fontcolor,alpha,x,y x=(w-text_w)/2:y=(h-text_h)/2จัดวางตรงกลางโดยไม่ขึ้นกับขนาดวิดีโอ
- ระบุตัวเลือก
- ลายน้ำรูปภาพสามารถวางที่มุมขวาบนด้วย
overlay=main_w-overlay_w-5:5 - timecode แบบ burn-in ใช้ตัวเลือก
timecode,box,boxcolor,rateของdrawtext- timecode เริ่มต้นอยู่ในรูปแบบ
hh:mm:ss[:;.]ff
- timecode เริ่มต้นอยู่ในรูปแบบ
- การฝังไฟล์ซับไตเติลใช้
-i subtitles_file -c copy -c:s mov_textmov_textทำงานในคอนเทนเนอร์ MP4 และ MOV- รูปแบบที่คอนเทนเนอร์ MKV รองรับคือ
ASS,SRT,SSA
- ดึงภาพย่อหนึ่งภาพด้วย
-ss 00:00:20 -vframes 1 thumb.png - หากต้องการสร้างภาพย่อทุก 1 นาที ให้ใช้
-vf fps=1/60 out%d.png - เมื่อสร้าง GIF จากลำดับภาพ ให้ใช้
image2,-framerate,-pattern_type glob,scale - GIF คุณภาพสูงสร้างเป็นสองขั้นตอน
- คำสั่งแรกสร้างพาเล็ตแบบกำหนดเองด้วย
palettegen - คำสั่งที่สองใช้พาเล็ตด้วย
paletteuse - วิธีที่ง่ายกว่าคือใช้
-vf "fps=10,scale=500:-1"แต่ dithering จะเห็นชัดกว่าและขนาดไฟล์เล็กกว่า
- คำสั่งแรกสร้างพาเล็ตแบบกำหนดเองด้วย
ลำดับภาพ สโคป OCR
- เมื่อสร้างลำดับภาพเป็นวิดีโอไม่บีบอัด 10-bit ให้ใช้
-f image2 -framerate 24 -i input_file_%06d.ext -c:v v210- เฟรมเรตเริ่มต้นของ demuxer
image2คือ 25fps %06dอ่านชื่อไฟล์ตัวเลขหกหลักตามลำดับจากน้อยไปมาก
- เฟรมเรตเริ่มต้นของ demuxer
- เมื่อรวมไฟล์ภาพและไฟล์เสียงเพื่อสร้างวิดีโอ ให้ใช้
-loop 1,-shortest,-vf scale=1280:720- อาจมีประโยชน์เมื่ออยากอัปโหลดไฟล์เสียงไปยังแพลตฟอร์มอย่าง YouTube
- สามารถใช้
ffplay -f lavfiกับฟิลเตอร์เพื่อแสดงภาพความลึกบิตของเสียง กราฟเดซิเบล พิกเซลที่อยู่นอกช่วงออกอากาศ และ vectorscope ได้ tblend=all_mode=difference128และhstackแสดงความต่างตามเวลาของวิดีโออินพุตสองรายการแบบวางข้างกันxstackใช้สร้างหน้าต่างเอาต์พุตที่ซ้อนแหล่งวิดีโอหลายรายการในแนวตั้งหรือแนวนอน และมีประโยชน์ในกรณีเดียวกับหน้าต่างเอาต์พุตที่vrecordใช้- ตัวอย่าง OCR ใช้ฟิลเตอร์
ocrและdrawtextเพื่อแสดงข้อความที่รู้จำได้บนวิดีโอ - เอาต์พุตข้อมูล OCR แสดงบนหน้าจอในรูปแบบ
ffprobe -show_entries frame_tags=lavfi.ocr.text -f lavfi -i "movie=input_file,ocr"
เมทาดาทา เช็กซัม งานถนอมรักษา
- การดึงเมทาดาทาทางเทคนิคทำด้วย
ffprobe -i input_file -show_format -show_streams -show_data -print_format xml- รูปแบบเอาต์พุตนอกจาก XML แล้วยังใช้ JSON และ flat ได้
- การลบเมทาดาทาใช้
-map_metadata -1 -c:v copy -c:a copy- คัดลอกวิดีโอและเสียง แต่ไม่คัดลอกเมทาดาทา
- การประมวลผลแบบแบตช์ใน Bash ทำด้วยไฟล์
.shและลูปfor- ตัวอย่าง:
for file in *.mxf; do ffmpeg -i "$file" -map 0 -c copy "${file%.mxf}.mov"; done - ไฟล์
.shและไฟล์.mxfเป้าหมายต้องอยู่ในไดเรกทอรีเดียวกัน และต้องรันจากไดเรกทอรีนั้น - สำหรับการประมวลผลแบบ recursive สามารถใช้
find input_directory -iname "*.mxf" -exec ffmpeg -i {} -map 0 -c copy {}.mov \;
- ตัวอย่าง:
- บน Windows ให้ประมวลผลแบบแบตช์ด้วยสคริปต์ PowerShell
.ps1- ตัวอย่างคือสร้างรายการไฟล์
.mp4แล้วเปลี่ยนนามสกุลของแต่ละไฟล์เป็น.mkvเพื่อ rewrap - หากต้องการเรียก
ffmpegโดยไม่ใส่พาธเต็ม ต้องตั้งค่าให้ถูกต้อง
- ตัวอย่างคือสร้างรายการไฟล์
- การตรวจสอบข้อผิดพลาดของตัวถอดรหัสทำโดยถอดรหัสด้วย
ffmpeg -i input_file -f null -โดยไม่มีไฟล์เอาต์พุต และแสดงข้อผิดพลาดบนหน้าจอ - การตรวจสอบ fixity ของ FFV1 Version 3 ใช้
-report -i input_file -f null -เพื่อตรวจหา CRC checksum mismatch- Frame CRC เปิดใช้เป็นค่าเริ่มต้นใน FFV1 Version 3
- วิดีโอ MD5 รายเฟรมสร้างด้วย
-f framemd5 -an - MD5 ตามกลุ่มตัวอย่างเสียงสร้างด้วย
asetnsamples=n=48000 -f framemd5 -vn- มีการเสนอว่าแนวปฏิบัติที่ดีคือให้จำนวนกลุ่มตัวอย่างสอดคล้องกับ sample rate ของสื่อ
- โดยค่าเริ่มต้น เสียงจะถูกทรานส์โค้ดเป็น 16-bit PCM แล้วสร้าง framemd5
- stream MD5 สามารถสร้างได้โดย
-mapสตรีมวิดีโอและเสียงแต่ละสตรีม แล้วใช้-c copy -f md5- ใช้ตรวจสอบความสมบูรณ์ของข้อมูล A/V โดยไม่ขึ้นกับการเปลี่ยนแปลงเมทาดาทาของคอนเทนเนอร์
streamhashส่งออกแฮชแยกตามสตรีมสำหรับทุกสตรีม- มีประโยชน์สำหรับการแฮช mixed born-digital material เพราะไม่จำเป็นต้องรู้ว่ามีสตรีมใดและกี่สตรีม
- รายงาน QCTools สร้าง
.qctools.xml.gzด้วยffprobe -f lavfiและsignalstats,cropdetect,idet,psnr,ssim,ebur128,astatsเป็นต้น- มีคำสั่งแยกสำหรับไฟล์ที่มีเสียงและไม่มีเสียง
- การดึง closed caption EIA-608 Line 21 ใช้ฟิลเตอร์
readeia608และffprobeเพื่อส่งออกค่า hex เป็น CSV
ไฟล์ทดสอบและตัวอย่าง FFmpeg อื่น ๆ
- สร้างหรือเล่นวิดีโอทดสอบได้ด้วยอินพุต lavfi เช่น
mandelbrot,smptebars,testsrc,smptehdbars- ตัวอย่าง Mandelbrot เป็นเอาต์พุต H.264 ขนาด 1280x720, 25fps, 10 วินาที
- ตัวอย่าง SMPTE bars เป็นเอาต์พุต ProRes ขนาด 720x576, 25fps, 10 วินาที
- การเล่น HD SMPTE bars คือ
ffplay -f lavfi -i smptehdbars=size=1920x1080 - การเล่น VGA SMPTE bars คือ
ffplay -f lavfi -i smptebars=size=640x480
- เสียงทดสอบคลื่นไซน์สร้างไฟล์ WAV ด้วย
sine=frequency=1000:sample_rate=48000:duration=5และpcm_s16le - วิดีโอทดสอบที่รวม SMPTE bars กับคลื่นไซน์ 1kHz ใช้อินพุต lavfi สองตัว พร้อม
-c:v ffv1,-c:a pcm_s16le - ไฟล์ทดสอบความเสียหายจงใจทำให้เนื้อหาแพ็กเก็ตเสียหายด้วย
-bsf noise=1 -c copyแต่ไม่ทำให้คอนเทนเนอร์เสียหาย - Conway's Game of Life จำลองด้วย
ffplay -f lavfi life=...และหากใช้ffmpegกับ-t 5ก็สามารถบันทึกบางช่วงได้ - การเปรียบเทียบความคล้ายเชิงการรับรู้ของวิดีโอสองไฟล์ใช้ฟิลเตอร์
signature=detectmode=full:nb_inputs=2 - แฮชเชิงการรับรู้ของวิดีโออินพุตสร้างเป็นไฟล์ XML ด้วย
signature=format=xml:filename="output.xml" - ลำดับภาพสามารถเล่นได้ทันทีโดยไม่ต้องสร้างวิดีโอด้วย
ffplay -framerate 5 input_file_%06d.ext - การแยกแทร็กเสียงและวิดีโอใช้
-map 0:v:0และ-map 0:a:0 - การรวมแทร็กเสียงและวิดีโอใช้
-map 0:v -map 1:a -c copyเพื่อรวมวิดีโอจากไฟล์แรกกับเสียงจากไฟล์ที่สอง - ไฟล์ MPEG สำหรับสร้าง ISO เพื่อเข้าถึงแบบ DVD สร้างด้วย
-aspect 4:3 -target ntsc-dvd output_file.mpgและต้องติดตั้งdvdauthor - CSV สำหรับการตรวจจับฉากบนพื้นฐาน YDIF ส่งออกค่าของ
lavfi.signalstats.YDIFจากffprobeและsignalstats - head switching noise สามารถปิดบังได้โดยวาดกล่องสีดำที่ด้านล่างของเฟรมด้วย
drawbox=w=iw:h=7:y=ih-h:t=max - หากต้องการไลฟ์สตรีมไปยังปลายทาง RTMP พร้อมบันทึก MP4 ในเครื่องพร้อมกัน ให้ใช้
teemuxer- สเกลอินพุตให้กว้าง 1280px และจบสตรีมหลังเวลาที่กำหนด
- ตัวอย่างมีบันทึกว่าถูกใช้ทุกวันในการไลฟ์สตรีมรายการทีวีจริงเป็นเวลาประมาณ 4 ปี
- ข้อมูลของดีโคเดอร์ เอนโคเดอร์ demuxer, muxer และฟิลเตอร์เฉพาะ ตรวจสอบได้ด้วย
ffmpeg -h type=name- ตัวอย่างคือ
encoder=libx264,decoder=mp3,muxer=matroska,demuxer=mov,filter=crop
- ตัวอย่างคือ
เครื่องมือที่เกี่ยวข้องซึ่งแนะนำร่วมกับ FFmpeg
- เครื่องมือริป CDDA ครอบคลุมการตรวจสอบออฟเซ็ตของไดรฟ์ CD และการริป Audio CD อย่างแม่นยำ
- ไดรฟ์ CD ต่างรุ่นกันมีตำแหน่งเริ่มอ่านไม่เหมือนกัน จึงต้องชดเชยออฟเซ็ตเพื่อตรวจสอบ checksum ของเนื้อหาเดียวกัน
- การระบุไดรฟ์ตรวจสอบได้ด้วย
cdda2wav -scanbus,cdda2wav,cdparanoia -vsQ - หาออฟเซ็ตได้จาก Accurate Rip CD drive offset list
- เครื่องมือ GUI สำหรับ macOS แนะนำ XLD
- การริปด้วย CD Paranoia ใช้
cdparanoia -L -B -O [Drive Offset] [Starting Track Number]-[Ending Track Number] output_file.wav-Bคือโหมด batch ที่แยกแทร็กเป็นไฟล์ต่างหากโดยอัตโนมัติ
- Cdda2wav เป็นเครื่องมือที่ใช้ Paranoia library เพื่อริป Audio CD อย่างแม่นยำ
- คำสั่งติดตั้งด้วย Homebrew คือ
brew install cdrtools - คำสั่งตัวอย่างริปทั้ง CD เป็น WAV ไฟล์เดียว ค้นหา CDDB และสร้าง cue sheet
- บน macOS ต้อง unmount CD ก่อนรันคำสั่ง
- คำสั่งติดตั้งด้วย Homebrew คือ
- CD emphasis อธิบายว่าเป็นวิธีลดสัญญาณรบกวนที่อาจมีผลกับ CD ยุคต้นทศวรรษ 1980 บางแผ่นและ CD pressing ของญี่ปุ่น
- การตรวจสอบว่ามีอยู่หรือไม่ทำด้วย
cdda2wav -Jหรือcdparanoia -Q - หากต้องการชดเชยระหว่างริปด้วย Cdda2wav ให้เพิ่มแฟล็ก
-T
- การตรวจสอบว่ามีอยู่หรือไม่ทำด้วย
- ImageMagick เป็นชุดซอฟต์แวร์โอเพนซอร์สฟรีสำหรับแสดง แปลง และแก้ไขไฟล์ภาพแรสเตอร์และภาพเวกเตอร์
- เรียกใช้คำสั่งเป็นคำสั่งแยก เช่น
convert,montage,mogrify - การเปรียบเทียบภาพใช้
compare -metric ae image1.ext image2.ext null:เพื่อคืนจำนวนพิกเซลที่ต่างกัน - การสร้างภาพขนาดย่อใช้
mogrify -resize 80x80 -format jpg -quality 75 -path thumbs *.jpg - กริดภาพสร้างด้วย
montage @list.txt -tile 6x12 -geometry +0+0 output_grid.jpg - การลบ EXIF ใช้
mogrify -path ./stripped/ -strip *.jpg
- เรียกใช้คำสั่งเป็นคำสั่งแยก เช่น
- เครื่องมือ
flacเป็นเครื่องมือทรานส์โค้ด FLAC และจัดการเมทาดาทาที่สร้างโดยโปรเจกต์ FLAC- มีข้อดีเมื่อเทียบกับเครื่องมืออื่น คือสามารถฝัง foreign metadata อย่าง BWF ได้
- หากต้องการแปลง WAV เป็น FLAC โดยคงเมทาดาทา BWF ไว้ ให้ใช้
flac --best --keep-foreign-metadata --preserve-modtime --verify input.wav - หากต้องการสร้าง BWF ต้นฉบับกลับจาก FLAC ให้ใช้
--decodeแทน--best
1 ความคิดเห็น
ความเห็นจาก Hacker News
อาจจะออกนอกประเด็นไปนิด แต่ผมมองว่า ffmpeg เป็นซอฟต์แวร์ระดับยอดเยี่ยมที่สุดเท่าที่เคยมีมา
วิศวกรผู้มีพรสวรรค์อย่าง Fabrice Bellard คือของขวัญชิ้นใหญ่สำหรับชุมชน FOSS และแม้แต่ยูนิคอร์นมูลค่าราว 2 พันล้านดอลลาร์ที่ผมเคยทำงานด้วยในอดีต ผลิตภัณฑ์ส่วนใหญ่ก็พึ่งพา ffmpeg
https://ffmpeg.org/donations.html
เขายังเป็นคนสร้าง QEMU, TCC, QuickJS และอื่น ๆ ด้วย
พูดจริง ๆ คือ ในช่วงเวลาใดก็ตาม จำนวนอุปกรณ์ที่รันโค้ดที่เขาเขียนนั้นมากจนน่าเหลือเชื่อ
command line ของ ffmpeg ยังทำให้ปวดหัวได้อยู่ดี แม้จะดูไกด์ดี ๆ แล้วก็ตาม เลยอยากแนะนำ VapourSynth
https://www.vapoursynth.com/
มันเป็นเครื่องมือฟิลเตอร์วิดีโอแบบ Python ที่ปรับแต่งมาอย่างดี แต่ก็มีมากกว่านั้นอีกเยอะ: https://vsdb.top/
และ StaxRip ใช้ ffmpeg, VapourSynth รวมถึงเอนโค้ดเดอร์และเครื่องมืออีกหลายสิบตัวได้ดีมาก จนผมยอมรีบูตจาก Linux ไป Windows เพื่อใช้มัน: https://github.com/staxrip/staxrip
มันซับซ้อนเกินจำเป็น และในบางมุมมองโครงสร้างทั้งหมดอาจจะสมเหตุสมผลก็ได้ แต่การที่งานที่พบบ่อยมาก ๆ ต้องรู้ option เหมือนคาถาเวทมนตร์ถึงจะทำได้ มันไม่ค่อยเหมาะ
ผมน่าจะมี bash alias เป็นสิบ ๆ อันที่ย่อคำสั่ง ffmpeg ยาว 150 ตัวอักษรให้เหลือสองคำ
ffprobe ก็ไม่สมเหตุสมผลเหมือนกัน เพราะ 99% คือการรันแบบไม่ใส่ argument เพื่อดูความยาว ความละเอียด frame rate และจำนวนแทร็กเสียงอย่างรวดเร็ว แต่ 99% ของ output กลับเป็นเรื่องที่ไม่เกี่ยวเลยอย่าง compile option
แหล่งข้อมูลที่น่าดูประกอบ:
https://ffmpeg.guide/ — สร้าง filter graph ของ FFmpeg ที่ซับซ้อนได้อย่างรวดเร็วและถูกต้อง
https://www.hadet.dev/ffmpeg-cheatsheet/ — ตัดวิดีโอ เพิ่ม fade in/out, scaling, ต่อวิดีโอ ฯลฯ
ด้วยเหตุผลที่ไม่ทราบ ffmpeg ทำงานต่างกันขึ้นอยู่กับว่า flag
-ssและ-t/-toอยู่ก่อนหรือหลัง-iและในกรณีของผม วางไว้ข้างหน้าจะได้ผลดีกว่าต้นฉบับก็มีปัญหาเดียวกัน
การยัดกราฟที่ไม่เป็นเชิงเส้นเข้าไปใน command line ที่แบนและเป็นเชิงเส้นมันแปลก
แค่มี configuration เป็น JSON ที่ละเอียดขึ้นก็คงดีกว่านี้มาก
มีประโยชน์มาก
ผมเริ่มใช้ ChatGPT ตอนสร้างคำสั่ง ffmpeg แล้วพบว่าสิ่งที่ต้องการได้เร็วและง่ายขึ้นมาก
เลยทำเครื่องมือเล็ก ๆ ให้ใช้ได้จาก command line โดยตรงด้วย: https://github.com/alexkrkn/help-cli
และยังทำวิดีโอที่เกี่ยวข้องไว้ด้วย: https://www.youtube.com/watch?v=pOda6TDBqcY
ช่วงหลังผมหา UI สำหรับ ffmpeg แล้วไปเจอ Shutter Encoder ซึ่งเป็นซอฟต์แวร์โอเพนซอร์สที่ดีมากและรองรับ mac/windows
ในที่สุดก็เริ่มบีบอัดคลังวิดีโอส่วนตัว 15 ปี ขนาด 300GB ของผมแล้ว
https://www.shutterencoder.com/
กำลังบีบอัดทั้งหมดเป็น H.265 และบางครั้งขนาดวิดีโอลดลงเหลือ 1/10 เลย มีเหตุผลอะไรไหมที่ไม่ควรทำแบบนี้? ผมอ่านมาว่าการเล่นวิดีโอที่ถูกบีบอัดต้องใช้พลังประมวลผลมากขึ้น แต่ก็ยังไม่แน่ใจว่าในอนาคตจะเป็นปัญหาใหญ่หรือไม่
ถือเป็นคำเตือนให้ตรวจสอบวิดีโอหลาย ๆ ไฟล์ก่อนลบต้นฉบับ
แต่ถ้าแค่ 300GB พื้นที่เก็บข้อมูลก็ถูกพอแล้ว เก็บต้นฉบับไว้เฉย ๆ ก็ได้
อีกอย่าง สำหรับการใช้กับ Plex แบบไม่ต้อง transcode ในโฮมแล็บของผม H.264 ก็ง่ายกว่าด้วย
ไกด์นี้แนะนำ
yadifเป็นฟิลเตอร์ deinterlacing แต่ในสายตาผม w3fdif ดูดีกว่ามันไม่ทำ motion tracking แบบ yadif จึงค่อนข้างเร็ว และหลีกเลี่ยง artifact ที่น่ารำคาญซึ่ง motion tracking สร้างขึ้นเป็นบางครั้งได้
ผมคิดว่าผลลัพธ์ที่สม่ำเสมอแม้จะกลาง ๆ ยังดีกว่าผลลัพธ์ที่บางครั้งยอดเยี่ยมแต่บางครั้งแย่
อย่างไรก็ตาม ต่างจาก yadif ที่ดูสอง field, w3fdif พิจารณาสาม field พร้อมกัน จึงซ่อน artifact จาก interlacing ได้ดีกว่า
ถ้าจะ re-encode อยู่แล้ว ใช้ QTGMC ไปเลยจะดีกว่า
w3fdif อาจทำให้เกิดอาการกระพริบได้ แต่ yadif ไม่เป็นแบบนั้น ดังนั้น bwdif จึงทำงานเหมือน yadif แต่ใช้การจับคู่ field ที่ดีกว่าของ w3fdif
bwdifเป็น ไฮบริด ของyadifและw3fdifอุปสรรคที่ใหญ่ที่สุดในการเริ่มใช้ ffmpeg น่าจะเป็น เครื่องมือฟรีเมียมแบบออฟไลน์ กับเว็บฟรอนต์เอนด์ต่าง ๆ
เว็บไซต์เหล่านั้นทำ SEO ไว้กับวลีที่คนมักพิมพ์ใน Google อย่าง “avi to mp4”, “mp3 to wav”
กว่าจะยอมรับแอปบรรทัดคำสั่งได้ใช้เวลานานกว่าที่คิด เพราะโลกของ Windows สอนมาว่าทุกอย่างควรมี GUI
คนบอกว่า ffmpeg ซับซ้อน แต่ต่อให้ทำเป็น GUI สวย ๆ ก็ไม่ได้ง่ายขึ้นเท่าไร สิ่งที่ซับซ้อนคือ การบีบอัดวิดีโอเอง
ถ้าไม่ใช่วิธีที่ตัดสินใจแทนให้แบบอินเทอร์เฟซคลิก ๆ อย่าง HandBrake ก็คงไม่มีซอฟต์แวร์ไหนทำให้มันง่ายขึ้นได้
ไม่แน่ใจนัก แต่ถ้าเรียนรู้การเข้ารหัสและการบีบอัดวิดีโอดิจิทัลอย่างละเอียดพอแล้ว สิ่งที่ต้องทำใน ffmpeg ก็น่าจะรู้สึกค่อนข้างเป็นธรรมชาติ มีใครเคยทำแบบนี้จริง ๆ ไหม?
ตอนนั้นยังไม่มีรูปแบบอย่าง mkv หรือ codec อย่าง HEVC แต่แนวคิดเรื่องการจัดการเสียง/วิดีโอผ่าน filter หลายตัวนั้นยอดเยี่ยม และซอฟต์แวร์แปลง A/V ส่วนใหญ่ก็ทำงานแบบนั้น
พอเริ่มดูหน้า manual ของ FFmpeg ก็เห็นความเชื่อมโยง และหลังลองเล่นอยู่ราวหนึ่งวันก็ใช้งานได้
อาจเป็นข้อได้เปรียบด้วยที่ชอบบรรทัดคำสั่งและเป็นคนอ่าน man page อยู่แล้ว
ffmpeg ทรงพลังจนใช้บ่อย แต่ โครงสร้าง API ไม่เข้าหัวเลย ถ้ามี LLM ฟรอนต์เอนด์ก็คงดี
เป็นไอเดียที่ดี การทำให้ FFmpeg ทำงานตามที่ต้องการเป็นเรื่องน่ากดดันเสมอ
ChatGPT ช่วยได้อยู่ แต่ก็ไม่ได้สมบูรณ์แบบ
การจำ option และอาร์กิวเมนต์ของ OpenSSL เป็นเรื่องยากมาตลอด ตอนนี้เลยใช้ GPT ไปเลย
เพียงแต่ความแตกต่างเล็ก ๆ น้อย ๆ ระหว่างระบบปฏิบัติการยังเป็นปัญหาเล็ก ๆ ที่เหลืออยู่