You need to enable JavaScript to run this app.
导航

使用 SDK

最近更新时间2024.03.05 11:07:46

首次发布时间2022.07.13 16:53:50

本文介绍了 Android 观播 SDK 的接入方式,以及如何实现功能定制和横竖屏直播间 UI 定制。

接入方式

您可以选择以下接入方式,实现观播功能。

标准化接入

该方式适用于接入完整直播间功能的场景,只需少量代码即可接入直播间。

进入直播间

调用 joinLiveRoom 进入直播间,观看直播。

说明

通过调用 CreateActivityAPIV2ListActivityAPI 获取直播间 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();        

说明

播放器控制和监听

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();

说明

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 方法定制直播间以下各项的显示效果:

  • 字体:通过 TypeFace 设置字体。
  • 字号:通过 Integer 类型的值设置字号。单位:sp。
  • 图片:通过 Drawable 对象设置图片。支持 PNG 和 JPG 格式的图片。
  • 颜色:通过 Integer 类型的值设置颜色,例如白色为 0xFFFFFFFF。
  • 其他。

说明

请在进入直播间或初始化播放器前设置。

具体方法说明,请参见 mSettings 类的相关方法

横屏直播间 UI 定制

在完成标准化接入后,您可以自定义横屏直播间的 UI。

步骤一:获取 TvuLivePlayerLayoutBinding 实例

SDK 触发 onLandLiveRoomBindingAvailable 回调后,您可以通过获取到的 ViewBinding 实例自定义横屏直播间的 UI。详见 onLandLiveRoomBindingAvailable

public interface LiveRoomStatusListener {
    ...
    default void onLandLiveRoomBindingAvailable(TvuLivePlayerLayoutBinding binding, LanguageManager languageManager) {
    }
    ...
}

获取到的 ViewBinding 实例 UI 结构如下所示。
图片

rootContainer(FrameLayout)
|-- contentContainer(LinearLayout)
    |-- headContainer(LinearLayout)
        |-- headTvuContainer
    |-- livePlayerContainer(FrameLayout)
        |-- livePlayerCardView(TVUAspectRatioCardView)
            |-- tvu_player_view(PlayerView)
    |-- midContainer(LinearLayout)
        |-- midTvuContainer     
    |-- bottomTvuMenuContainer        
|-- floatingContainer(FrameLayout)
    |-- tvuFloatingViewsContainer
  • contentContainer(内容区域)包含 headheadContainer)、播放器(livePlayerContainer)、midmidContainer)和 bottomMenubottomTvuMenuContainer)四个区域。
  • floatingContainer(悬浮区域)的层级在 contentContainer 之上。

替换 UI 组件

您可以通过隐藏默认组件并添加自定义 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);
}

添加自定义悬浮 View 组件

floatingContainer 用于存放直播间的悬浮 View 组件,并提供 addChildViewInFrameLayoutaddChildViewInLinearLayout 方法添加自定义悬浮 View 组件。
以下示例代码通过 setLiveRoomStatusListener 方法、onLandLiveRoomBindingAvailable 回调以及 addChildViewInLinearLayout 方法,在横屏直播间的 floatingContainer 中添加了自定义悬浮 View 组件。

// CustomSettings.Holder.mSettings.setLiveRoomStatusListener
// ...
@Override
public void onLandLiveRoomBindingAvailable(TvuLivePlayerLayoutBinding binding, LanguageManager languageManager)
    // 通过 findViewById 方法找到 floatingContainer。floatingContainer 在 Activity 中的 view id 为 R.id.tvu_floating_views_container。
    FloatingContainer floatingContainer = binding.getRoot().findViewById(R.id.tvu_floating_views_container);
    // 在 floatingContainer 中添加 TextView 组件。
    TextView textView = new TextView(binding.getRoot().getContext());
    textView.setText("Hello World");
    floatingContainer.addChildViewInLinearLayout(textView,true,false,
            new CustomSize(20,20));
}
// ...

addChildViewInFrameLayout

floatingContainer 中添加自定义悬浮 View 组件。该 View 组件不与 floatingContainer 中 SDK 默认的 View 组件进行位置联动,展示位置仅由 View 组件的配置决定。

说明

SDK 默认的 View 组件目前包含整组互动工具图标、商品浮窗以及浮标广告。

public void addChildViewInFrameLayout(View childView, SimpleLayoutParams layoutParams)

参数

名称

类型

说明

childView

View

要添加的 View 组件。

layoutParams

SimpleLayoutParams

要添加的 View 组件的位置。

addChildViewInLinearLayout

floatingContainer 中添加自定义悬浮 View 组件。该 View 组件与 floatingContainer 中 SDK 默认的 View 组件进行位置联动,即参与 View 组件展示顺序的重新排列。

说明

SDK 默认的 View 组件目前包含整组互动工具图标、商品浮窗以及浮标广告。

public void addChildViewInLinearLayout(View childView, boolean isLeftTop, boolean isLastChild, CustomSize customSize)

参数

名称

类型

说明

childView

View

要添加的 View 组件。

isLeftTop

Boolean

要添加的 View 组件在直播间的显示位置。

  • true:显示在直播间左上方。与竖屏直播间的整组互动工具图标进行位置联动。
  • false:显示在直播间右下方。与商品浮窗、浮标广告以及横屏直播间的整组互动工具图标进行位置联动。

isLastChild

Boolean

要添加的 View 组件与其他 View 组件的展示顺序。

  • true:展示在所有 View 组件的最下方。
  • false:展示在所有 View 组件的最上方。

customSize

CustomSize

要添加的 View 组件的大小。

(可选)步骤二:配置多语言

通过 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);

竖屏直播间 UI 定制

步骤一:获取 TvuPortraitLiveRoomLayoutBinding 实例

SDK 触发 onPortraitLiveRoomBindingAvailable 回调后,您可以通过获取到的 ViewBinding 实例自定义竖屏直播间的 UI。详见 onPortraitLiveRoomBindingAvailable

public interface LiveRoomStatusListener {
    ...default void onPortraitLiveRoomBindingAvailable(TvuPortraitLiveRoomLayoutBinding binding, LanguageManager languageManager) {
    }
    ...
}

获取到的 ViewBinding 实例 UI 结构如下所示。
图片

rootLayout(FrameLayout)
|-- portraitCommentListArea(LinearLayout)
|-- portraitLiveRoomBottomBarLayout(PortraitLiveRoomBottomBarLayout)         
|-- floatingContainer(FloatingContainer)

floatingContainer(悬浮区域)的层级在 portraitCommentListArea(评论区域) 和 portraitLiveRoomBottomBarLayout(底部图标区域)之上。

替换直播间底部图标的点击事件

portraitLiveRoomBottomBarLayout 用于存放竖屏直播间底部的图标,并提供 setBottomOnClickListener 方法将指定图标的点击事件替换为自定义的点击事件。观众点击图标触发自定义的点击事件后,即可执行自定义的点击行为。
以下示例代码通过 setLiveRoomStatusListener 方法、onPortraitLiveRoomBindingAvailable 回调以及 setBottomOnClickListener 方法,替换了竖屏直播间底部图文介绍图标的点击事件并自定义了点击事件触发后的点击行为。

// CustomSettings.Holder.mSettings.setLiveRoomStatusListener
// ...
@Override
public void onPortraitLiveRoomBindingAvailable(TvuPortraitLiveRoomLayoutBinding binding, LanguageManager languageManager) {
   // 通过 findViewById 方法找到 portraitLiveRoomBottomBarLayout。portraitLiveRoomBottomBarLayout 在 Activity 中的 view id 为 R.id.portrait_bottom_bar。
    PortraitLiveRoomBottomBarLayout portraitLiveRoomBottomBarLayout = findViewById(R.id.portrait_bottom_bar);
    // 将竖屏直播间底部图标的点击事件替换为您自定义的点击事件。此处以替换图文介绍图标的点击事件为例。
    portraitLiveRoomBottomBarLayout.setBottomOnClickListener(PortraitLiveRoomBottomBarLayout.BottomBar.IMAGE_TEXT_ICON, new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            // 触发图文介绍图标的点击事件后,执行自定义的点击行为。
             ToastUtil.displayToast("点击了图文介绍按钮");
        }
    });
}

setBottomOnClickListener

将竖屏直播间底部图标的点击事件替换为您自定义的点击事件。观众点击图标触发自定义的点击事件后,即可执行自定义的点击行为。

public void setBottomOnClickListener(PortraitLiveRoomBottomBarLayout.BottomBar bottomBar, View.OnClickListener listener)

参数

名称

类型

说明

bottomBar

PortraitLiveRoomBottomBarLayout.BottomBar

竖屏直播间底部的图标。

listener

View.OnClickListener

用于自定义图标的点击行为。

添加自定义悬浮 View 组件

以下示例代码通过 setLiveRoomStatusListener 方法、onPortraitLiveRoomBindingAvailable 回调以及 addChildViewInLinearLayout 方法,在竖屏直播间的 floatingContainer 中添加了自定义悬浮 View 组件。

// CustomSettings.Holder.mSettings.setLiveRoomStatusListener
// ...
@Override
public void onPortraitLiveRoomBindingAvailable(TvuPortraitLiveRoomLayoutBinding binding, LanguageManager languageManager) {
    // 通过 findViewById 方法找到 floatingContainer。floatingContainer 在 Activity 中的 view id 为 R.id.tvu_floating_views_container。
    FloatingContainer floatingContainer = binding.getRoot().findViewById(R.id.tvu_floating_views_container);
    // 在 floatingContainer 中添加 TextView 组件。
    TextView textView = new TextView(binding.getRoot().getContext());
    textView.setText("Hello World");
    floatingContainer.addChildViewInLinearLayout(textView,true,false,
            new CustomSize(20,20));
}
// ...

(可选)步骤二:配置多语言

通过 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);