リモートサーバーからオーディオを再生するアプリケーションを作成しています。私はストリーミングオーディオを実装するいくつかの方法を試しましたが、それらはすべて私にとって十分ではありません。オーディオストリーミングのベストプラクティス
ナイーブMediaPlayerの
のような何か使用して:私が試したものだ リモートプレイするとき
MediaPlayer player = new MediaPlayer();
player.setDataSource(context, Uri.parse("http://whatever.com/track.mp3"));
player.prepare();
player.start();
(またはprepareAsync
、関係なく)
しかし、標準MediaPlayer
は非常に不安定であり、コンテンツ。それは頻繁に落ちるか再生を停止し、私はこれを処理することができません。一方、私はメディアキャッシングを実装したいと思います。しかし、MediaPlayerからバッファされたコンテンツを取得して、デバイスのどこかに保存する方法は見つけていません。カスタムバッファリング
を実装
はその後、チャンクでメディアファイルをダウンロードする1つのローカルファイルにそれらを組み合わせて、このファイルを再生するという考えがありました。完全なファイルのダウンロードは、接続不良のために遅くなる可能性があります。最初の部分を十分にダウンロードしてから、再生を開始して、ローカルファイルのダウンロードと追加を続けてください。さらに、我々はキャッシュ機能を得る。
音が計画のようですが、必ずしもうまくいかない場合があります。これはHTC Sensation XEで完全に機能しますが、この最初の部分を終えた後は4.1タブレットの再生を停止しませんでした。わからない、なぜそうだ。私はこのことについてquestionに尋ねましたが、回答はありませんでした。 2 MediaPlayers
私は2つのMediaPlayerのインスタンスを作成し、それらがお互いを変更するために試してみたを使用し
。ロジックは以下の通りです:
- スタート それがダウンロードされ
- 、currentMediaPlayerを経由して再生を開始メディアの初期作品をダウンロードします。メディアの残り(これは再生中に添付されたように)、同じソースファイルとcurrentMediaPlayerの仕上げ前
- 261ミリ秒secondaryMediaPlayerを調製 ダウンロード片がほぼ再生さ
- (仕上げ前に1秒)をダウンロード を継続 - それを一時停止しますセカンダリを開始し、現在のセカンダリとして設定し、次のセカンダリプレーヤーの準備をスケジュールする。
ソース:
private static final String FILE_NAME="local.mp3";
private static final String URL = ...;
private static final long FILE_SIZE = 7084032;
private static final long PREPARE_NEXT_PLAYER_OFFSET = 1000;
private static final int START_NEXT_OFFSET = 261;
private static final int INIT_PERCENTAGE = 3;
private MediaPlayer mPlayer;
private MediaPlayer mSecondaryPlayer;
private Handler mHandler = new Handler();
public void startDownload() {
mDownloader = new Mp3Downloader(FILE_NAME, URL, getExternalCacheDir());
mDownloader.setDownloadListener(mInitDownloadListener);
mDownloader.startDownload();
}
private Mp3Downloader.DownloadListener mInitDownloadListener = new Mp3Downloader.DownloadListener() {
public void onDownloaded(long bytes) {
int percentage = Math.round(bytes * 100f/FILE_SIZE);
// Start playback when appropriate piece of media downloaded
if (percentage >= INIT_PERCENTAGE) {
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(mDownloader.getDownloadingFile().getAbsolutePath());
mPlayer.prepare();
mPlayer.start();
mHandler.postDelayed(prepareSecondaryPlayerRunnable, mPlayer.getDuration() - PREPARE_NEXT_PLAYER_OFFSET);
mHandler.postDelayed(startNextPlayerRunnable, mPlayer.getDuration() - START_NEXT_OFFSET);
} catch (IOException e) {
Log.e(e);
}
mDownloader.setDownloadListener(null);
}
}
};
// Starting to prepare secondary MediaPlayer
private Runnable prepareSecondaryPlayerRunnable = new Runnable() {
public void run() {
mSecondaryPlayer = new MediaPlayer();
try {
mSecondaryPlayer.setDataSource(mDownloader.getDownloadingFile().getAbsolutePath());
mSecondaryPlayer.prepare();
mSecondaryPlayer.seekTo(mPlayer.getDuration() - START_NEXT_OFFSET);
} catch (IOException e) {
Log.e(e);
}
}
};
// Starting secondary MediaPlayer playback, scheduling creating next MediaPlayer
private Runnable startNextPlayerRunnable = new Runnable() {
public void run() {
mSecondaryPlayer.start();
mHandler.postDelayed(prepareSecondaryPlayerRunnable, mSecondaryPlayer.getDuration() - mPlayer.getCurrentPosition() - PREPARE_NEXT_PLAYER_OFFSET);
mHandler.postDelayed(startNextPlayerRunnable, mSecondaryPlayer.getDuration() - mPlayer.getCurrentPosition() - START_NEXT_OFFSET);
mPlayer.pause();
mPlayer.release();
mPlayer = mSecondaryPlayer;
}
};
再び - 音、計画のような、しかし完全ではないに動作します。 MediaPlayersの切り替えの瞬間はかなり聞くことができます。ここで私は反対の状況があります:4.1タブレットでは大丈夫ですが、HTC Sensationには明らかな遅れがあります。
私もさまざまなダウンロード手法を実装しようとしました。私は10KbのチャンクとMP3フレームでダウンロードを実装しました。私は正確には分かりませんが、それはMP3フレームseekToの場合には、より良い作業を開始するようです。しかしそれはただの感情です、私は説明を知らない。
StreamingMediaPlayer
私はグーグルながら、この言葉に数回を見て、この実装を見つけました:https://code.google.com/p/mynpr/source/browse/trunk/mynpr/src/com/webeclubbin/mynpr/StreamingMediaPlayer.java?r=18
それは、誰もが使いソリューションですか?
はいの場合、それは私にとってもうまくいかないので悲しいです。私は実装に新鮮なアイデアは見当たりません。
だから、質問
はどのようにあなたたちは、あなたのアプリケーションでオーディオストリーミングを実装していますか?私は信じていない私はこのような問題に直面した唯一の人です。いくつかの良い習慣があるはずです。
非常に良い質問...また、過去2週間私を悩ましています...しかし、私は1つのデバイスから別のデバイスへのビデオストリーミングのために必要... –
オーディオストリーミングのためにあなたはAndroidサービス –
大きな質問...残念ながら、AndroidのMediaPlayerはこれまでに書かれたソフトウェアの中で最悪のものです。 – StackOverflowed