예제 #1
0
        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);
            }
        }
예제 #2
0
        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;
            }
        }
예제 #3
0
        private void Connection_OnDead(DiscordMediaConnection connection, WebSocketSharp.CloseEventArgs args)
        {
            ulong prevChannel = _channelId.Value;

            _channelId = null;
            _client.TriggerVCDisconnect(_guildId, prevChannel, args);
        }
예제 #4
0
        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();
        }
예제 #5
0
        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) { }
                }
            }
        }
예제 #6
0
        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();
        }
예제 #7
0
 internal IncomingVoiceStream(DiscordMediaConnection session, ulong userId)
 {
     _packets = new ConcurrentQueue <DiscordVoicePacket>();
     Session  = session;
     UserId   = userId;
 }