1.1.4 • Published 5 months ago

ecloud-rcr2 v1.1.4

Weekly downloads
-
License
-
Repository
-
Last release
5 months ago

天翼云实时云渲染 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 中获取同名 querystring-
hostElement云渲染容器,默认使用 #container DOM 元素HTMLElement-
baseOptions基础配置BaseOptionsType-
uiOptionsUI 配置UIOptions-

2.2 baseOptions 基础配置

属性说明类型是否必填
startType1:普通连接 3:投屏连接,默认1number-
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 图(如有)booleanFalse
showFakePercent展示加载百分⽐booleanTrue
phaseTextMap初始化加载⽂案配置Map<Phase, number,string>
minBitrate云渲染最⼩码率(kbs)(优先级⾼)number-2000
maxBitrate云渲染最⼤码率(kbs)(优先级⾼)number-5000
startBitrate云渲染初始码率(kbs)(优先级⾼)number-4000
rateLevel云渲染码率等级(优先级低)RateLevel1
landscapeType显示模式LandscapeType-
needLandscape开启强制横屏(不再⾃动旋转流⽅向以适应容器⼤⼩)boolean-
autoLoadingVideo是否⾃动挂载云渲染⾳视频(移动端适用)booleanTrue
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开启应⽤多点触控booleanFalse
eventOption事件选项(多用于自定义键盘事件)EventOptionType-
keyboardMappingConfig键⿏映射配置VirtualGlobalType-
inputHoverButtonPC 输⼊框显示情况InputHoverButton-
disablePointerManager是否禁⽤指针样式同步(常见于游戏应用改变节点机鼠标样式,默认同步显示)booleanFalse
disablePointerLock是否禁⽤指针锁定(默认开启指针锁定,应用会进入相对移动模式,鼠标不会移出页面范围)booleanFalse

注:

  • 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是否监听云渲染加载百分⽐变化booleanTrue
phaseChanged是否监听云渲染阶段变化booleanTrue
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允许持久化记录云渲染⽇志booleanTrue
enableTCP设置ICE以tcp⽅式连接,默认仅支持udpbooleanFalse
iceTransportPolicyICE 传输策略,all|relayRTCIceTransportPolicy'all'
autorunRivatuner启动统计信息,可供前端下载webrtc-stat分析数据booleanFalse
disableFileTransfer是否拒绝接收远端应用推送⽂件给 webbooleanFalse

2.4 Launcher 实例属性(Attributes)

属性名说明类型
loadingLoading 实例,详见三LoadingCompoent
launcherBaseLauncherBase 实例,详见四LauncherBase

2.5 Launcher 实例方法(Methods)

方法名说明参数回调参数
destory删除sdk渲染实例(text: String, opt:{ videoScreenshot: Boolean })void
liveStart(直播)设置直播流url地址,并开始推送;传参为空时,使用之前的url地址stringvoid
liveStop(直播)停⽌推直播流数据-void
liveUrl(直播)设置直播url地址,url地址必填(url?: string,delay?:number//超时时间,默认为 20s)void
launcher.destory("关闭应⽤");
//关闭之后并保持最后⼀帧视频流作为背景图
launcher.destory("关闭应⽤", { videoScreenshot: true });

三、Loading 实例

Demo: Loading 实例

3.1 属性(Attributes)

属性名说明类型默认值
loadingCompoentloading实例组件Loading-

3.2 方法(Methods)

方法名说明类型返回值
showLoadingText修改loading⽂本以及控制百分⽐(进度)显示(text: string, showPercent?: boolean)void
changePhase主动改变phase状态,loading⽂本以及百分⽐会被动变化Phasevoid
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)

属性名说明类型默认值
playerLivePlayer实例LivePlayerLivePlayer
connectionConnection实例ConnectionConnection
moveSensitivity获取⿏标或者触摸移动的敏感度TouchMoveTypeEnumTouchMoveTypeEnum
// ⿏标或者触摸移动的敏感度
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-
eventConnection 事件object-

5.2 方法(Methods)

方法名说明参数回调参数
emitUIInteraction发送消息到应用程序stringArrayBufferPromise\<boolean>
send发送消息到应⽤程序(第⼆个参数为true可重置超时时间)string|Blob|ArrayBuffer|booleanvoid
changeBandwidthByRenegotiation调节码率numbervoid
changeEncodeResolution修改云端推流的编码分辨率(默认1920*1080){width?: number; height?: number; }void
screenshot截图云端截图{index?: number; left?: number; top?: number; width?: number; height?: number;}void
controlAuthority投屏转移控制权限(详细参考投屏示例)tokenvoid

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)number0

6.2 方法(Methods)

方法名说明参数回调参数
setVideoVolume设置 video 播放⾳量值(应⽤声⾳,ios设备不⽀持numbervoid
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按下 altboolean
shift按下 shiftboolean
ctrl按下 ctrlboolean
nlock按下 nlockboolean
clock按下 clockboolean
slock按下 slockboolean
down按下boolean

7.2 鼠标移动事件(MouseMove)

import { MouseMove } from 'ecloud-rcr2';
connection.send(new MouseMove(100, 300, 3, 4).dumps());

参数说明:

属性说明类型
xxnumber
yynumber
dxdxnumber
dydynumber

7.3 鼠标按钮事件(MouseButton)

import { MouseButton } from 'ecloud-rcr2';
connection.send(new MouseButton(1, true).dumps());

参数说明:

属性说明类型
mouseButtonTypeleft = 1,middle=2, right=3number
down按下boolean

7.4 缩放事件(WheelScroll)

import { WheelScroll } from 'ecloud-rcr2';
connection.send(new WheelScroll(10, true).dumps());

参数说明:

属性说明类型
stepstepnumber
forwardforwardboolean

7.5 触控事件(TouchSet)

import { TouchSet } from 'ecloud-rcr2';
connection.send(new TouchSet(0, [{ x: 10, y: 10, id: 1 }]).dumps());

参数说明:

属性说明类型
touchTypedown = 0,update=1, up=2number
touchListTouchPoint:{x: number y: number id: number} //id:touch identifierTouchPoint[]

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 的界面给用户填写,填写后再启动应用
1.1.4

5 months ago

1.1.3

5 months ago

1.1.1

6 months ago

1.1.0

6 months ago

1.1.2

5 months ago

1.0.1

8 months ago

1.0.0

8 months ago