Skip to content

Commit 549f544

Browse files
authored
Merge pull request Sofie-Automation#1277 from bbc/upstream/segment-timing
2 parents 3818de8 + 817f9a0 commit 549f544

File tree

36 files changed

+373
-241
lines changed

36 files changed

+373
-241
lines changed

packages/blueprints-integration/src/documents/part.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ export interface IBlueprintMutatablePart<TPrivateData = unknown, TPublicData = u
5454
/** Expected duration of the line, in milliseconds */
5555
expectedDuration?: number
5656

57-
/** Budget duration of this part, in milliseconds */
58-
budgetDuration?: number
59-
6057
/** Whether this segment line supports being used in HOLD */
6158
holdMode?: PartHoldMode
6259

packages/blueprints-integration/src/documents/segment.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,25 @@ export enum SegmentDisplayMode {
44
List = 'list',
55
}
66

7+
export enum CountdownType {
8+
/** Should count down till the end of the current part */
9+
PART_EXPECTED_DURATION = 'part_expected_duration',
10+
/** Should count down till the end of the segment's budget */
11+
SEGMENT_BUDGET_DURATION = 'segment_budget_duration',
12+
}
13+
714
export interface SegmentTimingInfo {
815
/** A unix timestamp of when the segment is expected to begin. Affects rundown timing. */
916
expectedStart?: number
1017

1118
/** A unix timestamp of when the segment is expected to end. Affects rundown timing. */
1219
expectedEnd?: number
20+
21+
/** Budget duration of this segment, in milliseconds */
22+
budgetDuration?: number
23+
24+
/** Defines the behavior of countdowns during this segment. Default: `CountdownType.PART_EXPECTED_DURATION` */
25+
countdownType?: CountdownType
1326
}
1427

1528
/** The Segment generated from Blueprint */

packages/corelib/src/dataModel/RundownPlaylist.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,10 @@ export interface DBRundownPlaylist {
160160
lastIncorrectPartPlaybackReported?: Time
161161
/** Actual time of each rundown starting playback */
162162
rundownsStartedPlayback?: Record<string, Time>
163-
/** Actual time of SOME segments starting playback - usually just the previous and current one */
163+
/**
164+
* Actual time of SOME segments starting playback - usually just the previous and current one
165+
* This is not using SegmentId, but SegmentPlayoutId
166+
*/
164167
segmentsStartedPlayback?: Record<string, Time>
165168
/** Time of the last take */
166169
lastTakeTime?: Time

packages/job-worker/src/blueprints/context/lib.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ export const IBlueprintMutatablePartSampleKeys = allKeysOfObject<IBlueprintMutat
9494
disableNextInTransition: true,
9595
outTransition: true,
9696
expectedDuration: true,
97-
budgetDuration: true,
9897
holdMode: true,
9998
shouldNotifyCurrentPlayingPart: true,
10099
classes: true,
@@ -251,7 +250,6 @@ export function convertPartToBlueprints(part: ReadonlyDeep<DBPart>): IBlueprintP
251250
disableNextInTransition: part.disableNextInTransition,
252251
outTransition: clone(part.outTransition),
253252
expectedDuration: part.expectedDuration,
254-
budgetDuration: part.budgetDuration,
255253
holdMode: part.holdMode,
256254
shouldNotifyCurrentPlayingPart: part.shouldNotifyCurrentPlayingPart,
257255
classes: clone<string[] | undefined>(part.classes),

packages/job-worker/src/playout/model/PlayoutModel.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
RundownPlaylistActivationId,
88
RundownPlaylistId,
99
SegmentId,
10+
SegmentPlayoutId,
1011
} from '@sofie-automation/corelib/dist/dataModel/Ids'
1112
import { BaseModel } from '../../modelBase'
1213
import {
@@ -331,10 +332,10 @@ export interface PlayoutModel extends PlayoutModelReadonly, StudioPlayoutModelBa
331332

332333
/**
333334
* Track a Segment as having started playback
334-
* @param segmentId Id of the Segment
335+
* @param segmentPlayoutId Playout id of the Segment
335336
* @param timestamp Timestamp playback started
336337
*/
337-
setSegmentStartedPlayback(segmentId: SegmentId, timestamp: number): void
338+
setSegmentStartedPlayback(segmentPlayoutId: SegmentPlayoutId, timestamp: number): void
338339

339340
/**
340341
* Set or clear a QuickLoop Marker

packages/job-worker/src/playout/model/implementation/PlayoutModelImpl.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@ export class PlayoutModelImpl extends PlayoutModelReadonlyImpl implements Playou
587587
delete this.playlistImpl.lastTakeTime
588588
delete this.playlistImpl.startedPlayback
589589
delete this.playlistImpl.rundownsStartedPlayback
590+
delete this.playlistImpl.segmentsStartedPlayback
590591
delete this.playlistImpl.previousPersistentState
591592
delete this.playlistImpl.trackedAbSessions
592593
delete this.playlistImpl.queuedSegmentId
@@ -744,21 +745,21 @@ export class PlayoutModelImpl extends PlayoutModelReadonlyImpl implements Playou
744745
this.#playlistHasChanged = true
745746
}
746747

747-
setSegmentStartedPlayback(segmentId: SegmentId, timestamp: number): void {
748-
const segmentIdsToKeep: string[] = []
748+
setSegmentStartedPlayback(segmentPlayoutId: SegmentPlayoutId, timestamp: number): void {
749+
const segmentPlayoutIdsToKeep: string[] = []
749750
if (this.previousPartInstance) {
750-
segmentIdsToKeep.push(unprotectString(this.previousPartInstance.partInstance.segmentId))
751+
segmentPlayoutIdsToKeep.push(unprotectString(this.previousPartInstance.partInstance.segmentPlayoutId))
751752
}
752753
if (this.currentPartInstance) {
753-
segmentIdsToKeep.push(unprotectString(this.currentPartInstance.partInstance.segmentId))
754+
segmentPlayoutIdsToKeep.push(unprotectString(this.currentPartInstance.partInstance.segmentPlayoutId))
754755
}
755756

756757
this.playlistImpl.segmentsStartedPlayback = this.playlistImpl.segmentsStartedPlayback
757-
? _.pick(this.playlistImpl.segmentsStartedPlayback, segmentIdsToKeep)
758+
? _.pick(this.playlistImpl.segmentsStartedPlayback, segmentPlayoutIdsToKeep)
758759
: {}
759760

760-
const segmentIdStr = unprotectString(segmentId)
761-
this.playlistImpl.segmentsStartedPlayback[segmentIdStr] = timestamp
761+
const segmentPlayoutIdStr = unprotectString(segmentPlayoutId)
762+
this.playlistImpl.segmentsStartedPlayback[segmentPlayoutIdStr] = timestamp
762763
this.#playlistHasChanged = true
763764
}
764765

packages/job-worker/src/playout/timings/partPlayback.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,11 @@ export function reportPartInstanceHasStarted(
195195
playoutModel.setRundownStartedPlayback(partInstance.partInstance.rundownId, timestamp)
196196
}
197197

198-
if (partInstance.partInstance.segmentId !== playoutModel.previousPartInstance?.partInstance.segmentId) {
199-
playoutModel.setSegmentStartedPlayback(partInstance.partInstance.segmentId, timestamp)
198+
if (
199+
partInstance.partInstance.segmentPlayoutId !==
200+
playoutModel.previousPartInstance?.partInstance.segmentPlayoutId
201+
) {
202+
playoutModel.setSegmentStartedPlayback(partInstance.partInstance.segmentPlayoutId, timestamp)
200203
}
201204

202205
if (timestampUpdated) {

packages/live-status-gateway/api/schemas/activePlaylist.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,12 @@ $defs:
172172
projectedEndTime:
173173
description: Unix timestamp of when the segment is projected to end (milliseconds). The time this segment started, offset by its budget duration, if the segment has a defined budget duration. Otherwise, the time the current part started, offset by the difference between expected durations of all parts in this segment and the as-played durations of the parts that already stopped.
174174
type: number
175+
countdownType:
176+
description: 'Countdown type within the segment. Default: `part_expected_duration`'
177+
type: string
178+
enum:
179+
- part_expected_duration
180+
- segment_budget_duration
175181
required: [expectedDurationMs, projectedEndTime]
176182
required: [id, timing]
177183
additionalProperties: false
@@ -181,6 +187,7 @@ $defs:
181187
expectedDurationMs: 15000
182188
budgetDurationMs: 20000
183189
projectedEndTime: 1600000075000
190+
countdownType: segment_budget_duration
184191
piece:
185192
type: object
186193
properties:

packages/live-status-gateway/api/schemas/segments.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ $defs:
4848
budgetDurationMs:
4949
description: Budget duration of the segment (milliseconds)
5050
type: number
51+
countdownType:
52+
description: 'Countdown type within the segment. Default: `part_expected_duration`'
53+
type: string
54+
enum:
55+
- part_expected_duration
56+
- segment_budget_duration
5157
required: [expectedDurationMs]
5258
publicData:
5359
description: Optional arbitrary data
@@ -60,5 +66,6 @@ $defs:
6066
timing:
6167
expectedDurationMs: 15000
6268
budgetDurationMs: 20000
69+
countdownType: segment_budget_duration
6370
publicData:
6471
containsLiveSource: true

packages/live-status-gateway/src/collections/segmentHandler.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,19 @@ export class SegmentHandler
3131
if (!collection) throw new Error(`collection '${this._collectionName}' not found!`)
3232
const allSegments = collection.find(undefined)
3333
await this._segmentsHandler.setSegments(allSegments)
34-
if (this._currentSegmentId) {
35-
this._collectionData = collection.findOne(this._currentSegmentId)
34+
await this.updateAndNotify()
35+
}
36+
37+
private async updateAndNotify() {
38+
const collection = this._core.getCollection(this._collectionName)
39+
const newData = this._currentSegmentId ? collection.findOne(this._currentSegmentId) : undefined
40+
if (this._collectionData !== newData) {
41+
this._collectionData = newData
3642
await this.notify(this._collectionData)
3743
}
3844
}
3945

4046
async update(source: string, data: SelectedPartInstances | DBRundownPlaylist | undefined): Promise<void> {
41-
const previousSegmentId = this._currentSegmentId
4247
const previousRundownIds = this._rundownIds
4348

4449
switch (source) {
@@ -91,11 +96,6 @@ export class SegmentHandler
9196
const allSegments = collection.find(undefined)
9297
await this._segmentsHandler.setSegments(allSegments)
9398
}
94-
if (previousSegmentId !== this._currentSegmentId) {
95-
if (this._currentSegmentId) {
96-
this._collectionData = collection.findOne(this._currentSegmentId)
97-
await this.notify(this._collectionData)
98-
}
99-
}
99+
await this.updateAndNotify()
100100
}
101101
}

0 commit comments

Comments
 (0)