3_2-云课堂场景-播放器
1 功能概述
影片播放是多場景專案中提供的基礎功能,雲端課堂場景會使用到直播播放器和回放播放器。在雲端課堂場景模組中,對直播播放器整個佈局區域的元素封裝為 PLVLCLiveMediaLayout,對回放播放器整個佈局區的元素域封裝為 PLVLCPlaybackMediaLayout,它們共同實作 IPLVLCMediaLayout 介面。
2 使用演示
以下範例了如何建立直播播放器佈局、回放播放器佈局,以及它們的初始化及影片播放,程式碼如下:
//播放器布局
IPLVLCMediaLayout mediaLayout;
//ViewStub控件
ViewStub videoLyViewStub = findViewById(R.id.plvlc_video_ly);
if (liveRoomDataManager.getConfig().isLive()) {//直播类型
//设置直播播放器布局
videoLyViewStub.setLayoutResource(R.layout.plvlc_live_player_layout_view_stub);
//填充直播播放器布局
mediaLayout = (IPLVLCMediaLayout) videoLyViewStub.inflate();
//初始化
mediaLayout.init(liveRoomDataManager);
//设置横屏控制栏
mediaLayout.setLandscapeControllerView(liveLandscapeChannelController);
//开始播放
mediaLayout.startPlay();
} else {//回放类型
//设置回放播放器布局
videoLyViewStub.setLayoutResource(R.layout.plvlc_playback_player_layout_view_stub);
//填充回放播放器布局
mediaLayout = (IPLVLCMediaLayout) videoLyViewStub.inflate();
//初始化
mediaLayout.init(liveRoomDataManager);
//设置PPTView
mediaLayout.setPPTView(floatingPPTLayout.getPPTView().getPlaybackPPTViewToBindInPlayer());
//开始播放
mediaLayout.startPlay();
}
上述方法的具體用例可以在 polyv demo 專案中的 PLVLCCloudClassActivity 找到。
3 介面介紹
3.1 IPLVLCMediaLayout
雲端課堂場景下,針對播放器佈局進行封裝的介面。定義了:
1、外部直接呼叫的方法 2、需要外部回應的事件監聽器
public interface IPLVLCMediaLayout {
// <editor-fold defaultstate="collapsed" desc="1、外部直接调用的方法 - common部分,定义 直播播放器布局 和 回放播放器布局 通用的方法">
/**
* 初始化
*
* @param liveRoomDataManager 直播间数据管理器
*/
void init(IPLVLiveRoomDataManager liveRoomDataManager);
/**
* 开始播放
*/
void startPlay();
/**
* 暂停播放
*/
void pause();
/**
* 恢复播放
*/
void resume();
/**
* 停止播放
*/
void stop();
/**
* 是否在播放中
*
* @return true:在播放,false:不在播放
*/
boolean isPlaying();
/**
* 设置系统音量
*
* @param volume,音量值,范围[0,100]
*/
void setVolume(int volume);
/**
* 获取系统音量
*
* @return 音量值,范围[0,100]
*/
int getVolume();
/**
* 发送弹幕
*
* @param message 弹幕信息
*/
void sendDanmaku(CharSequence message);
/**
* 点击关闭悬浮窗
*/
void updateOnClickCloseFloatingView();
/**
* 获取播放器切换View
*
* @return 播放器切换View
*/
PLVSwitchViewAnchorLayout getPlayerSwitchView();
/**
* 获取横屏的聊天布局
*
* @return 横屏聊天布局
*/
PLVLCChatLandscapeLayout getChatLandscapeLayout();
/**
* 设置view交互事件监听器
*
* @param listener 监听器
*/
void setOnViewActionListener(OnViewActionListener listener);
/**
* 添加播放器状态的监听器
*
* @param listener 监听器
*/
void addOnPlayerStateListener(IPLVOnDataChangedListener<PLVPlayerState> listener);
/**
* 添加PPT是否显示状态的监听器
*
* @param listener 监听器
*/
void addOnPPTShowStateListener(IPLVOnDataChangedListener<Boolean> listener);
/**
* 是否拦截返回事件
*
* @return true:拦截,false:不拦截。如果当前处于横屏状态,会拦截返回事件,并切换到竖屏。
*/
boolean onBackPressed();
/**
* 销毁,销毁播放器及相关资源
*/
void destroy();
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="1、外部直接调用的方法 - live部分,定义 直播播放器布局 独有的方法">
/**
* 设置横屏控制器
*
* @param landscapeControllerView 横屏控制器
*/
void setLandscapeControllerView(@NonNull IPLVLiveLandscapePlayerController landscapeControllerView);
/**
* 更新观看热度
*
* @param viewerCount 热度数
*/
void updateViewerCount(long viewerCount);
/**
* 当加入连麦时,更新布局
*
* @param linkMicLayoutLandscapeWidth 连麦布局在横屏的宽度
*/
void updateWhenJoinLinkMic(int linkMicLayoutLandscapeWidth);
/**
* 当离开连麦时,更新布局
*
* @param shouldStartPlay 是否应该在离开连麦后播放视频
*/
void updateWhenLeaveLinkMic(boolean shouldStartPlay);
/**
* 添加连麦是否开启状态的监听器
*
* @param listener 监听器
*/
void addOnLinkMicStateListener(IPLVOnDataChangedListener<Pair<Boolean, Boolean>> listener);
/**
* 添加sei数据监听器
*
* @param listener 监听器
*/
void addOnSeiDataListener(IPLVOnDataChangedListener<Long> listener);
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="1、外部直接调用的方法 - playback部分,定义 回放播放器布局 独有的方法">
/**
* 获取视频总时长
*
* @return 视频总时长,单位:毫秒
*/
int getDuration();
/**
* 根据progress占max的百分比,跳转到视频总时间的该百分比进度
*
* @param progress 进度
* @param max 总进度
*/
void seekTo(int progress, int max);
/**
* 设置播放速度
*
* @param speed 速度值,建议范围为[0.5,2]
*/
void setSpeed(float speed);
/**
* 获取播放速度
*
* @return 速度值
*/
float getSpeed();
/**
* 设置PPTView
*
* @param pptView pptView
*/
void setPPTView(IPolyvPPTView pptView);
/**
* 添加播放信息的监听器
*
* @param listener 监听器
*/
void addOnPlayInfoVOListener(IPLVOnDataChangedListener<PLVPlayInfoVO> listener);
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="2、需要外部响应的事件监听器 - 定义 播放器布局中UI控件 触发的交互事件的回调方法">
/**
* view交互事件监听器
*/
interface OnViewActionListener {
/**
* 点击显示或隐藏浮窗/连麦布局(直播和回放共有)
*
* @param toShow true:显示,false:隐藏
*/
void onClickShowOrHideSubTab(boolean toShow);
/**
* 显示皮肤(直播独有)
*
* @param show true表示播放器皮肤显示,false表示播放器皮肤隐藏
*/
void onShowMediaController(boolean show);
/**
* 横屏发送的消息应同步到聊天室
*
* @param message 发送的信息
* @return <是否发送成功, 结果码>
*/
Pair<Boolean, Integer> onSendChatMessageAction(String message);
/**
* 显示公告动作(直播独有)
*/
void onShowBulletinAction();
/**
* 发送点赞动作
*/
void onSendLikesAction();
}
// </editor-fold>
}
4 實作介紹
4.1 PLVLCLiveMediaLayout
雲端課堂場景下的直播播放器佈局,實作 IPLVLCMediaLayout 介面。
該佈局包含的元素有:直播播放器、子播放器、橫向聊天室區、彈幕佈局、亮度手勢佈局、音量手勢佈局、直播控制列等,在直播播放區域出現的 UI。
下面會列舉介紹該佈局中涉及到的主要方法。
4.1.1 初始化 view 方法
PLVLCLiveMediaLayout 繼承於 FrameLayout,在建構子中對使用 initView 方法對 view 進行了初始化處理。
public PLVLCLiveMediaLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
//填充播放器布局到该view中
LayoutInflater.from(getContext()).inflate(R.layout.plvlc_live_player_layout, this);
//一系列findViewById,这里不详细列出
//初始化播放器布局中包含的view
initVideoView();
initDanmuView();
initMediaController();
initMoreLayout();
initAudioModeView();
initLoadingView();
initSwitchView();
initLayoutWH();
}
4.1.2 初始化資料方法
PLVLCLiveMediaLayout 的 init 方法是對外 API,需要外部傳入 IPLVLiveRoomDataManager 後進行初始化。
//播放器presenter
private IPLVLivePlayerContract.ILivePlayerPresenter livePlayerPresenter;
@Override
public void init(@NonNull IPLVLiveRoomDataManager liveRoomDataManager) {
this.liveRoomDataManager = liveRoomDataManager;
//观察直播间数据管理器中的直播详情数据
observeClassDetailVO();
//创建播放器mvp-presenter
livePlayerPresenter = new PLVLivePlayerPresenter(liveRoomDataManager);
//注册播放器mvp-view
livePlayerPresenter.registerView(livePlayerView);//这里的livePlayerView是播放器mvp-view
//初始化播放器mvp-prensenter
livePlayerPresenter.init();
//传递presenter给mediaController调用
mediaController.setLivePlayerPresenter(livePlayerPresenter);
}
//创建播放器mvp-view
private IPLVLivePlayerContract.ILivePlayerView livePlayerView = new PLVAbsLivePlayerView() {
//...
}
這裡的 PLVLivePlayerPresenter 是使用 mvp 模式封裝的播放器,用 presenter 將 view 和 mode 隔離開來,一切業務邏輯都是透過 presenter 來進行操作,也就是說 presenter 是視圖的資料的橋樑,視圖和資料相隔兩端。
4.1.3 設定橫向控制列方法
PLVLCLiveMediaLayout 的 setLandscapeControllerView 方法是對外 API,需要外部傳入 IPLVLiveLandscapePlayerController 進行配置。PLVLCLiveMediaLayout 內部已經包含了直向控制列,由於橫向控制列的層級在雲端課堂場景是需要覆蓋在浮動視窗、連麥控制器之上。因此需要在 xml 佈局中,調整橫向控制列的位置後,再傳入到 PLVLCLiveMediaLayout 中。
@Override
public void setLandscapeControllerView(@NonNull IPLVLiveLandscapePlayerController landscapeControllerView) {
mediaController.setLandscapeController(landscapeControllerView);
}
4.1.4 開始播放方法
PLVLCLiveMediaLayout 的 startPlay 方法是對外 API,該方法內部會呼叫 PLVLivePlayerPresenter 的 start 方法來進行影片的載入及播放。
@Override
public void startPlay() {
livePlayerPresenter.startPlay();
}
PLVLCLiveMediaLayout 內部持有 PLVLivePlayerPresenter,因此除了內部可以自由呼叫播放器相關的方法外,也能將其封裝成介面提供給外層呼叫,startPlay 方法就是其中一個例子。
4.2 PLVLCPlaybackMediaLayout
雲端課堂場景下的回放播放器佈局,實作 IPLVLCMediaLayout 介面
該佈局包含的元素有:回放播放器、亮度手勢佈局、音量手勢佈局、快進/退手勢佈局、回放控制列等,在回放播放區域出現的 UI。
下面會列舉介紹該佈局中涉及到的主要方法。
4.2.1 初始化 view 方法
PLVLCPlaybackMediaLayout 繼承於 FrameLayout,在建構子中對使用 initView 方法對 view 進行了初始化處理。
public PLVLCPlaybackMediaLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
//填充播放器布局到该view中
LayoutInflater.from(getContext()).inflate(R.layout.plvlc_playback_player_layout, this, true);
//一系列findViewById,这里不详细列出
//初始化播放器布局中包含的view
initVideoView();
initMediaController();
initLoadingView();
initSwitchView();
initLayoutWH();
}
4.2.2 初始化資料方法
PLVLCPlaybackMediaLayout 的 init 方法是對外 API,需要外部傳入 IPLVLiveRoomDataManager 後進行初始化。
//播放器presenter
private IPLVPlaybackPlayerContract.IPlaybackPlayerPresenter playbackPlayerPresenter;
@Override
public void init(IPLVLiveRoomDataManager liveRoomDataManager) {
this.liveRoomDataManager = liveRoomDataManager;
//创建播放器mvp-presenter
playbackPlayerPresenter = new PLVPlaybackPlayerPresenter(liveRoomDataManager);
//注册播放器mvp-view
playbackPlayerPresenter.registerView(playbackPlayerView);
//初始化播放器mvp-presneter
playbackPlayerPresenter.init();
//传递presenter给mediaController调用
mediaController.setPlaybackPlayerPresenter(playbackPlayerPresenter);
}
//创建播放器mvp-view
private IPLVPlaybackPlayerContract.IPlaybackPlayerView playbackPlayerView = new PLVAbsPlaybackPlayerView() {
//...
}
4.2.3 設定 PPTView 方法
PLVLCPlaybackMediaLayout 的 setPPTView 方法是對外 API,雲端課堂場景下,回放播放器需要關聯 PPTView,因此需要外部傳入 IPolyvPPTView 進行設定。
@Override
public void setPPTView(IPolyvPPTView pptView) {
playbackPlayerPresenter.bindPPTView(pptView);
}
4.2.4 開始播放方法
PLVLCPlaybackMediaLayout 的 startPlay 方法是對外 API,該方法內部會呼叫 PLVPlaybackPlayerPresenter 的 start 方法來進行影片的載入及播放。
@Override
public void startPlay() {
playbackPlayerPresenter.startPlay();
}
PLVLCPlaybackMediaLayout 內部持有 PLVPlaybackPlayerPresenter,因此除了內部可以自由呼叫播放器相關的方法外,也能將其封裝成介面提供給外層呼叫,startPlay 方法就是其中一個例子。
5 子目錄介紹
這裡的子目錄指的是雲端課堂場景播放器模組下的子目錄,對應專案中 polyvLiveCloudClassScene 模組裡套件名為 com.easfun.polyv.livecloudcalss.modules.nedia 套件下的子套件。
5.1 controller 目錄
//直播播放器控制栏接口
IPLVLCLiveMediaController
//回放播放器控制栏接口
IPLVLCPlaybackMediaController
//直播播放器控制栏接口实现类
PLVLCLiveMediaController
//回放播放器控制栏接口实现类
PLVLCPlaybackMediaController
該目錄主要是放置直播及回放控制列相關的類別。
5.2 danmu 目錄
//弹幕控制器接口
IPLVLCDanmuController
//横屏信息发送输入框布局接口
IPLVLCLandscapeMessageSender
//弹幕控制器接口实现类
PLVLCDanmuFragment
//横屏信息发送输入框布局接口实现类
PLVLCLandscapeMessageSendPanel
該目錄主要是放置彈幕相關的類別。
5.3 widget 目錄
//亮度手势提示view
PLVLCLightTipsView
//音频模式显示的view
PLVLCLiveAudioModeView
//直播"更多"布局的view
PLVLCLiveMoreLayout
//占位图view
PLVLCPlaceHolderView
//回放"更多"布局的view
PLVLCPlaybackMoreLayout
//快进/退手势提示view
PLVLCProgressTipsView
//缓冲中显示的view
PLVLCVideoLoadingLayout
//音量手势提示view
PLVLCVolumeTipsView
該目錄主要是放置播放器佈局中使用到的 view 元素。
