Fix recording conflict when host stream is active

When a live caller is on air, the host stream already has an InputStream
open. Opening a second one for push-to-talk recording causes a conflict.
Now recording piggybacks on the host stream callback instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-05 16:42:07 -07:00
parent 4d97ea9099
commit af8606b5b7

View File

@@ -52,6 +52,7 @@ class AudioService:
# Host mic streaming state # Host mic streaming state
self._host_stream: Optional[sd.InputStream] = None self._host_stream: Optional[sd.InputStream] = None
self._host_send_callback: Optional[Callable] = None self._host_send_callback: Optional[Callable] = None
self._host_device_sr: int = 48000
# Live caller routing state # Live caller routing state
self._live_caller_stream: Optional[sd.OutputStream] = None self._live_caller_stream: Optional[sd.OutputStream] = None
@@ -173,6 +174,13 @@ class AudioService:
self._recording = True self._recording = True
self._recorded_audio = [] self._recorded_audio = []
if self._host_stream is not None:
# Host stream already capturing — piggyback on it
self._record_device_sr = self._host_device_sr
print(f"Recording started (piggybacking on host stream @ {self._host_device_sr}Hz)")
return True
self._record_thread = threading.Thread(target=self._record_worker) self._record_thread = threading.Thread(target=self._record_worker)
self._record_thread.start() self._record_thread.start()
print(f"Recording started from device {self.input_device}") print(f"Recording started from device {self.input_device}")
@@ -188,6 +196,7 @@ class AudioService:
self._recording = False self._recording = False
if self._record_thread: if self._record_thread:
self._record_thread.join(timeout=2.0) self._record_thread.join(timeout=2.0)
self._record_thread = None
if not self._recorded_audio: if not self._recorded_audio:
return b"" return b""
@@ -451,6 +460,10 @@ class AudioService:
step = max(1, int(device_sr / 16000)) step = max(1, int(device_sr / 16000))
def callback(indata, frames, time_info, status): def callback(indata, frames, time_info, status):
# Capture for push-to-talk recording if active
if self._recording:
self._recorded_audio.append(indata[:, record_channel].copy())
if not self._host_send_callback: if not self._host_send_callback:
return return
mono = indata[:, record_channel] mono = indata[:, record_channel]
@@ -460,6 +473,7 @@ class AudioService:
pcm = (mono * 32767).astype(np.int16).tobytes() pcm = (mono * 32767).astype(np.int16).tobytes()
self._host_send_callback(pcm) self._host_send_callback(pcm)
self._host_device_sr = device_sr
self._host_stream = sd.InputStream( self._host_stream = sd.InputStream(
device=self.input_device, device=self.input_device,
channels=max_channels, channels=max_channels,