Como extrair um quadro de um vídeo a cada N segundos em uma imagem?


71

Como posso converter um arquivo de vídeo em uma sequência de imagens, por exemplo, um quadro a cada N segundos. O mplayer ou o ffmpeg podem fazer isso? Eu usei o MPlayer para capturar capturas de tela manualmente, mas gostaria de automatizar isso para um vídeo longo.


Veja esta pergunta relacionada sobre como escolher a qualidade das imagens: stackoverflow.com/questions/10225403/...
Pierz

Respostas:


70

É muito simples com o ffmpeg e pode gerar um quadro a cada N segundos sem scripts extras. Para exportar como uma sequência de imagens, use myimage_%04d.pngou similar à saída. O %0xdbit é convertido em um número inteiro preenchido com zero x- o exemplo que eu dei obtém saída como

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

    etc ..

Você pode usar muitos formatos de imagem estática, png, jpeg, tga, o que for (veja ffmpeg -formatsa lista completa).

Ok, agora sabemos como exportar o filme como uma sequência de imagens, mas dizemos que não queremos exportar todos os quadros?

O truque é simplesmente alterar a taxa de quadros da saída para o que quisermos usando a -r nopção onde nestá o número de quadros por segundo. 1 quadro por segundo seria -r 1, um quadro a cada quatro segundos -r 0.25, um quadro a cada dez segundos -r 0.1e assim por diante.

Então, para juntar tudo, é assim que seria possível salvar um quadro a input.movcada quatro segundos output_0000.png, output_0001.pngetc .:

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

Note que a -r 0.25opção vai depois a -i input.movparte, porque ele está controlando a taxa de quadros da saída . Se você o colocar antes da entrada, ele tratará o arquivo de entrada como se tivesse a taxa de quadros especificada.

Altere o% xd para quantos dígitos você precisar, por exemplo, se o comando criar mais de 10.000 quadros, mude %04dpara %05d. Isso também funciona para arquivos de entrada que são sequência de imagens. Leia mais aqui .

Usuários do Windows : Na linha de comando, use%

exemplo: ffmpeg -i inputFile.mp4 -r 1 outputFile_%02d.png

Nos scripts CMD e BAT, use %%

exemplo: ffmpeg -i inputFile.mp4 -r 1 outputFile %%02d.png

Portanto, duplique os %%scripts e escolha %a linha de comando interativa. Se errar em qualquer situação, isso gerará um erro.


No que devo colocar -rse quiser exportar todos os quadros? Se eu conheço o FPS do vídeo, acho que insiro isso, mas e se eu não?
Tomáš Zato

4
Não use o sinalizador -r. Em seguida, o FFMPEG usará a taxa de quadros do arquivo de entrada.
STIB

2
Observe que você realmente deseja usar jpegsisso, a menos que tenha certeza de pngque é o que deseja. No meu caso, jpegs eram cerca de 50kb cada e pnges eram cerca de 2MB.
mlissner

5
a vantagem dos pngs é a compactação sem perdas; portanto, se você estiver usando a sequência da imagem como intermediária e não se importar com o tamanho extra, é nesse momento que você poderá usar png.
Stib

Vale acrescentar que -q:v 1é uma opção muito útil aqui, como em superuser.com/questions/318845/…
Nikolay Shmyrev

27
mplayer -vo jpeg -sstep 5 file.avi

irá salvar um quadro como um arquivo JPEG a cada 5 segundos.

No entanto, ele não para no final do arquivo, continuará produzindo cópias do último quadro. Para evitar isso, encontre a duração do vídeo em segundos, usando outro player ou com o mplayer:

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

e procure uma linha como "ID_LENGTH = 147.00".

Subtraia 2 do comprimento e use esse valor para a -endposopção Por exemplo, para um vídeo de 147 segundos:

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

isso soa como um bug do mplayer. boa solução alternativa.
quack quixote

Você poderia ao menos mencionar em qual sistema operacional está usando este comando?
Tomáš Zato

Foi há 5 anos, mas provavelmente era o último Ubuntu Desktop da época, o Ubuntu 10.4.
Liam

Como posso escolher etapas menores que 1s. Ele aceita apenas números inteiros.
Fcpenha

Atualmente, mpv --vo=image --sstep=5 movie.mkvfunciona muito bem sem o bug mencionado anteriormente ( mpv é um fork do mplayer) usando o mpv 0.27.0 no Debian.
Adam Katz

11

Com ffmpeg, você pode fazer o seguinte:

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

Este comando gera uma miniatura JPG de tamanho 320 × 240 no 4º segundo do vídeo. Coloque isso em um script que altera a hora e o nome do arquivo e pronto.

Mais informações: crie uma imagem em miniatura a cada X segundos do vídeo


Isso parece fazer o que eu quero, mas com um problema. Ele processará o arquivo desde o início em cada iteração, ficando exponencialmente lento.
Liam

@ Liam - Ajuda se você deixar o tempo de folga em paz (defina-o como 1) e usar o -ss positionsinalizador para procurar mais no arquivo? -ss Seek to given time position in seconds. hh:mm:ss[.xxx] syntax is also supported
N29 de

11
@ liam: coloque o -ssantes do -ipara que a busca ocorra antes que o vídeo de entrada seja decodificado. isso deve acelerar. fonte
quack quixote

2
Existe uma maneira melhor e muito mais rápida de fazer isso com o ffmpeg. Veja minha resposta abaixo.
STIB

A solução da stib é a melhor IMO.
Griffin

8

Se você está atrás de um tipo de folha de contato e está trabalhando com um sistema operacional semelhante ao Unix, pode usar este script elaborado, chamado ao ponto Folha de contato de vídeo * NIX , vcs curtos .

Em segundo plano, ele também usa ffmpeg(por padrão) ou mplayer, portanto, pode lidar com muitos formatos de vídeo. Ele automatiza o processo de captura de imagens estáticas do filme e as compõe em uma imagem com algum cabeçalho e rodapé. Você pode escolher, por exemplo, quantas capturas deseja ou, alternativamente, as diferenças horárias entre elas.

Por um intervalo de 10 minutos, a chamada é assim:

vcs -i 10m input.avi

Verifique a lista completa de opções da linha de comando para ver outros ajustes.

Aqui está um exemplo de folha de contato, retirada da página inicial :

insira a descrição da imagem aqui


7

Com o VLC 1.1.0 e superior, você pode usar o filtro de vídeo de cena:

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

O exemplo acima salva 1 de cada 24 quadros (--cene-ratio = 24), iniciando às 00:00:10 e terminando às 00:00:11.

Acabei de testar e confirmar que isso funciona com o VLC 2.0.3 em uma nova instalação do Windows 8 (não tenho plug-ins de vídeo ou software adicionais).

Documentação completa: http://wiki.videolan.org/How_to_create_thumbnails


2

O VirtualDub pode fazer isso por você

File-> Export->Image sequence

insira a descrição da imagem aqui


Isso salvará todos os quadros como uma imagem?
Liam

sim, todo quadro.
Shevek

Preciso pular a maioria dos quadros, pois a saída de todos os quadros consumirá muito espaço de armazenamento. Eu preciso de apenas um quadro a cada poucos segundos.
Liam

1

Você também pode tentar isso

da linha de comando do VLC ...

vlc "C: \ SEU \ arquivo \ caminho \ arquivo.avi" -V imagem --imagem-fora-prefixo = nome do capitão --imagem-fora-relação = 60

file.avi é o vídeo do qual você deseja capturar, capname é o prefixo das imagens salvas, convém brincar com a proporção (60 significa que 1 de 60 imagens é capturada) Você pode adicionar mais comandos, por exemplo - JPEG de formato de imagem para fora salvará seus limites como JPEG em vez de pngs; --Snapshot-path permite que você escolha onde salvar seus limites.

Fonte acima


Recebi esta mensagem: Não foi possível carregar as opções da linha de comandos, verifique se são válidas.
Liam

No Ubuntu, recebi esta mensagem: opção desconhecida ou falta de argumento obrigatório `--image-out-prefix = capname '
Liam

1

Você pode pular quadros no VirtualDub. Basta usar a opção "Decimar por", localizada no menu Vídeo -> Taxa de quadros. Por exemplo, se você definir "Dizimar por 100" e usar Arquivo -> Exportar -> Sequência de imagens, ele salvará apenas cada centésimo quadro.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.