//Called from AudioClient.Cleanup internal async Task RemoveClient(Server server, AudioClient client) { using (await _asyncLock.LockAsync().ConfigureAwait(false)) { if (_voiceClients.TryUpdate(server.Id, null, client)) _voiceClients.TryRemove(server.Id, out client); } }
internal VoiceWebSocket(DiscordClient client, AudioClient audioClient, Logger logger) : base(client, logger) { _audioClient = audioClient; _config = client.Audio().Config; _decoders = new ConcurrentDictionary<uint, OpusDecoder>(); _targetAudioBufferLength = _config.BufferLength / 20; //20 ms frames _encodingBuffer = new byte[MaxOpusSize]; _ssrcMapping = new ConcurrentDictionary<uint, ulong>(); _encoder = new OpusEncoder(48000, _config.Channels, 20, _config.Bitrate, OpusApplication.MusicOrMixed); _sendBuffer = new VoiceBuffer((int)Math.Ceiling(_config.BufferLength / (double)_encoder.FrameLength), _encoder.FrameSize); }
void IService.Install(DiscordClient client) { Client = client; if (Config.EnableMultiserver) _voiceClients = new ConcurrentDictionary<ulong, AudioClient>(); else { var logger = Client.Log.CreateLogger("Voice"); _defaultClient = new AudioClient(Client, null, 0); } _talkingUsers = new ConcurrentDictionary<User, bool>(); client.GatewaySocket.Disconnected += async (s, e) => { if (Config.EnableMultiserver) { var tasks = _voiceClients .Select(x => { var val = x.Value; if (val != null) return x.Value.Disconnect(); else return TaskHelper.CompletedTask; }) .ToArray(); await Task.WhenAll(tasks).ConfigureAwait(false); _voiceClients.Clear(); } foreach (var member in _talkingUsers) { bool ignored; if (_talkingUsers.TryRemove(member.Key, out ignored)) OnUserIsSpeakingUpdated(member.Key, false); } }; }
void IService.Install(DiscordClient client) { Client = client; Config.Lock(); if (Config.EnableMultiserver) { _voiceClients = new ConcurrentDictionary <ulong, IAudioClient>(); } else { var logger = Client.Log.CreateLogger("Voice"); _defaultClient = new SimpleAudioClient(this, 0, logger); } _talkingUsers = new ConcurrentDictionary <User, bool>(); client.Disconnected += async(s, e) => { if (Config.EnableMultiserver) { var tasks = _voiceClients .Select(x => x.Value.Disconnect()) .ToArray(); await Task.WhenAll(tasks).ConfigureAwait(false); _voiceClients.Clear(); } foreach (var member in _talkingUsers) { bool ignored; if (_talkingUsers.TryRemove(member.Key, out ignored)) { OnUserIsSpeakingUpdated(member.Key, false); } } }; }
internal OutStream(AudioClient client) { _client = client; }
public VirtualClient(AudioClient client, Server server) { _client = client; Server = server; }
public async Task<IAudioClient> Join(Channel channel) { if (channel == null) throw new ArgumentNullException(nameof(channel)); var server = channel.Server; using (await _asyncLock.LockAsync().ConfigureAwait(false)) { AudioClient client; if (!_voiceClients.TryGetValue(server.Id, out client)) { client = new AudioClient(Client, server, unchecked(++_nextClientId)); _voiceClients[server.Id] = client; await client.Connect().ConfigureAwait(false); } await client.Join(channel).ConfigureAwait(false); return client; } }
private async Task<IAudioClient> CreateClient(Server server) { var client = _voiceClients.GetOrAdd(server.Id, _ => null); //Placeholder, so we can't have two clients connecting at once if (client == null) { int id = unchecked(++_nextClientId); var gatewayLogger = Client.Log.CreateLogger($"Gateway #{id}"); var voiceLogger = Client.Log.CreateLogger($"Voice #{id}"); var gatewaySocket = new GatewaySocket(Client, gatewayLogger); var voiceClient = new AudioClient(this, id, server, Client.GatewaySocket, voiceLogger); await voiceClient.Connect(true).ConfigureAwait(false); /*voiceClient.VoiceSocket.FrameReceived += (s, e) => { OnFrameReceieved(e); }; voiceClient.VoiceSocket.UserIsSpeaking += (s, e) => { var user = server.GetUser(e.UserId); OnUserIsSpeakingUpdated(user, e.IsSpeaking); };*/ //Update the placeholder only it still exists (RemoveClient wasnt called) if (!_voiceClients.TryUpdate(server.Id, voiceClient, null)) { //If it was, cleanup await voiceClient.Disconnect().ConfigureAwait(false); ; await gatewaySocket.Disconnect().ConfigureAwait(false); ; } } return client; }
public async Task<IAudioClient> Join(Channel channel) { if (channel == null) throw new ArgumentNullException(nameof(channel)); var server = channel.Server; using (await _asyncLock.LockAsync().ConfigureAwait(false)) { if (Config.EnableMultiserver) { AudioClient client; if (!_voiceClients.TryGetValue(server.Id, out client)) { client = new AudioClient(Client, server, unchecked(++_nextClientId)); _voiceClients[server.Id] = client; await client.Connect().ConfigureAwait(false); /*voiceClient.VoiceSocket.FrameReceived += (s, e) => { OnFrameReceieved(e); }; voiceClient.VoiceSocket.UserIsSpeaking += (s, e) => { var user = server.GetUser(e.UserId); OnUserIsSpeakingUpdated(user, e.IsSpeaking); };*/ } await client.Join(channel).ConfigureAwait(false); return client; } else { if (_defaultClient.Server != server) { await _defaultClient.Disconnect().ConfigureAwait(false); _defaultClient.VoiceSocket.Server = server; await _defaultClient.Connect().ConfigureAwait(false); } var client = new VirtualClient(_defaultClient, server); _currentClient = client; await client.Join(channel).ConfigureAwait(false); return client; } } }
void IService.Install(DiscordClient client) { Client = client; Config.Lock(); if (Config.EnableMultiserver) _voiceClients = new ConcurrentDictionary<ulong, IAudioClient>(); else { var logger = Client.Log.CreateLogger("Voice"); _defaultClient = new SimpleAudioClient(this, 0, logger); } _talkingUsers = new ConcurrentDictionary<User, bool>(); client.Disconnected += async (s, e) => { if (Config.EnableMultiserver) { var tasks = _voiceClients .Select(x => x.Value.Disconnect()) .ToArray(); await Task.WhenAll(tasks).ConfigureAwait(false); _voiceClients.Clear(); } foreach (var member in _talkingUsers) { bool ignored; if (_talkingUsers.TryRemove(member.Key, out ignored)) OnUserIsSpeakingUpdated(member.Key, false); } }; }