ESP32调用OpenAI语音转文本API:Multipart表单数据格式问题
解决ESP32调用OpenAI语音转文本API的音频格式错误问题
核心问题分析
你的代码存在三个关键错误,导致API返回音频格式不正确:
- 将二进制音频数据转为
String拼接,会破坏二进制数据(如0x00字节会被当作字符串结束符,非ASCII字符处理异常)。 - 音频文件的
Content-Type设置错误,使用了通用的application/octet-stream,而非WAV文件对应的audio/wav,导致API无法正确识别格式。 - 手动拼接整个multipart payload容易出错,且大文件会占用过多内存,增加数据损坏风险。
修正后的代码实现
void STTAPI() { HTTPClient http; const char *model = "whisper-1"; const char *filename = "/Test/CapitalofEngland.wav"; const char *boundary = "unique-boundary-123456"; // 使用唯一边界字符串 // 打开SD卡中的WAV文件 File file = SD.open(filename, FILE_READ); if (!file) { Serial.println("Error opening WAV file"); return; } // 初始化HTTP连接 if (!http.begin("https://api.openai.com/v1/audio/transcriptions")) { Serial.println("HTTP connection failed"); file.close(); return; } // 设置授权头 String authorizationHeader = "Bearer " + String(API_Key); http.addHeader("Authorization", authorizationHeader); // 启动HTTP请求 if (!http.startRequest()) { Serial.println("Failed to start request"); http.end(); file.close(); return; } // 发送文件字段的multipart头部 String filePartHeader = "--" + String(boundary) + "\r\n"; filePartHeader += "Content-Disposition: form-data; name=\"file\"; filename=\"" + String(filename) + "\"\r\n"; filePartHeader += "Content-Type: audio/wav\r\n\r\n"; // WAV文件正确的MIME类型 http.write((const uint8_t *)filePartHeader.c_str(), filePartHeader.length()); // 分块发送音频文件内容,避免内存溢出 const size_t bufferSize = 1024; uint8_t buffer[bufferSize]; size_t bytesRead; while ((bytesRead = file.read(buffer, bufferSize)) > 0) { http.write(buffer, bytesRead); } // 发送model字段的multipart内容 String modelPart = "\r\n--" + String(boundary) + "\r\n"; modelPart += "Content-Disposition: form-data; name=\"model\"\r\n\r\n"; modelPart += model + "\r\n"; http.write((const uint8_t *)modelPart.c_str(), modelPart.length()); // 发送multipart结束边界 String endBoundary = "--" + String(boundary) + "--\r\n"; http.write((const uint8_t *)endBoundary.c_str(), endBoundary.length()); // 获取响应并处理 int httpResponseCode = http.endRequest(); if (httpResponseCode > 0) { Serial.print("HTTP Response code: "); Serial.println(httpResponseCode); String responsePayload = http.getString(); Serial.println("Response payload: " + responsePayload); } else { Serial.print("HTTP Request failed, error: "); Serial.println(httpResponseCode); } // 清理资源 http.end(); file.close(); }
关键修改说明
- 分块发送音频数据:避免将整个文件读入内存,同时防止二进制数据被
String类错误处理。 - 正确设置Content-Type:针对WAV文件使用
audio/wav,让OpenAI API能准确识别音频格式。 - 逐段构建multipart内容:使用
startRequest()和write()方法分段发送数据,减少手动拼接的出错概率。 - 唯一边界字符串:避免边界字符串与音频内容中的字符冲突,确保multipart格式正确。
额外检查项
- 确认SD卡中的WAV文件为标准格式:建议使用16kHz采样率、16位单声道PCM编码,这是Whisper API最兼容的格式。
- 验证
API_Key的有效性,确保账号拥有音频转录API的访问权限。
内容的提问来源于stack exchange,提问作者Chris Ingham
相关产品推荐
相关产品推荐

