你以为摄像头权限只能靠一堆JS回调?今天一行HTML把这件事彻底原生化了
写过前端的人都踩过这个坑——每次要用摄像头或麦克风,navigator.mediaDevices.getUserMedia() 要写一套权限判断、错误处理、stream 赋值的样板。更难受的是:JavaScript 触发的权限请求特别容易被用户拒绝,Cisco 的数据说原来只有 10% 的「拒绝后重试」用户最终给了权限。
Chrome 153 今天把这个彻底原生化了——<camera> 和 <microphone> 两个声明式 HTML 元素,分别只请求视频和音频单一能力。
从 usermedia 到单一能力的梯度
Chrome 151 引入了 <usermedia>(同时请求视频+音频),Chrome 153 则补全了单一能力的梯度:
<usermedia>→ 视频 + 音频同时请求(Chrome 151)<camera>→ 仅视频捕获(Chrome 153)<microphone>→ 仅音频捕获(Chrome 153)
三个元素共享同一套安全模型,用法几乎一样,只是按需选择粒度更细的那个。
工作原理:浏览器接管权限 UI
<camera id="my-cam"></camera>
<video id="preview" autoplay></video>
<script>
const cam = document.getElementById(my-cam);
// 可选:设置约束
cam.setConstraints({ video: { width: 1280, height: 720 } });
// 成功:拿到 MediaStreamTrack
cam.ontrack = (e) => {
document.getElementById(preview).srcObject = e.track;
};
// 失败
cam.onerror = (e) => {
console.error(摄像头错误:, cam.error);
};
// 用户取消
cam.oncancel = () => {
console.log(用户拒绝了权限请求);
};
</script>
对比传统 getUserMedia() 的样板:
// 传统方式:各种错误类型要分别处理,样板代码多
navigator.mediaDevices.getUserMedia({ video: true })
.then(stream => {
const videoTrack = stream.getVideoTracks()[0];
document.getElementById(preview).srcObject = stream;
})
.catch(err => {
if (err.name === NotAllowedError) { /* ... */ }
if (err.name === NotFoundError) { /* ... */ }
if (err.name === OverconstrainedError) { /* ... */ }
});
<camera> 的核心区别在于:浏览器自己渲染控件、自己强制执行样式规则(不能伪装、不能隐藏),而且必须用户真实点击控件,权限请求才会发出。
数据说明一切
这不是炫技,是真的管用:
- Cisco:原来拒绝过的用户给权限率从 10% 提升到 65%
- Google Meet:权限恢复成功率提升 131%
- Zoom:摄像头/麦克风捕获错误下降 46.9%,「麦克风不工作」投诉下降 17%
本质原因是:浏览器原生渲染的按钮是用户熟悉的 UI,真实点击是可信的操作信号,权限提示的通过率自然就上去了。
W3C 规范定义
<camera> 和 <microphone> 属于 W3C Media Capture Extensions 规范,接口如下:
interface HTMLCameraElement : HTMLElement {
readonly attribute MediaStreamTrack? track; // 直接拿到 track
readonly attribute DOMException? error;
undefined setConstraints(optional MediaTrackConstraintSet constraints = {});
attribute EventHandler ontrack;
attribute EventHandler onerror;
attribute EventHandler oncancel;
}
和 getUserMedia() 一样,必须在 HTTPS 环境(或者 localhost)下才能工作。
什么时候用、什么时候不用
适合用 <camera> / <microphone>:
- 用户主动点击「打开摄像头」「开启麦克风」按钮的场景
- 视频会议、在线教育、直播等标准媒体交互
- 想提升权限获取成功率
仍需要 getUserMedia():
- 需要同时请求视频+音频(用
<usermedia>也可以) - 复杂设备选择(前/后摄像头、多个麦克风)
- 需要动态切换媒体约束
下一步
如果你的项目现在还在用 getUserMedia() 做摄像头/麦克风权限,可以:
- 先检查目标用户是否在 Chrome 153+(caniuse.com 查
<camera>支持) - 不支持的浏览器写
<camera>+ fallback content 渐进增强 - 把「打开摄像头」按钮从 JS 触发改成声明式 HTML 标签
下一个值得关注的 capability element 是 <speaker>——覆盖音频输出控制,Web Audio API 一直没解决的声明式方案。
评论区
登录后可评论。