Skip to main content
Documentation

Quickstart

Create a Live instance, pass a server-issued ticket, connect, and clean up.

This quickstart assumes your backend can return a Live WebSocket URL and ticket. Keep App credentials server-side; the browser should receive only the Live entrance URL, ticket, and optional voice sign data required for the current room.

Install

npm install @realsee/live@0.7.6 react@18 trtc-js-sdk amazon-chime-sdk-js @realsee/jsbridge-x

The browser-only co-viewing path can start with @realsee/live@0.7.6 and react@18. Add trtc-js-sdk, amazon-chime-sdk-js, or @realsee/jsbridge-x when you use the built-in RTC implementations.

Create the instance

The generic form is createLive<MyKeyframes>. The generic maps each keyframe channel to the serializable state shape your app will synchronize.

import { createLive, LiveState } from '@realsee/live'

interface MyKeyframes {
  FiveState: unknown
  activePoi: { id: string; title: string } | null
}

const live = createLive<MyKeyframes>({
  getTicket: async () => {
    const response = await fetch('/api/live/ticket')
    const payload = await response.json()
    return payload.ticket
  },
  __debug__: import.meta.env.DEV,
})

live.on('stateChange', (state, prevState) => {
  console.log({ state, prevState })
})

await live.connect({
  url: 'wss://ws-access.realsee.com/.../room',
  force: true,
})

if (live.state === LiveState.OPEN) {
  live.sendKeyframe('activePoi', null)
}

live.connect(options?) accepts url, force, getTicket, and rtcMicStatus. The package also supports passing url and getTicket to createLive; when both are present the instance can auto-connect.

React integration

Use createLiveReact<MyKeyframes> when your controls are React components. It creates a LiveProvider, action hooks, keyframe hooks, and state hooks around one Live instance.

import { createLiveReact } from '@realsee/live'

interface MyKeyframes {
  FiveState: unknown
  activePoi: { id: string; title: string } | null
}

export const LiveReact = createLiveReact<MyKeyframes>({
  getTicket: async () => {
    const response = await fetch('/api/live/ticket')
    return response.json().then((payload) => payload.ticket)
  },
})

export function LiveRoot({ children }: { children: React.ReactNode }) {
  return <LiveReact.LiveProvider>{children}</LiveReact.LiveProvider>
}

export function ConnectButton({ wsUrl }: { wsUrl: string }) {
  const { connect } = LiveReact.useLiveAction()

  return (
    <button onClick={() => connect({ url: wsUrl, force: true })}>
      Join live room
    </button>
  )
}

Clean up

Call live.exit() when the current user leaves the room. Call live.close() when the room owner closes the room for everyone. Call live.dispose() when the page or React tree is unmounted and the instance should not be reused.

window.addEventListener('beforeunload', () => {
  void live.dispose()
})

Backend boundary

Ticket and voice sign endpoints must be same-origin endpoints in your app:

  • GET /api/live/ticket returns the ticket used by getTicket.
  • POST /api/live/voice-sign returns the voice sign used by getVoiceSign.
  • OpenAPI app keys and app secrets stay on the server.

See OpenAPI for the credential model and Team app management for app request review.