Como fazer com que os timecodes de áudio e vídeo iniciem a partir do zero?

2

Esta pergunta provavelmente exigirá o conhecimento do formato matroska. Quando mudo o vídeo e o áudio juntos, os pacotes de áudio começam com o timecode 0 e o vídeo inicia com o código de tempo 7. Um vídeo 30fps começa com timecode 0, ou com timecode 33 (para o tempo 0.033, timecodes estão em milissegundos)? Posso fazer com que tanto o áudio quanto o vídeo iniciem com timecode 0?

Você não precisa ler abaixo, o resto é apenas informação adicional.

Eu tentei adicionar os filtros [v]setpts=N/(30*TB)[v];[a]asetpts=N/SR/TB[a] como os dois últimos filtros, mas isso não mudou nada.

Aqui está o comando completo que estou usando. É apenas uma codificação vp8 de duas passagens para vídeo e uma codificação opus para áudio. Ele também corta um vídeo em algumas partes de 3 segundos e as une.

ffmpeg -threads 1 -i 480P_600K_71149981.mp4 -force_key_frames 00:00:03.000 -filter_complex [0:v]scale=320x180:force_original_aspect_ratio=decrease,fps=30[vid];[vid]split[vid][vid_copy];[vid_copy]trim=start=0:duration=3,setpts=PTS-STARTPTS[c0v];[0:a]atrim=start=0:duration=3,asetpts=PTS-STARTPTS[c0a];[vid]split[vid][vid_copy];[vid_copy]trim=start=90:duration=3,setpts=PTS-STARTPTS[c1v];[0:a]atrim=start=90:duration=3,asetpts=PTS-STARTPTS[c1a];[vid]split[vid][vid_copy];[vid_copy]trim=start=180:duration=3,setpts=PTS-STARTPTS[c2v];[0:a]atrim=start=180:duration=3,asetpts=PTS-STARTPTS[c2a];[vid]trim=start=270:duration=3,setpts=PTS-STARTPTS[c3v];[0:a]atrim=start=270:duration=3,asetpts=PTS-STARTPTS[c3a];[c0v][c0a][c1v][c1a][c2v][c2a][c3v][c3a]concat=n=4:v=1:a=1[v][a];[v]setpts=N/(30*TB)[v];[a]asetpts=N/SR/TB[a] -map [v] -map [a] -c:v vp8 -b:v 200k -crf 54 -profile:v 1 -an -pass 1 -passlogfile jump_passlogfile -f null NUL


ffmpeg -threads 1 -i 480P_600K_71149981.mp4 -force_key_frames 00:00:03.000 -filter_complex [0:v]scale=320x180:force_original_aspect_ratio=decrease,fps=30[vid];[vid]split[vid][vid_copy];[vid_copy]trim=start=0:duration=3,setpts=PTS-STARTPTS[c0v];[0:a]atrim=start=0:duration=3,asetpts=PTS-STARTPTS[c0a];[vid]split[vid][vid_copy];[vid_copy]trim=start=90:duration=3,setpts=PTS-STARTPTS[c1v];[0:a]atrim=start=90:duration=3,asetpts=PTS-STARTPTS[c1a];[vid]split[vid][vid_copy];[vid_copy]trim=start=180:duration=3,setpts=PTS-STARTPTS[c2v];[0:a]atrim=start=180:duration=3,asetpts=PTS-STARTPTS[c2a];[vid]trim=start=270:duration=3,setpts=PTS-STARTPTS[c3v];[0:a]atrim=start=270:duration=3,asetpts=PTS-STARTPTS[c3a];[c0v][c0a][c1v][c1a][c2v][c2a][c3v][c3a]concat=n=4:v=1:a=1[v][a];[v]setpts=N/(30*TB)[v];[a]asetpts=N/SR/TB[a] -map [v] -map [a] -c:v vp8 -b:v 200k -crf 54 -profile:v 1 -c:a libopus -b:a 32k -vbr on -compression_level 7 -ac 1 -ar 48000 -pass 2 -passlogfile jump_passlogfile -f webm -reserve_index_space 512 480P_600K_71149981_vthumb.webm

Aqui está o arquivo 480P_600K_71149981.mp4 que estou testando.

E aqui está o resultado, 480P_600K_71149981_vthumb.webm e o text dump dele criado com webm_parser_demo.exe da libwebm (ligeiramente modificado para exibir hexadecimal em vez de decimal). As partes interessantes do despejo de texto são, procure por "timecode:" e "Cluster".

  Cluster                            header: [309, 311)  body: [311, 3487)
    Timecode: 0
    SimpleBlock                      header: [31a, 31c)  body: [31c, 323)
      track number: 2
      frames: 1
      timecode: 0
      lacing: 0 (none)
      flags: visible, key frame
      frame byte range: [320, 323)
    SimpleBlock                      header: [323, 325)  body: [325, 395)
      track number: 1
      frames: 1
      timecode: 7
      lacing: 0 (none)
      flags: visible, key frame
      frame byte range: [329, 395)
    SimpleBlock                      header: [395, 397)  body: [397, 39e)
      track number: 2
      frames: 1
      timecode: 15
      lacing: 0 (none)
      flags: visible, key frame
      frame byte range: [39b, 39e)
    SimpleBlock                      header: [39e, 3a0)  body: [3a0, 3bb)
      track number: 1
      frames: 1
      timecode: 28
      lacing: 0 (none)
      flags: visible
      frame byte range: [3a4, 3bb)
    SimpleBlock                      header: [3bb, 3bd)  body: [3bd, 3c4)
      track number: 2
      frames: 1
      timecode: 29
      lacing: 0 (none)
      flags: visible, key frame
      frame byte range: [3c1, 3c4)

O vídeo de origem e destino tem fps diferentes, isso é provavelmente importante. Existem setpts=PTS-STARTPTS filters, mas eles estranhamente não afetam o Start PresentationStamp.

Isso é importante para mim para garantir que -force_key_frames crie quadros-chave no momento correto e, posteriormente, usarei timecodes para deixar apenas 1 sugestão no arquivo. Eu só estou tentando polir, tentando aprender formatos de vídeo, enquanto eu tenho uma chance. Eu farei um player de vídeo para os mais tarde, preciso ter certeza de que esses arquivos são tão simples de ler e renderizar quanto possível.

Se houver apenas vídeo, ou somente áudio, os timecodes iniciam corretamente a partir de 0. Eu testei com este comando:

ffmpeg -i 480P_600K_71149981.mp4 -t 3 -an -reserve_index_space 512 out.webm

Além disso, gostaria de saber se é possível criar quadros de vídeo antes dos quadros de áudio, parece uma maneira mais natural de armazená-los, embora eu não tenha certeza sobre nada. Provavelmente resolverá a si mesmo assim que o problema do timestamps for resolvido.

Se a solução requer alguma alteração no ffmpeg e recompilação, estou bem com isso. Só precisa encontrar o que mudar primeiro.

No entanto, gostaria de saber se devo manter o áudio antes do vídeo e usar -audio_preload . Porque para procurar áudio opus, eu tenho que repetir SeekPreRoll milissegundos de qualquer maneira (80ms no meu caso). Não é como se eu me importasse com isso, neste caso, eu não pretendo nunca procurar dentro de um vídeo de 12 segundos, eu só preciso pegar rapidamente o quadro-chave do segundo 3 de um vídeo para a miniatura. Sim, não há -audio_preload aqui. Além disso, há mais algumas informações confusas sobre opus muxing em matroska aqui, provavelmente inúteis neste caso: link .

Espere, acho que descobri por que o vídeo demora 7 milissegundos. Porque no opus, você tem que tocar CodecDelay (6.5ms aqui) de áudio e simplesmente descartá-lo, antes que qualquer áudio possa ser ouvido, apenas para inicializar o decodificador. Hm, agora gostaria de saber se posso definir esse áudio descartado como um timestamp negativo. link o timecode aqui é um int16 assinado, então provavelmente eu posso. Mas como dizer ao ffmpeg isso ...

Edit1: aqui está a saída do ffprobe:

ffprobe 480P_600K_71149981_vthumb.webm -show_packets -select_streams v -read_intervals %+#5 -v 0

-

[PACKET]
codec_type=video
stream_index=0
pts=7
pts_time=0.007000
dts=7
dts_time=0.007000
duration=33
duration_time=0.033000
convergence_duration=N/A
convergence_duration_time=N/A
size=108
pos=897
flags=K_
[/PACKET]
[PACKET]
codec_type=video
stream_index=0
pts=40
pts_time=0.040000
dts=40
dts_time=0.040000
duration=33
duration_time=0.033000
convergence_duration=N/A
convergence_duration_time=N/A
size=23
pos=1020
flags=__
[/PACKET]
[PACKET]
codec_type=video
stream_index=0
pts=74
pts_time=0.074000
dts=74
dts_time=0.074000
duration=33
duration_time=0.033000
convergence_duration=N/A
convergence_duration_time=N/A
size=23
pos=1067
flags=__
[/PACKET]
[PACKET]
codec_type=video
stream_index=0
pts=107
pts_time=0.107000
dts=107
dts_time=0.107000
duration=33
duration_time=0.033000
convergence_duration=N/A
convergence_duration_time=N/A
size=23
pos=1114
flags=__
[/PACKET]
[PACKET]
codec_type=video
stream_index=0
pts=140
pts_time=0.140000
dts=140
dts_time=0.140000
duration=33
duration_time=0.033000
convergence_duration=N/A
convergence_duration_time=N/A
size=23
pos=1152
flags=__
[/PACKET]

-

ffprobe 480P_600K_71149981_vthumb.webm -show_packets -select_streams a -read_intervals %+#5 -v 0

-

[PACKET]
codec_type=audio
stream_index=1
pts=-7
pts_time=-0.007000
dts=-7
dts_time=-0.007000
duration=20
duration_time=0.020000
convergence_duration=N/A
convergence_duration_time=N/A
size=3
pos=888
flags=K_
[/PACKET]
[PACKET]
codec_type=audio
stream_index=1
pts=14
pts_time=0.014000
dts=14
dts_time=0.014000
duration=20
duration_time=0.020000
convergence_duration=N/A
convergence_duration_time=N/A
size=3
pos=1011
flags=K_
[/PACKET]
[PACKET]
codec_type=audio
stream_index=1
pts=34
pts_time=0.034000
dts=34
dts_time=0.034000
duration=20
duration_time=0.020000
convergence_duration=N/A
convergence_duration_time=N/A
size=3
pos=1049
flags=K_
[/PACKET]
[PACKET]
codec_type=audio
stream_index=1
pts=54
pts_time=0.054000
dts=54
dts_time=0.054000
duration=20
duration_time=0.020000
convergence_duration=N/A
convergence_duration_time=N/A
size=3
pos=1058
flags=K_
[/PACKET]
[PACKET]
codec_type=audio
stream_index=1
pts=74
pts_time=0.074000
dts=74
dts_time=0.074000
duration=20
duration_time=0.020000
convergence_duration=N/A
convergence_duration_time=N/A
size=3
pos=1096
flags=K_
[/PACKET]

Realmente estranho como o vídeo tem o primeiro timestamp 7 e o áudio tem o primeiro timestamp -7.

Na matroska (marcada com webm_parser_demo.exe ), o vídeo tem data e hora 7 e o áudio tem data e hora 0.

E meu objetivo é criar o primeiro timestamp de vídeo 0 e o primeiro timestamp de áudio -7 (todos os dados do CodecDelay).

Edit2: Estudei alguns webm com vorbis audio, eles também não iniciam ambos em 0. Neles, o áudio começa em 0 e o vídeo em 3. Não sei o que está acontecendo, é também CodecDelay?

    
por siods333333 11.01.2018 / 09:13

0 respostas