let audioChunks = []; let mediaRecorder; let stream; if (event.key === '1') { console.log('数字1键被按下了!'); navigator.mediaDevices.getUserMedia({ audio: true }).then(s => { stream = s; mediaRecorder = new MediaRecorder(stream); mediaRecorder.addEventListener('dataavailable', event => { audioChunks.push(event.data); }); mediaRecorder.start(); }) } console.log('audioChunks',audioChunks) if (event.key === '2') { console.log('数字2键被按下了!',audioChunks); mediaRecorder.stop(); stream.getTracks().forEach(track => track.stop()); const audioBlob = new Blob(audioChunks, { type: 'audio/wav' }); const reader = new FileReader(); reader.readAsDataURL(audioBlob); reader.onloadend = () => { const dataURI = reader.result; emitUIInteraction(JSON.stringify(dataURI)); console.log('dataURI', dataURI); // downloadAudio(dataURI) }; }这段代码audioChunks为什么打印不出来,怎么改
时间: 2024-02-14 09:22:43 浏览: 57
这段代码中,当按下数字1键时,会获取用户的音频流并将其存储在audioChunks数组中。但是,由于getUserMedia是一个异步操作,因此在按下数字1键后,console.log('audioChunks',audioChunks)语句会立即执行,并且此时audioChunks数组还是空的。当用户按下数字2键时,会停止录音并将audioChunks中的数据转换为Blob对象,然后使用FileReader将其转换为数据URI。因此,在数字2键按下之前,不能直接打印出audioChunks数组中的数据。
如果您想查看录制的音频数据,可以在数字2键按下之前,将console.log('audioChunks',audioChunks)移动到数字1键按下的回调函数中。这样,当您按下数字2键时,可以确保audioChunks数组中有数据,并且您也可以看到它们。
相关问题
let audioChunks = []; let mediaRecorder; let stream; if (event.key === '1') { console.log('数字1键被按下了!'); navigator.mediaDevices.getUserMedia({ audio: true }).then(s => { stream = s; mediaRecorder = new MediaRecorder(stream); mediaRecorder.addEventListener('dataavailable', event => { audioChunks.push(event.data); }); mediaRecorder.start(); }) } console.log('audioChunks',audioChunks) if (event.key === '2') { console.log('数字2键被按下了!',audioChunks); mediaRecorder.stop(); stream.getTracks().forEach(track => track.stop()); const audioBlob = new Blob(audioChunks, { type: 'audio/wav' }); const reader = new FileReader(); reader.readAsDataURL(audioBlob); reader.onloadend = () => { const dataURI = reader.result; emitUIInteraction(JSON.stringify(dataURI)); console.log('dataURI', dataURI); // downloadAudio(dataURI) }; }这段代码,怎么改
如果您想在数字2键按下之前查看audioChunks数组中的数据,可以将console.log('audioChunks',audioChunks)移动到数字1键按下的回调函数中,如下所示:
```
let audioChunks = [];
let mediaRecorder;
let stream;
if (event.key === '1') {
console.log('数字1键被按下了!');
navigator.mediaDevices.getUserMedia({ audio: true }).then(s => {
stream = s;
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.addEventListener('dataavailable', event => {
audioChunks.push(event.data);
});
mediaRecorder.start();
});
console.log('audioChunks',audioChunks); // 将console.log移动到此处
}
if (event.key === '2') {
console.log('数字2键被按下了!',audioChunks);
mediaRecorder.stop();
stream.getTracks().forEach(track => track.stop());
const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
const reader = new FileReader();
reader.readAsDataURL(audioBlob);
reader.onloadend = () => {
const dataURI = reader.result;
emitUIInteraction(JSON.stringify(dataURI));
console.log('dataURI', dataURI);
// downloadAudio(dataURI)
};
}
```
这将确保您只在audioChunks数组中有数据时才会打印它。
解释一下 mediaRecorder.ondataavailable = function (e) { chunks.push(e.data); var reader = new FileReader(); reader.addEventListener("loadend", function () { //reader.result是一个含有视频数据流的Blob对象 var videoData = new Uint8Array(reader.result); if (reader.result.byteLength > 0) { //加这个判断,是因为有很多数据是空的,这个没有必要发到后台服务器,减轻网络开销,提升性能吧。 // console.log(videoData) // 发送 // ws.send(JSON.stringify(videoData)); const decoder = new TextDecoder(); const videoString = decoder.decode(videoData); console.log( videoString); ws.send(videoString); } }); reader.readAsArrayBuffer(e.data); };
这段代码是一个使用MediaRecorder录制视频并发送到服务器的示例。我来解释一下代码的执行过程:
1. `mediaRecorder.ondataavailable` 是一个事件处理函数,当MediaRecorder录制到新的数据块时会触发该事件。
2. `chunks` 是一个数组,用于存储每个数据块。
3. `reader` 是一个FileReader对象,用于读取Blob对象中的数据。
4. `reader.addEventListener("loadend", function () { ... })` 是一个事件监听器,当读取操作完成时会触发该事件。
5. `reader.readAsArrayBuffer(e.data)` 是将数据块作为ArrayBuffer读取的方法。
6. 当读取操作完成后,`reader.result` 是一个包含视频数据流的ArrayBuffer对象。
7. `Uint8Array(reader.result)` 将ArrayBuffer对象转换为Uint8Array数组,以便后续处理。
8. `if (reader.result.byteLength > 0)` 检查视频数据流的长度是否大于0,以确保数据流不为空。
9. `const decoder = new TextDecoder()` 创建一个TextDecoder对象,用于将Uint8Array数组解码为字符串。
10. `decoder.decode(videoData)` 将视频数据流解码为字符串。
11. `ws.send(videoString)` 将解码后的视频数据字符串发送到服务器。
通过以上步骤,代码将录制的视频数据流进行了解码并发送到服务器。需要注意的是,这里使用了TextDecoder对象将视频数据解码为字符串,可能会导致数据损坏或无法正确解析。如果需要保持视频数据的完整性,应该将其保持为二进制形式而不是解码为字符串。
阅读全文