最近更新时间:2023.07.06 19:24:46
首次发布时间:2022.07.13 16:53:50
本文介绍了如何接入 Android 观播 SDK,以及如何实现功能定制和横屏直播间 UI 定制。
您可以选择以下接入方式,实现观播功能。
该方式适用于接入完整直播间功能的场景,只需少量代码即可接入直播间。
调用 joinLiveRoom 进入直播间,观看直播。
说明
通过调用 CreateActivityAPIV2 或 ListActivityAPI 获取直播间 ID,调用 GetSDKTokenAPI 获取进入直播间所需的授权 Token。
long activityId=1721010849258****; // 直播间 ID String token="pg****"; // 直播间所需的授权 Token /** * roomAuthMode 包含 PUBLIC 和 CUSTOM 两种模式。具体选择哪种取决于 GetSDKTokenAPI 传入的 mode 参数的值。 * mode=1:选择 PUBLIC * mode=2:选择 CUSTOM */ TVULiveRoom.TVURoomAuthMode roomAuthMode = TVULiveRoom.TVURoomAuthMode.PUBLIC; boolean isPortrait=true/false;//true:竖屏直播间;false:横屏直播间 //进入直播间 TVULiveRoom.joinLiveRoom(context, activityId, token, roomAuthMode, isPortrait)
调用 leaveLiveRoom 退出直播间。
//退出直播间 TVULiveRoom.leaveLiveRoom(Context context)
请在进入直播间前对直播间进行定制化设置。详情请参见功能定制。
如果无需使用当前悬浮窗,请及时对其进行销毁。
TVULiveRoom.destroyFloatWindow()
独立播放器 TVUSinglePlayerView
实例满足了自定义视频控制界面的需求。TVUSinglePlayerView
实例包含 TextureView
和视频封面图两个元素,并暴露了部分接口和事件供调用和监听,方便将独立播放器嵌入您自己的页面以及定制视频的控制栏。
Demo
创建 TVULiveRoomServer
实例(即直播间 Server),初始化独立播放器 TVUSinglePlayerView
实例,并将二者绑定。启动 TVULiveRoomServer
实例后,播放器会自动播放视频。
/** * SERVER_TYPE_LIVEROOM:完整直播间类型。如需在独立播放器的基础上,绑定聊天互动菜单、人气等直播间组件,请设置为该类型 * SERVER_TYPE_SINGLE:独立播放器类型。如只需接入独立播放器,而无需绑定聊天互动菜单、人气等直播间组件,请设置为该类型 * activityId:直播间 ID * token:进入直播间所需的授权 Token */ // 确保在调用 Activity.setContentView 方法前,创建 TVULiveRoomServer 实例 roomServer = new TVULiveRoomServer(this, activityId, token, TVULiveRoomServer.SERVER_TYPE_LIVEROOM); roomServer.setRoomAuthMode(isPublic ? TVULiveRoom.TVURoomAuthMode.PUBLIC : TVULiveRoom.TVURoomAuthMode.CUSTOM); // 初始化 TVUSinglePlayerView 实例 videoView = findViewById(R.id.video_view); InitConfig initConfig = new InitConfig(); initConfig.singlePlayerListener = new SinglePlayerListener() videoView.init(initConfig); // 绑定 TVUSinglePlayerView 实例和 TVULiveRoomServer 实例,并启动 TVULiveRoomServer 实例 roomServer.setPlayerView(videoView.getInnerPlayerView()); roomServer.start();
说明
setRoomAuthMode
,详见 setRoomAuthMode。在 TVULiveRoomServer
实例启动成功后,您可以调用相关方法实现播放器控制,详见 TVUSinglePlayerView。
如需监听独立播放器的事件,详见 SinglePlayerListener。
调用 .closeRoom
方法退出直播间后,与 TVULiveRoomServer
实例绑定的 TVUSinglePlayerView
实例会自动销毁。
@Override protected void onDestroy() { super.onDestroy(); // 在 TVULiveRoomServer 实例所在页面的 Activity 销毁时,退出直播间 roomServer.closeRoom(); }
该方式适用于接入直播间的单独模块。您需要在 layout.xml
文件里引入对应模块,同时创建一个 TVULiveRoomServer
实例。
说明
目前仅支持接入播放器模块。
// 设置定制项(不设置则为默认样式)。详情请参见下文中的功能定制。 CustomSettings.Holder.mSettings.setXXX...; // 创建一个 TVULiveRoomServer 实例 // activityId:直播间 ID // token:进入直播间所需的授权 Token TVULiveRoomServer mServer = new TVULiveRoomServer(this, activityId, token); // 引入 PlayerView 实例 Pl ayerView view = findViewById(R.id.player_view); // 设置 PlayerView 实例 mServer.setPlayerView(view); // 设置监听器 mServer.setListener(new ITVULiveRoomServerListener(){}); // 设置直播间 roomAuthMode(公开或自定义) mServer.setRoomAuthMode(roomAuthMode); // 加载播放器 mServer.start();
说明
roomAuthMode
的设置,详见 setRoomAuthMode。在 layout.xml
文件的 <include>
参数中做如下设置,引入播放器模块:
<include android:id="@+id/player_view" // 自定义 ID layout="@layout/tvu_player_layout" />
用于监听 TVULiveRoomServer
实例的回调类,获取该实例相关事件的回调通知。
public interface ITVULiveRoomServerListener { // 直播间信息获取成功 /** * @param activityResult 返回的服务端直播间数据 */ void onGetRoomDataSuccess(ActivityResult activityResult){ }; // 直播间信息获取失败 /** * errCode:错误码 ERR_BAD_DATA = 0; // 解析服务端数据失败 ERR_LIMITED_ROOM = 1; // 该直播间禁止手机观看 errMsg:失败原因 */ void onGetRoomDataFailed(int errCode, String errMsg); /** * 播放器全屏、退出全屏图标点击回调 * 实现横竖屏切换、状态栏的显示或隐藏等,并调用 adjustPlayer 方法自定义播放器尺寸 */ public void onFullScreenChange() { if (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT == getRequestedOrientation(){ //当前为竖屏,切换为横屏 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // 全屏状态,隐藏状态栏 WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN; getWindow().setAttributes(lp); getSupportActionBar().hide(); //调整播放器尺寸 mServer.adjustPlayer(activity, 0, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); } else { //当前为横屏,切换为竖屏 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); // 显示状态栏 WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().setAttributes(lp); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); getSupportActionBar().show(); //显示导航栏 View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility(0); //调整播放器尺寸 mServer.adjustPlayer(activity, 0, 200, ViewGroup.LayoutParams.MATCH_PARENT); } } // 直播状态变化回调 // LIVE(1):直播中 // FORE_SHOW(2):预告 // PLAYBACK(3):回放 // END(4):已结束 void liveRoomStatusChange(int value); /** * 播放状态变化回调 * @param playerStatus 0:暂停 1:播放 */ void playerStatusChange(int playerStatus); /** * 播放器倍速按钮点击回调 * 定制需求 */ void onSpeedButtonDidTouch(){ Log.i(TAG, "speedButtonDidTouch"); Toast.makeText(getBaseContext(), "点击【倍速】", Toast.LENGTH_LONG).show(); } /** * 播放器重放按钮点击回调 * 定制需求 */ void onReplayButtonDidTouch(){ Log.i(TAG, "replayButtonDidTouch"); Toast.makeText(getBaseContext(), "点击【重新播放】", Toast.LENGTH_LONG).show(); } }
在 TVULiveRoomServer
实例创建成功后,通过该实例调用以下方法:
adjustPlayer
调整播放器布局,适用于自定义横竖屏切换的场景。单位:px
/** * @param screenOrientation 0:横屏 1:竖屏 * @param horizontalMargin 外边距 * @param height 高 * @param width 宽 */ mServer.adjustPlayer(int screenOrientation, int horizontalMargin, int height, int width)
play
播放视频。
mServer.play()
pause
暂停视频。
mServer.pause()
onPause
停止直播间网络请求,暂停播放视频。适用于当前直播间的 Activity 被切换到后台的场景。
mServer.onPause()
onResume
打开直播间网络请求,继续播放视频。适用于原直播间的 Activity 被切换回前台的场景。
mServer.onResume()
退出直播间时调用。
mServer.closeRoom()
您可以调用 CustomSettings.Holder.mSettings.set
方法定制直播间以下各项的显示效果:
说明
请在进入直播间或初始化播放器前设置。
具体方法说明,请参见 mSettings 类的相关方法。
在完成标准化接入后,您可以通过添加自定义 UI 组件,自定义横屏直播间的 UI。
TvuLivePlayerLayoutBinding
实例触发 onLandLiveRoomBindingAvailable
回调后,获取到 TvuLivePlayerLayoutBinding
类型的 binding
来自定义横屏直播间 UI。详见 onLandLiveRoomBindingAvailable。
public interface LiveRoomStatusListener { ... default void onLandLiveRoomBindingAvailable(TvuLivePlayerLayoutBinding binding, LanguageManager languageManager) { } ... }
TvuLivePlayerLayoutBinding
实例的 UI 结构如下:
rootContainer(FrameLayout) |-- contentContainer(LinearLayout) |-- headContainer(LinearLayout) |-- headTvuContainer |-- livePlayerContainer(FrameLayout) |-- livePlayerCardView(TVUAspectRatioCardView) |-- tvu_player_view(PlayerView) |-- midContainer(LinearLayout) |-- midTvuContainer |-- bottomTvuMenuContainer |-- floatingContainer(FrameLayout) |-- tvuFloatingViewsContainer
contentContainer
(内容区域)包含 head
(headContainer)、播放器(livePlayerContainer)、mid
(midContainer)和 bottomMenu
(bottomTvuMenuContainer)四个区域。floatingContainer
(悬浮区域)的层级在 contentContainer
之上。您可以通过隐藏默认组件并添加自定义 UI 组件来替换横屏直播间的 UI 组件。
注意
不需要的默认 UI 组件不可移除,否则会导致空指针异常。
以下示例替换了横屏直播间的 head 区域并修改了播放器尺寸:
public void custom(TvuLivePlayerLayoutBinding binding) { // 隐藏横屏直播间默认的 head 组件 binding.headTvuContainer.setVisibility(View.GONE); // 引入自定义的 head 组件 View customHeadView = inflater.inflate(R.layout.include_custom_header, binding.headContainer, false); customHeadView.findViewById(R.id.back_btn).setOnClickListener(v -> { TVULiveRoom.manualClickLiveRoomExitBtn(context); }); customHeadView.findViewById(R.id.share_btn).setOnClickListener(v -> { ToastUtil.displayToast("点击了分享"); }); // 添加自定义的 head 组件 binding.headContainer.addView(customHeadView); ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) binding.livePlayerContainer.getLayoutParams(); // 去掉播放器的左右外边距和上下左右内边距 params.leftMargin = params.rightMargin = 0; binding.livePlayerContainer.setLayoutParams(params); binding.livePlayerContainer.setPadding(0, 0, 0, 0); // 将播放器尺寸设置为 16:9 binding.livePlayerCardView.setResizeMode(TVUAspectRatioFrameLayout.RESIZE_MODE_FIXED_WIDTH); binding.livePlayerCardView.setWidthRatio(16); binding.livePlayerCardView.setHeightRatio(9); // 去掉播放器的圆角 binding.livePlayerCardView.setRadius(0); }
通过 LanguageManager.LanguageManagerListener
监听器监听到观看页语言变化后,改变自定义组件的多语言。
LanguageManager.LanguageManagerListener listener = new LanguageManager.LanguageManagerListener() { @Override public void onLanguageChanged(LanguageManager.LANGUAGE language, int languageIdx, Properties properties) { // 监听到观看页语言变化后,改变自定义组件的多语言 switch (language) { case ZH_HANS: break; case EN: break; default: } } }; // 添加监听器 languageManager.addListener(listener); // 移除监听器 languageManager.removeListener(listener);