Fix iOS voice capture and screen sharing
This commit is contained in:
@@ -16,7 +16,7 @@ internal sealed class ClientMediaTransport : IAsyncDisposable
|
||||
private readonly byte[] binding = new byte[VoiceFrameHeader.Size + 16];
|
||||
private readonly byte[] keepalive = new byte[VoiceFrameHeader.Size];
|
||||
private readonly PacketQueue packets = new();
|
||||
private readonly Task sending;
|
||||
private readonly Thread sending;
|
||||
private readonly Task receiving;
|
||||
private readonly TaskCompletionSource bound = new(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
internal event EncodedVoiceHandler? Received;
|
||||
@@ -34,12 +34,13 @@ internal sealed class ClientMediaTransport : IAsyncDisposable
|
||||
token.CopyTo(binding.AsSpan(VoiceFrameHeader.Size));
|
||||
new VoiceFrameHeader(MediaFrameType.Keepalive, 0, 0, 0, 0, 0).Write(keepalive);
|
||||
receiving = ReceiveAsync();
|
||||
sending = SendAsync();
|
||||
sending = new Thread(Send) { IsBackground = true, Name = "VoiceCat UDP sender", Priority = ThreadPriority.AboveNormal };
|
||||
sending.Start();
|
||||
}
|
||||
|
||||
internal bool TrySend(VoiceFrameHeader header, ReadOnlySpan<byte> payload) => packets.TryWrite(header, payload);
|
||||
|
||||
private async Task SendAsync()
|
||||
private void Send()
|
||||
{
|
||||
byte[] plain = new byte[1275], packet = new byte[1275 + VoiceFrameHeader.Size + MediaEncryptor.TagSize];
|
||||
long nextKeepalive = 0;
|
||||
@@ -49,19 +50,19 @@ internal sealed class ClientMediaTransport : IAsyncDisposable
|
||||
{
|
||||
if (Environment.TickCount64 >= nextKeepalive)
|
||||
{
|
||||
if (!bound.Task.IsCompleted) await socket.SendAsync(binding, SocketFlags.None, stop.Token).ConfigureAwait(false);
|
||||
await socket.SendAsync(keepalive, SocketFlags.None, stop.Token).ConfigureAwait(false);
|
||||
if (!bound.Task.IsCompleted) socket.Send(binding, SocketFlags.None);
|
||||
socket.Send(keepalive, SocketFlags.None);
|
||||
nextKeepalive = Environment.TickCount64 + (bound.Task.IsCompleted ? 5000 : 250);
|
||||
}
|
||||
while (packets.TryRead(plain, out VoiceFrameHeader header, out int length))
|
||||
{
|
||||
int size = crypto.Encryptor.Encrypt(header, plain.AsSpan(0, length), packet);
|
||||
await socket.SendAsync(packet.AsMemory(0, size), SocketFlags.None, stop.Token).ConfigureAwait(false);
|
||||
socket.Send(packet.AsSpan(0, size), SocketFlags.None);
|
||||
}
|
||||
await Task.Delay(5, stop.Token).ConfigureAwait(false);
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
}
|
||||
catch (Exception exception) when (exception is OperationCanceledException or SocketException or ObjectDisposedException)
|
||||
catch (Exception exception) when (exception is SocketException or ObjectDisposedException)
|
||||
{ if (!stop.IsCancellationRequested) bound.TrySetException(exception); }
|
||||
finally { stop.Cancel(); }
|
||||
}
|
||||
@@ -91,7 +92,7 @@ internal sealed class ClientMediaTransport : IAsyncDisposable
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
stop.Cancel(); socket.Dispose();
|
||||
try { await Task.WhenAll(sending, receiving).ConfigureAwait(false); }
|
||||
try { sending.Join(); await receiving.ConfigureAwait(false); }
|
||||
finally { System.Security.Cryptography.CryptographicOperations.ZeroMemory(binding); stop.Dispose(); }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user