Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
cb276e3
feat: removing `Job` handling completely
omgate234 Jan 19, 2026
3c614f8
feat: fetch time case conversion in `makeRequest`
omgate234 Jan 19, 2026
3c19859
feat: ts and linting fixes
omgate234 Jan 19, 2026
071a271
fix: file upload
omgate234 Jan 19, 2026
41e4686
feat: feature parity
omgate234 Jan 19, 2026
bf180f5
chore: removed redundant files
omgate234 Jan 19, 2026
4f1604f
Merge pull request #31 from omgate234/feat/0.3.0
omgate234 Jan 19, 2026
cf9d8f6
feat: `prepare` command for git installs
omgate234 Jan 19, 2026
27bfbbc
fix: correct tsconfig.build to only include src files
omgate234 Jan 19, 2026
8cbd564
fix: update entrypoints to match dist/src structure
omgate234 Jan 19, 2026
5e0c976
fix: revert entrypoints to dist/index.js
omgate234 Jan 19, 2026
a6d5e7b
Merge pull request #32 from omgate234/feat/0.3.0
omgate234 Jan 19, 2026
75cce8a
feat: removed `meta` bound info to flat access
omgate234 Jan 19, 2026
b30ce0d
Merge pull request #33 from omgate234/feat/0.3.0
omgate234 Jan 19, 2026
9cc6249
feat: `v0.4.0` parity with python SDK
omgate234 Jan 19, 2026
94f4d53
Merge pull request #34 from omgate234/feat/0.4.0
omgate234 Jan 19, 2026
27a5424
feat: version bump to `v0.3.0`
omgate234 Jan 20, 2026
e0ca457
feat: recorder sdk addition
omgate234 Jan 20, 2026
60644b5
feat: reproduce recorder sdk setup script
omgate234 Jan 20, 2026
f7bec88
feat: new interface handling
omgate234 Jan 20, 2026
ec52548
fix: types and keys
omgate234 Jan 20, 2026
1bc51fb
test: extras
omgate234 Jan 20, 2026
5ad108b
fix: correct channel_id mapping
omgate234 Jan 20, 2026
703aa25
feat: missing keys
omgate234 Jan 20, 2026
bbd1507
feat: feature parity with python SDK
omgate234 Jan 21, 2026
ad62a59
feat: no trailing slashes
omgate234 Jan 21, 2026
2bace2d
feat: rtstream synced with python SDK
omgate234 Jan 21, 2026
45f8085
feat: websocket feature parity
omgate234 Jan 21, 2026
9ffdbaa
feat: websocket logger
omgate234 Jan 21, 2026
a3aebeb
feat: rtstream naming change
omgate234 Jan 21, 2026
31a5d81
feat: docs page
omgate234 Jan 21, 2026
cd1c2a4
docfix: correct command
omgate234 Jan 21, 2026
e7bad7e
Merge pull request #2 from omgate234/feat/recorder-sdk
omgate234 Jan 21, 2026
298f57a
fix: correct branch for docs
omgate234 Jan 21, 2026
cbded28
Merge branch 'feat/0.4.0' of https://github.com/omgate234/videodb-nod…
omgate234 Jan 21, 2026
3ab160f
Merge pull request #35 from omgate234/feat/0.4.0
omgate234 Jan 21, 2026
b15b540
feat: `listRtstreams` options for query params
omgate234 Jan 21, 2026
9a818cc
feat: remove logger module
omgate234 Jan 21, 2026
9a84c6b
feat: `wsConnectionId` for rtstream indexings
omgate234 Jan 21, 2026
4ec5189
feat: session and client token update
omgate234 Jan 22, 2026
ea4354d
feat: feature parity with python and cleanup format
omgate234 Jan 23, 2026
feb13c6
feat: case conversion for inputs
omgate234 Jan 27, 2026
43298ff
utils file
omgate234 Jan 27, 2026
685f218
feat: reframe options
omgate234 Jan 27, 2026
711bfc8
feat: docs branch
omgate234 Jan 27, 2026
2979bf9
feat: meeting attributes
omgate234 Jan 27, 2026
6265707
feat: docs from main branch
omgate234 Jan 27, 2026
60eb56d
feat: `streamUrl` caching
omgate234 Jan 27, 2026
9888fda
feat: updated `CHANGELOG`
omgate234 Feb 2, 2026
33df3b7
feat: apiUrl to binaryManager
omgate234 Feb 3, 2026
d32ebd6
Update recorder binary to version 0.2.5
lalit-videodb Feb 6, 2026
939a8e6
Fix binary version in package.json
lalit-videodb Feb 7, 2026
ea7ddc8
update scene index method
0xrohitgarg Feb 8, 2026
2ae7aa1
Merge branch 'release-0.4.0' of github.com:video-db/videodb-node into…
0xrohitgarg Feb 8, 2026
614bd4f
fix: handle EPIPE crash, robust requestPermission parsing, bump binar…
lalit-videodb Feb 10, 2026
57c6aa4
feat: list capture sessions
omgate234 Feb 10, 2026
824e1f2
fix: consolidate installer to single source of truth
lalit-videodb Feb 10, 2026
26529fb
Merge branch 'release-0.4.0', remote-tracking branch 'origin' into re…
omgate234 Feb 10, 2026
b89d8c3
feat: version match with 0.3.0
omgate234 Feb 10, 2026
df74a5a
Merge branch 'release-0.4.0' into release-0.3.0
omgate234 Feb 10, 2026
9137a98
fix: handle missing dist folder in setup.js
lalit-videodb Feb 10, 2026
af908d9
fix: restore lib/installer.js for npm install compatibility
lalit-videodb Feb 10, 2026
111b044
fix: support params for list capture sessions
omgate234 Feb 10, 2026
aed5186
Merge pull request #39 from video-db/release-0.4.0
lalit-videodb Feb 10, 2026
c36333e
chore: bump binary version to 0.2.7
lalit-videodb Feb 11, 2026
7a91892
feat: Python SDK sync
omgate234 Feb 12, 2026
2df90c3
feat: media type connection for rtstream
omgate234 Feb 12, 2026
663f3f9
feat: rtstream index scenes
omgate234 Feb 12, 2026
4971e2f
feat: python SDK sync for default values
omgate234 Feb 12, 2026
a3377c1
feat: `startCaptureSession`, `stopCaptureSession` -> `startCapture`, …
omgate234 Feb 12, 2026
b295608
feat: v0.2.0
omgate234 Feb 12, 2026
9539727
feat: export method in rtstream
omgate234 Feb 12, 2026
0c6ed6c
feat: clientId in capture session
omgate234 Feb 12, 2026
bda1662
feat: search added params and values
omgate234 Feb 12, 2026
dd2343c
feat: new checksums
omgate234 Feb 12, 2026
efa4d9b
fix: case conversion bug
omgate234 Feb 12, 2026
16acb65
feat: updated checksums
omgate234 Feb 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
239 changes: 239 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,244 @@
# Changelog

## [0.2.0] (2026-02-02)

### ⚠️ Breaking Changes

- **Removed meta wrapper from all classes** - Access properties directly instead of through `.meta`
- **Removed Job-based pattern** - All async operations now use async/await directly
- **Upload methods now return media objects directly** - No longer returns Job instances
- **Removed exports:** `Job`, `TranscriptJob`, `UploadJob`, `IndexJob`, `SceneIndexJob`, `ExtractScenesJob`

### New Modules

#### Capture Sessions (Desktop Recording)

Backend orchestration for desktop capture sessions with native binary support:

- **CaptureSession** (`cap-xxx`) - Server-side lifecycle object for capture runs
- **CaptureClient** - Desktop client for recording mic, system audio, and display
- **Session Token Authentication** - Secure client auth without exposing API keys
- **WebSocket Integration** - Real-time transcript and indexing event delivery

```typescript
// Backend: Create session and generate token
const cap = await coll.createCaptureSession({
endUserId: 'user_abc',
callbackUrl: 'https://example.com/webhook',
});
const token = await conn.generateClientToken(86400);

// Desktop client: Start capture
import { CaptureClient } from 'videodb/capture';
const client = new CaptureClient({ sessionToken: token });
await client.requestPermission('microphone');
await client.startCaptureSession({ sessionId: cap.id, channels: [...] });
```

**Supported channels:**
- `mic:default` (audio)
- `system_audio:default` (audio)
- `display:1`, `display:2`, ... (video)

#### Meeting Module

Record and manage meetings with bot integration:

```typescript
const meeting = await coll.recordMeeting({
meetingUrl: 'https://meet.google.com/xxx',
botName: 'RecorderBot',
callbackUrl: 'https://example.com/webhook',
});
```

#### RTStream Module

Real-time media streams for live capture and indexing:

- **RTStream** (`rts-xxx`) - Real-time media stream per channel
- **RTStreamSceneIndex** - Visual scene indexing on live streams
- **RTStreamSearchResult** / **RTStreamShot** - Search results from RTStreams

```typescript
const mic = cap.getRtstream('mic:default');
await mic.startTranscript({ socketId: ws.connectionId });

const scenes = await display.indexVisuals({
batchConfig: { type: 'time', value: 2, frameCount: 2 },
prompt: 'Describe the scene',
socketId: ws.connectionId,
});
await scenes.start();
```

#### Editor Module

Comprehensive video editing with Timeline, Track, and asset classes:

```typescript
import {
EditorTimeline,
Track,
Clip,
EditorVideoAsset,
CaptionAsset,
} from 'videodb';

const timeline = new EditorTimeline(conn);
const track = new Track();
track.addItem(new Clip({ asset: new EditorVideoAsset({ assetId: video.id }) }));
timeline.addTrack(track);
```

**New asset classes:**
- `EditorVideoAsset`, `EditorImageAsset`, `EditorAudioAsset`, `EditorTextAsset`, `CaptionAsset`

**Helper classes:**
- `Offset`, `Crop`, `Transition`, `Font`, `Border`, `Shadow`, `Background`, `Alignment`, `FontStyling`, `BorderAndShadow`, `Positioning`

**Enums:**
- `AssetType`, `Fit`, `Position`, `Filter`, `TextAlignment`, `HorizontalAlignment`, `VerticalAlignment`, `CaptionBorderStyle`, `CaptionAlignment`, `CaptionAnimation`

#### WebSocket Module

Real-time event streaming for transcript and indexing:

```typescript
const ws = await conn.connectWebsocket();
await ws.connect();

for await (const ev of ws.stream()) {
if (ev.channel === 'transcript') console.log(ev.data?.text);
if (ev.channel === 'scene_index') console.log(ev.data);
}
```

### New Methods

#### Video

- `getTranscriptText(start?, end?)` - Get plain text transcript
- `generateTranscript(force?)` - Generate transcript via POST
- `translateTranscript(language, additionalNotes?, callbackUrl?)` - Translate transcript
- `removeStorage()` - Remove video storage
- `getThumbnails()` - Get all thumbnails as Image objects
- `insertVideo(video, timestamp)` - Insert another video at timestamp
- `reframe(options?)` - Reframe video to new aspect ratio
- `smartVerticalReframe(options?)` - Object-aware vertical reframing
- `download(name?)` - Download video from stream URL
- `getMeeting()` - Get associated meeting info
- `clip(prompt, contentType, modelName)` - Generate clip from prompt

#### Audio

- `getTranscript(start?, end?, segmenter?, length?, force?)` - Get timestamped transcript
- `getTranscriptText(start?, end?)` - Get plain text transcript
- `generateTranscript(force?, languageCode?)` - Generate transcript
- `generateUrl()` - Generate signed URL

#### Image

- `generateUrl()` - Generate signed URL

#### Collection

- `delete()` - Delete the collection
- `makePublic()` / `makePrivate()` - Toggle collection visibility
- `generateVideo(prompt, duration?, callbackUrl?)` - Generate video from prompt
- `generateImage(prompt, aspectRatio?, callbackUrl?)` - Generate image from prompt
- `generateMusic(prompt, duration?, callbackUrl?)` - Generate music from prompt
- `generateSoundEffect(prompt, duration?, config?, callbackUrl?)` - Generate sound effect
- `generateVoice(text, voiceName?, config?, callbackUrl?)` - Generate voice from text
- `generateText(prompt, modelName?, responseType?)` - Generate text with GenAI
- `dubVideo(videoId, languageCode, callbackUrl?)` - Dub video to another language
- `searchTitle(query)` - Search by video title
- `connectRTStream(url, name, ...)` - Connect to real-time stream
- `getRTStream(id)` - Get RTStream by ID
- `listRTStreams(options?)` - List all RTStreams
- `recordMeeting(config)` - Record a meeting
- `getMeeting(meetingId)` - Get meeting by ID
- `createCaptureSession(config)` - Create capture session

#### Connection

- `recordMeeting(config)` - Record meeting to default collection
- `getMeeting(meetingId)` - Get meeting by ID
- `youtubeSearch(query, resultThreshold?, duration?)` - Search YouTube
- `download(streamLink, name)` - Download from stream link
- `transcode(source, callbackUrl, mode?, videoConfig?, audioConfig?)` - Transcode video
- `getTranscodeDetails(jobId)` - Get transcode job details
- `createEvent(eventPrompt, label)` - Create RTStream event
- `listEvents()` - List all RTStream events
- `checkUsage()` - Check account usage
- `getInvoices()` - Get list of invoices
- `connectWebsocket(collectionId?)` - Connect to WebSocket service
- `getCaptureSession(sessionId, collectionId?)` - Get capture session
- `listCaptureSessions(collectionId?, config?)` - List capture sessions
- `createCaptureSession(config)` - Create capture session (convenience)
- `generateClientToken(expiresIn?)` - Generate client token for capture

#### Scene

- Added `metadata` property for scene metadata

### New Types & Exports

#### Capture Session Types

```typescript
export {
ConnectionConfig,
CaptureSessionStatus,
ChannelType,
PermissionKind,
TranscriptStatusValues,
WebSocketChannel,
BatchConfig,
IndexVisualsConfig,
IndexSpokenWordsConfig,
AlertConfig,
// ... and more
} from 'videodb';
```

#### Editor Types

```typescript
export {
OffsetConfig,
CropConfig,
TransitionConfig,
FontConfig,
EditorVideoAssetConfig,
ClipConfig,
// ... and more
} from 'videodb';
```

#### Additional Exports

- `MeetingStatus`, `Segmenter`, `SegmentationType`
- `ReframeMode`, `ReframePreset`
- `TranscodeMode`, `ResizeMode`, `MediaType`
- `TextStyle`, `TextStyleConfig`
- `SpokenIndex`, `SceneIndex`, `SceneData`, `AlertData`

### Internal Improvements

- **Centralized snake_case/camelCase conversion** - Handled in HttpClient for consistent API communication
- **Simplified error handling** - Proper exception propagation with typed errors
- **Reduced bundle size** - Removed Job infrastructure (~400 lines)
- **Dual authentication support** - API key (backend) and session token (client) modes

### New Error Types

- `CaptureError` - Capture session related errors
- `BinaryError` - Native binary communication errors
- `PermissionError` - System permission errors

---

## [0.1.3] (2026-01-19)

### Added
Expand Down
134 changes: 134 additions & 0 deletions lib/installer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
const fs = require('fs');
const path = require('path');
const https = require('https');
const crypto = require('crypto');
const tar = require('tar');

class Installer {
constructor(config) {
this.config = config;
this.platform = process.platform;
this.arch = process.arch;
this.binDir = path.join(__dirname, '..', 'bin');
}

isPlatformSupported() {
const platformKey = `${this.platform}-${this.arch}`;
return this.config.checksums && this.config.checksums[platformKey];
}

getDownloadUrl() {
const platformKey = `${this.platform}-${this.arch}`;
return `${this.config.baseUrl}/v${this.config.version}/recorder-${platformKey}.tar.gz`;
}

getExpectedChecksum() {
const platformKey = `${this.platform}-${this.arch}`;
return this.config.checksums[platformKey];
}

async downloadFile(url, destPath) {
return new Promise((resolve, reject) => {
const file = fs.createWriteStream(destPath);
https.get(url, (response) => {
if (response.statusCode === 302 || response.statusCode === 301) {
file.close();
fs.unlinkSync(destPath);
this.downloadFile(response.headers.location, destPath)
.then(resolve)
.catch(reject);
return;
}
if (response.statusCode !== 200) {
file.close();
fs.unlinkSync(destPath);
reject(new Error(`Failed to download: ${response.statusCode}`));
return;
}
response.pipe(file);
file.on('finish', () => {
file.close();
resolve();
});
}).on('error', (err) => {
fs.unlink(destPath, () => { });
reject(err);
});
});
}

async verifyChecksum(filePath, expectedChecksum) {
return new Promise((resolve, reject) => {
const hash = crypto.createHash('sha256');
const stream = fs.createReadStream(filePath);
stream.on('data', data => hash.update(data));
stream.on('end', () => {
const actualChecksum = hash.digest('hex');
if (actualChecksum !== expectedChecksum) {
reject(new Error(`Checksum mismatch: expected ${expectedChecksum}, got ${actualChecksum}`));
} else {
resolve(true);
}
});
stream.on('error', reject);
});
}

async install() {
console.log(`Installing VideoDB Recorder for ${this.platform}-${this.arch}...`);

if (!this.isPlatformSupported()) {
const platformKey = `${this.platform}-${this.arch}`;
console.warn(`Platform ${platformKey} is not currently supported.`);
console.warn(`Supported platforms: ${Object.keys(this.config.checksums || {}).join(', ')}`);
console.warn('Skipping binary installation.');
return;
}

if (!fs.existsSync(this.binDir)) {
fs.mkdirSync(this.binDir, { recursive: true });
}

const platformKey = `${this.platform}-${this.arch}`;
const tarPath = path.join(this.binDir, `recorder-${platformKey}.tar.gz`);
const binaryName = this.platform === 'win32' ? 'recorder.exe' : 'recorder';
const binaryPath = path.join(this.binDir, binaryName);
const url = this.getDownloadUrl();

if (fs.existsSync(binaryPath)) {
console.log('Binary already installed, skipping download.');
return;
}

try {
console.log(`Downloading from ${url}...`);
await this.downloadFile(url, tarPath);

console.log('Verifying checksum...');
await this.verifyChecksum(tarPath, this.getExpectedChecksum());
console.log('Checksum verified.');

console.log('Extracting binary...');
await tar.x({
file: tarPath,
cwd: this.binDir
});

fs.unlinkSync(tarPath);

if (this.platform !== 'win32') {
fs.chmodSync(binaryPath, 0o755);
}

console.log('Installation complete!');
} catch (error) {
console.error('Installation failed:', error.message);
if (fs.existsSync(tarPath)) {
fs.unlinkSync(tarPath);
}
process.exit(1);
}
}
}

module.exports = Installer;
Loading