基于MediaDevices.getUserMedia的音频存储与Mlab/MongoDB取回问题
Let's tackle your questions step by step, focusing on practical fixes for your WebRTC audio app:
Since your audio files are only a few hundred bytes, GridFS is indeed overkill. The simplest and most efficient approach here is to encode your Blob as a Base64 string and store that directly in a MongoDB string field. This avoids the overhead of GridFS and works seamlessly with standard MongoDB document operations—your audio data will even show up in JSON/CSV exports from mLab.
The XML parsing error you're seeing stems from trying to send a raw Blob object directly via Axios.post. Axios defaults to serializing data to JSON, but Blobs can't be natively converted to valid JSON—this creates unparseable data that your backend rejects, triggering the error.
Here's how to adjust your code to fix this:
Update the saveAudio method to convert Blob to Base64:
saveAudio() { const blob = new Blob(this.chunks, { type: audioType }); // Convert Blob to a Base64 data URI const reader = new FileReader(); reader.onloadend = () => { const base64Audio = reader.result; // Looks like "data:audio/wav;base64,XYZ..." this.setState({ blob: base64Audio }); }; reader.readAsDataURL(blob); }
Fix the handleSubmit method to send the valid Base64 string:
async handleSubmit(e) { e.preventDefault(); try { const response = await Axios.post("/api/words", { sound: this.state.blob // Now this is a JSON-serializable string }); console.log("Audio saved successfully:", response.data); // Trigger your delete logic here once confirmed } catch (error) { console.error("Error saving audio:", error); } }
On your backend, just store the sound field as a standard string in MongoDB. When you export your database via mLab, the Base64 audio data will be included in the JSON/CSV files—no missing content anymore.
To play the stored audio, fetch the Base64 string from your backend, convert it back to a Blob, then create an audio element to play it:
// Example function to fetch and play stored audio async playStoredAudio(audioId) { try { const response = await Axios.get(`/api/words/${audioId}`); const base64Audio = response.data.sound; // Convert Base64 back to Blob const [metaPart, dataPart] = base64Audio.split(','); const mimeString = metaPart.split(':')[1].split(';')[0]; const byteString = atob(dataPart); const ab = new ArrayBuffer(byteString.length); const ia = new Uint8Array(ab); for (let i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } const audioBlob = new Blob([ab], { type: mimeString }); // Create and play the audio const audioUrl = URL.createObjectURL(audioBlob); const audio = new Audio(audioUrl); audio.play(); // Clean up the temporary URL after playback ends audio.onended = () => URL.revokeObjectURL(audioUrl); } catch (error) { console.error("Error fetching audio:", error); } }
Quick Reminders:
- Ensure your backend endpoint
/api/wordsaccepts the Base64 string and saves it as a regular string field in MongoDB—no special setup required. - When exporting from mLab, the JSON/CSV will now contain the full Base64 audio data, so you won't lose your recordings during exports.
内容的提问来源于stack exchange,提问作者Diagathe Josué

