feat: add ssrc definition (op 12)

This commit is contained in:
kozabrada123 2023-12-16 15:55:29 +01:00
parent d135e0a192
commit 3789596c19
3 changed files with 70 additions and 7 deletions

View File

@ -12,6 +12,7 @@ pub use select_protocol::*;
pub use session_description::*;
pub use speaking::*;
pub use voice_backend_version::*;
pub use ssrc_definition::*;
mod client_connect;
mod client_disconnect;
@ -23,6 +24,7 @@ mod select_protocol;
mod session_description;
mod speaking;
mod voice_backend_version;
mod ssrc_definition;
#[derive(Debug, Default, Serialize, Clone)]
/// The payload used for sending events to the webrtc gateway.
@ -102,8 +104,7 @@ pub const VOICE_HEARTBEAT_ACK: u8 = 6;
pub const VOICE_RESUME: u8 = 7;
pub const VOICE_HELLO: u8 = 8;
pub const VOICE_RESUMED: u8 = 9;
/// See <https://discord-userdoccers.vercel.app/topics/opcodes-and-status-codes#voice-opcodes>
pub const VOICE_VIDEO: u8 = 12;
pub const VOICE_SSRC_DEFINITION: u8 = 12;
pub const VOICE_CLIENT_DISCONNECT: u8 = 13;
pub const VOICE_SESSION_UPDATE: u8 = 14;

View File

@ -0,0 +1,39 @@
use crate::types::{Snowflake, WebSocketEvent};
use serde::{Serialize, Deserialize};
/// Defines an event which provides ssrcs for voice and video for a user id.
///
/// This event is sent via opcode 12.
///
/// Examples of the event:
///
/// When receiving:
/// ```
/// {"op":12,"d":{"video_ssrc":0,"user_id":"463640391196082177","streams":[{"ssrc":26595,"rtx_ssrc":26596,"rid":"100","quality":100,"max_resolution":{"width":1280,"type":"fixed","height":720},"max_framerate":30,"active":false}],"audio_ssrc":26597}}{"op":12,"d":{"video_ssrc":0,"user_id":"463640391196082177","streams":[{"ssrc":26595,"rtx_ssrc":26596,"rid":"100","quality":100,"max_resolution":{"width":1280,"type":"fixed","height":720},"max_framerate":30,"active":false}],"audio_ssrc":26597}}
/// ```
///
/// When sending:
/// ```
/// {"op":12,"d":{"audio_ssrc":2307250864,"video_ssrc":0,"rtx_ssrc":0,"streams":[{"type":"video","rid":"100","ssrc":26595,"active":false,"quality":100,"rtx_ssrc":26596,"max_bitrate":2500000,"max_framerate":30,"max_resolution":{"type":"fixed","width":1280,"height":720}}]}}
/// ```
#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)]
pub struct SsrcDefinition {
/// The ssrc used for video communications.
///
/// Is always sent and received, though is 0 if describing only the audio ssrc.
#[serde(default)]
pub video_ssrc: usize,
/// The ssrc used for audio communications.
///
/// Is always sent and received, though is 0 if describing only the video ssrc.
#[serde(default)]
pub audio_ssrc: usize,
/// The user id these ssrcs apply to.
///
/// Is never sent by the user and is filled in by the server
#[serde(skip_serializing)]
pub user_id: Option<Snowflake>,
// TODO: Add video streams
}
impl WebSocketEvent for SsrcDefinition {}

View File

@ -17,11 +17,12 @@ use tokio_tungstenite::{connect_async_tls_with_config, Connector, WebSocketStrea
use crate::errors::VoiceGatewayError;
use crate::gateway::{heartbeat::HEARTBEAT_ACK_TIMEOUT, GatewayEvent};
use crate::types::{
self, SelectProtocol, Speaking, VoiceGatewayReceivePayload, VoiceGatewaySendPayload,
VoiceIdentify, WebSocketEvent, VOICE_BACKEND_VERSION, VOICE_CLIENT_CONNECT_FLAGS,
VOICE_CLIENT_CONNECT_PLATFORM, VOICE_CLIENT_DISCONNECT, VOICE_HEARTBEAT, VOICE_HEARTBEAT_ACK,
VOICE_HELLO, VOICE_IDENTIFY, VOICE_MEDIA_SINK_WANTS, VOICE_READY, VOICE_RESUME,
VOICE_SELECT_PROTOCOL, VOICE_SESSION_DESCRIPTION, VOICE_SESSION_UPDATE, VOICE_SPEAKING,
self, SelectProtocol, Speaking, SsrcDefinition, VoiceGatewayReceivePayload,
VoiceGatewaySendPayload, VoiceIdentify, WebSocketEvent, VOICE_BACKEND_VERSION,
VOICE_CLIENT_CONNECT_FLAGS, VOICE_CLIENT_CONNECT_PLATFORM, VOICE_CLIENT_DISCONNECT,
VOICE_HEARTBEAT, VOICE_HEARTBEAT_ACK, VOICE_HELLO, VOICE_IDENTIFY, VOICE_MEDIA_SINK_WANTS,
VOICE_READY, VOICE_RESUME, VOICE_SELECT_PROTOCOL, VOICE_SESSION_DESCRIPTION,
VOICE_SESSION_UPDATE, VOICE_SPEAKING, VOICE_SSRC_DEFINITION,
};
use self::voice_events::VoiceEvents;
@ -159,6 +160,15 @@ impl VoiceGatewayHandle {
self.send_json(VOICE_SPEAKING, to_send_value).await;
}
/// Sends an ssrc definition event
pub async fn send_ssrc_definition(&self, to_send: SsrcDefinition) {
let to_send_value = serde_json::to_value(&to_send).unwrap();
trace!("VGW: Sending SsrcDefinition");
self.send_json(VOICE_SSRC_DEFINITION, to_send_value).await;
}
/// Sends a voice backend version request to the gateway
pub async fn send_voice_backend_version_request(&self) {
let data_empty_object = json!("{}");
@ -408,6 +418,18 @@ impl VoiceGateway {
warn!("Failed to parse VOICE_SPEAKING ({})", result.err().unwrap());
}
}
VOICE_SSRC_DEFINITION => {
trace!("VGW: Received Ssrc Definition");
let event = &mut self.events.lock().await.ssrc_definition;
let result = VoiceGateway::handle_event(gateway_payload.data.get(), event).await;
if result.is_err() {
warn!(
"Failed to parse VOICE_SSRC_DEFINITION ({})",
result.err().unwrap()
);
}
}
VOICE_CLIENT_DISCONNECT => {
trace!("VGW: Received Client Disconnect");
@ -663,6 +685,7 @@ pub mod voice_events {
pub session_description: GatewayEvent<SessionDescription>,
pub session_update: GatewayEvent<SessionUpdate>,
pub speaking: GatewayEvent<Speaking>,
pub ssrc_definition: GatewayEvent<SsrcDefinition>,
pub client_disconnect: GatewayEvent<VoiceClientDisconnection>,
pub client_connect_flags: GatewayEvent<VoiceClientConnectFlags>,
pub client_connect_platform: GatewayEvent<VoiceClientConnectPlatform>,