diff --git a/src/Discord.Net.Core/Entities/Channels/IAudioChannel.cs b/src/Discord.Net.Core/Entities/Channels/IAudioChannel.cs
index afb81d92f..a152ff744 100644
--- a/src/Discord.Net.Core/Entities/Channels/IAudioChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/IAudioChannel.cs
@@ -1,4 +1,4 @@
-using Discord.Audio;
+using Discord.Audio;
using System;
using System.Threading.Tasks;
@@ -7,6 +7,9 @@ namespace Discord
public interface IAudioChannel : IChannel
{
/// Connects to this audio channel.
- Task ConnectAsync(Action configAction = null);
+ Task ConnectAsync(bool selfDeaf = false, bool selfMute = false, bool external = false);
+
+ /// Disconnects from this audio channel.
+ Task DisconnectAsync();
}
}
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs
index 367abfb4a..5ac0f2c40 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs
@@ -147,7 +147,8 @@ namespace Discord.Rest
=> EnterTypingState(options);
//IAudioChannel
- Task IAudioChannel.ConnectAsync(Action configAction) { throw new NotSupportedException(); }
+ Task IAudioChannel.ConnectAsync(bool selfDeaf, bool selfMute, bool external) { throw new NotSupportedException(); }
+ Task IAudioChannel.DisconnectAsync() { throw new NotSupportedException(); }
//IChannel
Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs
index a2bead45f..13f3b5efa 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs
@@ -45,7 +45,8 @@ namespace Discord.Rest
private string DebuggerDisplay => $"{Name} ({Id}, Voice)";
//IAudioChannel
- Task IAudioChannel.ConnectAsync(Action configAction) { throw new NotSupportedException(); }
+ Task IAudioChannel.ConnectAsync(bool selfDeaf, bool selfMute, bool external) { throw new NotSupportedException(); }
+ Task IAudioChannel.DisconnectAsync() { throw new NotSupportedException(); }
//IGuildChannel
Task IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs
index 81b5cfbf3..125625456 100644
--- a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs
+++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs
@@ -211,7 +211,8 @@ namespace Discord.WebSocket
=> EnterTypingState(options);
//IAudioChannel
- Task IAudioChannel.ConnectAsync(Action configAction) { throw new NotSupportedException(); }
+ Task IAudioChannel.ConnectAsync(bool selfDeaf, bool selfMute, bool external) { throw new NotSupportedException(); }
+ Task IAudioChannel.DisconnectAsync() { throw new NotSupportedException(); }
//IChannel
Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs
index 349621fac..f967e6e6a 100644
--- a/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs
+++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs
@@ -43,11 +43,14 @@ namespace Discord.WebSocket
public Task ModifyAsync(Action func, RequestOptions options = null)
=> ChannelHelper.ModifyAsync(this, Discord, func, options);
- public async Task ConnectAsync(Action configAction = null)
+ public async Task ConnectAsync(bool selfDeaf, bool selfMute, bool external)
{
- return await Guild.ConnectAudioAsync(Id, false, false, configAction).ConfigureAwait(false);
+ return await Guild.ConnectAudioAsync(Id, selfDeaf, selfMute, external).ConfigureAwait(false);
}
+ public async Task DisconnectAsync()
+ => await Guild.DisconnectAudioAsync();
+
public override SocketGuildUser GetUser(ulong id)
{
var user = Guild.GetUser(id);
diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
index 14263f0af..f41f61a7c 100644
--- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
+++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
@@ -508,11 +508,8 @@ namespace Discord.WebSocket
{
return _audioClient?.GetInputStream(userId);
}
- internal async Task ConnectAudioAsync(ulong channelId, bool selfDeaf, bool selfMute, Action configAction)
+ internal async Task ConnectAudioAsync(ulong channelId, bool selfDeaf, bool selfMute, bool external)
{
- selfDeaf = false;
- selfMute = false;
-
TaskCompletionSource promise;
await _audioLock.WaitAsync().ConfigureAwait(false);
@@ -522,6 +519,13 @@ namespace Discord.WebSocket
promise = new TaskCompletionSource();
_audioConnectPromise = promise;
+ if (external)
+ {
+ var _ = promise.TrySetResultAsync(null);
+ await Discord.ApiClient.SendVoiceStateUpdateAsync(Id, channelId, selfDeaf, selfMute).ConfigureAwait(false);
+ return null;
+ }
+
if (_audioClient == null)
{
var audioClient = new AudioClient(this, Discord.GetAudioId(), channelId);
@@ -529,7 +533,9 @@ namespace Discord.WebSocket
{
if (!promise.Task.IsCompleted)
{
- try { audioClient.Dispose(); } catch { }
+ try
+ { audioClient.Dispose(); }
+ catch { }
_audioClient = null;
if (ex != null)
await promise.TrySetExceptionAsync(ex);
@@ -543,7 +549,6 @@ namespace Discord.WebSocket
var _ = promise.TrySetResultAsync(_audioClient);
return Task.Delay(0);
};
- configAction?.Invoke(audioClient);
_audioClient = audioClient;
}
@@ -602,8 +607,11 @@ namespace Discord.WebSocket
await _audioLock.WaitAsync().ConfigureAwait(false);
try
{
- await RepopulateAudioStreamsAsync().ConfigureAwait(false);
- await _audioClient.StartAsync(url, Discord.CurrentUser.Id, voiceState.VoiceSessionId, token).ConfigureAwait(false);
+ if (_audioClient != null)
+ {
+ await RepopulateAudioStreamsAsync().ConfigureAwait(false);
+ await _audioClient.StartAsync(url, Discord.CurrentUser.Id, voiceState.VoiceSessionId, token).ConfigureAwait(false);
+ }
}
catch (OperationCanceledException)
{