在mediaPlayer上加载新媒体时出错

时间:2013-10-25 02:10:27

标签: android android-mediaplayer

我一直坚持这个问题很长一段时间了。在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()上工作正常但是超级滞后。

2 个答案:

答案 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你已经完成了...希望这有助于某人。