9 điểm bởi GN⁺ 2025-01-15 | 1 bình luận | Chia sẻ qua WhatsApp
  • Các tác vụ FFmpeg thường dễ trở nên phức tạp do phải kết hợp nhiều tùy chọn, và FFmpeg By Example là một trang tài liệu giúp nhanh chóng tìm được cách xử lý media cần thiết thông qua các ví dụ lệnh thực tế
  • Trang cung cấp cả kho GitHub, cộng đồng Discord và trang đóng góp để người dùng có thể trực tiếp gửi các ý tưởng ứng dụng FFmpeg mới
  • Giống như ví dụ về bộ lọc testsrc, trang hiển thị nguồn đầu vào, độ phân giải, tốc độ khung hình và tệp đầu ra trong một lệnh duy nhất để có thể làm theo nguyên cấu trúc lệnh
  • Các ví dụ bao quát toàn bộ các tác vụ xử lý media như tính bitrate, thay đổi kích thước ảnh, giảm nhiễu âm thanh, hiệu ứng chuyển cảnh, ánh xạ stream, tăng tốc phần cứng và xử lý metadata
  • Mỗi ví dụ được chia theo thẻ và trang riêng, nên rất dễ duyệt các lệnh FFmpeg cần thiết dựa trên bộ lọc cụ thể hoặc mục đích chuyển đổi

Trang tài liệu FFmpeg tập trung vào ví dụ

  • FFmpeg By Example là một website tổng hợp nhiều cách sử dụng FFmpeg theo từng ví dụ cụ thể
  • Trang cũng cung cấp các liên kết để tham gia cộng đồng và đóng góp

Ví dụ tạo video kiểm thử bằng testsrc

ffmpeg -f lavfi -i testsrc=duration=10:size=1280x720:rate=30 testsrc.mpg

Mã hóa, chuyển đổi và tăng tốc phần cứng

Xử lý âm thanh

Hình ảnh và hoạt ảnh

Bộ lọc và hiệu ứng hình ảnh

Trích xuất, phân tích và metadata

Nguồn sinh và pipe đầu ra

1 bình luận

 
GN⁺ 2025-01-15
Các ý kiến trên Hacker News
  • Niềm vui khi dùng ffmpeg đã tăng ít nhất 1000%
    Trước đây tôi phải chán chường Google để tìm các câu trả lời trên Stack Overflow rồi ghép lại thành lệnh, còn giờ ChatGPT viết lệnh thay tôi nên tiện hơn nhiều

    • Nhờ LLM mà tôi dùng ffmpeg nhiều lần mỗi tuần
      Đây là ứng dụng tốt nhất cho công cụ llm cmd của tôi:

      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

    • Từ lâu tôi đã xếp ffmpeg vào cùng một hộp với regex: cảm giác “mình thật sự nên học, nhưng chắc sẽ cực kỳ ghét nó”
      Rồi ChatGPT xuất hiện và giải quyết cả hai

    • Tôi cũng vậy. Những việc kiểu này AI đã hoàn toàn đảm nhận, còn tôi chỉ là người trung gian sao chép và dán phần truy vết lỗi

    • Cũng đã có nhiều công cụ khác xuất hiện, nhưng tôi vừa viết một script giúp đơn giản hóa khá nhiều các chuỗi lệnh kiểu này: llmpeg https://github.com/jjcm/llmpeg
      Nếu đã cài ffmpeg và đặt khóa API trong biến môi trường OpenAI thì nó sẽ chạy ngay

      Demo: https://image.non.io/1c7a92ef-0917-49ef-9460-6298c7a9116c.we...

    • Sau khi học cách bộ lọc phức hợp hoạt động, trải nghiệm dùng ffmpeg của tôi đã tốt hơn

  • Tôi chợt nghĩ mình nên viết và công khai cách biến các băng video gia đình đã số hóa thành clip bằng phát hiện cảnh
    Biết đâu có ai đó tìm kiếm, nên tôi để lại gist từng hoạt động khá tốt [0]. Tuy nhiên đôi khi nó bị đánh lừa bởi đèn flash máy ảnh hoặc rung lắc, nên tôi phải cung cấp riêng các file bắt đầu/kết thúc rồi nối lại bằng ffmpeg [1]

    Điều kỳ lạ là trên bản cập nhật Mac mới nhất, hiệu năng lại tốt hơn khi không dùng -c:v h264_videotoolbox. Có thể là hồi quy hiệu năng của Sequoia, nhưng tôi không chắc. Cờ tương ứng trên máy Windows có GPU Nvidia là -c:v h264_nvenc. Tôi thắc mắc vì sao ffmpeg không tự phát hiện. Nhờ cái này tôi đạt được mức tăng hiệu năng khoảng 8 lần
    Khoảnh khắc duy nhất tôi thật sự xứng đáng với đồng lương ở công ty là khi phát hiện bản ffmpeg đã cài được biên dịch mà không có tăng tốc GPU, ngay trước lúc chúng tôi định chi thêm nhiều tiền cho máy chủ cloud có GPU để xử lý video

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

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

    • Vấn đề của CPU trên cloud là chúng không có bộ mã hóa video phần cứng như trong CPU tiêu dùng, nên phải chuyển sang máy GPU đắt hơn nhiều
      Thành thật mà nói tôi chưa thật sự so sánh giá đúng cách khi dùng tăng tốc phần cứng trên cloud, nên tôi tò mò liệu ý bạn có phải là bạn đã thử và thấy chi phí/hiệu quả ổn không

    • Tôi từng dùng ffmpeg để phát hiện cảnh trống
      Tôi có một camera hướng về đường bay SFO, và sau khi loại bỏ mọi khung hình không có chuyển động, chỉ còn lại một đoạn video liên tục các máy bay đi qua mà không có những đoạn nhàm chán

    • -c:v h264_nvenc hữu ích cho mã hóa hàng loạt khi mã hóa nhiều video cùng lúc, vì nó có thể tăng thông lượng mã hóa
      Tuy nhiên trong các thử nghiệm hạn chế trước đây của tôi, chất lượng đầu ra hơi kém hơn libx264. Tôi không biết có cách nào xử lý không, nhưng không chỉ mình tôi gặp chuyện này

    • Lý do ffmpeg không tự phát hiện điều này là mã hóa phần cứng thường có phạm vi cấu hình hẹp, phải đánh đổi nhiều hơn so với codec phần mềm tinh vi, và ngay cả với cùng tham số cũng không cho ra kết quả chính xác giống nhau
      Hơn nữa, trên một hệ thống thường có thể có nhiều API phần cứng để lựa chọn, và tính năng của chúng cũng khác nhau

      FFmpeg là một công cụ dòng lệnh phức tạp, nhắm tới người dùng sẵn sàng học các chi tiết, nên tôi không chắc việc đặt giá trị mặc định dựa trên giả định có phải là đúng hay không

    • Nhìn vào snippet thì có vẻ bạn không khử xen kẽ
      Nếu clip trước khi số hóa đã được khử xen kẽ thì không sao, nhưng nếu chưa thì bạn đang làm hỏng chất lượng khi mã hóa tư liệu interlaced thành progressive. Nên thử thêm bộ lọc bwdif để nội dung 30i được mã hóa thành 60p. Nó sẽ trông gần với băng video gốc hơn

  • Theo thời gian tôi đã khá quen với nhiều phần của ffmpeg. CLI của nó có logic riêng và phụ thuộc vào thứ tự. Không phải mọi CLI Unix đều như vậy
    Gần đây tôi đang thử một số tính năng khó hiểu hơn. Ví dụ như lưu trực tiếp video thô từ camera trên một máy khá chậm. Tôi đã làm một kính hiển vi và đọc các khung hình ở định dạng video thô (YUYV 1280x720) từ camera ở 120FPS; nếu lưu nguyên như vậy xuống đĩa thì dung lượng tăng theo đơn vị gigabyte mỗi phút. Đĩa thì rẻ, nhưng có vẻ lãng phí, nên tôi đã xem xét các kỹ thuật gần như lossless có thể nén và lưu ảnh chính xác thật nhanh

    Tôi phát hiện việc chuyển đổi RGB24 trong ffmpeg rất chậm, nên sau khi mày mò các dòng lệnh, tôi chốt ở lệnh sau:

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

Video thô không có container nên không có metadata như “định dạng pixel” hay “kích thước ảnh”, vì vậy phải cung cấp trực tiếp. Nó phụ thuộc vào thứ tự: mọi thứ trước -i test.raw dùng để giải mã đầu vào, còn mọi thứ sau đó dùng để ghi đầu ra. Chỉ thực hiện một phép chuyển đổi định dạng pixel rất nhỏ (ffmpeg có thể xử lý rất nhanh), rồi ghi dữ liệu sang một định dạng gần như lossless có container. Trong hầu hết trường hợp, container .mkv là tốt nhất

Vì không thích dòng lệnh nên cuối cùng tôi dùng ffmpeg-python, và để nó ghép dòng lệnh từ đoạn mã sau:

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)
)

Và thực tế là tôi write() các frame vào stdin của process đó. Máy có 12 core và việc điều khiển kính hiển vi luôn dùng ít nhất 2 core, nên tôi phải giới hạn số luồng

Tôi vẫn đang tìm một cách mã hóa YUV lossless tốt hơn và nhanh hơn

  • Việc phụ thuộc vào thứ tự là hợp lý. Pipeline Unix cũng phụ thuộc vào thứ tự các thành phần, và các lệnh FFMpeg phức tạp cũng làm việc tương tự
    Nhiều người thích tính thẩm mỹ của “fluent interface” như ffmpeg-python, nhưng trong Python nó thường bị xem là không giống phong cách Python. Theo tôi hiểu, ffmpeg-python được thiết kế để phản ánh sát thứ tự dòng lệnh

    Sở thích được củng cố bởi thiết kế của thư viện chuẩn và các kiểu tích hợp là https://en.wikipedia.org/wiki/Command%E2%80%93query_separati... mạnh mẽ. Theo nguyên tắc này thì đại khái sẽ trông như sau:

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

    Nếu biến đầu vào thành một quá trình cấu hình riêng, ta sẽ có một kiểu runtime khác, và cũng có thể báo cho mã xử lý rằng nó cần đọc từ stdin

  • Không cần tìm thêm nữa: FFV1 https://trac.ffmpeg.org/wiki/Encode/FFV1

  • Tôi chỉ muốn gợi ý một từ: RAM disk
    Nếu có tệp dùng cho bước xử lý trung gian nhưng không muốn lưu giữ, hãy dùng RAM disk. Thực sự rất tốt

  • Tôi tưởng đây sẽ là một website tập hợp và quản lý kiến thức mà các cao thủ FFmpeg đã tích lũy, nhưng ngay ví dụ đầu tiên tôi bấm vào đã khiến tôi thất vọng
    https://www.ffmpegbyexample.com/examples/l1bilxyl/get_the_du...

    Không nên gọi thêm đến hai công cụ chỉ để xử lý chuỗi. Chỉ riêng FFprobe cũng có thể trả trực tiếp thời lượng hoặc giá trị mong muốn:

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

    Đừng dừng lại ở thứ đầu tiên chạy được; sau khi nó chạy, hãy nghĩ xem có cách nào cải thiện hơn không

    • Tôi là tác giả bài gốc. Gọi là “điên rồ” thì có vẻ hơi phóng đại
      Dù vậy tôi thích giải pháp bạn đưa ra hơn
  • Hay đấy. Nó làm tôi nhớ đến cheatsheet ffmpeg tôi dùng. Tôi nghĩ ai thường dùng ffmpeg cũng có một bộ ghi chú tương tự
    https://github.com/fastily/cheatsheet/blob/master/ffmpeg.md

  • FFmpeg là một trong những công cụ mà tôi dùng quá thỉnh thoảng nên cú pháp chính xác không bao giờ đọng lại trong đầu. Cuối cùng tôi để LLM đưa cho mình dòng lệnh cần dùng
    Công cụ duy nhất từng khiến tôi khổ sở tương tự là MegaCLI kiểu thập niên 1990 của LSI Logic. Nó cũng gần như mỗi năm mới dùng một lần, nhưng lại là loại phải dùng chính xác trong lúc chịu áp lực

    • Tôi đã dùng FFMPEG hơn 15 năm mà vẫn gần như không nhớ nổi lệnh nào. Dù vậy, khi dùng FFMPEG thì LLM thực sự tuyệt vời
      Nếu nói với ChatGPT và Claude rằng “remux video sang mkv, nhúng subtitle.srt vào tệp, và tôi chỉ muốn đoạn từ 0:00:05 đến 0:01:00”, chúng xử lý rất tốt. Nếu bạn tò mò thì kết quả là: 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

      Tôi tự hỏi nếu mục tiêu chỉ là sinh lệnh ffmpeg thì có thể làm một LLM nhỏ đến mức nào. Biết đâu nó có thể nhỏ đủ để đưa lên một trang web tĩnh và chạy cục bộ?

    • Suốt 15 năm nay tôi duy trì một tài liệu ghi chú cá nhân chứa cú pháp mình hay dùng. Nếu vẫn không được thì tôi grep lịch sử bash

    • Tôi cũng vậy. Thứ còn đọng lại trong đầu chỉ là đổi từ định dạng X sang .mp4. Phần còn lại lần nào cũng phải tra lại
      XKCD liên quan https://xkcd.com/1168/

    • Vài ngày trước tôi nửa đùa nửa thật rằng, nếu LLM chỉ cần cho tôi biết các flag ffmpeg tôi muốn, thì có lẽ đốt sạch rừng nhiệt đới cũng đáng giá

  • Đừng quên là còn có GStreamer. Vì dựa trên pipeline nên dòng lệnh và tài liệu dễ hiểu hơn ffmpeg một chút, cách kết hợp cũng có phần hợp lý hơn
    Với các tác vụ video nặng, tôi đã bỏ hẳn ffmpeg và chỉ dùng GStreamer

    • GStreamer có thể cho bạn nhiều quyền kiểm soát hơn và API thân thiện hơn khi tạo pipeline bằng lập trình
      Nhưng với các tác vụ dùng một lần, ffmpeg có vẻ thân thiện hơn nhiều. Ví dụ ffmpeg có các giá trị mặc định x264 hợp lý, còn với gst-launch thì để mã hóa x264 chất lượng tốt, bạn thật sự phải biết mình đang làm gì
    • Tôi cứ nghĩ FFmpeg cũng dựa trên pipeline. Chẳng phải nó có filter graph sao? Hay tôi đang bỏ sót điều gì
      Có thể cấu thành các graph phức tạp gồm source, sink và filter chuyển đổi
    • GStreamer có cảm giác như một dự án bị bỏ bê. Gần đây cũng có lỗ hổng nghiêm trọng, tài liệu thì khá hỏng hóc
  • Có một kho GitHub về sách ffmpeg có thể bổ sung tốt cho trang này:
    https://github.com/jdriselvato/FFmpeg-For-Beginners-Ebook

  • ffmpeg luôn cho tôi cảm giác như một ứng dụng GUI bị nhồi nhét gượng ép vào dạng TUI
    Tôi cũng từng phải dùng C API vài lần khá khó chịu; về nhiều mặt thì nó trực quan, nhưng quá dễ biểu diễn các trạng thái sai. Ước gì có một framework mã hóa AV1 thời gian thực “cứ thế là chạy”

    • Về cơ bản, đây gần như là công cụ duy nhất khiến tôi tìm đến HandBrake, công cụ thay thế dạng GUI, trước tiên. Ngoại lệ chỉ là khi xử lý hàng loạt
      Cũng có vài GUI thuần cho ffmpeg. Có điều gì đó ở công việc video khiến dòng lệnh không khớp với cách tôi xử lý trong đầu

    • Nếu dùng qua API thì tôi có thể khuyên dùng GStreamer. Tôi dùng Rust binding nên không quá quen với C API, nhưng thấy nó có vẻ tốt
      Có những phần trở nên dài dòng vì GObject, nhưng khi đã hiểu thì bạn có thể tương tác nhất quán với mọi đối tượng trong API. Có rất nhiều độ phức tạp cần thiết (video khó mà), nhưng thiết kế, triển khai và tài liệu đều khá tốt

      Với các use case thông thường, Bins (decodebin, transcodebin, playbin) giúp làm khá dễ. Ngay cả các use case phức tạp hơn cũng làm được nhờ tính linh hoạt của thiết kế

    • Tôi thích nhận định này, nhưng TUI là thứ có tính đồ họa, còn ffmpeg chỉ là CLI
      Nếu có một công cụ TUI thì sẽ rất hay. Kiểu như https://github.com/Twinklebear/fbed, nhưng ở dạng hoàn thiện tính năng hơn

  • Trên hệ thống Linux, tôi thích build tĩnh ffmpeg. Lý do là phiên bản trong distro đôi khi quá cũ hoặc thiếu các module tôi muốn
    Phiên bản container hóa này rất hữu ích: https://github.com/wader/static-ffmpeg