如何编程获取MP4容器的PTS时间以解决双摄像头同步偏差?
背景
我们在一项研究项目中,通过两台摄像头采集视频数据,每秒向麦克风ADC输入一次同步脉冲。
问题
我们需要为每个摄像头帧推导脉冲源时钟下的帧时间戳,以此建立两台摄像头图像的时间关联。当前方法得出两台摄像头间存在约2帧的偏移,但实际检查视频发现,二者至少在某一节点存在明显的6帧偏移,推测是音视频信号关联方式有误导致的。
寻求帮助的方向
了解到MP4容器中存在视频和音频的PTS时间,想知道如何通过编程方式获取这些时间?优先用Python实现,若需要调用ffmpeg也可以接受。
当前方案的问题
最初的思路是通过以下方式计算音视频时间:
audio_sample_times = range(N_audiosamples)/audio_sampling_rate video_frame_times = range(N_videoframes)/video_frame_rate
随后在audio_sample_times中识别同步脉冲的时间,计算每个video_time在相邻audio_pulse_times间的相对位置,并将对应相对值映射到source_pulse_times中。但部分视频中N_audiosamples/audio_sampling_rate与N_videoframes/video_frame_rate相差多帧,说明这个方案存在问题。
已尝试的内容
使用OpenCV的cv2.CAP_PROP_POS_MSEC获取时间,但该方法逻辑和当前方案一致,并未访问到PTS时间。
补充:参考最优答案后的尝试
尝试了以下代码获取PTS:
container = av.open(video_path) signal = [] audio_sample_times = [] video_sample_times = [] for frame in tqdm(container.decode(video=0, audio=0)): if isinstance(frame, av.audio.frame.AudioFrame): sample_times = (frame.pts + np.arange(frame.samples)) / frame.sample_rate audio_sample_times += list(sample_times) signal_f_ch0 = frame.to_ndarray().reshape((-1, len(frame.layout.channels))).T[0] signal += list(signal_f_ch0) elif isinstance(frame, av.video.frame.VideoFrame): video_sample_times.append(float(frame.pts*frame.time_base)) signal = np.abs(np.array(signal)) audio_sample_times = np.array(audio_sample_times) video_sample_times = np.array(video_sample_times)
但在我的场景中,所有PTS均连续无间隙,结果和原始方案一致。通过图像线索发现视频中存在约10秒的不同步区间,但从获取的数据中找不到相关痕迹。
内容的提问来源于stack exchange,提问作者mcandril
相关产品推荐
相关产品推荐

