Added virtual output stream for AudioClient
This commit is contained in:
@@ -4,6 +4,7 @@ using Discord.Net.WebSockets;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Nito.AsyncEx;
|
using Nito.AsyncEx;
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -11,6 +12,35 @@ namespace Discord.Audio
|
|||||||
{
|
{
|
||||||
internal class AudioClient : IAudioClient
|
internal class AudioClient : IAudioClient
|
||||||
{
|
{
|
||||||
|
private class OutStream : Stream
|
||||||
|
{
|
||||||
|
public override bool CanRead => false;
|
||||||
|
public override bool CanSeek => false;
|
||||||
|
public override bool CanWrite => true;
|
||||||
|
|
||||||
|
private readonly AudioClient _client;
|
||||||
|
|
||||||
|
internal OutStream(AudioClient client)
|
||||||
|
{
|
||||||
|
_client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Length { get { throw new InvalidOperationException(); } }
|
||||||
|
public override long Position
|
||||||
|
{
|
||||||
|
get { throw new InvalidOperationException(); }
|
||||||
|
set { throw new InvalidOperationException(); }
|
||||||
|
}
|
||||||
|
public override void Flush() { throw new InvalidOperationException(); }
|
||||||
|
public override long Seek(long offset, SeekOrigin origin) { throw new InvalidOperationException(); }
|
||||||
|
public override void SetLength(long value) { throw new InvalidOperationException(); }
|
||||||
|
public override int Read(byte[] buffer, int offset, int count) { throw new InvalidOperationException(); }
|
||||||
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
_client.Send(buffer, offset, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private readonly AsyncLock _connectionLock;
|
private readonly AsyncLock _connectionLock;
|
||||||
private readonly JsonSerializer _serializer;
|
private readonly JsonSerializer _serializer;
|
||||||
private CancellationTokenSource _cancelTokenSource;
|
private CancellationTokenSource _cancelTokenSource;
|
||||||
@@ -20,6 +50,7 @@ namespace Discord.Audio
|
|||||||
public int Id { get; }
|
public int Id { get; }
|
||||||
public GatewaySocket GatewaySocket { get; }
|
public GatewaySocket GatewaySocket { get; }
|
||||||
public VoiceWebSocket VoiceSocket { get; }
|
public VoiceWebSocket VoiceSocket { get; }
|
||||||
|
public Stream OutputStream { get; }
|
||||||
|
|
||||||
public ConnectionState State => VoiceSocket.State;
|
public ConnectionState State => VoiceSocket.State;
|
||||||
public Server Server => VoiceSocket.Server;
|
public Server Server => VoiceSocket.Server;
|
||||||
@@ -31,6 +62,7 @@ namespace Discord.Audio
|
|||||||
Id = clientId;
|
Id = clientId;
|
||||||
GatewaySocket = gatewaySocket;
|
GatewaySocket = gatewaySocket;
|
||||||
Logger = logger;
|
Logger = logger;
|
||||||
|
OutputStream = new OutStream(this);
|
||||||
|
|
||||||
_connectionLock = new AsyncLock();
|
_connectionLock = new AsyncLock();
|
||||||
|
|
||||||
@@ -169,14 +201,15 @@ namespace Discord.Audio
|
|||||||
/// <summary> Sends a PCM frame to the voice server. Will block until space frees up in the outgoing buffer. </summary>
|
/// <summary> Sends a PCM frame to the voice server. Will block until space frees up in the outgoing buffer. </summary>
|
||||||
/// <param name="data">PCM frame to send. This must be a single or collection of uncompressed 48Kz monochannel 20ms PCM frames. </param>
|
/// <param name="data">PCM frame to send. This must be a single or collection of uncompressed 48Kz monochannel 20ms PCM frames. </param>
|
||||||
/// <param name="count">Number of bytes in this frame. </param>
|
/// <param name="count">Number of bytes in this frame. </param>
|
||||||
public void Send(byte[] data, int count)
|
public void Send(byte[] data, int offset, int count)
|
||||||
{
|
{
|
||||||
if (data == null) throw new ArgumentException(nameof(data));
|
if (data == null) throw new ArgumentException(nameof(data));
|
||||||
if (count < 0) throw new ArgumentOutOfRangeException(nameof(count));
|
if (count < 0) throw new ArgumentOutOfRangeException(nameof(count));
|
||||||
|
if (offset < 0) throw new ArgumentOutOfRangeException(nameof(count));
|
||||||
if (VoiceSocket.Server == null) return; //Has been closed
|
if (VoiceSocket.Server == null) return; //Has been closed
|
||||||
|
|
||||||
if (count != 0)
|
if (count != 0)
|
||||||
VoiceSocket.SendPCMFrames(data, count);
|
VoiceSocket.SendPCMFrames(data, offset, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Clears the PCM buffer. </summary>
|
/// <summary> Clears the PCM buffer. </summary>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace Discord.Audio
|
|||||||
public bool EnableMultiserver { get { return _enableMultiserver; } set { SetValue(ref _enableMultiserver, value); } }
|
public bool EnableMultiserver { get { return _enableMultiserver; } set { SetValue(ref _enableMultiserver, value); } }
|
||||||
private bool _enableMultiserver = false;
|
private bool _enableMultiserver = false;
|
||||||
|
|
||||||
/// <summary> Gets or sets the max buffer length (in milliseconds) for outgoing voice packets. </summary>
|
/// <summary> Gets or sets the buffer length (in milliseconds) for outgoing voice packets. </summary>
|
||||||
public int BufferLength { get { return _bufferLength; } set { SetValue(ref _bufferLength, value); } }
|
public int BufferLength { get { return _bufferLength; } set { SetValue(ref _bufferLength, value); } }
|
||||||
private int _bufferLength = 1000;
|
private int _bufferLength = 1000;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Discord.Logging;
|
using Discord.Logging;
|
||||||
using Nito.AsyncEx;
|
using Nito.AsyncEx;
|
||||||
using System.Threading;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Discord.Audio
|
namespace Discord.Audio
|
||||||
@@ -14,6 +14,7 @@ namespace Discord.Audio
|
|||||||
ConnectionState IAudioClient.State => _client.VoiceSocket.State;
|
ConnectionState IAudioClient.State => _client.VoiceSocket.State;
|
||||||
Server IAudioClient.Server => _client.VoiceSocket.Server;
|
Server IAudioClient.Server => _client.VoiceSocket.Server;
|
||||||
Channel IAudioClient.Channel => _client.VoiceSocket.Channel;
|
Channel IAudioClient.Channel => _client.VoiceSocket.Channel;
|
||||||
|
Stream IAudioClient.OutputStream => _client.OutputStream;
|
||||||
|
|
||||||
public VirtualClient(SimpleAudioClient client)
|
public VirtualClient(SimpleAudioClient client)
|
||||||
{
|
{
|
||||||
@@ -23,7 +24,7 @@ namespace Discord.Audio
|
|||||||
Task IAudioClient.Disconnect() => _client.Leave(this);
|
Task IAudioClient.Disconnect() => _client.Leave(this);
|
||||||
Task IAudioClient.Join(Channel channel) => _client.Join(channel);
|
Task IAudioClient.Join(Channel channel) => _client.Join(channel);
|
||||||
|
|
||||||
void IAudioClient.Send(byte[] data, int count) => _client.Send(data, count);
|
void IAudioClient.Send(byte[] data, int offset, int count) => _client.Send(data, offset, count);
|
||||||
void IAudioClient.Clear() => _client.Clear();
|
void IAudioClient.Clear() => _client.Clear();
|
||||||
void IAudioClient.Wait() => _client.Wait();
|
void IAudioClient.Wait() => _client.Wait();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user