npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ecloud-rcr2

v1.1.4

Published

天翼云实时云渲染JS SDK

Downloads

19

Readme

天翼云实时云渲染 JS SDK

ecloud-rcr2

[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 渲染配置

| 属性 | 说明 | 类型 | 是否必填 | 默认值 | |:-------------------|:-----------------------------------------|:----------------------------------------|:---------|:-------| | 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 实例

Demo: 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)

| 方法名 | 说明 | 参数 | 回调参数 | |:-------------------------------|:-----------------------------|:-----------------------------------|:-------------------| | 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 接入微信小程序

  • 步骤
    1. 使用 jssdk 开发,打包成 html 部署到线上(生产环境需要域名解析)
    2. 微信小程序通过 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 的界面给用户填写,填写后再启动应用