FFMPEG: Como dividir um vídeo * NOT * em um limite GOP / Keyframe SEM transcodificação?

1

Usando o FFMPEG, como você pode dividir um vídeo em segmentos de comprimento igual QUE PODEM OU NÃO PODEM iniciar em quadros-chave?

Supondo que você esteja familiarizado com o formato segmento e a opção break_non_keyframes , o FFMPEG NÃO parece fazer o que eu esperaria (pelo que Eu li por aí ... não consigo mais encontrar os links).

ffmpeg -i ...  -f segment -break_non_keyframes 1 -segment_time 2 -c copy 2secs%03d.ts

Ou seja, crie um segmento que pode, de fato, ser mais longo que o segmento desejado, incluindo todo o GOP, conforme necessário.

Por exemplo, suponha um GOP de 3 quadros com uma taxa de quadros tosca de 1 FPS com a seguinte cadência parva do IBP:

 01 02 03 11 12 13 21 22 23 31 32 33
  I  B  P  I  B  P  I  B  P  I  B  P

Se eu quiser dividir em segmentos de 2 segundos, esperaria ver os seguintes segmentos gerados (quadros em parênteses não devem ser exibidos nesse segmento):

01 02 03  (03 not displayed in this segment, only used for decoding)
01 02 03 11 (... 01 and 02)
11 12 13  (... 11 )
21 22 23  (... 23)
21 22 23 31 (...21 22)
31 32 33  (... 31)

Como você pode ver, cada segmento terá quadros extras, mas dado um início PTS e e PTS final, você sempre pode reproduzir / transcodificar apenas o segmento por si só.

Isso é realmente um desperdício de espaço (a soma dos segmentos será MUITO maior do que o ativo original), mas esse não é o ponto aqui. O objetivo é ter segmentos independentes sem transcodificação.

    
por Mark Gerolimatos 31.03.2016 / 12:42

2 respostas

3

Lamentamos informar que isso não é possível com o muxer do segmento atual. A opção break_non_keyframes é direcionada a casos como o HLS, em que muitos players tratam os segmentos como um fluxo contínuo de pacotes, portanto, os dados de referência que estão sendo divididos em vários arquivos não são um problema.

Estou curioso para saber qual é o seu caso de uso real aqui. Onde você precisa de segmentos de comprimento fixo, cada um dos quais deve ser decodificável como um arquivo completamente independente? Eu duvido que a maioria dos jogadores lidaria com isso do jeito que você quer; na ausência de uma imagem referenciada, os jogadores frequentemente exibirão artefatos verdes ou cinza em vez de soltarem o quadro.

Além disso, sua cadência no IBP é um pouco enganosa. Supondo que seus números de quadros são ordem de exibição, seus quadros seriam realmente ordenados IPB / IPB / IPB / IPB no fluxo.

Se você realmente precisar desse recurso, seria possível (mas não totalmente trivial) implementar no muxer do segmento. Você precisaria armazenar em buffer todos os pacotes que chegam, descartar o buffer toda vez que atingir um quadro IDR e gravar o buffer no próximo arquivo que você começar a escrever.

Citação: Implementei a configuração break_non_keyframes .

    
por 05.04.2016 / 10:44
0

Quando eu corro

ffmpeg -i input.mp4 -f segment -c copy -reset_timestamps 1 -segment_time 2 -break_non_keyframes 1 a%02d.mp4

e, em seguida, reproduzir os segmentos MP4 de saída usando ffplay, muitos deles jogam bem, apesar das muitas mensagens de erro. Apenas a parte de 2 segundos é reproduzida. Alguns jogam, mas com artefatos, ou seja, o quadro-chave não foi decodificado. No entanto, se eu definir o tempo do segmento para, por exemplo, 11, todos os segmentos serão reproduzidos como você gostaria, via ffplay. Este não é o caso da saída TS. A reprodução também não funciona bem em um player comum como o VLC.

Como alternativa, se eu criar um segmento usando o modelo abaixo

ffmpeg -ss N -t 2 -i input.mp4 -c copy aN.ts

Potplayer jogou bem - apenas a parte de 2 segundos, sem erros. ffplay jogou todos os quadros muxed, livre de erros. VLC jogou apenas o segmento de 2 segundos, mas com falhas. No meu teste, 229 quadros de um vídeo de 30 fps foram colocados na saída.

tl; dr Diferentes jogadores não se comportam da mesma forma com arquivos contendo quadros com DTS / PTS negativo. Qual é o seu caso de uso?

    
por 31.03.2016 / 14:03

Tags