Skip to content

Commit 84b7bda

Browse files
committed
feat: basic kairos device
1 parent 7a6c538 commit 84b7bda

File tree

37 files changed

+1583
-33
lines changed

37 files changed

+1583
-33
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"ts-jest": "^29.2.4",
5252
"ts-node": "^8.10.2",
5353
"typedoc": "^0.23.28",
54-
"typescript": "~4.9.5"
54+
"typescript": "~5.1"
5555
},
5656
"prettier": "@sofie-automation/code-standard-preset/.prettierrc.json",
5757
"packageManager": "yarn@3.5.0"

packages/timeline-state-resolver-api/tsconfig.build.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
"*": ["./node_modules/*"],
1010
"{{PACKAGE-NAME}}": ["./src/index.ts"]
1111
},
12-
"types": ["node"]
12+
"types": ["node"],
13+
14+
"moduleResolution": "node16",
15+
"esModuleInterop": true
1316
}
1417
}

packages/timeline-state-resolver-types/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
"production"
8484
],
8585
"dependencies": {
86+
"kairos-connection": "0.0.2-nightly-main-20250909-152736-9c6b607.0",
8687
"tslib": "^2.6.3"
8788
},
8889
"publishConfig": {

packages/timeline-state-resolver-types/src/__tests__/__snapshots__/index.spec.ts.snap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@ exports[`index imports 1`] = `
2222
"HttpMethod",
2323
"HttpSendActions",
2424
"HyperdeckActions",
25+
"KairosActions",
26+
"KairosMacroActiveState",
2527
"LawoDeviceMode",
2628
"MappingAtemType",
2729
"MappingCasparCGType",
2830
"MappingHyperdeckType",
31+
"MappingKairosType",
2932
"MappingLawoType",
3033
"MappingMultiOscType",
3134
"MappingObsType",
@@ -57,6 +60,7 @@ exports[`index imports 1`] = `
5760
"TimelineContentTypeHTTP",
5861
"TimelineContentTypeHTTPParamType",
5962
"TimelineContentTypeHyperdeck",
63+
"TimelineContentTypeKairos",
6064
"TimelineContentTypeLawo",
6165
"TimelineContentTypeMultiOSC",
6266
"TimelineContentTypeOBS",

packages/timeline-state-resolver-types/src/generated/device-options.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ export interface DeviceOptionsHyperdeck extends DeviceOptionsBase<HyperdeckOptio
3636
type: DeviceType.HYPERDECK
3737
}
3838

39+
import type { KairosOptions } from './kairos'
40+
export interface DeviceOptionsKairos extends DeviceOptionsBase<KairosOptions> {
41+
type: DeviceType.KAIROS
42+
}
43+
3944
import type { LawoOptions } from './lawo'
4045
export interface DeviceOptionsLawo extends DeviceOptionsBase<LawoOptions> {
4146
type: DeviceType.LAWO
@@ -133,6 +138,7 @@ export type DeviceOptionsAny =
133138
| DeviceOptionsHttpSend
134139
| DeviceOptionsHttpWatcher
135140
| DeviceOptionsHyperdeck
141+
| DeviceOptionsKairos
136142
| DeviceOptionsLawo
137143
| DeviceOptionsMultiOsc
138144
| DeviceOptionsObs
@@ -165,6 +171,7 @@ export enum DeviceType {
165171
HTTPSEND = 'HTTPSEND',
166172
HTTPWATCHER = 'HTTPWATCHER',
167173
HYPERDECK = 'HYPERDECK',
174+
KAIROS = 'KAIROS',
168175
LAWO = 'LAWO',
169176
MULTI_OSC = 'MULTI_OSC',
170177
OBS = 'OBS',

packages/timeline-state-resolver-types/src/generated/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ import type { SomeMappingHttpWatcher } from './httpWatcher'
2727
export * from './hyperdeck'
2828
import type { SomeMappingHyperdeck } from './hyperdeck'
2929

30+
export * from './kairos'
31+
import type { SomeMappingKairos } from './kairos'
32+
3033
export * from './lawo'
3134
import type { SomeMappingLawo } from './lawo'
3235

@@ -88,6 +91,7 @@ export type TSRMappingOptions =
8891
| SomeMappingHttpSend
8992
| SomeMappingHttpWatcher
9093
| SomeMappingHyperdeck
94+
| SomeMappingKairos
9195
| SomeMappingLawo
9296
| SomeMappingMultiOsc
9397
| SomeMappingObs
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/* eslint-disable */
2+
/**
3+
* This file was automatically generated by json-schema-to-typescript.
4+
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5+
* and re-run the "tsr-schema-types" tool to regenerate this file.
6+
*/
7+
import type { ActionExecutionResult } from "../actions"
8+
9+
export interface KairosOptions {
10+
/**
11+
* Host of KAIROS server
12+
*/
13+
host: string
14+
/**
15+
* Port of KAIROS server
16+
*/
17+
port?: number
18+
}
19+
20+
export interface MappingKairosScene {
21+
sceneName: string[]
22+
mappingType: MappingKairosType.Scene
23+
}
24+
25+
export interface MappingKairosSceneLayer {
26+
sceneName: string[]
27+
layerName: string[]
28+
mappingType: MappingKairosType.SceneLayer
29+
}
30+
31+
export interface MappingKairosAux {
32+
auxName: string
33+
mappingType: MappingKairosType.Aux
34+
}
35+
36+
export interface MappingKairosMacro {
37+
mappingType: MappingKairosType.Macro
38+
}
39+
40+
export interface MappingKairosClipPlayer {
41+
playerId: number
42+
mappingType: MappingKairosType.ClipPlayer
43+
}
44+
45+
export interface MappingKairosRamRecPlayer {
46+
playerId: number
47+
mappingType: MappingKairosType.RamRecPlayer
48+
}
49+
50+
export interface MappingKairosStillPlayer {
51+
playerId: number
52+
mappingType: MappingKairosType.StillPlayer
53+
}
54+
55+
export interface MappingKairosSoundPlayer {
56+
playerId: number
57+
mappingType: MappingKairosType.SoundPlayer
58+
}
59+
60+
export enum MappingKairosType {
61+
Scene = 'scene',
62+
SceneLayer = 'scene-layer',
63+
Aux = 'aux',
64+
Macro = 'macro',
65+
ClipPlayer = 'clip-player',
66+
RamRecPlayer = 'ram-rec-player',
67+
StillPlayer = 'still-player',
68+
SoundPlayer = 'sound-player',
69+
}
70+
71+
export type SomeMappingKairos = MappingKairosScene | MappingKairosSceneLayer | MappingKairosAux | MappingKairosMacro | MappingKairosClipPlayer | MappingKairosRamRecPlayer | MappingKairosStillPlayer | MappingKairosSoundPlayer
72+
73+
export interface ListClipsPayload {
74+
subDirectory?: string[]
75+
}
76+
77+
export type ListClipsResult = {
78+
name: string[]
79+
size: number
80+
datetime?: number
81+
frames: number
82+
framerate: number
83+
}[]
84+
85+
export interface ListStillsPayload {
86+
subDirectory?: string[]
87+
}
88+
89+
export type ListStillsResult = {
90+
name: string[]
91+
size: number
92+
datetime?: number
93+
}[]
94+
95+
export interface PlayMacroPayload {
96+
ref?: string[]
97+
}
98+
99+
export enum KairosActions {
100+
ListClips = 'listClips',
101+
ListStills = 'listStills',
102+
PlayMacro = 'playMacro'
103+
}
104+
export interface KairosActionMethods {
105+
[KairosActions.ListClips]: (payload: ListClipsPayload) => Promise<ActionExecutionResult<ListClipsResult>>,
106+
[KairosActions.ListStills]: (payload: ListStillsPayload) => Promise<ActionExecutionResult<ListStillsResult>>,
107+
[KairosActions.PlayMacro]: (payload: PlayMacroPayload) => Promise<ActionExecutionResult<void>>
108+
}
109+
110+
export interface KairosDeviceTypes {
111+
Options: KairosOptions
112+
Mappings: SomeMappingKairos
113+
Actions: KairosActionMethods
114+
}

packages/timeline-state-resolver-types/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ import { TimelineContentVMixAny } from './integrations/vmix'
2323
import { TimelineContentOBSAny } from './integrations/obs'
2424
import { TimelineContentTriCasterAny } from './integrations/tricaster'
2525
import { TimelineContentWebSocketClientAny } from './integrations/websocketClient'
26+
import { TimelineContentKairosAny } from './integrations/kairos'
2627
import { DeviceType } from './generated'
2728

2829
export * from './integrations/abstract'
2930
export * from './integrations/atem'
3031
export * from './integrations/casparcg'
3132
export * from './integrations/httpSend'
3233
export * from './integrations/hyperdeck'
34+
export * from './integrations/kairos'
3335
export * from './integrations/lawo'
3436
export * from './integrations/osc'
3537
export * from './integrations/pharos'
@@ -121,6 +123,7 @@ export type TSRTimelineContent =
121123
| TimelineContentTelemetricsAny
122124
| TimelineContentTriCasterAny
123125
| TimelineContentWebSocketClientAny
126+
| TimelineContentKairosAny
124127

125128
/**
126129
* A simple key value store that can be referred to from the timeline objects
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import type { DeviceType } from '..'
2+
import type {
3+
RefPath,
4+
MediaClipRef,
5+
UpdateSceneObject,
6+
UpdateSceneLayerObject,
7+
UpdateClipPlayerObject,
8+
MediaRamRecRef,
9+
MediaSoundRef,
10+
UpdateSceneSnapshotObject,
11+
UpdateAuxObject,
12+
// eslint-disable-next-line node/no-missing-import
13+
} from 'kairos-connection' // TODO - this needs to be a types/lib package, not the connection package
14+
15+
export enum TimelineContentTypeKairos {
16+
SCENE = 'scene',
17+
SCENE_LAYER = 'scene-layer',
18+
19+
// MVs? - no
20+
// gfx / painter - yes, to be implemented
21+
22+
CLIP_PLAYER = 'clip-player',
23+
RAMREC_PLAYER = 'ramrec-player',
24+
STILL_PLAYER = 'still-player',
25+
SOUND_PLAYER = 'sound-player',
26+
27+
AUX = 'aux',
28+
MACROS = 'macros',
29+
}
30+
31+
/*
32+
const DELETE_IT = 'delete-it-plz-actually-not-plz-just-do-it' as const
33+
type PartialOrNull<T> = {
34+
[P in keyof T]?: T[P] | typeof DELETE_IT;
35+
};
36+
*/
37+
38+
export type TimelineContentKairosAny =
39+
| TimelineContentKairosScene
40+
| TimelineContentKairosSceneLayer
41+
| TimelineContentKairosAux
42+
| TimelineContentKairosMacros
43+
| TimelineContentKairosClipPlayer
44+
| TimelineContentKairosRamRecPlayer
45+
| TimelineContentKairosStillPlayer
46+
| TimelineContentKairosSoundPlayer
47+
48+
export interface TimelineContentKairosScene {
49+
deviceType: DeviceType.KAIROS
50+
type: TimelineContentTypeKairos.SCENE
51+
52+
scene: Partial<UpdateSceneObject>
53+
54+
recallSnapshots: {
55+
// The snapshotName MUST be based on the ref (it's not really used in TSR, but should be unique)
56+
[snapshotName: string]: TimelineContentKairosSceneSnapshotInfo
57+
}
58+
}
59+
60+
export interface TimelineContentKairosSceneSnapshotInfo {
61+
/** Reference to the Snapshot */
62+
ref: RefPath
63+
/** When this is true, the Snapshot will be recalled */
64+
active: boolean
65+
66+
properties: Partial<UpdateSceneSnapshotObject>
67+
}
68+
69+
export interface TimelineContentKairosSceneLayer {
70+
deviceType: DeviceType.KAIROS
71+
type: TimelineContentTypeKairos.SCENE_LAYER
72+
73+
sceneLayer: Partial<UpdateSceneLayerObject>
74+
}
75+
76+
export interface TimelineContentKairosAux {
77+
deviceType: DeviceType.KAIROS
78+
type: TimelineContentTypeKairos.AUX
79+
80+
aux: Partial<UpdateAuxObject>
81+
}
82+
83+
export interface TimelineContentKairosMacros {
84+
deviceType: DeviceType.KAIROS
85+
type: TimelineContentTypeKairos.MACROS
86+
87+
macros: {
88+
// The macroName MUST be based on the ref (it's not really used in TSR, but should be unique)
89+
[macroName: string]: TimelineContentKairosMacroInfo
90+
}
91+
}
92+
export interface TimelineContentKairosMacroInfo {
93+
ref: RefPath
94+
active: KairosMacroActiveState
95+
}
96+
export enum KairosMacroActiveState {
97+
/** The Macro will be played */
98+
PLAYING = 'playing',
99+
/** The Macro will be stopped */
100+
STOPPED = 'stopped',
101+
/** No command will be sent */
102+
UNCHANGED = 'unchanged',
103+
}
104+
105+
export interface TimelineContentKairosClipPlayer {
106+
deviceType: DeviceType.KAIROS
107+
type: TimelineContentTypeKairos.CLIP_PLAYER
108+
109+
clipPlayer: TimelineContentKairosPlayerState<MediaClipRef>
110+
}
111+
export interface TimelineContentKairosRamRecPlayer {
112+
deviceType: DeviceType.KAIROS
113+
type: TimelineContentTypeKairos.RAMREC_PLAYER
114+
115+
ramRecPlayer: TimelineContentKairosPlayerState<MediaRamRecRef>
116+
}
117+
export interface TimelineContentKairosStillPlayer {
118+
deviceType: DeviceType.KAIROS
119+
type: TimelineContentTypeKairos.STILL_PLAYER
120+
121+
// stillPlayer: TimelineContentKairosPlayerState<MediaStillRef>
122+
}
123+
export interface TimelineContentKairosSoundPlayer {
124+
deviceType: DeviceType.KAIROS
125+
type: TimelineContentTypeKairos.SOUND_PLAYER
126+
127+
soundPlayer: TimelineContentKairosPlayerState<MediaSoundRef>
128+
}
129+
130+
// Note: This is quite inspired from the CasparCG Media type:
131+
export interface TimelineContentKairosPlayerState<TClip>
132+
extends Partial<Pick<UpdateClipPlayerObject, 'colorOverwrite' | 'color'>> {
133+
// clip player / ramrec player
134+
135+
/** Reference to the file to be played */
136+
clip?: TClip
137+
138+
/**
139+
* Whether the media file should be looping or not.
140+
* If this is true, the actual frame position is not guaranteed (ie seek is ignored).
141+
*/
142+
repeat?: boolean
143+
144+
/** The point where the file starts playing [milliseconds from start of file] */
145+
seek?: number
146+
147+
/** When pausing, the unix-time the playout was paused. */
148+
// pauseTime?: number
149+
150+
/** If the video is playing or is paused (defaults to true) */
151+
playing?: boolean
152+
153+
// reverse?: boolean
154+
155+
/** If true, the startTime won't be used to SEEK to the correct place in the media */
156+
// noStarttime?: boolean
157+
}

0 commit comments

Comments
 (0)