多种接入场景demo/实践

1、快速接入

公有化

import { Launcher } from 'live-cat'
const appKey = 'xxxxxxxxxxxxxxxxxxx'
const address = 'https://app.3dcat.live'
const bootstrap = async () => {
  try {
    const launch = new Launcher({
      address,
      appKey,
    })

    const player = document.querySelector('body')
    //容器必须指定宽高,否则不显示
    document.querySelector('body').style.width = '100vw'
    document.querySelector('body').style.height = '100vh'
    await launch.automata(player)
  } catch (error) {
    console.error(error)
  }
}
window.addEventListener('DOMContentLoaded', () => {
  if (
    navigator.userAgent.includes('miniProgram') ||
    navigator.userAgent.includes('MicroMessenger')
  ) {
    //微信浏览器/微信小程序环境
    document.addEventListener('WeixinJSBridgeReady', bootstrap, false)
  } else {
    bootstrap()
  }
})

私有化

import { LauncherPrivate } from 'live-cat'
const appKey = 'xxxxxxxxxxxxxxxxxxx'
const address = '私有化服务器地址'
const bootstrap = async () => {
  try {
    const launch = new LauncherPrivate({
      address,
      appKey,
    })
    const player = document.querySelector('body')
    //容器必须指定宽高,否则不显示
    document.querySelector('body').style.width = '100vw'
    document.querySelector('body').style.height = '100vh'
    await launch.automata(player)
  } catch (error) {
    console.error(error)
  }
}
window.addEventListener('DOMContentLoaded', () => {
  if (
    navigator.userAgent.includes('miniProgram') ||
    navigator.userAgent.includes('MicroMessenger')
  ) {
    //微信浏览器/微信小程序环境
    document.addEventListener('WeixinJSBridgeReady', bootstrap, false)
  } else {
    bootstrap()
  }
})

2、错误代码使用说明

import { Launcher } from 'live-cat'
const appKey = 'xxxxxxxxxxxxxxxxxxx'
const address = 'https://app.3dcat.live'
const bootstrap = async () => {
  try {
    const launch = new Launcher({
      address,
      appKey,
    })

    const player = document.querySelector('body')
    document.querySelector('body').style.width = '100vw'
    document.querySelector('body').style.height = '100vh'
    await launch.automata(player).catch((code)=>{
    	//错误代码 
    	console.error(code)
    })
  } catch (error) {
    console.error(error)
  }
}
window.addEventListener('DOMContentLoaded', () => {
  if (
    navigator.userAgent.includes('miniProgram') ||
    navigator.userAgent.includes('MicroMessenger')
  ) {
    //微信浏览器/微信小程序环境
    document.addEventListener('WeixinJSBridgeReady', bootstrap, false)
  } else {
    bootstrap()
  }
})

3、接入消息双向通信(ue4、unity)

  • 以公有化为例
  • 应用需要集成相应插件:ue4unity
import { Launcher } from 'live-cat'
const appKey = 'xxxxxxxxxxxxxxxxxxx'
const address = 'https://app.3dcat.live'
const bootstrap = async () => {
  try {
    const launch = new Launcher({
      address,
      appKey,
    })

    const player = document.querySelector('body')
    document.querySelector('body').style.width = '100vw'
    document.querySelector('body').style.height = '100vh'
    await launch.automata(player)
    const connection = launch.getConnection()
    //web端->应用
    connection.emitUIInteraction('text').then(res=>{
		console.log(res?'发送成功':'发送失败')
	})
	//应用->web端
    connection.event.interaction.on((msg) =>{ 						console.log('收到应用发来的消息:',msg)
    })
  } catch (error) {
    console.error(error)
  }
}
window.addEventListener('DOMContentLoaded', () => {
  if (
    navigator.userAgent.includes('miniProgram') ||
    navigator.userAgent.includes('MicroMessenger')
  ) {
    //微信浏览器/微信小程序环境
    document.addEventListener('WeixinJSBridgeReady', bootstrap, false)
  } else {
    bootstrap()
  }
})

4、进入有效画面后初始化

import { Launcher } from 'live-cat'
const appKey = 'xxxxxxxxxxxxxxxxxxx'
const address = 'https://app.3dcat.live'
const bootstrap = async () => {
  try {
    const launch = new Launcher({
      address,
      appKey,
      onPlay:()=>{
		// 初始化操作
		}
    })

    const player = document.querySelector('body')
    document.querySelector('body').style.width = '100vw'
    document.querySelector('body').style.height = '100vh'
    await launch.automata(player)
  } catch (error) {
    console.error(error)
  }
}
window.addEventListener('DOMContentLoaded', () => {
  if (
    navigator.userAgent.includes('miniProgram') ||
    navigator.userAgent.includes('MicroMessenger')
  ) {
    //微信浏览器/微信小程序环境
    document.addEventListener('WeixinJSBridgeReady', bootstrap, false)
  } else {
    bootstrap()
  }
})

5、接入微信小程序

  • 步骤
  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()
  }
})

6、投屏交互接入

  • 投屏交互分为主控端观看端(可被赋予临时操控权)
  • 待补充

7、替换加载页面各阶段提示

  1. 替换 "可视化服务启动中"
  • 运行await launch.automata(player)后,调用launch.getPlayer(),获取livePlayer,执行如下代码。
	livePlayer.showLoadingText('xxxxxx')
  1. 替换 "可视化服务连接中"
  • 运行await launch.automata(player)后,调用launch.getPlayer(),获取livePlayer;调用launch.getConnection(),获取connection,执行如下代码。
	connection.event.connect.on(() => livePlayer.showLoadingText('xxxxxx'))
  1. 替换 "连接成功,资源加载中"
  • 运行await launch.automata(player)后,调用launch.getPlayer(),获取livePlayer;调用launch.getConnection(),获取connection,执行如下代码。
	connection.event.dataChannelConnected.on(() => livePlayer.showLoadingText('xxxxxx'))
  1. 替换 所有的异常报错
  • 运行await launch.automata(player)后,执行如下代码。
	launch.destory('xxxx')
	//or
	livePlayer.showTextOverlay('xxxxxx')

8、去除/替换加载流程UI页面

  • 挂载容器的时候(await launch.automata(player)),把player元素隐藏掉,展示业务动画,在出现有效画面后,在onPlay回调中把player元素显示出来,参考代码如下。
  • 注意自动播放问题:Autoplay policy in Chrome ,可能会出现资源加载中一直进不去,需要引导用户点击player元素再隐藏。
	//以公有化为例
    const launch = new Launcher({
      address,
      appKey,
      onPlay: () => {
      	//开始播放回调
        player.style.display='block'
      },
    })
    const player = document.querySelector('body')
    document.querySelector('body').style.width = '100vw'
    document.querySelector('body').style.height = '100vh'
    document.querySelector('body').style.display = 'none'
    await launch.automata(player)

9、接入多点触控需求(UE4)

  • 接入3DCAT的UE4插件
  • 设置ueMultiTouch为true,参考代码如下。
	//以公有化为例
    const launch = new Launcher({
      address,
      appKey,
      ueMultiTouch:true
    })
    const player = document.querySelector('body')
    document.querySelector('body').style.width = '100vw'
    document.querySelector('body').style.height = '100vh'
    await launch.automata(player)

10、浏览器直接接入sdk

  • 参考链接
  • 需要引入jssdk的umd版本,以及相关依赖模块,具体见参考链接。

11、聚焦应用输入框,发送内容(复制粘贴)

  • 运行await launch.automata(player)后,调用launch.getConnection(),获取connection,执行如下代码。
	//开发可以自定义检测到键盘的粘贴事件后执行
	connection.send(new TextInput('test text').dumps())

12、调节码率

  • 运行await launch.automata(player)后,执行如下代码。
  • 建议:用户的下行网络最好高于最高码率的50%,体验最佳。
launcher.changeBandwidth(
  8000, // 初始码率(8M)
  10000, // 最高码率(10M)
  5000, // 最低码率(5M)
)
//or
launcher.changeBandwidth(
  10000, // 码率(均值)
)

13、消息通信传输中文乱码问题

  • 遇到web端->应用,传输中文消息出现乱码问题,参考如下代码。
  • 将string转为base64,再传输过去,应用那边再解析base64成string
const text = 'text测试内容'
const base64Text = window.btoa(encodeURIComponent(text))
connection.emitUIInteraction(base64Text).then(res=>{
	console.log(res?'发送成功':'发送失败')
})

14、获取连接状态具体说明

  • 通过launcher的 toggleStatistics方法可以获取连接状态的数据,参考代码如下:
launcher.toggleStatistics()
window.setInterval(() => {
  const { fps, bitrate, packetLossRate, latency, averageJitterBufferDelay,framesDecoded,framesDropped,framesReceived,keyFramesDecoded } = launcher.report()
  console.log(`
    FPS: ${fps}
    biterate: ${bitrate}kbps
    latency: ${latency}ms
    averageJitterBufferDelay: ${averageJitterBufferDelay}ms
    packetLossRate: ${(packetLossRate * 100).toFixed(3)}%
  `)
}, 1000)

15、RTCPeerConnection 、RTCDataChannel状态说明

  • RTCPeerConnection:通过connection.pc获取
//打印ICE的状态
console.log('RTCPeerConnection.connectionState',connection.dc.connectionState)
属性说明类型
new表示至少有一个 ICE 连接(RTCIceTransport (en-US) 或 RTCDtlsTransport (en-US) 对象)处于 new 状态,并且没有连接处于以下状态: connecting、checking、failed、disconnected,或者这些连接都处于 closed 状态string
connecting表示至少有一个 ICE 连接处于正在建立连接string
connected表示每一个 ICE 连接要么正在使用(connected 或 completed 状态),要么已被关闭(closed 状态);并且,至少有一个连接处于 connected 或 completed 状态string
disconnected表示至少有一个 ICE 连接处于 disconnected 状态,并且没有连接处于 failed、connecting 或 checking 状态。string
failed表示至少有一个 ICE 连接处于 failed 的状态string
closed表示 RTCPeerConnection 已关闭string
  • RTCDataChannel:通过connection.dc获取
//打印数据通道状态
console.log('RTCDataChannel.readyState',connection.dc.readyState)
属性说明类型
connecting正在初始化连接,正在启动string
open数据通道已经建立string
closing正在关闭数据通道string
closed数据通道已经关闭string

16、WebRTC调试参考

-在任一浏览器标签地址打开 "chrome://webrtc-internals",即可看到WebRTC的完整调试数据

业务咨询:400-8037-298