1

ノードサーバーからSoundcloud APIを使用しています。オーディオ トラックを複数のユーザーに同時にストリーミングしたいと考えています。

私はこのようなことを試しました(この質問のコードを使用Node.jsサーバーからHTML5 <audio>タグへのオーディオのストリーミング)が機能しません。どうすればこれを行うことができるかについて何か考えはありますか?

var radio = require("radio-stream");
var http = require('http');
var url = "http://api.soundcloud.com/tracks/79031167/stream?client_id=db10c5086fe237d1718f7a5184f33b51";
var stream = radio.createReadStream(url);

var clients = [];

stream.on("connect", function() {
    console.error("Radio Stream connected!");
    console.error(stream.headers);
});

stream.on("data", function (chunk) {
    if (clients.length > 0){
        for (client in clients){
            clients[client].write(chunk);
        };
    }
});

stream.on("metadata", function(title) {
    console.error(title);
});

var server = http.createServer(function(req, res){
    res.writeHead(200,{
        "Content-Type": "audio/mpeg",
        'Transfer-Encoding': 'chunked'
    });

    clients.push(res);
    console.log('Client connected; streaming');
});
server.listen("8000", "0.0.0.0");

console.log('Server running at http://127.0.0.1:8000'); 
4

1 に答える 1

5

いくつかの問題があります

リダイレクトに従う

radio-streamあなたが使用しているモジュールは 4 年間更新されていません。それは、Node.js API の時代では永遠です。Node.js の現在および将来のバージョンとの互換性の問題は間違いなくあるため、使用しないことをお勧めします。少なくとも、新しいストリーム API を使用すると、これを処理するためのはるかに優れた方法があります。

いずれにせよ、そのモジュールは HTTP リダイレクトに従いません。SoundCloud API が実際のメディア ファイルにリダイレクトしています。

さらに、このradio-streamモジュールは、MP3 ID3 データではなく、SHOUTcast/Icecast スタイルのメタデータを分離するように構築されています。それはあなたを助けません。

必要なのは単純なhttp.get(). その後、自分でリダイレクトに従うか、requestパッケージを使用できます。詳細はこちら: Node.js で HTTP リダイレクトをたどるにはどうすればよいですか?

チャンクエンコーディング

多くのストリーミング クライアントは、チャンク エンコーディングを処理できません。ストリーミング出力がある場合、Node.js は (正しく) それを追加します。ただし、目的のために、無効にしましょう。

res.useChunkedEncodingByDefault = false;

https://stackoverflow.com/a/11589937/362536

コヒーレント ストリームの構築

理論的には、MPEG ストリームの後に MPEG ストリームを追加するだけで、すべて正常に動作します。実際には、これは機能しません。ID3 タグはストリームを破損します。1 つのファイルが他のファイルとは異なるサンプル レートである可能性があり、ほとんどのソフトウェアはハードウェアをその新しいサンプル レートにオンザフライで切り替えることができません。基本的に、やろうとしていることを確実に行うことはできません。

唯一できることは、これらのオーディオ ファイルを再生してストリーム全体を再エンコードし、もう一方の端から安定したストリームを取得することです。これにより、MP3 だけでなく、他のコーデックや形式を処理できるという追加のボーナスが得られます。

コーデックの問題の多くを処理するために、FFmpeg を利用できます。ただし、エンコードのためにこれらのファイルを FFmpeg に再生する方法が必要になります。

レート制限

再生速度でオーディオをストリーミングする必要があります。(初期バッファを送信してクライアントをすばやく開始することはできますが、可能な限り高速にデータをスラミングし続けることはできません。)これを行わないと、サーバーのメモリがすぐに不足してしまいます。クライアントは TCP ウィンドウ サイズを 0 まで下げ、オーディオが十分に追いついてより多くのデータをバッファリングできるようになるまでそこにとどまります。を使用していないためpipe、ストリームはフロー モードであり、サーバー上で無期限にバッファリングされます。さて、これは実際にはいくつかの点で良いことです。これにより、1 つの遅いクライアントが他のクライアントの速度を低下させるのを防ぐことができるからです。ただし、コードが再生速度ではなく、可能な限り高速にストリーミングされているという点で悪いことです。

オーディオを別のエンコーダーで再生する場合は、RTC を数秒かけてクロックとして使用します。完璧である必要はありません。それがクライアント バッファーの目的です。オーディオ デバイスで再生している場合は、もちろん独自のクロックが使用されます。

実際にやるべきこと

あなたは巨大なプロジェクトに出くわしました。代わりにリキッドソープを使用することを強くお勧めします。Node.js から制御する方法があります。そこから、ストリーミングにIcecastなどのサーバーを使用します。

于 2015-01-18T15:03:23.293 に答える