0

私はかなり長い間この問題に悩まされてきました。私が作成した mediaPlayer では、最初の再生段階ではすべてがスムーズに実行されますが、ユーザーが次または前のオプションを選択すると、アプリケーション(0,-107) errorattempt 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()が、非常に遅いです。

4

2 に答える 2

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は、メディアが準備されるまで待機します。これはあなたが経験する遅れです。問題は解決しますが (タスクも待機するため)、推奨されません。

于 2013-10-25T09:01:05.730 に答える