How to set the preview image in videoview before p

2019-01-31 11:41发布

I created an VideoView in my activity, below is the code.

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();
        }
    });

Now the video gets started to play when the activity gets created. I want to make my activity as follows

  1. Video should not play when the activity gets open.
  2. It shoud display the starting video image(currently its displaying black color)
  3. It should play only when the user click on the video.
    please help me.

10条回答
兄弟一词,经得起流年.
2楼-- · 2019-01-31 11:48

Thought I'd share my solution. The seekTo method works great but only for some devices. Here is my work around. I handle this in the onPrepared method for the onPreparedListener but its up to you.

@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);
  }
}

Now when you play the video you will need to remove this background image like so:

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

Enjoy!

查看更多
爷的心禁止访问
3楼-- · 2019-01-31 11:48

I know it's an old question, but I needed the same solution and couldn't find the answer anywhere else so I did the solution and I'm sharing the love here:

I just created a little class for it:

   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);
         }
      }
   }

it simply asks to start playing and pauses the video back on the first frame as soon as it's actually playing (meaning it loaded the file and it's already rendering it on the SurfaceView).

The important note here is to remember to call stop() on this class so it can properly clean up and not memory leak anything.

I hope it helps.

查看更多
看我几分像从前
4楼-- · 2019-01-31 11:51

Create video thumbnail using this

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

and set to videoview

BitmapDrawable bitmapDrawable = new BitmapDrawable(thumb);
            mVideoView.setBackgroundDrawable(bitmapDrawable);
查看更多
来,给爷笑一个
5楼-- · 2019-01-31 11:59

You can do it with Glide 4.x. It will fetch the first frame of your video show it in an ImageView

add to your build.gradle

compile 'com.github.bumptech.glide:glide:4.3.1'

and in your Class

GlideApp.with(context)
                .load("your video URL")
                .into(videoImageView);;
查看更多
戒情不戒烟
6楼-- · 2019-01-31 12:02

Use seekTo( 1 ) to show the first frame.

Ensure the movie is paused and then use seekTo() to show the first frame of the video:

VideoView mVideoView = (VideoView) findViewById( R.id.video_preview );

mVideoView.setVideoURI( yourVideoPath );

mVideoView.seekTo( 1 );                 // 1 millisecond (0.001 s) into the clip.

NOTE: We use .seekTo( 1 ) because setting .seekTo( 0 ) did not work on Android 9.

To have it play when clicked on has been answered by @Lingviston in another answer.

查看更多
混吃等死
7楼-- · 2019-01-31 12:02

You can use a @Joshua Pinter's answer to solve the problem. But I want to give you more suggestion about it. You yourself answer that seekTo(100) works instead of seekTo(1). Neither of the two ways is perfect. That is because seekTo(1) would get a black image and the seekTo(100) may got an exception.

I prefer to do like this:

// 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);

If you don't have the backend server, it may be better. Or, if you had a backend server, you can try it in this way.

The thumbnail is calculate by the server, the client just display the image which the backend response. And when it come to server side, you can do a lot of things.

  • Which picture is better? What if the picture is black too?
  • Should the server side generate it? Or should the server side just cache the picture of the media?

If you want to discuss more about the two questions we can discuss them later.

查看更多
登录 后发表回答