如何获取AndroidX VideoCapture每秒录制回调实现数据时间对齐
解答
androidx.camera.core.VideoCapture本身没有内置每录制1秒、每捕获一帧的直接回调,你之前用Handler定时打点的方案不可能做到精准对齐:Handler的消息调度受主线程负载、队列排队影响,和视频实际编码写入的时间轴完全独立,再加上startRecording是异步接口,你调用后立刻打日志的时间点根本不是视频第一帧真正写入的时间点,初始偏移+累计误差根本满足不了严格时间对齐的要求。
要实现视频内容和关联数据的时间轴完全对齐,核心原则是不要用应用层自己的计时器,必须用相机硬件输出的同源时间戳做对齐,具体实现方案如下:
- 给同一个Camera实例额外绑定一个
ImageAnalysis用例,和VideoCapture配置相同的目标分辨率、输出方向。ImageAnalysis的分析回调会返回每一帧相机输出的图像,帧信息里携带的时间戳是相机传感器生成的硬件时间戳,和VideoCapture写入视频文件的帧PTS(显示时间戳)完全同源,对齐精度在微秒级,完全满足业务要求。 - 不要自己维护1秒定时器,在
ImageAnalysis的帧回调里,以视频第一帧的硬件时间戳为起点,计算每帧相对视频起点的偏移时间,既可以做逐帧的数据采集,也可以在时间跨过整秒边界时触发秒级打点,不存在任何累计误差。
你当前的代码可以参考如下逻辑修改:
// 初始化帧分析用例,配置和视频录制一致的输出参数 ImageAnalysis imageAnalysis = new ImageAnalysis.Builder() .setTargetResolution(new Size(1920, 1080)) // 和你VideoCapture配置的分辨率保持一致 .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) .build(); // 记录视频时间轴起点的硬件时间戳 final long[] videoStartTs = {-1}; // 记录上一次触发秒级打点的秒数,避免重复触发 final long[] lastTickSecond = {-1}; imageAnalysis.setAnalyzer(getExecutor(), image -> { long currentFrameTs = image.getImageInfo().getTimestamp(); // 第一帧到达时记录视频真实起始时间 if (videoStartTs[0] == -1) { videoStartTs[0] = currentFrameTs; Log.i(TAG, "Video recording actually started, sensor ts: " + currentFrameTs); } // 计算当前帧在视频时间轴上的相对偏移 long relativeNs = currentFrameTs - videoStartTs[0]; long relativeSec = relativeNs / 1_000_000_000; // 逐帧逻辑可以写在这里 // Log.i(TAG, "Frame arrived, relative time: " + relativeNs + "ns"); // 整秒打点逻辑:跨过整秒边界时触发一次 if (relativeSec != lastTickSecond[0]) { lastTickSecond[0] = relativeSec; Log.i(TAG, "Tick, current video duration: " + relativeSec + "s"); // 在这里写入和当前秒严格对齐的业务数据 } // 必须关闭image,不然分析队列会阻塞 image.close(); }); // 绑定用例时,把ImageAnalysis和VideoCapture、Preview一起绑定到相同生命周期和CameraSelector cameraProvider.bindToLifecycle( this, cameraSelector, preview, videoCapture, imageAnalysis ); // 之后再调用你原来的startRecording逻辑即可,不需要再自己开Handler做定时
补充说明:androidx.camera.core.VideoCapture已经在CameraX 1.1.0及以上版本被标记为废弃,官方推荐切换到androidx.camera.video包下的Recorder实现视频录制,新接口原生提供VideoRecordEvent回调,可以直接拿到录制过程中的精准时长、帧统计信息,不需要额外绑定ImageAnalysis就能拿到对齐的时间信息。
内容的提问来源于stack exchange,提问作者Frederik Petri
相关产品推荐
相关产品推荐

