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/