5 คะแนน โดย GN⁺ 2025-05-31 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • typed-ffmpeg เป็นอินเทอร์เฟซที่ทำให้ใช้งาน FFmpeg ได้อย่างปลอดภัยตามชนิดใน Python และ TypeScript โดยมีชนิดข้อมูลและเอกสารอย่างละเอียดสำหรับฟิลเตอร์กราฟที่ซับซ้อน
  • ได้แรงบันดาลใจจาก ffmpeg-python แต่เพิ่มความสามารถอย่าง การเติมโค้ดอัตโนมัติใน IDE, การกำหนดชนิดอย่างครอบคลุม, การซีเรียลไลซ์ฟิลเตอร์กราฟเป็น JSON และการตรวจสอบ FFmpeg อัตโนมัติ
  • v4 มีแพ็กเกจ PyPI แยกตาม FFmpeg 5.x~8.x และ typed-ffmpeg หลักจะติดตั้งไบน์ดิงของ FFmpeg 8.x ล่าสุด
  • แพ็กเกจ Python ทำงานได้ด้วยไลบรารีมาตรฐานเท่านั้น แต่การแสดงภาพกราฟและการพาร์ส CLI ต้องติดตั้งเป็น extra option [graph], [parse] ตามลำดับ
  • มี Interactive Playground ให้ทดลองฟิลเตอร์และคำสั่งบนเบราว์เซอร์ พร้อมดูกราฟแบบเรียลไทม์ จึงเรียนรู้และทำต้นแบบได้โดยไม่ต้องตั้งค่าสภาพแวดล้อมในเครื่อง

อินเทอร์เฟซ FFmpeg ที่ typed-ffmpeg มอบให้

  • typed-ffmpeg มอบอินเทอร์เฟซแบบสมัยใหม่และปลอดภัยตามชนิดสำหรับ FFmpeg ทั้งใน Python และ TypeScript
  • รองรับชนิดข้อมูลและเอกสารอย่างละเอียดสำหรับฟิลเตอร์ที่ซับซ้อน และแก้ข้อจำกัดทั่วไปของ ffmpeg-python เช่น การผสานกับ IDE ที่ไม่ดีพอและการขาดการกำหนดชนิดอย่างครอบคลุม
  • ฟีเจอร์ใหม่มีทั้ง การซีเรียลไลซ์ฟิลเตอร์กราฟเป็น JSON และการตรวจสอบ FFmpeg อัตโนมัติ
  • ดูเอกสารได้ที่ Documentation

ฟีเจอร์หลัก

  • Zero Dependencies: สร้างขึ้นด้วย Python standard library เท่านั้น เพื่อเพิ่มความเข้ากันได้และความปลอดภัย
  • อินเทอร์เฟซแบบ Pythonic ช่วยให้การประกอบฟิลเตอร์กราฟง่ายขึ้น
  • รองรับฟิลเตอร์ของ FFmpeg ส่วนใหญ่ตั้งแต่ต้น พร้อมการเติมโค้ดอัตโนมัติใน IDE
  • มี docstring แบบอินไลน์ให้อ้างอิงวิธีใช้ฟิลเตอร์ได้ทันที
  • มีการตรวจสอบชนิดทั้งแบบสแตติกและไดนามิก ช่วยเพิ่มความน่าเชื่อถือของโค้ดและประสบการณ์พัฒนา
  • สามารถบันทึกและโหลดฟิลเตอร์กราฟกลับมาใหม่ใน รูปแบบ JSON
  • การแสดงภาพกราฟด้วย graphviz ช่วยให้เข้าใจและดีบักได้ง่ายขึ้น
  • มีความสามารถช่วยระบุและแก้ไขข้อผิดพลาดของฟิลเตอร์กราฟ
  • มีอินเทอร์เฟซที่ครอบคลุมยิ่งขึ้น รวมถึงตัวเลือกอินพุต/เอาต์พุต โคเด็กเพิ่มเติม และฟอร์แมตต่าง ๆ
  • รองรับ partial evaluation เพื่อให้ประกอบและนำฟิลเตอร์กราฟกลับมาใช้ซ้ำได้แบบโมดูลาร์
  • รองรับในตัวสำหรับการวิเคราะห์ไฟล์มีเดียด้วย ffprobe ของ FFmpeg และดึงเมทาดาต้าผ่านอินเทอร์เฟซแบบ dictionary และ dataclass

โครงสร้างแพ็กเกจแยกตามเวอร์ชัน FFmpeg

  • typed-ffmpeg v4 มีแพ็กเกจ PyPI แยกตามเวอร์ชันหลักของ FFmpeg
    • typed-ffmpeg: เวอร์ชันล่าสุด, ไบน์ดิง FFmpeg 8.x
    • typed-ffmpeg-v5: ไบน์ดิง FFmpeg 5.x
    • typed-ffmpeg-v6: ไบน์ดิง FFmpeg 6.x
    • typed-ffmpeg-v7: ไบน์ดิง FFmpeg 7.x
    • typed-ffmpeg-v8: ไบน์ดิง FFmpeg 8.x
    • ffmpeg-core: รันไทม์ที่ใช้ร่วมกันและจะถูกติดตั้งอัตโนมัติ
  • ทุกแพ็กเกจเปิดเผยเนมสเปซ ffmpeg เดียวกัน ดังนั้นไม่ว่าจะติดตั้งแพ็กเกจเวอร์ชันใด รูปแบบโค้ดก็เหมือนเดิม
  • หากต้องการให้ตรงกับ FFmpeg ที่ติดตั้งอยู่ ให้ตรวจสอบเวอร์ชันด้วย ffmpeg -version | head -1 แล้วติดตั้งแพ็กเกจที่ตรงกัน
  • ดูรายละเอียดโครงสร้างแพ็กเกจ v4 ได้ที่ v4 Package Architecture
  • หากอัปเกรดจาก typed-ffmpeg 3.x ให้ดู Migration Guide

การติดตั้งและ extra option

  • ติดตั้งไบน์ดิง FFmpeg 8.x ล่าสุดด้วยคำสั่งต่อไปนี้
pip install typed-ffmpeg
  • ไบน์ดิงสำหรับ FFmpeg เวอร์ชันเฉพาะติดตั้งเป็นแพ็กเกจแยก
pip install typed-ffmpeg-v5   # FFmpeg 5.x
pip install typed-ffmpeg-v6   # FFmpeg 6.x
pip install typed-ffmpeg-v7   # FFmpeg 7.x
pip install typed-ffmpeg-v8   # FFmpeg 8.x
  • ฟังก์ชันเสริมติดตั้งผ่าน extra
    • [graph]: การแสดงภาพกราฟด้วย Graphviz
    • [parse]: การพาร์ส CLI และรองรับ compile_as_python()
  • extra [parse] จะติดตั้งข้อมูลแคชแยกตามเวอร์ชันตั้งแต่ ffmpeg-data-v5 ถึง ffmpeg-data-v8 ซึ่ง ffmpeg.compile.compile_cli.parse() ต้องใช้ในการประกอบฟิลเตอร์กราฟกลับจากคำสั่ง FFmpeg บนบรรทัดคำสั่ง
  • ผู้ใช้ส่วนใหญ่ไม่จำเป็นต้องใช้ extra [parse]
  • ระบบต้อง ติดตั้ง FFmpeg ไว้แล้ว
  • หากต้องติดตั้งร่วมกับ ffmpeg-python ให้ติดตั้ง typed-ffmpeg-compatible เพื่อหลีกเลี่ยงการชนกันของชื่อโมดูล และใช้ import typed_ffmpeg as ffmpeg

TypeScript binding และตัวอย่างการใช้งาน

  • TypeScript binding ยังเป็นฟีเจอร์เชิงทดลอง และมีแพ็กเกจ npm แยกตามเวอร์ชันหลักของ FFmpeg
    • @typed-ffmpeg/core: คอร์รันไทม์สำหรับ Node.js และเบราว์เซอร์ ESM
    • @typed-ffmpeg/v5: ไบน์ดิง FFmpeg 5.x
    • @typed-ffmpeg/v6: ไบน์ดิง FFmpeg 6.x
    • @typed-ffmpeg/v7: ไบน์ดิง FFmpeg 7.x
    • @typed-ffmpeg/v8: ไบน์ดิง FFmpeg 8.x
  • ติดตั้งไบน์ดิง FFmpeg ล่าสุดด้วยคำสั่งต่อไปนี้
npm install @typed-ffmpeg/core @typed-ffmpeg/v8
  • TypeScript API สะท้อน Python API แต่ใช้รูปแบบที่เป็นธรรมเนียมของ TypeScript เช่น ออบเจ็กต์ options แทน keyword arguments
import { input } from "@typed-ffmpeg/v8";

const cmd = input("input.mp4")
  .video
  .scale({ w: 1280, h: 720 })
  .output("output.mp4")
  .overwriteOutput()
  .compile();
// => ["-i", "input.mp4", "-filter_complex", "...", "output.mp4"]
  • @typed-ffmpeg/core มีทั้ง CJS, ESM และเบันเดิล ESM ที่ปลอดภัยสำหรับเบราว์เซอร์ โดยเลือกให้อัตโนมัติผ่านฟิลด์ exports
  • แต่ละแพ็กเกจเวอร์ชันมี คอมเมนต์ JSDoc ที่ระบุความพร้อมใช้งานของฟิลเตอร์ในแต่ละเวอร์ชันของ FFmpeg

ลำดับการใช้งาน Python และ Playground

  • ตัวอย่างการใช้งานพื้นฐานคือวิเคราะห์ไฟล์มีเดียด้วย ffmpeg.probe() แล้วพลิกภาพ input.mp4 ในแนวนอนก่อนส่งออกเป็น output.mp4
  • ตัวอย่างที่ซับซ้อนยิ่งขึ้นคือการประกอบฟิลเตอร์กราฟด้วย trim, concat, overlay, drawbox
  • ดูตัวอย่างเพิ่มเติมได้ที่ Usage
  • Interactive Playground เป็นสภาพแวดล้อมบนเบราว์เซอร์ที่ให้ลองรัน typed-ffmpeg ได้โดยตรง
    • ทดลองฟิลเตอร์และคำสั่งของ FFmpeg
    • แสดงภาพฟิลเตอร์กราฟแบบเรียลไทม์
    • ทดสอบการตั้งค่าอินพุต/เอาต์พุต
    • เรียนรู้ผ่านตัวอย่างแบบอินเทอร์แอกทีฟ
    • แชร์ฟิลเตอร์กราฟได้
  • Playground เหมาะสำหรับการเรียนรู้และทำต้นแบบเชนฟิลเตอร์ FFmpeg โดยไม่ต้องตั้งค่าสภาพแวดล้อมในเครื่อง

แนวทางการพัฒนาและที่มา

  • ไอเดียเริ่มต้นคือใช้ GPT-3 สร้าง FFmpeg filter SDK โดยตรงจากเอกสาร FFmpeg
  • ระหว่างการพัฒนาพบว่ามีข้อจำกัดในการทำงานให้เป็นอัตโนมัติทั้งหมดด้วย GPT-3 เพียงอย่างเดียว จึงเปลี่ยนไปใช้ แนวทางสร้างโค้ดแบบดั้งเดิม เพื่อให้ SDK สมบูรณ์
  • GitHub Copilot และ GPT-3 ช่วยเร่งความเร็วในการพัฒนาและประหยัดเวลา
  • สไตล์ API และแนวคิดด้านการออกแบบของโปรเจกต์ ffmpeg-python มีอิทธิพลต่อการพัฒนา typed-ffmpeg
  • dependency สำหรับการพัฒนาถูกจัดการด้วย pyproject.toml และ uv.lock และติดตั้งสภาพแวดล้อมพัฒนาได้ด้วยคำสั่งต่อไปนี้
uv pip install --group dev

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

 
GN⁺ 2025-05-31
ความคิดเห็นจาก Hacker News
  • ตัวแยก/เครื่องมือสำหรับออปชันบรรทัดคำสั่ง ทั้งหมด แท้จริงแล้วต่างก็เป็นภาษา configuration ที่สมบูรณ์ในตัวเอง และควรมองว่าเครื่องมือแต่ละตัวคือ “โปรแกรม/การตั้งค่า” ที่เขียนด้วยภาษานั้น ๆ แต่ประเด็นนี้มักถูกประเมินต่ำไป
    เพราะ Unix shell ช่วยแยกคำก่อนการตีความ argv ขั้นสุดท้าย ภาษาถิ่นจำนวนมากจึงดูคล้ายกันเพียงผิวเผิน แต่ในความเป็นจริงหลากหลายจนชวนมึน
    เมื่อก่อนเคยลองรัน --help และ -h กับทุกโปรแกรมใน /usr/bin แล้วพบว่าสัดส่วนที่ไม่ได้ข้อมูลช่วยเหลือที่มีประโยชน์นั้นค่อนข้างสูง
    ดังนั้นการใส่ type ให้เครื่องมือที่ซับซ้อนอย่าง ffmpeg จึงมีประโยชน์เชิงปฏิบัติ และยังช่วยให้เห็นความจริงข้อนี้ชัดขึ้นด้วย

    • อาจไม่ใช่ประเด็นหลักที่ตั้งใจสื่อ แต่รู้สึกว่า man foo น่าเชื่อถือและมีประโยชน์มากกว่า foo --help หรือ foo -h
    • ในมุมของผู้เริ่มต้น อยากรู้ว่าเกิดการชนกันตรงไหน
  • น่าสนใจและดีที่ยังพัฒนาอย่างคึกคัก แต่ดูเหมือนจะมีปัญหาบางส่วนคล้ายกับ ffmpeg-python
    ดูเหมือนจะไม่มีวิธีระบุ filter ที่ไม่มี input เช่น "color" และก็ดูเหมือนไม่มีวิธีส่ง flag ให้ Popen เพื่อไม่ให้หน้าต่าง CMD เด้งขึ้นมาในแอป Windows GUI เช่น subprocess.CREATE_NO_WINDOW
    ตัว ffmpeg เองยังพอทำได้ด้วยการ ffmpeg.compile() แล้วนำไปรันเอง แต่กับ ffprobe ที่ใช้ ffmpeg.probe() จะทำแบบนั้นได้ยาก
    แก้ไข: source filter แก้ได้ด้วย ffmpeg.sources.color แล้ว ยังสงสัยว่ามีวิธีใช้ source filter ใด ๆ แบบที่ใช้ vfilter/afilter กับ filter ทั่วไปหรือไม่

  • ถ้าจะทำการประมวลผลวิดีโอแบบสคริปต์ใน Python ขอแนะนำอย่างยิ่งให้ไปใช้ Vapoursynth ตรง ๆ ดีกว่า
    มันถูกสร้างมาเพื่อจุดประสงค์นั้นตั้งแต่แรก ยังมีการดูแลอย่างต่อเนื่อง มีชุมชนและเครื่องมือที่ใช้ได้ดี และไม่ถูกผูกไว้กับอินเทอร์เฟซบรรทัดคำสั่งของ ffmpeg
    https://www.vapoursynth.com/

  • typed-ffmpeg ชู “type safety แบบสมบูรณ์, autocomplete, validation” เป็นจุดหลัก แต่ช่วยอธิบายได้ไหมว่าทำไมการส่ง width/height หรือพิกัด x/y เป็น string ถึงสมเหตุสมผล?

    .drawbox(x="50", y="50", width="120", height="120", color="red", thickness="5")  
    

    ที่มา: https://github.com/livingbio/typed-ffmpeg?tab=readme-ov-file...

    • น่าจะเป็นเพราะค่าเหล่านั้นไม่ใช่จำนวนเต็ม แต่เป็น นิพจน์ของ ffmpeg ที่ประเมินผลออกมาเป็นจำนวนเต็ม
      ตัวอย่างเช่น ในเอกสาร ffmpeg มีตัวอย่างแบบนี้: drawbox=x=-t:y=0.5*(ih-iw/2.4)-t:w=iw+t*2:h=iw/2.4+t*2:t=2:c=red
      ถ้าจะตรวจ type ให้ถูกต้องจริง ๆ น่าจะต้องมี DSL สักแบบ
  • เป็นไอเดียที่ดี ส่วนตัวกำลังรอ เวอร์ชัน TypeScript อยู่

    • ลองให้ Jules preview ทำดูแล้ว implementation ค่อนข้างตรงไปตรงมาเกินไป
      มีแนวทางที่อ่านง่ายกว่านี้อยู่ในหัว แต่ถ้าคิดว่ามันถูกสร้างจาก prompt ที่สั้นมาก ก็ถือว่าไม่ได้แย่มาก
      ถ้าสนใจ การเปลี่ยนแปลงอยู่ใน branch นี้: https://github.com/matt-hensley/typed-ffmpeg/tree/feature/mu...
    • ไม่มีการกล่าวถึง TypeScript ที่ไหนเลย
  • น่าจะต้องมีข้อมูลอธิบาย บรรทัดคำสั่ง ffmpeg ในรูปแบบที่เครื่องอ่านได้ เพื่อให้ generate ออกมาได้หลายภาษา

  • เครื่องมือแบบ visual ดูยอดเยี่ยมเป็นพิเศษ FFMPEG เป็นตัวอย่างที่ดีจริง ๆ ว่า modular/visual programming ช่วยได้มาก เพราะยากที่จะรู้จักชิ้นส่วนทั้งหมดที่มันมีให้
    ข้อสังเกต UX เล็กน้อย: บน Win11/Chrome คิดว่าจะลบ node หรือ edge ด้วยปุ่ม DEL ได้
    โดยรวมแล้วเจ๋งมาก

    • ในที่สุดก็มีอะไรคล้าย DirectShow GraphEdit ของ MS ออกมาแล้ว
  • เจ๋งดี แต่สงสัยว่ารองรับ การเชื่อมต่อ frame pipe ระหว่างคำสั่งทั้งหมดหรือไม่
    ส่วนตัวมองว่าตั้งแต่นั้นเป็นต้นไป รูปแบบที่น่าสนใจที่สุดใน workflow ของ FFMpeg ถึงจะเริ่มเปิดออก

  • ดีเลย ถ้าอยากตัดต่อวิดีโอแบบ visual ก็ลองใช้เครื่องมือที่ผมทำได้: https://newbeelearn.com/tools/videoeditor/
    มันสร้างคำสั่ง ffmpeg ให้