VideoView ontouch события: пауза / возобновление видео и показать / скрыть MediaController и ActionBar
вопрос резюме:
1) Как отобразить видео на паузе и не сразу играть?
2) как приостановить/отменить паузу видео на ощупь, а также Скрыть/Показать панель действий и MediaController.
Я был бы признателен за любой совет. Спасибо! (соответствующий код прилагается)
обновление 1
найдено некоторое решение вопроса 2 (необходимо вернуть false), но я все еще не знаю, как ответ на вопрос 1.
когда пользователь нажимает кнопку в моем приложении, он берет их, чтобы посмотреть видео. Когда они впервые откроют этот экран, я бы хотел, чтобы видео было приостановлено и не воспроизводилось сразу. Хотелось бы также иметь возможность приостановить воспроизведение видео, нажав на экран. Когда видео приостановлено, я хотел бы показать ActionBar
и MediaController
. Когда видео возобновляется, я хотел бы скрыть ActionBar
и MediaController
(возможно, после небольшой задержки?)
Я пробовал несколько вещи, но я в конечном итоге с проблемами, как видео будет пауза, но не возобновится, или ActionBar
и MediaController
не будет отображаться или скрываться должным образом.
обновление 2
Я нашел частичное решение вопроса 1 и обновил код для отображения видео, как приостановлено при первом его открытии. Однако, когда он открывается в первый раз, он показывает только черный экран, пока я не коснусь videoview, чтобы воспроизвести его. После просмотра видео один раз, он будет сброшен на начало и пауза, ожидая воспроизведения снова, и покажет правильное изображение с начала видео. Но я не знаю как обойти черный экран в начале.
соответствующий код:
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();
}
}
3 ответов
чтобы сначала показать видео как приостановлено, просто измените seekTo(0)
to 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();
}
}
если я правильно понимаю, вы хотите отобразить кадр из видео в качестве заполнителя, пока не будете готовы запустить видео. Я знаю два способа добиться этого:--6-->
функцию 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 всегда был багги для меня в зависимости от типов видеокодеков, с которыми вы имеете дело.
Мои источники --
show ()
показать (тайм-аут int)
скрыть()
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();
}
}
Я предоставил другими методами, потому что в зависимости от того, как вы можете продолжать, они могут или не могут предотвратить будущие вопросы.