private void HandleMessage(DiscordMediaConnection connection, WebSockets.DiscordWebSocketMessage <DiscordMediaOpcode> message) { if (message.Opcode == DiscordMediaOpcode.SSRCUpdate) { SSRCUpdate ssrc = message.Data.ToObject <SSRCUpdate>(); if (!Viewers.Contains(ssrc.UserId)) { List <ulong> viewers = Viewers.ToList(); viewers.Add(ssrc.UserId); Viewers = viewers; OnUserConnected?.Invoke(this, ssrc.UserId); } } else if (message.Opcode == DiscordMediaOpcode.UserDisconnect) { ulong userId = message.Data.ToObject <JObject>().Value <ulong>("user_id"); List <ulong> viewers = Viewers.ToList(); if (viewers.Remove(userId)) { Viewers = viewers; } OnUserDisconnected?.Invoke(this, userId); } }
private void Connection_OnMessage(DiscordMediaConnection connection, DiscordWebSocketMessage <DiscordMediaOpcode> message) { switch (message.Opcode) { case DiscordMediaOpcode.Speaking: var state = message.Data.ToObject <DiscordSpeakingState>(); if (state.UserId.HasValue) { _ssrcToUserDictionary[state.SSRC] = state.UserId.Value; } break; case DiscordMediaOpcode.SSRCUpdate: SSRCUpdate update = message.Data.ToObject <SSRCUpdate>(); _ssrcToUserDictionary[update.Audio] = update.UserId; break; case DiscordMediaOpcode.UserDisconnect: ulong userId = message.Data.ToObject <JObject>().Value <ulong>("user_id"); if (_ssrcToUserDictionary.TryGetKey(userId, out uint ssrc)) { _ssrcToUserDictionary.Remove(ssrc); } break; } }
private void Connection_OnDead(DiscordMediaConnection connection, WebSocketSharp.CloseEventArgs args) { ulong prevChannel = _channelId.Value; _channelId = null; _client.TriggerVCDisconnect(_guildId, prevChannel, args); }
internal void SetServer(DiscordMediaServer server) { _ssrcToUserDictionary.Clear(); _receivers.Clear(); if (_guildId.HasValue) { Livestream = new DiscordLivestreamClient(_client, _guildId.Value, _channelId.Value); } Connection = new DiscordMediaConnection(_client, server.Guild == null ? _channelId.Value : server.Guild.Id, server); Connection.OnReady += (c) => { Microphone = new DiscordVoiceInput(this); Connection.SetSSRC(Connection.SSRC.Audio); _client.TriggerVCConnect(this); }; Connection.OnMessage += Connection_OnMessage; Connection.OnUdpPacket += Connection_OnUdpPacket; Connection.OnDead += Connection_OnDead; Connection.Connect(); }
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) { } } } }
internal void UpdateServer(DiscordMediaServer server) { _connection = new DiscordMediaConnection(Client, _rtcServerId, server); _connection.OnReady += (c) => { if (StreamerId == Client.User.Id) { Client.Send(GatewayOpcode.GoLiveUpdate, new StreamUpdate() { StreamKey = StreamKey, Paused = false }); } OnConnected?.Invoke(this); }; _connection.OnMessage += HandleMessage; _connection.Connect(); }
internal IncomingVoiceStream(DiscordMediaConnection session, ulong userId) { _packets = new ConcurrentQueue <DiscordVoicePacket>(); Session = session; UserId = userId; }