Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Changelog

## [0.2.3] (2026-03-18)

### Changed

- Synced channel config with Python SDK: removed `transcript` field, added `isPrimary` to `RecordingChannelConfig`, `ChannelConfig`, and `Channel`
- Removed `record` from `Channel.toDict()` (always sent as `true` server-side)
- Updated capture binary to v0.2.10

### Fixed

- Clip literal types for `contentType` parameter
- Shot URLs from search results
- Caption style warning on missing fields
- `generateTranscript` language code parameter

---

## [0.2.2] (2026-03-10)

### Added
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "videodb",
"version": "0.2.2",
"version": "0.2.3",
"description": "A NodeJS wrapper for VideoDB's API written in TypeScript",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down Expand Up @@ -40,11 +40,11 @@
},
"binaryConfig": {
"baseUrl": "https://artifacts.videodb.io/capture",
"version": "0.2.8",
"version": "0.2.10",
"checksums": {
"darwin-arm64": "4aab67e524c2541bebbae24b8dd845da5d7f74fba006ce860a4914844e185c5d",
"darwin-x64": "ac67dc1a9edd2094d36e6961ed1dabab3e8b3e3e2a61655a49195b7e518901ca",
"win32-x64": "f19110d9b632c0149088abc09f4c86e0f43f64ce4b52a73bca6eb20789e156d0"
"darwin-arm64": "fc4be7de94153aa9f492b014db7b4f7378e45c3c6f1b5f3f838c2c007bde832f",
"darwin-x64": "bdfc3aa33a961ff532a99639ea95c181d51baee74a1eda555598ce45c30908ac",
"win32-x64": "3f9b9a355edc54dd06cef051b0ec7ed55df6beef6eb9e299fa6ba5f02ba3a50a"
}
},
"repository": {
Expand Down
10 changes: 5 additions & 5 deletions src/capture/captureClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ import {
* await client.startSession({
* sessionId: 'ss-xxx', // Required: from CaptureSession.id
* channels: [
* { channelId: 'mic:default', type: 'audio', record: true, transcript: true },
* { channelId: 'display:1', type: 'video', record: true },
* { channelId: 'mic:default', type: 'audio', store: true },
* { channelId: 'display:1', type: 'video', store: true },
* ],
* });
*
Expand Down Expand Up @@ -236,16 +236,16 @@ export class CaptureClient extends EventEmitter implements ChannelClient {
channel_id:
(channel as { channel_id?: string }).channel_id ?? channel.channelId,
type: channel.type,
record: channel.record ?? true,
transcript: channel.transcript ?? false,
store: channel.store ?? true,
is_primary: channel.isPrimary ?? false,
}));

if (channels.some(ch => !ch.channel_id)) {
throw new Error('channels must include channelId for each channel');
}

const primaryVideo = channels.find(ch => ch.type === 'video');
const primaryVideo = channels.find(ch => ch.is_primary && ch.type === 'video')
|| channels.find(ch => ch.type === 'video');

await this.binaryManager.sendCommand('startRecording', {
uploadToken: this.sessionToken,
Expand Down
20 changes: 14 additions & 6 deletions src/capture/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export class Channel {
public readonly name: string;
public readonly type: 'audio' | 'video';
public store: boolean = false;
public isPrimary: boolean = false;

/** Reference to the CaptureClient for pause/resume operations */
#client: ChannelClient | null = null;
Expand Down Expand Up @@ -85,15 +86,15 @@ export class Channel {
channel_id: string;
type: string;
name: string;
record: boolean;
store: boolean;
is_primary: boolean;
} {
return {
channel_id: this.id,
type: this.type,
name: this.name,
record: true,
store: this.store,
is_primary: this.isPrimary,
};
}

Expand Down Expand Up @@ -150,19 +151,23 @@ export class Channels {
public displays: ChannelList<VideoChannel>;
/** System audio channels */
public systemAudio: ChannelList<AudioChannel>;
/** Camera channels (not yet supported for capture) */
public cameras: ChannelList<VideoChannel>;

constructor(
mics: AudioChannel[] = [],
displays: VideoChannel[] = [],
systemAudio: AudioChannel[] = []
systemAudio: AudioChannel[] = [],
cameras: VideoChannel[] = []
) {
this.mics = new ChannelList<AudioChannel>(...mics);
this.displays = new ChannelList<VideoChannel>(...displays);
this.systemAudio = new ChannelList<AudioChannel>(...systemAudio);
this.cameras = new ChannelList<VideoChannel>(...cameras);
}

/**
* Return a flat list of all channels
* Return a flat list of all capturable channels (excludes cameras)
*/
public all(): Channel[] {
return [
Expand All @@ -173,7 +178,7 @@ export class Channels {
}

toString(): string {
return `Channels(mics=${this.mics.length}, displays=${this.displays.length}, systemAudio=${this.systemAudio.length})`;
return `Channels(mics=${this.mics.length}, displays=${this.displays.length}, systemAudio=${this.systemAudio.length}, cameras=${this.cameras.length})`;
}
}

Expand Down Expand Up @@ -209,6 +214,7 @@ export function groupChannels(
const mics: AudioChannel[] = [];
const displays: VideoChannel[] = [];
const systemAudio: AudioChannel[] = [];
const cameras: VideoChannel[] = [];

for (const ch of channels) {
const channelId = ch.channelId;
Expand All @@ -222,6 +228,8 @@ export function groupChannels(
displays.push(new VideoChannel(ch, client));
} else if (channelId.startsWith('system_audio:')) {
systemAudio.push(new AudioChannel(ch, client));
} else if (channelId.startsWith('camera:')) {
cameras.push(new VideoChannel(ch, client));
} else if (ch.type === 'audio') {
// Fallback for unknown audio channels
mics.push(new AudioChannel(ch, client));
Expand All @@ -231,5 +239,5 @@ export function groupChannels(
}
}

return new Channels(mics, displays, systemAudio);
return new Channels(mics, displays, systemAudio, cameras);
}
4 changes: 2 additions & 2 deletions src/capture/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
* await client.startSession({
* sessionId: 'ss-xxx', // Required: from CaptureSession.id
* channels: [
* { channelId: 'mic:default', type: 'audio', record: true, transcript: true },
* { channelId: 'display:1', type: 'video', record: true },
* { channelId: 'mic:default', type: 'audio', store: true },
* { channelId: 'display:1', type: 'video', store: true },
* ],
* });
*
Expand Down
8 changes: 4 additions & 4 deletions src/capture/installer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ export class RecorderInstaller {
// Default binary config - can be overridden or loaded from package.json
this.binaryConfig = binaryConfig || {
baseUrl: 'https://artifacts.videodb.io/capture',
version: '0.2.8',
version: '0.2.10',
checksums: {
'darwin-x64': 'ac67dc1a9edd2094d36e6961ed1dabab3e8b3e3e2a61655a49195b7e518901ca',
'darwin-arm64': '4aab67e524c2541bebbae24b8dd845da5d7f74fba006ce860a4914844e185c5d',
'win32-x64': 'f19110d9b632c0149088abc09f4c86e0f43f64ce4b52a73bca6eb20789e156d0',
'darwin-x64': 'bdfc3aa33a961ff532a99639ea95c181d51baee74a1eda555598ce45c30908ac',
'darwin-arm64': 'fc4be7de94153aa9f492b014db7b4f7378e45c3c6f1b5f3f838c2c007bde832f',
'win32-x64': '3f9b9a355edc54dd06cef051b0ec7ed55df6beef6eb9e299fa6ba5f02ba3a50a',
},
};

Expand Down
6 changes: 2 additions & 4 deletions src/capture/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,10 @@ export interface RecordingChannelConfig {
channelId: string;
/** Channel type */
type: 'audio' | 'video';
/** Whether to record this channel */
record?: boolean;
/** Whether to enable transcription */
transcript?: boolean;
/** Whether to store the recording */
store?: boolean;
/** Whether this is the primary video channel */
isPrimary?: boolean;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/core/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,12 @@ export class CaptionAsset {

constructor(config: CaptionAssetConfig = {}) {
this.src = config.src ?? 'auto';
if (this.src === 'auto') {
console.warn(
"CaptionAsset(src='auto'): the video must be indexed " +
'(e.g. video.indexSpokenWords()) for captions to be generated.'
);
}
this.font = config.font ?? new FontStyling();
this.primaryColor = config.primaryColor ?? '&H00FFFFFF';
this.secondaryColor = config.secondaryColor ?? '&H000000FF';
Expand Down
2 changes: 2 additions & 0 deletions src/core/search/searchResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export class SearchResult {
sceneIndexId: doc.sceneIndexId,
sceneIndexName: doc.sceneIndexName,
metadata: doc.metadata,
streamUrl: doc.streamLink,
playerUrl: doc.playerUrl,
})
);
}
Expand Down
9 changes: 5 additions & 4 deletions src/core/video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,12 @@ export class Video implements IVideo {
* @returns Success status or transcript data
*/
public generateTranscript = async (
force: boolean = false
force: boolean = false,
languageCode?: string
): Promise<{ success: boolean; message: string } | Transcript> => {
const res = await this.#vhttp.post<TranscriptResponse, object>(
[video, this.id, transcription],
{ force }
{ force, language_code: languageCode }
);

const transcript = res.data?.wordTimestamps;
Expand Down Expand Up @@ -818,8 +819,8 @@ export class Video implements IVideo {
*/
public clip = async (
prompt: string,
contentType: string,
modelName: string
contentType: 'spoken' | 'visual' | 'multimodal',
modelName: 'basic' | 'pro' | 'ultra'
): Promise<SearchResult> => {
type ClipResponse = {
results: Array<{
Expand Down
6 changes: 2 additions & 4 deletions src/types/capture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,10 @@ export interface ChannelConfig {
channelId: string;
/** Type of the channel */
type: ChannelTypeValue;
/** Whether to record this channel */
record?: boolean;
/** Whether to enable transcription for this channel (audio only) */
transcript?: boolean;
/** Whether to store the recorded content */
store?: boolean;
/** Whether this is the primary video channel */
isPrimary?: boolean;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/types/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ export type SearchResponse = {
end: number;
score: number;
start: number;
stream_url: string;
stream_link?: string;
player_url?: string;
text: string;
scene_index_id?: string;
scene_index_name?: string;
Expand Down
Loading