5

嘿,我正在使用 MediaPlayer 播放常规的 ShoutCast 流。代码很简单,使用 prepareAsync() 和一个开始播放的处理程序。虽然它与 DI.FM 或 ETN.FM (http://u10.di.fm:80/di_progressive) 等某些流完美配合,但与其他流 (http://mp3.wpsu.org:8000/) 配合使用则不会t 超过准备状态。也没有调用其他侦听器。

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

任何反馈表示赞赏!

4

2 回答 2

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

于 2010-12-11T18:52:43.457 回答
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 或其他相应的值。

于 2011-08-09T09:36:29.233 回答