@rideview/livestream-web-sdk
v1.1.0
Published
Lightmetrics LiveStream SDK
Downloads
196
Readme
LiveStream SDK --- Technical Documentation
1. Overview
The LiveStreamSDK enables real-time video/audio streaming from devices using:
WebRTC → Media transport (low-latency streaming)
HLS → CDN-friendly scalable playback
Socket.IO signaling → Session negotiation
Factory-based transport selection → Host decides streaming mode
Event-driven architecture → Unified lifecycle events for UI
Browser autoplay-safe playback
This SDK is designed for web portals.
2. Architecture
Architecture Diagram
HostApplication
│
▼
LiveStreamSDK
│
├───────────────► Session Service ─────────► HTTP Client ─────────► Backend API
│ │
│ ├─ Session Creation
│ ├─ 409 Conflict Recovery (only for WebRTC)
│ └─ Returns Session
│
▼
StreamPlayerFactory
│
├──────────────► WebRTC Player
│ │
│ ├────────► SignalingClient (Socket Connection)
│ │ │
│ │ ▼
│ │ Signaling Server
│ │ │
│ │ └─ Exchanges ICE
│ │
│ └────────► PeerConnectionManager
│ │ │
│ │ ├─ Connects to relay server
│ │ └─ Receives the media
│ │
│ └────────► Attaches VideoStream
│ │
│ ▼
│ HTMLVideoElement
│
└──────────────► HLS Player
│
└─ Feeds Source Stream
│
▼
HTMLVideoElementIntegration Overview
| Mode | Responsibility | Use Case |
| -------------------- | ----------------------------------------------------------------- | ----------------------------------------- |
| sdk-managed | SDK handles API calls (Start / Stop / Join) via SessionService. | Standalone apps, simple integrations. |
| external-managed | Host provides session object; SDK skips lifecycle API calls. | Micro-frontends, shared backend sessions. |
3. Module Documentation
| Module | Layer | Responsibility | | --------------------- | ---------------------- | ----------------------------------------------------------------------------------- | | LiveStreamSDK | Facade / Orchestration | Public API for host, manages lifecycle, selects player via factory, re-emits events | | StreamPlayerFactory | Creation | Creates correct player (WebRTCPlayer, HLSPlayer) based on host choice | | IStreamPlayer | Abstraction | Defines common contract all players must follow | | WebRTCPlayer | Real-Time Transport | Handles WebRTC session, signaling coordination, attaches RTC media | | HLSPlayer | HTTP Streaming | Handles HLS playback via hls.js / native HLS | | Telemetry | External Monitoring | Error tracking across the SDK lifecycle for external monitoring plugins | | PeerConnectionManager | WebRTC Engine Wrapper | Manages RTCPeerConnection, ICE, tracks, MediaStream | | SignalingClient | Communication | Handles Socket.IO messaging for SDP/ICE exchange | | SessionService | API Calls | Handles session related API calls and automatic stream recovery. | | EventEmitter | Infrastructure | Provides internal event system between modules |
3.1 EventEmitter
File: utils/EventEmitter.ts
class EventEmitter {
-listeners: Record<string, Listener[]>
+on(event, cb)
+off(event, cb)
+removeAllListeners(event?)
#emit(event, data)
}Used For:
- Player → SDK communication
- SDK → Host UI events
- Lifecycle propagation
3.2 SessionService
File: session/sessionService.ts
Handles session related API calls and automatic stream recovery.
class SessionService {
- LiveStreamAPI api
- HttpClient http
- getHeaders()
+ createOrJoinRTCSession(payload: any)
+ createRTCSession(payload: any)
+ joinRTCSession(streamRequestId: string, fleetId: string)
+ createHLSSession(payload: any)
+ endSession(streamRequestId: string, fleetId: string)
}
3.3 SignalingClient
File: signaling/SignalingClient.ts
Handles ONLY signaling transport (no WebRTC logic).
class SignalingClient {
-socket: Socket
+connect(config)
+sendAnswer(answer)
+sendIce(candidate)
+close()
}Emits Events
| Event | Meaning | | ------------ | -------------------- | | connected | Socket established | | disconnected | Socket lost | | message | Offer / ICE received |
3.4 PeerConnectionManager
File: webrtc/PeerConnectionManager.ts
Encapsulates pure WebRTC logic.
class PeerConnectionManager {
-pc: RTCPeerConnection
-stream: MediaStream
+init(iceServers)
+handleOffer(offer)
+addIceCandidate(candidate)
+getStream()
+close()
}3.5 IStreamPlayer
File: players/IStreamPlayer.ts
Defines contract implemented by all playback types.
class IStreamPlayer {
<<interface>>
+init(session)
+attach(video)
+stop()
+on(event, cb)
+off(event, cb)
+removeAllListeners(event?)
}This abstraction allows adding new protocols without modifying SDK.
3.6 WebRTCPlayer
File: players/WebRTCPlayer.ts
Implements low-latency streaming using:
SignalingClientPeerConnectionManager- Relay transport
class WebRTCPlayer {
-signaling: SignalingClient
-pcManager: PeerConnectionManager
-video: HTMLVideoElement
}3.7 HLSPlayer
File: players/HLSPlayer.ts
Implements HTTP-based playback using:
hls.js(Chrome / Edge)- Native HLS (Safari)
class HLSPlayer {
-hls: Hls
-video: HTMLVideoElement
-url: string
}3.8 StreamPlayerFactory
File: factory/StreamPlayerFactory.ts
Creates appropriate player based on host preference.
StreamPlayerFactory.create('webrtc');
StreamPlayerFactory.create('hls');Adding a new protocol requires:
- Implement
IStreamPlayer - Register in factory
- No SDK changes required
class StreamPlayerFactory {
+create(mode): IStreamPlayer
}3.9 SdkTelemetry
File: telemetry/SDKtelemetry.ts | types/Telemetry.ts
Standardizes event normalization and error tracking across the SDK lifecycle for external monitoring plugins.
class SdkTelemetry {
- ITelemetryPlugin plugin
+ trackEvent(type: string, metadata?: object): void
+ trackError(sessionId: string, error: Error, phase: string): void
}
interface ITelemetryPlugin {
+ trackEvent(event: Omit<TelemetryEvent, 'timestamp' | 'sdkVersion'>): void
+ trackError(sessionId: string, error: Error, phase: string): void
}
type TelemetryEvent = {
type: string;
timestamp: number;
sdkVersion: string;
sessionId: string;
metadata?: Record<string, unknown>;
};
3.10 LiveStreamSDK (Public Interface)
File: LiveStreamSDK.ts
This is the only class host apps will use.
class LiveStreamSDK {
- HttpClient
- sessionService: SessionService
- player: IStreamPlayer
- sessionMode: SessionMode
- activeSession : {
currentSessionId: string
fleetId: string
currentMode: StreamMode
role: 'host' | 'guest'
}
- state: SDKState
- internalStart(mode, sessionResolver)
- safeRollback(session, fleetId)
- bindPlayerEvents()
- unbindPlayerEvents()
+ start(config, mode)
+ startWithSession(session, mode)
+ attach(video)
+ stop()
+ on(event, handler)
}
4. Streaming Lifecycle
Step 1 — Host Starts Stream
Depending on the initialization mode chosen in the constructor, the host calls one of two entry points:
SDK-Managed
sdk.start(config, 'webrtc' | 'hls');External-Managed
sdk.startWithSession(sessionObject, 'webrtc' | 'hls', 'fleetId');Step 2 — Session Creation
The SDK resolves the session metadata required to initialize the transport layer.
SDK-managed mode
The SDK performs the API handshake:
- WebRTC
POST /v2/live/create-stream-request- HLS
POST /live/create-stream-requestExternal-managed mode
The SDK skips the network request and immediately uses the provided sessionObject.
Step 3 — Conflict Resolution (Managed Mode Only)
If the backend returns a 409 Conflict (stream already active), the sessionService automatically catches this and issues:
POST /live/join-webrtc-streamHost Role
- If
streamRequestIdis returned, the SDK acts as the owner. - The SDK calls the
stop()API on exit.
Guest Role
- If
conflictStreamRequestIdis used, the SDK acts as a viewer. - The SDK skips the
stop()API on exit.
Step 4 — Player Created via Factory
The internalStart logic passes the resolved session to the Factory.
Factory Creation
StreamPlayerFactory.create(mode);This instantiates the correct player implementation.
Event Binding
The SDK attaches internal listeners to the player:
connectedplayingerror
These events are proxied to the Host UI.
Transport Initialization
player.init(session);This starts signaling (WebRTC) or manifest loading (HLS).
Step 5 — Transport Initialization
WebRTC
- Offer ← Relay
- Answer → Relay
- ICE negotiation
HLS
- Manifest fetched
- Segments buffered
Step 6 — Media Rendering Begins
The video element emits:
"playing"The SDK then emits the **playing event`.
This represents the first frame rendered (TTFF milestone).
5. Events Exposed to Host Application
SDK normalizes events across WebRTC & HLS.
sdk.on("connected", ...)
sdk.on("playing", ...)
sdk.on("error", ...)
sdk.on("stopped", ...)| Event | Meaning | | --------- | -------------------------- | | connected | Stream session established | | playing | First frame rendered | | error | Playback failure | | stopped | Stream closed |
Host UI must rely on "playing" to hide loaders.
6. Error Handling
The SDK separates errors into two distinct categories to prevent unhandled promise rejections and to provide predictable failure handling.
Startup Errors
Startup errors occur before a connection or stream is successfully established.
Examples:
- Invalid authentication credentials
- API unavailable or unreachable
- Configuration errors during initialization
These errors:
- Do not emit SDK events
- Must be handled using
try/catch
try {
await sdk.start(config);
} catch (error) {
console.error('Startup error:', error);
// Handle initialization failure
}Runtime / Stream Errors
Runtime errors occur after a session or stream has already started.
Examples:
- Network disconnection
- ICE negotiation failure
- WebRTC transport issues
- Unexpected stream termination
These errors:
- Emit an
errorevent - Do not automatically throw
You must subscribe to the error event:
sdk.on('error', (e) => {
console.error('Runtime error:', e);
// Handle recovery, cleanup, reconnection, UI updates, etc.
});7. Host Application Integration
HTML
<video id="player"></video>
<button id="start">Start</button>
<button id="stop">Stop</button>7.1 SDK Managed Mode
Initialise the SDK
import { LiveStreamSDK, LogLevel } from '@Lightmetrics/livestream-web-sdk';
const sdk = new LiveStreamSDK({
mode: 'sdk-managed',
apiBaseUrl: 'https://api.example.com',
// Option 1: Static headers
/*
headers: {
Authorization: "Bearer YOUR_ACCESS_TOKEN",
"x-tenant-id": "tenant-1"
},
*/
// Option 2: Dynamic header provider
headers: async () => {
const token = await authService.getFreshToken();
return {
Authorization: `Bearer ${token}`,
'x-tenant-id': getActiveTenant(),
};
},
// Optional: Override default API endpoints
endpoints: {
create: '/v3/start',
stop: '/v3/terminate',
join: '/v3/join',
createHLS: '/v3/startHLS',
},
logLevel: LogLevel.DEBUG,
enableTelemetry: false,
});Start Streaming
await sdk.start(
{
deviceId: 'device-123',
fleetId: 'fleet-abc',
videoType: 'road',
unitSystem: 'imperial',
videoResolution: '640x360',
userId: 'userId',
},
'webrtc', // Options: 'webrtc' | 'hls'
);
sdk.attach(document.getElementById('player'));7.2 External Managed Mode
Initialise the SDK
const sdk = new LiveStreamSDK({
mode: 'external-managed',
logLevel: LogLevel.DEBUG,
enableTelemetry: false,
});Create Session via Backend
The host application must create the stream session
const mySession = await fetch(`${EXTERNAL_API}`);Your backend should return a session object containing the necessary signalling information.
Start SDK with Session
await sdk.startWithSession(mySession, 'webrtc', 'fleet-abc');
sdk.attach(videoElement);8. Clean Shutdown
sdk.stop();Ensures:
- Peer connection closed
- Socket disconnected
- HLS destroyed
- Event listeners cleaned
Prevents memory leaks & ghost sessions.
9. SDK Internal Dependencies
| Library | Purpose | | ---------------- | ---------------------------------------------------------------------- | | socket.io-client | WebRTC signaling transport | | hls.js | HLS playback (non-Safari browsers) | | sentry | Captures and reports browser-side errors for monitoring and debugging. | | tslib | Provides TypeScript helper functions to reduce bundle size. |
