Solte todos os quadros pares ou ímpares usando o FFmpeg?

14

Existe uma maneira precisa de capturar um vídeo bruto e extrair dele um novo vídeo que contenha apenas quadros ímpares ou quadros pares (por opção)?

Por exemplo:

Eu tenho "blah.yuv" com 400 quadros (0-399). Eu quero criar "blahOdd.yuv" que contém quadros 1-399 (1,3,5,7 ... 399) e "blahEven" que contém quadros 0-398 (0,2,4,6 ... 398 )

Alguma idéia de como fazê-lo usando apenas FFmpeg?

Marca
fonte

Respostas:

11

Para funcionar com precisão, primeiro converta o vídeo em fluxo de bits RAW YUV (se ainda não o estiver):

ffmpeg -i input.mp4 -an -vcodec rawvideo -pix_fmt yuv420p rawbitstream.yuv

Próxima etapa: o selectfiltro pega uma expressão , onde nestá o número do quadro.

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="mod(n-1\,2)" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an odd.yuv

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="not(mod(n-1\,2))" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an even.yuv

Para ffmpegnão duplicar os quadros, você deve forçar metade da taxa de quadros da sua entrada - para definir "2" como entrada e "1" para a saída. Não se esqueça de substituir o WxH pelas dimensões reais do seu clipe, porque o fluxo de bits bruto não possui um cabeçalho que carrega essas informações.

Em vez do acima, outra possibilidade seria adicionar o setptsfiltro para definir novos registros de data e hora para a saída. Mas tenha cuidado, pois ele solta os quadros com precisão. Aqui, 25 é a taxa de quadros de saída real desejada:

ffmpeg -i input.mp4 -filter:v select="mod(n-1\,2)",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an odd.yuv

ffmpeg -i input.mp4 -filter:v select="not(mod(n-1\,2))",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an even.yuv

Obviamente, você pode escolher outro formato de pixel (qualquer um ffmpeg -pix_fmts). Certifique-se de que, ao ler o arquivo, saiba o tamanho e o formato do pixel:

ffmpeg -f rawvideo -s:v 1280x720 -pix_fmt yuv420p input.yuv …
slhck
fonte
Obrigado, para novas versões do FFMPEG, deve ser -vf em vez de -filter: v. Além disso, deve ser mod (n-1 \, 2) porque a contagem de n parece começar de 1, enquanto a contagem de quadros de 0 (caso contrário, o primeiro quadro é duplicado 3 vezes). Mas ainda há um problema, ele duplica os quadros enquanto eu quero me livrar deles - por exemplo, o clipe final conterá apenas metade dos quadros.
Mark
-vfé um apelido de -filter:v. Não posso testá-lo agora, mas analisarei isso mais tarde quando voltar à máquina. Talvez o tinterlacefiltro possa fazer o mesmo?
slhck
Eu tentei '-r 2 -i blah.yuv -r 1', mas ele me mostra um erro de taxa de quadros da opção não encontrado.
Mark
Ah, desculpe .. Risque isso, isso não funciona (mais?) E apenas para imagens.
slhck
1
@AnmolSinghJaggi Não, isso apenas remove quadros, mas não tenho certeza de que seja tão determinístico (ou seja, descarta todos os quadros ímpares). Será baseado em códigos de tempo, que podem não ser precisos.
slhck
2

Se o seu ffmpeg foi construído com a bandeira AviSynth, acredito que você pode passar um .avsarquivo.

Você pode verificar executando ffmpege procurando --enable-avisynthnos dados de configuração . --enable-avisynth

Se ele está lá, você pode usá-lo assim: ffmpeg -i blahEven.avs blahEven.yuv.

Onde blahEven.avsé simplesmente:

ffvideosource ("blah.yuv"). SelectEven ()

Para quadros ímpares, use SelectOdd().

Para um uso mais avançado, consulte a documentação do SelectEvery .

Louis
fonte
Essa é uma excelente alternativa, mas como eu mencionei - estou limitado a usar apenas o ffmpeg. A razão disso é que faz parte de um sistema automatizado que criará apenas arquivos .bat, sem possibilidade de adição do AVS.
Mark
@ Mark, eu estava pensando que, se --enable-avisynthexistisse, significava que o AviSynth foi incorporado ao ffmpeg, mas não tenho certeza disso.
Louis