WebRTC屏幕录制是实时协作、在线教学等场景的核心功能,其中鼠标轨迹与视频帧的同步效果直接影响录制内容的质量。如果两者出现时间差,用户观看录制内容时会发现鼠标移动和画面变化不匹配,降低内容的可读性。

核心同步原理
实现鼠标轨迹与视频帧同步的核心是保证两者的时间戳基准一致。视频帧采集时会生成采集时间戳,鼠标移动事件也会触发对应的事件时间戳,只要将两者的时间戳对齐到同一个基准,就能实现基础同步。
时间戳基准选择
建议使用performance.now()作为统一时间戳基准,该接口返回的时间戳精度更高,且不受系统时间调整的影响,比Date.now()更适合用于帧和事件的时序对齐。
帧率与采样率匹配
视频帧的采集帧率是固定的,比如常见的30fps,即每33ms左右生成一帧。鼠标移动的触发频率通常高于视频帧率,因此需要合理采样鼠标事件,避免冗余数据增加处理压力。
实现步骤
1. 采集视频帧并记录时间戳
通过WebRTC的getDisplayMedia接口获取屏幕流,使用MediaRecorder录制视频,同时在每一帧采集时记录对应的时间戳。
// 获取屏幕流
async function getScreenStream() {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: {
frameRate: 30 // 设置视频帧率为30fps
},
audio: false
});
return stream;
}
// 记录视频帧时间戳
let frameTimestamps = [];
function recordFrameTimestamp() {
const timestamp = performance.now();
frameTimestamps.push(timestamp);
// 请求下一帧时继续记录
requestAnimationFrame(recordFrameTimestamp);
}
2. 采集鼠标事件并标记时间戳
监听全局的鼠标移动事件,每次事件触发时记录鼠标位置和对应的时间戳,同时可以过滤掉短时间内重复的移动事件,减少数据量。
let mouseEvents = [];
let lastMouseTime = 0;
// 鼠标移动事件采样间隔,设置为30ms,和30fps的视频帧间隔匹配
const MOUSE_SAMPLE_INTERVAL = 30;
document.addEventListener('mousemove', (e) => {
const currentTime = performance.now();
// 间隔不足30ms则跳过本次事件
if (currentTime - lastMouseTime < MOUSE_SAMPLE_INTERVAL) {
return;
}
lastMouseTime = currentTime;
mouseEvents.push({
x: e.clientX,
y: e.clientY,
timestamp: currentTime
});
});
3. 时间戳对齐与轨迹渲染
在录制完成后处理数据时,将每个鼠标事件匹配到对应时间区间的视频帧,渲染时根据帧的时间戳绘制对应时间点的鼠标位置。
// 将鼠标事件匹配到对应的视频帧
function matchMouseToFrames(frames, mouseEvents) {
const result = [];
let mouseIndex = 0;
for (const frame of frames) {
const frameStart = frame.timestamp;
const frameEnd = frame.timestamp + 33; // 30fps对应每帧33ms
// 找到当前帧时间区间内的所有鼠标事件
const currentFrameMouses = [];
while (mouseIndex < mouseEvents.length && mouseEvents[mouseIndex].timestamp <= frameEnd) {
if (mouseEvents[mouseIndex].timestamp >= frameStart) {
currentFrameMouses.push(mouseEvents[mouseIndex]);
}
mouseIndex++;
}
result.push({
frame,
mouseEvents: currentFrameMouses
});
}
return result;
}
优化建议
- 可以在鼠标事件中加入事件类型标记,比如单击、双击、右键点击等,录制时同步这些事件,让轨迹更完整。
- 如果视频帧出现丢帧情况,需要动态调整鼠标事件的匹配逻辑,避免出现轨迹跳变。
- 对于高帧率的屏幕录制场景,可以适当提高鼠标事件的采样频率,保证轨迹的平滑度。
常见问题排查
如果出现同步偏差,可以先检查两者的时间戳基准是否一致,再确认鼠标采样间隔是否和视频帧间隔匹配。如果是录制后处理阶段的问题,可以打印时间戳对比,找到偏差出现的具体环节。
注意:如果录制过程中涉及跨标签页的鼠标事件,需要监听对应标签页的鼠标事件,避免遗漏轨迹数据。