Skip to content

Commit 8c78ed2

Browse files
committed
Merge branch 'release51' into release52
2 parents ecc1768 + d908ac6 commit 8c78ed2

File tree

16 files changed

+144
-39
lines changed

16 files changed

+144
-39
lines changed

packages/blueprints-integration/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## [1.51.1](https://github.com/nrkno/sofie-core/compare/v1.51.1-2...v1.51.1) (2024-11-13)
7+
8+
**Note:** Version bump only for package @sofie-automation/blueprints-integration
9+
10+
11+
12+
13+
614
## [1.51.1-2](https://github.com/nrkno/sofie-core/compare/v1.51.1-1...v1.51.1-2) (2024-10-24)
715

816
**Note:** Version bump only for package @sofie-automation/blueprints-integration

packages/corelib/src/playout/playlist.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ export function compareMarkerPositions(a: MarkerPosition, b: MarkerPosition): nu
109109

110110
export function sortRundownsWithinPlaylist(
111111
sortedPossibleIds: ReadonlyDeep<RundownId[]>,
112-
unsortedRundowns: DBRundown[]
113-
): DBRundown[] {
112+
unsortedRundowns: ReadonlyDeep<DBRundown[]>
113+
): ReadonlyDeep<DBRundown[]> {
114114
return unsortedRundowns.slice().sort((a, b) => {
115115
const indexA = sortedPossibleIds.indexOf(a._id)
116116
const indexB = sortedPossibleIds.indexOf(b._id)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export interface PlayoutModelPreInit {
5959
*/
6060
readonly playlist: ReadonlyDeep<DBRundownPlaylist>
6161
/**
62-
* The unwrapped Rundowns in this RundownPlaylist
62+
* The unwrapped Rundowns in this RundownPlaylist, sorted in order specified by RundownPlaylist
6363
*/
6464
readonly rundowns: ReadonlyDeep<DBRundown[]>
6565

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export async function createPlayoutModelFromIngestModel(
8989

9090
const [{ partInstances, groupedPieceInstances }, rundownsWithContent, timeline] = await Promise.all([
9191
loadPartInstances(context, loadedPlaylist, rundownIds),
92-
loadRundowns(context, ingestModel, rundowns),
92+
loadRundowns(context, ingestModel, sortRundownsWithinPlaylist(playlist.rundownIdsInOrder, rundowns)),
9393
loadTimeline(context),
9494
])
9595

packages/job-worker/src/playout/model/implementation/__tests__/LoadPlayoutModel.spec.ts

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ import { MockJobContext, setupDefaultJobEnvironment } from '../../../../__mocks_
77
import { ProcessedShowStyleCompound } from '../../../../jobs'
88
import { ReadonlyDeep } from 'type-fest'
99
import { protectString } from '@sofie-automation/corelib/dist/protectedString'
10-
import { loadPlayoutModelPreInit } from '../LoadPlayoutModel'
10+
import { createPlayoutModelFromIngestModel, loadPlayoutModelPreInit } from '../LoadPlayoutModel'
1111
import { runWithPlaylistLock } from '../../../../playout/lock'
12+
import { loadIngestModelFromRundown } from '../../../../ingest/model/implementation/LoadIngestModel'
13+
import { runWithRundownLock } from '../../../../ingest/lock'
14+
import { IngestModelReadonly } from '../../../../ingest/model/IngestModel'
1215

1316
describe('LoadPlayoutModel', () => {
1417
let context: MockJobContext
@@ -94,4 +97,63 @@ describe('LoadPlayoutModel', () => {
9497
})
9598
})
9699
})
100+
101+
describe('createPlayoutModelFromIngestModel', () => {
102+
afterEach(async () =>
103+
Promise.all([
104+
context.mockCollections.RundownBaselineAdLibPieces.remove({}),
105+
context.mockCollections.RundownBaselineAdLibActions.remove({}),
106+
context.mockCollections.RundownBaselineObjects.remove({}),
107+
context.mockCollections.AdLibActions.remove({}),
108+
context.mockCollections.AdLibPieces.remove({}),
109+
context.mockCollections.Pieces.remove({}),
110+
context.mockCollections.Parts.remove({}),
111+
context.mockCollections.Segments.remove({}),
112+
context.mockCollections.Rundowns.remove({}),
113+
context.mockCollections.RundownPlaylists.remove({}),
114+
])
115+
)
116+
117+
test('Rundowns are in order specified in RundownPlaylist', async () => {
118+
// Set up a playlist:
119+
const { rundownId: rundownId00, playlistId: playlistId0 } = await setupDefaultRundownPlaylist(
120+
context,
121+
showStyleCompound,
122+
protectString('rundown00')
123+
)
124+
const rundownId01 = protectString('rundown01')
125+
await setupDefaultRundown(context, showStyleCompound, playlistId0, rundownId01)
126+
const rundownId02 = protectString('rundown02')
127+
await setupDefaultRundown(context, showStyleCompound, playlistId0, rundownId02)
128+
129+
const rundownIdsInOrder = [rundownId01, rundownId02, rundownId00]
130+
131+
await context.mockCollections.RundownPlaylists.update(playlistId0, {
132+
rundownIdsInOrder,
133+
})
134+
135+
const playlist0 = await context.mockCollections.RundownPlaylists.findOne(playlistId0)
136+
expect(playlist0).toBeTruthy()
137+
138+
if (!playlist0) throw new Error(`Playlist "${playlistId0}" not found!`)
139+
140+
let ingestModel: IngestModelReadonly | undefined
141+
142+
await runWithRundownLock(context, rundownId01, async (rundown, lock) => {
143+
if (!rundown) throw new Error(`Rundown "${rundownId01}" not found!`)
144+
145+
ingestModel = await loadIngestModelFromRundown(context, lock, rundown)
146+
})
147+
148+
await runWithPlaylistLock(context, playlistId0, async (lock) => {
149+
if (!ingestModel) throw new Error('Ingest model could not be created!')
150+
151+
const rundowns = await context.mockCollections.Rundowns.findFetch({})
152+
153+
const model = await createPlayoutModelFromIngestModel(context, lock, playlist0, rundowns, ingestModel)
154+
155+
expect(model.rundowns.map((r) => r.rundown._id)).toMatchObject([rundownId01, rundownId02, rundownId00])
156+
})
157+
})
158+
})
97159
})

packages/job-worker/src/playout/resolvedPieces.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ export function getResolvedPiecesForPartInstancesOnTimeline(
4646
if (!partInstancesInfo.current) return []
4747

4848
const currentPartStarted = partInstancesInfo.current.partStarted ?? now
49+
4950
const nextPartStarted =
5051
partInstancesInfo.current.partInstance.part.autoNext &&
52+
partInstancesInfo.current.partInstance.part.expectedDuration !== 0 &&
5153
partInstancesInfo.current.partInstance.part.expectedDuration !== undefined
5254
? currentPartStarted + partInstancesInfo.current.partInstance.part.expectedDuration
5355
: null

packages/job-worker/src/playout/timeline/generate.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BlueprintId } from '@sofie-automation/corelib/dist/dataModel/Ids'
1+
import { BlueprintId, TimelineHash } from '@sofie-automation/corelib/dist/dataModel/Ids'
22
import { JobContext } from '../../jobs'
33
import { ReadonlyDeep } from 'type-fest'
44
import {
@@ -127,13 +127,13 @@ export async function updateStudioTimeline(
127127
logAnyRemainingNowTimes(context, baselineObjects)
128128
}
129129

130-
saveTimeline(context, playoutModel, baselineObjects, versions)
130+
const timelineHash = saveTimeline(context, playoutModel, baselineObjects, versions)
131131

132132
if (studioBaseline) {
133133
updateBaselineExpectedPackagesOnStudio(context, playoutModel, studioBaseline)
134134
}
135135

136-
logger.debug('updateStudioTimeline done!')
136+
logger.verbose(`updateStudioTimeline done, hash: "${timelineHash}"`)
137137
if (span) span.end()
138138
}
139139

@@ -157,9 +157,8 @@ export async function updateTimeline(context: JobContext, playoutModel: PlayoutM
157157
logAnyRemainingNowTimes(context, timelineObjs)
158158
}
159159

160-
saveTimeline(context, playoutModel, timelineObjs, versions)
161-
162-
logger.debug('updateTimeline done!')
160+
const timelineHash = saveTimeline(context, playoutModel, timelineObjs, versions)
161+
logger.verbose(`updateTimeline done, hash: "${timelineHash}"`)
163162

164163
if (span) span.end()
165164
}
@@ -231,11 +230,13 @@ export function saveTimeline(
231230
studioPlayoutModel: StudioPlayoutModelBase,
232231
timelineObjs: TimelineObjGeneric[],
233232
generationVersions: TimelineCompleteGenerationVersions
234-
): void {
233+
): TimelineHash {
235234
const newTimeline = studioPlayoutModel.setTimeline(timelineObjs, generationVersions)
236235

237236
// Also do a fast-track for the timeline to be published faster:
238237
context.hackPublishTimelineToFastTrack(newTimeline)
238+
239+
return newTimeline.timelineHash
239240
}
240241

241242
export interface SelectedPartInstancesTimelineInfo {

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

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export async function onPartPlaybackStarted(
2929
const playingPartInstance = playoutModel.getPartInstance(data.partInstanceId)
3030
if (!playingPartInstance)
3131
throw new Error(
32-
`PartInstance "${data.partInstanceId}" in RundownPlayst "${playoutModel.playlistId}" not found!`
32+
`PartInstance "${data.partInstanceId}" in RundownPlaylist "${playoutModel.playlistId}" not found!`
3333
)
3434

3535
// make sure we don't run multiple times, even if TSR calls us multiple times
@@ -178,33 +178,32 @@ export function reportPartInstanceHasStarted(
178178
partInstance: PlayoutPartInstanceModel,
179179
timestamp: Time
180180
): void {
181-
if (partInstance) {
182-
const timestampUpdated = partInstance.setReportedStartedPlayback(timestamp)
183-
if (timestamp && !playoutModel.isMultiGatewayMode) {
181+
const timestampUpdated = partInstance.setReportedStartedPlayback(timestamp)
182+
183+
if (!playoutModel.isMultiGatewayMode) {
184+
if (timestamp) {
184185
partInstance.setPlannedStartedPlayback(timestamp)
185186
}
186-
187187
const previousPartInstance = playoutModel.previousPartInstance
188-
if (timestampUpdated && !playoutModel.isMultiGatewayMode && previousPartInstance) {
188+
if (timestampUpdated && previousPartInstance) {
189189
// Ensure the plannedStoppedPlayback is set for the previous partinstance too
190190
previousPartInstance.setPlannedStoppedPlayback(timestamp)
191191
}
192+
}
192193

193-
// Update the playlist:
194-
if (!partInstance.partInstance.part.untimed) {
195-
playoutModel.setRundownStartedPlayback(partInstance.partInstance.rundownId, timestamp)
196-
}
194+
// Update the playlist:
195+
if (!partInstance.partInstance.part.untimed) {
196+
playoutModel.setRundownStartedPlayback(partInstance.partInstance.rundownId, timestamp)
197+
}
197198

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

205-
if (timestampUpdated) {
206-
playoutModel.queuePartInstanceTimingEvent(partInstance.partInstance._id)
207-
}
205+
if (timestampUpdated) {
206+
playoutModel.queuePartInstanceTimingEvent(partInstance.partInstance._id)
208207
}
209208
}
210209

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,9 @@ function timelineTriggerTimeInner(
181181
}
182182
}
183183
if (tlChanged) {
184-
saveTimeline(context, studioPlayoutModel, timelineObjs, timeline.generationVersions)
184+
const timelineHash = saveTimeline(context, studioPlayoutModel, timelineObjs, timeline.generationVersions)
185+
186+
logger.verbose(`timelineTriggerTime: Updated Timeline, hash: "${timelineHash}"`)
185187
}
186188
}
187189

packages/mos-gateway/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## [1.51.1](https://github.com/nrkno/sofie-core/compare/v1.51.1-2...v1.51.1) (2024-11-13)
7+
8+
**Note:** Version bump only for package mos-gateway
9+
10+
11+
12+
13+
614
## [1.51.1-2](https://github.com/nrkno/sofie-core/compare/v1.51.1-1...v1.51.1-2) (2024-10-24)
715

816
**Note:** Version bump only for package mos-gateway

0 commit comments

Comments
 (0)