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
34 changes: 33 additions & 1 deletion packages/live-status-gateway/api/schemas/activePlaylist.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,32 @@ $defs:
- $ref: '#/$defs/piece/examples/0'
publicData:
partType: 'intro'
currentSegmentPart:
type: object
properties:
id:
description: Unique id of the part
type: string
name:
description: User-presentable name of the part
type: string
autoNext:
description: If this part will progress to the next automatically
type: boolean
default: false
timing:
type: object
properties:
expectedDurationMs:
description: Expected duration of the part
type: number
required: [id, name, timing]
additionalProperties: false
examples:
- id: 'H5CBGYjThrMSmaYvRaa5FVKJIzk_'
name: 'Intro'
timing:
expectedDurationMs: 15000
part:
oneOf:
- $ref: '#/$defs/partBase'
Expand Down Expand Up @@ -196,7 +222,11 @@ $defs:
- part_expected_duration
- segment_budget_duration
required: [expectedDurationMs, projectedEndTime]
required: [id, timing]
parts:
type: array
items:
$ref: '#/$defs/currentSegmentPart'
required: [id, timing, parts]
additionalProperties: false
examples:
- id: 'H5CBGYjThrMSmaYvRaa5FVKJIzk_'
Expand All @@ -205,6 +235,8 @@ $defs:
budgetDurationMs: 20000
projectedEndTime: 1600000075000
countdownType: segment_budget_duration
parts:
- $ref: '#/$defs/currentSegmentPart/examples/0'
piece:
type: object
properties:
Expand Down
18 changes: 18 additions & 0 deletions packages/live-status-gateway/src/liveStatusServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,24 @@ export interface CollectionHandlers {
bucketAdLibActionsHandler: BucketAdLibActionsHandler
}

export interface CollectionHandlers {
studioHandler: StudioHandler
showStyleBaseHandler: ShowStyleBaseHandler
playlistHandler: PlaylistHandler
playlistsHandler: PlaylistsHandler
rundownHandler: RundownHandler
segmentsHandler: SegmentsHandler
segmentHandler: SegmentHandler
partsHandler: PartsHandler
partHandler: PartHandler
partInstancesHandler: PartInstancesHandler
pieceInstancesHandler: PieceInstancesHandler
adLibActionsHandler: AdLibActionsHandler
adLibsHandler: AdLibsHandler
globalAdLibActionsHandler: GlobalAdLibActionsHandler
globalAdLibsHandler: GlobalAdLibsHandler
}

export class LiveStatusServer {
_logger: Logger
_coreHandler: CoreHandler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,16 @@ describe('ActivePlaylistTopic', () => {
expectedDurationMs: 10000,
projectedEndTime: 1600000070000,
},
parts: [
{
id: 'PART_1',
name: 'Test Part',
timing: {
expectedDurationMs: 10000,
},
autoNext: undefined,
},
],
},
rundownIds: unprotectStringArray(playlist.rundownIdsInOrder),
publicData: { a: 'b' },
Expand Down Expand Up @@ -230,6 +240,16 @@ describe('ActivePlaylistTopic', () => {
projectedEndTime: 1600000072300,
countdownType: 'segment_budget_duration',
},
parts: [
{
id: 'PART_1',
name: 'Test Part',
timing: {
expectedDurationMs: 10000,
},
autoNext: undefined,
},
],
},
rundownIds: unprotectStringArray(playlist.rundownIdsInOrder),
publicData: { a: 'b' },
Expand Down
10 changes: 9 additions & 1 deletion packages/live-status-gateway/src/topics/activePlaylistTopic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { CurrentSegmentTiming, calculateCurrentSegmentTiming } from './helpers/s
import { DBPart } from '@sofie-automation/corelib/dist/dataModel/Part'
import _ = require('underscore')
import { PartTiming, calculateCurrentPartTiming } from './helpers/partTiming'
import { CurrentSegmentPart, getCurrentSegmentParts } from './helpers/segmentParts'
import { SelectedPieceInstances, PieceInstanceMin } from '../collections/pieceInstancesHandler'
import { PieceStatus, toPieceStatus } from './helpers/pieceStatus'
import { DBSegment } from '@sofie-automation/corelib/dist/dataModel/Segment'
Expand Down Expand Up @@ -42,6 +43,7 @@ interface CurrentPartStatus extends PartStatus {
interface CurrentSegmentStatus {
id: string
timing: CurrentSegmentTiming
parts: CurrentSegmentPart[]
}

interface ActivePlaylistQuickLoopMarker {
Expand Down Expand Up @@ -135,6 +137,8 @@ export class ActivePlaylistTopic extends WebSocketTopicBase implements WebSocket

const currentPart = this._currentPartInstance ? this._currentPartInstance.part : null
const nextPart = this._nextPartInstance ? this._nextPartInstance.part : null
const currentSegmentParts =
(currentPart && this._partsBySegmentId[unprotectString(currentPart.segmentId)]) ?? []

const message = this._activePlaylist
? literal<ActivePlaylistStatus>({
Expand Down Expand Up @@ -169,7 +173,11 @@ export class ActivePlaylistTopic extends WebSocketTopicBase implements WebSocket
this._currentPartInstance,
this._firstInstanceInSegmentPlayout,
this._partInstancesInCurrentSegment,
this._partsBySegmentId[unprotectString(currentPart.segmentId)] ?? []
currentSegmentParts
),
parts: getCurrentSegmentParts(
this._partInstancesInCurrentSegment,
currentSegmentParts
),
})
: null,
Expand Down
45 changes: 45 additions & 0 deletions packages/live-status-gateway/src/topics/helpers/segmentParts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { PartInstanceId } from '@sofie-automation/corelib/dist/dataModel/Ids'
import { DBPart } from '@sofie-automation/corelib/dist/dataModel/Part'
import { DBPartInstance } from '@sofie-automation/corelib/dist/dataModel/PartInstance'
import { unprotectString } from '@sofie-automation/server-core-integration'
import _ = require('underscore')

export interface CurrentSegmentPart {
id: string
name: string
autoNext: boolean | undefined
timing: {
expectedDurationMs?: number
}
}

export function getCurrentSegmentParts(
segmentPartInstances: DBPartInstance[],
segmentParts: DBPart[]
): CurrentSegmentPart[] {
const partInstancesByPartId: Record<string, { _id: string | PartInstanceId; part: DBPart }> = _.indexBy(
segmentPartInstances,
(partInstance) => unprotectString(partInstance.part._id)
)
segmentParts.forEach((part) => {
const partId = unprotectString(part._id)
if (partInstancesByPartId[partId]) return
const partInstance = {
_id: partId,
part,
}
partInstancesByPartId[partId] = partInstance
})
return Object.values<{ _id: string | PartInstanceId; part: DBPart }>(partInstancesByPartId)
.sort((a, b) => a.part._rank - b.part._rank)
.map(
(partInstance): CurrentSegmentPart => ({
id: unprotectString(partInstance.part._id),
name: partInstance.part.title,
autoNext: partInstance.part.autoNext,
timing: {
expectedDurationMs: partInstance.part.expectedDuration,
},
})
)
}