# RTC and environment — Live

Add voice RTC, voice signing, and platform requirements to a Live integration.

Canonical: https://developer.realsee.ai/docs/live/rtc-and-environment
Source: https://developer.realsee.ai/docs/live/rtc-and-environment.md
Language: en

Live co-viewing is WebSocket based. Voice is optional and delegated to an RTC implementation. The published package includes `BrowserRTC`, `BrowserRTC4Chime`, `VRWebViewRTC`, and the shared `RTCProtocol` type.

## Built-in RTC choices

Use `useBuiltInRTC` when the package should create an RTC implementation for you:

```ts
import { createLive, BuiltInRTCType } from '@realsee/live'

const live = createLive({
  useBuiltInRTC: true,
  builtInRTCType: BuiltInRTCType.TRTC,
  getTicket: async () => {
    const response = await fetch('/api/live/ticket')
    return response.json().then((payload) => payload.ticket)
  },
  getVoiceSign: async (params) => {
    const response = await fetch('/api/live/voice-sign', {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify(params),
    })
    return response.json()
  },
})
```

`getVoiceSign` is called by the SDK with voice parameters. Your backend should translate those parameters into the provider sign response expected by the RTC implementation. The browser should not hold Realsee app secrets or provider signing credentials.

## Custom RTC

For App, WebView, or mini-program containers, pass a custom object that satisfies `RTCProtocol`.

```ts
import { createLive, VRWebViewRTC } from '@realsee/live'
import { JSBridgeApp } from '@realsee/jsbridge-x/lib/app'

const jsBridge = new JSBridgeApp()
const rtc = new VRWebViewRTC({
  jsBridge,
  getVoiceSign: async (params) => {
    const response = await fetch('/api/live/voice-sign', {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify(params),
    })
    return response.json()
  },
})

const live = createLive({
  rtc,
  jsBridge,
  getTicket: async () => {
    const response = await fetch('/api/live/ticket')
    return response.json().then((payload) => payload.ticket)
  },
})
```

## RTC actions and events

The React helper exposes `useRTCAction` and `useRTCEventCallback`. The raw instance exposes `live.$RTC`.

```tsx
function VoicePanel() {
  const { join, quit, toggleMicro, detectMicro } = LiveReact.useRTCAction()

  LiveReact.useRTCEventCallback('userVolumes', (userVolumes) => {
    console.log(userVolumes)
  })

  return (
    <button
      onClick={async () => {
        const available = await detectMicro()
        if (available) await toggleMicro(true)
      }}
    >
      Enable microphone
    </button>
  )
}
```

Core RTC events include `error`, `initWillStart`, `inited`, `joinWillStart`, `joined`, `userVolumes`, and `weakNetwork`.

## Platform support

The domestic Live docs list these container requirements. Validate them against your product target and RTC provider before launch:

| Platform | Requirement |
| --- | --- |
| Web | Desktop Chrome 56 or newer is the baseline for the domestic guide; modern Chromium is recommended for WebRTC. |
| Android App | Android 5.0 or newer, Android Studio 3.5 or newer for container development. |
| iOS App | iOS 9.0 or newer, Xcode 11 or newer for container development. |
| WeChat Mini Program | WeChat iOS 7.0.9 or Android 7.0.8 or newer, base library 2.10.0 or newer, real device testing for native live components. |

## Failure handling

Treat Live connection and RTC voice as separate failure surfaces:

- If `live.connect()` returns an `Error`, keep the page open and offer retry.
- If `live.state` becomes `LiveState.CLOSED`, stop sending keyframes and show disconnected state.
- If RTC emits `error` or `weakNetwork`, keep WebSocket co-viewing available and degrade voice controls.
- Call `live.dispose()` during page teardown so RTC devices, WebSocket listeners, and keyframe observers are released.
