live-cat
v2.1.4
Published
ray-streaming launcher for 3dcat
Downloads
348
Readme
3DCAT RayStreaming Launcher
RayStreaming Launcher
Quick start
instantiation parameter
type Phase =
| 'initial'
| 'signaling-connected'
| 'node-ready'
| 'end-candidate'
| 'peer-connection-connected'
| 'data-channel-open'
| 'streaming-ready'
| 'loaded-metadata'
| 'streaming-playing'
interface Options {
minBitrate: number
maxBitrate: number
startBitrate: number
rateLevel: RateLevel
startType: StartType
autorunRivatuner: boolean
enableLogPersistent: boolean
audioToastDisplay: boolean
iceTransportPolicy: RTCIceTransportPolicy
autoLoadingVideo: boolean
isFullScreen: boolean
openMicrophone: boolean
openMultiTouch: boolean
needLandscape: boolean
landscapeType: LandscapeType
settingHoverButton: VirtualControlDisplayType
keyboardMappingConfig?: VirtualGlobalType
inputHoverButton: InputHoverButton
toolbarLogo: string
toolOption?: ToolOptionType
eventOption?: eventOptionType
onError: (reason: ErrorState) => void
onPhaseChange: (phase: Phase, deltaTime: number) => void
onPlay: () => void
onMount: (element: HTMLElement) => void
onRotate: (rotate: boolean) => void
}
enum RateLevel {
SD,
HD,
FHD,
UHD4K,
}
enum StartType {
Normal = 1,
Screen = 3,
}
enum VirtualControlDisplayType {
HideAll,
DisplayMobile,
DisplayPc,
DisplayAll,
}
interface VirtualGlobalType {
showButton: boolean
landscape: VirtualDataType[]
portrait: VirtualDataType[]
}
type VirtualDataType = {
type: ScreenDataType
value: SolutionValue
scale?: number
}
enum ScreenDataType {
Normal = 1,
UDLR,
WASD,
Joystick,
Mouse,
}
type SolutionValue = {
pos: number[]
value: number[]
width?: number
height: number
shape?: SolutionShape
}
enum SolutionShape {
Rectangle = 1,
Circle,
}
enum InputHoverButton {
Hide,
Display,
}
import { Launcher } from 'live-cat'
// NOTE: signaling,token and iceServers were provided by 3dcat
const signaling = 'wss://xxxxx'
const token = 'xxxxxxxx'
const iceServers = [
{
urls: 'turn:xxx.xxx.xxx.xxx',
username: 'xxxxxx',
credential: 'xxxxxx',
},
{
urls: 'stun:xxx.xxx.xxx.xxx',
username: 'xxxxxx',
credential: 'xxxxx',
},
]
const bootstrap = () => {
const container = document.querySelector('body')
document.querySelector('body').style.width = '100%'
document.querySelector('body').style.height = '100%'
const launcher = new Launcher(
`${signaling}/clientWebsocket/${token}`,
iceServers,
container,
options,
)
}
window.addEventListener('DOMContentLoaded', () => {
if (
navigator.userAgent.includes('miniProgram') ||
navigator.userAgent.includes('MicroMessenger')
) {
//NOTE: wechat environment started
document.addEventListener('WeixinJSBridgeReady', bootstrap)
} else {
bootstrap()
}
})
Adjust bandwidth
Launcher.connection().changeBandwidth(
8000, // start bitrate kbps
10000, // max bitrate kbps
5000, // min bitrate kbps
)
Launcher.connection().changeBandwidth(
10000, // medians bitrate kbps
)
Statistics
window.setInterval(() => {
const { fps, bitrate, packetLossRate, latency, averageJitterBufferDelay } = launcher.report()
console.log(`
FPS: ${fps}
biterate: ${bitrate}kbps
latency: ${latency}ms
averageJitterBufferDelay: ${averageJitterBufferDelay}ms
packetLossRate: ${(packetLossRate * 100).toFixed(3)}%
`)
}, 1000)
ToggleFullscreen
/* NOTE: fullscreen need user activation gesture
* @see https://html.spec.whatwg.org/multipage/interaction.html#user-activation-processing-model
*/
someTriggerElement.addEventListener('click', () => launcher.toggleFullscreen())
Dashboard
// ...
launcher.showDashboard()
launcher.hideDashboard()
// NOTE: export statistics and log data
launcher.exportLog()
Microphone
// start capture audio to node
launcher.openMicrophone()
// stop
launcher.closeMicrophone()
Camera
// start capture video to node
launcher.openCamera()
// stop
launcher.closeCamera()
File Transfer
//Upload file to node
//Note: When dir is empty, it actually points to the "<User>/Downloads" directory in node
launcher.changeUploadDir(dir:string)
launcher.uploadFile(file: File, onStateChange?: FileUploadStateChangeHandler)
//Download file from node
launcher.downloadFileByFullPath(absolutePath:string)
Destroy
launcher.destroy()