我正在尝试从浏览器录制音频并将其作为原始音频 (PCM) 流式传输到我想以 .mp3 格式保存到我的节点服务器。我在我的服务器上使用 node-lame 模块从 PCM 音频流创建一个 mp3 文件。这里的问题是mp3文件总是高音并且播放速度很快。我已经尝试将来自浏览器(客户端)的数据作为 int16 和作为 float32 发送并为它们设置适当的 lame.Encoder :
stream.pipe(new lame.Encoder({channels:2, bitDepth: 32, float:true,})) //float32
.pipe(fs.createWriteStream(path.resolve(__dirname, 'demo.mp3')))
stream.pipe(new lame.Encoder({channels:2, bitDepth: 16, sampleRate:44100,})) // int16
.pipe(fs.createWriteStream(path.resolve(__dirname, 'demo.mp3')))
这是客户端的代码
(function(window) {
var client = new BinaryClient('ws://localhost:9001');
client.on('open', function() {
window.Stream = client.createStream();
if (!navigator.getUserMedia)
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia;
if (navigator.getUserMedia) {
navigator.getUserMedia({audio:true}, success, function(e) {
alert('Error capturing audio.');
});
} else alert('getUserMedia not supported in this browser.');
var recording = false;
window.startRecording = function() {
recording = true;
}
window.stopRecording = function() {
recording = false;
window.Stream.end();
}
function success(e) {
audioContext = window.AudioContext || window.webkitAudioContext;
context = new audioContext();
// the sample rate is in context.sampleRate
audioInput = context.createMediaStreamSource(e);
var bufferSize = 2048;
recorder = context.createScriptProcessor(bufferSize, 1, 1);
recorder.onaudioprocess = function(e){
if(!recording) return;
console.log ('recording');
var left = e.inputBuffer.getChannelData(0);
window.Stream.write(left); //trying it with float32
}
audioInput.connect(recorder)
recorder.connect(context.destination);
}
function convertoFloat32ToInt16(buffer) {
var l = buffer.length;
var buf = new Int16Array(l)
while (l--) {
buf[l] = buffer[l]*0xFFFF; //convert to 16 bit
}
return buf.buffer
}
});
})(this);
这是节点应用程序
var express = require('express');
var BinaryServer = require('binaryjs').BinaryServer;
var fs = require('fs');
var lame = require("lame");
var path = require('path');
var KalmanFilter = require('kalmanjs').default;
var buffer = [];
var port = 3700;
var outFile = 'demo.mp3';
var app = express();
app.set('views', __dirname + '/tpl');
app.set('view engine', 'jade');
app.engine('jade', require('jade').__express);
app.use(express.static(__dirname + '/public'))
app.get('/', function(req, res){
res.render('index');
});
app.listen(port);
console.log('server open on port ' + port);
binaryServer = BinaryServer({port: 9001});
binaryServer.on('connection', function(client) {
console.log('new connection');
client.on('stream', function(stream, meta) {
console.log('new stream');
stream.pipe(new lame.Encoder({channels:2, bitDepth: 32, float:true}))
.pipe(fs.createWriteStream(path.resolve(__dirname, 'demo.mp3')))
.on('close',function () {
console.log('done?');
})
stream.on('end', function() {
console.log('wrote to file ' + outFile);
});
});
});
除 mp3 部分外,这两个片段均取自https://github.com/gabrielpoca/browser-pcm-stream 。