Added Flush support for audio streams
This commit is contained in:
@@ -314,6 +314,7 @@ namespace Discord.Audio
|
|||||||
|
|
||||||
internal void Dispose(bool disposing)
|
internal void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
|
DisconnectInternalAsync(null).GetAwaiter().GetResult();
|
||||||
if (!_isDisposed)
|
if (!_isDisposed)
|
||||||
_isDisposed = true;
|
_isDisposed = true;
|
||||||
ApiClient.Dispose();
|
ApiClient.Dispose();
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Discord.Audio
|
namespace Discord.Audio
|
||||||
{
|
{
|
||||||
@@ -24,6 +26,10 @@ namespace Discord.Audio
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(byte[] buffer, int offset, int count)
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
WriteAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
//Assume threadsafe
|
//Assume threadsafe
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
@@ -37,7 +43,7 @@ namespace Discord.Audio
|
|||||||
_partialFramePos = 0;
|
_partialFramePos = 0;
|
||||||
|
|
||||||
int encFrameSize = _encoder.EncodeFrame(_partialFrameBuffer, 0, _frameSize, _buffer, 0);
|
int encFrameSize = _encoder.EncodeFrame(_partialFrameBuffer, 0, _frameSize, _buffer, 0);
|
||||||
base.Write(_buffer, 0, encFrameSize);
|
await base.WriteAsync(_buffer, 0, encFrameSize, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -48,6 +54,22 @@ namespace Discord.Audio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Flush()
|
||||||
|
{
|
||||||
|
FlushAsync(CancellationToken.None).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
public override async Task FlushAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int encFrameSize = _encoder.EncodeFrame(_partialFrameBuffer, 0, _partialFramePos, _buffer, 0);
|
||||||
|
base.Write(_buffer, 0, encFrameSize);
|
||||||
|
}
|
||||||
|
catch (Exception) { } //Incomplete frame
|
||||||
|
_partialFramePos = 0;
|
||||||
|
await base.FlushAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Discord.Audio
|
namespace Discord.Audio
|
||||||
{
|
{
|
||||||
@@ -33,6 +35,10 @@ namespace Discord.Audio
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(byte[] buffer, int offset, int count)
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
WriteAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
unchecked
|
unchecked
|
||||||
{
|
{
|
||||||
@@ -48,10 +54,17 @@ namespace Discord.Audio
|
|||||||
|
|
||||||
count = SecretBox.Encrypt(buffer, offset, count, _buffer, 12, _nonce, _secretKey);
|
count = SecretBox.Encrypt(buffer, offset, count, _buffer, 12, _nonce, _secretKey);
|
||||||
Buffer.BlockCopy(_nonce, 0, _buffer, 0, 12); //Copy the RTP header from nonce to buffer
|
Buffer.BlockCopy(_nonce, 0, _buffer, 0, 12); //Copy the RTP header from nonce to buffer
|
||||||
_target.SendAsync(_buffer, count + 12).GetAwaiter().GetResult();
|
await _target.SendAsync(_buffer, count + 12).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Flush() { }
|
public override void Flush()
|
||||||
|
{
|
||||||
|
FlushAsync(CancellationToken.None).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
public override async Task FlushAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await _target.FlushAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
public override long Length { get { throw new NotSupportedException(); } }
|
public override long Length { get { throw new NotSupportedException(); } }
|
||||||
public override long Position
|
public override long Position
|
||||||
|
|||||||
@@ -65,6 +65,16 @@ namespace Discord.Audio
|
|||||||
return Task.Delay(0);
|
return Task.Delay(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task FlushAsync()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (_queue.Count == 0)
|
||||||
|
return;
|
||||||
|
await Task.Delay(250).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void Dispose(bool disposing)
|
protected void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
|
|||||||
@@ -12,5 +12,8 @@ namespace Discord.Audio
|
|||||||
|
|
||||||
public Task SendAsync(byte[] buffer, int count)
|
public Task SendAsync(byte[] buffer, int count)
|
||||||
=> _client.SendAsync(buffer, count);
|
=> _client.SendAsync(buffer, count);
|
||||||
|
|
||||||
|
public Task FlushAsync()
|
||||||
|
=> Task.Delay(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,6 @@ namespace Discord.Audio
|
|||||||
internal interface IAudioTarget
|
internal interface IAudioTarget
|
||||||
{
|
{
|
||||||
Task SendAsync(byte[] buffer, int count);
|
Task SendAsync(byte[] buffer, int count);
|
||||||
|
Task FlushAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user