internal void TriggerVCSpeaking(DiscordVoiceClient client, IncomingVoiceStream stream) { if (OnUserSpeaking != null) { Task.Run(() => OnUserSpeaking.Invoke(this, new VoiceChannelSpeakingEventArgs(client, stream))); } }
void HandleSpeaking(DiscordApiData payload, DiscordApiData data) { Snowflake userId = data.GetSnowflake("user_id").Value; int ssrc = data.GetInteger("ssrc").Value; bool isSpeaking = data.GetBoolean("speaking").Value; OnUserSpeaking?.Invoke(this, new VoiceSpeakingEventArgs(userId, ssrc, isSpeaking)); }
protected override void HandlePacket(RTPPacketHeader header, byte[] payload) { // for some reason discord sends us voice packets before we get the user's ID. i don't think this impacts the audio tho; it seems like these packets don't have any voice data if (header.Type == SupportedCodecs["opus"].PayloadType && _ssrcToUserDictionary.TryGetValue(header.SSRC, out ulong userId)) { if (!_receivers.TryGetValue(userId, out IncomingVoiceStream receiver)) { receiver = _receivers[userId] = new IncomingVoiceStream(this, userId); if (OnUserSpeaking != null) { Task.Run(() => OnUserSpeaking.Invoke(this, _receivers[userId])); } } if (payload.SequenceEqual(SilenceFrame)) { receiver.SilenceFramesReceived++; if (receiver.SilenceFramesReceived >= 10) { receiver.Close(); _receivers.Remove(receiver.UserId); } } else { try { byte[] decoded = new byte[OpusEncoder.FrameBytes]; int length = _decoder.DecodeFrame(payload, 0, payload.Length, decoded, 0, false); receiver.Enqueue(new DiscordVoicePacket(decoded)); } catch (OpusException) { } } } }
private void Socket_OnMessage(object sender, WebSocketSharp.MessageEventArgs e) { var payload = e.Data.Deserialize <DiscordVoiceResponse>(); Task.Run(() => { switch (payload.Opcode) { case DiscordVoiceOpcode.Ready: DiscordVoiceReady ready = payload.Deserialize <DiscordVoiceReady>(); SSRC = ready.SSRC; SendSocketData(DiscordVoiceOpcode.SelectProtocol, new DiscordVoiceProtocolSelection() { Protocol = "udp", ProtocolData = new DiscordVoiceProtocolData() { Host = ready.IP, Port = ready.Port, EncryptionMode = "xsalsa20_poly1305" } }); UdpClient.Connect(ready.IP, ready.Port); break; case DiscordVoiceOpcode.Speaking: OnUserSpeaking?.Invoke(this, payload.Deserialize <DiscordVoiceSpeaking>()); break; case DiscordVoiceOpcode.SessionDescription: List <byte> why = new List <byte>(); foreach (byte item in payload.Deserialize <dynamic>().secret_key) { why.Add(item); } SecretKey = why.ToArray(); State = DiscordVoiceClientState.Connected; OnConnected?.Invoke(this, null); break; case DiscordVoiceOpcode.Hello: var ident = new DiscordVoiceIdentify() { GuildId = Server.Guild == null ? ChannelId : Server.Guild.Id, UserId = _client.User.Id, SessionId = _client.SessionId, Token = Server.Token }; SendSocketData(DiscordVoiceOpcode.Identify, ident); try { while (true) { SendSocketData(DiscordVoiceOpcode.Heartbeat, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()); Thread.Sleep((int)payload.Deserialize <dynamic>().heartbeat_interval); } } catch { } break; } }); }