必须在HTTPS或localhost安全上下文中调用getUserMedia,HTTP或file://协议会触发NotAllowedError;constraints需显式指定facingMode、分辨率等避免黑屏静音;流须赋给video.srcObject并设autoplay、muted、playsinline等属性确保正常播放。

调用 getUserMedia 前必须确保页面在安全上下文中
浏览器只允许在 https:// 或 localhost(含 127.0.0.1)下启用摄像头和麦克风。HTTP 页面会直接拒绝请求,且控制台报错:NotAllowedError: Permission denied。开发时别用文件协议(file://)双击打开 HTML,必须起一个本地服务——比如用 python3 -m http.server 8000 启动后访问 http://localhost:8000。
constraints 对象怎么写才不被静音或黑屏
常见错误是只传 { video: true, audio: true },但实际设备可能因权限、驱动或系统设置返回空流或静音流。应显式声明期望能力:
- 麦克风静音?加
echoCancellation: false或autoGainControl: false可能缓解(某些浏览器默认开启回声抑制,反而导致无声) - 摄像头黑屏?指定分辨率:
width: { ideal: 1280 }, height: { ideal: 720 },避免浏览器选到不支持的格式 - 想强制前置摄像头?用
facingMode: "user";后置则用"environment"(注意 iOS Safari 对"environment"支持有限)
完整示例:
const constraints = {
video: { width: { ideal: 1280 }, height: { ideal: 720 }, facingMode: "user" },
audio: { echoCancellation: false }
};
捕获 NotAllowedError 和 NotFoundError 的真实含义
这两个错误常被混淆:
-
NotAllowedError:用户点了“拒绝”,或页面未激活(比如标签页被切走时请求)、或非安全上下文——此时重试无意义,需引导用户手动授权 -
NotFoundError:系统找不到对应设备(比如没插麦克风、摄像头被占用、Mac 上“相机”权限在系统设置里被关了)——可提示用户检查硬件连接或系统权限 - 还有
OverconstrainedError:约束条件太强(如指定不存在的帧率或分辨率),浏览器无法满足,应降级为ideal改成max或直接删掉该字段
拿到流之后,video 元素怎么显示才不卡顿或拉伸
直接 video.srcObject = stream 是对的,但显示效果取决于属性设置:
立即学习“前端免费学习笔记(深入)”;
- 必须加
autoplay和muted(即使有音频,首次播放也常因策略被静音;若要声音,需用户交互后调用video.play()) - 避免拉伸变形:设
video.style.objectFit = "cover"(填满容器并保持比例)或"contain"(完整显示但留黑边) - 移动端要注意:iOS Safari 要求
playsinline属性,否则视频会全屏弹出
最小可用片段:
<video id="cam" autoplay muted playsinline></video>
<script>
const video = document.getElementById("cam");
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => { video.srcObject = stream; })
.catch(err => console.error(err.name, err.message));
</script>
设备切换、权限变更、流中断这些情况不会自动触发回调,得自己监听 navigator.mediaDevices.ondevicechange 或轮询 enumerateDevices() ——这部分容易被忽略,但线上环境很关键。



















