localhost 打开而不是双击 HTML 文件。
使命说 WebRTC 是"浏览器之间直连"的标准答案 —— 它把 NAT 穿透、编解码协商、加密传输全包进浏览器。 但很多人一上手就想"两个浏览器连起来",结果被信令、SDP、ICE 一起砸晕。 正确的第一步是只碰最不容易出错的那部分:本地媒体。
getUserMedia(拿摄像头/麦克风)只在
https:// 或 http://localhost 下可用。双击本地 HTML 文件打开(file://)在多数浏览器里会被拒 ——
所以我们要起一个本地服务器。准备一个目录和一个页面文件:
mkdir -p /tmp/webrtc-练习 && cd /tmp/webrtc-练习
新建 media.html(内容如下):
<!doctype html>
<html lang="zh-CN">
<head><meta charset="utf-8"><title>本地媒体</title></head>
<body>
<h1>本地媒体</h1>
<video id="v" autoplay playsinline muted style="max-width:480px"></video>
<p id="s">等待授权…</p>
<script>
const v = document.getElementById('v'), s = document.getElementById('s');
navigator.mediaDevices.getUserMedia({ video: true, audio: false })
.then(stream => {
v.srcObject = stream;
const t = stream.getVideoTracks()[0].getSettings();
s.textContent = `成功:${t.width}x${t.height} @ ${t.frameRate}fps`;
})
.catch(err => { s.textContent = '失败:' + err.name + ' — ' + err.message; });
</script>
</body>
</html>
起服务器并打开:
cd /tmp/webrtc-练习
python -m http.server 8000
# 然后在浏览器访问:http://localhost:8000/media.html
你会看到两件事之一:
640x480 @ 30fps)NotAllowedError(你拒绝了权限或系统层禁用)、
NotFoundError(没找到摄像头)、NotReadableError(被别的程序占用,如会议软件)。
把错误名记住:它比"没画面"有用一百倍。加一道对比实验:把同一个文件用"双击打开"的方式(file://)试一次,看浏览器怎么拒绝你 —— 这一步会让你记住"安全上下文"这件事,而不是背规则。
1. WebRTC 规范不负责哪一部分?
对。信令(怎么把 SDP 与候选送到对方)规范不管 —— 这也是"为什么必须自己搭信令服务器"的答案。其余三项都由 WebRTC 提供。
2. 为什么这个练习页面不能用 file:// 打开?
对。getUserMedia 属于敏感接口,只在安全上下文(https 或 localhost)可用 —— 直接双击打开通常会被拒。注意选项 c 看着也像,但它说的"禁止读取"是结果,不是原因。
3. 看到 NotReadableError 通常意味着?
对。设备被占用(会议软件、录屏工具)是最常见成因;拒绝授权是 NotAllowedError,没有设备是 NotFoundError。认错误名 = 快速定位。