programing

재생하기 전에 videoview에서 미리보기 이미지를 설정하는 방법

nicescript 2021. 1. 17. 10:34
반응형

재생하기 전에 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() {
        public void onPrepared(MediaPlayer mp) {
            vvVideos.start();
        }
    });

이제 활동이 생성되면 비디오가 재생되기 시작합니다. 다음과 같은 활동을하고 싶습니다.

  1. 활동이 열리면 동영상이 재생되지 않아야합니다.
  2. 시작 비디오 이미지를 표시합니다 (현재 검은 색 표시).
  3. 사용자가 동영상을 클릭 할 때만 재생됩니다.
    제발 도와주세요.

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.

참고 : Android 9에서는 .seekTo( 1 )설정 .seekTo( 0 )이 작동하지 않았기 때문에 사용 합니다 .

클릭 할 때 재생되도록하려면 @Lingviston이 다른 답변으로 답변했습니다.


이것을 사용하여 비디오 섬네일 만들기

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

videoview로 설정

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

1) onPrepareListener를 제거하십시오. 활동 생성 후 비디오 재생이 시작되는 이유를 모르겠지만 onPrepareListener는 videoView.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) VideoView에 제스처 감지와 함께 OnTouchListener를 추가하십시오. 다음은 내가 지금 사용중인 예입니다.

    @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 () 메서드를 사용하여 썸네일을 표시하는 100 밀리 초까지 비디오를 찾습니다.

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

내 솔루션을 공유 할 것이라고 생각했습니다. seekTo방법은 훌륭하지만 일부 장치에서만 작동합니다. 여기 내 작업이 있습니다. 나는 onPreparedListener의 onPrepared 메소드에서 이것을 처리하지만 그것은 당신에게 달려 있습니다.

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

즐겨!


나는 그것이 오래된 질문이라는 것을 알고 있지만 동일한 해결책이 필요했고 다른 곳에서 답을 찾을 수 없었기 때문에 해결책을 찾았고 여기에서 사랑을 나누고 있습니다.

나는 그것을 위해 작은 수업을 만들었습니다.

   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()이 클래스 를 호출 하여 메모리 누수가 발생하지 않고 적절히 정리할 수 있도록하는 것입니다.

I hope it helps.


I Have Created A ImageView For Thumbnail Like This

<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>

And Add setOnPreparedListener and setOnCompletionListener in Java Like This Way

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

        }
    });

It Works For Me Very Well I Hope Its Usfull For All


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.


To make your video stop playing when the activity starts just remove the video.start() method.

ReferenceURL : https://stackoverflow.com/questions/17079593/how-to-set-the-preview-image-in-videoview-before-playing

반응형