My App允许用户从多个音频流中进行选择,当用户单击其中一个播放按钮时,将调用以下代码:

@Override
public void onClick(View view)
{
    mMediaPlayer.reset();
    mMediaPlayer.setOnCompletionListener(this);
    mMediaPlayer.setOnErrorListener(this);
    mMediaPlayer.setOnBufferingUpdateListener(this);
    try
    {
        mMediaPlayer.setDataSource(mSelected.getUrl());
        mMediaPlayer.prepareAsync();
    }
    catch (Exception e)
    {
        Toast.makeText(mActivity, R.string.error_media, Toast.LENGTH_LONG).show();
    }
}

然后是准备好的听众:
@Override
public void onPrepared(MediaPlayer mp)
{
    mHandler.post(new Runnable()
    {
        @Override
        public void run()
        {
            mPlayer.start();
        }
    });
}

这主要工作,但有时当用户点击其中一个播放按钮,而上一个仍在准备,我得到错误MEDIA_ERROR_IO错误(1,-1004)。查看调试日志,我看到消息callback on disconnected mediaplayer意味着它可能试图调用onprepared,但我认为mediaplayer已经重置。onerror listener被称为:
@Override
public boolean onError(MediaPlayer mp, int what, int extra)
{
    Toast.makeText(this, "error", Toast.LENGTH_SHORT).show();
    return true;
}

有什么办法可以解决这个问题或者取消之前音频的准备工作吗?

最佳答案

好吧,经过几周的处理,我发现你不可能对多个文件使用一个MediaPlayer实例,因为你不能取消一个prepareAsync()操作。如果您在第一个音频文件准备时为了播放第二个音频文件而reset()release(),那么当第一个准备操作尝试回调时,会发现MediaPlayer已断开连接,并出现MEDIA_ERROR_IO错误。
所以我所做的是将一个不同的MediaPlayer实例与我的每个播放按钮关联起来。我还跟踪了每个MediaPlayer实例的状态(reset、preparing或prepared)。代码如下:
myactivity.java

// Listener for every play button
@Override
public void onClick(View view)
{
    for (AudioItem item : mAudioItems)
    {
        if (item.getPlayButton().equals(view))
        {
            mCurrentAudio = item;
        }
        else
        {
            resetAudio(item);
        }
    }

    if (mCurrentAudio.getStatus() == MediaStatus.STOPPED)
    {
        MediaPlayer player = mCurrentAudio.getMediaPlayer();
        try
        {
            player.setDataSource(mCurrentAudio.getUrl());
            mCurrentAudio.setStatus(MediaStatus.PREPARING);
            player.prepareAsync();
        }
        catch (Exception e)
        {
            for (AudioItem item : mAudioItems)
            {
                resetAudio(item);
            }
        }
    }
    else if (mCurrentAudio.getStatus() == MediaStatus.PREPARED)
    {
        // toggle play/pause
    }
}

@Override
public void onPrepared(MediaPlayer mp)
{
    if (!mCurrentAudio.getMediaPlayer().equals(mp))
    {
        for (AudioItem item : mAudioItems)
        {
            if (item.getMediaPlayer().equals(mp))
            {
                item.setStatus(MediaStatus.PREPARED);
                resetAudio(item);
                return;
            }
        }
    }

    mCurrentAudio.setStatus(MediaStatus.PREPARED);

    // play audio
}

public void resetAudio(AudioItem item)
{
    if (item.getStatus() != MediaStatus.PREPARING)
    {
        item.getMediaPlayer().reset();
        item.setStatus(MediaStatus.STOPPED);
    }
}

audioitem.java语言
public class AudioItem
{
    private MediaPlayer mMediaPlayer;
    private ImageButton mPlayButton;
    private String      mUrl;
    private int         mStatus;

    public AudioItem(MediaPlayer player, ImageButton button, String url)
    {
        mMediaPlayer = player;
        mPlayButton = button;
        mUrl = url;
        mStatus = MediaStatus.STOPPED;
    }

    // getters and setters
}

关于android - 重用MediaPlayer时“断开媒体播放器上的回调”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22362056/

10-14 09:50