【问题标题】:MediaPlayer.prepare is throwing an IllegalStateException when playing m4a fileMediaPlayer.prepare 在播放 m4a 文件时抛出 IllegalStateException
【发布时间】:2013-06-07 00:06:30
【问题描述】:

我有一个使用 MediaPlayer 流式传输的歌曲列表。有些歌曲一直有效,而另一些则一直无效。我看不出这些文件之间有什么区别,而且它们似乎在 iTunes 等中可以正常播放。

当歌曲失败时,它会在 mediaPlayer.prepare() 行上抛出 IllegalStateException。抛出的 IllegalStateException 中没有有用的信息,(detailMessage 为 null,stackState 为 null)

这是我的代码

try {
    mediaPlayer.setDataSource(media.url);
    setPlayerState(PlayerState.PREPARING);
    mediaPlayer.prepare();
} catch (Exception e) {
    e.printStackTrace();
    Log.e(TAG, "bad stream");
}

这是一个不起作用的文件的 URL: skdy.bryceb.dev.mediarain.com/song.m4a

这是一个有效的方法: skdy.bryceb.dev.mediarain.com/song2.m4a

你知道为什么这对某些歌曲有效而对其他歌曲无效吗?

【问题讨论】:

  • 那个 url 是用于导致异常的文件之一吗???如果是这样,请发布一个不会导致问题的网址,我会尝试比较。
  • 这是一个有效的方法:skdy.bryceb.dev.mediarain.com/song2.m4a
  • 嗯,到目前为止我什么都不能告诉你。我可以使用 Winamp 从 url 流式传输这两个文件,也可以直接在我的 PC 上的 Chrome 中流式传输。我下载了两者并在 GraphEdit 中渲染它们,它们都生成相同的图形并且无故障播放。我目前在项目之间,所以会再玩一些 - 如果我找到答案,我会回复你。
  • @MisterSquonk,看起来这可能是一个单独的问题。这两个文件实际上都出现了异常。但是第一个文件也触发了媒体播放器错误侦听器,错误代码为 -38,现在正在调查。

标签: android android-mediaplayer


【解决方案1】:

感谢 MisterSquonk,我相信这种方式会奏效。

在我的特殊情况下,在我的头撞墙一段时间后,我意识到在某些歌曲中,我在播放器状态设置为准备之前就达到了缓冲量。所以我添加了一项检查以确保 MediaPlayer 处于“准备就绪”状态,然后它运行良好:

// Media prepared listener
    mediaPlayer.setOnPreparedListener(
            new MediaPlayer.OnPreparedListener() {
                public void onPrepared(MediaPlayer mp) {
                    setPlayerState(PlayerState.PREPARED);
                }
            });

    // Media buffer listener
    mediaPlayer.setOnBufferingUpdateListener(
            new MediaPlayer.OnBufferingUpdateListener() {
                public void onBufferingUpdate(MediaPlayer mp, int percent) {

                    // Sometimes the song will finish playing before the 100% loaded in has been
                    // dispatched, which result in the song playing again, so check to see if the 
                    // song has completed first
                    if(getPlayerState() == PlayerState.COMPLETED)
                        return;

                    if(getPlayerState() == PlayerState.PAUSED)
                        return;

                    // If the music isn't already playing, and the buffer has been reached
                    if(!mediaPlayer.isPlaying() && percent > PERCENT_BUFFER) {
                        if(getPlayerState() == PlayerState.PREPARED)
                        {
                            mediaPlayer.start();
                            setPlayerState(PlayerState.PLAYING);
                        }
                        //if it isn't prepared, then we'll wait till the next buffering
                        //update
                        return;
                    }
                }
            });

【讨论】:

    【解决方案2】:

    好的,我在一个“沙盒”应用程序/活动中构建了一个最小的 Mediaplayer 实现,我总是保留备用进行测试。

    我可能错了,但如果您通过网络流式传输这些歌曲,则需要在网址前加上 http://。

    我用 Winamp 和 Chrome 逐字(无协议前缀字符串)尝试了 url,它们运行良好,尽管这两个应用程序很可能会使用某种形式的智能来确定如何连接/流式传输。

    如果我在我的 mediaPlayer 代码中尝试这样做,我会得到与您相同的异常,但如果我在 URL 前加上 http:// 前缀,则歌曲播放正常。

    示例...

    // Activity scope
    Button button;
    CheckBox checkBox;
    String url = "";
    
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        //button declared in my activity
        button = (Button)findViewById(R.id.button);
        button.setOnClickListener(this);
    
        if (!checkBox.isChecked())
            url = getString(R.string.url_song1);
        else
            url = getString(R.string.url_song2);
    
        mediaPlayer = new MediaPlayer();
    }
    
    @Override
    public void onClick(View arg0) {
        try {
            Log.i(TAG, "onClick() entered...");
            mediaPlayer.setDataSource(url);
            Log.i(TAG, "Preparing mediaplayer...");
            mediaPlayer.prepare();
            Log.i(TAG, "Starting mediaplayer...");
            mediaPlayer.start();
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "bad stream");
        }       
    }
    

    如果我将歌曲复制到我的 SD 卡,它们都可以正常播放,并且只要 Internet url 字符串具有“http://”前缀,那么它们也可以工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-03
      • 1970-01-01
      • 2012-10-12
      • 1970-01-01
      • 2014-12-15
      • 2016-01-06
      • 1970-01-01
      相关资源
      最近更新 更多