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

从JS发送音频到actix-web服务器保存后无法播放的问题排查

问题根源

你现在的核心问题是服务器错误接收了整个multipart请求体,而非提取FormData中的纯音频内容。直接保存web::Bytes得到的是包含FormData边界、字段描述的原始请求数据,不是纯音频字节,导致VLC无法识别。另外,前端强行把Blob类型设为audio/mp3也可能有问题:浏览器MediaRecorder默认录制的是WebM格式,仅修改MIME类型不会自动转码,实际文件格式还是WebM。

解决步骤

1. 服务器端正确解析Multipart FormData

actix-web提供了Multipart类型专门处理FormData请求,替换当前的web::Bytes参数,提取并保存音频文件:

use actix_web::{web, HttpResponse, Responder};
use actix_multipart::Multipart;
use std::io::Write;
use std::fs::File;

async fn track_sampler(mut payload: Multipart) -> impl Responder {
    println!("track sampler hit");

    while let Some(mut field) = payload.next().await {
        let content_disposition = field.content_disposition();
        // 匹配FormData中的"audio"字段
        if content_disposition.get_name() == Some("audio") {
            // 提取文件名,或用固定名称
            let filename = content_disposition.get_filename().unwrap_or("received_audio.webm");
            let mut file = match File::create(filename) {
                Ok(file) => file,
                Err(_) => return HttpResponse::InternalServerError().finish(),
            };

            // 逐块写入音频数据
            while let Some(chunk) = field.next().await {
                let data = chunk.unwrap();
                if let Err(_) = file.write_all(&data) {
                    return HttpResponse::InternalServerError().finish();
                }
            }

            println!("Audio saved as {}", filename);
            return HttpResponse::Ok().body("Audio uploaded successfully");
        }
    }

    HttpResponse::BadRequest().body("No audio file found in request")
}

同时在路由配置中启用multipart支持:

use actix_web::{App, HttpServer};
use actix_multipart::MultipartConfig;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .app_data(MultipartConfig::default())
            .route("/track_sample", web::post().to(track_sampler))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

2. 修正前端音频格式

浏览器MediaRecorder不原生支持MP3,默认输出WebM格式,调整前端代码匹配实际格式:

// 使用WebM格式创建Blob
const blob = new Blob(chunks, { type: "audio/webm" });
// FormData中文件名对应WebM后缀
formData.append("audio", blob, "recorded_audio.webm");

如果确实需要MP3,前端需引入第三方转码库(如lamejs)将录制的音频转码后再发送。

3. 验证方法

  • 服务器保存文件后,用ffmpeg -i received_audio.webm命令查看文件信息,能识别音频流说明文件正确。
  • 直接用VLC打开保存的WebM文件,正常播放则流程没问题。

内容的提问来源于stack exchange,提问作者harsh82

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 10:22:47