Android 流媒体音频时MediaPlayer缓冲时间问题

Android 流媒体音频时MediaPlayer缓冲时间问题,android,android-mediaplayer,Android,Android Mediaplayer,我正在使用MediaPlayer通过HTTP传输广播。在棒棒糖上,我的流大约需要一分钟才能开始,这是不可接受的。在Kitkat上大约需要20秒,这已经是一种痛苦,但现在变得无法使用 这个组件有一个与缓冲相关的问题:缓冲区的字节数是经过harcoded的,不能更改 我的代码非常标准 player.reset(); player.setAudioStreamType(AudioManager.STREAM_MUSIC); player.setDataSource(streamUrl); player

我正在使用
MediaPlayer
通过HTTP传输广播。在棒棒糖上,我的流大约需要一分钟才能开始,这是不可接受的。在Kitkat上大约需要20秒,这已经是一种痛苦,但现在变得无法使用

这个组件有一个与缓冲相关的问题:缓冲区的字节数是经过harcoded的,不能更改

我的代码非常标准

player.reset();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(streamUrl);
player.prepareAsync();
我也准备好了

player.start();
我也听说过其他选择,但我无法让它在Windows上工作

我想知道是否有人有一个可行的解决方案,可以在HTTP上传输无线电,并且具有良好的启动延迟

编辑


我测试了ExoPlayer,但较低的启动时间是15秒。播放器被卡在“准备”状态(不是缓冲,我看到的是稍后的情况)

编辑

流的格式是AAC

编辑


我进行了测试,但该库唯一的问题是缺少对流暂停的支持。我的应用程序要求支持在线流暂停。

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

public static ExoPlayer newInstance(int rendererCount, int minBufferMs, int minRebufferMs) {
  return new ExoPlayerImpl(rendererCount, minBufferMs, minRebufferMs);
}
minBufferMS是指在用户操作(如搜索)后开始或恢复播放时必须缓冲的数据的最短持续时间

MinRebuffers是指在播放器调用rebuffer(即,由于缓冲区耗尽而不是由于开始播放或搜索等用户操作而发生的Rebuffers)后,必须缓冲以恢复播放的数据的最短持续时间


默认值分别为500和5000。

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

第1步: 下载VLC源代码并按照

第二步:
最重要的类是
org.videolan.vlc.audio.AudioServiceController
,它是从
org.videolan.vlc.gui.MRLPanelFragement.processUri()-->org.videolan.vlc.util.util.openStream(Context,String)-->AudioServiceController.load(String,boolean)
调用的。您可以删除除AudioServiceController及其支持类以外的所有不必要的代码,以缩小大小

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


我使用了以下库,效果非常好:

流媒体a中有两种延迟。是缓冲延迟,即启动延迟和b。是广播延迟

对于媒体播放器,缓冲流需要1分钟。因此,我们首先需要了解如何减少填充缓冲区所需的时间。我不确定在Android的媒体播放器代码中是否可以配置缓冲区大小

然而,如果我们尝试使用android的AAC解码器库(android-0.8.zip),那么我们就有了填充输入缓冲区的规定

请参阅下面的代码片段,您可以根据自己的要求填充输入缓冲区容量,然后开始播放。由于我们可以控制输入缓冲区的容量,我们可以尝试减少开始播放的时间延迟。检查一下这是否对你有帮助

 /**
 * 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;
  }

我将发布我是如何做到这一点的,并指出这会带来不同。它不是一个实时声音项目(它是一个来自在线api的mp3,但它大约有4-6mb),所以它可能会有所不同,但在我的genimotion虚拟机上加载不到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();
}

使用jelly bean在nexus 4上进行测试,时间响应类似。

如果您愿意花一些美元购买一个库,我建议它有一套完整的API调用,您可以集成,并且有一个可靠的文档。有一个共享软件版本,你可以测试

如果你不愿意花美元。我强烈推荐上面提到的VLC@Kai,将来你也可以用它扩展你的应用程序来流视频。我之前使用API为我的水族馆进行了现场直播@Kai为您提供了必要的链接


查看此文件了解更多信息。

您是否有显示缓冲设置的完整示例?我记得几个月前我测试了ExoPlayer,但我找不到在这个话题上取得任何进展的方法。不过我可能看不到。这是ExoPlayer的一个演示应用程序,你可以很容易地测试缓冲状态。谢谢,我会测试的。在任何情况下,我希望你有任何权威的来源,说明ExoPlayer解决了这个问题。我在google play上关注这个问题,但从来没有人提到过ExoPlayer。不过我会发现:)通过“我在google play上关注这个问题”我的意思是“我在google代码上关注这个问题”(我在上面粘贴了一个链接),我测试了ExoPlayer,但我得到的较低的开始时间是15秒。播放器被卡在“准备”状态(不是缓冲,我看到的是稍后的情况)。我想说,这就是为什么我在几个月前测试这款播放器时没有改进它的原因:到那时,与我所拥有的相比,它没有任何改进。您的流使用什么比特率?e、 g.32 kbps 64 kbps等@Simas:它使用32 kbps。我知道这会随着比特率的提高而提高,但这似乎不是一个真正的解决方案。你在播放什么格式的音频,AAC?@BojanKseneman:是的,AAC。网络api是一个选项吗?“你应该避免直播广播流的媒体播放器”——只是出于好奇:为什么?是否有关于此的文档/文章/其他内容?我们注意到很多设备上的media player存在问题。这些问题可能与编解码器有关,但在这些设备上使用上述库似乎是可行的。Bojan在acc decoderOf课程中有一种配置输入缓冲区大小的方法。有两种方法aacPlayer.setAudioBufferCapacityMs(343);aacPlayer.setDecodeBufferCapacityMs(