VideoView 和 MediaPlayer seekTo 总是从头开始
VideoView and MediaPlayer seekTo always starts from beginning
我在寻找在 VideoView 中播放的视频并继续播放时遇到了一些问题。
这是我的部分代码:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(MediaPlayer mp) {
Log.d("V", "onSeekComplete1 " + videoView.getCurrentPosition());
videoView.start();
Log.d("V", "onSeekComplete1 " + videoView.getCurrentPosition());
}
});
}
});
videoView.setVideoURI('some local uri');
有时我会使用以下方法暂停视频:
videoView.pause();
点击按钮后我正在寻找特定时间的视频,例如。 10 秒(10 000 毫秒)。
@OnClick(R2.id.ivMove)
void clickMove() {
videoView.seekTo(10000);
}
之后在日志中我看到:
onSeekComplete1 10000
onSeekComplete2 0
所以在调用 videoView.start() 之后,它正在从头开始播放视频!
但是当我在不寻找视频的情况下调用 start() 时(例如,一个按钮调用 pause()
和第二个调用 start()
然后视频正在正确播放 - 从暂停的那一刻开始,而不是从开始。
你能告诉我我做错了什么吗?
尝试 videoView.resume() 而不是 start()
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(MediaPlayer mp) {
Log.d("V", "onSeekComplete1 " + videoView.getCurrentPosition());
videoView.resume();
Log.d("V", "onSeekComplete1 " + videoView.getCurrentPosition());
}
});
}
});
videoView.setVideoURI('some local uri');
问题是由 MediaPlayer 引起的 - 它正在寻找最接近视频的关键帧,结果发现我的测试视频每隔约 30 秒就有一个关键帧。
我改成ExoPlayer
https://github.com/google/ExoPlayer - 它可以精确定位。
MediaPlayer seekTo 方法有一个新的重载。它有第二个 int 参数,您可以在其中传递一个 SEEK_CLOSEST 常量。根据Google,"This mode is used with seekTo(long, int) to move media position to a frame (not necessarily a key frame) associated with a data source that is located closest to or at the given time."在测试我自己的应用程序时,它解决了API级别> = 26的问题。我不确定[=14之前是否有任何好的选择=] 26级。
试试这个解决方案。它就像魅力....
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(MediaPlayer mp) {
mp.start();
}
});
}
});
我在寻找在 VideoView 中播放的视频并继续播放时遇到了一些问题。
这是我的部分代码:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(MediaPlayer mp) {
Log.d("V", "onSeekComplete1 " + videoView.getCurrentPosition());
videoView.start();
Log.d("V", "onSeekComplete1 " + videoView.getCurrentPosition());
}
});
}
});
videoView.setVideoURI('some local uri');
有时我会使用以下方法暂停视频:
videoView.pause();
点击按钮后我正在寻找特定时间的视频,例如。 10 秒(10 000 毫秒)。
@OnClick(R2.id.ivMove)
void clickMove() {
videoView.seekTo(10000);
}
之后在日志中我看到:
onSeekComplete1 10000
onSeekComplete2 0
所以在调用 videoView.start() 之后,它正在从头开始播放视频!
但是当我在不寻找视频的情况下调用 start() 时(例如,一个按钮调用 pause()
和第二个调用 start()
然后视频正在正确播放 - 从暂停的那一刻开始,而不是从开始。
你能告诉我我做错了什么吗?
尝试 videoView.resume() 而不是 start()
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(MediaPlayer mp) {
Log.d("V", "onSeekComplete1 " + videoView.getCurrentPosition());
videoView.resume();
Log.d("V", "onSeekComplete1 " + videoView.getCurrentPosition());
}
});
}
});
videoView.setVideoURI('some local uri');
问题是由 MediaPlayer 引起的 - 它正在寻找最接近视频的关键帧,结果发现我的测试视频每隔约 30 秒就有一个关键帧。
我改成ExoPlayer
https://github.com/google/ExoPlayer - 它可以精确定位。
MediaPlayer seekTo 方法有一个新的重载。它有第二个 int 参数,您可以在其中传递一个 SEEK_CLOSEST 常量。根据Google,"This mode is used with seekTo(long, int) to move media position to a frame (not necessarily a key frame) associated with a data source that is located closest to or at the given time."在测试我自己的应用程序时,它解决了API级别> = 26的问题。我不确定[=14之前是否有任何好的选择=] 26级。
试试这个解决方案。它就像魅力....
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(MediaPlayer mp) {
mp.start();
}
});
}
});