转载自:https://blog.youkuaiyun.com/xunshishi/article/details/74171379
说明
- 视频播放事件包括两个部分: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() {
-
}