本文介绍企业直播面向原生 App 内嵌场景的两个 WebView SDK:直播播放器 WebView SDK(byte-live-player) 与 uni web-view SDK(byte-live-webview)。两者定位与能力不同,请先选择适合的 SDK,再按对应章节接入。
您已开通尊享版套餐。详见计费说明。
byte-live-player)。byte-live-webview)。两个 SDK 的具体对比如下表所示:
| 对比项 | 直播播放器 WebView SDK(byte-live-player) | uni web-view SDK(byte-live-webview) |
|---|---|---|
| 交付形式 | 原生插件 + AAR / Framework | 纯 JavaScript uni_modules,无原生插件 |
| 支持平台 | uni-app / Android / iOS | uni-app(App Android、App iOS、H5) |
| 应用内小窗 / 系统画中画(PiP) | 支持✅ | 不支持,不提供 PiP ❌ |
| 宿主与 H5 双向通信 | 支持✅ | 支持✅(message / handlers) |
| Android 相机 / 麦克风运行时权限弹窗 | 需宿主自行实现 | 支持✅ 内置(allowedPermissions + manifest.json 声明) |
| Android 资源请求重写 / 离线替换 | 不涉及 | 支持✅(overrideResourceRequest) |
| 集成成本 | 较高,需自定义调试基座 / 云打包 | 较低,仅拷贝 JS 组件 |
| 典型场景 | 需要小窗 / PiP、与宿主深度联动的观播体验 | 只需内嵌观看页并解决连麦相机或麦克风权限弹窗的轻量接入 |
直播播放器 WebView SDK 是面向原生 App 的集成 SDK。它以企业直播 H5 页面和 Web 观播 SDK 为内容载体,通过封装 WebView 容器,为开发者提供页面生命周期管理、小窗与 PiP 控制、宿主与 H5 通信等能力,帮助您快速集成企业直播观看体验。本文将分别介绍如何在 uni-app、Android 和 iOS 项目中接入和使用企业直播 WebView SDK。
如果您希望将企业直播能力嵌入 Android、iOS 或 uni-app 宿主 App 中,并与 App 的原生能力进行联动,可以选择 WebView SDK。
WebView SDK 适用于以下场景:
如果您希望直接在浏览器中访问直播页面,或仅需在 Web 页面中集成直播能力,则建议使用集成 Web 观播 SDK。
企业直播 WebView SDK 提供以下核心能力:
notifyWebview() 将事件和业务数据发送给 H5 页面。| 能力 | uni-app | Android | iOS |
|---|---|---|---|
| 应用内小窗 | ✅ | ✅ | ✅ |
| 系统画中画 (PiP) | ✅ (Android 8.0+) | ✅ (Android 8.0+) | ✅ (iOS 12+) |
| 全屏播放 | ✅ | ✅ | ✅ |
| 宿主与 H5 通信 | ✅ | ✅ | ✅ |
| 原生能力扩展 | ✅ (内置部分 API 代理) | ✅ (宿主实现) | ✅ (宿主实现) |
| 下拉刷新 | ✅ | ✅ (宿主实现) | ✅ (宿主实现) |
| 侧滑返回 | ✅ | ✅ (宿主实现) | ✅ (宿主实现) |
uni-app SDK 以 DCloud 本地原生插件形式交付,包含 Android 和 iOS 原生能力封装,以及适用于 uni-app 的 JS 调用层。您可以通过 uni_modules/byte-live-player 调用 SDK 提供的 JS 接口,底层通过 nativeplugins/byteLivePlayer 接入 Android 和 iOS 原生能力。SDK 包同时包含 Android AAR、iOS Framework 以及 uni_modules 相关代码,您可直接集成至 uni-app 工程中使用。
byteLivePlayer 原生插件的自定义调试基座、离线打包工程或云打包产物;标准基座不包含该插件。.xcframework 产物。真机基座与模拟器基座不兼容,不能混用。byte-live-player-delivery-<version> ├── nativeplugins │ └── byteLivePlayer │ ├── android │ │ └── ByteLivePlayer.aar │ ├── ios │ │ └── ByteLivePlayer.framework │ └── package.json └── uni_modules └── byte-live-player
nativeplugins/byteLivePlayer 和 uni_modules/byte-live-player 分别拷贝到 uni-app 工程的同名目录下。package.json 中添加本地依赖,以便构建系统正确识别 SDK 模块:添加后请重新执行依赖安装(如{ "dependencies": { "@byte-live/live-player": "file:uni_modules/byte-live-player" } }
npm install 或 pnpm install)。在使用 SDK 前,需要在 uni-app 工程中启用原生插件 byteLivePlayer,否则运行时将无法调用相关能力。
manifest.json,进入 App 原生插件配置页,勾选 byteLivePlayer 插件并保存。manifest.json,请在 app-plus.nativePlugins 中添加如下配置:{ "app-plus": { "nativePlugins": { "byteLivePlayer": { "__plugin_info__": { "name": "byteLivePlayer", "description": "ByteLivePlayer: PiP, autoplay, etc (Android/iOS)", "platforms": "Android,iOS", "isCloud": false } } } } }
const byteLivePlayer = uni.requireNativePlugin('byteLivePlayer'); if (!byteLivePlayer) { // 当前基座未包含 byteLivePlayer,需重新制作自定义基座或检查 nativeplugins 目录与 manifest 配置。 }
本小节介绍打开 WebView 页面的两种方式。
LivePlayerManager 打开观播页面SDK 提供默认的 LivePlayerManager 单例,用于创建和管理直播页面。引入 SDK 后,您可以通过 LivePlayerManager.open() 打开直播页面。示例代码如下所示。参数说明请参考下文。
import LivePlayerManager from '@byte-live/live-player'; LivePlayerManager.open('https://example.com/live', { contentPlayerWebViewId: 'live-room-xxx', // 当前直播页面实例的唯一标识。必填。 title: '直播', fullscreen: false, keepSafeTop: false, pipStyles: { enableInAppPiP: true, enableSystemPiP: true, pipSize: { ratio: 0.45 }, allowedRoomStatuses: [1, 2, 3] }, enablePullRefresh: true, enableSwipeBack: true });
LivePlayer 组件集成直播能力如果希望以组件形式在页面中集成观播能力,也可以使用 LivePlayer 组件。多个组件实例之间相互独立,可分别进行生命周期管理。示例代码如下所示。参数说明请参考下文。
<template> <LivePlayer src="https://example.com/live" content-player-web-view-id="live-room-xxx" :pip-styles="pipStyles" @message="onMessage" @exit-web-view="onExitWebView" /> </template> <script> import { LivePlayer } from '@byte-live/live-player'; export default { components: { LivePlayer }, data() { return { pipStyles: { enableInAppPiP: true, enableSystemPiP: true, pipSize: { ratio: 0.45 }, allowedRoomStatuses: [1, 2, 3] } }; }, methods: { onMessage(event) { // event.detail.data 与 uni-app web-view message 形态对齐。 }, onExitWebView() { // 用户或 H5 触发退出播放。 } } }; </script>
参数说明
打开观播页面的参数说明如下所示。详情参考WebView SDK API 参考。
| 参数 | 类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
url | string | 是 | 无 | 观播页面地址。
|
| contentPlayerWebViewId | string | 是 | 无 | 当前观播页面实例的唯一标识。您需使用唯一字符串,例如直播间 ID 或播放器实例 ID。不同直播页面实例应使用不同的值。该标识用于直播页面的创建、恢复、小窗展示和系统画中画等场景。请勿直接使用 plus.webview.currentWebview().id 作为 contentPlayerWebViewId。 |
| title | string | 否 | 无 | 观播页面标题。部分场景下可用于导航栏标题展示。仅在通过 LivePlayerManager 打开直播页面场景有效。 |
| fullscreen | boolean | 否 | true | 是否以全屏模式展示观播页面。仅在通过 LivePlayerManager 打开直播页面场景有效。 |
| keepSafeTop | boolean | 否 | true | 是否保留顶部安全区域。开启后,观播页面内容不会覆盖状态栏区域。仅在通过 LivePlayerManager 打开直播页面场景有效。 |
| pipStyles | object | 否 | 无 | 小窗及系统画中画相关配置。 |
| pipStyles.enableInAppPiP | boolean | 否 | true | 是否启用应用内小窗能力。 |
| pipStyles.enableSystemPiP | boolean | 否 | false | 是否启用系统画中画(PiP)能力。Android 端系统级画中画(PiP)功能依赖 Android 8.0(API Level 26)及以上版本;低版本设备仍可使用应用内小窗能力。 |
| pipStyles.pipSize | object | 否 | 无 | 应用内小窗尺寸配置。 |
| pipStyles.pipSize.ratio | number | 否 | 0.45 | 应用内小窗宽度与屏幕宽度的比例,取值范围为 (0, 1]。 |
pipStyles.allowedRoomStatuses | number[] | 否 | [1, 2, 3] | 允许进入小窗或系统画中画的直播间状态列表。取值如下:
|
| enablePullRefresh | boolean | 否 | false | 是否启用下拉刷新。仅在通过 LivePlayerManager 打开直播页面场景有效。 |
| enableSwipeBack | boolean | 否 | true | 是否启用侧滑返回手势。仅在通过 LivePlayerManager 打开直播页面场景有效。 |
| uniStoragePrefetchKeys | string[] | boolean | 否 | 无 | 控制是否同步 uni storage 到 H5 页面。传 string[] 时仅同步指定 key;传 false 时关闭同步。 |
您可通过以下方法管理观播页面:
| 方法 | 说明 |
|---|---|
LivePlayerManager.close({ mode: 'hide' }) | 隐藏当前观播页面,后续可通过 show() 恢复。 |
LivePlayerManager.close() | 关闭并销毁当前观播页面。 |
LivePlayerManager.show() | 恢复大窗展示。 |
LivePlayerManager.maximize() | 将观播页面从系统画中画恢复为大窗模式。 |
LivePlayerManager.minimize() | 进入系统画中画。 |
LivePlayerManager.enterInAppPiP() | 进入应用内小窗,返回是否成功发起。 |
LivePlayerManager.exitMiniWindow() | 退出应用内小窗。 |
uni-app 适配层会将 H5 发起的部分 Native API 请求代理到宿主 uni 能力,包括 navigateTo、redirectTo、switchTab、showToast、showModal、downloadFile、downloadFileAbort、saveImageToPhotosAlbum、requestPayment 和 share。本地存储 get / set / remove 请求通过 uni storage bridge 承接。宿主仍需要按业务场景确认权限、支付/分享 provider、相册权限和路由白名单等配置。
compileSdk / targetSdk 34 或以上;SDK 构建产物当前按 34 编译。google() 与 mavenCentral(),用于解析 AndroidX 与 fastjson 依赖。core、appcompat、swiperefreshlayout、webkit 以及 fastjson。libs/bytelive-maven 下:project ├── app ├── libs │ └── bytelive-maven └── settings.gradle
repositories { google() mavenCentral() maven { url uri("$rootDir/libs/bytelive-maven") } }
dependencies { implementation "com.bytelive:byte-live-webview-sdk:0.1.0" }
通过 ByteLiveWebViewSdk.create() 创建 SDK 实例。
ByteLiveWebViewSdk sdk = ByteLiveWebViewSdk.create( activity, ByteLiveWebViewConfig.builder() .webViewDebugEnabled(true) .eventListener(event -> { // 监听 SDK 事件 }) .bridgeHandler(new ByteLiveBridgeHandler() { @Override public void onInvokeNative(ByteLiveInvokeRequest request) { // 处理 window.ByteLiveJsBridge.invokeNative(msg) } @Override public void onNativeApiRequest( ByteLiveNativeApiRequest request, ByteLiveNativeApiResponder responder) { // 处理 share / requestPayment / downloadFile / route / storage 等请求 responder.success(new JSONObject()); } }) .build());
通过 attachContent() 配置观播页面信息。
sdk.attachContent( ByteLiveContentOptions.builder("live-content-xxx") .url("https://example.com/live") .top(0) .height(0) .autoplay(true) .navShellVisible(false) .miniWindowPosition(24, 120) .miniWindowSize(360, 202) .build());
参数说明如下所示:
| 参数 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|
id | 是 | 无 | 观播页面内容的唯一标识,由业务自定义。该值与 open() 中的 options.contentPlayerWebViewId 对应,后续展示、隐藏、关闭和小窗控制会使用同一标识定位内容。 |
url | 是 | 无 | 观播页面地址。 |
top | 否 | 0 | 页面顶部偏移,单位为 px。 |
height | 否 | 0 | 页面高度;为 0 或未传时,由 SDK 按宿主容器可用区域计算。 |
autoplay | 否 | false | 是否自动播放。 |
navShellVisible | 否 | false | 是否显示 SDK 内置导航容器。默认不显示,宿主可自行承接导航栏。 |
miniWindowPosition | 否 | SDK 默认位置 | 应用内小窗初始位置,例如 miniWindowPosition(left, top)。 |
miniWindowSize | 否 | SDK 默认尺寸 | 应用内小窗尺寸,例如 miniWindowSize(width, height)。 |
navTitle | 否 | 无 | SDK 内置导航容器标题。 |
immersiveProgress | 否 | false | 是否使用沉浸式加载进度样式。 |
keepSafeTop | 否 | false | 是否保留顶部安全区。 |
miniWindowWidthRatio | 否 | 无 | 应用内小窗宽度占屏幕宽度的比例。 |
调用 showShell() 展示观播页面。
sdk.showShell("live-content-xxx");
ByteLiveWebViewSdk.xcframework,同时包含 iPhoneOS 与 iPhone Simulator slice。ByteLiveBridgeHandler 中处理。ByteLiveWebViewSdk.xcframework 加入 Xcode 工程,并设置 Embed & Sign。#import <ByteLiveWebViewSdk/ByteLiveWebViewSdk.h>
在 ViewController 中初始化 SDK,并实现协议:
@interface LiveHost () <ByteLiveEventListener, ByteLiveBridgeHandler> @property (nonatomic, strong) ByteLiveWebViewSdk *sdk; @end
初始化配置:
ByteLiveWebViewConfig *config = [ByteLiveWebViewConfig configWithEventListener:self bridgeHandler:self]; config.webViewDebugEnabled = YES; self.sdk = [ByteLiveWebViewSdk createWithViewController:self config:config];
通过 ByteLiveContentOptions 配置观播页面信息。
ByteLiveContentOptions *content = [[[[[[ByteLiveContentOptions optionsWithId:@"live-content-xxx"] url:@"https://example.com/live"] top:0] height:0] autoplay:YES] navShellVisible:NO];
| 参数 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|
id | 是 | 无 | 观播页面内容的唯一标识,由业务自定义。该值与 open() 中的 options.contentPlayerWebViewId 对应,后续展示、隐藏、关闭和小窗控制会使用同一标识定位内容。 |
url | 是 | 无 | 观播页面地址。 |
top | 否 | 0 | 页面顶部偏移,单位为 px。 |
height | 否 | 0 | 页面高度;为 0 或未传时,由 SDK 按宿主容器可用区域计算。 |
autoplay | 否 | false | 是否自动播放。 |
navShellVisible | 否 | false | 是否显示 SDK 内置导航容器。默认不显示,宿主可自行承接导航栏。 |
调用 showShell() 展示观播页面。
[self.sdk attachContent:content]; [self.sdk showShell:@"live-content-xxx"];
如果您的项目仅需在 uni-app 中加载企业直播 H5 页面,并承接 H5 与宿主之间的消息通信、Android 运行时权限申请等能力,可以接入 uni web-view SDK。该 SDK 是面向 Uni 环境的专用 SDK 包,以纯 JavaScript 的 uni_modules 组件形式交付。
0.3.0uni_modules,不包含原生插件、AAR 或 Framework安装 SDK:获取 SDK 压缩包并解压,将 uni_modules/byte-live-webview 目录复制到 uni-app 项目根目录下。
你的 uni-app 项目/ └── uni_modules/ └── byte-live-webview/ ├── components/ ├── js/ ├── static/ ├── web/ ├── index.js └── package.json
在项目的 pages.json 中增加 easycom 配置。如果项目已有 easycom,只需合并 custom 中的组件规则:
{ "easycom": { "autoscan": true, "custom": { "^ByteLiveWebView$": "@/uni_modules/byte-live-webview/components/ByteLiveWebView.vue" } } }
在需要加载观播页面的位置使用 ByteLiveWebView 组件。
<template> <view class="page"> <ByteLiveWebView :src="liveUrl" :webview-styles="webviewStyles" @message="onMessage" @load="onLoad" @error="onError" /> </view> </template> <script> export default { data() { return { liveUrl: 'https://example.com/live/index.html', webviewStyles: { top: '0px', bottom: '0px' } }; }, methods: { onMessage(event) { // 透传 H5 的原始消息,数据位于 event.detail.data。与 uni-app 原生 <web-view @message> 的数据结构一致。 console.log('收到 H5 消息:', event.detail.data); }, onLoad(event) { // WebView 页面加载完成。 console.log('页面加载完成:', event); }, onError(event) { // WebView 页面加载失败,或 Android WebView 初始化失败。 console.error('页面加载失败:', event); } } }; </script>
常用配置说明如下所示:
| 配置项 | 说明 |
|---|---|
src | 要加载的 H5 页面地址。 |
webview-styles | WebView 的位置、尺寸和进度条等样式。 |
| 当您需要将线上资源替换为 App 本地资源时,可配置
|
常用事件说明如下所示:
| 事件 | 说明 |
|---|---|
message | 透传 H5 的原始消息,数据位于 event.detail.data。与 uni-app 原生 <web-view @message> 的数据结构一致。 |
load | WebView 页面加载完成。 |
error | WebView 页面加载失败,或 Android WebView 初始化失败。 |
business-result | SDK 内置或自定义 handler 执行成功。 |
business-error | 消息校验或 handler 执行失败。 |
reply-error | 业务结果未能回传给 H5,不改变原业务执行结果。 |
resource-error | H5 中的 script、link、img 等资源加载失败。 |
如果 H5 需要申请相机、麦克风等权限,例如用于观众连麦,需要在宿主项目的 manifest.json 中声明对应权限,您也可以在组件中设置 allowedPermissions 权限白名单。
<ByteLiveWebView :src="liveUrl" :allowed-permissions="[ 'android.permission.CAMERA', 'android.permission.RECORD_AUDIO' ]" />
manifest.json 中声明对应权限。运行时申请不能代替 manifest.json 声明,两者必须同时配置。上述权限说明如下所示:{ "app-plus": { "distribute": { "android": { "permissions": [ "<uses-permission android:name=\"android.permission.CAMERA\"/>", "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>" "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>" ] } } } }
CAMERA:视频连麦所需的摄像头权限。RECORD_AUDIO:音频、视频连麦所需的麦克风权限。MODIFY_AUDIO_SETTINGS:连麦音频链路所需的音频设置权限。说明
App iOS 不提供同类批量权限接口,具体权限仍由相机、定位等业务 API 在实际调用时触发。