Skip to content

Commit

Permalink
fix(job-worker/playout): Hold mode doesn't work at all
Browse files Browse the repository at this point in the history
  • Loading branch information
jstarpl committed Dec 13, 2024
1 parent d2a3cdf commit a7d6999
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 47 deletions.
5 changes: 5 additions & 0 deletions packages/job-worker/src/playout/model/PlayoutModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,11 @@ export interface PlayoutModel extends PlayoutModelReadonly, StudioPlayoutModelBa
*/
cycleSelectedPartInstances(): void

/**
* Reset the hold state to a base state
*/
resetHoldState(): void

/**
* Set the RundownPlaylist as deactivated
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,15 +420,13 @@ export class PlayoutModelImpl extends PlayoutModelReadonlyImpl implements Playou
this.playlistImpl.nextPartInfo = null
this.playlistImpl.lastTakeTime = getCurrentTime()

if (!this.playlistImpl.holdState || this.playlistImpl.holdState === RundownHoldState.COMPLETE) {
this.playlistImpl.holdState = RundownHoldState.NONE
} else {
this.playlistImpl.holdState = this.playlistImpl.holdState + 1
}

this.#playlistHasChanged = true
}

resetHoldState(): void {
this.setHoldState(RundownHoldState.NONE)
}

deactivatePlaylist(): void {
delete this.playlistImpl.activationId

Expand Down
84 changes: 43 additions & 41 deletions packages/job-worker/src/playout/take.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,20 +178,23 @@ export async function performTakeToNextedPart(
}
}

// If hold is COMPLETE, clear the hold state by this take
if (playoutModel.playlist.holdState === RundownHoldState.COMPLETE) {
playoutModel.setHoldState(RundownHoldState.NONE)

// If hold is active, then this take is to clear it
// If hold is ACTIVE, then this take is to complete it
} else if (playoutModel.playlist.holdState === RundownHoldState.ACTIVE) {
await completeHold(context, playoutModel, await pShowStyle, currentPartInstance)

await updateTimeline(context, playoutModel)

if (span) span.end()

return
}

const takePartInstance = nextPartInstance
if (!takePartInstance) throw new Error('takePart not found!')
if (!takePartInstance) throw new Error('takePartInstance not found!')
const takeRundown = playoutModel.getRundown(takePartInstance.partInstance.rundownId)
if (!takeRundown)
throw new Error(`takeRundown: takeRundown not found! ("${takePartInstance.partInstance.rundownId}")`)
Expand Down Expand Up @@ -263,12 +266,10 @@ export async function performTakeToNextedPart(
// Once everything is synced, we can choose the next part
await setNextPart(context, playoutModel, nextPart, false)

// Setup the parts for the HOLD we are starting
if (
playoutModel.playlist.previousPartInfo &&
(playoutModel.playlist.holdState as RundownHoldState) === RundownHoldState.ACTIVE
) {
startHold(context, currentPartInstance, nextPartInstance)
// If the Hold is PENDING, make it active
if (playoutModel.playlist.holdState === RundownHoldState.PENDING) {
// Setup the parts for the HOLD we are starting
activateHold(context, playoutModel, currentPartInstance, takePartInstance)
}
await afterTake(context, playoutModel, takePartInstance)

Expand Down Expand Up @@ -535,35 +536,39 @@ export async function afterTake(
/**
* A Hold starts by extending the "extendOnHold"-able pieces in the previous Part.
*/
function startHold(
function activateHold(
context: JobContext,
playoutModel: PlayoutModel,
holdFromPartInstance: PlayoutPartInstanceModel | null,
holdToPartInstance: PlayoutPartInstanceModel | undefined
) {
if (!holdFromPartInstance) throw new Error('previousPart not found!')
if (!holdToPartInstance) throw new Error('currentPart not found!')
const span = context.startSpan('startHold')
const span = context.startSpan('activateHold')

playoutModel.setHoldState(RundownHoldState.ACTIVE)

// Make a copy of any item which is flagged as an 'infinite' extension
const pieceInstancesToCopy = holdFromPartInstance.pieceInstances.filter((p) => !!p.pieceInstance.piece.extendOnHold)
pieceInstancesToCopy.forEach((instance) => {
if (!instance.pieceInstance.infinite) {
// mark current one as infinite
instance.prepareForHold()

// This gets deleted once the nextpart is activated, so it doesnt linger for long
const extendedPieceInstance = holdToPartInstance.insertHoldPieceInstance(instance)

const content = clone(instance.pieceInstance.piece.content) as VTContent | undefined
if (content?.fileName && content.sourceDuration && instance.pieceInstance.plannedStartedPlayback) {
content.seek = Math.min(
content.sourceDuration,
getCurrentTime() - instance.pieceInstance.plannedStartedPlayback
)
}
extendedPieceInstance.updatePieceProps({ content })
for (const instance of pieceInstancesToCopy) {
// skip any infinites
if (instance.pieceInstance.infinite) continue

instance.prepareForHold()

// This gets deleted once the nextpart is activated, so it doesnt linger for long
const extendedPieceInstance = holdToPartInstance.insertHoldPieceInstance(instance)

const content = clone(instance.pieceInstance.piece.content) as VTContent | undefined
if (content?.fileName && content.sourceDuration && instance.pieceInstance.plannedStartedPlayback) {
content.seek = Math.min(
content.sourceDuration,
getCurrentTime() - instance.pieceInstance.plannedStartedPlayback
)
}
})
extendedPieceInstance.updatePieceProps({ content })
}

if (span) span.end()
}

Expand All @@ -575,19 +580,16 @@ async function completeHold(
): Promise<void> {
playoutModel.setHoldState(RundownHoldState.COMPLETE)

if (playoutModel.playlist.currentPartInfo) {
if (!currentPartInstance) throw new Error('currentPart not found!')
if (!playoutModel.playlist.currentPartInfo) return
if (!currentPartInstance) throw new Error('currentPart not found!')

// Clear the current extension line
innerStopPieces(
context,
playoutModel,
showStyleCompound.sourceLayers,
currentPartInstance,
(p) => !!p.infinite?.fromHold,
undefined
)
}

await updateTimeline(context, playoutModel)
// Clear the current extension line
innerStopPieces(
context,
playoutModel,
showStyleCompound.sourceLayers,
currentPartInstance,
(p) => !!p.infinite?.fromHold,
undefined
)
}
1 change: 1 addition & 0 deletions packages/job-worker/src/playout/timings/partPlayback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export async function onPartPlaybackStarted(
// this is the next part, clearly an autoNext has taken place

playoutModel.cycleSelectedPartInstances()
playoutModel.resetHoldState()

reportPartInstanceHasStarted(context, playoutModel, playingPartInstance, data.startedPlayback)

Expand Down

0 comments on commit a7d6999

Please sign in to comment.