From 9e202803a9893f31af25da0c3729c198673e5469 Mon Sep 17 00:00:00 2001 From: dank074 Date: Fri, 18 Apr 2025 12:40:03 -0500 Subject: [PATCH] changes --- package-lock.json | 2 +- src/webrtc/opcodes/Identify.ts | 19 ++++++++++++++++--- src/webrtc/opcodes/Speaking.ts | 2 +- src/webrtc/opcodes/Video.ts | 27 ++++++++++++++++++++------- src/webrtc/util/WebRtcWebSocket.ts | 2 ++ 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 46b8b2d2..0886c9fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9377,7 +9377,7 @@ }, "node_modules/spacebar-webrtc-types": { "version": "1.0.1", - "resolved": "git+ssh://git@github.com/dank074/spacebar-webrtc-types.git#04044902e71f2c80fc39c256ec5d27fdb8ca425a", + "resolved": "git+ssh://git@github.com/dank074/spacebar-webrtc-types.git#e8e13a32c7c0b446fb5c1b35111591ff1a55b919", "dev": true, "license": "ISC" }, diff --git a/src/webrtc/opcodes/Identify.ts b/src/webrtc/opcodes/Identify.ts index 2c93e924..adf47da3 100644 --- a/src/webrtc/opcodes/Identify.ts +++ b/src/webrtc/opcodes/Identify.ts @@ -40,7 +40,7 @@ export async function onIdentify(this: WebRtcWebSocket, data: VoicePayload) { // server_id can be one of the following: a unique id for a GO Live stream, a channel id for a DM voice call, or a guild id for a guild voice channel // not sure if there's a way to determine whether a snowflake is a channel id or a guild id without checking if it exists in db // luckily we will only have to determine this once - let type: "guild-voice" | "dm-voice" | "stream"; + let type: "guild-voice" | "dm-voice" | "stream" = "guild-voice"; let authenticated = false; // first check if its a guild voice connection or DM voice call @@ -54,6 +54,9 @@ export async function onIdentify(this: WebRtcWebSocket, data: VoicePayload) { if (voiceState) { type = voiceState.guild_id === server_id ? "guild-voice" : "dm-voice"; authenticated = true; + this.guild_id = + type === "guild-voice" ? voiceState.guild_id : undefined; + this.channel_id = voiceState.channel_id; } else { // if its not a guild/dm voice connection, check if it is a go live stream const streamSession = await StreamSession.findOne({ @@ -64,6 +67,7 @@ export async function onIdentify(this: WebRtcWebSocket, data: VoicePayload) { session_id, used: false, }, + relations: ["stream"], }); if (streamSession) { @@ -72,6 +76,8 @@ export async function onIdentify(this: WebRtcWebSocket, data: VoicePayload) { streamSession.used = true; await streamSession.save(); + this.channel_id = streamSession.stream.channel_id; + this.once("close", async () => { await streamSession.remove(); }); @@ -84,8 +90,15 @@ export async function onIdentify(this: WebRtcWebSocket, data: VoicePayload) { this.user_id = user_id; this.session_id = session_id; - this.type = type!; - this.webRtcClient = mediaServer.join(server_id, this.user_id, this, type!); + this.type = type; + + const voiceRoomId = type === "stream" ? server_id : voiceState!.channel_id; + this.webRtcClient = mediaServer.join( + voiceRoomId, + this.user_id, + this, + type!, + ); this.on("close", () => { // ice-lite media server relies on this to know when the peer went away diff --git a/src/webrtc/opcodes/Speaking.ts b/src/webrtc/opcodes/Speaking.ts index ee01c444..bff0db97 100644 --- a/src/webrtc/opcodes/Speaking.ts +++ b/src/webrtc/opcodes/Speaking.ts @@ -32,7 +32,7 @@ export async function onSpeaking(this: WebRtcWebSocket, data: VoicePayload) { await Promise.all( Array.from( mediaServer.getClientsForRtcServer( - this.webRtcClient.rtc_server_id, + this.webRtcClient.voiceRoomId, ), ).map((client) => { if (client.user_id === this.user_id) return Promise.resolve(); diff --git a/src/webrtc/opcodes/Video.ts b/src/webrtc/opcodes/Video.ts index 8a0745b8..55802b2f 100644 --- a/src/webrtc/opcodes/Video.ts +++ b/src/webrtc/opcodes/Video.ts @@ -28,13 +28,13 @@ import type { WebRtcClient } from "spacebar-webrtc-types"; export async function onVideo(this: WebRtcWebSocket, payload: VoicePayload) { if (!this.webRtcClient || !this.webRtcClient.webrtcConnected) return; - const { rtc_server_id } = this.webRtcClient; + const { voiceRoomId } = this.webRtcClient; const d = validateSchema("VoiceVideoSchema", payload.d) as VoiceVideoSchema; if (this.type === "stream") { const stream = await Stream.findOne({ - where: { id: rtc_server_id }, + where: { id: voiceRoomId }, }); if (!stream) return; @@ -50,9 +50,20 @@ export async function onVideo(this: WebRtcWebSocket, payload: VoicePayload) { await Send(this, { op: VoiceOPCodes.MEDIA_SINK_WANTS, d: { any: 100 } }); const clientsThatNeedUpdate = new Set>(); + const wantsToProduceAudio = d.audio_ssrc !== 0; + const wantsToProduceVideo = d.video_ssrc !== 0 && stream?.active; + + // first check if we need stop any tracks + if (!wantsToProduceAudio && this.webRtcClient.isProducingAudio()) { + this.webRtcClient.stopPublishingTrack("audio"); + } + + if (!wantsToProduceVideo && this.webRtcClient.isProducingVideo()) { + this.webRtcClient.stopPublishingTrack("video"); + } // check if client has signaled that it will send audio - if (d.audio_ssrc !== 0) { + if (wantsToProduceAudio) { // check if we are already producing audio, if not, publish a new audio track for it if (!this.webRtcClient!.isProducingAudio()) { console.log( @@ -65,7 +76,7 @@ export async function onVideo(this: WebRtcWebSocket, payload: VoicePayload) { // now check that all clients have subscribed to our audio for (const client of mediaServer.getClientsForRtcServer( - rtc_server_id, + voiceRoomId, )) { if (client.user_id === this.user_id) continue; @@ -80,7 +91,7 @@ export async function onVideo(this: WebRtcWebSocket, payload: VoicePayload) { } } // check if client has signaled that it will send video - if (d.video_ssrc !== 0 && stream?.active) { + if (wantsToProduceVideo) { this.webRtcClient!.videoStream = stream; // check if we are already publishing video, if not, publish a new video track for it if (!this.webRtcClient!.isProducingVideo()) { @@ -95,7 +106,7 @@ export async function onVideo(this: WebRtcWebSocket, payload: VoicePayload) { // now check that all clients have subscribed to our video track for (const client of mediaServer.getClientsForRtcServer( - rtc_server_id, + voiceRoomId, )) { if (client.user_id === this.user_id) continue; @@ -136,8 +147,10 @@ export async function onVideo(this: WebRtcWebSocket, payload: VoicePayload) { export async function subscribeToProducers( this: WebRtcWebSocket, ): Promise { + if (!this.webRtcClient || !this.webRtcClient.webrtcConnected) return; + const clients = mediaServer.getClientsForRtcServer( - this.webRtcClient!.rtc_server_id, + this.webRtcClient.voiceRoomId, ); await Promise.all( diff --git a/src/webrtc/util/WebRtcWebSocket.ts b/src/webrtc/util/WebRtcWebSocket.ts index 5bb2da46..bca8b994 100644 --- a/src/webrtc/util/WebRtcWebSocket.ts +++ b/src/webrtc/util/WebRtcWebSocket.ts @@ -3,5 +3,7 @@ import type { WebRtcClient } from "spacebar-webrtc-types"; export interface WebRtcWebSocket extends WebSocket { type: "guild-voice" | "dm-voice" | "stream"; + guild_id?: string; + channel_id: string; webRtcClient?: WebRtcClient; }