Черный экран при использовании seekTo с MediaPlayer в Android - PullRequest
0 голосов
/ 06 октября 2019

Моя цель - показать пользователю 9-кадровое видео, которое было записано, чтобы он мог выбрать один из них.

Итак, я сделал упражнение для записи видео и отправкиURI из видео в другое действие, которое покажет 9 кадров из этого записанного видео.

В интерфейсе 9 видеопоисков, каждый из которых изменяется с seekTo со значением, рассчитанным по этой переменной:

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

Другими словами, я разделил видео на 10 частей, используя MILISECONDS_TO_JUMP от начала видео.

После этого я использую seekTo из mediaPlayer.seekTo(video_seek); в методе onPrepared, чтобы начатькаждый из VideoViews в разное время.

Полный код выглядит так:

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

Журнал из приложения показывает, что я вычисляю правильные миллисекунды, которые я хотел.

Например, при переходе между кадрами на 256 миллисекунд и при переходе на первые 10 кадров видео получилось:

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) показывает изображение из записанного видео, а иногда нет. То же самое происходит со всеми другими VideoViews, иногда они работают правильно, иногда нет.

Поэтому мой вопрос: почему эти черные экраны показывают, что я делаю неправильно и как я могуисправить это?

Я уже ищу проблему, и некоторые попытки ее исправить я показал в коде выше. Проблемы случаются в большинстве случаев. По крайней мере 3 VideoViews показывают черные экраны.

На следующем рисунке показан пример ... Спасибо за любую помощь! Извините за длинное описание

Black screen Problem with VideoViews

1 Ответ

0 голосов
/ 22 октября 2019

Ну, я не смог найти причину черных экранов, однако, поскольку мне просто нужно показать изображение (не видео), я нашел решение своей проблемы, которое я опубликую здесь.

Вместо использования VideoViews я изменил их на ImageViews и использовал изображения, предоставленные 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();

...