fix: handle broken pipe and filter graph failures in playback loop
Co-authored-by: aider (gemini/gemini-3.1-pro-preview) <aider@aider.chat>
This commit is contained in:
@@ -75,19 +75,24 @@ def playback_thread(file_path, state):
|
|||||||
graph = build_graph(frame)
|
graph = build_graph(frame)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Filter graph error: {e}", file=sys.stderr)
|
print(f"Filter graph error: {e}", file=sys.stderr)
|
||||||
break
|
graph = "FAILED"
|
||||||
|
|
||||||
|
if graph == "FAILED":
|
||||||
|
frames_to_process = [frame]
|
||||||
|
else:
|
||||||
try:
|
try:
|
||||||
graph.push(frame)
|
graph.push(frame)
|
||||||
except av.AVError:
|
except av.AVError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
frames_to_process = []
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
filtered_frame = graph.pull()
|
frames_to_process.append(graph.pull())
|
||||||
except (av.AVError, BlockingIOError):
|
except (av.AVError, BlockingIOError):
|
||||||
break
|
break
|
||||||
|
|
||||||
|
for filtered_frame in frames_to_process:
|
||||||
resampled_frames = resampler.resample(filtered_frame)
|
resampled_frames = resampler.resample(filtered_frame)
|
||||||
for r_frame in resampled_frames:
|
for r_frame in resampled_frames:
|
||||||
arr = r_frame.to_ndarray()
|
arr = r_frame.to_ndarray()
|
||||||
@@ -98,7 +103,11 @@ def playback_thread(file_path, state):
|
|||||||
arr = arr.astype(np.float32) * multiplier
|
arr = arr.astype(np.float32) * multiplier
|
||||||
arr = np.clip(arr, -32768, 32767).astype(np.int16)
|
arr = np.clip(arr, -32768, 32767).astype(np.int16)
|
||||||
|
|
||||||
|
try:
|
||||||
fifo.write(arr.tobytes())
|
fifo.write(arr.tobytes())
|
||||||
|
except BrokenPipeError:
|
||||||
|
state.running = False
|
||||||
|
return
|
||||||
|
|
||||||
def handle_ipc_client(conn, state):
|
def handle_ipc_client(conn, state):
|
||||||
buffer = ""
|
buffer = ""
|
||||||
@@ -199,6 +208,9 @@ def main():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
playback_thread(args.file, state)
|
playback_thread(args.file, state)
|
||||||
|
# Keep the main thread alive until Navidrome explicitly sends 'quit'
|
||||||
|
while state.running:
|
||||||
|
time.sleep(0.1)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
Reference in New Issue
Block a user