WebRTC媒体流信息以及兼容性代码


捕获本地媒体
getUserMedia()在各浏览器的区别:
Chrome:
支持版本:53+(标准 API),旧版需前缀 webkitGetUserMedia。
标准用法:navigator.mediaDevices.getUserMedia()。
Firefox:
支持版本:36+,无前缀。
Safari:
支持版本:11+(iOS 11+ 和 macOS High Sierra+),旧版需前缀 webkitGetUserMedia。
Edge:
Chromium 内核版(79+):同 Chrome,无前缀。
旧版 EdgeHTML:部分支持,需前缀 msGetUserMedia。
Opera:
支持版本:40+,行为与 Chrome 一致。
HTTPS 要求
所有现代浏览器(Chrome、Firefox、Safari、Edge)要求非本地环境必须使用 HTTPS。
例外:localhost 和 file:// 协议下允许 HTTP(Safari 对 file:// 限制更严格)。
约束支持(Constraints)
Chrome/Firefox/Edge:
支持常用约束(如 width、height、frameRate)。
支持高级选项(如 noiseSuppression、echoCancellation)。
Safari:
支持基础约束(如分辨率、设备 ID)。
不支持 facingMode(前后摄像头切换需通过设备 ID 指定)。
某些音频处理选项可能受限(如 autoGainControl)。
. 权限行为
桌面浏览器:
弹窗请求摄像头/麦克风权限,可单独授权。
移动端(iOS Safari):
必须由用户手势触发(如点击事件),否则直接拒绝。
首次请求会弹窗,后续访问可能静默授权(需用户手动重置)。
移动端特殊限制
iOS Safari:
无法同时请求 audio 和 video(需分开授权)。
视频分辨率受系统限制(通常最高 720p)。
页面跳转或进入后台时,媒体流自动停止。
Android Chrome/Firefox:
行为接近桌面版,但受设备硬件影响更大。
兼容性代码
// 检测标准化 API
if (navigator.mediaDevices?.getUserMedia) {
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => console.log("成功获取媒体流"))
.catch(error => console.error("错误:", error.name));
} else {
// 处理旧版浏览器(如 Safari 10-)
const legacyGetUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
if (legacyGetUserMedia) {
legacyGetUserMedia.call(navigator, { video: true },
stream => console.log("成功"),
error => console.error("失败")
);
}
}
以下是一个完整的、兼容主流浏览器的WebRTC示例代码,包含摄像头/麦克风访问和基础错误处理:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebRTC 兼容性演示</title>
<!-- 引入 WebRTC 适配库 -->
<script src="adapter-latest.js"></script>
<style>
video {
width: 400px;
height: 300px;
border: 2px solid #333;
margin: 10px;
}
.container {
margin: 20px;
}
button {
padding: 10px;
margin: 5px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="container">
<h1>WebRTC 媒体演示</h1>
<video id="localVideo" autoplay playsinline></video>
<div>
<button id="startBtn">启动摄像头</button>
<button id="stopBtn" disabled>停止摄像头</button>
</div>
<div id="errorMsg" style="color: red;"></div>
</div>
<script>
const localVideo = document.getElementById('localVideo');
const startBtn = document.getElementById('startBtn');
const stopBtn = document.getElementById('stopBtn');
const errorMsg = document.getElementById('errorMsg');
let localStream = null;
// 浏览器兼容性处理函数
async function getMedia(constraints) {
try {
// 现代浏览器标准用法
if (navigator.mediaDevices?.getUserMedia) {
return await navigator.mediaDevices.getUserMedia(constraints);
}
// 旧版浏览器兼容处理
const legacyGetUserMedia = (
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia
);
if (legacyGetUserMedia) {
return await new Promise((resolve, reject) => {
legacyGetUserMedia.call(navigator, constraints, resolve, reject);
});
}
throw new Error('浏览器不支持媒体设备访问');
} catch (error) {
handleError(error);
throw error;
}
}
// 启动摄像头
async function startCamera() {
try {
errorMsg.textContent = '';
localStream = await getMedia({
video: {
width: { ideal: 1280 },
height: { ideal: 720 },
facingMode: "user"
},
audio: true
});
localVideo.srcObject = localStream;
startBtn.disabled = true;
stopBtn.disabled = false;
} catch (error) {
console.error('媒体访问错误:', error);
}
}
// 停止摄像头
function stopCamera() {
if (localStream) {
localStream.getTracks().forEach(track => track.stop());
localVideo.srcObject = null;
startBtn.disabled = false;
stopBtn.disabled = true;
}
}
// 错误处理
function handleError(error) {
console.error('错误:', error);
let message = '发生错误: ';
switch(error.name) {
case 'NotAllowedError':
message += '用户拒绝了权限请求';
break;
case 'NotFoundError':
message += '未找到媒体设备';
break;
case 'NotReadableError':
message += '设备正在被其他进程使用';
break;
case 'OverconstrainedError':
message += '无法满足约束条件';
break;
default:
message += error.message;
}
errorMsg.textContent = message;
}
// 事件监听
startBtn.addEventListener('click', startCamera);
stopBtn.addEventListener('click', stopCamera);
</script>
</body>
</html>
adapter-latest.js文件:
上传失败,有需要的人找我,发给你
更多推荐



所有评论(0)