Skip to content

Commit

Permalink
feat: refactor OBS integration
Browse files Browse the repository at this point in the history
  • Loading branch information
mint-dewit committed Dec 22, 2023
1 parent 5dd45c1 commit 9e23da8
Show file tree
Hide file tree
Showing 12 changed files with 928 additions and 694 deletions.
37 changes: 23 additions & 14 deletions packages/timeline-state-resolver-types/src/generated/obs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface MappingObsStreaming {
mappingType: MappingObsType.Streaming
}

export interface MappingObsSceneItemRender {
export interface MappingObsSceneItem {
/**
* Name of the scene item to be modified
*/
Expand All @@ -36,33 +36,42 @@ export interface MappingObsSceneItemRender {
* Scene item source name
*/
source: string
mappingType: MappingObsType.SceneItemRender
mappingType: MappingObsType.SceneItem
}

export interface MappingObsMute {
export interface MappingObsInputAudio {
/**
* Source name
* Input name
*/
source: string
mappingType: MappingObsType.Mute
input: string
mappingType: MappingObsType.InputAudio
}

export interface MappingObsSourceSettings {
export interface MappingObsInputSettings {
/**
* Source name
* Input name
*/
source: string
mappingType: MappingObsType.SourceSettings
input: string
mappingType: MappingObsType.InputSettings
}

export interface MappingObsInputMedia {
/**
* Input name
*/
input: string
mappingType: MappingObsType.InputMedia
}

export enum MappingObsType {
CurrentScene = 'currentScene',
CurrentTransition = 'currentTransition',
Recording = 'recording',
Streaming = 'streaming',
SceneItemRender = 'sceneItemRender',
Mute = 'mute',
SourceSettings = 'sourceSettings',
SceneItem = 'sceneItem',
InputAudio = 'inputAudio',
InputSettings = 'inputSettings',
InputMedia = 'inputMedia',
}

export type SomeMappingObs = MappingObsCurrentScene | MappingObsCurrentTransition | MappingObsRecording | MappingObsStreaming | MappingObsSceneItemRender | MappingObsMute | MappingObsSourceSettings
export type SomeMappingObs = MappingObsCurrentScene | MappingObsCurrentTransition | MappingObsRecording | MappingObsStreaming | MappingObsSceneItem | MappingObsInputAudio | MappingObsInputSettings | MappingObsInputMedia
85 changes: 61 additions & 24 deletions packages/timeline-state-resolver-types/src/integrations/obs.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,43 @@
import { DeviceType } from '..'

export enum OBSRequest {
SET_CURRENT_SCENE = 'SetCurrentScene',
SET_PREVIEW_SCENE = 'SetPreviewScene',
SET_CURRENT_TRANSITION = 'SetCurrentTransition',
START_RECORDING = 'StartRecording',
STOP_RECORDING = 'StopRecording',
START_STREAMING = 'StartStreaming',
STOP_STREAMING = 'StopStreaming',
SET_SCENE_ITEM_RENDEER = 'SetSceneItemRender',
SET_MUTE = 'SetMute',
SET_SOURCE_SETTINGS = 'SetSourceSettings',
SET_CURRENT_SCENE = 'SetCurrentProgramScene',
SET_PREVIEW_SCENE = 'SetCurrentPreviewScene',
SET_CURRENT_TRANSITION = 'SetCurrentSceneTransition',
START_RECORDING = 'StartRecord',
STOP_RECORDING = 'StopRecord',
START_STREAMING = 'StartStream',
STOP_STREAMING = 'StopStream',
SET_SCENE_ITEM_ENABLED = 'SetSceneItemEnabled',
SET_SCENE_ITEM_TRANSFORM = 'SetSceneItemTransform',
SET_MUTE = 'SetInputMute',
SET_SOURCE_SETTINGS = 'SetInputSettings',
SET_INPUT_VOLUME = 'SetInputVolume',
TRIGGER_MEDIA_INPUT_ACTION = 'TriggerMediaInputAction',
SET_MEDIA_INPUT_CURSOR = 'SetMediaInputCursor',
}

export type TimelineContentOBSAny =
| TimelineContentOBSCurrentScene
| TimelineContentOBSCurrentTransition
| TimelineContentOBSRecording
| TimelineContentOBSStreaming
| TimelineContentOBSSceneItemRender
| TimelineContentOBSMute
| TimelineContentOBSSourceSettings
| TimelineContentOBSSceneItem
| TimelineContentOBSInputAudio
| TimelineContentOBSInputSettings
| TimelineContentOBSInputMedia

export enum TimelineContentTypeOBS {
CURRENT_SCENE = 'CURRENT_SCENE',
CURRENT_TRANSITION = 'CURRENT_TRANSITION',
RECORDING = 'RECORDING',
STREAMING = 'STREAMING',
SCENE_ITEM_RENDER = 'SCENE_ITEM_RENDER',
MUTE = 'MUTE',
SOURCE_SETTINGS = 'SOURCE_SETTINGS',

SCENE_ITEM = 'SCENE_ITEM',

INPUT_AUDIO = 'INPUT_AUDIO',
INPUT_SETTINGS = 'INPUT_SETTINGS',
INPUT_MEDIA = 'INPUT_MEDIA',
}
export interface TimelineContentOBSBase {
deviceType: DeviceType.OBS
Expand Down Expand Up @@ -64,19 +72,22 @@ export interface TimelineContentOBSStreaming extends TimelineContentOBSBase {
on: boolean
}

export interface TimelineContentOBSSceneItemRender extends TimelineContentOBSBase {
export interface TimelineContentOBSSceneItem extends TimelineContentOBSBase {
deviceType: DeviceType.OBS
type: TimelineContentTypeOBS.SCENE_ITEM_RENDER
type: TimelineContentTypeOBS.SCENE_ITEM

/** Should the scene item be enabled */
on: boolean
on?: boolean

/** Should the scene item be enabled */
transform?: OBSSceneItemTransform
}

type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }
type XOR<T, U> = T | U extends Record<string, any> ? (Without<T, U> & U) | (Without<U, T> & T) : T | U

export type TimelineContentOBSSourceSettings = TimelineContentOBSBase & {
type: TimelineContentTypeOBS.SOURCE_SETTINGS
export type TimelineContentOBSInputSettings = TimelineContentOBSBase & {
type: TimelineContentTypeOBS.INPUT_SETTINGS
} & XOR<
{
sourceType: 'ffmpeg_source'
Expand All @@ -94,9 +105,35 @@ export type TimelineContentOBSSourceSettings = TimelineContentOBSBase & {
}
>

export interface TimelineContentOBSMute extends TimelineContentOBSBase {
type: TimelineContentTypeOBS.MUTE
export interface TimelineContentOBSInputAudio extends TimelineContentOBSBase {
type: TimelineContentTypeOBS.INPUT_AUDIO

/** If the audio should be muted (`true`: audio will not be output, `false`: audio will be output) */
mute: boolean
mute?: boolean

volume?: number
}
export interface TimelineContentOBSInputMedia extends TimelineContentOBSBase {
type: TimelineContentTypeOBS.INPUT_MEDIA

seek?: number
state?: 'playing' | 'paused' | 'stopped'
}

export interface OBSSceneItemTransform {
cropBottom?: number
cropLeft?: number
cropRight?: number
cropTop?: number

height?: number
width?: number

positionX?: number
positionY?: number

rotation?: number

scaleX?: number
scaleY?: number
}
2 changes: 1 addition & 1 deletion packages/timeline-state-resolver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
"hpagent": "^1.2.0",
"hyperdeck-connection": "2.0.0-nightly-master-20231205-105655-157a483.0",
"klona": "^2.0.6",
"obs-websocket-js": "^4.0.3",
"obs-websocket-js": "^5.0.3",
"osc": "^2.4.4",
"p-all": "^3.0.0",
"p-queue": "^6.6.2",
Expand Down
14 changes: 3 additions & 11 deletions packages/timeline-state-resolver/src/conductor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
TimelineDatastoreReferencesContent,
DeviceOptionsMultiOSC,
TimelineDatastoreReferences,
DeviceOptionsOBS,
DeviceOptionsOSC,
DeviceOptionsShotoku,
DeviceOptionsHTTPSend,
Expand All @@ -46,7 +47,6 @@ import { PharosDevice, DeviceOptionsPharosInternal } from './integrations/pharos
import { SisyfosMessageDevice, DeviceOptionsSisyfosInternal } from './integrations/sisyfos'
import { SingularLiveDevice, DeviceOptionsSingularLiveInternal } from './integrations/singularLive'
import { VMixDevice, DeviceOptionsVMixInternal } from './integrations/vmix'
import { OBSDevice, DeviceOptionsOBSInternal } from './integrations/obs'
import { VizMSEDevice, DeviceOptionsVizMSEInternal } from './integrations/vizMSE'
import { DeviceOptionsSofieChefInternal, SofieChefDevice } from './integrations/sofieChef'
import { TelemetricsDevice } from './integrations/telemetrics'
Expand Down Expand Up @@ -573,15 +573,6 @@ export class Conductor extends EventEmitter<ConductorEvents> {
getCurrentTime,
threadedClassOptions
)
case DeviceType.OBS:
return DeviceContainer.create<DeviceOptionsOBSInternal, typeof OBSDevice>(
'../../dist/integrations/obs/index.js',
'OBSDevice',
deviceId,
deviceOptions,
getCurrentTime,
threadedClassOptions
)
case DeviceType.TELEMETRICS:
return DeviceContainer.create<DeviceOptionsTelemetrics, typeof TelemetricsDevice>(
'../../dist/integrations/telemetrics/index.js',
Expand Down Expand Up @@ -623,6 +614,7 @@ export class Conductor extends EventEmitter<ConductorEvents> {
case DeviceType.HTTPSEND:
case DeviceType.HTTPWATCHER:
case DeviceType.HYPERDECK:
case DeviceType.OBS:
case DeviceType.OSC:
case DeviceType.SHOTOKU:
case DeviceType.TCPSEND:
Expand Down Expand Up @@ -1538,7 +1530,7 @@ export type DeviceOptionsAnyInternal =
| DeviceOptionsTCPSend
| DeviceOptionsHyperdeck
| DeviceOptionsPharosInternal
| DeviceOptionsOBSInternal
| DeviceOptionsOBS
| DeviceOptionsOSC
| DeviceOptionsMultiOSCInternal
| DeviceOptionsSisyfosInternal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"required": [],
"additionalProperties": false
},
"sceneItemRender": {
"sceneItem": {
"type": "object",
"properties": {
"sceneName": {
Expand All @@ -43,28 +43,40 @@
"required": ["sceneName", "source"],
"additionalProperties": false
},
"mute": {
"inputAudio": {
"type": "object",
"properties": {
"source": {
"input": {
"type": "string",
"ui:title": "Source",
"description": "Source name"
"ui:title": "Input",
"description": "Input name"
}
},
"required": ["source"],
"required": ["input"],
"additionalProperties": false
},
"sourceSettings": {
"inputSettings": {
"type": "object",
"properties": {
"source": {
"input": {
"type": "string",
"ui:title": "Source",
"description": "Source name"
"ui:title": "Input",
"description": "Input name"
}
},
"required": ["input"],
"additionalProperties": false
},
"inputMedia": {
"type": "object",
"properties": {
"input": {
"type": "string",
"ui:title": "Input",
"description": "Input name"
}
},
"required": ["source"],
"required": ["input"],
"additionalProperties": false
}
}
Expand Down
Loading

0 comments on commit 9e23da8

Please sign in to comment.