Android MediaPlayer准备时间过长

时间:2010-11-15 01:05:14

标签: android audio-player android-music-player

嘿 我正在使用MediaPlayer播放常规的ShoutCast流。使用prepareAsync()和开始播放的处理程序,代码很简单。虽然它与DI.FM或ETN.FM(http://u10.di.fm:80/di_progressive)等一些流程完美无瑕,但与其他人(http://mp3.wpsu.org:8000/)一起赢得了超过准备状态。也没有其他听众。

//Uri streamUri = Uri.parse("http://u10.di.fm:80/di_progressive"); /* works */
Uri streamUri = Uri.parse("http://mp3.wpsu.org:8000/"); /* stuck on prepare state */
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
    public void onPrepared(MediaPlayer mp) {
        mp.start();
    }
});
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(this.getBaseContext(), streamUri);
mediaPlayer.prepareAsync();

感谢任何反馈!

2 个答案:

答案 0 :(得分:2)

我认为服务器端存在一些兼容性问题。 这是相当奇怪的,因为模拟器在我的情况下处理它 - 只是不在我的Froyo Galaxy S上,即使它是相同的API版本。

这可能是编解码器问题,http流媒体问题,我不知道。 但是所有失败的服务器往往都是旧服务器,底部是“Copyright 1998 - 2004”......不是最近或者最新的服务器。

一个潜在的解决方法(我还没有尝试过)将使用StreamProxy,这也会使您的代码与2.1以及可能的早期版本兼容。额外的工作,额外的代码,毫无疑问是额外的错误......

如果你不知道它,还有另一个2.2的玩家错误报告也可能是相关的: Basic streaming audio works in 2.1 but not in 2.2

答案 1 :(得分:2)

我正面临一个问题,当MP“挂起”准备状态太长(流)并且我试图使用reset()停止它。这导致MP挂起,因此我的整个应用程序冻结。似乎没有办法阻止MP准备状态。我在考虑使用prepare()包装在线程而不是prepareAsync()。然后我将能够杀死那个线程。至于现在,我是按照以下方式做到的:

private void actionCancel(){
            try {
                mp.setDataSource(new String());
            } catch (Exception e) {
                e.printStackTrace();
                android.util.Log.d(TAG,"actionCancel(): mp.setDataSource() exception");
                mp.reset();
            }
}

它工作4me 另外我有一个跟随柜台:

    @Override
    public void onBufferingUpdate(final MediaPlayer mp, final int percent) {

        if (!mp.isPlaying()){
//          android.util.Log.d(TAG,"onBufferingUpdate(): onBufferingUpdateCount = "+onBufferingUpdateCount);
            if (onBufferingUpdateCount>MAX_BUFFERING_UPDATES_AT_PREPARING_STATE)
                restartMP();
            onBufferingUpdateCount++;
            return;
        }
      }

我发现这个听众总是在准备状态时触发。因此,如果它触发超过10次且MP仍未播放,我只是重新启动它:

private void restartMP(){
        if (mp!=null)
            if (mpState==MediaPlayerState.Preparing)
                actionCancel();
            else
                mp.reset();
    else
        mp = new MediaPlayer();
        mpState = MediaPlayerState.Idle;
        onBufferingUpdateCount=0;
        //isRequestCancelled=false;
        requestTrackInfoStartedAt=0;
        requestPlay();
}

注意MediaPlayerState是我的自定义枚举,它具有“准备”值。此外,mpState是一个类属性/字段,它保存当前的MediaPlayerState状态。在启动prepareAsync()之前,我将mpState设置为MediaPlayerState.Preparing,然后将其设置为MediaPlayerState.Started或其他相应的值。