5_2-手机开播场景-连麦推流
1 功能概述
推流與連麥模組是手機開播場景中的基礎功能,支援攝影機參數設定、音訊參數設定、視訊參數設定等。推流可用於講師上課,連麥支援音訊連麥、視訊連麥可自由選擇,並支援多人連麥,豐富課堂內容。
推流流程:初始化推流引擎 -> 設定推流配置參數 -> 開始推流。
連麥流程:講師端發起連麥 -> 學員舉手申請連麥 -> 講師端允許學員連麥 -> 學員正式加入連麥。
2 使用演示
以下範例如何建立推流與連麥佈局,以及如何呼叫初始化方法,程式碼如下:
// 推流和连麦布局
private IPLVLSStreamerLayout plvlsStreamerLy;
// findView
plvlsStreamerLy = findViewById(R.id.plvls_streamer_ly);
// 初始化推流和连麦布局
plvlsStreamerLy.init(liveRoomDataManager);
上述方法的具體用例可在 polyv demo 專案中的 PLVLSLiveStreamerActivity 找到。
3 介面介紹
3.1 IPLVLSStreamerLayout
手機開播場景下,針對推流與連麥佈局進行封裝的介面,定義了外部直接呼叫的方法。
public interface IPLVLSStreamerLayout {
/**
* 初始化
*
* @param liveRoomDataManager 直播间数据管理器
*/
void init(IPLVLiveRoomDataManager liveRoomDataManager);
/**
* 开始上课
*/
void startClass();
/**
* 停止上课
*/
void stopClass();
/**
* 设置推流码率
*
* @param bitrate 码率
*/
void setBitrate(@PLVSStreamerConfig.BitrateType int bitrate);
/**
* 获取推流的码率信息
*
* @return 码率信息<最大支持码率, 选择码率>
*/
Pair<Integer, Integer> getBitrateInfo();
/**
* 是否允许录制声音
*
* @param enable true:允许,false:不允许
*/
boolean enableRecordingAudioVolume(boolean enable);
/**
* 是否允许录制视频/打开摄像头
*
* @param enable true:允许,false:不允许
*/
boolean enableLocalVideo(boolean enable);
/**
* 设置相机方向
*
* @param front true:前置,false:后置
*/
boolean setCameraDirection(boolean front);
/**
* 控制成员列表中的用户加入或离开连麦
*
* @param position 列表中的位置
* @param isAllowJoin true:加入,false:离开
*/
void controlUserLinkMic(int position, boolean isAllowJoin);
/**
* 禁/启用用户媒体
*
* @param position 成员列表中的位置
* @param isVideoType true:视频,false:音频
* @param isMute true:禁用,false:启用
*/
void muteUserMedia(int position, boolean isVideoType, boolean isMute);
/**
* 下麦全体连麦用户
*/
void closeAllUserLinkMic();
/**
* 全体连麦用户禁用/开启声音
*
* @param isMute true:禁用,false:开启
*/
void muteAllUserAudio(boolean isMute);
/**
* 添加推流状态的监听器
*
* @param listener 监听器
*/
void addOnStreamerStatusListener(IPLVOnDataChangedListener<Boolean> listener);
/**
* 添加网络状态监听器
*
* @param listener 监听器
*/
void addOnNetworkQualityListener(IPLVOnDataChangedListener<Integer> listener);
/**
* 添加推流时间监听器
*
* @param listener 监听器
*/
void addOnStreamerTimeListener(IPLVOnDataChangedListener<Integer> listener);
/**
* 因断网延迟20s断流的状态
*
* @param listener 监听器
*/
void addOnShowNetBrokenListener(IPLVOnDataChangedListener<Boolean> listener);
/**
* 添加音频状态监听器
*
* @param listener 监听器
*/
void addOnEnableAudioListener(IPLVOnDataChangedListener<Boolean> listener);
/**
* 添加视频状态监听器
*
* @param listener 监听器
*/
void addOnEnableVideoListener(IPLVOnDataChangedListener<Boolean> listener);
/**
* 添加摄像头方向监听器
*
* @param listener 监听器
*/
void addOnIsFrontCameraListener(IPLVOnDataChangedListener<Boolean> listener);
/**
* 获取网络质量
*
* @return 网络质量常量
*/
int getNetworkQuality();
/**
* 是否推流开始成功
*
* @return true:成功,false:未成功
*/
boolean isStreamerStartSuccess();
/**
* 获取推流和连麦的presenter
*
* @return presenter
*/
IPLVStreamerContract.IStreamerPresenter getStreamerPresenter();
/**
* 销毁,释放资源
*/
void destroy();
}
4 實作介紹
4.1 PLVLSStreamerLayout
該類別是手機開播場景下的推流與連麥佈局,實作 IPLVLSStreamerLayout 介面。
該佈局包含講師的推流攝影機畫面、音訊開關狀態、講師頭銜、暱稱以及其他已連麥觀眾的相關資訊的 UI。
下面會列舉介紹該佈局中涉及到的主要方法。
4.1.1 初始化 view 方法
PLVLSStreamerLayout 繼承於 FrameLayout,在建構子中使用 initView 方法對 view 進行了初始化處理。
public PLVLSStreamerLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
//填充推流和连麦布局到该view中
LayoutInflater.from(getContext()).inflate(R.layout.plvls_streamer_layout, this);
//推流和连麦的列表视图
plvlsStreamerRv = findViewById(R.id.plvls_streamer_rv);
//init RecyclerView
plvlsStreamerRv.setLayoutManager(new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false));
plvlsStreamerRv.addItemDecoration(new PLVMessageRecyclerView.SpacesItemDecoration(ConvertUtils.dp2px(8), 0));
//禁用RecyclerView默认动画
plvlsStreamerRv.getItemAnimator().setAddDuration(0);
plvlsStreamerRv.getItemAnimator().setChangeDuration(0);
plvlsStreamerRv.getItemAnimator().setMoveDuration(0);
plvlsStreamerRv.getItemAnimator().setRemoveDuration(0);
RecyclerView.ItemAnimator rvAnimator = plvlsStreamerRv.getItemAnimator();
if (rvAnimator instanceof SimpleItemAnimator) {
((SimpleItemAnimator) rvAnimator).setSupportsChangeAnimations(false);
}
//init adapter
streamerAdapter = new PLVLSStreamerAdapter(plvlsStreamerRv, new PLVLSStreamerAdapter.OnStreamerAdapterCallback() {
@Override
public SurfaceView createLinkMicRenderView() {
return streamerPresenter.createRenderView(Utils.getApp());
}
@Override
public void setupRenderView(SurfaceView surfaceView, String linkMicId) {
streamerPresenter.setupRenderView(surfaceView, linkMicId);
}
});
//启动前台服务
PLVLSForegroundService.startService();
}
4.1.2 初始化資料方法
PLVLSStreamerLayout 的 init 方法是對外 API,需要外部傳入 IPLVLiveRoomDataManager 後進行初始化。
//推流和连麦presenter
private IPLVStreamerContract.IStreamerPresenter streamerPresenter;
@Override
public void init(IPLVLiveRoomDataManager liveRoomDataManager) {
this.liveRoomDataManager = liveRoomDataManager;
//创建推流和连麦mvp-presenter
streamerPresenter = new PLVStreamerPresenter(liveRoomDataManager);
//注册推流和连麦mvp-view
streamerPresenter.registerView(streamerView);
//初始化推流和连麦mvp-presenter
streamerPresenter.init();
}
//创建推流和连麦的mvp-view
private PLVAbsStreamerView streamerView = new PLVAbsStreamerView() {
//...
}
這裡的 PLVStreamerPresenter 是使用 mvp 模式封裝的推流與連麥 presenter,用 presenter 將 view 和 mode 隔離開來,一切業務邏輯都是透過 presenter 來進行操作,也就是說 presenter 是視圖與資料的橋樑,視圖和資料相隔兩端。
4.1.3 開始上課方法
PLVLSStreamerLayout 的 startClass 方法是對外 API,該方法內部會呼叫 PLVStreamerPresenter 的 startLiveStream 方法來進行推流到登入的頻道。
@Override
public void startClass() {
streamerPresenter.startLiveStream();
}
PLVLSStreamerLayout 內部持有 PLVStreamerPresenter,因此除了內部可以自由呼叫推流與連麥相關的方法外,也能將其封裝成介面提供給外層呼叫,startClass 方法就是其中一個例子。
4.1.4 停止上課方法
停止上課方法為 stopClass,該方法是對外 API,內部會呼叫 PLVStreamerPresenter 的 stopLiveStream 方法停止推流。
@Override
public void stopClass() {
streamerPresenter.stopLiveStream();
}
5 子目錄介紹
這裡的子目錄指的是手機開播場景推流與連麥模組下的子目錄,對應專案中 polyvLiveStreamerScene 模組包名為 com.easefun.polyv.livestreamer.modules.streamer 下的子包。
5.1 adapter 目錄
//推流和连麦列表适配器
PLVLSStreamerAdapter
該目錄主要放置推流與連麥功能的一些列表相關的適配器。
5.2 service 目錄
//前台服务。防止华为机型上锁屏超过1分钟导致摄像头预览画面卡住和断流
PLVLSForegroundService
該目錄主要放置推流與連麥功能使用到的一些服務。
