Added virtual output stream for AudioClient
This commit is contained in:
@@ -4,6 +4,7 @@ using Discord.Net.WebSockets;
|
||||
using Newtonsoft.Json;
|
||||
using Nito.AsyncEx;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -11,6 +12,35 @@ namespace Discord.Audio
|
||||
{
|
||||
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 JsonSerializer _serializer;
|
||||
private CancellationTokenSource _cancelTokenSource;
|
||||
@@ -20,6 +50,7 @@ namespace Discord.Audio
|
||||
public int Id { get; }
|
||||
public GatewaySocket GatewaySocket { get; }
|
||||
public VoiceWebSocket VoiceSocket { get; }
|
||||
public Stream OutputStream { get; }
|
||||
|
||||
public ConnectionState State => VoiceSocket.State;
|
||||
public Server Server => VoiceSocket.Server;
|
||||
@@ -31,7 +62,8 @@ namespace Discord.Audio
|
||||
Id = clientId;
|
||||
GatewaySocket = gatewaySocket;
|
||||
Logger = logger;
|
||||
|
||||
OutputStream = new OutStream(this);
|
||||
|
||||
_connectionLock = new AsyncLock();
|
||||
|
||||
_serializer = new JsonSerializer();
|
||||
@@ -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>
|
||||
/// <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>
|
||||
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 (count < 0) throw new ArgumentOutOfRangeException(nameof(count));
|
||||
if (offset < 0) throw new ArgumentOutOfRangeException(nameof(count));
|
||||
if (VoiceSocket.Server == null) return; //Has been closed
|
||||
|
||||
if (count != 0)
|
||||
VoiceSocket.SendPCMFrames(data, count);
|
||||
VoiceSocket.SendPCMFrames(data, offset, count);
|
||||
}
|
||||
|
||||
/// <summary> Clears the PCM buffer. </summary>
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Discord.Audio
|
||||
public bool EnableMultiserver { get { return _enableMultiserver; } set { SetValue(ref _enableMultiserver, value); } }
|
||||
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); } }
|
||||
private int _bufferLength = 1000;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Discord.Logging;
|
||||
using Nito.AsyncEx;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Audio
|
||||
@@ -14,6 +14,7 @@ namespace Discord.Audio
|
||||
ConnectionState IAudioClient.State => _client.VoiceSocket.State;
|
||||
Server IAudioClient.Server => _client.VoiceSocket.Server;
|
||||
Channel IAudioClient.Channel => _client.VoiceSocket.Channel;
|
||||
Stream IAudioClient.OutputStream => _client.OutputStream;
|
||||
|
||||
public VirtualClient(SimpleAudioClient client)
|
||||
{
|
||||
@@ -23,7 +24,7 @@ namespace Discord.Audio
|
||||
Task IAudioClient.Disconnect() => _client.Leave(this);
|
||||
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.Wait() => _client.Wait();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user