Skip to main content

Creating a Global AdLib Action

In this example we are creating a Global AdLib Action that can be executed any-time in the show.

This example builds on the stepped graphics piece we created here

As a result of these steps we will have a Global AdLib Action that when executed checks if the current part has any stepped graphics pieces and steps them until the last step.

Step 1: Add a new ActionId​

The first step is to come up with an identifier for your action. We just simply add it to the following enum:

export enum ActionId {
LastRemote = 'lastRemote',
LastDVE = 'lastDVE',
// added new id:
GFXStep = 'GFXStep',
}

packages\blueprints\src\base\showstyle\executeActions\actionDefinitions.ts

Step 2: Create a global action to step through the graphic​

We now need to define the action in our blueprint, this happens in getGlobalActions(). This function returns all global actions for the rundown.

An example of a simple Global AdLib Action

{
actionId: ActionId.GFXStep,
userData: {},
userDataManifest: {},
display: {
label: t('Control Graphic Step'),
sourceLayerId: SourceLayer.GFX,
outputLayerId: getOutputLayerForSourceLayer(SourceLayer.GFX),
},
triggerModes: [],
externalId: ingestRundown.externalId,
}

packages\blueprints\src\base\showstyle\rundown\globalActions.ts

Step 3: Execution logic​

Now we need to define what our action does, when we trigger it.

In executeAction() we can forward our action to our execution logic:

if (actionId === ActionId.LastRemote) {
await executeLastOnSourceLayer(context, SourceLayer.Remote)
} else if (actionId === ActionId.LastDVE) {
await executeLastOnSourceLayer(context, SourceLayer.DVE)
}
// Our new action is executed here:
else if (actionId === ActionId.GFXStep) {
await executeGraphicNextStep(context)
}

packages/blueprints/src/base/showstyle/executeActions/index.ts

And then we can have the actual logic in a separate function:

For our example we could choose from these approaches:​

  1. context.updatePieceInstance()
    • update the current piece and timeline object (we used this in the example)
    • add new timeline objects for each step execution, these are still part of the same piece
    • add keyframes to the already existing timeline object
  2. context.insertPiece() to add a new piece with the new step when advancing the graphic

Optionally a DataStoreAction can be used to fast-track the next slide instead of waiting for the database to update.

Relevant reading on Part and Piece actions: https://github.com/Sofie-Automation/sofie-core/blob/release53/packages/blueprints-integration/src/context/partsAndPieceActionContext.ts

export async function executeGraphicNextStep(context: IActionExecutionContext): Promise<void> {
const increment = 1

// we filter for any stepped graphic piece
const pieceInstances = await context.getPieceInstances('current')
const steppedPieceInstances = pieceInstances.filter(
(piece) => (piece.piece.content as unknown as WithTimeline<NoraContent>).step
)

// we execute the action for each of them
for (const piece of steppedPieceInstances) {
const content = piece.piece.content as unknown as WithTimeline<NoraContent>
if (content.step) {
const { count, current } = content.step

newStep = Math.min(newStep, count)

await context.updatePieceInstance(piece._id, {
...piece.piece,
content: {
...content,

// update step data
step: { ...content.step, current: newStep },

/* If needed modify the timelineObjects too.

timelineObjects: content.timelineObjects.map((tlObj) => ({
...tlObj,
content: {
...tlObj.content,
data: (tlObj.content as any).data
? { ...(tlObj.content as any).data, currentStep: content.step ? newStep : undefined }
: undefined,
},
})), */
},
})
}
}
}

packages/blueprints/src/base/showstyle/executeActions/steppedGraphicExample.ts

Result​