webRTC 房间直播模拟

117 阅读1分钟

环境搭建,要求需要学生html,学生客户端逻辑 信令服务器(websocket) 老师html,老师客户端逻辑,

学生html

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>学生</title>

<style>

</style>

</head>

<body>

<h1>学生</h1>

<div class="user-list">

<h3>用户列表</h3>

<ul id="userList"></ul>


<div style="display: flex; justify-content: space-between;">


<video id="remoteVideo" autoplay playsinline></video>

</div>

<script src="xuesheng.js"></script>

</body>

</html>

学生逻辑部分

这块贴了不发送自己流部分

conn.addTransceiver("audio", { direction: "recvonly" });

conn.addTransceiver("video", {direction: "recvonly"})

作用:

  1. 为音频或视频生成一个独立的传输通道(Transceiver),通过它管理数据的收发逻辑。

  2. 控制传输方向
    通过direction` 参数设定以下模式:

    • sendrecv(默认):同时发送和接收媒体。
    • sendonly:仅发送媒体(如输出摄像头画面)。
    • recvonly:仅接收媒体(如播放对方声音)。
    • inactive:暂不传输。
const socket = new WebSocket('ws://localhost:8080');

//创建 RTCPeerConnection
function createPeerConnection(peerId,isOfferer = false) {

console.log("createPeerConnection:",isOfferer,)

  


if (!localStream) {

addLocalStream(peerId,) // 添加本地媒体流

}

const conn = new RTCPeerConnection({iceServers});

localPc=conn

// 添加 Transceiver 接收视频(广播者的流)

conn.addTransceiver("audio", { direction: "recvonly" });

conn.addTransceiver("video", {direction: "recvonly"})
}

其余部分和我1对1通话逻辑相似

老师html


<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>老师</title>

<style>

</style>

</head>

<body>

<h1>老师</h1>

<div class="user-list">

<h3>用户列表</h3>

<ul id="userList"></ul>

<div style="display: flex; justify-content: space-between;">

<video id="localVideo" autoplay muted playsinline></video>

</div>

<script src="laoshi.js"></script>

</body>

</html>

老师js

...
let RtcPcMaps = new Map()//设置和不同同学建立链接的map

//监听同学们进入房间
socket.onmessage = event => {
if (data.type === 'peers-updated') {
const userList = document.getElementById('userList');

userList.innerHTML = '';

usersList=data.peers

data.peers.forEach((user) => {

const li = document.createElement('li');

li.textContent = user;

if (user !== clientId) {

const callBtn = document.createElement('button');

callBtn.textContent = '通话';

callBtn.onclick = () => createPeerConnection(user,true);

li.appendChild(callBtn);

}

userList.appendChild(li);

});


}
}
...
其余代码逻辑和之前一样

注意:这块只能老师发起通话

信令服务器

这部分替代join-success,用来实时更新房间人数

...
const peersList = Array.from(room.keys());

room.forEach(clientWs => {

clientWs.send(JSON.stringify({

type: 'peers-updated',

peers: peersList,

roomName

}));

});
...
其余代码一样

这样就可以创建一个模拟直播的webrtc通信了