Added Flush support for audio streams

This commit is contained in:
RogueException
2016-12-30 17:02:25 -04:00
parent beb2acb40c
commit f4469a76be
6 changed files with 53 additions and 3 deletions

View File

@@ -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();

View File

@@ -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);

View File

@@ -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

View File

@@ -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)

View File

@@ -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);
} }
} }

View File

@@ -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();
} }
} }