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
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
Loading