首页 > 其他分享 >WEBRTC 局域网 自己搭建信令服务 实现视频通讯

WEBRTC 局域网 自己搭建信令服务 实现视频通讯

时间:2024-03-06 18:02:51浏览次数:32  
标签:const log offer color 局域网 peer message WEBRTC 信令

信令服务

const app = require('express')();
const wsInstance = require('express-ws')(app);

app.ws('/', ws => {
	ws.on('message', data => {
		wsInstance.getWss().clients.forEach(server => {
			if (server !== ws) {
				server.send(data);
			}
		});
	});
});

app.get('/', (req, res) => {
	res.sendFile('./client/index.html', { root: __dirname });
});

app.get('/p2p', (req, res) => {
	res.sendFile('./client/p2p.html', { root: __dirname });
});

app.listen(8081);

启动服务

npm install
npm run dev

前端页面

  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>p2p webrtc</title>
	<style>
	.container {
		width: 250px;
		margin: 100px auto;
		padding: 10px 30px;
		border-radius: 4px;
    border: 1px solid #ebeef5;
    box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
    color: #303133;
	}
	</style>
</head>
<body>
	<div class="container">
		<p>流程:</p>
		<ul>
			<li>打开<a href="/p2p?type=answer" target="_blank">接收方页面</a>;</li>
			<li>打开<a href="/p2p?type=offer" target="_blank">发起方页面</a>;</li>
			<li>确认双方都已建立ws连接;</li>
			<li>发起方点击 start 按钮。</li>
		</ul>
	</div>
</body>
</html>
  • p2p..html
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style>
		* {
			padding: 0;
			margin: 0;
			box-sizing: border-box;
		}
		.container {
			width: 100%;
			display: flex;
			display: -webkit-flex;
			justify-content: space-around;
			padding-top: 20px;
		}
		.video-box {
			position: relative;
			width: 800px;
			height: 400px;
		}
		#remote-video {
			width: 100%;
			height: 100%;
			display: block;
			object-fit: cover;
			border: 1px solid #eee;
			background-color: #F2F6FC;
		}
		#local-video {
			position: absolute;
			right: 0;
			bottom: 0;
			width: 240px;
			height: 120px;
			object-fit: cover;
			border: 1px solid #eee;
			background-color: #EBEEF5;
		}
		.start-button {
			position: absolute;
			left: 50%;
			top: 50%;
			width: 100px;
			display: none;
			line-height: 40px;
			outline: none;
			color: #fff;
			background-color: #409eff;
			border: none;
			border-radius: 4px;
			cursor: pointer;
			transform: translate(-50%, -50%);
		}
		.logger {
			width: 40%;
			padding: 14px;
			line-height: 1.5;
			color: #4fbf40;
			border-radius: 6px;
			background-color: #272727;
		}
		.logger .error {
			color: #DD4A68;
		}
	</style>
</head>
<body>
	<div class="container">
		<div class="video-box">
			<video id="remote-video"></video>
			<video id="local-video" muted></video>
			<button class="start-button" onclick="startLive()">start</button>
		</div>
		<div class="logger"></div>
	</div>
	<script>
		const message = {
			el: document.querySelector('.logger'),
			log (msg) {
				this.el.innerHTML += `<span>${new Date().toLocaleTimeString()}:${msg}</span><br/>`;
			},
			error (msg) {
				this.el.innerHTML += `<span class="error">${new Date().toLocaleTimeString()}:${msg}</span><br/>`;
			}
		};
		
		const target = location.search.slice(6);
		const localVideo = document.querySelector('#local-video');
		const remoteVideo = document.querySelector('#remote-video');
		const button = document.querySelector('.start-button');

		localVideo.onloadeddata = () => {
			message.log('播放本地视频');
			localVideo.play();
		}
		remoteVideo.onloadeddata = () => {
			message.log('播放对方视频');
			remoteVideo.play();
		}

		document.title = target === 'offer' ? '发起方' : '接收方';

		message.log('信令通道(WebSocket)创建中......');
		const socket = new WebSocket('ws://localhost:8081');
		socket.onopen = () => {
			message.log('信令通道创建成功!');
			target === 'offer' && (button.style.display = 'block');
		}
		socket.onerror = () => message.error('信令通道创建失败!');
		socket.onmessage = e => {
			const { type, sdp, iceCandidate } = JSON.parse(e.data)
			if (type === 'answer') {
				peer.setRemoteDescription(new RTCSessionDescription({ type, sdp }));
			} else if (type === 'answer_ice') {
				peer.addIceCandidate(iceCandidate);
			} else if (type === 'offer') {
				startLive(new RTCSessionDescription({ type, sdp }));
			} else if (type === 'offer_ice') {
				peer.addIceCandidate(iceCandidate);
			}
		};

		const PeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
		!PeerConnection && message.error('浏览器不支持WebRTC!');
		const peer = new PeerConnection();

		peer.ontrack = e => {
			if (e && e.streams) {
				message.log('收到对方音频/视频流数据...');
				remoteVideo.srcObject = e.streams[0];
			}
		};

		peer.onicecandidate = e => {
			if (e.candidate) {
				message.log('搜集并发送候选人');
				socket.send(JSON.stringify({
					type: `${target}_ice`,
					iceCandidate: e.candidate
				}));
			} else {
				message.log('候选人收集完成!');
			}
		};

		async function startLive (offerSdp) {
			target === 'offer' && (button.style.display = 'none');
			let stream;
			try {
				message.log('尝试调取本地摄像头/麦克风');
				stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
				message.log('摄像头/麦克风获取成功!');
				localVideo.srcObject = stream;
			} catch {
				message.error('摄像头/麦克风获取失败!');
				return;
			}

			message.log(`------ WebRTC ${target === 'offer' ? '发起方' : '接收方'}流程开始 ------`);
			message.log('将媒体轨道添加到轨道集');
			stream.getTracks().forEach(track => {
				peer.addTrack(track, stream);
			});

			if (!offerSdp) {
				message.log('创建本地SDP');
				const offer = await peer.createOffer();
				await peer.setLocalDescription(offer);
				
				message.log(`传输发起方本地SDP`);
				socket.send(JSON.stringify(offer));
			} else {
				message.log('接收到发送方SDP');
				await peer.setRemoteDescription(offerSdp);

				message.log('创建接收方(应答)SDP');
				const answer = await peer.createAnswer();
				message.log(`传输接收方(应答)SDP`);
				socket.send(JSON.stringify(answer));
				await peer.setLocalDescription(answer);
			}
		}
	</script>
</body>
</html>

标签:const,log,offer,color,局域网,peer,message,WEBRTC,信令
From: https://www.cnblogs.com/guanchaoguo/p/18057208

相关文章

  • WebRTC 通讯隧道和信令服务实现服务视频通话
    安装NAT穿透服务器(ICEServer)brewinstallcoturn//添加用户turnadmin-a-uadmin-rrealm-padmin//测试服务turnutils_peer-p34800turnutils_uclient-v-e192.168.1.112-r34800-uadmin-wadmin-p3478192.168.1.112安装信令服务器gitclonehttps......
  • windows编译ZLMediaKit流媒体服务webrtc
    环境说明ZLMediaKit编译需要的软件visualstudio2022cmake3.29.0-rc2OpenSSL1.1.1w(不想踩坑的话安装这个版本)libsrtp2.6.0ZLMediaKit编译后运行需要libsrtp编译后且配置环境变量ZLMediaKit编译后文件visualstudiocmakevisualstuid......
  • AndroidStudio扫描局域网下的ESP32CAM并获取IP地址
    大概想法如下: 在ESP32CAM端直接下载示例代码udp_server这个历程,修改默认的WIFI和密码,启动之后会输出如下结果 由此我们知道了UDP的地址和端口IP地址为192.168.2.3,端口为3333此时我们使用小工具NetAssist.exe来测试,选择UDP协议之后向ESP32CAM的地址发送广播,如下图所示 ......
  • 基于debian12在局域网中部署gitlab步骤
    基于debian12在局域网中部署gitlab步骤来源  https://zhuanlan.zhihu.com/p/675515010 gitlab安装安装gitlab过程中需要的依赖,包括curl、postfix。使用命令为sudoaptinstallcurlpostfixufw。访问链接gitlab/gitlab-ee-Installation·packages.gitlab.com-Bash......
  • webrtc终极版(三)将官方的demo部署到自己的服务器中
    webrtc终极版(三)将官方的demo部署到自己的服务器中本节,我们详细介绍下,如何再本地搭建RTCMultiConnection服务目录webrtc终极版(三)将官方的demo部署到自己的服务器中前言一、安装步骤1.下载并解压文件2.使用npm安装总结前言webrtc终极版系列,再年前,写了前两篇,还剩下两篇没有写,......
  • Ubuntu18.04服务器局域网定时同步文件
    一、文件同步首先我们先了解一下rsync命令。rsync可以在本地系统之间或本地系统与远程系统之间同步、复制和备份文件和目录。rsync通过比较源与目标文件的差异来最小化数据传输,从而提高效率和速度。rsync命令有许多可选的参数,下面简单列一下常见的几个参数:-a:以归档模......
  • win10局域网共享文件夹设置步骤
    1、控制面板网络和共享中心设置,【控制面板\所有控制面板项\网络和共享中心\高级共享设置】 2、创建一个新的系统账户专门用于共享文件的访问(账户必须要设置密码)3、文件夹共享设置,选中文件夹,右键-属性,切换到共享界面点击共享,选择刚创建的用户,执行添加设置用户权限为......
  • webrtc终极版(二)搭建自己的iceserver服务,并用到RTCMultiConnection的demo中
    webrtc终极版(二)搭建自己的iceserver服务,并用到RTCMultiConnection的demo中目录webrtc终极版(二)搭建自己的iceserver服务,并用到RTCMultiConnection的demo中前言一、stunserver,turnserver,iceserver是什么?二、具体搭建步骤1.下载安装coturn2、处理证书问题3、处理各个ip以及端口的配......
  • webrtc终极版(题外话)辛苦写文章分享,竟然遇到喷子狂喷,写篇文章回怼下,顺便发表下面对喷子
    webrtc终极版(题外话)辛苦写文章分享,竟然遇到喷子狂喷,写篇文章回怼下,顺便发表下面对喷子的处理方式第一篇文章发过后,出人意料的是,收到了博客园某一位用户的狂喷【注:本系列文章会同步发布到csdn、博客园、稀土掘金等平台上】,如下图示图片可能不清楚,我再把这位喷子的原话粘贴下来:......
  • webrtc终极版(一)5分钟搭建多人实时会议系统webrtc
    webrtc终极版(一),支持https,在线部署【不是本地demo】,采用RTCMultiConnection官方demo,5分钟即可搭建成功@目录webrtc终极版(一),支持https,在线部署【不是本地demo】,采用RTCMultiConnection官方demo,5分钟即可搭建成功前言一、webrtc是什么?二、搭建demo步骤1.代码内容2.运行效果总结前......