78 lines
2.8 KiB
Python
78 lines
2.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Patch speaker.py in-place to be headless-safe.
|
|
Replaces the sd.OutputStream block with a dummy loop that just sends READY.
|
|
"""
|
|
import os
|
|
|
|
SPEAKER_PATH = "/opt/qwen3-tts/qwen3_tts_gguf/inference/workers/speaker.py"
|
|
|
|
with open(SPEAKER_PATH, "r") as f:
|
|
content = f.read()
|
|
|
|
# Replace the try block at the end of speaker_worker_proc
|
|
old = ''' try:
|
|
with sd.OutputStream(samplerate=sample_rate, channels=1, callback=audio_callback, blocksize=2048):
|
|
# 握手
|
|
if result_queue:
|
|
result_queue.put(SpeakerResponse(msg_type="READY"))
|
|
|
|
while True:
|
|
time.sleep(0.2)
|
|
if state.get("stop"): break
|
|
except KeyboardInterrupt:
|
|
pass
|
|
except Exception as e:
|
|
print(f"❌ [SpeakerWorker] 异常: {e}")'''
|
|
|
|
new = ''' try:
|
|
with sd.OutputStream(samplerate=sample_rate, channels=1, callback=audio_callback, blocksize=2048):
|
|
# 握手
|
|
if result_queue:
|
|
result_queue.put(SpeakerResponse(msg_type="READY"))
|
|
|
|
while True:
|
|
time.sleep(0.2)
|
|
if state.get("stop"): break
|
|
except KeyboardInterrupt:
|
|
pass
|
|
except Exception as e:
|
|
print(f"⚠️ [SpeakerWorker] No audio device, running headless: {e}")
|
|
# Headless fallback: send READY and drain queue without playback
|
|
if result_queue:
|
|
result_queue.put(SpeakerResponse(msg_type="READY"))
|
|
while not state.get("stop"):
|
|
try:
|
|
command = play_queue.get(timeout=0.5)
|
|
handle_command(command, state)
|
|
except Exception:
|
|
pass'''
|
|
|
|
if old in content:
|
|
content = content.replace(old, new)
|
|
with open(SPEAKER_PATH, "w") as f:
|
|
f.write(content)
|
|
print("OK: speaker.py patched with headless fallback")
|
|
else:
|
|
print("WARNING: exact match not found, trying simplified patch...")
|
|
# Try to find and patch just the except Exception block
|
|
if '❌ [SpeakerWorker] 异常' in content:
|
|
content = content.replace(
|
|
'print(f"❌ [SpeakerWorker] 异常: {e}")',
|
|
'''print(f"⚠️ [SpeakerWorker] No audio device, running headless: {e}")
|
|
# Headless fallback: send READY and drain queue without playback
|
|
if result_queue:
|
|
result_queue.put(SpeakerResponse(msg_type="READY"))
|
|
while not state.get("stop"):
|
|
try:
|
|
command = play_queue.get(timeout=0.5)
|
|
handle_command(command, state)
|
|
except Exception:
|
|
pass'''
|
|
)
|
|
with open(SPEAKER_PATH, "w") as f:
|
|
f.write(content)
|
|
print("OK: speaker.py patched (simplified)")
|
|
else:
|
|
print("ERROR: Could not find patch target in speaker.py")
|