Làm cách nào để trích xuất một khung hình của video mỗi N giây vào hình ảnh?


71

Làm cách nào tôi có thể chuyển đổi tệp video thành một chuỗi hình ảnh, ví dụ một khung hình mỗi N giây. Mplayer hoặc ffmpeg có thể làm điều này? Tôi đã sử dụng MPlayer để chụp ảnh màn hình bằng tay nhưng tôi muốn tự động hóa điều này cho một video dài.


Xem câu hỏi liên quan này về việc chọn chất lượng hình ảnh: stackoverflow.com/questions/10225403/
Khăn

Câu trả lời:


70

Nó rất đơn giản với ffmpeg và nó có thể xuất ra một khung hình mỗi N giây mà không cần thêm kịch bản. Để xuất dưới dạng chuỗi hình ảnh, chỉ cần sử dụng myimage_%04d.pnghoặc tương tự như đầu ra. Các %0xdbit được chuyển đổi sang một zero-đệm số nguyên xchữ số dài - ví dụ tôi đã nhận được đầu ra như

  • myimage_0000.png,
  • myimage_0001.png,
  • myimage_0002.png

    Vân vân..

Bạn có thể sử dụng nhiều định dạng hình ảnh tĩnh, png, jpeg, tga, bất cứ điều gì (xem ffmpeg -formatsdanh sách đầy đủ).

Bây giờ chúng ta đã biết cách xuất phim thành một chuỗi hình ảnh, nhưng nói rằng chúng ta không muốn xuất từng khung hình?

Mẹo nhỏ là chỉ cần thay đổi tốc độ khung hình của đầu ra thành bất cứ điều gì chúng ta muốn bằng cách sử dụng -r ntùy chọn trong đó nsố lượng khung hình mỗi giây. 1 khung hình mỗi giây sẽ là -r 1, cứ sau bốn giây lại có -r 0.25một khung hình, cứ sau mười giây lại có một khung hình -r 0.1.

Vì vậy, để kết hợp tất cả lại, đây là cách nó sẽ lưu một khung hình input.movcứ sau bốn giây output_0000.png, output_0001.pngv.v .:

ffmpeg -i input.mov -r 0.25 output_%04d.png

Lưu ý rằng -r 0.25tùy chọn đi sau khi các -i input.movphần, bởi vì nó kiểm soát tỷ lệ khung hình của đầu ra . Nếu bạn đặt nó trước đầu vào, nó sẽ xử lý tệp đầu vào như thể nó có tốc độ khung hình được chỉ định.

Thay đổi% xd thành nhiều chữ số bạn cần, ví dụ: nếu lệnh sẽ tạo hơn 10.000 khung thay đổi %04dthành %05d. Điều này cũng hoạt động cho các tập tin đầu vào là chuỗi hình ảnh. Đọc thêm ở đây .

Người dùng Windows : Trên dòng lệnh sử dụng%

thí dụ: ffmpeg -i inputFile.mp4 -r 1 outputFile_%02d.png

Trong tập lệnh CMD và BAT sử dụng %%

thí dụ: ffmpeg -i inputFile.mp4 -r 1 outputFile %%02d.png

Vì vậy, tăng gấp đôi %%trong các tập lệnh và đơn %trên dòng lệnh tương tác. Làm cho nó sai trong cả hai trường hợp sẽ tạo ra một lỗi.


Tôi nên đưa vào cái -rgì nếu tôi muốn xuất mọi khung hình? Nếu tôi biết FPS của video, tôi đoán tôi đã nhập nó, nhưng nếu tôi không biết thì sao?
Tomáš Zato

4
Đừng sử dụng cờ -r cả. Sau đó FFMPEG sẽ sử dụng tốc độ khung hình của tệp đầu vào.
stib

2
Lưu ý rằng bạn sẽ thực sự muốn sử dụng jpegscho việc này, trừ khi bạn chắc chắn pngđó là những gì bạn muốn. Trong trường hợp của tôi, jpegmỗi cái khoảng 50kb và pngs là khoảng 2MB.
mlissner

5
lợi thế của pngs là nén không mất dữ liệu, vì vậy nếu bạn đang sử dụng chuỗi hình ảnh làm trung gian và không bận tâm đến kích thước bổ sung thì đó là khi bạn có thể sử dụng png.
stib

Điều đáng nói -q:v 1là đây là một lựa chọn rất hữu ích ở đây như trong superuser.com/questions/318845/
Khăn

27
mplayer -vo jpeg -sstep 5 file.avi

sẽ lưu một khung dưới dạng tệp jpeg cứ sau 5 giây.

Tuy nhiên, nó sẽ không dừng lại ở cuối tập tin, nó sẽ tiếp tục tạo ra các bản sao của khung cuối cùng. Để tránh điều này, hãy tìm thời lượng của video tính bằng giây, sử dụng trình phát khác hoặc với trình phát:

mplayer -vo null -ao null -frames 0 -identify file.avi

và tìm một dòng như "ID_LENGTH = 147.00".

Trừ 2 từ độ dài và sử dụng giá trị này cho -endpostùy chọn. Ví dụ: đối với video dài 147 giây:

mplayer -vo jpeg -sstep 5 -endpos 145 file.avi

Điều này nghe có vẻ như một lỗi mplayer. cách giải quyết tốt đẹp.
quack quixote

Bạn có thể ít nhất đề cập đến hệ điều hành nào bạn đang sử dụng lệnh này?
Tomáš Zato

Đó là 5 năm trước, nhưng nó có lẽ là Máy tính để bàn Ubuntu mới nhất vào thời điểm đó, Ubuntu 10.4.
Liam

Làm cách nào tôi có thể chọn các bước ngắn hơn 1 giây. Nó chỉ chấp nhận số nguyên.
fcpenha

Ngày nay, mpv --vo=image --sstep=5 movie.mkvhoạt động rất tốt mà không có lỗi đã nói ở trên ( mpv là một nhánh của mplayer) sử dụng mpv 0.27.0 trên Debian.
Adam Katz

11

Với ffmpeg, bạn có thể làm như sau:

ffmpeg -ss 4 -i input.avi -s 320x240 -frames:v 1 output.jpg

Lệnh này tạo ra hình thu nhỏ JPG có kích thước 320 × 240 ở giây thứ 4 trong video. Đặt điều này trong một tập lệnh thay đổi thời gian và tên tệp và bạn đã hoàn tất.

Thông tin thêm: Tạo hình ảnh thu nhỏ cứ sau X giây của video


Điều này dường như để làm những gì tôi muốn, nhưng với một vấn đề. Nó sẽ xử lý tệp từ đầu trên mỗi lần lặp, bị chậm theo cấp số nhân.
Liam

@Liam - Nó có giúp ích gì không nếu bạn để thời gian bù một mình (đặt ở mức 1) và sử dụng -ss positioncờ để tìm kiếm thêm vào tệp thay thế? -ss Seek to given time position in seconds. hh:mm:ss[.xxx] syntax is also supported
Nifle

1
@ Nghị: đặt -sstrước -iđể tìm kiếm xảy ra trước khi video đầu vào được giải mã. điều này sẽ tăng tốc nó lên nguồn
quack quixote

2
Có một cách tốt hơn, nhanh hơn nhiều để làm điều đó với ffmpeg. Xem câu trả lời của tôi dưới đây.
stib 15/03 '

giải pháp của stib là IMO tốt nhất.
Griffin

8

Nếu bạn đang theo đuổi một loại trang liên hệ và nếu bạn đang làm việc với một hệ điều hành giống Unix, bạn có thể sử dụng tập lệnh phức tạp này, được gọi là Bảng liên hệ video điểm * NIX , vcs ngắn .

Trong nền, nó cũng sử dụng ffmpeg(theo mặc định) hoặc mplayerdo đó có thể xử lý rất nhiều định dạng video. Nó tự động hóa quá trình chụp ảnh tĩnh từ phim và ghép chúng thành hình ảnh với một số tiêu đề và chân trang. Bạn có thể chọn ví dụ: có bao nhiêu ảnh chụp bạn muốn hoặc thay vào đó là sự khác biệt về thời gian giữa chúng.

Trong khoảng thời gian 10 phút, lời mời là như thế:

vcs -i 10m input.avi

Kiểm tra danh sách đầy đủ các tùy chọn dòng lệnh cho một số điều chỉnh khác.

Dưới đây là một ví dụ liên lạc, lấy từ trang chủ :

nhập mô tả hình ảnh ở đây


7

Với VLC 1.1.0 trở lên, bạn có thể sử dụng bộ lọc video cảnh:

vlc C:\video\to\process.mp4 --rate=1 --video-filter=scene --vout=dummy --start-time=10 --stop-time=11 --scene-format=png --scene-ratio=24 --scene-prefix=snap --scene-path=C:\path\for\snapshots\ vlc://quit

Ở trên giúp tiết kiệm 1 trong số 24 khung hình (--scene-ratio = 24), bắt đầu từ 00:00:10 và kết thúc lúc 00:00:11.

Chỉ cần thử nghiệm và xác nhận điều này hoạt động với VLC 2.0.3 trên bản cài đặt Windows 8 mới (Tôi không có phần mềm bổ sung hoặc phần mềm video nào).

Tài liệu đầy đủ: http://wiki.videolan.org/How_to_create_thumbnails


2

VirtualDub có thể làm điều này cho bạn

File-> Export->Image sequence

nhập mô tả hình ảnh ở đây


Điều này sẽ lưu mọi khung hình như một hình ảnh?
Liam

vâng, mỗi khung hình.
Shevek

Tôi cần bỏ qua hầu hết các khung, xuất ra tất cả các khung sẽ sử dụng quá nhiều dung lượng lưu trữ. Tôi chỉ cần một khung hình cứ sau vài giây.
Liam

1

Bạn cũng có thể thử điều này

từ dòng lệnh VLC ...

vlc "C: \ Your \ file \ path \ file.avi" -V image --image-out-prefix = capname --image-out-ratio = 60

file.avi là video bạn muốn chụp từ đó, capname là tiền tố của các hình ảnh đã lưu, bạn có thể muốn phát xung quanh với tỷ lệ (60 có nghĩa là 1 trong số 60 hình ảnh được ghi lại) --image-out-format jpeg sẽ lưu mũ của bạn dưới dạng jpeg thay vì pngs, --snapshot-path cho phép bạn chọn nơi lưu mũ của mình.

Nguồn trên


Tôi nhận được thông báo này: Các tùy chọn dòng lệnh không thể được tải, kiểm tra xem chúng có hợp lệ không.
Liam

Trên Ubuntu, tôi nhận được thông báo này: tùy chọn không xác định hoặc thiếu đối số bắt buộc `--image-out-prefix = capname '
Liam

1

Bạn có thể bỏ qua các khung trong VirtualDub. Chỉ cần sử dụng tùy chọn "Decimate By" nằm trong menu Video -> Frame Rate. Ví dụ: nếu bạn đặt "Decimate By 100" thì sử dụng Tệp -> Xuất -> Chuỗi hình ảnh, nó sẽ chỉ lưu mỗi khung hình thứ 100.

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.