68 lines
2.3 KiB
C#
68 lines
2.3 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Discord.Audio.Streams
|
|
{
|
|
///<summary> Reads the payload from an RTP frame </summary>
|
|
public class RTPReadStream : AudioOutStream
|
|
{
|
|
private readonly InputStream _queue;
|
|
private readonly AudioOutStream _next;
|
|
private readonly byte[] _buffer, _nonce, _secretKey;
|
|
|
|
public override bool CanRead => true;
|
|
public override bool CanSeek => false;
|
|
public override bool CanWrite => true;
|
|
|
|
public RTPReadStream(InputStream queue, byte[] secretKey, int bufferSize = 4000)
|
|
: this(queue, null, secretKey, bufferSize) { }
|
|
public RTPReadStream(InputStream queue, AudioOutStream next, byte[] secretKey, int bufferSize = 4000)
|
|
{
|
|
_queue = queue;
|
|
_next = next;
|
|
_secretKey = secretKey;
|
|
_buffer = new byte[bufferSize];
|
|
_nonce = new byte[24];
|
|
}
|
|
|
|
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancelToken)
|
|
{
|
|
cancelToken.ThrowIfCancellationRequested();
|
|
|
|
if (buffer[offset + 0] != 0x80 || buffer[offset + 1] != 0x78)
|
|
return;
|
|
|
|
var payload = new byte[count - 12];
|
|
Buffer.BlockCopy(buffer, offset + 12, payload, 0, count - 12);
|
|
|
|
ushort seq = (ushort)((buffer[offset + 2] << 8) |
|
|
(buffer[offset + 3] << 0));
|
|
|
|
uint timestamp = (uint)((buffer[offset + 4] << 24) |
|
|
(buffer[offset + 5] << 16) |
|
|
(buffer[offset + 6] << 16) |
|
|
(buffer[offset + 7] << 0));
|
|
|
|
_queue.WriteHeader(seq, timestamp);
|
|
await (_next ?? _queue as Stream).WriteAsync(buffer, offset, count, cancelToken).ConfigureAwait(false);
|
|
}
|
|
|
|
public static bool TryReadSsrc(byte[] buffer, int offset, out uint ssrc)
|
|
{
|
|
if (buffer.Length - offset < 12)
|
|
{
|
|
ssrc = 0;
|
|
return false;
|
|
}
|
|
|
|
ssrc = (uint)((buffer[offset + 8] << 24) |
|
|
(buffer[offset + 9] << 16) |
|
|
(buffer[offset + 10] << 16) |
|
|
(buffer[offset + 11] << 0));
|
|
return true;
|
|
}
|
|
}
|
|
}
|