MediaPlayer.prepare在播放m4a文件时抛出IllegalStateException

时间:2010-12-15 00:29:01

标签: android android-mediaplayer

我有一个我正在使用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

为什么这对某些歌曲起作用而在其他歌曲上失败的任何想法?

2 个答案:

答案 0 :(得分:2)

谢谢MisterSquonk,我确信这种方式有效。

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

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

答案 1 :(得分:0)

好的,我在一个'沙盒'应用程序/活动中将最小的Mediaplayer实现混在一起我总是保留测试的空间。

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

我尝试使用Winamp和Chrome逐字(没有协议前缀字符串)的网址,虽然很可能这些应用程序都会使用某种形式的智能来确定如何连接/流式传输。

如果我在我的mediaPlayer代码中尝试过,我会得到与你相同的例外情况,但是如果我在网址前加上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卡,两者都可以正常播放,只要互联网网址字符串有一个'http://'前缀,那么它们也能正常工作。