JCA*_*era 5 javascript audio node.js
我正在开发一个项目,需要将音频流发送到 Node.js 服务器。我可以使用此功能捕获麦克风声音:
function micCapture(){
'use strict';
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
var constraints = {
audio: true,
video: false
};
var video = document.querySelector('video');
function successCallback(stream) {
window.stream = stream; // stream available to console
if (window.URL) {
video.src = window.webkitURL.createObjectURL(stream);
} else {
video.src = stream;
}
//Send audio stream
//server.send(stream);
}
function errorCallback(error) {
console.log('navigator.getUserMedia error: ', error);
}
navigator.getUserMedia(constraints, successCallback, errorCallback);
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我能够捕获音频并在网站上播放。
现在我想将该音频流发送到 Node.js 服务器,并将其发送回其他客户端。就像语音聊天一样,但我不想使用 WebRTC,因为我需要服务器中的流。我怎样才能实现这个目标?我可以使用 socket.io-stream 来做到这一点吗?在我看到的示例中,他们录制了音频并发送了文件,但我需要“实时”音频。
我最近使用 socket.io 从浏览器到服务器进行了实时音频上传。我将在这里回答,以防其他人需要。
var stream;
var socket = io();
var bufferSize = 1024 * 16;
var audioContext = new AudioContext();
// createScriptProcessor is deprecated. Let me know if anyone find alternative
var processor = audioContext.createScriptProcessor(bufferSize, 1, 1);
processor.connect(audioContext.destination);
navigator.mediaDevices.getUserMedia({ video: false, audio: true }).then(handleMicStream).catch(err => {
console.log('error from getUserMedia', err);
});
Run Code Online (Sandbox Code Playgroud)
handleMicStream当用户接受使用麦克风的权限时将运行。
function handleMicStream(streamObj) {
// keep the context in a global variable
stream = streamObj;
input = audioContext.createMediaStreamSource(stream);
input.connect(processor);
processor.onaudioprocess = e => {
microphoneProcess(e); // receives data from microphone
};
}
function microphoneProcess(e) {
const left = e.inputBuffer.getChannelData(0); // get only one audio channel
const left16 = convertFloat32ToInt16(left); // skip if you don't need this
socket.emit('micBinaryStream', left16); // send to server via web socket
}
// Converts data to BINARY16
function convertFloat32ToInt16(buffer) {
let l = buffer.length;
const buf = new Int16Array(l / 3);
while (l--) {
if (l % 3 === 0) {
buf[l / 3] = buffer[l] * 0xFFFF;
}
}
return buf.buffer;
}
Run Code Online (Sandbox Code Playgroud)
让您的 socket.io 服务器监听micBinaryStream,您应该获取数据。我需要数据作为BINARY16google api 的格式,如果你不需要这个,你可以跳过函数调用convertFloat32ToInt16()。
当您需要停止监听时,您必须断开处理器并结束流。运行下面的函数closeAll()。
function closeAll() {
const tracks = stream ? stream.getTracks() : null;
const track = tracks ? tracks[0] : null;
if (track) {
track.stop();
}
if (processor) {
if (input) {
try {
input.disconnect(processor);
} catch (error) {
console.warn('Attempt to disconnect input failed.');
}
}
processor.disconnect(audioContext.destination);
}
if (audioContext) {
audioContext.close().then(() => {
input = null;
processor = null;
audioContext = null;
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5201 次 |
| 最近记录: |