Exoplayer+Exomedia視訊播放事件監聽
說明
- 視訊播放事件包括兩個部分: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() {
-
}