Angular中使用navigator.mediaDevices.getUserMedia加载摄像头视频至video元素遇阻
解决摄像头画面无法加载到video元素的问题
你的代码存在几处关键问题,导致摄像头画面无法正常加载到video元素中,以下是问题分析和修正方案:
问题点梳理
语法错误:
sync应为async
异步方法声明的关键字是async,而非sync,错误的关键字会导致await无法生效,异步逻辑执行混乱。未触发视频播放
代码中this.videoC.play只是引用了方法对象,没有实际执行播放操作,必须调用this.videoC.play()才能启动视频流播放。混用
await与.then()/.catch()
使用await时,搭配try/catch处理异步错误会让代码逻辑更清晰,避免两种异步语法混用导致的执行顺序问题。不必要的MediaStream重复创建
getUserMedia返回的stream本身就是标准的MediaStream对象,直接赋值给video.srcObject即可,无需通过new MediaStream(stream.getTracks())重新创建。设备列表输出不完整
navigator.mediaDevices.enumerateDevices()返回的是Promise对象,直接console.log只会打印Promise状态,需要用await或.then()获取实际的设备列表数据。
修正后的代码
HTML代码(无需修改)
<button (click)="startCamera()">Get access to camera</button> <div style="width: 640px; height: 480px; border: 1px solid black;"> <video id="videoC" #videoC height="480px" width="640px" autoplay="true" loop="true" muted="true"></video> </div>
TypeScript代码
@ViewChild("videoC") videoC!: HTMLVideoElement; async startCamera() { // 正确获取并打印设备列表 try { const devices = await navigator.mediaDevices.enumerateDevices(); console.log(devices); } catch (err) { console.error("获取设备列表失败:", err); } // 处理摄像头权限与视频流加载 try { // 提前做兼容性检查 if (!navigator.mediaDevices?.getUserMedia) { console.error("当前浏览器不支持摄像头访问功能"); return; } const stream = await navigator.mediaDevices.getUserMedia({ video: { aspectRatio: 1.33, frameRate: 60, width: 640, height: 480 }, audio: false }); // 直接将视频流赋值给video元素 this.videoC.srcObject = stream; // 确保视频播放(即使设置了autoplay,部分浏览器仍需显式调用) await this.videoC.play(); console.log(this.videoC); console.log('Video run'); } catch (err) { console.error(`发生错误: ${err}`); } }
额外注意事项
- 确保页面运行在HTTPS环境下(localhost开发环境除外),
getUserMedia仅允许在安全上下文使用。 - 若仍无法加载,检查浏览器是否已授予摄像头权限,可在浏览器设置中确认权限状态。
内容的提问来源于stack exchange,提问作者rheza 555
相关产品推荐
相关产品推荐

