文章目录
前言
利用WebRTC和WebSocket技术,可以实现浏览器摄像头监控。这一实现过程主要依赖于WebRTC在浏览器中进行实时音视频通信的能力,以及WebSocket提供的全双工通信机制。
一、WebRTC是什么?
WebRTC(Web Real-Time Communication)是一项实时通讯技术,它允许网络应用或站点在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流、音频流或其他任意数据的传输。
二、Websocket是什么?
WebSocket允许服务器和客户端之间建立一个持久的连接,通过这个连接双方可以实时地进行双向数据传输。与传统的HTTP协议相比,WebSocket避免了频繁建立和断开连接的开销,从而降低了延迟,提高了数据传输的效率和实时性。
三、通过WebRTC和Websocket技术实现视频监控
本文仅使用webRTC的相关API获取音视频流通过websocket服务端转发实现流的播放。即通过webRTC的mediaDevices.getUserMedia请求用户媒体设备的摄像头和麦克风并获取音视频流,再通过websocket将实时音视频流转发给接收者并使用MediaSource实时播放,即可达到视频监控的目的。以下是个简单的示例。
1.websocket服务端
通过nodejs搭建websocekt服务器转发音视频流:
const WebSocket = require('ws');
const url = require('url');
const clientMap = new Map();
const wss = new WebSocket.Server({
port: 8081 });
wss.on('connection', (ws, req) => {
const id = url.parse(req.url, true).query.id;
if (!id) {
return;
}
// id:1是音视频流发送端客户端,2是音视频流接收端客户端
clientMap.set(id, ws);
ws.on('message', message => {
if (isJsonString(message)) {
const data = JSON.parse(message);
const {
toId, content } = data;
const toClient = clientMap.get(String(toId));
if (toClient && toClient.readyState === WebSocket.OPEN) {
console.log(content);
toClient.send(content);
} else {
console.log("toClient does not exist.");
}
} else {
const toClient = clientMap.get(String(2));
if (toClient && toClient.readyState === WebSocket.OPEN) {
//console.log(message);
toClient.send(message);
} else {
//console.log("toClient2 does not exist.");
}
}
});
ws.on('close', () => {
// 当连接关闭时,从映射中移除客户端
for (const [id, conn] of clientMap) {
if (conn === ws) {
clientMap.delete(id);
console.log(`Client ${
id} disconnected.`);
break;
}
}
});
});
function isJsonString(str) {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
}
console.log('WebSocket server is running on ws://localhost:8081');
2.获取摄像头麦克风音视频流html
通过webRTC的mediaDevices.getUserMedia获取音视频流:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Record Video</title>
<style>
.container {
width: 7em;
height: 7em;
position: relative;
}
.button {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
border: 4px solid #090909;
background-color: transparent;
background-image: linear-gradient(145deg, #171717, #444245);
box-sizing: border-box;
box-shadow: inset 2px 2px 0 #7d7c7e, inset -2px -2px 0px #1c1c1c;
display: flex;
align-items: center;
justify-content: center;
}
.container input {
display: none;
}
.button::before {
position: absolute;
content: "";
width: 7.25em;
height: 7.25em;
border-radius: inherit;
background-color: transparent;
background-image: linear-

最低0.47元/天 解锁文章
414

被折叠的 条评论
为什么被折叠?



