action
All checks were successful
Deploy WebSocket Server / deploy (push) Successful in 4s

This commit is contained in:
jeremygan2021
2026-03-05 21:09:37 +08:00
parent a784c88c60
commit 1b2c55afc7
5 changed files with 73 additions and 360 deletions

View File

@@ -57,10 +57,9 @@ def image_to_tspl_commands(image_path):
# 逻辑修正:
# 我们希望 黑色像素(0) -> 打印(1)
# 白色像素(255) -> 不打印(0)
# 使用 < 128 判定,增加容错性,防止像素值偏移
should_print = False
if pixel < 128: # Black or Dark Gray
if pixel == 0: # Black
should_print = True
if should_print:

View File

@@ -427,39 +427,6 @@ async def handle_font_request(websocket, message_type, data):
except Exception as e:
print(f"Error handling font request: {e}")
class LockedWebSocket:
"""
WebSocket wrapper with a lock to prevent concurrent write operations.
The websockets library (legacy protocol) does not support concurrent writes,
which can lead to 'AssertionError: assert waiter is None' when multiple tasks
try to send data simultaneously.
"""
def __init__(self, websocket: WebSocket):
self.websocket = websocket
self.lock = asyncio.Lock()
async def accept(self):
await self.websocket.accept()
async def receive(self):
return await self.websocket.receive()
async def send_text(self, data: str):
async with self.lock:
await self.websocket.send_text(data)
async def send_bytes(self, data: bytes):
async with self.lock:
await self.websocket.send_bytes(data)
async def send_json(self, data):
async with self.lock:
await self.websocket.send_json(data)
async def close(self, code=1000):
async with self.lock:
await self.websocket.close(code)
class MyRecognitionCallback(RecognitionCallback):
def __init__(self, websocket: WebSocket, loop: asyncio.AbstractEventLoop):
self.websocket = websocket
@@ -569,8 +536,8 @@ def optimize_prompt(asr_text, progress_callback=None):
1. 风格必须是:简单的黑白线稿、简笔画、图标风格 (Line art, Sketch, Icon style)。
2. 画面必须清晰、线条粗壮,适合低分辨率热敏打印机打印。
3. 绝对不要有复杂的阴影、渐变、黑白线条描述。
4. 背景必须是纯白 (White background),线条要粗方便打印
5. 提示词内容请使用英文描述,因为绘图模型对英文理解更好,但在描述中强调 "black and white line art", "bold simple lines", "vector style"
4. 背景必须是纯白 (White background)。
5. 提示词内容请使用英文描述,因为绘图模型对英文理解更好,但在描述中强调 "black and white line art", "simple lines", "vector style"
6. 尺寸比例遵循宽48mm:高30mm (约 1.6:1)。
7. 直接输出优化后的提示词,不要包含任何解释。"""
@@ -709,17 +676,8 @@ def generate_image(prompt, progress_callback=None, retry_count=0, max_retries=2)
from PIL import Image
img = Image.open(GENERATED_IMAGE_FILE)
# 缩小到THUMB_SIZE x THUMB_SIZE,保持比例并居中(防止拉伸)
img.thumbnail((THUMB_SIZE, THUMB_SIZE), Image.LANCZOS)
# 创建黑色背景 (240x240)
bg = Image.new("RGB", (THUMB_SIZE, THUMB_SIZE), (0, 0, 0))
# 计算居中位置
left = (THUMB_SIZE - img.width) // 2
top = (THUMB_SIZE - img.height) // 2
bg.paste(img, (left, top))
img = bg
# 缩小到THUMB_SIZE x THUMB_SIZE
img = img.resize((THUMB_SIZE, THUMB_SIZE), Image.LANCZOS)
# 转换为RGB565格式的原始数据
# 每个像素2字节 (R5 G6 B5)
@@ -791,8 +749,6 @@ def generate_image(prompt, progress_callback=None, retry_count=0, max_retries=2)
@app.websocket("/ws/audio")
async def websocket_endpoint(websocket: WebSocket):
# 使用 LockedWebSocket 包装原始 websocket 以防止并发写入冲突
websocket = LockedWebSocket(websocket)
global audio_buffer
await websocket.accept()
print("Client connected")
@@ -1025,5 +981,4 @@ if __name__ == "__main__":
local_ip = socket.gethostbyname(hostname)
print(f"Server running on ws://{local_ip}:8000/ws/audio")
# 禁用自动Ping以避免并发写入冲突 (ws_ping_interval=None)
uvicorn.run(app, host="0.0.0.0", port=8000, ws_ping_interval=None, ws_ping_timeout=None)
uvicorn.run(app, host="0.0.0.0", port=8000)