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

进阶功能

最近更新时间2024.04.15 18:16:49

首次发布时间2024.04.15 18:16:49

本文介绍 Android 观播 SDK 进阶功能的接入方法。您可以根据实际业务需求,按需实现复杂功能。

前提条件

功能列表

本文介绍以下功能的接入方法。

自定义登录

如果您需要观众先登录您的 App 再观看直播或参与评论、互动等操作,可以选择自定义登录方式,观众可以使用在您 App 中的身份信息进入直播间。
您可以按需选择观众在您 App 的登录时机。

  • 观众先完成登录,再进入直播间。
    图片

    1. 观众登录 App 并进入直播间后,您需通过调用 GetSDKTokenAPI 接口获取 mode=2 时的授权 Token。
    2. 获取 Token 后,调用 SDK 的 joinLiveRoom 方法进入直播间。

    示例代码如下所示。

    long activityId = 1721010849258****;  // 直播间的活动 ID。
    String token = "ak3T%2FdaGJDL5zSFD7%2F1GPGP****wx0zaTfQ1M4Dahp8%3D";  // mode=2 时的授权 Token。
    TVULiveRoom.TVURoomAuthMode roomAuthMode = TVULiveRoom.TVURoomAuthMode.CUSTOM; // 自定义模式。
    boolean isPortrait = true; // 竖屏直播间。
    TVULiveRoom.joinLiveRoom(context, activityId, token, roomAuthMode, isPortrait);
    
  • 观众先进入直播间观看直播、查看评论等,在参与评论、互动等操作时触发登录流程,将鉴权模式从公开模式切换为自定义模式。
    图片

    1. 观众先以公开模式进入直播间。
    2. 您需自行实现获取公开模式 Token 的方法,通过调用 GetSDKTokenAPI 接口请求 mode=1 时的授权 Token。
    3. 调用 setCustomLoginListener 方法,设置公开模式下登录自有账号系统的监听器。
    4. 调用 SDK 的 joinLiveRoom 方法进入直播间。
    5. 在观众进行以下需要用户信息的操作时,会触发 App 的自定义登录流程:
      • 点击聊天互动或私聊互动菜单的评论输入框
      • 点赞评论
      • 答题
      • 投票
      • 抽奖
      • 实名问卷
      • 观众连麦
      • 分享二维码、链接或邀请海报(仅在直播分享开启强制登录时会触发自定义登录流程)
    6. SDK 触发 onCustomLoginStart 回调,通知您的 App 观众需进行自定义登录。您需要自行实现获取自定义模式 Token 的方法,并在观众完成自定义登录后,通过调用 GetSDKTokenAPI 接口请求 mode=2 时的授权 Token。
    7. 观众自定义登录成功、失败或取消自定义登录后,触发 onLoginFinished 回调,告知 SDK 观众的登录结果。
      • 自定义登录成功:将自定义模式 Token 传入 SDK。
      • 自定义登录失败或取消自定义登录:传入 Null 到 SDK。
    8. SDK 通过 Token 向企业直播请求观众信息。
    9. 企业直播验证 Token 合法后,将观众信息传入 SDK。如果 Token 验证失败或为空,则将报错信息传入 SDK。

    示例代码如下所示。

    // 设置公开模式下登录自有账号系统的监听器。
    CustomSettings settings = CustomSettings.Holder.mSettings;
    settings.setCustomLoginListener((context, activityId, callBack) -> {
        // 触发 onCustomLoginStart 回调后,执行 App 的自定义登录逻辑。此处以弹出自定义登录对话框为例。您可以按需跳转至指定自定义登录页面。
        new AlertDialog.Builder(context)
                .setTitle("自定义登录")
                .setView(editText)
                .setCancelable(false)
                .setPositiveButton(android.R.string.yes, (dialog, which) -> {
                    // 此处以需要观众输入 Token 为例。观众自定义登录成功,触发 onLoginFinished 回调,将自定义模式 Token 传入 SDK。在传入前,调用 URLDecoder.decode 方法对 Token 进行解码。
                    String token = editText.getText().toString().trim();
                    callBack.onLoginFinished(URLDecoder.decode(token));
                })
                // 观众自定义登录失败或取消自定义登录,触发 onLoginFinished 回调,传入 Null 到 SDK。
                .setNegativeButton(android.R.string.no, ((dialog, which) -> callBack.onLoginFinished(null)))
                .setIcon(android.R.drawable.ic_dialog_alert)
                .show();
    });       
    

自定义跳转逻辑

观众在点击菜单内商品卡片、浮窗商品卡片、页头广告、页中广告、浮标广告、主播账号头像、评论中的 URL 时,SDK 会执行后续默认的跳转行为。

说明

调用 setRedirectPageListener 方法,设置直播间内的链接点击事件监听器后,观众在点击商品卡片、页头广告等时,SDK 会触发 redirectPage 回调。您可以通过返回值,决定在执行自定义跳转逻辑时,是否拦截后续默认的跳转行为。

  • 返回 true:拦截,即不执行默认的跳转行为。
  • 返回 false:不拦截,即执行默认的跳转行为。

以下示例代码在观众点击浮标广告、菜单内商品卡片和浮窗商品卡片时仅执行自定义跳转逻辑,在观众点击页头广告、页中广告、浮标广告、主播账号头像、评论中的 URL 时会同时执行自定义跳转逻辑和默认的跳转行为。

// 设置直播间内的链接点击事件监听器。
CustomSettings.Holder.mSettings.setRedirectPageListener(new RedirectPageListener() {
    /**
     *
     * @param liveActivity 直播间所在的 Activity。
     * @param redirectInfo 实现自定义跳转逻辑所需的信息。
     * @return 是否拦截后续 SDK 的默认跳转行为。true:拦截,SDK 不会执行后续默认的跳转行为。false:不拦截,SDK 会执行后续默认的跳转行为。
     */
    @Override
    public boolean redirectPage(Activity liveActivity, RedirectInfo redirectInfo) {
        // 通过 entrance 字段查看点击事件入口。
        String entrance = redirectInfo.getEntrance();
        switch (redirectInfo.getContentType()) {
            case RedirectInfo.CONTENT_TYPE_URL:
                // 当内容类型为 URL 时,获取 urlRedirectInfo 字段。
                UrlRedirectInfo urlRedirectInfo = redirectInfo.getUrlRedirectInfo();
                // 在点击浮标广告时
                if (entrance.equals(Entrance.FLOATING_ADVERTISEMENT.value)) {
                    // 执行自定义跳转逻辑。此处以弹出 SDK 内部的 WebViewDialog 为例。您也可以使用自定义的 Dialog。
                    new CommonWebViewDialog(liveActivity, urlRedirectInfo.getUrl(),
                            com.bytedance.live.sdk.R.style.TvuLiveBottomDialog).show();
                    // 执行自定义跳转逻辑,但不执行默认的跳转行为。
                    return true;
                }
                // 在点击菜单内商品卡片或浮窗商品卡片时
                if (entrance.equals(Entrance.FLOATING_SHOPPING_CARD.value)) {
                    String productUrl = urlRedirectInfo.getUrl();
                    ToastUtil.displayToast("click : " + productUrl);
                    // 执行自定义跳转逻辑。此处以跳转至商品详情 Activity 为例。
                    startActivities(new Intent[]{new Intent(MainActivity.this, ProductActivity.class)});
                    // 执行自定义跳转逻辑,但不执行默认的跳转行为。
                    return true;
                }
        }
        // 执行自定义跳转逻辑和默认的跳转行为。
        return false;
    }
});                

目前 SDK 支持自定义跳转逻辑的功能、entrance 字段的取值和观看页位置如下表所示。

说明

本文仅以移动端竖屏模式的观看页位置为例,如需查看 PC 端或移动端横屏模式的观看页位置,可查看对应的功能配置文档。

功能

entrance 字段取值

观看页位置

菜单内商品卡片

FLOATING_SHOPPING_CARD

图片

浮窗商品卡片

FLOATING_SHOPPING_CARD

图片

页头广告

HEADER_ADVERTISEMENT

图片

页中广告

BANNER_ADVERTISEMENT

图片

浮标广告

FLOATING_ADVERTISEMENT

图片

主播账号头像

BUSINESS_ACCOUNT

图片

评论中的 URL

COMMENT_LINK

图片

自定义完整直播间退出行为

观众在完整直播间内点击退出按钮或物理返回键时,默认会退出完整直播间。如果正在播放直播或点播视频且观众在移动端开启了悬浮窗权限,则默认会退出完整直播间并展示悬浮窗(即画中画)。
调用 setLiveRoomActionListener 方法,设置完整直播间的退出事件监听器后,观众在点击退出按钮或物理返回键退出完整直播间时,SDK 会触发 onClickExitLiveRoom 回调。您可以通过返回值,决定在执行自定义的完整直播间退出行为时,是否拦截以上默认的点击行为。

  • 返回 true:拦截,即不执行默认的点击行为。
  • 返回 false:不拦截,即执行默认的点击行为。

说明

Android 观播 SDK 自 1.33.0 版本开始,onClickExitLiveRoom 回调支持通过返回值决定是否拦截默认的点击行为。如未集成指定的 SDK 版本,则必然拦截默认的点击行为。

以下示例代码仅会执行自定义的完整直播间退出行为,而不会执行默认的点击行为。

// 设置完整直播间的退出事件监听器。
CustomSettings settings = CustomSettings.Holder.mSettings;
settings.setLiveRoomActionListener(context -> {
    ToastUtil.displayToast("自定义完整直播间退出行为");
    TVULiveRoom.leaveLiveRoom(MainActivity.this); // 执行自定义的完整直播间退出行为。    
    return true; // 仅 Android 观播 SDK 1.33.0 及以上版本支持。
});

横屏直播间 UI 定制

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

步骤一:获取 TvuLivePlayerLayoutBinding 实例

SDK 触发 onLandLiveRoomBindingAvailable 回调后,您可以通过获取到的 ViewBinding 实例自定义横屏直播间的 UI。
示例代码如下所示。

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 = LayoutInflater.from(context).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(com.bytedance.live.sdk.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.getInstance().addListener(listener);
// 移除监听器。
LanguageManager.getInstance().removeListener(listener);

竖屏直播间 UI 定制

在接入完整直播间后,您可以自定义竖屏直播间的 UI。

步骤一:获取 TvuPortraitLiveRoomLayoutBinding 实例

SDK 触发 onPortraitLiveRoomBindingAvailable 回调后,您可以通过获取到的 ViewBinding 实例自定义竖屏直播间的 UI。
示例代码如下所示。

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(com.bytedance.live.sdk.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(com.bytedance.live.sdk.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.getInstance().addListener(listener);
// 移除监听器。
LanguageManager.getInstance().removeListener(listener);

常见 UI 定制功能

您可以通过观播 SDK 自定义观看页的 UI 显示。
本文以直播带货场景中高频使用的 UI 定制功能点为例。更多 UI 定制相关方法与回调,详见 mSettings回调

视频画面填充模式

竖屏直播间内,默认视频会保持原有宽高比例填充播放器,视频的宽高会填满播放器的宽高。如果视频宽高比与播放器宽高比不同,会有部分视频内容被裁剪掉。您可以自定义视频画面的填充模式。详见 setPortraitPlayerLayoutMode
以下示例代码保持视频原有宽高比例填充播放器,视频的宽高会填满播放器的宽高。如果视频宽高比与播放器宽高比不同,视频会缩放显示。

图片

CustomSettings settings = CustomSettings.Holder.mSettings;
// 将视频画面的填充模式设置为 ImageAspectFit。
settings.setPortraitPlayerLayoutMode(0); 

完整直播间的关闭按钮样式

竖屏完整直播间的关闭按钮默认显示为 x。您可以自定义关闭按钮的显示样式。
以下示例代码将关闭按钮自定义为文件名为 tvu_nav_icon_back_melon 的图片。

图片

CustomSettings settings = CustomSettings.Holder.mSettings;
// 自定义按钮的图标为文件名 tvu_nav_icon_back_melon 的图片。
settings.setExitRoomIcon(ContextCompat.getDrawable(this, R.mipmap.tvu_nav_icon_back_melon));

互动工具浮窗

互动工具浮窗,即包含抽奖、答题、投票、问卷和公告图标的浮窗。竖屏直播间默认展示在直播间左上方。您可以自定义互动工具浮窗的默认位置。
以下示例代码将互动工具浮窗的默认位置从左上方移动至距离底部 80 dp 的左下方。

图片

CustomSettings settings = CustomSettings.Holder.mSettings;
// 将互动工具浮窗的默认位置移动至距离底部 80 dp 的左下方。
SimpleLayoutParams simpleLayoutParams = new SimpleLayoutParams(Gravity.START | Gravity.BOTTOM, 0, 0, 0, 80);
settings.setFloatInteractToolLayoutParams(simpleLayoutParams);

商品卡片菜单高度

商品卡片菜单的默认高度为 460 dp。您可以自定义菜单的高度。
以下示例代码将商品卡片菜单的高度设置为 700 dp。

图片

CustomSettings settings = CustomSettings.Holder.mSettings;
// 将商品卡片菜单的高度设置为 700 dp。
settings.setShoppingCardDialogHeight(700);