2、环境搭建:浏览器兼容性检查、本地HTTPS服务器搭建(Node.js)、第一个WebRTC页面
说实话,很多初学者一上来就急着写代码,结果卡在最基础的环境上。我见过太多人花了一整天,最后发现是浏览器不支持,或者没有HTTPS导致摄像头打不开。所以这一章,咱们先把地基打牢。
2.1 浏览器兼容性检查
WebRTC 虽然已经是个成熟技术了,但不同浏览器的支持程度还是有差异的。我自己的习惯是,开工前先跑一遍兼容性检测,省得后面踩坑。
2.1.1 哪些浏览器支持?
目前主流浏览器基本都支持 WebRTC,但细节上有些区别:
| 浏览器 | WebRTC 支持情况 | 备注 |
|---|---|---|
| Chrome / Edge (Chromium) | ✅ 完整支持 | 开发首选,调试工具最全 |
| Firefox | ✅ 完整支持 | 部分 API 命名略有不同 |
| Safari | ✅ 支持(iOS 11+) | H.264 编码支持更好 |
| Opera | ✅ 支持 | 和 Chrome 内核一致 |
| IE / 旧版 Edge | ❌ 不支持 | 别想了,换浏览器吧 |
2.1.2 快速检测方法
打开浏览器控制台,输入下面这行代码:
navigator.mediaDevices.getUserMedia === undefined ?
console.log('❌ 不支持') : console.log('✅ 支持')
如果返回 true,恭喜你,环境没问题。如果返回 false 或者报错,嗯……你可能需要换个浏览器。
2.2 为什么必须用 HTTPS?
这个问题我经常被问到。说白了,就是浏览器出于安全考虑,不允许在非安全环境下调用摄像头和麦克风。
你想想看,如果随便一个 HTTP 网站都能偷偷打开你的摄像头,那多吓人?所以 Chrome、Firefox 这些浏览器强制要求:调用 getUserMedia 必须在 HTTPS 环境下。
2.3 搭建本地 HTTPS 服务器(Node.js)
我个人比较喜欢用 Node.js 搭本地服务器,轻量又灵活。下面是我常用的两种方式。
2.3.1 方式一:使用 http-server(最简单)
如果你只是想快速跑起来,用这个:
# 安装
npm install -g http-server
# 启动(默认 HTTP)
http-server . -p 8080
但这样是 HTTP,不是 HTTPS。要启用 HTTPS,需要先生成证书。
2.3.2 生成自签名证书
打开终端,执行以下命令:
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out cert.pem
过程中会问你一些问题,随便填就行。重要的是,你会得到两个文件:
key.pem—— 私钥cert.pem—— 证书
2.3.3 方式二:用 Node.js 写一个 HTTPS 服务器
这是我更推荐的方式,因为可控性更强。创建一个 server.js 文件:
const https = require('https');
const fs = require('fs');
const path = require('path');
const options = {
key: fs.readFileSync(path.join(__dirname, 'key.pem')),
cert: fs.readFileSync(path.join(__dirname, 'cert.pem'))
};
https.createServer(options, (req, res) => {
// 设置静态文件服务
let filePath = path.join(__dirname, req.url === '/' ? 'index.html' : req.url);
let extname = path.extname(filePath);
let contentType = 'text/html';
// 根据文件扩展名设置 Content-Type
switch (extname) {
case '.js': contentType = 'text/javascript'; break;
case '.css': contentType = 'text/css'; break;
case '.json': contentType = 'application/json'; break;
case '.png': contentType = 'image/png'; break;
case '.jpg': contentType = 'image/jpg'; break;
}
fs.readFile(filePath, (err, content) => {
if (err) {
res.writeHead(404);
res.end('File not found');
} else {
res.writeHead(200, { 'Content-Type': contentType });
res.end(content);
}
});
}).listen(3000, () => {
console.log('✅ HTTPS 服务器已启动:https://localhost:3000');
});
然后运行:
node server.js
打开浏览器访问 https://localhost:3000,看到提示不安全?别慌,点「高级」→「继续前往」就行。
openssl version 能不能跑。
2.4 第一个 WebRTC 页面
好了,环境搭好了,咱们来写第一个页面。这个页面很简单:点击按钮,打开摄像头,把画面显示在页面上。
2.4.1 创建 index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个 WebRTC 页面</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
text-align: center;
}
video {
width: 100%;
max-width: 640px;
border: 2px solid #333;
border-radius: 8px;
margin: 20px 0;
}
button {
padding: 12px 24px;
font-size: 16px;
background: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #45a049;
}
#status {
margin: 10px 0;
color: #666;
}
</style>
</head>
<body>
<h1>📷 WebRTC 音视频采集</h1>
<p id="status">点击下方按钮打开摄像头</p>
<video id="localVideo" autoplay playsinline></video>
<br>
<button id="startBtn">打开摄像头</button>
<button id="stopBtn" disabled>关闭摄像头</button>
<script>
const localVideo = document.getElementById('localVideo');
const startBtn = document.getElementById('startBtn');
const stopBtn = document.getElementById('stopBtn');
const status = document.getElementById('status');
let localStream = null;
// 检查浏览器是否支持
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
status.textContent = '❌ 您的浏览器不支持 WebRTC';
startBtn.disabled = true;
}
// 打开摄像头
startBtn.addEventListener('click', async () => {
try {
status.textContent = '⏳ 正在请求摄像头权限...';
const constraints = {
video: {
width: { ideal: 1280 },
height: { ideal: 720 }
},
audio: false // 先不要音频,后面章节再讲
};
localStream = await navigator.mediaDevices.getUserMedia(constraints);
localVideo.srcObject = localStream;
status.textContent = '✅ 摄像头已打开';
startBtn.disabled = true;
stopBtn.disabled = false;
} catch (err) {
status.textContent = `❌ 打开摄像头失败:${err.message}`;
console.error('getUserMedia 错误:', err);
}
});
// 关闭摄像头
stopBtn.addEventListener('click', () => {
if (localStream) {
localStream.getTracks().forEach(track => track.stop());
localVideo.srcObject = null;
localStream = null;
status.textContent = '🛑 摄像头已关闭';
startBtn.disabled = false;
stopBtn.disabled = true;
}
});
</script>
</body>
</html>
2.4.2 运行效果
把 index.html 放到你的项目目录里,启动 HTTPS 服务器,然后访问 https://localhost:3000。点击「打开摄像头」,浏览器会弹出权限请求,允许后就能看到自己的脸了。
getUserMedia是 WebRTC 的入口 API,用于获取音视频流constraints参数可以指定分辨率、帧率等- 返回的
MediaStream对象可以直接赋值给<video>元素的srcObject - 记得用
autoplay属性,否则画面不会自动播放
2.5 本章知识体系
下面这张图帮你理清本章的核心逻辑:
2.6 常见问题与解决
我在教学和项目中遇到过不少新手踩坑,这里列几个最常见的:
- 摄像头打不开? 先检查是不是 HTTPS,再检查浏览器权限设置。Chrome 地址栏左边有个小锁图标,点开看看摄像头权限是不是被禁了。
- 画面黑屏? 确认
<video>标签加了autoplay和playsinline属性。iOS 上不加playsinline会默认全屏播放。 - 证书报错? 自签名证书第一次访问时,浏览器会拦截。记得手动点击「高级」→「继续前往」。
- 手机访问不了? 确保手机和电脑在同一个局域网,然后用电脑的 IP 地址访问,比如
https://192.168.1.100:3000。
好了,环境搭建就到这里。你现在应该有一个能正常工作的 HTTPS 服务器,并且成功打开了摄像头。下一章咱们会深入 getUserMedia 的各种参数配置,包括分辨率、帧率、音频等。
公众号:蓝海资料掘金营,微信deep3321