import { defineStore } from "pinia"; import { MSG_TYPE, MESSAGE_TYPE_USER, MESSAGE_TYPE_GROUP } from "@/common/constant/msgType"; import { useWebSocketStore } from "@/stores/modules/webSocketStore"; export const useWebRTCStore = defineStore("webrtc", { state: () => ({ // WebRTC 连接实例 peerConnection: null, // ICE 候选信息 iceCandidates: [], // 连接状态 connectionState: "disconnected", // 媒体流 localStream: null, remoteStream: null, // 配置项 config: { iceServers: [ { urls: "stun:stun.l.google.com:19302" }, // 可以添加更多 STUN/TURN 服务器 ], }, }), actions: { // 初始化 WebRTC 连接 initConnection(MESSAGE_TYPE) { this.cleanup(); const wsStore = useWebSocketStore(); try { this.peerConnection = new RTCPeerConnection(); // 设置事件监听: 对等方收到ice信息后,通过调用 addIceCandidate 将接收的候选者信息传递给浏览器的ICE代理 this.peerConnection.onicecandidate = (event) => { if (event.candidate) { if (MESSAGE_TYPE === MESSAGE_TYPE_USER) { let candidate = { type: "offer_ice", iceCandidate: event.candidate, }; wsStore.sendMessage({ contentType: MSG_TYPE.AUDIO_ONLINE, type: "webrtc", messageType: MESSAGE_TYPE, content: JSON.stringify(candidate), }); } if (MESSAGE_TYPE === MESSAGE_TYPE_GROUP) { this.iceCandidates.push(event.candidate); } } }; // 监听 ICE 状态变化 this.peerConnection.onconnectionstatechange = () => { this.connectionState = this.peerConnection.connectionState; }; // 当连接成功后,从里面获取语音视频流: 监听 ICE candidate:包含语音视频流 this.peerConnection.ontrack = (event) => { // 添加远程媒体流 if (!this.remoteStream) { this.remoteStream = new MediaStream(); } // 添加远程媒体流 event.streams[0].getTracks().forEach((track) => { this.remoteStream.addTrack(track); }); }; console.log("WebRTC 连接初始化成功"); } catch (error) { console.error("初始化 WebRTC 连接失败:", error); this.cleanup(); throw error; } }, // 添加本地媒体流 async addLocalStream(stream) { if (!this.peerConnection) { throw new Error("WebRTC 连接未初始化"); } this.localStream = stream; stream.getTracks().forEach((track) => { this.peerConnection.addTrack(track, stream); }); }, // 创建 Offer async createOffer() { if (!this.peerConnection) { throw new Error("WebRTC 连接未初始化"); } try { const offer = await this.peerConnection.createOffer(); await this.peerConnection.setLocalDescription(offer); return offer; } catch (error) { console.error("创建 Offer 失败:", error); throw error; } }, // 创建 Answer async createAnswer() { if (!this.peerConnection) { throw new Error("WebRTC 连接未初始化"); } try { const answer = await this.peerConnection.createAnswer(); await this.peerConnection.setLocalDescription(answer); return answer; } catch (error) { console.error("创建 Answer 失败:", error); throw error; } }, // 设置远程 Description async setRemoteDescription(desc) { if (!this.peerConnection) { throw new Error("WebRTC 连接未初始化"); } try { await this.peerConnection.setRemoteDescription(desc); } catch (error) { console.error("设置远程 Description 失败:", error); throw error; } }, // 添加 ICE 候选 async addIceCandidate(candidate) { if (!this.peerConnection) { throw new Error("WebRTC 连接未初始化"); } try { await this.peerConnection.addIceCandidate(candidate); } catch (error) { console.error("添加 ICE 候选失败:", error); throw error; } }, // 清理资源 cleanup() { if (this.peerConnection) { this.peerConnection.close(); this.peerConnection = null; } if (this.localStream) { this.localStream.getTracks().forEach((track) => track.stop()); this.localStream = null; } this.iceCandidates = []; this.connectionState = "disconnected"; }, }, });