Fix iOS voice capture and screen sharing
Build and test / test (macos-latest) (push) Canceled after 0s
Build and test / test (ubuntu-24.04) (push) Canceled after 0s
Build and test / test (windows-latest) (push) Canceled after 0s
Build and test / apple-client (push) Canceled after 0s

This commit is contained in:
2026-09-21 14:14:15 +02:00
parent 35617e9708
commit 0372baf589
13 changed files with 389 additions and 66 deletions
@@ -9,7 +9,7 @@ internal sealed class BroadcastAudioPump : IAsyncDisposable
private const uint Magic = 0x56434252, Version = 1;
private const int Header = 64, Capacity = 96_000, Frame = 960;
private readonly CancellationTokenSource stop = new();
private Task worker = Task.CompletedTask;
private Thread? worker;
private VoiceCatClient? client;
private uint streamId;
private bool active;
@@ -19,15 +19,21 @@ internal sealed class BroadcastAudioPump : IAsyncDisposable
internal event Action? Changed;
internal bool IsActive => active;
internal void Start(VoiceCatClient owner) { client = owner; worker = RunAsync(stop.Token); }
private async Task RunAsync(CancellationToken token)
internal void Start(VoiceCatClient owner)
{
client = owner;
worker = new Thread(Run) { IsBackground = true, Name = "VoiceCat iOS screen audio", Priority = ThreadPriority.AboveNormal };
worker.Start();
}
private void Run()
{
CancellationToken token = stop.Token;
while (!token.IsCancellationRequested)
{
try { await DrainAsync(token); }
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException) { }
await Task.Delay(10, token).ConfigureAwait(false);
try { DrainAsync(token).GetAwaiter().GetResult(); }
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException or OperationCanceledException) { }
if (!token.IsCancellationRequested) Thread.Sleep(5);
}
}
@@ -78,8 +84,9 @@ internal sealed class BroadcastAudioPump : IAsyncDisposable
private void SetActive(bool value) { if (active == value) return; active = value; Changed?.Invoke(); }
public async ValueTask DisposeAsync()
public ValueTask DisposeAsync()
{
stop.Cancel(); Interlocked.Increment(ref generation); try { await worker.ConfigureAwait(false); } catch (OperationCanceledException) { } StopStream(); SetActive(false); stop.Dispose();
stop.Cancel(); Interlocked.Increment(ref generation); worker?.Join(); worker = null;
StopStream(); SetActive(false); stop.Dispose(); return ValueTask.CompletedTask;
}
}