Como extrair 1 captura de tela de um vídeo com ffmpeg em um determinado momento?

109

Existem muitos tutoriais e outras coisas que mostram como extrair várias imagens de um vídeo usando o ffmpeg. Você define -r e pode até começar em um certo valor.

Mas eu quero apenas 1 captura de tela, digamos 01:23:45 em. Ou 1 captura de tela em 86% em

Tudo isso é possível com ffmpegthumbnailer, mas é outra dependência da qual não quero depender. Eu quero ser capaz de fazer isso com o ffmpeg.

Peter Bengtsson
fonte

Respostas:

208

Use a -ssopção:

ffmpeg -ss 01:23:45 -i input -vframes 1 -q:v 2 output.jpg
  • Para saída JPEG, use -q:vpara controlar a qualidade da saída. A faixa completa é uma escala linear de 1-31 em que um valor inferior resulta em uma qualidade superior. 2-5 é um bom intervalo para experimentar.

  • O filtro de seleção fornece um método alternativo para necessidades mais complexas, como selecionar apenas certos tipos de quadros, ou 1 por 100, etc.

  • Colocar -ssantes da entrada será mais rápido. Veja FFmpeg Wiki: Buscando e este trecho da ffmpegdocumentação da ferramenta cli :

-ss posição (entrada / saída)

Quando usado como uma opção de entrada (antes -i), busca neste arquivo de entrada a posição. Observe que, na maioria dos formatos, não é possível buscar exatamente, portanto ffmpeg, buscará o ponto de busca mais próximo antes da posição. Quando a transcodificação -accurate_seekestá ativada (o padrão), este segmento extra entre o ponto de busca e a posição será decodificado e descartado. Ao fazer a cópia de fluxo ou quando -noaccurate_seekfor usado, ele será preservado.

Quando usado como uma opção de saída (antes de um nome de arquivo de saída), decodifica, mas descarta a entrada até que os carimbos de data / hora cheguem à posição.

posição pode ser em segundos ou em hh:mm:ss[.xxx]forma.

llogan
fonte
2
Isso é MUITO mais rápido. Muito obrigado. Colocar o -ss primeiro faz uma grande diferença.
Peter Bengtsson
existe alguma maneira de obter o enésimo quadro após o tempo especificado?
dorien
@GuntherPiez Não vejo nenhuma menção em qualquer lugar sobre possíveis artefatos.
Stefan Reich
2
Observe que vframesestá obsoleto na (pelo menos) versão 4.2.2. Por manual "[ vframes] é um apelido obsoleto para ' -frames:v', que você deve usar em seu lugar."
Synexis
Funciona perfeito e rápido.
Smeterlink
37

O FFMpeg pode fazer isso buscando o carimbo de data / hora fornecido e extraindo exatamente um quadro como uma imagem, consulte, por exemplo:

ffmpeg -i input_file.mp4 -ss 01:23:45 -vframes 1 output.jpg

Vamos explicar as opções:

-i input file           the path to the input file
-ss 01:23:45            seek the position to the specified timestamp
-vframes 1              only handle one video frame
output.jpg              output filename, should have a well-known extension

O -ssparâmetro aceita um valor na forma HH:MM:SS[.xxx]ou como um número em segundos. Se você precisa de uma porcentagem, você precisa calcular a duração do vídeo com antecedência.

SirDarius
fonte
Parece funcionar conforme o esperado. No momento, estou testando se esta é a mesma velocidade de usar ffmpegthumbnailer.
Peter Bengtsson
Sim, essa abordagem é muito lenta. Consulte peterbe.com/plog/fastest-way-to-take-screencaps-out-of-videos
Peter Bengtsson
7
tente usar a opção -ss antes de -i, pois ela ignorará a parte de decodificação do pipeline. Isso pode acelerar o processo.
SirDarius
1
Existe alguma forma de saída como PNG para o fluxo em vez de um arquivo?
Nicke Manarin
1
@NickeManarin Sim .. ffmpeg -ss 01:23:45 -i video.mp4 -c:v png -frames:v 1 image.jpg. Observe que também coloco a -ssopção "buscar" antes do arquivo de entrada na linha de comando, como outros recomendaram.
Glenn Slayden