Làm cách nào để nhanh chóng tạo GIF động với chất lượng thấp với ffmpeg?


3

Chúng tôi tạo ra rất nhiều GIF hình thu nhỏ có chất lượng không quan trọng bằng thời gian cần thiết để tạo chúng. Tạo GIF chất lượng cao với ffmpeg được bảo vệ rất tốt, nhưng tôi không gặp nhiều may mắn khi tìm ra cách tạo ra những ảnh chất lượng thấp càng nhanh càng tốt.

Việc tính toán bảng màu chiếm phần lớn thời gian thực hiện bằng lệnh sau (được lấy từ câu trả lời của bộ lọc đa chuỗi ở đây: Cách tạo hiệu quả gif bảng màu tốt nhất từ ​​một phần video trực tiếp từ web ):

ffmpeg -y -threads 8 -r 24 -f image2 -start_number 1 -i "frames.%04d.jpg" -filter_complex "fps=24,scale=150:-1:flags=fast_bilinear,split=2 [a][b]; [a] palettegen [pal] fifo [b]; [b] [pal] paletteuse" output.gif

Thời gian thực hiện của lệnh đó với 1000 khung là khoảng 72 giây. Khoảng 67 giây đó là bảng màu vượt qua, và sau đó nó xuất hiện thông qua thế hệ GIF thực tế trong khoảng 5 giây. Tôi muốn giảm toàn bộ thời gian thực hiện xuống càng nhiều càng tốt, và sẵn sàng hy sinh rất nhiều chất lượng hình ảnh cho tốc độ.


1
Lệnh của bạn về mặt cú pháp không chính xác; bạn đang thiếu một [b]nhãn hiệu Dù bằng cách nào, sử dụng bảng màu chậm hơn khoảng 200⨉ đánh giá từ một bài kiểm tra nhanh. Không sử dụng nó hoàn toàn không phải là một lựa chọn cho bạn?
slhck

@slhck Tôi đang tìm các tài liệu ffmpeg xung quanh công cụ này khá khó khăn để tìm hiểu, nhưng tôi đã nghĩ ra cách này để loại bỏ bảng màu: ffmpeg -y -r 24 -f image2 -start_number 1 -i "frames.%04d.jpg" -filter:v "scale=150:-1:flags=fast_bilinear" output.gifHai vấn đề với điều này: 1) Nó chỉ lưu được 13 giây (59 giây thay vì 72) và 2 ) Tôi không chắc chắn 100% lệnh này sẽ loại bỏ hoàn toàn tính toán bảng màu (chỉ có tính toán bảng màu mà tôi đã chỉ định trước đó không được bao gồm).
Rjak

1
Vâng, về cơ bản đó là những gì tôi muốn nói. Xin lỗi vì không quá rõ ràng, tôi nghĩ bạn biết lệnh bộ lọc bạn đang sử dụng đang làm gì. Trong các thử nghiệm của tôi, để lại ra bảng màu hoàn toàn thực sự tăng tốc lệnh đáng kể . Điều gì dẫn bạn đến kết luận ban đầu rằng mã hóa thực tế chỉ mất 5 giây?
slhck

Quan sát đầu ra, có lẽ không phải là một chỉ số tuyệt vời. Khi tôi chạy lệnh mà không tạo bảng màu, chỉ báo "khung hiện tại" sẽ quay ngay lập tức và chúng tôi bắt đầu xử lý các khung. Khi tôi chạy nó với việc tạo bảng màu, khung hình hiện tại nằm ở mức 0 cho đến khoảng 5 giây trước khi kết thúc quá trình xử lý, sau đó nó sẽ quay vòng qua các khung hình rất nhanh.
Rjak

1
Vâng, đó cũng là những gì tôi đang quan sát, nhưng sau đó nó nhanh hơn nhiều. Nhưng tôi đoán nó phụ thuộc vào độ dài của video. Thành thật mà nói, tôi không biết có cách nào để tạo GIF nhanh hơn là chỉ làm không ffmpeg -i <input> <scale> <output.gif>.
slhck

Câu trả lời:


2

Việc bạn sử dụng các bộ lọc palettegen/ paletteuseđang làm cho lệnh chạy chậm hơn. Cách đơn giản để đạt được GIF chất lượng thấp hơn sẽ là:

ffmpeg -f image2 -i "frames.%04d.jpg" output.gif

Với tỉ lệ bổ sung:

ffmpeg -f image2 -i "frames.%04d.jpg" -vf scale=150:-1 output.gif

Bạn cũng có thể thả các khung trong GIF đầu ra, tức là lấy mẫu các khung, để không phải tất cả chúng đều được xử lý. Ví dụ: chỉ có 1 đầu ra FPS, bằng cách sử dụng fpsbộ lọc:

ffmpeg -i "frames.%04d.jpg" -vf "fps=fps=1,scale=150:-1" output.gif

Tôi nghĩ rằng có một lỗi đánh máy trong ví dụ cuối cùng đó ... nên là `-vf" fps = 1, scale = 150: -1 ". Thời gian thực hiện của ví dụ thứ hai là 68,48s. Chỉ định fps = 1 không dẫn đến GIF 1 FPS, nhưng nguồn là 120 khung hình / giây nên kết quả phát lại quá chậm và thời gian thực hiện không được cải thiện đủ (59,44 giây). Tôi đang thử nghiệm sử dụng trình tải concat và có ffmpeg đọc mọi khung hình thứ N. Làm điều đó, nếu tôi lấy mẫu mỗi khung hình thứ 5 bằng cách sử dụng tái tạo lại bảng màu và mỗi khung hình Lanczos, chất lượng tạm thời trông rất tuyệt, chất lượng màu trông rất tuyệt và lệnh thực thi trong vòng dưới 8 giây.
Rjak

Sẽ chia sẻ toàn bộ trong một nhận xét ở đây khi tôi đã kiểm tra đầy đủ và có thời gian thực hiện.
Rjak

@Rjak Tùy chọn đầu tiên của fpsbộ lọc được đặt tên fps, vì vậy những cái này là tương đương. Nếu nguồn của bạn là 120fps, bạn cần chỉ định -framerate 120 -i "frames…", vì mặc định cho đầu vào là 24.
slhck

1

Tôi được giao nhiệm vụ giảm thời gian cần thiết để tạo một GIF hoạt hình gần nhất có thể với 30 khung hình với chiều rộng 150 pixel. Hầu hết các chuỗi chúng tôi tạo ra là dưới 1000 khung hình. Chúng tôi đã có một chuỗi 15.000 khung hình và các nút kết xuất của chúng tôi đã mất 17 phút để tạo ra GIF ~ 30 khung hình này, tốc độ chậm không thể chấp nhận được.

Chúng tôi đã sử dụng ffmpeg như một demuxer và đường ống để tưởng tượng. Qua vài giờ thử nghiệm, tôi đã đi đến kết luận sau:

  • Số lượng khung hình đầu vào mà bạn yêu cầu ffmpeg xử lý là BY FAR , đầu vào có tác động mạnh nhất về tốc độ thực hiện. Nếu sử dụng bộ giải mã concat để bỏ qua các khung đầu vào là một tùy chọn, điều này sẽ tạo ra sự khác biệt hiệu suất lớn nhất. Bằng cách lấy mọi khung hình thứ 5, tôi có thể giảm tổng thời gian tính toán xuống còn 1 phút 45 giây với tính năng thay đổi kích thước lanczos chất lượng cao và tính toán bảng màu trên mỗi khung hình. Tạo hình thu nhỏ xem trước 30 khung hình của chúng tôi bây giờ mất dưới 1 giây .

  • Thuật toán thay đổi kích thước là tác động hiệu suất lớn nhất tiếp theo (nhưng là một giây rất xa). Sử dụng fast_bilinear thay vì lanczos đã tiết kiệm 150 giây thời gian tính toán trên tất cả 15.000 khung hình.

  • Biến số ít ảnh hưởng nhất là tính toán bảng màu và điều này thay đổi theo thuật toán bán lại. Hơn 15.000 khung hình sử dụng lanczos, chúng tôi đã tiết kiệm khoảng 17 giây thời gian thực hiện nếu chúng tôi loại bỏ tính toán bảng màu. Sử dụng fast_bilinear, chúng tôi đã tiết kiệm được khoảng 75 giây thời gian thực hiện.

Bởi vì thuật toán thay đổi kích thước và tính toán bảng màu là không đáng kể, cuối cùng chúng tôi đã giữ chúng ở chất lượng cao nhất. Chúng tôi đã giảm thời gian tính toán từ 17 phút xuống dưới 1 giây chủ yếu bằng cách yêu cầu ffmpeg bỏ qua việc đọc các tệp đầu vào.

NHIỆM VỤ CHÍNH: SK Picks INPUT FRAME vs SK Picks OUTPUT FRAME

Lý do quá trình của chúng tôi mất quá nhiều thời gian là vì việc giảm khung hình không giúp ích gì cho thời gian thực hiện khi sử dụng trình giải mã image2. Nếu bạn nhét -rcờ và fpsbộ lọc, bạn sẽ ảnh hưởng đến số lượng khung hình xuất hiện trong GIF cuối cùng, nhưng ffmpeg dường như vẫn làm gì đó với tất cả 15.000 khung hình đầu vào.

Cách duy nhất tôi có thể tìm thấy để ffmpeg bỏ qua các khung đầu vào là sử dụng bộ giải concatmã.

Đây là cách bây giờ tôi tạo hình thu nhỏ GIF hoạt hình chất lượng cao trên máy dev của mình trong chưa đầy 1 giây bằng cách bỏ qua các khung đầu vào:

# create text file which describes the ~30 input frames we want ffmpeg to process
seq -f "file 'left_frames.%04g.jpg'" 10000 500 25000 > tmp.txt

# generate the animated gif using ffmpeg only
ffmpeg -f concat -i tmp.txt -filter_complex "scale=150:-1:flags=lanczos,split=2 [a][b]; [a] palettegen [pal]; [b] fifo [b]; [b] [pal] paletteuse" output.gif
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.