2016-07-02 13 views
0

nodejsサーバーからリアルタイムで複数のhtmlクライアントにオーディオをストリーミングしようとすると、複数の問題が発生する。以下のコードでは、bufferArrayに2つのmp3ファイルをロードし、クライアントが接続したらbufferArrayからデキューした後、16384バイト/秒〜128kbits /秒でスロットルしてクライアントに書き込みます。しかし、私は、 のバッファがかなり早く空になったと感じています。私のアプローチは正しいのですか?基本的には、すべてのクライアントが曲の同じ部分を再生する必要があることを確認する必要があります。そしてまず第一に、私のクライアントの誰もその曲を演奏することができない、それは別の問題です。ストリームオーディオnodejsからhtml5オーディオタグ

ご協力いただければ幸いです。

var http = require('http'); 
var fs = require("fs"); 
var url = require('url'); 
var stream = require('stream'); 
var Throttle = require('throttle'); 
var bufferArray = []; 
var clients = []; 
var entry = true; 
setInterval(function() { 
    if(bufferArray.length > 0 && clients.length > 0){ 
    entry = false; 
    var buffer = bufferArray.shift(); 
    var bufferStream = new stream.PassThrough(); 
    var throttledStream = new stream.PassThrough(); 
    var throttle = new Throttle(16384); 
    bufferStream.end(new Buffer(buffer)); 
    bufferStream.pipe(throttle).pipe(throttledStream); 
    throttledStream.on('data',function(data){ 
     console.log("Going to write to all the clients "+clients.length); 
     for(var i = 0; i < clients.length; i++){ 
      clients[i].write(data); 
     } 
    }); 
    throttledStream.on('end',function(){ 
     console.log("finished the buffer. Still have to write tot "+bufferArray.length+" buffers"); 
     entry = true; 
    }); 
    } 
},1); 
function readMp3FilesInBuffer(songName,callback){ 
    var fd = fs.createReadStream("./songs/"+songName); 
    fd.on('data',function(chunk){ 
     bufferArray.push(chunk); 
    }); 
    fd.on('end',callback); 
} 

readMp3FilesInBuffer("FeelOfLove.mp3",function(){ 
    readMp3FilesInBuffer("ILoveAfrica.mp3",function() { 
    console.log("successfully read the songs.."); 
    http.createServer(function (request, response) { 
     var parsedUrl = url.parse(request.url,true); 
     var requestType = parsedUrl.query.requestType; 
     if(requestType == "renderHtml"){ 
     console.log("got a request to render html"); 
     response.writeHead(200, { 
      'Content-Type': 'text/html' 
     }); 
     var htmlStream = fs.createReadStream("./views/audioStreaming.html"); 
     htmlStream.pipe(response); 
     } 
     else if (requestType === "stream") { 
     response.writeHead(200,{ 
      "Content-Type": "audio/mpeg", 
      'Transfer-Encoding': 'chunked' 
     }); 
     clients.push(response); 
     console.log("got a request to stream. Tot clients available : "+clients.length); 
     } 
     else{ 
     response.end(); 
     } 
    }).listen(8081,function() { 
     console.log("listening"); 
    }); 

    }); 
}); 

答えて

1

あり、ここでのコードのかなりのだ、との情報が不足しているかなりの...しかし、それはあなたの特定の問題の源であるかもしれない指摘する価値はかなりの数のものもあります。

あなたはクライアントが再生できないと述べました。彼らはあなたのストリームを使用するために正しいルートで終わっていますか?彼らは正しいヘッダーとデータを取得していますか?そうでない場合は、最初に修正します。

ストリーミングメディアオーディオプレーヤーの約3分の1だけが実際にチャンクエンコーディングを正しく処理します。あなたがブラウザに入っている(実際にはWebページ上にある)場合、通常は大丈夫ですが、その外では、チャンクエンコーディングは非スターターです。 Node.jsにチャンクエンコーディングをスキップさせる必要があります。

使用しているスロットルモジュールを指定していません。それはTooTallNateさんですか?もしそうなら、私は過去にそのモジュールに問題がありました。最近更新されておらず、現代のNode.js "streams3"でうまくいきません。

いずれにしても、スロットリングを行う方法は適切ではありません。あなたの平均ビットレートは128kかもしれませんが、必ずしも正確に128kになるとは限りません。あなたはビットレートを仮定すべきではありません。 MP3フレームヘッダーを読み込んでそれに応じて同期する独自のコードを書くこともできますが、他の場所で既に行われているときにはなぜそうするのでしょうか? FFmpegを子プロセスとして起動し、それをリアルタイムで実行させます。未テストが、このような何か:

ffmpeg -re -i yourfile.mp3 -map_metadata -1 -acodec copy -f mp3 - 

実際のメディアに基づいて、スロットリングに加えて、これは与えて、iTunesのようなソフトウェアは、MP3に埋め込むのが好きなことをすべてランダムID3タグを削除することの利点およびその他のランダムながらくたを持っていますごくわずかなオーバーヘッドで、きれいなストリームが得られます。

次の問題は、クライアントがバッファリングして再生を開始するのに時間がかかることです。接続直後に大量のバッファをフラッシュして問題を解決する準備ができました。

多くのブラウザ(Chromeなど)は、他のMP3ファイルと同様にストリームを扱うために範囲要求を行います。あなたがやっているような範囲リクエストを単に無視すれば、すべて正常に動作します。あなたは何をしているのかに基づいてそれらを扱うことを検討するかもしれません。

この作業を終えると、多くのリスナーがストリームを利用できるようにするために、多くの作業が必要になります。アイスキャストのように、ストリームがすでにこれを行う何かに役立つことをお勧めしますか? Node.jsでストリームをソースすることができ、ストリームのソースの周りに必要なアプリケーションロジックを結びつけることができます。自己宣伝のビット...私はIcecastに接続するためにあなたにライセンスすることができるいくつかのNode.jsコードを持っています。また、Node.jsアプリから直接ストリームできるCDNもあります。あなたはhttps://audiopump.coでそれを調べるか、[email protected]に私に電子メールを送ってください。あなたがそれをすべて自分でやろうと決心したとしても、Node.jsアプリからストリームを取得し、他のものから提供することを検討してください。

+0

返信用のHey tnx。私は、提案したように、fmpegを使用するnpmモジュールhttps://github.com/fluent-ffmpeg/node-fluent-ffmpegを使用して、出力mp3ファイルのビットレートを128kbpsに設定することができました。しかし、私の2番目の質問は、ライブストリーミングアプリをやろうとしていることです。予備のステップとして、私はちょうど2つのmp3ファイルで試してみたかった。私はまた、異なる時点でサーバに接続していた2人のクライアント(一般的にはブラウザ)が、両方のクライアントが同じ曲を再生するように同期させる必要があることを確認したかったのです。どのように私はこのシナリオに近づくだろう。どんな入力も素晴らしいでしょう。 –

+0

ADTS付きMP3およびAACは、任意にセグメント化することができます。これは、同時にデータをブラウザに送信できることを意味し、それらは自動的に同期します。これは、サーバーがデータの流れを知り、気にする必要がないため、非常に便利です。バッファリングしてそのままクライアントに送信してください。理想的には、既存のサーバーを使用し、そのサーバーのソースとしてアプリケーションを使用します。ストリームのソースに必要なコードを書いておけば、すでに利用可能な部品を再開発する時間を大幅に節約することができます。 – Brad

関連する問題