Я обнаружил, что просто сделать VideoView.seekTo(n)
недостаточно на всех устройствах, чтобы показать первый кадр видео.
Если все, что вам нужно, это показать первый кадр, но не воспроизводить видеозатем вы можете просто сделать это, что полезно для отображения миниатюры видео:
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(context, uri);
Bitmap firstFrame = MediaMetadataRetriever.getFrameAtTime(0);
// Set firstFrame bitmap to ImageView...
Однако, чтобы надежно отображать первый кадр в тех случаях, когда вы хотите воспроизвести видео в какой-то момент после рендеринга,Начиная с взаимодействия с пользователем, мое решение состоит в том, чтобы зарегистрировать OnPreparedListener
, а затем вызвать start()
.Я также регистрирую OnInfoListener
, чтобы получать уведомления о начале рендеринга.Затем я проверяю, действительно ли информация является событием «начало рендеринга», и проверяю, впервые ли VideoView
начал рендеринг.Если это так, я pause()
, а затем seekTo(0)
.
Вот как это будет выглядеть:
private void showFirstFrame(final VideoView videoView, Uri uri) {
videoView.setVideoURI(uri);
final AtomicBoolean showedFirstFrame = new AtomicBoolean(false);
videoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
// If this is our first time starting video rendering, pause and show first frame
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START
&& showedFirstFrame.compareAndSet(false, true)) {
videoView.pause();
videoView.seekTo(0);
}
return false;
}
});
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
videoView.start();
}
});
}