You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 01:25:38