web-dev-qa-db-ja.com

オーディオをストリーミングするときのMediaPlayerのバッファリング時間に関する問題

MediaPlayerを使用してHTTP経由でラジオをストリーミングしています。 Lollipopでは、ストリームの開始に約1分かかりますが、これは受け入れられません。キットカットでは約20秒かかります。これはすでに苦痛ですが、現在は使用できなくなりました。

バッファリングに関連するこのコンポーネントには よく知られている問題 があります。バッファリングするバイト数はハーコード化されており、変更できません。

私のコードは本当に標準的です

player.reset();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(streamUrl);
player.prepareAsync();

そして準備ができたら

player.start();

代替案について GStreamer と聞いたことがありますが、Windowsで動作させることができませんでした。

誰かがまともな開始遅延でHTTP経由でラジオをストリーミングするための実用的な解決策を持っているのだろうか。

[〜#〜]編集[〜#〜]

ExoPlayerをテストしましたが、開始時間が15秒と短くなっています。プレーヤーは「準備中」の状態でスタックします(バッファリングではなく、これは後でわかります)。

[〜#〜]編集[〜#〜]

ストリームの形式はAACです

[〜#〜]編集[〜#〜]

テストしました https://code.google.com/p/aacdecoder-Android/ しかし、このライブラリの唯一の問題は、ストリームの一時停止がサポートされていないことです。オンラインストリームの一時停止をサポートすることは、私のアプリケーションの要件です。

10
StackOverflower

ユースケースがGPL/LGPLライセンスと互換性がある場合、VLCはまさに必要なものでなければなりません。 VLCは、わずか1秒の遅延で3Gネットワ​​ーク上のURLからストリーミングできます。

ステップ1:VLCソースコードをダウンロードし、 指示 に従ってコンパイルします。

ステップ2:最も重要なクラスは_org.videolan.vlc.audio.AudioServiceController_で、これはorg.videolan.vlc.gui.MRLPanelFragement.processUri() --> org.videolan.vlc.util.Util.openStream(Context, String) --> AudioServiceController.load(String, boolean)から呼び出されました。 AudioServiceControllerとそのサポートクラス以外の不要なコードをすべて削除して、サイズをスリム化できます

8
Kai

MediaPlayerから ExoPlayer に切り替えることをお勧めします。 ExoPlayerを使用すると、次のようにバッファリングパラメータを設定できます。

public static ExoPlayer newInstance(int rendererCount, int minBufferMs, int minRebufferMs) {
  return new ExoPlayerImpl(rendererCount, minBufferMs, minRebufferMs);
}

minBufferMSは、シークなどのユーザーアクションの後に再生を開始または再開するためにバッファリングする必要があるデータの最小期間を意味します。

minRebufferMsは、プレーヤーが再バッファリングを呼び出した後に再生を再開するためにバッファリングする必要があるデータの最小期間を意味します(つまり、再生の開始やシークなどのユーザーアクションが原因ではなく、バッファの枯渇が原因で発生する再バッファリング)。

デフォルト値はそれぞれ500と5000です。

2
Dekra

ライブラジオストリームにはメディアプレーヤーを使用しないでください。

私は次のライブラリを使用しましたが、うまく機能します: https://code.google.com/p/aacdecoder-Android/

1
Bojan Kseneman

ストリーミングには2種類の遅延があります。は起動遅延であるバッファリング遅延であり、b。配信の遅延です。

メディアプレーヤーの場合、ストリームのバッファリングに1分かかります。したがって、最初に、バッファを埋めるのにかかる時間をどのように短縮できるかを確認する必要があります。 Androidのメディアプレーヤーコードでバッファサイズを設定することが可能かどうかはわかりません。

ただし、AACデコーダーライブラリをAndroid( https://code.google.com/p/aacdecoder-Android/downloads/detail? name = aacdecoder- Android-0.8.Zip)次に、入力バッファーを埋める準備ができています。

Pl。以下のコードスニペットを参照してください。要件に基づいて入力バッファ容量を埋めてから、再生を開始できます。入力バッファ容量を制御できるので、再生を開始するまでの時間遅延を減らすことができます。 Pl。これが役立つかどうかを確認してください。

 /**
 * Sets the audio buffer (AudioTrack) capacity.
 * The capacity can be expressed in time of audio playing of such buffer.
 * For example 1 second buffer capacity is 88100 samples for 44kHz stereo.
 * By setting this the audio will start playing after the audio buffer 
   is    first filled.
 *
 * NOTE: this should be set BEFORE any of the play methods are called.
 *
 * @param audioBufferCapacityMs the capacity of the buffer in milliseconds
 */
  public void setAudioBufferCapacityMs( int audioBufferCapacityMs ) {
    this.audioBufferCapacityMs = audioBufferCapacityMs;
  }
0
shri

私はそれをどのように行うかを投稿し、それが違いをもたらすと思います。リアルタイムのサウンドアイテムではないため(オンラインAPIのmp3ですが、約4〜6 MBです)、変動する可能性がありますが、genimotion VMにロードするのに3〜5秒もかかりません。

私はそれがあなたのコードとほとんど同じであることを知っています。同じ問題を引き起こすURLまたは同様のURLを共有できれば、アプリでテストできます。

runThread(url);//ran on the oncreate.


 private void runThread(final String url) {
    new Thread() {
        public void run() {
            mediaPlayer  = new MediaPlayer();//mediaplayer is a global variable.
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

                try{
                    mediaPlayer.setDataSource(url);

                    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mediaPlayer) {
                            //audio did finish.

                        }
                    });
                    mediaPlayer.prepare(); // might take long! (for buffering, etc)
                    duration = mediaPlayer.getDuration();
                    mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                        @Override
                        public void onPrepared(MediaPlayer mp) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {

                                    //here you should start playing it.
                                }
                            });
                        }
                    });
                }
                catch(Exception e)
                {

                }


            }
    }.start();
}

ジェリービーンズとネクサス4でテスト済み、同様の時間応答。

0
CptEric

ライブラリにいくらか$を費やしても構わないと思っているなら、私はお勧めします Bass 統合できるAPI呼び出しのフルセットと、しっかりしたドキュメントがあります。テストできるシェアウェアのバージョンがあります。

あなたが$を使う気がないならば。言及されたVLC @ Kaiを強くお勧めします。また、将来的には、アプリケーションを拡張してビデオをストリーミングすることもできます。私は以前にAPIを使用して、水族館のライブストリームを実行していました。 @Kaiはあなたに必要なリンクを提供しました。

詳細については、これをチェックしてください リンク

0