private void Connection_OnUdpPacket(DiscordMediaConnection connection, MediaPacketEventArgs args) { if (_decoder != null && args.Header.Type == DiscordMediaConnection.SupportedCodecs["opus"].PayloadType && _ssrcToUserDictionary.TryGetValue(args.Header.SSRC, out ulong userId)) { if (!_receivers.TryGetValue(userId, out IncomingVoiceStream receiver)) { receiver = _receivers[userId] = new IncomingVoiceStream(Connection, userId); _client.TriggerVCSpeaking(this, receiver); } if (args.Payload.SequenceEqual(_silenceFrame)) { receiver.SilenceFramesReceived++; if (receiver.SilenceFramesReceived >= 10) { receiver.Close(); _receivers.Remove(receiver.UserId); } } else { try { byte[] decoded = new byte[OpusConverter.FrameBytes]; int length = _decoder.DecodeFrame(args.Payload, 0, args.Payload.Length, decoded, 0, false); receiver.Enqueue(new DiscordVoicePacket(decoded)); } catch (OpusException) { } } } }
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) { } } } }