说明
- 视频播放事件包括两个部分:1.播放器本身的事件(开始、暂停、结束播放等) 2.用户动作触发的事件(拖拽进度条、点击屏幕等)
- 播放事件监听的途径主要是通过视频播放框架(或开发者自定义)的控制器来实现的。
- 控制器是指操作播放器的组件(按钮、进度条等)的容器。
- 事件的监听经常与视频当前时间配合使用。
- 本文基于Exoplayer+Exomedia实现视频事件监听。
关键点
VideoView与视频时间、播放进度相关的主要方法。
- 获取视频当前时间
long getCurrentPosition()
- 获取视频总时长
long getDuration()
- 控制播放进度
void seekTo(long millis)
实现接口
包含VideoView的Activity请实现接口,全部接口及回调如下所示,实际使用中请挑选所需接口实现(若有遗漏请谅解).
public class XunshiVideoDemoActivity extends AppCompatActivity
implements
ExoPlayerListener,
VideoControlsSeekListener,
VideoControlsButtonListener,
VideoControlsVisibilityListener,
OnCompletionListener,
OnPreparedListener,
OnBufferUpdateListener {
@Override
public void onStateChanged(boolean playWhenReady, int playbackState) {
}
@Override
public void onError(ExoMediaPlayer exoMediaPlayer, Exception e) {
}
@Override
public void onVideoSizeChanged(int width, int height, int unAppliedRotationDegrees, float pixelWidthHeightRatio) {
}
@Override
public void onBufferingUpdate(@IntRange(from = 0, to = 100) int percent) {
}
@Override
public void onCompletion() {
}
@Override
public void onPrepared() {
}
@Override
public void onSeekComplete() {
}
@Override
public boolean onPlayPauseClicked() {
return false;
}
@Override
public boolean onPreviousClicked() {
return false;
}
@Override
public boolean onNextClicked() {
return false;
}
@Override
public boolean onRewindClicked() {
return false;
}
@Override
public boolean onFastForwardClicked() {
return false;
}
@Override
public boolean onSeekStarted() {
return false;
}
@Override
public boolean onSeekEnded(long seekTime) {
return false;
}
@Override
public void onControlsShown() {
}
@Override
public void onControlsHidden() {
}
}
设置监听
//1.控制器的监听
mVideoView.getVideoControls().setVisibilityListener(this);
mVideoView.getVideoControls().setSeekListener(this);
mVideoView.getVideoControls().setButtonListener(this);
//2.播放器的监听
mVideoView.setOnCompletionListener(this);
mVideoView.setOnSeekCompletionListener(this);
mVideoView.setOnPreparedListener(this);
mVideoView.setOnBufferUpdateListener(this);
这里的参数this
是因为Activity实现了接口,也可以直接传匿名函数如下:
mVideoView.setOnBufferUpdateListener(new OnBufferUpdateListener() {
@Override
public void onBufferingUpdate(@IntRange(from = 0, to = 100) int percent) {
//do something
}
});
详细说明
播放器监听类
- ExoPlayerListener
与Exoplayer的addListener回调类似,监听了视频播放状态变化、报错、尺寸变化、进度条拖拽结束。
mVideoView.setOnSeekCompletionListener(this);
@Override
public void onStateChanged(boolean playWhenReady, int playbackState) {
//视频播放状态
}
@Override
public void onError(ExoMediaPlayer exoMediaPlayer, Exception e) {
//报错
}
@Override
public void onVideoSizeChanged(int width, int height, int unAppliedRotationDegrees, float pixelWidthHeightRatio) {
//尺寸
}
@Override
public void onSeekComplete() {
//拖拽进度条结束
}
- OnCompletionListener
视频加载并且播放完毕时回调.
mVideoView.setOnCompletionListener(this);
@Override
public void onCompletion() {
}
- OnPreparedListener
视频准备完毕可以播放时回调.经常在这里获取视频播放长度.
mVideoView.setOnPreparedListener(this);
@Override
public void onPrepared() {
Log.d(TAG, "视频时长=" + mVideoView.getDuration());
}
- OnBufferUpdateListener
视频缓冲时回调/视频播放中不断的回调,非常适合监听播放当前时刻--->getCurrentPosition()
mVideoView.setOnBufferUpdateListener(this);
@Override
public void onBufferingUpdate(@IntRange(from = 0L, to = 100L) int percent) {
Log.d(TAG, "当前播放时刻=" + mVideoView.getCurrentPosition());
}
-
OnBufferUpdateListener
监听Log示例:
06-30 16:46:44.570 15602-15602/com.xunshi.videodemo D/VideoActivity: onBufferingUpdate.getCurrentPosition():478
06-30 16:46:45.570 15602-15602/com.xunshi.videodemo D/VideoActivity: onBufferingUpdate.getCurrentPosition():1479
06-30 16:46:46.570 15602-15602/com.xunshi.videodemo D/VideoActivity: onBufferingUpdate.getCurrentPosition():2474
06-30 16:46:47.570 15602-15602/com.xunshi.videodemo D/VideoActivity: onBufferingUpdate.getCurrentPosition():3477
06-30 16:46:48.570 15602-15602/com.xunshi.videodemo D/VideoActivity: onBufferingUpdate.getCurrentPosition():4484
06-30 16:46:49.570 15602-15602/com.xunshi.videodemo D/VideoActivity: onBufferingUpdate.getCurrentPosition():5469
06-30 16:46:50.570 15602-15602/com.xunshi.videodemo D/VideoActivity: onBufferingUpdate.getCurrentPosition():6492
06-30 16:46:51.570 15602-15602/com.xunshi.videodemo D/VideoActivity: onBufferingUpdate.getCurrentPosition():7492
可以看出此getCurrentPosition()
的值随播放时刻变化而变化,说明此回调是在持续进行监听的.
注意!
此方法在视频播放完毕后即停止监听,restart()视频也不会再次监听!如果想重新监听有两种方法:
- 释放视频资源,重新加载;
-
利用OnBufferUpdateListener持续监听的特性,在视频播放完毕前暂停,此时restart()视频即可再次监听了!总时间减去当前时间:getDuration() - getCurrentPosition() >= 1000毫秒时说明视频没有播放完毕。
@Override
public void onBufferingUpdate(@IntRange(from = 0L, to = 100L) int percent) {
Log.d(TAG, "onBufferingUpdate.getCurrentPosition():" + mVideoView.getCurrentPosition());
if (mVideoView.getDuration() - mVideoView.getCurrentPosition() < 1000) {
//计算时长小于1000毫秒
//视同视频播放完毕
return;
}
}
控制器监听类
- VideoControlsSeekListener
监听进度条拖拽的开始与结束.
mVideoView.getVideoControls().setSeekListener(this);
@Override
public boolean onSeekStarted() {
//开始拖拽时刻
Log.d(TAG, "开始拖拽时刻=" + mVideoView.getCurrentPosition());
return false;
}
@Override
public boolean onSeekEnded(long seekTime) {
//结束拖拽时刻
Log.d(TAG, "结束拖拽时刻=" + mVideoView.getCurrentPosition());
return false;
}
- VideoControlsButtonListener
控制器按钮点击事件监听.
mVideoView.getVideoControls().setButtonListener(this);
@Override
public boolean onPlayPauseClicked() {
//开始/暂停
return false;
}
@Override
public boolean onPreviousClicked() {
//回退
return false;
}
@Override
public boolean onNextClicked() {
return false;
}
@Override
public boolean onRewindClicked() {
//前进
return false;
}
@Override
public boolean onFastForwardClicked() {
//快进
return false;
}
3.VideoControlsVisibilityListener
控制器可见性监听.
mVideoView.getVideoControls().setVisibilityListener(this);
@Override
public void onControlsShown() {
}
@Override
public void onControlsHidden() {
}
其他
相关文章请点击下面链接: