![ffmpeg:从 alsa/madi 捕获到 mpeg-ts 时保留时间戳](https://linux22.com/image/1623890/ffmpeg%EF%BC%9A%E4%BB%8E%20alsa%2Fmadi%20%E6%8D%95%E8%8E%B7%E5%88%B0%20mpeg-ts%20%E6%97%B6%E4%BF%9D%E7%95%99%E6%97%B6%E9%97%B4%E6%88%B3.png)
编码为 mpeg-ts/aac 时,从 ALSA/MADI 输入(包含时间戳)捕获时是否可以保留原始时间戳?MADI 源由第三方提供给我们。
FFMpeg 版本:4.2.2
起初,这似乎是一项简单的任务,但我无法让它正常工作。源代码提供了一个纪元时间戳(第一行显示系统的当前时间戳作为参考):
$ date +%s && ffprobe -show_entries stream -f alsa -i RME-5556
1589812196
ffprobe version 4.2.2 Copyright (c) 2007-2019 the FFmpeg developers
built with gcc 7 (GCC)
configuration: --prefix=/software/ffmpeg-4.2.2-aeef8c6f --enable-pic --enable-pthreads --disable-shared --enable-static --enable-gpl --enable-nonfree --enable-libmp3lame --enable-libx264 --enable-libvorbis --enable-libx265 --enable-libtheora --enable-libxvid --enable-libfdk_aac --disable-crystalhd --enable-avfilter --enable-postproc --enable-bzlib --extra-cflags=-I/compile/lame-3.100-4190d36b/include --extra-cflags=-I/compile/faad2-2.8.8-0a416c66/include --extra-cflags=-I/compile/faac-1.29.9.2-d0f85fb8/include --extra-cflags=-I/compile/xvidcore-1.3.7-b5c2cdca/include --extra-cflags=-I/compile/libogg-1.3.4-de57aa91/include --extra-cflags=-I/compile/libtheora-1.1.1-7256273f/include --extra-cflags=-I/compile/alsa-lib-1.2.1.2-babf7811/include --extra-ldflags=-L/compile/lame-3.100-4190d36b/lib --extra-ldflags=-L/compile/faad2-2.8.8-0a416c66/lib --extra-ldflags=-L/compile/faac-1.29.9.2-d0f85fb8/lib --extra-ldflags=-L/compile/xvidcore-1.3.7-b5c2cdca/lib --extra-ldflags=-L/compile/libogg-1.3.4-de57aa91/lib --extra-ldflags=-L/compile/libtheora-1.1.1-7256273f/lib --extra-ldflags=-L/compile/alsa-lib-1.2.1.2-babf7811/lib --enable-rpath --pkg-config-flags=--static --extra-ldflags=-lpthread --extra-ldflags=-lm
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, alsa, from 'RME-5556':
Duration: N/A, start: 1589812196.319736, bitrate: 1536 kb/s
Stream #0:0: Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s
[STREAM]
index=0
codec_name=pcm_s16le
codec_long_name=PCM signed 16-bit little-endian
profile=unknown
codec_type=audio
codec_time_base=1/48000
codec_tag_string=[0][0][0][0]
codec_tag=0x0000
sample_fmt=s16
sample_rate=48000
channels=2
channel_layout=unknown
bits_per_sample=16
id=N/A
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/1000000
start_pts=1589812196319736
start_time=1589812196.319736
duration_ts=N/A
duration=N/A
bit_rate=1536000
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
[/STREAM]
但是当使用以下命令进行编码时,会显示一个“奇怪的”start_time。
编码一些帧:
$ ffmpeg -hide_banner -v verbose -f alsa -y -i RME-5556 -copyts -acodec aac -ar 48000 -b:a 256k -ac 2 -frames 100 -f mpegts -mpegts_copyts 1 test.ts
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, alsa, from 'RME-5556':
Duration: N/A, start: 1589813372.332589, bitrate: 1536 kb/s
Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Applying unspecific -frames to non video streams, maybe you meant -vframes ?
Stream mapping:
Stream #0:0 -> #0:0 (pcm_s16le (native) -> aac (native))
Press [q] to stop, [?] for help
[graph_0_in_0_0 @ 0x3c5e040] tb:1/48000 samplefmt:s16 samplerate:48000 chlayout:0x3
[format_out_0_0 @ 0x3c5e400] auto-inserting filter 'auto_resampler_0' between the filter 'Parsed_anull_0' and the filter 'format_out_0_0'
[auto_resampler_0 @ 0x3c61680] ch:2 chl:stereo fmt:s16 r:48000Hz -> ch:2 chl:stereo fmt:fltp r:48000Hz
[mpegts @ 0x3c52500] frame size not set
[mpegts @ 0x3c52500] muxrate VBR, pcr every 9 pkts, sdt every 200, pat/pmt every 40 pkts
Output #0, mpegts, to 'test.ts':
Metadata:
encoder : Lavf58.29.100
Stream #0:0: Audio: aac (LC), 48000 Hz, stereo, fltp, delay 1024, 256 kb/s
Metadata:
encoder : Lavc58.54.100 aac
No more output streams to write to, finishing. 0.0kbits/s speed=7.84e+08x
size= 76kB time=441614:49:34.45 bitrate= 0.0kbits/s speed=7.43e+08x
video:0kB audio:66kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 14.145925%
Input file #0 (RME-5556):
Input stream #0:0 (audio): 101 packets read (413696 bytes); 101 frames decoded (103424 samples);
Total: 101 packets (413696 bytes) demuxed
Output file #0 (test.ts):
Output stream #0:0 (audio): 101 frames encoded (103424 samples); 100 packets muxed (67857 bytes);
Total: 100 packets (67857 bytes) muxed
[AVIOContext @ 0x3c4eac0] Statistics: 0 seeks, 1 writeouts
[aac @ 0x3c53980] Qavg: 197.511
分析一下:
$ ffprobe -hide_banner -loglevel warning -show_entries program test.ts
[PROGRAM]
program_id=1
program_num=1
nb_streams=1
pmt_pid=4096
pcr_pid=256
start_pts=7366767433
start_time=7366.767433
end_pts=7368906744
end_time=7368.906744
TAG:service_name=Service01
TAG:service_provider=FFmpeg
[STREAM]
index=0
codec_name=aac
codec_long_name=AAC (Advanced Audio Coding)
profile=LC
codec_type=audio
codec_time_base=1/48000
codec_tag_string=[15][0][0][0]
codec_tag=0x000f
sample_fmt=fltp
sample_rate=48000
channels=2
channel_layout=stereo
bits_per_sample=0
id=0x100
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/90000
start_pts=663009069
start_time=7366.767433
duration_ts=192538
duration=2.139311
bit_rate=262125
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
...
[/STREAM]
[/PROGRAM]
所以start_pts
设置了,但值很奇怪。这是什么问题?
我尝试并注意到的是:
-copyts
编码时,定义后输入中会显示正确的时间戳(上面输出中的 441614:49:34.45)- 不同
time_base
之处:time_base=1/1000000
输入不同,time_base=1/90000
输出文件不同。这会是个问题吗? -mpegts_copyts 1
似乎是我正在寻找的选项,但似乎没有任何作用。- 我尝试了许多选项,例如试验
-af setpts=
、-copytb
和-enc_time_base
,但都没有任何成功。
由于时间戳似乎因某些因素而偏离,它可能与 time_base 值或某种类型有关?我尝试time_base=1/90000
使用enc_time_base
或更改报告,copytb
但不起作用(所以我可能误解了)
我是否遗漏了什么?
感谢任何提示或建议!
答案1
ALSA 的输入时间戳为 64 位,而 MPEG-TS 将时间戳存储为 33 位(有额外的位可用于更高的精度但不扩大范围)。
因此,在您的编码运行中,初始时间为,1589813372.332589
代表 PTS 为1589813372332589
。转换为时间基数 90000,即 ~,143083203509933
但使用 33 位宽度,余数保留为663010989
。与实际起始 PTS 的差异是由于编码器添加并在解码后丢弃的 AAC 启动样本。