android-如何在播放前在videoview中设置预览图像
我在活动中创建了VideoView,下面是代码。
VideoView vvVideos = (VideoView) rootView.findViewById(R.id.videoView);
MediaController mediacontroller = new MediaController(ctx);
mediacontroller.setAnchorView(vvVideos);
Uri video = Uri.parse(“android.resource://” + packageName +”/”+R.raw.sample);
vvVideos.setMediaController(mediacontroller);
LayoutParams params=vvVideos.getLayoutParams();
params.height=150;
vvVideos.setLayoutParams(params);
vvVideos.setVideoURI(video);
vvVideos.requestFocus();
vvVideos.setOnPreparedListener(new OnPreparedListener() {undefined
public void onPrepared(MediaPlayer mp) {undefined
vvVideos.start();
}
});
现在,在创建活动后,视频便开始播放。 我要进行以下活动
活动开始时不应播放视频。
它应该显示开始的视频图像(当前显示为黑色)
仅当用户单击视频时才播放。
请帮我。
10个解决方案
102 votes
使用.seekTo( 1 )显示第一帧。
确保电影已暂停,然后使用.seekTo( 1 )来显示视频的第一帧:
VideoView mVideoView = (VideoView) findViewById( R.id.video_preview );
mVideoView.setVideoURI( yourVideoPath );
mVideoView.seekTo( 1 ); // 1 millisecond (0.001 s) into the clip.
注意:我们使用.seekTo( 1 ),因为设置.seekTo( 0 )在Android 9上不起作用。
@Lingviston在另一个答案中回答了如何在单击时播放它。
Joshua Pinter answered 2019-11-18T12:35:35Z
27 votes
使用此创建视频缩略图
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(“file path/url”,
MediaStore.Images.Thumbnails.MINI_KIND);
并设置为videoview
BitmapDrawable bitmapDrawable = new BitmapDrawable(thumb);
mVideoView.setBackgroundDrawable(bitmapDrawable);
Shijil answered 2019-11-18T12:36:08Z
9 votes
1)删除您的onPrepareListener。 我不知道为什么您的视频在创建活动后开始播放,但是在videoView.start()之后调用onPrepareListener。
2)在VideoView顶部的布局中添加一个ImageView小部件。 然后像这样设置另一个onPrepareListener:
vvVideos.setOnPreparedListener(new OnPreparedListener() {undefined
public void onPrepared(MediaPlayer mp) {undefined
previewImage.setVisibility(View.GONE);
}
});
我注意到onPreparedListener触发得太早,因此您可以使用
new Handler().postDelay(Runnable, timeInMilis)
关闭预览图像。
3)将带有任何手势检测的OnTouchListener添加到您的VideoView。 这是我现在正在使用的示例:
@Override
public void onCreate(Bundle savedInstanceState) {undefined
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video);
mGestureDetector = new GestureDetector(this, mGestureListener);
((VideoView) findViewById(R.id.activity_video_videoview)).setOnTouchListener(mTouchListener);
}
private OnTouchListener mTouchListener = new OnTouchListener() {undefined
@Override
public boolean onTouch(View v, MotionEvent event) {undefined
mGestureDetector.onTouchEvent(event);
return true;
}
};
private SimpleOnGestureListener mGestureListener = new SimpleOnGestureListener() {undefined
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {undefined
if(mVideoView.isPlaying())
mVideoView.pause();
else
mVideoView.start();
return true;
};
};
点击开始/停止播放。
Lingviston answered 2019-11-18T12:37:17Z
7 votes
只是将视频搜索到100毫秒,它会使用seekTo()方法显示缩略图
videoView.seekTo(100);
Sai Gopi N answered 2019-11-18T12:37:43Z
5 votes
您可以使用build.gradle来完成。它将获取视频的第一帧,并在ImageView中显示
添加到您的build.gradle
implementation ‘com.github.bumptech.glide:glide:4.x.x’
在你班上
GlideApp.with(context)
.load(“your video URL”)
.into(videoImageView);;
N.Droid answered 2019-11-18T12:38:28Z
3 votes
以为我会分享我的解决方案。 seekTo方法效果很好,但仅适用于某些设备。 这是我的工作。 我在onPreparedListener的onPrepared方法中处理此问题,但这取决于您。
@Override
public void onPrepared(MediaPlayer mp) {undefined
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(uri.getPath());
try {undefined
Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime(currentPosition);
videoView.setBackgroundDrawable(new BitmapDrawable(bitmap));
} catch (OutOfMemoryError outOfMemoryError) {undefined
//Not entirely sure if this will ever be thrown but better safe than sorry.
videoView.seekTo(currentPosition);
}
}
现在,当您播放视频时,您将需要删除该背景图片,如下所示:
private void play() {undefined
…
videoView.setBackgroundDrawable(null);
..
}
请享用!
DroidT answered 2019-11-18T12:39:06Z
2 votes
我知道这是一个老问题,但是我需要相同的解决方案,在其他任何地方都找不到答案,所以我做了解决方案,在这里分享我的爱:
我为此创建了一个小类:
public class LoadFirstVideoFrame implements Runnable {undefined
private static Handler uiHandler = new Handler(Looper.getMainLooper());
private VideoView videoView;
private LoadFirstVideoFrame(VideoView videoView) {undefined
this.videoView = videoView;
videoView.start();
videoView.resume();
uiHandler.post(this);
}
public void stop() {undefined
videoView = null;
uiHandler.removeCallbacks(this);
}
@Override public void run() {undefined
if (videoView == null) return;
if (videoView.isPlaying()) {undefined
videoView.pause();
videoView.seekTo(0);
videoView = null;
} else {undefined
uiHandler.post(this);
}
}
}
它只是要求开始播放,并在实际播放后立即在第一帧上暂停视频(这意味着它已加载文件并且已经在SurfaceView上呈现了该文件)。
这里重要的一点是记住要在此类上调用stop(),以便可以正确清理并且不会内存泄漏。
我希望它有所帮助。
Budius answered 2019-11-18T12:39:56Z
1 votes
我已经为缩略图创建了一个像这样的ImageView
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:background=”@color/white”
android:clickable=”true”
android:focusable=”true”>
android:id=”@+id/video_view”
android:layout_width=”match_parent”
android:layout_height=”220dp”/>
android:id=”@+id/videoView_thumbnail”
android:layout_width=”match_parent”
android:layout_height=”220dp”
android:scaleType=”centerCrop”/>
并以这种方式在Java中添加setOnPreparedListener和setOnCompletionListener
VideoView videoView = (VideoView) view.findViewById(R.id.video_view);
ImageView thumbnailView=(ImageView)view.findViewById(R.id.videoView_thumbnail);
Glide.with(getApplicationContext()).load(your_Image_Path).into(thumbnailView);
//you can add progress dialog here until video is start playing;
mediaController= new MediaController(getContext());
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.setKeepScreenOn(true);
videoView.setVideoPath(your_video_path);
videoView.start(); //call this method for auto playing video
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {undefined
@Override
public void onPrepared(MediaPlayer mediaPlayer) {undefined
thumbnailView.setVisibility(View.GONE);
//you can Hide progress dialog here when video is start playing;
}
});
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {undefined
@Override
public void onCompletion(MediaPlayer mediaPlayer) {undefined
videoView.stopPlayback();
thumbnailView.setVisibility(View.VISIBLE);
}
});
它对我有用,我希望它对所有人有用
Dilip Sonigra answered 2019-11-18T12:40:41Z
0 votes
您可以使用@Joshua Pinter的答案来解决问题。 但我想给您更多建议。 您自己会回答seekTo(100)代替seekTo(1)有效。两种方法都不完美。 这是因为seekTo(1)将获得黑色图像,而seekTo(100)可能会出现异常。
我更喜欢这样:
// calculate the during time of the media
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
long time = mediaPlayer.getDuration();
// use a proper number
mVideoView.seekTo(time/2);
如果您没有后端服务器,可能会更好。 或者,如果您有后端服务器,则可以这种方式尝试。
缩略图是由服务器计算的,客户端只显示后端响应的图像。 当涉及到服务器端时,您可以做很多事情。
哪张照片更好? 如果图片也是黑色的怎么办?
服务器端应该生成它吗? 还是服务器端只缓存媒体图片?
如果您想进一步讨论这两个问题,我们可以在以后讨论。
blackdog answered 2019-11-18T12:41:57Z
-1 votes
要使视频在活动开始时停止播放,只需删除video.start()方法。
David Joel Lukombo answered 2019-11-18T12:42:24Z