ecloud-rcr2
v1.1.4
Published
天翼云实时云渲染JS SDK
Downloads
19
Readme
天翼云实时云渲染 JS SDK
[toc]
安装
npm install ecloud-rcr2
一、快速启动
1.1 前端项目引入
import { RCRLaunch } from 'ecloud-rcr2';
const bootstrap = async () => {
try {
const hostElement = document.getElementById("container");
const launch = await RCRLaunch({
appKey,
hostElement,
uiOptions: {
onChange: (cb) => {
const { phase, fakePercent } = cb;
console.log('百分⽐:',fakePercent);
// launcherBase 实例获取是在 phase ⾄少为 'signaling-connected' 阶段,即
if (phase === "signaling-connected") {
console.log("信令已连接")
// const connection = launch.launcherBase.connection;
}
},
onPhaseChange: (phase, deltaTime) => {
if (phase === "signaling-connected") {
const { connection, player } = launch.launcherBase;
console.log(connection, player);
}
},
onPlay: () => {
console.log('出现了有效画⾯');
},
}
});
} catch (error) {
console.error(error);
}
};
bootstrap();
1.2 浏览器直接引入
// 注意全局对象的名称
const { RCRLaunch } = window.ECloudRCR;
二、启动器(Launcher)
import { RCRLaunch } from 'ecloud-rcr2';
const launch = RCRLaunch({
appKey,
hostElement,
baseOptions: { ... },
uiOptions: { ... },
});
2.1 Launcher 构造属性(Constructors)
| 属性 | 说明 | 类型 | 是否必填 | |:--------------|:--------------------------------------|:----------------|:---------| | appKey | 应用 key ,优先从 url 中获取同名 query | string | - | | hostElement | 云渲染容器,默认使用 #container DOM 元素 | HTMLElement | - | | baseOptions | 基础配置 | BaseOptionsType | - | | uiOptions | UI 配置 | UIOptions | - |
2.2 baseOptions 基础配置
| 属性 | 说明 | 类型 | 是否必填 | |:-------------------|:--------------------------------------|:--------|:---------| | startType | 1:普通连接 3:投屏连接,默认1 | number | - | | appSecret | 密钥 | string | - | | exeParameter | 自定义应用启动参数 | string | - | | webrtcEnable | 是否开启webrtc推流,默认为true(详见示例) | boolean | - | | isCastScreenMaster | (投屏)是否为主控 | boolean | - | | nickname | (投屏-观看端)昵称 | string | - |
2.3 UIOptions UI配置
默认值 "-" 代表该配置优先从云端服务(前台应⽤配置)获取,或者是平台默认特性
2.3.1 渲染配置
- Demo: 设置加载相关
- demo: 设置码率:可以指定初始化码率以及动态调节码率,建议⽤户的下⾏⽹络最好⾼于最⾼码率的 50%,体验最佳。
- Demo: 设置显示模式
- Demo: 设置音视频相关
| 属性 | 说明 | 类型 | 是否必填 | 默认值 | |:-------------------|:-----------------------------------------|:----------------------------------------|:---------|:-------| | loadingImage | 加载过程 loading 图 | String|HTMLImageElement | - | - | | loadingBgImage | 加载过程背景图(区分横竖屏) | { portrait: String, landscape: String } | - | - | | loadingBarImage | 加载过程⼩图标(设置背景图时候⽣效) | String|HTMLImageElement | - | - | | showDefaultLoading | 未设置 loading 时,是否需要显示默认 loading 图(如有)| boolean | 否 | False | | showFakePercent | 展示加载百分⽐ | boolean | 否 | True | | phaseTextMap | 初始化加载⽂案配置 | Map<Phase, [number,string]> | 否 | | minBitrate | 云渲染最⼩码率(kbs)(优先级⾼) | number | - | 2000 | | maxBitrate | 云渲染最⼤码率(kbs)(优先级⾼) | number | - | 5000 | | startBitrate | 云渲染初始码率(kbs)(优先级⾼) | number | - | 4000 | | rateLevel | 云渲染码率等级(优先级低) | RateLevel | 否 | 1 | | landscapeType | 显示模式 | LandscapeType | 否 | - | | needLandscape | 开启强制横屏(不再⾃动旋转流⽅向以适应容器⼤⼩) | boolean | 否 | - | | autoLoadingVideo | 是否⾃动挂载云渲染⾳视频(移动端适用) | boolean | 否 | True | | audioToastDisplay | 是否开启音频提示弹窗 | boolean | - | True |
// 云渲染码率等级(优先级低)
enum RateLevel {
SD, // 0 流畅
HD, // 1 ⾼清
FHD, // 2 超清
UHD4K, // 3 蓝光
}
// 显示模式
enum LandscapeType {
Auto = 1, // 1 ⾃适应模式(默认)
Auto, // 2 拉伸模式,IOS不⽀持
Auto, // 3 裁剪模式
}
2.3.2 输入控制
| 属性 | 说明 | 类型 | 是否必填 | 默认值 | |:----------------------|:-----------------------------------------------|:--------------------------|:---------|:-------| | settingHoverButton | ⼯具栏显示情况 | VirtualControlDisplayType | 否 | - | | toolbarLogo | ⼯具栏图标 | string | 否 | - | | toolOption | 工具栏选项 | ToolOptionType | - | | | openMicrophone | 开启⻨克⻛输⼊ | boolean | 否 | - | | openMultiTouch | 开启应⽤多点触控 | boolean | 否 | False | | eventOption | 事件选项(多用于自定义键盘事件) | EventOptionType | - | | | keyboardMappingConfig | 键⿏映射配置 | VirtualGlobalType | 否 | - | | inputHoverButton | PC 输⼊框显示情况 | InputHoverButton | 否 | - | | disablePointerManager | 是否禁⽤指针样式同步(常见于游戏应用改变节点机鼠标样式,默认同步显示)| boolean | 否 | False | | disablePointerLock | 是否禁⽤指针锁定(默认开启指针锁定,应用会进入相对移动模式,鼠标不会移出页面范围) | boolean | 否 | False |
注:
- v2.x sdk 开启多点触控时,不再需要对接插件
- v1.x sdk 开启多点触控是,需要接入 3DCAT 的 UE4 插件,并在后台管理->应用详情->设置->开启多点触控。
// ⼯具栏显示情况
enum VirtualControlDisplayType {
HideAll, // 全平台隐藏
DisplayMobile, // 移动端可⻅
DisplayPc, // PC端可⻅
DisplayAll, // 全平台可⻅
}
// 工具栏所属平台
enum ToolsPlatformType {
Pc = 1, // pc 1
Mobile, // 移动端 2
All, // 全部 3
}
// 工具栏选项
interface ToolOptionType {
dropTools?: DropToolsType; // 删除⼯具栏
extendTools?: ExtendToolsType[]; // 新增⼯具栏
}
interface DropToolsType {
toolsIndex: number[]; // ⼯具栏位置(从 0 开始)
platform: ToolsPlatformType;
}
interface ExtendToolsType {
icon: string; // 图标(base64/url)
text: string; // 标题
platform: ToolsPlatformType;
order: number; //新增位置(从 0 开始)
onClick: () => void; //点击触发事件
}
// 事件选项
interface EventOptionType {
enableKeyBoard?: boolean; // 是否挂载键盘事件(默认为 true)
}
// 键⿏映射配置
interface VirtualGlobalType {
resolutionRatio: string // 推流分辨率 如 `1920*1080`
buttonSize: ButtonSizeType // 按键⼤⼩
perspectiveShift: PerspectiveShiftType // 遗留参数,作废
showButton: boolean// 是否显示键⿏映射控件
showAlias: boolean // 是否显示按键别名
landscape: VirtualDataType[]
portrait: VirtualDataType[]
}
type VirtualDataType = {
type: ScreenDataType//控件类型
value: SolutionValue//控件数据
scale?: number//⽐例
}
// PC 输⼊框显示情况
enum InputHoverButton {
Hide, // 不可⻅
Display, // 可⻅
}
2.3.3 回调监听
| 属性 | 说明 | 类型 | 是否必填 | 默认值 | |:--------------------|:-----------------------------------|:------------------------------------------|:---------|:-------| | percentChanged | 是否监听云渲染加载百分⽐变化 | boolean | 否 | True | | phaseChanged | 是否监听云渲染阶段变化 | boolean | 否 | True | | onChange | 监听云渲染阶段/加载百分⽐变化(任一变化都触发)| (cb: OnChange) => void | 否 | | | onPhaseChange | 监听云渲染阶段变化 | (phase: Phase, deltaTime: number) => void | 否 | - | | onRunningId | 监听云渲染 runningId 返回 | (runningId: number) => void | 否 | | | onRunningOptions | 监听云渲染连接服务参数 | (opt: OnRunningOptions) => void | 否 | | | onRotate | (视图)视频容器方向变化回调 | (rotate: boolean) => void | - | | | onQueue | 监听排队变化 | (rank: number) => void | 否 | | | onPlay | 监听云渲染展示有效画面 | () => void | - | | | onRtmpActive | (数据)监听是否有datachannel消息返回 | (result: boolean) => void | 否- | | | onGetTicketCallBack | (异常)监听校验错误信息 | (res: GetTicketRes) => void | 否- | | | onLoadingError | (异常)监听加载过程报错(包含渲染错误) | (err: LoadingError) => void | 否 | | | onError | (异常)监听云渲染报错 | (reason: ErrorState) => void | 否 | - | | onMount | (工具栏)监听云渲染虚拟控件挂载节点 | (el: HTMLElement) => void | - | | | onQuit | (工具栏)监听主动关闭(⼯具栏关闭按钮) | () => void | 否 | - | | onShowUserList | (投屏)监听是否展示投屏列表 | (showCastScreenUsers: boolean) => void | 否 | | | onSupportTransfer | (投屏)监听是否⽀持转移控制权 | (supportTransfer: boolean) => void | 否 | | | onLiveState | (直播)监听设置直播回调 | (liveState: LiveStateType) => void | 否 | |
// 百分⽐进度-状态-数值说明
const PhasePercentMap = new Map<Phase, [number, string]>([
["initial", [0, "可视化服务启动中..."]],
["signaling-connected", [25, "可视化服务连接中..."]], // 0-25
["node-ready", [45, "可视化服务连接中..."]], // 25-45
["streaming-ready", [55, "可视化服务连接中..."]],
["end-candidate", [65, "可视化服务连接中..."]],
["peer-connection-connected", [85, "可视化服务连接中..."]],
["data-channel-open", [90, "连接成功,资源加载中..."]],
["loaded-metadata", [99, "连接成功,资源加载中..."]],
["streaming-playing", [100, "连接成功,资源加载中..."]],
]);
// 云渲染-阶段说明
type Phase =
| 'initial' // 初始化
| 'signaling-connected' // 信令已连接
| 'node-ready' // 节点就绪
| 'end-candidate' // webRTC 候选结束
| 'peer-connection-connected' // RTCPeerConnection 已连接
| 'data-channel-open' // RTCDataChannel 已连接
| 'streaming-ready' // 视频流刚开始接收(⿊屏⽆画⾯)
| 'loaded-metadata' // 视频流 loadedmetadata 事件触发
| 'streaming-playing' // 视频流 play(有画⾯)
// 监听云渲染阶段/加载百分⽐变化
interface OnChange {
phase: Phase; // 渲染阶段
fakePercent: number; // 连接百分⽐(参考PhasePercentMap)
deltaTime: number; // 耗时
}
// 监听云渲染连接服务参数
interface OnRunningOptions {
token: string; // 信令token
signaling: string; // 信令服务器
coturns: RTCIceServer[]; // ICE 服务器地址信息 https://developer.mozilla.org/en-US/docs/Web/API/RTCIceServer
}
/**
* 云渲染报错
* disconnect: 应⽤连接已断开
* afk: 应⽤⻓时间未进⾏操作,已⾃动结束运⾏
* kick: 当前应⽤已在其他⻚⾯打开(开启重连配置)
* hangup: 当前应⽤已在其他⻚⾯打开(开启重连配置)
*/
type ErrorState = 'disconnect' | 'afk' | 'kick' | 'hangup';
// 监听加载过程报错
interface LoadingError {
code: number | string;
/**
* app: app启动阶段报错
* task: app调度阶段报错
* connection: app已连接阶段报错(reason:ErrorState)
*/
type: 'app' | 'task' | 'connection';
reason: string | ErrorState;
}
// 监听校验错误信息
interface GetTicketRes {
codeImage: string; // 验证码base64
errorNum: number; // 密钥验证失败次数
temporaryCredentials: string; // 凭证
}
// 投屏连接
interface ClientsType {
isMaster: boolean; // 是否为主控
nickname: string; // ⽤户名
isControlAuthority: boolean; // 是否有操控权
token: string;
}
2.3.4 更多能力
| 属性 | 说明 | 类型 | 是否必填 | 默认值 | |:--------------------|:------------------------|:----------------------|:--------|:-------| | enableLogPersistent | 允许持久化记录云渲染⽇志 | boolean | 否 | True | | enableTCP | 设置ICE以tcp⽅式连接,默认仅支持udp | boolean | 否 | False | | iceTransportPolicy | ICE 传输策略,all|relay | RTCIceTransportPolicy | 否 | 'all' | | autorunRivatuner | 启动统计信息,可供前端下载webrtc-stat分析数据 | boolean | 否 | False | | disableFileTransfer | 是否拒绝接收远端应用推送⽂件给 web | boolean | 否 | False |
2.4 Launcher 实例属性(Attributes)
| 属性名 | 说明 | 类型 | |:-------------|:-----------------------|:----------------| | loading | Loading 实例,详见三 | LoadingCompoent | | launcherBase | LauncherBase 实例,详见四 | LauncherBase |
2.5 Launcher 实例方法(Methods)
| 方法名 | 说明 | 参数 | 回调参数 | |:----------|:--------------------------------------------------------|:-------------------------------------------------|:---------| | destory | 删除sdk渲染实例 | (text: String, opt:{ videoScreenshot: Boolean }) | void | | liveStart | (直播)设置直播流url地址,并开始推送;传参为空时,使用之前的url地址 | string | void | | liveStop | (直播)停⽌推直播流数据 | - | void | | liveUrl | (直播)设置直播url地址,url地址必填 | (url?: string,delay?:number//超时时间,默认为 20s) | void |
launcher.destory("关闭应⽤");
//关闭之后并保持最后⼀帧视频流作为背景图
launcher.destory("关闭应⽤", { videoScreenshot: true });
三、Loading 实例
3.1 属性(Attributes)
| 属性名 | 说明 | 类型 | 默认值 | |:----------------|:--------------|:--------|:-------| | loadingCompoent | loading实例组件 | Loading | - |
3.2 方法(Methods)
| 方法名 | 说明 | 类型 | 返回值 | |:----------------|:----------------------------------------------|:--------------------------------------|:-------| | showLoadingText | 修改loading⽂本以及控制百分⽐(进度)显示 | (text: string, showPercent?: boolean) | void | | changePhase | 主动改变phase状态,loading⽂本以及百分⽐会被动变化 | Phase | void | | destroy | 注销loading组件 | | void |
四、LauncherBase 实例
const launch = await RCRLaunch({
...
uiOptions: {
onChange: (cb) => {
const { phase, fakePercent } = cb;
// launcherBase 实例获取是在 phase ⾄少为 'signaling-connected' 阶段,即
if (phase === "signaling-connected") {
// const { connection, player } = launch.launcherBase;
}
},
onPlay: () => {
console.log(launch.launcherBase);
}
}
});
4.1 属性(Attributes)
| 属性名 | 说明 | 类型 | 默认值 | |:----------------|:--------------------------|:------------------|:------------------| | player | LivePlayer实例 | LivePlayer | LivePlayer | | connection | Connection实例 | Connection | Connection | | moveSensitivity | 获取⿏标或者触摸移动的敏感度 | TouchMoveTypeEnum | TouchMoveTypeEnum |
// ⿏标或者触摸移动的敏感度
enum TouchMoveTypeEnum {
NORMAL, // 正常
HIGH, // ⾼
HIGHMAX, // 最⾼
}
4.2 方法(Methods)
| 方法名 | 说明 | 参数 | 返回值 | |:---------------------------|:-----------------------------------------------------------|:---------------------------------|:-------| | report | 获取实时连接状态 | | Object | | setMoveSensitivity | 设置⿏标或者触摸移动的敏感度 | (type:TouchMoveTypeEnum) | void | | resumeVideoStream | ⼿动触发播放 | | void | | toggleStatistics | 切换统计数据开关(默认关) | | void | | handleSubscribe | ⼿动挂载⿏标、键盘、触控等事件 | (ele:HTMLElement) | void | | handleUnsubscribe | ⼿动取消⿏标、键盘、触控等事件 | | void | | toggleFullscreen | 切换全屏(横屏),⽀持情况 | | void | | openMicrophone | 开启⻨克⻛(后台可设置初始化开启⻨克⻛) | - | | | closeMicrophone | 关闭⻨克⻛ | | void | | toggleVirtualControl | 切换键⿏映射显示状态(默认显示,与键⿏映射设置显示按钮优先级⼀致) | | void | | setLogAccordingToLevel | 设置统计数据级别; 1:log/info,2:warn,3:error | (lavel:number) | | | showDashboard | 显示仪表盘推流性能数据 | | void | | hideDashboard | 隐藏仪表盘推流性能数据 | | void | | exportLog | 导出webrtc-internals统计数据 | | void | | downloadFileByAbsolutePath | 下载远端节点⽂件(绝对路径+⽂件名) | (path: string) | | | destory | 断开全部连接 | | void | | handleChangeSubscribe | (投屏)切换猫头⼯具的控制权 | (status:boolean) | void |
五、Connection 实例
const launch = await RCRLaunch({
...
uiOptions: {
onPlay: () => {
const { connection } = launch.launcherBase;
}
}
});
5.1 属性(Attributes)
| 属性名 | 说明 | 类型 | 默认值 | |:-------|:--------------------------|:----------------------------------------------------------------------------------------|:-------| | dc | 获取 RTCDataChannel 实例 | RTCDataChannel | - | | pc | 获取 RTCPeerConnection 实例 | RTCPeerConnection | - | | event | Connection 事件 | object | - |
5.2 方法(Methods)
- demo: 和应用双向通信
- demo: 重置超时时间:常用于手动挂载键鼠时间时,避免有操作前提下超时断联的问题
- demo: 云端截图下载
| 方法名 | 说明 | 参数 | 回调参数 | |:-------------------------------|:-----------------------------|:-----------------------------------|:-------------------| | emitUIInteraction | 发送消息到应用程序 | string|ArrayBuffer | Promise<boolean> | | send | 发送消息到应⽤程序(第⼆个参数为true可重置超时时间) | string|Blob|ArrayBuffer|boolean | void | | changeBandwidthByRenegotiation | 调节码率 | number | void | | changeEncodeResolution | 修改云端推流的编码分辨率(默认1920*1080) | {width?: number; height?: number; } | void | | screenshot | [截图]云端截图 | {index?: number; left?: number; top?: number; width?: number; height?: number;} | void | | controlAuthority | [投屏]转移控制权限(详细参考投屏示例) | token | void |
5.3 事件(Events)
| 事件名 | 说明 | 回调参数 | |:---------------------|:--------------------------------------|:--------------------------------------------------------------------------| | connect | 可视化服务连接中 | - | | dataChannelConnected | 连接成功,资源加载中 | - | | close | 连接中断回调 | CloseEvent | | disconnect | 信令断开回调 | string | | interaction | 接收应用端返回数据 | string | | afk | 超时断开 | - | | screenshot | 完整接收完截图数据时;payload 为截图数据 | Blob | | screenshotData | 收到截图数据时;payload 为数据字节⻓度 | number |
六、Player 实例
const launch = await RCRLaunch({
...
uiOptions: {
onPlay: () => {
const { player } = launch.launcherBase;
}
}
});
6.1 属性(Attributes)
| 属性名 | 说明 | 类型 | 默认值 | |:------------|:--------------------|:--------------------------------------------------------------------------------------|:-------| | video | 播放实例节点 | HTMLVideoElement | - | | playerEle | 播放实例父级容器 | HTMLDivElement | - | | videoVolume | 获取 video 当前音量值(应用声音,ios设备永远返回1) | number | 0 |
6.2 方法(Methods)
| 方法名 | 说明 | 参数 | 回调参数 | |:----------------------------|:------------------------------|:---------------------------------|:---------| | setVideoVolume | 设置 video 播放⾳量值(应⽤声⾳,ios设备不⽀持) | number | void | | handleChangeLandscapeType | 设置显示模式 | number(1:自适应|2:拉伸|3:裁剪) | void | | handleChangeOrientationLock | 移动端调节旋转 | boolean(false:横屏|true:竖屏) | void |
七、鼠标键盘控制相关接口(可选扩展)
当您需要对鼠标、键盘进行定制时(eg:组合键、改键映射),可以使用下面的能力。
7.1 键盘事件(Keyboard)
import { RCRLaunch, Keyboard } from 'ecloud-rcr2';
let eventConnection;
const launch = await RCRLaunch({
...
uiOptions: {
uiOptions: {
enableKeyBoard: false, // 关闭默认键盘挂载
},
onPlay() {
// 处理键盘映射
},
onPhaseChange: (phase, deltaTime) => {
if (phase === "signaling-connected") {
const { connection } = launch.launcherBase;
eventConnection = onnection
}
}
},
});
// eg:发送键盘事件
document.addEventListener('keyup', (e) => {
e.preventDefault()
eventConnection.send(Keyboard.fromKeyboardEvent(e, false).dumps(), true)
})
参数说明:
| 属性 | 说明 | 类型 | |:--------|:---------|:--------| | keycode | 键码 | number | | alt | 按下 alt | boolean | | shift | 按下 shift | boolean | | ctrl | 按下 ctrl | boolean | | nlock | 按下 nlock | boolean | | clock | 按下 clock | boolean | | slock | 按下 slock | boolean | | down | 按下 | boolean |
7.2 鼠标移动事件(MouseMove)
import { MouseMove } from 'ecloud-rcr2';
connection.send(new MouseMove(100, 300, 3, 4).dumps());
参数说明:
| 属性 | 说明 | 类型 | |:-----|:-----|:-------| | x | x | number | | y | y | number | | dx | dx | number | | dy | dy | number |
7.3 鼠标按钮事件(MouseButton)
import { MouseButton } from 'ecloud-rcr2';
connection.send(new MouseButton(1, true).dumps());
参数说明:
| 属性 | 说明 | 类型 | |:----------------|:---------------------------|:--------| | mouseButtonType | left = 1,middle=2, right=3 | number | | down | 按下 | boolean |
7.4 缩放事件(WheelScroll)
import { WheelScroll } from 'ecloud-rcr2';
connection.send(new WheelScroll(10, true).dumps());
参数说明:
| 属性 | 说明 | 类型 | |:--------|:--------|:--------| | step | step | number | | forward | forward | boolean |
7.5 触控事件(TouchSet)
import { TouchSet } from 'ecloud-rcr2';
connection.send(new TouchSet(0, [{ x: 10, y: 10, id: 1 }]).dumps());
参数说明:
| 属性 | 说明 | 类型 | |:----------|:------------------------------------------------------------------|:-------------| | touchType | down = 0,update=1, up=2 | number | | touchList | TouchPoint:{x: number y: number id: number} //id:touch identifier | TouchPoint[] |
7.6 文本传输事件(TextInput)
import { TextInput } from 'ecloud-rcr2';
connection.send(new TextInput('test text').dumps());
参数说明:
| 属性 | 说明 | 类型 | |:-----|:----------------------------------------------------|:-------| | text | 聚焦应用输入框时能够快速发送内容,比如实现复制粘贴功能 | string |
八、常用问题
8.1 接入微信小程序
- 步骤
- 使用 jssdk 开发,打包成 html 部署到线上(生产环境需要域名解析)
- 微信小程序通过
web-view
嵌入 html 地址(域名链接)
- 开发 html 时候,微信(小程序)环境需要注意监听
WeixinJSBridgeReady
事件,然后开始对接 jssdk
window.addEventListener('DOMContentLoaded', () => {
if (navigator.userAgent.includes('miniProgram') || navigator.userAgent.includes('MicroMessenger')) {
//微信浏览器/微信小程序环境
document.addEventListener('WeixinJSBridgeReady', bootstrap, false);
} else {
bootstrap();
}
});
8.2 WebRTC 调试参考
- 方法1:在任一浏览器标签地址打开
chrome://webrtc-internals
,即可看到 WebRTC 的完整调试数据 - 方法2:调⽤
Launcher showDashboard
⽅法,显示仪表盘推流性能数据(注:空数据情况下记得调⽤launcher toggleStatistics
⽅法切换状态) - 方法3:调⽤
Launcher exportLog
⽅法,导出 webrtc-internal s统计数据(注:空数据情况下记得调⽤launcher toggleStatistics
⽅法切换状态)
8.4 投屏分享功能
功能说明:
- 投屏交互分为主控端、观看端
- 主控端需要使用投屏 appKey 初始化应用
- 主控端生成观看端链接
- 主控端可以赋予/回收临时操控权给观看端(需要创建投屏链接时勾选该功能)
主控端示例:
let clientToken;
const launch = await RCRLaunch({
appKey, // 投屏专用 appKey ,需要先增加投屏链接获取
address, // 投屏需要指定集群地址,和观看端保持同集群
baseOptions: {
startType: 3, // 投屏链接
isCastScreenMaster: true,
},
uiOptions: {
onMount: () => {
// 获取投屏观看端临时 appKey ,拼接投屏地址
// 投屏地址可以直接使用当前页面(定义 query 参数来区分端),或使用独立的分享页面来进行物理分隔
copyUrl = `${window.location.origin}${window.location.pathname}?appKey=${key}&type=share`;
},
onRunningOptions: (options) => {
clientToken = options.token;
},
onPhaseChange: (phase, deltaTime) => {
if (phase === "signaling-connected") {
const { connection } = launch.launcherBase;
connection.event.clientInfo.on((data) => {
renderClients(data);
});
}
}
toolOption: {
// 生成投屏的功能按钮
extendTools:[
{
icon: "your icon",
text: "访问邀请",
platform: 3,
onClick: () => {
// 复制生成的投屏地址
},
},
],
},
},
});
function renderClients(data) {
const list = data.clients || [];
list.forEach((client) => {
const { nickname, isControlAuthority, token } = client;
// 渲染投屏用户列表,注意:
// 1、仅主控端可以进行权限转移
// 2、列表样式用户自行定义
// 判断当前用户是自己
if (token === clientToken) {
launch.launcherBase.handleChangeSubscribe(isControlAuthority); // 切换猫头工具的控制权
isControlAuthority ? launch.launcherBase.handleSubscribe(videoEle) : launch.launcherBase.handleUnsubscribe(); // 订阅交互 or 取消订阅交互
}
});
};
观看端示例:
const bootstrap = async (nickname) => {
try {
const launch = await RCRLaunch({
// appKey, // 不需要填,默认从 query 中读取观看端 appKey
address, // 需要显式指定集群地址,确保和主控端在同一集群
baseOptions: {
startType: 3, // 投屏链接
isCastScreenMaster: false,
nickname: nickname, // 分享端必填
},
uiOptions: {
onPhaseChange: (phase, deltaTime) => {
if (phase === "signaling-connected") {
const { connection } = launch.launcherBase;
connection.event.clientInfo.on((data) => {
//
});
}
}
}
});
} catch (error) {
console.error(error);
}
};
// 分享端要先拿到分享信息,渲染一个需要输入 nickname 的界面给用户填写,填写后再启动应用