1つのクライアントからサーバー、複数のリスナークライアントへのリアルタイムのライブオーディオストリームが必要です。
現在、クライアントからの録音が機能しており、socket.ioを介してオーディオをサーバーにストリーミングしています。サーバーはこのデータを受信し、このストリームをリッスンするクライアントに(socket.io?を介しても)オーディオをストリーミングする必要があります。できるだけリアルタイムでなければなりません(遅延を最小限に抑えます)。
GetUserMediaを使用してマイクを録音しています(ここでは、ブラウザーの互換性は重要ではありません)。クライアントがHTML5オーディオタグを使用してストリームをリッスンしてほしい。サーバーで受信したデータは、タイプaudio/wavのblobにパックされたチャンク(現在は700でパックされています)です。
これはサーバーに送信するための私のコードです:
mediaRecorder.ondataavailable = function(e) {
this.chunks.Push(e.data);
if (this.chunks.length >= 700)
{
this.sendData(this.chunks);
this.chunks = [];
}
};
mediaRecorder.sendData = function(buffer) {
blob = new Blob(buffer, { 'type' : 'audio/wav' });
socket.emit('voice', blob);
}
サーバーでは、次のようにクライアントにチャンクを送信できます。
socket.on('voice', function(blob) {
socket.broadcast.emit('voice', blob);
});
クライアントでは、次のように再生できます。
var audio = document.createElement('audio');
socket.on('voice', function(arrayBuffer) {
var blob = new Blob([arrayBuffer], { 'type' : 'audio/wav' });
audio.src = window.URL.createObjectURL(blob);
audio.play();
});
これは、私が送信するチャンクの最初のblobに対して機能しますが、新しいURLソースにaudio.srcを変更し続けることは許可されていないため、これは有効なソリューションではありません。
サーバー上で何らかのストリームを作成する必要があると思います。これをリスニングクライアントのHTML5のオーディオタグに挿入できますが、方法がわかりません。チャンクを含む受信したBLOBは、このストリームにリアルタイムで追加する必要があります。
これを行うための最良のアプローチは何ですか?クライアントのマイクからサーバーに直接行っていますか?
ここのパーティーには少し遅れますが、まだ完了していない場合は、WebオーディオAPIがあなたの友達になるようです。オーディオエレメントにアタッチすることで、いじりを行うことなく、オーディオストリームを出力デバイスに直接再生できます。
私は同じことをしているのを見ていて、あなたの質問は私の質問に答えました-クライアントからサーバーにデータを取得する方法。 WebオーディオAPIの利点は、ストリームを一緒に追加して、サーバー上のオーディオエフェクトに適用できることです。
Ioイベントは、オーディオコンテキストのオーディオバッファオブジェクトのデータを置き換える必要があります。オーディオ処理は、各クライアントに単一のストリームとして送信される前に、nodeJS Webオーディオコンテキストで発生する可能性があります。
次のようにaudio
src
を動的に変更できます(mp3タイプを想定):
<audio id="audio" controls="controls">
<source id="mp3Source" type="audio/mp3"></source>
Your browser does not support the audio format.
</audio>
ソケットイベントを受信するたびに次の関数を呼び出します。
function updateSource() {
var audio = document.getElementById('audio');
var source = document.getElementById('mp3Source');
source.src= <blob>;
audio.load(); //call this to just preload the audio without playing
audio.play(); //call this to play the song right away
}