javascript - 用 arrayBuffer 录制 mp3
问题描述
我用 Stackoverflow 尝试了很多东西,但我无法得到它。所以我尝试用 nodejs (1) 从树莓派录制音频。在此流通过 websocket 服务器之后(我没有放置此代码,因为它只是一个重定向)。最后一个 vuejs 中的 websocket 监听流。在我想用 mp3 (2) 录制这个流之后。但我有噪音或什么都没有。1 - 树莓派:
ai = new audio.AudioIO({
inOptions: {
channelCount: 1,
sampleFormat: audio.SampleFormat16Bit,
sampleRate: 44100,
deviceId: 6, // Use -1 or omit the deviceId to select the default device
closeOnError: true // Close the stream if an audio error is detected, if set false then just log the error
}
});
ai.on('data', buf => {
clientAudioWebsocket.send(buf)
}
);
ai.start();
2-部分vuejs
插座 :
this.dataBuffer = [] var self = this var connectionToLocalServer = new WebSocket("ws://"+ip +":4444") connectionToLocalServer.binaryType = "arraybuffer" connectionToLocalServer.onmessage = function(event) { self.dataBuffer.push(event.data); } connectionToLocalServer.onopen = function(event) { }
部分 arraybuffer 到 mp3
concatArrayBuffers (bufs) { var offset = 0; var bytes = 0; var bufs2=bufs.map(function(buf,total){ bytes += buf.byteLength; return buf; }); var buffer = new ArrayBuffer(bytes); var store = new Uint8Array(buffer); bufs2.forEach(function(buf){ store.set(new Uint8Array(buf.buffer||buf,buf.byteOffset),offset); offset += buf.byteLength; }); return buffer } this.tmpResult = this.concatArrayBuffers(this.dataBuffer); var mp3Data = []; var mp3encoder = new lamejs.Mp3Encoder(1, 44100, 128); var mp3Tmp = mp3encoder.encodeBuffer(this.tmpResult, 0, Math.floor(this.tmpResult.byteLength / 2)); //Push encode buffer to mp3Data variable mp3Data.push(mp3Tmp); // Get end part of mp3 mp3Tmp = mp3encoder.flush(); // Write last data to the output data, too // mp3Data contains now the complete mp3Data mp3Data.push(mp3Tmp);
而且我不明白为什么我有 16384 大小的缓冲区的数组缓冲区。我真的对任何解决方案持开放态度,但我不想在服务器端这样做。谢谢
解决方案
所以我找到了解决方案,这是因为我没有创建一个 Int16Array :-( (有时最好在 1 小时之外,然后你会找到解决方案)
解决方案是:
let tmpResult = this.concatArrayBuffers(this.dataBuffer)
var samples = new Int16Array(tmpResult);
var buffer = [];
var mp3enc = new lamejs.Mp3Encoder(1, 44100, 128);
var remaining = samples.length;
var maxSamples = 1152;
for (var i = 0; remaining >= maxSamples; i += maxSamples) {
var mono = samples.subarray(i, i + maxSamples);
var mp3buf = mp3enc.encodeBuffer(mono);
if (mp3buf.length > 0) {
buffer.push(new Int8Array(mp3buf));
}
remaining -= maxSamples;
}
var d = mp3enc.flush();
if(d.length > 0){
buffer.push(new Int8Array(d));
}
console.log('done encoding, size=', buffer.length);
var blob = new Blob(buffer, {type: 'audio/mp3'});
推荐阅读
- angular - ngx-Image-Cropper:如何在加载时和裁剪前定义宽度
- python - Python 持续集成:忽略某些单元测试
- c# - 我使用 UWP 应用程序,但我在访问用户文件时遇到了一些问题
- katalon-studio - 多次调用对象时不生成新的动态ID
- java - 如何对数组进行排序,使其与另一个数组具有相同的顺序?
- r - 使用rep函数和for循环处理在R中输出变量对的语法
- mysql - 使用 Express 将多个 SQL 结果返回到 .handlebars
- swift - 如何使用具有许多链接到独特页面的点击点的大图像?
- jquery - jquery 捕获在 .on() 之前触发的事件
- python - 无法在 Gcloud 上部署 Flask 应用程序:ModuleNotFoundError:没有名为“flask_bcrypt”的模块