Cortar vídeos em quadros exatos com o filtro de seleção ffmpeg

16

Em vez de usar -sse -tobuscar parâmetros, que não parecem muito precisos, posso cortar vídeos para determinados números de quadros? Por exemplo;

ffmpeg -i video.webm -startingframe 80 -endingframe 560 output.webm

[80º e 560º quadros incluídos. Então, como total, ele faz (560 - 80 +1) quadros]

Após as respostas e uma pequena pesquisa, tentei alguns comandos. Mas até agora não consegui encontrar uma maneira aceitável.

Se alguém quiser cortar o fluxo de vídeo entre 250 e 750 quadros, este é o caminho a percorrer. Ele fornecerá 501 quadros como saída:

Nota: movie.mp4 tem 25 qps e sua taxa de amostragem de áudio 48k

ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm

Como esperado, a saída dura 20 segundos exatamente.

Usando o mesmo método para áudio:

ffmpeg -i movie.mp4 -vn -af "aselect=between(n\,480\,1440),setpts=PTS-STARTPTS" a_stream.webm

Inesperadamente, este tem uma precisão muito baixa. Deveria ter me fornecido 960001 (960k + 1) amostras que equivalem a 20 segundos de áudio. Mas, em vez disso, a saída durou 20.505 segundos e possui 984240 amostras. Além disso, se eu aumentar a duração, o erro também aumentará.

Então tentei usar os parâmetros -ss -to para cortar o fluxo de áudio:

ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm

A velha maneira clássica funciona muito melhor. A produção durou 20.003 segundos e possui 960144 amostras. Além disso, o aumento da duração não aumenta o erro, o erro é constante, sempre há 144 amostras excedentes com esse arquivo de entrada.

Resumindo: o selectfiltro funciona bem na maioria das vezes, mas uma seleção não. Os -ssparâmetros clássicos funcionam melhor para áudio, mas não são precisos para a amostra. Além disso, não é possível usar parâmetros -vf selecte -ssjuntos, porque -ssafetará os fluxos de áudio e vídeo enquanto queremos que apenas o áudio seja afetado.

Então, para cortar com precisão um arquivo de mídia, eu tenho que executar estas 3 etapas:

ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm 
ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm 
ffmpeg -i v_stream.webm -i a_stream.webm -c:v copy -c:a copy  movie-between_10th_and 20th_seconds.webm

Isso fornece os resultados mais precisos. O vídeo tem 20.000 segundos de duração e o áudio com quadros precisos tem 20.003 segundos de duração e possui 960144 amostras. Não corresponde exatamente ao fluxo de vídeo, mas está OK. Há apenas 144 amostras excedentes. A maior desvantagem é que, sempre que eu quero cortar um arquivo, tenho que enviar 3 comandos para um trabalho simples e ele cria dois arquivos desnecessários: a_stream.webm e v_stream.webm. E o selectfiltro não está funcionando em alguns arquivos de entrada que tentei. Ele executa o trabalho com êxito (?), Mas nunca interrompe o processo de codificação, por isso tenho que fechar o prompt de comando todas as vezes.

destorcer
fonte
Eu li essa página antes de postar esta pergunta. Essa página não me ajudou. Se uma entrada tem variável fps, podemos simplesmente calcular usando essa equação? Acho que não. Também acho que '-ss' não me dará uma posição precisa. Procurar quadro a quadro seria melhor, eu acho.
destor
Observe que o -ssquadro é preciso (veja aqui ). Você realmente tem entrada de fps variável? Minha resposta está vinculada ao segmento da lista de discussão, que menciona o uso de selectfiltros, onde você pode especificar o número do quadro. Você já tentou isso?
slhck
Eu tentei usar selecte aselectfiltros para fluxos de vídeo e áudio. Selecttem precisão de quadro para vídeo, mas aselectnão é precisa de amostra. Na verdade, está longe de ser preciso. Dá resultados muito mais piores do que usar os -ss -toparâmetros simples . Por isso, por enquanto, uso a combinação de selectfiltro e -ss -toparâmetros para obter um corte mais preciso. Mas é uma maneira suja de fazer isso. Por favor, olhe para o meu primeiro post eu adicionei algumas
linhas de
versão ffmpeg?
fie
Por que você está tentando cortar por um número de quadro de qualquer maneira? Se alguém precisa desse tipo de precisão, por que não usar o avidemux? Além disso, talvez seus problemas originais sejam porque ele seleciona o quadro-chave mais próximo?
fie

Respostas:

3

O áudio é proveniente de segundos, não de quadros; portanto, se você deseja cortar um vídeo, é necessário calcular fps de vídeo × 20 segundos assim: 20 segundos de 23,97 fps = 479,4

O corte do quadro não é preciso porque você não pode obter fps completos no último segundo; portanto, o áudio terá mais segundos ou apenas meio segundo ou um pouco mais ou menos! Talvez você deva usar segundos em vez de quadros para obter o corte exato, dizendo ao ffmpeg para fazer isso por você. E se você conseguir 1 quadro extra, que tal mudar os 250º e 750º quadros para os 250º e 749º quadros ?! Use menos 1 para obter sempre quantos quadros você pede!

Mojtaba Golestani
fonte
Na verdade áudio vem de amostras, não segundos ...
Anubioz