You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTMLCanvasElement.captureStream生成的MediaStream如何捕获鼠标光标?

结论

直接通过HTMLCanvasElement.captureStream()生成的MediaStream不支持原生捕获鼠标光标,你尝试的cursor约束仅对navigator.mediaDevices.getDisplayMedia()返回的屏幕共享轨道生效,canvas捕获轨道不识别该参数,所以调用applyConstraints传入{cursor: 'always'}不会生效。


可行实现方案

你可以通过手动在canvas绘制光标的方式实现录制内容带光标,有两种常用实现路径:

1. 直接在原canvas绘制光标

监听canvas的鼠标事件获取光标位置,在原有canvas渲染逻辑中额外绘制自定义光标,录制的流自然会包含光标内容:

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
// 存储光标状态
const cursor = {
  x: 0,
  y: 0,
  visible: false
};

// 监听鼠标事件更新光标状态
canvas.addEventListener('mousemove', (e) => {
  const rect = canvas.getBoundingClientRect();
  cursor.x = e.clientX - rect.left;
  cursor.y = e.clientY - rect.top;
  cursor.visible = true;
});
canvas.addEventListener('mouseleave', () => {
  cursor.visible = false;
});

// 原有渲染循环中加入光标绘制逻辑
function render() {
  // 此处保留你原有的canvas绘制逻辑

  // 额外绘制光标
  if (cursor.visible) {
    // 示例为绘制简单的箭头光标,也可以用drawImage绘制自定义光标图片
    ctx.fillStyle = '#000';
    ctx.beginPath();
    ctx.moveTo(cursor.x, cursor.y);
    ctx.lineTo(cursor.x + 10, cursor.y + 2);
    ctx.lineTo(cursor.x + 2, cursor.y + 10);
    ctx.closePath();
    ctx.fill();
  }

  requestAnimationFrame(render);
}
render();

// 原有录制逻辑保持不变即可
let stream = canvas.captureStream(20);
let recorder = new MediaRecorder(stream, {mimeType: 'video/webm'});

2. 离屏canvas录制(不影响用户看到的原canvas内容)

如果不希望用户看到页面上的canvas多出额外绘制的光标,可以创建一个离屏canvas,每一帧先把原canvas内容复制到离屏canvas上,再在离屏canvas绘制光标,最后对离屏canvas调用captureStream()进行录制即可。


内容的提问来源于stack exchange,提问作者junvar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 01:51:04