Chuyển đổi khung hình PNG thành video ở tốc độ 1 FPS


21

Tôi có các khung hình video ở định dạng PNG ở 1 FPS và tôi đang cố gắng chuyển đổi chúng thành video bằng ffmpeg.

Nếu tôi làm một cái gì đó như thế này:

ffmpeg -i data/input-%4d.png data/output.mp4

Tôi nhận được một video ở 25FPS, về cơ bản là chuyển tiếp rất nhanh của đầu vào (được quay ở 1FPS).

Nếu tôi cố gắng:

ffmpeg -i data/input-%4d.png -r 1 data/output.mp4

Tôi nhận được một cái gì đó mà VLC không muốn chơi :)

Bây giờ, nếu tôi quay video đầu tiên (FF) và áp dụng bộ lọc để làm chậm nó (ví dụ -filter:v 'setpts=24.0*PTS'), tôi có thể làm cho nó phát như video 1 FPS, nhưng tất nhiên giá là kích thước tệp. Tôi đoán nó đang tạo ra một loạt các khung lặp đi lặp lại.

Vì vậy, câu hỏi là làm thế nào để tôi tạo một video có chính xác 1 FPS và thực sự phát ở tốc độ đó? Định dạng đầu ra, btw, không quan trọng đối với tôi.


Tôi không chắc ffmpeglà đủ thông minh để tìm ra codec video chỉ từ phần mở rộng tệp định dạng chứa , .mp4. Hãy thử thêm -vcodec libx264 -vpre hqvào dòng lệnh, để nói với nó các tham số codec và mã hóa.
Warren Young

Nó thực sự đã tìm ra nó ổn, và như tôi đã đề cập, nó hoạt động tốt và chỉ tạo ra kết quả kỳ lạ khi tôi thêm vào -r 1.
Assaf Lavie

Tôi nghĩ rằng bạn có thể có may mắn hơn với câu trả lời ffmpeg trên stackoverflow.com hoặc superuser.com .
Damien

Câu trả lời:


19

Nếu bạn muốn một lớp lót cho FFMPEG tạo video phát ở tốc độ 1 khung hình mỗi giây, điều bạn muốn làm là chỉ định tốc độ khung hình cho cả đầu vào và đầu ra, như sau:

ffmpeg -r 1 -i dữ liệu / đầu vào-% 4d.png -pix_fmt yuv420p -r 10 dữ liệu / đầu ra.mp4

-r 1nghĩa là video sẽ phát ở 1 trong số các hình ảnh gốc mỗi giây.
-r 10nghĩa là video sẽ phát ở 10 khung hình mỗi giây.

( -pix_fmt yuv420pChỉ có ở đó để đảm bảo khả năng tương thích với một loạt các chương trình phát lại. Ví dụ, nó được yêu cầu ở đây để video có thể phát được bởi Windows Media Player.)

Tôi đã thử nghiệm nhiều tốc độ khung hình đầu ra khác nhau và 10 dường như là con số thấp nhất bạn có thể sử dụng sẽ vẫn tạo ra một video mà VLC sẽ phát.

Tất nhiên, lệnh trên có nghĩa là mỗi hình ảnh gốc đang được nhân lên, nhưng nó là một phương pháp đơn giản hơn so với "làm chậm nó" mà bạn đã đề cập, và tùy thuộc vào codec, nó có thể không tạo ra video lớn hơn 1 FPS thực video.

Để kiểm tra điều này, tôi chỉ sản xuất một video 1 FPS thực sự, đạt tới 2,24 kiB. Sau đó, tôi đã tạo ra một video có cùng hình ảnh đầu vào nhưng đầu ra ở mức 24 FPS và nó đạt tới 5,76 kiB. Đó chỉ là hơn gấp đôi kích thước, và không nơi nào gần gấp 24 lần kích thước. :)


+1 trên -pix_fmt. Dễ quên một số người khăng khăng sử dụng WMP :-)
Smalltown2k

Tại sao bạn muốn định dạng đầu ra là 10 khung hình / giây trong khi đầu vào chỉ là 1? Nó sẽ không tạo ra 90% khung hình dư thừa giống hệt nhau chứ?
Herbert

@Herbert nó tạo ra các khung dự phòng để bạn có thể đạt tốc độ khung hình lên tới 10, điều này được thực hiện chỉ để VLC không phàn nàn và trực quan không thay đổi video. Bộ mã hóa đủ thông minh để thấy rằng các khung đều giống hệt nhau nên bạn không kết thúc với một tệp lớn hơn nhiều
chiliNUT

@chiliNUT rõ ràng, điều keyframe, không phải tất cả các định dạng, nhưng hầu hết các định dạng lành mạnh sẽ làm. Cảm ơn!
Herbert

5

Sử dụng cả hai -framerate-r

Ví dụ: để có một video cuối cùng trông giống như 1FPS:

ffmpeg -framerate 1 -pattern_type glob -i '*.png' \
    -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4

Điều này tương tự với những gì Chuyển đổi khung hình PNG thành video ở 1 FPS | Unix & Linux Stack Exchange nói, nhưng tôi cần -frameratethay vì -rđể nó hoạt động.

Điều này được đề cập trên wiki tại: http://trac.ffmpeg.org/wiki/SlIDIA#Framerates

Nó đặt tốc độ khung hình đầu ra 30, mà VLC có thể xử lý và sao chép mỗi hình ảnh 30 lần, để video đầu ra xuất hiện ở mức 1 FPS. Xem thêm: Sự cố phát lại trong VLC với video khung hình / giây thấp từ hình ảnh bằng cách sử dụng ffmpeg | Tràn ngăn xếp

VLC sau đó có thể phát video bình thường.

Đã thử nghiệm trên Ubuntu 16.10, VLC 2.2.4, ffmpeg3.0.5, trong một thư mục có 10 PNG.

Xem thêm: /programming/19267443/vlc-freezes-for-low-1-fps-video-created-from-images-with-ffmpeg


Sự khác biệt giữa -rvà là -framerategì?
Royi 17/03/2017

@Royi Tôi thực sự không biết, ngoại trừ đó là điều duy nhất có hiệu quả với tôi :-) Nhưng nếu bạn quản lý để trích xuất nó từ các mantrang, hãy cho tôi biết ;-) Một câu trích dẫn có ý nghĩa là "-r Như một tùy chọn đầu vào, bỏ qua mọi dấu thời gian được lưu trong tệp và thay vào đó tạo ra dấu thời gian giả sử tốc độ khung hình không đổi fps. Điều này không giống với tùy chọn -framerator được sử dụng cho một số định dạng đầu vào như image2 hoặc v4l2 (nó được sử dụng giống nhau trong các phiên bản cũ hơn của FFmpeg). Nếu nghi ngờ, hãy sử dụng -framerator thay vì tùy chọn đầu vào -r. "
Ciro Santilli 新疆 心 心 事件

3

Điều gì xảy ra nếu bạn tăng nhẹ ví dụ thứ hai của mình như sau:

$ ffmpeg -r 1 -i data/input-%4d.png -c:v libx264 out.mp4

Các -r 1nhu cầu phải đến trước các tệp .png, không phải sau.

Từ tài liệu FFmpeg :

Theo nguyên tắc chung, các tùy chọn được áp dụng cho tệp được chỉ định tiếp theo. Do đó, thứ tự là quan trọng và bạn có thể có cùng tùy chọn trên dòng lệnh nhiều lần. Mỗi lần xuất hiện sau đó được áp dụng cho tệp đầu vào hoặc đầu ra tiếp theo.


Thật không may, điều này không làm việc. Tuy nhiên, đề cập đến việc đặt hàng là quan trọng giúp tôi tiết kiệm rất nhiều thời gian. Cảm ơn.
Mohammed Noureldin

0

Đây là một lỗi trong VLC (vẫn còn tồn tại trong phiên bản 3.0.6). Sau một số thử nghiệm, tôi nhận ra rằng VLC gặp sự cố đối với các video có FPS dưới 10 . Vì vậy, tất cả các video có 10 FPS trở lên không phải là vấn đề. Vì vậy, hiện tại không có cách nào rõ ràng để có được video có 1 FPS có thể phát trong VLC ( đừng bỏ cuộc, hãy tiếp tục đọc ).

Một cách giải quyết khác là - được thể hiện trong câu trả lời ở trên - để giả mạo hiệu ứng của 1 FPS bằng cách sao chép hình ảnh (khi chúng ta thực sự có FPS bằng 10 trở lên, điều này phù hợp với VLC).

Ví dụ: nếu bạn có một thư mục có 12 hình ảnh và bạn muốn tạo video có 1 FPS (có thể phát trong VLC), thì bạn cần nhân đôi mỗi hình ảnh nhiều lần (giả sử 10 lần), sau đó nói với FFMPEG để tạo video 10 FPS. Bằng cách này, chúng tôi sẽ nhận được một video có tổng số khung là 120, trong đó mỗi hình ảnh sẽ được phát trong 1 giây (vì nó được nhân đôi 10 lần), đơn giản chỉ là giả mạo trong 1 FPS.

Tôi thích sử dụng fpstham số hơn là-r (được hiển thị trong câu trả lời khác) trong một số trường hợp có thể có vấn đề (theo tài liệu chính thức ).

ffmpeg -framerate 1 -i "img (%d).jpg" -c:v libvpx-vp9 -vf "fps=10,format=yuv420p" out.mkv

Vì đầu vào -frameratethấp hơn đầu ra fps, FFMPEG sẽ nhân đôi khung hình để đạt tốc độ khung hình đầu ra mong muốn của bạn (là 10 theo lệnh trên).

Cũng cần lưu ý rằng thứ tự -framerate-vf fpsrất quan trọng , vì cấu hình này sẽ được áp dụng cho video được đề cập tiếp theo (trong hoặc đầu ra). Đó là theo các tài liệu chính thức :

tùy chọn được áp dụng cho tập tin được chỉ định tiếp theo. Do đó, trật tự rất quan trọng ...

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.