forked from Sofie-Automation/sofie-core
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathstudio.ts
More file actions
453 lines (412 loc) · 15.1 KB
/
studio.ts
File metadata and controls
453 lines (412 loc) · 15.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
import { PlayoutChangedResults } from '@sofie-automation/shared-lib/dist/peripheralDevice/peripheralDeviceAPI'
import {
AdLibActionId,
BucketAdLibActionId,
BucketAdLibId,
BucketId,
ExpectedPackageId,
PartId,
PartInstanceId,
PieceId,
PieceInstanceId,
RundownBaselineAdLibActionId,
RundownId,
RundownPlaylistId,
SegmentId,
StudioId,
} from '../dataModel/Ids.js'
import { JSONBlob } from '@sofie-automation/shared-lib/dist/lib/JSONBlob'
import { CoreRundownPlaylistSnapshot } from '../snapshots.js'
import { NoteSeverity } from '@sofie-automation/blueprints-integration'
import { ITranslatableMessage } from '../TranslatableMessage.js'
import { QuickLoopMarker } from '../dataModel/RundownPlaylist.js'
/** List of all Jobs performed by the Worker related to a certain Studio */
export enum StudioJobs {
/**
* Debug: Regenerate the timeline for the Studio
*/
UpdateTimeline = 'updateTimeline',
/**
* Regenerate the timeline for the specified Playlist in the Studio
* Has no effect if specified Playlist is not active
*/
UpdateTimelineAfterIngest = 'updateTimelineAfterIngest',
/**
* Play an AdLib piece by its id
*/
AdlibPieceStart = 'adLibPieceStart',
/**
* Play an existing Piece in the Rundown as an AdLib
*/
TakePieceAsAdlibNow = 'takePieceAsAdlibNow',
/**
* Find and play a sticky Piece on a SourceLayer
*/
StartStickyPieceOnSourceLayer = 'startStickyPieceOnSourceLayer',
/**
* Stop any playing Pieces on some SourceLayers
*/
StopPiecesOnSourceLayers = 'stopPiecesOnSourceLayers',
/**
* Activate Hold
*/
ActivateHold = 'activateHold',
/**
* Deactivate Hold
*/
DeactivateHold = 'deactivateHold',
/**
* Prepare the rundown for transmission
* To be triggered well before the broadcast, since it may take time and cause outputs to flicker
*/
PrepareRundownForBroadcast = 'prepareRundownForBroadcast',
/**
* Reset the rundown.
* Optionally activate the rundown at the end.
*/
ResetRundownPlaylist = 'resetRundownPlaylist',
/**
* Only activate the rundown, don't reset anything
*/
ActivateRundownPlaylist = 'activateRundownPlaylist',
/**
* Deactivate the rundown
*/
DeactivateRundownPlaylist = 'deactivateRundownPlaylist',
/**
* Set the nexted Part to a specified id
*/
SetNextPart = 'setNextPart',
/**
* Set the nexted part to first part of the Segment with a specified id
*/
SetNextSegment = 'setNextSegment',
/**
* Set the queued Segment to a specified id
*/
QueueNextSegment = 'queueNextSegment',
/**
* Move which Part is nexted by a Part(horizontal) or Segment (vertical) delta
*/
MoveNextPart = 'moveNextPart',
/**
* Execute an AdLib Action
*/
ExecuteAction = 'executeAction',
/**
* Execute a Bucket AdLib (Action)
*/
ExecuteBucketAdLibOrAction = 'executeBucketAdLibOrAction',
/**
* Take the currently Next:ed Part (start playing it)
*/
TakeNextPart = 'takeNextPart',
/**
* Disable the next Piece which allows being disabled
*/
DisableNextPiece = 'disableNextPiece',
/**
* Debug: Remove a Playlist and all its contents
*/
RemovePlaylist = 'removePlaylist',
/**
* Run the cached data through blueprints in order to re-generate the Rundown
*/
RegeneratePlaylist = 'regeneratePlaylist',
/**
* Called by playout-gateway when playback timings of any Parts or Pieces on the timeline have changed
*/
OnPlayoutPlaybackChanged = 'onPlayoutPlaybackChanged',
/**
* Called from Playout-gateway when the trigger-time of a timeline object has updated
* ( typically when using the "now"-feature )
*/
OnTimelineTriggerTime = 'onTimelineTriggerTime',
/**
* Recalculate T-Timer estimates based on current playlist state
* Called after setNext, takes, and ingest changes to update timing anchor estimates
*/
RecalculateTTimerEstimates = 'recalculateTTimerEstimates',
/**
* Update the timeline with a regenerated Studio Baseline
* Has no effect if a Playlist is active
*/
UpdateStudioBaseline = 'updateStudioBaseline',
/**
* Cleanup any RundownPlaylists that contain no Rundowns
*/
CleanupEmptyPlaylists = 'cleanupEmptyPlaylists',
/**
* Restore the order of rundowns in a playlist, giving control over the ordering back to the NRCS
*/
OrderRestoreToDefault = 'orderRestoreToDefault',
/**
* Move a rundown manually into a specific Playlist (by a user in Sofie)
*/
OrderMoveRundownToPlaylist = 'orderMoveRundownToPlaylist',
/**
* Debug: Regenerate the nexted-partinstance from its part.
*/
DebugRegenerateNextPartInstance = 'debugRegenerateNextPartInstance',
/**
* Debug: Ensure that the infinite pieces on the nexted-part are correct
*/
DebugSyncInfinitesForNextPartInstance = 'debugSyncInfinitesForNextPartInstance',
/**
* Debug: Force the worker to throw an error
*/
DebugCrash = 'debugCrash',
/**
* Generate the Playlist owned portions of a Playlist snapshot
*/
GeneratePlaylistSnapshot = 'generatePlaylistSnapshot',
/**
* Restore the Playlist owned portions of a Playlist snapshot
*/
RestorePlaylistSnapshot = 'restorePlaylistSnapshot',
/**
* Run the Blueprint applyConfig for the studio
*/
BlueprintUpgradeForStudio = 'blueprintUpgradeForStudio',
/**
* Validate the blueprintConfig for the Studio, with the Blueprint validateConfig
*/
BlueprintValidateConfigForStudio = 'blueprintValidateConfigForStudio',
/**
* Run the 'fixUpConfig' method for the Studio blueprint config
*/
BlueprintFixUpConfigForStudio = 'blueprintFixUpConfigForStudio',
/**
* Ignore the 'fixUpConfig' method for the Studio blueprint config
*/
BlueprintIgnoreFixUpConfigForStudio = 'blueprintIgnoreFixUpConfigForStudio',
/**
* Activate AdlibTesting for the Rundown containing the nexted part.
*/
ActivateAdlibTesting = 'activateAdlibTesting',
/**
* Set QuickLoop marker
*/
SetQuickLoopMarker = 'setQuickLoopMarker',
/**
* Clear all QuickLoop markers
*/
ClearQuickLoopMarkers = 'clearQuickLoopMarkers',
/**
* Switch the route of the studio
* for use in ad.lib actions and other triggers
*/
SwitchRouteSet = 'switchRouteSet',
/**
* Cleanup any expected packages playout references that are orphaned
* During playout it is hard to track removal of PieceInstances (particularly when resetting PieceInstances)
*/
CleanupOrphanedExpectedPackageReferences = 'cleanupOrphanedExpectedPackageReferences',
}
export interface RundownPlayoutPropsBase {
playlistId: RundownPlaylistId
}
export type UpdateTimelineAfterIngestProps = RundownPlayoutPropsBase
export interface AdlibPieceStartProps extends RundownPlayoutPropsBase {
partInstanceId: PartInstanceId
adLibPieceId: PieceId | BucketAdLibId
pieceType: 'baseline' | 'normal' | 'bucket'
queue?: boolean
}
export interface TakePieceAsAdlibNowProps extends RundownPlayoutPropsBase {
partInstanceId: PartInstanceId
pieceInstanceIdOrPieceIdToCopy: PieceInstanceId | PieceId
}
export interface StartStickyPieceOnSourceLayerProps extends RundownPlayoutPropsBase {
sourceLayerId: string
}
export interface StopPiecesOnSourceLayersProps extends RundownPlayoutPropsBase {
partInstanceId: PartInstanceId
sourceLayerIds: string[]
}
export interface MoveNextPartProps extends RundownPlayoutPropsBase {
partDelta: number
segmentDelta: number
ignoreQuickLoop?: boolean
}
export type ActivateHoldProps = RundownPlayoutPropsBase
export type DeactivateHoldProps = RundownPlayoutPropsBase
export type PrepareRundownForBroadcastProps = RundownPlayoutPropsBase
export interface ResetRundownPlaylistProps extends RundownPlayoutPropsBase {
/** If set, also activate the RundownPlaylist */
activate?: 'active' | 'rehearsal'
/** If true and `activate` is set, deactivates any other active Playlists and activates this one. */
forceActivate?: boolean
}
export interface ActivateRundownPlaylistProps extends RundownPlayoutPropsBase {
rehearsal: boolean
}
export type DeactivateRundownPlaylistProps = RundownPlayoutPropsBase
export interface SetNextPartProps extends RundownPlayoutPropsBase {
nextPartId: PartId
setManually?: boolean
nextTimeOffset?: number
}
export interface SetNextSegmentProps extends RundownPlayoutPropsBase {
nextSegmentId: SegmentId
}
export interface QueueNextSegmentProps extends RundownPlayoutPropsBase {
queuedSegmentId: SegmentId | null
}
export type QueueNextSegmentResult = { nextPartId: PartId } | { queuedSegmentId: SegmentId | null }
export interface ExecuteActionProps extends RundownPlayoutPropsBase {
actionDocId: AdLibActionId | RundownBaselineAdLibActionId | BucketAdLibActionId
actionId: string
userData: any
triggerMode?: string
actionOptions?: { [key: string]: any }
}
export interface ExecuteBucketAdLibOrActionProps extends RundownPlayoutPropsBase {
bucketId: BucketId
externalId: string
triggerMode?: string
}
export interface ExecuteBucketAdLibOrActionProps extends RundownPlayoutPropsBase {
bucketId: BucketId
externalId: string
triggerMode?: string
}
export interface ExecuteActionResult {
queuedPartInstanceId?: PartInstanceId
taken?: boolean
}
export interface TakeNextPartProps extends RundownPlayoutPropsBase {
fromPartInstanceId: PartInstanceId | null
}
export interface DisableNextPieceProps extends RundownPlayoutPropsBase {
undo: boolean
}
export type RemovePlaylistProps = RundownPlayoutPropsBase
export type RegeneratePlaylistProps = RundownPlayoutPropsBase
export interface OnPlayoutPlaybackChangedProps extends RundownPlayoutPropsBase {
changes: PlayoutChangedResults['changes']
}
export interface OnTimelineTriggerTimeProps {
results: Array<{ id: string; time: number }>
}
export type OrderRestoreToDefaultProps = RundownPlayoutPropsBase
export interface OrderMoveRundownToPlaylistProps {
/** The rundown to be moved */
rundownId: RundownId
/** Which playlist to move into. If null, move into a (new) separate playlist */
intoPlaylistId: RundownPlaylistId | null
/** The new rundowns in the new playlist */
rundownsIdsInPlaylistInOrder: RundownId[]
}
export type DebugRegenerateNextPartInstanceProps = RundownPlayoutPropsBase
export type DebugSyncInfinitesForNextPartInstanceProps = RundownPlayoutPropsBase
export interface GeneratePlaylistSnapshotProps extends RundownPlayoutPropsBase {
// Include all Instances, or just recent ones
full: boolean
// Include the Timeline
withTimeline: boolean
}
export interface GeneratePlaylistSnapshotResult {
/**
* Stringified JSON of the snapshot
* Note: it is kept as a string to avoid needing to parse the very large blob unnecesarily
*/
snapshotJson: JSONBlob<CoreRundownPlaylistSnapshot>
}
export interface RestorePlaylistSnapshotProps {
/**
* Stringified JSON of the snapshot
* Note: it is kept as a string to avoid needing to parse the very large blob unnecesarily
*/
snapshotJson: JSONBlob<CoreRundownPlaylistSnapshot>
}
export interface RestorePlaylistSnapshotResult {
playlistId: RundownPlaylistId
remappedIds: {
rundownId: [RundownId, RundownId][]
segmentId: [SegmentId, SegmentId][]
partId: [PartId, PartId][]
partInstanceId: [PartInstanceId, PartInstanceId][]
expectedPackageId: [ExpectedPackageId, ExpectedPackageId][]
}
}
export interface BlueprintValidateConfigForStudioResult {
messages: Array<{
level: NoteSeverity
message: ITranslatableMessage
}>
}
export interface BlueprintFixUpConfigForStudioResult {
messages: Array<{
path: string
message: ITranslatableMessage
}>
}
export interface ActivateAdlibTestingProps extends RundownPlayoutPropsBase {
rundownId: RundownId
}
export interface SetQuickLoopMarkerProps extends RundownPlayoutPropsBase {
type: 'start' | 'end'
marker: QuickLoopMarker | null
}
export type ClearQuickLoopMarkersProps = RundownPlayoutPropsBase
export interface SwitchRouteSetProps {
routeSetId: string
state: boolean | 'toggle'
}
export interface CleanupOrphanedExpectedPackageReferencesProps {
playlistId: RundownPlaylistId
rundownId: RundownId
}
/**
* Set of valid functions, of form:
* `id: (data) => return`
*/
export type StudioJobFunc = {
[StudioJobs.UpdateTimeline]: () => void
[StudioJobs.UpdateTimelineAfterIngest]: (data: UpdateTimelineAfterIngestProps) => void
[StudioJobs.AdlibPieceStart]: (data: AdlibPieceStartProps) => void
[StudioJobs.TakePieceAsAdlibNow]: (data: TakePieceAsAdlibNowProps) => void
[StudioJobs.StartStickyPieceOnSourceLayer]: (data: StartStickyPieceOnSourceLayerProps) => void
[StudioJobs.StopPiecesOnSourceLayers]: (data: StopPiecesOnSourceLayersProps) => void
[StudioJobs.MoveNextPart]: (data: MoveNextPartProps) => PartId | null
[StudioJobs.ActivateHold]: (data: ActivateHoldProps) => void
[StudioJobs.DeactivateHold]: (data: DeactivateHoldProps) => void
[StudioJobs.PrepareRundownForBroadcast]: (data: PrepareRundownForBroadcastProps) => void
[StudioJobs.ResetRundownPlaylist]: (data: ResetRundownPlaylistProps) => void
[StudioJobs.ActivateRundownPlaylist]: (data: ActivateRundownPlaylistProps) => void
[StudioJobs.DeactivateRundownPlaylist]: (data: DeactivateRundownPlaylistProps) => void
[StudioJobs.SetNextPart]: (data: SetNextPartProps) => void
[StudioJobs.SetNextSegment]: (data: SetNextSegmentProps) => PartId
[StudioJobs.QueueNextSegment]: (data: QueueNextSegmentProps) => QueueNextSegmentResult
[StudioJobs.ExecuteAction]: (data: ExecuteActionProps) => ExecuteActionResult
[StudioJobs.ExecuteBucketAdLibOrAction]: (data: ExecuteBucketAdLibOrActionProps) => ExecuteActionResult
[StudioJobs.TakeNextPart]: (data: TakeNextPartProps) => void
[StudioJobs.DisableNextPiece]: (data: DisableNextPieceProps) => void
[StudioJobs.RemovePlaylist]: (data: RemovePlaylistProps) => void
[StudioJobs.RegeneratePlaylist]: (data: RegeneratePlaylistProps) => void
[StudioJobs.OnPlayoutPlaybackChanged]: (data: OnPlayoutPlaybackChangedProps) => void
[StudioJobs.OnTimelineTriggerTime]: (data: OnTimelineTriggerTimeProps) => void
[StudioJobs.RecalculateTTimerEstimates]: () => void
[StudioJobs.UpdateStudioBaseline]: () => string | false
[StudioJobs.CleanupEmptyPlaylists]: () => void
[StudioJobs.OrderRestoreToDefault]: (data: OrderRestoreToDefaultProps) => void
[StudioJobs.OrderMoveRundownToPlaylist]: (data: OrderMoveRundownToPlaylistProps) => void
[StudioJobs.DebugRegenerateNextPartInstance]: (data: DebugRegenerateNextPartInstanceProps) => void
[StudioJobs.DebugSyncInfinitesForNextPartInstance]: (data: DebugSyncInfinitesForNextPartInstanceProps) => void
[StudioJobs.GeneratePlaylistSnapshot]: (data: GeneratePlaylistSnapshotProps) => GeneratePlaylistSnapshotResult
[StudioJobs.RestorePlaylistSnapshot]: (data: RestorePlaylistSnapshotProps) => RestorePlaylistSnapshotResult
[StudioJobs.DebugCrash]: (data: DebugRegenerateNextPartInstanceProps) => void
[StudioJobs.BlueprintUpgradeForStudio]: () => void
[StudioJobs.BlueprintValidateConfigForStudio]: () => BlueprintValidateConfigForStudioResult
[StudioJobs.BlueprintFixUpConfigForStudio]: () => BlueprintFixUpConfigForStudioResult
[StudioJobs.BlueprintIgnoreFixUpConfigForStudio]: () => void
[StudioJobs.ActivateAdlibTesting]: (data: ActivateAdlibTestingProps) => void
[StudioJobs.SetQuickLoopMarker]: (data: SetQuickLoopMarkerProps) => void
[StudioJobs.ClearQuickLoopMarkers]: (data: ClearQuickLoopMarkersProps) => void
[StudioJobs.SwitchRouteSet]: (data: SwitchRouteSetProps) => void
[StudioJobs.CleanupOrphanedExpectedPackageReferences]: (data: CleanupOrphanedExpectedPackageReferencesProps) => void
}
export function getStudioQueueName(id: StudioId): string {
return `studio:${id}`
}