如何在Angular中替换Camera函数并向Facemesh.js传入自定义MediaStream
解决方法
你需要把自定义的MediaStream绑定到video元素上,然后通过帧循环持续将video的当前帧传入faceMesh.send(),替代原Camera类的帧捕获逻辑,具体步骤如下:
1. 绑定MediaStream到Video元素
先将从其他模块获取的自定义MediaStream赋值给video元素的srcObject,让video渲染流内容:
// 在Angular组件中,假设已通过服务获取到customStream: MediaStream const videoElement = document.getElementById('facemesh-video') as HTMLVideoElement; videoElement.srcObject = customStream; await videoElement.play(); // 必须等待video开始播放才能获取有效帧
2. 实现自定义帧循环
用requestAnimationFrame创建持续的帧回调,在回调中调用faceMesh.send(),和原Camera类的onFrame逻辑一致:
// 初始化FaceMesh(按官方文档配置) const faceMesh = new FaceMesh({ locateFile: (file) => `https://cdn.jsdelivr.net/npm/@mediapipe/face_mesh/${file}` }); // 配置FaceMesh的结果回调 faceMesh.onResults((results) => { // 处理人脸检测结果,比如绘制关键点等 console.log(results.multiFaceLandmarks); }); // 定义帧循环函数 let animationId: number; const processFrame = async () => { await faceMesh.send({ image: videoElement }); animationId = requestAnimationFrame(processFrame); }; // 启动帧循环 processFrame();
3. 清理资源
在Angular组件销毁时,记得停止帧循环并释放FaceMesh资源,避免内存泄漏:
ngOnDestroy() { cancelAnimationFrame(animationId); faceMesh.close(); }
关键说明
faceMesh.send()接收的image参数可以是HTMLVideoElement,只要video正在播放有效流,就能从中提取当前帧- 必须等待
video.play()完成后再启动帧循环,否则会传入空帧导致FaceMesh报错 - 如果需要固定分辨率,可以在获取MediaStream时指定(比如通过
getUserMedia的constraints参数),或者对video元素设置宽高样式
内容的提问来源于stack exchange,提问作者rishabh pandey
相关产品推荐
相关产品推荐

