用 arrayBuffer 录制 mp3
record mp3 with arrayBuffer
我用 Whosebug 尝试了很多东西,但我做不到。所以我尝试使用 nodejs (1) 从 raspberry pi 录制音频。在这个流通过一个 websocket 服务器之后(我没有放这段代码,因为它只是一个重定向)。最后一个在vuejs中的websocket监听流。在我想以 mp3 (2) 格式录制此流之后。但我有噪音或没有。
1 - Raspberry pi :
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) {
}
部分数组缓冲区到 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'});
您可以在此处导航 -> https://github.com/charlielee/mp3-stream-recorder
我推荐这个。在某些时候,我会制作一个不错的 GUI Web 应用程序来执行此操作,而不是依赖 cronjob。
用法
运行 终端中的以下内容 window 或作为 cronjob:
$节点index.js -s "http://firewall.pulsradio.com" -d 20000 -o "./shows"
注意:如果运行这是一个cronjob,节点和index.js需要是它们各自位置的绝对路径。
参数
-s The URL of the stream to record (default http://firewall.pulsradio.com)
-d The duration in milliseconds to record for (default 5000)
-o The output directory of the file (default ./shows)
IFTTT 支持
还可以提供以下参数,以便在每次录制完成时触发 IFTTT Webhook 小程序。
--ifttt_event The Event Name entered on the Webhook applet
--ifttt_key The user's IFTTT Webhooks key
我用 Whosebug 尝试了很多东西,但我做不到。所以我尝试使用 nodejs (1) 从 raspberry pi 录制音频。在这个流通过一个 websocket 服务器之后(我没有放这段代码,因为它只是一个重定向)。最后一个在vuejs中的websocket监听流。在我想以 mp3 (2) 格式录制此流之后。但我有噪音或没有。 1 - Raspberry pi :
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) { }
部分数组缓冲区到 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'});
您可以在此处导航 -> https://github.com/charlielee/mp3-stream-recorder 我推荐这个。在某些时候,我会制作一个不错的 GUI Web 应用程序来执行此操作,而不是依赖 cronjob。 用法
运行 终端中的以下内容 window 或作为 cronjob:
$节点index.js -s "http://firewall.pulsradio.com" -d 20000 -o "./shows"
注意:如果运行这是一个cronjob,节点和index.js需要是它们各自位置的绝对路径。 参数
-s The URL of the stream to record (default http://firewall.pulsradio.com)
-d The duration in milliseconds to record for (default 5000)
-o The output directory of the file (default ./shows)
IFTTT 支持
还可以提供以下参数,以便在每次录制完成时触发 IFTTT Webhook 小程序。
--ifttt_event The Event Name entered on the Webhook applet
--ifttt_key The user's IFTTT Webhooks key