通过ajax上传一个二进制编码的audio文件并保存

我有一个本地保存的audio文件,我想读取,通过ajax上传到服务器,然后存储在服务器上。 在这个过程中的某处,文件被损坏,使得保存在服务器上的文件无法播放。

我将列出简化的代码,显示我正在经历的过程,希望这将是明显的地方,我会出错。

1)录制audio(使用getUserMedia和MediaRecorder )后,会保存一个本地文件:

var audioData = new Blob(chunks, { type: 'audio/webm' }); var fileReader = new FileReader(); fileReader.onloadend = function() { var buffer = this.result, uint8Array = new Uint8Array(buffer); fs.writeFile('path/to/file.webm', uint8Array, { flags: 'w' }); } fileReader.readAsArrayBuffer(audioData); 

2)稍后读取本地文件并发送到服务器(使用库axios发送ajax请求)

 fs.readFile('path/to/file.webm', 'binary', (err, data) => { var formData = new FormData(); formData.append('file', new Blob([data], {type: 'audio/webm'}), 'file.webm'); axios.put('/upload', formData); }); 

3)然后服务器处理这个请求并保存文件

 [HttpPut] public IActionResult Upload(IFormFile file) { using (var fileStream = new FileStream("path/to/file.webm", FileMode.Create)) { file.CopyTo(fileStream); } } 

本地audio文件可以成功播放,但是服务器上的audio文件不能播放。

我不确定这是否是有用的信息,但这是我在文本编辑器(记事本++)中打开本地文件时看到的前几行文本:

在这里输入图像描述

而当我打开服务器上的一个:

在这里输入图像描述

所以有点相同…但不同。 我试过编码的方式无数,但一切似乎都失败了。 手指交叉的人可以在这里指向正确的方向。

       

网上收集的解决方案 "通过ajax上传一个二进制编码的audio文件并保存"

问题在于如何传递来自fs.readFile的文件内容。 如果我通过json从fs.readFile传递一个base64编码的原始缓冲区,将其转换为服务器上的一个字节数组并保存,然后我可以在服务器上成功地播放它。


 fs.readFile('path/to/file.webm', (err, data) => { axios.put('/upload', { audioData: data.toString('base64') }); }); 

 [HttpPut] public IActionResult Upload([FromBody]UploadViewModel upload) { var audioDataBytes = Convert.FromBase64String(upload.AudioData); using (var memoryStream = new MemoryStream(audioDataBytes)) using (var fileStream = new FileStream("path/to/file.webm", FileMode.Create)) { await memoryStream.CopyToAsync(fileStream); } } 

其实这是字符编码的问题。 您可能混合了导致文件被破坏的UTF-8和ISO-8859。

您应该将HTML页面中的字符集设置为服务器上的字符集。 或者,如果您不知道您将收到的数据的字符集,请在服务器上执行初步检查。

转换到base64将解决这个问题,因为它只会使用ASCII范围内的字符。