在Android中将seekTo与MediaPlayer一起使用

在Android中将seekTo与MediaPlayer一起使用

本文介绍了在Android中将seekTo与MediaPlayer一起使用时出现黑屏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是向用户显示9帧已录制的视频,以便他可以选择其中之一.

所以我要做的是一个活动来录制视频,并将视频中的URI发送到另一个活动,该活动将显示该录制的视频中的9帧.

So what i did was make an activity to record the video and send the URI from the video to another activity that will show 9 frames from that recorded video.

界面中有9个VideoView,每个视频都通过一次seekTo进行更改,该值由此变量计算得出:

There're 9 VideoViews in the interface each one being change with a seekTo with value calculated by this variable:

        video_frames_to_jump = (mediaPlayer.getDuration() - MILISECONDS_TO_JUMP)/10;

换句话说,我将视频分为10段,从视频开头开始使用MILISECONDS_TO_JUMP.

In other words, i divided the video in 10 pieces, with MILISECONDS_TO_JUMP from the beginning of the video.

此后,我使用 onPrepared 方法中的 mediaPlayer.seekTo(video_seek); 中的seekTo在不同的时间启动每个VideoView.

After that i use the seekTo from mediaPlayer.seekTo(video_seek); in the method onPrepared to start each of the VideoViews in a different time.

完整代码如下:

// Activity OnCreated
OnCreated(){


        // preparing the Video file for the VideoView
        video_file_string = getIntent().getStringExtra("video_file");
        video_file = new File(video_file_string);
        Uri videoUri = Uri.fromFile(video_file);

        // Using OnPrepared so we can use the mediaPlayer.getDuration() and to avoid further problems
        MediaPlayer.OnPreparedListener onpreparedlistener = new MediaPlayer.OnPreparedListener() {
            // Make some important initialization explained above to calculate video_frames_to_jump and
            // video_seek
            videoseek_initialization();

            // here i update the variable, so the next video will seekTo a later point in the video
            video_seek = (video_seek > mediaPlayer.getDuration())?
                        (mediaPlayer.getDuration()-1) : (video_seek+video_frames_to_jump);
            mediaPlayer.seekTo(video_seek);
            Log.v(TAG, "FramesSelection VideoSeek(" + video_seek + ") MaxDuration(" +mediaPlayer.getDuration() +")");

            // the two lines below was me trying to fix the black screen error, but it didn't work
            // some people said that playing and pause the video would update the VideoView and fix the
            // black screen

            mediaPlayer.start();
            mediaPlayer.pause();
        }


        // here i'm initializing the videoviews
        VideoView video_view1 = (VideoView) this.findViewById(R.id.video_view1);
        VideoView video_view2 = (VideoView) this.findViewById(R.id.video_view2);
        ...
        VideoView video_view8 = (VideoView) this.findViewById(R.id.video_view8);
        VideoView video_view9 = (VideoView) this.findViewById(R.id.video_view9);

        video_view1.setVideoURI(videoUri);

        video_view1.setZOrderOnTop(false);
        // The line above was a possible fix for the black screen, i changed it to true/false but
        // when false - nothing changes and my problem continues.
        // when true  - the issue continues but instead of black screen, i got a white screen

        video_view1.setOnPreparedListener(onpreparedlistener);
        video_view2.setVideoURI(videoUri);
        video_view2.setZOrderOnTop(false);
        video_view2.setOnPreparedListener(onpreparedlistener);
        ...
        video_view8.setVideoURI(videoUri);
        video_view8.setZOrderOnTop(false);
        video_view8.setOnPreparedListener(onpreparedlistener);
        video_view9.setVideoURI(videoUri);
        video_view9.setZOrderOnTop(false);
        video_view9.setOnPreparedListener(onpreparedlistener);
}

应用程序的日志显示,我正在计算所需的正确毫秒数.

The log from the application shows that i'm calculating the correct miliseconds that i wanted.

例如,在每帧之间跳跃256毫秒,并在视频中跳跃前10帧,结果是:

For example with a jump of 256 miliseconds between frames and jumping the first 10 frames in the video the result was:

myapplication: FramesSelection VideoSeek(266) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(522) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(778) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(1034) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(1290) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(1546) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(1802) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(2058) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(2314) MaxDuration(2576)

请注意,我不是在播放视频,只是在VideoView中显示了固定的图像"或帧".

所以问题在于某些VideoView随机显示黑屏.

例如,有时第一个VideoView(video_view1)显示来自录制视频的图像,有时不显示.所有其他VideoView也会发生同样的情况,有时它们可​​以正常工作,有时却无法正常工作.

For example, sometimes the first VideoView (video_view1)show a image from the recorded video and sometimes don't. The same happens with all the other VideoViews, sometimes they work correctly, sometimes don't.

所以我的问题是:为什么显示黑屏,我在做什么错,我该如何解决?

我已经搜索了问题,并且在上面的代码中显示了一些解决此问题的尝试.问题在大多数时候都会发生.至少有3个VideoView显示黑屏.

I already search for the problem and some of the tries to fix it i showed in the code above. The problems happens most of the times. At least 3 VideoViews are showing black screens.

下图显示了一个示例...感谢您的帮助!抱歉,很长的描述

The following image shows an example... Thanks for any help! Sorry for long description

推荐答案

好吧,我找不到黑屏的原因,但是由于我只需要显示图像(而不是视频),所以我找到了解决方案问题,我将在这里发布.

Well i couldn't find the reason of the black screens, however since i just need to show a image (not a video) i found a solution to my problem, which i'll post here.

我没有使用VideoViews,而是将它们更改为ImageViews,并使用MediaMetadataRetriever提供的图像.

Instead of using VideoViews i changed them to ImageViews and use the images provided by MediaMetadataRetriever.

我的代码

    // Lines below are to find the video duration and to initialize the MediaMetadataRetriever
    MediaMetadataRetriever mediaMetadataretriever = new MediaMetadataRetriever();
    mediaMetadataretriever.setDataSource(video_file_string);
    // getting video duration
    String time = mediaMetadataretriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
    final int timeInMillisec = Integer.parseInt(time);

    // again finding the frames to jump between frames
    video_frames_to_jump = (timeInMillisec - MILISECONDS_TO_JUMP)/10;
    video_seek = MILISECONDS_TO_JUMP;

    Bitmap[] bmFrame = new Bitmap[NUMBER_OF_IMAGEVIEW];
    ImageView[] img_view  = new ImageView[NUMBER_OF_IMAGEVIEW];

    // get imageview components
    img_view[0] = this.findViewById(R.id.image_view1);
    img_view[1] = this.findViewById(R.id.image_view2);
    ...
    img_view[7] = this.findViewById(R.id.image_view8);
    img_view[8] = this.findViewById(R.id.image_view9);

    for(int i = 0; i < bmFrame.length; i++) {
        // calculating the video frames that i want
        video_seek = (video_seek >= timeInMillisec) ? (timeInMillisec - 1) : (video_seek + video_frames_to_jump);

        // setting a frame image to ImageView
        bmFrame[i] = mediaMetadataretriever.getFrameAtTime(video_seek * 1000); // time MUST be in MICROseconds
        img_view[i].setImageBitmap(bmFrame[i]);
    }
    // Release the mediaMetadataretriever
    mediaMetadataretriever.release();

这篇关于在Android中将seekTo与MediaPlayer一起使用时出现黑屏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 23:01