流式传输音频时MediaPlayer缓冲时间问题

时间:2015-04-03 13:06:40

标签: android android-mediaplayer

我正在使用MediaPlayer通过HTTP流式传输广播。在Lollipop上,我的流程需要大约一分钟才能启动,这是不可接受的。 Kitkat需要大约20秒,这已经很痛,但现在变得无法使用。

这个组件有一个well known problem与缓冲有关:缓冲区的字节数是加密的,无法更改。

我的代码非常标准

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/,但这个库唯一的问题是缺乏对流暂停的支持。我的应用程序要求支持在线流的暂停。

6 个答案:

答案 0 :(得分:8)

如果您的用例与GPL / LGPL许可证兼容,那么VLC应该是您所需要的。 VLC能够在3G网络上从您的URL流式传输,延迟时间仅为1秒。

第1步: 下载VLC源代码并根据instruction

进行编译

第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及其支持类之外,您可以删除所有不必要的代码以缩小尺寸

答案 1 :(得分:2)

我可以建议从MediaPlayer切换到ExoPlayer。使用ExoPlayer可以设置缓冲参数如下:

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

minBufferMS 表示必须缓冲的最小数据持续时间,以便在用户操作(如搜索)后开始或恢复播放。

minRebufferMs表示必须缓冲的数据的最小持续时间,以便在播放器调用rebuffer后重放缓存(即由于缓冲区耗尽而不是由于用户操作(如开始播放或搜索)而发生的缓冲区。)< / p>

默认值分别为500和5000.

答案 2 :(得分:1)

您应该避免使用媒体播放器播放实时广播流。

我使用了以下库,效果很好:https://code.google.com/p/aacdecoder-android/

答案 3 :(得分:0)

流式传输有两种延迟。是缓冲延迟,它是启动延迟和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;
  }

答案 4 :(得分:0)

我将发布我是如何做到这一点的并且锄头给出了不同。它不是一个实时声音项目(它是来自在线api的mp3,但它大约是4-6mb)所以它可能会有所不同,但加载我的genimotion虚拟机需要不到3-5秒。

我知道它和你的代码几乎一样。也许如果你可以分享网址或类似问题,我可以在我的应用程序中测试它。

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();
}

在带有果冻豆的nexus 4上进行测试,时间响应相似。

答案 5 :(得分:0)

如果您愿意在图书馆花一些钱,我建议Bass它有一整套可以集成的API调用,还有一个可靠的文档。您可以测试共享软件版本。

如果你不愿意花钱。我强烈推荐VLC @Kai提到,同样在将来您可以扩展您的应用程序以使用它来流式传输视频。之前我曾使用API​​为我的水族馆执行实时流程。 @Kai为您提供了必要的链接。

查看此link了解详情。