[英]Android - VideoView, getting current position as video is playing?
我有一個從內部存儲器播放的 VideoView。 當我的視頻正在播放 VideoView 日志MediaPlayer: error (1, -1004)
。 我有一個 onErrorListener 附加到 VideoView 我想從那里管理這個錯誤。 我的目標是獲得最后一個位置(來自getCurrentPosition()
)並使用seekTo(int position)
從該位置再次啟動我的播放器。 我的視頻文件有效(通過在其他播放器上播放驗證)。 我現在的問題是從 VideoView 獲取最后一個有效位置。 當我執行mp.getCurrentPosition / mVideoView.getCurrentPosition()
時,從 onError(MediaPlayer mp, int what, int extra) 調用getCurrentPosition()
返回 0(非常正確)。 如何在播放時跟蹤播放器的當前位置?
這是我的代碼:
mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
switch (what) {
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.v("error", "media error unknown");
mediaErrorExtra(mp, extra, path);
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.v("error", "media error server died");
mediaErrorExtra(mp, extra, path);
break;
}
return true;
}
});
private void mediaErrorExtra(MediaPlayer mp, int extra, String path){
switch(extra){
case MediaPlayer.MEDIA_ERROR_IO:
if(!mp.isPlaying()){
Integer currentposition = mVideoView.getCurrentPosition();
if(currentposition != null){
Log.v("currentpos",Integer.toString(currentposition));
}
mVideoView.setVideoPath(path);
mVideoView.start();
//mVideoView.seekTo(currentposition);
}
break;
case MediaPlayer.MEDIA_ERROR_MALFORMED:
Log.v("error extra","media error malformed");
break;
case MediaPlayer.MEDIA_ERROR_UNSUPPORTED:
Log.v("error extra","media error unsupported");
break;
case MediaPlayer.MEDIA_ERROR_TIMED_OUT:
Log.v("error extra","media error timed out");
break;
}
}
或者,是否有任何偵聽器在播放時提供播放器的當前位置? 我可以使用while(isPlaying()){int currentposition = mVideoView.getCurrrentPosition()}
但我認為這是一種糟糕的處理方式。 任何建議將不勝感激。 提前致謝。
我展示了我使用的處理程序......
private double currentTime = 0;
private Handler mHandler = new Handler();
//update Seekbar on UI thread
public void updateProgressBar() {
if (mHandler != null) {
mHandler.postDelayedUpdateProgress 100);
}
}
private Runnable UpdateProgress = new Runnable() {
public void run() {
currentTime = mediaPlayer.getCurrentPosition();
txt.setText(String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes((long) startTime),
TimeUnit.MILLISECONDS.toSeconds((long) startTime) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.
toMinutes((long) startTime)))
);
seekbar.setProgress((int)startTime);
myHandler.postDelayed(this, 100);
}
};
你應該使用處理程序..
回答我的問題:
ScheduledExecutorService
幫助解決了這個問題:
以下是我在播放器播放時獲取當前位置的方法:
ScheduledExecutorService mScheduledExecutorService;
int mCurrentposition = 0;
Runnable UpdateCurrentPosition = new Runnable(){
@Override
public void run() {
mCurrentposition = mVideoView.getCurrentPosition();
}
};
@Override
protected void onCreate(){
...
mScheduledExecutorService = new ScheduledExecutor(1);
mScheduledExecutorService.scheduleWithFixedDelay(new Runnable(){
@Override
public void run() {
mVideoView.post(UpdateCurrentPosition);
}
},3000,1000,TimeUnit.MILLISECONDS);
}
您對while
的處理是正確的,但它需要更多的改進,因為 while 可能會完全阻塞 UI。
所以你應該做的是使用一個Handler
,它會每 1 秒觸發一次MediaPlayer
位置的檢查,我認為,1 秒是非常合理的。
我已經使用這種方法為 MediaPlayer 實現了一個自定義的SeekBar
,它工作得很好。
private int time = 0;
private ScheduledExecutorService mScheduledExecutorService;
Runnable getPositionVideo = () -> {
time = binding.videoView.getCurrentPosition();
};
binding.videoView.setOnPreparedListener(mediaPlayer -> {
binding.videoView.seekTo(position);
binding.videoView.start();
mScheduledExecutorService = new ScheduledThreadPoolExecutor(1);
mScheduledExecutorService.scheduleWithFixedDelay(() -> {
runOnUiThread(getPositionVideo);
MediaControllerExitFullScreen.init(video_url, time);
}, 1000, 1000, TimeUnit.MILLISECONDS);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.