Como forçar o primeiro quadro a ser quadro-chave?

Como forçar o primeiro quadro a ser quadro-chave?

Quero codificar depois de buscar uma determinada posição e quero transformar o primeiro quadro em um quadro-chave, aqui está o comando que usei:

ffmpeg -ss 300  -i howimet.mp4 -acodec libfaac -ar 48000 -ab 128k -ac 2  -vcodec libx264 -vf "scale=480:270" -f mpegts -force_key_frames 300 -t 120 howimet2.ts

o -force_key_frames está configurado para buscar a posição para criar um quadro-chave lá. Eu uso o seguinte script (deaqui) para verificar se o primeiro quadro é um quadro-chave

ffprobe -show_frames -v quiet howimet2.ts | awk -F= '   /pict_type=/ { if (index($2, "I")) { i=1; } else { i=0; } } 
  /pkt_pts_time/ { if (i && ($2 >= 0)) print $2; }  
' | head -n 1

O resultado mostra que o primeiro quadro-chave não está localizado no segundo 0.

Acho que meu comando não está correto. o que estou perdendo?

Responder1

Ao codificar vídeo, o primeiro quadrotempara ser um quadro-chave. Será o primeiro totalmente codificado e os quadros subsequentes poderão usá-lo para previsão entre quadros. Além disso, no início da sequência de vídeo codificado, você terá uma unidade de acesso H.264 que informa ao decodificador para atualizar.

Portanto, independentemente do que você estiver fazendo: a menos que você apenas copie o fluxo de bits, você estará recodificando o vídeo e seu primeiro quadro deverá ser um quadro-chave.

Agora, por qualquer motivo, seu stream tem um deslocamento no horário de início. Isso significa que todos os carimbos de data/hora da apresentação também são alterados de acordo com esse deslocamento. Se você inspecionar o cabeçalho da ffprobe -show_framessaída, verá que o quadro 0 será de fato um quadro-chave, mas com um PTS diferente.

Para compensar isso, você pode subtrair o horário de início de todos os PTS.

Responder2

Como mencionado, o primeiro quadro do seu vídeo deve ser um I-Frame. Seu problema não vem da codificação (ou cópia, se esse for o seu gosto), mas da decodificação. Ter -ss antes da entrada é inexato, então o ffmpeg está fazendo o melhor que pode para chegar onde você deseja. O Ffmpeg passou por esse local e, portanto, informa um primeiro carimbo de data/hora diferente de zero.

Eu recomendaria tentar um segundo -ss depois do seu -i. Seguindo as linhas -ss 299 -i insira -ss 1.

Isso diz para ir até o local desejado e decodificar por 1 segundo antes do processamento. Não tenho certeza se isso resolverá seu problema de pts, mas espero que isso o leve na direção certa.

Para ressaltar, não acho que o comando force_key_frames esteja fazendo o que você pensa que está. Se estiver fazendo alguma coisa, provavelmente está apenas dizendo para adicionar um quadro-chave na saída a cada 300 segundos, mas isso é apenas um palpite. Significa que apenas o primeiro quadro da sua saída seria um quadro-chave (t=120).

https://ffmpeg.org/ffmpeg.html

Responder3

Defina o tamanho do GOP com "-g"

Apenas para demonstrar precisão, aqui estão segmentos de 1 segundo

ffmpeg -i  in.mkv -g 30  -hls_time 1 -hls_list_size 0 index.m3u8

Esta é a aparência do m3u8:

    #EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:1.001000,
index0.ts
#EXTINF:1.001000,
index1.ts
#EXTINF:1.001000,
index2.ts
#EXTINF:1.001000,
index3.ts
#EXTINF:1.001000,
index4.ts
#EXTINF:1.001000,
index5.ts
#EXTINF:1.001000,
index6.ts
#EXTINF:1.001000,
index7.ts
#EXTINF:1.001000,
index8.ts
#EXTINF:1.001000,
index9.ts
#EXTINF:1.001000,
index10.ts
#EXTINF:1.001000,
index11.ts
#EXTINF:1.001000,
index12.ts
#EXTINF:1.001000,
index13.ts
#EXTINF:1.001000,
....

informação relacionada