9 คะแนน โดย GN⁺ 2025-01-15 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • งานของ FFmpeg มักมีชุดตัวเลือกที่ซับซ้อนได้ง่าย แต่ FFmpeg By Example เป็นเว็บไซต์เอกสารที่ช่วยให้ค้นหาวิธีประมวลผลสื่อที่ต้องการได้อย่างรวดเร็วจากตัวอย่างคำสั่งจริง
  • มีทั้งที่เก็บ GitHub, คอมมูนิตี้ Discord และหน้าสำหรับการมีส่วนร่วม เพื่อให้ผู้ใช้สามารถ ส่ง ไอเดียการใช้งาน FFmpeg ใหม่ ๆ ได้ด้วยตนเอง
  • เช่นตัวอย่างฟิลเตอร์ testsrc ที่แสดงแหล่งอินพุต ความละเอียด เฟรมเรต และไฟล์เอาต์พุตได้ในคำสั่งเดียว ทำให้ลองทำตามโครงสร้างคำสั่งได้โดยตรง
  • ตัวอย่างครอบคลุม งานประมวลผลสื่อ โดยรวม เช่น การคำนวณบิตเรต, การปรับขนาดรูปภาพ, การลดนอยส์เสียง, เอฟเฟกต์ทรานซิชัน, การแมปสตรีม, การเร่งความเร็วด้วยฮาร์ดแวร์ และการจัดการเมทาดาทา
  • แต่ละตัวอย่างถูกแยกเป็นแท็กและหน้าเฉพาะ ทำให้ค้นหาคำสั่ง FFmpeg ที่ต้องการตามฟิลเตอร์เฉพาะหรือเป้าหมายการแปลงได้ง่าย

เว็บไซต์เอกสาร FFmpeg ที่เน้นตัวอย่าง

  • FFmpeg By Example เป็นเว็บไซต์ที่รวบรวมวิธีใช้ FFmpeg หลายรูปแบบเป็นรายตัวอย่าง
  • มีลิงก์สำหรับการมีส่วนร่วมของคอมมูนิตี้และการส่งผลงานด้วย

ตัวอย่างสร้างวิดีโอทดสอบด้วย testsrc

  • Generate test video color pattern with 'testsrc' filter เป็นตัวอย่างการสร้างวิดีโอแพตเทิร์นสีสำหรับทดสอบด้วยฟิลเตอร์ testsrc
  • คำสั่งนี้สร้างวิดีโอ 10 วินาที ความละเอียด 1280x720 ที่ 30fps เป็นไฟล์ testsrc.mpg โดยใช้ อินพุต lavfi
ffmpeg -f lavfi -i testsrc=duration=10:size=1280x720:rate=30 testsrc.mpg

การเข้ารหัส การแปลง และการเร่งความเร็วด้วยฮาร์ดแวร์

การประมวลผลเสียง

รูปภาพและแอนิเมชัน

ฟิลเตอร์และเอฟเฟกต์ภาพ

การแยก การวิเคราะห์ และเมทาดาทา

แหล่งกำเนิดที่สร้างขึ้นและ output pipe

1 ความคิดเห็น

 
GN⁺ 2025-01-15
ความคิดเห็นจาก Hacker News
  • ความสนุกในการใช้ ffmpeg เพิ่มขึ้น 1000%
    เมื่อก่อนต้องน่าเบื่อกับการ Google หาและประกอบคำตอบจาก Stack Overflow เพื่อสร้างคำสั่ง แต่ตอนนี้ ChatGPT เขียนคำสั่งให้แทน สะดวกขึ้นมาก

    • เพราะ LLM ทำให้ใช้ ffmpeg หลายครั้งต่อสัปดาห์
      เป็นการใช้งานที่ดีที่สุดของเครื่องมือ llm cmd ของผม:

      uv tool install llm
      llm install llm-cmd

      llm cmd use ffmpeg to extract audio from myfile.mov and save that as mp3

      https://github.com/simonw/llm-cmd

    • ผมเก็บ ffmpeg ไว้ในกล่องเดียวกับ regex มานานแล้ว: ความรู้สึกแบบ “ควรจะเรียนจริง ๆ แต่คงจะเกลียดมันมากแน่ ๆ”
      แล้ว ChatGPT ก็โผล่มาแก้ให้ทั้งสองอย่าง

    • ผมก็เหมือนกัน งานแบบนี้ AI รับช่วงไปหมดแล้ว ส่วนผมเป็นแค่ตัวกลางที่คัดลอกแล้ววาง error trace เท่านั้น

    • มีเครื่องมืออื่นออกมาเยอะแล้วเหมือนกัน แต่ผมเพิ่งทำสคริปต์ที่ช่วยทำให้ คำสั่งแบบต่อเนื่องเป็นลูกโซ่ แบบนี้ง่ายขึ้นพอสมควร: llmpeg https://github.com/jjcm/llmpeg
      ถ้าติดตั้ง ffmpeg ไว้แล้ว และตั้งค่า API key ใน environment variable ของ OpenAI ไว้ ก็น่าจะใช้งานได้ทันที

      เดโม: https://image.non.io/1c7a92ef-0917-49ef-9460-6298c7a9116c.we...

    • พอได้เรียนรู้ว่า complex filters ทำงานอย่างไร ประสบการณ์การใช้ ffmpeg ก็ดีขึ้นอีก

  • นึกขึ้นได้ว่าควรเขียนและเผยแพร่วิธีแปลง วิดีโอเทปครอบครัว ที่ทำเป็นดิจิทัลแล้ว ให้กลายเป็นคลิปด้วย scene detection
    เผื่อมีใครค้นหา เลยฝาก gist ที่เคยใช้แล้วทำงานได้ค่อนข้างดีไว้ [0] แต่มีบางครั้งที่มันหลงกับแสงแฟลชกล้องหรือภาพสั่น จึงต้องให้ไฟล์ต้น/ท้ายแยกต่างหาก แล้วใช้ ffmpeg ต่อกลับเข้าด้วยกันอีกที [1]

    จุดแปลกคือในอัปเดต Mac รุ่นล่าสุด ประสิทธิภาพดีกว่าโดยไม่ต้องใช้ -c:v h264_videotoolbox อาจเป็น performance regression ของ Sequoia ก็ได้ แต่ไม่แน่ใจ แฟล็กที่เทียบเท่าบนเครื่อง Windows ที่มี Nvidia GPU คือ -c:v h264_nvenc สงสัยว่าทำไม ffmpeg ถึงไม่ตรวจจับให้อัตโนมัติ ใช้แบบนี้แล้วได้ ประสิทธิภาพเพิ่มขึ้นประมาณ 8 เท่า
    ช่วงเวลาเดียวที่รู้สึกว่าตัวเองคุ้มเงินเดือนจริง ๆ ในบริษัท คือ ตอนกำลังจะจ่ายเพิ่มแพง ๆ เพื่อใช้ cloud server ที่มี GPU สำหรับประมวลผลวิดีโอ แล้วดันพบว่า ffmpeg ที่ติดตั้งอยู่ถูก คอมไพล์มาโดยไม่มี GPU acceleration

    [0] https://gist.githubusercontent.com/nielsbom/c86c504fa5fd61ae...

    [1] https://gist.githubusercontent.com/jazzyjackson/bf9282df0a40...

    • ปัญหาของ CPU บนคลาวด์คือไม่มี hardware video encoder แบบที่อยู่ใน CPU สำหรับผู้บริโภค จึงต้องขยับไปใช้เครื่อง GPU ที่แพงกว่ามาก
      พูดตามตรง ผมยังไม่ได้ลองเทียบราคาอย่างจริงจังโดยใช้ hardware acceleration บนคลาวด์ เลยสงสัยว่าคุณหมายถึงว่าได้ลองจริงแล้ว และคุ้มค่าต่อราคาหรือเปล่า

    • เคยลองทำ blank scene detection ด้วย ffmpeg
      มีกล้องหันไปทางเส้นทางบินของ SFO และเมื่อลบเฟรมที่ไม่มีการเคลื่อนไหวทั้งหมดออก ก็เหลือเพียงวิดีโอต่อเนื่องของเครื่องบินที่บินผ่าน โดยไม่มีช่วงน่าเบื่อ

    • -c:v h264_nvenc มีประโยชน์สำหรับ batch encoding ที่เข้ารหัสวิดีโอหลายไฟล์พร้อมกัน เพราะช่วยเพิ่ม throughput ของการเข้ารหัสได้
      แต่จากการทดลองแบบจำกัดเมื่อก่อน คุณภาพผลลัพธ์แย่กว่า libx264 เล็กน้อย ไม่รู้ว่ามีวิธีเลี่ยงไหม แต่นี่ไม่ใช่ปัญหาที่ผมเจอคนเดียว

    • เหตุผลที่ ffmpeg ไม่ตรวจจับสิ่งนี้ให้อัตโนมัติ คือ hardware encoding มักมีขอบเขตการตั้งค่าที่แคบกว่า และต้องแลกเปลี่ยนมากกว่า codec แบบซอฟต์แวร์ที่ละเอียดกว่า อีกทั้งแม้ใช้พารามิเตอร์เดียวกันก็ไม่ได้ให้ผลลัพธ์เหมือนกันเป๊ะ
      แถมหลายระบบยังมี hardware API ให้เลือกได้หลายแบบ และความสามารถก็แตกต่างกัน

      FFmpeg เป็นเครื่องมือ command line ที่ซับซ้อน และมุ่งเป้าไปยังผู้ใช้ที่เต็มใจเรียนรู้รายละเอียด จึงไม่แน่ใจว่าการตั้งค่า default บนพื้นฐานของการคาดเดาจะเหมาะหรือไม่

    • ดูจาก snippet แล้วเหมือนจะไม่ได้ทำ deinterlace
      ถ้าคลิปก่อนทำดิจิทัลถูก deinterlace ไว้แล้วก็ไม่เป็นไร แต่ถ้าไม่ใช่ ก็เท่ากับกำลังทำลายคุณภาพโดยเข้ารหัสไฟล์ interlaced ให้เป็น progressive ควรลองเพิ่มฟิลเตอร์ bwdif เพื่อให้คอนเทนต์ 30i ถูกเข้ารหัสเป็น 60p น่าจะดูใกล้เคียงวิดีโอเทปต้นฉบับมากกว่า

  • เมื่อเวลาผ่านไป ผมค่อนข้างคุ้นกับหลายส่วนของ ffmpeg แล้ว CLI มีตรรกะในแบบของมัน และ ขึ้นกับลำดับ ไม่ใช่ Unix CLI ทุกตัวที่เป็นแบบนั้น
    ช่วงหลัง ๆ ผมลองแตะฟีเจอร์ที่เข้าใจยากขึ้น เช่น การบันทึกวิดีโอดิบจากกล้องวิดีโอลงโดยตรงบนเครื่องที่ค่อนข้างช้า ผมทำกล้องจุลทรรศน์ขึ้นมา และอ่านเฟรมจากกล้องเป็นรูปแบบวิดีโอดิบ (YUYV 1280x720) ที่ 120FPS ถ้าบันทึกลงดิสก์ตรง ๆ ขนาดจะโตเป็นระดับกิกะไบต์ต่อนาที แม้ดิสก์จะถูก แต่ก็รู้สึกสิ้นเปลือง เลยลองดูเทคนิคแบบเกือบ lossless ที่สามารถบีบอัดและบันทึกภาพที่แม่นยำได้อย่างรวดเร็ว

    ผมพบว่าใน ffmpeg การแปลงเป็น RGB24 ช้ามาก หลังจากลองปรับ command line ไปมาหลายแบบ สุดท้ายก็ลงตัวที่คำสั่งนี้:

    ffmpeg -f rawvideo -pix_fmt yuyv422 -s 1280x720 -i test.raw -vcodec libx264 -pix_fmt yuv420p movie.mp4 -crf 13 -y

วิดีโอดิบไม่มีคอนเทนเนอร์ จึงไม่มีเมทาดาทาอย่าง “รูปแบบพิกเซล” หรือ “ขนาดภาพ” ต้องระบุเอง และเพราะมันขึ้นกับลำดับ ทุกอย่างก่อน -i test.raw จะใช้สำหรับการถอดรหัสอินพุต ส่วนทุกอย่างหลังจากนั้นจะใช้สำหรับการเขียนเอาต์พุต ทำการแปลงรูปแบบพิกเซลเล็ก ๆ เพียงอย่างเดียว (ffmpeg จัดการได้เร็วมาก) แล้วเขียนข้อมูลออกเป็นรูปแบบที่มีคอนเทนเนอร์และแทบไม่สูญเสียคุณภาพ ในกรณีส่วนใหญ่คอนเทนเนอร์ .mkv ดีที่สุด

เพราะไม่ชอบ command line สุดท้ายจึงใช้ ffmpeg-python และให้โค้ดต่อไปนี้ประกอบ command line ให้:

self.process = (
ffmpeg.
input(
"pipe:",
format="rawvideo",
pix_fmt="yuyv422",
s="{}x{}".format(1280, 720),
threads=8
)
.output(
fname, pix_fmt="yuv422p", vcodec="libx264", crf=13
)
.overwrite_output()
.global_args("-threads", "8")
.run_async(pipe_stdin=True)
)

แล้วในทางปฏิบัติก็ write() เฟรมเข้าไปที่อินพุตมาตรฐานของโปรเซสนั้น เครื่องมี 12 คอร์ และการขับเคลื่อนกล้องจุลทรรศน์ใช้ขั้นต่ำ 2 คอร์เสมอ จึงต้องจำกัดจำนวนเธรด

ยังหาการเข้ารหัส YUV แบบ lossless ที่ดีกว่าและเร็วกว่าอยู่

  • การที่มันขึ้นกับลำดับนั้นเหมาะสมแล้ว เพราะ Unix pipeline ก็ขึ้นกับลำดับของส่วนประกอบ และการเรียก FFMpeg ที่ซับซ้อนก็ทำอะไรคล้าย ๆ กัน
    หลายคนชอบสุนทรียะของ “fluent interface” อย่าง ffmpeg-python แต่ใน Python มักถูกมองว่าไม่ค่อย Pythonic ผมเข้าใจว่า ffmpeg-python ถูกออกแบบมาให้สะท้อนลำดับของ command line อย่างใกล้เคียง

    ความชอบที่ไลบรารีมาตรฐานและการออกแบบชนิดข้อมูลในตัวช่วยตอกย้ำ คือ https://en.wikipedia.org/wiki/Command%E2%80%93query_separati... อย่างเข้มข้น ถ้าตามหลักการนี้ น่าจะหน้าตาประมาณนี้:

    ffmpeg(global_args=..., overwrite_output=True).process_async(piped_input(...), output(...))

    หากทำให้อินพุตเป็นขั้นตอนการประกอบแยกต่างหาก ก็จะเกิด runtime type อีกแบบ และยังส่งสัญญาณให้โค้ดประมวลผลรู้ว่าต้องอ่านจากอินพุตมาตรฐานได้ด้วย

  • ไม่ต้องหาเพิ่มแล้ว: FFV1 https://trac.ffmpeg.org/wiki/Encode/FFV1

  • อยากแนะนำคำเดียว: RAM disk
    ถ้ามีไฟล์ที่ต้องใช้ประมวลผลขั้นกลาง แต่ไม่อยากเก็บไว้ ก็คือ RAM disk นี่แหละ ดีจริง ๆ

  • คิดว่าจะเป็นเว็บไซต์ที่รวบรวมและดูแลความรู้ที่ผู้เชี่ยวชาญ FFmpeg สั่งสมมา แต่พอกดตัวอย่างแรกก็ผิดหวังทันที
    https://www.ffmpegbyexample.com/examples/l1bilxyl/get_the_du...

    ไม่ควรเรียกเครื่องมือเพิ่มอีกตั้งสองตัวเพื่อประมวลผลสตริง แค่ FFprobe ก็ให้ระยะเวลาหรือค่าที่ต้องการได้โดยตรง:

    ffprobe -loglevel quiet -output_format csv=p=0 -show_entries format=duration video.mp4

    อย่าหยุดอยู่แค่สิ่งแรกที่ใช้งานได้ หลังจากมันทำงานแล้วควรคิดต่อว่ามีวิธีปรับปรุงให้ดีขึ้นไหม

    • ผมเป็นผู้เขียนบทความต้นฉบับเอง คิดว่าเรียกว่า “บ้า” นี่อาจจะเกินไปหน่อย
      แต่ก็ชอบวิธีแก้ที่เสนอมากกว่าเหมือนกัน
  • ดีเลย ทำให้นึกถึง ชีตสรุป ffmpeg ที่ผมใช้ คนที่ใช้ ffmpeg บ่อย ๆ น่าจะมีชุดโน้ตคล้าย ๆ กันทุกคน
    https://github.com/fastily/cheatsheet/blob/master/ffmpeg.md

  • FFmpeg เป็นหนึ่งในเครื่องมือที่ใช้ไม่บ่อยพอจนไวยากรณ์ที่ถูกต้องไม่เคยติดหัวเลย สุดท้าย command line ที่ต้องใช้ก็ให้ LLM ช่วยเขียนให้
    เครื่องมือเดียวที่ลำบากพอ ๆ กันคือ MegaCLI สไตล์ยุค 1990 ของ LSI Logic ใช้มันแทบไม่กี่ครั้งต่อปีเหมือนกัน แต่เป็นของที่ต้องพิมพ์ให้ถูกภายใต้ความกดดัน

    • ใช้ FFMPEG มามากกว่า 15 ปีแล้ว แต่ก็ยังจำคำสั่งแทบไม่ได้ ถึงอย่างนั้น LLM ก็ยอดเยี่ยมจริง ๆ เวลาใช้กับ FFMPEG
      บอก ChatGPT กับ Claude ว่า “remux วิดีโอเป็น mkv, ใส่ subtitle.srt เข้าไปในไฟล์ และต้องการแค่ช่วง 0:00:05 ถึง 0:01:00” มันก็จัดการได้ดีมาก เผื่อสงสัย ผลลัพธ์คือ: ffmpeg -i input.mp4 -i subtitle.srt -ss 00:00:05 -to 00:01:00 -map 0 -map 1 -c copy -c:s mov_text output.mkv

      ถ้าเป้าหมายมีแค่สร้างคำสั่ง ffmpeg อย่างเดียว จะสร้าง LLM ให้เล็กได้แค่ไหนกันนะ อาจเล็กพอจะเอาไปวางบนหน้าเว็บแบบ static แล้วรันในเครื่องได้หรือเปล่า?

    • ผมดูแล เอกสารโน้ตส่วนตัว ที่รวมไวยากรณ์ที่ใช้บ่อยมา 15 ปีแล้ว ถ้ายังไม่ได้ผลก็ grep ประวัติ bash เอา

    • ผมก็เหมือนกัน สิ่งเดียวที่จำได้คือการแปลงจากรูปแบบ X เป็น .mp4 ที่เหลือต้องค้นใหม่ทุกครั้ง
      XKCD ที่เกี่ยวข้อง https://xkcd.com/1168/

    • เมื่อไม่กี่วันก่อน ผมพูดแบบครึ่งล้อเล่นครึ่งจริงจังว่า ถ้า LLM แค่บอก flag ของ ffmpeg ที่ผมต้องการได้ การ เผาป่าฝนให้หมด ก็อาจคุ้มค่าก็ได้

  • อย่าลืมว่ายังมี GStreamer ด้วย เพราะเป็นแบบ pipeline คำสั่ง command line และเอกสารจึงเข้าใจง่ายกว่า ffmpeg เล็กน้อย และการประกอบใช้งานก็ดูสมเหตุสมผลกว่า
    สำหรับงานวิดีโอหนัก ๆ ผมเลิกใช้ ffmpeg ไปเลย แล้วใช้แต่ GStreamer

    • GStreamer สามารถให้การควบคุมที่มากกว่าและ API ที่เป็นมิตรกว่าเมื่อสร้าง pipeline ด้วยการเขียนโปรแกรม
      แต่สำหรับงานครั้งเดียว ffmpeg ดูเป็นมิตรกว่ามาก ตัวอย่างเช่น ffmpeg มีค่าเริ่มต้น x264 ที่สมเหตุสมผล แต่ถ้าจะเข้ารหัส x264 คุณภาพดีด้วย gst-launch ต้องรู้จริง ๆ ว่ากำลังทำอะไรอยู่
    • ผมนึกว่า FFmpeg ก็เป็นแบบ pipeline เหมือนกัน ไม่ใช่ว่ามี filter graph หรือ? ผมพลาดอะไรไปหรือเปล่า
      มันสามารถประกอบกราฟซับซ้อนของ source, sink และ filter สำหรับแปลงข้อมูลได้
    • GStreamer ให้ความรู้สึกเหมือนเป็น โปรเจกต์ที่ถูกปล่อยทิ้งไว้ ช่วงนี้ก็มีช่องโหว่ใหญ่ และเอกสารก็ค่อนข้างพัง
  • มี GitHub repository ของ หนังสือ ffmpeg ที่น่าจะใช้เสริมไซต์นี้ได้ดี:
    https://github.com/jdriselvato/FFmpeg-For-Beginners-Ebook

  • ffmpeg มักให้ความรู้สึกเหมือน แอปพลิเคชัน GUI ที่ถูกยัดเยียดให้มาอยู่ในรูปแบบ TUI
    C API ก็เคยลองใช้อย่างไม่ค่อยสบอารมณ์อยู่หลายครั้ง หลาย ๆ ด้านมันก็เข้าใจได้ตามสัญชาตญาณ แต่การแสดงสถานะที่ผิดพลาดทำได้ง่ายเกินไป อยากให้มีเฟรมเวิร์กเข้ารหัส AV1 แบบเรียลไทม์ที่ “แค่ใช้ก็ทำงานได้”

    • โดยพื้นฐานแล้ว นี่แทบจะเป็นเครื่องมือเดียวที่ทำให้ผมมองหา HandBrake ซึ่งเป็นเครื่องมือ GUI ทดแทนก่อน ยกเว้นเฉพาะตอนทำ batch processing
      GUI สำหรับ ffmpeg ล้วน ๆ ก็มีอยู่บ้าง งานวิดีโอมีอะไรบางอย่างที่ command line ไม่เข้ากับวิธีประมวลผลในหัวผม

    • ถ้าเป็น API ขอแนะนำ GStreamer ผมใช้ Rust bindings เลยไม่คุ้นกับ C API มากนัก แต่ดูดี
      มีส่วนที่เยิ่นเย้อเพราะ GObject อยู่บ้าง แต่พอเข้าใจแล้วก็สามารถโต้ตอบกับทุก object ของ API ได้อย่างสม่ำเสมอ มีความซับซ้อนที่จำเป็นเยอะมากจริง ๆ (วิดีโอเป็นเรื่องยาก) แต่การออกแบบ การใช้งานจริง และเอกสารทำไว้ค่อนข้างดี

      สำหรับ use case ทั่วไป Bins (decodebin, transcodebin, playbin) ช่วยให้ทำได้ค่อนข้างง่าย แม้ use case ที่ซับซ้อนกว่านั้นก็เป็นไปได้ด้วยความยืดหยุ่นของการออกแบบ

    • เห็นด้วยกับ insight นี้นะ แต่ TUI เป็นสิ่งที่มีลักษณะกราฟิก ส่วน ffmpeg เป็นแค่ CLI
      ถ้ามีเครื่องมือ TUI ก็คงเจ๋งดี อยากได้อะไรคล้าย https://github.com/Twinklebear/fbed แต่ฟีเจอร์ครบกว่านี้

  • บนระบบ Linux ผมชอบ static build ของ ffmpeg เพราะบางครั้งเวอร์ชันในดิสโทรเก่าเกินไป หรือไม่มีโมดูลที่ชอบใช้รวมมาให้
    เวอร์ชันแบบ containerized นี้มีประโยชน์มาก: https://github.com/wader/static-ffmpeg