我希望从浏览器中获取音频输入并将其流传输到多个侦听器。预期用途是用于音乐,因此质量必须是mp3标准或左右。
我已经尝试了两种方法,均未取得成功的结果:
WebRTC
Websockets
问题是从浏览器到服务器的传输。事实证明,我可以通过以下方法获取的PCM音频数据太大,无法通过websocket重复流到服务器。该流在高速Internet环境中完美运行,但在较慢的wifi上则无法使用。
var context = new webkitAudioContext()
navigator.webkitGetUserMedia({audio:true}, gotStream)
function gotStream (stream)
{
var source = context.createMediaStreamSource(stream)
var proc = context.createScriptProcessor(2048, 2, 2)
source.connect(proc)
proc.connect(context.destination)
proc.onaudioprocess = function(event)
{
var audio_data = event.inputBuffer.getChannelData(0)|| new Float32Array(2048)
console.log(audio_data)
// send audio_data to server
}
}
所以主要问题是,是否有任何压缩PCM数据的方法,以便使其更易于流传输到服务器?也许有更简单的方法可以解决此问题?
当然,有很多压缩PCM数据的方法,但是最好的选择是让WebRTC正常工作。 WebRTC旨在做到这一点-自适应流媒体-尽管您没有定义“多个”侦听器的含义(3个侦听器与300,000个同时侦听器之间存在巨大差异)。
有几种可能的方法来重新采样和/或压缩数据,但是没有一种是本机的。我使用speex.js环境中的xaudio.js lib将数据重新采样到8Khz Mono(您的里程可能有所不同)。您也可以使用speex压缩流,尽管该流通常仅用于音频。在您的情况下,我可能会将流发送到服务器,在那里进行压缩,然后将其发送给您的听众。我真的不相信简单的浏览器足以将数据提供给大量受众。
WebRTC似乎默认为42 kb / s左右的一个单声道,它似乎主要是为语音设计的。
您可以使用约束禁用音频处理功能,以使用以下方式从浏览器获得更一致的输入:
navigator.mediaDevices.getUserMedia({音频:{autoGainControl:否,channelCount:2echoCancellation:否,延迟:0,NoiseSuppression:错误,sampleRate:48000,样本大小:16音量:1.0}});
然后您还应该在SDP上设置stereo
和maxaveragebitrate
参数:
let answer = await peer.conn.createAnswer(offerOptions);
answer.sdp = answer.sdp.replace('useinbandfec=1', 'useinbandfec=1; stereo=1; maxaveragebitrate=510000');
await peer.conn.setLocalDescription(answer);
这应该输出一个看起来像这样的字符串:
a=fmtp:111 minptime=10;useinbandfec=1; stereo=1; maxaveragebitrate=510000
这可以将立体声的比特率提高到520kb / s,即每个通道260kps。实际比特率取决于网络速度和信号强度。