Skip to content
Open
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
143 changes: 142 additions & 1 deletion js/module.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,7 @@ export interface IVideo {
destroy(): void;
readonly skippedFrames: number;
readonly encodedFrames: number;
readonly canvasId: number;
}
export interface IVideoFactory {
create(): IVideo;
Expand Down Expand Up @@ -965,11 +966,151 @@ export interface IAudioTrackFactory {
importLegacySettings(): void;
saveLegacySettings(): void;
}
export interface IAutoConfigCapabilities {
apiVersion: 2;
resultSchemaVersion: 1;
previewApplySplit: true;
awaitableCancel: true;
perUploadLegResults: true;
desktopOwnedApply: true;
multipleActiveProbes: true;
bandwidthModes: ['twitch-standard-active', 'youtube-unbound-active', 'estimate'];
}
export type AutoConfigTopology = 'direct-single' | 'cloud-multistream' | 'custom-rtmp' | 'dual-output' | 'enhanced-broadcasting' | 'stream-shift' | 'mixed';
export type AutoConfigDisplay = 'horizontal' | 'vertical' | 'both';
export type AutoConfigPlatform = 'twitch' | 'youtube' | 'facebook' | 'kick' | 'tiktok' | 'custom' | 'other';
export type AutoConfigEstimateReason = 'non_twitch' | 'custom_rtmp' | 'cloud_multistream' | 'dual_output' | 'enhanced_broadcasting' | 'stream_shift' | 'mixed_topology' | 'probe_disabled';
export interface IAutoConfigDestination {
platform: AutoConfigPlatform;
}
export interface IAutoConfigCurrentSettings {
width: number;
height: number;
fpsNum: number;
fpsDen: number;
bitrateKbps: number;
encoderId: string;
codec: string;
preset?: string;
}
export interface IAutoConfigLimits {
maxBitrateKbps?: number;
maxWidth?: number;
maxHeight?: number;
maxFpsNum?: number;
maxFpsDen?: number;
}
export interface IAutoConfigLegRequest {
legId: string;
display: AutoConfigDisplay;
destinations: IAutoConfigDestination[];
current: IAutoConfigCurrentSettings;
limits?: IAutoConfigLimits;
estimateReason?: AutoConfigEstimateReason;
}
export interface IAutoConfigTwitchActiveProbe {
probeId: string;
kind: 'twitch-standard-v1';
legId: string;
serviceName: 'Twitch';
server: string;
streamKey: string;
}
export interface IAutoConfigYoutubeActiveProbe {
probeId: string;
kind: 'youtube-unbound-v1';
legId: string;
serviceName: 'YouTube - RTMPS';
server: string;
streamKey: string;
}
export type IAutoConfigActiveProbe = IAutoConfigTwitchActiveProbe | IAutoConfigYoutubeActiveProbe;
export interface IAutoConfigRequest {
schemaVersion: 1;
topology: AutoConfigTopology;
legs: IAutoConfigLegRequest[];
activeProbes?: IAutoConfigActiveProbe[];
}
export type AutoConfigEventType = 'phase' | 'progress' | 'result' | 'error' | 'cancelled' | 'complete';
export type AutoConfigPhase = 'preflight' | 'hardware' | 'bandwidth' | 'recommendation' | 'cleanup';
export type AutoConfigMeasurementMode = 'active' | 'estimated';
export interface IAutoConfigEvent {
schemaVersion: 1;
sessionId: string;
sequence: number;
type: AutoConfigEventType;
phase: AutoConfigPhase;
progress: number;
code?: string;
legId?: string;
measurementMode?: AutoConfigMeasurementMode;
probeId?: string;
provider?: 'twitch' | 'youtube';
targetBitrateKbps?: number;
}
export interface IAutoConfigProbeMeasurement {
provider: 'twitch' | 'youtube';
method: 'twitch-bandwidth-test-v1' | 'youtube-unbound-ramp-v1';
success: boolean;
measuredKbps?: number;
safeKbps?: number;
headroomPercent?: number;
ceilingReached: boolean;
}
export interface IAutoConfigMeasurement {
mode: AutoConfigMeasurementMode;
confidence: 'high' | 'medium' | 'low';
reason?: string;
probes?: IAutoConfigProbeMeasurement[];
}
export interface IAutoConfigRecommendation {
width: number;
height: number;
fpsNum: number;
fpsDen: number;
bitrateKbps: number;
encoderId: string;
codec: string;
preset?: string;
}
export interface IAutoConfigResultDestination {
platform: string;
}
export interface IAutoConfigLegResult {
legId: string;
display: AutoConfigDisplay;
destinations: IAutoConfigResultDestination[];
measurement: IAutoConfigMeasurement;
recommendation: IAutoConfigRecommendation;
limits?: IAutoConfigLimits;
}
export interface IAutoConfigError {
code: string;
}
export interface IAutoConfigResult {
schemaVersion: 1;
sessionId: string;
status: 'complete' | 'partial' | 'cancelled' | 'failed';
error?: IAutoConfigError;
legs: IAutoConfigLegResult[];
}
export interface IAutoConfigNativeApi {
GetAutoConfigCapabilities(): string;
CreateAutoConfigSession(requestJson: string, callback: (event: IAutoConfigEvent) => void): string;
StartAutoConfigSession(sessionId: string): void;
ConfirmAutoConfigProbeIngest(sessionId: string, probeId: string, received: boolean): void;
GetAutoConfigResult(sessionId: string): string;
CancelAutoConfigSession(sessionId: string): void;
CloseAutoConfigSession(sessionId: string): void;
}
export interface INodeObsApi extends IAutoConfigNativeApi {
[key: string]: any;
}
export declare const enum VCamOutputType {
Invalid = 0,
SceneOutput = 1,
SourceOutput = 2,
ProgramView = 3,
PreviewOutput = 4
}
export declare const NodeObs: any;
export declare const NodeObs: INodeObsApi;
211 changes: 210 additions & 1 deletion js/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1470,6 +1470,11 @@ export interface IVideo {
* Number of total encoded frames
*/
readonly encodedFrames: number;

/**
* Server-side canvas id. Pass to APIs that reference video contexts by id.
*/
readonly canvasId: number;
}

export interface IVideoFactory {
Expand Down Expand Up @@ -1921,6 +1926,210 @@ export interface IAudioTrackFactory {
saveLegacySettings(): void;
}

// ---- Auto Optimizer API v1 (native API version 2) ----

export interface IAutoConfigCapabilities {
apiVersion: 2;
resultSchemaVersion: 1;
previewApplySplit: true;
awaitableCancel: true;
perUploadLegResults: true;
desktopOwnedApply: true;
multipleActiveProbes: true;
bandwidthModes: ['twitch-standard-active', 'youtube-unbound-active', 'estimate'];
}

export type AutoConfigTopology =
'direct-single' |
'cloud-multistream' |
'custom-rtmp' |
'dual-output' |
'enhanced-broadcasting' |
'stream-shift' |
'mixed';

export type AutoConfigDisplay = 'horizontal' | 'vertical' | 'both';

export type AutoConfigPlatform =
'twitch' |
'youtube' |
'facebook' |
'kick' |
'tiktok' |
'custom' |
'other';

export type AutoConfigEstimateReason =
'non_twitch' |
'custom_rtmp' |
'cloud_multistream' |
'dual_output' |
'enhanced_broadcasting' |
'stream_shift' |
'mixed_topology' |
'probe_disabled';

export interface IAutoConfigDestination {
platform: AutoConfigPlatform;
}

export interface IAutoConfigCurrentSettings {
width: number;
height: number;
fpsNum: number;
fpsDen: number;
bitrateKbps: number;
encoderId: string;
codec: string;
preset?: string;
}

export interface IAutoConfigLimits {
maxBitrateKbps?: number;
maxWidth?: number;
maxHeight?: number;
maxFpsNum?: number;
maxFpsDen?: number;
}

export interface IAutoConfigLegRequest {
legId: string;
display: AutoConfigDisplay;
destinations: IAutoConfigDestination[];
current: IAutoConfigCurrentSettings;
limits?: IAutoConfigLimits;
estimateReason?: AutoConfigEstimateReason;
}

export interface IAutoConfigTwitchActiveProbe {
probeId: string;
kind: 'twitch-standard-v1';
legId: string;
serviceName: 'Twitch';
server: string;
streamKey: string;
}

export interface IAutoConfigYoutubeActiveProbe {
/**
* Security contract: Desktop's trusted worker must create an exact-marked,
* reusable-but-unbound liveStream and status-confirm that same resource.
* Native validates the official RTMPS endpoint but cannot query YouTube
* resource ownership or binding. Desktop must close the native session
* before deleting the liveStream through the YouTube API.
*/
probeId: string;
kind: 'youtube-unbound-v1';
legId: string;
serviceName: 'YouTube - RTMPS';
server: string;
streamKey: string;
}

export type IAutoConfigActiveProbe = IAutoConfigTwitchActiveProbe | IAutoConfigYoutubeActiveProbe;

export interface IAutoConfigRequest {
schemaVersion: 1;
topology: AutoConfigTopology;
legs: IAutoConfigLegRequest[];
activeProbes?: IAutoConfigActiveProbe[];
}

export type AutoConfigEventType = 'phase' | 'progress' | 'result' | 'error' | 'cancelled' | 'complete';
export type AutoConfigPhase = 'preflight' | 'hardware' | 'bandwidth' | 'recommendation' | 'cleanup';
export type AutoConfigMeasurementMode = 'active' | 'estimated';

export interface IAutoConfigEvent {
schemaVersion: 1;
sessionId: string;
sequence: number;
type: AutoConfigEventType;
phase: AutoConfigPhase;
progress: number;
code?: string;
legId?: string;
measurementMode?: AutoConfigMeasurementMode;
probeId?: string;
provider?: 'twitch' | 'youtube';
/** Applied video bitrate for the active probe substep; audio is additional. */
targetBitrateKbps?: number;
}

export interface IAutoConfigProbeMeasurement {
provider: 'twitch' | 'youtube';
method: 'twitch-bandwidth-test-v1' | 'youtube-unbound-ramp-v1';
success: boolean;
/** Observed aggregate RTMP throughput, including audio. */
measuredKbps?: number;
/** Safe video bitrate after headroom and the probe audio reserve. */
safeKbps?: number;
headroomPercent?: number;
ceilingReached: boolean;
}

export interface IAutoConfigMeasurement {
mode: AutoConfigMeasurementMode;
confidence: 'high' | 'medium' | 'low';
reason?: string;
probes?: IAutoConfigProbeMeasurement[];
}

export interface IAutoConfigRecommendation {
width: number;
height: number;
fpsNum: number;
fpsDen: number;
bitrateKbps: number;
encoderId: string;
codec: string;
preset?: string;
}

export interface IAutoConfigResultDestination {
platform: string;
}

export interface IAutoConfigLegResult {
legId: string;
display: AutoConfigDisplay;
destinations: IAutoConfigResultDestination[];
measurement: IAutoConfigMeasurement;
recommendation: IAutoConfigRecommendation;
limits?: IAutoConfigLimits;
}

export interface IAutoConfigError {
code: string;
}

export interface IAutoConfigResult {
schemaVersion: 1;
sessionId: string;
status: 'complete' | 'partial' | 'cancelled' | 'failed';
error?: IAutoConfigError;
legs: IAutoConfigLegResult[];
}

/** Raw native methods. Requests and results cross IPC as JSON strings. */
export interface IAutoConfigNativeApi {
GetAutoConfigCapabilities(): string;
CreateAutoConfigSession(requestJson: string, callback: (event: IAutoConfigEvent) => void): string;
StartAutoConfigSession(sessionId: string): void;
ConfirmAutoConfigProbeIngest(sessionId: string, probeId: string, received: boolean): void;
GetAutoConfigResult(sessionId: string): string;
CancelAutoConfigSession(sessionId: string): void;
CloseAutoConfigSession(sessionId: string): void;
}

/**
* Most of the addon's non-optimizer surface remains dynamically typed. This
* intersection gives the Auto Optimizer methods useful declarations without
* changing unrelated callers.
*/
export interface INodeObsApi extends IAutoConfigNativeApi {
[key: string]: any;
}

export const enum VCamOutputType {
Invalid,
SceneOutput,
Expand All @@ -1942,4 +2151,4 @@ else if (fs.existsSync(path.resolve(__dirname, `obs64.exe`).replace('app.asar',
else {
obs.IPC.setServerPath(path.resolve(__dirname, `obs32.exe`).replace('app.asar', 'app.asar.unpacked'), path.resolve(__dirname).replace('app.asar', 'app.asar.unpacked'));
}
export const NodeObs = obs;
export const NodeObs: INodeObsApi = obs;
Loading
Loading