123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- <!-- templates/room.html -->
- <!DOCTYPE html>
- <html>
- <head>
- <title>语音聊天室 - {{ room_id }}</title>
- <!-- 中文-->
- <meta charset="UTF-8"></meta>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
- </head>
- <body>
- <h1>语音聊天室 {{ room_id }}</h1>
- <button id="micButton" onclick="toggleMic()">🎤 点击说话</button>
- <div id="status"></div>
- <script>
- const room_id = "{{ room_id }}";
- let isMute = true;
- let localStream;
- let socket;
- const peers = {};
- // 初始化WebSocket连接
- function initSocket() {
- socket = io({
- transports: ['websocket'],
- upgrade: false,
- reconnection: true,
- reconnectionAttempts: 5
- });
- socket.on('connect', () => {
- console.log('Connected to server');
- document.getElementById('status').innerHTML = "已连接到服务器";
- socket.emit("join", { room: room_id });
- });
- socket.on('connect_error', (error) => {
- console.error('Connection error:', error);
- document.getElementById('status').innerHTML = "连接错误: " + error.message;
- });
- socket.on('disconnect', (reason) => {
- console.log('Disconnected:', reason);
- document.getElementById('status').innerHTML = "已断开连接: " + reason;
- });
- // 其他事件处理...
- }
- initSocket();
- // 获取麦克风权限
- async function init() {
- try {
- localStream = await navigator.mediaDevices.getUserMedia({
- audio: true,
- });
- document.getElementById("status").innerHTML = "麦克风已就绪";
- document.getElementById("micButton").disabled = false;
- } catch (err) {
- console.error("Error accessing microphone:", err);
- document.getElementById("status").innerHTML = "无法访问麦克风: " + err.message;
- document.getElementById("micButton").disabled = true;
- }
- }
- // 切换麦克风状态
- async function toggleMic() {
- if (!localStream) {
- console.error("No localStream available");
- document.getElementById("status").innerHTML = "麦克风未就绪,请刷新页面重试";
- return;
- }
- isMute = !isMute;
- const button = document.getElementById("micButton");
- button.textContent = isMute ? "🎤 点击说话" : "🔴 正在说话";
- localStream
- .getAudioTracks()
- .forEach((track) => (track.enabled = !isMute));
- if (!isMute) {
- createPeerConnections();
- }
- }
- // 创建与房间内其他用户的对等连接
- async function createPeerConnections() {
- for (let peerId in peers) {
- if (peerId !== socket.id) {
- const peer = new RTCPeerConnection();
- peers[peerId] = peer;
- localStream
- .getTracks()
- .forEach((track) => peer.addTrack(track, localStream));
- peer.onicecandidate = (e) => {
- if (e.candidate) {
- socket.emit("candidate", {
- candidate: e.candidate,
- room: room_id,
- target: peerId,
- });
- }
- };
- try {
- const offer = await peer.createOffer();
- await peer.setLocalDescription(offer);
- socket.emit("offer", {
- sdp: offer,
- room: room_id,
- target: peerId,
- });
- } catch (err) {
- console.error("Error creating or sending offer:", err);
- document.getElementById("status").innerHTML = "创建连接时出错,请刷新页面重试";
- }
- }
- }
- }
- // WebRTC信令处理
- socket.on("offer", async (data) => {
- if (data.sender === socket.id) return;
- const peer = new RTCPeerConnection();
- peers[data.sender] = peer;
- peer.onicecandidate = (e) => {
- if (e.candidate) {
- socket.emit("candidate", {
- candidate: e.candidate,
- target: data.sender,
- room: room_id,
- });
- }
- };
- peer.ontrack = (e) => {
- const audio = document.createElement("audio");
- audio.srcObject = e.streams[0];
- audio.autoplay = true;
- document.body.appendChild(audio);
- };
- await peer.setRemoteDescription(data.sdp);
- const answer = await peer.createAnswer();
- await peer.setLocalDescription(answer);
- socket.emit("answer", {
- sdp: answer,
- target: data.sender,
- room: room_id,
- });
- });
- socket.on("answer", (data) => {
- if (data.sender === socket.id) return;
- const peer = peers[data.sender];
- if (peer) {
- peer.setRemoteDescription(data.sdp);
- }
- });
- socket.on("candidate", (data) => {
- if (data.sender === socket.id) return;
- const peer = peers[data.sender];
- if (peer) {
- peer.addIceCandidate(new RTCIceCandidate(data.candidate));
- }
- });
- socket.on("user_joined", (userId) => {
- peers[userId] = null;
- if (!isMute) {
- createPeerConnections();
- }
- });
- socket.on("user_left", (userId) => {
- if (peers[userId]) {
- peers[userId].close();
- delete peers[userId];
- }
- });
- init();
- </script>
- </body>
- </html>
|