Polyv Help Center

Help Center

3_2-云课堂场景-播放器

Updated: 2023-04-17 15:27:57

1 Feature Overview

Video playback is a fundamental feature provided in multi-scenario projects. The cloud classroom scenario uses both a live player and a playback player. In the cloud classroom scenario module, the elements of the entire layout area of the live player are encapsulated as PLVLCLiveMediaLayout, and the elements of the entire layout area of the playback player are encapsulated as PLVLCPlaybackMediaLayout. They both implement the IPLVLCMediaLayout interface.

2 Usage Demo

The following example demonstrates how to create a live player layout and a playback player layout, along with their initialization and video playback. The code is as follows:

//播放器布局
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();
}

Specific use cases for the above methods can be found in the PLVLCCloudClassActivity within the polyv demo project.

3 Interface Introduction

3.1 IPLVLCMediaLayout

An interface encapsulating the player layout in the cloud classroom scenario. It defines:

  1. Methods called directly from external code
  2. Event listeners that require external responses
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 Implementation Introduction

4.1 PLVLCLiveMediaLayout

The live player layout in the cloud classroom scenario, implementing the IPLVLCMediaLayout interface.

The elements included in this layout are: live player, sub-player, landscape chat room area, danmu layout, brightness gesture layout, volume gesture layout, live control bar, and other UI elements that appear in the live playback area.

The following lists and introduces the main methods involved in this layout.

4.1.1 View Initialization Method

PLVLCLiveMediaLayout inherits from FrameLayout. In the constructor, the initView method is used to initialize 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 Data Initialization Method

The init method of PLVLCLiveMediaLayout is an external API. It requires the external input of IPLVLiveRoomDataManager for initialization.

//播放器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() {
     //...
}

Here, PLVLivePlayerPresenter is a player encapsulated using the mvp pattern. presenter isolates view and mode. All business logic is operated through presenter. That is, presenter acts as a bridge between the view and the data, with the view and data separated at both ends.

4.1.3 Setting the Landscape Control Bar Method

The setLandscapeControllerView method of PLVLCLiveMediaLayout is an external API. It requires the external input of IPLVLiveLandscapePlayerController for configuration. PLVLCLiveMediaLayout already includes a portrait control bar internally. Since the landscape control bar needs to be layered above the floating window and the microphone connection controller in the cloud classroom scenario, its position must be adjusted within the xml layout before being passed into PLVLCLiveMediaLayout.

@Override
public void setLandscapeControllerView(@NonNull IPLVLiveLandscapePlayerController landscapeControllerView) {
    mediaController.setLandscapeController(landscapeControllerView);
}
4.1.4 Start Playback Method

The startPlay method of PLVLCLiveMediaLayout is an external API. Internally, this method calls the start method of PLVLivePlayerPresenter to load and play the video.

@Override
public void startPlay() {
    livePlayerPresenter.startPlay();
}

PLVLCLiveMediaLayout internally holds PLVLivePlayerPresenter. Therefore, in addition to freely calling player-related methods internally, it can also encapsulate them into interfaces for external calls. The startPlay method is one such example.

4.2 PLVLCPlaybackMediaLayout

The playback player layout in the cloud classroom scenario, implementing the IPLVLCMediaLayout interface.

The elements included in this layout are: playback player, brightness gesture layout, volume gesture layout, fast forward/rewind gesture layout, playback control bar, and other UI elements that appear in the playback area.

The following lists and introduces the main methods involved in this layout.

4.2.1 View Initialization Method

PLVLCPlaybackMediaLayout inherits from FrameLayout. In the constructor, the initView method is used to initialize 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 Data Initialization Method

The init method of PLVLCPlaybackMediaLayout is an external API. It requires the external input of IPLVLiveRoomDataManager for initialization.

//播放器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 Setting the PPTView Method

The setPPTView method of PLVLCPlaybackMediaLayout is an external API. In the cloud classroom scenario, the playback player needs to be associated with the PPTView, so the external input of IPolyvPPTView is required for configuration.

@Override
public void setPPTView(IPolyvPPTView pptView) {
    playbackPlayerPresenter.bindPPTView(pptView);
}
4.2.4 Start Playback Method

The startPlay method of PLVLCPlaybackMediaLayout is an external API. Internally, this method calls the start method of PLVPlaybackPlayerPresenter to load and play the video.

@Override
public void startPlay() {
    playbackPlayerPresenter.startPlay();
}

PLVLCPlaybackMediaLayout internally holds PLVPlaybackPlayerPresenter. Therefore, in addition to freely calling player-related methods internally, it can also encapsulate them into interfaces for external calls. The startPlay method is one such example.

5 Subdirectory Introduction

The subdirectories here refer to the subdirectories under the cloud classroom scenario player module, corresponding to the sub-packages under the package named com.easfun.polyv.livecloudcalss.modules.nedia in the polyvLiveCloudClassScene module of the project.

5.1 controller Directory

//直播播放器控制栏接口
IPLVLCLiveMediaController
//回放播放器控制栏接口
IPLVLCPlaybackMediaController
//直播播放器控制栏接口实现类
PLVLCLiveMediaController
//回放播放器控制栏接口实现类
PLVLCPlaybackMediaController

This directory mainly contains classes related to the live and playback control bars.

5.2 danmu Directory

//弹幕控制器接口
IPLVLCDanmuController
//横屏信息发送输入框布局接口
IPLVLCLandscapeMessageSender
//弹幕控制器接口实现类
PLVLCDanmuFragment
//横屏信息发送输入框布局接口实现类
PLVLCLandscapeMessageSendPanel

This directory mainly contains classes related to danmu (bullet comments).

5.3 widget Directory

//亮度手势提示view
PLVLCLightTipsView
//音频模式显示的view
PLVLCLiveAudioModeView
//直播"更多"布局的view
PLVLCLiveMoreLayout
//占位图view
PLVLCPlaceHolderView
//回放"更多"布局的view
PLVLCPlaybackMoreLayout
//快进/退手势提示view
PLVLCProgressTipsView
//缓冲中显示的view
PLVLCVideoLoadingLayout
//音量手势提示view
PLVLCVolumeTipsView

This directory mainly contains view elements used in the player layout.

联系客服,在线咨询