web-dev-qa-db-ja.com

Android MediaPlayerへのストリーミング

アプリで軽量のHTTPサーバーをfeed動的に生成されたMP3データに組み込みのAndroidMediaPlayer。コンテンツをSD cardに保存することは許可されていません。

私の入力データは本質的に無限の長さです。 MediaPlayerに、そのデータソースは基本的に"http://localhost/myfile.mp3"のようなものでなければならないと言います。 MediaPlayerがこのリクエストを行うのを待つ簡単なサーバーをセットアップしました。ただし、MediaPlayerはあまり協力的ではありません。最初に、それはHTTP GETを作成し、ファイル全体を取得しようとします。データをsocketに単純にダンプしようとするとタイムアウトになるため、HTTPRangeヘッダーを使用してデータをチャンクに書き込んでみました。 MediaPlayerはこれが気に入らず、後続のチャンクを要求し続けません。

誰かがデータをMediaPlayerに直接ストリーミングすることに成功した人はいますか?代わりにRTSPまたはShoutcastサーバーを実装する必要がありますか?重要なHTTP headerがないだけですか?ここではどのような戦略を使用する必要がありますか?

23

HTTPサーバーは実際に電話自体でホストされていました。非常に単純でした。threadHTTP GETリクエストをソケットでリッスンしているだけです。 HTTPリクエストを受け取ると、new socketになり、いくつかのHTTPヘッダーを書き戻し、MP3オーディオデータをsocket。このHTTPサーバーは他に何もしませんでした。

Android Media Playerは、ストリーミング中に音楽を再生していました。オーディオの再生中に再生bufferが空になった場合、Media Playerの動作は非常に悪くなりました。 HTTPサーバーがそのsocketにデータを書き込み続けることを確認することは私にとって非常に重要でした。バイトを小さなチャンク(10 kB)でソケットに移動しました。 HTTP応答のヘッダーは次のようになりました。

// Build response headers
StringBuilder sb = new StringBuilder();
sb.append( "HTTP/1.1 200 OK\r\n");
sb.append( "Content-Type: audio/mpeg\r\n");
sb.append( "Connection: close\r\n" );
sb.append( "Accept-Ranges: bytes\r\n" );
sb.append( "Content-Length: " + totalFileSize + "\r\n" );
sb.append( "Content-Disposition: inline; filename=xxxxx.mp3\r\n\r\n");

私がパイプを刺激し続けている限り、Android Media Playerは文句なしにそれを消費し続けました。オーディオの再生には、1つの要求と応答のみが必要でした。それはかなりうまく機能することになった。

4
Robert Harvey