Android - VideoView,在播放视频时获取当前位置?
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) returns 0 调用 getCurrentPosition()
(非常正确)。如何在播放时跟踪播放器的当前位置?
这是我的代码:
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()}
但我认为这是一种糟糕的处理方式。任何建议将不胜感激。提前致谢。
你在 while
方面走在了正确的轨道上,但它需要更多的改进,因为 while 可能会完全阻止 UI。
所以你应该做的是使用一个Handler
,它会每1秒触发一次检查MediaPlayer
位置,我认为1秒是很合理的。
我已经使用这种方法为 MediaPlayer 实现了自定义 SeekBar
,并且效果很好。
我展示了我使用的处理程序...
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);
}
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);
我有一个 VideoView 可以从内部存储器播放。当我的视频正在播放 VideoView 日志时 MediaPlayer: error (1, -1004)
。我有一个 onErrorListener 附加到 VideoView,我想从那里管理这个错误。我的目标是获得最后一个位置(从 getCurrentPosition()
)并使用 seekTo(int position)
从该位置再次启动我的播放器。我的视频文件是有效的(通过在其他播放器上播放验证)。我现在的问题是从 VideoView 获取最后一个有效位置。当我执行 mp.getCurrentPosition / mVideoView.getCurrentPosition()
时,从 onError(MediaPlayer mp, int what, int extra) returns 0 调用 getCurrentPosition()
(非常正确)。如何在播放时跟踪播放器的当前位置?
这是我的代码:
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()}
但我认为这是一种糟糕的处理方式。任何建议将不胜感激。提前致谢。
你在 while
方面走在了正确的轨道上,但它需要更多的改进,因为 while 可能会完全阻止 UI。
所以你应该做的是使用一个Handler
,它会每1秒触发一次检查MediaPlayer
位置,我认为1秒是很合理的。
我已经使用这种方法为 MediaPlayer 实现了自定义 SeekBar
,并且效果很好。
我展示了我使用的处理程序...
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);
}
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);