O vídeo convertido pelo FFMPEG tem uma duração diferente, por quê?

9

Eu converto vídeos usando o FFMPEG. Meu objetivo é convertê-los para o formato MP4 ( MPEG-4 Parte 14 ) com fluxo de áudio codificado em AAC e fluxo de vídeo codificado em MPEG-4 parte 10 .

Eu uso a seguinte linha para converter os vídeos:

ffmpeg -y -i "{inputFile}" "{outputFile}"

O vídeo convertido parece bom, no entanto, a duração dos fluxos no arquivo convertido e no arquivo de entrada nem sempre corresponde.

Eu fiz alguns experimentos e a diferença na duração está, sem dúvida, lá, no entanto, não é tanto assim - de qualquer maneira eu estou testando com pequenos vídeos. Aqui estão os meus resultados:

| InputFile  | InputAudio | InputVideo | OutputAudio | OutputVideo  |
|------------|------------|------------|-------------|--------------|
| h.avi      | 3s 631ms   | 3s 567ms   | 3s 668ms    | 3s 567ms     |
| h.flv      | 3s 631ms   | 3s 558ms   | 3s 668ms    | 3s 567ms     |
| h.mov      | 3s 532ms   | 3s 533ms   | 3s 682ms    | 3s 534ms     |
| h.mp4      | 3s 605ms   | 3s 534ms   | 3s 682ms    | 3s 567ms     |
| h.mpg      | 3s 605ms   | 3s 533ms   | 3s 563ms    | 3s 534ms     |
| h.wmv      | 3s 620ms   | 3s 633ms   | 3s 659ms    | 3s 567ms     |

Como eu criaria um software no topo do FFMPEG, ficaria mais feliz se pudesse ao menos entender o motivo dessa diferença. É por causa de alguma transcodificação desnecessária?

Nesse caso, posso desativar essa transcodificação para impedir que o FFMPEG redefina meu arquivo de vídeo de entrada?

Se não consigo desativá-lo, como posso ter certeza (além dos testes) de que essa diferença não é proporcional ao tamanho do vídeo?

Se eu converter, por exemplo, um vídeo de 10 horas, uma diferença de vários segundos ou até minutos não será adequada para mim.

Zsolt
fonte
11
Eu acho que isso depende dos seus codecs de entrada e saída. Os codecs GOP longos podem alterar a duração do fluxo de vídeo para colocar os quadros-chave onde precisam estar e fechar GOPs. Você não deve enfrentar esse problema ao transcodificar de intra codecs para intra codecs. Se você não precisar recodificar o vídeo, use a opção 'c: v copy' se o contêiner de destino suportar esse codec.
Audionuma 20/05
Espero que as diferenças de tamanho não piorem com vídeos mais longos. É mais provável que seja um problema de início / fim, não um desvio de velocidade ou algo assim. Quando codifico coisas com ffmpeg, o número de quadros, taxa de quadros e duração em segundos sempre permanece o mesmo. (a menos que eu queira que isso mude!).
Peter Cordes
@audionuma: nenhum codec são adiciona / remove quadros. Às vezes, o mencoder, por causa da sincronização a / v, ANTES de alimentar os quadros no codec de vídeo. Um codec colocará os quadros-chave onde achar melhor (intervalo fixo ou em cenários) e, quando o codificador informar ao codec que esse é o último quadro, ele fechará o último GOP, por mais longo que seja. Mesmo com o posicionamento do quadro-chave não adaptável, nenhum codec adicionará quadros extras apenas para tornar o último GOP do mesmo tamanho!
Peter Cordes

Respostas:

7

Espero que esta explicação seja o que você está procurando:

  • Ao transcodificar para uma codificação como H.264 (MPEG-4 parte 10), você também necessariamente reanalisa o vídeo, isso faz parte da técnica de compactação H.264. No entanto, duvido que esse seja o motivo pelo qual você enfrenta um intervalo de tempo, pois a reamostragem não influencia necessariamente a taxa de clock da mídia. Portanto, não me preocuparia muito com a reamostragem, isso pode causar alguma variação, mas provavelmente muito marginal.

  • Os formatos de contêiner que você listou são meio irrelevantes, porque definem como o fluxo compactado é empacotado, enquanto a fonte da diferença de tempo é a própria compactação. O .flvarquivo, por exemplo, pode conter um fluxo codificado pelo codec Flash Sorenson herdado ou pelo H.264 mais recente. No primeiro caso, você estaria transcodificando o fluxo de vídeo, mas no último é possível que você não esteja - dependendo do codec de áudio usado. Os contêineres .avie .wmvsão independentes de codec, portanto não há como adivinhar a codificação do conteúdo.

  • Você não mencionou como a duração foi testada. Observe que ffmpeg, por padrão, mostra a duração que aparece nos metadados do arquivo e não um valor calculado. Se sua lista for baseada nos dados que o ffmpeg despeja como parte de seus avisos de abertura, observe que esses são metadados explicitamente e não um valor medido real.

  • O delta nas durações que você apresentou está dentro do intervalo de um ou dois quadros no intervalo de 25 ou 30 fps. É razoável que os codecs atinjam ou removam os quadros em branco dos fluxos de acordo com seu algoritmo (ou a organização do desenvolvedor ...). Não deve influenciar o carimbo de data / hora quando você concatena corretamente os fluxos.

  • Só posso pensar em duas razões que podem alterar substancialmente a duração da sua mídia, nem aplicável no seu caso específico:

    1. Recodificação em uma velocidade-alvo diferente. Às vezes, isso acontece acidentalmente devido a metadados incorretos no arquivo de entrada. Mas não no seu caso, que, como mencionado acima, corresponde a um único quadro eliminado ou ganho.

    2. Quando você aplica um codec que recria qualquer fluxo. Exemplos incluem remoção de anúncios, detecção de silêncio, limpeza de ruído etc.

Resumindo, se você está preocupado com o que acontecerá com um vídeo de 10 horas - basta executar um teste real. Se você tiver problemas e procurar assistência, lembre-se de postar os detalhes do codec do arquivo de entrada e o método que você mediu a duração do fluxo.

Espero que isto ajude.

avnr
fonte
Na verdade, o formato do contêiner é provavelmente relevante. Diferentes contêineres armazenam timestamps / frame durações de maneira diferente. E calculadoras de comprimento precisam de código diferente para diferentes formatos de contêiner, e esse código pode se comportar de maneira diferente. por exemplo, contando a duração em que o último quadro é mostrado em um, mas não em outro.
Peter Cordes
@ PeterCordes, o que você quer dizer com "comprimento" no seu comentário? Se você quis dizer "duração", está errado, a duração é sempre o número de quadros vezes a base de tempo. Se você quer dizer outra coisa, indique o que você quer dizer com "comprimento".
AVNR
Eu quis dizer duração. Nem todo vídeo tem taxa de quadros constante. E a maneira como as durações dos quadros são armazenadas (como uma fração ou qualquer outra coisa, geralmente múltiplos de uma base de tempo) é diferente para diferentes contêineres. Isso é meio ondulado e inventivo da minha parte, já que eu não olhei para os detalhes, mas tenho certeza de que não é tão simples quanto gostaríamos que fosse.
27568 Peter
@ PeterCordes, tudo bem, mas isso é tão raro e realmente não pertence aqui, é usado apenas em alguns casos extremos, como gravação de tela, apresentações de slides, etc. o termo mais conciso no caso deles é o vídeo híbrido (ou seja, fluxos com taxas ou bases de tempo diferentes, mantendo suas taxas constantes originais quando agrupadas em conjunto). No caso de um "filme comum", quase sempre existe uma taxa de quadros conhecida, independentemente de como o contêiner o representa em seus metadados.
AVNR