我一直坚持这个问题很长一段时间了。在mediaPlayer中,我创建的所有内容都在初始播放阶段顺利运行,但当用户选择下一个或上一个选项时,应用程序会为(0,-107) error
提供attempt to call getDuration without a valid mediaplayer
代码:
public void playPodCast(int index) {
try {
urlToSend = toGet.get(index).get("URL").toString();
mediaPlayer.reset();
mediaPlayer.setDataSource(urlToSend);
mediaPlayer.prepareAsync();
onPlayerLoad();
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnErrorListener(this);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
此处onPlayerLoad()
只是在mediaPlayer加载时隐藏所有视图的方法。
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
onPlayerLoaded();
updateProgressBar();
mediaPlayer.start();
}
onPlayerLoaded()
加载回视图。
public void updateProgressBar() {
seekHandler.postDelayed(updateSeekTime, 100);
}
private Runnable updateSeekTime = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
long totalDuration = mediaPlayer.getDuration();
long currentDuration = mediaPlayer.getCurrentPosition();
// Displaying the total time duration
seekRight.setText("" + utils.milliSecondsToTimer(totalDuration));
// Displaying completed playing time
seekLeft.setText("" + utils.milliSecondsToTimer(currentDuration));
// Updating the SeekBar progress
int progress = (int) (utils.getProgressPercentage(currentDuration,
totalDuration));
seekBar.setProgress(progress);
seekHandler.postDelayed(this, 100);
}
};
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
}
// @Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
seekHandler.removeCallbacks(updateSeekTime);
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
seekHandler.removeCallbacks(updateSeekTime);
int totalDuration = mediaPlayer.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(),
totalDuration);
// forward or backward to certain seconds
mediaPlayer.seekTo(currentPosition);
// update timer progress again
updateProgressBar();
}
此处private Handler seekHandler = new Handler();
就像我之前说的那样,对playPodCast(index)
的初始调用并没有给我任何错误,它的工作非常顺利。但是当用户单击下一个和上一个按钮时,会生成错误。如果在没有updateProgressBar()
的情况下实现,则下一个和上一个方法不会发出任何错误,所有内容都会非常粗略地运行。那我为什么会收到这个错误呢?我不知道为什么......请帮忙。
这是下一个按钮的实现:
btnNext.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (getPosition == totalList - 1) {
getPosition = 0;
playPodCast(getPosition);
} else {
getPosition = getPosition + 1;
playPodCast(getPosition);
}
}
});
其中getPosition
是被引用的媒体文件的位置。
我也尝试了
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
mediaPlayer.start();
onPlayerLoaded();
updateProgressBar();
}
更新1:
我发现使用prepareAsync()
时发生错误,该程序在prepare()
上工作正常但是超级滞后。
答案 0 :(得分:1)
问题是getDuration
在新媒体准备时被updateSeekTask
调用。这会出错。没有准备的视频的持续时间是多少?
解决方案是在用户点击下一步时取消updateSeekTask
的任何回调,并在媒体准备好后恢复它们。
public void onClick(View arg0) {
if (getPosition == totalList - 1) {
getPosition = 0;
seekHandler.removeCallbacks(updateSeekTime); // Cancel me!
playPodCast(getPosition);
} else {
getPosition = getPosition + 1;
seekHandler.removeCallbacks(updateSeekTime); // Cancel me!
playPodCast(getPosition);
}
}
然后在onPrepared
中重新启动当前的任务:
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
onPlayerLoaded();
updateProgressBar();
}
您仍然应该使用prepareAsync
。如果你只使用prepare
,一切都会等到媒体准备好之后。这是您经历的滞后。它将解决您的问题(因为即使任务将等待),但不建议这样做。
答案 1 :(得分:0)
而不是调用以下内容:
int totalDuration = mediaPlayer.getDuration();
Runnable updateSeekTime()
内的使totalDuration
成为一个全局变量,并在onPrepared(MediaPlayer mp)
内引用初始化totalDuration的值,如下所示:
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
onPlayerLoaded();
totalDuration = mp.getDuration() // mp is the MediaPlayer instantiated by this method
updateProgressBar();
mediaPlayer.start();
}
和Presto你已经完成了...希望这有助于某人。