@truncatetechnologies/streamsdk-rn
v1.0.2
Published
Truncate Video SDK for React Native — live streaming, multi-party video rooms.
Maintainers
Readme
StreamSDK — React Native
React Native SDK for StreamSDK — real-time live streaming and multi-party video rooms for iOS and Android. Built on react-native-webrtc + mediasoup-client.
Full documentation: https://streamsdk.io/docs — includes guides, API reference, token server setup, and platform quickstarts.
Features
- Live streaming (publisher) — WHIP ingest via WebRTC, camera preview, mic/cam controls, front/back camera flip
- Live streaming (viewer) — WHEP playback via WebRTC, auto-reconnect with exponential backoff
- Multi-party video rooms — SFU-based calls via Mediasoup + Socket.IO, up to N participants
- Stream interactions — SSE-based floating reactions, admin chat, stream settings
- Headless hooks —
usePublisher,useViewer,useVideoCall,useStreamInteraction - JWT config — server URLs and ICE servers can be embedded in your auth token
Installation
npm install @truncatetechnologies/streamsdk-rnThen install the required peer dependencies:
npm install react-native-webrtc react-native-sse socket.io-client mediasoup-clientFor iOS, run CocoaPods after installing:
cd ios && pod installSetup
Call registerGlobals() once at app startup in your index.js before AppRegistry:
import { registerGlobals } from 'react-native-webrtc';
registerGlobals();
import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('MyApp', () => App);Permissions
Android — add to AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />iOS — add to Info.plist:
<key>NSCameraUsageDescription</key>
<string>Camera access required for live video.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone access required for live audio.</string>
<key>NSLocalNetworkUsageDescription</key>
<string>Local network access is needed for low-latency video connections.</string>Authentication
Your backend exchanges an API key for a short-lived JWT — never put the API key in the app bundle.
import { TruncateClient } from '@truncatetechnologies/streamsdk-rn';
const res = await fetch('https://your-backend.com/sdk-token?role=publisher&streamId=my-stream');
const { token, config } = await res.json();
const client = new TruncateClient({ token, apiUrl: config.apiUrl, mediaUrl: config.mediaUrl });See Token Server setup for a ready-made Express example.
Quick Start
Live Streaming (Publisher)
import { RTCView } from 'react-native-webrtc';
import { usePublisher } from '@truncatetechnologies/streamsdk-rn';
export default function StreamScreen({ client }) {
const {
streamURL, status, elapsed, micOn, camOn,
startStream, stopStream, toggleMic, toggleCam, switchCamera,
} = usePublisher(client, 'my-stream-123');
return (
<View style={{ flex: 1 }}>
{streamURL && <RTCView streamURL={streamURL} style={{ flex: 1 }} objectFit="cover" mirror />}
{status === 'idle' && <Button title="Go Live" onPress={startStream} />}
{status === 'live' && (
<>
<Text>LIVE — {elapsed}s</Text>
<Button title={micOn ? 'Mute' : 'Unmute'} onPress={toggleMic} />
<Button title={camOn ? 'Cam Off' : 'Cam On'} onPress={toggleCam} />
<Button title="Flip Camera" onPress={switchCamera} />
<Button title="End Stream" onPress={stopStream} />
</>
)}
</View>
);
}Live Streaming (Viewer)
import { RTCView } from 'react-native-webrtc';
import { useViewer } from '@truncatetechnologies/streamsdk-rn';
export default function WatchScreen({ client }) {
const { streamURL, status } = useViewer(client, 'my-stream-123');
return (
<View style={{ flex: 1 }}>
{streamURL
? <RTCView streamURL={streamURL} style={{ flex: 1 }} objectFit="cover" />
: <Text>{status === 'waiting' ? 'Stream not started yet...' : 'Connecting...'}</Text>
}
</View>
);
}Multi-party Video Room
import { RTCView } from 'react-native-webrtc';
import { useVideoCall } from '@truncatetechnologies/streamsdk-rn';
export default function RoomScreen({ client, roomId }) {
const {
localStreamURL, remoteStreamURLs, peers,
micOn, camOn, connected,
toggleMic, toggleCam, leaveCall, sendTextMessage,
} = useVideoCall(client, roomId, { displayName: 'Alice' });
return (
<View style={{ flex: 1 }}>
<FlatList
data={peers}
keyExtractor={p => p.id}
numColumns={2}
renderItem={({ item }) => (
remoteStreamURLs[item.id]
? <RTCView streamURL={remoteStreamURLs[item.id]} style={{ width: '50%', aspectRatio: 1 }} />
: null
)}
/>
{localStreamURL && (
<RTCView streamURL={localStreamURL} style={{ width: 100, height: 150, position: 'absolute', bottom: 80, right: 10 }} mirror />
)}
<View style={{ flexDirection: 'row', justifyContent: 'center', padding: 12 }}>
<Button title={micOn ? 'Mute' : 'Unmute'} onPress={toggleMic} />
<Button title={camOn ? 'Cam Off' : 'Cam On'} onPress={toggleCam} />
<Button title="Leave" onPress={leaveCall} color="red" />
</View>
</View>
);
}API Reference
TruncateClient
new TruncateClient({ token, apiUrl, mediaUrl })| Param | Type | Description |
|---|---|---|
| token | string | JWT from your token server |
| apiUrl | string | API base URL (signaling, WHIP, WHEP, SSE) |
| mediaUrl | string | Media server URL |
usePublisher(client, streamId)
| Return | Type | Description |
|---|---|---|
| streamURL | string \| null | Pass to <RTCView streamURL={...} /> |
| status | string | idle \| starting \| live \| error |
| elapsed | number | Seconds since going live |
| micOn | boolean | Microphone enabled state |
| camOn | boolean | Camera enabled state |
| startStream | fn | Begin WHIP publishing |
| stopStream | fn | End stream (sends WHIP DELETE) |
| toggleMic | fn | Toggle microphone |
| toggleCam | fn | Toggle camera |
| switchCamera | fn | Flip front/back camera |
useViewer(client, streamId)
| Return | Type | Description |
|---|---|---|
| streamURL | string \| null | Pass to <RTCView streamURL={...} /> |
| status | string | connecting \| live \| waiting \| reconnecting \| error |
| muted | boolean | Current mute state |
| toggleMute | fn | Toggle audio mute |
Auto-reconnects with exponential backoff (3–10 s, max 10 retries). Returns waiting when stream is offline (HTTP 404).
useVideoCall(client, roomId, options)
| Return | Type | Description |
|---|---|---|
| localStreamURL | string \| null | Local camera stream URL |
| remoteStreamURLs | { [peerId]: string } | Remote peer stream URLs |
| peers | Peer[] | Connected participants |
| connected | boolean | Room connection state |
| micOn / camOn | boolean | Mic/cam state |
| toggleMic / toggleCam | fn | Toggle mic/cam |
| leaveCall | fn | Leave room and clean up |
| messages | ChatMessage[] | Chat history |
| sendTextMessage(text) | fn | Send chat message |
Options: { displayName: string }
useStreamInteraction(client, streamId)
| Return | Type | Description |
|---|---|---|
| chatMessages | ChatMessage[] | Broadcast chat messages |
| floatingReactions | Reaction[] | Active floating reactions (auto-expire after 3.5s) |
| settings | object | { reactionsEnabled: boolean } |
| sendReaction(emoji) | fn | Send a reaction (viewer role) |
| sendChat(message) | fn | Broadcast chat (publisher role) |
| updateSettings(patch) | fn | Update stream settings (publisher role) |
Links
- Documentation: https://streamsdk.io/docs
- Live demo: https://demo.streamsdk.io
- npm: https://www.npmjs.com/package/@truncatetechnologies/streamsdk-rn
- Issues: https://github.com/truncatetechnologies/streamsdk-rn/issues
MIT License. Copyright © Truncate Technologies.
