通过WebSocket以JSON发送Blob与字符串至Python服务器遇播放异常
问题根源与解决方案
核心问题是JSON无法直接序列化Blob对象:当你用JSON.stringify把Blob放进JSON对象时,Blob会被转换成无意义的字符串(比如"[object Blob]"或空对象结构),完全丢失了原始的音频二进制数据。后端拿到的是这个无效字符串,再编码写入文件,自然生成的音频无法播放。
必须先对Blob做格式转换,以下是两种可行的解决方案:
方案一:将Blob转成Base64字符串发送(兼容文本消息格式)
前端代码
// 工具函数:把Blob转成不带前缀的Base64字符串 async function blobToBase64(blob) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result.split(',')[1]); reader.onerror = reject; reader.readAsDataURL(blob); }); } // 构建消息并发送 const base64Audio = await blobToBase64(blob); const messageJson = JSON.stringify({ "type": "recordedAudio", "content": base64Audio }); websocket.send(messageJson);
后端Python代码
import base64 import json import os async def handler(websocket): while True: message = await websocket.recv() messageAsJSON = json.loads(message) messageType = messageAsJSON["type"] messageContent = messageAsJSON["content"] if messageType == "recordedAudio": if os.path.isfile("output.wav"): os.remove("output.wav") # 解码Base64为原始二进制音频数据 audio_data = base64.b64decode(messageContent) with open("output.wav", 'wb') as f: f.write(audio_data)
方案二:分开发送类型标识与二进制数据(更高效,无Base64体积损耗)
WebSocket支持同时发送文本和二进制帧,可以先发送类型标识,再发送原始Blob二进制:
前端代码
// 先发送类型标识文本消息 websocket.send(JSON.stringify({"type": "recordedAudio"})); // 再发送Blob二进制数据 websocket.send(blob);
后端Python代码
import json import os async def handler(websocket): current_msg_type = None while True: message = await websocket.recv() # 判断消息类型:文本是类型标识,二进制是音频数据 if isinstance(message, str): try: msg_json = json.loads(message) current_msg_type = msg_json.get("type") except: current_msg_type = None elif isinstance(message, bytes): if current_msg_type == "recordedAudio": if os.path.isfile("output.wav"): os.remove("output.wav") with open("output.wav", 'wb') as f: f.write(message) current_msg_type = None
内容的提问来源于stack exchange,提问作者user16345050
相关产品推荐
相关产品推荐

