如何在播放前设置预览图像的视频视图

我在我的活动中创建了一个 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() {
public void onPrepared(MediaPlayer mp) {
vvVideos.start();
}
});

现在,当活动被创建时,视频就开始播放了

  1. 当活动开始时,视频不应该播放。
  2. 它应该显示起始视频图像(当前显示黑色)
  3. 它应该只在用户点击视频时播放。
    请帮帮我。
90846 次浏览

1)删除 onPrepareListener。我不知道为什么你的视频在创建活动之后才开始播放,但是 onPrepareListener 是在 video View.start ()之后调用的。

2)在 VideoView 上面添加一个 ImageView 小部件,然后像这样设置另一个 onPrepareListener:

vvVideos.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
previewImage.setVisibility(View.GONE);
}
});

我已经注意到,onPreparedListener 启动得太早,因此您可以使用

new Handler().postDelay(Runnable, timeInMilis)

删除预览图像。

3)添加 OnTouchListener 和任何手势检测到你 VideoView 下面是我现在使用的一个例子:

    @Override
public void onCreate(Bundle savedInstanceState) {
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() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return true;
}
};
private SimpleOnGestureListener mGestureListener = new SimpleOnGestureListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if(mVideoView.isPlaying())
mVideoView.pause();
else
mVideoView.start();
return true;
};
};

轻轻一敲,它就开始/停止演奏。

使用 seekTo( 1 )显示第一帧。

确保电影暂停,然后使用 seekTo()显示视频的第一帧:

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 )在 Android9上不起作用。

在另一个回答中,@Lingviston 回答说点击就可以播放。

使用这个创建视频缩略图

Bitmap thumb = ThumbnailUtils.createVideoThumbnail("file path/url",
MediaStore.Images.Thumbnails.MINI_KIND);

设置为视频画面

BitmapDrawable bitmapDrawable = new BitmapDrawable(thumb);
mVideoView.setBackgroundDrawable(bitmapDrawable);

我知道这是一个老问题,但我需要同样的解决方案,在其他任何地方都找不到答案,所以我做了解决方案,我在这里分享爱:

我只是为它创建了一个小类:

   public class LoadFirstVideoFrame implements Runnable {


private static Handler uiHandler = new Handler(Looper.getMainLooper());
private VideoView videoView;


private LoadFirstVideoFrame(VideoView videoView) {
this.videoView = videoView;
videoView.start();
videoView.resume();
uiHandler.post(this);
}


public void stop() {
videoView = null;
uiHandler.removeCallbacks(this);
}


@Override public void run() {
if (videoView == null) return;
if (videoView.isPlaying()) {
videoView.pause();
videoView.seekTo(0);


videoView = null;
} else {
uiHandler.post(this);
}
}
}

它只是简单地要求开始播放,并在视频实际播放时立即将其暂停回到第一帧(这意味着它加载了文件并且已经在 SurfaceView 上呈现了它)。

这里的重要注意事项是记住在这个类上调用 stop(),这样它就可以正确地清理内存,而不会泄漏任何内存。

希望能有所帮助。

我想分享一下我的解决方案。seekTo方法工作得很好,但只适用于某些设备。这是我的工作。我在 onPreparedListener 的 onPreready 方法中处理这个问题,但这取决于您。

@Override
public void onPrepared(MediaPlayer mp) {
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(uri.getPath());
try {
Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime(currentPosition);
videoView.setBackgroundDrawable(new BitmapDrawable(bitmap));
} catch (OutOfMemoryError outOfMemoryError) {
//Not entirely sure if this will ever be thrown but better safe than sorry.
videoView.seekTo(currentPosition);
}
}

现在,当你播放视频时,你需要像这样移除背景图片:

private void play() {
...
videoView.setBackgroundDrawable(null);
..
}

好好享受吧!

只要查找视频到100毫秒,它就会使用 SeekTo ()方法显示缩略图

videoView.seekTo(100);

你可以用 Glide 4.x来做,它会获取你视频的第一帧,用 ImageView来显示

加入你的 build.gradle

implementation 'com.github.bumptech.glide:glide:4.x.x'

在你的班级里

GlideApp.with(context)
.load("your video URL")
.into(videoImageView);;

要使视频在活动开始时停止播放,只需删除 video.start()方法。

我已经为这样的缩略图创建了一个图像视图

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:clickable="true"
android:focusable="true">


<VideoView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="220dp"/>
<ImageView
android:id="@+id/videoView_thumbnail"
android:layout_width="match_parent"
android:layout_height="220dp"
android:scaleType="centerCrop"/>


</RelativeLayout>

并像这样在 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() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
thumbnailView.setVisibility(View.GONE);
//you can Hide progress dialog here when video is start playing;


}
});
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
videoView.stopPlayback();
thumbnailView.setVisibility(View.VISIBLE);


}
});

它对我很有用,我希望它对所有人都有用

你可以用@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);

如果没有后端服务器,可能会更好。或者,如果您有一个后端服务器,您可以以这种方式尝试。

缩略图由服务器计算,客户端只显示后端响应的图像。在服务器端,您可以做很多事情。

  • 哪张照片更好? 如果照片也是黑色的怎么办?
  • 服务器端应该生成它吗? 或者服务器端应该只缓存媒体的图片吗?

如果你想进一步讨论这两个问题,我们可以以后再讨论。

在 xml 中添加这个

    `<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dimen180"
android:background="@color/color_bg">


<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/epPlayer"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="match_parent"/>


<FrameLayout
android:id="@+id/flTv"
android:layout_width="match_parent"
android:background="@color/color_bg"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/ivTv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/tv"/>
</FrameLayout>








<ProgressBar
android:id="@+id/pbVideoView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_centerInParent="true"
android:indeterminate="true" />
</RelativeLayout>

` 科特林的使用者

声明变量

private var simpleExoPlayer: ExoPlayer? = null

用这个

  simpleExoPlayer = SimpleExoPlayer.Builder(this).build()
epPlayer.player = simpleExoPlayer
val dataSourceFactory = DefaultDataSourceFactory(
this,
Util.getUserAgent(this, getString(R.string.app_name))
)
val videoSource = ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(it1))
simpleExoPlayer!!.prepare(videoSource)
simpleExoPlayer!!.playWhenReady = true
simpleExoPlayer!!.addListener(object : Player.EventListener{
override fun onPlayerStateChanged(
playWhenReady: Boolean,
playbackState: Int
) {
if(playbackState== Player.STATE_READY)
{
pbVideoView.visibility= View.GONE
epPlayer.visibility= View.VISIBLE
flTv.visibility= View.GONE
}
if (playbackState== Player.STATE_BUFFERING)
{
pbVideoView.visibility= View.VISIBLE
}
}
})

希望能有所帮助。

很简单! ! ! 你可以使用滑动库。

首先在 videoView上添加一个 imageView,并使用以下代码:

   GlideApp.with(getApplicationContext()).load("empty")
.thumbnail(GlideApp.with(getApplicationContext()).load("videoURL"))
.into(imageView);

这段代码将下载一个图像,最终,这将导致更少的互联网消费。