RealtimeSession: uplink pump + downlink audio.delta forwarding
This commit is contained in:
@@ -26,6 +26,16 @@ public class RealtimeSession
|
||||
private EndReason _endReason = EndReason.Unknown;
|
||||
private bool _endRequested;
|
||||
|
||||
private readonly System.Threading.Channels.Channel<byte[]> _uplink =
|
||||
System.Threading.Channels.Channel.CreateBounded<byte[]>(
|
||||
new System.Threading.Channels.BoundedChannelOptions(64)
|
||||
{
|
||||
FullMode = System.Threading.Channels.BoundedChannelFullMode.DropOldest,
|
||||
});
|
||||
|
||||
public ValueTask WriteUplinkAsync(byte[] frame, CancellationToken ct)
|
||||
=> _uplink.Writer.WriteAsync(frame, ct);
|
||||
|
||||
public RealtimeSession(
|
||||
Guid deviceId,
|
||||
IRealtimeUpstream upstream,
|
||||
@@ -69,7 +79,10 @@ public class RealtimeSession
|
||||
["conversation_id"] = _conversation.Id.ToString(),
|
||||
}, ct);
|
||||
|
||||
var uplinkTask = Task.Run(() => PumpUplinkAsync(ct), ct);
|
||||
await PumpAsync(ct);
|
||||
_uplink.Writer.TryComplete();
|
||||
await uplinkTask;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -102,9 +115,37 @@ public class RealtimeSession
|
||||
{
|
||||
var evt = await _upstream.ReceiveJsonAsync(ct);
|
||||
if (evt is null) { _endReason = EndReason.Error; return; }
|
||||
var type = (string?)evt["type"];
|
||||
switch (type)
|
||||
{
|
||||
case "response.audio.delta":
|
||||
await ForwardAudioDeltaAsync(evt, ct);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ForwardAudioDeltaAsync(JsonObject evt, CancellationToken ct)
|
||||
{
|
||||
var b64 = (string?)evt["delta"];
|
||||
if (string.IsNullOrEmpty(b64)) return;
|
||||
var bytes = Convert.FromBase64String(b64);
|
||||
await _output.WriteBinaryAsync(bytes, ct);
|
||||
}
|
||||
|
||||
private async Task PumpUplinkAsync(CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
await foreach (var frame in _uplink.Reader.ReadAllAsync(ct))
|
||||
{
|
||||
await _upstream.SendJsonAsync(RealtimeEvents.InputAudioBufferAppend(frame), ct);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
catch (Exception ex) { _logger.LogWarning(ex, "uplink pump errored"); }
|
||||
}
|
||||
|
||||
private async Task<JsonObject?> WaitForUpstreamTypeAsync(string type, CancellationToken ct)
|
||||
{
|
||||
while (true)
|
||||
|
||||
Reference in New Issue
Block a user