@videodb/recorder
v0.2.4
Published
VideoDB Recorder SDK for local recording and live transcription in Electron applications
Readme
VideoDB Desktop SDK
A Node.js SDK for local recording and live transcription in Electron applications. Capture meetings, screens, and audio with real-time transcription powered by VideoDB.
Installation
npm install @videodb/recorderQuick Start
const VideoDBRecorder = require('@videodb/recorder');
// 1. Initialize the SDK
await VideoDBRecorder.init({
apiUrl: 'https://api.videodb.io'
});
// 2. Request Permissions (macOS only)
await VideoDBRecorder.requestPermission('microphone');
await VideoDBRecorder.requestPermission('screen-capture');
// 3. Get available channels
const { channels } = await VideoDBRecorder.getChannels();
console.log('Available channels:', channels);
// 4. Listen for Events
VideoDBRecorder.addEventListener('meeting-detected', async (evt) => {
console.log('Meeting detected at:', evt.timestamp);
// Start recording with channel-based configuration
await VideoDBRecorder.startRecording({
uploadToken: 'session-token-from-backend',
sessionId: 'ss-your-session-id',
channels: [
{ channel_id: 'mic:default', type: 'audio', record: true, transcript: true, store: true },
{ channel_id: 'system_audio:default', type: 'audio', record: true, transcript: false, store: true },
{ channel_id: 'display:1', type: 'video', record: true, store: true },
],
primary_video_channel_id: 'display:1',
});
});
// 5. Handle Real-time Transcripts
VideoDBRecorder.addEventListener('transcript-segment', (data) => {
console.log(`[${data.speaker}]: ${data.text}`);
});Usage
Initialization
Initialize the SDK at application startup:
await VideoDBRecorder.init({
apiUrl: 'https://api.videodb.io', // Your VideoDB API endpoint
dev: false // Set true to use mock binary for testing
});Permissions (macOS)
On macOS, request system permissions before recording:
await VideoDBRecorder.requestPermission('microphone');
await VideoDBRecorder.requestPermission('screen-capture');
await VideoDBRecorder.requestPermission('accessibility');Listen for permission status:
VideoDBRecorder.addEventListener('permission-status', (evt) => {
console.log(`${evt.permission}: ${evt.status}`);
});Starting a Recording
Obtain a session token from your backend, then start recording with channel-based configuration:
// First, get available channels
const { channels } = await VideoDBRecorder.getChannels();
// channels: [{ channel_id: 'mic:default', type: 'audio', name: 'Microphone' }, ...]
await VideoDBRecorder.startRecording({
uploadToken: 'session-token', // Required: Auth token from backend
sessionId: 'ss-session-123', // Required: Session ID from backend
channels: [ // Required: Channel configurations
{ channel_id: 'mic:default', type: 'audio', record: true, transcript: true, store: true },
{ channel_id: 'system_audio:default', type: 'audio', record: true, transcript: false, store: true },
{ channel_id: 'display:1', type: 'video', record: true, store: true },
],
primary_video_channel_id: 'display:1', // Required: Primary video channel
ws_connection_id: 'ws-123', // Optional: WebSocket ID for transcription
callbackUrl: 'https://...', // Optional: Webhook URL
});Stopping a Recording
await VideoDBRecorder.stopRecording('session-123');Pausing and Resuming Tracks
Temporarily mute audio or video streams during a recording without stopping the session:
// Pause the microphone
await VideoDBRecorder.pauseTracks({ tracks: ['mic'] });
// Pause system audio and screen
await VideoDBRecorder.pauseTracks({ tracks: ['system_audio', 'screen'] });
// Resume tracks
await VideoDBRecorder.resumeTracks({ tracks: ['mic', 'system_audio', 'screen'] });Valid track types: mic, system_audio, screen
Note: These commands only affect the active recording. Use them when you need to temporarily mute specific inputs (e.g., during a private conversation) without stopping the entire recording session.
Cleanup
Gracefully shutdown the SDK when your app closes:
await VideoDBRecorder.shutdown();API Reference
Methods
| Method | Parameters | Description |
|--------|------------|-------------|
| init(options) | { apiUrl, dev? } | Initialize the SDK and spawn the native binary |
| requestPermission(type) | 'microphone' \| 'screen-capture' \| 'accessibility' | Request system permissions (macOS) |
| getChannels() | - | Get available audio/video channels |
| startRecording(options) | { uploadToken, sessionId, channels, primary_video_channel_id, ws_connection_id?, callbackUrl? } | Start a recording session |
| stopRecording(sessionId) | string | Stop the recording and trigger upload |
| pauseTracks(options) | { tracks: string[] } | Pause specific tracks (mic, system_audio, screen) |
| resumeTracks(options) | { tracks: string[] } | Resume specific tracks (mic, system_audio, screen) |
| shutdown() | - | Gracefully terminate the SDK |
| addEventListener(event, callback) | string, Function | Subscribe to SDK events |
| removeEventListener(event, callback) | string, Function | Unsubscribe from SDK events |
Events
| Event | Payload | Description |
|-------|---------|-------------|
| meeting-detected | { camera, event, timestamp } | Meeting window detected |
| permissions-granted | {} | All required permissions granted |
| permission-status | { permission, status } | Permission status update |
| channel-list | { channels } | Available channels list |
| recording-started | { sessionId, channels } | Recording started with RTSP URLs |
| transcript-segment | { sessionId, text, speaker } | Real-time transcription segment |
| recording-stopped | { sessionId } | Recording stopped |
| recording-complete | { sessionId, uploadId } | Upload completed |
| error | { type, message } | Error occurred |
meeting-detected Reference Payload
The meeting-detected event is emitted when an active meeting is detected. Here is the payload schema:
{
"camera": true,
"event": "meeting_detected",
"timestamp": "2026-01-07T13:55:51Z"
}recording-started Reference Payload
The recording-started event includes RTSP URLs for each active channel:
{
"sessionId": "ss-ab6dadf0-a718-4b8d-89f4-1c5985d06b2f",
"channels": [
{ "channel": "mic", "rtspUrl": "rtsps://..." },
{ "channel": "screen", "rtspUrl": "rtsps://..." },
{ "channel": "system_audio", "rtspUrl": "rtsps://..." }
]
}Backend Integration
Session Tokens
Your backend must generate session tokens by calling the VideoDB API. Never hardcode API keys in your Electron app.
Webhooks (Optional)
Provide a callbackUrl in startRecording() to receive server-side notifications:
sdk_upload.uploading- Upload startedsdk_upload.complete- Upload finished successfullysdk_upload.failed- Upload failed
Note: Real-time events (like transcription) are delivered directly to the SDK via addEventListener, not to the webhook.
Development
For contributors and binary implementers, see CONTRIBUTING.md for:
- Project architecture
- Binary protocol specification
- Testing with mock binary
- Release process
