События VideoView onTouch: приостановить/возобновить видео и показать/скрыть MediaController и ActionBar

Резюме вопроса:

1) Как перенести видео как приостановленное и не воспроизводить его сразу?

2) Как приостановить/отключить видео при касании, а также скрыть/показать ActionBar и MediaController.

Буду признателен за любые советы. Благодарю! (Соответствующий код прилагается)

Обновление 1

Нашел несколько решение вопроса 2 (необходимо вернуть false), но я до сих пор не знаю, как ответить на вопрос 1.

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

Я пробовал несколько вещей, но в итоге у меня проблемы, такие как видео будет приостановлено, но не возобновлено, или ActionBar и MediaController не будут отображаться или скрываться должным образом.

Обновление 2

Я нашел частичное решение вопроса 1 и обновил код, чтобы отобразить видео как приостановленное при первом открытии. Однако, когда он открывается в первый раз, он показывает только черный экран, пока я не коснусь видеовидео, чтобы воспроизвести его. После просмотра видео один раз, он будет reset в начале и паузе, ожидая повторного воспроизведения и покажет правильное изображение с начала видео. Но я не знаю, как обойти черный экран в начале.

Соответствующий код:

public class ViewImageVideoFragment extends Fragment
{

    private int position = 0;
    private MediaController mMediaController;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        mMediaController = new MediaController(getActivity());
        ...
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
    {

        if (savedInstanceState != null)
        {
            position = savedInstanceState.getInt("position");
        }

        View v = inflater.inflate(R.layout.fragment_video_view, parent, false);

        mVideoView = (VideoView) v.findViewById(R.id.fragmentVideoView);
        mVideoView.setVideoPath(videoPath);
        mVideoView.setMediaController(mMediaController);

        mVideoView.setOnTouchListener(new View.OnTouchListener()
        {
            @Override
            public boolean onTouch(View v, MotionEvent motionEvent)
            {
                if (mVideoView.isPlaying())
                {
                    mVideoView.pause();
                    if (!getActivity().getActionBar().isShowing())
                    {
                        getActivity().getActionBar().show();
                        mMediaController.show(0);
                    }
                    position = mVideoView.getCurrentPosition();
                    return false;
                }
                else
                {
                    if (getActivity().getActionBar().isShowing())
                    {
                        getActivity().getActionBar().hide();
                        mMediaController.hide();
                    }
                    mVideoView.seekTo(position);
                    mVideoView.start();
                    return false;
                }
            }
        });

        mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
        {
            @Override
            public void onCompletion(MediaPlayer mediaPlayer)
            {
                mVideoView.seekTo(0);
            }
        });

        if (position != 0)
        {
            mVideoView.seekTo(position);
            mVideoView.start();
        }
        else
        {
             mVideoView.seekTo(0);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState)
    {
        super.onSaveInstanceState(savedInstanceState);

        if (mVideoView != null)
        {
            savedInstanceState.putInt("position", mVideoView.getCurrentPosition());
        }

        mVideoView.pause();
    }
}

Ответ 1

Чтобы сначала показать видео как приостановленное, просто измените seekTo(0) на seekTo(1) в своем коде. Это переместит видео на время в 1 миллисекунду, и вы сможете взять его оттуда.

//edited here
private int position = 1;
private MediaController mMediaController;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    mMediaController = new MediaController(getActivity());
    ...
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
{

    if (savedInstanceState != null)
    {
        position = savedInstanceState.getInt("position");
    }

    View v = inflater.inflate(R.layout.fragment_video_view, parent, false);

    mVideoView = (VideoView) v.findViewById(R.id.fragmentVideoView);
    mVideoView.setVideoPath(videoPath);
    mVideoView.setMediaController(mMediaController);

    mVideoView.setOnTouchListener(new View.OnTouchListener()
    {
        @Override
        public boolean onTouch(View v, MotionEvent motionEvent)
        {
            if (mVideoView.isPlaying())
            {
                mVideoView.pause();
                if (!getActivity().getActionBar().isShowing())
                {
                    getActivity().getActionBar().show();
                    mMediaController.show(0);
                }
                position = mVideoView.getCurrentPosition();
                return false;
            }
            else
            {
                if (getActivity().getActionBar().isShowing())
                {
                    getActivity().getActionBar().hide();
                    mMediaController.hide();
                }
                mVideoView.seekTo(position);
                mVideoView.start();
                return false;
            }
        }
    });

    mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
    {
        @Override
        public void onCompletion(MediaPlayer mediaPlayer)
        {
            //here
            mVideoView.seekTo(1);
        }
    });
    //here
    if (position != 1)
    {
        mVideoView.seekTo(position);
        mVideoView.start();
    }
    else
    {
         //here
         mVideoView.seekTo(1);
    }
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
    super.onSaveInstanceState(savedInstanceState);

    if (mVideoView != null)
    {
        savedInstanceState.putInt("position", mVideoView.getCurrentPosition());
    }

    mVideoView.pause();
}

}

Ответ 2

Если я правильно понимаю, вы хотите отобразить кадр из видео в качестве заполнителя, пока не будете готовы начать видео. Для этого я знаю два способа:

seekTo

Вы можете использовать MediaPlayer.seekTo для перемещения видео в несколько кадров вперед, например, используя значение 150, чтобы отобразить кадр на 150-й миллисекунде в видеофайле. Видео не нужно запускать, чтобы искать.

MediaMetadataRetriever

MediaMetadataRetriever met = new MediaMetadataRetriever();

try { 
    met.setDataSource(data[0], new HashMap<String, String>()); //use this constructor, other one has a bug...
    Bitmap b = met.getFrameAtTime();

    if (b == null)
        b = met.getFrameAtTime(150, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);

    met.release();
    return b;

} catch (Exception e) {
    Log.d(TAG, "MediaMetadata failed", e);
}

Это даст вам Bitmap, который вы затем можете вставить в ImageView и установить вместо видео. Однако этот API всегда был для меня ошибкой в ​​зависимости от типов видеокодеков, с которыми вы имеете дело.

Ответ 3

Мои источники -

show()
show (int timeout)
hide()
isShowing()
onTouchEvent()

Все примечания находятся в коде

public class ViewImageVideoFragment extends Fragment
{

   private int position = 0;
   private MediaController mMediaController;

   @Override
   public void onCreate(Bundle savedInstanceState)
   {
      super.onCreate(savedInstanceState);
      mMediaController = new MediaController(getActivity());
   }

   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
   {

      if (savedInstanceState != null)
      {
         position = savedInstanceState.getInt("position");
      }

      v = inflater.inflate(R.layout.fragment_video_view, parent, false);

      mVideoView = (VideoView) v.findViewById(R.id.fragmentVideoView);
      mVideoView.setVideoPath(videoPath);
      mVideoView.setMediaController(mMediaController);

      mVideoView.setOnTouchListener(
            new View.OnTouchListener()
            {
               @Override
               public boolean onTouch(View v, MotionEvent motionEvent)
               {
                  if (mVideoView.isPlaying())
                  {
                     mVideoView.pause();


                  /*

                  Ok, so now you want to use that show(), preferrably without the int timeout

                  I didn't add it in myself but you should be able to handle it yourself

                  */

                     return true;
                  }
                  else /* I changed it to else, change it to if else if you have something specific you want to deal with */
                  {                                  

                  /* 

                  I would use that hide method I linked here, then start the 
                  video, I assume you know how to play the video yourself 

                  */

                  }

                  return false;
               }
            });

      mVideoView.seekTo(position);

      mVideoView.start();
   }

   @Override
   public void onSaveInstanceState(Bundle savedInstanceState)
   {
      super.onSaveInstanceState(savedInstanceState);

      if (mVideoView != null)
      {
         savedInstanceState.putInt("position", mVideoView.getCurrentPosition());
      }

      mVideoView.pause();
   }
}

Я представил другие методы, потому что, в зависимости от того, как вы можете продолжать, они могут или не могут препятствовать будущим вопросам.