javascript - 如何将 JS 音频 Blob 保存为文件,以便可以将其发送到 Flask API
问题描述
我正在为我的朋友构建一个应用程序,我需要录制音频并将其存储在服务器上。我已经用文本和图像成功地完成了它,但我不能让它适用于音频。
创建文件时我可能遗漏了一些东西(文件已创建但不可播放)。从 JS Blob 到实际文件的数据转换肯定有问题。
我设法获得了音频 blob,甚至在 JS 中播放它。但是当我从 blob 创建一个文件时,它无法播放(我试图以相同的结果将其保存在本地 - 得到了文件但无法播放)。我还尝试以不同的格式保存它,但没有成功(wav、mp3)。所以问题必须在从blob到实际文件的转换中。对于文本和图像,它很简单,只需使用文件名保存它们就可以从 blob 创建文件。但我想音频并不是那么简单。
我的理解是我有一些二进制数据(JS Blob),可以保存为文件。但是对于音频,必须进行一些特殊的转换或编码,以便输出文件可以正常工作并且可以播放。
这是前端代码(我将它与一些变量一起使用,因为它是 Vue 组件的一部分)
this.mediaRecorder.addEventListener("stop", () => {
// tried to save it as WAV with the same result got the file, but couldn't play it
this.audioBlob = new Blob(this.audioChunks, { 'type' : 'audio/mpeg-3' })
//debugging - playing back the sound in the browser works fine
const audioUrl = URL.createObjectURL(this.audioBlob);
const audio = new Audio(audioUrl);
audio.play();
//adding the blob to the request
let filename = this.$store.state.counter + "-" + this.$store.state.step
const formData = new FormData();
formData.append('file', this.audioBlob, `${filename}.mp3`);
const config = {
headers: { 'content-type': 'multipart/form-data' }
}
//sending it to my Flask API (xxx is the name of the folder it gets saved to on the server)
this.$axios.post('http://localhost:5000/api/v1/file/upload/xxx', formData, config)
})
这是我在服务器上的端点
@app.route('/api/v1/file/upload/<test_id>', methods=['POST'])
def upload_file(test_id):
uploaded_file = request.files['file']
filename = secure_filename(uploaded_file.filename)
if filename != '':
uploaded_file.save(os.path.join(app.config['UPLOAD_PATH'], test_id, filename))
return jsonify({'message': 'file saved'})
这是整个录音代码片段
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
this.mediaRecorder = new MediaRecorder(stream);
// audio.srcObject = stream
this.mediaRecorder.start();
this.mediaRecorder.addEventListener("dataavailable", event => {
this.audioChunks.push(event.data)
})
this.mediaRecorder.addEventListener("stop", () => {
this.audioBlob = new Blob(this.audioChunks, { 'type' : 'audio/mpeg-3' })
//debugging - playing back the sound in the browser works fine
const audioUrl = URL.createObjectURL(this.audioBlob);
const audio = new Audio(audioUrl);
audio.play();
//adding the blob to the request
let filename = this.$store.state.counter + "-" + this.$store.state.step
const formData = new FormData();
formData.append('file', this.audioBlob, `${filename}.mp3`);
const config = {
headers: { 'content-type': 'multipart/form-data' }
}
//sending it to my Flask API (xxx is the name of the folder it gets saved to on the server)
this.$axios.post('http://localhost:5000/api/v1/file/upload/xxx', formData, config)
})
})
解决方案
推荐阅读
- apache-spark - 使用 HDFS 存储的 Spark 作业
- react-native - React-native-multiple-select 在提交时获取项目
- ruby-on-rails - 我正在尝试添加简单的控制器来查看在 ruby rails 中使用 preact 组件
- android - Kotlin 为 Double 数组添加 Parcelable 实现
- c# - Regex.Matches 找不到匹配项
- mongodb - Mongo 聚合和过滤器
- javascript - 使用 Google 跟踪代码管理器在 HubSpot 表单上使用动态 ID 跟踪复选框
- java - 有没有办法动态生成 Spring Data Jpa 查询?
- python - Tensorflow ImportError:DLL加载失败:找不到指定的模块
- javascript - JavaScript 日期转换导致浏览器和节点 js 的值不同