2013-10-25 14 views
0

我一直在這個問題上停留了很長一段時間。在媒體播放器我已經創造了萬物運行在初始階段播放流暢,但是當用戶選擇一個或下一個選項,應用程序給了我與attempt to call getDuration without a valid mediaplayer在mediaPlayer上加載新媒體時出錯

代碼沿(0,-107) error

 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()但超級laggy。

回答

1

問題是getDuration在您的新媒體正在準備時正在通過您的updateSeekTask調用。這會出錯。無準備視頻的持續時間是多少?

解決方法是在用戶單擊下一個時取消updateSeekTask的任何回調,並在介質準備就緒後恢復它們。

public void onPrepared(MediaPlayer mp) { 
    mediaPlayer.start(); 
    onPlayerLoaded(); 
    updateProgressBar(); 
} 

還是應該prepareAsync

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作爲目前您重新啓動該任務。如果您只使用prepare,則所有內容都將等待媒體準備就緒。這是你經歷的滯後。它會解決你的問題(因爲即使任務也會等待),但不推薦。

+0

非常感謝你:) –

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(); 
} 

和普雷斯托你完成...希望這可以幫助某人。