当前正在尝试将一些录制的音频从浏览器发送到 actix-web 服务器,并尝试以从通用媒体播放器生成可播放曲目的方式将其保存到磁盘。我发现这很难做到,特别是因为我以前从未与媒体合作过。我所做的一切都是基于我所做的事情。一些谷歌搜索和一些 GPTing 的组合。 问题:文件似乎确实保存到磁盘上。它是一个非零大小的文件,但似乎无法在 VLC 媒体播放器中播放。 将录音发送到 actix-web 服务器的脚本:
const blob = new Blob(chunks, { type: "audio/mp3" });
const audioURL = URL.createObjectURL(blob);
const audio = new Audio(audioURL);
// create a button
let button = document.createElement("BUTTON");
// creating text to be
//displayed on button
let text = document.createTextNode("Play recording ", audio_rec_num + 1);
button.appendChild(text);
button.setAttribute("num", audio_rec_num);
audio_rec_num++;
document.body.appendChild(button);
button.addEventListener("click", function () {
let num = Number(button.getAttribute("num"));
// audio_chunks[num].play();
// Create FormData object to send the audio data
const formData = new FormData();
formData.append("audio", blob, "recorded_audio.mp3");
// Send the audio data to the server using fetch or XMLHttpRequest
fetch("http://127.0.0.1:8080/track_sample", {
method: "POST",
body: formData,
})
.then((response) => {
if (response.ok) {
console.log("Audio sent successfully");
} else {
console.error("Failed to send audio");
}
})
.catch((error) => {
console.error("Error sending audio: ", error);
});
});
接收数据的处理程序:
async fn track_sampler(req_body: web::Bytes) -> impl Responder {
println!("track sampler hit");
let audio_data = req_body.to_vec();
println!("Received audio data with length: {}", audio_data.len());
// Save the audio data to a WAV file
let file_path = "received_audio.mp3";
let mut file = match File::create(file_path) {
Ok(file) => file,
Err(_) => return HttpResponse::InternalServerError().finish(),
};
// Write the bytes of the audio file to the file on disk
if let Err(_) = file.write_all(&audio_data) {
return HttpResponse::InternalServerError().finish();
}
println!("done");
// Return a success response
HttpResponse::Ok().body("Audio file uploaded successfully")
}
我只需要一些明确的指示就可以实现这一点。我不一定需要代码,但这也可能非常有帮助。我究竟做错了什么 ?我知道我保存错误,但如何“正确”保存?
注意:我不希望直接从 JS 将音频保存到磁盘
JavaScript
FormData
类型将主体编码为 "multipart/form-data"
。要在 Actix-Web 处理程序中解码此正文,您需要使用 actix-multipart 板条箱。
使用它的简单方法是在反映您期望的数据的结构上使用派生宏。
actix_multipart::form::bytes::Bytes
将字节存储在内存中:
use actix_multipart::form::MultipartForm;
use actix_multipart::form::bytes::Bytes;
#[derive(MultipartForm)]
struct TrackUpload {
audio: Bytes,
}
actix_multipart::form::tempfile::TempFile
将其立即存储到磁盘:
use actix_multipart::form::MultipartForm;
use actix_multipart::form::tempfile::TempFile;
#[derive(MultipartForm)]
struct TrackUpload {
audio: TempFile,
}
Text
、Json
),但这些选项看起来与您无关。
然后在你的处理程序中使用它,如下所示:
use actix_multipart::form::MultipartForm;
async fn track_sampler(MultipartForm(upload): MultipartForm<TrackUpload>) -> impl Responder {
// use upload.audio
}
还可以选择将
actix_multipart::Multipart
接受到您的处理程序中,以比上述技术更手动地处理字段和内容流。