From f2ba44b61755e3e1f5f7d09c94f69457fff10415 Mon Sep 17 00:00:00 2001 From: ianshade Date: Fri, 18 Nov 2022 13:52:16 +0100 Subject: [PATCH 01/86] feat: SOF-1065 use showName(s) instead of showId(s) --- src/tv2-common/actions/executeAction.ts | 2 +- src/tv2-common/evaluateCues.ts | 4 ++-- .../helpers/graphics/design/index.ts | 2 +- src/tv2-common/helpers/graphics/viz/index.ts | 2 +- src/tv2_afvd_showstyle/getRundown.ts | 2 +- .../pieces/__tests__/grafikViz.spec.ts | 20 +++++++++---------- .../helpers/pieces/__tests__/telefon.spec.ts | 2 +- .../helpers/pieces/clearGrafiks.ts | 2 +- .../helpers/pieces/graphicBackgroundLoop.ts | 2 +- .../helpers/pieces/showLifecycle.ts | 8 ++++---- 10 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 4b91c92c..7372af27 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -2146,7 +2146,7 @@ async function executeActionClearGraphics< deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, channelsToSendCommands: userData.sendCommands ? ['OVL1', 'FULL1', 'WALL1'] : undefined, - showId: config.selectedGraphicsSetup.OvlShowName ?? '' // @todo: improve types at the junction of HTML and Viz + showName: config.selectedGraphicsSetup.OvlShowName ?? '' // @todo: improve types at the junction of HTML and Viz } }) ] diff --git a/src/tv2-common/evaluateCues.ts b/src/tv2-common/evaluateCues.ts index 7d245448..36d7e0b6 100644 --- a/src/tv2-common/evaluateCues.ts +++ b/src/tv2-common/evaluateCues.ts @@ -442,7 +442,7 @@ export async function EvaluateCuesBase( templateName: (obj as TSR.TimelineObjVIZMSEElementInternal).content.templateName, templateData: (obj as TSR.TimelineObjVIZMSEElementInternal).content.templateData, channel: o.content.channelName, - showId: o.content.showId + showName: o.content.showName } }) } @@ -465,7 +465,7 @@ export async function EvaluateCuesBase( templateName: 'altud', channel: 'OVL1', templateData: [], - showId: o.content.showId + showName: o.content.showName } }) } diff --git a/src/tv2-common/helpers/graphics/design/index.ts b/src/tv2-common/helpers/graphics/design/index.ts index dc84f9e8..886417de 100644 --- a/src/tv2-common/helpers/graphics/design/index.ts +++ b/src/tv2-common/helpers/graphics/design/index.ts @@ -100,7 +100,7 @@ function designTimeline(config: TV2BlueprintConfig, parsedCue: CueDefinitionGrap type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: parsedCue.design, templateData: [], - showId: config.selectedGraphicsSetup.OvlShowName ?? '' // @todo: improve types at the junction of HTML and Viz + showName: config.selectedGraphicsSetup.OvlShowName ?? '' // @todo: improve types at the junction of HTML and Viz } }) ] diff --git a/src/tv2-common/helpers/graphics/viz/index.ts b/src/tv2-common/helpers/graphics/viz/index.ts index d01a2702..a8c77bdb 100644 --- a/src/tv2-common/helpers/graphics/viz/index.ts +++ b/src/tv2-common/helpers/graphics/viz/index.ts @@ -109,7 +109,7 @@ export function GetInternalGraphicContentVIZ( templateName: mappedTemplate, templateData: parsedCue.graphic.textFields, channelName: engine === 'WALL' ? 'WALL1' : 'OVL1', // TODO: TranslateEngine - showId: findShowName(config, context, engine) + showName: findShowName(config, context, engine) } }), // Assume DSK is off by default (config table) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 631a873c..122c855e 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -459,7 +459,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'BG_LOADER_SC', templateData: [], - showId: config.selectedGraphicsSetup.OvlShowName + showName: config.selectedGraphicsSetup.OvlShowName } }) ) diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts index 6a117ed3..64220f24 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -165,7 +165,7 @@ describe('grafik piece', () => { templateName: 'bund', templateData: ['Odense', 'Copenhagen'], channelName: 'OVL1', - showId: OVL_SHOW_NAME + showName: OVL_SHOW_NAME } }), dskEnableObj @@ -238,7 +238,7 @@ describe('grafik piece', () => { templateName: 'bund', templateData: ['Odense', 'Copenhagen'], channelName: 'OVL1', - showId: OVL_SHOW_NAME + showName: OVL_SHOW_NAME } }), dskEnableObj @@ -278,7 +278,7 @@ describe('grafik piece', () => { templateName: 'bund', templateData: ['Odense', 'Copenhagen'], channelName: 'OVL1', - showId: OVL_SHOW_NAME + showName: OVL_SHOW_NAME } }), dskEnableObj @@ -353,7 +353,7 @@ describe('grafik piece', () => { templateName: 'bund', templateData: ['Odense', 'Copenhagen'], channelName: 'OVL1', - showId: OVL_SHOW_NAME + showName: OVL_SHOW_NAME } }), dskEnableObj @@ -393,7 +393,7 @@ describe('grafik piece', () => { templateName: 'bund', templateData: ['Odense', 'Copenhagen'], channelName: 'OVL1', - showId: OVL_SHOW_NAME + showName: OVL_SHOW_NAME } }), dskEnableObj @@ -470,7 +470,7 @@ describe('grafik piece', () => { templateName: 'bund', templateData: ['Odense', 'Copenhagen'], channelName: 'OVL1', - showId: OVL_SHOW_NAME + showName: OVL_SHOW_NAME } }), dskEnableObj @@ -649,7 +649,7 @@ describe('grafik piece', () => { templateName: 'direkte', templateData: ['KØBENHAVN'], channelName: 'OVL1', - showId: OVL_SHOW_NAME + showName: OVL_SHOW_NAME } }), dskEnableObj @@ -726,7 +726,7 @@ describe('grafik piece', () => { templateName: 'arkiv', templateData: ['unnamed org'], channelName: 'OVL1', - showId: OVL_SHOW_NAME + showName: OVL_SHOW_NAME } }), dskEnableObj @@ -799,7 +799,7 @@ describe('grafik piece', () => { templateName: 'tlftoptlive', templateData: ['Line 1', 'Line 2'], channelName: 'OVL1', - showId: OVL_SHOW_NAME + showName: OVL_SHOW_NAME } }), dskEnableObj @@ -838,7 +838,7 @@ describe('grafik piece', () => { templateName: 'tlftoptlive', templateData: ['Line 1', 'Line 2'], channelName: 'OVL1', - showId: OVL_SHOW_NAME + showName: OVL_SHOW_NAME } }), dskEnableObj diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts index 61c358f6..78dd050b 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -140,7 +140,7 @@ describe('telefon', () => { templateName: 'bund', templateData: ['Odense', 'Copenhagen'], channelName: 'OVL1', - showId: OVL_SHOW_NAME + showName: OVL_SHOW_NAME } }), literal({ diff --git a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts index 55b7cc95..7a95ff05 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts @@ -69,7 +69,7 @@ export function EvaluateClearGrafiks( content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, - showId: config.selectedGraphicsSetup.OvlShowName + showName: config.selectedGraphicsSetup.OvlShowName } }) ] diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts index f699720a..2ac4c9ec 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts @@ -130,7 +130,7 @@ function fullLoopTimeline(config: TV2BlueprintConfig, parsedCue: CueDefinitionBa type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: parsedCue.backgroundLoop, templateData: [], - showId: config.selectedGraphicsSetup.FullShowName + showName: config.selectedGraphicsSetup.FullShowName } }) ] diff --git a/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts b/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts index e9613f93..a671569d 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts @@ -7,8 +7,8 @@ import { SourceLayer } from '../../layers' export function CreateShowLifecyclePieces( config: TV2BlueprintConfig, part: BlueprintResultPart, - initializeShowIds: string[], - cleanupShowIds: string[] + initializeShowNames: string[], + cleanupShowNames: string[] ) { if (config.studio.GraphicsType === 'VIZ') { part.pieces.push({ @@ -29,7 +29,7 @@ export function CreateShowLifecyclePieces( content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.INITIALIZE_SHOWS, - showIds: initializeShowIds + showNames: initializeShowNames } }), literal({ @@ -41,7 +41,7 @@ export function CreateShowLifecyclePieces( content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CLEANUP_SHOWS, - showIds: cleanupShowIds + showNames: cleanupShowNames } }) ] From dafb6979aba2eb5eb67b26e695814251353ae037 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Thu, 24 Nov 2022 11:59:21 +0100 Subject: [PATCH 02/86] SOF-1242 Create expected jingle media for transtions that have a number for a name --- src/tv2-common/helpers/rundownAdLibActions.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tv2-common/helpers/rundownAdLibActions.ts b/src/tv2-common/helpers/rundownAdLibActions.ts index 090363c1..0558625c 100644 --- a/src/tv2-common/helpers/rundownAdLibActions.ts +++ b/src/tv2-common/helpers/rundownAdLibActions.ts @@ -152,7 +152,6 @@ function makeTransitionAction( currentPieceTags: [tag], nextPieceTags: [tag], content: - isEffekt || /^MIX ?\d+$/i.test(transitionValues.label) || /^CUT$/i.test(transitionValues.label) || /^DIP ?\d+$/i.test(transitionValues.label) From 0583ed576d9b8b11d81f7388d36a19e7f0478401 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 7 Dec 2022 10:53:36 +0100 Subject: [PATCH 03/86] chore: SOF-1065 update blueprints-integration includes TSR types update for human readable show names --- package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index ae6afd90..859f7998 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "webpack-cli": "^3.1.2" }, "dependencies": { - "@sofie-automation/blueprints-integration": "npm:@tv2media/blueprints-integration@46.0.2", + "@sofie-automation/blueprints-integration": "npm:@tv2media/blueprints-integration@46.0.4", "underscore": "^1.12.1" }, "resolutions": { diff --git a/yarn.lock b/yarn.lock index 399954f4..52402d3f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -560,13 +560,13 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@sofie-automation/blueprints-integration@npm:@tv2media/blueprints-integration@46.0.2": - version "46.0.1" - resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-46.0.1.tgz#e344f31e3fcc48d582914ebc33378a626cebd0e6" - integrity sha512-y0ITMUH0JrDligG9X+mWsvVnnGYmZJTrx5iE2XVsHiQ1xQTeBrqDyoxOag2lpbUIF8HI7mXCQkGfk7AYvQLopQ== +"@sofie-automation/blueprints-integration@npm:@tv2media/blueprints-integration@46.0.4": + version "46.0.4" + resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-46.0.4.tgz#70907f5d6be3d6c45eaa2432fffd59103625a2c7" + integrity sha512-BTrnMzV5ijCgdHyZl9XpXadz6GN8ts7AeY202oQGGxS4wntV31vX4u0QG0ooZWGm9K44GpTTO2jnmtFznxnOrA== dependencies: "@sofie-automation/shared-lib" "npm:@tv2media/shared-lib@46.0.0" - timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@2.2.3" + timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@3.0.3" tslib "^2.4.0" type-fest "^2.19.0" @@ -5956,10 +5956,10 @@ through@2, "through@>=2.2.7 <3": resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -"timeline-state-resolver-types@npm:@tv2media/timeline-state-resolver-types@2.2.3": - version "2.2.3" - resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-2.2.3.tgz#4b40293b564d1c774e98dab193e719ba0cf3854c" - integrity sha512-Dj+hXIYrl6OCozBfK5ZkRQkyXPwmZKjRY+wwLw04+sJdnCqTT2W+42ZvH+pVu3MKd/GFGeF9N+7aWa02ITaDRg== +"timeline-state-resolver-types@npm:@tv2media/timeline-state-resolver-types@3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-3.0.3.tgz#cb22a1dee460403c2a306e666003a1d57af7f8d2" + integrity sha512-PqqV2EFCfhQyphngRFh0K7UcO+pptB5e6vk73uT+gz0S+j/aV2uAtOKA3PPeEc7W37ov4KCsP10T4KVTntNkAw== dependencies: tslib "^2.3.1" From f4381265d90548daad2debb5e1273314be88185f Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Tue, 20 Dec 2022 09:15:41 +0100 Subject: [PATCH 04/86] SOF-1277 Rename Graphics to GFX for GraphicsSetup and SelectedGraphicsSetup. Rename Overlay to GFX for OverlayShowMapping --- package.json | 2 +- src/tv2-common/actions/executeAction.ts | 2 +- src/tv2-common/blueprintConfig.ts | 12 +-- src/tv2-common/helpers/config.ts | 20 ++-- .../helpers/graphics/caspar/index.ts | 2 +- .../helpers/graphics/design/index.ts | 2 +- src/tv2-common/helpers/graphics/layers.ts | 8 +- src/tv2-common/helpers/graphics/name.ts | 2 +- src/tv2-common/helpers/graphics/timing.ts | 6 +- src/tv2-common/helpers/graphics/viz/index.ts | 10 +- .../inewsConversion/converters/ParseCue.ts | 4 +- src/tv2-common/showstyle/config-manifests.ts | 16 +-- .../__tests__/config-manifest.spec.ts | 8 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 14 +-- .../__tests__/grafikConfigDefault.ts | 2 +- src/tv2_afvd_showstyle/config-manifests.ts | 34 +++---- src/tv2_afvd_showstyle/getRundown.ts | 4 +- src/tv2_afvd_showstyle/getSegment.ts | 16 +-- src/tv2_afvd_showstyle/helpers/config.ts | 20 ++-- .../helpers/pieces/__tests__/lyd.spec.ts | 10 +- .../helpers/pieces/__tests__/telefon.spec.ts | 4 +- .../helpers/pieces/clearGrafiks.ts | 2 +- .../helpers/pieces/graphicBackgroundLoop.ts | 4 +- src/tv2_afvd_showstyle/migrations/index.ts | 15 ++- src/tv2_afvd_showstyle/migrations/util.ts | 97 +++++++++++++++++++ .../__tests__/config-manifest.spec.ts | 6 +- src/tv2_offtube_showstyle/config-manifests.ts | 18 +--- src/tv2_offtube_showstyle/helpers/config.ts | 10 +- src/tv2_offtube_showstyle/migrations/index.ts | 6 ++ 29 files changed, 224 insertions(+), 132 deletions(-) diff --git a/package.json b/package.json index 4dbdb385..5cbd39d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tv2-sofie-blueprints-inews", - "version": "1.7.8", + "version": "1.7.9", "repository": "https://github.com/olzzon/tv2-sofie-blueprints-inews", "license": "MIT", "private": true, diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 7372af27..1cf4d43d 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -2146,7 +2146,7 @@ async function executeActionClearGraphics< deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, channelsToSendCommands: userData.sendCommands ? ['OVL1', 'FULL1', 'WALL1'] : undefined, - showName: config.selectedGraphicsSetup.OvlShowName ?? '' // @todo: improve types at the junction of HTML and Viz + showName: config.selectedGfxSetup.OvlShowName ?? '' // @todo: improve types at the junction of HTML and Viz } }) ] diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 622e9d57..b988457b 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -33,7 +33,7 @@ export interface TableConfigItemGfxDesignTemplate { VizTemplate: string } -export interface TableConfigItemOverlayShowMapping { +export interface TableConfigItemGfxShowMapping { Design: string GraphicsSetup: string[] Schema: string[] @@ -49,7 +49,7 @@ export interface TableConfigGfxSchema { VizTemplate: string } -export interface TableConfigGraphicsSetup { +export interface TableConfigGfxSetup { Name: string HtmlPackageFolder: string OvlShowName?: string @@ -152,21 +152,21 @@ export interface TV2ShowstyleBlueprintConfigBase { CasparCGLoadingClip: string BreakerConfig: TableConfigItemBreakers[] DVEStyles: DVEConfigInput[] - GFXTemplates: TableConfigItemGfxTemplate[] + GfxTemplates: TableConfigItemGfxTemplate[] GfxDesignTemplates: TableConfigItemGfxDesignTemplate[] Transitions: TableConfigItemAdLibTransitions[] ShowstyleTransition: string MakeAdlibsForFulls: boolean LYDConfig: TableConfigItemValue GfxSchemaTemplates: TableConfigGfxSchema[] - GraphicsSetups: TableConfigGraphicsSetup[] - SelectedGraphicsSetupName: string + GfxSetups: TableConfigGfxSetup[] + SelectedGfxSetupName: string } export interface TV2BlueprintConfigBase extends TV2StudioBlueprintConfigBase { showStyle: TV2ShowstyleBlueprintConfigBase - selectedGraphicsSetup: TableConfigGraphicsSetup + selectedGfxSetup: TableConfigGfxSetup } export type TV2BlueprintConfig = TV2BlueprintConfigBase diff --git a/src/tv2-common/helpers/config.ts b/src/tv2-common/helpers/config.ts index 25af5f81..fd9c2cb6 100644 --- a/src/tv2-common/helpers/config.ts +++ b/src/tv2-common/helpers/config.ts @@ -1,5 +1,5 @@ import { ICommonContext } from 'blueprints-integration' -import { TableConfigGraphicsSetup, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' +import { TableConfigGfxSetup, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' export interface DVEConfigInput { // _id: string @@ -12,17 +12,17 @@ export interface DVEConfigInput { // [key: string]: BasicConfigItemValue } -export function findGraphicsSetup( +export function findGfxSetup( context: ICommonContext, config: ShowStyleConfig, - fallbackGraphicsSetup: ShowStyleConfig['GraphicsSetups'][0] -): ShowStyleConfig['GraphicsSetups'][0] { - const foundTableConfigGraphicsSetup: TableConfigGraphicsSetup | undefined = config.GraphicsSetups.find( - tableConfigGraphicsSetup => tableConfigGraphicsSetup.Name === config.SelectedGraphicsSetupName + fallbackGfxSetup: ShowStyleConfig['GfxSetups'][0] +): ShowStyleConfig['GfxSetups'][0] { + const foundTableConfigGfxSetup: TableConfigGfxSetup | undefined = config.GfxSetups.find( + tableConfigGfxSetup => tableConfigGfxSetup.Name === config.SelectedGfxSetupName ) - if (!foundTableConfigGraphicsSetup) { - context.logWarning(`No graphics setup found for profile: ${config.SelectedGraphicsSetupName}`) - return fallbackGraphicsSetup + if (!foundTableConfigGfxSetup) { + context.logWarning(`No GFX setup found for profile: ${config.SelectedGfxSetupName}`) + return fallbackGfxSetup } - return foundTableConfigGraphicsSetup + return foundTableConfigGfxSetup } diff --git a/src/tv2-common/helpers/graphics/caspar/index.ts b/src/tv2-common/helpers/graphics/caspar/index.ts index 0dd7a125..6c8968cd 100644 --- a/src/tv2-common/helpers/graphics/caspar/index.ts +++ b/src/tv2-common/helpers/graphics/caspar/index.ts @@ -310,5 +310,5 @@ function getFullPilotBaselineTimelineObject(templateName: string): TSR.TimelineO } export function getHtmlTemplateName(config: TV2BlueprintConfig) { - return joinAssetToFolder(config.selectedGraphicsSetup.HtmlPackageFolder, 'index') + return joinAssetToFolder(config.selectedGfxSetup.HtmlPackageFolder, 'index') } diff --git a/src/tv2-common/helpers/graphics/design/index.ts b/src/tv2-common/helpers/graphics/design/index.ts index 886417de..1e07e763 100644 --- a/src/tv2-common/helpers/graphics/design/index.ts +++ b/src/tv2-common/helpers/graphics/design/index.ts @@ -100,7 +100,7 @@ function designTimeline(config: TV2BlueprintConfig, parsedCue: CueDefinitionGrap type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: parsedCue.design, templateData: [], - showName: config.selectedGraphicsSetup.OvlShowName ?? '' // @todo: improve types at the junction of HTML and Viz + showName: config.selectedGfxSetup.OvlShowName ?? '' // @todo: improve types at the junction of HTML and Viz } }) ] diff --git a/src/tv2-common/helpers/graphics/layers.ts b/src/tv2-common/helpers/graphics/layers.ts index 54e914b0..8c1254a8 100644 --- a/src/tv2-common/helpers/graphics/layers.ts +++ b/src/tv2-common/helpers/graphics/layers.ts @@ -2,8 +2,8 @@ import { TV2BlueprintConfig } from 'tv2-common' import { SharedGraphicLLayer, SharedSourceLayers } from 'tv2-constants' export function GetSourceLayerForGraphic(config: TV2BlueprintConfig, name: string) { - const conf = config.showStyle.GFXTemplates - ? config.showStyle.GFXTemplates.find(gfk => gfk.VizTemplate.toString() === name) + const conf = config.showStyle.GfxTemplates + ? config.showStyle.GfxTemplates.find(gfx => gfx.VizTemplate.toString() === name) : undefined if (!conf) { @@ -38,8 +38,8 @@ export function GetSourceLayerForGraphic(config: TV2BlueprintConfig, name: strin } export function GetTimelineLayerForGraphic(config: TV2BlueprintConfig, name: string) { - const conf = config.showStyle.GFXTemplates - ? config.showStyle.GFXTemplates.find(gfk => gfk.VizTemplate.toString() === name) + const conf = config.showStyle.GfxTemplates + ? config.showStyle.GfxTemplates.find(gfx => gfx.VizTemplate.toString() === name) : undefined if (!conf) { diff --git a/src/tv2-common/helpers/graphics/name.ts b/src/tv2-common/helpers/graphics/name.ts index e4a8bed7..e257d867 100644 --- a/src/tv2-common/helpers/graphics/name.ts +++ b/src/tv2-common/helpers/graphics/name.ts @@ -34,7 +34,7 @@ export function GetFullGraphicTemplateNameFromCue( } export function GetFullGrafikTemplateName(config: TV2BlueprintConfig, iNewsTempalateName: string): string { - const template = config.showStyle.GFXTemplates.find(templ => + const template = config.showStyle.GfxTemplates.find(templ => templ.INewsName ? templ.INewsName.toString().toUpperCase() === iNewsTempalateName.toUpperCase() : false ) if (template && template.VizTemplate.toString().length) { diff --git a/src/tv2-common/helpers/graphics/timing.ts b/src/tv2-common/helpers/graphics/timing.ts index 2df2ba6f..465efc8e 100644 --- a/src/tv2-common/helpers/graphics/timing.ts +++ b/src/tv2-common/helpers/graphics/timing.ts @@ -40,7 +40,7 @@ export function FindInfiniteModeFromConfig( ): PieceLifespan { const template = GetFullGraphicTemplateNameFromCue(config, parsedCue) const iNewsName = GraphicIsInternal(parsedCue) ? parsedCue.graphic.template : undefined - const conf = config.showStyle.GFXTemplates.find(cnf => + const conf = config.showStyle.GfxTemplates.find(cnf => cnf.VizTemplate ? cnf.VizTemplate.toString().toUpperCase() === template.toUpperCase() && (iNewsName ? cnf.INewsName.toUpperCase() === iNewsName.toUpperCase() : true) @@ -68,7 +68,7 @@ export function GetGraphicDuration( config: TV2BlueprintConfig, cue: CueDefinitionGraphic ): number | undefined { - if (config.showStyle.GFXTemplates) { + if (config.showStyle.GfxTemplates) { const template = findGfxTemplate(config, cue) if (template && template.OutType && !template.OutType.toString().match(/default/i)) { return undefined @@ -118,7 +118,7 @@ export function findGfxTemplate( if (graphicId === undefined) { return undefined } - return config.showStyle.GFXTemplates.find(templ => + return config.showStyle.GfxTemplates.find(templ => templ.INewsName ? templ.INewsName.toString().toUpperCase() === graphicId?.toUpperCase() : false ) } diff --git a/src/tv2-common/helpers/graphics/viz/index.ts b/src/tv2-common/helpers/graphics/viz/index.ts index a8c77bdb..38a7d8e6 100644 --- a/src/tv2-common/helpers/graphics/viz/index.ts +++ b/src/tv2-common/helpers/graphics/viz/index.ts @@ -119,21 +119,21 @@ export function GetInternalGraphicContentVIZ( } function findShowName(config: TV2BlueprintConfig, context: IShowStyleUserContext, engine: GraphicEngine): string { - const graphicsSetup = config.selectedGraphicsSetup + const gfxSetup = config.selectedGfxSetup switch (engine) { case 'FULL': case 'WALL': - if (graphicsSetup.FullShowName === undefined) { + if (gfxSetup.FullShowName === undefined) { context.logWarning("You're using Viz graphics with an incompatible ShowStyle") return '' } - return graphicsSetup.FullShowName + return gfxSetup.FullShowName case 'TLF': case 'OVL': - if (graphicsSetup.OvlShowName === undefined) { + if (gfxSetup.OvlShowName === undefined) { context.logWarning("You're using Viz graphics with an incompatible ShowStyle") return '' } - return graphicsSetup.OvlShowName + return gfxSetup.OvlShowName } } diff --git a/src/tv2-common/inewsConversion/converters/ParseCue.ts b/src/tv2-common/inewsConversion/converters/ParseCue.ts index b773c4e5..6322d9b9 100644 --- a/src/tv2-common/inewsConversion/converters/ParseCue.ts +++ b/src/tv2-common/inewsConversion/converters/ParseCue.ts @@ -351,7 +351,7 @@ function parsekg( } const graphicConfig = code - ? config.showStyle.GFXTemplates.find( + ? config.showStyle.GfxTemplates.find( template => template.INewsCode.replace(/^KG=?/gi, '#KG').toUpperCase() === code.replace(/^KG=?/gi, '#KG').toUpperCase() && template.INewsName.toUpperCase() === graphic.template.toUpperCase() @@ -734,7 +734,7 @@ function parseTargetEngine( }) } - const graphicConfig = config.showStyle.GFXTemplates.find( + const graphicConfig = config.showStyle.GfxTemplates.find( template => template.INewsCode.toUpperCase() === code?.toUpperCase() && template.INewsName.toUpperCase() === iNewsName.toUpperCase() diff --git a/src/tv2-common/showstyle/config-manifests.ts b/src/tv2-common/showstyle/config-manifests.ts index bdfd4a82..12aab46f 100644 --- a/src/tv2-common/showstyle/config-manifests.ts +++ b/src/tv2-common/showstyle/config-manifests.ts @@ -1,19 +1,19 @@ import { ConfigManifestEntry, ConfigManifestEntryTable, ConfigManifestEntryType } from 'blueprints-integration' -export const GRAPHICS_SETUPS_TABLE_ID = 'GraphicsSetups' +export const GRAPHICS_SETUPS_TABLE_ID = 'GfxSetups' export const GRAPHICS_SETUPS_NAME_COLUMN_ID = 'Name' -export const getGraphicsSetupsEntries = (columns: ConfigManifestEntryTable['columns']): ConfigManifestEntry[] => [ +export const getGfxSetupsEntries = (columns: ConfigManifestEntryTable['columns']): ConfigManifestEntry[] => [ { id: GRAPHICS_SETUPS_TABLE_ID, - name: 'Graphics Setups', - description: 'Possible graphics setups', + name: 'GFX Setups', + description: 'Possible GFX setups', type: ConfigManifestEntryType.TABLE, required: false, defaultVal: [], columns: [ { - id: 'Name', + id: GRAPHICS_SETUPS_NAME_COLUMN_ID, name: 'Name', description: 'The code as it will appear in iNews', type: ConfigManifestEntryType.STRING, @@ -36,9 +36,9 @@ export const getGraphicsSetupsEntries = (columns: ConfigManifestEntryTable['colu hint: '' }, { - id: 'SelectedGraphicsSetupName', - name: 'Graphic Setup name', - description: 'Name of the Graphic Setup that should be used', + id: 'SelectedGfxSetupName', + name: 'GFX Setup name', + description: 'Name of the GFX Setup that should be used', type: ConfigManifestEntryType.SELECT_FROM_COLUMN, tableId: GRAPHICS_SETUPS_TABLE_ID, columnId: GRAPHICS_SETUPS_NAME_COLUMN_ID, diff --git a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts index b068654f..23e4ff81 100644 --- a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts @@ -5,7 +5,7 @@ import { ShowStyleConfig } from '../helpers/config' const blankShowStyleConfig: ShowStyleConfig = { MakeAdlibsForFulls: true, DVEStyles: [], - GFXTemplates: [], + GfxTemplates: [], GfxDesignTemplates: [], WipesConfig: [], BreakerConfig: [], @@ -14,10 +14,10 @@ const blankShowStyleConfig: ShowStyleConfig = { CasparCGLoadingClip: '', Transitions: [{ Transition: '1' }, { Transition: '2' }], ShowstyleTransition: 'CUT', - SelectedGraphicsSetupName: '', - GraphicsSetups: [], + SelectedGfxSetupName: '', + GfxSetups: [], GfxSchemaTemplates: [], - OverlayShowMapping: [] + GfxShowMapping: [] } describe('Config Manifest', () => { diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index a2b9525d..c47d368f 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -1,6 +1,6 @@ import { literal, parseMapStr } from 'tv2-common' import { defaultDSKConfig, StudioConfig } from '../../tv2_afvd_studio/helpers/config' -import { GalleryTableConfigGraphicsSetup, ShowStyleConfig } from '../helpers/config' +import { GalleryTableConfigGfxSetup, ShowStyleConfig } from '../helpers/config' import { DefaultBreakerConfig } from './breakerConfigDefault' import { DefaultGrafikConfig } from './grafikConfigDefault' @@ -44,7 +44,7 @@ function prepareConfig( export const OVL_SHOW_NAME = 'ovl-show-id' export const FULL_SHOW_NAME = 'full-show-id' -export const DEFAULT_GRAPHICS_SETUP: GalleryTableConfigGraphicsSetup = { +export const DEFAULT_GFX_SETUP: GalleryTableConfigGfxSetup = { Name: 'SomeProfile', VcpConcept: 'SomeConcept', OvlShowName: OVL_SHOW_NAME, @@ -186,9 +186,9 @@ export const defaultShowStyleConfig: ShowStyleConfig = { WipesConfig: [], BreakerConfig: DefaultBreakerConfig(), MakeAdlibsForFulls: true, - GFXTemplates: [ + GfxTemplates: [ ...DefaultGrafikConfig(), - ...literal([ + ...literal([ { INewsCode: 'GRAFIK', INewsName: 'wall', @@ -267,12 +267,12 @@ export const defaultShowStyleConfig: ShowStyleConfig = { FadeOut: 0 } ], - SelectedGraphicsSetupName: 'SomeProfile', - GraphicsSetups: [DEFAULT_GRAPHICS_SETUP], + SelectedGfxSetupName: 'SomeProfile', + GfxSetups: [DEFAULT_GFX_SETUP], Transitions: [{ Transition: '1' }, { Transition: '2' }], ShowstyleTransition: 'CUT', GfxSchemaTemplates: [], - OverlayShowMapping: [] + GfxShowMapping: [] } export const EMPTY_SOURCE_CONFIG = { diff --git a/src/tv2_afvd_showstyle/__tests__/grafikConfigDefault.ts b/src/tv2_afvd_showstyle/__tests__/grafikConfigDefault.ts index e8c6f7b2..7ceceb6e 100644 --- a/src/tv2_afvd_showstyle/__tests__/grafikConfigDefault.ts +++ b/src/tv2_afvd_showstyle/__tests__/grafikConfigDefault.ts @@ -1,5 +1,5 @@ import { DEFAULT_GRAPHICS, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' -export function DefaultGrafikConfig(): TV2ShowstyleBlueprintConfigBase['GFXTemplates'] { +export function DefaultGrafikConfig(): TV2ShowstyleBlueprintConfigBase['GfxTemplates'] { return DEFAULT_GRAPHICS } diff --git a/src/tv2_afvd_showstyle/config-manifests.ts b/src/tv2_afvd_showstyle/config-manifests.ts index b4176be5..52f054a5 100644 --- a/src/tv2_afvd_showstyle/config-manifests.ts +++ b/src/tv2_afvd_showstyle/config-manifests.ts @@ -1,7 +1,7 @@ import { ConfigManifestEntry, ConfigManifestEntryType, TSR } from 'blueprints-integration' import { DEFAULT_GRAPHICS, - getGraphicsSetupsEntries, + getGfxSetupsEntries, GRAPHICS_SETUPS_NAME_COLUMN_ID, GRAPHICS_SETUPS_TABLE_ID } from 'tv2-common' @@ -147,7 +147,7 @@ export const dveStylesManifest: ConfigManifestEntry = { ] } -const graphicsSetups = getGraphicsSetupsEntries([ +const gfxSetups = getGfxSetupsEntries([ { id: 'VcpConcept', name: 'VCP Concept', @@ -266,9 +266,9 @@ export const gfxSchemaTemplates: ConfigManifestEntry[] = [ } ] -export const overlayShowMapping: ConfigManifestEntry = { - id: 'OverlayShowMapping', - name: 'Overlay Show mapping', +export const gfxShowMapping: ConfigManifestEntry = { + id: 'GfxShowMapping', + name: 'GFX Show mapping', description: 'Maps Overlay Shows to the variety of Skemas and Designs', type: ConfigManifestEntryType.TABLE, required: false, @@ -287,10 +287,10 @@ export const overlayShowMapping: ConfigManifestEntry = { defaultVal: '' }, { - id: 'GraphicsSetup', - name: 'Graphics Setup', + id: 'GfxSetup', + name: 'GFX Setup', rank: 1, - description: 'Names of the Graphics Setups', + description: 'Names of the GFX Setups', type: ConfigManifestEntryType.SELECT_FROM_COLUMN, tableId: GRAPHICS_SETUPS_TABLE_ID, columnId: GRAPHICS_SETUPS_NAME_COLUMN_ID, @@ -332,19 +332,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ }, dveStylesManifest, { - /* - Graphic template setup - Grafik template (viz) - Source layer - Layer mapping - inews code - inews name - destination default out (default, S, B, O) - var 1 name - var 2 name - note - */ - id: 'GFXTemplates', + id: 'GfxTemplates', name: 'GFX Templates', description: 'This table can contain info in two ways. Things marked (**) are always required. If you want to do the mapping from iNews-code, then all (*)-elements are also required. GFX Template Name is what the graphic is called in viz. Source layer is the ID of the Sofie Source layer in the UI (i.e. "studio0_graphicsTema"). Layer mapping is the Sofie studio layer mapping (i.e "viz_layer_tema"). iNews command can be something like "KG=", then iNews Name is the thing that follows in iNews i.e. "ident_nyhederne"', @@ -426,9 +414,9 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ ] }, ...gfxDesignTemplates, - ...graphicsSetups, + ...gfxSetups, ...gfxSchemaTemplates, - overlayShowMapping, + gfxShowMapping, { /* Wipes Config diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 122c855e..1a9eff62 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -459,7 +459,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'BG_LOADER_SC', templateData: [], - showName: config.selectedGraphicsSetup.OvlShowName + showName: config.selectedGfxSetup.OvlShowName } }) ) @@ -1167,7 +1167,7 @@ function getBaseline(config: BlueprintConfig): BlueprintResultBaseline { content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CONCEPT, - concept: config.selectedGraphicsSetup.VcpConcept + concept: config.selectedGfxSetup.VcpConcept } }) ] diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index e7bf2a4b..39685e16 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -119,16 +119,16 @@ function insertSpecialPieces( return } - const graphicsSetupsToInitialize = segmentPayload?.initializeShows - if (graphicsSetupsToInitialize) { + const gfxSetupsToInitialize = segmentPayload?.initializeShows + if (gfxSetupsToInitialize) { const showsToInitialize = new Set() const allShows = new Set() - config.showStyle.GraphicsSetups.forEach(graphicsSetup => { - allShows.add(graphicsSetup.FullShowName) - allShows.add(graphicsSetup.OvlShowName) - if (graphicsSetupsToInitialize.includes(graphicsSetup.Name)) { - showsToInitialize.add(graphicsSetup.FullShowName) - showsToInitialize.add(graphicsSetup.OvlShowName) + config.showStyle.GfxSetups.forEach(gfxSetup => { + allShows.add(gfxSetup.FullShowName) + allShows.add(gfxSetup.OvlShowName) + if (gfxSetupsToInitialize.includes(gfxSetup.Name)) { + showsToInitialize.add(gfxSetup.FullShowName) + showsToInitialize.add(gfxSetup.OvlShowName) } }) const showsToCleanup = Array.from(allShows).filter(show => !showsToInitialize.has(show)) diff --git a/src/tv2_afvd_showstyle/helpers/config.ts b/src/tv2_afvd_showstyle/helpers/config.ts index b4a541a7..586f9bf0 100644 --- a/src/tv2_afvd_showstyle/helpers/config.ts +++ b/src/tv2_afvd_showstyle/helpers/config.ts @@ -1,13 +1,13 @@ import { IBlueprintConfig, ICommonContext, IShowStyleContext, TableConfigItemValue } from 'blueprints-integration' import { - findGraphicsSetup, - TableConfigGraphicsSetup, - TableConfigItemOverlayShowMapping, + findGfxSetup, + TableConfigGfxSetup, + TableConfigItemGfxShowMapping, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' import { BlueprintConfig as BlueprintConfigBase } from '../../tv2_afvd_studio/helpers/config' -export interface GalleryTableConfigGraphicsSetup extends TableConfigGraphicsSetup { +export interface GalleryTableConfigGfxSetup extends TableConfigGfxSetup { VcpConcept: string FullShowName: string OvlShowName: string @@ -15,19 +15,19 @@ export interface GalleryTableConfigGraphicsSetup extends TableConfigGraphicsSetu export interface BlueprintConfig extends BlueprintConfigBase { showStyle: ShowStyleConfig - selectedGraphicsSetup: GalleryTableConfigGraphicsSetup + selectedGfxSetup: GalleryTableConfigGfxSetup } export interface ShowStyleConfig extends TV2ShowstyleBlueprintConfigBase { WipesConfig: TableConfigItemValue - SelectedGraphicsSetupName: string - GraphicsSetups: GalleryTableConfigGraphicsSetup[] - OverlayShowMapping: TableConfigItemOverlayShowMapping[] + SelectedGfxSetupName: string + GfxSetups: GalleryTableConfigGfxSetup[] + GfxShowMapping: TableConfigItemGfxShowMapping[] } export function parseConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { const showstyleConfig = (rawConfig as unknown) as ShowStyleConfig - const selectedGraphicsSetup = findGraphicsSetup(context, showstyleConfig, { + const selectedGfxSetup = findGfxSetup(context, showstyleConfig, { Name: '', VcpConcept: '', OvlShowName: '', @@ -36,7 +36,7 @@ export function parseConfig(context: ICommonContext, rawConfig: IBlueprintConfig }) return { showStyle: showstyleConfig, - selectedGraphicsSetup + selectedGfxSetup } } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts index 5ed3827f..48915915 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts @@ -9,7 +9,7 @@ import { CueDefinitionLYD, EvaluateLYD, literal, ParseCue, PartDefinitionKam } f import { AdlibTags, NoteType, PartType, SharedOutputLayers, SharedSourceLayers, SourceType } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' import { - DEFAULT_GRAPHICS_SETUP, + DEFAULT_GFX_SETUP, defaultShowStyleConfig, defaultStudioConfig, EMPTY_SOURCE_CONFIG @@ -59,7 +59,7 @@ describe('lyd', () => { sources: EMPTY_SOURCE_CONFIG, mediaPlayers: [], dsk: defaultDSKConfig, - selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP + selectedGfxSetup: DEFAULT_GFX_SETUP }, pieces, adlibPieces, @@ -91,7 +91,7 @@ describe('lyd', () => { sources: EMPTY_SOURCE_CONFIG, mediaPlayers: [], dsk: defaultDSKConfig, - selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP + selectedGfxSetup: DEFAULT_GFX_SETUP }, pieces, adlibPieces, @@ -126,7 +126,7 @@ describe('lyd', () => { sources: EMPTY_SOURCE_CONFIG, mediaPlayers: [], dsk: defaultDSKConfig, - selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP + selectedGfxSetup: DEFAULT_GFX_SETUP }, pieces, adlibPieces, @@ -154,7 +154,7 @@ describe('lyd', () => { sources: EMPTY_SOURCE_CONFIG, mediaPlayers: [], dsk: defaultDSKConfig, - selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP + selectedGfxSetup: DEFAULT_GFX_SETUP }, pieces, adlibPieces, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts index 78dd050b..5395250d 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -19,7 +19,7 @@ import { import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayers, SourceType } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' import { - DEFAULT_GRAPHICS_SETUP, + DEFAULT_GFX_SETUP, defaultShowStyleConfig, defaultStudioConfig, OVL_SHOW_NAME @@ -95,7 +95,7 @@ describe('telefon', () => { }, mediaPlayers: [], dsk: defaultDSKConfig, - selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP + selectedGfxSetup: DEFAULT_GFX_SETUP }, mockContext, pieces, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts index 7a95ff05..d2d88e4f 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts @@ -69,7 +69,7 @@ export function EvaluateClearGrafiks( content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, - showName: config.selectedGraphicsSetup.OvlShowName + showName: config.selectedGfxSetup.OvlShowName } }) ] diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts index 2ac4c9ec..8bc76145 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts @@ -116,7 +116,7 @@ function dveLoopTimeline(path: string): TSR.TSRTimelineObj[] { } function fullLoopTimeline(config: TV2BlueprintConfig, parsedCue: CueDefinitionBackgroundLoop): TSR.TSRTimelineObj[] { - if (!config.selectedGraphicsSetup.FullShowName) { + if (!config.selectedGfxSetup.FullShowName) { return [] } return [ @@ -130,7 +130,7 @@ function fullLoopTimeline(config: TV2BlueprintConfig, parsedCue: CueDefinitionBa type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: parsedCue.backgroundLoop, templateData: [], - showName: config.selectedGraphicsSetup.FullShowName + showName: config.selectedGfxSetup.FullShowName } }) ] diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 562deedf..d56b5ef4 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -25,7 +25,10 @@ import sourcelayerDefaults from './sourcelayer-defaults' import { forceSourceLayerToDefaults, getOutputLayerDefaultsMigrationSteps, - getSourceLayerDefaultsMigrationSteps + getSourceLayerDefaultsMigrationSteps, + renameColumnId, + renameColumnIdForAllVariants, + renameTableId } from './util' import { getCreateVariantMigrationSteps } from './variants-defaults' @@ -250,6 +253,16 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ */ forceSourceLayerToDefaults('1.7.7', SourceLayer.PgmContinuity), + /** + * 1.7.9 Rename to "Gfx" + */ + renameTableId('1.7.9', 'GFXTemplates', 'GfxTemplates'), + renameTableId('1.7.9', 'GraphicsSetups', 'GfxSetups'), + renameColumnId('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), + renameColumnIdForAllVariants('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), + renameTableColumn('1.7.9', 'OverlayShowMapping', 'GraphicsSetup', 'GfxSetup'), + renameTableId('1.7.9', 'OverlayShowMapping', 'GfxShowMapping'), + // Fill in any layers that did not exist before // Note: These should only be run as the very final step of all migrations. otherwise they will add items too early, and confuse old migrations ...getSourceLayerDefaultsMigrationSteps(VERSION), diff --git a/src/tv2_afvd_showstyle/migrations/util.ts b/src/tv2_afvd_showstyle/migrations/util.ts index 0c0f93b1..523fd45d 100644 --- a/src/tv2_afvd_showstyle/migrations/util.ts +++ b/src/tv2_afvd_showstyle/migrations/util.ts @@ -1,6 +1,8 @@ +import { BasicConfigItemValue, IBlueprintShowStyleVariant } from '@sofie-automation/blueprints-integration' import { IOutputLayer, ISourceLayer, MigrationContextShowStyle, MigrationStepShowStyle } from 'blueprints-integration' import { forceSourceLayerToDefaultsBase, literal } from 'tv2-common' import * as _ from 'underscore' +import { TableConfigItemValue } from '../../types/blueprints-integration' import { showStyleConfigManifest } from '../config-manifests' import OutputlayerDefaults from './outputlayer-defaults' import SourcelayerDefaults from './sourcelayer-defaults' @@ -105,3 +107,98 @@ export function getOutputLayerDefaultsMigrationSteps(versionStr: string): Migrat }) ) } + +/** + * "Renames" the id of a table by copying over all values over into a new table which has the new id - then removes the values from the old table + */ +export function renameTableId(version: string, oldTableId: string, newTableId: string): MigrationStepShowStyle { + return { + id: `${version}.rename.table.id.${oldTableId}.to.${newTableId}`, + version, + canBeRunAutomatically: true, + validate: (context: MigrationContextShowStyle) => { + const oldConfigTable = (context.getBaseConfig(oldTableId) as unknown) as TableConfigItemValue + if (!oldConfigTable || oldConfigTable.length === 0) { + return false + } + + const newConfigTable = (context.getBaseConfig(newTableId) as unknown) as TableConfigItemValue + return !newConfigTable + }, + migrate: (context: MigrationContextShowStyle) => { + const oldConfigTable = (context.getBaseConfig(oldTableId) as unknown) as TableConfigItemValue + const newConfigTable = ((context.getBaseConfig(newTableId) as unknown) as TableConfigItemValue) ?? [] + oldConfigTable.map(value => newConfigTable.push(value)) + + context.setBaseConfig(newTableId, newConfigTable) + context.setBaseConfig(oldTableId, []) + } + } +} + +/** + * "Renames" the id of a column by overriding the value of the old column onto the new column - then removes the value from the old column + */ +export function renameColumnId(version: string, oldColumnId: string, newColumnId: string): MigrationStepShowStyle { + return { + id: `${version}.rename.column.id.${oldColumnId}.to.${newColumnId}`, + version, + canBeRunAutomatically: true, + validate: (context: MigrationContextShowStyle) => { + const oldConfigTable = (context.getBaseConfig(oldColumnId) as unknown) as BasicConfigItemValue + if (!oldConfigTable || Object.keys(oldConfigTable).length === 0) { + return false + } + + const newConfigTable = (context.getBaseConfig(newColumnId) as unknown) as BasicConfigItemValue + return !newConfigTable + }, + migrate: (context: MigrationContextShowStyle) => { + const oldConfigColumn = (context.getBaseConfig(oldColumnId) as unknown) as BasicConfigItemValue + + context.setBaseConfig(newColumnId, oldConfigColumn) + context.setBaseConfig(oldColumnId, []) + } + } +} + +/** + * For all variants: "Renames" the id of a column by overriding the value of the old column onto the new column - then removes the value from the old column + */ +export function renameColumnIdForAllVariants( + version: string, + oldColumnId: string, + newColumnId: string +): MigrationStepShowStyle { + return { + id: `${version}.rename.column.id.${oldColumnId}.to.${newColumnId}.for.all.variants`, + version, + canBeRunAutomatically: true, + validate: (context: MigrationContextShowStyle) => { + const allVariants: IBlueprintShowStyleVariant[] = context.getAllVariants() + + if (allVariants.length === 0) { + return false + } + + const noVariantsHaveValueInOldColumn: boolean = allVariants.every((variant: IBlueprintShowStyleVariant) => { + const oldColumn = context.getVariantConfig(variant._id, oldColumnId) + return !oldColumn || Object.keys(oldColumn).length === 0 + }) + + return !noVariantsHaveValueInOldColumn + }, + migrate: (context: MigrationContextShowStyle) => { + const allVariants: IBlueprintShowStyleVariant[] = context.getAllVariants() + allVariants.forEach((variant: IBlueprintShowStyleVariant) => { + const oldColumn = context.getVariantConfig(variant._id, oldColumnId) + if (!oldColumn || Object.keys(oldColumn).length === 0) { + return + } + + context.setVariantConfig(variant._id, newColumnId, oldColumn) + context.setVariantConfig(variant._id, oldColumnId, {}) + }) + } + } +} diff --git a/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts index 4e3a81e1..d20508f4 100644 --- a/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts @@ -4,7 +4,7 @@ import { OfftubeShowStyleConfig } from '../helpers/config' const blankShowStyleConfig: OfftubeShowStyleConfig = { DVEStyles: [], - GFXTemplates: [], + GfxTemplates: [], GfxDesignTemplates: [], WipesConfig: [], BreakerConfig: [], @@ -15,8 +15,8 @@ const blankShowStyleConfig: OfftubeShowStyleConfig = { ShowstyleTransition: 'CUT', MakeAdlibsForFulls: true, GfxSchemaTemplates: [], - GraphicsSetups: [], - SelectedGraphicsSetupName: '' + GfxSetups: [], + SelectedGfxSetupName: '' } describe('Config Manifest', () => { diff --git a/src/tv2_offtube_showstyle/config-manifests.ts b/src/tv2_offtube_showstyle/config-manifests.ts index 1fb3308e..24ec9cb6 100644 --- a/src/tv2_offtube_showstyle/config-manifests.ts +++ b/src/tv2_offtube_showstyle/config-manifests.ts @@ -1,5 +1,5 @@ import { ConfigManifestEntry, ConfigManifestEntryType, TSR } from 'blueprints-integration' -import { DEFAULT_GRAPHICS, getGraphicsSetupsEntries } from 'tv2-common' +import { DEFAULT_GRAPHICS, getGfxSetupsEntries } from 'tv2-common' export const dveStylesManifest: ConfigManifestEntry = { id: 'DVEStyles', @@ -247,19 +247,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ }, dveStylesManifest, { - /* - Graphic template setup - Grafik template (viz) - Source layer - Layer mapping - inews code - inews name - destination default out (default, S, B, O) - var 1 name - var 2 name - note - */ - id: 'GFXTemplates', + id: 'GfxTemplates', name: 'GFX Templates', description: 'This table can contain info in two ways. Things marked (**) are always required. If you want to do the mapping from iNews-code, then all (*)-elements are also required. GFX Template Name is what the graphic is called in the HTML package. Source layer is the ID of the Sofie Source layer in the UI (i.e. "studio0_graphicsTema"). Layer mapping is the Sofie studio layer mapping (i.e "viz_layer_tema"). iNews command can be something like "KG=", then iNews Name is the thing that follows in iNews i.e. "ident_nyhederne"', @@ -595,5 +583,5 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ ] }, ...gfxSchemaTemplates, - ...getGraphicsSetupsEntries([]) + ...getGfxSetupsEntries([]) ] diff --git a/src/tv2_offtube_showstyle/helpers/config.ts b/src/tv2_offtube_showstyle/helpers/config.ts index df3d65a6..938e9985 100644 --- a/src/tv2_offtube_showstyle/helpers/config.ts +++ b/src/tv2_offtube_showstyle/helpers/config.ts @@ -5,7 +5,7 @@ import { IStudioContext, TableConfigItemValue } from 'blueprints-integration' -import { findGraphicsSetup, TableConfigGraphicsSetup, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' +import { findGfxSetup, TableConfigGfxSetup, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' import * as _ from 'underscore' import { OfftubeStudioBlueprintConfig } from '../../tv2_offtube_studio/helpers/config' @@ -22,7 +22,7 @@ export interface TableConfigItemGfxTemplates { export interface OfftubeShowstyleBlueprintConfig extends OfftubeStudioBlueprintConfig { showStyle: OfftubeShowStyleConfig - selectedGraphicsSetup: TableConfigGraphicsSetup + selectedGfxSetup: TableConfigGfxSetup } export interface DVEConfigInput { @@ -36,18 +36,18 @@ export interface DVEConfigInput { export interface OfftubeShowStyleConfig extends TV2ShowstyleBlueprintConfigBase { WipesConfig: TableConfigItemValue - GraphicsSetups: TableConfigGraphicsSetup[] + GfxSetups: TableConfigGfxSetup[] } export function parseConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { const showstyleConfig = (rawConfig as unknown) as OfftubeShowStyleConfig - const selectedGraphicsSetup = findGraphicsSetup(context, showstyleConfig, { + const selectedGfxSetup = findGfxSetup(context, showstyleConfig, { Name: '', HtmlPackageFolder: '' }) return { showStyle: showstyleConfig, - selectedGraphicsSetup + selectedGfxSetup } } diff --git a/src/tv2_offtube_showstyle/migrations/index.ts b/src/tv2_offtube_showstyle/migrations/index.ts index 7153ae46..c923cacb 100644 --- a/src/tv2_offtube_showstyle/migrations/index.ts +++ b/src/tv2_offtube_showstyle/migrations/index.ts @@ -16,6 +16,7 @@ import { UpsertValuesIntoTransitionTable } from 'tv2-common' import { SharedGraphicLLayer, SharedSourceLayers } from 'tv2-constants' +import { renameColumnId, renameColumnIdForAllVariants, renameTableId } from '../../tv2_afvd_showstyle/migrations/util' import { ATEMModel } from '../../types/atem' import { OfftubeSourceLayer } from '../layers' import { GetDefaultStudioSourcesForOfftube } from './hotkeys' @@ -281,6 +282,11 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ forceSourceLayerToDefaults('1.7.7', OfftubeSourceLayer.PgmContinuity), forceSourceLayerToDefaults('1.7.7', OfftubeSourceLayer.PgmDVEBackground), + renameTableId('1.7.9', 'GFXTemplates', 'GfxTemplates'), + renameTableId('1.7.9', 'GraphicsSetups', 'GfxSetups'), + renameColumnId('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), + renameColumnIdForAllVariants('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), + ...getSourceLayerDefaultsMigrationSteps(VERSION), ...getOutputLayerDefaultsMigrationSteps(VERSION), GetDefaultAdLibTriggers(VERSION, SHOW_STYLE_ID, {}, GetDefaultStudioSourcesForOfftube, false) From 9cec734a3ac876ac84f20550fec6a7ca5c48da09 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 21 Dec 2022 11:12:21 +0100 Subject: [PATCH 05/86] fix: SOF-1290 disable Server Resume in Qboxes make `RESET` the default trigger mode in the Qbox (Offtube) Show Style --- src/tv2-common/actions/executeAction.ts | 18 +++++++++--------- src/tv2_afvd_showstyle/actions.ts | 7 +++++-- src/tv2_offtube_showstyle/actions.ts | 7 +++++-- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 4b91c92c..e1bcaa28 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -21,7 +21,6 @@ import { ActionClearGraphics, ActionCommentatorSelectDVE, ActionCommentatorSelectFull, - ActionCommentatorSelectServer, ActionCutSourceToBox, ActionCutToCamera, ActionCutToRemote, @@ -192,6 +191,11 @@ export interface ActionExecutionSettings< alphaAtEnd: number ) => WithTimeline pilotGraphicSettings: PilotGeneratorSettings + serverActionSettings: ServerActionSettings +} + +interface ServerActionSettings { + defaultTriggerMode: ServerSelectMode } export async function executeAction< @@ -249,9 +253,7 @@ export async function executeAction< case AdlibActionType.COMMENTATOR_SELECT_SERVER: await executeActionCommentatorSelectServer( context, - settings, - actionId, - userData as ActionCommentatorSelectServer + settings ) break case AdlibActionType.COMMENTATOR_SELECT_FULL: @@ -451,7 +453,7 @@ async function executeActionSelectServerClip< session: sessionToContinue ?? externalId, adLibPix: userData.adLibPix, lastServerPosition: await getServerPosition(context), - actionTriggerMode: triggerMode + actionTriggerMode: triggerMode ?? settings.serverActionSettings.defaultTriggerMode }, { SourceLayer: { @@ -1738,9 +1740,7 @@ async function executeActionCommentatorSelectServer< ShowStyleConfig extends TV2BlueprintConfigBase >( context: ITV2ActionExecutionContext, - settings: ActionExecutionSettings, - _actionId: string, - _userData: ActionCommentatorSelectServer + settings: ActionExecutionSettings ) { const data = await findDataStore(context, [ settings.SelectedAdlibs.SourceLayer.Server, @@ -1766,7 +1766,7 @@ async function executeActionCommentatorSelectServer< settings, AdlibActionType.SELECT_SERVER_CLIP, data, - ServerSelectMode.RESET, + settings.serverActionSettings.defaultTriggerMode, session ) } diff --git a/src/tv2_afvd_showstyle/actions.ts b/src/tv2_afvd_showstyle/actions.ts index 4da99a84..8a492e8c 100644 --- a/src/tv2_afvd_showstyle/actions.ts +++ b/src/tv2_afvd_showstyle/actions.ts @@ -1,5 +1,5 @@ import { ActionUserData, IActionExecutionContext } from 'blueprints-integration' -import { executeAction } from 'tv2-common' +import { executeAction, ServerSelectMode } from 'tv2-common' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' import { getConfig } from './helpers/config' import { AFVD_DVE_GENERATOR_OPTIONS } from './helpers/content/dve' @@ -64,7 +64,10 @@ export async function executeActionAFVD( SELECTED_ADLIB_LAYERS: [SourceLayer.SelectedServer, SourceLayer.SelectedVoiceOver] }, createJingleContent: createJingleContentAFVD, - pilotGraphicSettings: pilotGeneratorSettingsAFVD + pilotGraphicSettings: pilotGeneratorSettingsAFVD, + serverActionSettings: { + defaultTriggerMode: ServerSelectMode.RESUME + } }, actionId, userData, diff --git a/src/tv2_offtube_showstyle/actions.ts b/src/tv2_offtube_showstyle/actions.ts index 674351e8..eb55a771 100644 --- a/src/tv2_offtube_showstyle/actions.ts +++ b/src/tv2_offtube_showstyle/actions.ts @@ -1,5 +1,5 @@ import { ActionUserData, IActionExecutionContext } from 'blueprints-integration' -import { executeAction } from 'tv2-common' +import { executeAction, ServerSelectMode } from 'tv2-common' import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' import { OFFTUBE_DVE_GENERATOR_OPTIONS } from './content/OfftubeDVEContent' import { pilotGeneratorSettingsOfftube } from './cues/OfftubeGraphics' @@ -71,7 +71,10 @@ export async function executeActionOfftube( SELECTED_ADLIB_LAYERS }, createJingleContent: createJingleContentOfftube, - pilotGraphicSettings: pilotGeneratorSettingsOfftube + pilotGraphicSettings: pilotGeneratorSettingsOfftube, + serverActionSettings: { + defaultTriggerMode: ServerSelectMode.RESET + } }, actionId, userData From be9693a8f63b4713c340c0c886439515751c38b0 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Tue, 3 Jan 2023 13:00:32 +0100 Subject: [PATCH 06/86] SOF-1277 Refactor renameColumnId migration to renameBlueprintConfiguration --- src/tv2-common/helpers/graphics/name.ts | 6 +-- src/tv2_afvd_showstyle/migrations/index.ts | 8 +-- src/tv2_afvd_showstyle/migrations/util.ts | 50 ++++++++++--------- src/tv2_offtube_showstyle/migrations/index.ts | 10 ++-- 4 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/tv2-common/helpers/graphics/name.ts b/src/tv2-common/helpers/graphics/name.ts index e257d867..413054aa 100644 --- a/src/tv2-common/helpers/graphics/name.ts +++ b/src/tv2-common/helpers/graphics/name.ts @@ -33,14 +33,14 @@ export function GetFullGraphicTemplateNameFromCue( } } -export function GetFullGrafikTemplateName(config: TV2BlueprintConfig, iNewsTempalateName: string): string { +export function GetFullGrafikTemplateName(config: TV2BlueprintConfig, iNewsTemplateName: string): string { const template = config.showStyle.GfxTemplates.find(templ => - templ.INewsName ? templ.INewsName.toString().toUpperCase() === iNewsTempalateName.toUpperCase() : false + templ.INewsName ? templ.INewsName.toString().toUpperCase() === iNewsTemplateName.toUpperCase() : false ) if (template && template.VizTemplate.toString().length) { return template.VizTemplate.toString() } // This means unconfigured templates will still be supported, with default out. - return iNewsTempalateName + return iNewsTemplateName } diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index d56b5ef4..ee9d3c58 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -26,8 +26,8 @@ import { forceSourceLayerToDefaults, getOutputLayerDefaultsMigrationSteps, getSourceLayerDefaultsMigrationSteps, - renameColumnId, - renameColumnIdForAllVariants, + renameBlueprintConfiguration, + renameBlueprintsConfigurationForAllVariants, renameTableId } from './util' import { getCreateVariantMigrationSteps } from './variants-defaults' @@ -258,8 +258,8 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ */ renameTableId('1.7.9', 'GFXTemplates', 'GfxTemplates'), renameTableId('1.7.9', 'GraphicsSetups', 'GfxSetups'), - renameColumnId('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), - renameColumnIdForAllVariants('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), + renameBlueprintConfiguration('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), + renameBlueprintsConfigurationForAllVariants('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), renameTableColumn('1.7.9', 'OverlayShowMapping', 'GraphicsSetup', 'GfxSetup'), renameTableId('1.7.9', 'OverlayShowMapping', 'GfxShowMapping'), diff --git a/src/tv2_afvd_showstyle/migrations/util.ts b/src/tv2_afvd_showstyle/migrations/util.ts index 523fd45d..11cc1c25 100644 --- a/src/tv2_afvd_showstyle/migrations/util.ts +++ b/src/tv2_afvd_showstyle/migrations/util.ts @@ -137,41 +137,45 @@ export function renameTableId(version: string, oldTableId: string, newTableId: s } /** - * "Renames" the id of a column by overriding the value of the old column onto the new column - then removes the value from the old column + * "Renames" the name of a Blueprint configuration by overriding the value of the old configuration onto the new configuration - then removes the old configuration */ -export function renameColumnId(version: string, oldColumnId: string, newColumnId: string): MigrationStepShowStyle { +export function renameBlueprintConfiguration( + version: string, + oldConfigurationName: string, + newConfigurationName: string +): MigrationStepShowStyle { return { - id: `${version}.rename.column.id.${oldColumnId}.to.${newColumnId}`, + id: `${version}.rename.blueprint.configuration.${oldConfigurationName}.to.${newConfigurationName}`, version, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const oldConfigTable = (context.getBaseConfig(oldColumnId) as unknown) as BasicConfigItemValue - if (!oldConfigTable || Object.keys(oldConfigTable).length === 0) { + const oldConfig = (context.getBaseConfig(oldConfigurationName) as unknown) as BasicConfigItemValue + if (!oldConfig || Object.keys(oldConfig).length === 0) { return false } - const newConfigTable = (context.getBaseConfig(newColumnId) as unknown) as BasicConfigItemValue - return !newConfigTable + const newConfig = (context.getBaseConfig(newConfigurationName) as unknown) as BasicConfigItemValue + return !newConfig }, migrate: (context: MigrationContextShowStyle) => { - const oldConfigColumn = (context.getBaseConfig(oldColumnId) as unknown) as BasicConfigItemValue + const oldConfig = (context.getBaseConfig(oldConfigurationName) as unknown) as BasicConfigItemValue - context.setBaseConfig(newColumnId, oldConfigColumn) - context.setBaseConfig(oldColumnId, []) + context.setBaseConfig(newConfigurationName, oldConfig) + context.removeBaseConfig(oldConfigurationName) } } } /** - * For all variants: "Renames" the id of a column by overriding the value of the old column onto the new column - then removes the value from the old column + * For all variants: "Renames" the blueprint configuration by overriding the value of the old configuration onto the new configuration - then removes the old configuration */ -export function renameColumnIdForAllVariants( +export function renameBlueprintsConfigurationForAllVariants( version: string, - oldColumnId: string, - newColumnId: string + oldConfigName: string, + newConfigName: string ): MigrationStepShowStyle { return { - id: `${version}.rename.column.id.${oldColumnId}.to.${newColumnId}.for.all.variants`, + id: `${version}.rename.blueprint.configuration.${oldConfigName}.to.${newConfigName}.for.all.variants`, version, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { @@ -181,23 +185,23 @@ export function renameColumnIdForAllVariants( return false } - const noVariantsHaveValueInOldColumn: boolean = allVariants.every((variant: IBlueprintShowStyleVariant) => { - const oldColumn = context.getVariantConfig(variant._id, oldColumnId) - return !oldColumn || Object.keys(oldColumn).length === 0 + const noVariantsHaveOldConfig: boolean = allVariants.every((variant: IBlueprintShowStyleVariant) => { + const oldConfig = context.getVariantConfig(variant._id, oldConfigName) + return !oldConfig || Object.keys(oldConfig).length === 0 }) - return !noVariantsHaveValueInOldColumn + return !noVariantsHaveOldConfig }, migrate: (context: MigrationContextShowStyle) => { const allVariants: IBlueprintShowStyleVariant[] = context.getAllVariants() allVariants.forEach((variant: IBlueprintShowStyleVariant) => { - const oldColumn = context.getVariantConfig(variant._id, oldColumnId) - if (!oldColumn || Object.keys(oldColumn).length === 0) { + const oldConfig = context.getVariantConfig(variant._id, oldConfigName) + if (!oldConfig || Object.keys(oldConfig).length === 0) { return } - context.setVariantConfig(variant._id, newColumnId, oldColumn) - context.setVariantConfig(variant._id, oldColumnId, {}) + context.setVariantConfig(variant._id, newConfigName, oldConfig) + context.removeVariantConfig(variant._id, oldConfigName) }) } } diff --git a/src/tv2_offtube_showstyle/migrations/index.ts b/src/tv2_offtube_showstyle/migrations/index.ts index c923cacb..c5e8fd75 100644 --- a/src/tv2_offtube_showstyle/migrations/index.ts +++ b/src/tv2_offtube_showstyle/migrations/index.ts @@ -16,7 +16,11 @@ import { UpsertValuesIntoTransitionTable } from 'tv2-common' import { SharedGraphicLLayer, SharedSourceLayers } from 'tv2-constants' -import { renameColumnId, renameColumnIdForAllVariants, renameTableId } from '../../tv2_afvd_showstyle/migrations/util' +import { + renameBlueprintConfiguration, + renameBlueprintsConfigurationForAllVariants, + renameTableId +} from '../../tv2_afvd_showstyle/migrations/util' import { ATEMModel } from '../../types/atem' import { OfftubeSourceLayer } from '../layers' import { GetDefaultStudioSourcesForOfftube } from './hotkeys' @@ -284,8 +288,8 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ renameTableId('1.7.9', 'GFXTemplates', 'GfxTemplates'), renameTableId('1.7.9', 'GraphicsSetups', 'GfxSetups'), - renameColumnId('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), - renameColumnIdForAllVariants('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), + renameBlueprintConfiguration('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), + renameBlueprintsConfigurationForAllVariants('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), ...getSourceLayerDefaultsMigrationSteps(VERSION), ...getOutputLayerDefaultsMigrationSteps(VERSION), From d5f25fa5869bfe2c69a890faa4b94525d10fbf0f Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Tue, 3 Jan 2023 13:03:23 +0100 Subject: [PATCH 07/86] SOF-1277 Removes the old table when renaming the tableId in a migration --- src/tv2_afvd_showstyle/migrations/util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv2_afvd_showstyle/migrations/util.ts b/src/tv2_afvd_showstyle/migrations/util.ts index 11cc1c25..92b0584e 100644 --- a/src/tv2_afvd_showstyle/migrations/util.ts +++ b/src/tv2_afvd_showstyle/migrations/util.ts @@ -131,7 +131,7 @@ export function renameTableId(version: string, oldTableId: string, newTableId: s oldConfigTable.map(value => newConfigTable.push(value)) context.setBaseConfig(newTableId, newConfigTable) - context.setBaseConfig(oldTableId, []) + context.removeBaseConfig(oldTableId) } } } From f7f7e0a9f288d8505ceb26452343440634e7a6e9 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Thu, 5 Jan 2023 07:40:00 +0100 Subject: [PATCH 08/86] SOF-1277 Simplify validate logic. Move migration functions to a shared file between afvd and qbox --- .../migrations/renameConfigurationHelper.ts | 98 +++++++++++++++++ src/tv2_afvd_showstyle/migrations/index.ts | 10 +- src/tv2_afvd_showstyle/migrations/util.ts | 101 ------------------ src/tv2_offtube_showstyle/migrations/index.ts | 2 +- 4 files changed, 105 insertions(+), 106 deletions(-) create mode 100644 src/tv2-common/migrations/renameConfigurationHelper.ts diff --git a/src/tv2-common/migrations/renameConfigurationHelper.ts b/src/tv2-common/migrations/renameConfigurationHelper.ts new file mode 100644 index 00000000..95559368 --- /dev/null +++ b/src/tv2-common/migrations/renameConfigurationHelper.ts @@ -0,0 +1,98 @@ +import { BasicConfigItemValue, IBlueprintShowStyleVariant } from '@sofie-automation/blueprints-integration' +import { + MigrationContextShowStyle, + MigrationStepShowStyle, + TableConfigItemValue +} from '../../types/blueprints-integration' + +/** + * "Renames" the id of a table by copying over all values over into a new table which has the new id - then removes the values from the old table + */ +export function renameTableId(version: string, oldTableId: string, newTableId: string): MigrationStepShowStyle { + return { + id: `${version}.rename.table.id.${oldTableId}.to.${newTableId}`, + version, + canBeRunAutomatically: true, + validate: (context: MigrationContextShowStyle) => { + const oldConfigTable = (context.getBaseConfig(oldTableId) as unknown) as TableConfigItemValue + if (!oldConfigTable || oldConfigTable.length === 0) { + return false + } + + const newConfigTable = (context.getBaseConfig(newTableId) as unknown) as TableConfigItemValue + return !newConfigTable + }, + migrate: (context: MigrationContextShowStyle) => { + const oldConfigTable = (context.getBaseConfig(oldTableId) as unknown) as TableConfigItemValue + const newConfigTable = ((context.getBaseConfig(newTableId) as unknown) as TableConfigItemValue) ?? [] + oldConfigTable.map(value => newConfigTable.push(value)) + + context.setBaseConfig(newTableId, newConfigTable) + context.removeBaseConfig(oldTableId) + } + } +} + +/** + * "Renames" the name of a Blueprint configuration by overriding the value of the old configuration onto the new configuration - then removes the old configuration + */ +export function renameBlueprintConfiguration( + version: string, + oldConfigurationName: string, + newConfigurationName: string +): MigrationStepShowStyle { + return { + id: `${version}.rename.blueprint.configuration.${oldConfigurationName}.to.${newConfigurationName}`, + version, + canBeRunAutomatically: true, + validate: (context: MigrationContextShowStyle) => { + const oldConfig = (context.getBaseConfig(oldConfigurationName) as unknown) as BasicConfigItemValue + return oldConfig !== undefined + }, + migrate: (context: MigrationContextShowStyle) => { + const oldConfig = (context.getBaseConfig(oldConfigurationName) as unknown) as BasicConfigItemValue + + context.setBaseConfig(newConfigurationName, oldConfig) + context.removeBaseConfig(oldConfigurationName) + } + } +} + +/** + * For all variants: "Renames" the blueprint configuration by overriding the value of the old configuration onto the new configuration - then removes the old configuration + */ +export function renameBlueprintsConfigurationForAllVariants( + version: string, + oldConfigName: string, + newConfigName: string +): MigrationStepShowStyle { + return { + id: `${version}.rename.blueprint.configuration.${oldConfigName}.to.${newConfigName}.for.all.variants`, + version, + canBeRunAutomatically: true, + validate: (context: MigrationContextShowStyle) => { + const allVariants: IBlueprintShowStyleVariant[] = context.getAllVariants() + + if (allVariants.length === 0) { + return false + } + + return allVariants.some((variant: IBlueprintShowStyleVariant) => { + const oldConfig = context.getVariantConfig(variant._id, oldConfigName) + return oldConfig !== undefined + }) + }, + migrate: (context: MigrationContextShowStyle) => { + const allVariants: IBlueprintShowStyleVariant[] = context.getAllVariants() + allVariants.forEach((variant: IBlueprintShowStyleVariant) => { + const oldConfig = context.getVariantConfig(variant._id, oldConfigName) + if (!oldConfig || Object.keys(oldConfig).length === 0) { + return + } + + context.setVariantConfig(variant._id, newConfigName, oldConfig) + context.removeVariantConfig(variant._id, oldConfigName) + }) + } + } +} diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index ee9d3c58..8fef3da8 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -16,6 +16,11 @@ import { UpsertValuesIntoTransitionTable } from 'tv2-common' import { SharedGraphicLLayer } from 'tv2-constants' +import { + renameBlueprintConfiguration, + renameBlueprintsConfigurationForAllVariants, + renameTableId +} from '../../tv2-common/migrations/renameConfigurationHelper' import { remapVizDOvl, remapVizLLayer } from '../../tv2_offtube_showstyle/migrations' import { remapTableColumnValues } from '../../tv2_offtube_showstyle/migrations/util' import { ATEMModel } from '../../types/atem' @@ -25,10 +30,7 @@ import sourcelayerDefaults from './sourcelayer-defaults' import { forceSourceLayerToDefaults, getOutputLayerDefaultsMigrationSteps, - getSourceLayerDefaultsMigrationSteps, - renameBlueprintConfiguration, - renameBlueprintsConfigurationForAllVariants, - renameTableId + getSourceLayerDefaultsMigrationSteps } from './util' import { getCreateVariantMigrationSteps } from './variants-defaults' diff --git a/src/tv2_afvd_showstyle/migrations/util.ts b/src/tv2_afvd_showstyle/migrations/util.ts index 92b0584e..0c0f93b1 100644 --- a/src/tv2_afvd_showstyle/migrations/util.ts +++ b/src/tv2_afvd_showstyle/migrations/util.ts @@ -1,8 +1,6 @@ -import { BasicConfigItemValue, IBlueprintShowStyleVariant } from '@sofie-automation/blueprints-integration' import { IOutputLayer, ISourceLayer, MigrationContextShowStyle, MigrationStepShowStyle } from 'blueprints-integration' import { forceSourceLayerToDefaultsBase, literal } from 'tv2-common' import * as _ from 'underscore' -import { TableConfigItemValue } from '../../types/blueprints-integration' import { showStyleConfigManifest } from '../config-manifests' import OutputlayerDefaults from './outputlayer-defaults' import SourcelayerDefaults from './sourcelayer-defaults' @@ -107,102 +105,3 @@ export function getOutputLayerDefaultsMigrationSteps(versionStr: string): Migrat }) ) } - -/** - * "Renames" the id of a table by copying over all values over into a new table which has the new id - then removes the values from the old table - */ -export function renameTableId(version: string, oldTableId: string, newTableId: string): MigrationStepShowStyle { - return { - id: `${version}.rename.table.id.${oldTableId}.to.${newTableId}`, - version, - canBeRunAutomatically: true, - validate: (context: MigrationContextShowStyle) => { - const oldConfigTable = (context.getBaseConfig(oldTableId) as unknown) as TableConfigItemValue - if (!oldConfigTable || oldConfigTable.length === 0) { - return false - } - - const newConfigTable = (context.getBaseConfig(newTableId) as unknown) as TableConfigItemValue - return !newConfigTable - }, - migrate: (context: MigrationContextShowStyle) => { - const oldConfigTable = (context.getBaseConfig(oldTableId) as unknown) as TableConfigItemValue - const newConfigTable = ((context.getBaseConfig(newTableId) as unknown) as TableConfigItemValue) ?? [] - oldConfigTable.map(value => newConfigTable.push(value)) - - context.setBaseConfig(newTableId, newConfigTable) - context.removeBaseConfig(oldTableId) - } - } -} - -/** - * "Renames" the name of a Blueprint configuration by overriding the value of the old configuration onto the new configuration - then removes the old configuration - */ -export function renameBlueprintConfiguration( - version: string, - oldConfigurationName: string, - newConfigurationName: string -): MigrationStepShowStyle { - return { - id: `${version}.rename.blueprint.configuration.${oldConfigurationName}.to.${newConfigurationName}`, - version, - canBeRunAutomatically: true, - validate: (context: MigrationContextShowStyle) => { - const oldConfig = (context.getBaseConfig(oldConfigurationName) as unknown) as BasicConfigItemValue - if (!oldConfig || Object.keys(oldConfig).length === 0) { - return false - } - - const newConfig = (context.getBaseConfig(newConfigurationName) as unknown) as BasicConfigItemValue - return !newConfig - }, - migrate: (context: MigrationContextShowStyle) => { - const oldConfig = (context.getBaseConfig(oldConfigurationName) as unknown) as BasicConfigItemValue - - context.setBaseConfig(newConfigurationName, oldConfig) - context.removeBaseConfig(oldConfigurationName) - } - } -} - -/** - * For all variants: "Renames" the blueprint configuration by overriding the value of the old configuration onto the new configuration - then removes the old configuration - */ -export function renameBlueprintsConfigurationForAllVariants( - version: string, - oldConfigName: string, - newConfigName: string -): MigrationStepShowStyle { - return { - id: `${version}.rename.blueprint.configuration.${oldConfigName}.to.${newConfigName}.for.all.variants`, - version, - canBeRunAutomatically: true, - validate: (context: MigrationContextShowStyle) => { - const allVariants: IBlueprintShowStyleVariant[] = context.getAllVariants() - - if (allVariants.length === 0) { - return false - } - - const noVariantsHaveOldConfig: boolean = allVariants.every((variant: IBlueprintShowStyleVariant) => { - const oldConfig = context.getVariantConfig(variant._id, oldConfigName) - return !oldConfig || Object.keys(oldConfig).length === 0 - }) - - return !noVariantsHaveOldConfig - }, - migrate: (context: MigrationContextShowStyle) => { - const allVariants: IBlueprintShowStyleVariant[] = context.getAllVariants() - allVariants.forEach((variant: IBlueprintShowStyleVariant) => { - const oldConfig = context.getVariantConfig(variant._id, oldConfigName) - if (!oldConfig || Object.keys(oldConfig).length === 0) { - return - } - - context.setVariantConfig(variant._id, newConfigName, oldConfig) - context.removeVariantConfig(variant._id, oldConfigName) - }) - } - } -} diff --git a/src/tv2_offtube_showstyle/migrations/index.ts b/src/tv2_offtube_showstyle/migrations/index.ts index c5e8fd75..ac39bdec 100644 --- a/src/tv2_offtube_showstyle/migrations/index.ts +++ b/src/tv2_offtube_showstyle/migrations/index.ts @@ -20,7 +20,7 @@ import { renameBlueprintConfiguration, renameBlueprintsConfigurationForAllVariants, renameTableId -} from '../../tv2_afvd_showstyle/migrations/util' +} from '../../tv2-common/migrations/renameConfigurationHelper' import { ATEMModel } from '../../types/atem' import { OfftubeSourceLayer } from '../layers' import { GetDefaultStudioSourcesForOfftube } from './hotkeys' From 7186bc69502e7d94fe149e3a2336313b8bd29354 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Fri, 6 Jan 2023 08:12:52 +0100 Subject: [PATCH 09/86] SOF-1277 Update conditional to allow for different types i.e. booleans --- src/tv2-common/migrations/renameConfigurationHelper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv2-common/migrations/renameConfigurationHelper.ts b/src/tv2-common/migrations/renameConfigurationHelper.ts index 95559368..64b6b7b4 100644 --- a/src/tv2-common/migrations/renameConfigurationHelper.ts +++ b/src/tv2-common/migrations/renameConfigurationHelper.ts @@ -86,7 +86,7 @@ export function renameBlueprintsConfigurationForAllVariants( const allVariants: IBlueprintShowStyleVariant[] = context.getAllVariants() allVariants.forEach((variant: IBlueprintShowStyleVariant) => { const oldConfig = context.getVariantConfig(variant._id, oldConfigName) - if (!oldConfig || Object.keys(oldConfig).length === 0) { + if (oldConfig === undefined) { return } From a0b08dccf67f6a451d48f832217b2d809efa9b7a Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 1 Feb 2023 09:55:31 +0100 Subject: [PATCH 10/86] wip: SOF-1260 refactor most places to use the new context ready to start replacing timeline objects --- src/__mocks__/context.ts | 65 +- src/inews-mixins/__tests__/playlist.spec.ts | 4 +- .../__tests__/EvaluateCueTelemetrics.spec.ts | 44 +- .../__tests__/getshowStyleVariantId.spec.ts | 8 +- .../__tests__/transitionSettings.spec.ts | 6 +- .../actions/CoreActionExecutionContext.ts | 238 ++++++ src/tv2-common/actions/context.ts | 252 +------ src/tv2-common/actions/executeAction.ts | 465 +++++------- src/tv2-common/blueprintConfig.ts | 15 +- src/tv2-common/content/dve.ts | 73 +- src/tv2-common/content/jingle.ts | 14 +- src/tv2-common/content/server.ts | 10 +- src/tv2-common/cues/EvaluateCueRobotCamera.ts | 3 +- src/tv2-common/cues/ekstern.ts | 17 +- src/tv2-common/cues/lyd.ts | 17 +- src/tv2-common/cues/mixMinus.ts | 11 +- src/tv2-common/evaluateCues.ts | 102 +-- src/tv2-common/getSegment.ts | 88 +-- .../helpers/__tests__/sisyfos.spec.ts | 5 +- src/tv2-common/helpers/abPlayback.ts | 111 +-- src/tv2-common/helpers/dsk.ts | 167 ++--- src/tv2-common/helpers/graphics/Graphic.ts | 178 +++++ .../helpers/graphics/InternalGraphic.ts | 126 ---- .../graphics/caspar/HtmlInternalGraphic.ts | 26 + .../htmlPilotGraphicGenerator.spec.ts | 32 +- .../caspar/htmlPilotGraphicGenerator.ts | 123 ++++ .../helpers/graphics/caspar/index.ts | 316 +------- .../helpers/graphics/caspar/util.ts | 195 +++++ .../helpers/graphics/design/index.ts | 21 +- src/tv2-common/helpers/graphics/index.ts | 31 +- .../graphics/internal/InternalGraphic.ts | 145 ++++ .../helpers/graphics/internal/create.ts | 36 + .../helpers/graphics/internal/index.ts | 39 +- src/tv2-common/helpers/graphics/layers.ts | 42 +- src/tv2-common/helpers/graphics/name.ts | 46 +- .../graphics/pilot/PilotGraphicGenerator.ts | 242 ++++++ .../helpers/graphics/pilot/create.ts | 2 +- .../helpers/graphics/pilot/index.ts | 247 +------ src/tv2-common/helpers/graphics/timing.ts | 145 +--- src/tv2-common/helpers/graphics/util.ts | 26 + .../graphics/viz/VizInternalGraphic.ts | 52 ++ .../graphics/viz/VizPilotGraphicGenerator.ts | 125 ++++ src/tv2-common/helpers/graphics/viz/index.ts | 141 +--- src/tv2-common/helpers/index.ts | 2 +- src/tv2-common/helpers/rundownAdLibActions.ts | 10 +- src/tv2-common/helpers/serverResume.ts | 13 +- src/tv2-common/helpers/sisyfos.ts | 18 +- src/tv2-common/index.ts | 5 +- .../inewsConversion/converters/ParseBody.ts | 6 +- .../inewsConversion/converters/ParseCue.ts | 14 +- .../converters/__tests__/body-parser.spec.ts | 35 +- .../converters/__tests__/cue-parser.spec.ts | 35 +- src/tv2-common/jinglePartProperties.ts | 12 +- src/tv2-common/onTimelineGenerate.ts | 41 +- src/tv2-common/parts/effekt.ts | 41 +- src/tv2-common/parts/kam.ts | 15 +- src/tv2-common/parts/server.ts | 20 +- src/tv2-common/pieces/adlibServer.ts | 12 +- src/tv2-common/pieces/telemetric.ts | 3 +- src/tv2-common/segment/context.ts | 17 + src/tv2-common/showstyle/context.ts | 25 + src/tv2-common/showstyle/index.ts | 3 + .../showstyle/timelineEventContext.ts | 11 + src/tv2-common/studio/context.ts | 17 + src/tv2-common/studio/index.ts | 1 + src/tv2-common/transitionSettings.ts | 6 +- src/tv2-common/videoSwitchers/Atem.ts | 119 +++ src/tv2-common/videoSwitchers/TriCaster.ts | 56 ++ .../videoSwitchers/VideoSwitcher.ts | 32 + src/tv2-common/videoSwitchers/index.ts | 4 + src/tv2-common/videoSwitchers/types.ts | 66 ++ .../__tests__/actions.spec.ts | 4 +- .../__tests__/baseline.spec.ts | 4 +- .../__tests__/blueprint.spec.ts | 170 +++-- .../__tests__/breakerConfigDefault.ts | 8 +- .../__tests__/config-manifest.spec.ts | 4 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 9 +- .../__tests__/layers-check.ts | 7 +- .../__tests__/rundown_story_exception.spec.ts | 6 +- .../syncIngestChangesToPartInstance.spec.ts | 4 +- .../__tests__/transitions.spec.ts | 8 +- src/tv2_afvd_showstyle/actions.ts | 2 - src/tv2_afvd_showstyle/getRundown.ts | 690 +++++++++--------- src/tv2_afvd_showstyle/getSegment.ts | 24 +- src/tv2_afvd_showstyle/helpers/config.ts | 18 +- src/tv2_afvd_showstyle/helpers/content/dve.ts | 18 +- .../pieces/__tests__/grafikViz.spec.ts | 58 +- .../helpers/pieces/__tests__/lyd.spec.ts | 134 +--- .../helpers/pieces/__tests__/telefon.spec.ts | 43 +- .../helpers/pieces/adlib.ts | 23 +- .../helpers/pieces/clearGrafiks.ts | 20 +- .../helpers/pieces/design.ts | 14 +- src/tv2_afvd_showstyle/helpers/pieces/dve.ts | 20 +- .../helpers/pieces/ekstern.ts | 15 +- .../helpers/pieces/evaluateCues.ts | 10 +- .../helpers/pieces/graphic.ts | 18 +- .../helpers/pieces/graphicBackgroundLoop.ts | 16 +- .../helpers/pieces/graphicPilot.ts | 98 +-- .../helpers/pieces/jingle.ts | 34 +- .../helpers/pieces/routing.ts | 24 +- .../helpers/pieces/showLifecycle.ts | 4 +- .../helpers/pieces/telefon.ts | 21 +- src/tv2_afvd_showstyle/helpers/studio.ts | 15 - src/tv2_afvd_showstyle/index.ts | 4 +- src/tv2_afvd_showstyle/parts/cueonly.ts | 99 --- src/tv2_afvd_showstyle/parts/effekt.ts | 11 +- src/tv2_afvd_showstyle/parts/evs.ts | 23 +- src/tv2_afvd_showstyle/parts/grafik.ts | 22 +- src/tv2_afvd_showstyle/parts/intro.ts | 26 +- src/tv2_afvd_showstyle/parts/kam.ts | 24 +- src/tv2_afvd_showstyle/parts/live.ts | 15 +- src/tv2_afvd_showstyle/parts/server.ts | 19 +- src/tv2_afvd_showstyle/parts/teknik.ts | 13 +- src/tv2_afvd_showstyle/parts/unknown.ts | 18 +- .../postProcessTimelineObjects.ts | 27 +- .../__tests__/config-manifest.spec.ts | 2 + .../__tests__/graphics.spec.ts | 119 ++- src/tv2_afvd_studio/config-manifests.ts | 10 + src/tv2_afvd_studio/getBaseline.ts | 16 +- src/tv2_afvd_studio/helpers/config.ts | 15 +- src/tv2_afvd_studio/index.ts | 4 +- .../migrations/mappings-defaults.ts | 4 +- src/tv2_afvd_studio/onTimelineGenerate.ts | 36 +- .../__tests__/actions.spec.ts | 4 +- src/tv2_offtube_showstyle/actions.ts | 2 - .../content/OfftubeDVEContent.ts | 18 +- .../cues/OfftubeAdlib.ts | 18 +- src/tv2_offtube_showstyle/cues/OfftubeDVE.ts | 28 +- .../cues/OfftubeEkstern.ts | 20 +- .../cues/OfftubeGraphicBackgroundLoop.ts | 5 +- .../cues/OfftubeGraphicDesign.ts | 16 +- .../cues/OfftubeGraphics.ts | 58 +- .../cues/OfftubeJingle.ts | 38 +- .../cues/OfftubePgmClean.ts | 12 +- src/tv2_offtube_showstyle/getRundown.ts | 65 +- src/tv2_offtube_showstyle/getSegment.ts | 16 +- .../helpers/EvaluateCues.ts | 18 +- src/tv2_offtube_showstyle/helpers/config.ts | 12 +- src/tv2_offtube_showstyle/index.ts | 4 +- .../onTimelineGenerate.ts | 38 +- src/tv2_offtube_showstyle/parts/OfftubeDVE.ts | 13 +- .../parts/OfftubeEffekt.ts | 11 +- .../parts/OfftubeGrafik.ts | 21 +- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 22 +- .../parts/OfftubeServer.ts | 25 +- .../parts/OfftubeUnknown.ts | 16 +- .../postProcessTimelineObjects.ts | 19 +- .../__tests__/config-manifest.spec.ts | 2 + src/tv2_offtube_studio/config-manifests.ts | 10 + src/tv2_offtube_studio/helpers/config.ts | 2 +- src/tv2_offtube_studio/index.ts | 4 +- 151 files changed, 3494 insertions(+), 3763 deletions(-) create mode 100644 src/tv2-common/actions/CoreActionExecutionContext.ts create mode 100644 src/tv2-common/helpers/graphics/Graphic.ts delete mode 100644 src/tv2-common/helpers/graphics/InternalGraphic.ts create mode 100644 src/tv2-common/helpers/graphics/caspar/HtmlInternalGraphic.ts create mode 100644 src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts create mode 100644 src/tv2-common/helpers/graphics/caspar/util.ts create mode 100644 src/tv2-common/helpers/graphics/internal/InternalGraphic.ts create mode 100644 src/tv2-common/helpers/graphics/internal/create.ts create mode 100644 src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts create mode 100644 src/tv2-common/helpers/graphics/util.ts create mode 100644 src/tv2-common/helpers/graphics/viz/VizInternalGraphic.ts create mode 100644 src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts create mode 100644 src/tv2-common/segment/context.ts create mode 100644 src/tv2-common/showstyle/context.ts create mode 100644 src/tv2-common/showstyle/index.ts create mode 100644 src/tv2-common/showstyle/timelineEventContext.ts create mode 100644 src/tv2-common/studio/context.ts create mode 100644 src/tv2-common/studio/index.ts create mode 100644 src/tv2-common/videoSwitchers/Atem.ts create mode 100644 src/tv2-common/videoSwitchers/TriCaster.ts create mode 100644 src/tv2-common/videoSwitchers/VideoSwitcher.ts create mode 100644 src/tv2-common/videoSwitchers/index.ts create mode 100644 src/tv2-common/videoSwitchers/types.ts delete mode 100644 src/tv2_afvd_showstyle/helpers/studio.ts delete mode 100644 src/tv2_afvd_showstyle/parts/cueonly.ts diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index 576355bd..79a15ff5 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -27,13 +27,27 @@ import { PackageInfo, PieceLifespan, PlaylistTimingType, - Time + Time, + TSR } from 'blueprints-integration' -import { ITV2ActionExecutionContext, PieceMetaData } from 'tv2-common' +import { + AuxProps, + DskProps, + ExtendedSegmentContext, + ITV2ActionExecutionContext, + MixEffectProps, + PieceMetaData, + VideoSwitcher, + VideoSwitcherImpl +} from 'tv2-common' import { NoteType } from 'tv2-constants' import { defaultShowStyleConfig, defaultStudioConfig } from '../tv2_afvd_showstyle/__tests__/configs' -import { parseConfig as parseShowStyleConfigAFVD } from '../tv2_afvd_showstyle/helpers/config' -import { parseConfig as parseStudioConfigAFVD, StudioConfig } from '../tv2_afvd_studio/helpers/config' +import { + GalleryBlueprintConfig, + GalleryShowStyleConfig, + preprocessConfig as parseShowStyleConfigAFVD +} from '../tv2_afvd_showstyle/helpers/config' +import { preprocessConfig as parseStudioConfigAFVD, StudioConfig } from '../tv2_afvd_studio/helpers/config' import mappingsDefaultsAFVD from '../tv2_afvd_studio/migrations/mappings-defaults' export function getHash(str: string): string { @@ -44,7 +58,7 @@ export function getHash(str: string): string { .replace(/[\+\/\=]/gi, '_') // remove +/= from strings, because they cause troubles } -// tslint:disable-next-line: max-classes-per-file +// tslint:disable: max-classes-per-file export class CommonContext implements ICommonContext { protected savedNotes: PartNote[] = [] protected notesRundownId?: string @@ -104,7 +118,6 @@ export class CommonContext implements ICommonContext { } } -// tslint:disable-next-line: max-classes-per-file export class UserNotesContext extends CommonContext implements IUserNotesContext { constructor(contextName: string, rundownId?: string, segmentId?: string, partId?: string) { super(contextName, rundownId, segmentId, partId) @@ -122,7 +135,6 @@ export class UserNotesContext extends CommonContext implements IUserNotesContext } } -// tslint:disable-next-line: max-classes-per-file export class StudioContext extends CommonContext implements IStudioContext { public studioId: string = 'studio0' public studioConfig: { [key: string]: ConfigItemValue } = {} @@ -155,7 +167,6 @@ export class StudioContext extends CommonContext implements IStudioContext { } } -// tslint:disable-next-line: max-classes-per-file export class ShowStyleContext extends StudioContext implements IShowStyleContext, IPackageInfoContext { public studioConfig: { [key: string]: ConfigItemValue } = {} public showStyleConfig: { [key: string]: ConfigItemValue } = {} @@ -189,7 +200,6 @@ export class ShowStyleContext extends StudioContext implements IShowStyleContext } } -// tslint:disable-next-line: max-classes-per-file export class ShowStyleUserContext extends ShowStyleContext implements IUserNotesContext { public notifyUserError(message: string, _params?: { [key: string]: any }): void { this.pushNote(NoteType.NOTIFY_USER_ERROR, message) @@ -203,7 +213,6 @@ export class ShowStyleUserContext extends ShowStyleContext implements IUserNotes } } -// tslint:disable-next-line: max-classes-per-file export class GetRundownContext extends ShowStyleUserContext implements IGetRundownContext { public async getCurrentPlaylist(): Promise | undefined> { return undefined @@ -218,7 +227,6 @@ export class GetRundownContext extends ShowStyleUserContext implements IGetRundo } } -// tslint:disable-next-line: max-classes-per-file export class RundownContext extends ShowStyleContext implements IRundownContext { public readonly rundownId: string = 'rundown0' public readonly rundown: Readonly @@ -246,7 +254,6 @@ export class RundownContext extends ShowStyleContext implements IRundownContext } } -// tslint:disable-next-line: max-classes-per-file export class RundownUserContext extends RundownContext implements IRundownUserContext { public notifyUserError(message: string, _params?: { [key: string]: any }): void { this.pushNote(NoteType.NOTIFY_USER_ERROR, message) @@ -260,7 +267,6 @@ export class RundownUserContext extends RundownContext implements IRundownUserCo } } -// tslint:disable-next-line: max-classes-per-file export class SegmentUserContext extends RundownContext implements ISegmentUserContext { constructor( contextName: string, @@ -300,7 +306,6 @@ export class SegmentUserContext extends RundownContext implements ISegmentUserCo } } -// tslint:disable-next-line: max-classes-per-file export class SyncIngestUpdateToPartInstanceContext extends RundownUserContext implements ISyncIngestUpdateToPartInstanceContext { public syncedPieceInstances: string[] = [] @@ -405,7 +410,6 @@ export class SyncIngestUpdateToPartInstanceContext extends RundownUserContext } } -// tslint:disable-next-line: max-classes-per-file export class ActionExecutionContext extends ShowStyleUserContext implements ITV2ActionExecutionContext { public currentPart: IBlueprintPartInstance public currentPieceInstances: Array> @@ -637,15 +641,38 @@ export interface PartNote { message: string } -export function makeMockAFVDContext(studioConfigOverrides?: Partial) { - const mockContext = new SegmentUserContext( +// @ts-ignore +class MockVideoSwitcher implements VideoSwitcher { + public getMixEffectTimelineObject = (properties: MixEffectProps) => (properties as any) as TSR.TSRTimelineObj + public getDskTimelineObjects = (properties: DskProps) => ([properties] as any) as TSR.TSRTimelineObj[] + public getAuxTimelineObject = (properties: AuxProps) => (properties as any) as TSR.TSRTimelineObj +} + +interface ConfigOverrides { + studioConfig?: Partial + showStyleConfig?: Partial +} + +export function makeMockCoreGalleryContext(overrides?: ConfigOverrides) { + const mockCoreContext = new SegmentUserContext( 'test', mappingsDefaultsAFVD, parseStudioConfigAFVD, parseShowStyleConfigAFVD ) - mockContext.studioConfig = { ...defaultStudioConfig, ...studioConfigOverrides } as any - mockContext.showStyleConfig = defaultShowStyleConfig as any + mockCoreContext.studioConfig = { ...defaultStudioConfig, ...overrides?.studioConfig } as any + mockCoreContext.showStyleConfig = { ...defaultShowStyleConfig, ...overrides?.showStyleConfig } as any + return mockCoreContext +} +export function makeMockGalleryContext(overrides?: ConfigOverrides) { + const mockCoreContext = makeMockCoreGalleryContext(overrides) + const config = { ...(mockCoreContext.getStudioConfig() as any), ...(mockCoreContext.getShowStyleConfig() as any) } + const mockContext: ExtendedSegmentContext = { + core: mockCoreContext, + // @todo: this is awful, fix it perhaps by replacing defaultShowStyleConfig and defaultStudioConfig with preparsed config?! + config, + videoSwitcher: VideoSwitcherImpl.getVideoSwitcher(config) // new MockVideoSwitcher() + } return mockContext } diff --git a/src/inews-mixins/__tests__/playlist.spec.ts b/src/inews-mixins/__tests__/playlist.spec.ts index fb4427b4..f341807d 100644 --- a/src/inews-mixins/__tests__/playlist.spec.ts +++ b/src/inews-mixins/__tests__/playlist.spec.ts @@ -7,8 +7,8 @@ import { } from 'blueprints-integration' import { getRundownWithBackTime } from 'inews-mixins' import { ShowStyleUserContext } from '../../__mocks__/context' -import { parseConfig as parseShowStyleConfig } from '../../tv2_afvd_showstyle/helpers/config' -import { parseConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' +import { preprocessConfig as parseShowStyleConfig } from '../../tv2_afvd_showstyle/helpers/config' +import { preprocessConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' import { makeSegmentWithTime } from './rundownDuration.spec' diff --git a/src/tv2-common/__tests__/EvaluateCueTelemetrics.spec.ts b/src/tv2-common/__tests__/EvaluateCueTelemetrics.spec.ts index 2872926e..76953e1c 100644 --- a/src/tv2-common/__tests__/EvaluateCueTelemetrics.spec.ts +++ b/src/tv2-common/__tests__/EvaluateCueTelemetrics.spec.ts @@ -1,20 +1,14 @@ -import { IBlueprintPiece, IShowStyleUserContext, PieceLifespan, TSR } from 'blueprints-integration' +import { IBlueprintPiece, PieceLifespan, TSR } from 'blueprints-integration' import { CueType, RobotCameraLayer, SharedOutputLayers, SharedSourceLayers } from '../../tv2-constants' import { EvaluateCueRobotCamera } from '../cues/EvaluateCueRobotCamera' import { CueDefinitionRobotCamera } from '../inewsConversion' describe('EvaluateCueRobotCamera', () => { - let context: IShowStyleUserContext - - beforeEach(() => { - context = ({} as unknown) as IShowStyleUserContext - }) - it('adds a Robot Camera piece', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition() const pieces: IBlueprintPiece[] = [] - EvaluateCueRobotCamera(context, cueDefinition, pieces, '') + EvaluateCueRobotCamera(cueDefinition, pieces, '') expect(pieces).toHaveLength(1) }) @@ -35,7 +29,7 @@ describe('EvaluateCueRobotCamera', () => { const externalId: string = 'someExternalId' const pieces: IBlueprintPiece[] = [] - EvaluateCueRobotCamera(context, cueDefinition, pieces, externalId) + EvaluateCueRobotCamera(cueDefinition, pieces, externalId) expect(pieces[0].externalId).toEqual(externalId) }) @@ -44,7 +38,7 @@ describe('EvaluateCueRobotCamera', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition() const pieces: IBlueprintPiece[] = [] - EvaluateCueRobotCamera(context, cueDefinition, pieces, '') + EvaluateCueRobotCamera(cueDefinition, pieces, '') expect(pieces[0].lifespan).toEqual(PieceLifespan.WithinPart) }) @@ -53,7 +47,7 @@ describe('EvaluateCueRobotCamera', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition() const pieces: IBlueprintPiece[] = [] - EvaluateCueRobotCamera(context, cueDefinition, pieces, '') + EvaluateCueRobotCamera(cueDefinition, pieces, '') expect(pieces[0].content.timelineObjects).toHaveLength(1) const result = pieces[0].content.timelineObjects[0] @@ -65,7 +59,7 @@ describe('EvaluateCueRobotCamera', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition() const pieces: IBlueprintPiece[] = [] - EvaluateCueRobotCamera(context, cueDefinition, pieces, '') + EvaluateCueRobotCamera(cueDefinition, pieces, '') expect((pieces[0].content.timelineObjects[0].enable as { start: number }).start).toEqual(0) }) @@ -74,7 +68,7 @@ describe('EvaluateCueRobotCamera', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition() const pieces: IBlueprintPiece[] = [] - EvaluateCueRobotCamera(context, cueDefinition, pieces, '') + EvaluateCueRobotCamera(cueDefinition, pieces, '') expect(pieces[0].sourceLayerId).toEqual(SharedSourceLayers.RobotCamera) }) @@ -83,7 +77,7 @@ describe('EvaluateCueRobotCamera', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition() const pieces: IBlueprintPiece[] = [] - EvaluateCueRobotCamera(context, cueDefinition, pieces, '') + EvaluateCueRobotCamera(cueDefinition, pieces, '') expect(pieces[0].outputLayerId).toEqual(SharedOutputLayers.SEC) }) @@ -96,7 +90,7 @@ describe('EvaluateCueRobotCamera', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition(preset) const pieces: IBlueprintPiece[] = [] - EvaluateCueRobotCamera(context, cueDefinition, pieces, '') + EvaluateCueRobotCamera(cueDefinition, pieces, '') const result: IBlueprintPiece = pieces[0] expect(result.name).toEqual(`Robot[${preset}]`) @@ -114,7 +108,7 @@ describe('EvaluateCueRobotCamera', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition(presetShot) const pieces: IBlueprintPiece[] = [] - EvaluateCueRobotCamera(context, cueDefinition, pieces, '') + EvaluateCueRobotCamera(cueDefinition, pieces, '') const result: TSR.TimelineObjTelemetrics = pieces[0].content.timelineObjects[0] as TSR.TimelineObjTelemetrics expect(result.content.presetShotIdentifiers).toEqual([presetShot]) @@ -132,7 +126,7 @@ describe('EvaluateCueRobotCamera', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition(1, startTimeInSeconds) const pieces: IBlueprintPiece[] = [] - EvaluateCueRobotCamera(context, cueDefinition, pieces, '') + EvaluateCueRobotCamera(cueDefinition, pieces, '') const result: IBlueprintPiece = pieces[0] expect(result.enable.start).toEqual(startTimeInSeconds * 1000) @@ -146,7 +140,7 @@ describe('EvaluateCueRobotCamera', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition(1) const pieces: IBlueprintPiece[] = [] - EvaluateCueRobotCamera(context, cueDefinition, pieces, '') + EvaluateCueRobotCamera(cueDefinition, pieces, '') const result: IBlueprintPiece = pieces[0] expect(result.enable.duration).toEqual(100) @@ -156,7 +150,7 @@ describe('EvaluateCueRobotCamera', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition() const pieces: IBlueprintPiece[] = [createRobotCameraBlueprintPiece(SharedSourceLayers.PgmDesign)] - EvaluateCueRobotCamera(context, cueDefinition, pieces, 'someOtherExternalId') + EvaluateCueRobotCamera(cueDefinition, pieces, 'someOtherExternalId') expect(pieces.length).toEqual(2) }) @@ -185,7 +179,7 @@ describe('EvaluateCueRobotCamera', () => { existingPiece.content.timelineObjects.push(createTelemetricsTimelineObject(2)) const pieces: IBlueprintPiece[] = [existingPiece] - EvaluateCueRobotCamera(context, cueDefinition, pieces, 'randomExternalId') + EvaluateCueRobotCamera(cueDefinition, pieces, 'randomExternalId') expect(pieces).toHaveLength(2) }) @@ -215,7 +209,7 @@ describe('EvaluateCueRobotCamera', () => { existingPiece.content.timelineObjects.push(createTelemetricsTimelineObject()) const pieces: IBlueprintPiece[] = [existingPiece] - EvaluateCueRobotCamera(context, cueDefinition, pieces, 'randomExternalId') + EvaluateCueRobotCamera(cueDefinition, pieces, 'randomExternalId') expect(pieces[0].content.timelineObjects).toHaveLength(1) }) @@ -231,7 +225,7 @@ describe('EvaluateCueRobotCamera', () => { existingPiece.content.timelineObjects.push(createTelemetricsTimelineObject(1)) const pieces: IBlueprintPiece[] = [existingPiece] - EvaluateCueRobotCamera(context, cueDefinition, pieces, 'randomExternalId') + EvaluateCueRobotCamera(cueDefinition, pieces, 'randomExternalId') const timelineObject: TSR.TimelineObjTelemetrics = pieces[0].content .timelineObjects[0] as TSR.TimelineObjTelemetrics @@ -246,7 +240,7 @@ describe('EvaluateCueRobotCamera', () => { existingPiece.content.timelineObjects.push(createTelemetricsTimelineObject(1)) const pieces: IBlueprintPiece[] = [existingPiece] - EvaluateCueRobotCamera(context, cueDefinition, pieces, 'randomExternalId') + EvaluateCueRobotCamera(cueDefinition, pieces, 'randomExternalId') const timelineObject: TSR.TimelineObjTelemetrics = pieces[0].content .timelineObjects[0] as TSR.TimelineObjTelemetrics @@ -261,7 +255,7 @@ describe('EvaluateCueRobotCamera', () => { existingPiece.content.timelineObjects.push(createTelemetricsTimelineObject(1)) const pieces: IBlueprintPiece[] = [existingPiece] - EvaluateCueRobotCamera(context, cueDefinition, pieces, 'randomExternalId') + EvaluateCueRobotCamera(cueDefinition, pieces, 'randomExternalId') expect(pieces).toHaveLength(1) }) @@ -274,7 +268,7 @@ describe('EvaluateCueRobotCamera', () => { existingPiece.content.timelineObjects.push(createTelemetricsTimelineObject(1)) const pieces: IBlueprintPiece[] = [existingPiece] - EvaluateCueRobotCamera(context, cueDefinition, pieces, 'randomExternalId') + EvaluateCueRobotCamera(cueDefinition, pieces, 'randomExternalId') expect(existingPiece.name).toEqual('Robot[1,2]') }) diff --git a/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts b/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts index 6aa270c0..7c6f12d8 100644 --- a/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts +++ b/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts @@ -1,5 +1,5 @@ -import { IBlueprintShowStyleVariant, IngestRundown, IStudioUserContext } from 'blueprints-integration' -import { makeMockAFVDContext } from '../../__mocks__/context' +import { IBlueprintShowStyleVariant, IngestRundown } from 'blueprints-integration' +import { makeMockCoreGalleryContext } from '../../__mocks__/context' import { getShowStyleVariantId } from '../getShowStyleVariantId' describe('getShowStyleVariantId', () => { @@ -24,8 +24,8 @@ describe('getShowStyleVariantId', () => { } } - function getMockContext(): IStudioUserContext { - return makeMockAFVDContext() + function getMockContext() { + return makeMockCoreGalleryContext() } function getShowStyleVariants(variantNames?: string[]): IBlueprintShowStyleVariant[] { diff --git a/src/tv2-common/__tests__/transitionSettings.spec.ts b/src/tv2-common/__tests__/transitionSettings.spec.ts index d46184a0..8278fac1 100644 --- a/src/tv2-common/__tests__/transitionSettings.spec.ts +++ b/src/tv2-common/__tests__/transitionSettings.spec.ts @@ -1,17 +1,17 @@ import { TSR } from 'blueprints-integration' import { PartType } from '../../tv2-constants' import { AtemSourceIndex } from '../../types/atem' -import { TV2BlueprintConfig, TV2BlueprintConfigBase, TV2StudioConfigBase } from '../blueprintConfig' +import { TV2BlueprintConfigBase, TV2ShowStyleConfig, TV2StudioConfigBase } from '../blueprintConfig' import { PartDefinition, PartTransition } from '../inewsConversion' import { TransitionSettings } from '../transitionSettings' const DURATION: number = 50 describe('transitionsSettingsSuite', () => { - let mockConfig: TV2BlueprintConfig + let mockConfig: TV2ShowStyleConfig beforeEach(() => { - mockConfig = ({} as unknown) as TV2BlueprintConfig + mockConfig = ({} as unknown) as TV2ShowStyleConfig }) describe('TransitionSettings', () => { diff --git a/src/tv2-common/actions/CoreActionExecutionContext.ts b/src/tv2-common/actions/CoreActionExecutionContext.ts new file mode 100644 index 00000000..a0cb8fd3 --- /dev/null +++ b/src/tv2-common/actions/CoreActionExecutionContext.ts @@ -0,0 +1,238 @@ +import { + BlueprintMappings, + IActionExecutionContext, + IBlueprintMutatablePart, + IBlueprintPart, + IBlueprintPartInstance, + IBlueprintPiece, + IBlueprintPieceDB, + IBlueprintPieceInstance, + IBlueprintResolvedPieceInstance, + PackageInfo, + Time +} from 'blueprints-integration' +import { literal, PartMetaData, PieceMetaData } from 'tv2-common' +import { ITV2ActionExecutionContext } from './context' + +export class CoreActionExecutionContext implements ITV2ActionExecutionContext { + public studioId: string + public isTV2Context: true = true + + private modifiedParts: Set<'current' | 'next'> = new Set() + + constructor(readonly core: IActionExecutionContext) { + this.studioId = core.studioId + } + + public async getPartInstance(part: 'current' | 'next'): Promise | undefined> { + return this.core.getPartInstance(part) + } + + public async getPieceInstances(part: 'current' | 'next'): Promise>> { + return this.core.getPieceInstances(part) as Promise>> + } + + public async getResolvedPieceInstances( + part: 'current' | 'next' + ): Promise>> { + return this.core.getResolvedPieceInstances(part) as Promise>> + } + + public async findLastPieceOnLayer( + sourceLayerId: string | string[], + options?: { + excludeCurrentPart?: boolean + originalOnly?: boolean + pieceMetaDataFilter?: any + } + ): Promise | undefined> { + return this.core.findLastPieceOnLayer(sourceLayerId, options) as Promise< + IBlueprintPieceInstance | undefined + > + } + + public async findLastScriptedPieceOnLayer( + sourceLayerId: string | string[], + options?: { excludeCurrentPart?: boolean; pieceMetaDataFilter?: any } + ): Promise | undefined> { + return this.core.findLastScriptedPieceOnLayer(sourceLayerId, options) as Promise< + IBlueprintPiece | undefined + > + } + + public async getPartInstanceForPreviousPiece( + piece: IBlueprintPieceInstance + ): Promise> { + return this.core.getPartInstanceForPreviousPiece(piece) + } + + public async getPartForPreviousPiece( + piece: IBlueprintPieceDB + ): Promise | undefined> { + return this.core.getPartForPreviousPiece(piece) + } + + public async stopPiecesOnLayers(sourceLayerIds: string[], timeOffset?: number): Promise { + return this.core.stopPiecesOnLayers(sourceLayerIds, timeOffset) + } + + public async stopPieceInstances(pieceInstanceIds: string[], timeOffset?: number): Promise { + return this.core.stopPieceInstances(pieceInstanceIds, timeOffset) + } + + public async takeAfterExecuteAction(take: boolean): Promise { + return this.core.takeAfterExecuteAction(take) + } + + public notifyUserError(message: string, params?: { [key: string]: any }): void { + return this.core.notifyUserError(message, params) + } + + public notifyUserWarning(message: string, params?: { [key: string]: any }): void { + return this.core.notifyUserWarning(message, params) + } + + public getHashId(originString: string, originIsNotUnique?: boolean | undefined) { + return this.core.getHashId(originString, originIsNotUnique) + } + + public unhashId(hash: string) { + return this.core.unhashId(hash) + } + + public logDebug(message: string) { + return this.core.logDebug(message) + } + + public logInfo(message: string) { + return this.core.logInfo(message) + } + + public logWarning(message: string) { + return this.core.logWarning(message) + } + + public logError(message: string) { + return this.core.logError(message) + } + + public getShowStyleConfig(): unknown { + return this.core.getShowStyleConfig() + } + + public getShowStyleConfigRef(configKey: string): string { + return this.core.getShowStyleConfigRef(configKey) + } + + public getStudioConfig(): unknown { + return this.core.getStudioConfig() + } + + public getStudioConfigRef(configKey: string): string { + return this.core.getShowStyleConfigRef(configKey) + } + + public getStudioMappings(): Readonly { + return this.core.getStudioMappings() + } + + public getPackageInfo(packageId: string): readonly PackageInfo.Any[] { + return this.core.getPackageInfo(packageId) + } + + public async hackGetMediaObjectDuration(mediaId: string): Promise { + return this.core.hackGetMediaObjectDuration(mediaId) + } + + public getCurrentTime(): number { + return this.core.getCurrentTime() + } + + public async moveNextPart(partDelta: number, segmentDelta: number): Promise { + this.modifiedParts.add('next') + + return this.core.moveNextPart(partDelta, segmentDelta) + } + + public async queuePart( + rawPart: IBlueprintPart, + rawPieces: Array> + ): Promise { + this.modifiedParts.add('next') + + return this.core.queuePart(rawPart, rawPieces) + } + + public async removePieceInstances(part: 'next', pieceInstanceIds: string[]): Promise { + this.modifiedParts.add('next') + + return this.core.removePieceInstances(part, pieceInstanceIds) + } + + public async insertPiece( + part: 'current' | 'next', + piece: IBlueprintPiece + ): Promise> { + this.modifiedParts.add(part) + return this.core.insertPiece(part, piece) as Promise> + } + + public async updatePartInstance( + part: 'current' | 'next', + props: Partial + ): Promise { + this.modifiedParts.add(part) + return this.core.updatePartInstance(part, props) + } + + public async updatePieceInstance( + pieceInstanceId: string, + piece: Partial> + ): Promise> { + const currentPieceInstances = await this.core.getPieceInstances('current') + if (currentPieceInstances.map(p => p._id).includes(pieceInstanceId)) { + this.modifiedParts.add('current') + } else { + const nextPieceInstances = await this.core.getPieceInstances('next') + if (nextPieceInstances.map(p => p._id).includes(pieceInstanceId)) { + this.modifiedParts.add('next') + } + } + + // Regardless of above, let core handle errors + return this.core.updatePieceInstance(pieceInstanceId, piece) as Promise> + } + + /** + * Call this when the context is finished with. + * After this, no further calls can be made. + */ + public async afterActions() { + for (const part of this.modifiedParts) { + await this.markPartAsModifiedByAction(part) + } + } + + public blockTakeUntil(time: Time | null): Promise { + return this.core.blockTakeUntil(time) + } + + public notifyUserInfo(message: string, params?: { [p: string]: any }): void { + this.core.notifyUserInfo(message, params) + } + + private async markPartAsModifiedByAction(part: 'current' | 'next') { + const partInstance = await this.core.getPartInstance(part) + if (!partInstance) { + return + } + + if (!partInstance.part.metaData) { + partInstance.part.metaData = {} + } + + await this.core.updatePartInstance(part, { + metaData: literal({ ...(partInstance.part.metaData as PartMetaData), dirty: true }) + }) + } +} diff --git a/src/tv2-common/actions/context.ts b/src/tv2-common/actions/context.ts index af83548d..e0309c98 100644 --- a/src/tv2-common/actions/context.ts +++ b/src/tv2-common/actions/context.ts @@ -1,5 +1,4 @@ import { - BlueprintMappings, IActionExecutionContext, IBlueprintMutatablePart, IBlueprintPart, @@ -7,11 +6,10 @@ import { IBlueprintPiece, IBlueprintPieceDB, IBlueprintPieceInstance, - IBlueprintResolvedPieceInstance, - PackageInfo, - Time + IBlueprintResolvedPieceInstance } from 'blueprints-integration' -import { literal, PartMetaData, PieceMetaData } from 'tv2-common' +import { ExtendedShowStyleContextImpl, PieceMetaData, TV2ShowStyleConfig } from 'tv2-common' +import { CoreActionExecutionContext } from './CoreActionExecutionContext' export interface ITV2ActionExecutionContext extends IActionExecutionContext { /** To prompt type errors for wrong context type */ @@ -49,241 +47,21 @@ export interface ITV2ActionExecutionContext extends IActionExecutionContext { updatePartInstance(part: 'current' | 'next', props: Partial): Promise } -class TV2ActionExecutionContext implements ITV2ActionExecutionContext { - public studioId: string - public isTV2Context: true = true - - private coreContext: IActionExecutionContext - - private modifiedParts: Set<'current' | 'next'> = new Set() - - constructor(coreContext: IActionExecutionContext) { - this.coreContext = coreContext - this.studioId = coreContext.studioId - } - - public async getPartInstance(part: 'current' | 'next'): Promise | undefined> { - return this.coreContext.getPartInstance(part) - } - - public async getPieceInstances(part: 'current' | 'next'): Promise>> { - return this.coreContext.getPieceInstances(part) as Promise>> - } - - public async getResolvedPieceInstances( - part: 'current' | 'next' - ): Promise>> { - return this.coreContext.getResolvedPieceInstances(part) as Promise< - Array> - > - } - - public async findLastPieceOnLayer( - sourceLayerId: string | string[], - options?: { - excludeCurrentPart?: boolean - originalOnly?: boolean - pieceMetaDataFilter?: any - } - ): Promise | undefined> { - return this.coreContext.findLastPieceOnLayer(sourceLayerId, options) as Promise< - IBlueprintPieceInstance | undefined - > - } - - public async findLastScriptedPieceOnLayer( - sourceLayerId: string | string[], - options?: { excludeCurrentPart?: boolean; pieceMetaDataFilter?: any } - ): Promise | undefined> { - return this.coreContext.findLastScriptedPieceOnLayer(sourceLayerId, options) as Promise< - IBlueprintPiece | undefined - > - } - - public async getPartInstanceForPreviousPiece( - piece: IBlueprintPieceInstance - ): Promise> { - return this.coreContext.getPartInstanceForPreviousPiece(piece) - } - - public async getPartForPreviousPiece( - piece: IBlueprintPieceDB - ): Promise | undefined> { - return this.coreContext.getPartForPreviousPiece(piece) - } - - public async stopPiecesOnLayers(sourceLayerIds: string[], timeOffset?: number): Promise { - return this.coreContext.stopPiecesOnLayers(sourceLayerIds, timeOffset) - } - - public async stopPieceInstances(pieceInstanceIds: string[], timeOffset?: number): Promise { - return this.coreContext.stopPieceInstances(pieceInstanceIds, timeOffset) - } - - public async takeAfterExecuteAction(take: boolean): Promise { - return this.coreContext.takeAfterExecuteAction(take) - } - - public notifyUserError(message: string, params?: { [key: string]: any }): void { - return this.coreContext.notifyUserError(message, params) - } - - public notifyUserWarning(message: string, params?: { [key: string]: any }): void { - return this.coreContext.notifyUserWarning(message, params) - } - - public getHashId(originString: string, originIsNotUnique?: boolean | undefined) { - return this.coreContext.getHashId(originString, originIsNotUnique) - } - - public unhashId(hash: string) { - return this.coreContext.unhashId(hash) - } - - public logDebug(message: string) { - return this.coreContext.logDebug(message) - } - - public logInfo(message: string) { - return this.coreContext.logInfo(message) - } - - public logWarning(message: string) { - return this.coreContext.logWarning(message) - } - - public logError(message: string) { - return this.coreContext.logError(message) - } - - public getShowStyleConfig(): unknown { - return this.coreContext.getShowStyleConfig() - } - - public getShowStyleConfigRef(configKey: string): string { - return this.coreContext.getShowStyleConfigRef(configKey) - } - - public getStudioConfig(): unknown { - return this.coreContext.getStudioConfig() - } - - public getStudioConfigRef(configKey: string): string { - return this.coreContext.getShowStyleConfigRef(configKey) - } - - public getStudioMappings(): Readonly { - return this.coreContext.getStudioMappings() - } - - public getPackageInfo(packageId: string): readonly PackageInfo.Any[] { - return this.coreContext.getPackageInfo(packageId) - } - - public async hackGetMediaObjectDuration(mediaId: string): Promise { - return this.coreContext.hackGetMediaObjectDuration(mediaId) - } - - public getCurrentTime(): number { - return this.coreContext.getCurrentTime() - } - - public async moveNextPart(partDelta: number, segmentDelta: number): Promise { - this.modifiedParts.add('next') - - return this.coreContext.moveNextPart(partDelta, segmentDelta) - } - - public async queuePart( - rawPart: IBlueprintPart, - rawPieces: Array> - ): Promise { - this.modifiedParts.add('next') - - return this.coreContext.queuePart(rawPart, rawPieces) - } - - public async removePieceInstances(part: 'next', pieceInstanceIds: string[]): Promise { - this.modifiedParts.add('next') - - return this.coreContext.removePieceInstances(part, pieceInstanceIds) - } - - public async insertPiece( - part: 'current' | 'next', - piece: IBlueprintPiece - ): Promise> { - this.modifiedParts.add(part) - return this.coreContext.insertPiece(part, piece) as Promise> - } - - public async updatePartInstance( - part: 'current' | 'next', - props: Partial - ): Promise { - this.modifiedParts.add(part) - return this.coreContext.updatePartInstance(part, props) - } - - public async updatePieceInstance( - pieceInstanceId: string, - piece: Partial> - ): Promise> { - const currentPieceInstances = await this.coreContext.getPieceInstances('current') - if (currentPieceInstances.map(p => p._id).includes(pieceInstanceId)) { - this.modifiedParts.add('current') - } else { - const nextPieceInstances = await this.coreContext.getPieceInstances('next') - if (nextPieceInstances.map(p => p._id).includes(pieceInstanceId)) { - this.modifiedParts.add('next') - } - } - - // Regardless of above, let core handle errors - return this.coreContext.updatePieceInstance(pieceInstanceId, piece) as Promise< - IBlueprintPieceInstance - > - } - - /** - * Call this when the context is finished with. - * After this, no further calls can be made. - */ - public async afterActions() { - for (const part of this.modifiedParts) { - await this.markPartAsModifiedByAction(part) - } - } - - public blockTakeUntil(time: Time | null): Promise { - return this.coreContext.blockTakeUntil(time) - } - - public notifyUserInfo(message: string, params?: { [p: string]: any }): void { - this.coreContext.notifyUserInfo(message, params) - } - - private async markPartAsModifiedByAction(part: 'current' | 'next') { - const partInstance = await this.coreContext.getPartInstance(part) - if (!partInstance) { - return - } - - if (!partInstance.part.metaData) { - partInstance.part.metaData = {} - } - - await this.coreContext.updatePartInstance(part, { - metaData: literal({ ...(partInstance.part.metaData as PartMetaData), dirty: true }) - }) +export class ExtendedActionExecutionContext< + BlueprintConfig extends TV2ShowStyleConfig = TV2ShowStyleConfig +> extends ExtendedShowStyleContextImpl { + constructor(readonly core: CoreActionExecutionContext) { + super(core) + this.core = core } } -export async function executeWithContext( +export async function executeWithContext( coreContext: IActionExecutionContext, - func: (context: ITV2ActionExecutionContext) => Promise -) { - const context = new TV2ActionExecutionContext(coreContext) + func: (context: ExtendedActionExecutionContext) => Promise +): Promise { + const coreContextWrapped = new CoreActionExecutionContext(coreContext) + const context = new ExtendedActionExecutionContext(coreContextWrapped) await func(context) - await context.afterActions() + await coreContextWrapped.afterActions() } diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 945a5db5..1c8ea979 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -10,7 +10,6 @@ import { IBlueprintPieceDB, IBlueprintPieceGeneric, IBlueprintPieceInstance, - IShowStyleUserContext, PieceLifespan, SplitsContent, TSR, @@ -19,8 +18,6 @@ import { } from 'blueprints-integration' import { ActionClearGraphics, - ActionCommentatorSelectDVE, - ActionCommentatorSelectFull, ActionCutSourceToBox, ActionCutToCamera, ActionCutToRemote, @@ -41,18 +38,26 @@ import { DVESources, EvaluateCuesOptions, executeWithContext, + ExtendedActionExecutionContext, + ExtendedShowStyleContext, GetDVETemplate, - GetFullGrafikTemplateName, + GetEnableForWall, + getServerPosition, + GetSisyfosTimelineObjForCamera, + GetSisyfosTimelineObjForRemote, GraphicPilot, - ITV2ActionExecutionContext, literal, MakeContentDVE2, MixTransitionSettings, PartDefinition, PieceMetaData, + PilotGeneratorSettings, + PilotGraphicGenerator, + ServerSelectMode, SisyfosPersistMetaData, TimeFromFrames, TimelineBlueprintExt, + TransitionStyle, TV2AdlibAction, TV2BlueprintConfigBase, TV2StudioConfigBase @@ -69,15 +74,6 @@ import { } from 'tv2-constants' import _ = require('underscore') import { EnableServer } from '../content' -import { - GetEnableForWall, - getServerPosition, - GetSisyfosTimelineObjForCamera, - GetSisyfosTimelineObjForRemote, - PilotGeneratorSettings, - PilotGraphicGenerator, - ServerSelectMode -} from '../helpers' import { GetJinglePartPropertiesFromTableValue } from '../jinglePartProperties' import { CreateEffektForPartBase, CreateEffektForPartInner, CreateMixTransitionBlueprintPieceForPart } from '../parts' import { @@ -92,13 +88,7 @@ import { import { createTelemetricsPieceForRobotCamera } from '../pieces/telemetric' import { findSourceInfo } from '../sources' import { assertUnreachable } from '../util' -import { - ActionCommentatorSelectJingle, - ActionRecallLastDVE, - ActionRecallLastLive, - ActionSelectJingle, - ActionTakeWithTransition -} from './actionTypes' +import { ActionSelectJingle, ActionTakeWithTransition } from './actionTypes' const STOPPABLE_GRAPHICS_LAYERS = [ SharedSourceLayers.PgmGraphicsIdent, @@ -117,16 +107,13 @@ export interface ActionExecutionSettings< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase > { - getConfig: (context: IShowStyleUserContext) => ShowStyleConfig postProcessPieceTimelineObjects: ( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, piece: IBlueprintPieceGeneric, isAdlib: boolean ) => void EvaluateCues: ( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, part: IBlueprintPart, pieces: IBlueprintPiece[], adLibPieces: IBlueprintAdLibPiece[], @@ -183,7 +170,7 @@ export interface ActionExecutionSettings< SELECTED_ADLIB_LAYERS: string[] } createJingleContent: ( - config: ShowStyleConfig, + context: ExtendedShowStyleContext, file: string, alphaAtStart: number, loadFirstFrame: boolean, @@ -208,7 +195,7 @@ export async function executeAction< userData: ActionUserData, triggerMode?: string ): Promise { - await executeWithContext(coreContext, async context => { + await executeWithContext(coreContext, async context => { const existingTransition = await getExistingTransition(context, settings, 'next') const actionId = actionIdStr as AdlibActionType @@ -230,13 +217,13 @@ export async function executeAction< await executeActionSelectDVELayout(context, settings, actionId, userData as ActionSelectDVELayout) break case AdlibActionType.SELECT_FULL_GRAFIK: - await executeActionSelectFull(context, settings, actionId, userData as ActionSelectFullGrafik) + await executeActionSelectFull(context, settings, userData as ActionSelectFullGrafik) break case AdlibActionType.SELECT_JINGLE: await executeActionSelectJingle(context, settings, actionId, userData as ActionSelectJingle) break case AdlibActionType.CLEAR_GRAPHICS: - await executeActionClearGraphics(context, settings, actionId, userData as ActionClearGraphics) + await executeActionClearGraphics(context, userData as ActionClearGraphics) break case AdlibActionType.CUT_TO_CAMERA: await executeActionCutToCamera(context, settings, actionId, userData as ActionCutToCamera) @@ -248,41 +235,33 @@ export async function executeAction< await executeActionCutSourceToBox(context, settings, actionId, userData as ActionCutSourceToBox) break case AdlibActionType.COMMENTATOR_SELECT_DVE: - await executeActionCommentatorSelectDVE(context, settings, actionId, userData as ActionCommentatorSelectDVE) + await executeActionCommentatorSelectDVE(context, settings) break case AdlibActionType.COMMENTATOR_SELECT_SERVER: - await executeActionCommentatorSelectServer( - context, - settings - ) + await executeActionCommentatorSelectServer(context, settings) break case AdlibActionType.COMMENTATOR_SELECT_FULL: - await executeActionCommentatorSelectFull(context, settings, actionId, userData as ActionCommentatorSelectFull) + await executeActionCommentatorSelectFull(context, settings) break case AdlibActionType.COMMENTATOR_SELECT_JINGLE: - await executeActionCommentatorSelectJingle( - context, - settings, - actionId, - userData as ActionCommentatorSelectJingle - ) + await executeActionCommentatorSelectJingle(context, settings) break case AdlibActionType.TAKE_WITH_TRANSITION: await executeActionTakeWithTransition(context, settings, actionId, userData as ActionTakeWithTransition) break case AdlibActionType.RECALL_LAST_LIVE: - await executeActionRecallLastLive(context, settings, actionId, userData as ActionRecallLastLive) + await executeActionRecallLastLive(context, settings, actionId) break case AdlibActionType.RECALL_LAST_DVE: - await executeActionRecallLastDVE(context, settings, actionId, userData as ActionRecallLastDVE) + await executeActionRecallLastDVE(context, settings, actionId) break case AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS: - await executeActionFadeDownPersistedAudioLevels(context, settings) + await executeActionFadeDownPersistedAudioLevels(context) break case AdlibActionType.CALL_ROBOT_PRESET: { const preset: number = Number(triggerMode) if (Number.isNaN(preset)) { - context.notifyUserWarning(`Calling Robot preset ignored. '${triggerMode}' is not a number`) + context.core.notifyUserWarning(`Calling Robot preset ignored. '${triggerMode}' is not a number`) break } await executeActionCallRobotPreset(context, preset) @@ -318,11 +297,11 @@ async function getExistingTransition< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, part: 'current' | 'next' ): Promise { - const existingTransition = await context + const existingTransition = await context.core .getPieceInstances(part) .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.Effekt)) @@ -388,12 +367,14 @@ function sanitizePieceId(piece: IBlueprintPieceDB): IBlueprintPie } export async function getPiecesToPreserve( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, adlibLayers: string[], ignoreLayers: string[] ): Promise>> { - const currentPartSegmentId = await context.getPartInstance('current').then(partInstance => partInstance?.segmentId) - const nextPartSegmentId = await context.getPartInstance('next').then(partInstance => partInstance?.segmentId) + const currentPartSegmentId = await context.core + .getPartInstance('current') + .then(partInstance => partInstance?.segmentId) + const nextPartSegmentId = await context.core.getPartInstance('next').then(partInstance => partInstance?.segmentId) if (!currentPartSegmentId || !nextPartSegmentId) { return [] @@ -403,7 +384,7 @@ export async function getPiecesToPreserve( return [] } - return context.getPieceInstances('next').then(pieceInstances => { + return context.core.getPieceInstances('next').then(pieceInstances => { return pieceInstances .filter(p => adlibLayers.includes(p.piece.sourceLayerId) && !ignoreLayers.includes(p.piece.sourceLayerId)) .filter(p => !p.infinite?.fromPreviousPart && !p.infinite?.fromPreviousPlayhead) @@ -413,15 +394,15 @@ export async function getPiecesToPreserve( }) } -function generateExternalId(context: ITV2ActionExecutionContext, actionId: string, args: string[]): string { - return `adlib_action_${actionId}_${context.getHashId(args.join('_'), true)}` +function generateExternalId(context: ExtendedActionExecutionContext, actionId: string, args: string[]): string { + return `adlib_action_${actionId}_${context.core.getHashId(args.join('_'), true)}` } async function executeActionSelectServerClip< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionSelectServerClip, @@ -430,19 +411,17 @@ async function executeActionSelectServerClip< ) { const file = userData.file const partDefinition = userData.partDefinition - const config = settings.getConfig(context) const externalId = generateExternalId(context, actionId, [file]) const currentPiece = settings.SelectedAdlibs - ? await context + ? await context.core .getPieceInstances('current') .then(pieceInstances => pieceInstances.find(p => isServerOnPgm(p, settings, userData.voLayer))) : undefined const basePart = await CreatePartServerBase( context, - config, partDefinition, { voLayer: userData.voLayer, @@ -495,39 +474,28 @@ async function executeActionSelectServerClip< part = { ...part, - ...CreateEffektForPartBase(context, config, partDefinition, effektPieces, { + ...CreateEffektForPartBase(context, partDefinition, effektPieces, { sourceLayer: settings.SourceLayers.Effekt, sisyfosLayer: settings.LLayer.Sisyfos.Effekt, casparLayer: settings.LLayer.Caspar.Effekt }) } - settings.EvaluateCues( - context, - config, - basePart.part.part, - grafikPieces, - [], - [], - [], - partDefinition.cues, - partDefinition, - { - excludeAdlibs: true, - selectedCueTypes: [CueType.Graphic] - } - ) + settings.EvaluateCues(context, basePart.part.part, grafikPieces, [], [], [], partDefinition.cues, partDefinition, { + excludeAdlibs: true, + selectedCueTypes: [CueType.Graphic] + }) if (basePart.invalid || !activeServerPiece || !serverDataStore) { - context.notifyUserWarning(`Could not start server clip`) + context.core.notifyUserWarning(`Could not start server clip`) return } if (activeServerPiece.content && activeServerPiece.content.timelineObjects) { - settings.postProcessPieceTimelineObjects(context, config, activeServerPiece, false) + settings.postProcessPieceTimelineObjects(context, activeServerPiece, false) } - await context.queuePart(part, [ + await context.core.queuePart(part, [ activeServerPiece as IBlueprintPiece, // @todo: get rid of these casts serverDataStore as IBlueprintPiece, ...grafikPieces, @@ -541,7 +509,7 @@ async function executeActionSelectServerClip< ]) if (settings.SelectedAdlibs && !currentPiece) { - await context.stopPiecesOnLayers([ + await context.core.stopPiecesOnLayers([ userData.voLayer ? settings.SelectedAdlibs.SourceLayer.VO : settings.SelectedAdlibs.SourceLayer.Server ]) } @@ -575,20 +543,18 @@ async function executeActionSelectDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionSelectDVE ) { const externalId = generateExternalId(context, actionId, [userData.config.template]) - const config = settings.getConfig(context) - const parsedCue: CueDefinitionDVE = userData.config - const rawTemplate = GetDVETemplate(config.showStyle.DVEStyles, parsedCue.template) + const rawTemplate = GetDVETemplate(context.config.showStyle.DVEStyles, parsedCue.template) if (!rawTemplate) { - context.notifyUserWarning(`DVE layout not recognised`) + context.core.notifyUserWarning(`DVE layout not recognised`) return } @@ -599,7 +565,6 @@ async function executeActionSelectDVE< const pieceContent = MakeContentDVE2( context, - config, rawTemplate, graphicsTemplateContent, parsedCue.sources, @@ -635,7 +600,7 @@ async function executeActionSelectDVE< content: { ...pieceContent.content }, - prerollDuration: Number(config.studio.CasparPrerollDuration) || 0, + prerollDuration: Number(context.config.studio.CasparPrerollDuration) || 0, metaData, tags: [ GetTagForDVE(userData.segmentExternalId, parsedCue.template, parsedCue.sources), @@ -648,13 +613,11 @@ async function executeActionSelectDVE< await startNewDVELayout( context, - config, settings, dvePiece, pieceContent.content, metaData, parsedCue.template, - parsedCue.sources, externalId, 'next', 'queue', @@ -666,7 +629,7 @@ async function cutServerToBox< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, newDvePiece: IBlueprintPiece, containedServerBefore?: boolean, @@ -690,7 +653,7 @@ async function cutServerToBox< } if (newDvePiece.content?.timelineObjects) { - const currentServer = await context + const currentServer = await context.core .getPieceInstances('current') .then(currentPieces => currentPieces.find( @@ -701,7 +664,7 @@ async function cutServerToBox< ) if (!currentServer || !currentServer.piece.content?.timelineObjects) { - context.notifyUserWarning(`No server is playing, cannot start DVE`) + context.core.notifyUserWarning(`No server is playing, cannot start DVE`) return newDvePiece } @@ -727,7 +690,7 @@ async function cutServerToBox< !existingCasparObj.metaData || !existingCasparObj.metaData.mediaPlayerSession ) { - context.notifyUserWarning(`Failed to start DVE with server`) + context.core.notifyUserWarning(`Failed to start DVE with server`) return newDvePiece } @@ -750,35 +713,33 @@ async function cutServerToBox< return newDvePiece } -function stopServerMetaData(context: ITV2ActionExecutionContext, metaData: DVEPieceMetaData) { +function stopServerMetaData(context: ExtendedActionExecutionContext, metaData: DVEPieceMetaData) { const length = metaData.serverPlaybackTiming?.length if (metaData.serverPlaybackTiming && length) { - metaData.serverPlaybackTiming[length - 1].end = context.getCurrentTime() + metaData.serverPlaybackTiming[length - 1].end = context.core.getCurrentTime() } } function startServerMetaData( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, metaData: DVEPieceMetaData, modifiesCurrent?: boolean ) { if (!metaData.serverPlaybackTiming) { metaData.serverPlaybackTiming = [] } - metaData.serverPlaybackTiming.push(modifiesCurrent ? { start: context.getCurrentTime() } : {}) + metaData.serverPlaybackTiming.push(modifiesCurrent ? { start: context.core.getCurrentTime() } : {}) } async function executeActionSelectDVELayout< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionSelectDVELayout ) { - const config = settings.getConfig(context) - if (!settings.SourceLayers.DVEAdLib) { return } @@ -792,9 +753,9 @@ async function executeActionSelectDVELayout< const externalId = generateExternalId(context, actionId, [userData.config.DVEName]) - const nextPart = await context.getPartInstance('next') + const nextPart = await context.core.getPartInstance('next') - const nextDVE = (await context + const nextDVE = (await context.core .getPieceInstances('next') .then(nextPieceInstances => nextPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE))) as | IBlueprintPieceInstance @@ -802,8 +763,13 @@ async function executeActionSelectDVELayout< const meta = nextDVE?.piece.metaData - if (!nextPart || !nextDVE || !meta || nextPart.segmentId !== (await context.getPartInstance('current'))?.segmentId) { - const content = MakeContentDVE2(context, config, userData.config, {}, sources, settings.DVEGeneratorOptions) + if ( + !nextPart || + !nextDVE || + !meta || + nextPart.segmentId !== (await context.core.getPartInstance('current'))?.segmentId + ) { + const content = MakeContentDVE2(context, userData.config, {}, sources, settings.DVEGeneratorOptions) if (!content.valid) { return @@ -847,13 +813,11 @@ async function executeActionSelectDVELayout< return startNewDVELayout( context, - config, settings, newDVEPiece, content.content, newMetaData, userData.config.DVEName, - sources, externalId, 'next', 'queue', @@ -869,7 +833,7 @@ async function executeActionSelectDVELayout< } } - const pieceContent = MakeContentDVE2(context, config, userData.config, {}, meta.sources, settings.DVEGeneratorOptions) + const pieceContent = MakeContentDVE2(context, userData.config, {}, meta.sources, settings.DVEGeneratorOptions) let dvePiece: IBlueprintPiece = { ...nextDVE.piece, content: pieceContent.content, @@ -885,13 +849,11 @@ async function executeActionSelectDVELayout< await startNewDVELayout( context, - config, settings, dvePiece, pieceContent.content, newMetaData2, userData.config.DVEName, - sources, externalId, 'next', { @@ -905,20 +867,18 @@ async function startNewDVELayout< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, - config: ShowStyleConfig, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, dvePiece: IBlueprintPiece, pieceContent: WithTimeline, metaData: DVEPieceMetaData, templateName: string, - _sources: CueDefinitionDVE['sources'], externalId: string, part: 'current' | 'next', replacePieceInstancesOrQueue: { activeDVE?: string; dataStore?: string } | 'queue', nextTag: string ) { - settings.postProcessPieceTimelineObjects(context, config, dvePiece, false) + settings.postProcessPieceTimelineObjects(context, dvePiece, false) const dveDataStore: IBlueprintPiece | undefined = settings.SelectedAdlibs.SourceLayer.DVE ? { @@ -956,7 +916,7 @@ async function startNewDVELayout< expectedDuration: 0 } - const currentPieceInstances = await context.getPieceInstances('current') + const currentPieceInstances = await context.core.getPieceInstances('current') // If a DVE is not on air, but a layout is selected, stop the selected layout and replace with the new one. const onAirPiece = currentPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE) @@ -965,10 +925,10 @@ async function startNewDVELayout< currentPieceInstances.find(p => p.piece.sourceLayerId === settings.SelectedAdlibs.SourceLayer.DVE) if (onAirPiece === undefined && dataPiece !== undefined) { - await context.stopPieceInstances([dataPiece._id]) + await context.core.stopPieceInstances([dataPiece._id]) } - dvePiece.prerollDuration = config.studio.CasparPrerollDuration - await context.queuePart(newPart, [ + dvePiece.prerollDuration = context.config.studio.CasparPrerollDuration + await context.core.queuePart(newPart, [ dvePiece, ...(dveDataStore ? [dveDataStore] : []), ...(settings.SelectedAdlibs @@ -980,17 +940,17 @@ async function startNewDVELayout< : []) ]) if (settings.SelectedAdlibs.SourceLayer.DVE) { - await context.stopPiecesOnLayers([settings.SelectedAdlibs.SourceLayer.DVE]) + await context.core.stopPiecesOnLayers([settings.SelectedAdlibs.SourceLayer.DVE]) } } else { if (replacePieceInstancesOrQueue.activeDVE) { - await context.updatePieceInstance(replacePieceInstancesOrQueue.activeDVE, dvePiece) - await context.updatePartInstance(part, { expectedDuration: 0 }) + await context.core.updatePieceInstance(replacePieceInstancesOrQueue.activeDVE, dvePiece) + await context.core.updatePartInstance(part, { expectedDuration: 0 }) if (dveDataStore) { if (replacePieceInstancesOrQueue.dataStore) { - await context.updatePieceInstance(replacePieceInstancesOrQueue.dataStore, dveDataStore) + await context.core.updatePieceInstance(replacePieceInstancesOrQueue.dataStore, dveDataStore) } else { - await context.insertPiece(part, dveDataStore) + await context.core.insertPiece(part, dveDataStore) } } } @@ -1001,27 +961,25 @@ async function executeActionSelectJingle< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionSelectJingle ) { let file = '' - const config = settings.getConfig(context) - - if (!config.showStyle.BreakerConfig) { - context.notifyUserWarning(`Jingles have not been configured`) + if (!context.config.showStyle.BreakerConfig) { + context.core.notifyUserWarning(`Jingles have not been configured`) return } const externalId = generateExternalId(context, actionId, [userData.clip]) - const jingle = config.showStyle.BreakerConfig.find(brkr => + const jingle = context.config.showStyle.BreakerConfig.find(brkr => brkr.BreakerName ? brkr.BreakerName.toString().toUpperCase() === userData.clip.toUpperCase() : false ) if (!jingle) { - context.notifyUserWarning(`Jingle ${userData.clip} is not configured`) + context.core.notifyUserWarning(`Jingle ${userData.clip} is not configured`) return } else { file = jingle.ClipName.toString() @@ -1030,7 +988,7 @@ async function executeActionSelectJingle< const props = GetJinglePartPropertiesFromTableValue(jingle) const pieceContent = settings.createJingleContent( - config, + context, file, jingle.StartAlpha, jingle.LoadFirstFrame, @@ -1047,7 +1005,7 @@ async function executeActionSelectJingle< lifespan: PieceLifespan.WithinPart, outputLayerId: SharedOutputLayers.JINGLE, sourceLayerId: settings.SourceLayers.Effekt, - prerollDuration: config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), + prerollDuration: context.config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), content: pieceContent, tags: [ GetTagForJingle(userData.segmentExternalId, userData.clip), @@ -1057,7 +1015,7 @@ async function executeActionSelectJingle< ] } - settings.postProcessPieceTimelineObjects(context, config, piece, false) + settings.postProcessPieceTimelineObjects(context, piece, false) const part: IBlueprintPart = { externalId, @@ -1066,7 +1024,7 @@ async function executeActionSelectJingle< ...props } - await context.queuePart(part, [ + await context.core.queuePart(part, [ piece, ...(settings.SelectedAdlibs ? await getPiecesToPreserve( @@ -1078,7 +1036,7 @@ async function executeActionSelectJingle< ]) if (settings.SelectedAdlibs.SourceLayer.Effekt) { - await context.stopPiecesOnLayers([settings.SelectedAdlibs.SourceLayer.Effekt]) + await context.core.stopPiecesOnLayers([settings.SelectedAdlibs.SourceLayer.Effekt]) } } @@ -1086,13 +1044,11 @@ async function executeActionCutToCamera< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionCutToCamera ) { - const config = settings.getConfig(context) - const externalId = generateExternalId(context, actionId, [userData.sourceDefinition.name]) const part: IBlueprintPart = { @@ -1102,12 +1058,12 @@ async function executeActionCutToCamera< expectedDuration: 0 } - const sourceInfoCam = findSourceInfo(config.sources, userData.sourceDefinition) + const sourceInfoCam = findSourceInfo(context.config.sources, userData.sourceDefinition) if (sourceInfoCam === undefined) { return } - const currentPieceInstances = await context.getPieceInstances('current') + const currentPieceInstances = await context.core.getPieceInstances('current') const serverInCurrentPart = currentPieceInstances.some( p => p.piece.sourceLayerId === settings.SourceLayers.Server || p.piece.sourceLayerId === settings.SourceLayers.VO @@ -1115,7 +1071,7 @@ async function executeActionCutToCamera< const currentKam = currentPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.Cam) - const camSisyfos = GetSisyfosTimelineObjForCamera(config, sourceInfoCam, false) + const camSisyfos = GetSisyfosTimelineObjForCamera(context.config, sourceInfoCam, false) const kamPiece: IBlueprintPiece = { externalId, @@ -1134,18 +1090,14 @@ async function executeActionCutToCamera< tags: [GetTagForKam(userData.sourceDefinition)], content: { timelineObjects: _.compact([ - literal({ + context.videoSwitcher.getMixEffectTimelineObject({ id: '', enable: { while: '1' }, priority: 1, layer: settings.LLayer.Atem.cutOnclean ? settings.LLayer.Atem.MEClean : settings.LLayer.Atem.MEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: sourceInfoCam.port, - transition: TSR.AtemTransitionStyle.CUT - } + input: sourceInfoCam.port, + transition: TransitionStyle.CUT } }), ...camSisyfos @@ -1153,10 +1105,10 @@ async function executeActionCutToCamera< } } - settings.postProcessPieceTimelineObjects(context, config, kamPiece, false) + settings.postProcessPieceTimelineObjects(context, kamPiece, false) if (userData.queue || serverInCurrentPart) { - await context.queuePart(part, [ + await context.core.queuePart(part, [ kamPiece, ...(settings.SelectedAdlibs ? await getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, []) @@ -1164,7 +1116,7 @@ async function executeActionCutToCamera< ]) if (serverInCurrentPart && !userData.queue) { - await context.takeAfterExecuteAction(true) + await context.core.takeAfterExecuteAction(true) } } else if (currentKam) { kamPiece.externalId = currentKam.piece.externalId @@ -1175,9 +1127,9 @@ async function executeActionCutToCamera< await stopGraphicPiecesThatShouldEndWithPart(context, currentPieceInstances) - await context.updatePieceInstance(currentKam._id, kamPiece) + await context.core.updatePieceInstance(currentKam._id, kamPiece) } else { - const currentExternalId = await context + const currentExternalId = await context.core .getPartInstance('current') .then(currentPartInstance => currentPartInstance?.part.externalId) @@ -1185,7 +1137,7 @@ async function executeActionCutToCamera< kamPiece.externalId = currentExternalId } - await context.stopPiecesOnLayers([ + await context.core.stopPiecesOnLayers([ settings.SourceLayers.DVE, ...(settings.SourceLayers.DVEAdLib ? [settings.SourceLayers.DVEAdLib] : []), settings.SourceLayers.Effekt, @@ -1198,15 +1150,15 @@ async function executeActionCutToCamera< await stopGraphicPiecesThatShouldEndWithPart(context, currentPieceInstances) kamPiece.enable = { start: 'now' } - await context.insertPiece('current', kamPiece) + await context.core.insertPiece('current', kamPiece) } } async function stopGraphicPiecesThatShouldEndWithPart( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, currentPieceInstances: Array> ) { - await context.stopPieceInstances( + await context.core.stopPieceInstances( currentPieceInstances .filter(pieceInstance => isGraphicThatShouldEndWithPart(pieceInstance)) .map(pieceInstance => pieceInstance._id) @@ -1225,13 +1177,11 @@ async function executeActionCutToRemote< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionCutToRemote ) { - const config = settings.getConfig(context) - const externalId = generateExternalId(context, actionId, [userData.sourceDefinition.name]) const title = userData.sourceDefinition.name @@ -1243,13 +1193,13 @@ async function executeActionCutToRemote< expectedDuration: 0 } - const sourceInfo = findSourceInfo(config.sources, userData.sourceDefinition) + const sourceInfo = findSourceInfo(context.config.sources, userData.sourceDefinition) if (sourceInfo === undefined) { - context.notifyUserWarning(`Invalid source: ${userData.sourceDefinition.name}`) + context.core.notifyUserWarning(`Invalid source: ${userData.sourceDefinition.name}`) return } - const eksternSisyfos: TSR.TimelineObjSisyfosAny[] = GetSisyfosTimelineObjForRemote(config, sourceInfo) + const eksternSisyfos: TSR.TimelineObjSisyfosAny[] = GetSisyfosTimelineObjForRemote(context.config, sourceInfo) const sisyfosPersistMetaData: SisyfosPersistMetaData = sourceInfo !== undefined @@ -1295,9 +1245,9 @@ async function executeActionCutToRemote< } } - settings.postProcessPieceTimelineObjects(context, config, remotePiece, false) + settings.postProcessPieceTimelineObjects(context, remotePiece, false) - await context.queuePart(part, [ + await context.core.queuePart(part, [ remotePiece, ...(settings.SelectedAdlibs ? await getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, []) @@ -1309,15 +1259,13 @@ async function executeActionCutSourceToBox< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, _actionId: string, userData: ActionCutSourceToBox ) { - const config = settings.getConfig(context) - - const currentPieces: IBlueprintPieceInstance[] = await context.getPieceInstances('current') - const nextPieces: IBlueprintPieceInstance[] = await context.getPieceInstances('next') + const currentPieces: IBlueprintPieceInstance[] = await context.core.getPieceInstances('current') + const nextPieces: IBlueprintPieceInstance[] = await context.core.getPieceInstances('next') const currentDVE = currentPieces.find( p => @@ -1382,7 +1330,6 @@ async function executeActionCutSourceToBox< const newPieceContent = MakeContentDVE2( context, - config, meta.config, graphicsTemplateContent, meta.sources, @@ -1402,13 +1349,11 @@ async function executeActionCutSourceToBox< if (newPieceContent.valid) { await startNewDVELayout( context, - config, settings, newDVEPiece, newPieceContent.content, meta, meta.config.DVEName, - meta.sources, newDVEPiece.externalId, modify, { activeDVE: modifiedPiece._id, dataStore: modifiedDataStore?._id }, @@ -1459,7 +1404,7 @@ async function applyPrerollToWallGraphics< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, piecesBySourceLayer: PiecesBySourceLayer ) { @@ -1482,7 +1427,7 @@ async function applyPrerollToWallGraphics< timelineObjectsToUpdate.forEach(timelineObject => { timelineObject.enable = enable }) - await context.updatePieceInstance(pieceInstance._id, newPieceProps) + await context.core.updatePieceInstance(pieceInstance._id, newPieceProps) } } } @@ -1491,19 +1436,19 @@ async function executeActionTakeWithTransition< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionTakeWithTransition ) { const externalId = generateExternalId(context, actionId, [userData.variant.type]) - const nextPieces = await context.getPieceInstances('next') + const nextPieces = await context.core.getPieceInstances('next') const nextPiecesBySourceLayer = groupPiecesBySourceLayer(nextPieces) const primaryPiece = findPrimaryPieceUsingPriority(settings, nextPiecesBySourceLayer) - await context.takeAfterExecuteAction(userData.takeNow) + await context.core.takeAfterExecuteAction(userData.takeNow) if ( !primaryPiece || @@ -1534,7 +1479,7 @@ async function executeActionTakeWithTransition< const existingEffektPiece = nextPieces.find(p => p.piece.sourceLayerId === settings.SourceLayers.Effekt) if (existingEffektPiece) { - await context.removePieceInstances('next', [existingEffektPiece._id]) + await context.core.removePieceInstances('next', [existingEffektPiece._id]) } let partProps: Partial | false = false @@ -1546,7 +1491,7 @@ async function executeActionTakeWithTransition< primaryPiece.piece.content.timelineObjects[timelineObjectIndex] = timelineObject - await context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) + await context.core.updatePieceInstance(primaryPiece._id, primaryPiece.piece) const cutTransitionPiece: IBlueprintPiece = { enable: { @@ -1569,8 +1514,8 @@ async function executeActionTakeWithTransition< inTransition: undefined } - await context.insertPiece('next', cutTransitionPiece) - await context.updatePartInstance('next', partProps) + await context.core.insertPiece('next', cutTransitionPiece) + await context.core.updatePartInstance('next', partProps) } break case 'breaker': { @@ -1578,13 +1523,11 @@ async function executeActionTakeWithTransition< primaryPiece.piece.content.timelineObjects[timelineObjectIndex] = timelineObject - await context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) + await context.core.updatePieceInstance(primaryPiece._id, primaryPiece.piece) - const config = settings.getConfig(context) const pieces: Array> = [] partProps = CreateEffektForPartInner( context, - config, pieces, userData.variant.breaker, externalId, @@ -1597,8 +1540,8 @@ async function executeActionTakeWithTransition< ) if (partProps) { - await context.updatePartInstance('next', partProps) - pieces.forEach(p => context.insertPiece('next', { ...p, tags: [GetTagForTransition(userData.variant)] })) + await context.core.updatePartInstance('next', partProps) + pieces.forEach(p => context.core.insertPiece('next', { ...p, tags: [GetTagForTransition(userData.variant)] })) } break } @@ -1619,18 +1562,17 @@ async function executeActionTakeWithTransition< ) partProps = CreateInTransitionForAtemTransitionStyle(userData.variant.frames) - await context.updatePartInstance('next', partProps) - await context.insertPiece('next', { ...blueprintPiece, tags: [GetTagForTransition(userData.variant)] }) + await context.core.updatePartInstance('next', partProps) + await context.core.insertPiece('next', { ...blueprintPiece, tags: [GetTagForTransition(userData.variant)] }) break } case 'dip': { - const config = settings.getConfig(context) await updateTimelineObjectMeTransition( context, timelineObject, TSR.AtemTransitionStyle.DIP, - DipTransitionSettings(config, userData.variant.frames), + DipTransitionSettings(context.config, userData.variant.frames), primaryPiece, timelineObjectIndex ) @@ -1641,8 +1583,8 @@ async function executeActionTakeWithTransition< ) partProps = CreateInTransitionForAtemTransitionStyle(userData.variant.frames) - await context.updatePartInstance('next', partProps) - await context.insertPiece('next', { ...blueprintPiece, tags: [GetTagForTransition(userData.variant)] }) + await context.core.updatePartInstance('next', partProps) + await context.core.insertPiece('next', { ...blueprintPiece, tags: [GetTagForTransition(userData.variant)] }) break } } @@ -1653,7 +1595,7 @@ async function executeActionTakeWithTransition< } async function updateTimelineObjectMeTransition( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, timelineObject: TSR.TimelineObjAtemME, transitionStyle: TSR.AtemTransitionStyle, transitionSettings: TSR.AtemTransitionSettings, @@ -1664,14 +1606,14 @@ async function updateTimelineObjectMeTransition( timelineObject.content.me.transitionSettings = transitionSettings pieceInstance.piece.content.timelineObjects[indexOfTimelineObject] = timelineObject - await context.updatePieceInstance(pieceInstance._id, pieceInstance.piece) + await context.core.updatePieceInstance(pieceInstance._id, pieceInstance.piece) } async function findPieceToRecoverDataFrom( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, dataStoreLayers: string[] ): Promise<{ piece: IBlueprintPieceInstance; part: 'current' | 'next' } | undefined> { - const pieces = await Promise.all([context.getPieceInstances('current'), context.getPieceInstances('next')]) + const pieces = await Promise.all([context.core.getPieceInstances('current'), context.core.getPieceInstances('next')]) const currentPieces = pieces[0] const nextPieces = pieces[1] @@ -1701,7 +1643,7 @@ async function findPieceToRecoverDataFrom( } async function findDataStore( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, dataStoreLayers: string[] ): Promise { const dataStorePiece = await findPieceToRecoverDataFrom(context, dataStoreLayers) @@ -1714,7 +1656,7 @@ async function findDataStore( } async function findMediaPlayerSessions( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, sessionLayers: string[] ): Promise<{ session: string | undefined; part: 'current' | 'next' | undefined }> { const mediaPlayerSessionPiece = await findPieceToRecoverDataFrom(context, sessionLayers) @@ -1739,7 +1681,7 @@ async function executeActionCommentatorSelectServer< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings ) { const data = await findDataStore(context, [ @@ -1775,10 +1717,8 @@ async function executeActionCommentatorSelectDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, - settings: ActionExecutionSettings, - _actionId: string, - _userData: ActionCommentatorSelectDVE + context: ExtendedActionExecutionContext, + settings: ActionExecutionSettings ) { if (!settings.SelectedAdlibs.SourceLayer.DVE) { return @@ -1797,10 +1737,8 @@ async function executeActionCommentatorSelectFull< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, - settings: ActionExecutionSettings, - _actionId: string, - _userData: ActionCommentatorSelectFull + context: ExtendedActionExecutionContext, + settings: ActionExecutionSettings ) { const data = await findDataStore(context, [SharedSourceLayers.SelectedAdlibGraphicsFull]) @@ -1808,17 +1746,15 @@ async function executeActionCommentatorSelectFull< return } - await executeActionSelectFull(context, settings, AdlibActionType.SELECT_FULL_GRAFIK, data) + await executeActionSelectFull(context, settings, data) } async function executeActionCommentatorSelectJingle< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, - settings: ActionExecutionSettings, - _actionId: string, - _userData: ActionCommentatorSelectJingle + context: ExtendedActionExecutionContext, + settings: ActionExecutionSettings ) { if (!settings.SelectedAdlibs.SourceLayer.Effekt) { return @@ -1837,12 +1773,11 @@ async function executeActionRecallLastLive< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, - actionId: string, - _userData: ActionRecallLastLive + actionId: string ) { - const lastLive = await context.findLastPieceOnLayer(settings.SourceLayers.Live, { + const lastLive = await context.core.findLastPieceOnLayer(settings.SourceLayers.Live, { originalOnly: true, excludeCurrentPart: false }) @@ -1851,7 +1786,7 @@ async function executeActionRecallLastLive< return } - const lastIdent = await context.findLastPieceOnLayer(settings.SourceLayers.Ident, { + const lastIdent = await context.core.findLastPieceOnLayer(settings.SourceLayers.Ident, { originalOnly: true, excludeCurrentPart: false, pieceMetaDataFilter: { @@ -1885,25 +1820,24 @@ async function executeActionRecallLastLive< }) } - await context.queuePart(part, pieces) + await context.core.queuePart(part, pieces) } async function executeActionRecallLastDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, - actionId: string, - _userData: ActionRecallLastDVE + actionId: string ) { - const currentPart = context.getPartInstance('current') + const currentPart = context.core.getPartInstance('current') if (!currentPart) { return } - const lastPlayedScheduledDVE = (await context.findLastPieceOnLayer(settings.SourceLayers.DVE, { + const lastPlayedScheduledDVE = (await context.core.findLastPieceOnLayer(settings.SourceLayers.DVE, { originalOnly: true })) as IBlueprintPieceInstance | undefined const isLastPlayedAScheduledDVE: boolean = !lastPlayedScheduledDVE?.dynamicallyInserted @@ -1915,12 +1849,12 @@ async function executeActionRecallLastDVE< } async function addLatestPieceOnLayerForDve( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, layer: string, actionId: string, dvePiece: IBlueprintPiece ): Promise { - const lastIdent = await context.findLastPieceOnLayer(layer, { + const lastIdent = await context.core.findLastPieceOnLayer(layer, { originalOnly: true, excludeCurrentPart: false, pieceMetaDataFilter: { @@ -1940,13 +1874,10 @@ async function addLatestPieceOnLayerForDve( lifespan: PieceLifespan.WithinPart } - await context.insertPiece('next', newIdentPiece) + await context.core.insertPiece('next', newIdentPiece) } -async function executeActionFadeDownPersistedAudioLevels< - StudioConfig extends TV2StudioConfigBase, - ShowStyleConfig extends TV2BlueprintConfigBase ->(context: ITV2ActionExecutionContext, _settings: ActionExecutionSettings) { +async function executeActionFadeDownPersistedAudioLevels(context: ExtendedActionExecutionContext) { const fadeSisyfosMetaData = await createFadeSisyfosLevelsMetaData(context) const resetSisyfosPersistedLevelsPiece: IBlueprintPiece = { externalId: 'fadeSisyfosPersistedLevelsDown', @@ -1962,20 +1893,20 @@ async function executeActionFadeDownPersistedAudioLevels< timelineObjects: [] } } - await context.insertPiece('current', resetSisyfosPersistedLevelsPiece) + await context.core.insertPiece('current', resetSisyfosPersistedLevelsPiece) } -async function executeActionCallRobotPreset(context: ITV2ActionExecutionContext, preset: number): Promise { +async function executeActionCallRobotPreset(context: ExtendedActionExecutionContext, preset: number): Promise { const robotCameraPiece: IBlueprintPiece = createTelemetricsPieceForRobotCamera( `callRobotPreset${preset}`, preset, 'now' - ) as IBlueprintPiece - await context.insertPiece('current', robotCameraPiece) + ) + await context.core.insertPiece('current', robotCameraPiece) } -async function createFadeSisyfosLevelsMetaData(context: ITV2ActionExecutionContext) { - const resolvedPieceInstances = await context.getResolvedPieceInstances('current') +async function createFadeSisyfosLevelsMetaData(context: ExtendedActionExecutionContext) { + const resolvedPieceInstances = await context.core.getResolvedPieceInstances('current') const emptySisyfosMetaData: SisyfosPersistMetaData = { sisyfosLayers: [] } @@ -2004,7 +1935,7 @@ async function scheduleLastPlayedDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, actionId: string, lastPlayedDVE: IBlueprintPieceInstance @@ -2025,35 +1956,17 @@ async function executeActionSelectFull< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITV2ActionExecutionContext, + context: ExtendedActionExecutionContext, settings: ActionExecutionSettings, - _actionId: string, userData: ActionSelectFullGrafik ) { - const config = settings.getConfig(context) + const externalId = generateExternalId(context, 'cut_to_full', [userData.name]) - const template = GetFullGrafikTemplateName(config, userData.name) - - const hash = context.getHashId(`cut_to_full_${template}`) - const externalId = `adlib-action_${hash}` - - const graphicType = config.studio.GraphicsType + const graphicType = context.config.studio.GraphicsType const previousPartKeepaliveDuration = graphicType === 'HTML' - ? config.studio.HTMLGraphics.KeepAliveDuration - : config.studio.VizPilotGraphics.KeepAliveDuration - - const part: IBlueprintPart = { - externalId, - title: `Full ${template}`, - metaData: {}, - expectedDuration: 0, - inTransition: { - previousPartKeepaliveDuration, - partContentDelayDuration: 0, - blockTakeDuration: 0 - } - } + ? context.config.studio.HTMLGraphics.KeepAliveDuration + : context.config.studio.VizPilotGraphics.KeepAliveDuration const cue: CueDefinitionGraphic = { type: CueType.Graphic, @@ -2068,7 +1981,6 @@ async function executeActionSelectFull< } const generator = PilotGraphicGenerator.createPilotGraphicGenerator({ - config, context, partId: externalId, settings: settings.pilotGraphicSettings, @@ -2079,11 +1991,23 @@ async function executeActionSelectFull< const fullPiece = generator.createPiece() - settings.postProcessPieceTimelineObjects(context, config, fullPiece, false) + settings.postProcessPieceTimelineObjects(context, fullPiece, false) const fullDataStore = generator.createFullDataStore() - await context.queuePart(part, [ + const part: IBlueprintPart = { + externalId, + title: `Full ${generator.getTemplateName()}`, + metaData: {}, + expectedDuration: 0, + inTransition: { + previousPartKeepaliveDuration, + partContentDelayDuration: 0, + blockTakeDuration: 0 + } + } + + await context.core.queuePart(part, [ fullPiece, fullDataStore, ...(await getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, [ @@ -2091,22 +2015,15 @@ async function executeActionSelectFull< ])) ]) - await context.stopPiecesOnLayers([SharedSourceLayers.SelectedAdlibGraphicsFull]) + await context.core.stopPiecesOnLayers([SharedSourceLayers.SelectedAdlibGraphicsFull]) } async function executeActionClearGraphics< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase ->( - context: ITV2ActionExecutionContext, - settings: ActionExecutionSettings, - _actionId: string, - userData: ActionClearGraphics -) { - const config = settings.getConfig(context) - - await context.stopPiecesOnLayers(STOPPABLE_GRAPHICS_LAYERS) - await context.insertPiece('current', { +>(context: ExtendedActionExecutionContext, userData: ActionClearGraphics) { + await context.core.stopPiecesOnLayers(STOPPABLE_GRAPHICS_LAYERS) + await context.core.insertPiece('current', { enable: { start: 'now', duration: 3000 @@ -2117,7 +2034,7 @@ async function executeActionClearGraphics< outputLayerId: SharedOutputLayers.SEC, lifespan: PieceLifespan.WithinPart, content: - config.studio.GraphicsType === 'HTML' + context.config.studio.GraphicsType === 'HTML' ? { timelineObjects: [ literal({ @@ -2146,7 +2063,7 @@ async function executeActionClearGraphics< deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, channelsToSendCommands: userData.sendCommands ? ['OVL1', 'FULL1', 'WALL1'] : undefined, - showName: config.selectedGfxSetup.OvlShowName ?? '' // @todo: improve types at the junction of HTML and Viz + showName: context.config.selectedGfxSetup.OvlShowName ?? '' // @todo: improve types at the junction of HTML and Viz } }) ] diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index b988457b..e4aadf76 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -1,7 +1,11 @@ import { TableConfigItemValue } from 'blueprints-integration' -import { TableConfigItemDSK, TableConfigItemSourceMappingWithSisyfos } from 'tv2-common' -import { DVEConfigInput } from './helpers' -import { SourceInfo } from './sources' +import { + DVEConfigInput, + SourceInfo, + SwitcherType, + TableConfigItemDSK, + TableConfigItemSourceMappingWithSisyfos +} from 'tv2-common' export type MediaPlayerConfig = Array<{ id: string; val: string }> @@ -94,6 +98,7 @@ export interface TV2StudioConfigBase { DVEIgnoreStatus: boolean ABPlaybackDebugLogging: boolean + SwitcherType: SwitcherType AtemSource: { Default: number SplitArtF: number @@ -169,4 +174,6 @@ export interface TV2BlueprintConfigBase +export type TV2StudioConfig = TV2StudioBlueprintConfigBase + +export type TV2ShowStyleConfig = TV2BlueprintConfigBase diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 66e7f40c..431e1e13 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -15,6 +15,7 @@ import { CueDefinitionDVE, DVEConfigInput, DVESources, + ExtendedShowStyleContext, FindDSKFullGFX, findSourceInfo, joinAssetToFolder, @@ -22,6 +23,7 @@ import { PartDefinition, PieceMetaData, TimelineBlueprintExt, + TransitionStyle, TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' @@ -128,15 +130,14 @@ export function MakeContentDVEBase< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, parsedCue: CueDefinitionDVE, dveConfig: DVEConfigInput | undefined, dveGeneratorOptions: DVEOptions ): { content: WithTimeline; valid: boolean } { if (!dveConfig) { - context.notifyUserWarning(`DVE ${parsedCue.template} is not configured`) + context.core.notifyUserWarning(`DVE ${parsedCue.template} is not configured`) return { valid: false, content: { @@ -153,7 +154,6 @@ export function MakeContentDVEBase< return MakeContentDVE2( context, - config, dveConfig, graphicsTemplateContent, parsedCue.sources, @@ -166,8 +166,7 @@ export function MakeContentDVE2< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, dveConfig: DVEConfigInput, graphicsTemplateContent: { [key: string]: string }, sources: DVESources | undefined, @@ -178,7 +177,7 @@ export function MakeContentDVE2< try { template = JSON.parse(dveConfig.DVEJSON) as DVEConfig } catch (e) { - context.notifyUserWarning(`DVE Config JSON is not valid for ${dveConfig.DVEName}`) + context.core.notifyUserWarning(`DVE Config JSON is not valid for ${dveConfig.DVEName}`) return { valid: false, content: { @@ -194,11 +193,11 @@ export function MakeContentDVE2< const classes: string[] = [] - const boxAssigments = makeBoxAssignments(inputs, context, classes, dveGeneratorOptions, sources) + const boxAssigments = makeBoxAssignments(inputs, context.core, classes, dveGeneratorOptions, sources) const boxes: BoxConfig[] = Object.entries(template.boxes).map(([_num, box]) => ({ ...box, - source: config.studio.AtemSource.Default + source: context.config.studio.AtemSource.Default })) const dveTimeline: TSR.TSRTimelineObj[] = [] const boxSources: BoxSources = [] @@ -212,7 +211,7 @@ export function MakeContentDVE2< if (sources) { // If it is intentional there are no sources, then ignore // TODO - should this warn? - context.notifyUserWarning(`Missing source type for DVE box: ${num + 1}`) + context.core.notifyUserWarning(`Missing source type for DVE box: ${num + 1}`) setBoxToBlack(box, boxSources) valid = false } @@ -224,54 +223,56 @@ export function MakeContentDVE2< case SourceType.DEFAULT: setBoxSource(box, boxSources, { sourceLayerType: SourceLayerType.UNKNOWN, - port: config.studio.AtemSource.Default + port: context.config.studio.AtemSource.Default }) break case SourceType.KAM: - const sourceInfoCam = findSourceInfo(config.sources, mappingFrom) + const sourceInfoCam = findSourceInfo(context.config.sources, mappingFrom) if (sourceInfoCam === undefined) { - context.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) + context.core.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) setBoxToBlack(box, boxSources) valid = false return } setBoxSource(box, boxSources, sourceInfoCam) - dveTimeline.push(...GetSisyfosTimelineObjForCamera(config, sourceInfoCam, mappingFrom.minusMic, audioEnable)) + dveTimeline.push( + ...GetSisyfosTimelineObjForCamera(context.config, sourceInfoCam, mappingFrom.minusMic, audioEnable) + ) break case SourceType.REMOTE: - const sourceInfoLive = findSourceInfo(config.sources, mappingFrom) + const sourceInfoLive = findSourceInfo(context.config.sources, mappingFrom) if (sourceInfoLive === undefined) { - context.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) + context.core.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) setBoxToBlack(box, boxSources) valid = false return } setBoxSource(box, boxSources, sourceInfoLive) - dveTimeline.push(...GetSisyfosTimelineObjForRemote(config, sourceInfoLive, audioEnable)) + dveTimeline.push(...GetSisyfosTimelineObjForRemote(context.config, sourceInfoLive, audioEnable)) break case SourceType.REPLAY: - const sourceInfoReplay = findSourceInfo(config.sources, mappingFrom) + const sourceInfoReplay = findSourceInfo(context.config.sources, mappingFrom) if (sourceInfoReplay === undefined) { - context.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) + context.core.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) setBoxToBlack(box, boxSources) valid = false return } setBoxSource(box, boxSources, sourceInfoReplay) - dveTimeline.push(...GetSisyfosTimelineObjForReplay(config, sourceInfoReplay, mappingFrom.vo)) + dveTimeline.push(...GetSisyfosTimelineObjForReplay(context.config, sourceInfoReplay, mappingFrom.vo)) break case SourceType.GRAFIK: if (mappingFrom.name === 'FULL') { setBoxSource(box, boxSources, { sourceLayerType: SourceLayerType.GRAPHICS, - port: FindDSKFullGFX(config).Fill + port: FindDSKFullGFX(context.config).Fill }) - dveTimeline.push(...GetSisyfosTimelineObjForFull(config)) + dveTimeline.push(...GetSisyfosTimelineObjForFull(context.config)) } else { - context.notifyUserWarning(`Unsupported engine for DVE: ${mappingFrom.name}`) + context.core.notifyUserWarning(`Unsupported engine for DVE: ${mappingFrom.name}`) setBoxToBlack(box, boxSources) } break @@ -292,18 +293,18 @@ export function MakeContentDVE2< graphicsTemplateStyle = JSON.parse(dveConfig.DVEGraphicsTemplateJSON.toString()) } } catch { - context.notifyUserWarning(`DVE Graphics Template JSON is not valid for ${dveConfig.DVEName}`) + context.core.notifyUserWarning(`DVE Graphics Template JSON is not valid for ${dveConfig.DVEName}`) } let keyFile = dveConfig.DVEGraphicsKey ? dveConfig.DVEGraphicsKey.toString() : undefined let frameFile = dveConfig.DVEGraphicsFrame ? dveConfig.DVEGraphicsFrame.toString() : undefined if (keyFile) { - keyFile = joinAssetToFolder(config.studio.DVEFolder, keyFile) + keyFile = joinAssetToFolder(context.config.studio.DVEFolder, keyFile) } if (frameFile) { - frameFile = joinAssetToFolder(config.studio.DVEFolder, frameFile) + frameFile = joinAssetToFolder(context.config.studio.DVEFolder, frameFile) } return { @@ -338,15 +339,15 @@ export function MakeContentDVE2< }), literal({ id: '', - enable: getDVEEnable(Number(config.studio.CasparPrerollDuration) - 10), // TODO - why 10ms? + enable: getDVEEnable(Number(context.config.studio.CasparPrerollDuration) - 10), // TODO - why 10ms? priority: 1, layer: dveGeneratorOptions.dveLayers.ATEM.SSrcArt, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRCPROPS, ssrcProps: { - artFillSource: config.studio.AtemSource.SplitArtF, - artCutSource: config.studio.AtemSource.SplitArtK, + artFillSource: context.config.studio.AtemSource.SplitArtF, + artCutSource: context.config.studio.AtemSource.SplitArtK, artOption: 1, ...(template.properties && template.properties?.artPreMultiplied === false ? { @@ -364,18 +365,14 @@ export function MakeContentDVE2< } } }), - literal({ + context.videoSwitcher.getMixEffectTimelineObject({ id: '', - enable: getDVEEnable(Number(config.studio.CasparPrerollDuration)), + enable: getDVEEnable(Number(context.config.studio.CasparPrerollDuration)), priority: 1, layer: dveGeneratorOptions.dveLayers.ATEM.MEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: AtemSourceIndex.SSrc, - transition: TSR.AtemTransitionStyle.CUT - } + input: AtemSourceIndex.SSrc, + transition: TransitionStyle.CUT } }), literal({ @@ -383,7 +380,7 @@ export function MakeContentDVE2< enable: getDVEEnable(), priority: 1, layer: SharedGraphicLLayer.GraphicLLayerLocators, - content: CreateHTMLRendererContent(config, 'locators', { + content: CreateHTMLRendererContent(context.config, 'locators', { ...graphicsTemplateContent, style: graphicsTemplateStyle ?? {} }) diff --git a/src/tv2-common/content/jingle.ts b/src/tv2-common/content/jingle.ts index d0463cc4..6a83beb5 100644 --- a/src/tv2-common/content/jingle.ts +++ b/src/tv2-common/content/jingle.ts @@ -1,7 +1,6 @@ import { TimelineObjectCoreExt, TSR, VTContent, WithTimeline } from 'blueprints-integration' -import { TimeFromFrames } from 'tv2-common' -import { TV2BlueprintConfig, TV2BlueprintConfigBase, TV2StudioConfigBase } from '../blueprintConfig' -import { EnableDSK, FindDSKJingle } from '../helpers' +import { EnableDSK, ExtendedShowStyleContext, FindDSKJingle, TimeFromFrames } from 'tv2-common' +import { TV2BlueprintConfigBase, TV2ShowStyleConfig, TV2StudioConfigBase } from '../blueprintConfig' import { TimelineBlueprintExt } from '../onTimelineGenerate' import { joinAssetToFolder, joinAssetToNetworkPath, literal } from '../util' @@ -20,7 +19,7 @@ export interface JingleLayers { } export function CreateJingleExpectedMedia( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, jingle: string, alphaAtStart: number, duration: number, @@ -51,7 +50,7 @@ export function CreateJingleContentBase< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - config: ShowStyleConfig, + context: ExtendedShowStyleContext, file: string, alphaAtStart: number, loadFirstFrame: boolean, @@ -59,6 +58,7 @@ export function CreateJingleContentBase< alphaAtEnd: number, layers: JingleLayers ) { + const { config } = context const fileName = joinAssetToFolder(config.studio.JingleFolder, file) const jingleDSK = FindDSKJingle(config) return literal>({ @@ -66,9 +66,9 @@ export function CreateJingleContentBase< timelineObjects: literal([ CreateJingleCasparTimelineObject(fileName, loadFirstFrame, layers), - ...EnableDSK(config, 'JINGLE', { start: Number(config.studio.CasparPrerollDuration) }), + ...EnableDSK(context, 'JINGLE', { start: Number(config.studio.CasparPrerollDuration) }), - ...(layers.ATEM.USKJinglePreview + ...(layers.ATEM.USKJinglePreview // @todo: this is a QBOX-only feature, should be refactored at some point ? [ literal({ id: '', diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 13758610..ebc3df48 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -1,7 +1,7 @@ import { IShowStyleUserContext, TimelineObjectCoreExt, TSR, VTContent, WithTimeline } from 'blueprints-integration' import { GetSisyfosTimelineObjForServer, literal, PartDefinition, TransitionSettings } from 'tv2-common' import { AbstractLLayer, ControlClasses, GetEnableClassForServer } from 'tv2-constants' -import { TV2BlueprintConfig } from '../blueprintConfig' +import { TV2ShowStyleConfig } from '../blueprintConfig' import { TimelineBlueprintExt } from '../onTimelineGenerate' import { ServerContentProps, ServerPartProps } from '../parts' import { AdlibServerOfftubeOptions } from '../pieces' @@ -26,7 +26,7 @@ type VTProps = Pick< > export function GetVTContentProperties( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, contentProps: Omit ): VTProps { return literal({ @@ -47,7 +47,7 @@ export function GetVTContentProperties( export function MakeContentServer( _context: IShowStyleUserContext, - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, sourceLayers: MakeContentServerSourceLayers, partProps: ServerPartProps, contentProps: ServerContentProps @@ -60,7 +60,7 @@ export function MakeContentServer( } function GetServerTimeline( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, sourceLayers: MakeContentServerSourceLayers, partProps: ServerPartProps, contentProps: ServerContentProps @@ -135,7 +135,7 @@ function GetServerTimeline( export function CutToServer( mediaPlayerSessionId: string, partDefinition: PartDefinition, - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, atemLLayerMEPGM: string, offtubeOptions?: AdlibServerOfftubeOptions ) { diff --git a/src/tv2-common/cues/EvaluateCueRobotCamera.ts b/src/tv2-common/cues/EvaluateCueRobotCamera.ts index 5453ff5a..8cf731f2 100644 --- a/src/tv2-common/cues/EvaluateCueRobotCamera.ts +++ b/src/tv2-common/cues/EvaluateCueRobotCamera.ts @@ -1,11 +1,10 @@ -import { IBlueprintPiece, IShowStyleUserContext, TSR } from 'blueprints-integration' +import { IBlueprintPiece, TSR } from 'blueprints-integration' import { SharedSourceLayers } from '../../tv2-constants' import { CalculateTime } from '../cueTiming' import { CueDefinitionRobotCamera } from '../inewsConversion' import { createTelemetricsPieceForRobotCamera, ROBOT_CAMERA_NAME_PREFIX } from '../pieces/telemetric' export function EvaluateCueRobotCamera( - _context: IShowStyleUserContext, cueDefinition: CueDefinitionRobotCamera, pieces: IBlueprintPiece[], externalId: string diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index c81a9f8c..99d019d3 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -2,7 +2,6 @@ import { IBlueprintAdLibPiece, IBlueprintPart, IBlueprintPiece, - IShowStyleUserContext, PieceLifespan, RemoteContent, TimelineObjectCoreExt, @@ -11,6 +10,7 @@ import { } from 'blueprints-integration' import { CueDefinitionEkstern, + ExtendedShowStyleContext, literal, PartDefinition, PieceMetaData, @@ -36,8 +36,7 @@ export function EvaluateEksternBase< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, part: IBlueprintPart, pieces: Array>, adlibPieces: Array>, @@ -48,9 +47,9 @@ export function EvaluateEksternBase< adlib?: boolean, rank?: number ) { - const sourceInfoEkstern = findSourceInfo(config.sources, parsedCue.sourceDefinition) + const sourceInfoEkstern = findSourceInfo(context.config.sources, parsedCue.sourceDefinition) if (parsedCue.sourceDefinition.sourceType !== SourceType.REMOTE || sourceInfoEkstern === undefined) { - context.notifyUserWarning(`EKSTERN source is not valid: "${parsedCue.sourceDefinition.raw}"`) + context.core.notifyUserWarning(`EKSTERN source is not valid: "${parsedCue.sourceDefinition.raw}"`) part.invalid = true return } @@ -89,13 +88,13 @@ export function EvaluateEksternBase< me: { input: atemInput, transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(config, partDefinition) + transitionSettings: TransitionSettings(context.config, partDefinition) } }, classes: [ControlClasses.LiveSourceOnAir] }), - ...GetSisyfosTimelineObjForRemote(config, sourceInfoEkstern) + ...GetSisyfosTimelineObjForRemote(context.config, sourceInfoEkstern) ]) }) }) @@ -135,12 +134,12 @@ export function EvaluateEksternBase< me: { input: atemInput, transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(config, partDefinition) + transitionSettings: TransitionSettings(context.config, partDefinition) } } }), - ...GetSisyfosTimelineObjForRemote(config, sourceInfoEkstern) + ...GetSisyfosTimelineObjForRemote(context.config, sourceInfoEkstern) ]) }) }) diff --git a/src/tv2-common/cues/lyd.ts b/src/tv2-common/cues/lyd.ts index b50845e8..6bf1df7a 100644 --- a/src/tv2-common/cues/lyd.ts +++ b/src/tv2-common/cues/lyd.ts @@ -3,7 +3,6 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece, - IShowStyleUserContext, PieceLifespan, TimelineObjectCoreExt, TSR, @@ -12,6 +11,7 @@ import { import { CreateTimingEnable, CueDefinitionLYD, + ExtendedShowStyleContext, joinAssetToFolder, literal, PartDefinition, @@ -26,11 +26,10 @@ import { SharedSisyfosLLayer, SharedSourceLayers } from 'tv2-constants' -import { TV2BlueprintConfig } from '../blueprintConfig' +import { TV2ShowStyleConfig } from '../blueprintConfig' export function EvaluateLYD( - context: IShowStyleUserContext, - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], _actions: IBlueprintActionManifest[], @@ -39,14 +38,14 @@ export function EvaluateLYD( adlib?: boolean, rank?: number ) { - const conf = config.showStyle.LYDConfig.find(lyd => + const conf = context.config.showStyle.LYDConfig.find(lyd => lyd.INewsName ? lyd.INewsName.toString().toUpperCase() === parsedCue.variant.toUpperCase() : false ) const stop = !!parsedCue.variant.match(/^[^_]*STOP[^_]*$/i) // TODO: STOP 1 / STOP 2 etc. const fade = parsedCue.variant.match(/FADE ?(\d+)/i) if (!conf && !stop && !fade) { - context.notifyUserWarning(`LYD ${parsedCue.variant} not configured`) + context.core.notifyUserWarning(`LYD ${parsedCue.variant} not configured`) return } @@ -71,7 +70,7 @@ export function EvaluateLYD( : fade ? Math.max(1000, fadeIn ? TimeFromFrames(fadeIn) : 0) : CreateTimingEnable(parsedCue).enable.duration ?? undefined, - content: LydContent(config, file, lydType, fadeIn, fadeOut), + content: LydContent(context.config, file, lydType, fadeIn, fadeOut), tags: [AdlibTags.ADLIB_FLOW_PRODUCER] }) } else { @@ -91,13 +90,13 @@ export function EvaluateLYD( outputLayerId: SharedOutputLayers.MUSIK, sourceLayerId: SharedSourceLayers.PgmAudioBed, lifespan, - content: LydContent(config, file, lydType, fadeIn, fadeOut) + content: LydContent(context.config, file, lydType, fadeIn, fadeOut) }) } } function LydContent( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, file: string, lydType: 'bed' | 'stop' | 'fade', fadeIn?: number, diff --git a/src/tv2-common/cues/mixMinus.ts b/src/tv2-common/cues/mixMinus.ts index aacb4ce8..3b0edd9d 100644 --- a/src/tv2-common/cues/mixMinus.ts +++ b/src/tv2-common/cues/mixMinus.ts @@ -1,29 +1,26 @@ import { BaseContent, IBlueprintPiece, - IShowStyleUserContext, PieceLifespan, TimelineObjectCoreExt, TSR, WithTimeline } from 'blueprints-integration' -import { CueDefinitionMixMinus, findSourceInfo, literal, PartDefinition } from 'tv2-common' +import { CueDefinitionMixMinus, ExtendedShowStyleContext, findSourceInfo, literal, PartDefinition } from 'tv2-common' import { ControlClasses, SharedATEMLLayer, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' -import { TV2BlueprintConfig } from '../blueprintConfig' export function EvaluateCueMixMinus( - context: IShowStyleUserContext, - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], part: PartDefinition, parsedCue: CueDefinitionMixMinus ) { - const sourceInfo = findSourceInfo(config.sources, parsedCue.sourceDefinition) + const sourceInfo = findSourceInfo(context.config.sources, parsedCue.sourceDefinition) const name = parsedCue.sourceDefinition.name || parsedCue.sourceDefinition.sourceType if (sourceInfo === undefined) { - context.notifyUserWarning(`${name} does not exist in this studio (MINUSKAM)`) + context.core.notifyUserWarning(`${name} does not exist in this studio (MINUSKAM)`) return } const atemInput = sourceInfo.port diff --git a/src/tv2-common/evaluateCues.ts b/src/tv2-common/evaluateCues.ts index 36d7e0b6..7611b161 100644 --- a/src/tv2-common/evaluateCues.ts +++ b/src/tv2-common/evaluateCues.ts @@ -4,8 +4,6 @@ import { IBlueprintAdLibPiece, IBlueprintPart, IBlueprintPiece, - ISegmentUserContext, - IShowStyleUserContext, TSR } from 'blueprints-integration' import { @@ -19,12 +17,13 @@ import { CueDefinitionLYD, CueDefinitionRobotCamera, CueDefinitionTelefon, + ExtendedShowStyleContext, IsTargetingFull, IsTargetingOVL, PartDefinition } from 'tv2-common' import { CueType } from 'tv2-constants' -import { TV2BlueprintConfig } from './blueprintConfig' +import { TV2ShowStyleConfig } from './blueprintConfig' import { CueDefinitionBackgroundLoop, CueDefinitionGraphic, @@ -41,8 +40,7 @@ export interface Adlib { } export interface EvaluateCuesShowstyleOptions { EvaluateCueGraphic?: ( - config: TV2BlueprintConfig, - context: ISegmentUserContext, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -52,7 +50,7 @@ export interface EvaluateCuesShowstyleOptions { adlib?: Adlib ) => void EvaluateCueBackgroundLoop?: ( - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -62,8 +60,7 @@ export interface EvaluateCuesShowstyleOptions { rank?: number ) => void EvaluateCueGraphicDesign?: ( - config: TV2BlueprintConfig, - context: ISegmentUserContext, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -73,17 +70,13 @@ export interface EvaluateCuesShowstyleOptions { rank?: number ) => void EvaluateCueRouting?: ( - config: TV2BlueprintConfig, - context: ISegmentUserContext, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], - _adlibPieces: IBlueprintAdLibPiece[], - _actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionRouting ) => void EvaluateCueEkstern?: ( - context: ISegmentUserContext, - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, part: IBlueprintPart, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], @@ -95,8 +88,7 @@ export interface EvaluateCuesShowstyleOptions { rank?: number ) => void EvaluateCueDVE?: ( - context: ISegmentUserContext, - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], actions: IBlueprintActionManifest[], partDefinition: PartDefinition, @@ -105,8 +97,7 @@ export interface EvaluateCuesShowstyleOptions { rank?: number ) => void EvaluateCueAdLib?: ( - context: ISegmentUserContext, - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, actions: IBlueprintActionManifest[], mediaSubscriptions: HackPartMediaObjectSubscription[], parsedCue: CueDefinitionAdLib, @@ -114,8 +105,7 @@ export interface EvaluateCuesShowstyleOptions { rank: number ) => Promise EvaluateCueTelefon?: ( - config: TV2BlueprintConfig, - context: ISegmentUserContext, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -125,8 +115,7 @@ export interface EvaluateCuesShowstyleOptions { adlib?: Adlib ) => void EvaluateCueJingle?: ( - context: ISegmentUserContext, - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -137,8 +126,7 @@ export interface EvaluateCuesShowstyleOptions { effekt?: boolean ) => void EvaluateCueLYD?: ( - context: ISegmentUserContext, - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -148,7 +136,7 @@ export interface EvaluateCuesShowstyleOptions { rank?: number ) => void EvaluateCueClearGrafiks?: ( - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -157,15 +145,13 @@ export interface EvaluateCuesShowstyleOptions { shouldAdlib: boolean ) => void EvaluateCuePgmClean?: ( - context: ISegmentUserContext, - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], partId: string, parsedCue: CueDefinitionPgmClean ) => void EvaluateCueMixMinus?: ( - context: ISegmentUserContext, - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], part: PartDefinition, parsedCue: CueDefinitionMixMinus @@ -174,12 +160,7 @@ export interface EvaluateCuesShowstyleOptions { EvaluateCueProfile?: () => void /** TODO: Mic -> For the future */ EvaluateCueMic?: () => void - EvaluateCueRobotCamera?: ( - context: IShowStyleUserContext, - cueDefinition: CueDefinitionRobotCamera, - pieces: IBlueprintPiece[], - partId: string - ) => void + EvaluateCueRobotCamera?: (cueDefinition: CueDefinitionRobotCamera, pieces: IBlueprintPiece[], partId: string) => void } export interface EvaluateCuesOptions { @@ -197,8 +178,7 @@ export interface EvaluateCuesOptions { export async function EvaluateCuesBase( showStyleOptions: EvaluateCuesShowstyleOptions, - context: ISegmentUserContext, - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, part: IBlueprintPart, pieces: IBlueprintPiece[], adLibPieces: IBlueprintAdLibPiece[], @@ -219,16 +199,15 @@ export async function EvaluateCuesBase( case CueType.Graphic: if (showStyleOptions.EvaluateCueGraphic) { if ( - config.studio.PreventOverlayWithFull && + context.config.studio.PreventOverlayWithFull && GraphicIsPilot(cue) && IsTargetingOVL(cue.target) && cues.some(c => c.type === CueType.Graphic && GraphicIsPilot(c) && IsTargetingFull(c.target)) ) { - context.notifyUserWarning(`Cannot create overlay graphic with FULL`) + context.core.notifyUserWarning(`Cannot create overlay graphic with FULL`) break } showStyleOptions.EvaluateCueGraphic( - config, context, pieces, adLibPieces, @@ -244,7 +223,6 @@ export async function EvaluateCuesBase( if (showStyleOptions.EvaluateCueEkstern) { showStyleOptions.EvaluateCueEkstern( context, - config, part, pieces, adLibPieces, @@ -259,19 +237,10 @@ export async function EvaluateCuesBase( break case CueType.DVE: if (showStyleOptions.EvaluateCueDVE) { - showStyleOptions.EvaluateCueDVE( - context, - config, - pieces, - actions, - partDefinition, - cue, - shouldAdlib, - adLibRank - ) + showStyleOptions.EvaluateCueDVE(context, pieces, actions, partDefinition, cue, shouldAdlib, adLibRank) // Always make an adlib for DVEs if (!shouldAdlib) { - showStyleOptions.EvaluateCueDVE(context, config, pieces, actions, partDefinition, cue, true, adLibRank) + showStyleOptions.EvaluateCueDVE(context, pieces, actions, partDefinition, cue, true, adLibRank) } } break @@ -279,7 +248,6 @@ export async function EvaluateCuesBase( if (showStyleOptions.EvaluateCueAdLib) { await showStyleOptions.EvaluateCueAdLib( context, - config, actions, mediaSubscriptions, cue, @@ -291,7 +259,6 @@ export async function EvaluateCuesBase( case CueType.Telefon: if (showStyleOptions.EvaluateCueTelefon) { showStyleOptions.EvaluateCueTelefon( - config, context, pieces, adLibPieces, @@ -307,7 +274,6 @@ export async function EvaluateCuesBase( if (showStyleOptions.EvaluateCueJingle) { showStyleOptions.EvaluateCueJingle( context, - config, pieces, adLibPieces, actions, @@ -322,7 +288,6 @@ export async function EvaluateCuesBase( if (showStyleOptions.EvaluateCueLYD) { showStyleOptions.EvaluateCueLYD( context, - config, pieces, adLibPieces, actions, @@ -336,7 +301,6 @@ export async function EvaluateCuesBase( case CueType.GraphicDesign: if (showStyleOptions.EvaluateCueGraphicDesign) { showStyleOptions.EvaluateCueGraphicDesign( - config, context, pieces, adLibPieces, @@ -351,7 +315,7 @@ export async function EvaluateCuesBase( case CueType.ClearGrafiks: if (showStyleOptions.EvaluateCueClearGrafiks) { showStyleOptions.EvaluateCueClearGrafiks( - config, + context, pieces, adLibPieces, actions, @@ -364,7 +328,7 @@ export async function EvaluateCuesBase( case CueType.BackgroundLoop: if (showStyleOptions.EvaluateCueBackgroundLoop) { showStyleOptions.EvaluateCueBackgroundLoop( - config, + context, pieces, adLibPieces, actions, @@ -377,36 +341,28 @@ export async function EvaluateCuesBase( break case CueType.Routing: if (showStyleOptions.EvaluateCueRouting) { - showStyleOptions.EvaluateCueRouting( - config, - context, - pieces, - adLibPieces, - actions, - partDefinition.externalId, - cue - ) + showStyleOptions.EvaluateCueRouting(context, pieces, partDefinition.externalId, cue) } break case CueType.PgmClean: if (showStyleOptions.EvaluateCuePgmClean) { - showStyleOptions.EvaluateCuePgmClean(context, config, pieces, partDefinition.externalId, cue) + showStyleOptions.EvaluateCuePgmClean(context, pieces, partDefinition.externalId, cue) } break case CueType.MixMinus: if (showStyleOptions.EvaluateCueMixMinus) { - showStyleOptions.EvaluateCueMixMinus(context, config, pieces, partDefinition, cue) + showStyleOptions.EvaluateCueMixMinus(context, pieces, partDefinition, cue) } break case CueType.UNPAIRED_TARGET: - context.notifyUserWarning(`No graphic found after ${cue.iNewsCommand} cue`) + context.core.notifyUserWarning(`No graphic found after ${cue.iNewsCommand} cue`) break case CueType.UNPAIRED_PILOT: - context.notifyUserWarning(`Graphic found without target engine`) + context.core.notifyUserWarning(`Graphic found without target engine`) break case CueType.RobotCamera: if (showStyleOptions.EvaluateCueRobotCamera) { - showStyleOptions.EvaluateCueRobotCamera(context, cue, pieces, partDefinition.externalId) + showStyleOptions.EvaluateCueRobotCamera(cue, pieces, partDefinition.externalId) } break default: diff --git a/src/tv2-common/getSegment.ts b/src/tv2-common/getSegment.ts index 002c5833..cd26be5a 100644 --- a/src/tv2-common/getSegment.ts +++ b/src/tv2-common/getSegment.ts @@ -1,12 +1,8 @@ -import { - BlueprintResultPart, - BlueprintResultSegment, - IBlueprintSegment, - IngestSegment, - IShowStyleUserContext -} from 'blueprints-integration' +import { BlueprintResultPart, BlueprintResultSegment, IBlueprintSegment, IngestSegment } from 'blueprints-integration' import { assertUnreachable, + ExtendedSegmentContext, + ExtendedShowStyleContext, GetNextPartCue, INewsPayload, IsTargetingFull, @@ -18,7 +14,7 @@ import { PartMetaData } from 'tv2-common' import { CueType, PartType, SharedSourceLayers, TallyTags } from 'tv2-constants' -import { TV2BlueprintConfigBase, TV2StudioConfigBase } from './blueprintConfig' +import { TV2ShowStyleConfig } from './blueprintConfig' import { CueDefinitionUnpairedTarget, PartDefinitionDVE, @@ -30,83 +26,68 @@ import { } from './inewsConversion' import { CreatePartInvalid, ServerPartProps } from './parts' -export interface GetSegmentShowstyleOptions< - StudioConfig extends TV2StudioConfigBase, - ShowStyleConfig extends TV2BlueprintConfigBase -> { - getConfig: (context: IShowStyleUserContext) => ShowStyleConfig - CreatePartContinuity: (config: ShowStyleConfig, ingestSegment: IngestSegment) => BlueprintResultPart +export interface GetSegmentShowstyleOptions { + CreatePartContinuity: (config: TV2ShowStyleConfig, ingestSegment: IngestSegment) => BlueprintResultPart CreatePartUnknown: ( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, totalWords: number, asAdlibs?: boolean ) => BlueprintResultPart | Promise CreatePartIntro?: ( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, totalWords: number ) => BlueprintResultPart | Promise CreatePartKam?: ( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinitionKam, totalWords: number ) => BlueprintResultPart | Promise CreatePartServer?: ( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, partProps: ServerPartProps ) => BlueprintResultPart | Promise CreatePartTeknik?: ( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinitionTeknik, totalWords: number ) => BlueprintResultPart | Promise CreatePartGrafik?: ( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinitionGrafik, totalWords: number ) => BlueprintResultPart | Promise CreatePartEkstern?: ( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinitionEkstern, totalWords: number ) => BlueprintResultPart | Promise CreatePartTelefon?: ( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinitionTelefon, totalWords: number ) => BlueprintResultPart | Promise CreatePartDVE?: ( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinitionDVE, totalWords: number ) => BlueprintResultPart | Promise CreatePartEVS?: ( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinitionEVS, totalWords: number ) => BlueprintResultPart | Promise } -export async function getSegmentBase< - StudioConfig extends TV2StudioConfigBase, - ShowStyleConfig extends TV2BlueprintConfigBase ->( - context: IShowStyleUserContext, +export async function getSegmentBase( + context: ExtendedSegmentContext, ingestSegment: IngestSegment, - showStyleOptions: GetSegmentShowstyleOptions + showStyleOptions: GetSegmentShowstyleOptions ): Promise { + const { config } = context + const segmentPayload = ingestSegment.payload as INewsPayload | undefined const iNewsStory = segmentPayload?.iNewsStory const segment: IBlueprintSegment = { @@ -118,7 +99,6 @@ export async function getSegmentBase< ? iNewsStory.fields.pageNumber.trim() : undefined } - const config = showStyleOptions.getConfig(context) if (!segmentPayload || !iNewsStory || iNewsStory.meta.float === 'float' || !iNewsStory.body) { segment.isHidden = true @@ -168,7 +148,7 @@ export async function getSegmentBase< part.type === PartType.Unknown && part.cues.filter(cue => cue.type === CueType.Jingle || cue.type === CueType.AdLib).length === 0 ) { - blueprintParts.push(await showStyleOptions.CreatePartUnknown(context, config, part, totalWords, true)) + blueprintParts.push(await showStyleOptions.CreatePartUnknown(context, part, totalWords, true)) continue } @@ -178,7 +158,7 @@ export async function getSegmentBase< if (unpairedTargets.length) { blueprintParts.push(CreatePartInvalid(part)) unpairedTargets.forEach(cue => { - context.notifyUserWarning(`No graphic found after ${cue.iNewsCommand} cue`) + context.core.notifyUserWarning(`No graphic found after ${cue.iNewsCommand} cue`) }) continue } @@ -186,18 +166,18 @@ export async function getSegmentBase< switch (part.type) { case PartType.INTRO: if (showStyleOptions.CreatePartIntro) { - blueprintParts.push(await showStyleOptions.CreatePartIntro(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartIntro(context, part, totalWords)) } break case PartType.Kam: if (showStyleOptions.CreatePartKam) { - blueprintParts.push(await showStyleOptions.CreatePartKam(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartKam(context, part, totalWords)) } break case PartType.Server: if (showStyleOptions.CreatePartServer) { blueprintParts.push( - await showStyleOptions.CreatePartServer(context, config, part, { + await showStyleOptions.CreatePartServer(context, part, { voLayer: false, voLevels: false, totalTime, @@ -210,18 +190,18 @@ export async function getSegmentBase< break case PartType.Teknik: if (showStyleOptions.CreatePartTeknik) { - blueprintParts.push(await showStyleOptions.CreatePartTeknik(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartTeknik(context, part, totalWords)) } break case PartType.Grafik: if (showStyleOptions.CreatePartGrafik) { - blueprintParts.push(await showStyleOptions.CreatePartGrafik(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartGrafik(context, part, totalWords)) } break case PartType.VO: if (showStyleOptions.CreatePartServer) { blueprintParts.push( - await showStyleOptions.CreatePartServer(context, config, part, { + await showStyleOptions.CreatePartServer(context, part, { voLayer: true, voLevels: true, totalTime, @@ -234,27 +214,27 @@ export async function getSegmentBase< break case PartType.DVE: if (showStyleOptions.CreatePartDVE) { - blueprintParts.push(await showStyleOptions.CreatePartDVE(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartDVE(context, part, totalWords)) } break case PartType.REMOTE: if (showStyleOptions.CreatePartEkstern) { - blueprintParts.push(await showStyleOptions.CreatePartEkstern(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartEkstern(context, part, totalWords)) } break case PartType.Telefon: if (showStyleOptions.CreatePartTelefon) { - blueprintParts.push(await showStyleOptions.CreatePartTelefon(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartTelefon(context, part, totalWords)) } break case PartType.Unknown: if (part.cues.length) { - blueprintParts.push(await showStyleOptions.CreatePartUnknown(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartUnknown(context, part, totalWords)) } break case PartType.EVS: if (showStyleOptions.CreatePartEVS) { - blueprintParts.push(await showStyleOptions.CreatePartEVS(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartEVS(context, part, totalWords)) } break default: diff --git a/src/tv2-common/helpers/__tests__/sisyfos.spec.ts b/src/tv2-common/helpers/__tests__/sisyfos.spec.ts index b47f8ba9..986a4560 100644 --- a/src/tv2-common/helpers/__tests__/sisyfos.spec.ts +++ b/src/tv2-common/helpers/__tests__/sisyfos.spec.ts @@ -6,11 +6,10 @@ import { SourceInfoType } from 'tv2-common' import { SharedSisyfosLLayer } from 'tv2-constants' -import { makeMockAFVDContext } from '../../../__mocks__/context' -import { getConfig } from '../../../tv2_afvd_showstyle/helpers/config' +import { makeMockGalleryContext } from '../../../__mocks__/context' describe('Sisyfos', () => { - const config = getConfig(makeMockAFVDContext()) + const config = makeMockGalleryContext().config it('Enables audio layers for cameras', () => { const sourceInfo = { type: SourceInfoType.KAM, diff --git a/src/tv2-common/helpers/abPlayback.ts b/src/tv2-common/helpers/abPlayback.ts index 4b6de3bc..f38eabb9 100644 --- a/src/tv2-common/helpers/abPlayback.ts +++ b/src/tv2-common/helpers/abPlayback.ts @@ -1,9 +1,4 @@ -import { - IBlueprintResolvedPieceInstance, - ITimelineEventContext, - OnGenerateTimelineObj, - TSR -} from 'blueprints-integration' +import { IBlueprintResolvedPieceInstance, OnGenerateTimelineObj, TSR } from 'blueprints-integration' import { AbstractLLayer, MEDIA_PLAYER_AUTO, MediaPlayerClaimType } from 'tv2-constants' import * as _ from 'underscore' import { TV2BlueprintConfigBase, TV2StudioConfigBase } from '../blueprintConfig' @@ -14,6 +9,7 @@ import { TimelineBlueprintExt, TimelinePersistentStateExt } from '../onTimelineGenerate' +import { ExtendedTimelineContext } from '../showstyle' export interface SessionToPlayerMap { [sessionId: string]: MediaPlayerClaim | undefined @@ -70,10 +66,7 @@ interface SessionTime { optional: boolean duration: number | undefined } -function calculateSessionTimeRanges( - _context: ITimelineEventContext, - resolvedPieces: Array> -) { +function calculateSessionTimeRanges(resolvedPieces: Array>) { const piecesWantingMediaPlayers = _.filter(resolvedPieces, p => { if (!p.piece.metaData) { return false @@ -201,13 +194,11 @@ export function resolveMediaPlayerAssignments< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITimelineEventContext, - config: ShowStyleConfig, + context: ExtendedTimelineContext, previousAssignmentRev: SessionToPlayerMap, resolvedPieces: Array> ) { - const debugLog = config.studio.ABPlaybackDebugLogging - const sessionRequests = calculateSessionTimeRanges(context, resolvedPieces) + const sessionRequests = calculateSessionTimeRanges(resolvedPieces) // In future this may want a better fit algorithm than this. This only applies if being done for multiple clips playing simultaneously, and more players @@ -230,48 +221,36 @@ export function resolveMediaPlayerAssignments< _.sortBy(activeRequests, r => r.start) // Go through and assign players - if (debugLog) { - context.logWarning('all reqs' + JSON.stringify(activeRequests, undefined, 4)) - } + context.core.logDebug('all reqs' + JSON.stringify(activeRequests, undefined, 4)) for (const req of activeRequests) { if (req.player !== undefined) { // Keep existing assignment - if (debugLog) { - context.logWarning('Retained mp' + req.player + ' for ' + req.id) - } + context.core.logDebug('Retained mp' + req.player + ' for ' + req.id) continue } const otherActive = _.filter(activeRequests, r => doesRequestOverlap(req, r)) - if (debugLog) { - context.logWarning(`for ${JSON.stringify(req)} there is: ${JSON.stringify(otherActive, undefined, 4)}`) - } + context.core.logDebug(`for ${JSON.stringify(req)} there is: ${JSON.stringify(otherActive, undefined, 4)}`) // TODO - what about playing the same piece back-to-back? - const nextPlayerId = findNextAvailablePlayer(config, otherActive, req) + const nextPlayerId = findNextAvailablePlayer(context.config, otherActive, req) if (nextPlayerId === undefined) { - context.logWarning('All the mediaplayers are in use (' + req.id + ')!') + context.core.logWarning('All the mediaplayers are in use (' + req.id + ')!') } else { for (const o of otherActive) { if (o.player === nextPlayerId) { - if (debugLog) { - context.logWarning('Stole mp from ' + o.id) - } + context.core.logDebug('Stole mp from ' + o.id) o.player = undefined } } req.player = nextPlayerId - if (debugLog) { - context.logWarning('Assigned mp' + req.player + ' to ' + req.id + '_' + JSON.stringify(req)) - } + context.core.logDebug('Assigned mp' + req.player + ' to ' + req.id + '_' + JSON.stringify(req)) } } - if (debugLog) { - context.logWarning('result' + JSON.stringify(activeRequests)) - } + context.core.logDebug('result' + JSON.stringify(activeRequests)) return activeRequests } @@ -280,8 +259,7 @@ function updateObjectsToMediaPlayer< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITimelineEventContext, - config: ShowStyleConfig, + context: ExtendedTimelineContext, playerId: number, objs: OnGenerateTimelineObj[], sourceLayers: ABSourceLayers @@ -297,14 +275,14 @@ function updateObjectsToMediaPlayer< obj.layer = (obj.layer + '').replace(obj.lookaheadForLayer.toString(), CasparPlayerClip(playerId)) obj.lookaheadForLayer = CasparPlayerClip(playerId) } else { - context.logWarning(`Moving object to mediaPlayer that probably shouldnt be? (from layer: ${obj.layer})`) + context.core.logWarning(`Moving object to mediaPlayer that probably shouldnt be? (from layer: ${obj.layer})`) // context.notifyUserWarning(obj) } } else if (obj.content.deviceType === TSR.DeviceType.ATEM) { - let atemInput = _.find(config.mediaPlayers, mp => mp.id === playerId.toString()) + let atemInput = _.find(context.config.mediaPlayers, mp => mp.id === playerId.toString()) if (!atemInput) { - context.logWarning(`Trying to find atem input for unknown mediaPlayer: #${playerId}`) - atemInput = { id: playerId.toString(), val: config.studio.AtemSource.Default.toString() } + context.core.logWarning(`Trying to find atem input for unknown mediaPlayer: #${playerId}`) + atemInput = { id: playerId.toString(), val: context.config.studio.AtemSource.Default.toString() } } const atemObj = obj as TSR.TimelineObjAtemAny @@ -328,7 +306,7 @@ function updateObjectsToMediaPlayer< } }) } else { - context.logWarning( + context.core.logWarning( `Trying to move ATEM object of unknown type (${atemObj.content.type}) for media player assignment` ) } @@ -346,7 +324,7 @@ function updateObjectsToMediaPlayer< obj.layer = (obj.layer + '').replace(obj.lookaheadForLayer.toString(), targetPlayer) obj.lookaheadForLayer = targetPlayer } else { - context.logWarning(`Moving object to mediaPlayer that probably shouldnt be? (from layer: ${obj.layer})`) + context.core.logWarning(`Moving object to mediaPlayer that probably shouldnt be? (from layer: ${obj.layer})`) // context.notifyUserWarning(obj) } } else if (obj.content.deviceType === TSR.DeviceType.ABSTRACT) { @@ -354,7 +332,7 @@ function updateObjectsToMediaPlayer< obj.layer = AbstractLLayerServerEnable(playerId) } } else { - context.logWarning( + context.core.logWarning( `Trying to move object of unknown type (${obj.content.deviceType}) for media player assignment` ) } @@ -365,19 +343,17 @@ export function assignMediaPlayers< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITimelineEventContext, - config: ShowStyleConfig, + context: ExtendedTimelineContext, timelineObjs: OnGenerateTimelineObj[], previousAssignment: TimelinePersistentStateExt['activeMediaPlayers'], resolvedPieces: Array>, sourceLayers: ABSourceLayers ): TimelinePersistentStateExt['activeMediaPlayers'] { const previousAssignmentRev = reversePreviousAssignment(previousAssignment, timelineObjs) - const activeRequests = resolveMediaPlayerAssignments(context, config, previousAssignmentRev, resolvedPieces) + const activeRequests = resolveMediaPlayerAssignments(context, previousAssignmentRev, resolvedPieces) return applyMediaPlayersAssignments( context, - config, timelineObjs, previousAssignmentRev, activeRequests, @@ -389,15 +365,13 @@ export function applyMediaPlayersAssignments< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITimelineEventContext, - config: ShowStyleConfig, + context: ExtendedTimelineContext, timelineObjs: OnGenerateTimelineObj[], previousAssignmentRev: SessionToPlayerMap, activeRequests: ActiveRequest[], sourceLayers: ABSourceLayers, resolvedPieces: IBlueprintResolvedPieceInstance[] ): TimelinePersistentStateExt['activeMediaPlayers'] { - const debugLog = config.studio.ABPlaybackDebugLogging const newAssignments: TimelinePersistentStateExt['activeMediaPlayers'] = {} const persistAssignment = (sessionId: string, playerId: number, lookahead: boolean) => { let ls = newAssignments[playerId] @@ -429,7 +403,7 @@ export function applyMediaPlayersAssignments< if (request) { if (request.player) { // TODO - what if player is undefined? - updateObjectsToMediaPlayer(context, config, Number(request.player) || 0, group, sourceLayers) + updateObjectsToMediaPlayer(context, Number(request.player) || 0, group, sourceLayers) persistAssignment(groupId, Number(request.player) || 0, false) } } else { @@ -463,13 +437,13 @@ export function applyMediaPlayersAssignments< const objIds = _.map(grp.objs, o => o.id) const prev = previousAssignmentRev[grp.id] if (prev) { - updateObjectsToMediaPlayer(context, config, prev.playerId, grp.objs, sourceLayers) + updateObjectsToMediaPlayer(context, prev.playerId, grp.objs, sourceLayers) persistAssignment(grp.id, prev.playerId, false) - context.logWarning( + context.core.logWarning( `Found unexpected session remaining on the timeline: "${grp.id}" belonging to ${objIds}. This may cause playback glitches` ) } else { - context.logWarning( + context.core.logWarning( `Found unexpected unknown session on the timeline: "${grp.id}" belonging to ${objIds}. This could result in black playback` ) } @@ -481,7 +455,7 @@ export function applyMediaPlayersAssignments< } let mediaPlayerUsageEnd: MediaPlayerUsageEnd[] = [] - for (const mp of config.mediaPlayers) { + for (const mp of context.config.mediaPlayers) { // Block players with an 'infinite' clip from being used for lookahead const endTimes = _.map( _.filter(activeRequests, s => s.player === mp.id), @@ -501,22 +475,16 @@ export function applyMediaPlayersAssignments< // Finish up with allocating lookahead based on what is left. If there is no space left that is not a problem until playback is closer for (const grp of lookaheadGroups) { - if (debugLog) { - context.logWarning(`Attempting assignment for future lookahead ${grp.id}`) - } + context.core.logDebug(`Attempting assignment for future lookahead ${grp.id}`) const prev = previousAssignmentRev[grp.id] let nextPlayer: MediaPlayerUsageEnd | undefined - if (debugLog) { - context.logWarning('Players are available at:' + JSON.stringify(mediaPlayerUsageEnd)) - } + context.core.logDebug('Players are available at:' + JSON.stringify(mediaPlayerUsageEnd)) const prevAssignment = prev ? _.find(mediaPlayerUsageEnd, mp => mp.playerId === prev.playerId) : undefined if (prevAssignment && (prevAssignment.end === 0 || false)) { // TODO - decide if the previous assignment is still suitable - if (debugLog) { - context.logWarning('lookahead can retain existing player') - } + context.core.logDebug('lookahead can retain existing player') nextPlayer = prevAssignment mediaPlayerUsageEnd = _.without(mediaPlayerUsageEnd, prevAssignment) } else { @@ -525,23 +493,18 @@ export function applyMediaPlayersAssignments< } if (nextPlayer === undefined) { - if (debugLog) { - context.logWarning('no player available for lookahead. This likely means one is in use by a playing clip') - } + context.core.logDebug('no player available for lookahead. This likely means one is in use by a playing clip') } else { - if (debugLog) { - context.logWarning(`lookahead chose: ${nextPlayer.playerId} (Free after: ${nextPlayer.end})`) - } + context.core.logDebug(`lookahead chose: ${nextPlayer.playerId} (Free after: ${nextPlayer.end})`) // Record the assignment, so that the next update can try and reuse it persistAssignment(grp.id, nextPlayer.playerId, true) - updateObjectsToMediaPlayer(context, config, nextPlayer.playerId, grp.objs, sourceLayers) + updateObjectsToMediaPlayer(context, nextPlayer.playerId, grp.objs, sourceLayers) } } - if (debugLog) { - context.logWarning('new assignments:' + JSON.stringify(newAssignments)) - } + context.core.logDebug('new assignments:' + JSON.stringify(newAssignments)) + return newAssignments } diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index ede3d2d5..a471105d 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -6,25 +6,25 @@ import { TableConfigItemValue, TSR } from 'blueprints-integration' -import { AtemLLayerDSK, literal, SourceLayerAtemDSK } from 'tv2-common' +import { AtemLLayerDSK, ExtendedShowStyleContext, literal, SourceLayerAtemDSK, VideoSwitcher } from 'tv2-common' import { AdlibTags, DSKRoles, SharedOutputLayers } from 'tv2-constants' import { ATEMModel } from '../../types/atem' -import { TV2BlueprintConfigBase, TV2StudioConfigBase } from '../blueprintConfig' +import { TV2BlueprintConfigBase, TV2ShowStyleConfig, TV2StudioConfigBase } from '../blueprintConfig' import { TableConfigItemDSK } from '../types' -export function FindDSKFullGFX(config: TV2BlueprintConfigBase): TableConfigItemDSK { +export function FindDSKFullGFX(config: TV2ShowStyleConfig): TableConfigItemDSK { return FindDSKWithRoles(config, [DSKRoles.FULLGFX]) } -export function FindDSKOverlayGFX(config: TV2BlueprintConfigBase): TableConfigItemDSK { +export function FindDSKOverlayGFX(config: TV2ShowStyleConfig): TableConfigItemDSK { return FindDSKWithRoles(config, [DSKRoles.OVERLAYGFX]) } -export function FindDSKJingle(config: TV2BlueprintConfigBase): TableConfigItemDSK { +export function FindDSKJingle(config: TV2ShowStyleConfig): TableConfigItemDSK { return FindDSKWithRoles(config, [DSKRoles.JINGLE]) } -function FindDSKWithRoles(config: TV2BlueprintConfigBase, roles: DSKRoles[]): TableConfigItemDSK { +function FindDSKWithRoles(config: TV2ShowStyleConfig, roles: DSKRoles[]): TableConfigItemDSK { return config.dsk.find(dsk => dsk.Roles?.some(role => roles.includes(role))) ?? config.dsk[0] } @@ -42,46 +42,42 @@ export function GetDSKCount(atemModel: ATEMModel) { } export function EnableDSK( - config: TV2BlueprintConfigBase, + context: ExtendedShowStyleContext, dsk: 'FULL' | 'OVL' | 'JINGLE', enable?: TSR.TSRTimelineObj['enable'] ): TSR.TSRTimelineObj[] { const dskConf = - dsk === 'FULL' ? FindDSKFullGFX(config) : dsk === 'OVL' ? FindDSKOverlayGFX(config) : FindDSKJingle(config) + dsk === 'FULL' + ? FindDSKFullGFX(context.config) + : dsk === 'OVL' + ? FindDSKOverlayGFX(context.config) + : FindDSKJingle(context.config) - return [ - literal({ - id: '', - enable: enable ?? { - start: 0 + return context.videoSwitcher.getDskTimelineObjects({ + id: '', + enable: enable ?? { + start: 0 + }, + priority: 1, + layer: AtemLLayerDSK(dskConf.Number), + content: { + onAir: true, + sources: { + fillSource: dskConf.Fill, + cutSource: dskConf.Key }, - priority: 1, - layer: AtemLLayerDSK(dskConf.Number), - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.DSK, - dsk: { - onAir: true, - sources: { - fillSource: dskConf.Fill, - cutSource: dskConf.Key - }, - properties: { - clip: Number(dskConf.Clip) * 10, - gain: Number(dskConf.Gain) * 10, - mask: { - enabled: false - } - } - } + properties: { + clip: Number(dskConf.Clip) * 10, + gain: Number(dskConf.Gain) * 10 } - }) - ] + } + }) } export function CreateDSKBaselineAdlibs( config: TV2BlueprintConfigBase, - baseRank: number + baseRank: number, + videoSwitcher: VideoSwitcher ): IBlueprintAdLibPiece[] { const adlibItems: IBlueprintAdLibPiece[] = [] for (const dsk of config.dsk) { @@ -97,21 +93,15 @@ export function CreateDSKBaselineAdlibs( tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_NO_NEXT_HIGHLIGHT, AdlibTags.ADLIB_DSK_OFF], invertOnAirState: true, content: { - timelineObjects: [ - literal({ - id: '', - enable: { while: '1' }, - priority: 10, - layer: AtemLLayerDSK(dsk.Number), - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.DSK, - dsk: { - onAir: false - } - } - }) - ] + timelineObjects: videoSwitcher.getDskTimelineObjects({ + id: '', + enable: { while: '1' }, + priority: 10, + layer: AtemLLayerDSK(dsk.Number), + content: { + onAir: false + } + }) } }) } else { @@ -124,34 +114,25 @@ export function CreateDSKBaselineAdlibs( lifespan: PieceLifespan.OutOnRundownChange, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_NO_NEXT_HIGHLIGHT, AdlibTags.ADLIB_DSK_ON], content: { - timelineObjects: [ - literal({ - id: '', - enable: { while: '1' }, - priority: 10, - layer: AtemLLayerDSK(dsk.Number), - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.DSK, - dsk: { - onAir: true, - sources: { - fillSource: dsk.Fill, - cutSource: dsk.Key - }, - properties: { - tie: false, - preMultiply: false, - clip: Number(dsk.Clip) * 10, // input is percents (0-100), atem uses 1-000, - gain: Number(dsk.Gain) * 10, // input is percents (0-100), atem uses 1-000, - mask: { - enabled: false - } - } - } + timelineObjects: videoSwitcher.getDskTimelineObjects({ + id: '', + enable: { while: '1' }, + priority: 10, + layer: AtemLLayerDSK(dsk.Number), // @todo + content: { + onAir: true, + sources: { + fillSource: dsk.Fill, + cutSource: dsk.Key + }, + properties: { + tie: false, + preMultiply: false, + clip: Number(dsk.Clip) * 10, // input is percents (0-100), atem uses 1-000, + gain: Number(dsk.Gain) * 10 // input is percents (0-100), atem uses 1-000, } - }) - ] + } + }) } }) } @@ -160,17 +141,18 @@ export function CreateDSKBaselineAdlibs( return adlibItems } -export function CreateDSKBaseline(config: TV2BlueprintConfigBase): TSR.TSRTimelineObj[] { - return config.dsk.map(dsk => { - return literal({ - id: '', - enable: { while: '1' }, - priority: 0, - layer: AtemLLayerDSK(dsk.Number), - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.DSK, - dsk: { +export function CreateDSKBaseline( + config: TV2BlueprintConfigBase, + videoSwitcher: VideoSwitcher +): TSR.TSRTimelineObj[] { + return config.dsk + .map(dsk => { + return videoSwitcher.getDskTimelineObjects({ + id: '', + enable: { while: '1' }, + priority: 0, + layer: AtemLLayerDSK(dsk.Number), // @todo + content: { onAir: dsk.DefaultOn, sources: { fillSource: dsk.Fill, @@ -180,15 +162,12 @@ export function CreateDSKBaseline(config: TV2BlueprintConfigBase + ) { + this.config = context.config + this.engine = cue.target + } + + public abstract getTemplateName(): string + + protected getGraphicDuration(): number | undefined { + if (this.config.showStyle.GfxTemplates) { + const template = this.findGfxTemplate() + if (template && template.OutType && !template.OutType.toString().match(/default/i)) { + return undefined + } + } + + return GetDefaultOut(this.config) + } + + protected getSourceLayerForGraphic(name: string) { + const conf = this.config.showStyle.GfxTemplates + ? this.config.showStyle.GfxTemplates.find(gfx => gfx.VizTemplate.toString() === name) + : undefined + + if (!conf) { + return SharedSourceLayers.PgmGraphicsOverlay + } + + switch (conf.SourceLayer) { + // TODO: When adding more sourcelayers + // This is here to guard against bad user input + case SharedSourceLayers.PgmGraphicsHeadline: + if (this.config.studio.GraphicsType === 'HTML') { + return SharedSourceLayers.PgmGraphicsLower + } + return SharedSourceLayers.PgmGraphicsHeadline + case SharedSourceLayers.PgmGraphicsIdent: + return SharedSourceLayers.PgmGraphicsIdent + case SharedSourceLayers.PgmGraphicsLower: + return SharedSourceLayers.PgmGraphicsLower + case SharedSourceLayers.PgmGraphicsOverlay: + return SharedSourceLayers.PgmGraphicsOverlay + case SharedSourceLayers.PgmGraphicsTLF: + return SharedSourceLayers.PgmGraphicsTLF + case SharedSourceLayers.PgmGraphicsTema: + return SharedSourceLayers.PgmGraphicsTema + case SharedSourceLayers.PgmGraphicsTop: + return SharedSourceLayers.PgmGraphicsTop + case SharedSourceLayers.WallGraphics: + return SharedSourceLayers.WallGraphics + default: + return SharedSourceLayers.PgmGraphicsOverlay + } + } + + protected createTimingGraphic(): { start: number; duration?: number } { + const ret: { start: number; duration?: number } = { start: 0, duration: 0 } + const start = this.cue.start ? CalculateTime(this.cue.start) : 0 + start !== undefined ? (ret.start = start) : (ret.start = 0) + + const duration = this.getGraphicDuration() + const end = this.cue.end + ? this.cue.end.infiniteMode + ? undefined + : CalculateTime(this.cue.end) + : duration + ? ret.start + duration + : undefined + ret.duration = end ? end - ret.start : undefined + + return ret + } + + protected GetEnableForGraphic(): TSR.TSRTimelineObj['enable'] { + if (IsTargetingWall(this.engine)) { + return GetEnableForWall() + } + + const timing = CreateTimingEnable(this.cue, GetDefaultOut(this.config)) + + if (!timing.lifespan) { + return timing.enable + } + + if (this.config.studio.PreventOverlayWithFull) { + return { + while: '!.full' + } + } else { + return { + start: 0 + } + } + } + + protected findGfxTemplate(): TableConfigItemGfxTemplate | undefined { + let graphicId: string | undefined + // @todo: this should be implemented in derivatives + if (GraphicIsInternal(this.cue)) { + graphicId = this.cue.graphic.template + } else if (GraphicIsPilot(this.cue)) { + graphicId = this.cue.graphic.vcpid.toString() + } + if (graphicId === undefined) { + return undefined + } + return this.config.showStyle.GfxTemplates.find(templ => + templ.INewsName ? templ.INewsName.toString().toUpperCase() === graphicId?.toUpperCase() : false + ) + } + + protected getPieceLifespan(): PieceLifespan { + if (IsTargetingWall(this.engine)) { + return PieceLifespan.OutOnShowStyleEnd + } + if (IsTargetingTLF(this.engine)) { + return PieceLifespan.WithinPart + } + if (this.cue.end?.infiniteMode) { + return LifeSpan(this.cue.end.infiniteMode) + } + if (this.cue.end && CalculateTime(this.cue.end)) { + return PieceLifespan.WithinPart + } + return this.FindInfiniteModeFromConfig() + } + + protected FindInfiniteModeFromConfig(): PieceLifespan { + const template = this.getTemplateName() + const iNewsName = GraphicIsInternal(this.cue) ? this.cue.graphic.template : undefined + const conf = this.config.showStyle.GfxTemplates.find(gfx => + gfx.VizTemplate + ? gfx.VizTemplate.toString().toUpperCase() === template.toUpperCase() && + (iNewsName ? gfx.INewsName.toUpperCase() === iNewsName.toUpperCase() : true) + : false + ) + + if (!conf) { + return PieceLifespan.WithinPart + } + + if (!conf.OutType || !conf.OutType.toString().length) { + return PieceLifespan.WithinPart + } + + const type = conf.OutType.toString().toUpperCase() + + if (type !== 'B' && type !== 'S' && type !== 'O') { + return PieceLifespan.WithinPart + } + + return LifeSpan(type) + } +} diff --git a/src/tv2-common/helpers/graphics/InternalGraphic.ts b/src/tv2-common/helpers/graphics/InternalGraphic.ts deleted file mode 100644 index d28c6861..00000000 --- a/src/tv2-common/helpers/graphics/InternalGraphic.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { IBlueprintAdLibPiece, IBlueprintPiece, IShowStyleUserContext, PieceLifespan } from 'blueprints-integration' -import _ = require('underscore') -import { AdlibTags, GraphicEngine, SharedOutputLayers, SharedSourceLayers } from '../../../tv2-constants' -import { TV2BlueprintConfig } from '../../blueprintConfig' -import { CueDefinitionGraphic, GraphicInternal, PartDefinition } from '../../inewsConversion' -import { GraphicPieceMetaData, PieceMetaData } from '../../onTimelineGenerate' -import { GetInternalGraphicContentCaspar } from './caspar' -import { GetSourceLayerForGraphic } from './layers' -import { GetFullGraphicTemplateNameFromCue, GraphicDisplayName } from './name' -import { IsTargetingTLF, IsTargetingWall } from './target' -import { CreateTimingGraphic, GetPieceLifespanForGraphic } from './timing' -import { GetInternalGraphicContentVIZ } from './viz' - -export class InternalGraphic { - public mappedTemplate: string - private readonly config: TV2BlueprintConfig - private readonly context: IShowStyleUserContext - private readonly parsedCue: CueDefinitionGraphic - private readonly partDefinition?: PartDefinition - private readonly engine: GraphicEngine - private readonly name: string - private readonly sourceLayerId: SharedSourceLayers - private readonly outputLayerId: SharedOutputLayers - private readonly partId?: string - private readonly rank?: number - private readonly content: IBlueprintPiece['content'] - - public constructor( - config: TV2BlueprintConfig, - context: IShowStyleUserContext, - parsedCue: CueDefinitionGraphic, - partId?: string, - partDefinition?: PartDefinition - ) { - const mappedTemplate = GetFullGraphicTemplateNameFromCue(config, parsedCue) - - const sourceLayerId = GetSourceLayerForGraphic(config, mappedTemplate) - - this.config = config - this.context = context - this.parsedCue = parsedCue - this.partDefinition = partDefinition - this.mappedTemplate = mappedTemplate - this.engine = parsedCue.target - this.name = GraphicDisplayName(config, parsedCue) - this.sourceLayerId = sourceLayerId - this.outputLayerId = IsTargetingWall(this.engine) ? SharedOutputLayers.SEC : SharedOutputLayers.OVERLAY - this.partId = partId - this.content = this.getInternalGraphicContent() - } - - public createCommentatorAdlib(): IBlueprintAdLibPiece { - return { - _rank: this.rank || 0, - externalId: this.partId ?? '', - name: this.name, - uniquenessId: `gfx_${this.name}_${this.sourceLayerId}_${this.outputLayerId}_commentator`, - sourceLayerId: this.sourceLayerId, - outputLayerId: SharedOutputLayers.OVERLAY, - lifespan: PieceLifespan.WithinPart, - metaData: { - sisyfosPersistMetaData: { - sisyfosLayers: [] - } - }, - expectedDuration: 5000, - tags: [AdlibTags.ADLIB_KOMMENTATOR], - content: _.clone(this.content) - } - } - - public createAdlib(): IBlueprintAdLibPiece { - return { - _rank: this.rank || 0, - externalId: this.partId ?? '', - name: this.name, - uniquenessId: `gfx_${this.name}_${this.sourceLayerId}_${this.outputLayerId}_flow`, - sourceLayerId: this.sourceLayerId, - outputLayerId: this.outputLayerId, - tags: [AdlibTags.ADLIB_FLOW_PRODUCER], - ...(IsTargetingTLF(this.engine) || (this.parsedCue.end && this.parsedCue.end.infiniteMode) - ? {} - : { - expectedDuration: CreateTimingGraphic(this.config, this.parsedCue).duration - }), - lifespan: GetPieceLifespanForGraphic(this.engine, this.config, this.parsedCue), - metaData: { - sisyfosPersistMetaData: { - sisyfosLayers: [] - } - }, - content: _.clone(this.content) - } - } - - public createPiece(): IBlueprintPiece { - return { - externalId: this.partId ?? '', - name: this.name, - ...(IsTargetingTLF(this.engine) || IsTargetingWall(this.engine) - ? { enable: { start: 0 } } - : { - enable: { - ...CreateTimingGraphic(this.config, this.parsedCue) - } - }), - outputLayerId: this.outputLayerId, - sourceLayerId: this.sourceLayerId, - lifespan: GetPieceLifespanForGraphic(this.engine, this.config, this.parsedCue), - metaData: { - sisyfosPersistMetaData: { - sisyfosLayers: [] - }, - partType: this.partDefinition?.type, - pieceExternalId: this.partDefinition?.externalId - }, - content: _.clone(this.content) - } - } - - private getInternalGraphicContent(): IBlueprintPiece['content'] { - return this.config.studio.GraphicsType === 'HTML' - ? GetInternalGraphicContentCaspar(this.config, this.engine, this.parsedCue, this.mappedTemplate) - : GetInternalGraphicContentVIZ(this.config, this.context, this.engine, this.parsedCue, this.mappedTemplate) - } -} diff --git a/src/tv2-common/helpers/graphics/caspar/HtmlInternalGraphic.ts b/src/tv2-common/helpers/graphics/caspar/HtmlInternalGraphic.ts new file mode 100644 index 00000000..a508409c --- /dev/null +++ b/src/tv2-common/helpers/graphics/caspar/HtmlInternalGraphic.ts @@ -0,0 +1,26 @@ +import { SomeContent, TSR, WithTimeline } from 'blueprints-integration' +import { CreateHTMLRendererContent, EnableDSK, GetTimelineLayerForGraphic, literal } from 'tv2-common' + +import { InternalGraphic } from '../internal' + +export class HtmlInternalGraphic extends InternalGraphic { + protected getContent(): WithTimeline { + return { + timelineObjects: this.getTimeline() + } + } + + protected getTimeline(): TSR.TSRTimelineObj[] { + return [ + literal({ + id: '', + enable: this.GetEnableForGraphic(), + priority: 1, + layer: GetTimelineLayerForGraphic(this.config, this.templateName), + content: CreateHTMLRendererContent(this.config, this.templateName, { ...this.cue.graphic.textFields }) + }), + // Assume DSK is off by default (config table) + ...EnableDSK(this.context, 'OVL') + ] + } +} diff --git a/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts b/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts index 77edb718..41d66d68 100644 --- a/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts +++ b/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts @@ -1,41 +1,17 @@ -import { IBlueprintRundownDB, PieceLifespan, PlaylistTimingType, TSR } from 'blueprints-integration' +import { PieceLifespan, TSR } from 'blueprints-integration' import { CueDefinitionGraphic, GraphicPilot, HtmlPilotGraphicGenerator, literal } from 'tv2-common' import { CueType, SharedGraphicLLayer } from 'tv2-constants' -import { SegmentUserContext } from '../../../../../__mocks__/context' -import { defaultShowStyleConfig, defaultStudioConfig } from '../../../../../tv2_afvd_showstyle/__tests__/configs' -import { getConfig, parseConfig as parseShowStyleConfig } from '../../../../../tv2_afvd_showstyle/helpers/config' -import { parseConfig as parseStudioConfig } from '../../../../../tv2_afvd_studio/helpers/config' -import mappingsDefaults from '../../../../../tv2_afvd_studio/migrations/mappings-defaults' +import { makeMockGalleryContext } from '../../../../../__mocks__/context' import { pilotGeneratorSettingsOfftube } from '../../../../../tv2_offtube_showstyle/cues/OfftubeGraphics' -const RUNDOWN_EXTERNAL_ID = 'TEST.SOFIE.JEST' function makeMockContext() { - const rundown = literal({ - externalId: RUNDOWN_EXTERNAL_ID, - name: RUNDOWN_EXTERNAL_ID, - _id: '', - showStyleVariantId: '', - timing: { - type: PlaylistTimingType.None - } - }) - const mockContext = new SegmentUserContext( - 'test', - mappingsDefaults, - parseStudioConfig, - parseShowStyleConfig, - rundown._id - ) - mockContext.studioConfig = defaultStudioConfig as any - mockContext.showStyleConfig = defaultShowStyleConfig as any - return mockContext + // @todo: perhaps make the tests run with two contexts + return makeMockGalleryContext() } function makeGenerator(cue: CueDefinitionGraphic) { const context = makeMockContext() - const config = getConfig(context) const generator = new HtmlPilotGraphicGenerator({ - config, context, partId: 'part01', parsedCue: cue, diff --git a/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts new file mode 100644 index 00000000..4a264d55 --- /dev/null +++ b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts @@ -0,0 +1,123 @@ +import { GraphicsContent, TSR, WithTimeline } from 'blueprints-integration' +import { + EnableDSK, + FindDSKFullGFX, + getHtmlTemplateName, + GetSisyfosTimelineObjForFull, + IsTargetingFull, + joinAssetToFolder, + joinAssetToNetworkPath, + layerToHTMLGraphicSlot, + literal, + PilotGraphicProps, + TimelineBlueprintExt +} from 'tv2-common' + +import { PilotGraphicGenerator } from '../pilot' + +export class HtmlPilotGraphicGenerator extends PilotGraphicGenerator { + private readonly layerMappingName + + constructor(graphicProps: PilotGraphicProps) { + super(graphicProps) + this.layerMappingName = this.getLayerMappingName() + } + public getContent(): WithTimeline { + const graphicFolder = this.config.studio.GraphicFolder ? `${this.config.studio.GraphicFolder}\\` : '' + const sceneName = this.getSceneName() + const fileName = joinAssetToFolder(this.config.studio.GraphicFolder, sceneName) + const absoluteFilePath = `${this.config.studio.HTMLGraphics.GraphicURL}\\${fileName}${this.config.studio.GraphicFileExtension}` + const payloadType = IsTargetingFull(this.engine) ? 'still' : 'overlay' + const templateData = { + display: 'program', + slots: { + [layerToHTMLGraphicSlot[this.layerMappingName]]: { + payload: { + type: payloadType, + url: encodeURI( + absoluteFilePath + + .replace(/\//g, '\\') // Replace forward slash with backward slash + .replace(/\\/g, '\\\\') // Replace every \ with \\ and encodURI. Double backslash means the HTML template will be able to parse the string correctly. encodeURI so Caspar doesn't mangle the data. + ), + noAnimation: false + }, + display: 'program' + } + }, + partialUpdate: !IsTargetingFull(this.engine) + } + return { + fileName, + path: joinAssetToNetworkPath( + this.config.studio.GraphicNetworkBasePath, + graphicFolder, + sceneName, + this.config.studio.GraphicFileExtension + ), + mediaFlowIds: [this.config.studio.GraphicMediaFlowId], + ignoreMediaObjectStatus: this.config.studio.GraphicIgnoreStatus, + ignoreBlackFrames: true, + ignoreFreezeFrame: true, + timelineObjects: [ + literal({ + id: '', + enable: { + while: '1' + }, + priority: 100, + layer: this.layerMappingName, + metaData: { templateData, fileName }, + content: { + deviceType: TSR.DeviceType.CASPARCG, + type: TSR.TimelineContentTypeCasparCg.TEMPLATE, + templateType: 'html', + name: getHtmlTemplateName(this.config), + data: templateData, + useStopCommand: false, + mixer: { + opacity: 100 + } + } + }), + ...(IsTargetingFull(this.engine) ? this.getFullPilotTimeline() : EnableDSK(this.context, 'OVL')) + ] + } + } + + protected getFullPilotTimeline(): TSR.TSRTimelineObj[] { + const fullDSK = FindDSKFullGFX(this.config) + return [ + literal({ + id: '', + enable: { + start: Number(this.config.studio.CasparPrerollDuration) + }, + priority: 1, + layer: this.settings.ProgramLayer, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.ME, + me: { + input: fullDSK.Fill, + transition: TSR.AtemTransitionStyle.WIPE, + transitionSettings: { + wipe: { + rate: Number(this.config.studio.HTMLGraphics.TransitionSettings.wipeRate), + pattern: 1, + reverseDirection: true, + borderSoftness: this.config.studio.HTMLGraphics.TransitionSettings.borderSoftness + } + } + } + } + }), + ...GetSisyfosTimelineObjForFull(this.config) + ] + } + + private getSceneName() { + const nameChunks = this.cue.graphic.name.split('/') + return nameChunks[nameChunks.length - 1] + } +} diff --git a/src/tv2-common/helpers/graphics/caspar/index.ts b/src/tv2-common/helpers/graphics/caspar/index.ts index 6c8968cd..810f82a8 100644 --- a/src/tv2-common/helpers/graphics/caspar/index.ts +++ b/src/tv2-common/helpers/graphics/caspar/index.ts @@ -1,314 +1,4 @@ export * from './slotMappings' - -import { GraphicsContent, IBlueprintPiece, TSR, WithTimeline } from 'blueprints-integration' -import { - CueDefinitionGraphic, - GetEnableForGraphic, - GetTimelineLayerForGraphic, - GraphicInternal, - joinAssetToFolder, - joinAssetToNetworkPath, - literal, - PilotGraphicProps, - TimelineBlueprintExt, - TV2BlueprintConfig -} from 'tv2-common' -import { GraphicEngine, SharedGraphicLLayer } from 'tv2-constants' -import { EnableDSK } from '../../dsk' -import { PilotGraphicGenerator } from '../pilot' -import { IsTargetingFull } from '../target' -import { layerToHTMLGraphicSlot, Slots } from './slotMappings' - -export interface CasparPilotGeneratorSettings { - createFullPilotTimelineForStudio(config: TV2BlueprintConfig): TSR.TSRTimelineObj[] -} - -export function GetInternalGraphicContentCaspar( - config: TV2BlueprintConfig, - engine: GraphicEngine, - parsedCue: CueDefinitionGraphic, - mappedTemplate: string -): IBlueprintPiece['content'] { - return { - timelineObjects: CasparOverlayTimeline(config, engine, parsedCue, mappedTemplate) - } -} - -export class HtmlPilotGraphicGenerator extends PilotGraphicGenerator { - private readonly layerMappingName - - constructor(graphicProps: PilotGraphicProps) { - super(graphicProps) - this.layerMappingName = this.getLayerMappingName() - } - public getContent(): WithTimeline { - const graphicFolder = this.config.studio.GraphicFolder ? `${this.config.studio.GraphicFolder}\\` : '' - const sceneName = this.getSceneName() - const fileName = joinAssetToFolder(this.config.studio.GraphicFolder, sceneName) - const absoluteFilePath = `${this.config.studio.HTMLGraphics.GraphicURL}\\${fileName}${this.config.studio.GraphicFileExtension}` - const payloadType = IsTargetingFull(this.engine) ? 'still' : 'overlay' - const templateData = { - display: 'program', - slots: { - [layerToHTMLGraphicSlot[this.layerMappingName]]: { - payload: { - type: payloadType, - url: encodeURI( - absoluteFilePath - - .replace(/\//g, '\\') // Replace forward slash with backward slash - .replace(/\\/g, '\\\\') // Replace every \ with \\ and encodURI. Double backslash means the HTML template will be able to parse the string correctly. encodeURI so Caspar doesn't mangle the data. - ), - noAnimation: false - }, - display: 'program' - } - }, - partialUpdate: !IsTargetingFull(this.engine) - } - return { - fileName, - path: joinAssetToNetworkPath( - this.config.studio.GraphicNetworkBasePath, - graphicFolder, - sceneName, - this.config.studio.GraphicFileExtension - ), - mediaFlowIds: [this.config.studio.GraphicMediaFlowId], - ignoreMediaObjectStatus: this.config.studio.GraphicIgnoreStatus, - ignoreBlackFrames: true, - ignoreFreezeFrame: true, - timelineObjects: [ - literal({ - id: '', - enable: { - while: '1' - }, - priority: 100, - layer: this.layerMappingName, - metaData: { templateData, fileName }, - content: { - deviceType: TSR.DeviceType.CASPARCG, - type: TSR.TimelineContentTypeCasparCg.TEMPLATE, - templateType: 'html', - name: getHtmlTemplateName(this.config), - data: templateData, - useStopCommand: false, - mixer: { - opacity: 100 - } - } - }), - ...(IsTargetingFull(this.engine) - ? this.settings.caspar.createFullPilotTimelineForStudio(this.config) - : EnableDSK(this.config, 'OVL')) - ] - } - } - - private getSceneName() { - const nameChunks = this.parsedCue.graphic.name.split('/') - return nameChunks[nameChunks.length - 1] - } -} - -function CasparOverlayTimeline( - config: TV2BlueprintConfig, - engine: GraphicEngine, - parsedCue: CueDefinitionGraphic, - mappedTemplate: string -): TSR.TSRTimelineObj[] { - return [ - literal({ - id: '', - enable: GetEnableForGraphic(config, engine, parsedCue), - priority: 1, - layer: GetTimelineLayerForGraphic(config, mappedTemplate), - content: CreateHTMLRendererContent(config, mappedTemplate, { ...parsedCue.graphic.textFields }) - }), - // Assume DSK is off by default (config table) - ...EnableDSK(config, 'OVL') - ] -} - -export function CreateHTMLRendererContent( - config: TV2BlueprintConfig, - mappedTemplate: string, - data: object -): TSR.TimelineObjCCGTemplate['content'] { - return { - deviceType: TSR.DeviceType.CASPARCG, - type: TSR.TimelineContentTypeCasparCg.TEMPLATE, - templateType: 'html', - name: getHtmlTemplateName(config), - data: { - display: 'program', - slots: getHtmlTemplateContent(config, mappedTemplate, data), - partialUpdate: true - }, - useStopCommand: false, - mixer: { - opacity: 100 - } - } -} - -function getHtmlTemplateContent(config: TV2BlueprintConfig, graphicTemplate: string, data: object): Partial { - const layer = GetTimelineLayerForGraphic(config, graphicTemplate) - - const slot = layerToHTMLGraphicSlot[layer] - - if (!slot) { - return {} - } - - return { - [slot]: { - display: 'program', - payload: { - type: graphicTemplate, - ...data - } - } - } -} - -export function getHtmlGraphicBaseline(config: TV2BlueprintConfig) { - const templateName = getHtmlTemplateName(config) - const partiallyUpdatableLayerMappings = [ - SharedGraphicLLayer.GraphicLLayerOverlayIdent, - SharedGraphicLLayer.GraphicLLayerOverlayLower, - SharedGraphicLLayer.GraphicLLayerOverlayTema, - SharedGraphicLLayer.GraphicLLayerOverlayTopt, - SharedGraphicLLayer.GraphicLLayerOverlayPilot, - SharedGraphicLLayer.GraphicLLayerLocators - ] - return [ - ...getSlotBaselineTimelineObjects(templateName, partiallyUpdatableLayerMappings), - getCompoundSlotBaselineTimelineObject(templateName, partiallyUpdatableLayerMappings), - getDesignBaselineTimelineObject(templateName), - getFullPilotBaselineTimelineObject(templateName) - ] -} - -function getSlotBaselineTimelineObjects( - templateName: string, - layerMappings: SharedGraphicLLayer[] -): TSR.TSRTimelineObj[] { - return layerMappings - .filter(layer => layerToHTMLGraphicSlot[layer]) - .map(layer => ({ - id: '', - enable: { - while: '1' - }, - priority: 0, - layer, - content: { - deviceType: TSR.DeviceType.CASPARCG, - type: TSR.TimelineContentTypeCasparCg.TEMPLATE, - templateType: 'html', - name: templateName, - data: { - display: 'program', - slots: { - [layerToHTMLGraphicSlot[layer]]: { - payload: {}, - display: 'hidden' - } - }, - partialUpdate: true - }, - useStopCommand: false - } - })) -} - -function getCompoundSlotBaselineTimelineObject( - templateName: string, - layerMappings: SharedGraphicLLayer[] -): TSR.TimelineObjCCGTemplate { - const slots = layerMappings.reduce((obj: Record, layer) => { - if (layerToHTMLGraphicSlot[layer]) { - obj[layerToHTMLGraphicSlot[layer]] = { - payload: {}, - display: 'hidden' - } - } - return obj - }, {}) - return { - id: '', - enable: { - while: '1' - }, - priority: 0, - layer: SharedGraphicLLayer.GraphicLLayerOverlay, - content: { - deviceType: TSR.DeviceType.CASPARCG, - type: TSR.TimelineContentTypeCasparCg.TEMPLATE, - templateType: 'html', - name: templateName, - data: { - display: 'program', - slots, - partialUpdate: true - }, - useStopCommand: false - } - } -} - -function getDesignBaselineTimelineObject(templateName: string): TSR.TimelineObjCCGTemplate { - return { - id: '', - enable: { - while: '1' - }, - priority: 0, - layer: SharedGraphicLLayer.GraphicLLayerDesign, - content: { - deviceType: TSR.DeviceType.CASPARCG, - type: TSR.TimelineContentTypeCasparCg.TEMPLATE, - templateType: 'html', - name: templateName, - data: { - display: 'program', - design: '', - partialUpdate: true - }, - useStopCommand: false - } - } -} - -function getFullPilotBaselineTimelineObject(templateName: string): TSR.TimelineObjCCGTemplate { - return { - id: '', - enable: { - while: '1' - }, - priority: 0, - layer: SharedGraphicLLayer.GraphicLLayerPilot, - content: { - deviceType: TSR.DeviceType.CASPARCG, - type: TSR.TimelineContentTypeCasparCg.TEMPLATE, - templateType: 'html', - name: templateName, - data: { - display: 'program', - slots: { - [layerToHTMLGraphicSlot[SharedGraphicLLayer.GraphicLLayerPilot]]: { - payload: {}, - display: 'hidden' - } - } - }, - useStopCommand: false - } - } -} - -export function getHtmlTemplateName(config: TV2BlueprintConfig) { - return joinAssetToFolder(config.selectedGfxSetup.HtmlPackageFolder, 'index') -} +export * from './htmlPilotGraphicGenerator' +export * from './HtmlInternalGraphic' +export * from './util' diff --git a/src/tv2-common/helpers/graphics/caspar/util.ts b/src/tv2-common/helpers/graphics/caspar/util.ts new file mode 100644 index 00000000..ac8c6f43 --- /dev/null +++ b/src/tv2-common/helpers/graphics/caspar/util.ts @@ -0,0 +1,195 @@ +import { TSR } from 'blueprints-integration' +import { + GetTimelineLayerForGraphic, + joinAssetToFolder, + layerToHTMLGraphicSlot, + Slots, + TV2ShowStyleConfig +} from 'tv2-common' +import { SharedGraphicLLayer } from 'tv2-constants' + +export function CreateHTMLRendererContent( + config: TV2ShowStyleConfig, + mappedTemplate: string, + data: object +): TSR.TimelineObjCCGTemplate['content'] { + return { + deviceType: TSR.DeviceType.CASPARCG, + type: TSR.TimelineContentTypeCasparCg.TEMPLATE, + templateType: 'html', + name: getHtmlTemplateName(config), + data: { + display: 'program', + slots: getHtmlTemplateContent(config, mappedTemplate, data), + partialUpdate: true + }, + useStopCommand: false, + mixer: { + opacity: 100 + } + } +} + +export function getHtmlTemplateContent( + config: TV2ShowStyleConfig, + graphicTemplate: string, + data: object +): Partial { + const layer = GetTimelineLayerForGraphic(config, graphicTemplate) + + const slot = layerToHTMLGraphicSlot[layer] + + if (!slot) { + return {} + } + + return { + [slot]: { + display: 'program', + payload: { + type: graphicTemplate, + ...data + } + } + } +} + +export function getHtmlGraphicBaseline(config: TV2ShowStyleConfig) { + const templateName = getHtmlTemplateName(config) + const partiallyUpdatableLayerMappings = [ + SharedGraphicLLayer.GraphicLLayerOverlayIdent, + SharedGraphicLLayer.GraphicLLayerOverlayLower, + SharedGraphicLLayer.GraphicLLayerOverlayTema, + SharedGraphicLLayer.GraphicLLayerOverlayTopt, + SharedGraphicLLayer.GraphicLLayerOverlayPilot, + SharedGraphicLLayer.GraphicLLayerLocators + ] + return [ + ...getSlotBaselineTimelineObjects(templateName, partiallyUpdatableLayerMappings), + getCompoundSlotBaselineTimelineObject(templateName, partiallyUpdatableLayerMappings), + getDesignBaselineTimelineObject(templateName), + getFullPilotBaselineTimelineObject(templateName) + ] +} + +function getSlotBaselineTimelineObjects( + templateName: string, + layerMappings: SharedGraphicLLayer[] +): TSR.TSRTimelineObj[] { + return layerMappings + .filter(layer => layerToHTMLGraphicSlot[layer]) + .map(layer => ({ + id: '', + enable: { + while: '1' + }, + priority: 0, + layer, + content: { + deviceType: TSR.DeviceType.CASPARCG, + type: TSR.TimelineContentTypeCasparCg.TEMPLATE, + templateType: 'html', + name: templateName, + data: { + display: 'program', + slots: { + [layerToHTMLGraphicSlot[layer]]: { + payload: {}, + display: 'hidden' + } + }, + partialUpdate: true + }, + useStopCommand: false + } + })) +} + +function getCompoundSlotBaselineTimelineObject( + templateName: string, + layerMappings: SharedGraphicLLayer[] +): TSR.TimelineObjCCGTemplate { + const slots = layerMappings.reduce((obj: Record, layer) => { + if (layerToHTMLGraphicSlot[layer]) { + obj[layerToHTMLGraphicSlot[layer]] = { + payload: {}, + display: 'hidden' + } + } + return obj + }, {}) + return { + id: '', + enable: { + while: '1' + }, + priority: 0, + layer: SharedGraphicLLayer.GraphicLLayerOverlay, + content: { + deviceType: TSR.DeviceType.CASPARCG, + type: TSR.TimelineContentTypeCasparCg.TEMPLATE, + templateType: 'html', + name: templateName, + data: { + display: 'program', + slots, + partialUpdate: true + }, + useStopCommand: false + } + } +} + +function getDesignBaselineTimelineObject(templateName: string): TSR.TimelineObjCCGTemplate { + return { + id: '', + enable: { + while: '1' + }, + priority: 0, + layer: SharedGraphicLLayer.GraphicLLayerDesign, + content: { + deviceType: TSR.DeviceType.CASPARCG, + type: TSR.TimelineContentTypeCasparCg.TEMPLATE, + templateType: 'html', + name: templateName, + data: { + display: 'program', + design: '', + partialUpdate: true + }, + useStopCommand: false + } + } +} + +function getFullPilotBaselineTimelineObject(templateName: string): TSR.TimelineObjCCGTemplate { + return { + id: '', + enable: { + while: '1' + }, + priority: 0, + layer: SharedGraphicLLayer.GraphicLLayerPilot, + content: { + deviceType: TSR.DeviceType.CASPARCG, + type: TSR.TimelineContentTypeCasparCg.TEMPLATE, + templateType: 'html', + name: templateName, + data: { + display: 'program', + slots: { + [layerToHTMLGraphicSlot[SharedGraphicLLayer.GraphicLLayerPilot]]: { + payload: {}, + display: 'hidden' + } + } + }, + useStopCommand: false + } + } +} + +export function getHtmlTemplateName(config: TV2ShowStyleConfig) { + return joinAssetToFolder(config.selectedGfxSetup.HtmlPackageFolder, 'index') +} diff --git a/src/tv2-common/helpers/graphics/design/index.ts b/src/tv2-common/helpers/graphics/design/index.ts index 1e07e763..f0311dca 100644 --- a/src/tv2-common/helpers/graphics/design/index.ts +++ b/src/tv2-common/helpers/graphics/design/index.ts @@ -3,17 +3,22 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece, - IShowStyleUserContext, PieceLifespan, TSR, WithTimeline } from 'blueprints-integration' -import { CalculateTime, CueDefinitionGraphicDesign, getHtmlTemplateName, literal, TV2BlueprintConfig } from 'tv2-common' +import { + CalculateTime, + CueDefinitionGraphicDesign, + ExtendedShowStyleContext, + getHtmlTemplateName, + literal, + TV2ShowStyleConfig +} from 'tv2-common' import { SharedGraphicLLayer, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' export function EvaluateDesignBase( - config: TV2BlueprintConfig, - context: IShowStyleUserContext, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], _actions: IBlueprintActionManifest[], @@ -24,7 +29,7 @@ export function EvaluateDesignBase( ) { const start = (parsedCue.start ? CalculateTime(parsedCue.start) : 0) ?? 0 if (!parsedCue.design || !parsedCue.design.length) { - context.notifyUserWarning(`No valid design found for ${parsedCue.design}`) + context.core.notifyUserWarning(`No valid design found for ${parsedCue.design}`) return } @@ -40,7 +45,7 @@ export function EvaluateDesignBase( fileName: parsedCue.design, path: parsedCue.design, ignoreMediaObjectStatus: true, - timelineObjects: designTimeline(config, parsedCue) + timelineObjects: designTimeline(context.config, parsedCue) }) }) } else { @@ -57,13 +62,13 @@ export function EvaluateDesignBase( fileName: parsedCue.design, path: parsedCue.design, ignoreMediaObjectStatus: true, - timelineObjects: designTimeline(config, parsedCue) + timelineObjects: designTimeline(context.config, parsedCue) }) }) } } -function designTimeline(config: TV2BlueprintConfig, parsedCue: CueDefinitionGraphicDesign): TSR.TSRTimelineObj[] { +function designTimeline(config: TV2ShowStyleConfig, parsedCue: CueDefinitionGraphicDesign): TSR.TSRTimelineObj[] { switch (config.studio.GraphicsType) { case 'HTML': return [ diff --git a/src/tv2-common/helpers/graphics/index.ts b/src/tv2-common/helpers/graphics/index.ts index 5e31ff82..0b478467 100644 --- a/src/tv2-common/helpers/graphics/index.ts +++ b/src/tv2-common/helpers/graphics/index.ts @@ -1,36 +1,13 @@ +export * from './Graphic' export * from './pilot' -export * from './pilot/create' export * from './caspar' export * from './viz' +export * from './pilot' +export * from './internal' export * from './name' export * from './timing' export * from './target' export * from './layers' export * from './internal' export * from './design' -import { IBlueprintPart, TSR } from 'blueprints-integration' -import { getHtmlGraphicBaseline, TV2BlueprintConfig } from 'tv2-common' - -export function ApplyFullGraphicPropertiesToPart(config: TV2BlueprintConfig, part: IBlueprintPart) { - const keepAliveDuration = - config.studio.GraphicsType === 'HTML' - ? config.studio.HTMLGraphics.KeepAliveDuration - : config.studio.VizPilotGraphics.KeepAliveDuration - if (part.inTransition === undefined) { - part.inTransition = { - partContentDelayDuration: 0, - blockTakeDuration: 0, - previousPartKeepaliveDuration: keepAliveDuration - } - } else { - part.inTransition.previousPartKeepaliveDuration = keepAliveDuration - } -} - -export function CreateGraphicBaseline(config: TV2BlueprintConfig): TSR.TSRTimelineObj[] { - if (config.studio.GraphicsType === 'VIZ') { - return [] - } else { - return getHtmlGraphicBaseline(config) - } -} +export * from './util' diff --git a/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts b/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts new file mode 100644 index 00000000..fb3e0454 --- /dev/null +++ b/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts @@ -0,0 +1,145 @@ +import { IBlueprintAdLibPiece, IBlueprintPiece, IShowStyleUserContext, PieceLifespan } from 'blueprints-integration' +import { + CueDefinitionGraphic, + ExtendedShowStyleContext, + GraphicInternal, + GraphicPieceMetaData, + HtmlInternalGraphic, + IsTargetingTLF, + IsTargetingWall, + PartDefinition, + PieceMetaData, + VizInternalGraphic +} from 'tv2-common' +import { AdlibTags, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' +import * as _ from 'underscore' + +import { Graphic } from '../Graphic' + +export abstract class InternalGraphic extends Graphic { + public static createInternalGraphicGenerator(graphicProps: InternalGraphicProps): InternalGraphic { + if (graphicProps.context.config.studio.GraphicsType === 'HTML') { + return new HtmlInternalGraphic(graphicProps) + } + return new VizInternalGraphic(graphicProps) + } + public readonly templateName: string + protected readonly cue: CueDefinitionGraphic + protected readonly core: IShowStyleUserContext + private readonly partDefinition?: PartDefinition + private readonly displayName: string + private readonly sourceLayerId: SharedSourceLayers + private readonly outputLayerId: SharedOutputLayers + private readonly partId?: string + private readonly rank?: number + private readonly content: IBlueprintPiece['content'] + + protected constructor(graphicProps: InternalGraphicProps) { + super(graphicProps.context, graphicProps.parsedCue) + this.templateName = this.getTemplateName() + this.sourceLayerId = this.getSourceLayerForGraphic(this.templateName) + this.core = graphicProps.context.core + this.context = graphicProps.context + this.cue = graphicProps.parsedCue + this.partDefinition = graphicProps.partDefinition + this.displayName = this.getDisplayName() + this.outputLayerId = IsTargetingWall(this.engine) ? SharedOutputLayers.SEC : SharedOutputLayers.OVERLAY + this.partId = graphicProps.partId + this.content = this.getContent() + } + + public createCommentatorAdlib(): IBlueprintAdLibPiece { + return { + _rank: this.rank || 0, + externalId: this.partId ?? '', + name: this.displayName, + uniquenessId: `gfx_${this.displayName}_${this.sourceLayerId}_${this.outputLayerId}_commentator`, + sourceLayerId: this.sourceLayerId, + outputLayerId: SharedOutputLayers.OVERLAY, + lifespan: PieceLifespan.WithinPart, + metaData: { + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }, + expectedDuration: 5000, + tags: [AdlibTags.ADLIB_KOMMENTATOR], + content: _.clone(this.content) + } + } + + public createAdlib(): IBlueprintAdLibPiece { + return { + _rank: this.rank || 0, + externalId: this.partId ?? '', + name: this.displayName, + uniquenessId: `gfx_${this.displayName}_${this.sourceLayerId}_${this.outputLayerId}_flow`, + sourceLayerId: this.sourceLayerId, + outputLayerId: this.outputLayerId, + tags: [AdlibTags.ADLIB_FLOW_PRODUCER], + ...(IsTargetingTLF(this.engine) || (this.cue.end && this.cue.end.infiniteMode) + ? {} + : { + expectedDuration: this.createTimingGraphic().duration + }), + lifespan: this.getPieceLifespan(), + metaData: { + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }, + content: _.clone(this.content) + } + } + + public createPiece(): IBlueprintPiece { + return { + externalId: this.partId ?? '', + name: this.displayName, + ...(IsTargetingTLF(this.engine) || IsTargetingWall(this.engine) + ? { enable: { start: 0 } } + : { + enable: this.createTimingGraphic() + }), + outputLayerId: this.outputLayerId, + sourceLayerId: this.sourceLayerId, + lifespan: this.getPieceLifespan(), + metaData: { + sisyfosPersistMetaData: { + sisyfosLayers: [] + }, + partType: this.partDefinition?.type, + pieceExternalId: this.partDefinition?.externalId + }, + content: _.clone(this.content) + } + } + + public getTemplateName(): string { + const iNewsTemplateName = this.cue.graphic.template + const template = this.config.showStyle.GfxTemplates.find(templ => + templ.INewsName ? templ.INewsName.toString().toUpperCase() === iNewsTemplateName.toUpperCase() : false + ) + if (template && template.VizTemplate.toString().length) { + return template.VizTemplate.toString() + } + + // This means unconfigured templates will still be supported, with default out. + return iNewsTemplateName + } + + public getDisplayName(): string { + return `${this.cue.graphic.template ? `${this.templateName}` : ''}${ + this.cue.graphic.textFields.length ? ' - ' : '' + }${this.cue.graphic.textFields.filter(txt => !txt.match(/^;.\.../i)).join('\n - ')}` + } + + protected abstract getContent(): IBlueprintPiece['content'] +} + +export interface InternalGraphicProps { + context: ExtendedShowStyleContext + parsedCue: CueDefinitionGraphic + partId?: string + partDefinition?: PartDefinition +} diff --git a/src/tv2-common/helpers/graphics/internal/create.ts b/src/tv2-common/helpers/graphics/internal/create.ts new file mode 100644 index 00000000..74358aed --- /dev/null +++ b/src/tv2-common/helpers/graphics/internal/create.ts @@ -0,0 +1,36 @@ +import { IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' +import { + Adlib, + CueDefinitionGraphic, + ExtendedShowStyleContext, + GraphicInternal, + InternalGraphic, + IsTargetingOVL, + PartDefinition +} from 'tv2-common' + +export function CreateInternalGraphic( + context: ExtendedShowStyleContext, + pieces: IBlueprintPiece[], + adlibPieces: IBlueprintAdLibPiece[], + partId: string, + parsedCue: CueDefinitionGraphic, + partDefinition: PartDefinition, + adlib?: Adlib +) { + const internalGraphic = InternalGraphic.createInternalGraphicGenerator({ context, parsedCue, partId, partDefinition }) + + if (!internalGraphic.templateName || !internalGraphic.templateName.length) { + context.core.notifyUserWarning(`No valid template found for ${parsedCue.graphic.template}`) + return + } + + if (adlib) { + if (IsTargetingOVL(parsedCue.target)) { + adlibPieces.push(internalGraphic.createCommentatorAdlib()) + } + adlibPieces.push(internalGraphic.createAdlib()) + } else { + pieces.push(internalGraphic.createPiece()) + } +} diff --git a/src/tv2-common/helpers/graphics/internal/index.ts b/src/tv2-common/helpers/graphics/internal/index.ts index 96f09685..63f892b1 100644 --- a/src/tv2-common/helpers/graphics/internal/index.ts +++ b/src/tv2-common/helpers/graphics/internal/index.ts @@ -1,37 +1,2 @@ -import { IBlueprintAdLibPiece, IBlueprintPiece, IShowStyleUserContext } from 'blueprints-integration' -import { - Adlib, - CueDefinitionGraphic, - GraphicInternal, - IsTargetingOVL, - PartDefinition, - TV2BlueprintConfig -} from 'tv2-common' -import { InternalGraphic } from '../InternalGraphic' - -export function CreateInternalGraphic( - config: TV2BlueprintConfig, - context: IShowStyleUserContext, - pieces: IBlueprintPiece[], - adlibPieces: IBlueprintAdLibPiece[], - partId: string, - parsedCue: CueDefinitionGraphic, - partDefinition: PartDefinition, - adlib?: Adlib -) { - const internalGraphic: InternalGraphic = new InternalGraphic(config, context, parsedCue, partId, partDefinition) - - if (!internalGraphic.mappedTemplate || !internalGraphic.mappedTemplate.length) { - context.notifyUserWarning(`No valid template found for ${parsedCue.graphic.template}`) - return - } - - if (adlib) { - if (IsTargetingOVL(parsedCue.target)) { - adlibPieces.push(internalGraphic.createCommentatorAdlib()) - } - adlibPieces.push(internalGraphic.createAdlib()) - } else { - pieces.push(internalGraphic.createPiece()) - } -} +export * from './InternalGraphic' +export * from './create' diff --git a/src/tv2-common/helpers/graphics/layers.ts b/src/tv2-common/helpers/graphics/layers.ts index 8c1254a8..5eb1e28a 100644 --- a/src/tv2-common/helpers/graphics/layers.ts +++ b/src/tv2-common/helpers/graphics/layers.ts @@ -1,43 +1,7 @@ -import { TV2BlueprintConfig } from 'tv2-common' -import { SharedGraphicLLayer, SharedSourceLayers } from 'tv2-constants' +import { TV2ShowStyleConfig } from 'tv2-common' +import { SharedGraphicLLayer } from 'tv2-constants' -export function GetSourceLayerForGraphic(config: TV2BlueprintConfig, name: string) { - const conf = config.showStyle.GfxTemplates - ? config.showStyle.GfxTemplates.find(gfx => gfx.VizTemplate.toString() === name) - : undefined - - if (!conf) { - return SharedSourceLayers.PgmGraphicsOverlay - } - - switch (conf.SourceLayer) { - // TODO: When adding more sourcelayers - // This is here to guard against bad user input - case SharedSourceLayers.PgmGraphicsHeadline: - if (config.studio.GraphicsType === 'HTML') { - return SharedSourceLayers.PgmGraphicsLower - } - return SharedSourceLayers.PgmGraphicsHeadline - case SharedSourceLayers.PgmGraphicsIdent: - return SharedSourceLayers.PgmGraphicsIdent - case SharedSourceLayers.PgmGraphicsLower: - return SharedSourceLayers.PgmGraphicsLower - case SharedSourceLayers.PgmGraphicsOverlay: - return SharedSourceLayers.PgmGraphicsOverlay - case SharedSourceLayers.PgmGraphicsTLF: - return SharedSourceLayers.PgmGraphicsTLF - case SharedSourceLayers.PgmGraphicsTema: - return SharedSourceLayers.PgmGraphicsTema - case SharedSourceLayers.PgmGraphicsTop: - return SharedSourceLayers.PgmGraphicsTop - case SharedSourceLayers.WallGraphics: - return SharedSourceLayers.WallGraphics - default: - return SharedSourceLayers.PgmGraphicsOverlay - } -} - -export function GetTimelineLayerForGraphic(config: TV2BlueprintConfig, name: string) { +export function GetTimelineLayerForGraphic(config: TV2ShowStyleConfig, name: string) { const conf = config.showStyle.GfxTemplates ? config.showStyle.GfxTemplates.find(gfx => gfx.VizTemplate.toString() === name) : undefined diff --git a/src/tv2-common/helpers/graphics/name.ts b/src/tv2-common/helpers/graphics/name.ts index 413054aa..bd13160d 100644 --- a/src/tv2-common/helpers/graphics/name.ts +++ b/src/tv2-common/helpers/graphics/name.ts @@ -1,46 +1,24 @@ import { CueDefinitionGraphic, GraphicInternalOrPilot, - GraphicIsInternal, - GraphicIsPilot, - TV2BlueprintConfig + // GraphicIsInternal, + // GraphicIsPilot, + TV2ShowStyleConfig } from 'tv2-common' export function GraphicDisplayName( - config: TV2BlueprintConfig, + _config: TV2ShowStyleConfig, parsedCue: CueDefinitionGraphic ): string { - if (GraphicIsInternal(parsedCue)) { - return `${parsedCue.graphic.template ? `${GetFullGraphicTemplateNameFromCue(config, parsedCue)}` : ''}${ - parsedCue.graphic.textFields.length ? ' - ' : '' - }${parsedCue.graphic.textFields.filter(txt => !txt.match(/^;.\.../i)).join('\n - ')}` - } else if (GraphicIsPilot(parsedCue)) { - return `${parsedCue.graphic.name ? parsedCue.graphic.name : ''}` - } + // @todo: bring this back + // if (GraphicIsInternal(parsedCue)) { + // return `${parsedCue.graphic.template ? `${GetFullGraphicTemplateNameFromCue(config, parsedCue)}` : ''}${ + // parsedCue.graphic.textFields.length ? ' - ' : '' + // }${parsedCue.graphic.textFields.filter(txt => !txt.match(/^;.\.../i)).join('\n - ')}` + // } else if (GraphicIsPilot(parsedCue)) { + // return `${parsedCue.graphic.name ? parsedCue.graphic.name : ''}` + // } // Shouldn't be possible return parsedCue.iNewsCommand } - -export function GetFullGraphicTemplateNameFromCue( - config: TV2BlueprintConfig, - cue: CueDefinitionGraphic -): string { - if (cue.graphic.type === 'pilot') { - return cue.graphic.name - } else { - return GetFullGrafikTemplateName(config, cue.graphic.template) - } -} - -export function GetFullGrafikTemplateName(config: TV2BlueprintConfig, iNewsTemplateName: string): string { - const template = config.showStyle.GfxTemplates.find(templ => - templ.INewsName ? templ.INewsName.toString().toUpperCase() === iNewsTemplateName.toUpperCase() : false - ) - if (template && template.VizTemplate.toString().length) { - return template.VizTemplate.toString() - } - - // This means unconfigured templates will still be supported, with default out. - return iNewsTemplateName -} diff --git a/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts new file mode 100644 index 00000000..39ebeaa9 --- /dev/null +++ b/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts @@ -0,0 +1,242 @@ +import { + GraphicsContent, + IBlueprintActionManifest, + IBlueprintAdLibPiece, + IBlueprintPiece, + IShowStyleUserContext, + PieceLifespan, + TSR, + WithTimeline +} from 'blueprints-integration' +import { + ActionSelectFullGrafik, + Adlib, + assertUnreachable, + CueDefinitionGraphic, + ExtendedShowStyleContext, + FullPieceMetaData, + generateExternalId, + GetTagForFull, + GetTagForFullNext, + GraphicPilot, + HtmlPilotGraphicGenerator, + IsTargetingFull, + IsTargetingWall, + literal, + PieceMetaData, + SisyfosPersistMetaData, + t, + TV2ShowStyleConfig, + VizPilotGraphicGenerator +} from 'tv2-common' +import { + AdlibActionType, + AdlibTags, + GraphicEngine, + SharedGraphicLLayer, + SharedOutputLayers, + SharedSourceLayers, + TallyTags +} from 'tv2-constants' +import { Graphic } from '../index' + +export interface PilotGeneratorSettings { + ProgramLayer: string + AuxProgramLayer?: string +} + +export interface PilotGraphicProps { + context: ExtendedShowStyleContext + partId: string + parsedCue: CueDefinitionGraphic + settings: PilotGeneratorSettings + adlib?: Adlib + segmentExternalId: string +} + +export abstract class PilotGraphicGenerator extends Graphic { + public static createPilotGraphicGenerator(graphicProps: PilotGraphicProps): PilotGraphicGenerator { + if (graphicProps.context.config.studio.GraphicsType === 'HTML') { + return new HtmlPilotGraphicGenerator(graphicProps) + } + return new VizPilotGraphicGenerator(graphicProps) + } + protected readonly config: TV2ShowStyleConfig + protected readonly core: IShowStyleUserContext + protected readonly engine: GraphicEngine + protected readonly partId: string + protected readonly cue: CueDefinitionGraphic + protected readonly settings: PilotGeneratorSettings + protected readonly adlib?: Adlib + protected readonly segmentExternalId: string + + protected constructor(graphicProps: PilotGraphicProps) { + super(graphicProps.context, graphicProps.parsedCue) + this.config = graphicProps.context.config + this.core = graphicProps.context.core + this.engine = graphicProps.parsedCue.target + this.cue = graphicProps.parsedCue + this.partId = graphicProps.partId + this.settings = graphicProps.settings + this.adlib = graphicProps.adlib + this.segmentExternalId = graphicProps.segmentExternalId + } + + public abstract getContent(): WithTimeline + + public createFullPilotAdLibAction(): IBlueprintActionManifest { + const name = this.getTemplateName() + const sourceLayerId = this.getSourceLayer() + const outputLayerId = this.getOutputLayer() + + const userData: ActionSelectFullGrafik = { + type: AdlibActionType.SELECT_FULL_GRAFIK, + name: this.cue.graphic.name, + vcpid: this.cue.graphic.vcpid, + segmentExternalId: this.segmentExternalId + } + return { + externalId: generateExternalId(this.core, userData), + actionId: AdlibActionType.SELECT_FULL_GRAFIK, + userData, + userDataManifest: {}, + display: { + _rank: (this.adlib && this.adlib.rank) || 0, + label: t(this.getTemplateName()), + sourceLayerId: SharedSourceLayers.PgmPilot, + outputLayerId: SharedOutputLayers.PGM, + content: this.getContent(), + uniquenessId: `gfx_${name}_${sourceLayerId}_${outputLayerId}`, + tags: [ + AdlibTags.ADLIB_KOMMENTATOR, + ...(this.config.showStyle.MakeAdlibsForFulls && IsTargetingFull(this.engine) + ? [AdlibTags.ADLIB_FLOW_PRODUCER] + : []) + ], + currentPieceTags: [GetTagForFull(this.segmentExternalId, this.cue.graphic.vcpid)], + nextPieceTags: [GetTagForFullNext(this.segmentExternalId, this.cue.graphic.vcpid)] + } + } + } + + public createPiece(): IBlueprintPiece { + return { + externalId: this.partId, + name: this.getTemplateName(), + ...(IsTargetingFull(this.engine) || IsTargetingWall(this.engine) + ? { enable: { start: 0 } } + : { + enable: this.createTimingGraphic() + }), + outputLayerId: this.getOutputLayer(), + sourceLayerId: this.getSourceLayer(), + prerollDuration: this.getPrerollDuration(), + lifespan: this.getPieceLifespan(), + metaData: { + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }, + content: this.getContent(), + tags: IsTargetingFull(this.engine) + ? [GetTagForFull(this.segmentExternalId, this.cue.graphic.vcpid), TallyTags.FULL_IS_LIVE] + : [] + } + } + + public createAdlibPiece(rank?: number): IBlueprintAdLibPiece { + const pilotPiece = this.createPiece() + pilotPiece.tags = [...(pilotPiece.tags ?? []), AdlibTags.ADLIB_FLOW_PRODUCER, AdlibTags.ADLIB_KOMMENTATOR] + return { + ...pilotPiece, + _rank: rank ?? 0 + } + } + + public createFullDataStore(): IBlueprintPiece { + const content = this.getContent() + content.timelineObjects = content.timelineObjects.filter( + o => + o.content.deviceType !== TSR.DeviceType.ATEM && + o.content.deviceType !== TSR.DeviceType.SISYFOS && + o.content.deviceType !== TSR.DeviceType.VIZMSE && + o.content.deviceType !== TSR.DeviceType.CASPARCG + ) + return { + externalId: this.partId, + name: this.getTemplateName(), + enable: { + start: 0 + }, + outputLayerId: SharedOutputLayers.SELECTED_ADLIB, + sourceLayerId: SharedSourceLayers.SelectedAdlibGraphicsFull, + lifespan: PieceLifespan.OutOnSegmentEnd, + metaData: { + userData: { + type: AdlibActionType.SELECT_FULL_GRAFIK, + name: this.cue.graphic.name, + vcpid: this.cue.graphic.vcpid, + segmentExternalId: this.segmentExternalId + }, + sisyfosPersistMetaData: literal({ + sisyfosLayers: [] + }) + }, + content, + tags: [GetTagForFullNext(this.segmentExternalId, this.cue.graphic.vcpid)] + } + } + + public getTemplateName(): string { + return this.cue.graphic.name + } + + protected getPrerollDuration(): number { + return this.config.studio.GraphicsType === 'HTML' + ? this.config.studio.CasparPrerollDuration + : this.config.studio.VizPilotGraphics.PrerollDuration + } + + protected getSourceLayer(): SharedSourceLayers { + switch (this.engine) { + case 'WALL': + return SharedSourceLayers.WallGraphics + case 'TLF': + return SharedSourceLayers.PgmGraphicsTLF + case 'OVL': + return SharedSourceLayers.PgmPilotOverlay + case 'FULL': + return SharedSourceLayers.PgmPilot + default: + assertUnreachable(this.engine) + } + } + + protected getOutputLayer(): SharedOutputLayers { + switch (this.engine) { + case 'WALL': + return SharedOutputLayers.SEC + case 'OVL': + return SharedOutputLayers.OVERLAY + case 'FULL': + case 'TLF': + return SharedOutputLayers.PGM + default: + assertUnreachable(this.engine) + } + } + + protected getLayerMappingName(): SharedGraphicLLayer { + switch (this.engine) { + case 'WALL': + return SharedGraphicLLayer.GraphicLLayerWall + case 'OVL': + return SharedGraphicLLayer.GraphicLLayerOverlayPilot + case 'FULL': + case 'TLF': + return SharedGraphicLLayer.GraphicLLayerPilot + default: + assertUnreachable(this.engine) + } + } +} diff --git a/src/tv2-common/helpers/graphics/pilot/create.ts b/src/tv2-common/helpers/graphics/pilot/create.ts index 84a7b692..8e384d4f 100644 --- a/src/tv2-common/helpers/graphics/pilot/create.ts +++ b/src/tv2-common/helpers/graphics/pilot/create.ts @@ -9,7 +9,7 @@ export function CreatePilotGraphic( ) { const { context, adlib, parsedCue } = pilotGraphicProps if (parsedCue.graphic.vcpid < 0) { - context.notifyUserWarning('No valid VCPID provided') + context.core.notifyUserWarning('No valid VCPID provided') return } diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index 18a503b3..34d64000 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -1,245 +1,2 @@ -import { - GraphicsContent, - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPiece, - IShowStyleUserContext, - PieceLifespan, - TSR, - WithTimeline -} from 'blueprints-integration' -import { - ActionSelectFullGrafik, - Adlib, - assertUnreachable, - CasparPilotGeneratorSettings, - CreateTimingGraphic, - CueDefinitionGraphic, - FullPieceMetaData, - generateExternalId, - GetFullGraphicTemplateNameFromCue, - GetPieceLifespanForGraphic, - GetTagForFull, - GetTagForFullNext, - GraphicDisplayName, - GraphicPilot, - HtmlPilotGraphicGenerator, - IsTargetingFull, - IsTargetingWall, - literal, - PieceMetaData, - SisyfosPersistMetaData, - t, - TV2BlueprintConfig, - VizPilotGeneratorSettings, - VizPilotGraphicGenerator -} from 'tv2-common' -import { - AdlibActionType, - AdlibTags, - GraphicEngine, - SharedGraphicLLayer, - SharedOutputLayers, - SharedSourceLayers, - TallyTags -} from 'tv2-constants' - -// Work needed, this should be more generic than expecting showstyles to define how to display pilot graphics -export interface PilotGeneratorSettings { - caspar: CasparPilotGeneratorSettings - viz: VizPilotGeneratorSettings -} - -export interface PilotGraphicProps { - config: TV2BlueprintConfig - context: IShowStyleUserContext - partId: string - parsedCue: CueDefinitionGraphic - settings: PilotGeneratorSettings - adlib?: Adlib - segmentExternalId: string -} - -export abstract class PilotGraphicGenerator { - public static createPilotGraphicGenerator(graphicProps: PilotGraphicProps): PilotGraphicGenerator { - if (graphicProps.config.studio.GraphicsType === 'HTML') { - return new HtmlPilotGraphicGenerator(graphicProps) - } - return new VizPilotGraphicGenerator(graphicProps) - } - protected readonly config: TV2BlueprintConfig - protected readonly context: IShowStyleUserContext - protected readonly engine: GraphicEngine - protected readonly partId: string - protected readonly parsedCue: CueDefinitionGraphic - protected readonly settings: PilotGeneratorSettings - protected readonly adlib?: Adlib - protected readonly segmentExternalId: string - - protected constructor(graphicProps: PilotGraphicProps) { - this.config = graphicProps.config - this.context = graphicProps.context - this.engine = graphicProps.parsedCue.target - this.parsedCue = graphicProps.parsedCue - this.partId = graphicProps.partId - this.settings = graphicProps.settings - this.adlib = graphicProps.adlib - this.segmentExternalId = graphicProps.segmentExternalId - } - - public abstract getContent(): WithTimeline - - public createFullPilotAdLibAction(): IBlueprintActionManifest { - const name = GraphicDisplayName(this.config, this.parsedCue) - const sourceLayerId = this.getSourceLayer() - const outputLayerId = this.getOutputLayer() - - const userData: ActionSelectFullGrafik = { - type: AdlibActionType.SELECT_FULL_GRAFIK, - name: this.parsedCue.graphic.name, - vcpid: this.parsedCue.graphic.vcpid, - segmentExternalId: this.segmentExternalId - } - return { - externalId: generateExternalId(this.context, userData), - actionId: AdlibActionType.SELECT_FULL_GRAFIK, - userData, - userDataManifest: {}, - display: { - _rank: (this.adlib && this.adlib.rank) || 0, - label: t(GetFullGraphicTemplateNameFromCue(this.config, this.parsedCue)), - sourceLayerId: SharedSourceLayers.PgmPilot, - outputLayerId: SharedOutputLayers.PGM, - content: this.getContent(), - uniquenessId: `gfx_${name}_${sourceLayerId}_${outputLayerId}`, - tags: [ - AdlibTags.ADLIB_KOMMENTATOR, - ...(this.config.showStyle.MakeAdlibsForFulls && IsTargetingFull(this.engine) - ? [AdlibTags.ADLIB_FLOW_PRODUCER] - : []) - ], - currentPieceTags: [GetTagForFull(this.segmentExternalId, this.parsedCue.graphic.vcpid)], - nextPieceTags: [GetTagForFullNext(this.segmentExternalId, this.parsedCue.graphic.vcpid)] - } - } - } - - public createPiece(): IBlueprintPiece { - return { - externalId: this.partId, - name: GraphicDisplayName(this.config, this.parsedCue), - ...(IsTargetingFull(this.engine) || IsTargetingWall(this.engine) - ? { enable: { start: 0 } } - : { - enable: { - ...CreateTimingGraphic(this.config, this.parsedCue) - } - }), - outputLayerId: this.getOutputLayer(), - sourceLayerId: this.getSourceLayer(), - prerollDuration: this.getPrerollDuration(), - lifespan: GetPieceLifespanForGraphic(this.engine, this.config, this.parsedCue), - metaData: { - sisyfosPersistMetaData: { - sisyfosLayers: [] - } - }, - content: this.getContent(), - tags: IsTargetingFull(this.engine) - ? [GetTagForFull(this.segmentExternalId, this.parsedCue.graphic.vcpid), TallyTags.FULL_IS_LIVE] - : [] - } - } - - public createAdlibPiece(rank?: number): IBlueprintAdLibPiece { - const pilotPiece = this.createPiece() - pilotPiece.tags = [...(pilotPiece.tags ?? []), AdlibTags.ADLIB_FLOW_PRODUCER, AdlibTags.ADLIB_KOMMENTATOR] - return { - ...pilotPiece, - _rank: rank ?? 0 - } - } - - public createFullDataStore(): IBlueprintPiece { - const content = this.getContent() - content.timelineObjects = content.timelineObjects.filter( - o => - o.content.deviceType !== TSR.DeviceType.ATEM && - o.content.deviceType !== TSR.DeviceType.SISYFOS && - o.content.deviceType !== TSR.DeviceType.VIZMSE && - o.content.deviceType !== TSR.DeviceType.CASPARCG - ) - return { - externalId: this.partId, - name: GraphicDisplayName(this.config, this.parsedCue), - enable: { - start: 0 - }, - outputLayerId: SharedOutputLayers.SELECTED_ADLIB, - sourceLayerId: SharedSourceLayers.SelectedAdlibGraphicsFull, - lifespan: PieceLifespan.OutOnSegmentEnd, - metaData: { - userData: { - type: AdlibActionType.SELECT_FULL_GRAFIK, - name: this.parsedCue.graphic.name, - vcpid: this.parsedCue.graphic.vcpid, - segmentExternalId: this.segmentExternalId - }, - sisyfosPersistMetaData: literal({ - sisyfosLayers: [] - }) - }, - content, - tags: [GetTagForFullNext(this.segmentExternalId, this.parsedCue.graphic.vcpid)] - } - } - - protected getPrerollDuration(): number { - return this.config.studio.GraphicsType === 'HTML' - ? this.config.studio.CasparPrerollDuration - : this.config.studio.VizPilotGraphics.PrerollDuration - } - - protected getSourceLayer(): SharedSourceLayers { - switch (this.engine) { - case 'WALL': - return SharedSourceLayers.WallGraphics - case 'TLF': - return SharedSourceLayers.PgmGraphicsTLF - case 'OVL': - return SharedSourceLayers.PgmPilotOverlay - case 'FULL': - return SharedSourceLayers.PgmPilot - default: - assertUnreachable(this.engine) - } - } - - protected getOutputLayer(): SharedOutputLayers { - switch (this.engine) { - case 'WALL': - return SharedOutputLayers.SEC - case 'OVL': - return SharedOutputLayers.OVERLAY - case 'FULL': - case 'TLF': - return SharedOutputLayers.PGM - default: - assertUnreachable(this.engine) - } - } - - protected getLayerMappingName(): SharedGraphicLLayer { - switch (this.engine) { - case 'WALL': - return SharedGraphicLLayer.GraphicLLayerWall - case 'OVL': - return SharedGraphicLLayer.GraphicLLayerOverlayPilot - case 'FULL': - case 'TLF': - return SharedGraphicLLayer.GraphicLLayerPilot - default: - assertUnreachable(this.engine) - } - } -} +export * from './PilotGraphicGenerator' +export * from './create' diff --git a/src/tv2-common/helpers/graphics/timing.ts b/src/tv2-common/helpers/graphics/timing.ts index 465efc8e..c26cb2d8 100644 --- a/src/tv2-common/helpers/graphics/timing.ts +++ b/src/tv2-common/helpers/graphics/timing.ts @@ -1,149 +1,8 @@ -import { PieceLifespan, TSR } from 'blueprints-integration' -import { - CalculateTime, - CreateTimingEnable, - CueDefinitionGraphic, - GetDefaultOut, - GraphicInternalOrPilot, - GraphicIsInternal, - GraphicIsPilot, - LifeSpan, - TableConfigItemGfxTemplate, - TV2BlueprintConfig -} from 'tv2-common' -import { GraphicEngine } from 'tv2-constants' -import { GetFullGraphicTemplateNameFromCue, IsTargetingTLF, IsTargetingWall } from '.' - -export function GetPieceLifespanForGraphic( - engine: GraphicEngine, - config: TV2BlueprintConfig, - parsedCue: CueDefinitionGraphic -): PieceLifespan { - if (IsTargetingWall(engine)) { - return PieceLifespan.OutOnShowStyleEnd - } - if (IsTargetingTLF(engine)) { - return PieceLifespan.WithinPart - } - if (parsedCue.end?.infiniteMode) { - return LifeSpan(parsedCue.end.infiniteMode) - } - if (parsedCue.end && CalculateTime(parsedCue.end)) { - return PieceLifespan.WithinPart - } - return FindInfiniteModeFromConfig(config, parsedCue) -} - -export function FindInfiniteModeFromConfig( - config: TV2BlueprintConfig, - parsedCue: CueDefinitionGraphic -): PieceLifespan { - const template = GetFullGraphicTemplateNameFromCue(config, parsedCue) - const iNewsName = GraphicIsInternal(parsedCue) ? parsedCue.graphic.template : undefined - const conf = config.showStyle.GfxTemplates.find(cnf => - cnf.VizTemplate - ? cnf.VizTemplate.toString().toUpperCase() === template.toUpperCase() && - (iNewsName ? cnf.INewsName.toUpperCase() === iNewsName.toUpperCase() : true) - : false - ) - - if (!conf) { - return PieceLifespan.WithinPart - } - - if (!conf.OutType || !conf.OutType.toString().length) { - return PieceLifespan.WithinPart - } - - const type = conf.OutType.toString().toUpperCase() - - if (type !== 'B' && type !== 'S' && type !== 'O') { - return PieceLifespan.WithinPart - } - - return LifeSpan(type) -} - -export function GetGraphicDuration( - config: TV2BlueprintConfig, - cue: CueDefinitionGraphic -): number | undefined { - if (config.showStyle.GfxTemplates) { - const template = findGfxTemplate(config, cue) - if (template && template.OutType && !template.OutType.toString().match(/default/i)) { - return undefined - } - } - - return GetDefaultOut(config) -} - -export function CreateTimingGraphic( - config: TV2BlueprintConfig, - cue: CueDefinitionGraphic -): { start: number; duration?: number } { - const ret: { start: number; duration?: number } = { start: 0, duration: 0 } - const start = cue.start ? CalculateTime(cue.start) : 0 - start !== undefined ? (ret.start = start) : (ret.start = 0) - - const duration = GetGraphicDuration(config, cue) - const end = cue.end - ? cue.end.infiniteMode - ? undefined - : CalculateTime(cue.end) - : duration - ? ret.start + duration - : undefined - ret.duration = end ? end - ret.start : undefined - - return ret -} +import { TSR } from 'blueprints-integration' +// @todo: this has to go somewhere export function GetEnableForWall(): TSR.TSRTimelineObj['enable'] { return { while: '1' } } - -export function findGfxTemplate( - config: TV2BlueprintConfig, - cue: CueDefinitionGraphic -): TableConfigItemGfxTemplate | undefined { - let graphicId: string | undefined - if (GraphicIsInternal(cue)) { - graphicId = cue.graphic.template - } else if (GraphicIsPilot(cue)) { - graphicId = cue.graphic.vcpid.toString() - } - if (graphicId === undefined) { - return undefined - } - return config.showStyle.GfxTemplates.find(templ => - templ.INewsName ? templ.INewsName.toString().toUpperCase() === graphicId?.toUpperCase() : false - ) -} -export function GetEnableForGraphic( - config: TV2BlueprintConfig, - engine: GraphicEngine, - cue: CueDefinitionGraphic -): TSR.TSRTimelineObj['enable'] { - if (IsTargetingWall(engine)) { - return GetEnableForWall() - } - - const timing = CreateTimingEnable(cue, GetDefaultOut(config)) - - if (!timing.lifespan) { - return timing.enable - } - - if (config.studio.PreventOverlayWithFull) { - return { - while: '!.full' - } - } else { - return { - start: 0 - } - } -} diff --git a/src/tv2-common/helpers/graphics/util.ts b/src/tv2-common/helpers/graphics/util.ts new file mode 100644 index 00000000..bf29f3ed --- /dev/null +++ b/src/tv2-common/helpers/graphics/util.ts @@ -0,0 +1,26 @@ +import { IBlueprintPart, TSR } from 'blueprints-integration' +import { getHtmlGraphicBaseline, TV2ShowStyleConfig } from 'tv2-common' + +export function ApplyFullGraphicPropertiesToPart(config: TV2ShowStyleConfig, part: IBlueprintPart) { + const keepAliveDuration = + config.studio.GraphicsType === 'HTML' + ? config.studio.HTMLGraphics.KeepAliveDuration + : config.studio.VizPilotGraphics.KeepAliveDuration + if (part.inTransition === undefined) { + part.inTransition = { + partContentDelayDuration: 0, + blockTakeDuration: 0, + previousPartKeepaliveDuration: keepAliveDuration + } + } else { + part.inTransition.previousPartKeepaliveDuration = keepAliveDuration + } +} + +export function CreateGraphicBaseline(config: TV2ShowStyleConfig): TSR.TSRTimelineObj[] { + if (config.studio.GraphicsType === 'VIZ') { + return [] + } else { + return getHtmlGraphicBaseline(config) + } +} diff --git a/src/tv2-common/helpers/graphics/viz/VizInternalGraphic.ts b/src/tv2-common/helpers/graphics/viz/VizInternalGraphic.ts new file mode 100644 index 00000000..713bfa87 --- /dev/null +++ b/src/tv2-common/helpers/graphics/viz/VizInternalGraphic.ts @@ -0,0 +1,52 @@ +import { SomeContent, TSR, WithTimeline } from 'blueprints-integration' +import { EnableDSK, GetTimelineLayerForGraphic, literal } from 'tv2-common' + +import { InternalGraphic } from '../internal' + +export class VizInternalGraphic extends InternalGraphic { + protected getContent(): WithTimeline { + return { + fileName: this.cue.graphic.template, + path: this.cue.graphic.template, + ignoreMediaObjectStatus: true, + timelineObjects: literal([ + literal({ + id: '', + enable: this.GetEnableForGraphic(), + priority: 1, + layer: GetTimelineLayerForGraphic(this.config, this.templateName), + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, + templateName: this.templateName, + templateData: this.cue.graphic.textFields, + channelName: this.engine === 'WALL' ? 'WALL1' : 'OVL1', // TODO: TranslateEngine + showName: this.findShowName() + } + }), + // Assume DSK is off by default (config table) + ...EnableDSK(this.context, 'OVL') + ]) + } + } + + private findShowName(): string { + const graphicsSetup = this.config.selectedGfxSetup + switch (this.engine) { + case 'FULL': + case 'WALL': + if (graphicsSetup.FullShowName === undefined) { + this.core.logWarning("You're using Viz graphics with an incompatible ShowStyle") + return '' + } + return graphicsSetup.FullShowName + case 'TLF': + case 'OVL': + if (graphicsSetup.OvlShowName === undefined) { + this.core.logWarning("You're using Viz graphics with an incompatible ShowStyle") + return '' + } + return graphicsSetup.OvlShowName + } + } +} diff --git a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts new file mode 100644 index 00000000..a02adbce --- /dev/null +++ b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts @@ -0,0 +1,125 @@ +import { GraphicsContent, TSR, WithTimeline } from 'blueprints-integration' +import { + assertUnreachable, + EnableDSK, + FindDSKFullGFX, + GetSisyfosTimelineObjForFull, + IsTargetingFull, + IsTargetingOVL, + IsTargetingWall, + literal, + PilotGraphicProps +} from 'tv2-common' + +import { PilotGraphicGenerator } from '../pilot' + +export class VizPilotGraphicGenerator extends PilotGraphicGenerator { + constructor(graphicProps: PilotGraphicProps) { + super(graphicProps) + } + public getContent(): WithTimeline { + return { + fileName: 'PILOT_' + this.cue.graphic.vcpid.toString(), + path: this.cue.graphic.vcpid.toString(), + timelineObjects: [ + literal({ + id: '', + enable: this.getEnable(), + priority: 1, + layer: this.getLayerMappingName(), + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT, + templateVcpId: this.cue.graphic.vcpid, + continueStep: this.cue.graphic.continueCount, + noAutoPreloading: false, + channelName: this.getChannelName(), + ...this.getOutTransitionProperties() + }, + ...(IsTargetingFull(this.engine) ? { classes: ['full'] } : {}) + }), + ...(IsTargetingFull(this.engine) ? this.getFullPilotTimeline() : []) + ] + } + } + + private getEnable() { + if (IsTargetingOVL(this.engine) || IsTargetingWall(this.engine)) { + return this.GetEnableForGraphic() + } + return { start: 0 } + } + + private getChannelName() { + switch (this.engine) { + case 'WALL': + return 'WALL1' + case 'OVL': + return 'OVL1' + case 'FULL': + case 'TLF': + return 'FULL1' + default: + assertUnreachable(this.engine) + } + } + + private getOutTransitionProperties(): Partial { + if (IsTargetingWall(this.engine) || !this.config.studio.PreventOverlayWithFull) { + return {} + } + return { + delayTakeAfterOutTransition: true, + outTransition: { + type: TSR.VIZMSETransitionType.DELAY, + delay: this.config.studio.VizPilotGraphics.OutTransitionDuration + } + } + } + + private getFullPilotTimeline() { + const fullDSK = FindDSKFullGFX(this.config) + const timelineObjects = [ + literal({ + id: '', + enable: { + start: this.config.studio.VizPilotGraphics.CutToMediaPlayer + }, + priority: 1, + layer: this.settings.ProgramLayer, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.ME, + me: { + input: this.config.studio.VizPilotGraphics.FullGraphicBackground, + transition: TSR.AtemTransitionStyle.CUT + } + } + }), + // Assume DSK is off by default (config table) + ...EnableDSK(this.context, 'FULL'), + ...GetSisyfosTimelineObjForFull(this.config) + ] + if (this.settings.AuxProgramLayer) { + timelineObjects.push( + literal({ + id: '', + enable: { + start: this.config.studio.VizPilotGraphics.CutToMediaPlayer + }, + priority: 1, + layer: this.settings.AuxProgramLayer, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.AUX, + aux: { + input: fullDSK.Fill + } + }, + classes: ['MIX_MINUS_OVERRIDE_DSK', 'PLACEHOLDER_OBJECT_REMOVEME'] + }) + ) + } + return timelineObjects + } +} diff --git a/src/tv2-common/helpers/graphics/viz/index.ts b/src/tv2-common/helpers/graphics/viz/index.ts index 38a7d8e6..10f74ffc 100644 --- a/src/tv2-common/helpers/graphics/viz/index.ts +++ b/src/tv2-common/helpers/graphics/viz/index.ts @@ -1,139 +1,2 @@ -import { GraphicsContent, IShowStyleUserContext, TSR, WithTimeline } from 'blueprints-integration' -import { - assertUnreachable, - CueDefinitionGraphic, - GetEnableForGraphic, - GetFullGraphicTemplateNameFromCue, - GetTimelineLayerForGraphic, - GraphicInternal, - IsTargetingFull, - IsTargetingOVL, - IsTargetingWall, - literal, - PilotGraphicProps, - TV2BlueprintConfig -} from 'tv2-common' -import { GraphicEngine } from 'tv2-constants' -import { EnableDSK } from '../../dsk' -import { PilotGraphicGenerator } from '../pilot/index' - -export class VizPilotGraphicGenerator extends PilotGraphicGenerator { - constructor(graphicProps: PilotGraphicProps) { - super(graphicProps) - } - public getContent(): WithTimeline { - return { - fileName: 'PILOT_' + this.parsedCue.graphic.vcpid.toString(), - path: this.parsedCue.graphic.vcpid.toString(), - timelineObjects: [ - literal({ - id: '', - enable: this.getEnable(), - priority: 1, - layer: this.getLayerMappingName(), - content: { - deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT, - templateVcpId: this.parsedCue.graphic.vcpid, - continueStep: this.parsedCue.graphic.continueCount, - noAutoPreloading: false, - channelName: this.getChannelName(), - ...this.getOutTransitionProperties() - }, - ...(IsTargetingFull(this.engine) ? { classes: ['full'] } : {}) - }), - ...(IsTargetingFull(this.engine) ? this.settings.viz.createFullPilotTimelineForStudio(this.config) : []) - ] - } - } - - private getEnable() { - if (IsTargetingOVL(this.engine) || IsTargetingWall(this.engine)) { - return GetEnableForGraphic(this.config, this.engine, this.parsedCue) - } - return { start: 0 } - } - - private getChannelName() { - switch (this.engine) { - case 'WALL': - return 'WALL1' - case 'OVL': - return 'OVL1' - case 'FULL': - case 'TLF': - return 'FULL1' - default: - assertUnreachable(this.engine) - } - } - - private getOutTransitionProperties(): Partial { - if (IsTargetingWall(this.engine) || !this.config.studio.PreventOverlayWithFull) { - return {} - } - return { - delayTakeAfterOutTransition: true, - outTransition: { - type: TSR.VIZMSETransitionType.DELAY, - delay: this.config.studio.VizPilotGraphics.OutTransitionDuration - } - } - } -} - -export interface VizPilotGeneratorSettings { - createFullPilotTimelineForStudio(config: TV2BlueprintConfig): TSR.TSRTimelineObj[] -} - -export function GetInternalGraphicContentVIZ( - config: TV2BlueprintConfig, - context: IShowStyleUserContext, - engine: GraphicEngine, - parsedCue: CueDefinitionGraphic, - mappedTemplate: string -): WithTimeline { - return { - fileName: parsedCue.graphic.template, - path: parsedCue.graphic.template, - ignoreMediaObjectStatus: true, - timelineObjects: literal([ - literal({ - id: '', - enable: GetEnableForGraphic(config, engine, parsedCue), - priority: 1, - layer: GetTimelineLayerForGraphic(config, GetFullGraphicTemplateNameFromCue(config, parsedCue)), - content: { - deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, - templateName: mappedTemplate, - templateData: parsedCue.graphic.textFields, - channelName: engine === 'WALL' ? 'WALL1' : 'OVL1', // TODO: TranslateEngine - showName: findShowName(config, context, engine) - } - }), - // Assume DSK is off by default (config table) - ...EnableDSK(config, 'OVL') - ]) - } -} - -function findShowName(config: TV2BlueprintConfig, context: IShowStyleUserContext, engine: GraphicEngine): string { - const gfxSetup = config.selectedGfxSetup - switch (engine) { - case 'FULL': - case 'WALL': - if (gfxSetup.FullShowName === undefined) { - context.logWarning("You're using Viz graphics with an incompatible ShowStyle") - return '' - } - return gfxSetup.FullShowName - case 'TLF': - case 'OVL': - if (gfxSetup.OvlShowName === undefined) { - context.logWarning("You're using Viz graphics with an incompatible ShowStyle") - return '' - } - return gfxSetup.OvlShowName - } -} +export * from './VizInternalGraphic' +export * from './VizPilotGraphicGenerator' diff --git a/src/tv2-common/helpers/index.ts b/src/tv2-common/helpers/index.ts index 9e36821a..e846e008 100644 --- a/src/tv2-common/helpers/index.ts +++ b/src/tv2-common/helpers/index.ts @@ -1,8 +1,8 @@ export * from './abPlayback' export * from './config' +export * from './graphics' export * from './dsk' export * from './sisyfos' -export * from './graphics/index' export * from './rundownAdLibActions' export * from './postProcessDefinitions' export * from './translation' diff --git a/src/tv2-common/helpers/rundownAdLibActions.ts b/src/tv2-common/helpers/rundownAdLibActions.ts index 0558625c..c0b31fca 100644 --- a/src/tv2-common/helpers/rundownAdLibActions.ts +++ b/src/tv2-common/helpers/rundownAdLibActions.ts @@ -12,7 +12,7 @@ import { TV2StudioConfigBase } from 'tv2-common' import { AdlibActionType, AdlibTags, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' -import { TV2BlueprintConfig } from '../blueprintConfig' +import { TV2ShowStyleConfig } from '../blueprintConfig' import { CreateJingleExpectedMedia } from '../content' import { t } from './translation' @@ -50,7 +50,7 @@ export function GetTransitionAdLibActions< } function createActionsForTransition( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, transition: string, rank: number ): IBlueprintActionManifest[] { @@ -104,7 +104,7 @@ export function ParseTransitionString(transitionString: string): ActionTakeWithT } function makeTransitionOnTakeAction( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, variant: ActionTakeWithTransitionVariant, transitionValues: TransitionValues ): IBlueprintActionManifest { @@ -117,7 +117,7 @@ function makeTransitionOnTakeAction( } function makeTransitionOnNextTakeAction( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, variant: ActionTakeWithTransitionVariant, transitionValues: TransitionValues ): IBlueprintActionManifest { @@ -130,7 +130,7 @@ function makeTransitionOnNextTakeAction( } function makeTransitionAction( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, userData: ActionTakeWithTransition, transitionValues: TransitionValues, adlibTag: AdlibTags diff --git a/src/tv2-common/helpers/serverResume.ts b/src/tv2-common/helpers/serverResume.ts index 74157719..b69c80bc 100644 --- a/src/tv2-common/helpers/serverResume.ts +++ b/src/tv2-common/helpers/serverResume.ts @@ -1,11 +1,10 @@ import { - IActionExecutionContext, IBlueprintActionTriggerMode, IBlueprintPartInstance, IBlueprintResolvedPieceInstance, VTContent } from 'blueprints-integration' -import { PartEndStateExt, PieceMetaData, t } from 'tv2-common' +import { ExtendedActionExecutionContext, PartEndStateExt, PieceMetaData, t, TV2ShowStyleConfig } from 'tv2-common' import { SharedSourceLayers } from 'tv2-constants' import _ = require('underscore') import { DVEPieceMetaData } from '../content' @@ -48,22 +47,20 @@ export function getServerSeek( } export async function getServerPosition( - context: IActionExecutionContext, + context: ExtendedActionExecutionContext, replacingCurrentPieceWithOffset?: number ): Promise { - const partInstance = await context.getPartInstance('current') + const partInstance = await context.core.getPartInstance('current') if (!partInstance) { throw new Error('Missing current PartInstance while calculating serverOffsets') } const pieceEnd = replacingCurrentPieceWithOffset !== undefined - ? context.getCurrentTime() + replacingCurrentPieceWithOffset + ? context.core.getCurrentTime() + replacingCurrentPieceWithOffset : undefined - const pieceInstances = (await context.getResolvedPieceInstances('current')) as Array< - IBlueprintResolvedPieceInstance - > + const pieceInstances = await context.core.getResolvedPieceInstances('current') return getServerPositionForPartInstance(partInstance, pieceInstances, pieceEnd) } diff --git a/src/tv2-common/helpers/sisyfos.ts b/src/tv2-common/helpers/sisyfos.ts index a1df4abe..52fcc8b5 100644 --- a/src/tv2-common/helpers/sisyfos.ts +++ b/src/tv2-common/helpers/sisyfos.ts @@ -1,11 +1,11 @@ import { Timeline, TSR } from 'blueprints-integration' import { SourceInfo, TimelineBlueprintExt } from 'tv2-common' import { SharedSisyfosLLayer } from 'tv2-constants' -import { TV2BlueprintConfig } from '../blueprintConfig' +import { TV2ShowStyleConfig } from '../blueprintConfig' import { literal } from '../util' export function GetSisyfosTimelineObjForCamera( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, sourceInfo: SourceInfo, minusMic: boolean, enable?: Timeline.TimelineEnable @@ -14,19 +14,19 @@ export function GetSisyfosTimelineObjForCamera( } export function GetSisyfosTimelineObjForRemote( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, sourceInfo: SourceInfo, enable?: Timeline.TimelineEnable ) { return GetSisyfosTimelineObjForSource(config, sourceInfo, false, false, enable) } -export function GetSisyfosTimelineObjForReplay(config: TV2BlueprintConfig, sourceInfo: SourceInfo, vo: boolean) { +export function GetSisyfosTimelineObjForReplay(config: TV2ShowStyleConfig, sourceInfo: SourceInfo, vo: boolean) { return GetSisyfosTimelineObjForSource(config, sourceInfo, vo, true) } export function GetSisyfosTimelineObjForServer( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, vo: boolean, clipPendingLayer: string, mediaPlayerSession: string, @@ -57,7 +57,7 @@ export function GetSisyfosTimelineObjForServer( } export function GetSisyfosTimelineObjForFull( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, enable?: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosAny[] { const result: TSR.TimelineObjSisyfosAny[] = [] @@ -67,7 +67,7 @@ export function GetSisyfosTimelineObjForFull( } export function GetSisyfosTimelineObjForTelefon( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, telefonLayer: string, enable?: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosAny[] { @@ -90,7 +90,7 @@ export function GetSisyfosTimelineObjForTelefon( } function GetSisyfosTimelineObjForSource( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, sourceInfo: SourceInfo, vo: boolean, enableStudioMicsOnlyForVo: boolean, @@ -120,7 +120,7 @@ function GetSisyfosTimelineObjForSource( } function getStudioMicsTimelineObj( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, timelineEnable: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosChannels { const studioMicsChannels: TSR.TimelineObjSisyfosChannels['content']['channels'] = [] diff --git a/src/tv2-common/index.ts b/src/tv2-common/index.ts index f2f8a3f5..91c660ed 100644 --- a/src/tv2-common/index.ts +++ b/src/tv2-common/index.ts @@ -1,3 +1,5 @@ +export * from './showstyle' +export * from './studio' export * from './actions' export * from './blueprintConfig' export * from './content' @@ -24,4 +26,5 @@ export * from './transitionSettings' export * from './types' export * from './updatePolicies' export * from './util' -export * from './showstyle/config-manifests' +export * from './segment/context' +export * from './videoSwitchers' diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index e221fcc5..dc376341 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -3,7 +3,7 @@ import { AtemTransitionStyleFromString, CueDefinitionFromLayout, PostProcessDefinitions, - TV2BlueprintConfig, + TV2ShowStyleConfig, UnparsedCue } from 'tv2-common' import { CueType, PartType, SourceType } from 'tv2-constants' @@ -181,7 +181,7 @@ const ENGINE_CUE = /ENGINE ?([^\s]+)/i const MAX_ALLOWED_TRANSITION_FRAMES = 250 export function ParseBody( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, segmentId: string, segmentName: string, body: string, @@ -429,7 +429,7 @@ function cueInLine(line: string) { } /** Returns all the cues in a given line as parsed cues. */ -function getCuesInLine(line: string, cues: UnparsedCue[], config: TV2BlueprintConfig): CueDefinition[] { +function getCuesInLine(line: string, cues: UnparsedCue[], config: TV2ShowStyleConfig): CueDefinition[] { if (!cueInLine(line)) { return [] } diff --git a/src/tv2-common/inewsConversion/converters/ParseCue.ts b/src/tv2-common/inewsConversion/converters/ParseCue.ts index 6322d9b9..b74b4581 100644 --- a/src/tv2-common/inewsConversion/converters/ParseCue.ts +++ b/src/tv2-common/inewsConversion/converters/ParseCue.ts @@ -1,4 +1,4 @@ -import { literal, TableConfigItemGfxDesignTemplate, TV2BlueprintConfig, UnparsedCue } from 'tv2-common' +import { literal, TableConfigItemGfxDesignTemplate, TV2ShowStyleConfig, UnparsedCue } from 'tv2-common' import { CueType, GraphicEngine, SourceType } from 'tv2-constants' import { getSourceDefinition, @@ -198,7 +198,7 @@ export function GraphicIsPilot( return o.graphic.type === 'pilot' } -export function ParseCue(cue: UnparsedCue, config: TV2BlueprintConfig): CueDefinition | undefined { +export function ParseCue(cue: UnparsedCue, config: TV2ShowStyleConfig): CueDefinition | undefined { if (!cue) { return undefined } @@ -266,7 +266,7 @@ export function ParseCue(cue: UnparsedCue, config: TV2BlueprintConfig): CueDefin function parsekg( cue: string[], - config: TV2BlueprintConfig + config: TV2ShowStyleConfig ): CueDefinitionGraphic | CueDefinitionGraphicDesign | CueDefinitionUnpairedTarget { let kgCue: CueDefinitionGraphic = { type: CueType.Graphic, @@ -496,7 +496,7 @@ function parseDVE(cue: string[]): CueDefinitionDVE { return dvecue } -function parseTelefon(cue: string[], config: TV2BlueprintConfig): CueDefinitionTelefon { +function parseTelefon(cue: string[], config: TV2ShowStyleConfig): CueDefinitionTelefon { const telefonCue: CueDefinitionTelefon = { type: CueType.Telefon, source: '', @@ -663,7 +663,7 @@ function parseJingle(cue: string[]) { function parseTargetEngine( cue: string[], - config: TV2BlueprintConfig + config: TV2ShowStyleConfig ): CueDefinitionUnpairedTarget | CueDefinitionGraphic | CueDefinitionGraphicDesign { let engineCue: CueDefinitionUnpairedTarget = { type: CueType.UNPAIRED_TARGET, @@ -894,7 +894,7 @@ export function parseTime(line: string): Pick({ - externalId: RUNDOWN_EXTERNAL_ID, - name: RUNDOWN_EXTERNAL_ID, - _id: '', - showStyleVariantId: '', - timing: { - type: PlaylistTimingType.None - } - }) - const mockContext = new SegmentUserContext( - 'test', - mappingsDefaults, - parseStudioConfig, - parseShowStyleConfig, - rundown._id - ) - mockContext.studioConfig = defaultStudioConfig as any - mockContext.showStyleConfig = defaultShowStyleConfig as any - - return mockContext -} - -const config = getConfig(makeMockContext()) +const config = makeMockGalleryContext().config describe('Body parser', () => { test('test1', () => { diff --git a/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts b/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts index fb1092b6..a4865344 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts @@ -1,11 +1,7 @@ -import { IBlueprintRundownDB, PlaylistTimingType, TSR } from 'blueprints-integration' +import { TSR } from 'blueprints-integration' import { CueDefinitionRobotCamera, RemoteType, SourceDefinitionKam, SourceDefinitionRemote } from 'tv2-common' import { CueType, SourceType } from 'tv2-constants' -import { SegmentUserContext } from '../../../../__mocks__/context' -import { defaultShowStyleConfig, defaultStudioConfig } from '../../../../tv2_afvd_showstyle/__tests__/configs' -import { getConfig, parseConfig as parseShowStyleConfig } from '../../../../tv2_afvd_showstyle/helpers/config' -import { parseConfig as parseStudioConfig } from '../../../../tv2_afvd_studio/helpers/config' -import mappingsDefaults from '../../../../tv2_afvd_studio/migrations/mappings-defaults' +import { makeMockGalleryContext } from '../../../../__mocks__/context' import { literal } from '../../../util' import { CueDefinitionAdLib, @@ -32,8 +28,6 @@ import { parseTime } from '../ParseCue' -const RUNDOWN_EXTERNAL_ID = 'TEST.SOFIE.JEST' - const SOURCE_DEFINITION_KAM_1: SourceDefinitionKam = { sourceType: SourceType.KAM, id: '1', @@ -63,30 +57,7 @@ const SOURCE_DEFINITION_LIVE_2: SourceDefinitionRemote = { raw: 'LIVE 2' } -function makeMockContext() { - const rundown = literal({ - externalId: RUNDOWN_EXTERNAL_ID, - name: RUNDOWN_EXTERNAL_ID, - _id: '', - showStyleVariantId: '', - timing: { - type: PlaylistTimingType.None - } - }) - const mockContext = new SegmentUserContext( - 'test', - mappingsDefaults, - parseStudioConfig, - parseShowStyleConfig, - rundown._id - ) - mockContext.studioConfig = defaultStudioConfig as any - mockContext.showStyleConfig = defaultShowStyleConfig as any - - return mockContext -} - -const config = getConfig(makeMockContext()) +const config = makeMockGalleryContext().config describe('Cue parser', () => { test('Null Cue', () => { diff --git a/src/tv2-common/jinglePartProperties.ts b/src/tv2-common/jinglePartProperties.ts index 6b848bff..1fb5967e 100644 --- a/src/tv2-common/jinglePartProperties.ts +++ b/src/tv2-common/jinglePartProperties.ts @@ -1,18 +1,18 @@ -import { IBlueprintPart, IShowStyleUserContext } from 'blueprints-integration' +import { IBlueprintPart } from 'blueprints-integration' import { CueType } from 'tv2-constants' -import { TableConfigItemBreakers, TV2BlueprintConfigBase, TV2StudioConfigBase } from './blueprintConfig' +import { TableConfigItemBreakers } from './blueprintConfig' import { TimeFromFrames } from './frameTime' import { CueDefinitionJingle, PartDefinition } from './inewsConversion' +import { ExtendedShowStyleContext } from './showstyle' -export function GetJinglePartProperties( - _context: IShowStyleUserContext, - config: TV2BlueprintConfigBase, +export function GetJinglePartProperties( + context: ExtendedShowStyleContext, part: PartDefinition ): Pick | {} { if (part.cues) { const cue = part.cues.find(c => c.type === CueType.Jingle) as CueDefinitionJingle if (cue) { - const realBreaker = config.showStyle.BreakerConfig.find(conf => { + const realBreaker = context.config.showStyle.BreakerConfig.find(conf => { return conf.BreakerName && typeof conf.BreakerName === 'string' ? conf.BreakerName.toString() .trim() diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index 5a832fe7..d53fd744 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -4,20 +4,27 @@ import { IBlueprintPartInstance, IBlueprintResolvedPieceInstance, IRundownContext, - IShowStyleContext, - ITimelineEventContext, OnGenerateTimelineObj, PartEndState, TimelineObjectCoreExt, TimelinePersistentState, TSR } from 'blueprints-integration' -import { ActionSelectFullGrafik, ActionSelectJingle, ActionSelectServerClip, CasparPlayerClip } from 'tv2-common' +import { + ABSourceLayers, + ActionSelectFullGrafik, + ActionSelectJingle, + ActionSelectServerClip, + assignMediaPlayers, + CasparPlayerClip, + ExtendedTimelineContext, + getServerPositionForPartInstance, + ServerPosition +} from 'tv2-common' import { AbstractLLayer, PartType, TallyTags } from 'tv2-constants' import * as _ from 'underscore' import { SisyfosLLAyer } from '../tv2_afvd_studio/layers' import { TV2BlueprintConfigBase, TV2StudioConfigBase } from './blueprintConfig' -import { ABSourceLayers, assignMediaPlayers, getServerPositionForPartInstance, ServerPosition } from './helpers' export interface PartEndStateExt { sisyfosPersistMetaData: SisyfosPersistMetaData @@ -93,25 +100,20 @@ export function onTimelineGenerate< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ITimelineEventContext, + context: ExtendedTimelineContext, timeline: OnGenerateTimelineObj[], previousPersistentState: TimelinePersistentState | undefined, previousPartEndState: PartEndState | undefined, resolvedPieces: Array>, - getConfig: (context: IShowStyleContext) => ShowStyleConfig, - sourceLayers: ABSourceLayers, - _casparLayerClipPending: string, - _atemLayerNext: string + sourceLayers: ABSourceLayers ): Promise { const previousPartEndState2 = previousPartEndState as PartEndStateExt | undefined const persistentState: TimelinePersistentStateExt = { activeMediaPlayers: {}, - isNewSegment: context.previousPartInstance?.segmentId !== context.currentPartInstance?.segmentId + isNewSegment: context.core.previousPartInstance?.segmentId !== context.core.currentPartInstance?.segmentId } - const config = getConfig(context) - - if (!persistentState.isNewSegment || isAnyPieceInjectedIntoPart(resolvedPieces, context)) { + if (!persistentState.isNewSegment || isAnyPieceInjectedIntoPart(context, resolvedPieces)) { const sisyfosPersistedLevelsTimelineObject = createSisyfosPersistedLevelsTimelineObject( resolvedPieces, previousPartEndState2 ? previousPartEndState2.sisyfosPersistMetaData.sisyfosLayers : [] @@ -125,7 +127,6 @@ export function onTimelineGenerate< persistentState.activeMediaPlayers = assignMediaPlayers( context, - config, timeline, previousPersistentState2 ? previousPersistentState2.activeMediaPlayers : {}, resolvedPieces, @@ -141,7 +142,7 @@ export function onTimelineGenerate< } function processServerLookaheads( - context: ITimelineEventContext, + context: ExtendedTimelineContext, timeline: OnGenerateTimelineObj[], resolvedPieces: IBlueprintResolvedPieceInstance[], sourceLayers: ABSourceLayers @@ -161,7 +162,9 @@ function processServerLookaheads( return ( [sourceLayers.Caspar.ClipPending, CasparPlayerClip(1), CasparPlayerClip(2)].includes(layer) && !obj.isLookahead && - resolvedPieces.some(p => p._id === obj.pieceInstanceId && p.partInstanceId === context.currentPartInstance?._id) + resolvedPieces.some( + p => p._id === obj.pieceInstanceId && p.partInstanceId === context.core.currentPartInstance?._id + ) ) }) @@ -205,11 +208,11 @@ function processServerLookaheads( } function isAnyPieceInjectedIntoPart( - resolvedPieces: Array>, - context: ITimelineEventContext + context: ExtendedTimelineContext, + resolvedPieces: Array> ) { return resolvedPieces - .filter(piece => piece.partInstanceId === context.currentPartInstance?._id) + .filter(piece => piece.partInstanceId === context.core.currentPartInstance?._id) .some(piece => { return piece.piece.metaData?.sisyfosPersistMetaData?.isPieceInjectedInPart }) diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index fb8e0886..34ed3203 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -2,7 +2,6 @@ import { IBlueprintPart, IBlueprintPiece, IBlueprintPieceType, - IShowStyleUserContext, PieceLifespan, TimelineObjectCoreExt, TSR, @@ -13,6 +12,7 @@ import { ActionTakeWithTransitionVariantDip, ActionTakeWithTransitionVariantMix, EnableDSK, + ExtendedShowStyleContext, GetTagForTransition, literal, PartDefinition, @@ -23,13 +23,12 @@ import { TV2StudioConfigBase } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' -import { TV2BlueprintConfig } from '../blueprintConfig' +import { TV2ShowStyleConfig } from '../blueprintConfig' import { joinAssetToFolder, joinAssetToNetworkPath } from '../util' /** Has to be executed before calling EvaluateCues, as some cues may depend on it */ export function CreateEffektForPartBase( - context: IShowStyleUserContext, - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, pieces: IBlueprintPiece[], layers: { @@ -44,7 +43,6 @@ export function CreateEffektForPartBase( if (effekt !== undefined) { const ret = CreateEffektForPartInner( context, - config, pieces, effekt.toString(), partDefinition.externalId, @@ -81,8 +79,7 @@ export function CreateEffektForPartInner< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], effekt: string, externalId: string, @@ -93,30 +90,30 @@ export function CreateEffektForPartInner< }, label: string ): Pick | false { - if (!config.showStyle.BreakerConfig) { - context.notifyUserWarning(`Jingles have not been configured`) + if (!context.config.showStyle.BreakerConfig) { + context.core.notifyUserWarning(`Jingles have not been configured`) return false } - const effektConfig = config.showStyle.BreakerConfig.find( + const effektConfig = context.config.showStyle.BreakerConfig.find( conf => conf.BreakerName.toString() .trim() .toUpperCase() === effekt.toUpperCase() ) if (!effektConfig) { - context.notifyUserWarning(`Could not find effekt ${effekt}`) + context.core.notifyUserWarning(`Could not find effekt ${effekt}`) return false } const file = effektConfig.ClipName.toString() if (!file) { - context.notifyUserWarning(`Could not find file for ${effekt}`) + context.core.notifyUserWarning(`Could not find file for ${effekt}`) return false } - const fileName = joinAssetToFolder(config.studio.JingleFolder, file) + const fileName = joinAssetToFolder(context.config.studio.JingleFolder, file) pieces.push({ externalId, @@ -129,14 +126,14 @@ export function CreateEffektForPartInner< content: literal>({ fileName, path: joinAssetToNetworkPath( - config.studio.JingleNetworkBasePath, - config.studio.JingleFolder, + context.config.studio.JingleNetworkBasePath, + context.config.studio.JingleFolder, file, - config.studio.JingleFileExtension + context.config.studio.JingleFileExtension ), // full path on the source network storage - mediaFlowIds: [config.studio.JingleMediaFlowId], + mediaFlowIds: [context.config.studio.JingleMediaFlowId], previewFrame: Number(effektConfig.StartAlpha), - ignoreMediaObjectStatus: config.studio.JingleIgnoreStatus, + ignoreMediaObjectStatus: context.config.studio.JingleIgnoreStatus, ignoreBlackFrames: true, ignoreFreezeFrame: true, timelineObjects: literal([ @@ -153,7 +150,7 @@ export function CreateEffektForPartInner< file: fileName } }), - ...EnableDSK(config, 'JINGLE', { start: Number(config.studio.CasparPrerollDuration) }), + ...EnableDSK(context, 'JINGLE', { start: Number(context.config.studio.CasparPrerollDuration) }), literal({ id: '', enable: { @@ -173,13 +170,13 @@ export function CreateEffektForPartInner< return { inTransition: { - blockTakeDuration: TimeFromFrames(Number(effektConfig.Duration)) + config.studio.CasparPrerollDuration, + blockTakeDuration: TimeFromFrames(Number(effektConfig.Duration)) + context.config.studio.CasparPrerollDuration, previousPartKeepaliveDuration: - TimeFromFrames(Number(effektConfig.StartAlpha)) + config.studio.CasparPrerollDuration, + TimeFromFrames(Number(effektConfig.StartAlpha)) + context.config.studio.CasparPrerollDuration, partContentDelayDuration: TimeFromFrames(Number(effektConfig.Duration)) - TimeFromFrames(Number(effektConfig.EndAlpha)) + - config.studio.CasparPrerollDuration + context.config.studio.CasparPrerollDuration }, autoNext: false } diff --git a/src/tv2-common/parts/kam.ts b/src/tv2-common/parts/kam.ts index 64bfecc2..ce288b38 100644 --- a/src/tv2-common/parts/kam.ts +++ b/src/tv2-common/parts/kam.ts @@ -1,16 +1,21 @@ -import { BlueprintResultPart, IBlueprintPart, IShowStyleUserContext } from 'blueprints-integration' -import { PartDefinition, PartTime, TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' +import { BlueprintResultPart, IBlueprintPart } from 'blueprints-integration' +import { + ExtendedShowStyleContext, + PartDefinition, + PartTime, + TV2BlueprintConfigBase, + TV2StudioConfigBase +} from 'tv2-common' export function CreatePartKamBase< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - _context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, totalWords: number ): { part: BlueprintResultPart; duration: number; invalid?: true } { - const partTime = PartTime(config, partDefinition, totalWords, false) + const partTime = PartTime(context.config, partDefinition, totalWords, false) const part: IBlueprintPart = { externalId: partDefinition.externalId, diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index 3a7ceb64..0cbcbf6e 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -9,6 +9,7 @@ import { } from 'blueprints-integration' import { CutToServer, + ExtendedShowStyleContext, GetTagForServer, GetTagForServerNext, MakeContentServer, @@ -62,21 +63,20 @@ export async function CreatePartServerBase< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, partProps: ServerPartProps, layers: ServerPartLayers ): Promise<{ part: BlueprintResultPart; file: string; duration: number; invalid?: true }> { if (isVideoIdMissing(partDefinition)) { - context.notifyUserWarning('Video ID not set!') + context.core.notifyUserWarning('Video ID not set!') return { part: CreatePartInvalid(partDefinition), file: '', duration: 0, invalid: true } } const file = getVideoId(partDefinition) - const mediaObjectDurationSec = await context.hackGetMediaObjectDuration(file) + const mediaObjectDurationSec = await context.core.hackGetMediaObjectDuration(file) const mediaObjectDuration = mediaObjectDurationSec && mediaObjectDurationSec * 1000 - const sourceDuration = getSourceDuration(mediaObjectDuration, config.studio.ServerPostrollDuration) + const sourceDuration = getSourceDuration(mediaObjectDuration, context.config.studio.ServerPostrollDuration) const duration = getDuration(mediaObjectDuration, sourceDuration, partProps) const sanitisedScript = getScriptWithoutLineBreaks(partDefinition) const actualDuration = getActualDuration(duration, sanitisedScript, partProps) @@ -100,9 +100,9 @@ export async function CreatePartServerBase< partProps, contentProps, layers, - context, - config, - config.studio.CasparPrerollDuration + context.core, + context.config, + context.config.studio.CasparPrerollDuration ) const pgmBlueprintPiece = getPgmBlueprintPiece( @@ -110,8 +110,8 @@ export async function CreatePartServerBase< partProps, contentProps, layers, - config, - config.studio.CasparPrerollDuration + context.config, + context.config.studio.CasparPrerollDuration ) pieces.push(serverSelectionBlueprintPiece) diff --git a/src/tv2-common/pieces/adlibServer.ts b/src/tv2-common/pieces/adlibServer.ts index 7d83b1a6..94d5a4bb 100644 --- a/src/tv2-common/pieces/adlibServer.ts +++ b/src/tv2-common/pieces/adlibServer.ts @@ -1,6 +1,7 @@ -import { IBlueprintActionManifest, IShowStyleUserContext } from 'blueprints-integration' +import { IBlueprintActionManifest } from 'blueprints-integration' import { ActionSelectServerClip, + ExtendedShowStyleContext, getSourceDuration, GetTagForServer, GetTagForServerNext, @@ -23,8 +24,7 @@ export async function CreateAdlibServer< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: IShowStyleUserContext, - config: ShowStyleConfig, + context: ExtendedShowStyleContext, rank: number, partDefinition: PartDefinition, file: string, @@ -33,9 +33,9 @@ export async function CreateAdlibServer< sourceLayers: ServerPartLayers, tagAsAdlib: boolean ): Promise { - const mediaObjectDurationSec = await context.hackGetMediaObjectDuration(file) + const mediaObjectDurationSec = await context.core.hackGetMediaObjectDuration(file) const mediaObjectDuration = mediaObjectDurationSec && mediaObjectDurationSec * 1000 - const sourceDuration = getSourceDuration(mediaObjectDuration, config.studio.ServerPostrollDuration) + const sourceDuration = getSourceDuration(mediaObjectDuration, context.config.studio.ServerPostrollDuration) return { externalId: partDefinition.externalId + '-adLib-server', @@ -55,7 +55,7 @@ export async function CreateAdlibServer< label: t(`${partDefinition.storyName}`), sourceLayerId: sourceLayers.SourceLayer.PgmServer, outputLayerId: SharedOutputLayers.PGM, - content: GetVTContentProperties(config, { + content: GetVTContentProperties(context.config, { file, clipDuration: mediaObjectDuration, sourceDuration diff --git a/src/tv2-common/pieces/telemetric.ts b/src/tv2-common/pieces/telemetric.ts index db66f86d..6f97da89 100644 --- a/src/tv2-common/pieces/telemetric.ts +++ b/src/tv2-common/pieces/telemetric.ts @@ -1,5 +1,6 @@ import { IBlueprintPiece, PieceLifespan, TSR } from 'blueprints-integration' import { RobotCameraLayer, SharedOutputLayers, SharedSourceLayers } from '../../tv2-constants' +import { PieceMetaData } from '../onTimelineGenerate' import { literal } from '../util' export const ROBOT_CAMERA_NAME_PREFIX: string = 'Robot' @@ -8,7 +9,7 @@ export function createTelemetricsPieceForRobotCamera( externalId: string, preset: number, startTime: number | 'now' -): IBlueprintPiece { +): IBlueprintPiece { return { externalId, name: `${ROBOT_CAMERA_NAME_PREFIX}[${preset}]`, diff --git a/src/tv2-common/segment/context.ts b/src/tv2-common/segment/context.ts new file mode 100644 index 00000000..14d702e7 --- /dev/null +++ b/src/tv2-common/segment/context.ts @@ -0,0 +1,17 @@ +import { ISegmentUserContext } from 'blueprints-integration' +import { ExtendedShowStyleContext, ExtendedShowStyleContextImpl, TV2ShowStyleConfig, VideoSwitcher } from 'tv2-common' + +export interface ExtendedSegmentContext + extends ExtendedShowStyleContext { + readonly core: ISegmentUserContext + readonly config: BlueprintConfig + readonly videoSwitcher: VideoSwitcher +} + +export class ExtendedSegmentContextImpl + extends ExtendedShowStyleContextImpl + implements ExtendedSegmentContext { + constructor(readonly core: ISegmentUserContext) { + super(core) + } +} diff --git a/src/tv2-common/showstyle/context.ts b/src/tv2-common/showstyle/context.ts new file mode 100644 index 00000000..b7a832db --- /dev/null +++ b/src/tv2-common/showstyle/context.ts @@ -0,0 +1,25 @@ +import { IShowStyleContext, IShowStyleUserContext } from 'blueprints-integration' +import { TV2ShowStyleConfig, VideoSwitcher, VideoSwitcherImpl } from 'tv2-common' + +export interface ExtendedShowStyleContext { + readonly core: IShowStyleUserContext + readonly config: BlueprintConfig + readonly videoSwitcher: VideoSwitcher +} + +export class ExtendedShowStyleContextImpl< + BlueprintConfig extends TV2ShowStyleConfig = TV2ShowStyleConfig, + CoreContext extends IShowStyleUserContext | IShowStyleContext = IShowStyleUserContext +> { + public readonly config: BlueprintConfig + public readonly videoSwitcher: VideoSwitcher + + constructor(readonly core: CoreContext) { + this.config = this.makeConfig() + this.videoSwitcher = VideoSwitcherImpl.getVideoSwitcher(this.config) + } + + private makeConfig(): BlueprintConfig { + return { ...(this.core.getStudioConfig() as any), ...(this.core.getShowStyleConfig() as any) } + } +} diff --git a/src/tv2-common/showstyle/index.ts b/src/tv2-common/showstyle/index.ts new file mode 100644 index 00000000..c9abb91e --- /dev/null +++ b/src/tv2-common/showstyle/index.ts @@ -0,0 +1,3 @@ +export * from './config-manifests' +export * from './context' +export * from './timelineEventContext' diff --git a/src/tv2-common/showstyle/timelineEventContext.ts b/src/tv2-common/showstyle/timelineEventContext.ts new file mode 100644 index 00000000..2da5c1aa --- /dev/null +++ b/src/tv2-common/showstyle/timelineEventContext.ts @@ -0,0 +1,11 @@ +import { ITimelineEventContext } from 'blueprints-integration' +import { TV2ShowStyleConfig } from '../blueprintConfig' +import { ExtendedShowStyleContextImpl } from './context' + +export class ExtendedTimelineContext< + BlueprintConfig extends TV2ShowStyleConfig = TV2ShowStyleConfig +> extends ExtendedShowStyleContextImpl { + constructor(readonly core: ITimelineEventContext) { + super(core) + } +} diff --git a/src/tv2-common/studio/context.ts b/src/tv2-common/studio/context.ts new file mode 100644 index 00000000..41e9fff3 --- /dev/null +++ b/src/tv2-common/studio/context.ts @@ -0,0 +1,17 @@ +import { IStudioContext } from 'blueprints-integration' +import { VideoSwitcher, VideoSwitcherImpl } from 'tv2-common' +import { TV2StudioConfig } from '../blueprintConfig' + +export class ExtendedStudioContext { + public readonly config: BlueprintConfig + public readonly videoSwitcher: VideoSwitcher + + constructor(readonly core: IStudioContext) { + this.config = this.makeConfig() + this.videoSwitcher = VideoSwitcherImpl.getVideoSwitcher(this.config) + } + + private makeConfig(): BlueprintConfig { + return { ...(this.core.getStudioConfig() as any) } + } +} diff --git a/src/tv2-common/studio/index.ts b/src/tv2-common/studio/index.ts new file mode 100644 index 00000000..630b4d7e --- /dev/null +++ b/src/tv2-common/studio/index.ts @@ -0,0 +1 @@ +export * from './context' diff --git a/src/tv2-common/transitionSettings.ts b/src/tv2-common/transitionSettings.ts index 1c87ec2f..74bd9b93 100644 --- a/src/tv2-common/transitionSettings.ts +++ b/src/tv2-common/transitionSettings.ts @@ -1,8 +1,8 @@ import { TSR } from 'blueprints-integration' -import { PartDefinition, TV2BlueprintConfig } from 'tv2-common' +import { PartDefinition, TV2ShowStyleConfig } from 'tv2-common' import { AtemSourceIndex } from '../types/atem' -export function TransitionSettings(config: TV2BlueprintConfig, part: PartDefinition): TSR.AtemTransitionSettings { +export function TransitionSettings(config: TV2ShowStyleConfig, part: PartDefinition): TSR.AtemTransitionSettings { if (!part.transition || !part.transition.duration) { return {} } @@ -25,7 +25,7 @@ function WipeTransitionSettings(rate: number): TSR.AtemTransitionSettings { } } -export function DipTransitionSettings(config: TV2BlueprintConfig, rate: number): TSR.AtemTransitionSettings { +export function DipTransitionSettings(config: TV2ShowStyleConfig, rate: number): TSR.AtemTransitionSettings { return { dip: { rate, diff --git a/src/tv2-common/videoSwitchers/Atem.ts b/src/tv2-common/videoSwitchers/Atem.ts new file mode 100644 index 00000000..438a36a9 --- /dev/null +++ b/src/tv2-common/videoSwitchers/Atem.ts @@ -0,0 +1,119 @@ +import { TSR } from 'blueprints-integration' +import { AtemSourceIndex } from '../../types/atem' +import { + AuxProps, + DskProps, + MixEffectProps, + SpecialInput, + SwitcherType, + TransitionStyle, + VideoSwitcherImpl +} from './index' + +const SPECIAL_INPUT_MAP = { + [SpecialInput.ME1_PROGRAM]: AtemSourceIndex.Prg1, + [SpecialInput.ME2_PROGRAM]: AtemSourceIndex.Prg2, + [SpecialInput.SSRC]: AtemSourceIndex.SSrc +} + +const TRANSITION_MAP = { + [TransitionStyle.CUT]: TSR.AtemTransitionStyle.CUT, + [TransitionStyle.DIP]: TSR.AtemTransitionStyle.DIP, + [TransitionStyle.MIX]: TSR.AtemTransitionStyle.MIX, + [TransitionStyle.WIPE]: TSR.AtemTransitionStyle.WIPE +} + +export class Atem extends VideoSwitcherImpl { + public readonly type = SwitcherType.ATEM + + public getMixEffectTimelineObject(props: MixEffectProps): TSR.TimelineObjAtemME { + const { content } = props + return { + id: props.id, + enable: props.enable, + layer: props.layer, + priority: props.priority, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.ME, + me: { + input: this.getInputNumber(content.input), + transition: this.getTransition(content.transition), + transitionSettings: this.getTransitionSettings(content.transition, content.transitionDuration) + } + } + } + } + + public getDskTimelineObjects(props: DskProps) { + const { content } = props + const timelineObject: TSR.TimelineObjAtemDSK = { + id: props.id, + enable: props.enable, + layer: props.layer, + priority: props.priority, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.DSK, + dsk: { + onAir: content.onAir, + sources: content.sources && { + fillSource: this.getInputNumber(content.sources.fillSource), + cutSource: this.getInputNumber(content.sources.cutSource) + }, + properties: content.properties && { + ...content.properties, + mask: { + enabled: false + } + } + } + } + } + return [timelineObject] + } + + public getAuxTimelineObject(props: AuxProps): TSR.TimelineObjAtemAUX { + return { + id: props.id, + enable: props.enable, + layer: props.layer, + priority: props.priority, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.AUX, + aux: { + input: this.getInputNumber(props.content.input) + } + } + } + } + + private getInputNumber(input: number | SpecialInput) { + if (typeof input === 'number') { + return input + } + return SPECIAL_INPUT_MAP[input] + } + private getTransition(transition: TransitionStyle) { + return TRANSITION_MAP[transition] + } + private getTransitionSettings( + transition: TransitionStyle, + duration?: number + ): TSR.AtemTransitionSettings | undefined { + if (!duration) { + duration = 1000 + } + switch (transition) { + case TransitionStyle.CUT: + return undefined + case TransitionStyle.WIPE: + return { wipe: { rate: duration } } + case TransitionStyle.MIX: + return { mix: { rate: duration } } + case TransitionStyle.DIP: + return { dip: { rate: duration, input: this.config.studio?.AtemSource?.Dip ?? AtemSourceIndex.Col2 } } + } + } +} diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts new file mode 100644 index 00000000..30d8cace --- /dev/null +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -0,0 +1,56 @@ +import { TSR } from 'blueprints-integration' +import { AuxProps, DskProps, MixEffectProps, SpecialInput, SwitcherType, TransitionStyle } from './types' +import { VideoSwitcherImpl } from './VideoSwitcher' + +const SPECIAL_INPUT_MAP = { + [SpecialInput.ME1_PROGRAM]: 'v1', + [SpecialInput.ME2_PROGRAM]: 'v2', + [SpecialInput.SSRC]: 'v2' // todo: get this from config +} + +const TRANSITION_MAP: Record = { + [TransitionStyle.CUT]: 'cut', + [TransitionStyle.MIX]: 'fade', + // making assumptions about the session here + [TransitionStyle.DIP]: 1, + [TransitionStyle.WIPE]: 2 +} + +export class TriCaster extends VideoSwitcherImpl { + public readonly type = SwitcherType.ATEM + + public getMixEffectTimelineObject(props: MixEffectProps): TSR.TimelineObjTriCasterME { + const { content } = props + return { + id: props.id, + enable: props.enable, + layer: props.layer, + priority: props.priority, + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME, + me: { + programInput: this.getInputName(content.input), + transition: { + effect: TRANSITION_MAP[content.transition], + duration: content.transitionDuration ?? 1000 // @todo defaults and ranges + } + } + } + } + } + + public getDskTimelineObjects(_properties: DskProps): TSR.TSRTimelineObj[] { + throw new Error('Method not implemented.') + } + public getAuxTimelineObject(_properties: AuxProps): TSR.TSRTimelineObj { + throw new Error('Method not implemented.') + } + + private getInputName(input: number | SpecialInput) { + if (typeof input === 'number') { + return `input${input}` + } + return SPECIAL_INPUT_MAP[input] + } +} diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts new file mode 100644 index 00000000..446ccd87 --- /dev/null +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -0,0 +1,32 @@ +import { TSR } from 'blueprints-integration' +import { + Atem, + AuxProps, + DskProps, + MixEffectProps, + SwitcherType, + TriCaster, + TV2StudioConfig, + VideoSwitcher +} from 'tv2-common' + +export abstract class VideoSwitcherImpl implements VideoSwitcher { + public static videoSwitcherSingleton: VideoSwitcherImpl | undefined = undefined + public static getVideoSwitcher(config: TV2StudioConfig): VideoSwitcherImpl { + if (!this.videoSwitcherSingleton || this.videoSwitcherSingleton.type !== config.studio.SwitcherType) { + this.videoSwitcherSingleton = + config.studio.SwitcherType === SwitcherType.ATEM ? new Atem(config) : new TriCaster(config) + } + return this.videoSwitcherSingleton + } + public abstract readonly type: SwitcherType + protected readonly config: TV2StudioConfig + + protected constructor(config: TV2StudioConfig) { + this.config = config + } + + public abstract getMixEffectTimelineObject(properties: MixEffectProps): TSR.TSRTimelineObj + public abstract getDskTimelineObjects(properties: DskProps): TSR.TSRTimelineObj[] + public abstract getAuxTimelineObject(properties: AuxProps): TSR.TSRTimelineObj +} diff --git a/src/tv2-common/videoSwitchers/index.ts b/src/tv2-common/videoSwitchers/index.ts new file mode 100644 index 00000000..f1a4488e --- /dev/null +++ b/src/tv2-common/videoSwitchers/index.ts @@ -0,0 +1,4 @@ +export * from './types' +export * from './VideoSwitcher' +export * from './Atem' +export * from './TriCaster' diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts new file mode 100644 index 00000000..cacf45f8 --- /dev/null +++ b/src/tv2-common/videoSwitchers/types.ts @@ -0,0 +1,66 @@ +import { TSR } from 'blueprints-integration' + +export enum SwitcherType { + ATEM = 'ATEM', + TRICASTER = 'TRICASTER' +} + +export enum SpecialInput { + ME1_PROGRAM = 'me1_program', + ME2_PROGRAM = 'me2_program', + SSRC = 'ssrc' + // ... +} + +export enum TransitionStyle { + CUT = 'cut', + MIX = 'mix', + WIPE = 'wipe', + DIP = 'dip' + // ... +} + +export interface TimelineObjectProps { + id: string + enable: TimelineObjectEnable + layer: string + priority: number +} + +type TimelineObjectEnable = TSR.TSRTimelineObj['enable'] + +export interface MixEffectProps extends TimelineObjectProps { + content: { + input: number | SpecialInput + transition: TransitionStyle + transitionDuration?: number + } +} + +export interface DskProps extends TimelineObjectProps { + content: { + onAir: boolean + sources?: { + fillSource: number | SpecialInput + cutSource: number | SpecialInput + } + properties?: { + tie?: boolean + preMultiply?: boolean + clip?: number // percents (0-100), atem uses 1-000, + gain?: number // percents (0-100), atem uses 1-000, + } + } +} + +export interface AuxProps extends TimelineObjectProps { + content: { + input: number | SpecialInput + } +} + +export interface VideoSwitcher { + getMixEffectTimelineObject: (properties: MixEffectProps) => TSR.TSRTimelineObj + getDskTimelineObjects: (properties: DskProps) => TSR.TSRTimelineObj[] + getAuxTimelineObject: (properties: AuxProps) => TSR.TSRTimelineObj +} diff --git a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts index c27aec8a..fe3e48a3 100644 --- a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts @@ -10,11 +10,11 @@ import { import { ActionCutToCamera, ActionTakeWithTransition, literal, SourceDefinitionKam } from 'tv2-common' import { AdlibActionType, NoteType, SharedOutputLayers, SourceType } from 'tv2-constants' import { ActionExecutionContext } from '../../__mocks__/context' -import { parseConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' +import { preprocessConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' import { AtemLLayer } from '../../tv2_afvd_studio/layers' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' import { executeActionAFVD } from '../actions' -import { parseConfig as parseShowStyleConfig } from '../helpers/config' +import { preprocessConfig as parseShowStyleConfig } from '../helpers/config' import { SourceLayer } from '../layers' import { MOCK_EFFEKT_1 } from './breakerConfigDefault' import { defaultShowStyleConfig, defaultStudioConfig } from './configs' diff --git a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts index 9cdf57a2..78db23c2 100644 --- a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts @@ -10,9 +10,9 @@ global.VERSION_INTEGRATION = 'test' import { ExtendedIngestRundown, IGetRundownContext, TSR } from 'blueprints-integration' import { GetRundownContext } from '../../__mocks__/context' import { SharedGraphicLLayer } from '../../tv2-constants' -import { parseConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' +import { preprocessConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' -import { parseConfig as parseShowStyleConfig } from '../helpers/config' +import { preprocessConfig as parseShowStyleConfig } from '../helpers/config' import Blueprints from '../index' import { defaultShowStyleConfig, defaultStudioConfig } from './configs' diff --git a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts index a517fa91..131bbafd 100644 --- a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts @@ -1,7 +1,7 @@ import { BlueprintResultSegment, IBlueprintActionManifestDisplayContent, IngestSegment } from 'blueprints-integration' import { INewsStory, literal, UnparsedCue } from 'tv2-common' import { SharedSourceLayers } from 'tv2-constants' -import { makeMockAFVDContext, SegmentUserContext } from '../../__mocks__/context' +import { makeMockCoreGalleryContext, SegmentUserContext } from '../../__mocks__/context' import { SisyfosLLAyer } from '../../tv2_afvd_studio/layers' import { getSegment } from '../getSegment' import { SourceLayer } from '../layers' @@ -49,7 +49,7 @@ function expectAllPartsToBeValid(result: BlueprintResultSegment) { describe('AFVD Blueprint', () => { it('Accepts KAM CS 3', async () => { const ingestSegment = makeIngestSegment([], `\r\nKam CS 3\r\n`) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -65,7 +65,7 @@ describe('AFVD Blueprint', () => { it('Accepts KAM CS3', async () => { const ingestSegment = makeIngestSegment([], `\r\nKam CS3\r\n`) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -92,7 +92,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['Graphic found without target engine']) expect(result.segment.isHidden).toBe(false) @@ -112,7 +112,7 @@ describe('AFVD Blueprint', () => { [['GRAFIK=FULL']], `\r\nKam 1\r\n

Some script

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after GRAFIK cue']) expect(result.segment.isHidden).toBe(false) @@ -144,7 +144,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -189,7 +189,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after GRAFIK cue']) expect(result.segment.isHidden).toBe(false) @@ -229,7 +229,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

\r\n

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['Cannot create overlay graphic with FULL']) expect(result.segment.isHidden).toBe(false) @@ -281,7 +281,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

\r\n

\r\n

\r\n` ) - const context = makeMockAFVDContext({ PreventOverlayWithFull: false }) + const context = makeMockCoreGalleryContext({ studioConfig: { PreventOverlayWithFull: false } }) const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -327,7 +327,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

Some script

\r\n

Some script

\r\n

Some script

\r\n

Some script

\r\n

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -373,7 +373,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

Some script

\r\n

Some script

\r\n

Some script

\r\n

Some script

\r\n

\r\n

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after GRAFIK cue', 'Graphic found without target engine']) expect(result.segment.isHidden).toBe(false) @@ -409,7 +409,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

Some script

\r\n

Some script

\r\n

Some script

\r\n

Some script

\r\n

\r\n

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after GRAFIK cue', 'Graphic found without target engine']) expect(result.segment.isHidden).toBe(false) @@ -444,7 +444,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

\r\nKam 2\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after GRAFIK cue', 'Graphic found without target engine']) expect(result.segment.isHidden).toBe(false) @@ -486,7 +486,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -519,7 +519,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -552,7 +552,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -597,7 +597,7 @@ describe('AFVD Blueprint', () => { ], `\r\n

Kam 1

\r\n

\r\n

\r\n

Some script

\r\n

Kam 2

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -630,7 +630,7 @@ describe('AFVD Blueprint', () => { ], `\r\n

Kam 1

\r\n

\r\n

Some script

\r\n

Kam 2

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after SS cue']) expect(result.segment.isHidden).toBe(false) @@ -663,7 +663,7 @@ describe('AFVD Blueprint', () => { ], `\r\n

Kam 1

\r\n

\r\n

\r\n

Some script

\r\n

Kam 2

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after SS cue']) expect(result.segment.isHidden).toBe(false) @@ -703,7 +703,7 @@ describe('AFVD Blueprint', () => { ], `\r\n

Kam 1

\r\n

\r\n

Some script

\r\n

Kam 2

\r\n

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after SS cue', 'Graphic found without target engine']) expect(result.segment.isHidden).toBe(false) @@ -733,7 +733,7 @@ describe('AFVD Blueprint', () => { ], `\r\n

KAM 1

\r\n

\r\n

\r\n

\r\n

Some script

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -754,7 +754,7 @@ describe('AFVD Blueprint', () => { it('Creates Live1', async () => { const ingestSegment = makeIngestSegment([['EKSTERN=LIVE1']], `\r\n

\r\n

`) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -769,7 +769,7 @@ describe('AFVD Blueprint', () => { it('Creates Live 1', async () => { const ingestSegment = makeIngestSegment([['EKSTERN=LIVE 1']], `\r\n

\r\n

`) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -784,7 +784,7 @@ describe('AFVD Blueprint', () => { it('Creates Feed1', async () => { const ingestSegment = makeIngestSegment([['EKSTERN=FEED1']], `\r\n

\r\n

`) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -799,7 +799,7 @@ describe('AFVD Blueprint', () => { it('Creates Feed 1', async () => { const ingestSegment = makeIngestSegment([['EKSTERN=FEED 1']], `\r\n

\r\n

`) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -817,7 +817,7 @@ describe('AFVD Blueprint', () => { [['EKSTERN=LIVE'], ['#kg direkte ODDER', ';0.00']], `\r\n

***LIVE***

\r\n

\r\n

\r\n` ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['EKSTERN source is not valid: "LIVE"']) @@ -828,7 +828,7 @@ describe('AFVD Blueprint', () => { it('Creates effekt for KAM 1 EFFEKT 1', async () => { const ingestSegment = makeIngestSegment([], '\r\n

KAM 1 EFFEKT 1

\r\n') - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expectAllPartsToBeValid(result) @@ -844,7 +844,7 @@ describe('AFVD Blueprint', () => { it('Creates mix for KAM 1 MIX 5', async () => { const ingestSegment = makeIngestSegment([], '\r\n

KAM 1 MIX 5

\r\n') - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expectAllPartsToBeValid(result) @@ -863,7 +863,7 @@ describe('AFVD Blueprint', () => { [['EKSTERN=LIVE 1 EFFEKT 1']], '\r\n

***LIVE***

\r\n

\r\n' ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expectAllPartsToBeValid(result) @@ -885,7 +885,7 @@ describe('AFVD Blueprint', () => { [['EKSTERN=LIVE 1 MIX 10']], '\r\n

***LIVE***

\r\n

\r\n' ) - const context = makeMockAFVDContext() + const context = makeMockCoreGalleryContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expectAllPartsToBeValid(result) @@ -904,16 +904,18 @@ describe('AFVD Blueprint', () => { it('Enables studio mics for LIVE when useStudioMics is enabled', async () => { const ingestSegment = makeIngestSegment([['EKSTERN=LIVE 1']], '\r\n

\r\n') - const context = makeMockAFVDContext({ - SourcesRM: [ - { - SourceName: '1', - AtemSource: 10, - SisyfosLayers: [], - StudioMics: true, - WantsToPersistAudio: false - } - ] + const context = makeMockCoreGalleryContext({ + studioConfig: { + SourcesRM: [ + { + SourceName: '1', + AtemSource: 10, + SisyfosLayers: [], + StudioMics: true, + WantsToPersistAudio: false + } + ] + } }) const result = await getSegment(context, ingestSegment) const livePart = result.parts[0] @@ -926,16 +928,18 @@ describe('AFVD Blueprint', () => { it('Does not enable studio mics for LIVE when useStudioMics is disabled', async () => { const ingestSegment = makeIngestSegment([['EKSTERN=LIVE 1']], '\r\n

\r\n') - const context = makeMockAFVDContext({ - SourcesRM: [ - { - SourceName: '1', - AtemSource: 10, - SisyfosLayers: [], - StudioMics: false, - WantsToPersistAudio: false - } - ] + const context = makeMockCoreGalleryContext({ + studioConfig: { + SourcesRM: [ + { + SourceName: '1', + AtemSource: 10, + SisyfosLayers: [], + StudioMics: false, + WantsToPersistAudio: false + } + ] + } }) const result = await getSegment(context, ingestSegment) const livePart = result.parts[0] @@ -948,16 +952,18 @@ describe('AFVD Blueprint', () => { it('Enables studio mics for KAM when useStudioMics is enabled', async () => { const ingestSegment = makeIngestSegment([], '\r\n

KAM 1

\r\n') - const context = makeMockAFVDContext({ - SourcesCam: [ - { - SourceName: '1', - AtemSource: 1, - SisyfosLayers: [], - StudioMics: true, - WantsToPersistAudio: false - } - ] + const context = makeMockCoreGalleryContext({ + studioConfig: { + SourcesCam: [ + { + SourceName: '1', + AtemSource: 1, + SisyfosLayers: [], + StudioMics: true, + WantsToPersistAudio: false + } + ] + } }) const result = await getSegment(context, ingestSegment) const livePart = result.parts[0] @@ -970,16 +976,18 @@ describe('AFVD Blueprint', () => { it('Does not enable studio mics for KAM minus mic when useStudioMics is enabled', async () => { const ingestSegment = makeIngestSegment([], '\r\n

KAM 1 minus mic

\r\n') - const context = makeMockAFVDContext({ - SourcesCam: [ - { - SourceName: '1', - AtemSource: 1, - SisyfosLayers: [], - StudioMics: true, - WantsToPersistAudio: false - } - ] + const context = makeMockCoreGalleryContext({ + studioConfig: { + SourcesCam: [ + { + SourceName: '1', + AtemSource: 1, + SisyfosLayers: [], + StudioMics: true, + WantsToPersistAudio: false + } + ] + } }) const result = await getSegment(context, ingestSegment) const livePart = result.parts[0] @@ -992,16 +1000,18 @@ describe('AFVD Blueprint', () => { it('Does not enable studio mics for KAM when useStudioMics is disabled', async () => { const ingestSegment = makeIngestSegment([], '\r\n

KAM 1

\r\n') - const context = makeMockAFVDContext({ - SourcesCam: [ - { - SourceName: '1', - AtemSource: 1, - SisyfosLayers: [], - StudioMics: false, - WantsToPersistAudio: false - } - ] + const context = makeMockCoreGalleryContext({ + studioConfig: { + SourcesCam: [ + { + SourceName: '1', + AtemSource: 1, + SisyfosLayers: [], + StudioMics: false, + WantsToPersistAudio: false + } + ] + } }) const result = await getSegment(context, ingestSegment) const livePart = result.parts[0] diff --git a/src/tv2_afvd_showstyle/__tests__/breakerConfigDefault.ts b/src/tv2_afvd_showstyle/__tests__/breakerConfigDefault.ts index 5096ccb9..00fc7199 100644 --- a/src/tv2_afvd_showstyle/__tests__/breakerConfigDefault.ts +++ b/src/tv2_afvd_showstyle/__tests__/breakerConfigDefault.ts @@ -1,6 +1,6 @@ -import { ShowStyleConfig } from '../helpers/config' +import { GalleryShowStyleConfig } from '../helpers/config' -export const MOCK_EFFEKT_1: ShowStyleConfig['BreakerConfig'][0] = { +export const MOCK_EFFEKT_1: GalleryShowStyleConfig['BreakerConfig'][0] = { BreakerName: '1', ClipName: 'EFFEKT_1', Duration: 100, @@ -10,7 +10,7 @@ export const MOCK_EFFEKT_1: ShowStyleConfig['BreakerConfig'][0] = { LoadFirstFrame: false } -export const MOCK_EFFEKT_2: ShowStyleConfig['BreakerConfig'][0] = { +export const MOCK_EFFEKT_2: GalleryShowStyleConfig['BreakerConfig'][0] = { BreakerName: '2', ClipName: 'EFFEKT_2', Duration: 200, @@ -20,7 +20,7 @@ export const MOCK_EFFEKT_2: ShowStyleConfig['BreakerConfig'][0] = { LoadFirstFrame: false } -export function DefaultBreakerConfig(): ShowStyleConfig['BreakerConfig'] { +export function DefaultBreakerConfig(): GalleryShowStyleConfig['BreakerConfig'] { return [ { BreakerName: 'WTA-OUTRO', diff --git a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts index 23e4ff81..6a5454be 100644 --- a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts @@ -1,8 +1,8 @@ import * as _ from 'underscore' import { showStyleConfigManifest } from '../config-manifests' -import { ShowStyleConfig } from '../helpers/config' +import { GalleryShowStyleConfig } from '../helpers/config' -const blankShowStyleConfig: ShowStyleConfig = { +const blankShowStyleConfig: GalleryShowStyleConfig = { MakeAdlibsForFulls: true, DVEStyles: [], GfxTemplates: [], diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index c47d368f..b017085e 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -1,6 +1,6 @@ -import { literal, parseMapStr } from 'tv2-common' +import { literal, parseMapStr, SwitcherType } from 'tv2-common' import { defaultDSKConfig, StudioConfig } from '../../tv2_afvd_studio/helpers/config' -import { GalleryTableConfigGfxSetup, ShowStyleConfig } from '../helpers/config' +import { GalleryShowStyleConfig, GalleryTableConfigGfxSetup } from '../helpers/config' import { DefaultBreakerConfig } from './breakerConfigDefault' import { DefaultGrafikConfig } from './grafikConfigDefault' @@ -54,6 +54,7 @@ export const DEFAULT_GFX_SETUP: GalleryTableConfigGfxSetup = { // in here will be some mock configs that can be referenced paired with ro's for the tests export const defaultStudioConfig: StudioConfig = { + SwitcherType: SwitcherType.ATEM, ClipMediaFlowId: '', GraphicMediaFlowId: '', JingleMediaFlowId: '', @@ -147,7 +148,7 @@ export const defaultStudioConfig: StudioConfig = { } } -export const defaultShowStyleConfig: ShowStyleConfig = { +export const defaultShowStyleConfig: GalleryShowStyleConfig = { ...defaultStudioConfig, DefaultTemplateDuration: 4, CasparCGLoadingClip: 'LoadingLoop', @@ -188,7 +189,7 @@ export const defaultShowStyleConfig: ShowStyleConfig = { MakeAdlibsForFulls: true, GfxTemplates: [ ...DefaultGrafikConfig(), - ...literal([ + ...literal([ { INewsCode: 'GRAFIK', INewsName: 'wall', diff --git a/src/tv2_afvd_showstyle/__tests__/layers-check.ts b/src/tv2_afvd_showstyle/__tests__/layers-check.ts index 1413a70a..55aed802 100644 --- a/src/tv2_afvd_showstyle/__tests__/layers-check.ts +++ b/src/tv2_afvd_showstyle/__tests__/layers-check.ts @@ -9,14 +9,14 @@ import { } from 'blueprints-integration' import { GetDSKSourceLayerNames } from 'tv2-common' +import { makeMockGalleryContext } from '../../__mocks__/context' import mappingsDefaults, { getMediaPlayerMappings } from '../../tv2_afvd_studio/migrations/mappings-defaults' import { ATEMModel } from '../../types/atem' -import { getConfig } from '../helpers/config' import { SourceLayer } from '../layers' import OutputlayerDefaults from '../migrations/outputlayer-defaults' export function checkAllLayers( - context: IShowStyleUserContext, + _context: IShowStyleUserContext, pieces: IBlueprintPieceGeneric[], otherObjs?: TSR.TSRTimelineObjBase[] ) { @@ -25,7 +25,8 @@ export function checkAllLayers( const missingLayers: Array = [] const wrongDeviceLayers: Array = [] - const config = getConfig(context) + // @todo: is this right? + const config = makeMockGalleryContext().config const allSourceLayers: string[] = _.values(SourceLayer) .map(l => l.toString()) diff --git a/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts b/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts index 6f89f7f8..da9a3c14 100644 --- a/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts @@ -13,15 +13,15 @@ global.VERSION_INTEGRATION = 'test' import { INewsStory } from 'tv2-common' import { SegmentUserContext } from '../../__mocks__/context' -import { parseConfig as parseStudioConfig, StudioConfig } from '../../tv2_afvd_studio/helpers/config' +import { preprocessConfig as parseStudioConfig, StudioConfig } from '../../tv2_afvd_studio/helpers/config' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' -import { parseConfig as parseShowStyleConfig, ShowStyleConfig } from '../helpers/config' +import { GalleryShowStyleConfig, preprocessConfig as parseShowStyleConfig } from '../helpers/config' import Blueprints from '../index' const onAirRundownRelativePath = '../../../rundowns/on-air.json' // More ROs can be listed here to make them part of the basic blueprint -const rundowns: Array<{ ro: string; studioConfig: StudioConfig; showStyleConfig: ShowStyleConfig }> = [ +const rundowns: Array<{ ro: string; studioConfig: StudioConfig; showStyleConfig: GalleryShowStyleConfig }> = [ { ro: onAirRundownRelativePath, studioConfig: defaultStudioConfig, showStyleConfig: defaultShowStyleConfig } ] diff --git a/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts b/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts index 5c709431..a92771d6 100644 --- a/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts @@ -11,9 +11,9 @@ import { import { literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import { SyncIngestUpdateToPartInstanceContext } from '../../__mocks__/context' -import { parseConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' +import { preprocessConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' -import { parseConfig as parseShowStyleConfig } from '../helpers/config' +import { preprocessConfig as parseShowStyleConfig } from '../helpers/config' import { SourceLayer } from '../layers' import { syncIngestUpdateToPartInstance } from '../syncIngestUpdateToPartInstance' diff --git a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts index a18fe971..164215dc 100644 --- a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts @@ -3,11 +3,11 @@ import { BlueprintResultSegment, IBlueprintPart, IBlueprintPiece, IngestSegment, import { TimeFromFrames } from 'tv2-common' import * as _ from 'underscore' import { SegmentUserContext } from '../../__mocks__/context' -import { parseConfig } from '../../tv2_afvd_studio/helpers/config' +import { preprocessConfig } from '../../tv2_afvd_studio/helpers/config' import { AtemLLayer } from '../../tv2_afvd_studio/layers' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' import { getSegment } from '../getSegment' -import { parseConfig as parseShowStyleConfig, ShowStyleConfig } from '../helpers/config' +import { GalleryShowStyleConfig, preprocessConfig as parseShowStyleConfig } from '../helpers/config' import { SourceLayer } from '../layers' import { MOCK_EFFEKT_1, MOCK_EFFEKT_2 } from './breakerConfigDefault' import { defaultShowStyleConfig, defaultStudioConfig } from './configs' @@ -68,7 +68,7 @@ function makeMockContextWithoutTransitionsConfig(): SegmentUserContext { function makeMockContext(): SegmentUserContext { const config = { id: 'default', studioConfig: defaultStudioConfig, showStyleConfig: defaultShowStyleConfig } - const mockContext = new SegmentUserContext('test', mappingsDefaults, parseConfig, parseShowStyleConfig) + const mockContext = new SegmentUserContext('test', mappingsDefaults, preprocessConfig, parseShowStyleConfig) mockContext.studioConfig = config.studioConfig as any mockContext.showStyleConfig = config.showStyleConfig as any @@ -88,7 +88,7 @@ function checkPartExistsWithProperties(segment: BlueprintResultSegment, props: P } } -function getTransitionProperties(effekt: ShowStyleConfig['BreakerConfig'][0]): Partial { +function getTransitionProperties(effekt: GalleryShowStyleConfig['BreakerConfig'][0]): Partial { const preroll = defaultStudioConfig.CasparPrerollDuration as number return { inTransition: { diff --git a/src/tv2_afvd_showstyle/actions.ts b/src/tv2_afvd_showstyle/actions.ts index 8a492e8c..81138715 100644 --- a/src/tv2_afvd_showstyle/actions.ts +++ b/src/tv2_afvd_showstyle/actions.ts @@ -1,7 +1,6 @@ import { ActionUserData, IActionExecutionContext } from 'blueprints-integration' import { executeAction, ServerSelectMode } from 'tv2-common' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' -import { getConfig } from './helpers/config' import { AFVD_DVE_GENERATOR_OPTIONS } from './helpers/content/dve' import { EvaluateCues } from './helpers/pieces/evaluateCues' import { pilotGeneratorSettingsAFVD } from './helpers/pieces/graphicPilot' @@ -18,7 +17,6 @@ export async function executeActionAFVD( await executeAction( context, { - getConfig, postProcessPieceTimelineObjects, EvaluateCues, DVEGeneratorOptions: AFVD_DVE_GENERATOR_OPTIONS, diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 1a9eff62..3191c956 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -7,7 +7,6 @@ import { ICommonContext, IngestRundown, IShowStyleUserContext, - IStudioUserContext, PieceLifespan, PlaylistTimingType, TimelineObjectCoreExt, @@ -28,6 +27,8 @@ import { CreateDSKBaselineAdlibs, CreateGraphicBaseline, CreateLYDBaseline, + ExtendedShowStyleContext, + ExtendedShowStyleContextImpl, FindDSKJingle, generateExternalId, GetSisyfosTimelineObjForRemote, @@ -40,7 +41,9 @@ import { SourceInfo, SourceInfoToSourceDefinition, SourceInfoType, - t + t, + TransitionStyle, + VideoSwitcher } from 'tv2-common' import { AdlibActionType, @@ -56,14 +59,13 @@ import * as _ from 'underscore' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' import { SisyfosChannel, sisyfosChannels } from '../tv2_afvd_studio/sisyfosChannels' import { AtemSourceIndex } from '../types/atem' -import { BlueprintConfig, getConfig as getShowStyleConfig } from './helpers/config' +import { GalleryBlueprintConfig } from './helpers/config' import { NUMBER_OF_DVE_BOXES } from './helpers/content/dve' import { SourceLayer } from './layers' import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' -export function getRundown(context: IShowStyleUserContext, ingestRundown: IngestRundown): BlueprintResultRundown { - const config = getShowStyleConfig(context) - +export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: IngestRundown): BlueprintResultRundown { + const context = new ExtendedShowStyleContextImpl(coreContext) return { rundown: { externalId: ingestRundown.externalId, @@ -72,16 +74,108 @@ export function getRundown(context: IShowStyleUserContext, ingestRundown: Ingest type: PlaylistTimingType.None } }, - globalAdLibPieces: getGlobalAdLibPiecesAFVD(context, config), - globalActions: getGlobalAdlibActionsAFVD(context, config), - baseline: getBaseline(config) + globalAdLibPieces: new GlobalAdLibPiecesGenerator(context).generate(), + globalActions: getGlobalAdlibActionsAFVD(context.core, context.config), // @todo + baseline: getBaseline(context.config, context.videoSwitcher) // @todo } } -function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: BlueprintConfig): IBlueprintAdLibPiece[] { - function makeEVSAdLibs(info: SourceInfo, rank: number, vo: boolean): Array> { - const res: Array> = [] - res.push({ +class GlobalAdLibPiecesGenerator { + private config: GalleryBlueprintConfig + constructor(private readonly context: ExtendedShowStyleContext) { + this.config = context.config + } + + public generate(): IBlueprintAdLibPiece[] { + const adLibPieces: IBlueprintAdLibPiece[] = [] + let globalRank = 1000 + + this.config.sources.lives + .slice(0, 10) // the first x lives to create live-adlibs from + .forEach(info => { + adLibPieces.push(...this.makeRemoteAdLibs(info, globalRank++)) + }) + + this.config.sources.lives + .slice(0, 10) // the first x lives to create AUX1 (studio) adlibs + .forEach(info => { + adLibPieces.push(...this.makeRemoteAuxStudioAdLibs(info, globalRank++)) + }) + + this.config.sources.replays.forEach(info => { + if (!/EPSIO/i.test(info.id)) { + adLibPieces.push(this.makeEvsAdLib(info, globalRank++, false)) + } + adLibPieces.push(this.makeEvsAdLib(info, globalRank++, true)) + adLibPieces.push(this.makeEvsStudioAuxAdLib(info, globalRank++)) + adLibPieces.push(this.makeEvsVizAuxAdLib(info, globalRank++)) + }) + + // the rank (order) of adlibs on SourceLayer.PgmAdlibVizCmd is important, to ensure keyboard shortcuts + adLibPieces.push(...this.makeGfxCommandAdLibs()) + adLibPieces.push(...CreateDSKBaselineAdlibs(this.config, 500, this.context.videoSwitcher)) + + adLibPieces.push(...this.makeSisyfosAdLibs()) + adLibPieces.push(this.makeAudioBedAdLib()) + + adLibPieces.forEach(p => postProcessPieceTimelineObjects(this.context, p, true)) + return adLibPieces + } + + // viz styles and dve backgrounds + public makeDesignAdLib(): IBlueprintAdLibPiece { + const timelineObjects: TimelineObjectCoreExt[] = [ + literal({ + id: '', + enable: { start: 0 }, + priority: 110, + layer: CasparLLayer.CasparCGDVELoop, + content: { + deviceType: TSR.DeviceType.CASPARCG, + type: TSR.TimelineContentTypeCasparCg.MEDIA, + file: 'dve/BG_LOADER_SC', + loop: true + } + }) + ] + // @todo: use GraphicsGenerator + if (this.config.studio.GraphicsType === 'VIZ') { + timelineObjects.push( + literal({ + id: '', + enable: { start: 0 }, + priority: 110, + layer: SharedGraphicLLayer.GraphicLLayerDesign, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, + templateName: 'BG_LOADER_SC', + templateData: [], + showName: this.config.selectedGfxSetup.OvlShowName + } + }) + ) + } + const adLibPiece: IBlueprintAdLibPiece = { + _rank: 301, + externalId: 'dve-design-sc', + name: 'DVE Design SC', + outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SourceLayer.PgmDesign, + lifespan: PieceLifespan.OutOnShowStyleEnd, + tags: [AdlibTags.ADLIB_DESIGN_STYLE_SC], + content: literal>({ + fileName: 'BG_LOADER_SC', + path: 'BG_LOADER_SC', + ignoreMediaObjectStatus: true, + timelineObjects + }) + } + return adLibPiece + } + + private makeEvsAdLib(info: SourceInfo, rank: number, vo: boolean): IBlueprintAdLibPiece { + return { externalId: 'delayed', name: replaySourceName(info.id, vo), _rank: rank, @@ -100,30 +194,81 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint content: { ignoreMediaObjectStatus: true, timelineObjects: [ - literal({ + this.context.videoSwitcher.getMixEffectTimelineObject({ id: '', enable: { while: '1' }, priority: 1, layer: AtemLLayer.AtemMEProgram, + content: { + input: info.port, + transition: TransitionStyle.CUT + } + }), + ...GetSisyfosTimelineObjForReplay(this.config, info, vo) + ] + } + } + } + + private makeEvsStudioAuxAdLib(info: SourceInfo, rank: number) { + return { + externalId: 'delayedaux', + name: `EVS in studio aux`, + _rank: rank, + sourceLayerId: SourceLayer.AuxStudioScreen, + outputLayerId: SharedOutputLayers.AUX, + expectedDuration: 0, + lifespan: PieceLifespan.OutOnShowStyleEnd, + tags: [AdlibTags.ADLIB_TO_STUDIO_SCREEN_AUX], + content: { + timelineObjects: [ + this.context.videoSwitcher.getAuxTimelineObject({ + id: '', + enable: { while: '1' }, + priority: 1, + layer: AtemLLayer.AtemAuxAR, + content: { + input: info.port + } + }) + ] + } + } + } + + private makeEvsVizAuxAdLib(info: SourceInfo, rank: number) { + return { + externalId: 'delayedaux', + name: `EVS in viz aux`, + _rank: rank, + sourceLayerId: SourceLayer.VizFullIn1, + outputLayerId: SharedOutputLayers.AUX, + expectedDuration: 0, + lifespan: PieceLifespan.OutOnShowStyleEnd, + tags: [AdlibTags.ADLIB_TO_GRAPHICS_ENGINE_AUX], + content: { + timelineObjects: [ + literal({ + id: '', + enable: { while: '1' }, + priority: 1, + layer: AtemLLayer.AtemAuxVizOvlIn1, content: { deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: info.port, - transition: TSR.AtemTransitionStyle.CUT + type: TSR.TimelineContentTypeAtem.AUX, + aux: { + input: info.port } } - }), - ...GetSisyfosTimelineObjForReplay(config, info, vo) + }) ] } - }) - return res + } } - function makeRemoteAdLibs(info: SourceInfo, rank: number): Array> { + private makeRemoteAdLibs(info: SourceInfo, rank: number): Array> { const res: Array> = [] - const eksternSisyfos = GetSisyfosTimelineObjForRemote(config, info) + const eksternSisyfos = GetSisyfosTimelineObjForRemote(this.config, info) res.push({ externalId: 'live', name: `LIVE ${info.id}`, @@ -166,7 +311,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint } // aux adlibs - function makeRemoteAuxStudioAdLibs(info: SourceInfo, rank: number): Array> { + private makeRemoteAuxStudioAdLibs(info: SourceInfo, rank: number): Array> { const res: Array> = [] res.push({ externalId: 'auxstudio', @@ -206,317 +351,192 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint return res } - const adlibItems: IBlueprintAdLibPiece[] = [] - - let globalRank = 1000 - - config.sources.lives - .slice(0, 10) // the first x lives to create live-adlibs from - .forEach(o => { - adlibItems.push(...makeRemoteAdLibs(o, globalRank++)) - }) - - config.sources.lives - .slice(0, 10) // the first x lives to create AUX1 (studio) adlibs - .forEach(o => { - adlibItems.push(...makeRemoteAuxStudioAdLibs(o, globalRank++)) - }) + private makeGfxCommandAdLibs() { + // the rank (order) of adlibs on SourceLayer.PgmAdlibVizCmd is important, to ensure keyboard shortcuts + return [ + { + externalId: 'loadGFX', + name: 'OVL INIT', + _rank: 100, + sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, + outputLayerId: SharedOutputLayers.SEC, + expectedDuration: 1000, + lifespan: PieceLifespan.WithinPart, + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_LOAD], + content: { + timelineObjects: _.compact([ + literal({ + id: 'loadAllElements', + enable: { + start: 0, + duration: 1000 + }, + priority: 100, + layer: SharedGraphicLLayer.GraphicLLayerAdLibs, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.LOAD_ALL_ELEMENTS + } + }) + ]) + } + }, + { + externalId: 'continueForward', + name: 'GFX Continue', + _rank: 200, + sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, + outputLayerId: SharedOutputLayers.SEC, + expectedDuration: 1000, + lifespan: PieceLifespan.WithinPart, + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_CONTINUE_FORWARD], + content: { + timelineObjects: [ + literal({ + id: '', + enable: { + start: 0, + duration: 1000 + }, + priority: 100, + layer: SharedGraphicLLayer.GraphicLLayerAdLibs, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.CONTINUE, + direction: 1, + reference: SharedGraphicLLayer.GraphicLLayerPilot + } + }) + ] + } + } + ] + } - config.sources.replays.forEach(o => { - if (!/EPSIO/i.test(o.id)) { - adlibItems.push(...makeEVSAdLibs(o, globalRank++, false)) - } - adlibItems.push(...makeEVSAdLibs(o, globalRank++, true)) - adlibItems.push({ - externalId: 'delayedaux', - name: `EVS in studio aux`, - _rank: globalRank++, - sourceLayerId: SourceLayer.AuxStudioScreen, - outputLayerId: SharedOutputLayers.AUX, - expectedDuration: 0, - lifespan: PieceLifespan.OutOnShowStyleEnd, - tags: [AdlibTags.ADLIB_TO_STUDIO_SCREEN_AUX], - content: { - timelineObjects: [ - literal({ - id: '', - enable: { while: '1' }, - priority: 1, - layer: AtemLLayer.AtemAuxAR, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: o.port + private makeSisyfosAdLibs(): IBlueprintAdLibPiece[] { + return [ + { + externalId: 'micUp', + name: 'Mics Up', + _rank: 600, + sourceLayerId: SourceLayer.PgmSisyfosAdlibs, + outputLayerId: SharedOutputLayers.SEC, + lifespan: PieceLifespan.WithinPart, + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_MICS_UP], + expectedDuration: 0, + content: { + timelineObjects: [ + literal({ + id: '', + enable: { start: 0 }, + priority: 10, + layer: SisyfosLLAyer.SisyfosGroupStudioMics, + content: { + deviceType: TSR.DeviceType.SISYFOS, + type: TSR.TimelineContentTypeSisyfos.CHANNELS, + channels: this.config.studio.StudioMics.map(layer => ({ + mappedLayer: layer, + isPgm: 1 + })), + overridePriority: 10 } - } - }) - ] + }) + ] + } + }, + { + externalId: 'micDown', + name: 'Mics Down', + _rank: 650, + sourceLayerId: SourceLayer.PgmSisyfosAdlibs, + outputLayerId: SharedOutputLayers.SEC, + lifespan: PieceLifespan.WithinPart, + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_MICS_DOWN], + expectedDuration: 0, + content: { + timelineObjects: [ + literal({ + id: '', + enable: { start: 0 }, + priority: 10, + layer: SisyfosLLAyer.SisyfosGroupStudioMics, + content: { + deviceType: TSR.DeviceType.SISYFOS, + type: TSR.TimelineContentTypeSisyfos.CHANNELS, + channels: this.config.studio.StudioMics.map(layer => ({ + mappedLayer: layer, + isPgm: 0 + })), + overridePriority: 10 + } + }) + ] + } + }, + { + externalId: 'resyncSisyfos', + name: 'Resync Sisyfos', + _rank: 700, + sourceLayerId: SourceLayer.PgmSisyfosAdlibs, + outputLayerId: SharedOutputLayers.SEC, + lifespan: PieceLifespan.WithinPart, + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIBS_RESYNC_SISYFOS], + expectedDuration: 1000, + content: { + timelineObjects: [ + literal({ + id: '', + enable: { start: 0 }, + priority: 2, + layer: SisyfosLLAyer.SisyfosResync, + content: { + deviceType: TSR.DeviceType.SISYFOS, + type: TSR.TimelineContentTypeSisyfos.CHANNEL, + resync: true + } + }) + ] + } } - }) - adlibItems.push({ - externalId: 'delayedaux', - name: `EVS in viz aux`, - _rank: globalRank++, - sourceLayerId: SourceLayer.VizFullIn1, - outputLayerId: SharedOutputLayers.AUX, - expectedDuration: 0, - lifespan: PieceLifespan.OutOnShowStyleEnd, - tags: [AdlibTags.ADLIB_TO_GRAPHICS_ENGINE_AUX], + ] + } + + private makeAudioBedAdLib(): IBlueprintAdLibPiece { + return { + externalId: 'stopAudioBed', + name: 'Stop Soundplayer', + _rank: 700, + sourceLayerId: SourceLayer.PgmAudioBed, + outputLayerId: 'musik', + expectedDuration: 1000, + lifespan: PieceLifespan.WithinPart, + tags: [AdlibTags.ADLIB_STOP_AUDIO_BED], content: { timelineObjects: [ - literal({ + literal({ id: '', - enable: { while: '1' }, - priority: 1, - layer: AtemLLayer.AtemAuxVizOvlIn1, + enable: { + start: 0, + duration: 1000 + }, + priority: 50, + layer: SisyfosLLAyer.SisyfosSourceAudiobed, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: o.port - } - } + deviceType: TSR.DeviceType.ABSTRACT, + type: 'empty' + }, + classes: [] }) ] } - }) - }) - - // the rank (order) of adlibs on SourceLayer.PgmAdlibVizCmd is important, to ensure keyboard shortcuts - adlibItems.push({ - externalId: 'loadGFX', - name: 'OVL INIT', - _rank: 100, - sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, - outputLayerId: SharedOutputLayers.SEC, - expectedDuration: 1000, - lifespan: PieceLifespan.WithinPart, - tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_LOAD], - content: { - timelineObjects: _.compact([ - literal({ - id: 'loadAllElements', - enable: { - start: 0, - duration: 1000 - }, - priority: 100, - layer: SharedGraphicLLayer.GraphicLLayerAdLibs, - content: { - deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.LOAD_ALL_ELEMENTS - } - }) - ]) - } - }) - // the rank (order) of adlibs on SourceLayer.PgmAdlibVizCmd is important, to ensure keyboard shortcuts - adlibItems.push({ - externalId: 'continueForward', - name: 'GFX Continue', - _rank: 200, - sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, - outputLayerId: SharedOutputLayers.SEC, - expectedDuration: 1000, - lifespan: PieceLifespan.WithinPart, - tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_CONTINUE_FORWARD], - content: { - timelineObjects: [ - literal({ - id: '', - enable: { - start: 0, - duration: 1000 - }, - priority: 100, - layer: SharedGraphicLLayer.GraphicLLayerAdLibs, - content: { - deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.CONTINUE, - direction: 1, - reference: SharedGraphicLLayer.GraphicLLayerPilot - } - }) - ] } - }) - - // the rank (order) of adlibs on SourceLayer.PgmAdlibVizCmd is important, to ensure keyboard shortcuts - adlibItems.push(...CreateDSKBaselineAdlibs(config, 500)) - - adlibItems.push({ - externalId: 'micUp', - name: 'Mics Up', - _rank: 600, - sourceLayerId: SourceLayer.PgmSisyfosAdlibs, - outputLayerId: SharedOutputLayers.SEC, - lifespan: PieceLifespan.WithinPart, - tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_MICS_UP], - expectedDuration: 0, - content: { - timelineObjects: [ - literal({ - id: '', - enable: { start: 0 }, - priority: 10, - layer: SisyfosLLAyer.SisyfosGroupStudioMics, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: config.studio.StudioMics.map(layer => ({ - mappedLayer: layer, - isPgm: 1 - })), - overridePriority: 10 - } - }) - ] - } - }) - - adlibItems.push({ - externalId: 'micDown', - name: 'Mics Down', - _rank: 650, - sourceLayerId: SourceLayer.PgmSisyfosAdlibs, - outputLayerId: SharedOutputLayers.SEC, - lifespan: PieceLifespan.WithinPart, - tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_MICS_DOWN], - expectedDuration: 0, - content: { - timelineObjects: [ - literal({ - id: '', - enable: { start: 0 }, - priority: 10, - layer: SisyfosLLAyer.SisyfosGroupStudioMics, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: config.studio.StudioMics.map(layer => ({ - mappedLayer: layer, - isPgm: 0 - })), - overridePriority: 10 - } - }) - ] - } - }) - - adlibItems.push({ - externalId: 'resyncSisyfos', - name: 'Resync Sisyfos', - _rank: 700, - sourceLayerId: SourceLayer.PgmSisyfosAdlibs, - outputLayerId: SharedOutputLayers.SEC, - lifespan: PieceLifespan.WithinPart, - tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIBS_RESYNC_SISYFOS], - expectedDuration: 1000, - content: { - timelineObjects: [ - literal({ - id: '', - enable: { start: 0 }, - priority: 2, - layer: SisyfosLLAyer.SisyfosResync, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - resync: true - } - }) - ] - } - }) - - // viz styles and dve backgrounds - function makeDesignAdLib(): IBlueprintAdLibPiece { - const timelineObjects: TimelineObjectCoreExt[] = [ - literal({ - id: '', - enable: { start: 0 }, - priority: 110, - layer: CasparLLayer.CasparCGDVELoop, - content: { - deviceType: TSR.DeviceType.CASPARCG, - type: TSR.TimelineContentTypeCasparCg.MEDIA, - file: 'dve/BG_LOADER_SC', - loop: true - } - }) - ] - if (config.studio.GraphicsType === 'VIZ') { - timelineObjects.push( - literal({ - id: '', - enable: { start: 0 }, - priority: 110, - layer: SharedGraphicLLayer.GraphicLLayerDesign, - content: { - deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, - templateName: 'BG_LOADER_SC', - templateData: [], - showName: config.selectedGfxSetup.OvlShowName - } - }) - ) - } - const adLibPiece: IBlueprintAdLibPiece = { - _rank: 301, - externalId: 'dve-design-sc', - name: 'DVE Design SC', - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: SourceLayer.PgmDesign, - lifespan: PieceLifespan.OutOnShowStyleEnd, - tags: [AdlibTags.ADLIB_DESIGN_STYLE_SC], - content: literal>({ - fileName: 'BG_LOADER_SC', - path: 'BG_LOADER_SC', - ignoreMediaObjectStatus: true, - timelineObjects - }) - } - return adLibPiece } - adlibItems.push(makeDesignAdLib()) - - adlibItems.push({ - externalId: 'stopAudioBed', - name: 'Stop Soundplayer', - _rank: 700, - sourceLayerId: SourceLayer.PgmAudioBed, - outputLayerId: 'musik', - expectedDuration: 1000, - lifespan: PieceLifespan.WithinPart, - tags: [AdlibTags.ADLIB_STOP_AUDIO_BED], - content: { - timelineObjects: [ - literal({ - id: '', - enable: { - start: 0, - duration: 1000 - }, - priority: 50, - layer: SisyfosLLAyer.SisyfosSourceAudiobed, - content: { - deviceType: TSR.DeviceType.ABSTRACT, - type: 'empty' - }, - classes: [] - }) - ] - } - }) - - adlibItems.forEach(p => postProcessPieceTimelineObjects(context, config, p, true)) - return adlibItems } -function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: BlueprintConfig): IBlueprintActionManifest[] { +function getGlobalAdlibActionsAFVD( + context: IShowStyleUserContext, + config: GalleryBlueprintConfig +): IBlueprintActionManifest[] { const blueprintActions: IBlueprintActionManifest[] = [] let globalRank = 1000 @@ -533,7 +553,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri sourceDefinition: SourceInfoToSourceDefinition(info) } blueprintActions.push({ - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.CUT_SOURCE_TO_BOX, userData, userDataManifest: {}, @@ -565,7 +585,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri } } blueprintActions.push({ - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.CUT_SOURCE_TO_BOX, userData, userDataManifest: {}, @@ -590,7 +610,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri sourceDefinition: { sourceType: SourceType.SERVER } } blueprintActions.push({ - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.CUT_SOURCE_TO_BOX, userData, userDataManifest: {}, @@ -614,7 +634,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri sourceDefinition } blueprintActions.push({ - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.CUT_TO_CAMERA, userData, userDataManifest: {}, @@ -652,7 +672,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri type: AdlibActionType.RECALL_LAST_LIVE } blueprintActions.push({ - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.RECALL_LAST_LIVE, userData, userDataManifest: {}, @@ -696,7 +716,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri label: 'GFX Clear' } return { - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.CLEAR_GRAPHICS, userData, userDataManifest: {}, @@ -720,7 +740,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri label: 'GFX Altud' } return { - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.CLEAR_GRAPHICS, userData, userDataManifest: {}, @@ -745,7 +765,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri type: AdlibActionType.RECALL_LAST_DVE } blueprintActions.push({ - externalId: generateExternalId(_context, recallLastLiveDveUserData), + externalId: generateExternalId(context, recallLastLiveDveUserData), actionId: AdlibActionType.RECALL_LAST_DVE, userData: recallLastLiveDveUserData, userDataManifest: {}, @@ -764,7 +784,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri config: dveConfig } blueprintActions.push({ - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.SELECT_DVE_LAYOUT, userData, userDataManifest: {}, @@ -782,7 +802,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri type: AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS } blueprintActions.push({ - externalId: generateExternalId(_context, fadeDownPersistedAudioLevelsUserData), + externalId: generateExternalId(context, fadeDownPersistedAudioLevelsUserData), actionId: AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS, userData: fadeDownPersistedAudioLevelsUserData, userDataManifest: {}, @@ -795,7 +815,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri } }) - blueprintActions.push(createRobotPresetAction(_context)) + blueprintActions.push(createRobotPresetAction(context)) return blueprintActions } @@ -819,7 +839,7 @@ function createRobotPresetAction(context: ICommonContext): IBlueprintActionManif } } -function getBaseline(config: BlueprintConfig): BlueprintResultBaseline { +function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitcher): BlueprintResultBaseline { const jingleDSK = FindDSKJingle(config) return { @@ -936,7 +956,7 @@ function getBaseline(config: BlueprintConfig): BlueprintResultBaseline { }), // keyers - ...CreateDSKBaseline(config), + ...CreateDSKBaseline(config, videoSwitcher), // ties the DSK for jingles to ME4 USK1 to have effects on CLEAN (ME4) literal({ diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index 39685e16..6aaa8d58 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -9,12 +9,11 @@ import { TSR, WithTimeline } from 'blueprints-integration' -import { getSegmentBase, INewsPayload, literal } from 'tv2-common' +import { ExtendedSegmentContextImpl, getSegmentBase, INewsPayload, literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import * as _ from 'underscore' -import { StudioConfig } from '../tv2_afvd_studio/helpers/config' import { AtemLLayer } from '../tv2_afvd_studio/layers' -import { BlueprintConfig as ShowStyleConfig, getConfig } from './helpers/config' +import { GalleryBlueprintConfig } from './helpers/config' import { CreateShowLifecyclePieces } from './helpers/pieces/showLifecycle' import { SourceLayer } from './layers' import { CreatePartEVS } from './parts/evs' @@ -26,15 +25,15 @@ import { CreatePartServer } from './parts/server' import { CreatePartTeknik } from './parts/teknik' import { CreatePartUnknown } from './parts/unknown' import { postProcessPartTimelineObjects } from './postProcessTimelineObjects' + export async function getSegment( - context: ISegmentUserContext, + coreContext: ISegmentUserContext, ingestSegment: IngestSegment ): Promise { - const config = getConfig(context) const segmentPayload = ingestSegment.payload as INewsPayload | undefined + const context = new ExtendedSegmentContextImpl(coreContext) - const result: BlueprintResultSegment = await getSegmentBase(context, ingestSegment, { - getConfig, + const result: BlueprintResultSegment = await getSegmentBase(context, ingestSegment, { CreatePartContinuity, CreatePartUnknown, CreatePartIntro, @@ -51,10 +50,10 @@ export async function getSegment( const blueprintParts = result.parts if (segmentPayload) { - insertSpecialPieces(config, blueprintParts, segmentPayload) + insertSpecialPieces(context.config, blueprintParts, segmentPayload) } - postProcessPartTimelineObjects(context, config, blueprintParts) + postProcessPartTimelineObjects(context, blueprintParts) return { segment: result.segment, @@ -62,7 +61,10 @@ export async function getSegment( } } -export function CreatePartContinuity(config: ShowStyleConfig, ingestSegment: IngestSegment): BlueprintResultPart { +export function CreatePartContinuity( + config: GalleryBlueprintConfig, + ingestSegment: IngestSegment +): BlueprintResultPart { return { part: { externalId: `${ingestSegment.externalId}-CONTINUITY`, @@ -109,7 +111,7 @@ export function CreatePartContinuity(config: ShowStyleConfig, ingestSegment: Ing } function insertSpecialPieces( - config: ShowStyleConfig, + config: GalleryBlueprintConfig, blueprintParts: BlueprintResultPart[], segmentPayload: INewsPayload ) { diff --git a/src/tv2_afvd_showstyle/helpers/config.ts b/src/tv2_afvd_showstyle/helpers/config.ts index 586f9bf0..f0aced4f 100644 --- a/src/tv2_afvd_showstyle/helpers/config.ts +++ b/src/tv2_afvd_showstyle/helpers/config.ts @@ -1,11 +1,11 @@ -import { IBlueprintConfig, ICommonContext, IShowStyleContext, TableConfigItemValue } from 'blueprints-integration' +import { IBlueprintConfig, ICommonContext, TableConfigItemValue } from 'blueprints-integration' import { findGfxSetup, TableConfigGfxSetup, TableConfigItemGfxShowMapping, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' -import { BlueprintConfig as BlueprintConfigBase } from '../../tv2_afvd_studio/helpers/config' +import { GalleryStudioConfig } from '../../tv2_afvd_studio/helpers/config' export interface GalleryTableConfigGfxSetup extends TableConfigGfxSetup { VcpConcept: string @@ -13,20 +13,20 @@ export interface GalleryTableConfigGfxSetup extends TableConfigGfxSetup { OvlShowName: string } -export interface BlueprintConfig extends BlueprintConfigBase { - showStyle: ShowStyleConfig +export interface GalleryBlueprintConfig extends GalleryStudioConfig { + showStyle: GalleryShowStyleConfig selectedGfxSetup: GalleryTableConfigGfxSetup } -export interface ShowStyleConfig extends TV2ShowstyleBlueprintConfigBase { +export interface GalleryShowStyleConfig extends TV2ShowstyleBlueprintConfigBase { WipesConfig: TableConfigItemValue SelectedGfxSetupName: string GfxSetups: GalleryTableConfigGfxSetup[] GfxShowMapping: TableConfigItemGfxShowMapping[] } -export function parseConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { - const showstyleConfig = (rawConfig as unknown) as ShowStyleConfig +export function preprocessConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { + const showstyleConfig = (rawConfig as unknown) as GalleryShowStyleConfig const selectedGfxSetup = findGfxSetup(context, showstyleConfig, { Name: '', VcpConcept: '', @@ -39,7 +39,3 @@ export function parseConfig(context: ICommonContext, rawConfig: IBlueprintConfig selectedGfxSetup } } - -export function getConfig(context: IShowStyleContext): BlueprintConfig { - return ({ ...(context.getStudioConfig() as any), ...(context.getShowStyleConfig() as any) } as any) as BlueprintConfig -} diff --git a/src/tv2_afvd_showstyle/helpers/content/dve.ts b/src/tv2_afvd_showstyle/helpers/content/dve.ts index e30d2c16..c03c65c5 100644 --- a/src/tv2_afvd_showstyle/helpers/content/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/content/dve.ts @@ -1,6 +1,13 @@ -import { IShowStyleUserContext, SplitsContent, WithTimeline } from 'blueprints-integration' -import { CueDefinitionDVE, DVEConfigInput, DVEOptions, MakeContentDVEBase, PartDefinition } from 'tv2-common' -import { BlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' +import { SplitsContent, WithTimeline } from 'blueprints-integration' +import { + CueDefinitionDVE, + DVEConfigInput, + DVEOptions, + ExtendedShowStyleContext, + MakeContentDVEBase, + PartDefinition +} from 'tv2-common' +import { GalleryBlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' export const NUMBER_OF_DVE_BOXES = 4 @@ -29,11 +36,10 @@ export const AFVD_DVE_GENERATOR_OPTIONS: DVEOptions = { } export function MakeContentDVE( - context: IShowStyleUserContext, - config: BlueprintConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, parsedCue: CueDefinitionDVE, dveConfig: DVEConfigInput | undefined ): { content: WithTimeline; valid: boolean } { - return MakeContentDVEBase(context, config, partDefinition, parsedCue, dveConfig, AFVD_DVE_GENERATOR_OPTIONS) + return MakeContentDVEBase(context, partDefinition, parsedCue, dveConfig, AFVD_DVE_GENERATOR_OPTIONS) } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts index 64220f24..6c9c90e1 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -19,24 +19,11 @@ import { PieceMetaData } from 'tv2-common' import { AdlibTags, CueType, PartType, SharedGraphicLLayer, SharedOutputLayers, SourceType } from 'tv2-constants' -import { SegmentUserContext } from '../../../../__mocks__/context' -import { parseConfig as parseStudioConfig } from '../../../../tv2_afvd_studio/helpers/config' -import mappingsDefaults from '../../../../tv2_afvd_studio/migrations/mappings-defaults' -import { defaultShowStyleConfig, defaultStudioConfig, OVL_SHOW_NAME } from '../../../__tests__/configs' +import { makeMockGalleryContext } from '../../../../__mocks__/context' +import { OVL_SHOW_NAME } from '../../../__tests__/configs' import { SourceLayer } from '../../../layers' -import { BlueprintConfig, getConfig, parseConfig as parseShowStyleConfig } from '../../config' import { EvaluateCueGraphic } from '../graphic' -function makeMockContext() { - const mockContext = new SegmentUserContext('test', mappingsDefaults, parseStudioConfig, parseShowStyleConfig) - mockContext.studioConfig = defaultStudioConfig as any - mockContext.showStyleConfig = defaultShowStyleConfig as any - - return mockContext -} - -const config = getConfig(makeMockContext()) - const dummyPart = literal({ type: PartType.Kam, sourceDefinition: { sourceType: SourceType.KAM, id: '1', raw: 'Kam 1', minusMic: false, name: 'KAM 1' }, @@ -119,8 +106,7 @@ describe('grafik piece', () => { const partId = '0000000001' EvaluateCueGraphic( - config, - makeMockContext(), + makeMockGalleryContext(), pieces, adLibPieces, actions, @@ -194,8 +180,7 @@ describe('grafik piece', () => { const partId = '0000000001' EvaluateCueGraphic( - config, - makeMockContext(), + makeMockGalleryContext(), pieces, adLibPieces, actions, @@ -305,12 +290,9 @@ describe('grafik piece', () => { const adLibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - const newConfig = JSON.parse(JSON.stringify(config)) as BlueprintConfig - newConfig.studio.PreventOverlayWithFull = false EvaluateCueGraphic( - newConfig, - makeMockContext(), + makeMockGalleryContext({ studioConfig: { PreventOverlayWithFull: false } }), pieces, adLibPieces, actions, @@ -424,8 +406,7 @@ describe('grafik piece', () => { const partId = '0000000001' EvaluateCueGraphic( - config, - makeMockContext(), + makeMockGalleryContext(), pieces, adLibPieces, actions, @@ -488,8 +469,7 @@ describe('grafik piece', () => { const partId = '0000000001' EvaluateCueGraphic( - config, - makeMockContext(), + makeMockGalleryContext(), pieces, adLibPieces, actions, @@ -522,8 +502,7 @@ describe('grafik piece', () => { const partId = '0000000001' EvaluateCueGraphic( - config, - makeMockContext(), + makeMockGalleryContext(), pieces, adLibPieces, actions, @@ -556,8 +535,7 @@ describe('grafik piece', () => { const partId = '0000000001' EvaluateCueGraphic( - config, - makeMockContext(), + makeMockGalleryContext(), pieces, adLibPieces, actions, @@ -604,8 +582,7 @@ describe('grafik piece', () => { const partId = '0000000001' EvaluateCueGraphic( - config, - makeMockContext(), + makeMockGalleryContext(), pieces, adLibPieces, actions, @@ -680,8 +657,7 @@ describe('grafik piece', () => { const partId = '0000000001' EvaluateCueGraphic( - config, - makeMockContext(), + makeMockGalleryContext(), pieces, adLibPieces, actions, @@ -755,8 +731,7 @@ describe('grafik piece', () => { const partId = '0000000001' EvaluateCueGraphic( - config, - makeMockContext(), + makeMockGalleryContext(), pieces, adLibPieces, actions, @@ -872,8 +847,7 @@ describe('grafik piece', () => { const partId = '0000000001' EvaluateCueGraphic( - config, - makeMockContext(), + makeMockGalleryContext(), pieces, adLibPieces, actions, @@ -915,8 +889,7 @@ describe('grafik piece', () => { const partId = '0000000001' EvaluateCueGraphic( - config, - makeMockContext(), + makeMockGalleryContext(), pieces, adLibPieces, actions, @@ -953,8 +926,7 @@ describe('grafik piece', () => { const partId = '0000000001' EvaluateCueGraphic( - config, - makeMockContext(), + makeMockGalleryContext(), pieces, adLibPieces, actions, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts index 48915915..c5958427 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts @@ -7,30 +7,9 @@ import { } from 'blueprints-integration' import { CueDefinitionLYD, EvaluateLYD, literal, ParseCue, PartDefinitionKam } from 'tv2-common' import { AdlibTags, NoteType, PartType, SharedOutputLayers, SharedSourceLayers, SourceType } from 'tv2-constants' -import { SegmentUserContext } from '../../../../__mocks__/context' -import { - DEFAULT_GFX_SETUP, - defaultShowStyleConfig, - defaultStudioConfig, - EMPTY_SOURCE_CONFIG -} from '../../../../tv2_afvd_showstyle/__tests__/configs' -import { - defaultDSKConfig, - parseConfig as parseStudioConfig, - StudioConfig -} from '../../../../tv2_afvd_studio/helpers/config' -import mappingsDefaults from '../../../../tv2_afvd_studio/migrations/mappings-defaults' -import { getConfig, parseConfig as parseShowStyleConfig, ShowStyleConfig } from '../../config' - -function makeMockContext() { - const mockContext = new SegmentUserContext('test', mappingsDefaults, parseStudioConfig, parseShowStyleConfig) - mockContext.studioConfig = defaultStudioConfig as any - mockContext.showStyleConfig = defaultShowStyleConfig as any - - return mockContext -} - -const CONFIG = getConfig(makeMockContext()) +import { makeMockGalleryContext, SegmentUserContext } from '../../../../__mocks__/context' + +const CONFIG = makeMockGalleryContext().config const MOCK_PART = literal({ type: PartType.Kam, sourceDefinition: { sourceType: SourceType.KAM, id: '1', raw: 'Kam 1', minusMic: false, name: 'KAM 1' }, @@ -51,22 +30,7 @@ describe('lyd', () => { const adlibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] - EvaluateLYD( - makeMockContext(), - { - showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, - studio: (defaultStudioConfig as unknown) as StudioConfig, - sources: EMPTY_SOURCE_CONFIG, - mediaPlayers: [], - dsk: defaultDSKConfig, - selectedGfxSetup: DEFAULT_GFX_SETUP - }, - pieces, - adlibPieces, - actions, - parsedCue, - MOCK_PART - ) + EvaluateLYD(makeMockGalleryContext(), pieces, adlibPieces, actions, parsedCue, MOCK_PART) expect(pieces[0].enable).toEqual( literal({ @@ -83,22 +47,7 @@ describe('lyd', () => { const adlibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] - EvaluateLYD( - makeMockContext(), - { - showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, - studio: (defaultStudioConfig as unknown) as StudioConfig, - sources: EMPTY_SOURCE_CONFIG, - mediaPlayers: [], - dsk: defaultDSKConfig, - selectedGfxSetup: DEFAULT_GFX_SETUP - }, - pieces, - adlibPieces, - actions, - parsedCue, - MOCK_PART - ) + EvaluateLYD(makeMockGalleryContext(), pieces, adlibPieces, actions, parsedCue, MOCK_PART) expect(pieces[0].enable).toEqual( literal({ @@ -116,28 +65,13 @@ describe('lyd', () => { const adlibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] - const context = makeMockContext() + const context = makeMockGalleryContext() - EvaluateLYD( - context, - { - showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, - studio: (defaultStudioConfig as unknown) as StudioConfig, - sources: EMPTY_SOURCE_CONFIG, - mediaPlayers: [], - dsk: defaultDSKConfig, - selectedGfxSetup: DEFAULT_GFX_SETUP - }, - pieces, - adlibPieces, - actions, - parsedCue, - MOCK_PART - ) + EvaluateLYD(context, pieces, adlibPieces, actions, parsedCue, MOCK_PART) expect(pieces.length).toEqual(0) - expect(context.getNotes().length).toEqual(1) - expect(context.getNotes()[0].type).toEqual(NoteType.NOTIFY_USER_WARNING) + expect((context.core as SegmentUserContext).getNotes().length).toEqual(1) + expect((context.core as SegmentUserContext).getNotes()[0].type).toEqual(NoteType.NOTIFY_USER_WARNING) }) test('Lyd adlib', () => { @@ -146,23 +80,7 @@ describe('lyd', () => { const adlibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] - EvaluateLYD( - makeMockContext(), - { - showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, - studio: (defaultStudioConfig as unknown) as StudioConfig, - sources: EMPTY_SOURCE_CONFIG, - mediaPlayers: [], - dsk: defaultDSKConfig, - selectedGfxSetup: DEFAULT_GFX_SETUP - }, - pieces, - adlibPieces, - actions, - parsedCue, - MOCK_PART, - true - ) + EvaluateLYD(makeMockGalleryContext(), pieces, adlibPieces, actions, parsedCue, MOCK_PART, true) expect(adlibPieces.length).toEqual(1) expect(adlibPieces[0]).toMatchObject( @@ -184,7 +102,7 @@ describe('lyd', () => { CONFIG.studio.AudioBedFolder = 'audio' - EvaluateLYD(makeMockContext(), CONFIG, pieces, adLibPieces, actions, parsedCue, MOCK_PART) + EvaluateLYD(makeMockGalleryContext(), pieces, adLibPieces, actions, parsedCue, MOCK_PART) expect(pieces).toHaveLength(1) const timelineObject: TSR.TimelineObjCCGMedia = pieces[0].content.timelineObjects[0] as TSR.TimelineObjCCGMedia @@ -200,18 +118,28 @@ describe('lyd', () => { const actions: IBlueprintActionManifest[] = [] const audioBedFolder = 'audio' - CONFIG.studio.AudioBedFolder = audioBedFolder const fileName: string = 'someFileName' - CONFIG.showStyle.LYDConfig = [ - { - _id: 'someId', - INewsName: iNewsName, - FileName: fileName - } - ] - - EvaluateLYD(makeMockContext(), CONFIG, pieces, adLibPieces, actions, parsedCue, MOCK_PART) + + EvaluateLYD( + makeMockGalleryContext({ + studioConfig: { AudioBedFolder: audioBedFolder }, + showStyleConfig: { + LYDConfig: [ + { + _id: 'someId', + INewsName: iNewsName, + FileName: fileName + } + ] + } + }), + pieces, + adLibPieces, + actions, + parsedCue, + MOCK_PART + ) expect(pieces).toHaveLength(1) const timelineObject: TSR.TimelineObjCCGMedia = pieces[0].content.timelineObjects[0] as TSR.TimelineObjCCGMedia diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts index 5395250d..21d4283e 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -17,27 +17,13 @@ import { PartDefinitionKam } from 'tv2-common' import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayers, SourceType } from 'tv2-constants' -import { SegmentUserContext } from '../../../../__mocks__/context' -import { - DEFAULT_GFX_SETUP, - defaultShowStyleConfig, - defaultStudioConfig, - OVL_SHOW_NAME -} from '../../../../tv2_afvd_showstyle/__tests__/configs' +import { makeMockGalleryContext } from '../../../../__mocks__/context' +import { OVL_SHOW_NAME } from '../../../../tv2_afvd_showstyle/__tests__/configs' import { SourceLayer } from '../../../../tv2_afvd_showstyle/layers' -import { - defaultDSKConfig, - parseConfig as parseStudioConfig, - StudioConfig -} from '../../../../tv2_afvd_studio/helpers/config' import { SisyfosLLAyer } from '../../../../tv2_afvd_studio/layers' -import mappingsDefaults from '../../../../tv2_afvd_studio/migrations/mappings-defaults' -import { parseConfig as parseShowStyleConfig, ShowStyleConfig } from '../../config' import { EvaluateTelefon } from '../telefon' -const mockContext = new SegmentUserContext('test', mappingsDefaults, parseStudioConfig, parseShowStyleConfig) -mockContext.studioConfig = defaultStudioConfig as any -mockContext.showStyleConfig = defaultShowStyleConfig as any +const mockContext = makeMockGalleryContext() const dummyPart = literal({ type: PartType.Kam, @@ -83,28 +69,7 @@ describe('telefon', () => { const adLibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateTelefon( - { - showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, - studio: (defaultStudioConfig as unknown) as StudioConfig, - sources: { - cameras: [], - lives: [], - feeds: [], - replays: [] - }, - mediaPlayers: [], - dsk: defaultDSKConfig, - selectedGfxSetup: DEFAULT_GFX_SETUP - }, - mockContext, - pieces, - adLibPieces, - actions, - partId, - dummyPart, - cue - ) + EvaluateTelefon(mockContext, pieces, adLibPieces, actions, partId, dummyPart, cue) expect(pieces).toEqual([ literal>({ externalId: partId, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts index 82cbea1b..4536fe76 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts @@ -1,13 +1,10 @@ -import { - HackPartMediaObjectSubscription, - IBlueprintActionManifest, - IShowStyleUserContext -} from 'blueprints-integration' +import { HackPartMediaObjectSubscription, IBlueprintActionManifest } from 'blueprints-integration' import { ActionSelectDVE, CreateAdlibServer, CueDefinitionAdLib, CueDefinitionDVE, + ExtendedShowStyleContext, generateExternalId, GetDVETemplate, getUniquenessIdDVE, @@ -16,14 +13,13 @@ import { TemplateIsValid } from 'tv2-common' import { AdlibActionType, AdlibTags, CueType, SharedOutputLayers } from 'tv2-constants' -import { BlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' +import { GalleryBlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' import { MakeContentDVE } from '../content/dve' export async function EvaluateAdLib( - context: IShowStyleUserContext, - config: BlueprintConfig, + context: ExtendedShowStyleContext, actions: IBlueprintActionManifest[], mediaSubscriptions: HackPartMediaObjectSubscription[], parsedCue: CueDefinitionAdLib, @@ -41,7 +37,6 @@ export async function EvaluateAdLib( actions.push( await CreateAdlibServer( context, - config, rank, partDefinition, file, @@ -74,14 +69,14 @@ export async function EvaluateAdLib( return } - const rawTemplate = GetDVETemplate(config.showStyle.DVEStyles, parsedCue.variant) + const rawTemplate = GetDVETemplate(context.config.showStyle.DVEStyles, parsedCue.variant) if (!rawTemplate) { - context.notifyUserWarning(`Could not find template ${parsedCue.variant}`) + context.core.notifyUserWarning(`Could not find template ${parsedCue.variant}`) return } if (!TemplateIsValid(rawTemplate.DVEJSON)) { - context.notifyUserWarning(`Invalid DVE template ${parsedCue.variant}`) + context.core.notifyUserWarning(`Invalid DVE template ${parsedCue.variant}`) return } @@ -93,7 +88,7 @@ export async function EvaluateAdLib( iNewsCommand: 'DVE' } - const content = MakeContentDVE(context, config, partDefinition, cueDVE, rawTemplate) + const content = MakeContentDVE(context, partDefinition, cueDVE, rawTemplate) const userData: ActionSelectDVE = { type: AdlibActionType.SELECT_DVE, @@ -103,7 +98,7 @@ export async function EvaluateAdLib( segmentExternalId: partDefinition.segmentExternalId } actions.push({ - externalId: generateExternalId(context, userData), + externalId: generateExternalId(context.core, userData), actionId: AdlibActionType.SELECT_DVE, userData, userDataManifest: {}, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts index d2d88e4f..edbd22fb 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts @@ -5,13 +5,19 @@ import { PieceLifespan, TSR } from 'blueprints-integration' -import { CreateTimingEnable, CueDefinitionClearGrafiks, GetDefaultOut, literal } from 'tv2-common' +import { + CreateTimingEnable, + CueDefinitionClearGrafiks, + ExtendedShowStyleContext, + GetDefaultOut, + literal +} from 'tv2-common' import { SharedGraphicLLayer, SharedOutputLayers } from 'tv2-constants' -import { BlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' +import { GalleryBlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { SourceLayer } from '../../../tv2_afvd_showstyle/layers' export function EvaluateClearGrafiks( - config: BlueprintConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], _adLibPieces: IBlueprintAdLibPiece[], _actions: IBlueprintActionManifest[], @@ -35,7 +41,7 @@ export function EvaluateClearGrafiks( externalId: partId, name: `CLEAR ${sourceLayerId}`, enable: { - start: CreateTimingEnable(parsedCue, GetDefaultOut(config)).enable.start, + start: CreateTimingEnable(parsedCue, GetDefaultOut(context.config)).enable.start, duration: 1000 }, outputLayerId: SharedOutputLayers.SEC, @@ -51,12 +57,12 @@ export function EvaluateClearGrafiks( pieces.push({ externalId: partId, name: 'CLEAR', - ...CreateTimingEnable(parsedCue, GetDefaultOut(config)), + ...CreateTimingEnable(parsedCue, GetDefaultOut(context.config)), outputLayerId: SharedOutputLayers.SEC, sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, lifespan: PieceLifespan.WithinPart, content: { - timelineObjects: config.studio.HTMLGraphics + timelineObjects: context.config.studio.HTMLGraphics ? [ literal({ id: '', @@ -69,7 +75,7 @@ export function EvaluateClearGrafiks( content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, - showName: config.selectedGfxSetup.OvlShowName + showName: context.config.selectedGfxSetup.OvlShowName } }) ] diff --git a/src/tv2_afvd_showstyle/helpers/pieces/design.ts b/src/tv2_afvd_showstyle/helpers/pieces/design.ts index af0d22e1..d94c3edc 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/design.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/design.ts @@ -1,15 +1,9 @@ -import { - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPiece, - ISegmentUserContext -} from 'blueprints-integration' -import { CueDefinitionGraphicDesign, EvaluateDesignBase, TV2BlueprintConfig } from 'tv2-common' +import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' +import { CueDefinitionGraphicDesign, EvaluateDesignBase, ExtendedShowStyleContext } from 'tv2-common' import * as _ from 'underscore' export function EvaluateCueDesign( - config: TV2BlueprintConfig, - context: ISegmentUserContext, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -18,5 +12,5 @@ export function EvaluateCueDesign( adlib?: boolean, rank?: number ) { - EvaluateDesignBase(config, context, pieces, adlibPieces, actions, partId, parsedCue, adlib, rank) + EvaluateDesignBase(context, pieces, adlibPieces, actions, partId, parsedCue, adlib, rank) } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts index e4db171f..6e88718e 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts @@ -1,9 +1,10 @@ -import { IBlueprintActionManifest, IBlueprintPiece, ISegmentUserContext, PieceLifespan } from 'blueprints-integration' +import { IBlueprintActionManifest, IBlueprintPiece, PieceLifespan } from 'blueprints-integration' import { ActionSelectDVE, CalculateTime, CueDefinitionDVE, DVEPieceMetaData, + ExtendedShowStyleContext, generateExternalId, GetDVETemplate, getUniquenessIdDVE, @@ -13,13 +14,12 @@ import { TemplateIsValid } from 'tv2-common' import { AdlibActionType, AdlibTags, SharedOutputLayers } from 'tv2-constants' -import { BlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' +import { GalleryBlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { SourceLayer } from '../../../tv2_afvd_showstyle/layers' import { MakeContentDVE } from '../content/dve' export function EvaluateDVE( - context: ISegmentUserContext, - config: BlueprintConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], actions: IBlueprintActionManifest[], partDefinition: PartDefinition, @@ -31,18 +31,18 @@ export function EvaluateDVE( return } - const rawTemplate = GetDVETemplate(config.showStyle.DVEStyles, parsedCue.template) + const rawTemplate = GetDVETemplate(context.config.showStyle.DVEStyles, parsedCue.template) if (!rawTemplate) { - context.notifyUserWarning(`Could not find template ${parsedCue.template}`) + context.core.notifyUserWarning(`Could not find template ${parsedCue.template}`) return } if (!TemplateIsValid(rawTemplate.DVEJSON)) { - context.notifyUserWarning(`Invalid DVE template ${parsedCue.template}`) + context.core.notifyUserWarning(`Invalid DVE template ${parsedCue.template}`) return } - const content = MakeContentDVE(context, config, partDefinition, parsedCue, rawTemplate) + const content = MakeContentDVE(context, partDefinition, parsedCue, rawTemplate) if (content.valid) { if (adlib) { @@ -54,7 +54,7 @@ export function EvaluateDVE( segmentExternalId: partDefinition.segmentExternalId } actions.push({ - externalId: generateExternalId(context, userData), + externalId: generateExternalId(context.core, userData), actionId: AdlibActionType.SELECT_DVE, userData, userDataManifest: {}, @@ -86,7 +86,7 @@ export function EvaluateDVE( lifespan: PieceLifespan.WithinPart, toBeQueued: true, content: content.content, - prerollDuration: Number(config.studio.CasparPrerollDuration) || 0, + prerollDuration: Number(context.config.studio.CasparPrerollDuration) || 0, metaData: { mediaPlayerSessions: [partDefinition.segmentExternalId], sources: parsedCue.sources, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts index 1426431e..a31efac6 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts @@ -1,23 +1,17 @@ -import { - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPart, - IBlueprintPiece, - ISegmentUserContext -} from 'blueprints-integration' +import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, IBlueprintPiece } from 'blueprints-integration' import { CueDefinitionEkstern, EvaluateEksternBase, + ExtendedShowStyleContext, PartDefinition, PieceMetaData, - TV2BlueprintConfig + TV2ShowStyleConfig } from 'tv2-common' import { AtemLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' export function EvaluateEkstern( - context: ISegmentUserContext, - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, part: IBlueprintPart, pieces: Array>, adlibPieces: Array>, @@ -30,7 +24,6 @@ export function EvaluateEkstern( ) { EvaluateEksternBase( context, - config, part, pieces, adlibPieces, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts b/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts index 9ae85a17..e7092114 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts @@ -3,8 +3,7 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, - IBlueprintPiece, - ISegmentUserContext + IBlueprintPiece } from 'blueprints-integration' import { CueDefinition, @@ -13,9 +12,10 @@ import { EvaluateCuesBase, EvaluateCuesOptions, EvaluateLYD, + ExtendedShowStyleContext, PartDefinition } from 'tv2-common' -import { BlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' +import { GalleryBlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { EvaluateAdLib } from './adlib' import { EvaluateClearGrafiks } from './clearGrafiks' import { EvaluateCueDesign } from './design' @@ -28,8 +28,7 @@ import { EvaluateCueRouting } from './routing' import { EvaluateTelefon } from './telefon' export async function EvaluateCues( - context: ISegmentUserContext, - config: BlueprintConfig, + context: ExtendedShowStyleContext, part: IBlueprintPart, pieces: IBlueprintPiece[], adLibPieces: IBlueprintAdLibPiece[], @@ -56,7 +55,6 @@ export async function EvaluateCues( EvaluateCueRobotCamera }, context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts index 6f679233..0badea54 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts @@ -1,25 +1,20 @@ -import { - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPiece, - ISegmentUserContext -} from 'blueprints-integration' +import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' import { Adlib, CreateInternalGraphic, CueDefinitionGraphic, + ExtendedShowStyleContext, GraphicInternalOrPilot, GraphicIsInternal, GraphicIsPilot, PartDefinition } from 'tv2-common' -import { BlueprintConfig } from '../config' +import { GalleryBlueprintConfig } from '../config' import { EvaluateCueGraphicPilot } from './graphicPilot' import { EvaluateCueRouting } from './routing' export function EvaluateCueGraphic( - config: BlueprintConfig, - context: ISegmentUserContext, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -29,14 +24,13 @@ export function EvaluateCueGraphic( adlib?: Adlib ) { if (parsedCue.routing) { - EvaluateCueRouting(config, context, pieces, adlibPieces, actions, partId, parsedCue.routing) + EvaluateCueRouting(context, pieces, partId, parsedCue.routing) } if (GraphicIsInternal(parsedCue)) { - CreateInternalGraphic(config, context, pieces, adlibPieces, partId, parsedCue, partDefinition, adlib) + CreateInternalGraphic(context, pieces, adlibPieces, partId, parsedCue, partDefinition, adlib) } else if (GraphicIsPilot(parsedCue)) { EvaluateCueGraphicPilot( - config, context, pieces, adlibPieces, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts index 8bc76145..a7e0af34 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts @@ -7,13 +7,19 @@ import { TSR, WithTimeline } from 'blueprints-integration' -import { CalculateTime, CueDefinitionBackgroundLoop, literal, TV2BlueprintConfig } from 'tv2-common' +import { + CalculateTime, + CueDefinitionBackgroundLoop, + ExtendedShowStyleContext, + literal, + TV2ShowStyleConfig +} from 'tv2-common' import { SharedGraphicLLayer, SharedOutputLayers } from 'tv2-constants' import { CasparLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' export function EvaluateCueBackgroundLoop( - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], _actions: IBlueprintActionManifest[], @@ -74,7 +80,7 @@ export function EvaluateCueBackgroundLoop( fileName: parsedCue.backgroundLoop, path: parsedCue.backgroundLoop, ignoreMediaObjectStatus: true, - timelineObjects: fullLoopTimeline(config, parsedCue) + timelineObjects: fullLoopTimeline(context.config, parsedCue) }) }) } else { @@ -91,7 +97,7 @@ export function EvaluateCueBackgroundLoop( fileName: parsedCue.backgroundLoop, path: parsedCue.backgroundLoop, ignoreMediaObjectStatus: true, - timelineObjects: fullLoopTimeline(config, parsedCue) + timelineObjects: fullLoopTimeline(context.config, parsedCue) }) }) } @@ -115,7 +121,7 @@ function dveLoopTimeline(path: string): TSR.TSRTimelineObj[] { ] } -function fullLoopTimeline(config: TV2BlueprintConfig, parsedCue: CueDefinitionBackgroundLoop): TSR.TSRTimelineObj[] { +function fullLoopTimeline(config: TV2ShowStyleConfig, parsedCue: CueDefinitionBackgroundLoop): TSR.TSRTimelineObj[] { if (!config.selectedGfxSetup.FullShowName) { return [] } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts index d4ec238f..615d7614 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts @@ -1,33 +1,21 @@ -import { - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPiece, - IShowStyleUserContext, - TSR -} from 'blueprints-integration' +import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' import { Adlib, CreatePilotGraphic, CueDefinitionGraphic, - EnableDSK, - FindDSKFullGFX, - GetSisyfosTimelineObjForFull, + ExtendedShowStyleContext, GraphicPilot, - literal, - PilotGeneratorSettings, - TV2BlueprintConfig + PilotGeneratorSettings } from 'tv2-common' import { AtemLLayer } from '../../../tv2_afvd_studio/layers' -import { BlueprintConfig } from '../config' export const pilotGeneratorSettingsAFVD: PilotGeneratorSettings = { - caspar: { createFullPilotTimelineForStudio: makeStudioTimelineCaspar }, - viz: { createFullPilotTimelineForStudio: makeStudioTimelineViz } + ProgramLayer: AtemLLayer.AtemMEProgram, + AuxProgramLayer: AtemLLayer.AtemAuxPGM } export function EvaluateCueGraphicPilot( - config: TV2BlueprintConfig, - context: IShowStyleUserContext, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -37,7 +25,6 @@ export function EvaluateCueGraphicPilot( adlib?: Adlib ) { CreatePilotGraphic(pieces, adlibPieces, actions, { - config, context, partId, parsedCue, @@ -46,76 +33,3 @@ export function EvaluateCueGraphicPilot( segmentExternalId }) } - -function makeStudioTimelineViz(config: BlueprintConfig): TSR.TSRTimelineObj[] { - const fullDSK = FindDSKFullGFX(config) - - return [ - literal({ - id: '', - enable: { - start: config.studio.VizPilotGraphics.CutToMediaPlayer - }, - priority: 1, - layer: AtemLLayer.AtemMEProgram, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: config.studio.VizPilotGraphics.FullGraphicBackground, - transition: TSR.AtemTransitionStyle.CUT - } - } - }), - literal({ - id: '', - enable: { - start: config.studio.VizPilotGraphics.CutToMediaPlayer - }, - priority: 1, - layer: AtemLLayer.AtemAuxPGM, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: fullDSK.Fill - } - }, - classes: ['MIX_MINUS_OVERRIDE_DSK', 'PLACEHOLDER_OBJECT_REMOVEME'] - }), - // Assume DSK is off by default (config table) - ...EnableDSK(config, 'FULL'), - ...GetSisyfosTimelineObjForFull(config) - ] -} - -function makeStudioTimelineCaspar(config: BlueprintConfig) { - const fullDSK = FindDSKFullGFX(config) - return [ - literal({ - id: '', - enable: { - start: Number(config.studio.CasparPrerollDuration) - }, - priority: 1, - layer: AtemLLayer.AtemMEProgram, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: fullDSK.Fill, - transition: TSR.AtemTransitionStyle.WIPE, - transitionSettings: { - wipe: { - rate: Number(config.studio.HTMLGraphics.TransitionSettings.wipeRate), - pattern: 1, - reverseDirection: true, - borderSoftness: config.studio.HTMLGraphics.TransitionSettings.borderSoftness - } - } - } - } - }), - ...GetSisyfosTimelineObjForFull(config) - ] -} diff --git a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts index 465560a8..71caf50e 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts @@ -1,14 +1,9 @@ -import { - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPiece, - ISegmentUserContext, - PieceLifespan -} from 'blueprints-integration' +import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece, PieceLifespan } from 'blueprints-integration' import { ActionSelectJingle, CreateJingleContentBase, CueDefinitionJingle, + ExtendedShowStyleContext, generateExternalId, GetTagForJingle, GetTagForJingleNext, @@ -19,11 +14,10 @@ import { import { AdlibActionType, AdlibTags, SharedOutputLayers, TallyTags } from 'tv2-constants' import { SourceLayer } from '../../../tv2_afvd_showstyle/layers' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' -import { BlueprintConfig } from '../config' +import { GalleryBlueprintConfig } from '../config' export function EvaluateJingle( - context: ISegmentUserContext, - config: BlueprintConfig, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], _adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -33,18 +27,18 @@ export function EvaluateJingle( rank?: number, effekt?: boolean ) { - if (!config.showStyle.BreakerConfig) { - context.notifyUserWarning(`Jingles have not been configured`) + if (!context.config.showStyle.BreakerConfig) { + context.core.notifyUserWarning(`Jingles have not been configured`) return } let file = '' - const jingle = config.showStyle.BreakerConfig.find(brkr => + const jingle = context.config.showStyle.BreakerConfig.find(brkr => brkr.BreakerName ? brkr.BreakerName.toString().toUpperCase() === parsedCue.clip.toUpperCase() : false ) if (!jingle) { - context.notifyUserWarning(`Jingle ${parsedCue.clip} is not configured`) + context.core.notifyUserWarning(`Jingle ${parsedCue.clip} is not configured`) return } else { file = jingle.ClipName.toString() @@ -57,7 +51,7 @@ export function EvaluateJingle( segmentExternalId: part.segmentExternalId } actions.push({ - externalId: generateExternalId(context, userData), + externalId: generateExternalId(context.core, userData), actionId: AdlibActionType.SELECT_JINGLE, userData, userDataManifest: {}, @@ -68,7 +62,7 @@ export function EvaluateJingle( outputLayerId: SharedOutputLayers.JINGLE, content: { ...createJingleContentAFVD( - config, + context, file, jingle.StartAlpha, jingle.LoadFirstFrame, @@ -91,10 +85,10 @@ export function EvaluateJingle( lifespan: PieceLifespan.WithinPart, outputLayerId: SharedOutputLayers.JINGLE, sourceLayerId: SourceLayer.PgmJingle, - prerollDuration: config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), + prerollDuration: context.config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), tags: [!effekt ? TallyTags.JINGLE : ''], content: createJingleContentAFVD( - config, + context, file, jingle.StartAlpha, jingle.LoadFirstFrame, @@ -106,14 +100,14 @@ export function EvaluateJingle( } export function createJingleContentAFVD( - config: BlueprintConfig, + context: ExtendedShowStyleContext, file: string, alphaAtStart: number, loadFirstFrame: boolean, duration: number, alphaAtEnd: number ) { - return CreateJingleContentBase(config, file, alphaAtStart, loadFirstFrame, duration, alphaAtEnd, { + return CreateJingleContentBase(context, file, alphaAtStart, loadFirstFrame, duration, alphaAtEnd, { Caspar: { PlayerJingle: CasparLLayer.CasparPlayerJingle }, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts index bf080c2b..54789a67 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts @@ -1,39 +1,27 @@ -import { - CameraContent, - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPiece, - ISegmentUserContext, - PieceLifespan, - TSR, - WithTimeline -} from 'blueprints-integration' -import { CalculateTime, CueDefinitionRouting, findSourceInfo, literal, TV2BlueprintConfig } from 'tv2-common' +import { CameraContent, IBlueprintPiece, PieceLifespan, TSR, WithTimeline } from 'blueprints-integration' +import { CalculateTime, CueDefinitionRouting, ExtendedShowStyleContext, findSourceInfo, literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import _ = require('underscore') import { AtemLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' export function EvaluateCueRouting( - config: TV2BlueprintConfig, - context: ISegmentUserContext, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], - _adlibPieces: IBlueprintAdLibPiece[], - _actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionRouting ) { const time = (parsedCue.start ? CalculateTime(parsedCue.start) : 0) ?? 0 const sourceDefinition = parsedCue.INP1 ?? parsedCue.INP if (!sourceDefinition) { - context.notifyUserWarning(`No input provided for viz engine aux`) + context.core.notifyUserWarning(`No input provided for viz engine aux`) return } - const sourceInfo = findSourceInfo(config.sources, sourceDefinition) + const sourceInfo = findSourceInfo(context.config.sources, sourceDefinition) const name = sourceDefinition.name || sourceDefinition.sourceType if (!sourceInfo) { - context.notifyUserWarning(`Could not find source ${name}`) + context.core.notifyUserWarning(`Could not find source ${name}`) return } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts b/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts index a671569d..5bccb8bb 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts @@ -1,11 +1,11 @@ import { BlueprintResultPart, PieceLifespan, TSR } from 'blueprints-integration' -import { literal, TV2BlueprintConfig } from 'tv2-common' +import { literal, TV2ShowStyleConfig } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import { GraphicLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' export function CreateShowLifecyclePieces( - config: TV2BlueprintConfig, + config: TV2ShowStyleConfig, part: BlueprintResultPart, initializeShowNames: string[], cleanupShowNames: string[] diff --git a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts index 5ff91195..dc0ab47f 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts @@ -1,23 +1,18 @@ -import { - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPiece, - ISegmentUserContext -} from 'blueprints-integration' +import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' import { Adlib, CueDefinitionTelefon, + ExtendedShowStyleContext, GetSisyfosTimelineObjForTelefon, GraphicDisplayName, PartDefinition } from 'tv2-common' import { SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' -import { BlueprintConfig } from '../config' +import { GalleryBlueprintConfig } from '../config' import { EvaluateCueGraphic } from './graphic' export function EvaluateTelefon( - config: BlueprintConfig, - context: ISegmentUserContext, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -27,18 +22,16 @@ export function EvaluateTelefon( adlib?: Adlib ) { if (parsedCue.graphic) { - EvaluateCueGraphic(config, context, pieces, adlibPieces, actions, partId, parsedCue.graphic, partDefinition, adlib) + EvaluateCueGraphic(context, pieces, adlibPieces, actions, partId, parsedCue.graphic, partDefinition, adlib) if ((!adlib && pieces.length) || (adlib && adlibPieces.length)) { if (!adlib) { - const graphicPieceIndex = pieces.findIndex(p => p.name === GraphicDisplayName(config, parsedCue.graphic!)) - const graphicPiece = pieces[graphicPieceIndex] + const graphicPiece = pieces.find(p => p.name === GraphicDisplayName(context.config, parsedCue.graphic!)) if (graphicPiece && graphicPiece.content && graphicPiece.content.timelineObjects) { graphicPiece.content.timelineObjects.push( - ...GetSisyfosTimelineObjForTelefon(config, SisyfosLLAyer.SisyfosSourceTLF) + ...GetSisyfosTimelineObjForTelefon(context.config, SisyfosLLAyer.SisyfosSourceTLF) ) graphicPiece.name = `${parsedCue.source}` - pieces[graphicPieceIndex] = graphicPiece } } } diff --git a/src/tv2_afvd_showstyle/helpers/studio.ts b/src/tv2_afvd_showstyle/helpers/studio.ts deleted file mode 100644 index 23597efa..00000000 --- a/src/tv2_afvd_showstyle/helpers/studio.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { IStudioContext } from 'blueprints-integration' - -/** - * Gets the name of the studio this context belongs to. - * @param {IStudioContext} context Context to find the studio name for. - */ -export function getStudioName(context: IStudioContext) { - const studio = (context as any).studio - - if (studio) { - return studio.name - } - - return '' -} diff --git a/src/tv2_afvd_showstyle/index.ts b/src/tv2_afvd_showstyle/index.ts index 5b9d8b01..857fccdb 100644 --- a/src/tv2_afvd_showstyle/index.ts +++ b/src/tv2_afvd_showstyle/index.ts @@ -8,7 +8,7 @@ import { onTimelineGenerateAFVD } from '../tv2_afvd_studio/onTimelineGenerate' import { executeActionAFVD } from './actions' import { getRundown } from './getRundown' import { getSegment } from './getSegment' -import { parseConfig } from './helpers/config' +import { preprocessConfig } from './helpers/config' import { syncIngestUpdateToPartInstance } from './syncIngestUpdateToPartInstance' declare const VERSION: string // Injected by webpack @@ -22,7 +22,7 @@ const manifest: ShowStyleBlueprintManifest = GetShowStyleManifestWithMixins( blueprintVersion: VERSION, integrationVersion: VERSION_INTEGRATION, TSRVersion: VERSION_TSR, - preprocessConfig: parseConfig, + preprocessConfig, getShowStyleVariantId, getRundown, diff --git a/src/tv2_afvd_showstyle/parts/cueonly.ts b/src/tv2_afvd_showstyle/parts/cueonly.ts deleted file mode 100644 index 19f2b0e7..00000000 --- a/src/tv2_afvd_showstyle/parts/cueonly.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { - HackPartMediaObjectSubscription, - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPart, - IBlueprintPiece, - ISegmentUserContext -} from 'blueprints-integration' -import { - AddScript, - ApplyFullGraphicPropertiesToPart, - CueDefinition, - GetJinglePartProperties, - GraphicIsPilot, - PartDefinition, - PartTime -} from 'tv2-common' -import { CueType } from 'tv2-constants' -import { BlueprintConfig } from '../helpers/config' -import { EvaluateCues } from '../helpers/pieces/evaluateCues' -import { SourceLayer } from '../layers' - -export async function CreatePartCueOnly( - context: ISegmentUserContext, - config: BlueprintConfig, - partDefinition: PartDefinition, - id: string, - title: string, - cue: CueDefinition, - totalWords: number, - makeAdlibs?: boolean -) { - const partDefinitionWithID = { ...partDefinition, ...{ externalId: id } } - const partTime = PartTime(config, partDefinitionWithID, totalWords, false) - - let part: IBlueprintPart = { - externalId: id, - title, - metaData: {} - } - - const adLibPieces: IBlueprintAdLibPiece[] = [] - const pieces: IBlueprintPiece[] = [] - const actions: IBlueprintActionManifest[] = [] - const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - - part = { ...part, ...GetJinglePartProperties(context, config, partDefinitionWithID) } - - if ( - partDefinition.cues.filter(c => c.type === CueType.Graphic && GraphicIsPilot(c) && c.target === 'FULL').length && - !partDefinition.cues.filter(c => c.type === CueType.Jingle).length - ) { - ApplyFullGraphicPropertiesToPart(config, part) - } - - await EvaluateCues( - context, - config, - part, - pieces, - adLibPieces, - actions, - mediaSubscriptions, - [cue], - partDefinitionWithID, - {} - ) - AddScript(partDefinitionWithID, pieces, partTime, SourceLayer.PgmScript) - - if (makeAdlibs) { - await EvaluateCues( - context, - config, - part, - pieces, - adLibPieces, - actions, - mediaSubscriptions, - [cue], - partDefinitionWithID, - { - adlib: true - } - ) - } - - part.hackListenToMediaObjectUpdates = mediaSubscriptions - - if (pieces.length === 0 && adLibPieces.length === 0) { - part.invalid = true - } - - return { - part, - adLibPieces, - pieces, - actions - } -} diff --git a/src/tv2_afvd_showstyle/parts/effekt.ts b/src/tv2_afvd_showstyle/parts/effekt.ts index 8dd53bbb..49686a32 100644 --- a/src/tv2_afvd_showstyle/parts/effekt.ts +++ b/src/tv2_afvd_showstyle/parts/effekt.ts @@ -1,16 +1,15 @@ -import { IBlueprintPiece, ISegmentUserContext } from 'blueprints-integration' -import { CreateEffektForPartBase, PartDefinition } from 'tv2-common' +import { IBlueprintPiece } from 'blueprints-integration' +import { CreateEffektForPartBase, ExtendedShowStyleContext, PartDefinition } from 'tv2-common' import { CasparLLayer, SisyfosLLAyer } from '../../tv2_afvd_studio/layers' -import { BlueprintConfig } from '../helpers/config' +import { GalleryBlueprintConfig } from '../helpers/config' import { SourceLayer } from '../layers' export function CreateEffektForpart( - context: ISegmentUserContext, - config: BlueprintConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, pieces: IBlueprintPiece[] ) { - return CreateEffektForPartBase(context, config, partDefinition, pieces, { + return CreateEffektForPartBase(context, partDefinition, pieces, { sourceLayer: SourceLayer.PgmJingle, casparLayer: CasparLLayer.CasparPlayerJingle, sisyfosLayer: SisyfosLLAyer.SisyfosSourceJingle diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index 0fb00e95..d8734097 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -5,7 +5,6 @@ import { IBlueprintAdLibPiece, IBlueprintPart, IBlueprintPiece, - ISegmentUserContext, PieceLifespan, TimelineObjectCoreExt, TSR @@ -13,6 +12,8 @@ import { import { AddScript, CreatePartInvalid, + ExtendedSegmentContext, + ExtendedShowStyleContext, findSourceInfo, GetSisyfosTimelineObjForReplay, literal, @@ -24,18 +25,17 @@ import { } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import { AtemLLayer } from '../../tv2_afvd_studio/layers' -import { BlueprintConfig } from '../helpers/config' +import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' export async function CreatePartEVS( - context: ISegmentUserContext, - config: BlueprintConfig, + context: ExtendedSegmentContext, partDefinition: PartDefinitionEVS, totalWords: number ): Promise { - const partTime = PartTime(config, partDefinition, totalWords, false) + const partTime = PartTime(context.config, partDefinition, totalWords, false) const title = partDefinition.sourceDefinition.name let part: IBlueprintPart = { @@ -50,9 +50,9 @@ export async function CreatePartEVS( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - part = { ...part, ...CreateEffektForpart(context, config, partDefinition, pieces) } + part = { ...part, ...CreateEffektForpart(context, partDefinition, pieces) } - const sourceInfoReplay = findSourceInfo(config.sources, partDefinition.sourceDefinition) + const sourceInfoReplay = findSourceInfo(context.config.sources, partDefinition.sourceDefinition) if (sourceInfoReplay === undefined) { return CreatePartInvalid(partDefinition) } @@ -70,12 +70,11 @@ export async function CreatePartEVS( sisyfosLayers: [] } }, - content: makeContentEVS(config, atemInput, partDefinition, sourceInfoReplay) + content: makeContentEVS(context, atemInput, partDefinition, sourceInfoReplay) }) await EvaluateCues( context, - config, part, pieces, adLibPieces, @@ -102,7 +101,7 @@ export async function CreatePartEVS( } function makeContentEVS( - config: BlueprintConfig, + context: ExtendedShowStyleContext, atemInput: number, partDefinition: PartDefinitionEVS, sourceInfoReplay: SourceInfo @@ -125,11 +124,11 @@ function makeContentEVS( me: { input: atemInput, transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(config, partDefinition) + transitionSettings: TransitionSettings(context.config, partDefinition) } } }), - ...GetSisyfosTimelineObjForReplay(config, sourceInfoReplay, partDefinition.sourceDefinition.vo) + ...GetSisyfosTimelineObjForReplay(context.config, sourceInfoReplay, partDefinition.sourceDefinition.vo) ]) } } diff --git a/src/tv2_afvd_showstyle/parts/grafik.ts b/src/tv2_afvd_showstyle/parts/grafik.ts index fa869c01..0c24017d 100644 --- a/src/tv2_afvd_showstyle/parts/grafik.ts +++ b/src/tv2_afvd_showstyle/parts/grafik.ts @@ -4,22 +4,27 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, - IBlueprintPiece, - ISegmentUserContext + IBlueprintPiece } from 'blueprints-integration' -import { AddScript, ApplyFullGraphicPropertiesToPart, GraphicIsPilot, PartDefinition, PartTime } from 'tv2-common' +import { + AddScript, + ApplyFullGraphicPropertiesToPart, + ExtendedShowStyleContext, + GraphicIsPilot, + PartDefinition, + PartTime +} from 'tv2-common' import { CueType } from 'tv2-constants' -import { BlueprintConfig } from '../helpers/config' +import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' export async function CreatePartGrafik( - context: ISegmentUserContext, - config: BlueprintConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, totalWords: number ): Promise { - const partTime = PartTime(config, partDefinition, totalWords, false) + const partTime = PartTime(context.config, partDefinition, totalWords, false) const part: IBlueprintPart = { externalId: partDefinition.externalId, title: partDefinition.type + ' - ' + partDefinition.rawType, @@ -32,12 +37,11 @@ export async function CreatePartGrafik( const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] if (partDefinition.cues.filter(c => c.type === CueType.Graphic && GraphicIsPilot(c) && c.target === 'FULL').length) { - ApplyFullGraphicPropertiesToPart(config, part) + ApplyFullGraphicPropertiesToPart(context.config, part) } await EvaluateCues( context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_afvd_showstyle/parts/intro.ts b/src/tv2_afvd_showstyle/parts/intro.ts index 55d7b86d..99dccdcf 100644 --- a/src/tv2_afvd_showstyle/parts/intro.ts +++ b/src/tv2_afvd_showstyle/parts/intro.ts @@ -4,29 +4,28 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, - IBlueprintPiece, - ISegmentUserContext + IBlueprintPiece } from 'blueprints-integration' import { AddScript, CreatePartInvalid, CueDefinitionJingle, + ExtendedShowStyleContext, GetJinglePartProperties, PartDefinition, PartTime } from 'tv2-common' import { CueType } from 'tv2-constants' -import { BlueprintConfig } from '../helpers/config' +import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' export async function CreatePartIntro( - context: ISegmentUserContext, - config: BlueprintConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, totalWords: number ): Promise { - const partTime = PartTime(config, partDefinition, totalWords, false) + const partTime = PartTime(context.config, partDefinition, totalWords, false) const jingleCue = partDefinition.cues.find(cue => { const parsedCue = cue @@ -34,29 +33,29 @@ export async function CreatePartIntro( }) if (!jingleCue) { - context.notifyUserWarning(`Intro must contain a jingle`) + context.core.notifyUserWarning(`Intro must contain a jingle`) return CreatePartInvalid(partDefinition) } const parsedJingle = jingleCue as CueDefinitionJingle - if (!config.showStyle.BreakerConfig) { - context.notifyUserWarning(`Jingles have not been configured`) + if (!context.config.showStyle.BreakerConfig) { + context.core.notifyUserWarning(`Jingles have not been configured`) return CreatePartInvalid(partDefinition) } - const jingle = config.showStyle.BreakerConfig.find(jngl => + const jingle = context.config.showStyle.BreakerConfig.find(jngl => jngl.BreakerName ? jngl.BreakerName.toString().toUpperCase() === parsedJingle.clip.toString().toUpperCase() : false ) if (!jingle) { - context.notifyUserWarning(`Jingle ${parsedJingle.clip} is not configured`) + context.core.notifyUserWarning(`Jingle ${parsedJingle.clip} is not configured`) return CreatePartInvalid(partDefinition) } const overlapFrames = jingle.EndAlpha if (overlapFrames === undefined) { - context.notifyUserWarning(`Jingle ${parsedJingle.clip} does not have an out-duration set.`) + context.core.notifyUserWarning(`Jingle ${parsedJingle.clip} does not have an out-duration set.`) return CreatePartInvalid(partDefinition) } @@ -73,12 +72,11 @@ export async function CreatePartIntro( part = { ...part, - ...GetJinglePartProperties(context, config, partDefinition) + ...GetJinglePartProperties(context, partDefinition) } await EvaluateCues( context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index c1a570de..123d308e 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -4,7 +4,6 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece, - ISegmentUserContext, PieceLifespan, TimelineObjectCoreExt, TSR, @@ -15,6 +14,7 @@ import { AddScript, CreatePartInvalid, CreatePartKamBase, + ExtendedSegmentContext, FindDSKJingle, findSourceInfo, GetSisyfosTimelineObjForCamera, @@ -26,18 +26,17 @@ import { } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import { AtemLLayer } from '../../tv2_afvd_studio/layers' -import { BlueprintConfig } from '../helpers/config' +import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' export async function CreatePartKam( - context: ISegmentUserContext, - config: BlueprintConfig, + context: ExtendedSegmentContext, partDefinition: PartDefinitionKam, totalWords: number ): Promise { - const partKamBase = CreatePartKamBase(context, config, partDefinition, totalWords) + const partKamBase = CreatePartKamBase(context, partDefinition, totalWords) let part = partKamBase.part.part const partTime = partKamBase.duration @@ -47,7 +46,7 @@ export async function CreatePartKam( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - const jingleDSK = FindDSKJingle(config) + const jingleDSK = FindDSKJingle(context.config) if (/\bcs *\d*/i.test(partDefinition.sourceDefinition.id)) { pieces.push({ @@ -80,7 +79,7 @@ export async function CreatePartKam( me: { input: jingleDSK.Fill, transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(config, partDefinition) + transitionSettings: TransitionSettings(context.config, partDefinition) } } }) @@ -89,14 +88,14 @@ export async function CreatePartKam( }) part.expectedDuration = TimeFromINewsField(partDefinition.fields.totalTime) * 1000 } else { - const sourceInfoCam = findSourceInfo(config.sources, partDefinition.sourceDefinition) + const sourceInfoCam = findSourceInfo(context.config.sources, partDefinition.sourceDefinition) if (sourceInfoCam === undefined) { - context.notifyUserWarning(`${partDefinition.rawType} does not exist in this studio`) + context.core.notifyUserWarning(`${partDefinition.rawType} does not exist in this studio`) return CreatePartInvalid(partDefinition) } const atemInput = sourceInfoCam.port - part = { ...part, ...CreateEffektForpart(context, config, partDefinition, pieces) } + part = { ...part, ...CreateEffektForpart(context, partDefinition, pieces) } pieces.push({ externalId: partDefinition.externalId, @@ -128,11 +127,11 @@ export async function CreatePartKam( me: { input: Number(atemInput), transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(config, partDefinition) + transitionSettings: TransitionSettings(context.config, partDefinition) } } }), - ...GetSisyfosTimelineObjForCamera(config, sourceInfoCam, partDefinition.sourceDefinition.minusMic) + ...GetSisyfosTimelineObjForCamera(context.config, sourceInfoCam, partDefinition.sourceDefinition.minusMic) ]) } }) @@ -140,7 +139,6 @@ export async function CreatePartKam( await EvaluateCues( context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_afvd_showstyle/parts/live.ts b/src/tv2_afvd_showstyle/parts/live.ts index 5331e293..91cd5f70 100644 --- a/src/tv2_afvd_showstyle/parts/live.ts +++ b/src/tv2_afvd_showstyle/parts/live.ts @@ -4,23 +4,21 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, - IBlueprintPiece, - ISegmentUserContext + IBlueprintPiece } from 'blueprints-integration' -import { AddScript, CueDefinitionEkstern, PartDefinition, PartTime } from 'tv2-common' +import { AddScript, CueDefinitionEkstern, ExtendedSegmentContext, PartDefinition, PartTime } from 'tv2-common' import { CueType } from 'tv2-constants' -import { BlueprintConfig } from '../../tv2_afvd_showstyle/helpers/config' +import { GalleryBlueprintConfig } from '../../tv2_afvd_showstyle/helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' export async function CreatePartLive( - context: ISegmentUserContext, - config: BlueprintConfig, + context: ExtendedSegmentContext, partDefinition: PartDefinition, totalWords: number ): Promise { - const partTime = PartTime(config, partDefinition, totalWords, false) + const partTime = PartTime(context.config, partDefinition, totalWords, false) let part: IBlueprintPart = { externalId: partDefinition.externalId, title: partDefinition.title || 'Ekstern', @@ -33,11 +31,10 @@ export async function CreatePartLive( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - part = { ...part, ...CreateEffektForpart(context, config, partDefinition, pieces) } + part = { ...part, ...CreateEffektForpart(context, partDefinition, pieces) } await EvaluateCues( context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_afvd_showstyle/parts/server.ts b/src/tv2_afvd_showstyle/parts/server.ts index b7ffb80a..4703ef24 100644 --- a/src/tv2_afvd_showstyle/parts/server.ts +++ b/src/tv2_afvd_showstyle/parts/server.ts @@ -1,23 +1,17 @@ -import { - BlueprintResultPart, - HackPartMediaObjectSubscription, - IBlueprintActionManifest, - ISegmentUserContext -} from 'blueprints-integration' -import { AddScript, CreatePartServerBase, PartDefinition, ServerPartProps } from 'tv2-common' +import { BlueprintResultPart, HackPartMediaObjectSubscription, IBlueprintActionManifest } from 'blueprints-integration' +import { AddScript, CreatePartServerBase, ExtendedSegmentContext, PartDefinition, ServerPartProps } from 'tv2-common' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../../tv2_afvd_studio/layers' -import { BlueprintConfig } from '../helpers/config' +import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' export async function CreatePartServer( - context: ISegmentUserContext, - config: BlueprintConfig, + context: ExtendedSegmentContext, partDefinition: PartDefinition, partProps: ServerPartProps ): Promise { - const basePartProps = await CreatePartServerBase(context, config, partDefinition, partProps, { + const basePartProps = await CreatePartServerBase(context, partDefinition, partProps, { SourceLayer: { PgmServer: partProps.voLayer ? SourceLayer.PgmVoiceOver : SourceLayer.PgmServer, // TODO this actually is shared SelectedServer: partProps.voLayer ? SourceLayer.SelectedVoiceOver : SourceLayer.SelectedServer @@ -47,13 +41,12 @@ export async function CreatePartServer( part = { ...part, - ...CreateEffektForpart(context, config, partDefinition, pieces) + ...CreateEffektForpart(context, partDefinition, pieces) } AddScript(partDefinition, pieces, duration, SourceLayer.PgmScript) await EvaluateCues( context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_afvd_showstyle/parts/teknik.ts b/src/tv2_afvd_showstyle/parts/teknik.ts index 0eedccef..0d9f179f 100644 --- a/src/tv2_afvd_showstyle/parts/teknik.ts +++ b/src/tv2_afvd_showstyle/parts/teknik.ts @@ -4,21 +4,19 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, - IBlueprintPiece, - ISegmentUserContext + IBlueprintPiece } from 'blueprints-integration' -import { AddScript, PartDefinition, PartTime } from 'tv2-common' -import { BlueprintConfig } from '../helpers/config' +import { AddScript, ExtendedSegmentContext, PartDefinition, PartTime } from 'tv2-common' +import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' export async function CreatePartTeknik( - context: ISegmentUserContext, - config: BlueprintConfig, + context: ExtendedSegmentContext, partDefinition: PartDefinition, totalWords: number ): Promise { - const partTime = PartTime(config, partDefinition, totalWords, false) + const partTime = PartTime(context.config, partDefinition, totalWords, false) const part: IBlueprintPart = { externalId: partDefinition.externalId, title: partDefinition.type + ' - ' + partDefinition.rawType, @@ -32,7 +30,6 @@ export async function CreatePartTeknik( await EvaluateCues( context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_afvd_showstyle/parts/unknown.ts b/src/tv2_afvd_showstyle/parts/unknown.ts index 80286462..96647bf0 100644 --- a/src/tv2_afvd_showstyle/parts/unknown.ts +++ b/src/tv2_afvd_showstyle/parts/unknown.ts @@ -3,31 +3,30 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, - IBlueprintPiece, - ISegmentUserContext + IBlueprintPiece } from 'blueprints-integration' import { AddScript, ApplyFullGraphicPropertiesToPart, + ExtendedShowStyleContext, GetJinglePartProperties, GraphicIsPilot, PartDefinition, PartTime } from 'tv2-common' import { CueType } from 'tv2-constants' -import { BlueprintConfig } from '../helpers/config' +import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' export async function CreatePartUnknown( - context: ISegmentUserContext, - config: BlueprintConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, totalWords: number, asAdlibs?: boolean ) { - const partTime = PartTime(config, partDefinition, totalWords, false) + const partTime = PartTime(context.config, partDefinition, totalWords, false) let part: IBlueprintPart = { externalId: partDefinition.externalId, @@ -42,19 +41,18 @@ export async function CreatePartUnknown( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - part = { ...part, ...CreateEffektForpart(context, config, partDefinition, pieces) } - part = { ...part, ...GetJinglePartProperties(context, config, partDefinition) } + part = { ...part, ...CreateEffektForpart(context, partDefinition, pieces) } + part = { ...part, ...GetJinglePartProperties(context, partDefinition) } if ( partDefinition.cues.some(cue => cue.type === CueType.Graphic && GraphicIsPilot(cue) && cue.target === 'FULL') && !partDefinition.cues.filter(c => c.type === CueType.Jingle).length ) { - ApplyFullGraphicPropertiesToPart(config, part) + ApplyFullGraphicPropertiesToPart(context.config, part) } await EvaluateCues( context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts index 152bc582..bb0b5127 100644 --- a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts @@ -1,7 +1,6 @@ import { BlueprintResultPart, IBlueprintPieceGeneric, - IStudioUserContext, OnGenerateTimelineObj, SourceLayerType, SplitsContent, @@ -9,31 +8,29 @@ import { TimelineObjHoldMode, TSR } from 'blueprints-integration' -import { AtemLLayerDSK, FindDSKJingle, TimelineBlueprintExt } from 'tv2-common' +import { AtemLLayerDSK, ExtendedShowStyleContext, FindDSKJingle, TimelineBlueprintExt } from 'tv2-common' import * as _ from 'underscore' import { AtemLLayer } from '../tv2_afvd_studio/layers' -import { BlueprintConfig } from './helpers/config' +import { GalleryBlueprintConfig } from './helpers/config' import { SourceLayer } from './layers' export function postProcessPartTimelineObjects( - context: IStudioUserContext, - config: BlueprintConfig, + context: ExtendedShowStyleContext, parts: BlueprintResultPart[] ) { _.each(parts, part => { - _.each(part.pieces, p => postProcessPieceTimelineObjects(context, config, p, false)) - _.each(part.adLibPieces, p => postProcessPieceTimelineObjects(context, config, p, true)) + _.each(part.pieces, p => postProcessPieceTimelineObjects(context, p, false)) + _.each(part.adLibPieces, p => postProcessPieceTimelineObjects(context, p, true)) }) } // Do any post-process of timeline objects export function postProcessPieceTimelineObjects( - context: IStudioUserContext, - config: BlueprintConfig, + context: ExtendedShowStyleContext, piece: IBlueprintPieceGeneric, isAdlib: boolean ) { - const jingleDSK = FindDSKJingle(config) + const jingleDSK = FindDSKJingle(context.config) const jingleDSKLayer = AtemLLayerDSK(jingleDSK.Number) if (piece.content?.timelineObjects) { @@ -51,7 +48,7 @@ export function postProcessPieceTimelineObjects( _.each(atemMeObjs, tlObj => { if (tlObj.layer === AtemLLayer.AtemMEProgram || tlObj.classes?.includes('MIX_MINUS_OVERRIDE_DSK')) { if (!tlObj.id) { - tlObj.id = context.getHashId(AtemLLayer.AtemMEProgram, true) + tlObj.id = context.core.getHashId(AtemLLayer.AtemMEProgram, true) } if (!tlObj.metaData) { tlObj.metaData = {} @@ -84,8 +81,8 @@ export function postProcessPieceTimelineObjects( aux: { input: tlObj.content.me.input !== -1 - ? tlObj.content.me.input ?? config.studio.AtemSource.Default - : config.studio.AtemSource.Default + ? tlObj.content.me.input ?? context.config.studio.AtemSource.Default + : context.config.studio.AtemSource.Default } }, metaData: { @@ -132,7 +129,7 @@ export function postProcessPieceTimelineObjects( input: mixMinusSource !== undefined && mixMinusSource !== -1 ? mixMinusSource - : config.studio.AtemSource.MixMinusDefault + : context.config.studio.AtemSource.MixMinusDefault } }, metaData: { @@ -158,7 +155,7 @@ export function postProcessPieceTimelineObjects( if (tlObj.layer === jingleDSKLayer) { const newProps = _.pick(tlObj.content.dsk, 'onAir') if (_.isEqual(newProps, tlObj.content.dsk)) { - context.notifyUserWarning(`Unhandled Keyer properties for Clean keyer, it may look wrong`) + context.core.notifyUserWarning(`Unhandled Keyer properties for Clean keyer, it may look wrong`) } const cleanObj: TSR.TimelineObjAtemME & TimelineBlueprintExt = { diff --git a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts index 9130af84..10c15107 100644 --- a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts @@ -1,3 +1,4 @@ +import { SwitcherType } from 'tv2-common' import * as _ from 'underscore' import { CORE_INJECTED_KEYS, studioConfigManifest } from '../config-manifests' import { defaultDSKConfig, StudioConfig } from '../helpers/config' @@ -5,6 +6,7 @@ import { defaultDSKConfig, StudioConfig } from '../helpers/config' const blankStudioConfig: StudioConfig = { SofieHostURL: '', + SwitcherType: SwitcherType.ATEM, ClipMediaFlowId: '', GraphicMediaFlowId: '', JingleMediaFlowId: '', diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index 93966427..0904fd3d 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -1,4 +1,4 @@ -import { IBlueprintRundownDB, PieceLifespan, PlaylistTimingType, TSR } from 'blueprints-integration' +import { PieceLifespan, TSR } from 'blueprints-integration' import { CueDefinition, CueDefinitionBackgroundLoop, @@ -13,46 +13,36 @@ import { RemoteType } from 'tv2-common' import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayers, SourceType } from 'tv2-constants' -import { SegmentUserContext } from '../../__mocks__/context' -import { defaultShowStyleConfig, defaultStudioConfig } from '../../tv2_afvd_showstyle/__tests__/configs' -import { getConfig, parseConfig as parseShowStyleConfig } from '../../tv2_afvd_showstyle/helpers/config' +import { makeMockGalleryContext, SegmentUserContext } from '../../__mocks__/context' import { SourceLayer } from '../../tv2_afvd_showstyle/layers' import { CreatePartGrafik } from '../../tv2_afvd_showstyle/parts/grafik' import { CreatePartUnknown } from '../../tv2_afvd_showstyle/parts/unknown' -import { parseConfig as parseStudioConfig } from '../helpers/config' import { AtemLLayer, CasparLLayer } from '../layers' -import mappingsDefaults from '../migrations/mappings-defaults' -const RUNDOWN_EXTERNAL_ID = 'TEST.SOFIE.JEST' const SEGMENT_EXTERNAL_ID = '00000000' -function makeMockContext() { - const rundown = literal({ - externalId: RUNDOWN_EXTERNAL_ID, - name: RUNDOWN_EXTERNAL_ID, - _id: '', - showStyleVariantId: '', - timing: { - type: PlaylistTimingType.None - } - }) - const mockContext = new SegmentUserContext( - 'mock_context', - mappingsDefaults, - parseStudioConfig, - parseShowStyleConfig, - rundown._id - ) - mockContext.studioConfig = defaultStudioConfig as any - mockContext.showStyleConfig = defaultShowStyleConfig as any - - return mockContext -} +// function makeMockGalleryContext(): ExtendedSegmentContext { +// const mockCoreContext = new SegmentUserContext( +// 'mock_context', +// mappingsDefaults, +// parseStudioConfig, +// parseShowStyleConfig, +// rundown._id +// ) +// mockCoreContext.studioConfig = defaultStudioConfig as any +// mockCoreContext.showStyleConfig = defaultShowStyleConfig as any +// const mockContext: ExtendedSegmentContext = { +// core: mockCoreContext, +// // @todo: this is awful, fix it perhaps by replacing defaultShowStyleConfig and defaultStudioConfig with preparsed config?! +// config: { ...(mockCoreContext.getStudioConfig() as any), ...(mockCoreContext.getShowStyleConfig() as any) }, +// videoSwitcher: new MockSwitcher() +// } +// return mockContext +// } describe('Graphics', () => { it('Throws warning for unpaired target and creates invalid part', async () => { - const context = makeMockContext() - const config = getConfig(context) + const context = makeMockGalleryContext() const cues: CueDefinition[] = [ literal({ @@ -74,9 +64,11 @@ describe('Graphics', () => { storyName: '' }) - const result = await CreatePartGrafik(context, config, partDefintion, 0) + const result = await CreatePartGrafik(context, partDefintion, 0) - expect(context.getNotes().map(msg => msg.message)).toEqual([`No graphic found after GRAFIK cue`]) + expect((context.core as SegmentUserContext).getNotes().map(msg => msg.message)).toEqual([ + `No graphic found after GRAFIK cue` + ]) expect(result.pieces).toHaveLength(0) expect(result.adLibPieces).toHaveLength(0) expect(result.actions).toHaveLength(0) @@ -84,8 +76,7 @@ describe('Graphics', () => { }) it('Throws warning for unpaired pilot', () => { - const context = makeMockContext() - const config = getConfig(context) + const context = makeMockGalleryContext() const cues: CueDefinition[] = [ literal({ @@ -109,14 +100,15 @@ describe('Graphics', () => { storyName: '' }) - CreatePartGrafik(context, config, partDefinition, 0) + CreatePartGrafik(context, partDefinition, 0) - expect(context.getNotes().map(msg => msg.message)).toEqual([`Graphic found without target engine`]) + expect((context.core as SegmentUserContext).getNotes().map(msg => msg.message)).toEqual([ + `Graphic found without target engine` + ]) }) it('Creates FULL graphic correctly', async () => { - const context = makeMockContext() - const config = getConfig(context) + const context = makeMockGalleryContext() const cues: CueDefinition[] = [ literal>({ @@ -144,7 +136,7 @@ describe('Graphics', () => { storyName: '' }) - const result = await CreatePartGrafik(context, config, partDefinition, 0) + const result = await CreatePartGrafik(context, partDefinition, 0) expect(result.pieces).toHaveLength(2) const piece = result.pieces[0] expect(piece.sourceLayerId).toBe(SourceLayer.PgmPilot) @@ -167,14 +159,13 @@ describe('Graphics', () => { expect(vizObj.content.delayTakeAfterOutTransition).toBe(true) expect(vizObj.content.outTransition).toEqual({ type: TSR.VIZMSETransitionType.DELAY, - delay: config.studio.VizPilotGraphics.OutTransitionDuration + delay: context.config.studio.VizPilotGraphics.OutTransitionDuration }) expect(vizObj.classes).toEqual(['full']) }) it('Creates OVL pilot graphic correctly', async () => { - const context = makeMockContext() - const config = getConfig(context) + const context = makeMockGalleryContext() const cues: CueDefinition[] = [ literal>({ @@ -208,13 +199,13 @@ describe('Graphics', () => { storyName: '' }) - const result = await CreatePartGrafik(context, config, partDefinition, 0) + const result = await CreatePartGrafik(context, partDefinition, 0) expect(result.pieces).toHaveLength(1) const piece = result.pieces[0] expect(piece.sourceLayerId).toBe(SourceLayer.PgmPilotOverlay) expect(piece.outputLayerId).toBe(SharedOutputLayers.OVERLAY) expect(piece.enable).toEqual({ start: 2000 }) - expect(piece.prerollDuration).toBe(config.studio.VizPilotGraphics.PrerollDuration) + expect(piece.prerollDuration).toBe(context.config.studio.VizPilotGraphics.PrerollDuration) expect(piece.lifespan).toBe(PieceLifespan.OutOnShowStyleEnd) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] @@ -230,14 +221,13 @@ describe('Graphics', () => { expect(vizObj.content.continueStep).toBe(-1) expect(vizObj.content.delayTakeAfterOutTransition).toBe(true) expect(vizObj.content.outTransition).toEqual({ - delay: config.studio.VizPilotGraphics.OutTransitionDuration, + delay: context.config.studio.VizPilotGraphics.OutTransitionDuration, type: TSR.VIZMSETransitionType.DELAY }) }) it('Creates WALL graphic correctly', async () => { - const context = makeMockContext() - const config = getConfig(context) + const context = makeMockGalleryContext() const cues: CueDefinition[] = [ literal>({ @@ -265,13 +255,13 @@ describe('Graphics', () => { storyName: '' }) - const result = await CreatePartGrafik(context, config, partDefinition, 0) + const result = await CreatePartGrafik(context, partDefinition, 0) expect(result.pieces).toHaveLength(1) const piece = result.pieces[0] expect(piece.sourceLayerId).toBe(SourceLayer.WallGraphics) expect(piece.outputLayerId).toBe(SharedOutputLayers.SEC) expect(piece.enable).toEqual({ start: 0 }) - expect(piece.prerollDuration).toBe(config.studio.VizPilotGraphics.PrerollDuration) + expect(piece.prerollDuration).toBe(context.config.studio.VizPilotGraphics.PrerollDuration) expect(piece.lifespan).toBe(PieceLifespan.OutOnShowStyleEnd) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] @@ -290,8 +280,7 @@ describe('Graphics', () => { }) it('Creates TLF graphic correctly', async () => { - const context = makeMockContext() - const config = getConfig(context) + const context = makeMockGalleryContext() const cues: CueDefinition[] = [ literal>({ @@ -319,13 +308,13 @@ describe('Graphics', () => { storyName: '' }) - const result = await CreatePartGrafik(context, config, partDefinition, 0) + const result = await CreatePartGrafik(context, partDefinition, 0) expect(result.pieces).toHaveLength(2) const piece = result.pieces[0] expect(piece.sourceLayerId).toBe(SourceLayer.PgmGraphicsTLF) expect(piece.outputLayerId).toBe(SharedOutputLayers.PGM) expect(piece.enable).toEqual({ start: 0 }) - expect(piece.prerollDuration).toBe(config.studio.VizPilotGraphics.PrerollDuration) + expect(piece.prerollDuration).toBe(context.config.studio.VizPilotGraphics.PrerollDuration) expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] @@ -342,14 +331,13 @@ describe('Graphics', () => { expect(vizObj.content.delayTakeAfterOutTransition).toBe(true) expect(vizObj.content.outTransition).toEqual({ type: TSR.VIZMSETransitionType.DELAY, - delay: config.studio.VizPilotGraphics.OutTransitionDuration + delay: context.config.studio.VizPilotGraphics.OutTransitionDuration }) expect(vizObj.classes).toEqual(['full']) }) it('Routes source to engine', async () => { - const context = makeMockContext() - const config = getConfig(context) + const context = makeMockGalleryContext() const cues: CueDefinition[] = [ literal>({ @@ -383,7 +371,7 @@ describe('Graphics', () => { storyName: '' }) - const result = await CreatePartGrafik(context, config, partDefinition, 0) + const result = await CreatePartGrafik(context, partDefinition, 0) expect(result.pieces).toHaveLength(3) const auxPiece = result.pieces.find(p => p.outputLayerId === SharedOutputLayers.AUX)! expect(auxPiece.enable).toEqual({ start: 0 }) @@ -399,8 +387,7 @@ describe('Graphics', () => { }) it('Creates design element', async () => { - const context = makeMockContext() - const config = getConfig(context) + const context = makeMockGalleryContext() const cues: CueDefinition[] = [ literal({ @@ -422,7 +409,7 @@ describe('Graphics', () => { storyName: '' }) - const result = await CreatePartUnknown(context, config, partDefinition, 0) + const result = await CreatePartUnknown(context, partDefinition, 0) expect(result.pieces).toHaveLength(1) const piece = result.pieces[0] expect(piece).toBeTruthy() @@ -433,8 +420,7 @@ describe('Graphics', () => { }) it('Creates background loop', async () => { - const context = makeMockContext() - const config = getConfig(context) + const context = makeMockGalleryContext() const cues: CueDefinition[] = [ literal({ @@ -457,7 +443,7 @@ describe('Graphics', () => { storyName: '' }) - const result = await CreatePartUnknown(context, config, partDefinition, 0) + const result = await CreatePartUnknown(context, partDefinition, 0) expect(result.pieces).toHaveLength(1) const piece = result.pieces[0] expect(piece).toBeTruthy() @@ -476,8 +462,7 @@ describe('Graphics', () => { }) it('Creates overlay internal graphic', async () => { - const context = makeMockContext() - const config = getConfig(context) + const context = makeMockGalleryContext() const cues: CueDefinition[] = [ literal>({ @@ -508,7 +493,7 @@ describe('Graphics', () => { storyName: '' }) - const result = await CreatePartUnknown(context, config, partDefinition, 0) + const result = await CreatePartUnknown(context, partDefinition, 0) expect(result.pieces).toHaveLength(1) const piece = result.pieces[0] expect(piece).toBeTruthy() diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index ad821703..40028ab7 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -10,6 +10,7 @@ import { literal, MakeConfigForSources, MakeConfigWithMediaFlow, + SwitcherType, TableConfigItemSourceMapping } from 'tv2-common' import { AtemSourceIndex } from '../types/atem' @@ -275,6 +276,15 @@ export const manifestAFVDStudioMics: ConfigManifestEntry = { export const manifestAFVDDownstreamKeyers: ConfigManifestEntryTable = DSKConfigManifest(defaultDSKConfig) export const studioConfigManifest: ConfigManifestEntry[] = [ + { + id: 'SwitcherType', + name: 'Video Switcher Type', + description: 'Type of the video switcher', + type: ConfigManifestEntryType.ENUM, + options: Object.values(SwitcherType), + required: true, + defaultVal: SwitcherType.ATEM + }, ...MakeConfigWithMediaFlow('Clip', '', 'flow0', '.mxf', '', false), ...MakeConfigWithMediaFlow('Jingle', '', 'flow1', '.mov', '', true), ...MakeConfigWithMediaFlow('Graphic', '', 'flow2', '.png', '', true), diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index b35656ba..09183106 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -5,11 +5,11 @@ import { IStudioContext, TSR } from 'blueprints-integration' -import { literal } from 'tv2-common' +import { ExtendedStudioContext, literal } from 'tv2-common' import * as _ from 'underscore' import { SharedGraphicLLayer } from '../tv2-constants' import { AtemSourceIndex } from '../types/atem' -import { getStudioConfig } from './helpers/config' +import { GalleryStudioConfig } from './helpers/config' import { AtemLLayer, SisyfosLLAyer } from './layers' import { sisyfosChannels } from './sisyfosChannels' @@ -32,9 +32,9 @@ function convertMappings(input: BlueprintMappings, func: (k: string, v: Bluep return _.map(_.keys(input), k => func(k, input[k])) } -export function getBaseline(context: IStudioContext): BlueprintResultBaseline { - const config = getStudioConfig(context) - const mappings = context.getStudioMappings() +export function getBaseline(coreContext: IStudioContext): BlueprintResultBaseline { + const context = new ExtendedStudioContext(coreContext) + const mappings = coreContext.getStudioMappings() const atemMeMappings = filterMappings( mappings, @@ -150,10 +150,10 @@ export function getBaseline(context: IStudioContext): BlueprintResultBaseline { type: TSR.TimelineContentTypeAtem.MEDIAPLAYER, mediaPlayer: { sourceType: TSR.MediaSourceType.Clip, - clipIndex: config.studio.AtemSettings.MP1Baseline.Clip - 1, // counting from 1 in the config + clipIndex: context.config.studio.AtemSettings.MP1Baseline.Clip - 1, // counting from 1 in the config stillIndex: 0, - playing: config.studio.AtemSettings.MP1Baseline.Playing, - loop: config.studio.AtemSettings.MP1Baseline.Loop, + playing: context.config.studio.AtemSettings.MP1Baseline.Playing, + loop: context.config.studio.AtemSettings.MP1Baseline.Loop, atBeginning: false, clipFrame: 0 } diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index 40e26ef2..eea0a78a 100644 --- a/src/tv2_afvd_studio/helpers/config.ts +++ b/src/tv2_afvd_studio/helpers/config.ts @@ -1,4 +1,4 @@ -import { IBlueprintConfig, ICommonContext, IStudioContext } from 'blueprints-integration' +import { IBlueprintConfig, ICommonContext } from 'blueprints-integration' import { MediaPlayerConfig, SourceMapping, @@ -8,13 +8,11 @@ import { TV2StudioConfigBase } from 'tv2-common' import { DSKRoles } from 'tv2-constants' -import { ShowStyleConfig } from '../../tv2_afvd_showstyle/helpers/config' import { parseMediaPlayers, parseSources } from './sources' -export interface BlueprintConfig { +export interface GalleryStudioConfig { studio: StudioConfig sources: SourceMapping - showStyle: ShowStyleConfig mediaPlayers: MediaPlayerConfig // Atem Input Ids dsk: TableConfigItemDSK[] } @@ -47,11 +45,10 @@ export interface StudioConfig extends TV2StudioConfigBase { } } -export function parseConfig(_context: ICommonContext, rawConfig: IBlueprintConfig): any { +export function preprocessConfig(_context: ICommonContext, rawConfig: IBlueprintConfig): any { const studioConfig = (rawConfig as unknown) as StudioConfig - const config: BlueprintConfig = { + const config: GalleryStudioConfig = { studio: studioConfig, - showStyle: {} as any, sources: parseSources(studioConfig), mediaPlayers: parseMediaPlayers(studioConfig), dsk: studioConfig.AtemSource.DSK @@ -60,10 +57,6 @@ export function parseConfig(_context: ICommonContext, rawConfig: IBlueprintConfi return config } -export function getStudioConfig(context: IStudioContext): BlueprintConfig { - return context.getStudioConfig() as BlueprintConfig -} - export const defaultDSKConfig: TableConfigItemDSK[] = [ { Number: 0, diff --git a/src/tv2_afvd_studio/index.ts b/src/tv2_afvd_studio/index.ts index 9b2775df..128e899a 100644 --- a/src/tv2_afvd_studio/index.ts +++ b/src/tv2_afvd_studio/index.ts @@ -4,7 +4,7 @@ import * as _ from 'underscore' import { studioConfigManifest } from './config-manifests' import { getBaseline } from './getBaseline' import { getShowStyleId } from './getShowStyleId' -import { parseConfig } from './helpers/config' +import { preprocessConfig } from './helpers/config' import { studioMigrations } from './migrations' declare const VERSION: string // Injected by webpack @@ -19,7 +19,7 @@ const manifest: StudioBlueprintManifest = GetStudioManifestWithMixins( integrationVersion: VERSION_INTEGRATION, TSRVersion: VERSION_TSR, - preprocessConfig: parseConfig, + preprocessConfig, studioConfigManifest, studioMigrations, diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index fa3b59bb..2c9ef865 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -9,7 +9,7 @@ import { } from 'tv2-common' import { AbstractLLayer, RobotCameraLayer } from 'tv2-constants' import { ATEMModel } from '../../types/atem' -import { BlueprintConfig } from '../helpers/config' +import { GalleryStudioConfig } from '../helpers/config' import { AtemLLayer, CasparLLayer, GraphicLLayer, SisyfosLLAyer } from '../layers' export const MAPPINGS_ABSTRACT: BlueprintMappings = { @@ -730,7 +730,7 @@ export default literal({ ...MAPPINGS_TELEMETRICS }) -export function getMediaPlayerMappings(mediaPlayers: BlueprintConfig['mediaPlayers']) { +export function getMediaPlayerMappings(mediaPlayers: GalleryStudioConfig['mediaPlayers']) { const res: BlueprintMappings = { casparcg_player_clip_pending: literal({ device: TSR.DeviceType.ABSTRACT, diff --git a/src/tv2_afvd_studio/onTimelineGenerate.ts b/src/tv2_afvd_studio/onTimelineGenerate.ts index 527c8097..08729670 100644 --- a/src/tv2_afvd_studio/onTimelineGenerate.ts +++ b/src/tv2_afvd_studio/onTimelineGenerate.ts @@ -6,35 +6,25 @@ import { PartEndState, TimelinePersistentState } from 'blueprints-integration' -import { onTimelineGenerate, PieceMetaData } from 'tv2-common' -import { getConfig } from '../tv2_afvd_showstyle/helpers/config' -import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from './layers' +import { ExtendedTimelineContext, onTimelineGenerate, PieceMetaData } from 'tv2-common' +import { CasparLLayer, SisyfosLLAyer } from './layers' export function onTimelineGenerateAFVD( - context: ITimelineEventContext, + coreContext: ITimelineEventContext, timeline: OnGenerateTimelineObj[], previousPersistentState: TimelinePersistentState | undefined, previousPartEndState: PartEndState | undefined, resolvedPieces: Array> ): Promise { - return onTimelineGenerate( - context, - timeline, - previousPersistentState, - previousPartEndState, - resolvedPieces, - getConfig, - { - Caspar: { - ClipPending: CasparLLayer.CasparPlayerClipPending - }, - Sisyfos: { - ClipPending: SisyfosLLAyer.SisyfosSourceClipPending, - PlayerA: SisyfosLLAyer.SisyfosSourceServerA, - PlayerB: SisyfosLLAyer.SisyfosSourceServerB - } + const context = new ExtendedTimelineContext(coreContext) + return onTimelineGenerate(context, timeline, previousPersistentState, previousPartEndState, resolvedPieces, { + Caspar: { + ClipPending: CasparLLayer.CasparPlayerClipPending }, - CasparLLayer.CasparPlayerClipPending, - AtemLLayer.AtemMEProgram - ) + Sisyfos: { + ClipPending: SisyfosLLAyer.SisyfosSourceClipPending, + PlayerA: SisyfosLLAyer.SisyfosSourceServerA, + PlayerB: SisyfosLLAyer.SisyfosSourceServerB + } + }) } diff --git a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts index 55330e27..935d6fff 100644 --- a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts @@ -24,11 +24,11 @@ import { AdlibActionType, CueType, NoteType, PartType, SharedSourceLayers, Sourc import { ActionExecutionContext } from '../../__mocks__/context' import { defaultShowStyleConfig, defaultStudioConfig } from '../../tv2_afvd_showstyle/__tests__/configs' import { AtemLLayer } from '../../tv2_afvd_studio/layers' -import { OfftubeStudioConfig, parseConfig as parseStudioConfig } from '../../tv2_offtube_studio/helpers/config' +import { OfftubeStudioConfig, preprocessConfig as parseStudioConfig } from '../../tv2_offtube_studio/helpers/config' import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' import mappingsDefaults from '../../tv2_offtube_studio/migrations/mappings-defaults' import { executeActionOfftube } from '../actions' -import { parseConfig as parseShowStyleConfig } from '../helpers/config' +import { preprocessConfig as parseShowStyleConfig } from '../helpers/config' import { OfftubeOutputLayers, OfftubeSourceLayer } from '../layers' const RUNDOWN_ID = 'MOCK_ACTION_RUNDOWN' diff --git a/src/tv2_offtube_showstyle/actions.ts b/src/tv2_offtube_showstyle/actions.ts index eb55a771..907551af 100644 --- a/src/tv2_offtube_showstyle/actions.ts +++ b/src/tv2_offtube_showstyle/actions.ts @@ -4,7 +4,6 @@ import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '.. import { OFFTUBE_DVE_GENERATOR_OPTIONS } from './content/OfftubeDVEContent' import { pilotGeneratorSettingsOfftube } from './cues/OfftubeGraphics' import { createJingleContentOfftube } from './cues/OfftubeJingle' -import { getConfig } from './helpers/config' import { OfftubeEvaluateCues } from './helpers/EvaluateCues' import { OfftubeOutputLayers, OfftubeSourceLayer } from './layers' import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' @@ -25,7 +24,6 @@ export async function executeActionOfftube( await executeAction( context, { - getConfig, postProcessPieceTimelineObjects, EvaluateCues: OfftubeEvaluateCues, DVEGeneratorOptions: OFFTUBE_DVE_GENERATOR_OPTIONS, diff --git a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts index f1140b91..c7a89dea 100644 --- a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts +++ b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts @@ -1,7 +1,14 @@ -import { ISegmentUserContext, SplitsContent, WithTimeline } from 'blueprints-integration' -import { CueDefinitionDVE, DVEConfigInput, DVEOptions, MakeContentDVEBase, PartDefinition } from 'tv2-common' +import { SplitsContent, WithTimeline } from 'blueprints-integration' +import { + CueDefinitionDVE, + DVEConfigInput, + DVEOptions, + ExtendedShowStyleContext, + MakeContentDVEBase, + PartDefinition +} from 'tv2-common' import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { OfftubeBlueprintConfig } from '../helpers/config' export const NUMBER_OF_DVE_BOXES = 4 @@ -36,11 +43,10 @@ export const OFFTUBE_DVE_GENERATOR_OPTIONS: DVEOptions = { } export function OfftubeMakeContentDVE( - context: ISegmentUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, parsedCue: CueDefinitionDVE, dveConfig: DVEConfigInput | undefined ): { content: WithTimeline; valid: boolean } { - return MakeContentDVEBase(context, config, partDefinition, parsedCue, dveConfig, OFFTUBE_DVE_GENERATOR_OPTIONS) + return MakeContentDVEBase(context, partDefinition, parsedCue, dveConfig, OFFTUBE_DVE_GENERATOR_OPTIONS) } diff --git a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts index 723dd584..7df329c5 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts @@ -1,7 +1,6 @@ import { HackPartMediaObjectSubscription, IBlueprintActionManifest, - ISegmentUserContext, SplitsContent, TimelineObjectCoreExt, TSR @@ -11,6 +10,7 @@ import { CreateAdlibServer, CueDefinitionAdLib, CueDefinitionDVE, + ExtendedSegmentContext, generateExternalId, GetDVETemplate, getUniquenessIdDVE, @@ -23,12 +23,11 @@ import { AdlibActionType, AdlibTags, CueType } from 'tv2-constants' import _ = require('underscore') import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeMakeContentDVE } from '../content/OfftubeDVEContent' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeOutputLayers, OfftubeSourceLayer } from '../layers' export async function OfftubeEvaluateAdLib( - context: ISegmentUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedSegmentContext, actions: IBlueprintActionManifest[], mediaSubscriptions: HackPartMediaObjectSubscription[], parsedCue: CueDefinitionAdLib, @@ -46,7 +45,6 @@ export async function OfftubeEvaluateAdLib( actions.push( await CreateAdlibServer( context, - config, rank, partDefinition, file, @@ -81,14 +79,14 @@ export async function OfftubeEvaluateAdLib( return } - const rawTemplate = GetDVETemplate(config.showStyle.DVEStyles, parsedCue.variant) + const rawTemplate = GetDVETemplate(context.config.showStyle.DVEStyles, parsedCue.variant) if (!rawTemplate) { - context.notifyUserWarning(`Could not find template ${parsedCue.variant}`) + context.core.notifyUserWarning(`Could not find template ${parsedCue.variant}`) return } if (!TemplateIsValid(rawTemplate.DVEJSON)) { - context.notifyUserWarning(`Invalid DVE template ${parsedCue.variant}`) + context.core.notifyUserWarning(`Invalid DVE template ${parsedCue.variant}`) return } @@ -100,7 +98,7 @@ export async function OfftubeEvaluateAdLib( iNewsCommand: 'DVE' } - const adlibContent = OfftubeMakeContentDVE(context, config, partDefinition, cueDVE, rawTemplate) + const adlibContent = OfftubeMakeContentDVE(context, partDefinition, cueDVE, rawTemplate) const userData: ActionSelectDVE = { type: AdlibActionType.SELECT_DVE, @@ -110,7 +108,7 @@ export async function OfftubeEvaluateAdLib( segmentExternalId: partDefinition.segmentExternalId } actions.push({ - externalId: generateExternalId(context, userData), + externalId: generateExternalId(context.core, userData), actionId: AdlibActionType.SELECT_DVE, userData, userDataManifest: {}, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts index 8d76aef8..c810ac00 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts @@ -1,15 +1,10 @@ -import { - IBlueprintActionManifest, - IBlueprintPiece, - ISegmentUserContext, - PieceLifespan, - SplitsContent -} from 'blueprints-integration' +import { IBlueprintActionManifest, IBlueprintPiece, PieceLifespan, SplitsContent } from 'blueprints-integration' import { ActionSelectDVE, CalculateTime, CueDefinitionDVE, DVEPieceMetaData, + ExtendedSegmentContext, generateExternalId, GetDVETemplate, GetTagForDVE, @@ -21,12 +16,11 @@ import { } from 'tv2-common' import { AdlibActionType, AdlibTags, SharedOutputLayers, TallyTags } from 'tv2-constants' import { OfftubeMakeContentDVE } from '../content/OfftubeDVEContent' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeOutputLayers, OfftubeSourceLayer } from '../layers' export function OfftubeEvaluateDVE( - context: ISegmentUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedSegmentContext, pieces: IBlueprintPiece[], actions: IBlueprintActionManifest[], partDefinition: PartDefinition, @@ -38,20 +32,20 @@ export function OfftubeEvaluateDVE( return } - const rawTemplate = GetDVETemplate(config.showStyle.DVEStyles, parsedCue.template) + const rawTemplate = GetDVETemplate(context.config.showStyle.DVEStyles, parsedCue.template) if (!rawTemplate) { - context.notifyUserWarning(`Could not find template ${parsedCue.template}`) + context.core.notifyUserWarning(`Could not find template ${parsedCue.template}`) return } if (!TemplateIsValid(rawTemplate.DVEJSON)) { - context.notifyUserWarning(`Invalid DVE template ${parsedCue.template}`) + context.core.notifyUserWarning(`Invalid DVE template ${parsedCue.template}`) return } - const adlibContent = OfftubeMakeContentDVE(context, config, partDefinition, parsedCue, rawTemplate) + const adlibContent = OfftubeMakeContentDVE(context, partDefinition, parsedCue, rawTemplate) - const pieceContent = OfftubeMakeContentDVE(context, config, partDefinition, parsedCue, rawTemplate) + const pieceContent = OfftubeMakeContentDVE(context, partDefinition, parsedCue, rawTemplate) if (adlibContent.valid && pieceContent.valid) { let start = parsedCue.start ? CalculateTime(parsedCue.start) : 0 @@ -72,7 +66,7 @@ export function OfftubeEvaluateDVE( ...pieceContent.content, timelineObjects: [...pieceContent.content.timelineObjects] }, - prerollDuration: Number(config.studio.CasparPrerollDuration) || 0, + prerollDuration: Number(context.config.studio.CasparPrerollDuration) || 0, metaData: literal({ mediaPlayerSessions: [partDefinition.segmentExternalId], sources: parsedCue.sources, @@ -103,7 +97,7 @@ export function OfftubeEvaluateDVE( segmentExternalId: partDefinition.segmentExternalId } actions.push({ - externalId: generateExternalId(context, userData), + externalId: generateExternalId(context.core, userData), actionId: AdlibActionType.SELECT_DVE, userData, userDataManifest: {}, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts index 687fe761..41302122 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts @@ -1,18 +1,17 @@ +import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, IBlueprintPiece } from 'blueprints-integration' import { - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPart, - IBlueprintPiece, - ISegmentUserContext -} from 'blueprints-integration' -import { CueDefinitionEkstern, EvaluateEksternBase, PartDefinition, PieceMetaData } from 'tv2-common' + CueDefinitionEkstern, + EvaluateEksternBase, + ExtendedSegmentContext, + PartDefinition, + PieceMetaData +} from 'tv2-common' import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeSourceLayer } from '../layers' export function OfftubeEvaluateEkstern( - context: ISegmentUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedSegmentContext, part: IBlueprintPart, pieces: Array>, _adlibPieces: Array>, @@ -25,7 +24,6 @@ export function OfftubeEvaluateEkstern( ) { EvaluateEksternBase( context, - config, part, pieces, [], diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts index 5fcd2956..40658cca 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts @@ -7,14 +7,15 @@ import { TSR, WithTimeline } from 'blueprints-integration' -import { CalculateTime, CueDefinitionBackgroundLoop, literal, TV2BlueprintConfig } from 'tv2-common' +import { CalculateTime, CueDefinitionBackgroundLoop, ExtendedSegmentContext, literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import _ = require('underscore') import { OfftubeCasparLLayer } from '../../tv2_offtube_studio/layers' +import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeSourceLayer } from '../layers' export function OfftubeEvaluateCueBackgroundLoop( - _config: TV2BlueprintConfig, + _context: ExtendedSegmentContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], _actions: IBlueprintActionManifest[], diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphicDesign.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphicDesign.ts index 278f38ed..16c54e3a 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphicDesign.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphicDesign.ts @@ -1,15 +1,9 @@ -import { - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPiece, - ISegmentUserContext -} from 'blueprints-integration' -import { CueDefinitionGraphicDesign, EvaluateDesignBase } from 'tv2-common' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' +import { CueDefinitionGraphicDesign, EvaluateDesignBase, ExtendedSegmentContext } from 'tv2-common' +import { OfftubeBlueprintConfig } from '../helpers/config' export function OfftubeEvaluateGraphicDesign( - config: OfftubeShowstyleBlueprintConfig, - context: ISegmentUserContext, + context: ExtendedSegmentContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -18,5 +12,5 @@ export function OfftubeEvaluateGraphicDesign( adlib?: boolean, rank?: number ) { - EvaluateDesignBase(config, context, pieces, adlibPieces, actions, partId, parsedCue, adlib, rank) + EvaluateDesignBase(context, pieces, adlibPieces, actions, partId, parsedCue, adlib, rank) } diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts index b1894a09..23be27af 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts @@ -1,39 +1,25 @@ -import { - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPiece, - IShowStyleUserContext, - TSR -} from 'blueprints-integration' +import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' import { Adlib, CreateInternalGraphic, CreatePilotGraphic, CueDefinitionGraphic, - FindDSKFullGFX, - GetSisyfosTimelineObjForFull, + ExtendedShowStyleContext, GraphicInternalOrPilot, GraphicIsInternal, GraphicIsPilot, - literal, PartDefinition, PilotGeneratorSettings } from 'tv2-common' import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { OfftubeBlueprintConfig } from '../helpers/config' export const pilotGeneratorSettingsOfftube: PilotGeneratorSettings = { - caspar: { - createFullPilotTimelineForStudio: createPilotTimeline - }, - viz: { - createFullPilotTimelineForStudio: () => [] - } + ProgramLayer: OfftubeAtemLLayer.AtemMEClean } export function OfftubeEvaluateGrafikCaspar( - config: OfftubeShowstyleBlueprintConfig, - context: IShowStyleUserContext, + context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -44,7 +30,6 @@ export function OfftubeEvaluateGrafikCaspar( ) { if (GraphicIsPilot(parsedCue)) { CreatePilotGraphic(pieces, adlibPieces, actions, { - config, context, partId, parsedCue, @@ -53,37 +38,6 @@ export function OfftubeEvaluateGrafikCaspar( segmentExternalId: partDefinition.segmentExternalId }) } else if (GraphicIsInternal(parsedCue)) { - CreateInternalGraphic(config, context, pieces, adlibPieces, partId, parsedCue, partDefinition, adlib) + CreateInternalGraphic(context, pieces, adlibPieces, partId, parsedCue, partDefinition, adlib) } } - -function createPilotTimeline(config: OfftubeShowstyleBlueprintConfig): TSR.TSRTimelineObj[] { - const fullDSK = FindDSKFullGFX(config) - return [ - literal({ - id: '', - enable: { - start: Number(config.studio.CasparPrerollDuration) - }, - priority: 1, - layer: OfftubeAtemLLayer.AtemMEClean, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: fullDSK.Fill, - transition: TSR.AtemTransitionStyle.WIPE, - transitionSettings: { - wipe: { - rate: Number(config.studio.HTMLGraphics.TransitionSettings.wipeRate), - pattern: 1, - reverseDirection: true, - borderSoftness: config.studio.HTMLGraphics.TransitionSettings.borderSoftness - } - } - } - } - }), - ...GetSisyfosTimelineObjForFull(config) - ] -} diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index f5fc5ec2..acdd46a5 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -1,14 +1,9 @@ -import { - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPiece, - ISegmentUserContext, - PieceLifespan -} from 'blueprints-integration' +import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece, PieceLifespan } from 'blueprints-integration' import { ActionSelectJingle, CreateJingleContentBase, CueDefinitionJingle, + ExtendedSegmentContext, generateExternalId, GetJinglePartProperties, GetTagForJingle, @@ -20,12 +15,11 @@ import { } from 'tv2-common' import { AdlibActionType, AdlibTags, SharedOutputLayers, TallyTags } from 'tv2-constants' import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeOutputLayers, OfftubeSourceLayer } from '../layers' export function OfftubeEvaluateJingle( - context: ISegmentUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedSegmentContext, pieces: Array>, _adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -35,27 +29,27 @@ export function OfftubeEvaluateJingle( _rank?: number, effekt?: boolean ) { - if (!config.showStyle.BreakerConfig) { - context.notifyUserWarning(`Jingles have not been configured`) + if (!context.config.showStyle.BreakerConfig) { + context.core.notifyUserWarning(`Jingles have not been configured`) return } let file = '' - const jingle = config.showStyle.BreakerConfig.find(brkr => + const jingle = context.config.showStyle.BreakerConfig.find(brkr => brkr.BreakerName ? brkr.BreakerName.toString().toUpperCase() === parsedCue.clip.toUpperCase() : false ) if (!jingle) { - context.notifyUserWarning(`Jingle ${parsedCue.clip} is not configured`) + context.core.notifyUserWarning(`Jingle ${parsedCue.clip} is not configured`) return } else { file = jingle.ClipName.toString() } - const p = GetJinglePartProperties(context, config, part) + const p = GetJinglePartProperties(context, part) if (JSON.stringify(p) === JSON.stringify({})) { - context.notifyUserWarning(`Could not create adlib for ${parsedCue.clip}`) + context.core.notifyUserWarning(`Could not create adlib for ${parsedCue.clip}`) return } @@ -65,7 +59,7 @@ export function OfftubeEvaluateJingle( segmentExternalId: part.segmentExternalId } actions.push({ - externalId: generateExternalId(context, userData), + externalId: generateExternalId(context.core, userData), actionId: AdlibActionType.SELECT_JINGLE, userData, userDataManifest: {}, @@ -75,7 +69,7 @@ export function OfftubeEvaluateJingle( outputLayerId: OfftubeOutputLayers.JINGLE, content: { ...createJingleContentOfftube( - config, + context, file, jingle.StartAlpha, jingle.LoadFirstFrame, @@ -103,9 +97,9 @@ export function OfftubeEvaluateJingle( sisyfosLayers: [] } }, - prerollDuration: config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), + prerollDuration: context.config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), content: createJingleContentOfftube( - config, + context, file, jingle.StartAlpha, jingle.LoadFirstFrame, @@ -122,14 +116,14 @@ export function OfftubeEvaluateJingle( } export function createJingleContentOfftube( - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedSegmentContext, file: string, alphaAtStart: number, loadFirstFrame: boolean, duration: number, alphaAtEnd: number ) { - return CreateJingleContentBase(config, file, alphaAtStart, loadFirstFrame, duration, alphaAtEnd, { + return CreateJingleContentBase(context, file, alphaAtStart, loadFirstFrame, duration, alphaAtEnd, { Caspar: { PlayerJingle: OfftubeCasparLLayer.CasparPlayerJingle, PlayerJinglePreload: OfftubeCasparLLayer.CasparPlayerJinglePreload diff --git a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts index bd152146..7d93ffca 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts @@ -1,21 +1,19 @@ import { BaseContent, IBlueprintPiece, - IShowStyleUserContext, PieceLifespan, TimelineObjectCoreExt, TSR, WithTimeline } from 'blueprints-integration' -import { CueDefinitionPgmClean, findSourceInfo, literal, SourceInfo } from 'tv2-common' +import { CueDefinitionPgmClean, ExtendedSegmentContext, findSourceInfo, literal, SourceInfo } from 'tv2-common' import { SharedOutputLayers, SourceType } from 'tv2-constants' import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeSourceLayer } from '../layers' export function OfftubeEvaluatePgmClean( - context: IShowStyleUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedSegmentContext, pieces: IBlueprintPiece[], partId: string, parsedCue: CueDefinitionPgmClean @@ -25,12 +23,12 @@ export function OfftubeEvaluatePgmClean( return } - sourceInfo = findSourceInfo(config.sources, parsedCue.sourceDefinition) + sourceInfo = findSourceInfo(context.config.sources, parsedCue.sourceDefinition) const name = parsedCue.sourceDefinition.name || parsedCue.sourceDefinition.sourceType if (!sourceInfo) { - context.notifyUserWarning(`Invalid source for clean output: ${name}`) + context.core.notifyUserWarning(`Invalid source for clean output: ${name}`) return } diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 3ec174b1..13b22eab 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -28,6 +28,8 @@ import { CreateDSKBaselineAdlibs, CreateGraphicBaseline, CreateLYDBaseline, + ExtendedShowStyleContext, + ExtendedShowStyleContextImpl, generateExternalId, GetTagForKam, GetTagForLive, @@ -39,7 +41,8 @@ import { SourceInfoToSourceDefinition, SourceInfoType, t, - TimeFromINewsField + TimeFromINewsField, + VideoSwitcher } from 'tv2-common' import { AdlibActionType, @@ -53,10 +56,7 @@ import { TallyTags } from 'tv2-constants' import * as _ from 'underscore' -import { - getConfig as getShowStyleConfig, - OfftubeShowstyleBlueprintConfig -} from '../tv2_offtube_showstyle/helpers/config' +import { OfftubeBlueprintConfig } from '../tv2_offtube_showstyle/helpers/config' import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' import { SisyfosChannel, sisyfosChannels } from '../tv2_offtube_studio/sisyfosChannels' import { AtemSourceIndex } from '../types/atem' @@ -64,8 +64,8 @@ import { NUMBER_OF_DVE_BOXES } from './content/OfftubeDVEContent' import { OfftubeOutputLayers, OfftubeSourceLayer } from './layers' import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' -export function getRundown(context: IShowStyleUserContext, ingestRundown: IngestRundown): BlueprintResultRundown { - const config = getShowStyleConfig(context) +export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: IngestRundown): BlueprintResultRundown { + const context = new ExtendedShowStyleContextImpl(coreContext) let startTime: number = 0 let endTime: number = 0 @@ -97,21 +97,20 @@ export function getRundown(context: IShowStyleUserContext, ingestRundown: Ingest expectedEnd: endTime } }), - globalAdLibPieces: getGlobalAdLibPiecesOfftube(context, config), - globalActions: getGlobalAdlibActionsOfftube(context, config), - baseline: getBaseline(config) + globalAdLibPieces: getGlobalAdLibPiecesOfftube(context), + globalActions: getGlobalAdlibActionsOfftube(context.core, context.config), + baseline: getBaseline(context.config, context.videoSwitcher) } } function getGlobalAdLibPiecesOfftube( - context: IStudioUserContext, - config: OfftubeShowstyleBlueprintConfig + context: ExtendedShowStyleContext ): IBlueprintAdLibPiece[] { const adlibItems: IBlueprintAdLibPiece[] = [] - adlibItems.forEach(p => postProcessPieceTimelineObjects(context, config, p, true)) + adlibItems.forEach(p => postProcessPieceTimelineObjects(context, p, true)) - adlibItems.push(...CreateDSKBaselineAdlibs(config, 500)) + adlibItems.push(...CreateDSKBaselineAdlibs(context.config, 500, context.videoSwitcher)) adlibItems.push({ externalId: 'micUp', @@ -132,7 +131,7 @@ function getGlobalAdLibPiecesOfftube( content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: config.studio.StudioMics.map(layer => ({ + channels: context.config.studio.StudioMics.map(layer => ({ mappedLayer: layer, isPgm: 1 })), @@ -162,7 +161,7 @@ function getGlobalAdLibPiecesOfftube( content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: config.studio.StudioMics.map(layer => ({ + channels: context.config.studio.StudioMics.map(layer => ({ mappedLayer: layer, isPgm: 0 })), @@ -228,13 +227,13 @@ function getGlobalAdLibPiecesOfftube( } }) - adlibItems.forEach(p => postProcessPieceTimelineObjects(context, config, p, true)) + adlibItems.forEach(p => postProcessPieceTimelineObjects(context, p, true)) return adlibItems } function getGlobalAdlibActionsOfftube( - _context: IStudioUserContext, - config: OfftubeShowstyleBlueprintConfig + context: IStudioUserContext, + config: OfftubeBlueprintConfig ): IBlueprintActionManifest[] { const blueprintActions: IBlueprintActionManifest[] = [] @@ -248,7 +247,7 @@ function getGlobalAdlibActionsOfftube( sourceDefinition } blueprintActions.push({ - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.CUT_TO_CAMERA, userData, userDataManifest: {}, @@ -272,7 +271,7 @@ function getGlobalAdlibActionsOfftube( sourceDefinition } blueprintActions.push({ - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.CUT_TO_REMOTE, userData, userDataManifest: {}, @@ -304,7 +303,7 @@ function getGlobalAdlibActionsOfftube( sourceDefinition } blueprintActions.push({ - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.CUT_SOURCE_TO_BOX, userData, userDataManifest: {}, @@ -329,7 +328,7 @@ function getGlobalAdlibActionsOfftube( sourceDefinition: { sourceType: SourceType.SERVER } } blueprintActions.push({ - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.CUT_SOURCE_TO_BOX, userData, userDataManifest: {}, @@ -350,7 +349,7 @@ function getGlobalAdlibActionsOfftube( type: AdlibActionType.COMMENTATOR_SELECT_SERVER } return { - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.COMMENTATOR_SELECT_SERVER, userData, userDataManifest: {}, @@ -374,7 +373,7 @@ function getGlobalAdlibActionsOfftube( type: AdlibActionType.COMMENTATOR_SELECT_DVE } return { - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.COMMENTATOR_SELECT_DVE, userData, userDataManifest: {}, @@ -398,7 +397,7 @@ function getGlobalAdlibActionsOfftube( type: AdlibActionType.COMMENTATOR_SELECT_FULL } return { - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.COMMENTATOR_SELECT_FULL, userData, userDataManifest: {}, @@ -424,7 +423,7 @@ function getGlobalAdlibActionsOfftube( label: 'GFX Altud' } return { - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.CLEAR_GRAPHICS, userData, userDataManifest: {}, @@ -450,7 +449,7 @@ function getGlobalAdlibActionsOfftube( type: AdlibActionType.RECALL_LAST_DVE } return { - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.RECALL_LAST_DVE, userData, userDataManifest: {}, @@ -472,7 +471,7 @@ function getGlobalAdlibActionsOfftube( config: dveConfig } blueprintActions.push({ - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.SELECT_DVE_LAYOUT, userData, userDataManifest: {}, @@ -509,7 +508,7 @@ function getGlobalAdlibActionsOfftube( type: AdlibActionType.RECALL_LAST_LIVE } return { - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.RECALL_LAST_LIVE, userData, userDataManifest: {}, @@ -556,7 +555,7 @@ function getGlobalAdlibActionsOfftube( type: AdlibActionType.COMMENTATOR_SELECT_JINGLE } return { - externalId: generateExternalId(_context, userData), + externalId: generateExternalId(context, userData), actionId: AdlibActionType.COMMENTATOR_SELECT_JINGLE, userData, userDataManifest: {}, @@ -578,7 +577,7 @@ function getGlobalAdlibActionsOfftube( return blueprintActions } -function getBaseline(config: OfftubeShowstyleBlueprintConfig): BlueprintResultBaseline { +function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitcher): BlueprintResultBaseline { return { timelineObjects: [ ...CreateGraphicBaseline(config), @@ -651,7 +650,7 @@ function getBaseline(config: OfftubeShowstyleBlueprintConfig): BlueprintResultBa }), // keyers - ...CreateDSKBaseline(config), + ...CreateDSKBaseline(config, videoSwitcher), literal({ id: '', diff --git a/src/tv2_offtube_showstyle/getSegment.ts b/src/tv2_offtube_showstyle/getSegment.ts index 4b8167bf..55bdf54a 100644 --- a/src/tv2_offtube_showstyle/getSegment.ts +++ b/src/tv2_offtube_showstyle/getSegment.ts @@ -8,11 +8,11 @@ import { TSR, WithTimeline } from 'blueprints-integration' -import { getSegmentBase, literal } from 'tv2-common' +import { ExtendedSegmentContextImpl, getSegmentBase, literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import * as _ from 'underscore' import { OfftubeAtemLLayer } from '../tv2_offtube_studio/layers' -import { getConfig, OfftubeShowstyleBlueprintConfig } from './helpers/config' +import { OfftubeBlueprintConfig } from './helpers/config' import { OfftubeSourceLayer } from './layers' import { OfftubeCreatePartDVE } from './parts/OfftubeDVE' import { OfftubeCreatePartGrafik } from './parts/OfftubeGrafik' @@ -22,13 +22,12 @@ import { CreatePartUnknown } from './parts/OfftubeUnknown' import { postProcessPartTimelineObjects } from './postProcessTimelineObjects' export async function getSegment( - context: ISegmentUserContext, + coreContext: ISegmentUserContext, ingestSegment: IngestSegment ): Promise { - const config = getConfig(context) + const context = new ExtendedSegmentContextImpl(coreContext) const result: BlueprintResultSegment = await getSegmentBase(context, ingestSegment, { - getConfig, CreatePartContinuity, CreatePartUnknown, CreatePartKam: OfftubeCreatePartKam, @@ -44,7 +43,7 @@ export async function getSegment( const blueprintParts = result.parts - postProcessPartTimelineObjects(context, config, blueprintParts) + postProcessPartTimelineObjects(context, blueprintParts) return { segment: result.segment, @@ -52,10 +51,7 @@ export async function getSegment( } } -function CreatePartContinuity( - config: OfftubeShowstyleBlueprintConfig, - ingestSegment: IngestSegment -): BlueprintResultPart { +function CreatePartContinuity(config: OfftubeBlueprintConfig, ingestSegment: IngestSegment): BlueprintResultPart { return { part: { externalId: `${ingestSegment.externalId}-CONTINUITY`, diff --git a/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts b/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts index ff522c37..f981b851 100644 --- a/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts +++ b/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts @@ -3,10 +3,16 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, - IBlueprintPiece, - ISegmentUserContext + IBlueprintPiece } from 'blueprints-integration' -import { CueDefinition, EvaluateCuesBase, EvaluateCuesOptions, EvaluateLYD, PartDefinition } from 'tv2-common' +import { + CueDefinition, + EvaluateCuesBase, + EvaluateCuesOptions, + EvaluateLYD, + ExtendedSegmentContext, + PartDefinition +} from 'tv2-common' import { OfftubeEvaluateAdLib } from '../cues/OfftubeAdlib' import { OfftubeEvaluateDVE } from '../cues/OfftubeDVE' import { OfftubeEvaluateEkstern } from '../cues/OfftubeEkstern' @@ -15,11 +21,10 @@ import { OfftubeEvaluateGraphicDesign } from '../cues/OfftubeGraphicDesign' import { OfftubeEvaluateGrafikCaspar } from '../cues/OfftubeGraphics' import { OfftubeEvaluateJingle } from '../cues/OfftubeJingle' import { OfftubeEvaluatePgmClean } from '../cues/OfftubePgmClean' -import { OfftubeShowstyleBlueprintConfig } from './config' +import { OfftubeBlueprintConfig } from './config' export async function OfftubeEvaluateCues( - context: ISegmentUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedSegmentContext, part: IBlueprintPart, pieces: IBlueprintPiece[], adLibPieces: IBlueprintAdLibPiece[], @@ -42,7 +47,6 @@ export async function OfftubeEvaluateCues( EvaluateCueLYD: EvaluateLYD }, context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_offtube_showstyle/helpers/config.ts b/src/tv2_offtube_showstyle/helpers/config.ts index 938e9985..70979243 100644 --- a/src/tv2_offtube_showstyle/helpers/config.ts +++ b/src/tv2_offtube_showstyle/helpers/config.ts @@ -20,7 +20,7 @@ export interface TableConfigItemGfxTemplates { IsDesign: boolean } -export interface OfftubeShowstyleBlueprintConfig extends OfftubeStudioBlueprintConfig { +export interface OfftubeBlueprintConfig extends OfftubeStudioBlueprintConfig { showStyle: OfftubeShowStyleConfig selectedGfxSetup: TableConfigGfxSetup } @@ -39,7 +39,7 @@ export interface OfftubeShowStyleConfig extends TV2ShowstyleBlueprintConfigBase GfxSetups: TableConfigGfxSetup[] } -export function parseConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { +export function preprocessConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { const showstyleConfig = (rawConfig as unknown) as OfftubeShowStyleConfig const selectedGfxSetup = findGfxSetup(context, showstyleConfig, { Name: '', @@ -51,13 +51,13 @@ export function parseConfig(context: ICommonContext, rawConfig: IBlueprintConfig } } -export function getConfig(context: IShowStyleContext): OfftubeShowstyleBlueprintConfig { +export function getConfig(context: IShowStyleContext): OfftubeBlueprintConfig { return ({ ...(context.getStudioConfig() as any), ...(context.getShowStyleConfig() as any) - } as any) as OfftubeShowstyleBlueprintConfig + } as any) as OfftubeBlueprintConfig } -export function getStudioConfig(context: IStudioContext): OfftubeShowstyleBlueprintConfig { - return context.getStudioConfig() as OfftubeShowstyleBlueprintConfig +export function getStudioConfig(context: IStudioContext): OfftubeBlueprintConfig { + return context.getStudioConfig() as OfftubeBlueprintConfig } diff --git a/src/tv2_offtube_showstyle/index.ts b/src/tv2_offtube_showstyle/index.ts index 800ebb8d..86b90276 100644 --- a/src/tv2_offtube_showstyle/index.ts +++ b/src/tv2_offtube_showstyle/index.ts @@ -8,7 +8,7 @@ import { onTimelineGenerateOfftube } from '../tv2_offtube_showstyle/onTimelineGe import { executeActionOfftube } from './actions' import { getRundown } from './getRundown' import { getSegment } from './getSegment' -import { parseConfig } from './helpers/config' +import { preprocessConfig } from './helpers/config' import { syncIngestUpdateToPartInstance } from './syncIngestUpdateToPartInstances' declare const VERSION: string // Injected by webpack @@ -23,7 +23,7 @@ const manifest: ShowStyleBlueprintManifest = GetShowStyleManifestWithMixins( integrationVersion: VERSION_INTEGRATION, TSRVersion: VERSION_TSR, - preprocessConfig: parseConfig, + preprocessConfig, getShowStyleVariantId, getRundown, diff --git a/src/tv2_offtube_showstyle/onTimelineGenerate.ts b/src/tv2_offtube_showstyle/onTimelineGenerate.ts index 1650ef7b..2a7a09fe 100644 --- a/src/tv2_offtube_showstyle/onTimelineGenerate.ts +++ b/src/tv2_offtube_showstyle/onTimelineGenerate.ts @@ -9,17 +9,17 @@ import { } from 'blueprints-integration' import { disablePilotWipeAfterJingle, + ExtendedTimelineContext, onTimelineGenerate, PartEndStateExt, PieceMetaData, TimelineBlueprintExt } from 'tv2-common' import { SharedGraphicLLayer, TallyTags } from 'tv2-constants' -import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' -import { getConfig } from './helpers/config' +import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' export function onTimelineGenerateOfftube( - context: ITimelineEventContext, + coreContext: ITimelineEventContext, timeline: OnGenerateTimelineObj[], previousPersistentState: TimelinePersistentState | undefined, previousPartEndState: PartEndState | undefined, @@ -27,28 +27,18 @@ export function onTimelineGenerateOfftube( ): Promise { const previousPartEndState2 = previousPartEndState as PartEndStateExt | undefined disablePilotWipeAfterJingle(timeline, previousPartEndState2, resolvedPieces) - disableFirstPilotGFXAnimation(context, timeline, previousPartEndState2, resolvedPieces) - - return onTimelineGenerate( - context, - timeline, - previousPersistentState, - previousPartEndState, - resolvedPieces, - getConfig, - { - Caspar: { - ClipPending: OfftubeCasparLLayer.CasparPlayerClipPending - }, - Sisyfos: { - ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending, - PlayerA: OfftubeSisyfosLLayer.SisyfosSourceServerA, - PlayerB: OfftubeSisyfosLLayer.SisyfosSourceServerB - } + disableFirstPilotGFXAnimation(coreContext, timeline, previousPartEndState2, resolvedPieces) + const context = new ExtendedTimelineContext(coreContext) + return onTimelineGenerate(context, timeline, previousPersistentState, previousPartEndState, resolvedPieces, { + Caspar: { + ClipPending: OfftubeCasparLLayer.CasparPlayerClipPending }, - OfftubeCasparLLayer.CasparPlayerClipPending, - OfftubeAtemLLayer.AtemMENext - ) + Sisyfos: { + ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending, + PlayerA: OfftubeSisyfosLLayer.SisyfosSourceServerA, + PlayerB: OfftubeSisyfosLLayer.SisyfosSourceServerB + } + }) } export function disableFirstPilotGFXAnimation( diff --git a/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts b/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts index 6975bd53..4fc6ca98 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts @@ -4,21 +4,19 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, - IBlueprintPiece, - ISegmentUserContext + IBlueprintPiece } from 'blueprints-integration' -import { AddScript, PartDefinitionDVE, PartTime } from 'tv2-common' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { AddScript, ExtendedSegmentContext, PartDefinitionDVE, PartTime } from 'tv2-common' +import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' export async function OfftubeCreatePartDVE( - context: ISegmentUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedSegmentContext, partDefinition: PartDefinitionDVE, totalWords: number ): Promise { - const partTime = PartTime(config, partDefinition, totalWords, false) + const partTime = PartTime(context.config, partDefinition, totalWords, false) const part: IBlueprintPart = { externalId: partDefinition.externalId, @@ -33,7 +31,6 @@ export async function OfftubeCreatePartDVE( await OfftubeEvaluateCues( context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeEffekt.ts b/src/tv2_offtube_showstyle/parts/OfftubeEffekt.ts index 71050555..0224ec94 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeEffekt.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeEffekt.ts @@ -1,16 +1,15 @@ -import { IBlueprintPiece, IShowStyleUserContext } from 'blueprints-integration' -import { CreateEffektForPartBase, PartDefinition } from 'tv2-common' +import { IBlueprintPiece } from 'blueprints-integration' +import { CreateEffektForPartBase, ExtendedShowStyleContext, PartDefinition } from 'tv2-common' import { SharedSourceLayers } from 'tv2-constants' import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { OfftubeBlueprintConfig } from '../helpers/config' export function CreateEffektForpart( - context: IShowStyleUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedShowStyleContext, partDefinition: PartDefinition, pieces: IBlueprintPiece[] ) { - return CreateEffektForPartBase(context, config, partDefinition, pieces, { + return CreateEffektForPartBase(context, partDefinition, pieces, { sourceLayer: SharedSourceLayers.PgmJingle, casparLayer: OfftubeCasparLLayer.CasparPlayerJingle, sisyfosLayer: OfftubeSisyfosLLayer.SisyfosSourceJingle diff --git a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts index 997ab8a4..2e5125be 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts @@ -3,22 +3,26 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, - IBlueprintPiece, - ISegmentUserContext + IBlueprintPiece } from 'blueprints-integration' -import { AddScript, ApplyFullGraphicPropertiesToPart, PartDefinition, PartTime } from 'tv2-common' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { + AddScript, + ApplyFullGraphicPropertiesToPart, + ExtendedSegmentContext, + PartDefinition, + PartTime +} from 'tv2-common' +import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' export async function OfftubeCreatePartGrafik( - context: ISegmentUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedSegmentContext, partDefinition: PartDefinition, totalWords: number, asAdlibs?: boolean ) { - const partTime = PartTime(config, partDefinition, totalWords) + const partTime = PartTime(context.config, partDefinition, totalWords) const part: IBlueprintPart = { externalId: partDefinition.externalId, @@ -33,11 +37,10 @@ export async function OfftubeCreatePartGrafik( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - ApplyFullGraphicPropertiesToPart(config, part) + ApplyFullGraphicPropertiesToPart(context.config, part) await OfftubeEvaluateCues( context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index 4b9ca72f..10f2a757 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -4,7 +4,6 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece, - ISegmentUserContext, PieceLifespan, TimelineObjectCoreExt, TSR, @@ -15,6 +14,7 @@ import { AddScript, CreatePartInvalid, CreatePartKamBase, + ExtendedSegmentContext, FindDSKJingle, findSourceInfo, GetSisyfosTimelineObjForCamera, @@ -26,18 +26,17 @@ import { } from 'tv2-common' import { SharedOutputLayers, TallyTags } from 'tv2-constants' import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' import { CreateEffektForpart } from './OfftubeEffekt' export async function OfftubeCreatePartKam( - context: ISegmentUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedSegmentContext, partDefinition: PartDefinitionKam, totalWords: number ): Promise { - const partKamBase = CreatePartKamBase(context, config, partDefinition, totalWords) + const partKamBase = CreatePartKamBase(context, partDefinition, totalWords) let part = partKamBase.part.part const partTime = partKamBase.duration @@ -47,7 +46,7 @@ export async function OfftubeCreatePartKam( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - const jingleDSK = FindDSKJingle(config) + const jingleDSK = FindDSKJingle(context.config) if (/\bcs *\d*/i.test(partDefinition.sourceDefinition.id)) { pieces.push({ @@ -76,7 +75,7 @@ export async function OfftubeCreatePartKam( me: { input: jingleDSK.Fill, transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(config, partDefinition) + transitionSettings: TransitionSettings(context.config, partDefinition) } } }) @@ -84,13 +83,13 @@ export async function OfftubeCreatePartKam( }) }) } else { - const sourceInfoCam = findSourceInfo(config.sources, partDefinition.sourceDefinition) + const sourceInfoCam = findSourceInfo(context.config.sources, partDefinition.sourceDefinition) if (sourceInfoCam === undefined) { return CreatePartInvalid(partDefinition) } const atemInput = sourceInfoCam.port - part = { ...part, ...CreateEffektForpart(context, config, partDefinition, pieces) } + part = { ...part, ...CreateEffektForpart(context, partDefinition, pieces) } pieces.push({ externalId: partDefinition.externalId, @@ -123,12 +122,12 @@ export async function OfftubeCreatePartKam( me: { input: Number(atemInput), transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(config, partDefinition) + transitionSettings: TransitionSettings(context.config, partDefinition) } } }), - ...GetSisyfosTimelineObjForCamera(config, sourceInfoCam, partDefinition.sourceDefinition.minusMic) + ...GetSisyfosTimelineObjForCamera(context.config, sourceInfoCam, partDefinition.sourceDefinition.minusMic) ]) } }) @@ -136,7 +135,6 @@ export async function OfftubeCreatePartKam( await OfftubeEvaluateCues( context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts index 9252c1fb..3547999f 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts @@ -1,23 +1,24 @@ +import { BlueprintResultPart, HackPartMediaObjectSubscription, IBlueprintActionManifest } from 'blueprints-integration' import { - BlueprintResultPart, - HackPartMediaObjectSubscription, - IBlueprintActionManifest, - ISegmentUserContext -} from 'blueprints-integration' -import { AddScript, CreateAdlibServer, CreatePartServerBase, PartDefinition, ServerPartProps } from 'tv2-common' + AddScript, + CreateAdlibServer, + CreatePartServerBase, + ExtendedSegmentContext, + PartDefinition, + ServerPartProps +} from 'tv2-common' import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' import { CreateEffektForpart } from './OfftubeEffekt' export async function OfftubeCreatePartServer( - context: ISegmentUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedSegmentContext, partDefinition: PartDefinition, partProps: ServerPartProps ): Promise { - const basePartProps = await CreatePartServerBase(context, config, partDefinition, partProps, { + const basePartProps = await CreatePartServerBase(context, partDefinition, partProps, { SourceLayer: { PgmServer: partProps.voLayer ? OfftubeSourceLayer.PgmVoiceOver : OfftubeSourceLayer.PgmServer, // TODO this actually is shared SelectedServer: partProps.voLayer ? OfftubeSourceLayer.SelectedVoiceOver : OfftubeSourceLayer.SelectedServer @@ -49,12 +50,11 @@ export async function OfftubeCreatePartServer( const file = basePartProps.file const duration = basePartProps.duration - part = { ...part, ...CreateEffektForpart(context, config, partDefinition, pieces) } + part = { ...part, ...CreateEffektForpart(context, partDefinition, pieces) } actions.push( await CreateAdlibServer( context, - config, 0, partDefinition, file, @@ -85,7 +85,6 @@ export async function OfftubeCreatePartServer( await OfftubeEvaluateCues( context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts index fbdf8535..ec22ec80 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts @@ -3,30 +3,29 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, - IBlueprintPiece, - ISegmentUserContext + IBlueprintPiece } from 'blueprints-integration' import { AddScript, ApplyFullGraphicPropertiesToPart, + ExtendedSegmentContext, GetJinglePartProperties, GraphicIsPilot, PartDefinition, PartTime } from 'tv2-common' import { CueType } from 'tv2-constants' -import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' +import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' export async function CreatePartUnknown( - context: ISegmentUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedSegmentContext, partDefinition: PartDefinition, totalWords: number, asAdlibs?: boolean ) { - const partTime = PartTime(config, partDefinition, totalWords) + const partTime = PartTime(context.config, partDefinition, totalWords) let part: IBlueprintPart = { externalId: partDefinition.externalId, @@ -41,18 +40,17 @@ export async function CreatePartUnknown( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - part = { ...part, ...GetJinglePartProperties(context, config, partDefinition) } + part = { ...part, ...GetJinglePartProperties(context, partDefinition) } if ( partDefinition.cues.some(cue => cue.type === CueType.Graphic && GraphicIsPilot(cue) && cue.target === 'FULL') && !partDefinition.cues.filter(c => c.type === CueType.Jingle).length ) { - ApplyFullGraphicPropertiesToPart(config, part) + ApplyFullGraphicPropertiesToPart(context.config, part) } await OfftubeEvaluateCues( context, - config, part, pieces, adLibPieces, diff --git a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts b/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts index 231deb03..280cbeac 100644 --- a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts @@ -1,33 +1,30 @@ import { BlueprintResultPart, IBlueprintPieceGeneric, - IStudioUserContext, OnGenerateTimelineObj, TimelineObjectCoreExt, TimelineObjHoldMode, TSR } from 'blueprints-integration' -import { TimelineBlueprintExt, TV2BlueprintConfig } from 'tv2-common' +import { ExtendedShowStyleContext, TimelineBlueprintExt } from 'tv2-common' import { ControlClasses } from 'tv2-constants' import _ = require('underscore') import { OfftubeAbstractLLayer, OfftubeAtemLLayer } from '../tv2_offtube_studio/layers' -import { OfftubeShowstyleBlueprintConfig } from './helpers/config' +import { OfftubeBlueprintConfig } from './helpers/config' export function postProcessPartTimelineObjects( - context: IStudioUserContext, - config: OfftubeShowstyleBlueprintConfig, + context: ExtendedShowStyleContext, parts: BlueprintResultPart[] ) { _.each(parts, part => { - _.each(part.pieces, p => postProcessPieceTimelineObjects(context, config, p, false)) - _.each(part.adLibPieces, p => postProcessPieceTimelineObjects(context, config, p, true)) + _.each(part.pieces, p => postProcessPieceTimelineObjects(context, p, false)) + _.each(part.adLibPieces, p => postProcessPieceTimelineObjects(context, p, true)) }) } // Do any post-process of timeline objects export function postProcessPieceTimelineObjects( - context: IStudioUserContext, - config: TV2BlueprintConfig, + context: ExtendedShowStyleContext, piece: IBlueprintPieceGeneric, isAdlib: boolean ) { @@ -46,7 +43,7 @@ export function postProcessPieceTimelineObjects( _.each(atemMeObjs, tlObj => { if (tlObj.layer === OfftubeAtemLLayer.AtemMEClean || tlObj.classes?.includes('MIX_MINUS_OVERRIDE_DSK')) { if (!tlObj.id) { - tlObj.id = context.getHashId(OfftubeAtemLLayer.AtemMEClean, true) + tlObj.id = context.core.getHashId(OfftubeAtemLLayer.AtemMEClean, true) } if (!tlObj.metaData) { tlObj.metaData = {} @@ -89,7 +86,7 @@ export function postProcessPieceTimelineObjects( type: TSR.TimelineContentTypeAtem.ME, me: { previewInput: - tlObj.content.me.input !== -1 ? tlObj.content.me.input : config.studio.AtemSource.Default + tlObj.content.me.input !== -1 ? tlObj.content.me.input : context.config.studio.AtemSource.Default } }, metaData: { diff --git a/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts b/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts index d3a4f982..093024ca 100644 --- a/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts @@ -1,3 +1,4 @@ +import { SwitcherType } from 'tv2-common' import * as _ from 'underscore' import { CORE_INJECTED_KEYS, studioConfigManifest } from '../config-manifests' import { defaultDSKConfig, OfftubeStudioConfig } from '../helpers/config' @@ -5,6 +6,7 @@ import { defaultDSKConfig, OfftubeStudioConfig } from '../helpers/config' const blankStudioConfig: OfftubeStudioConfig = { SofieHostURL: '', + SwitcherType: SwitcherType.ATEM, ClipMediaFlowId: '', JingleMediaFlowId: '', GraphicMediaFlowId: '', diff --git a/src/tv2_offtube_studio/config-manifests.ts b/src/tv2_offtube_studio/config-manifests.ts index 69eaf00d..eb2c0652 100644 --- a/src/tv2_offtube_studio/config-manifests.ts +++ b/src/tv2_offtube_studio/config-manifests.ts @@ -10,6 +10,7 @@ import { literal, MakeConfigForSources, MakeConfigWithMediaFlow, + SwitcherType, TableConfigItemSourceMapping } from 'tv2-common' import { AtemSourceIndex } from '../types/atem' @@ -121,6 +122,15 @@ export const manifestOfftubeStudioMics: ConfigManifestEntry = { export const manifestOfftubeDownstreamKeyers: ConfigManifestEntryTable = DSKConfigManifest(defaultDSKConfig) export const studioConfigManifest: ConfigManifestEntry[] = [ + { + id: 'SwitcherType', + name: 'Video Switcher Type', + description: 'Type of the video switcher', + type: ConfigManifestEntryType.ENUM, + options: Object.values(SwitcherType), + required: true, + defaultVal: SwitcherType.ATEM + }, ...MakeConfigWithMediaFlow('Clip', '', 'flow0', '.mxf', '', false), ...MakeConfigWithMediaFlow('Jingle', '', 'flow1', '.mov', 'jingler', false), ...MakeConfigWithMediaFlow('Graphic', '', 'flow2', '.png', '', false), diff --git a/src/tv2_offtube_studio/helpers/config.ts b/src/tv2_offtube_studio/helpers/config.ts index 37c23c15..56daf083 100644 --- a/src/tv2_offtube_studio/helpers/config.ts +++ b/src/tv2_offtube_studio/helpers/config.ts @@ -48,7 +48,7 @@ export interface OfftubeStudioConfig extends TV2StudioConfigBase { IdleSisyfosLayers: string[] } -export function parseConfig(_context: ICommonContext, rawConfig: IBlueprintConfig): OfftubeStudioBlueprintConfig { +export function preprocessConfig(_context: ICommonContext, rawConfig: IBlueprintConfig): OfftubeStudioBlueprintConfig { const studioConfig = (rawConfig as unknown) as OfftubeStudioConfig const config: OfftubeStudioBlueprintConfig = { studio: rawConfig as any, diff --git a/src/tv2_offtube_studio/index.ts b/src/tv2_offtube_studio/index.ts index 9b2775df..128e899a 100644 --- a/src/tv2_offtube_studio/index.ts +++ b/src/tv2_offtube_studio/index.ts @@ -4,7 +4,7 @@ import * as _ from 'underscore' import { studioConfigManifest } from './config-manifests' import { getBaseline } from './getBaseline' import { getShowStyleId } from './getShowStyleId' -import { parseConfig } from './helpers/config' +import { preprocessConfig } from './helpers/config' import { studioMigrations } from './migrations' declare const VERSION: string // Injected by webpack @@ -19,7 +19,7 @@ const manifest: StudioBlueprintManifest = GetStudioManifestWithMixins( integrationVersion: VERSION_INTEGRATION, TSRVersion: VERSION_TSR, - preprocessConfig: parseConfig, + preprocessConfig, studioConfigManifest, studioMigrations, From caabc3a3c1424217e50e89f0423fadbd522eff66 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 1 Feb 2023 15:51:12 +0100 Subject: [PATCH 11/86] wip: SOF-1260 replace most of the ME objects --- .../__tests__/transition-from-string.spec.ts | 26 ++--- .../__tests__/transitionSettings.spec.ts | 5 +- src/tv2-common/actions/executeAction.ts | 71 ++++------- .../atemTransitionStyleFromString.ts | 15 --- src/tv2-common/content/jingle.ts | 33 ++---- src/tv2-common/content/server.ts | 27 ++--- src/tv2-common/cues/ekstern.ts | 35 ++---- src/tv2-common/getSegment.ts | 7 +- .../caspar/htmlPilotGraphicGenerator.ts | 22 +--- .../graphics/viz/VizPilotGraphicGenerator.ts | 14 +-- src/tv2-common/index.ts | 3 +- .../inewsConversion/converters/ParseBody.ts | 8 +- .../converters/__tests__/body-parser.spec.ts | 4 +- .../converters/__tests__/cue-parser.spec.ts | 11 +- src/tv2-common/onTimelineGenerate.ts | 21 ++-- src/tv2-common/parts/effekt.ts | 13 +-- src/tv2-common/parts/server.ts | 20 +--- src/tv2-common/transitionSettings.ts | 43 ------- src/tv2-common/transitionStyleFromString.ts | 14 +++ src/tv2-common/videoSwitchers/Atem.ts | 110 ++++++++++++++---- src/tv2-common/videoSwitchers/TriCaster.ts | 82 +++++++++++-- .../videoSwitchers/VideoSwitcher.ts | 8 ++ src/tv2-common/videoSwitchers/types.ts | 49 ++++++-- src/tv2_afvd_showstyle/getRundown.ts | 67 +++-------- src/tv2_afvd_showstyle/getSegment.ts | 28 ++--- src/tv2_afvd_showstyle/parts/evs.ts | 21 +--- src/tv2_afvd_showstyle/parts/kam.ts | 44 +++---- .../postProcessTimelineObjects.ts | 4 +- src/tv2_afvd_studio/getBaseline.ts | 28 ++--- src/tv2_offtube_showstyle/getRundown.ts | 36 ++---- src/tv2_offtube_showstyle/getSegment.ts | 33 +++--- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 35 +++--- .../postProcessTimelineObjects.ts | 7 +- src/tv2_offtube_studio/getBaseline.ts | 32 ++--- 34 files changed, 454 insertions(+), 522 deletions(-) delete mode 100644 src/tv2-common/atemTransitionStyleFromString.ts create mode 100644 src/tv2-common/transitionStyleFromString.ts diff --git a/src/tv2-common/__tests__/transition-from-string.spec.ts b/src/tv2-common/__tests__/transition-from-string.spec.ts index ec038df8..18bf30cd 100644 --- a/src/tv2-common/__tests__/transition-from-string.spec.ts +++ b/src/tv2-common/__tests__/transition-from-string.spec.ts @@ -1,18 +1,18 @@ -import { TSR } from 'blueprints-integration' -import { AtemTransitionStyleFromString } from '../atemTransitionStyleFromString' +import { TransitionStyle } from 'tv2-common' +import { TransitionStyleFromString } from '../transitionStyleFromString' describe('Transition From String', () => { it('Converts strings', () => { - expect(AtemTransitionStyleFromString('mix')).toEqual(TSR.AtemTransitionStyle.MIX) - expect(AtemTransitionStyleFromString('MIX')).toEqual(TSR.AtemTransitionStyle.MIX) - expect(AtemTransitionStyleFromString('dip')).toEqual(TSR.AtemTransitionStyle.DIP) - expect(AtemTransitionStyleFromString('DIP')).toEqual(TSR.AtemTransitionStyle.DIP) - expect(AtemTransitionStyleFromString('wipe')).toEqual(TSR.AtemTransitionStyle.WIPE) - expect(AtemTransitionStyleFromString('WIPE')).toEqual(TSR.AtemTransitionStyle.WIPE) - expect(AtemTransitionStyleFromString('sting')).toEqual(TSR.AtemTransitionStyle.STING) - expect(AtemTransitionStyleFromString('STING')).toEqual(TSR.AtemTransitionStyle.STING) - expect(AtemTransitionStyleFromString('cut')).toEqual(TSR.AtemTransitionStyle.CUT) - expect(AtemTransitionStyleFromString('CUT')).toEqual(TSR.AtemTransitionStyle.CUT) - expect(AtemTransitionStyleFromString('unknown')).toEqual(TSR.AtemTransitionStyle.CUT) + expect(TransitionStyleFromString('mix')).toEqual(TransitionStyle.MIX) + expect(TransitionStyleFromString('MIX')).toEqual(TransitionStyle.MIX) + expect(TransitionStyleFromString('dip')).toEqual(TransitionStyle.DIP) + expect(TransitionStyleFromString('DIP')).toEqual(TransitionStyle.DIP) + expect(TransitionStyleFromString('wipe')).toEqual(TransitionStyle.WIPE) + expect(TransitionStyleFromString('WIPE')).toEqual(TransitionStyle.WIPE) + expect(TransitionStyleFromString('sting')).toEqual(TransitionStyle.STING) + expect(TransitionStyleFromString('STING')).toEqual(TransitionStyle.STING) + expect(TransitionStyleFromString('cut')).toEqual(TransitionStyle.CUT) + expect(TransitionStyleFromString('CUT')).toEqual(TransitionStyle.CUT) + expect(TransitionStyleFromString('unknown')).toEqual(TransitionStyle.CUT) }) }) diff --git a/src/tv2-common/__tests__/transitionSettings.spec.ts b/src/tv2-common/__tests__/transitionSettings.spec.ts index 8278fac1..91497e34 100644 --- a/src/tv2-common/__tests__/transitionSettings.spec.ts +++ b/src/tv2-common/__tests__/transitionSettings.spec.ts @@ -1,9 +1,9 @@ -import { TSR } from 'blueprints-integration' +// @todo: rewrite for Atem and TriCaster +/*import { TSR } from 'blueprints-integration' import { PartType } from '../../tv2-constants' import { AtemSourceIndex } from '../../types/atem' import { TV2BlueprintConfigBase, TV2ShowStyleConfig, TV2StudioConfigBase } from '../blueprintConfig' import { PartDefinition, PartTransition } from '../inewsConversion' -import { TransitionSettings } from '../transitionSettings' const DURATION: number = 50 @@ -166,3 +166,4 @@ function createAtemSourceConfig(dip: number) { DSK: [] } } +*/ diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 1c8ea979..aedd4cfa 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -27,12 +27,11 @@ import { ActionSelectServerClip, CalculateTime, CreateDipTransitionBlueprintPieceForPart, - CreateInTransitionForAtemTransitionStyle, + CreateInTransitionForTransitionStyle, CreatePartServerBase, CueDefinition, CueDefinitionDVE, CueDefinitionGraphic, - DipTransitionSettings, DVEOptions, DVEPieceMetaData, DVESources, @@ -48,7 +47,6 @@ import { GraphicPilot, literal, MakeContentDVE2, - MixTransitionSettings, PartDefinition, PieceMetaData, PilotGeneratorSettings, @@ -1091,8 +1089,6 @@ async function executeActionCutToCamera< content: { timelineObjects: _.compact([ context.videoSwitcher.getMixEffectTimelineObject({ - id: '', - enable: { while: '1' }, priority: 1, layer: settings.LLayer.Atem.cutOnclean ? settings.LLayer.Atem.MEClean : settings.LLayer.Atem.MEProgram, content: { @@ -1458,21 +1454,11 @@ async function executeActionTakeWithTransition< return } - const timelineObjectIndex = (primaryPiece.piece.content.timelineObjects as TSR.TSRTimelineObj[]).findIndex( - obj => - obj.layer === (settings.LLayer.Atem.cutOnclean ? settings.LLayer.Atem.MEClean : settings.LLayer.Atem.MEProgram) && - obj.content.deviceType === TSR.DeviceType.ATEM && - obj.content.type === TSR.TimelineContentTypeAtem.ME + const mixEffectTimelineObject = context.videoSwitcher.findMixEffectTimelineObject( + primaryPiece.piece.content.timelineObjects ) - const timelineObject = - timelineObjectIndex > -1 - ? ((primaryPiece.piece.content.timelineObjects as TSR.TSRTimelineObj[])[ - timelineObjectIndex - ] as TSR.TimelineObjAtemME) - : undefined - - if (!timelineObject) { + if (!mixEffectTimelineObject) { return } @@ -1487,12 +1473,7 @@ async function executeActionTakeWithTransition< switch (userData.variant.type) { case 'cut': { - timelineObject.content.me.transition = TSR.AtemTransitionStyle.CUT - - primaryPiece.piece.content.timelineObjects[timelineObjectIndex] = timelineObject - - await context.core.updatePieceInstance(primaryPiece._id, primaryPiece.piece) - + await updateTransition(context, mixEffectTimelineObject, primaryPiece, TransitionStyle.CUT) const cutTransitionPiece: IBlueprintPiece = { enable: { start: 0, @@ -1519,12 +1500,7 @@ async function executeActionTakeWithTransition< } break case 'breaker': { - timelineObject.content.me.transition = TSR.AtemTransitionStyle.CUT - - primaryPiece.piece.content.timelineObjects[timelineObjectIndex] = timelineObject - - await context.core.updatePieceInstance(primaryPiece._id, primaryPiece.piece) - + await updateTransition(context, mixEffectTimelineObject, primaryPiece, TransitionStyle.CUT) const pieces: Array> = [] partProps = CreateEffektForPartInner( context, @@ -1546,13 +1522,12 @@ async function executeActionTakeWithTransition< break } case 'mix': { - await updateTimelineObjectMeTransition( + await updateTransition( context, - timelineObject, - TSR.AtemTransitionStyle.MIX, - MixTransitionSettings(userData.variant.frames), + mixEffectTimelineObject, primaryPiece, - timelineObjectIndex + TransitionStyle.MIX, + userData.variant.frames ) const blueprintPiece = CreateMixTransitionBlueprintPieceForPart( @@ -1561,20 +1536,19 @@ async function executeActionTakeWithTransition< settings.SourceLayers.Effekt ) - partProps = CreateInTransitionForAtemTransitionStyle(userData.variant.frames) + partProps = CreateInTransitionForTransitionStyle(userData.variant.frames) await context.core.updatePartInstance('next', partProps) await context.core.insertPiece('next', { ...blueprintPiece, tags: [GetTagForTransition(userData.variant)] }) break } case 'dip': { - await updateTimelineObjectMeTransition( + await updateTransition( context, - timelineObject, - TSR.AtemTransitionStyle.DIP, - DipTransitionSettings(context.config, userData.variant.frames), + mixEffectTimelineObject, primaryPiece, - timelineObjectIndex + TransitionStyle.DIP, + userData.variant.frames ) const blueprintPiece = CreateDipTransitionBlueprintPieceForPart( externalId, @@ -1582,7 +1556,7 @@ async function executeActionTakeWithTransition< settings.SourceLayers.Effekt ) - partProps = CreateInTransitionForAtemTransitionStyle(userData.variant.frames) + partProps = CreateInTransitionForTransitionStyle(userData.variant.frames) await context.core.updatePartInstance('next', partProps) await context.core.insertPiece('next', { ...blueprintPiece, tags: [GetTagForTransition(userData.variant)] }) break @@ -1594,18 +1568,15 @@ async function executeActionTakeWithTransition< } } -async function updateTimelineObjectMeTransition( +async function updateTransition( context: ExtendedActionExecutionContext, - timelineObject: TSR.TimelineObjAtemME, - transitionStyle: TSR.AtemTransitionStyle, - transitionSettings: TSR.AtemTransitionSettings, + timelineObject: TSR.TSRTimelineObj, pieceInstance: IBlueprintPieceInstance, - indexOfTimelineObject: number + transitionStyle: TransitionStyle, + transitionDuration?: number ): Promise { - timelineObject.content.me.transition = transitionStyle - timelineObject.content.me.transitionSettings = transitionSettings + context.videoSwitcher.updateTransition(timelineObject, transitionStyle, transitionDuration) - pieceInstance.piece.content.timelineObjects[indexOfTimelineObject] = timelineObject await context.core.updatePieceInstance(pieceInstance._id, pieceInstance.piece) } diff --git a/src/tv2-common/atemTransitionStyleFromString.ts b/src/tv2-common/atemTransitionStyleFromString.ts deleted file mode 100644 index 70ad6045..00000000 --- a/src/tv2-common/atemTransitionStyleFromString.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { TSR } from 'blueprints-integration' - -export function AtemTransitionStyleFromString(str: string): TSR.AtemTransitionStyle { - if (str.match(/MIX/i)) { - return TSR.AtemTransitionStyle.MIX - } else if (str.match(/DIP/i)) { - return TSR.AtemTransitionStyle.DIP - } else if (str.match(/WIPE/i)) { - return TSR.AtemTransitionStyle.WIPE - } else if (str.match(/STING/i)) { - return TSR.AtemTransitionStyle.STING - } - - return TSR.AtemTransitionStyle.CUT -} diff --git a/src/tv2-common/content/jingle.ts b/src/tv2-common/content/jingle.ts index 6a83beb5..19e62440 100644 --- a/src/tv2-common/content/jingle.ts +++ b/src/tv2-common/content/jingle.ts @@ -68,7 +68,8 @@ export function CreateJingleContentBase< ...EnableDSK(context, 'JINGLE', { start: Number(config.studio.CasparPrerollDuration) }), - ...(layers.ATEM.USKJinglePreview // @todo: this is a QBOX-only feature, should be refactored at some point + // @todo: this is a Qbox-only feature, should be refactored at some point not to use ATEM object directly + ...(layers.ATEM.USKJinglePreview ? [ literal({ id: '', @@ -123,34 +124,20 @@ export function CreateJingleContentBase< ...(layers.ATEM.USKCleanEffekt ? [ - literal({ - id: '', + context.videoSwitcher.getMixEffectTimelineObject({ enable: { start: Number(config.studio.CasparPrerollDuration) }, priority: 1, layer: layers.ATEM.USKCleanEffekt, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - upstreamKeyers: [ - { - upstreamKeyerId: 0, - onAir: true, - mixEffectKeyType: 0, - flyEnabled: false, - fillSource: jingleDSK.Fill, - cutSource: jingleDSK.Key, - maskEnabled: false, - lumaSettings: { - preMultiplied: false, - clip: Number(jingleDSK.Clip) * 10, // input is percents (0-100), atem uses 1-000 - gain: Number(jingleDSK.Gain) * 10 // input is percents (0-100), atem uses 1-000 - } - } - ] - } + keyers: [ + { + id: 0, + onAir: true, + config: jingleDSK + } + ] } }) ] diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index ebc3df48..0efba2e6 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -1,5 +1,11 @@ import { IShowStyleUserContext, TimelineObjectCoreExt, TSR, VTContent, WithTimeline } from 'blueprints-integration' -import { GetSisyfosTimelineObjForServer, literal, PartDefinition, TransitionSettings } from 'tv2-common' +import { + ExtendedShowStyleContext, + GetSisyfosTimelineObjForServer, + literal, + PartDefinition, + TransitionStyle +} from 'tv2-common' import { AbstractLLayer, ControlClasses, GetEnableClassForServer } from 'tv2-constants' import { TV2ShowStyleConfig } from '../blueprintConfig' import { TimelineBlueprintExt } from '../onTimelineGenerate' @@ -133,29 +139,24 @@ function GetServerTimeline( } export function CutToServer( + context: ExtendedShowStyleContext, mediaPlayerSessionId: string, partDefinition: PartDefinition, - config: TV2ShowStyleConfig, atemLLayerMEPGM: string, offtubeOptions?: AdlibServerOfftubeOptions -) { +): TimelineBlueprintExt[] { return [ EnableServer(mediaPlayerSessionId), - literal({ - id: '', + context.videoSwitcher.getMixEffectTimelineObject({ enable: { - start: config.studio.CasparPrerollDuration + start: context.config.studio.CasparPrerollDuration }, priority: 1, layer: atemLLayerMEPGM, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: -1, - transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(config, partDefinition) - } + input: -1, + transition: partDefinition.transition?.style ?? TransitionStyle.CUT, + transitionDuration: partDefinition.transition?.duration }, metaData: { mediaPlayerSession: mediaPlayerSessionId diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index 99d019d3..fbdbba1c 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -5,7 +5,6 @@ import { PieceLifespan, RemoteContent, TimelineObjectCoreExt, - TSR, WithTimeline } from 'blueprints-integration' import { @@ -14,7 +13,7 @@ import { literal, PartDefinition, PieceMetaData, - TransitionSettings, + TransitionStyle, TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' @@ -75,21 +74,13 @@ export function EvaluateEksternBase< studioLabel: '', switcherInput: atemInput, timelineObjects: literal([ - literal({ - id: '', - enable: { - start: 0 - }, + context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, layer: layersEkstern.ATEM.MEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: atemInput, - transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(context.config, partDefinition) - } + input: atemInput, + transition: partDefinition.transition?.style ?? TransitionStyle.CUT, + transitionDuration: partDefinition.transition?.duration }, classes: [ControlClasses.LiveSourceOnAir] }), @@ -121,21 +112,13 @@ export function EvaluateEksternBase< studioLabel: '', switcherInput: atemInput, timelineObjects: literal([ - literal({ - id: '', - enable: { - start: 0 - }, + context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, layer: layersEkstern.ATEM.MEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: atemInput, - transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(context.config, partDefinition) - } + input: atemInput, + transition: partDefinition.transition?.style ?? TransitionStyle.CUT, + transitionDuration: partDefinition.transition?.duration } }), diff --git a/src/tv2-common/getSegment.ts b/src/tv2-common/getSegment.ts index cd26be5a..6bf6d6b0 100644 --- a/src/tv2-common/getSegment.ts +++ b/src/tv2-common/getSegment.ts @@ -27,7 +27,10 @@ import { import { CreatePartInvalid, ServerPartProps } from './parts' export interface GetSegmentShowstyleOptions { - CreatePartContinuity: (config: TV2ShowStyleConfig, ingestSegment: IngestSegment) => BlueprintResultPart + CreatePartContinuity: ( + context: ExtendedShowStyleContext, + ingestSegment: IngestSegment + ) => BlueprintResultPart CreatePartUnknown: ( context: ExtendedShowStyleContext, partDefinition: PartDefinition, @@ -130,7 +133,7 @@ export async function getSegmentBase }, 0) if (segment.name && segment.name.trim().match(/^\s*continuity\s*$/i)) { - blueprintParts.push(showStyleOptions.CreatePartContinuity(config, ingestSegment)) + blueprintParts.push(showStyleOptions.CreatePartContinuity(context, ingestSegment)) return { segment, parts: blueprintParts diff --git a/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts index 4a264d55..e0482aeb 100644 --- a/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts @@ -10,7 +10,8 @@ import { layerToHTMLGraphicSlot, literal, PilotGraphicProps, - TimelineBlueprintExt + TimelineBlueprintExt, + TransitionStyle } from 'tv2-common' import { PilotGraphicGenerator } from '../pilot' @@ -88,28 +89,15 @@ export class HtmlPilotGraphicGenerator extends PilotGraphicGenerator { protected getFullPilotTimeline(): TSR.TSRTimelineObj[] { const fullDSK = FindDSKFullGFX(this.config) return [ - literal({ - id: '', + this.context.videoSwitcher.getMixEffectTimelineObject({ enable: { start: Number(this.config.studio.CasparPrerollDuration) }, priority: 1, layer: this.settings.ProgramLayer, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: fullDSK.Fill, - transition: TSR.AtemTransitionStyle.WIPE, - transitionSettings: { - wipe: { - rate: Number(this.config.studio.HTMLGraphics.TransitionSettings.wipeRate), - pattern: 1, - reverseDirection: true, - borderSoftness: this.config.studio.HTMLGraphics.TransitionSettings.borderSoftness - } - } - } + input: fullDSK.Fill, + transition: TransitionStyle.WIPE_FOR_GFX } }), ...GetSisyfosTimelineObjForFull(this.config) diff --git a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts index a02adbce..62fde4b8 100644 --- a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts @@ -8,7 +8,8 @@ import { IsTargetingOVL, IsTargetingWall, literal, - PilotGraphicProps + PilotGraphicProps, + TransitionStyle } from 'tv2-common' import { PilotGraphicGenerator } from '../pilot' @@ -80,20 +81,15 @@ export class VizPilotGraphicGenerator extends PilotGraphicGenerator { private getFullPilotTimeline() { const fullDSK = FindDSKFullGFX(this.config) const timelineObjects = [ - literal({ - id: '', + this.context.videoSwitcher.getMixEffectTimelineObject({ enable: { start: this.config.studio.VizPilotGraphics.CutToMediaPlayer }, priority: 1, layer: this.settings.ProgramLayer, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: this.config.studio.VizPilotGraphics.FullGraphicBackground, - transition: TSR.AtemTransitionStyle.CUT - } + input: this.config.studio.VizPilotGraphics.FullGraphicBackground, + transition: TransitionStyle.CUT } }), // Assume DSK is off by default (config table) diff --git a/src/tv2-common/index.ts b/src/tv2-common/index.ts index 91c660ed..9f998876 100644 --- a/src/tv2-common/index.ts +++ b/src/tv2-common/index.ts @@ -21,8 +21,7 @@ export * from './parts' export * from './pieces' export * from './sources' export * from './time/partTime' -export * from './atemTransitionStyleFromString' -export * from './transitionSettings' +export * from './transitionStyleFromString' export * from './types' export * from './updatePolicies' export * from './util' diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index dc376341..4b190c86 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -1,8 +1,8 @@ -import { TSR } from 'blueprints-integration' import { - AtemTransitionStyleFromString, CueDefinitionFromLayout, PostProcessDefinitions, + TransitionStyle, + TransitionStyleFromString, TV2ShowStyleConfig, UnparsedCue } from 'tv2-common' @@ -10,7 +10,7 @@ import { CueType, PartType, SourceType } from 'tv2-constants' import { CueDefinition, ParseCue, UnpairedPilotToGraphic } from './ParseCue' export interface PartTransition { - style: TSR.AtemTransitionStyle + style: TransitionStyle duration?: number } @@ -567,7 +567,7 @@ export function getTransitionProperties(typeStr: string): Pick { type: PartType.Kam, sourceDefinition: SOURCE_DEFINITION_KAM_1, transition: { - style: TSR.AtemTransitionStyle.MIX, + style: TransitionStyle.MIX, duration: 200 }, rawType: 'KAM 1', diff --git a/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts b/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts index a4865344..17bcb04b 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts @@ -1,5 +1,10 @@ -import { TSR } from 'blueprints-integration' -import { CueDefinitionRobotCamera, RemoteType, SourceDefinitionKam, SourceDefinitionRemote } from 'tv2-common' +import { + CueDefinitionRobotCamera, + RemoteType, + SourceDefinitionKam, + SourceDefinitionRemote, + TransitionStyle +} from 'tv2-common' import { CueType, SourceType } from 'tv2-constants' import { makeMockGalleryContext } from '../../../../__mocks__/context' import { literal } from '../../../util' @@ -1088,7 +1093,7 @@ describe('Cue parser', () => { iNewsCommand: 'EKSTERN', transition: { transition: { - style: TSR.AtemTransitionStyle.MIX, + style: TransitionStyle.MIX, duration: 10 } } diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index d53fd744..38e94b5c 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -6,7 +6,6 @@ import { IRundownContext, OnGenerateTimelineObj, PartEndState, - TimelineObjectCoreExt, TimelinePersistentState, TSR } from 'blueprints-integration' @@ -47,15 +46,17 @@ export interface TimelinePersistentStateExt { isNewSegment?: boolean } -export interface TimelineBlueprintExt extends TimelineObjectCoreExt { - /** Metadata for use by the OnTimelineGenerate or other callbacks */ - metaData?: { - context?: string - mediaPlayerSession?: string - dveAdlibEnabler?: string // Used to restore the original while rule after lookahead - templateData?: any - fileName?: string - } +/** Metadata for use by the OnTimelineGenerate or other callbacks */ +export interface TimelineObjectMetaData { + context?: string + mediaPlayerSession?: string + dveAdlibEnabler?: string // Used to restore the original while rule after lookahead + templateData?: any + fileName?: string +} + +export type TimelineBlueprintExt = TSR.TSRTimelineObjBase & { + metaData?: TimelineObjectMetaData } export interface PieceMetaData { diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index 34ed3203..f2d484f7 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -19,6 +19,7 @@ import { PieceMetaData, TimeFromFrames, TimelineBlueprintExt, + TransitionStyle, TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' @@ -57,19 +58,19 @@ export function CreateEffektForPartBase( return {} } - if (transition.style === TSR.AtemTransitionStyle.MIX) { + if (transition.style === TransitionStyle.MIX) { const blueprintPiece: IBlueprintPiece = CreateMixTransitionBlueprintPieceForPart(partDefinition.externalId, transition.duration, layers.sourceLayer) ?? {} pieces.push(blueprintPiece) - return CreateInTransitionForAtemTransitionStyle(transition.duration) + return CreateInTransitionForTransitionStyle(transition.duration) } - if (transition.style === TSR.AtemTransitionStyle.DIP) { + if (transition.style === TransitionStyle.DIP) { const blueprintPiece: IBlueprintPiece = CreateDipTransitionBlueprintPieceForPart(partDefinition.externalId, transition.duration, layers.sourceLayer) ?? {} pieces.push(blueprintPiece) - return CreateInTransitionForAtemTransitionStyle(transition.duration) + return CreateInTransitionForTransitionStyle(transition.duration) } return {} @@ -224,9 +225,7 @@ function createEffectBlueprintPiece( } } -export function CreateInTransitionForAtemTransitionStyle( - durationInFrames: number -): Pick { +export function CreateInTransitionForTransitionStyle(durationInFrames: number): Pick { const transitionDuration = TimeFromFrames(durationInFrames) return { inTransition: { diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index 0cbcbf6e..b47aaaed 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -105,14 +105,7 @@ export async function CreatePartServerBase< context.config.studio.CasparPrerollDuration ) - const pgmBlueprintPiece = getPgmBlueprintPiece( - partDefinition, - partProps, - contentProps, - layers, - context.config, - context.config.studio.CasparPrerollDuration - ) + const pgmBlueprintPiece = getPgmBlueprintPiece(context, partDefinition, partProps, contentProps, layers) pieces.push(serverSelectionBlueprintPiece) pieces.push(pgmBlueprintPiece) @@ -270,12 +263,11 @@ function getPgmBlueprintPiece< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( + context: ExtendedShowStyleContext, partDefinition: PartDefinition, partProps: ServerPartProps, contentProps: ServerContentProps, - layers: ServerPartLayers, - config: ShowStyleConfig, - prerollDuration: number + layers: ServerPartLayers ): IBlueprintPiece { return { externalId: partDefinition.externalId, @@ -288,13 +280,13 @@ function getPgmBlueprintPiece< mediaPlayerSessions: [contentProps.mediaPlayerSession] }, content: { - ...GetVTContentProperties(config, contentProps), - timelineObjects: CutToServer(contentProps.mediaPlayerSession, partDefinition, config, layers.AtemLLayer.MEPgm) + ...GetVTContentProperties(context.config, contentProps), + timelineObjects: CutToServer(context, contentProps.mediaPlayerSession, partDefinition, layers.AtemLLayer.MEPgm) }, tags: [ GetTagForServer(partDefinition.segmentExternalId, contentProps.file, partProps.voLayer), TallyTags.SERVER_IS_LIVE ], - prerollDuration + prerollDuration: context.config.studio.CasparPrerollDuration } } diff --git a/src/tv2-common/transitionSettings.ts b/src/tv2-common/transitionSettings.ts index 74bd9b93..e69de29b 100644 --- a/src/tv2-common/transitionSettings.ts +++ b/src/tv2-common/transitionSettings.ts @@ -1,43 +0,0 @@ -import { TSR } from 'blueprints-integration' -import { PartDefinition, TV2ShowStyleConfig } from 'tv2-common' -import { AtemSourceIndex } from '../types/atem' - -export function TransitionSettings(config: TV2ShowStyleConfig, part: PartDefinition): TSR.AtemTransitionSettings { - if (!part.transition || !part.transition.duration) { - return {} - } - - if (part.transition.style === TSR.AtemTransitionStyle.WIPE) { - return WipeTransitionSettings(part.transition.duration) - } - - if (part.transition.style === TSR.AtemTransitionStyle.DIP) { - return DipTransitionSettings(config, part.transition.duration) - } - return MixTransitionSettings(part.transition.duration) -} - -function WipeTransitionSettings(rate: number): TSR.AtemTransitionSettings { - return { - wipe: { - rate - } - } -} - -export function DipTransitionSettings(config: TV2ShowStyleConfig, rate: number): TSR.AtemTransitionSettings { - return { - dip: { - rate, - input: config.studio?.AtemSource?.Dip ?? AtemSourceIndex.Col2 - } - } -} - -export function MixTransitionSettings(rate: number): TSR.AtemTransitionSettings { - return { - mix: { - rate - } - } -} diff --git a/src/tv2-common/transitionStyleFromString.ts b/src/tv2-common/transitionStyleFromString.ts new file mode 100644 index 00000000..a16f51fa --- /dev/null +++ b/src/tv2-common/transitionStyleFromString.ts @@ -0,0 +1,14 @@ +import { TransitionStyle } from 'tv2-common' + +export function TransitionStyleFromString(str: string): TransitionStyle { + if (/MIX/i.test(str)) { + return TransitionStyle.MIX + } else if (/DIP/i.test(str)) { + return TransitionStyle.DIP + } else if (/WIPE/i.test(str)) { + return TransitionStyle.WIPE + } else if (/STING/i.test(str)) { + return TransitionStyle.STING + } + return TransitionStyle.CUT +} diff --git a/src/tv2-common/videoSwitchers/Atem.ts b/src/tv2-common/videoSwitchers/Atem.ts index 438a36a9..2823f8a7 100644 --- a/src/tv2-common/videoSwitchers/Atem.ts +++ b/src/tv2-common/videoSwitchers/Atem.ts @@ -1,11 +1,15 @@ import { TSR } from 'blueprints-integration' +import _ = require('underscore') import { AtemSourceIndex } from '../../types/atem' +import { TimelineBlueprintExt } from '../onTimelineGenerate' import { AuxProps, DskProps, + Keyer, MixEffectProps, SpecialInput, SwitcherType, + TIMELINE_OBJECT_DEFAULTS, TransitionStyle, VideoSwitcherImpl } from './index' @@ -20,38 +24,71 @@ const TRANSITION_MAP = { [TransitionStyle.CUT]: TSR.AtemTransitionStyle.CUT, [TransitionStyle.DIP]: TSR.AtemTransitionStyle.DIP, [TransitionStyle.MIX]: TSR.AtemTransitionStyle.MIX, - [TransitionStyle.WIPE]: TSR.AtemTransitionStyle.WIPE + [TransitionStyle.STING]: TSR.AtemTransitionStyle.STING, + [TransitionStyle.WIPE]: TSR.AtemTransitionStyle.WIPE, + [TransitionStyle.WIPE_FOR_GFX]: TSR.AtemTransitionStyle.WIPE } export class Atem extends VideoSwitcherImpl { + public static isMixEffectTimelineObject(timelineObject: TSR.TSRTimelineObj): timelineObject is TSR.TimelineObjAtemME { + return ( + timelineObject.content.deviceType === TSR.DeviceType.ATEM && + timelineObject.content.type === TSR.TimelineContentTypeAtem.ME + ) + } public readonly type = SwitcherType.ATEM - public getMixEffectTimelineObject(props: MixEffectProps): TSR.TimelineObjAtemME { + public getMixEffectTimelineObject(props: MixEffectProps): TSR.TimelineObjAtemME & TimelineBlueprintExt { const { content } = props + const me: TSR.TimelineObjAtemME['content']['me'] = + content.input && content.transition + ? { + input: this.getInputNumber(content.input), + transition: this.getTransition(content.transition), + transitionSettings: this.getTransitionSettings(content.transition, content.transitionDuration) + } + : { + programInput: content.input && this.getInputNumber(content.input), + previewInput: content.previewInput && this.getInputNumber(content.previewInput) + } + const upstreamKeyers = content.keyers && this.getUpstreamKeyers(content.keyers) + if (upstreamKeyers) { + me.upstreamKeyers = upstreamKeyers + } return { - id: props.id, - enable: props.enable, - layer: props.layer, - priority: props.priority, + ...TIMELINE_OBJECT_DEFAULTS, + ..._.omit(props, 'content'), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.ME, - me: { - input: this.getInputNumber(content.input), - transition: this.getTransition(content.transition), - transitionSettings: this.getTransitionSettings(content.transition, content.transitionDuration) - } + me } } } + public findMixEffectTimelineObject(timelineObjects: TSR.TSRTimelineObj[]): TSR.TSRTimelineObj | undefined { + return timelineObjects.find(Atem.isMixEffectTimelineObject) + } + + public updateTransition( + timelineObject: TSR.TSRTimelineObj, + transition: TransitionStyle, + transitionDuration?: number | undefined + ): TSR.TSRTimelineObj { + if (!Atem.isMixEffectTimelineObject(timelineObject)) { + // @todo: log error or throw + return timelineObject + } + timelineObject.content.me.transition = this.getTransition(transition) + timelineObject.content.me.transitionSettings = this.getTransitionSettings(transition, transitionDuration) + return timelineObject + } + public getDskTimelineObjects(props: DskProps) { const { content } = props const timelineObject: TSR.TimelineObjAtemDSK = { - id: props.id, - enable: props.enable, - layer: props.layer, - priority: props.priority, + ...TIMELINE_OBJECT_DEFAULTS, + ..._.omit(props, 'content'), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.DSK, @@ -75,10 +112,8 @@ export class Atem extends VideoSwitcherImpl { public getAuxTimelineObject(props: AuxProps): TSR.TimelineObjAtemAUX { return { - id: props.id, - enable: props.enable, - layer: props.layer, - priority: props.priority, + ...TIMELINE_OBJECT_DEFAULTS, + ..._.omit(props, 'content'), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.AUX, @@ -107,13 +142,42 @@ export class Atem extends VideoSwitcherImpl { } switch (transition) { case TransitionStyle.CUT: + case TransitionStyle.STING: return undefined - case TransitionStyle.WIPE: - return { wipe: { rate: duration } } - case TransitionStyle.MIX: - return { mix: { rate: duration } } case TransitionStyle.DIP: return { dip: { rate: duration, input: this.config.studio?.AtemSource?.Dip ?? AtemSourceIndex.Col2 } } + case TransitionStyle.MIX: + return { mix: { rate: duration } } + case TransitionStyle.WIPE: + return { wipe: { rate: duration } } + case TransitionStyle.WIPE_FOR_GFX: + return { + wipe: { + rate: Number(this.config.studio.HTMLGraphics.TransitionSettings.wipeRate), + pattern: 1, + reverseDirection: true, + borderSoftness: this.config.studio.HTMLGraphics.TransitionSettings.borderSoftness + } + } } } + private getUpstreamKeyers(keyers: Keyer[]) { + if (!keyers?.length) { + return + } + return keyers.map(keyer => ({ + upstreamKeyerId: keyer.id, + onAir: keyer.onAir, + mixEffectKeyType: 0, + flyEnabled: false, + fillSource: keyer.config.Fill, + cutSource: keyer.config.Key, + maskEnabled: false, + lumaSettings: { + preMultiplied: false, + clip: Number(keyer.config.Clip) * 10, // input is percents (0-100), atem uses 1-000 + gain: Number(keyer.config.Gain) * 10 // input is percents (0-100), atem uses 1-000 + } + })) + } } diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 30d8cace..42ea7a82 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -1,5 +1,15 @@ import { TSR } from 'blueprints-integration' -import { AuxProps, DskProps, MixEffectProps, SpecialInput, SwitcherType, TransitionStyle } from './types' +import _ = require('underscore') +import { + AuxProps, + DskProps, + Keyer, + MixEffectProps, + SpecialInput, + SwitcherType, + TIMELINE_OBJECT_DEFAULTS, + TransitionStyle +} from './types' import { VideoSwitcherImpl } from './VideoSwitcher' const SPECIAL_INPUT_MAP = { @@ -11,35 +21,62 @@ const SPECIAL_INPUT_MAP = { const TRANSITION_MAP: Record = { [TransitionStyle.CUT]: 'cut', [TransitionStyle.MIX]: 'fade', - // making assumptions about the session here - [TransitionStyle.DIP]: 1, - [TransitionStyle.WIPE]: 2 + // making assumptions about the session here: + [TransitionStyle.DIP]: 2, + [TransitionStyle.WIPE]: 3, + [TransitionStyle.WIPE_FOR_GFX]: 4, + [TransitionStyle.STING]: 5 // not really supported?? } export class TriCaster extends VideoSwitcherImpl { + public static isMixEffectTimelineObject( + timelineObject: TSR.TSRTimelineObj + ): timelineObject is TSR.TimelineObjTriCasterME { + return TSR.isTimelineObjTriCasterME(timelineObject) + } public readonly type = SwitcherType.ATEM public getMixEffectTimelineObject(props: MixEffectProps): TSR.TimelineObjTriCasterME { const { content } = props return { - id: props.id, - enable: props.enable, - layer: props.layer, - priority: props.priority, + ...TIMELINE_OBJECT_DEFAULTS, + ..._.omit(props, 'content'), content: { deviceType: TSR.DeviceType.TRICASTER, type: TSR.TimelineContentTypeTriCaster.ME, me: { programInput: this.getInputName(content.input), + previewInput: this.getInputName(content.previewInput), transition: { - effect: TRANSITION_MAP[content.transition], + effect: this.getTransition(content.transition), duration: content.transitionDuration ?? 1000 // @todo defaults and ranges - } + }, + keyers: content.keyers && this.getKeyers(content.keyers) } } } } + public findMixEffectTimelineObject(timelineObjects: TSR.TSRTimelineObj[]): TSR.TSRTimelineObj | undefined { + return timelineObjects.find(TriCaster.isMixEffectTimelineObject) + } + + public updateTransition( + timelineObject: TSR.TSRTimelineObj, + transition: TransitionStyle, + transitionDuration?: number | undefined + ): TSR.TSRTimelineObj { + if (!TriCaster.isMixEffectTimelineObject(timelineObject)) { + // @todo: log error or throw + return timelineObject + } + timelineObject.content.me.transition = { + effect: this.getTransition(transition), + duration: transitionDuration ?? 1000 // @todo defaults and ranges + } + return timelineObject + } + public getDskTimelineObjects(_properties: DskProps): TSR.TSRTimelineObj[] { throw new Error('Method not implemented.') } @@ -47,10 +84,33 @@ export class TriCaster extends VideoSwitcherImpl { throw new Error('Method not implemented.') } - private getInputName(input: number | SpecialInput) { + private getKeyers(keyers: Keyer[]): Record | undefined { + if (!keyers?.length) { + return + } + return keyers.reduce>((accumulator, keyer) => { + accumulator[`dsk${keyer.id + 1}`] = { + onAir: keyer.onAir, + input: this.getInputName(keyer.config.Fill) + } + return accumulator + }, {}) + } + + private getInputName(input: number | SpecialInput | undefined) { + if (typeof input === 'undefined') { + return undefined + } if (typeof input === 'number') { return `input${input}` } return SPECIAL_INPUT_MAP[input] } + + private getTransition(transition: TransitionStyle | undefined) { + if (transition === undefined) { + return 'cut' + } + return TRANSITION_MAP[transition] + } } diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts index 446ccd87..1129fdab 100644 --- a/src/tv2-common/videoSwitchers/VideoSwitcher.ts +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -5,6 +5,7 @@ import { DskProps, MixEffectProps, SwitcherType, + TransitionStyle, TriCaster, TV2StudioConfig, VideoSwitcher @@ -27,6 +28,13 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { } public abstract getMixEffectTimelineObject(properties: MixEffectProps): TSR.TSRTimelineObj + public abstract findMixEffectTimelineObject(timelineObjects: TSR.TSRTimelineObj[]): TSR.TSRTimelineObj | undefined + public abstract updateTransition( + timelineObjects: TSR.TSRTimelineObj, + transition: TransitionStyle, + transitionDuration?: number | undefined + ): TSR.TSRTimelineObj + public abstract getDskTimelineObjects(properties: DskProps): TSR.TSRTimelineObj[] public abstract getAuxTimelineObject(properties: AuxProps): TSR.TSRTimelineObj } diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index cacf45f8..3409b7df 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -1,4 +1,5 @@ -import { TSR } from 'blueprints-integration' +import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' +import { TableConfigItemDSK, TimelineObjectMetaData } from 'tv2-common' export enum SwitcherType { ATEM = 'ATEM', @@ -16,27 +17,49 @@ export enum TransitionStyle { CUT = 'cut', MIX = 'mix', WIPE = 'wipe', - DIP = 'dip' + WIPE_FOR_GFX = 'wipe_for_gfx', + DIP = 'dip', + STING = 'sting' // ... } +export const TIMELINE_OBJECT_DEFAULTS = { + id: '', + enable: { start: 0 }, + priority: 0 +} + export interface TimelineObjectProps { - id: string - enable: TimelineObjectEnable + // Default: '' + id?: string + // Default: { while: '1' } + enable?: TimelineObjectEnable + // Default: 0 + priority?: number layer: string - priority: number + metaData?: TimelineObjectMetaData + classes?: string[] } type TimelineObjectEnable = TSR.TSRTimelineObj['enable'] export interface MixEffectProps extends TimelineObjectProps { content: { - input: number | SpecialInput - transition: TransitionStyle + input?: number | SpecialInput + previewInput?: number | SpecialInput + transition?: TransitionStyle transitionDuration?: number + keyers?: Keyer[] } } +export interface Keyer { + // id starting from 0 + id: number + onAir: boolean + config: TableConfigItemDSK +} + export interface DskProps extends TimelineObjectProps { content: { onAir: boolean @@ -60,7 +83,13 @@ export interface AuxProps extends TimelineObjectProps { } export interface VideoSwitcher { - getMixEffectTimelineObject: (properties: MixEffectProps) => TSR.TSRTimelineObj - getDskTimelineObjects: (properties: DskProps) => TSR.TSRTimelineObj[] - getAuxTimelineObject: (properties: AuxProps) => TSR.TSRTimelineObj + getMixEffectTimelineObject(properties: MixEffectProps): TSR.TSRTimelineObj + findMixEffectTimelineObject(timelineObjects: TimelineObjectCoreExt[]): TSR.TSRTimelineObj | undefined + updateTransition( + timelineObjects: TSR.TSRTimelineObj, + transition: TransitionStyle, + transitionDuration?: number + ): TSR.TSRTimelineObj + getDskTimelineObjects(properties: DskProps): TSR.TSRTimelineObj[] + getAuxTimelineObject(properties: AuxProps): TSR.TSRTimelineObj } diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 3191c956..dff5fbda 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -195,7 +195,6 @@ class GlobalAdLibPiecesGenerator { ignoreMediaObjectStatus: true, timelineObjects: [ this.context.videoSwitcher.getMixEffectTimelineObject({ - id: '', enable: { while: '1' }, priority: 1, layer: AtemLLayer.AtemMEProgram, @@ -288,18 +287,13 @@ class GlobalAdLibPiecesGenerator { tags: [AdlibTags.ADLIB_QUEUE_NEXT], content: { timelineObjects: [ - literal({ - id: '', + this.context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, priority: 1, layer: AtemLLayer.AtemMEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: info.port, - transition: TSR.AtemTransitionStyle.CUT - } + input: info.port, + transition: TransitionStyle.CUT } }), ...eksternSisyfos @@ -846,32 +840,20 @@ function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitche timelineObjects: [ ...CreateGraphicBaseline(config), // Default timeline - literal({ - id: '', + videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - priority: 0, layer: AtemLLayer.AtemMEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: config.studio.AtemSource.Default, - transition: TSR.AtemTransitionStyle.CUT - } + input: config.studio.AtemSource.Default, + transition: TransitionStyle.CUT } }), - literal({ - id: '', + videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - priority: 0, layer: AtemLLayer.AtemMEClean, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: config.studio.AtemSource.Default, - transition: TSR.AtemTransitionStyle.CUT - } + input: config.studio.AtemSource.Default, + transition: TransitionStyle.CUT } }), @@ -959,32 +941,17 @@ function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitche ...CreateDSKBaseline(config, videoSwitcher), // ties the DSK for jingles to ME4 USK1 to have effects on CLEAN (ME4) - literal({ - id: '', + videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - priority: 0, layer: AtemLLayer.AtemCleanUSKEffect, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - upstreamKeyers: [ - { - upstreamKeyerId: 0, - onAir: false, - mixEffectKeyType: 0, - flyEnabled: false, - fillSource: jingleDSK.Fill, - cutSource: jingleDSK.Key, - maskEnabled: false, - lumaSettings: { - preMultiplied: false, - clip: Number(jingleDSK.Clip) * 10, // input is percents (0-100), atem uses 1-000 - gain: Number(jingleDSK.Gain) * 10 // input is percents (0-100), atem uses 1-000 - } - } - ] - } + keyers: [ + { + id: 0, + onAir: false, + config: jingleDSK + } + ] } }), literal({ diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index 6aaa8d58..d3cd5b61 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -6,10 +6,16 @@ import { IngestSegment, ISegmentUserContext, PieceLifespan, - TSR, WithTimeline } from 'blueprints-integration' -import { ExtendedSegmentContextImpl, getSegmentBase, INewsPayload, literal } from 'tv2-common' +import { + ExtendedSegmentContext, + ExtendedSegmentContextImpl, + getSegmentBase, + INewsPayload, + literal, + TransitionStyle +} from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import * as _ from 'underscore' import { AtemLLayer } from '../tv2_afvd_studio/layers' @@ -62,7 +68,7 @@ export async function getSegment( } export function CreatePartContinuity( - config: GalleryBlueprintConfig, + context: ExtendedSegmentContext, ingestSegment: IngestSegment ): BlueprintResultPart { return { @@ -83,9 +89,9 @@ export function CreatePartContinuity( lifespan: PieceLifespan.WithinPart, content: literal>({ studioLabel: '', - switcherInput: config.studio.AtemSource.Continuity, - timelineObjects: _.compact([ - literal({ + switcherInput: context.config.studio.AtemSource.Continuity, + timelineObjects: [ + context.videoSwitcher.getMixEffectTimelineObject({ id: '', enable: { start: 0 @@ -93,15 +99,11 @@ export function CreatePartContinuity( priority: 1, layer: AtemLLayer.AtemMEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: config.studio.AtemSource.Continuity, - transition: TSR.AtemTransitionStyle.CUT - } + input: context.config.studio.AtemSource.Continuity, + transition: TransitionStyle.CUT } }) - ]) + ] }) }) ], diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index d8734097..8b656f75 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -6,8 +6,7 @@ import { IBlueprintPart, IBlueprintPiece, PieceLifespan, - TimelineObjectCoreExt, - TSR + TimelineObjectCoreExt } from 'blueprints-integration' import { AddScript, @@ -21,7 +20,7 @@ import { PartTime, PieceMetaData, SourceInfo, - TransitionSettings + TransitionStyle } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import { AtemLLayer } from '../../tv2_afvd_studio/layers' @@ -111,21 +110,13 @@ function makeContentEVS( switcherInput: atemInput, ignoreMediaObjectStatus: true, timelineObjects: literal([ - literal({ - id: ``, - enable: { - start: 0 - }, + context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, layer: AtemLLayer.AtemMEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: atemInput, - transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(context.config, partDefinition) - } + input: atemInput, + transition: partDefinition.transition?.style ?? TransitionStyle.CUT, + transitionDuration: partDefinition.transition?.duration } }), ...GetSisyfosTimelineObjForReplay(context.config, sourceInfoReplay, partDefinition.sourceDefinition.vo) diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index 123d308e..d3bf8b0e 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -5,8 +5,6 @@ import { IBlueprintAdLibPiece, IBlueprintPiece, PieceLifespan, - TimelineObjectCoreExt, - TSR, VTContent, WithTimeline } from 'blueprints-integration' @@ -22,7 +20,7 @@ import { PartDefinitionKam, PieceMetaData, TimeFromINewsField, - TransitionSettings + TransitionStyle } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import { AtemLLayer } from '../../tv2_afvd_studio/layers' @@ -65,25 +63,17 @@ export async function CreatePartKam( ignoreMediaObjectStatus: true, fileName: '', path: '', - timelineObjects: literal([ - literal({ - id: ``, - enable: { - start: 0 - }, + timelineObjects: [ + context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, layer: AtemLLayer.AtemMEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: jingleDSK.Fill, - transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(context.config, partDefinition) - } + input: jingleDSK.Fill, + transition: partDefinition.transition?.style ?? TransitionStyle.CUT, + transitionDuration: partDefinition.transition?.duration } }) - ]) + ] }) }) part.expectedDuration = TimeFromINewsField(partDefinition.fields.totalTime) * 1000 @@ -113,26 +103,18 @@ export async function CreatePartKam( content: { studioLabel: '', switcherInput: atemInput, - timelineObjects: literal([ - literal({ - id: ``, - enable: { - start: 0 - }, + timelineObjects: [ + context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, layer: AtemLLayer.AtemMEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: Number(atemInput), - transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(context.config, partDefinition) - } + input: Number(atemInput), + transition: partDefinition.transition?.style ?? TransitionStyle.CUT, + transitionDuration: partDefinition.transition?.duration } }), ...GetSisyfosTimelineObjForCamera(context.config, sourceInfoCam, partDefinition.sourceDefinition.minusMic) - ]) + ] } }) } diff --git a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts index bb0b5127..50757ce3 100644 --- a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts @@ -5,7 +5,6 @@ import { SourceLayerType, SplitsContent, TimelineObjectCoreExt, - TimelineObjHoldMode, TSR } from 'blueprints-integration' import { AtemLLayerDSK, ExtendedShowStyleContext, FindDSKJingle, TimelineBlueprintExt } from 'tv2-common' @@ -72,9 +71,8 @@ export function postProcessPieceTimelineObjects( const lookaheadObj: TSR.TimelineObjAtemAUX & TimelineBlueprintExt = { id: '', enable: { start: 0 }, - priority: tlObj.holdMode === TimelineObjHoldMode.ONLY ? 5 : 0, // Must be below lookahead, except when forced by hold + priority: 0, // Must be below lookahead, except when forced by hold layer: AtemLLayer.AtemAuxLookahead, - holdMode: tlObj.holdMode, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.AUX, diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index 09183106..e0ba84b9 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -5,7 +5,7 @@ import { IStudioContext, TSR } from 'blueprints-integration' -import { ExtendedStudioContext, literal } from 'tv2-common' +import { ExtendedStudioContext, literal, TransitionStyle } from 'tv2-common' import * as _ from 'underscore' import { SharedGraphicLLayer } from '../tv2-constants' import { AtemSourceIndex } from '../types/atem' @@ -69,18 +69,12 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin return { timelineObjects: [ ...convertMappings(atemMeMappings, id => - literal({ - id: '', - enable: { while: '1' }, - priority: 0, + context.videoSwitcher.getMixEffectTimelineObject({ layer: id, + enable: { while: '1' }, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: AtemSourceIndex.Bars, - transition: TSR.AtemTransitionStyle.CUT - } + input: AtemSourceIndex.Bars, + transition: TransitionStyle.CUT } }) ), @@ -126,18 +120,12 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin } } }), - literal({ - id: '', + context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - priority: 0, layer: AtemLLayer.AtemMEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: AtemSourceIndex.MP1, - transition: TSR.AtemTransitionStyle.CUT - } + input: AtemSourceIndex.MP1, + transition: TransitionStyle.CUT } }), literal({ diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 13b22eab..a9667da2 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -40,8 +40,10 @@ import { SourceInfo, SourceInfoToSourceDefinition, SourceInfoType, + SpecialInput, t, TimeFromINewsField, + TransitionStyle, VideoSwitcher } from 'tv2-common' import { @@ -582,31 +584,19 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche timelineObjects: [ ...CreateGraphicBaseline(config), // Default timeline - literal({ - id: '', - enable: { while: '1' }, - priority: 0, + videoSwitcher.getMixEffectTimelineObject({ layer: OfftubeAtemLLayer.AtemMEClean, + enable: { while: '1' }, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: config.studio.AtemSource.Default, - transition: TSR.AtemTransitionStyle.CUT - } + input: config.studio.AtemSource.Default, + transition: TransitionStyle.CUT } }), - literal({ - id: '', + videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - priority: 0, layer: OfftubeAtemLLayer.AtemMENext, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - previewInput: config.studio.AtemSource.Default - } + previewInput: config.studio.AtemSource.Default } }), @@ -796,17 +786,11 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche }), // Route ME 2 PGM to ME 1 PGM - literal({ - id: '', + videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - priority: 0, layer: OfftubeAtemLLayer.AtemMEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - programInput: AtemSourceIndex.Prg2 - } + input: SpecialInput.ME2_PROGRAM } }), diff --git a/src/tv2_offtube_showstyle/getSegment.ts b/src/tv2_offtube_showstyle/getSegment.ts index 55bdf54a..a934ebe8 100644 --- a/src/tv2_offtube_showstyle/getSegment.ts +++ b/src/tv2_offtube_showstyle/getSegment.ts @@ -8,7 +8,13 @@ import { TSR, WithTimeline } from 'blueprints-integration' -import { ExtendedSegmentContextImpl, getSegmentBase, literal } from 'tv2-common' +import { + ExtendedSegmentContextImpl, + ExtendedShowStyleContext, + getSegmentBase, + literal, + TransitionStyle +} from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import * as _ from 'underscore' import { OfftubeAtemLLayer } from '../tv2_offtube_studio/layers' @@ -51,7 +57,10 @@ export async function getSegment( } } -function CreatePartContinuity(config: OfftubeBlueprintConfig, ingestSegment: IngestSegment): BlueprintResultPart { +function CreatePartContinuity( + context: ExtendedShowStyleContext, + ingestSegment: IngestSegment +): BlueprintResultPart { return { part: { externalId: `${ingestSegment.externalId}-CONTINUITY`, @@ -70,25 +79,17 @@ function CreatePartContinuity(config: OfftubeBlueprintConfig, ingestSegment: Ing lifespan: PieceLifespan.WithinPart, content: literal>({ studioLabel: '', - switcherInput: config.studio.AtemSource.Continuity, - timelineObjects: _.compact([ - literal({ - id: '', - enable: { - start: 0 - }, + switcherInput: context.config.studio.AtemSource.Continuity, + timelineObjects: [ + context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, layer: OfftubeAtemLLayer.AtemMEClean, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: config.studio.AtemSource.Continuity, - transition: TSR.AtemTransitionStyle.CUT - } + input: context.config.studio.AtemSource.Continuity, + transition: TransitionStyle.CUT } }) - ]) + ] }) } ], diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index 10f2a757..96e4f82a 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -22,7 +22,7 @@ import { literal, PartDefinitionKam, PieceMetaData, - TransitionSettings + TransitionStyle } from 'tv2-common' import { SharedOutputLayers, TallyTags } from 'tv2-constants' import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' @@ -61,8 +61,8 @@ export async function OfftubeCreatePartKam( ignoreMediaObjectStatus: true, fileName: '', path: '', - timelineObjects: literal([ - literal({ + timelineObjects: [ + context.videoSwitcher.getMixEffectTimelineObject({ id: ``, enable: { start: 0 @@ -70,16 +70,12 @@ export async function OfftubeCreatePartKam( priority: 1, layer: OfftubeAtemLLayer.AtemMEClean, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: jingleDSK.Fill, - transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(context.config, partDefinition) - } + input: jingleDSK.Fill, + transition: partDefinition.transition?.style ?? TransitionStyle.CUT, + transitionDuration: partDefinition.transition?.duration } }) - ]) + ] }) }) } else { @@ -108,8 +104,8 @@ export async function OfftubeCreatePartKam( content: { studioLabel: '', switcherInput: atemInput, - timelineObjects: literal([ - literal({ + timelineObjects: [ + context.videoSwitcher.getMixEffectTimelineObject({ id: ``, enable: { start: 0 @@ -117,18 +113,13 @@ export async function OfftubeCreatePartKam( priority: 1, layer: OfftubeAtemLLayer.AtemMEClean, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: Number(atemInput), - transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(context.config, partDefinition) - } + input: Number(atemInput), + transition: partDefinition.transition?.style ?? TransitionStyle.CUT, + transitionDuration: partDefinition.transition?.duration } }), - ...GetSisyfosTimelineObjForCamera(context.config, sourceInfoCam, partDefinition.sourceDefinition.minusMic) - ]) + ] } }) } diff --git a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts b/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts index 280cbeac..51b0e3b4 100644 --- a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts @@ -3,7 +3,6 @@ import { IBlueprintPieceGeneric, OnGenerateTimelineObj, TimelineObjectCoreExt, - TimelineObjHoldMode, TSR } from 'blueprints-integration' import { ExtendedShowStyleContext, TimelineBlueprintExt } from 'tv2-common' @@ -60,9 +59,8 @@ export function postProcessPieceTimelineObjects( const lookaheadObj: TSR.TimelineObjAbstractAny & TimelineBlueprintExt = { id: '', enable: { start: 0 }, - priority: tlObj.holdMode === TimelineObjHoldMode.ONLY ? 5 : 0, // Must be below lookahead, except when forced by hold + priority: 0, layer: OfftubeAbstractLLayer.OfftubeAbstractLLayerAbstractLookahead, - holdMode: tlObj.holdMode, content: { deviceType: TSR.DeviceType.ABSTRACT }, @@ -78,9 +76,8 @@ export function postProcessPieceTimelineObjects( const lookaheadObj: TSR.TimelineObjAtemME & TimelineBlueprintExt = { id: '', enable: { start: 0 }, - priority: tlObj.holdMode === TimelineObjHoldMode.ONLY ? 5 : 0, // Must be below lookahead, except when forced by hold + priority: 0, // Must be below lookahead, except when forced by hold layer: OfftubeAtemLLayer.AtemMENext, - holdMode: tlObj.holdMode, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.ME, diff --git a/src/tv2_offtube_studio/getBaseline.ts b/src/tv2_offtube_studio/getBaseline.ts index 3b4d9d5c..6a339b4f 100644 --- a/src/tv2_offtube_studio/getBaseline.ts +++ b/src/tv2_offtube_studio/getBaseline.ts @@ -5,7 +5,7 @@ import { IStudioContext, TSR } from 'blueprints-integration' -import { literal } from 'tv2-common' +import { ExtendedStudioContext, literal, SpecialInput, TransitionStyle } from 'tv2-common' import * as _ from 'underscore' import { AtemSourceIndex } from '../types/atem' import { OfftubeStudioBlueprintConfig } from './helpers/config' @@ -28,9 +28,9 @@ function filterMappings( return result } -export function getBaseline(context: IStudioContext): BlueprintResultBaseline { - const mappings = context.getStudioMappings() - const config = context.getStudioConfig() as OfftubeStudioBlueprintConfig +export function getBaseline(coreContext: IStudioContext): BlueprintResultBaseline { + const context = new ExtendedStudioContext(coreContext) + const mappings = coreContext.getStudioMappings() const sisyfosMappings = filterMappings(mappings, (_id, v) => v.device === TSR.DeviceType.SISYFOS) @@ -41,7 +41,7 @@ export function getBaseline(context: IStudioContext): BlueprintResultBaseline { if (sisyfosChannel) { mappedChannels.push({ mappedLayer: id, - isPgm: config.studio.IdleSisyfosLayers.includes(id) ? 1 : sisyfosChannel.isPgm, + isPgm: context.config.studio.IdleSisyfosLayers.includes(id) ? 1 : sisyfosChannel.isPgm, visible: true }) } else { @@ -73,33 +73,21 @@ export function getBaseline(context: IStudioContext): BlueprintResultBaseline { }), // have ATEM output default still image - literal({ - id: '', + context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - priority: 0, layer: OfftubeAtemLLayer.AtemMEClean, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: config.studio.IdleSource, - transition: TSR.AtemTransitionStyle.CUT - } + input: context.config.studio.IdleSource, + transition: TransitionStyle.CUT } }), // Route ME 2 PGM to ME 1 PGM - literal({ - id: '', + context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - priority: 0, layer: OfftubeAtemLLayer.AtemMEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - programInput: AtemSourceIndex.Prg2 - } + input: SpecialInput.ME2_PROGRAM } }), literal({ From 7a52697cd8c959df156a334d34def07665de0d78 Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 2 Feb 2023 12:25:45 +0100 Subject: [PATCH 12/86] wip: SOF-1260 mostly renaming and VideoSwitcher interface changes --- .../__tests__/transitionSettings.spec.ts | 2 +- src/tv2-common/actions/executeAction.ts | 10 +- src/tv2-common/blueprintConfig.ts | 3 +- src/tv2-common/content/dve.ts | 8 +- src/tv2-common/cues/ekstern.ts | 10 +- src/tv2-common/cues/mixMinus.ts | 8 +- src/tv2-common/helpers/abPlayback.ts | 38 +++---- src/tv2-common/helpers/dsk.ts | 6 +- .../graphics/viz/VizPilotGraphicGenerator.ts | 3 +- .../migrations/moveSourcesToTable.ts | 4 +- src/tv2-common/migrations/sourceManifest.ts | 8 +- src/tv2-common/sources.ts | 2 +- src/tv2-common/types/config.ts | 2 +- src/tv2-common/videoSwitchers/Atem.ts | 40 +++++-- src/tv2-common/videoSwitchers/TriCaster.ts | 15 +-- .../videoSwitchers/VideoSwitcher.ts | 11 ++ src/tv2-common/videoSwitchers/types.ts | 28 ++++- src/tv2-constants/enums.ts | 5 +- .../__tests__/blueprint.spec.ts | 10 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 13 ++- src/tv2_afvd_showstyle/getRundown.ts | 12 +-- src/tv2_afvd_showstyle/getSegment.ts | 4 +- src/tv2_afvd_showstyle/parts/evs.ts | 10 +- src/tv2_afvd_showstyle/parts/kam.ts | 6 +- .../postProcessTimelineObjects.ts | 27 ++--- .../__tests__/config-manifest.spec.ts | 5 +- src/tv2_afvd_studio/config-manifests.ts | 100 ++++++++++-------- src/tv2_afvd_studio/helpers/config.ts | 4 +- src/tv2_afvd_studio/helpers/sources.ts | 2 +- src/tv2_afvd_studio/migrations/index.ts | 2 +- src/tv2_offtube_showstyle/getRundown.ts | 12 +-- src/tv2_offtube_showstyle/getSegment.ts | 5 +- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 8 +- .../postProcessTimelineObjects.ts | 11 +- .../__tests__/config-manifest.spec.ts | 3 +- src/tv2_offtube_studio/config-manifests.ts | 60 +++++------ src/tv2_offtube_studio/helpers/config.ts | 9 +- src/tv2_offtube_studio/helpers/sources.ts | 2 +- 38 files changed, 283 insertions(+), 225 deletions(-) diff --git a/src/tv2-common/__tests__/transitionSettings.spec.ts b/src/tv2-common/__tests__/transitionSettings.spec.ts index 91497e34..f9c280f0 100644 --- a/src/tv2-common/__tests__/transitionSettings.spec.ts +++ b/src/tv2-common/__tests__/transitionSettings.spec.ts @@ -139,7 +139,7 @@ function assertDipInputValueFromConfig( dipInputSource: number ) { mockConfig.studio = ({ - AtemSource: createAtemSourceConfig(dipInputSource) + SwitcherSource: createAtemSourceConfig(dipInputSource) } as any) as TV2StudioConfigBase const transition: PartTransition = { style: TSR.AtemTransitionStyle.DIP, diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index aedd4cfa..5a5b419a 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1222,18 +1222,14 @@ async function executeActionCutToRemote< tags: [GetTagForLive(userData.sourceDefinition)], content: { timelineObjects: _.compact([ - literal({ + context.videoSwitcher.getMixEffectTimelineObject({ id: '', enable: { while: '1' }, priority: 1, layer: settings.LLayer.Atem.cutOnclean ? settings.LLayer.Atem.MEClean : settings.LLayer.Atem.MEProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - input: sourceInfo.port, - transition: TSR.AtemTransitionStyle.CUT - } + input: sourceInfo.port, + transition: TransitionStyle.CUT } }), ...eksternSisyfos diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index e4aadf76..74d27bd8 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -99,13 +99,14 @@ export interface TV2StudioConfigBase { ABPlaybackDebugLogging: boolean SwitcherType: SwitcherType - AtemSource: { + SwitcherSource: { Default: number SplitArtF: number SplitArtK: number DSK: TableConfigItemDSK[] Dip: number } + TriCasterSettings: {} AtemSettings: {} StudioMics: string[] SourcesRM: TableConfigItemSourceMappingWithSisyfos[] diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 431e1e13..9ce9e0df 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -197,7 +197,7 @@ export function MakeContentDVE2< const boxes: BoxConfig[] = Object.entries(template.boxes).map(([_num, box]) => ({ ...box, - source: context.config.studio.AtemSource.Default + source: context.config.studio.SwitcherSource.Default })) const dveTimeline: TSR.TSRTimelineObj[] = [] const boxSources: BoxSources = [] @@ -223,7 +223,7 @@ export function MakeContentDVE2< case SourceType.DEFAULT: setBoxSource(box, boxSources, { sourceLayerType: SourceLayerType.UNKNOWN, - port: context.config.studio.AtemSource.Default + port: context.config.studio.SwitcherSource.Default }) break case SourceType.KAM: @@ -346,8 +346,8 @@ export function MakeContentDVE2< deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRCPROPS, ssrcProps: { - artFillSource: context.config.studio.AtemSource.SplitArtF, - artCutSource: context.config.studio.AtemSource.SplitArtK, + artFillSource: context.config.studio.SwitcherSource.SplitArtF, + artCutSource: context.config.studio.SwitcherSource.SplitArtK, artOption: 1, ...(template.properties && template.properties?.artPreMultiplied === false ? { diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index fbdbba1c..e1c1d042 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -52,7 +52,7 @@ export function EvaluateEksternBase< part.invalid = true return } - const atemInput = sourceInfoEkstern.port + const switcherInput = sourceInfoEkstern.port if (adlib) { adlibPieces.push({ @@ -72,13 +72,13 @@ export function EvaluateEksternBase< }, content: literal>({ studioLabel: '', - switcherInput: atemInput, + switcherInput, timelineObjects: literal([ context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, layer: layersEkstern.ATEM.MEProgram, content: { - input: atemInput, + input: switcherInput, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration }, @@ -110,13 +110,13 @@ export function EvaluateEksternBase< tags: [GetTagForLive(parsedCue.sourceDefinition)], content: literal>({ studioLabel: '', - switcherInput: atemInput, + switcherInput, timelineObjects: literal([ context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, layer: layersEkstern.ATEM.MEProgram, content: { - input: atemInput, + input: switcherInput, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration } diff --git a/src/tv2-common/cues/mixMinus.ts b/src/tv2-common/cues/mixMinus.ts index 3b0edd9d..eb017152 100644 --- a/src/tv2-common/cues/mixMinus.ts +++ b/src/tv2-common/cues/mixMinus.ts @@ -23,7 +23,7 @@ export function EvaluateCueMixMinus( context.core.notifyUserWarning(`${name} does not exist in this studio (MINUSKAM)`) return } - const atemInput = sourceInfo.port + const switcherInput = sourceInfo.port pieces.push({ externalId: part.externalId, @@ -34,11 +34,11 @@ export function EvaluateCueMixMinus( lifespan: PieceLifespan.OutOnShowStyleEnd, sourceLayerId: SharedSourceLayers.AuxMixMinus, outputLayerId: SharedOutputLayers.AUX, - content: MixMinusContent(atemInput) + content: MixMinusContent(switcherInput) }) } -function MixMinusContent(atemInput: number): WithTimeline { +function MixMinusContent(switcherInput: number): WithTimeline { return { timelineObjects: literal([ literal({ @@ -46,7 +46,7 @@ function MixMinusContent(atemInput: number): WithTimeline { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.AUX, aux: { - input: atemInput + input: switcherInput } }, enable: { diff --git a/src/tv2-common/helpers/abPlayback.ts b/src/tv2-common/helpers/abPlayback.ts index f38eabb9..89f7bf94 100644 --- a/src/tv2-common/helpers/abPlayback.ts +++ b/src/tv2-common/helpers/abPlayback.ts @@ -278,36 +278,26 @@ function updateObjectsToMediaPlayer< context.core.logWarning(`Moving object to mediaPlayer that probably shouldnt be? (from layer: ${obj.layer})`) // context.notifyUserWarning(obj) } - } else if (obj.content.deviceType === TSR.DeviceType.ATEM) { - let atemInput = _.find(context.config.mediaPlayers, mp => mp.id === playerId.toString()) - if (!atemInput) { + } else if (context.videoSwitcher.isVideoSwitcherTimelineObject(obj)) { + let switcherInput = _.find(context.config.mediaPlayers, mp => mp.id === playerId.toString()) + if (!switcherInput) { context.core.logWarning(`Trying to find atem input for unknown mediaPlayer: #${playerId}`) - atemInput = { id: playerId.toString(), val: context.config.studio.AtemSource.Default.toString() } + switcherInput = { id: playerId.toString(), val: context.config.studio.SwitcherSource.Default.toString() } } - - const atemObj = obj as TSR.TimelineObjAtemAny - if (atemObj.content.type === TSR.TimelineContentTypeAtem.ME) { - const atemObj2 = atemObj as TSR.TimelineObjAtemME - if (atemObj2.classes?.includes('ab_on_preview')) { - atemObj2.content.me.previewInput = Number(atemInput.val) || 0 + const input = Number(switcherInput.val) || 0 + if (context.videoSwitcher.isMixEffect(obj)) { + if (obj.classes?.includes('ab_on_preview')) { + context.videoSwitcher.updatePreviewInput(obj, input) } else { - atemObj2.content.me.input = Number(atemInput.val) || 0 + context.videoSwitcher.updateInput(obj, input) } - } else if (atemObj.content.type === TSR.TimelineContentTypeAtem.AUX) { - const atemObj2 = atemObj as TSR.TimelineObjAtemAUX - atemObj2.content.aux.input = Number(atemInput.val) || 0 - } else if (atemObj.content.type === TSR.TimelineContentTypeAtem.SSRC) { - const atemObj2 = atemObj as TSR.TimelineObjAtemSsrc - // Find box with no source - const input = Number(atemInput.val) || 0 - atemObj2.content.ssrc.boxes.forEach((box, i) => { - if (box.source === -1) { - atemObj2.content.ssrc.boxes[i].source = input // Pgm box - } - }) + } else if (context.videoSwitcher.isAux(obj)) { + context.videoSwitcher.updateAuxInput(obj, input) + } else if (context.videoSwitcher.isDve(obj)) { + context.videoSwitcher.updateUnpopulatedDveBoxes(obj, input) } else { context.core.logWarning( - `Trying to move ATEM object of unknown type (${atemObj.content.type}) for media player assignment` + `Trying to move ATEM object of unknown type (${(obj.content as any).type}) for media player assignment` ) } } else if (obj.content.deviceType === TSR.DeviceType.SISYFOS) { diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index a471105d..12e64998 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -172,9 +172,9 @@ export function CreateDSKBaseline( export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { return literal({ - id: 'AtemSource.DSK', - name: 'ATEM DSK', - description: 'ATEM Downstream Keyers Fill and Key', + id: 'SwitcherSource.DSK', + name: 'Switcher DSK', + description: 'Video Switcher Downstream Keyers Fill and Key', type: ConfigManifestEntryType.TABLE, required: false, defaultVal: literal>( diff --git a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts index 62fde4b8..3fa98ee3 100644 --- a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts @@ -11,6 +11,7 @@ import { PilotGraphicProps, TransitionStyle } from 'tv2-common' +import { ControlClasses } from 'tv2-constants' import { PilotGraphicGenerator } from '../pilot' @@ -112,7 +113,7 @@ export class VizPilotGraphicGenerator extends PilotGraphicGenerator { input: fullDSK.Fill } }, - classes: ['MIX_MINUS_OVERRIDE_DSK', 'PLACEHOLDER_OBJECT_REMOVEME'] + classes: [ControlClasses.MixMinusOverrideDsk, ControlClasses.Placeholder] }) ) } diff --git a/src/tv2-common/migrations/moveSourcesToTable.ts b/src/tv2-common/migrations/moveSourcesToTable.ts index 33e87380..4fc96d6e 100644 --- a/src/tv2-common/migrations/moveSourcesToTable.ts +++ b/src/tv2-common/migrations/moveSourcesToTable.ts @@ -34,7 +34,7 @@ export function MoveSourcesToTable( literal({ _id: i.toString(), SourceName: source.id, - AtemSource: source.val, + SwitcherSource: source.val, SisyfosLayers: getSisyfosLayersForMigration(configName, source.id.toString().toUpperCase()), StudioMics: !!studioMics }) @@ -44,7 +44,7 @@ export function MoveSourcesToTable( literal({ _id: i.toString(), SourceName: source.id, - AtemSource: source.val + SwitcherSource: source.val }) ) } diff --git a/src/tv2-common/migrations/sourceManifest.ts b/src/tv2-common/migrations/sourceManifest.ts index 10d7758d..2b34e626 100644 --- a/src/tv2-common/migrations/sourceManifest.ts +++ b/src/tv2-common/migrations/sourceManifest.ts @@ -11,7 +11,7 @@ export function MakeConfigForSources( return { id: `Sources${name}`, name: `${displayName} Mapping`, - description: `${displayName} number to ATEM input and Sisyfos layer`, + description: `${displayName} number to Video Switcher input and Sisyfos layer`, type: ConfigManifestEntryType.TABLE, required: false, defaultVal, @@ -26,9 +26,9 @@ export function MakeConfigForSources( rank: 0 }, { - id: 'AtemSource', - name: 'ATEM input', - description: `ATEM vision mixer input for ${displayName} input`, + id: 'SwitcherSource', + name: 'Switcher input', + description: `Video Switcher input for ${displayName} input`, type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, diff --git a/src/tv2-common/sources.ts b/src/tv2-common/sources.ts index 14fde8d0..dce167c2 100644 --- a/src/tv2-common/sources.ts +++ b/src/tv2-common/sources.ts @@ -63,7 +63,7 @@ export function ParseMappingTable( return studioConfig.map(conf => ({ type, id: conf.SourceName, - port: conf.AtemSource, + port: conf.SwitcherSource, sisyfosLayers: conf.SisyfosLayers, useStudioMics: conf.StudioMics, wantsToPersistAudio: conf.WantsToPersistAudio, diff --git a/src/tv2-common/types/config.ts b/src/tv2-common/types/config.ts index 65d66b27..c192cbac 100644 --- a/src/tv2-common/types/config.ts +++ b/src/tv2-common/types/config.ts @@ -2,7 +2,7 @@ import { DSKRoles } from 'tv2-constants' export interface TableConfigItemSourceMapping { SourceName: string - AtemSource: number + SwitcherSource: number } export type TableConfigItemSourceMappingWithSisyfos = { diff --git a/src/tv2-common/videoSwitchers/Atem.ts b/src/tv2-common/videoSwitchers/Atem.ts index 2823f8a7..dba56c35 100644 --- a/src/tv2-common/videoSwitchers/Atem.ts +++ b/src/tv2-common/videoSwitchers/Atem.ts @@ -30,13 +30,12 @@ const TRANSITION_MAP = { } export class Atem extends VideoSwitcherImpl { - public static isMixEffectTimelineObject(timelineObject: TSR.TSRTimelineObj): timelineObject is TSR.TimelineObjAtemME { - return ( - timelineObject.content.deviceType === TSR.DeviceType.ATEM && - timelineObject.content.type === TSR.TimelineContentTypeAtem.ME - ) - } + public readonly type = SwitcherType.ATEM + + public isVideoSwitcherTimelineObject = (timelineObject: TSR.TSRTimelineObj): boolean => { + return timelineObject.content.deviceType === TSR.DeviceType.ATEM + } public getMixEffectTimelineObject(props: MixEffectProps): TSR.TimelineObjAtemME & TimelineBlueprintExt { const { content } = props @@ -67,7 +66,14 @@ export class Atem extends VideoSwitcherImpl { } public findMixEffectTimelineObject(timelineObjects: TSR.TSRTimelineObj[]): TSR.TSRTimelineObj | undefined { - return timelineObjects.find(Atem.isMixEffectTimelineObject) + return timelineObjects.find(this.isMixEffect) + } + + public isMixEffect = (timelineObject: TSR.TSRTimelineObj): timelineObject is TSR.TimelineObjAtemME => { + return ( + timelineObject.content.deviceType === TSR.DeviceType.ATEM && + timelineObject.content.type === TSR.TimelineContentTypeAtem.ME + ) } public updateTransition( @@ -75,7 +81,7 @@ export class Atem extends VideoSwitcherImpl { transition: TransitionStyle, transitionDuration?: number | undefined ): TSR.TSRTimelineObj { - if (!Atem.isMixEffectTimelineObject(timelineObject)) { + if (!this.isMixEffect(timelineObject)) { // @todo: log error or throw return timelineObject } @@ -83,6 +89,22 @@ export class Atem extends VideoSwitcherImpl { timelineObject.content.me.transitionSettings = this.getTransitionSettings(transition, transitionDuration) return timelineObject } + public updatePreviewInput(timelineObject: TSR.TSRTimelineObj, previewInput: number | SpecialInput): TSR.TSRTimelineObj { + if (!this.isMixEffect(timelineObject)) { + // @todo: log error or throw + return timelineObject + } + timelineObject.content.me.previewInput = this.getInputNumber(previewInput) + return timelineObject + } + public updateInput(timelineObject: TSR.TSRTimelineObj, input: number | SpecialInput): TSR.TSRTimelineObj { + if (!this.isMixEffect(timelineObject)) { + // @todo: log error or throw + return timelineObject + } + timelineObject.content.me.input = this.getInputNumber(input) + return timelineObject + } public getDskTimelineObjects(props: DskProps) { const { content } = props @@ -145,7 +167,7 @@ export class Atem extends VideoSwitcherImpl { case TransitionStyle.STING: return undefined case TransitionStyle.DIP: - return { dip: { rate: duration, input: this.config.studio?.AtemSource?.Dip ?? AtemSourceIndex.Col2 } } + return { dip: { rate: duration, input: this.config.studio?.SwitcherSource?.Dip ?? AtemSourceIndex.Col2 } } case TransitionStyle.MIX: return { mix: { rate: duration } } case TransitionStyle.WIPE: diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 42ea7a82..baf10c93 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -29,11 +29,6 @@ const TRANSITION_MAP: Record = { } export class TriCaster extends VideoSwitcherImpl { - public static isMixEffectTimelineObject( - timelineObject: TSR.TSRTimelineObj - ): timelineObject is TSR.TimelineObjTriCasterME { - return TSR.isTimelineObjTriCasterME(timelineObject) - } public readonly type = SwitcherType.ATEM public getMixEffectTimelineObject(props: MixEffectProps): TSR.TimelineObjTriCasterME { @@ -57,8 +52,14 @@ export class TriCaster extends VideoSwitcherImpl { } } + public isMixEffect = ( + timelineObject: TSR.TSRTimelineObj + ): timelineObject is TSR.TimelineObjTriCasterME => { + return TSR.isTimelineObjTriCasterME(timelineObject) + } + public findMixEffectTimelineObject(timelineObjects: TSR.TSRTimelineObj[]): TSR.TSRTimelineObj | undefined { - return timelineObjects.find(TriCaster.isMixEffectTimelineObject) + return timelineObjects.find(this.isMixEffect) } public updateTransition( @@ -66,7 +67,7 @@ export class TriCaster extends VideoSwitcherImpl { transition: TransitionStyle, transitionDuration?: number | undefined ): TSR.TSRTimelineObj { - if (!TriCaster.isMixEffectTimelineObject(timelineObject)) { + if (!this.isMixEffect(timelineObject)) { // @todo: log error or throw return timelineObject } diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts index 1129fdab..9a8826d8 100644 --- a/src/tv2-common/videoSwitchers/VideoSwitcher.ts +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -4,6 +4,7 @@ import { AuxProps, DskProps, MixEffectProps, + SpecialInput, SwitcherType, TransitionStyle, TriCaster, @@ -29,11 +30,21 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { public abstract getMixEffectTimelineObject(properties: MixEffectProps): TSR.TSRTimelineObj public abstract findMixEffectTimelineObject(timelineObjects: TSR.TSRTimelineObj[]): TSR.TSRTimelineObj | undefined + public abstract isVideoSwitcherTimelineObject(timelineObject: TSR.TSRTimelineObj): boolean + public abstract isMixEffect(timelineObject: TSR.TSRTimelineObj): boolean public abstract updateTransition( timelineObjects: TSR.TSRTimelineObj, transition: TransitionStyle, transitionDuration?: number | undefined ): TSR.TSRTimelineObj + public abstract updatePreviewInput( + timelineObject: TSR.TSRTimelineObj, + previewInput: number | SpecialInput + ): TSR.TSRTimelineObj + public abstract updateInput( + timelineObject: TSR.TSRTimelineObj, + input: number | SpecialInput + ): TSR.TSRTimelineObj public abstract getDskTimelineObjects(properties: DskProps): TSR.TSRTimelineObj[] public abstract getAuxTimelineObject(properties: AuxProps): TSR.TSRTimelineObj diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index 3409b7df..37bcbc8b 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -83,13 +83,39 @@ export interface AuxProps extends TimelineObjectProps { } export interface VideoSwitcher { + + isMixEffect(timelineObject: TimelineObjectCoreExt): boolean getMixEffectTimelineObject(properties: MixEffectProps): TSR.TSRTimelineObj findMixEffectTimelineObject(timelineObjects: TimelineObjectCoreExt[]): TSR.TSRTimelineObj | undefined + isVideoSwitcherTimelineObject(timelineObject: TimelineObjectCoreExt): boolean updateTransition( - timelineObjects: TSR.TSRTimelineObj, + timelineObject: TimelineObjectCoreExt, transition: TransitionStyle, transitionDuration?: number ): TSR.TSRTimelineObj + updatePreviewInput( + timelineObject: TimelineObjectCoreExt, + previewInput: number | SpecialInput + ): TSR.TSRTimelineObj + updateInput( + timelineObject: TimelineObjectCoreExt, + input: number | SpecialInput + ): TSR.TSRTimelineObj + + isDsk(timelineObject: TimelineObjectCoreExt): boolean getDskTimelineObjects(properties: DskProps): TSR.TSRTimelineObj[] + + isAux(timelineObject: TimelineObjectCoreExt): boolean getAuxTimelineObject(properties: AuxProps): TSR.TSRTimelineObj + updateAuxInput( + timelineObject: TimelineObjectCoreExt, + input: number | SpecialInput + ): TSR.TSRTimelineObj + + isDve(timelineObject: TimelineObjectCoreExt): boolean + getDveTimelineObject(properties: AuxProps): TSR.TSRTimelineObj + updateUnpopulatedDveBoxes( + timelineObject: TimelineObjectCoreExt, + input: number | SpecialInput + ): TSR.TSRTimelineObj } diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index fcbb4708..db531133 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -123,9 +123,10 @@ export enum ControlClasses { ServerOnAir = 'server_on_air', LYDOnAir = 'lyd_on_air', LiveSourceOnAir = 'live_source_on_air', - NOLookahead = 'no_lookahead', CopyMediaPlayerSession = 'copy_media_player_session', - AbstractLookahead = 'abstract_lookahead' + AbstractLookahead = 'abstract_lookahead', + MixMinusOverrideDsk = 'MIX_MINUS_OVERRIDE_DSK', + Placeholder = 'PLACEHOLDER_OBJECT_REMOVEME' } export function GetEnableClassForServer(mediaPlayerSessionId: string) { diff --git a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts index 131bbafd..4195a593 100644 --- a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts @@ -909,7 +909,7 @@ describe('AFVD Blueprint', () => { SourcesRM: [ { SourceName: '1', - AtemSource: 10, + SwitcherSource: 10, SisyfosLayers: [], StudioMics: true, WantsToPersistAudio: false @@ -933,7 +933,7 @@ describe('AFVD Blueprint', () => { SourcesRM: [ { SourceName: '1', - AtemSource: 10, + SwitcherSource: 10, SisyfosLayers: [], StudioMics: false, WantsToPersistAudio: false @@ -957,7 +957,7 @@ describe('AFVD Blueprint', () => { SourcesCam: [ { SourceName: '1', - AtemSource: 1, + SwitcherSource: 1, SisyfosLayers: [], StudioMics: true, WantsToPersistAudio: false @@ -981,7 +981,7 @@ describe('AFVD Blueprint', () => { SourcesCam: [ { SourceName: '1', - AtemSource: 1, + SwitcherSource: 1, SisyfosLayers: [], StudioMics: true, WantsToPersistAudio: false @@ -1005,7 +1005,7 @@ describe('AFVD Blueprint', () => { SourcesCam: [ { SourceName: '1', - AtemSource: 1, + SwitcherSource: 1, SisyfosLayers: [], StudioMics: false, WantsToPersistAudio: false diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index b017085e..db4d356e 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -26,7 +26,7 @@ function prepareConfig( wantsToPersistAudio?: boolean ): Array<{ SourceName: string - AtemSource: number + SwitcherSource: number SisyfosLayers: string[] StudioMics: boolean wantsToPersistAudio: boolean @@ -34,7 +34,7 @@ function prepareConfig( return parseMapStr(undefined, conf, true).map(c => { return { SourceName: c.id, - AtemSource: c.val, + SwitcherSource: c.val, SisyfosLayers: getSisyfosLayers(configName, c.id), StudioMics: studioMics, wantsToPersistAudio: wantsToPersistAudio ?? false @@ -101,7 +101,7 @@ export const defaultStudioConfig: StudioConfig = { 'sisyfos_source_Guest_3_st_a', 'sisyfos_source_Guest_4_st_a' ], - AtemSource: { + SwitcherSource: { MixMinusDefault: 2, DSK: defaultDSKConfig, SplitArtF: 30, @@ -112,8 +112,8 @@ export const defaultStudioConfig: StudioConfig = { }, SofieHostURL: '', ABMediaPlayers: [ - { SourceName: '1', AtemSource: 1 }, - { SourceName: '2', AtemSource: 2 } + { SourceName: '1', SwitcherSource: 1 }, + { SourceName: '2', SwitcherSource: 2 } ], ABPlaybackDebugLogging: false, AtemSettings: { @@ -123,6 +123,9 @@ export const defaultStudioConfig: StudioConfig = { Playing: true } }, + TriCasterSettings: { + DveMixEffect: 1 + }, AudioBedSettings: { fadeIn: 1000, fadeOut: 1000, diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index dff5fbda..8ccbf813 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -844,7 +844,7 @@ function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitche enable: { while: '1' }, layer: AtemLLayer.AtemMEProgram, content: { - input: config.studio.AtemSource.Default, + input: config.studio.SwitcherSource.Default, transition: TransitionStyle.CUT } }), @@ -852,7 +852,7 @@ function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitche enable: { while: '1' }, layer: AtemLLayer.AtemMEClean, content: { - input: config.studio.AtemSource.Default, + input: config.studio.SwitcherSource.Default, transition: TransitionStyle.CUT } }), @@ -893,7 +893,7 @@ function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitche deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.AUX, aux: { - input: config.studio.AtemSource.Default + input: config.studio.SwitcherSource.Default } } }), @@ -919,7 +919,7 @@ function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitche deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.AUX, aux: { - input: config.studio.AtemSource.MixMinusDefault + input: config.studio.SwitcherSource.MixMinusDefault } } }), @@ -963,8 +963,8 @@ function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitche deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRCPROPS, ssrcProps: { - artFillSource: config.studio.AtemSource.SplitArtF, - artCutSource: config.studio.AtemSource.SplitArtK, + artFillSource: config.studio.SwitcherSource.SplitArtF, + artCutSource: config.studio.SwitcherSource.SplitArtK, artOption: 1, artPreMultiplied: true } diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index d3cd5b61..d0feb89a 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -89,7 +89,7 @@ export function CreatePartContinuity( lifespan: PieceLifespan.WithinPart, content: literal>({ studioLabel: '', - switcherInput: context.config.studio.AtemSource.Continuity, + switcherInput: context.config.studio.SwitcherSource.Continuity, timelineObjects: [ context.videoSwitcher.getMixEffectTimelineObject({ id: '', @@ -99,7 +99,7 @@ export function CreatePartContinuity( priority: 1, layer: AtemLLayer.AtemMEProgram, content: { - input: context.config.studio.AtemSource.Continuity, + input: context.config.studio.SwitcherSource.Continuity, transition: TransitionStyle.CUT } }) diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index 8b656f75..a1d7c716 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -55,7 +55,7 @@ export async function CreatePartEVS( if (sourceInfoReplay === undefined) { return CreatePartInvalid(partDefinition) } - const atemInput = sourceInfoReplay.port + const switcherInput = sourceInfoReplay.port pieces.push({ externalId: partDefinition.externalId, @@ -69,7 +69,7 @@ export async function CreatePartEVS( sisyfosLayers: [] } }, - content: makeContentEVS(context, atemInput, partDefinition, sourceInfoReplay) + content: makeContentEVS(context, switcherInput, partDefinition, sourceInfoReplay) }) await EvaluateCues( @@ -101,20 +101,20 @@ export async function CreatePartEVS( function makeContentEVS( context: ExtendedShowStyleContext, - atemInput: number, + switcherInput: number, partDefinition: PartDefinitionEVS, sourceInfoReplay: SourceInfo ): IBlueprintPiece['content'] { return { studioLabel: '', - switcherInput: atemInput, + switcherInput, ignoreMediaObjectStatus: true, timelineObjects: literal([ context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, layer: AtemLLayer.AtemMEProgram, content: { - input: atemInput, + input: switcherInput, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration } diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index d3bf8b0e..6a103659 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -83,7 +83,7 @@ export async function CreatePartKam( context.core.notifyUserWarning(`${partDefinition.rawType} does not exist in this studio`) return CreatePartInvalid(partDefinition) } - const atemInput = sourceInfoCam.port + const switcherInput = sourceInfoCam.port part = { ...part, ...CreateEffektForpart(context, partDefinition, pieces) } @@ -102,13 +102,13 @@ export async function CreatePartKam( }, content: { studioLabel: '', - switcherInput: atemInput, + switcherInput, timelineObjects: [ context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, layer: AtemLLayer.AtemMEProgram, content: { - input: Number(atemInput), + input: Number(switcherInput), transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration } diff --git a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts index 50757ce3..a39f4513 100644 --- a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts @@ -8,6 +8,7 @@ import { TSR } from 'blueprints-integration' import { AtemLLayerDSK, ExtendedShowStyleContext, FindDSKJingle, TimelineBlueprintExt } from 'tv2-common' +import { ControlClasses } from 'tv2-constants' import * as _ from 'underscore' import { AtemLLayer } from '../tv2_afvd_studio/layers' import { GalleryBlueprintConfig } from './helpers/config' @@ -35,17 +36,11 @@ export function postProcessPieceTimelineObjects( if (piece.content?.timelineObjects) { const extraObjs: TimelineObjectCoreExt[] = [] - const atemMeObjs = (piece.content.timelineObjects as Array< - | (TSR.TimelineObjAtemME & TimelineBlueprintExt & OnGenerateTimelineObj) - | (TSR.TimelineObjAtemDSK & TimelineBlueprintExt & OnGenerateTimelineObj) - >).filter( + const atemMeObjs = piece.content.timelineObjects.filter( obj => - obj.content && - obj.content.deviceType === TSR.DeviceType.ATEM && - (obj.content.type === TSR.TimelineContentTypeAtem.ME || obj.content.type === TSR.TimelineContentTypeAtem.DSK) - ) + context.videoSwitcher.isMixEffect(obj) || context.videoSwitcher.isDsk(obj)) _.each(atemMeObjs, tlObj => { - if (tlObj.layer === AtemLLayer.AtemMEProgram || tlObj.classes?.includes('MIX_MINUS_OVERRIDE_DSK')) { + if (tlObj.layer === AtemLLayer.AtemMEProgram || tlObj.classes?.includes(ControlClasses.MixMinusOverrideDsk)) { if (!tlObj.id) { tlObj.id = context.core.getHashId(AtemLLayer.AtemMEProgram, true) } @@ -79,8 +74,8 @@ export function postProcessPieceTimelineObjects( aux: { input: tlObj.content.me.input !== -1 - ? tlObj.content.me.input ?? context.config.studio.AtemSource.Default - : context.config.studio.AtemSource.Default + ? tlObj.content.me.input ?? context.config.studio.SwitcherSource.Default + : context.config.studio.SwitcherSource.Default } }, metaData: { @@ -94,7 +89,7 @@ export function postProcessPieceTimelineObjects( // mix minus let mixMinusSource: number | undefined | null // TODO - what about clips? // tslint:disable-next-line:prefer-conditional-expression - if (tlObj.classes?.includes('MIX_MINUS_OVERRIDE_DSK')) { + if (tlObj.classes?.includes(ControlClasses.MixMinusOverrideDsk)) { mixMinusSource = (tlObj as TSR.TimelineObjAtemDSK).content.dsk.sources?.fillSource } else { mixMinusSource = (tlObj as TSR.TimelineObjAtemME).content.me.input @@ -119,7 +114,7 @@ export function postProcessPieceTimelineObjects( ..._.omit(tlObj, 'content'), id: '', layer: AtemLLayer.AtemAuxVideoMixMinus, - priority: tlObj.classes?.includes('MIX_MINUS_OVERRIDE_DSK') ? 10 : tlObj.priority, + priority: tlObj.classes?.includes(ControlClasses.MixMinusOverrideDsk) ? 10 : tlObj.priority, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.AUX, @@ -127,7 +122,7 @@ export function postProcessPieceTimelineObjects( input: mixMinusSource !== undefined && mixMinusSource !== -1 ? mixMinusSource - : context.config.studio.AtemSource.MixMinusDefault + : context.config.studio.SwitcherSource.MixMinusDefault } }, metaData: { @@ -136,7 +131,7 @@ export function postProcessPieceTimelineObjects( } } mixMinusObj.classes = mixMinusObj.classes?.filter( - c => !c.match(`studio0_parent_`) && !c.match('PLACEHOLDER_OBJECT_REMOVEME') + c => !c.match(`studio0_parent_`) && !c.match(ControlClasses.Placeholder) ) extraObjs.push(mixMinusObj) } @@ -182,7 +177,7 @@ export function postProcessPieceTimelineObjects( piece.content.timelineObjects = piece.content.timelineObjects.concat(extraObjs) piece.content.timelineObjects = piece.content.timelineObjects.filter( - (obj: TSR.TSRTimelineObjBase) => !obj.classes?.includes('PLACEHOLDER_OBJECT_REMOVEME') + (obj: TSR.TSRTimelineObjBase) => !obj.classes?.includes(ControlClasses.Placeholder) ) } } diff --git a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts index 10c15107..ae888902 100644 --- a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts @@ -40,7 +40,7 @@ const blankStudioConfig: StudioConfig = { StudioMics: [], ABPlaybackDebugLogging: false, - AtemSource: { + SwitcherSource: { DSK: defaultDSKConfig, SplitArtF: 0, SplitArtK: 0, @@ -56,6 +56,9 @@ const blankStudioConfig: StudioConfig = { Playing: true } }, + TriCasterSettings: { + DveMixEffect: 1 + }, AudioBedSettings: { fadeIn: 0, fadeOut: 0, diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index 40028ab7..3f42f4fd 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -32,70 +32,70 @@ export const manifestAFVDSourcesCam = MakeConfigForSources('Cam', 'Camera', fals { _id: '', SourceName: '1', - AtemSource: 11, + SwitcherSource: 11, SisyfosLayers: [], StudioMics: true }, { _id: '', SourceName: '2', - AtemSource: 12, + SwitcherSource: 12, SisyfosLayers: [], StudioMics: true }, { _id: '', SourceName: '3', - AtemSource: 13, + SwitcherSource: 13, SisyfosLayers: [], StudioMics: true }, { _id: '', SourceName: '4', - AtemSource: 14, + SwitcherSource: 14, SisyfosLayers: [], StudioMics: true }, { _id: '', SourceName: '5', - AtemSource: 15, + SwitcherSource: 15, SisyfosLayers: [], StudioMics: true }, { _id: '', SourceName: '1S', - AtemSource: 16, + SwitcherSource: 16, SisyfosLayers: [], StudioMics: true }, { _id: '', SourceName: '2S', - AtemSource: 17, + SwitcherSource: 17, SisyfosLayers: [], StudioMics: true }, { _id: '', SourceName: '3S', - AtemSource: 18, + SwitcherSource: 18, SisyfosLayers: [], StudioMics: true }, { _id: '', SourceName: '4S', - AtemSource: 19, + SwitcherSource: 19, SisyfosLayers: [], StudioMics: true }, { _id: '', SourceName: '5S', - AtemSource: 20, + SwitcherSource: 20, SisyfosLayers: [], StudioMics: true } @@ -105,7 +105,7 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, tr { _id: '', SourceName: '1', - AtemSource: 1, + SwitcherSource: 1, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_1], StudioMics: true, WantsToPersistAudio: true, @@ -114,7 +114,7 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, tr { _id: '', SourceName: '2', - AtemSource: 2, + SwitcherSource: 2, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_2], StudioMics: false, WantsToPersistAudio: true, @@ -123,7 +123,7 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, tr { _id: '', SourceName: '3', - AtemSource: 3, + SwitcherSource: 3, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_3], StudioMics: false, WantsToPersistAudio: true, @@ -132,7 +132,7 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, tr { _id: '', SourceName: '4', - AtemSource: 4, + SwitcherSource: 4, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_4], StudioMics: false, WantsToPersistAudio: true, @@ -141,7 +141,7 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, tr { _id: '', SourceName: '5', - AtemSource: 5, + SwitcherSource: 5, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_5], StudioMics: false, WantsToPersistAudio: true, @@ -150,7 +150,7 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, tr { _id: '', SourceName: '6', - AtemSource: 6, + SwitcherSource: 6, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_6], StudioMics: false, WantsToPersistAudio: true, @@ -159,7 +159,7 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, tr { _id: '', SourceName: '7', - AtemSource: 7, + SwitcherSource: 7, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_7], StudioMics: false, WantsToPersistAudio: true, @@ -168,7 +168,7 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, tr { _id: '', SourceName: '8', - AtemSource: 8, + SwitcherSource: 8, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_8], StudioMics: false, WantsToPersistAudio: true, @@ -177,7 +177,7 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, tr { _id: '', SourceName: '9', - AtemSource: 9, + SwitcherSource: 9, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_9], StudioMics: false, WantsToPersistAudio: true, @@ -186,7 +186,7 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, tr { _id: '', SourceName: '10', - AtemSource: 10, + SwitcherSource: 10, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_10], StudioMics: false, WantsToPersistAudio: true, @@ -200,21 +200,21 @@ export const manifestAFVDSourcesReplay = MakeConfigForSources('Replay', 'Replay' { _id: '', SourceName: '1', - AtemSource: 22, + SwitcherSource: 22, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceEVS_1], StudioMics: true }, { _id: '', SourceName: '2', - AtemSource: 23, + SwitcherSource: 23, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceEVS_2], StudioMics: true }, { _id: '', SourceName: 'EPSIO', - AtemSource: 25, + SwitcherSource: 25, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceEpsio], StudioMics: true } @@ -230,12 +230,12 @@ export const manifestAFVDSourcesABMediaPlayers: ConfigManifestEntryTable = { { _id: '', SourceName: '1', - AtemSource: 26 + SwitcherSource: 26 }, { _id: '', SourceName: '2', - AtemSource: 27 + SwitcherSource: 27 } ]), columns: [ @@ -249,9 +249,9 @@ export const manifestAFVDSourcesABMediaPlayers: ConfigManifestEntryTable = { rank: 0 }, { - id: 'AtemSource', - name: 'ATEM input', - description: 'ATEM vision mixer input for Media player', + id: 'SwicherSource', + name: 'Switcher input', + description: 'Video Switcher input for Media player', type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, @@ -306,49 +306,49 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ defaultVal: false }, { - id: 'AtemSource.SplitArtF', - name: 'ATEM Split Screen Art Fill', - description: 'ATEM vision mixer input for Split Screen Art Fill', + id: 'SwitcherSource.SplitArtF', + name: 'Switcher Split Screen Art Fill', + description: 'Video Switcher input for Split Screen Art Fill', type: ConfigManifestEntryType.INT, required: true, defaultVal: 30 }, { - id: 'AtemSource.SplitArtK', - name: 'ATEM Split Screen Art Key', - description: 'ATEM vision mixer input for Split Screen Art Key', + id: 'SwitcherSource.SplitArtK', + name: 'Switcher Split Screen Art Key', + description: 'Video Switcher input for Split Screen Art Key', type: ConfigManifestEntryType.INT, required: true, defaultVal: 32 }, { - id: 'AtemSource.Default', - name: 'ATEM Default source', - description: 'ATEM vision mixer default source', + id: 'SwitcherSource.Default', + name: 'Switcher Default source', + description: 'Video Switcher default source', type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col1 }, { - id: 'AtemSource.MixMinusDefault', - name: 'ATEM Mix-minus default source', - description: 'ATEM vision mixer default source for mix-minus', + id: 'SwitcherSource.MixMinusDefault', + name: 'Switcher Mix-minus default source', + description: 'Video Switcher default source for mix-minus', type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col1 }, { - id: 'AtemSource.Continuity', - name: 'ATEM continuity source', - description: 'ATEM input for continuity', + id: 'SwitcherSource.Continuity', + name: 'Switcher continuity source', + description: 'Video Switcher input for continuity', type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col2 }, { - id: 'AtemSource.Dip', - name: 'ATEM Dip Source', - description: 'ATEM input for the Dip - should match the desired input in the ATEM', + id: 'SwitcherSource.Dip', + name: 'Switcher Dip Source', + description: 'Video Switcher source for the Dip - should match the desired input in the Video Switcher', type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col2 @@ -377,6 +377,14 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ required: false, defaultVal: true }, + { + id: 'TriCasterSettings.DveMixEffect', + name: 'TriCaster DVE MixEffect', + description: 'TriCaster MixEffect used to make DVEs', + type: ConfigManifestEntryType.BOOLEAN, + required: false, + defaultVal: true + }, { id: 'AudioBedSettings.fadeIn', name: 'Bed Fade In', diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index eea0a78a..336fc246 100644 --- a/src/tv2_afvd_studio/helpers/config.ts +++ b/src/tv2_afvd_studio/helpers/config.ts @@ -25,7 +25,7 @@ export interface StudioConfig extends TV2StudioConfigBase { ABMediaPlayers: TableConfigItemSourceMapping[] ABPlaybackDebugLogging: boolean StudioMics: string[] - AtemSource: { + SwitcherSource: { SplitArtF: number // Atem MP1 Fill SplitArtK: number // Atem MP1 Key DSK: TableConfigItemDSK[] @@ -51,7 +51,7 @@ export function preprocessConfig(_context: ICommonContext, rawConfig: IBlueprint studio: studioConfig, sources: parseSources(studioConfig), mediaPlayers: parseMediaPlayers(studioConfig), - dsk: studioConfig.AtemSource.DSK + dsk: studioConfig.SwitcherSource.DSK } return config diff --git a/src/tv2_afvd_studio/helpers/sources.ts b/src/tv2_afvd_studio/helpers/sources.ts index 2642894e..956fb140 100644 --- a/src/tv2_afvd_studio/helpers/sources.ts +++ b/src/tv2_afvd_studio/helpers/sources.ts @@ -7,7 +7,7 @@ import { StudioConfig } from './config' export function parseMediaPlayers(studioConfig: StudioConfig): Array<{ id: string; val: string }> { return studioConfig.ABMediaPlayers.map(player => ({ id: player.SourceName, - val: player.AtemSource.toString() + val: player.SwitcherSource.toString() })) } diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index 0428d9fd..51e90f5c 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -187,7 +187,7 @@ export const studioMigrations: MigrationStepStudio[] = [ RenameStudioConfig('1.7.4', 'AFVD', 'SourcesDelayedPlayback', 'SourcesReplay'), addSourceToSourcesConfig('1.7.4', 'AFVD', 'SourcesReplay', { SourceName: 'EPSIO', - AtemSource: 25, + SwitcherSource: 25, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceEpsio], StudioMics: true }), diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index a9667da2..12e9d496 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -588,7 +588,7 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche layer: OfftubeAtemLLayer.AtemMEClean, enable: { while: '1' }, content: { - input: config.studio.AtemSource.Default, + input: config.studio.SwitcherSource.Default, transition: TransitionStyle.CUT } }), @@ -596,7 +596,7 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche enable: { while: '1' }, layer: OfftubeAtemLLayer.AtemMENext, content: { - previewInput: config.studio.AtemSource.Default + previewInput: config.studio.SwitcherSource.Default } }), @@ -623,7 +623,7 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.AUX, aux: { - input: config.studio.AtemSource.Loop + input: config.studio.SwitcherSource.Loop } } }), @@ -651,8 +651,8 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRCPROPS, ssrcProps: { - artFillSource: config.studio.AtemSource.SplitArtF, - artCutSource: config.studio.AtemSource.SplitArtK, + artFillSource: config.studio.SwitcherSource.SplitArtF, + artCutSource: config.studio.SwitcherSource.SplitArtK, artOption: 1, // foreground artPreMultiplied: true } @@ -671,7 +671,7 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche { // left enabled: true, - source: config.studio.AtemSource.SplitBackground, + source: config.studio.SwitcherSource.SplitBackground, size: 1000, x: 0, y: 0, diff --git a/src/tv2_offtube_showstyle/getSegment.ts b/src/tv2_offtube_showstyle/getSegment.ts index a934ebe8..a633a0d5 100644 --- a/src/tv2_offtube_showstyle/getSegment.ts +++ b/src/tv2_offtube_showstyle/getSegment.ts @@ -5,7 +5,6 @@ import { IngestSegment, ISegmentUserContext, PieceLifespan, - TSR, WithTimeline } from 'blueprints-integration' import { @@ -79,13 +78,13 @@ function CreatePartContinuity( lifespan: PieceLifespan.WithinPart, content: literal>({ studioLabel: '', - switcherInput: context.config.studio.AtemSource.Continuity, + switcherInput: context.config.studio.SwitcherSource.Continuity, timelineObjects: [ context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, layer: OfftubeAtemLLayer.AtemMEClean, content: { - input: context.config.studio.AtemSource.Continuity, + input: context.config.studio.SwitcherSource.Continuity, transition: TransitionStyle.CUT } }) diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index 96e4f82a..8fe8af6c 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -5,8 +5,6 @@ import { IBlueprintAdLibPiece, IBlueprintPiece, PieceLifespan, - TimelineObjectCoreExt, - TSR, VTContent, WithTimeline } from 'blueprints-integration' @@ -83,7 +81,7 @@ export async function OfftubeCreatePartKam( if (sourceInfoCam === undefined) { return CreatePartInvalid(partDefinition) } - const atemInput = sourceInfoCam.port + const switcherInput = sourceInfoCam.port part = { ...part, ...CreateEffektForpart(context, partDefinition, pieces) } @@ -103,7 +101,7 @@ export async function OfftubeCreatePartKam( tags: [GetTagForKam(partDefinition.sourceDefinition)], content: { studioLabel: '', - switcherInput: atemInput, + switcherInput, timelineObjects: [ context.videoSwitcher.getMixEffectTimelineObject({ id: ``, @@ -113,7 +111,7 @@ export async function OfftubeCreatePartKam( priority: 1, layer: OfftubeAtemLLayer.AtemMEClean, content: { - input: Number(atemInput), + input: Number(switcherInput), transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration } diff --git a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts b/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts index 51b0e3b4..5d12b955 100644 --- a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts @@ -40,7 +40,7 @@ export function postProcessPieceTimelineObjects( (obj.content.type === TSR.TimelineContentTypeAtem.ME || obj.content.type === TSR.TimelineContentTypeAtem.DSK) ) _.each(atemMeObjs, tlObj => { - if (tlObj.layer === OfftubeAtemLLayer.AtemMEClean || tlObj.classes?.includes('MIX_MINUS_OVERRIDE_DSK')) { + if (tlObj.layer === OfftubeAtemLLayer.AtemMEClean || tlObj.classes?.includes(ControlClasses.MixMinusOverrideDsk)) { if (!tlObj.id) { tlObj.id = context.core.getHashId(OfftubeAtemLLayer.AtemMEClean, true) } @@ -51,8 +51,7 @@ export function postProcessPieceTimelineObjects( if ( (!isAdlib || piece.toBeQueued) && 'me' in tlObj.content && - (tlObj.content.me.input !== -1 || tlObj.metaData?.mediaPlayerSession !== undefined) && - !tlObj.classes?.includes(ControlClasses.NOLookahead) + (tlObj.content.me.input !== -1 || tlObj.metaData?.mediaPlayerSession !== undefined) ) { if (tlObj.classes?.includes(ControlClasses.AbstractLookahead)) { // Create a lookahead-lookahead object for this me-program @@ -83,7 +82,9 @@ export function postProcessPieceTimelineObjects( type: TSR.TimelineContentTypeAtem.ME, me: { previewInput: - tlObj.content.me.input !== -1 ? tlObj.content.me.input : context.config.studio.AtemSource.Default + tlObj.content.me.input !== -1 + ? tlObj.content.me.input + : context.config.studio.SwitcherSource.Default } }, metaData: { @@ -100,7 +101,7 @@ export function postProcessPieceTimelineObjects( piece.content.timelineObjects = piece.content.timelineObjects.concat(extraObjs) piece.content.timelineObjects = piece.content.timelineObjects.filter( - (obj: TSR.TSRTimelineObjBase) => !obj.classes?.includes('PLACEHOLDER_OBJECT_REMOVEME') + (obj: TSR.TSRTimelineObjBase) => !obj.classes?.includes(ControlClasses.Placeholder) ) } } diff --git a/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts b/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts index 093024ca..0e4b477c 100644 --- a/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts @@ -30,7 +30,7 @@ const blankStudioConfig: OfftubeStudioConfig = { StudioMics: [], ABPlaybackDebugLogging: false, - AtemSource: { + SwitcherSource: { DSK: defaultDSKConfig, SplitArtF: 0, SplitArtK: 0, @@ -41,6 +41,7 @@ const blankStudioConfig: OfftubeStudioConfig = { Dip: 0 }, AtemSettings: {}, + TriCasterSettings: {}, AudioBedSettings: { fadeIn: 0, fadeOut: 0, diff --git a/src/tv2_offtube_studio/config-manifests.ts b/src/tv2_offtube_studio/config-manifests.ts index eb2c0652..cb7eacd8 100644 --- a/src/tv2_offtube_studio/config-manifests.ts +++ b/src/tv2_offtube_studio/config-manifests.ts @@ -29,7 +29,7 @@ export const manifestOfftubeSourcesCam = MakeConfigForSources('Cam', 'Cameras', { _id: '', SourceName: '1', - AtemSource: 4, + SwitcherSource: 4, SisyfosLayers: [], StudioMics: true } @@ -39,7 +39,7 @@ export const manifestOfftubeSourcesRM = MakeConfigForSources('RM', 'Live', true, { _id: '', SourceName: '1', - AtemSource: 3, + SwitcherSource: 3, SisyfosLayers: [OfftubeSisyfosLLayer.SisyfosSourceLive_3], StudioMics: true, WantsToPersistAudio: true, @@ -51,7 +51,7 @@ export const manifestOfftubeSourcesFeed = MakeConfigForSources('Feed', 'Feed', t { _id: '', SourceName: '1', - AtemSource: 1, + SwitcherSource: 1, SisyfosLayers: [OfftubeSisyfosLLayer.SisyfosSourceLive_1_Stereo, OfftubeSisyfosLLayer.SisyfosSourceLive_1_Surround], StudioMics: true, WantsToPersistAudio: false @@ -59,7 +59,7 @@ export const manifestOfftubeSourcesFeed = MakeConfigForSources('Feed', 'Feed', t { _id: '', SourceName: '2', - AtemSource: 2, + SwitcherSource: 2, SisyfosLayers: [OfftubeSisyfosLLayer.SisyfosSourceLive_2_Stereo], StudioMics: true, WantsToPersistAudio: false @@ -69,19 +69,19 @@ export const manifestOfftubeSourcesFeed = MakeConfigForSources('Feed', 'Feed', t export const manifestOfftubeSourcesABMediaPlayers: ConfigManifestEntryTable = { id: 'ABMediaPlayers', name: 'Media Players inputs', - description: 'ATEM inputs for A/B media players', + description: 'Switcher inputs for A/B media players', type: ConfigManifestEntryType.TABLE, required: false, defaultVal: literal>([ { _id: '', SourceName: '1', - AtemSource: 5 + SwitcherSource: 5 }, { _id: '', SourceName: '2', - AtemSource: 6 + SwitcherSource: 6 } ]), columns: [ @@ -95,9 +95,9 @@ export const manifestOfftubeSourcesABMediaPlayers: ConfigManifestEntryTable = { rank: 0 }, { - id: 'AtemSource', - name: 'ATEM input', - description: 'ATEM vision mixer input for Media player', + id: 'SwitcherSource', + name: 'Switcher input', + description: 'Video Switcher input for Media player', type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, @@ -151,57 +151,57 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ defaultVal: false }, { - id: 'AtemSource.SplitArtF', - name: 'ATEM Split Screen Art Fill', - description: 'ATEM vision mixer input for Split Screen Art Fill', + id: 'SwitcherSource.SplitArtF', + name: 'Switcher Split Screen Art Fill', + description: 'Video Switcher input for Split Screen Art Fill', type: ConfigManifestEntryType.INT, required: true, defaultVal: 10 }, { - id: 'AtemSource.SplitArtK', - name: 'ATEM Split Screen Art Key', - description: 'ATEM vision mixer input for Split Screen Art Key', + id: 'SwitcherSource.SplitArtK', + name: 'Switcher Split Screen Art Key', + description: 'Video Switcher input for Split Screen Art Key', type: ConfigManifestEntryType.INT, required: true, defaultVal: 9 }, { - id: 'AtemSource.SplitBackground', - name: 'ATEM split screen background loop source', - description: 'ATEM source for mos full-frame grafik background source', + id: 'SwitcherSource.SplitBackground', + name: 'Switcher split screen background loop source', + description: 'Video Switcher source for mos full-frame grafik background source', type: ConfigManifestEntryType.INT, required: false, defaultVal: 11 }, { - id: 'AtemSource.Loop', + id: 'SwitcherSource.Loop', name: 'Studio screen loop graphics source', - description: 'ATEM source for loop for studio screen', + description: 'Video Switcher source for loop for studio screen', type: ConfigManifestEntryType.INT, required: false, defaultVal: 12 }, { - id: 'AtemSource.Default', - name: 'ATEM Default source', - description: 'ATEM vision mixer default source', + id: 'SwitcherSource.Default', + name: 'Switcher Default source', + description: 'Video Switcher default source', type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col1 }, { - id: 'AtemSource.Continuity', - name: 'ATEM continuity source', - description: 'ATEM input for continuity', + id: 'SwitcherSource.Continuity', + name: 'Switcher continuity source', + description: 'Video Switcher input for continuity', type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col2 }, { - id: 'AtemSource.Dip', - name: 'ATEM Dip Source', - description: 'ATEM input for the Dip - should match the desired input in the ATEM', + id: 'SwitcherSource.Dip', + name: 'Switcher Dip Source', + description: 'Video Switcher source for the Dip - should match the desired input in the Video Switcher', type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col2 diff --git a/src/tv2_offtube_studio/helpers/config.ts b/src/tv2_offtube_studio/helpers/config.ts index 56daf083..24c238e8 100644 --- a/src/tv2_offtube_studio/helpers/config.ts +++ b/src/tv2_offtube_studio/helpers/config.ts @@ -23,9 +23,9 @@ export interface OfftubeStudioConfig extends TV2StudioConfigBase { ABMediaPlayers: TableConfigItemSourceMapping[] ABPlaybackDebugLogging: boolean - AtemSource: { - SplitArtF: number // Atem MP1 Fill - SplitArtK: number // Atem MP1 Key + SwitcherSource: { + SplitArtF: number + SplitArtK: number SplitBackground: number Loop: number DSK: TableConfigItemDSK[] @@ -36,6 +36,7 @@ export interface OfftubeStudioConfig extends TV2StudioConfigBase { } AtemSettings: {} + TriCasterSettings: {} AudioBedSettings: { fadeIn: number @@ -55,7 +56,7 @@ export function preprocessConfig(_context: ICommonContext, rawConfig: IBlueprint // showStyle: {} as any, sources: parseSources(studioConfig), mediaPlayers: parseMediaPlayers(studioConfig), - dsk: studioConfig.AtemSource.DSK + dsk: studioConfig.SwitcherSource.DSK } return config } diff --git a/src/tv2_offtube_studio/helpers/sources.ts b/src/tv2_offtube_studio/helpers/sources.ts index 4f2875cb..774dd7d0 100644 --- a/src/tv2_offtube_studio/helpers/sources.ts +++ b/src/tv2_offtube_studio/helpers/sources.ts @@ -5,7 +5,7 @@ import { ParseMappingTable, SourceInfoType, SourceMapping } from 'tv2-common' import { OfftubeStudioConfig } from './config' export function parseMediaPlayers(studioConfig: OfftubeStudioConfig): Array<{ id: string; val: string }> { - return studioConfig.ABMediaPlayers.map(player => ({ id: player.SourceName, val: player.AtemSource.toString() })) + return studioConfig.ABMediaPlayers.map(player => ({ id: player.SourceName, val: player.SwitcherSource.toString() })) } export function parseSources(studioConfig: OfftubeStudioConfig): SourceMapping { From 6850f05ca385d81cbb5d66bd7a211884d21df810 Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 2 Feb 2023 16:26:55 +0100 Subject: [PATCH 13/86] wip: SOF-1260 tearing down configs --- src/tv2-common/actions/context.ts | 9 +- src/tv2-common/actions/executeAction.ts | 27 ++--- src/tv2-common/content/dve.ts | 28 +---- src/tv2-common/content/jingle.ts | 14 +-- src/tv2-common/content/server.ts | 21 ++-- src/tv2-common/index.ts | 1 + src/tv2-common/parts/server.ts | 32 ++--- src/tv2-common/segment/context.ts | 6 +- src/tv2-common/showstyle/context.ts | 5 +- .../showstyle/timelineEventContext.ts | 5 +- src/tv2-common/studio/context.ts | 4 +- src/tv2-common/uniformConfig.ts | 15 +++ .../videoSwitchers/VideoSwitcher.ts | 9 +- src/tv2-common/videoSwitchers/types.ts | 6 + src/tv2-constants/enums.ts | 34 ++++-- src/tv2_afvd_showstyle/actions.ts | 11 +- src/tv2_afvd_showstyle/getRundown.ts | 3 +- src/tv2_afvd_showstyle/getSegment.ts | 3 +- src/tv2_afvd_showstyle/helpers/content/dve.ts | 1 - .../helpers/pieces/adlib.ts | 4 - .../helpers/pieces/jingle.ts | 3 - src/tv2_afvd_showstyle/parts/server.ts | 6 +- .../postProcessTimelineObjects.ts | 2 - src/tv2_afvd_studio/layers.ts | 6 - .../migrations/mappings-defaults.ts | 113 ++++++++++++------ src/tv2_afvd_studio/uniformConfig.ts | 8 ++ src/tv2_offtube_showstyle/actions.ts | 12 +- .../content/OfftubeDVEContent.ts | 8 -- .../cues/OfftubeAdlib.ts | 6 - .../cues/OfftubeJingle.ts | 3 - src/tv2_offtube_showstyle/getRundown.ts | 3 +- src/tv2_offtube_showstyle/getSegment.ts | 6 +- .../onTimelineGenerate.ts | 3 +- .../parts/OfftubeServer.ts | 14 --- src/tv2_offtube_studio/layers.ts | 4 - .../migrations/mappings-defaults.ts | 32 ----- src/tv2_offtube_studio/uniformConfig.ts | 9 ++ 37 files changed, 216 insertions(+), 260 deletions(-) create mode 100644 src/tv2-common/uniformConfig.ts create mode 100644 src/tv2_afvd_studio/uniformConfig.ts create mode 100644 src/tv2_offtube_studio/uniformConfig.ts diff --git a/src/tv2-common/actions/context.ts b/src/tv2-common/actions/context.ts index e0309c98..8ae60032 100644 --- a/src/tv2-common/actions/context.ts +++ b/src/tv2-common/actions/context.ts @@ -8,7 +8,7 @@ import { IBlueprintPieceInstance, IBlueprintResolvedPieceInstance } from 'blueprints-integration' -import { ExtendedShowStyleContextImpl, PieceMetaData, TV2ShowStyleConfig } from 'tv2-common' +import { ExtendedShowStyleContextImpl, PieceMetaData, TV2ShowStyleConfig, UniformConfig } from 'tv2-common' import { CoreActionExecutionContext } from './CoreActionExecutionContext' export interface ITV2ActionExecutionContext extends IActionExecutionContext { @@ -50,18 +50,19 @@ export interface ITV2ActionExecutionContext extends IActionExecutionContext { export class ExtendedActionExecutionContext< BlueprintConfig extends TV2ShowStyleConfig = TV2ShowStyleConfig > extends ExtendedShowStyleContextImpl { - constructor(readonly core: CoreActionExecutionContext) { - super(core) + constructor(readonly core: CoreActionExecutionContext, uniformConfig: UniformConfig) { + super(core, uniformConfig) this.core = core } } export async function executeWithContext( coreContext: IActionExecutionContext, + uniformConfig: UniformConfig, func: (context: ExtendedActionExecutionContext) => Promise ): Promise { const coreContextWrapped = new CoreActionExecutionContext(coreContext) - const context = new ExtendedActionExecutionContext(coreContextWrapped) + const context = new ExtendedActionExecutionContext(coreContextWrapped, uniformConfig) await func(context) await coreContextWrapped.afterActions() } diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 5a5b419a..b3030d27 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -58,7 +58,8 @@ import { TransitionStyle, TV2AdlibAction, TV2BlueprintConfigBase, - TV2StudioConfigBase + TV2StudioConfigBase, + UniformConfig } from 'tv2-common' import { AdlibActionType, @@ -146,14 +147,6 @@ export interface ActionExecutionSettings< Effekt: string StudioMics: string } - Atem: { - MEProgram: string - MEClean: string - Next: string - ServerLookaheadAUX?: string - SSrcDefault: string - cutOnclean: boolean - } } SelectedAdlibs: { SourceLayer: { @@ -188,12 +181,13 @@ export async function executeAction< ShowStyleConfig extends TV2BlueprintConfigBase >( coreContext: IActionExecutionContext, + uniformConfig: UniformConfig, settings: ActionExecutionSettings, actionIdStr: string, userData: ActionUserData, triggerMode?: string ): Promise { - await executeWithContext(coreContext, async context => { + await executeWithContext(coreContext, uniformConfig, async context => { const existingTransition = await getExistingTransition(context, settings, 'next') const actionId = actionIdStr as AdlibActionType @@ -439,19 +433,12 @@ async function executeActionSelectServerClip< ? settings.SelectedAdlibs.SourceLayer.VO : settings.SelectedAdlibs.SourceLayer.Server }, - AtemLLayer: { - MEPgm: settings.LLayer.Atem.cutOnclean ? settings.LLayer.Atem.MEClean : settings.LLayer.Atem.MEProgram, - ServerLookaheadAux: settings.LLayer.Atem.ServerLookaheadAUX - }, Caspar: { ClipPending: settings.LLayer.Caspar.ClipPending }, Sisyfos: { ClipPending: settings.LLayer.Sisyfos.ClipPending }, - ATEM: { - ServerLookaheadAux: settings.LLayer.Atem.ServerLookaheadAUX - } } ) @@ -677,7 +664,7 @@ async function cutServerToBox< // Find SSRC object in DVE piece const ssrcObjIndex = newDvePiece.content?.timelineObjects ? (newDvePiece.content?.timelineObjects as TSR.TSRTimelineObj[]).findIndex( - obj => obj.layer === settings.LLayer.Atem.SSrcDefault + obj => obj.layer === settings.LLayer.VideoSwitcher.Dve ) : -1 @@ -1090,7 +1077,7 @@ async function executeActionCutToCamera< timelineObjects: _.compact([ context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, - layer: settings.LLayer.Atem.cutOnclean ? settings.LLayer.Atem.MEClean : settings.LLayer.Atem.MEProgram, + layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: sourceInfoCam.port, transition: TransitionStyle.CUT @@ -1226,7 +1213,7 @@ async function executeActionCutToRemote< id: '', enable: { while: '1' }, priority: 1, - layer: settings.LLayer.Atem.cutOnclean ? settings.LLayer.Atem.MEClean : settings.LLayer.Atem.MEProgram, + layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: sourceInfo.port, transition: TransitionStyle.CUT diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 9ce9e0df..1b612f07 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -11,7 +11,6 @@ import { WithTimeline } from 'blueprints-integration' import { - createEmptyObject, CueDefinitionDVE, DVEConfigInput, DVESources, @@ -27,7 +26,7 @@ import { TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' -import { ControlClasses, MEDIA_PLAYER_AUTO, SharedGraphicLLayer, SourceType } from 'tv2-constants' +import { MEDIA_PLAYER_AUTO, SharedGraphicLLayer, SourceType } from 'tv2-constants' import * as _ from 'underscore' import { AtemSourceIndex } from '../../types/atem' import { ActionSelectDVE } from '../actions' @@ -118,7 +117,6 @@ export interface DVEPieceMetaData extends PieceMetaData { export interface DVEOptions { dveLayers: DVELayers - boxMappings: [string, string, string, string] /** All audio layers */ AUDIO_LAYERS: string[] } @@ -191,9 +189,7 @@ export function MakeContentDVE2< ? dveConfig.DVEInputs.toString().split(';') : '1:INP1;2:INP2;3:INP3;4:INP4'.split(';') - const classes: string[] = [] - - const boxAssigments = makeBoxAssignments(inputs, context.core, classes, dveGeneratorOptions, sources) + const boxAssigments = makeBoxAssignments(inputs, context.core, sources) const boxes: BoxConfig[] = Object.entries(template.boxes).map(([_num, box]) => ({ ...box, @@ -203,7 +199,7 @@ export function MakeContentDVE2< const boxSources: BoxSources = [] let valid = true - let server = false + let hasServer = false boxAssigments.forEach((mappingFrom, num) => { const box = boxes[num] @@ -277,7 +273,7 @@ export function MakeContentDVE2< } break case SourceType.SERVER: - server = true + hasServer = true setBoxSource(box, boxSources, { sourceLayerType: SourceLayerType.VT, port: -1 @@ -312,13 +308,6 @@ export function MakeContentDVE2< content: literal>({ boxSourceConfiguration: boxSources, timelineObjects: _.compact([ - // Setup classes for adlibs to be able to override boxes - createEmptyObject({ - enable: getDVEEnable(), - layer: 'dve_lookahead_control', - classes: [ControlClasses.DVEOnAir] - }), - // setup ssrc literal({ id: '', @@ -332,9 +321,8 @@ export function MakeContentDVE2< type: TSR.TimelineContentTypeAtem.SSRC, ssrc: { boxes } }, - classes, metaData: literal({ - mediaPlayerSession: server ? mediaPlayerSessionId ?? MEDIA_PLAYER_AUTO : undefined + mediaPlayerSession: hasServer ? mediaPlayerSessionId ?? MEDIA_PLAYER_AUTO : undefined }) }), literal({ @@ -420,7 +408,7 @@ export function MakeContentDVE2< }) ] : []), - ...(server && mediaPlayerSessionId ? [EnableServer(mediaPlayerSessionId)] : []), + ...(hasServer && mediaPlayerSessionId ? [EnableServer(mediaPlayerSessionId)] : []), ...dveTimeline ]) }) @@ -456,8 +444,6 @@ const setBoxToBlack = (boxConfig: BoxConfig, boxSources: BoxSources) => { function makeBoxAssignments( inputs: string[], context: IShowStyleUserContext, - classes: string[], - dveGeneratorOptions: DVEOptions, sources: DVESources | undefined ) { const boxAssignments: Array = [] @@ -470,8 +456,6 @@ function makeBoxAssignments( return } - classes.push(`${fromCue.replace(/\s/g, '')}_${dveGeneratorOptions.boxMappings[targetBox - 1]}`) - if (!sources) { // Need something to keep the layout etc boxAssignments[targetBox - 1] = undefined diff --git a/src/tv2-common/content/jingle.ts b/src/tv2-common/content/jingle.ts index 19e62440..97e37963 100644 --- a/src/tv2-common/content/jingle.ts +++ b/src/tv2-common/content/jingle.ts @@ -9,10 +9,6 @@ export interface JingleLayers { PlayerJingle: string PlayerJinglePreload?: string } - ATEM: { - USKCleanEffekt?: string - USKJinglePreview?: string - } Sisyfos: { PlayerJingle: string } @@ -69,7 +65,7 @@ export function CreateJingleContentBase< ...EnableDSK(context, 'JINGLE', { start: Number(config.studio.CasparPrerollDuration) }), // @todo: this is a Qbox-only feature, should be refactored at some point not to use ATEM object directly - ...(layers.ATEM.USKJinglePreview + ...(context.uniformConfig.SwitcherLLayers.JingleNextMixEffect ? [ literal({ id: '', @@ -78,7 +74,7 @@ export function CreateJingleContentBase< duration: 1 }, priority: 1, - layer: layers.ATEM.USKJinglePreview, + layer: context.uniformConfig.SwitcherLLayers.JingleNextMixEffect, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.ME, @@ -112,7 +108,7 @@ export function CreateJingleContentBase< start: 1 }, priority: 1, - layer: layers.ATEM.USKJinglePreview, + layer: context.uniformConfig.SwitcherLLayers.JingleNextMixEffect, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.ME, @@ -122,14 +118,14 @@ export function CreateJingleContentBase< ] : []), - ...(layers.ATEM.USKCleanEffekt + ...(context.uniformConfig.SwitcherLLayers.JingleUskMixEffect ? [ context.videoSwitcher.getMixEffectTimelineObject({ enable: { start: Number(config.studio.CasparPrerollDuration) }, priority: 1, - layer: layers.ATEM.USKCleanEffekt, + layer: context.uniformConfig.SwitcherLLayers.JingleUskMixEffect, content: { keyers: [ { diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 0efba2e6..2011aad5 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -21,9 +21,6 @@ export interface MakeContentServerSourceLayers { Sisyfos: { ClipPending: string } - ATEM: { - ServerLookaheadAux?: string - } } type VTProps = Pick< @@ -52,21 +49,20 @@ export function GetVTContentProperties( } export function MakeContentServer( - _context: IShowStyleUserContext, - config: TV2ShowStyleConfig, + context: ExtendedShowStyleContext, sourceLayers: MakeContentServerSourceLayers, partProps: ServerPartProps, contentProps: ServerContentProps ): WithTimeline { return literal>({ - ...GetVTContentProperties(config, contentProps), + ...GetVTContentProperties(context.config, contentProps), ignoreMediaObjectStatus: true, - timelineObjects: GetServerTimeline(config, sourceLayers, partProps, contentProps) + timelineObjects: GetServerTimeline(context, sourceLayers, partProps, contentProps) }) } function GetServerTimeline( - config: TV2ShowStyleConfig, + context: ExtendedShowStyleContext, sourceLayers: MakeContentServerSourceLayers, partProps: ServerPartProps, contentProps: ServerContentProps @@ -107,13 +103,13 @@ function GetServerTimeline( mediaObj, mediaOffObj, ...GetSisyfosTimelineObjForServer( - config, + context.config, partProps.voLevels, sourceLayers.Sisyfos.ClipPending, contentProps.mediaPlayerSession, audioEnable ), - ...(sourceLayers.ATEM.ServerLookaheadAux + ...(context.uniformConfig.SwitcherLLayers.ServerLookaheadAux ? [ literal({ id: '', @@ -121,7 +117,7 @@ function GetServerTimeline( start: 0 }, priority: 0, - layer: sourceLayers.ATEM.ServerLookaheadAux, + layer: context.uniformConfig.SwitcherLLayers.ServerLookaheadAux, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.AUX, @@ -142,7 +138,6 @@ export function CutToServer( context: ExtendedShowStyleContext, mediaPlayerSessionId: string, partDefinition: PartDefinition, - atemLLayerMEPGM: string, offtubeOptions?: AdlibServerOfftubeOptions ): TimelineBlueprintExt[] { return [ @@ -152,7 +147,7 @@ export function CutToServer( start: context.config.studio.CasparPrerollDuration }, priority: 1, - layer: atemLLayerMEPGM, + layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: -1, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, diff --git a/src/tv2-common/index.ts b/src/tv2-common/index.ts index 9f998876..1b7cef76 100644 --- a/src/tv2-common/index.ts +++ b/src/tv2-common/index.ts @@ -26,4 +26,5 @@ export * from './types' export * from './updatePolicies' export * from './util' export * from './segment/context' +export * from './uniformConfig' export * from './videoSwitchers' diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index b47aaaed..ff429070 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -2,7 +2,6 @@ import { BlueprintResultPart, IBlueprintPart, IBlueprintPiece, - IShowStyleUserContext, PieceLifespan, VTContent, WithTimeline @@ -53,10 +52,6 @@ export type ServerPartLayers = { PgmServer: string SelectedServer: string } - AtemLLayer: { - MEPgm: string - ServerLookaheadAux?: string - } } & MakeContentServerSourceLayers export async function CreatePartServerBase< @@ -95,13 +90,12 @@ export async function CreatePartServerBase< const pieces: Array> = [] const serverSelectionBlueprintPiece = getServerSelectionBlueprintPiece( + context, partDefinition, actualDuration, partProps, contentProps, layers, - context.core, - context.config, context.config.studio.CasparPrerollDuration ) @@ -193,19 +187,14 @@ function getUserData( } } -function getContentServerElement< - StudioConfig extends TV2StudioConfigBase, - ShowStyleConfig extends TV2BlueprintConfigBase ->( +function getContentServerElement( + context: ExtendedShowStyleContext, partProps: ServerPartProps, contentProps: ServerContentProps, layers: ServerPartLayers, - context: IShowStyleUserContext, - config: ShowStyleConfig ): WithTimeline { return MakeContentServer( context, - config, { Caspar: { ClipPending: layers.Caspar.ClipPending @@ -213,30 +202,23 @@ function getContentServerElement< Sisyfos: { ClipPending: layers.Sisyfos.ClipPending }, - ATEM: { - ServerLookaheadAux: layers.ATEM.ServerLookaheadAux - } }, partProps, contentProps ) } -function getServerSelectionBlueprintPiece< - StudioConfig extends TV2StudioConfigBase, - ShowStyleConfig extends TV2BlueprintConfigBase ->( +function getServerSelectionBlueprintPiece( + context: ExtendedShowStyleContext, partDefinition: PartDefinition, actualDuration: number, partProps: ServerPartProps, contentProps: ServerContentProps, layers: ServerPartLayers, - context: IShowStyleUserContext, - config: ShowStyleConfig, prerollDuration: number ): IBlueprintPiece { const userDataElement = getUserData(partDefinition, contentProps.file, actualDuration, partProps) - const contentServerElement = getContentServerElement(partProps, contentProps, layers, context, config) + const contentServerElement = getContentServerElement(context, partProps, contentProps, layers) return { externalId: partDefinition.externalId, @@ -281,7 +263,7 @@ function getPgmBlueprintPiece< }, content: { ...GetVTContentProperties(context.config, contentProps), - timelineObjects: CutToServer(context, contentProps.mediaPlayerSession, partDefinition, layers.AtemLLayer.MEPgm) + timelineObjects: CutToServer(context, contentProps.mediaPlayerSession, partDefinition) }, tags: [ GetTagForServer(partDefinition.segmentExternalId, contentProps.file, partProps.voLayer), diff --git a/src/tv2-common/segment/context.ts b/src/tv2-common/segment/context.ts index 14d702e7..c528ce0b 100644 --- a/src/tv2-common/segment/context.ts +++ b/src/tv2-common/segment/context.ts @@ -1,5 +1,5 @@ import { ISegmentUserContext } from 'blueprints-integration' -import { ExtendedShowStyleContext, ExtendedShowStyleContextImpl, TV2ShowStyleConfig, VideoSwitcher } from 'tv2-common' +import { ExtendedShowStyleContext, ExtendedShowStyleContextImpl, TV2ShowStyleConfig, UniformConfig, VideoSwitcher } from 'tv2-common' export interface ExtendedSegmentContext extends ExtendedShowStyleContext { @@ -11,7 +11,7 @@ export interface ExtendedSegmentContext extends ExtendedShowStyleContextImpl implements ExtendedSegmentContext { - constructor(readonly core: ISegmentUserContext) { - super(core) + constructor(readonly core: ISegmentUserContext, readonly uniformConfig: UniformConfig) { + super(core, uniformConfig) } } diff --git a/src/tv2-common/showstyle/context.ts b/src/tv2-common/showstyle/context.ts index b7a832db..da86e936 100644 --- a/src/tv2-common/showstyle/context.ts +++ b/src/tv2-common/showstyle/context.ts @@ -1,9 +1,10 @@ import { IShowStyleContext, IShowStyleUserContext } from 'blueprints-integration' -import { TV2ShowStyleConfig, VideoSwitcher, VideoSwitcherImpl } from 'tv2-common' +import { TV2ShowStyleConfig, UniformConfig, VideoSwitcher, VideoSwitcherImpl } from 'tv2-common' export interface ExtendedShowStyleContext { readonly core: IShowStyleUserContext readonly config: BlueprintConfig + readonly uniformConfig: UniformConfig readonly videoSwitcher: VideoSwitcher } @@ -14,7 +15,7 @@ export class ExtendedShowStyleContextImpl< public readonly config: BlueprintConfig public readonly videoSwitcher: VideoSwitcher - constructor(readonly core: CoreContext) { + constructor(readonly core: CoreContext, public readonly uniformConfig: UniformConfig) { this.config = this.makeConfig() this.videoSwitcher = VideoSwitcherImpl.getVideoSwitcher(this.config) } diff --git a/src/tv2-common/showstyle/timelineEventContext.ts b/src/tv2-common/showstyle/timelineEventContext.ts index 2da5c1aa..aeda56b0 100644 --- a/src/tv2-common/showstyle/timelineEventContext.ts +++ b/src/tv2-common/showstyle/timelineEventContext.ts @@ -1,11 +1,12 @@ import { ITimelineEventContext } from 'blueprints-integration' import { TV2ShowStyleConfig } from '../blueprintConfig' +import { UniformConfig } from '../uniformConfig' import { ExtendedShowStyleContextImpl } from './context' export class ExtendedTimelineContext< BlueprintConfig extends TV2ShowStyleConfig = TV2ShowStyleConfig > extends ExtendedShowStyleContextImpl { - constructor(readonly core: ITimelineEventContext) { - super(core) + constructor(readonly core: ITimelineEventContext, uniformConfig: UniformConfig) { + super(core, uniformConfig) } } diff --git a/src/tv2-common/studio/context.ts b/src/tv2-common/studio/context.ts index 41e9fff3..9bf27785 100644 --- a/src/tv2-common/studio/context.ts +++ b/src/tv2-common/studio/context.ts @@ -1,12 +1,12 @@ import { IStudioContext } from 'blueprints-integration' -import { VideoSwitcher, VideoSwitcherImpl } from 'tv2-common' +import { UniformConfig, VideoSwitcher, VideoSwitcherImpl } from 'tv2-common' import { TV2StudioConfig } from '../blueprintConfig' export class ExtendedStudioContext { public readonly config: BlueprintConfig public readonly videoSwitcher: VideoSwitcher - constructor(readonly core: IStudioContext) { + constructor(readonly core: IStudioContext, public readonly uniformConfig: UniformConfig) { this.config = this.makeConfig() this.videoSwitcher = VideoSwitcherImpl.getVideoSwitcher(this.config) } diff --git a/src/tv2-common/uniformConfig.ts b/src/tv2-common/uniformConfig.ts new file mode 100644 index 00000000..ac85e977 --- /dev/null +++ b/src/tv2-common/uniformConfig.ts @@ -0,0 +1,15 @@ +import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from "tv2-constants" + +/** This config contains hardcoded values that differ between Gallery and Qbox Blueprints */ +export interface UniformConfig { + SwitcherLLayers: { + /** The layer where cuts and transitions between primary pieces are happening */ + PrimaryMixEffect: SwitcherMixEffectLLayer + /** Optional layer to show the jingles on an USK */ + JingleUskMixEffect?: SwitcherMixEffectLLayer + /** Optional layer to show the jingles lookahead on */ + JingleNextMixEffect?: SwitcherMixEffectLLayer + /** Optional layer to preview servers on Aux */ + ServerLookaheadAux?: SwitcherAuxLLayer + } +} \ No newline at end of file diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts index 9a8826d8..bcc404fe 100644 --- a/src/tv2-common/videoSwitchers/VideoSwitcher.ts +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -1,4 +1,4 @@ -import { TSR } from 'blueprints-integration' +import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' import { Atem, AuxProps, @@ -27,7 +27,12 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { protected constructor(config: TV2StudioConfig) { this.config = config } - + public abstract isDsk(timelineObject: TimelineObjectCoreExt): boolean + public abstract isAux(timelineObject: TimelineObjectCoreExt): boolean + public abstract updateAuxInput(timelineObject: TimelineObjectCoreExt, input: number | SpecialInput): TSR.TSRTimelineObj + public abstract isDve(timelineObject: TimelineObjectCoreExt): boolean + public abstract getDveTimelineObject(properties: AuxProps): TSR.TSRTimelineObj + public abstract updateUnpopulatedDveBoxes(timelineObject: TimelineObjectCoreExt, input: number | SpecialInput): TSR.TSRTimelineObj public abstract getMixEffectTimelineObject(properties: MixEffectProps): TSR.TSRTimelineObj public abstract findMixEffectTimelineObject(timelineObjects: TSR.TSRTimelineObj[]): TSR.TSRTimelineObj | undefined public abstract isVideoSwitcherTimelineObject(timelineObject: TSR.TSRTimelineObj): boolean diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index 37bcbc8b..2091779c 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -1,5 +1,6 @@ import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' import { TableConfigItemDSK, TimelineObjectMetaData } from 'tv2-common' +import { SwitcherMixEffectLLayer } from 'tv2-constants' export enum SwitcherType { ATEM = 'ATEM', @@ -23,6 +24,10 @@ export enum TransitionStyle { // ... } +export enum SwitcherLLayer { + +} + export const TIMELINE_OBJECT_DEFAULTS = { id: '', enable: { start: 0 }, @@ -44,6 +49,7 @@ export interface TimelineObjectProps { type TimelineObjectEnable = TSR.TSRTimelineObj['enable'] export interface MixEffectProps extends TimelineObjectProps { + layer: SwitcherMixEffectLLayer content: { input?: number | SpecialInput previewInput?: number | SpecialInput diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index db531133..7744184f 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -63,11 +63,6 @@ export const enum SourceType { INVALID = 'INVALID' } -export enum Enablers { - OFFTUBE_ENABLE_FULL = 'offtube_enable_full', - OFFTUBE_ENABLE_SERVER_LOOKAHEAD = 'offtube_enable_server_lookahead' -} - export enum AdlibTags { OFFTUBE_ADLIB_SERVER = 'offtube_adlib_server', OFFTUBE_100pc_SERVER = 'offtube_adlib_100pc_server', @@ -118,12 +113,9 @@ export function AdlibTagCutToBox(box: number): AdlibTags { } export enum ControlClasses { - /** Indicates that a DVE is currently on air */ - DVEOnAir = 'dve_on_air', ServerOnAir = 'server_on_air', LYDOnAir = 'lyd_on_air', LiveSourceOnAir = 'live_source_on_air', - CopyMediaPlayerSession = 'copy_media_player_session', AbstractLookahead = 'abstract_lookahead', MixMinusOverrideDsk = 'MIX_MINUS_OVERRIDE_DSK', Placeholder = 'PLACEHOLDER_OBJECT_REMOVEME' @@ -199,8 +191,32 @@ export enum AbstractLLayer { AudioBedBaseline = 'audio_bed_baseline' } +export enum SwitcherMixEffectLLayer { + Program = 'me_program', + Clean = 'me_clean', + CleanUSKEffect = 'clean_usk_effect', +} + +export enum SwitcherAuxLLayer { + AuxPGM = 'aux_pgm', + AuxClean = 'aux_clean', + AuxWall = 'aux_wall', + AuxAR = 'aux_ar', + AuxVizOvlIn1 = 'aux_viz_ovl_in_1', + AuxVenue = 'aux_venue', + AuxLookahead = 'aux_lookahead', + AuxSSrc = 'aux_ssrc', + AuxVideoMixMinus = 'aux_video_mix_minus', + AuxServerLookahead = 'aux_server_lookahead', +} + +export enum SwitcherDveLLayer { + Dve = 'dve', + DveBoxes = 'dve_boxes', +} + export enum SharedATEMLLayer { - AtemAuxVideoMixMinus = 'atem_aux_video_mix_minus' + AtemAuxVideoMixMinus = 'atem_aux_video_mix_minus', } export enum SharedCasparLLayer { diff --git a/src/tv2_afvd_showstyle/actions.ts b/src/tv2_afvd_showstyle/actions.ts index 81138715..b5cc81fe 100644 --- a/src/tv2_afvd_showstyle/actions.ts +++ b/src/tv2_afvd_showstyle/actions.ts @@ -1,6 +1,7 @@ import { ActionUserData, IActionExecutionContext } from 'blueprints-integration' +import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { executeAction, ServerSelectMode } from 'tv2-common' -import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' +import { CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' import { AFVD_DVE_GENERATOR_OPTIONS } from './helpers/content/dve' import { EvaluateCues } from './helpers/pieces/evaluateCues' import { pilotGeneratorSettingsAFVD } from './helpers/pieces/graphicPilot' @@ -16,6 +17,7 @@ export async function executeActionAFVD( ): Promise { await executeAction( context, + GALLERY_UNIFORM_CONFIG, { postProcessPieceTimelineObjects, EvaluateCues, @@ -43,13 +45,6 @@ export async function executeActionAFVD( Effekt: SisyfosLLAyer.SisyfosSourceJingle, StudioMics: SisyfosLLAyer.SisyfosGroupStudioMics }, - Atem: { - MEProgram: AtemLLayer.AtemMEProgram, - MEClean: AtemLLayer.AtemMEClean, - Next: AtemLLayer.AtemAuxLookahead, - SSrcDefault: AtemLLayer.AtemSSrcDefault, - cutOnclean: false - } }, SelectedAdlibs: { SourceLayer: { diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 8ccbf813..89fd0a88 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -13,6 +13,7 @@ import { TSR, WithTimeline } from 'blueprints-integration' +import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { ActionCallRobotPreset, ActionClearGraphics, @@ -65,7 +66,7 @@ import { SourceLayer } from './layers' import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: IngestRundown): BlueprintResultRundown { - const context = new ExtendedShowStyleContextImpl(coreContext) + const context = new ExtendedShowStyleContextImpl(coreContext, GALLERY_UNIFORM_CONFIG) return { rundown: { externalId: ingestRundown.externalId, diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index d0feb89a..8bf9d9e5 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -8,6 +8,7 @@ import { PieceLifespan, WithTimeline } from 'blueprints-integration' +import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { ExtendedSegmentContext, ExtendedSegmentContextImpl, @@ -37,7 +38,7 @@ export async function getSegment( ingestSegment: IngestSegment ): Promise { const segmentPayload = ingestSegment.payload as INewsPayload | undefined - const context = new ExtendedSegmentContextImpl(coreContext) + const context = new ExtendedSegmentContextImpl(coreContext, GALLERY_UNIFORM_CONFIG) const result: BlueprintResultSegment = await getSegmentBase(context, ingestSegment, { CreatePartContinuity, diff --git a/src/tv2_afvd_showstyle/helpers/content/dve.ts b/src/tv2_afvd_showstyle/helpers/content/dve.ts index c03c65c5..bb7c2479 100644 --- a/src/tv2_afvd_showstyle/helpers/content/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/content/dve.ts @@ -31,7 +31,6 @@ export const AFVD_DVE_GENERATOR_OPTIONS: DVEOptions = { ClipPending: CasparLLayer.CasparPlayerClipPending } }, - boxMappings: [AtemLLayer.AtemSSrcBox1, AtemLLayer.AtemSSrcBox2, AtemLLayer.AtemSSrcBox3, AtemLLayer.AtemSSrcBox4], AUDIO_LAYERS: Object.keys(SisyfosLLAyer) } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts index 4536fe76..188f9b3a 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts @@ -53,10 +53,6 @@ export async function EvaluateAdLib( Sisyfos: { ClipPending: SisyfosLLAyer.SisyfosSourceClipPending }, - AtemLLayer: { - MEPgm: AtemLLayer.AtemMEProgram - }, - ATEM: {} }, true ) diff --git a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts index 71caf50e..f0f69092 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts @@ -111,9 +111,6 @@ export function createJingleContentAFVD( Caspar: { PlayerJingle: CasparLLayer.CasparPlayerJingle }, - ATEM: { - USKCleanEffekt: AtemLLayer.AtemCleanUSKEffect - }, Sisyfos: { PlayerJingle: SisyfosLLAyer.SisyfosSourceJingle } diff --git a/src/tv2_afvd_showstyle/parts/server.ts b/src/tv2_afvd_showstyle/parts/server.ts index 4703ef24..185a085f 100644 --- a/src/tv2_afvd_showstyle/parts/server.ts +++ b/src/tv2_afvd_showstyle/parts/server.ts @@ -1,6 +1,6 @@ import { BlueprintResultPart, HackPartMediaObjectSubscription, IBlueprintActionManifest } from 'blueprints-integration' import { AddScript, CreatePartServerBase, ExtendedSegmentContext, PartDefinition, ServerPartProps } from 'tv2-common' -import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../../tv2_afvd_studio/layers' +import { CasparLLayer, SisyfosLLAyer } from '../../tv2_afvd_studio/layers' import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' @@ -16,16 +16,12 @@ export async function CreatePartServer( PgmServer: partProps.voLayer ? SourceLayer.PgmVoiceOver : SourceLayer.PgmServer, // TODO this actually is shared SelectedServer: partProps.voLayer ? SourceLayer.SelectedVoiceOver : SourceLayer.SelectedServer }, - AtemLLayer: { - MEPgm: AtemLLayer.AtemMEProgram - }, Caspar: { ClipPending: CasparLLayer.CasparPlayerClipPending }, Sisyfos: { ClipPending: SisyfosLLAyer.SisyfosSourceClipPending }, - ATEM: {} }) if (basePartProps.invalid) { diff --git a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts index a39f4513..041510a2 100644 --- a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts @@ -1,7 +1,6 @@ import { BlueprintResultPart, IBlueprintPieceGeneric, - OnGenerateTimelineObj, SourceLayerType, SplitsContent, TimelineObjectCoreExt, @@ -59,7 +58,6 @@ export function postProcessPieceTimelineObjects( if ( (!isAdlib || piece.toBeQueued) && - 'me' in tlObj.content && (tlObj.content.me.input !== -1 || tlObj.metaData?.mediaPlayerSession !== undefined) ) { // Create a lookahead-lookahead object for this me-program diff --git a/src/tv2_afvd_studio/layers.ts b/src/tv2_afvd_studio/layers.ts index de316adb..12d8f25d 100644 --- a/src/tv2_afvd_studio/layers.ts +++ b/src/tv2_afvd_studio/layers.ts @@ -37,19 +37,13 @@ export enum AFVDAtemLLayer { AtemCleanUSKEffect = 'atem_clean_usk_effect', AtemSSrcArt = 'atem_supersource_art', AtemSSrcDefault = 'atem_supersource_default', - AtemSSrcBox1 = 'atem_supersource_z_box1', - AtemSSrcBox2 = 'atem_supersource_z_box2', - AtemSSrcBox3 = 'atem_supersource_z_box3', - AtemSSrcBox4 = 'atem_supersource_z_box4', AtemMP1 = 'atem_mp_1', AtemAuxPGM = 'atem_aux_pgm', AtemAuxClean = 'atem_aux_clean', - AtemAuxWall = 'atem_aux_wall', AtemAuxAR = 'atem_aux_ar', AtemAuxVizOvlIn1 = 'atem_aux_viz_ovl_in_1', // AtemAuxVizFullIn1 = 'atem_aux_viz_full_in_1', - AtemAuxVenue = 'atem_aux_venue', AtemAuxLookahead = 'atem_aux_lookahead', AtemAuxSSrc = 'atem_aux_ssrc' } diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index 2c9ef865..071d5d2b 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -601,13 +601,6 @@ export const MAPPINGS_ATEM: BlueprintMappings = { mappingType: TSR.MappingAtemType.Auxilliary, index: 1 // 1 = out 2 }), - [AtemLLayer.AtemAuxWall]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingAtemType.Auxilliary, - index: 2 // 2 = out 3 - }), [AtemLLayer.AtemAuxAR]: literal({ device: TSR.DeviceType.ATEM, deviceId: 'atem0', @@ -622,13 +615,6 @@ export const MAPPINGS_ATEM: BlueprintMappings = { mappingType: TSR.MappingAtemType.Auxilliary, index: 4 // 4 = out 5 }), - // atem_aux_viz_full_in_1: literal({ - // device: TSR.DeviceType.ATEM, - // deviceId: 'atem0', - // lookahead: LookaheadMode.WHEN_CLEAR, - // mappingType: TSR.MappingAtemType.Auxilliary, - // index: 5 // 5 = out 6 - // }), [AtemLLayer.AtemAuxVideoMixMinus]: literal({ device: TSR.DeviceType.ATEM, deviceId: 'atem0', @@ -636,13 +622,6 @@ export const MAPPINGS_ATEM: BlueprintMappings = { mappingType: TSR.MappingAtemType.Auxilliary, index: 6 // 6 = out 7 }), - [AtemLLayer.AtemAuxVenue]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingAtemType.Auxilliary, - index: 7 // 7 = out 8 - }), [AtemLLayer.AtemAuxLookahead]: literal({ device: TSR.DeviceType.ATEM, deviceId: 'atem0', @@ -672,35 +651,98 @@ export const MAPPINGS_ATEM: BlueprintMappings = { mappingType: TSR.MappingAtemType.SuperSourceBox, index: 0 // 0 = SS }), - [AtemLLayer.AtemSSrcBox1]: literal({ + [AtemLLayer.AtemMP1]: literal({ + device: TSR.DeviceType.ATEM, + deviceId: 'atem0', + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingAtemType.MediaPlayer, + index: 0 + }) +} + +export const MAPPINGS_TRICASTER: BlueprintMappings = { + [AtemLLayer.AtemMEProgram]: literal({ + device: TSR.DeviceType.ATEM, + deviceId: 'atem0', + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingAtemType.MixEffect, + index: 0 // 0 = ME1 + }), + [AtemLLayer.AtemMEClean]: literal({ + device: TSR.DeviceType.ATEM, + deviceId: 'atem0', + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingAtemType.MixEffect, + index: 3 // 3 = ME4 + }), + [AtemLLayer.AtemCleanUSKEffect]: literal({ + device: TSR.DeviceType.ATEM, + deviceId: 'atem0', + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingAtemType.MixEffect, + index: 3 // 3 = ME4 + }), + [AtemLLayer.AtemAuxPGM]: literal({ + device: TSR.DeviceType.ATEM, + deviceId: 'atem0', + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingAtemType.Auxilliary, + index: 0 // 0 = out 1 + }), + [AtemLLayer.AtemAuxClean]: literal({ + device: TSR.DeviceType.ATEM, + deviceId: 'atem0', + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingAtemType.Auxilliary, + index: 1 // 1 = out 2 + }), + [AtemLLayer.AtemAuxAR]: literal({ device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, - lookaheadMaxSearchDistance: 1, - mappingType: TSR.MappingAtemType.SuperSourceBox, - index: 0 // 0 = SS + mappingType: TSR.MappingAtemType.Auxilliary, + index: 3 // 3 = out 4 }), - [AtemLLayer.AtemSSrcBox2]: literal({ + [AtemLLayer.AtemAuxVizOvlIn1]: literal({ device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, - lookaheadMaxSearchDistance: 1, - mappingType: TSR.MappingAtemType.SuperSourceBox, - index: 0 // 0 = SS + mappingType: TSR.MappingAtemType.Auxilliary, + index: 4 // 4 = out 5 }), - [AtemLLayer.AtemSSrcBox3]: literal({ + [AtemLLayer.AtemAuxVideoMixMinus]: literal({ device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, - lookaheadMaxSearchDistance: 1, - mappingType: TSR.MappingAtemType.SuperSourceBox, - index: 0 // 0 = SS + mappingType: TSR.MappingAtemType.Auxilliary, + index: 6 // 6 = out 7 }), - [AtemLLayer.AtemSSrcBox4]: literal({ + [AtemLLayer.AtemAuxLookahead]: literal({ + device: TSR.DeviceType.ATEM, + deviceId: 'atem0', + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingAtemType.Auxilliary, + index: 10 // 10 = out 11 + }), + [AtemLLayer.AtemAuxSSrc]: literal({ device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, - lookaheadMaxSearchDistance: 1, + mappingType: TSR.MappingAtemType.Auxilliary, + index: 11 // 11 = out 12 + }), + ...GetDSKMappings(ATEMModel.CONSTELLATION_8K_UHD_MODE), + [AtemLLayer.AtemSSrcArt]: literal({ + device: TSR.DeviceType.ATEM, + deviceId: 'atem0', + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingAtemType.SuperSourceProperties, + index: 0 // 0 = SS + }), + [AtemLLayer.AtemSSrcDefault]: literal({ + device: TSR.DeviceType.ATEM, + deviceId: 'atem0', + lookahead: LookaheadMode.WHEN_CLEAR, // TODO - verify mappingType: TSR.MappingAtemType.SuperSourceBox, index: 0 // 0 = SS }), @@ -727,6 +769,7 @@ export default literal({ ...MAPPINGS_CASPAR, ...MAPPINGS_GRAPHICS, ...MAPPINGS_ATEM, + ...MAPPINGS_TRICASTER, ...MAPPINGS_TELEMETRICS }) diff --git a/src/tv2_afvd_studio/uniformConfig.ts b/src/tv2_afvd_studio/uniformConfig.ts new file mode 100644 index 00000000..f2519bc5 --- /dev/null +++ b/src/tv2_afvd_studio/uniformConfig.ts @@ -0,0 +1,8 @@ +import { UniformConfig } from "tv2-common"; +import { SwitcherMixEffectLLayer } from "tv2-constants"; + +export const GALLERY_UNIFORM_CONFIG: UniformConfig = { + SwitcherLLayers: { + PrimaryMixEffect: SwitcherMixEffectLLayer.Program + } +} diff --git a/src/tv2_offtube_showstyle/actions.ts b/src/tv2_offtube_showstyle/actions.ts index 907551af..00f950b3 100644 --- a/src/tv2_offtube_showstyle/actions.ts +++ b/src/tv2_offtube_showstyle/actions.ts @@ -1,6 +1,7 @@ import { ActionUserData, IActionExecutionContext } from 'blueprints-integration' +import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' import { executeAction, ServerSelectMode } from 'tv2-common' -import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' +import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' import { OFFTUBE_DVE_GENERATOR_OPTIONS } from './content/OfftubeDVEContent' import { pilotGeneratorSettingsOfftube } from './cues/OfftubeGraphics' import { createJingleContentOfftube } from './cues/OfftubeJingle' @@ -23,6 +24,7 @@ export async function executeActionOfftube( ): Promise { await executeAction( context, + QBOX_UNIFORM_CONFIG, { postProcessPieceTimelineObjects, EvaluateCues: OfftubeEvaluateCues, @@ -49,14 +51,6 @@ export async function executeActionOfftube( Effekt: OfftubeSisyfosLLayer.SisyfosSourceJingle, StudioMics: OfftubeSisyfosLLayer.SisyfosGroupStudioMics }, - Atem: { - MEProgram: OfftubeAtemLLayer.AtemMEProgram, - MEClean: OfftubeAtemLLayer.AtemMEClean, - Next: OfftubeAtemLLayer.AtemMENext, - ServerLookaheadAUX: OfftubeAtemLLayer.AtemAuxServerLookahead, - SSrcDefault: OfftubeAtemLLayer.AtemSSrcDefault, - cutOnclean: true - } }, SelectedAdlibs: { SourceLayer: { diff --git a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts index c7a89dea..dbb07f6d 100644 --- a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts +++ b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts @@ -12,13 +12,6 @@ import { OfftubeBlueprintConfig } from '../helpers/config' export const NUMBER_OF_DVE_BOXES = 4 -export const boxMappings: [string, string, string, string] = [ - OfftubeAtemLLayer.AtemSSrcBox1, - OfftubeAtemLLayer.AtemSSrcBox2, - OfftubeAtemLLayer.AtemSSrcBox3, - OfftubeAtemLLayer.AtemSSrcBox4 -] - export const OFFTUBE_DVE_GENERATOR_OPTIONS: DVEOptions = { dveLayers: { ATEM: { @@ -38,7 +31,6 @@ export const OFFTUBE_DVE_GENERATOR_OPTIONS: DVEOptions = { ClipPending: OfftubeCasparLLayer.CasparPlayerClipPending } }, - boxMappings, AUDIO_LAYERS: [] // TODO } diff --git a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts index 7df329c5..d6d5ee92 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts @@ -61,12 +61,6 @@ export async function OfftubeEvaluateAdLib( Sisyfos: { ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending }, - AtemLLayer: { - MEPgm: OfftubeAtemLLayer.AtemMEClean - }, - ATEM: { - ServerLookaheadAux: OfftubeAtemLLayer.AtemAuxServerLookahead - } }, true ) diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index acdd46a5..f79eb610 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -128,9 +128,6 @@ export function createJingleContentOfftube( PlayerJingle: OfftubeCasparLLayer.CasparPlayerJingle, PlayerJinglePreload: OfftubeCasparLLayer.CasparPlayerJinglePreload }, - ATEM: { - USKJinglePreview: OfftubeAtemLLayer.AtemMENextJingle - }, Sisyfos: { PlayerJingle: OfftubeSisyfosLLayer.SisyfosSourceJingle } diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 12e9d496..9dbafef7 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -11,6 +11,7 @@ import { PlaylistTimingType, TSR } from 'blueprints-integration' +import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' import { ActionClearGraphics, ActionCommentatorSelectDVE, @@ -67,7 +68,7 @@ import { OfftubeOutputLayers, OfftubeSourceLayer } from './layers' import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: IngestRundown): BlueprintResultRundown { - const context = new ExtendedShowStyleContextImpl(coreContext) + const context = new ExtendedShowStyleContextImpl(coreContext, QBOX_UNIFORM_CONFIG) let startTime: number = 0 let endTime: number = 0 diff --git a/src/tv2_offtube_showstyle/getSegment.ts b/src/tv2_offtube_showstyle/getSegment.ts index a633a0d5..5574d7e9 100644 --- a/src/tv2_offtube_showstyle/getSegment.ts +++ b/src/tv2_offtube_showstyle/getSegment.ts @@ -7,6 +7,7 @@ import { PieceLifespan, WithTimeline } from 'blueprints-integration' +import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' import { ExtendedSegmentContextImpl, ExtendedShowStyleContext, @@ -16,7 +17,6 @@ import { } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import * as _ from 'underscore' -import { OfftubeAtemLLayer } from '../tv2_offtube_studio/layers' import { OfftubeBlueprintConfig } from './helpers/config' import { OfftubeSourceLayer } from './layers' import { OfftubeCreatePartDVE } from './parts/OfftubeDVE' @@ -30,7 +30,7 @@ export async function getSegment( coreContext: ISegmentUserContext, ingestSegment: IngestSegment ): Promise { - const context = new ExtendedSegmentContextImpl(coreContext) + const context = new ExtendedSegmentContextImpl(coreContext, QBOX_UNIFORM_CONFIG) const result: BlueprintResultSegment = await getSegmentBase(context, ingestSegment, { CreatePartContinuity, @@ -82,7 +82,7 @@ function CreatePartContinuity( timelineObjects: [ context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, - layer: OfftubeAtemLLayer.AtemMEClean, + layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: context.config.studio.SwitcherSource.Continuity, transition: TransitionStyle.CUT diff --git a/src/tv2_offtube_showstyle/onTimelineGenerate.ts b/src/tv2_offtube_showstyle/onTimelineGenerate.ts index 2a7a09fe..09327c8a 100644 --- a/src/tv2_offtube_showstyle/onTimelineGenerate.ts +++ b/src/tv2_offtube_showstyle/onTimelineGenerate.ts @@ -7,6 +7,7 @@ import { TimelinePersistentState, TSR } from 'blueprints-integration' +import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' import { disablePilotWipeAfterJingle, ExtendedTimelineContext, @@ -28,7 +29,7 @@ export function onTimelineGenerateOfftube( const previousPartEndState2 = previousPartEndState as PartEndStateExt | undefined disablePilotWipeAfterJingle(timeline, previousPartEndState2, resolvedPieces) disableFirstPilotGFXAnimation(coreContext, timeline, previousPartEndState2, resolvedPieces) - const context = new ExtendedTimelineContext(coreContext) + const context = new ExtendedTimelineContext(coreContext, QBOX_UNIFORM_CONFIG) return onTimelineGenerate(context, timeline, previousPersistentState, previousPartEndState, resolvedPieces, { Caspar: { ClipPending: OfftubeCasparLLayer.CasparPlayerClipPending diff --git a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts index 3547999f..90920e83 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts @@ -23,19 +23,12 @@ export async function OfftubeCreatePartServer( PgmServer: partProps.voLayer ? OfftubeSourceLayer.PgmVoiceOver : OfftubeSourceLayer.PgmServer, // TODO this actually is shared SelectedServer: partProps.voLayer ? OfftubeSourceLayer.SelectedVoiceOver : OfftubeSourceLayer.SelectedServer }, - AtemLLayer: { - MEPgm: OfftubeAtemLLayer.AtemMEClean, - ServerLookaheadAux: OfftubeAtemLLayer.AtemAuxServerLookahead - }, Caspar: { ClipPending: OfftubeCasparLLayer.CasparPlayerClipPending }, Sisyfos: { ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending }, - ATEM: { - ServerLookaheadAux: OfftubeAtemLLayer.AtemAuxServerLookahead - } }) if (basePartProps.invalid) { @@ -71,13 +64,6 @@ export async function OfftubeCreatePartServer( Sisyfos: { ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending }, - AtemLLayer: { - MEPgm: OfftubeAtemLLayer.AtemMEClean, - ServerLookaheadAux: OfftubeAtemLLayer.AtemAuxServerLookahead - }, - ATEM: { - ServerLookaheadAux: OfftubeAtemLLayer.AtemAuxServerLookahead - } }, false ) diff --git a/src/tv2_offtube_studio/layers.ts b/src/tv2_offtube_studio/layers.ts index 96797bb7..21268e3e 100644 --- a/src/tv2_offtube_studio/layers.ts +++ b/src/tv2_offtube_studio/layers.ts @@ -60,10 +60,6 @@ export enum AtemLLayer { AtemAuxClean = 'atem_aux_clean', AtemAuxScreen = 'atem_aux_screen', AtemAuxServerLookahead = 'atem_aux_server_lookahead', - AtemSSrcBox1 = 'atem_supersource_z_box1', - AtemSSrcBox2 = 'atem_supersource_z_box2', - AtemSSrcBox3 = 'atem_supersource_z_box3', - AtemSSrcBox4 = 'atem_supersource_z_box4' } // tslint:disable-next-line: variable-name diff --git a/src/tv2_offtube_studio/migrations/mappings-defaults.ts b/src/tv2_offtube_studio/migrations/mappings-defaults.ts index d7fadb61..a16a908c 100644 --- a/src/tv2_offtube_studio/migrations/mappings-defaults.ts +++ b/src/tv2_offtube_studio/migrations/mappings-defaults.ts @@ -524,38 +524,6 @@ const MAPPINGS_ATEM: BlueprintMappings = { mappingType: TSR.MappingAtemType.SuperSourceBox, index: 0 // 0 = SS }), - [OfftubeAtemLLayer.AtemSSrcBox1]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.WHEN_CLEAR, - lookaheadMaxSearchDistance: 1, - mappingType: TSR.MappingAtemType.SuperSourceBox, - index: 0 // 0 = SS - }), - [OfftubeAtemLLayer.AtemSSrcBox2]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.WHEN_CLEAR, - lookaheadMaxSearchDistance: 1, - mappingType: TSR.MappingAtemType.SuperSourceBox, - index: 0 // 0 = SS - }), - [OfftubeAtemLLayer.AtemSSrcBox3]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.WHEN_CLEAR, - lookaheadMaxSearchDistance: 1, - mappingType: TSR.MappingAtemType.SuperSourceBox, - index: 0 // 0 = SS - }), - [OfftubeAtemLLayer.AtemSSrcBox4]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.WHEN_CLEAR, - lookaheadMaxSearchDistance: 1, - mappingType: TSR.MappingAtemType.SuperSourceBox, - index: 0 // 0 = SS - }), // TODO: Future: Mix Minus in Offtubes [OfftubeAtemLLayer.AtemAuxVideoMixMinus]: literal({ device: TSR.DeviceType.ABSTRACT, diff --git a/src/tv2_offtube_studio/uniformConfig.ts b/src/tv2_offtube_studio/uniformConfig.ts new file mode 100644 index 00000000..70f9ba21 --- /dev/null +++ b/src/tv2_offtube_studio/uniformConfig.ts @@ -0,0 +1,9 @@ +import { UniformConfig } from "tv2-common"; +import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from "tv2-constants"; + +export const QBOX_UNIFORM_CONFIG: UniformConfig = { + SwitcherLLayers: { + PrimaryMixEffect: SwitcherMixEffectLLayer.Clean, + ServerLookaheadAux: SwitcherAuxLLayer.AuxServerLookahead + } +} From 2956134643baf63082728ad0846090d7864621e5 Mon Sep 17 00:00:00 2001 From: ianshade Date: Fri, 3 Feb 2023 16:43:05 +0100 Subject: [PATCH 14/86] wip: SOF-1260 implement auxes and layers --- src/tv2-common/actions/executeAction.ts | 6 +- src/tv2-common/content/dve.ts | 11 +- src/tv2-common/content/server.ts | 13 +- src/tv2-common/cues/ekstern.ts | 4 +- src/tv2-common/cues/mixMinus.ts | 18 +- src/tv2-common/helpers/abPlayback.ts | 2 +- .../caspar/htmlPilotGraphicGenerator.ts | 2 +- .../graphics/pilot/PilotGraphicGenerator.ts | 8 - .../graphics/viz/VizPilotGraphicGenerator.ts | 15 +- src/tv2-common/layers/timelineLayers.ts | 43 ++- src/tv2-common/parts/server.ts | 4 +- src/tv2-common/segment/context.ts | 8 +- src/tv2-common/showstyle/context.ts | 2 +- src/tv2-common/uniformConfig.ts | 31 +- src/tv2-common/videoSwitchers/Atem.ts | 78 +++-- src/tv2-common/videoSwitchers/TriCaster.ts | 110 +++++-- .../videoSwitchers/VideoSwitcher.ts | 27 +- src/tv2-common/videoSwitchers/types.ts | 46 ++- src/tv2-constants/enums.ts | 13 +- src/tv2_afvd_showstyle/actions.ts | 5 +- src/tv2_afvd_showstyle/getRundown.ts | 130 ++++----- src/tv2_afvd_showstyle/getSegment.ts | 8 +- .../helpers/pieces/adlib.ts | 2 +- .../helpers/pieces/routing.ts | 8 +- src/tv2_afvd_showstyle/parts/evs.ts | 2 +- src/tv2_afvd_showstyle/parts/kam.ts | 4 +- src/tv2_afvd_showstyle/parts/server.ts | 2 +- .../postProcessTimelineObjects.ts | 5 +- src/tv2_afvd_studio/getBaseline.ts | 51 +--- .../migrations/mappings-defaults.ts | 270 ++++++++++-------- src/tv2_afvd_studio/onTimelineGenerate.ts | 3 +- src/tv2_afvd_studio/uniformConfig.ts | 12 +- src/tv2_offtube_showstyle/actions.ts | 6 +- .../cues/OfftubeAdlib.ts | 2 +- .../cues/OfftubeGraphics.ts | 9 +- .../cues/OfftubePgmClean.ts | 14 +- src/tv2_offtube_showstyle/getRundown.ts | 34 +-- src/tv2_offtube_showstyle/getSegment.ts | 2 +- .../onTimelineGenerate.ts | 2 +- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 5 +- .../parts/OfftubeServer.ts | 4 +- .../postProcessTimelineObjects.ts | 5 +- src/tv2_offtube_studio/getBaseline.ts | 20 +- src/tv2_offtube_studio/layers.ts | 2 +- .../migrations/mappings-defaults.ts | 4 +- src/tv2_offtube_studio/uniformConfig.ts | 13 +- 46 files changed, 554 insertions(+), 511 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index b3030d27..7dc0912b 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -49,7 +49,6 @@ import { MakeContentDVE2, PartDefinition, PieceMetaData, - PilotGeneratorSettings, PilotGraphicGenerator, ServerSelectMode, SisyfosPersistMetaData, @@ -168,7 +167,6 @@ export interface ActionExecutionSettings< duration: number, alphaAtEnd: number ) => WithTimeline - pilotGraphicSettings: PilotGeneratorSettings serverActionSettings: ServerActionSettings } @@ -438,7 +436,7 @@ async function executeActionSelectServerClip< }, Sisyfos: { ClipPending: settings.LLayer.Sisyfos.ClipPending - }, + } } ) @@ -1210,7 +1208,6 @@ async function executeActionCutToRemote< content: { timelineObjects: _.compact([ context.videoSwitcher.getMixEffectTimelineObject({ - id: '', enable: { while: '1' }, priority: 1, layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, @@ -1937,7 +1934,6 @@ async function executeActionSelectFull< const generator = PilotGraphicGenerator.createPilotGraphicGenerator({ context, partId: externalId, - settings: settings.pilotGraphicSettings, parsedCue: cue, segmentExternalId: userData.segmentExternalId, adlib: { rank: 0 } diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 1b612f07..c8a4ae5d 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -21,6 +21,7 @@ import { literal, PartDefinition, PieceMetaData, + SpecialInput, TimelineBlueprintExt, TransitionStyle, TV2BlueprintConfigBase, @@ -357,9 +358,9 @@ export function MakeContentDVE2< id: '', enable: getDVEEnable(Number(context.config.studio.CasparPrerollDuration)), priority: 1, - layer: dveGeneratorOptions.dveLayers.ATEM.MEProgram, + layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { - input: AtemSourceIndex.SSrc, + input: SpecialInput.DVE, transition: TransitionStyle.CUT } }), @@ -441,11 +442,7 @@ const setBoxToBlack = (boxConfig: BoxConfig, boxSources: BoxSources) => { }) } -function makeBoxAssignments( - inputs: string[], - context: IShowStyleUserContext, - sources: DVESources | undefined -) { +function makeBoxAssignments(inputs: string[], context: IShowStyleUserContext, sources: DVESources | undefined) { const boxAssignments: Array = [] inputs.forEach(source => { const sourceProps = source.split(':') diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 2011aad5..e590e83a 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -111,19 +111,10 @@ function GetServerTimeline( ), ...(context.uniformConfig.SwitcherLLayers.ServerLookaheadAux ? [ - literal({ - id: '', - enable: { - start: 0 - }, - priority: 0, + context.videoSwitcher.getAuxTimelineObject({ layer: context.uniformConfig.SwitcherLLayers.ServerLookaheadAux, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: -1 - } + input: -1 }, metaData: { mediaPlayerSession: contentProps.mediaPlayerSession diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index e1c1d042..564b4397 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -76,7 +76,7 @@ export function EvaluateEksternBase< timelineObjects: literal([ context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, - layer: layersEkstern.ATEM.MEProgram, + layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: switcherInput, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, @@ -114,7 +114,7 @@ export function EvaluateEksternBase< timelineObjects: literal([ context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, - layer: layersEkstern.ATEM.MEProgram, + layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: switcherInput, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, diff --git a/src/tv2-common/cues/mixMinus.ts b/src/tv2-common/cues/mixMinus.ts index eb017152..c174a455 100644 --- a/src/tv2-common/cues/mixMinus.ts +++ b/src/tv2-common/cues/mixMinus.ts @@ -3,11 +3,10 @@ import { IBlueprintPiece, PieceLifespan, TimelineObjectCoreExt, - TSR, WithTimeline } from 'blueprints-integration' import { CueDefinitionMixMinus, ExtendedShowStyleContext, findSourceInfo, literal, PartDefinition } from 'tv2-common' -import { ControlClasses, SharedATEMLLayer, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' +import { ControlClasses, SharedOutputLayers, SharedSourceLayers, SwitcherAuxLLayer } from 'tv2-constants' export function EvaluateCueMixMinus( context: ExtendedShowStyleContext, @@ -34,26 +33,21 @@ export function EvaluateCueMixMinus( lifespan: PieceLifespan.OutOnShowStyleEnd, sourceLayerId: SharedSourceLayers.AuxMixMinus, outputLayerId: SharedOutputLayers.AUX, - content: MixMinusContent(switcherInput) + content: MixMinusContent(context, switcherInput) }) } -function MixMinusContent(switcherInput: number): WithTimeline { +function MixMinusContent(context: ExtendedShowStyleContext, switcherInput: number): WithTimeline { return { timelineObjects: literal([ - literal({ + context.videoSwitcher.getAuxTimelineObject({ content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: switcherInput - } + input: switcherInput }, enable: { while: `.${ControlClasses.LiveSourceOnAir}` }, - layer: SharedATEMLLayer.AtemAuxVideoMixMinus, - id: '', + layer: SwitcherAuxLLayer.AuxVideoMixMinus, priority: 1 }) ]) diff --git a/src/tv2-common/helpers/abPlayback.ts b/src/tv2-common/helpers/abPlayback.ts index 89f7bf94..58b69472 100644 --- a/src/tv2-common/helpers/abPlayback.ts +++ b/src/tv2-common/helpers/abPlayback.ts @@ -293,7 +293,7 @@ function updateObjectsToMediaPlayer< } } else if (context.videoSwitcher.isAux(obj)) { context.videoSwitcher.updateAuxInput(obj, input) - } else if (context.videoSwitcher.isDve(obj)) { + } else if (context.videoSwitcher.isDveBoxes(obj)) { context.videoSwitcher.updateUnpopulatedDveBoxes(obj, input) } else { context.core.logWarning( diff --git a/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts index e0482aeb..4e55eafc 100644 --- a/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts @@ -94,7 +94,7 @@ export class HtmlPilotGraphicGenerator extends PilotGraphicGenerator { start: Number(this.config.studio.CasparPrerollDuration) }, priority: 1, - layer: this.settings.ProgramLayer, + layer: this.context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: fullDSK.Fill, transition: TransitionStyle.WIPE_FOR_GFX diff --git a/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts index 39ebeaa9..ea5ce53c 100644 --- a/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts @@ -40,16 +40,10 @@ import { } from 'tv2-constants' import { Graphic } from '../index' -export interface PilotGeneratorSettings { - ProgramLayer: string - AuxProgramLayer?: string -} - export interface PilotGraphicProps { context: ExtendedShowStyleContext partId: string parsedCue: CueDefinitionGraphic - settings: PilotGeneratorSettings adlib?: Adlib segmentExternalId: string } @@ -66,7 +60,6 @@ export abstract class PilotGraphicGenerator extends Graphic { protected readonly engine: GraphicEngine protected readonly partId: string protected readonly cue: CueDefinitionGraphic - protected readonly settings: PilotGeneratorSettings protected readonly adlib?: Adlib protected readonly segmentExternalId: string @@ -77,7 +70,6 @@ export abstract class PilotGraphicGenerator extends Graphic { this.engine = graphicProps.parsedCue.target this.cue = graphicProps.parsedCue this.partId = graphicProps.partId - this.settings = graphicProps.settings this.adlib = graphicProps.adlib this.segmentExternalId = graphicProps.segmentExternalId } diff --git a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts index 3fa98ee3..8f85da7f 100644 --- a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts @@ -87,7 +87,7 @@ export class VizPilotGraphicGenerator extends PilotGraphicGenerator { start: this.config.studio.VizPilotGraphics.CutToMediaPlayer }, priority: 1, - layer: this.settings.ProgramLayer, + layer: this.context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: this.config.studio.VizPilotGraphics.FullGraphicBackground, transition: TransitionStyle.CUT @@ -97,21 +97,16 @@ export class VizPilotGraphicGenerator extends PilotGraphicGenerator { ...EnableDSK(this.context, 'FULL'), ...GetSisyfosTimelineObjForFull(this.config) ] - if (this.settings.AuxProgramLayer) { + if (this.context.uniformConfig.SwitcherLLayers.ProgramAux) { timelineObjects.push( - literal({ - id: '', + this.context.videoSwitcher.getAuxTimelineObject({ enable: { start: this.config.studio.VizPilotGraphics.CutToMediaPlayer }, priority: 1, - layer: this.settings.AuxProgramLayer, + layer: this.context.uniformConfig.SwitcherLLayers.ProgramAux, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: fullDSK.Fill - } + input: fullDSK.Fill }, classes: [ControlClasses.MixMinusOverrideDsk, ControlClasses.Placeholder] }) diff --git a/src/tv2-common/layers/timelineLayers.ts b/src/tv2-common/layers/timelineLayers.ts index ed1d2357..0d57d76e 100644 --- a/src/tv2-common/layers/timelineLayers.ts +++ b/src/tv2-common/layers/timelineLayers.ts @@ -1,8 +1,14 @@ import { BlueprintMapping, BlueprintMappings, LookaheadMode, TSR } from 'blueprints-integration' -import { literal } from 'tv2-common' import { ATEMModel } from '../../types/atem' import { GetDSKCount } from '../helpers' +export const TRICASTER_DEVICE_ID = 'tricaster0' +export const TRICASTER_CLEAN_ME = 'v1' +export const TRICASTER_DVE_ME = 'v2' + +export const ATEM_LAYER_PREFIX = 'atem_' +export const TRICASTER_LAYER_PREFIX = 'tricaster_' + export function AbstractLLayerServerEnable(i: number) { return `server_enable_${i}` } @@ -24,7 +30,7 @@ export function SisyfosPlayerClip(i: number | string) { * @param i DSK number starting from 0 */ export function AtemLLayerDSK(i: number) { - return `atem_dsk_${i + 1}` + return `dsk_${i + 1}` } export function GetDSKMappingNames(atemModel: ATEMModel): string[] { @@ -37,16 +43,41 @@ export function GetDSKMappingNames(atemModel: ATEMModel): string[] { return names } -export function GetDSKMappings(atemModel: ATEMModel): BlueprintMappings { - const base: BlueprintMappings = {} +export function getAtemDskMappings(atemModel: ATEMModel): BlueprintMappings { + const base: Record = {} return GetDSKMappingNames(atemModel).reduce((prev, name, index) => { - prev[name] = literal({ + prev[name] = { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.DownStreamKeyer, index - }) + } return prev }, base) } + +export function getTriCasterDskMappings(): BlueprintMappings { + const base: Record = {} + return [1, 2, 3, 4].reduce((prev, index) => { + prev[`dsk_${index}`] = { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.DSK, + name: `dsk${index}` + } + return prev + }, base) +} + +export function prefixLayers( + prefix: string, + layers: Record +): Record { + const result: Record = {} + return Object.entries(layers).reduce((acc, [name, layer]) => { + acc[prefix + name] = layer + return acc + }, result) +} diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index ff429070..5de556a6 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -191,7 +191,7 @@ function getContentServerElement( context: ExtendedShowStyleContext, partProps: ServerPartProps, contentProps: ServerContentProps, - layers: ServerPartLayers, + layers: ServerPartLayers ): WithTimeline { return MakeContentServer( context, @@ -201,7 +201,7 @@ function getContentServerElement( }, Sisyfos: { ClipPending: layers.Sisyfos.ClipPending - }, + } }, partProps, contentProps diff --git a/src/tv2-common/segment/context.ts b/src/tv2-common/segment/context.ts index c528ce0b..4128b422 100644 --- a/src/tv2-common/segment/context.ts +++ b/src/tv2-common/segment/context.ts @@ -1,5 +1,11 @@ import { ISegmentUserContext } from 'blueprints-integration' -import { ExtendedShowStyleContext, ExtendedShowStyleContextImpl, TV2ShowStyleConfig, UniformConfig, VideoSwitcher } from 'tv2-common' +import { + ExtendedShowStyleContext, + ExtendedShowStyleContextImpl, + TV2ShowStyleConfig, + UniformConfig, + VideoSwitcher +} from 'tv2-common' export interface ExtendedSegmentContext extends ExtendedShowStyleContext { diff --git a/src/tv2-common/showstyle/context.ts b/src/tv2-common/showstyle/context.ts index da86e936..8b90fc34 100644 --- a/src/tv2-common/showstyle/context.ts +++ b/src/tv2-common/showstyle/context.ts @@ -4,7 +4,7 @@ import { TV2ShowStyleConfig, UniformConfig, VideoSwitcher, VideoSwitcherImpl } f export interface ExtendedShowStyleContext { readonly core: IShowStyleUserContext readonly config: BlueprintConfig - readonly uniformConfig: UniformConfig + readonly uniformConfig: UniformConfig readonly videoSwitcher: VideoSwitcher } diff --git a/src/tv2-common/uniformConfig.ts b/src/tv2-common/uniformConfig.ts index ac85e977..6fab1b4a 100644 --- a/src/tv2-common/uniformConfig.ts +++ b/src/tv2-common/uniformConfig.ts @@ -1,15 +1,22 @@ -import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from "tv2-constants" +import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' /** This config contains hardcoded values that differ between Gallery and Qbox Blueprints */ export interface UniformConfig { - SwitcherLLayers: { - /** The layer where cuts and transitions between primary pieces are happening */ - PrimaryMixEffect: SwitcherMixEffectLLayer - /** Optional layer to show the jingles on an USK */ - JingleUskMixEffect?: SwitcherMixEffectLLayer - /** Optional layer to show the jingles lookahead on */ - JingleNextMixEffect?: SwitcherMixEffectLLayer - /** Optional layer to preview servers on Aux */ - ServerLookaheadAux?: SwitcherAuxLLayer - } -} \ No newline at end of file + SwitcherLLayers: { + /** The layer where cuts and transitions between primary pieces are happening */ + PrimaryMixEffect: SwitcherMixEffectLLayer + /** Optional layer to show the jingles on an USK */ + JingleUskMixEffect?: SwitcherMixEffectLLayer + /** Optional layer to show the jingles lookahead on */ + JingleNextMixEffect?: SwitcherMixEffectLLayer + /** Optional layer to preview servers on Aux */ + ServerLookaheadAux?: SwitcherAuxLLayer + /** Optional layer to output Program on */ + ProgramAux?: SwitcherAuxLLayer + } + // @todo: implement this + // SwitcherMixEffects: { + // TriCasterClean: SpecialInput + // AtemClean: SpecialInput + // } +} diff --git a/src/tv2-common/videoSwitchers/Atem.ts b/src/tv2-common/videoSwitchers/Atem.ts index dba56c35..12ff9a83 100644 --- a/src/tv2-common/videoSwitchers/Atem.ts +++ b/src/tv2-common/videoSwitchers/Atem.ts @@ -1,6 +1,7 @@ -import { TSR } from 'blueprints-integration' +import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' import _ = require('underscore') import { AtemSourceIndex } from '../../types/atem' +import { ATEM_LAYER_PREFIX } from '../layers' import { TimelineBlueprintExt } from '../onTimelineGenerate' import { AuxProps, @@ -10,16 +11,11 @@ import { SpecialInput, SwitcherType, TIMELINE_OBJECT_DEFAULTS, + TimelineObjectProps, TransitionStyle, VideoSwitcherImpl } from './index' -const SPECIAL_INPUT_MAP = { - [SpecialInput.ME1_PROGRAM]: AtemSourceIndex.Prg1, - [SpecialInput.ME2_PROGRAM]: AtemSourceIndex.Prg2, - [SpecialInput.SSRC]: AtemSourceIndex.SSrc -} - const TRANSITION_MAP = { [TransitionStyle.CUT]: TSR.AtemTransitionStyle.CUT, [TransitionStyle.DIP]: TSR.AtemTransitionStyle.DIP, @@ -30,10 +26,11 @@ const TRANSITION_MAP = { } export class Atem extends VideoSwitcherImpl { - public readonly type = SwitcherType.ATEM - - public isVideoSwitcherTimelineObject = (timelineObject: TSR.TSRTimelineObj): boolean => { + + public isVideoSwitcherTimelineObject = ( + timelineObject: TSR.TSRTimelineObj + ): timelineObject is TSR.TimelineObjAtemAny => { return timelineObject.content.deviceType === TSR.DeviceType.ATEM } @@ -55,8 +52,7 @@ export class Atem extends VideoSwitcherImpl { me.upstreamKeyers = upstreamKeyers } return { - ...TIMELINE_OBJECT_DEFAULTS, - ..._.omit(props, 'content'), + ...this.getBaseProperties(props), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.ME, @@ -71,7 +67,7 @@ export class Atem extends VideoSwitcherImpl { public isMixEffect = (timelineObject: TSR.TSRTimelineObj): timelineObject is TSR.TimelineObjAtemME => { return ( - timelineObject.content.deviceType === TSR.DeviceType.ATEM && + this.isVideoSwitcherTimelineObject(timelineObject) && timelineObject.content.type === TSR.TimelineContentTypeAtem.ME ) } @@ -89,7 +85,10 @@ export class Atem extends VideoSwitcherImpl { timelineObject.content.me.transitionSettings = this.getTransitionSettings(transition, transitionDuration) return timelineObject } - public updatePreviewInput(timelineObject: TSR.TSRTimelineObj, previewInput: number | SpecialInput): TSR.TSRTimelineObj { + public updatePreviewInput( + timelineObject: TSR.TSRTimelineObj, + previewInput: number | SpecialInput + ): TSR.TSRTimelineObj { if (!this.isMixEffect(timelineObject)) { // @todo: log error or throw return timelineObject @@ -109,8 +108,7 @@ export class Atem extends VideoSwitcherImpl { public getDskTimelineObjects(props: DskProps) { const { content } = props const timelineObject: TSR.TimelineObjAtemDSK = { - ...TIMELINE_OBJECT_DEFAULTS, - ..._.omit(props, 'content'), + ...this.getBaseProperties(props), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.DSK, @@ -134,8 +132,7 @@ export class Atem extends VideoSwitcherImpl { public getAuxTimelineObject(props: AuxProps): TSR.TimelineObjAtemAUX { return { - ...TIMELINE_OBJECT_DEFAULTS, - ..._.omit(props, 'content'), + ...this.getBaseProperties(props), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.AUX, @@ -146,11 +143,48 @@ export class Atem extends VideoSwitcherImpl { } } - private getInputNumber(input: number | SpecialInput) { - if (typeof input === 'number') { - return input + public isDsk = (timelineObject: TSR.TSRTimelineObj): timelineObject is TSR.TimelineObjAtemDSK => { + return ( + this.isVideoSwitcherTimelineObject(timelineObject) && + timelineObject.content.type === TSR.TimelineContentTypeAtem.DSK + ) + } + public isAux = (timelineObject: TSR.TSRTimelineObj): timelineObject is TSR.TimelineObjAtemAUX => { + return ( + this.isVideoSwitcherTimelineObject(timelineObject) && + timelineObject.content.type === TSR.TimelineContentTypeAtem.AUX + ) + } + public updateAuxInput(timelineObject: TSR.TSRTimelineObj, input: number | SpecialInput): TSR.TSRTimelineObj { + throw new Error('Method not implemented.') + } + public isDveBoxes = (timelineObject: TSR.TSRTimelineObj): timelineObject is TSR.TimelineObjAtemSsrc => { + return ( + this.isVideoSwitcherTimelineObject(timelineObject) && + timelineObject.content.type === TSR.TimelineContentTypeAtem.SSRC + ) + } + public getDveTimelineObject(properties: AuxProps): TSR.TSRTimelineObj { + throw new Error('Method not implemented.') + } + public updateUnpopulatedDveBoxes( + timelineObject: TimelineObjectCoreExt, + input: number | SpecialInput + ): TSR.TSRTimelineObj { + throw new Error('Method not implemented.') + } + + private getBaseProperties(props: TimelineObjectProps): Omit { + return { + ...TIMELINE_OBJECT_DEFAULTS, + ..._.omit(props, 'content'), + layer: ATEM_LAYER_PREFIX + props.layer } - return SPECIAL_INPUT_MAP[input] + } + + private getInputNumber(input: number | SpecialInput) { + // this is kind of pointless, but I'm not sure SpecialInput being ATEM values is right + return input } private getTransition(transition: TransitionStyle) { return TRANSITION_MAP[transition] diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index baf10c93..9b6375ac 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -1,5 +1,6 @@ -import { TSR } from 'blueprints-integration' +import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' import _ = require('underscore') +import { TRICASTER_CLEAN_ME, TRICASTER_DVE_ME, TRICASTER_LAYER_PREFIX } from '../layers' import { AuxProps, DskProps, @@ -8,14 +9,19 @@ import { SpecialInput, SwitcherType, TIMELINE_OBJECT_DEFAULTS, + TimelineObjectProps, TransitionStyle } from './types' import { VideoSwitcherImpl } from './VideoSwitcher' -const SPECIAL_INPUT_MAP = { - [SpecialInput.ME1_PROGRAM]: 'v1', - [SpecialInput.ME2_PROGRAM]: 'v2', - [SpecialInput.SSRC]: 'v2' // todo: get this from config +const SPECIAL_INPUT_MAP: Record = { + [SpecialInput.ME1_PROGRAM]: 'main', + [SpecialInput.ME2_PROGRAM]: 'v1', + [SpecialInput.ME3_PROGRAM]: 'v2', + [SpecialInput.ME4_PROGRAM]: TRICASTER_CLEAN_ME, // @todo: fixme, I'm a hack because with TriCaster we're using a different M/E for Clean + [SpecialInput.DVE]: TRICASTER_DVE_ME, + [SpecialInput.COLOR_GENERATOR1]: 'bfr1', + [SpecialInput.COLOR_GENERATOR2]: 'bfr2' } const TRANSITION_MAP: Record = { @@ -31,11 +37,16 @@ const TRANSITION_MAP: Record = { export class TriCaster extends VideoSwitcherImpl { public readonly type = SwitcherType.ATEM + public isMixEffect = TSR.isTimelineObjTriCasterME + + public isDsk = TSR.isTimelineObjTriCasterDSK + public isAux = TSR.isTimelineObjTriCasterMixOutput + public isVideoSwitcherTimelineObject = TSR.isTimelineObjTriCaster + public getMixEffectTimelineObject(props: MixEffectProps): TSR.TimelineObjTriCasterME { const { content } = props return { - ...TIMELINE_OBJECT_DEFAULTS, - ..._.omit(props, 'content'), + ...this.getBaseProperties(props), content: { deviceType: TSR.DeviceType.TRICASTER, type: TSR.TimelineContentTypeTriCaster.ME, @@ -52,12 +63,6 @@ export class TriCaster extends VideoSwitcherImpl { } } - public isMixEffect = ( - timelineObject: TSR.TSRTimelineObj - ): timelineObject is TSR.TimelineObjTriCasterME => { - return TSR.isTimelineObjTriCasterME(timelineObject) - } - public findMixEffectTimelineObject(timelineObjects: TSR.TSRTimelineObj[]): TSR.TSRTimelineObj | undefined { return timelineObjects.find(this.isMixEffect) } @@ -77,14 +82,73 @@ export class TriCaster extends VideoSwitcherImpl { } return timelineObject } + public updatePreviewInput( + timelineObject: TSR.TSRTimelineObj, + previewInput: number | SpecialInput + ): TSR.TSRTimelineObj { + if (!this.isMixEffect(timelineObject)) { + // @todo: log error or throw + return timelineObject + } + ;(timelineObject.content.me as TSR.TriCasterMixEffectWithPreview).previewInput = this.getInputName(previewInput) + return timelineObject + } + public updateInput(timelineObject: TSR.TSRTimelineObj, input: number | SpecialInput): TSR.TSRTimelineObj { + if (!this.isMixEffect(timelineObject)) { + // @todo: log error or throw + return timelineObject + } + ;(timelineObject.content.me as TSR.TriCasterMixEffectInMixMode).programInput = this.getInputName(input) + return timelineObject + } public getDskTimelineObjects(_properties: DskProps): TSR.TSRTimelineObj[] { throw new Error('Method not implemented.') } - public getAuxTimelineObject(_properties: AuxProps): TSR.TSRTimelineObj { + public getAuxTimelineObject(props: AuxProps): TSR.TimelineObjTriCasterMixOutput { + return { + ...this.getBaseProperties(props), + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.MIX_OUTPUT, + source: this.getInputName(props.content.input) + } + } + } + + public updateAuxInput(timelineObject: TSR.TSRTimelineObj, input: number | SpecialInput): TSR.TSRTimelineObj { + if (!this.isAux(timelineObject)) { + // @todo: log error or throw + return timelineObject + } + timelineObject.content.source = this.getInputName(input) + return timelineObject + } + public isDveBoxes = (timelineObject: TimelineObjectCoreExt): boolean => { + // @todo: this is ugly + return ( + TSR.isTimelineObjTriCasterME(timelineObject) && + !!(timelineObject.content.me as TSR.TriCasterMixEffectInEffectMode).layers + ) + } + public getDveTimelineObject(properties: AuxProps): TSR.TSRTimelineObj { + throw new Error('Method not implemented.') + } + public updateUnpopulatedDveBoxes( + timelineObject: TSR.TSRTimelineObj, + input: number | SpecialInput + ): TSR.TSRTimelineObj { throw new Error('Method not implemented.') } + private getBaseProperties(props: TimelineObjectProps): Omit { + return { + ...TIMELINE_OBJECT_DEFAULTS, + ..._.omit(props, 'content'), + layer: TRICASTER_LAYER_PREFIX + props.layer + } + } + private getKeyers(keyers: Keyer[]): Record | undefined { if (!keyers?.length) { return @@ -98,14 +162,24 @@ export class TriCaster extends VideoSwitcherImpl { }, {}) } - private getInputName(input: number | SpecialInput | undefined) { + private getInputName(input: number | SpecialInput): TSR.TriCasterSourceName | TSR.TriCasterMixEffectName + private getInputName( + input: number | SpecialInput | undefined + ): TSR.TriCasterSourceName | TSR.TriCasterMixEffectName | undefined + private getInputName( + input: number | SpecialInput | undefined + ): TSR.TriCasterSourceName | TSR.TriCasterMixEffectName | undefined { if (typeof input === 'undefined') { return undefined } - if (typeof input === 'number') { - return `input${input}` + if (input < 1000) { + return `input${input as number}` + } + const specialInput = SPECIAL_INPUT_MAP[input] + if (specialInput) { + return specialInput } - return SPECIAL_INPUT_MAP[input] + return 'black' } private getTransition(transition: TransitionStyle | undefined) { diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts index bcc404fe..3c265f03 100644 --- a/src/tv2-common/videoSwitchers/VideoSwitcher.ts +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -22,21 +22,27 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { return this.videoSwitcherSingleton } public abstract readonly type: SwitcherType + public abstract isDsk: (timelineObject: TimelineObjectCoreExt) => boolean + public abstract isAux: (timelineObject: TimelineObjectCoreExt) => boolean + public abstract isDveBoxes: (timelineObject: TimelineObjectCoreExt) => boolean + public abstract isVideoSwitcherTimelineObject: (timelineObject: TimelineObjectCoreExt) => boolean + public abstract isMixEffect: (timelineObject: TSR.TSRTimelineObj) => boolean protected readonly config: TV2StudioConfig protected constructor(config: TV2StudioConfig) { this.config = config } - public abstract isDsk(timelineObject: TimelineObjectCoreExt): boolean - public abstract isAux(timelineObject: TimelineObjectCoreExt): boolean - public abstract updateAuxInput(timelineObject: TimelineObjectCoreExt, input: number | SpecialInput): TSR.TSRTimelineObj - public abstract isDve(timelineObject: TimelineObjectCoreExt): boolean + public abstract updateAuxInput( + timelineObject: TimelineObjectCoreExt, + input: number | SpecialInput + ): TSR.TSRTimelineObj public abstract getDveTimelineObject(properties: AuxProps): TSR.TSRTimelineObj - public abstract updateUnpopulatedDveBoxes(timelineObject: TimelineObjectCoreExt, input: number | SpecialInput): TSR.TSRTimelineObj + public abstract updateUnpopulatedDveBoxes( + timelineObject: TimelineObjectCoreExt, + input: number | SpecialInput + ): TSR.TSRTimelineObj public abstract getMixEffectTimelineObject(properties: MixEffectProps): TSR.TSRTimelineObj public abstract findMixEffectTimelineObject(timelineObjects: TSR.TSRTimelineObj[]): TSR.TSRTimelineObj | undefined - public abstract isVideoSwitcherTimelineObject(timelineObject: TSR.TSRTimelineObj): boolean - public abstract isMixEffect(timelineObject: TSR.TSRTimelineObj): boolean public abstract updateTransition( timelineObjects: TSR.TSRTimelineObj, transition: TransitionStyle, @@ -44,12 +50,9 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { ): TSR.TSRTimelineObj public abstract updatePreviewInput( timelineObject: TSR.TSRTimelineObj, - previewInput: number | SpecialInput - ): TSR.TSRTimelineObj - public abstract updateInput( - timelineObject: TSR.TSRTimelineObj, - input: number | SpecialInput + previewInput: number | SpecialInput ): TSR.TSRTimelineObj + public abstract updateInput(timelineObject: TSR.TSRTimelineObj, input: number | SpecialInput): TSR.TSRTimelineObj public abstract getDskTimelineObjects(properties: DskProps): TSR.TSRTimelineObj[] public abstract getAuxTimelineObject(properties: AuxProps): TSR.TSRTimelineObj diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index 2091779c..50c239c4 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -1,16 +1,22 @@ import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' import { TableConfigItemDSK, TimelineObjectMetaData } from 'tv2-common' -import { SwitcherMixEffectLLayer } from 'tv2-constants' +import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' +import { AtemSourceIndex } from '../../types/atem' export enum SwitcherType { ATEM = 'ATEM', TRICASTER = 'TRICASTER' } +/** Using Atem values for compatibility */ export enum SpecialInput { - ME1_PROGRAM = 'me1_program', - ME2_PROGRAM = 'me2_program', - SSRC = 'ssrc' + ME1_PROGRAM = AtemSourceIndex.Prg1, + ME2_PROGRAM = AtemSourceIndex.Prg2, + ME3_PROGRAM = AtemSourceIndex.Prg3, + ME4_PROGRAM = AtemSourceIndex.Prg4, + DVE = AtemSourceIndex.SSrc, + COLOR_GENERATOR1 = AtemSourceIndex.Col1, + COLOR_GENERATOR2 = AtemSourceIndex.Col2 // ... } @@ -24,9 +30,7 @@ export enum TransitionStyle { // ... } -export enum SwitcherLLayer { - -} +export enum SwitcherLLayer {} export const TIMELINE_OBJECT_DEFAULTS = { id: '', @@ -49,7 +53,7 @@ export interface TimelineObjectProps { type TimelineObjectEnable = TSR.TSRTimelineObj['enable'] export interface MixEffectProps extends TimelineObjectProps { - layer: SwitcherMixEffectLLayer + layer: SwitcherMixEffectLLayer content: { input?: number | SpecialInput previewInput?: number | SpecialInput @@ -83,13 +87,13 @@ export interface DskProps extends TimelineObjectProps { } export interface AuxProps extends TimelineObjectProps { + layer: SwitcherAuxLLayer content: { input: number | SpecialInput } } export interface VideoSwitcher { - isMixEffect(timelineObject: TimelineObjectCoreExt): boolean getMixEffectTimelineObject(properties: MixEffectProps): TSR.TSRTimelineObj findMixEffectTimelineObject(timelineObjects: TimelineObjectCoreExt[]): TSR.TSRTimelineObj | undefined @@ -99,29 +103,17 @@ export interface VideoSwitcher { transition: TransitionStyle, transitionDuration?: number ): TSR.TSRTimelineObj - updatePreviewInput( - timelineObject: TimelineObjectCoreExt, - previewInput: number | SpecialInput - ): TSR.TSRTimelineObj - updateInput( - timelineObject: TimelineObjectCoreExt, - input: number | SpecialInput - ): TSR.TSRTimelineObj + updatePreviewInput(timelineObject: TimelineObjectCoreExt, previewInput: number | SpecialInput): TSR.TSRTimelineObj + updateInput(timelineObject: TimelineObjectCoreExt, input: number | SpecialInput): TSR.TSRTimelineObj isDsk(timelineObject: TimelineObjectCoreExt): boolean getDskTimelineObjects(properties: DskProps): TSR.TSRTimelineObj[] - + isAux(timelineObject: TimelineObjectCoreExt): boolean getAuxTimelineObject(properties: AuxProps): TSR.TSRTimelineObj - updateAuxInput( - timelineObject: TimelineObjectCoreExt, - input: number | SpecialInput - ): TSR.TSRTimelineObj + updateAuxInput(timelineObject: TimelineObjectCoreExt, input: number | SpecialInput): TSR.TSRTimelineObj - isDve(timelineObject: TimelineObjectCoreExt): boolean + isDveBoxes(timelineObject: TimelineObjectCoreExt): boolean getDveTimelineObject(properties: AuxProps): TSR.TSRTimelineObj - updateUnpopulatedDveBoxes( - timelineObject: TimelineObjectCoreExt, - input: number | SpecialInput - ): TSR.TSRTimelineObj + updateUnpopulatedDveBoxes(timelineObject: TimelineObjectCoreExt, input: number | SpecialInput): TSR.TSRTimelineObj } diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index 7744184f..a135951c 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -195,28 +195,31 @@ export enum SwitcherMixEffectLLayer { Program = 'me_program', Clean = 'me_clean', CleanUSKEffect = 'clean_usk_effect', + Next = 'me_next', + NextJingle = 'me_next_jingle' } export enum SwitcherAuxLLayer { - AuxPGM = 'aux_pgm', + AuxProgram = 'aux_pgm', AuxClean = 'aux_clean', AuxWall = 'aux_wall', AuxAR = 'aux_ar', AuxVizOvlIn1 = 'aux_viz_ovl_in_1', AuxVenue = 'aux_venue', AuxLookahead = 'aux_lookahead', - AuxSSrc = 'aux_ssrc', + AuxDve = 'aux_dve', AuxVideoMixMinus = 'aux_video_mix_minus', - AuxServerLookahead = 'aux_server_lookahead', + AuxScreen = 'aux_screen', + AuxServerLookahead = 'aux_server_lookahead' } export enum SwitcherDveLLayer { Dve = 'dve', - DveBoxes = 'dve_boxes', + DveBoxes = 'dve_boxes' } export enum SharedATEMLLayer { - AtemAuxVideoMixMinus = 'atem_aux_video_mix_minus', + AtemAuxVideoMixMinus = 'atem_aux_video_mix_minus' } export enum SharedCasparLLayer { diff --git a/src/tv2_afvd_showstyle/actions.ts b/src/tv2_afvd_showstyle/actions.ts index b5cc81fe..53f62135 100644 --- a/src/tv2_afvd_showstyle/actions.ts +++ b/src/tv2_afvd_showstyle/actions.ts @@ -1,7 +1,7 @@ import { ActionUserData, IActionExecutionContext } from 'blueprints-integration' -import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { executeAction, ServerSelectMode } from 'tv2-common' import { CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' +import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { AFVD_DVE_GENERATOR_OPTIONS } from './helpers/content/dve' import { EvaluateCues } from './helpers/pieces/evaluateCues' import { pilotGeneratorSettingsAFVD } from './helpers/pieces/graphicPilot' @@ -44,7 +44,7 @@ export async function executeActionAFVD( ClipPending: SisyfosLLAyer.SisyfosSourceClipPending, Effekt: SisyfosLLAyer.SisyfosSourceJingle, StudioMics: SisyfosLLAyer.SisyfosGroupStudioMics - }, + } }, SelectedAdlibs: { SourceLayer: { @@ -57,7 +57,6 @@ export async function executeActionAFVD( SELECTED_ADLIB_LAYERS: [SourceLayer.SelectedServer, SourceLayer.SelectedVoiceOver] }, createJingleContent: createJingleContentAFVD, - pilotGraphicSettings: pilotGeneratorSettingsAFVD, serverActionSettings: { defaultTriggerMode: ServerSelectMode.RESUME } diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 89fd0a88..beb0099d 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -13,7 +13,6 @@ import { TSR, WithTimeline } from 'blueprints-integration' -import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { ActionCallRobotPreset, ActionClearGraphics, @@ -42,6 +41,7 @@ import { SourceInfo, SourceInfoToSourceDefinition, SourceInfoType, + SpecialInput, t, TransitionStyle, VideoSwitcher @@ -54,11 +54,14 @@ import { SharedGraphicLLayer, SharedOutputLayers, SourceType, + SwitcherAuxLLayer, + SwitcherMixEffectLLayer, TallyTags } from 'tv2-constants' import * as _ from 'underscore' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' import { SisyfosChannel, sisyfosChannels } from '../tv2_afvd_studio/sisyfosChannels' +import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { AtemSourceIndex } from '../types/atem' import { GalleryBlueprintConfig } from './helpers/config' import { NUMBER_OF_DVE_BOXES } from './helpers/content/dve' @@ -77,7 +80,7 @@ export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: In }, globalAdLibPieces: new GlobalAdLibPiecesGenerator(context).generate(), globalActions: getGlobalAdlibActionsAFVD(context.core, context.config), // @todo - baseline: getBaseline(context.config, context.videoSwitcher) // @todo + baseline: getBaseline(context, context.videoSwitcher) // @todo } } @@ -198,7 +201,7 @@ class GlobalAdLibPiecesGenerator { this.context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, priority: 1, - layer: AtemLLayer.AtemMEProgram, + layer: this.context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: info.port, transition: TransitionStyle.CUT @@ -223,10 +226,9 @@ class GlobalAdLibPiecesGenerator { content: { timelineObjects: [ this.context.videoSwitcher.getAuxTimelineObject({ - id: '', enable: { while: '1' }, priority: 1, - layer: AtemLLayer.AtemAuxAR, + layer: SwitcherAuxLLayer.AuxAR, content: { input: info.port } @@ -248,17 +250,12 @@ class GlobalAdLibPiecesGenerator { tags: [AdlibTags.ADLIB_TO_GRAPHICS_ENGINE_AUX], content: { timelineObjects: [ - literal({ - id: '', + this.context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, priority: 1, - layer: AtemLLayer.AtemAuxVizOvlIn1, + layer: SwitcherAuxLLayer.AuxVizOvlIn1, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: info.port - } + input: info.port } }) ] @@ -291,7 +288,7 @@ class GlobalAdLibPiecesGenerator { this.context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, priority: 1, - layer: AtemLLayer.AtemMEProgram, + layer: this.context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: info.port, transition: TransitionStyle.CUT @@ -326,17 +323,12 @@ class GlobalAdLibPiecesGenerator { tags: [AdlibTags.ADLIB_TO_STUDIO_SCREEN_AUX], content: { timelineObjects: [ - literal({ - id: '', + this.context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, priority: 1, - layer: AtemLLayer.AtemAuxAR, + layer: SwitcherAuxLLayer.AuxAR, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: info.port - } + input: info.port } }) ] @@ -834,94 +826,70 @@ function createRobotPresetAction(context: ICommonContext): IBlueprintActionManif } } -function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitcher): BlueprintResultBaseline { - const jingleDSK = FindDSKJingle(config) +function getBaseline( + context: ExtendedShowStyleContext, + videoSwitcher: VideoSwitcher +): BlueprintResultBaseline { + const jingleDSK = FindDSKJingle(context.config) return { timelineObjects: [ - ...CreateGraphicBaseline(config), + ...CreateGraphicBaseline(context.config), // Default timeline videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - layer: AtemLLayer.AtemMEProgram, + layer: SwitcherMixEffectLLayer.Program, content: { - input: config.studio.SwitcherSource.Default, + input: context.config.studio.SwitcherSource.Default, transition: TransitionStyle.CUT } }), videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - layer: AtemLLayer.AtemMEClean, + layer: SwitcherMixEffectLLayer.Clean, content: { - input: config.studio.SwitcherSource.Default, + input: context.config.studio.SwitcherSource.Default, transition: TransitionStyle.CUT } }), // route default outputs - literal({ - id: '', + videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - priority: 0, - layer: AtemLLayer.AtemAuxPGM, + layer: SwitcherAuxLLayer.AuxProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: AtemSourceIndex.Prg1 - } + input: SpecialInput.ME1_PROGRAM } }), - literal({ + videoSwitcher.getAuxTimelineObject({ id: '', enable: { while: '1' }, - priority: 0, - layer: AtemLLayer.AtemAuxClean, + layer: SwitcherAuxLLayer.AuxClean, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: AtemSourceIndex.Prg4 - } + input: SpecialInput.ME4_PROGRAM // @todo: this is incorrect - how to get the parity } }), - literal({ - id: '', + videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - priority: 0, - layer: AtemLLayer.AtemAuxLookahead, + layer: SwitcherAuxLLayer.AuxLookahead, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: config.studio.SwitcherSource.Default - } + input: context.config.studio.SwitcherSource.Default } }), - literal({ - id: '', + videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - priority: 0, - layer: AtemLLayer.AtemAuxSSrc, + layer: SwitcherAuxLLayer.AuxDve, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: AtemSourceIndex.SSrc - } + input: SpecialInput.DVE } }), - literal({ + videoSwitcher.getAuxTimelineObject({ id: '', enable: { while: '1' }, priority: 0, - layer: AtemLLayer.AtemAuxVideoMixMinus, + layer: SwitcherAuxLLayer.AuxVideoMixMinus, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: config.studio.SwitcherSource.MixMinusDefault - } + input: context.config.studio.SwitcherSource.MixMinusDefault } }), @@ -934,17 +902,17 @@ function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitche content: { deviceType: TSR.DeviceType.CASPARCG, type: TSR.TimelineContentTypeCasparCg.HTMLPAGE, - url: config.studio.SofieHostURL + '/countdowns/studio0/presenter' + url: context.config.studio.SofieHostURL + '/countdowns/studio0/presenter' } }), // keyers - ...CreateDSKBaseline(config, videoSwitcher), + ...CreateDSKBaseline(context.config, videoSwitcher), // ties the DSK for jingles to ME4 USK1 to have effects on CLEAN (ME4) videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - layer: AtemLLayer.AtemCleanUSKEffect, + layer: SwitcherMixEffectLLayer.CleanUSKEffect, content: { keyers: [ { @@ -964,8 +932,8 @@ function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitche deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRCPROPS, ssrcProps: { - artFillSource: config.studio.SwitcherSource.SplitArtF, - artCutSource: config.studio.SwitcherSource.SplitArtK, + artFillSource: context.config.studio.SwitcherSource.SplitArtF, + artCutSource: context.config.studio.SwitcherSource.SplitArtK, artOption: 1, artPreMultiplied: true } @@ -1081,7 +1049,7 @@ function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitche } }), - ...(config.studio.GraphicsType === 'HTML' + ...(context.config.studio.GraphicsType === 'HTML' ? [ literal({ id: '', @@ -1131,8 +1099,8 @@ function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitche ...CreateLYDBaseline('afvd'), - ...(config.showStyle.CasparCGLoadingClip && config.showStyle.CasparCGLoadingClip.length - ? [...config.mediaPlayers.map(mp => CasparPlayerClipLoadingLoop(mp.id))].map(layer => { + ...(context.config.showStyle.CasparCGLoadingClip && context.config.showStyle.CasparCGLoadingClip.length + ? [...context.config.mediaPlayers.map(mp => CasparPlayerClipLoadingLoop(mp.id))].map(layer => { return literal({ id: '', enable: { while: '1' }, @@ -1141,7 +1109,7 @@ function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitche content: { deviceType: TSR.DeviceType.CASPARCG, type: TSR.TimelineContentTypeCasparCg.MEDIA, - file: config.showStyle.CasparCGLoadingClip, + file: context.config.showStyle.CasparCGLoadingClip, loop: true } }) @@ -1155,7 +1123,7 @@ function getBaseline(config: GalleryBlueprintConfig, videoSwitcher: VideoSwitche content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CONCEPT, - concept: config.selectedGfxSetup.VcpConcept + concept: context.config.selectedGfxSetup.VcpConcept } }) ] diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index 8bf9d9e5..11751182 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -8,7 +8,6 @@ import { PieceLifespan, WithTimeline } from 'blueprints-integration' -import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { ExtendedSegmentContext, ExtendedSegmentContextImpl, @@ -20,6 +19,7 @@ import { import { SharedOutputLayers } from 'tv2-constants' import * as _ from 'underscore' import { AtemLLayer } from '../tv2_afvd_studio/layers' +import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { GalleryBlueprintConfig } from './helpers/config' import { CreateShowLifecyclePieces } from './helpers/pieces/showLifecycle' import { SourceLayer } from './layers' @@ -93,12 +93,8 @@ export function CreatePartContinuity( switcherInput: context.config.studio.SwitcherSource.Continuity, timelineObjects: [ context.videoSwitcher.getMixEffectTimelineObject({ - id: '', - enable: { - start: 0 - }, priority: 1, - layer: AtemLLayer.AtemMEProgram, + layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: context.config.studio.SwitcherSource.Continuity, transition: TransitionStyle.CUT diff --git a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts index 188f9b3a..bc4086bd 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts @@ -52,7 +52,7 @@ export async function EvaluateAdLib( }, Sisyfos: { ClipPending: SisyfosLLAyer.SisyfosSourceClipPending - }, + } }, true ) diff --git a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts index 54789a67..36f55655 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts @@ -1,6 +1,6 @@ import { CameraContent, IBlueprintPiece, PieceLifespan, TSR, WithTimeline } from 'blueprints-integration' import { CalculateTime, CueDefinitionRouting, ExtendedShowStyleContext, findSourceInfo, literal } from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' +import { SharedOutputLayers, SwitcherAuxLLayer } from 'tv2-constants' import _ = require('underscore') import { AtemLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' @@ -38,11 +38,9 @@ export function EvaluateCueRouting( studioLabel: '', switcherInput: sourceInfo.port, timelineObjects: _.compact([ - literal({ - id: '', - enable: { start: 0 }, + context.videoSwitcher.getAuxTimelineObject({ priority: 100, - layer: AtemLLayer.AtemAuxVizOvlIn1, + layer: SwitcherAuxLLayer.AuxVizOvlIn1, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.AUX, diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index a1d7c716..271e4179 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -112,7 +112,7 @@ function makeContentEVS( timelineObjects: literal([ context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, - layer: AtemLLayer.AtemMEProgram, + layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: switcherInput, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index 6a103659..01fbbfe6 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -66,7 +66,7 @@ export async function CreatePartKam( timelineObjects: [ context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, - layer: AtemLLayer.AtemMEProgram, + layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: jingleDSK.Fill, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, @@ -106,7 +106,7 @@ export async function CreatePartKam( timelineObjects: [ context.videoSwitcher.getMixEffectTimelineObject({ priority: 1, - layer: AtemLLayer.AtemMEProgram, + layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: Number(switcherInput), transition: partDefinition.transition?.style ?? TransitionStyle.CUT, diff --git a/src/tv2_afvd_showstyle/parts/server.ts b/src/tv2_afvd_showstyle/parts/server.ts index 185a085f..8d687240 100644 --- a/src/tv2_afvd_showstyle/parts/server.ts +++ b/src/tv2_afvd_showstyle/parts/server.ts @@ -21,7 +21,7 @@ export async function CreatePartServer( }, Sisyfos: { ClipPending: SisyfosLLAyer.SisyfosSourceClipPending - }, + } }) if (basePartProps.invalid) { diff --git a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts index 041510a2..7bdc1a7b 100644 --- a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts @@ -36,8 +36,8 @@ export function postProcessPieceTimelineObjects( const extraObjs: TimelineObjectCoreExt[] = [] const atemMeObjs = piece.content.timelineObjects.filter( - obj => - context.videoSwitcher.isMixEffect(obj) || context.videoSwitcher.isDsk(obj)) + obj => context.videoSwitcher.isMixEffect(obj) || context.videoSwitcher.isDsk(obj) + ) _.each(atemMeObjs, tlObj => { if (tlObj.layer === AtemLLayer.AtemMEProgram || tlObj.classes?.includes(ControlClasses.MixMinusOverrideDsk)) { if (!tlObj.id) { @@ -48,6 +48,7 @@ export function postProcessPieceTimelineObjects( } // Basic clone of every object to AtemMEClean + // @todo: this can probably be replaced by some TriCaster feature(?) const cleanObj = _.clone(tlObj) // Note: shallow clone cleanObj.layer = AtemLLayer.AtemMEClean cleanObj.id = '' // Force new id diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index e0ba84b9..462dacd7 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -5,13 +5,14 @@ import { IStudioContext, TSR } from 'blueprints-integration' -import { ExtendedStudioContext, literal, TransitionStyle } from 'tv2-common' +import { ExtendedStudioContext, literal, SpecialInput, TransitionStyle } from 'tv2-common' import * as _ from 'underscore' -import { SharedGraphicLLayer } from '../tv2-constants' +import { SharedGraphicLLayer, SwitcherAuxLLayer, SwitcherMixEffectLLayer } from '../tv2-constants' import { AtemSourceIndex } from '../types/atem' import { GalleryStudioConfig } from './helpers/config' import { AtemLLayer, SisyfosLLAyer } from './layers' import { sisyfosChannels } from './sisyfosChannels' +import { GALLERY_UNIFORM_CONFIG } from './uniformConfig' function filterMappings( input: BlueprintMappings, @@ -28,19 +29,11 @@ function filterMappings( return result } -function convertMappings(input: BlueprintMappings, func: (k: string, v: BlueprintMapping) => T): T[] { - return _.map(_.keys(input), k => func(k, input[k])) -} export function getBaseline(coreContext: IStudioContext): BlueprintResultBaseline { - const context = new ExtendedStudioContext(coreContext) + const context = new ExtendedStudioContext(coreContext, GALLERY_UNIFORM_CONFIG) const mappings = coreContext.getStudioMappings() - const atemMeMappings = filterMappings( - mappings, - (_id, v) => v.device === TSR.DeviceType.ATEM && (v as any).mappingType === TSR.MappingAtemType.MixEffect - ) - const sisyfosMappings = filterMappings( mappings, (_id, v) => v.device === TSR.DeviceType.SISYFOS && (v as any).mappingType !== TSR.MappingSisyfosType.CHANNELS @@ -68,16 +61,6 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin return { timelineObjects: [ - ...convertMappings(atemMeMappings, id => - context.videoSwitcher.getMixEffectTimelineObject({ - layer: id, - enable: { while: '1' }, - content: { - input: AtemSourceIndex.Bars, - transition: TransitionStyle.CUT - } - }) - ), literal({ id: '', enable: { @@ -94,35 +77,23 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin }), // have ATEM output default still image - literal({ - id: '', + context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - priority: 0, - layer: AtemLLayer.AtemAuxPGM, + layer: SwitcherAuxLLayer.AuxProgram, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: AtemSourceIndex.Prg1 - } + input: SpecialInput.ME1_PROGRAM } }), - literal({ - id: '', + context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - priority: 0, - layer: AtemLLayer.AtemAuxLookahead, + layer: SwitcherAuxLLayer.AuxLookahead, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: AtemSourceIndex.Prg1 - } + input: SpecialInput.ME1_PROGRAM } }), context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - layer: AtemLLayer.AtemMEProgram, + layer: SwitcherMixEffectLLayer.Program, content: { input: AtemSourceIndex.MP1, transition: TransitionStyle.CUT diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index 071d5d2b..7cdc69e7 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -1,13 +1,26 @@ import { BlueprintMapping, BlueprintMappings, LookaheadMode, TSR } from 'blueprints-integration' import { AbstractLLayerServerEnable, + ATEM_LAYER_PREFIX, CasparPlayerClip, CasparPlayerClipLoadingLoop, - GetDSKMappings, + getAtemDskMappings, + getTriCasterDskMappings, literal, - SisyfosPlayerClip + prefixLayers, + SisyfosPlayerClip, + TRICASTER_CLEAN_ME, + TRICASTER_DEVICE_ID, + TRICASTER_DVE_ME, + TRICASTER_LAYER_PREFIX } from 'tv2-common' -import { AbstractLLayer, RobotCameraLayer } from 'tv2-constants' +import { + AbstractLLayer, + RobotCameraLayer, + SwitcherAuxLLayer, + SwitcherDveLLayer, + SwitcherMixEffectLLayer +} from 'tv2-constants' import { ATEMModel } from '../../types/atem' import { GalleryStudioConfig } from '../helpers/config' import { AtemLLayer, CasparLLayer, GraphicLLayer, SisyfosLLAyer } from '../layers' @@ -565,195 +578,200 @@ export const MAPPINGS_GRAPHICS: BlueprintMappings = { }) } -export const MAPPINGS_ATEM: BlueprintMappings = { - [AtemLLayer.AtemMEProgram]: literal({ +export const MAPPINGS_ATEM: Record = prefixLayers(ATEM_LAYER_PREFIX, { + [SwitcherMixEffectLLayer.Program]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 0 // 0 = ME1 - }), - [AtemLLayer.AtemMEClean]: literal({ + }, + [SwitcherMixEffectLLayer.Clean]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 3 // 3 = ME4 - }), - [AtemLLayer.AtemCleanUSKEffect]: literal({ + }, + [SwitcherMixEffectLLayer.CleanUSKEffect]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 3 // 3 = ME4 - }), - [AtemLLayer.AtemAuxPGM]: literal({ + }, + [SwitcherAuxLLayer.AuxProgram]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.Auxilliary, index: 0 // 0 = out 1 - }), - [AtemLLayer.AtemAuxClean]: literal({ + }, + [SwitcherAuxLLayer.AuxClean]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.Auxilliary, index: 1 // 1 = out 2 - }), - [AtemLLayer.AtemAuxAR]: literal({ + }, + [SwitcherAuxLLayer.AuxAR]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 3 // 3 = out 4 - }), - [AtemLLayer.AtemAuxVizOvlIn1]: literal({ + }, + [SwitcherAuxLLayer.AuxVizOvlIn1]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 4 // 4 = out 5 - }), - [AtemLLayer.AtemAuxVideoMixMinus]: literal({ + }, + [SwitcherAuxLLayer.AuxVideoMixMinus]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 6 // 6 = out 7 - }), - [AtemLLayer.AtemAuxLookahead]: literal({ + }, + [SwitcherAuxLLayer.AuxLookahead]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 10 // 10 = out 11 - }), - [AtemLLayer.AtemAuxSSrc]: literal({ + }, + [SwitcherAuxLLayer.AuxDve]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 11 // 11 = out 12 - }), - ...GetDSKMappings(ATEMModel.CONSTELLATION_8K_UHD_MODE), - [AtemLLayer.AtemSSrcArt]: literal({ + }, + ...getAtemDskMappings(ATEMModel.CONSTELLATION_8K_UHD_MODE), + [SwitcherDveLLayer.Dve]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.SuperSourceProperties, index: 0 // 0 = SS - }), - [AtemLLayer.AtemSSrcDefault]: literal({ + }, + [SwitcherDveLLayer.DveBoxes]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, // TODO - verify mappingType: TSR.MappingAtemType.SuperSourceBox, index: 0 // 0 = SS - }), - [AtemLLayer.AtemMP1]: literal({ + }, + [AtemLLayer.AtemMP1]: { + // @todo device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MediaPlayer, index: 0 - }) -} + } +}) -export const MAPPINGS_TRICASTER: BlueprintMappings = { - [AtemLLayer.AtemMEProgram]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingAtemType.MixEffect, - index: 0 // 0 = ME1 - }), - [AtemLLayer.AtemMEClean]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingAtemType.MixEffect, - index: 3 // 3 = ME4 - }), - [AtemLLayer.AtemCleanUSKEffect]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingAtemType.MixEffect, - index: 3 // 3 = ME4 - }), - [AtemLLayer.AtemAuxPGM]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingAtemType.Auxilliary, - index: 0 // 0 = out 1 - }), - [AtemLLayer.AtemAuxClean]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingAtemType.Auxilliary, - index: 1 // 1 = out 2 - }), - [AtemLLayer.AtemAuxAR]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingAtemType.Auxilliary, - index: 3 // 3 = out 4 - }), - [AtemLLayer.AtemAuxVizOvlIn1]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingAtemType.Auxilliary, - index: 4 // 4 = out 5 - }), - [AtemLLayer.AtemAuxVideoMixMinus]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingAtemType.Auxilliary, - index: 6 // 6 = out 7 - }), - [AtemLLayer.AtemAuxLookahead]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingAtemType.Auxilliary, - index: 10 // 10 = out 11 - }), - [AtemLLayer.AtemAuxSSrc]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingAtemType.Auxilliary, - index: 11 // 11 = out 12 - }), - ...GetDSKMappings(ATEMModel.CONSTELLATION_8K_UHD_MODE), - [AtemLLayer.AtemSSrcArt]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingAtemType.SuperSourceProperties, - index: 0 // 0 = SS - }), - [AtemLLayer.AtemSSrcDefault]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.WHEN_CLEAR, // TODO - verify - mappingType: TSR.MappingAtemType.SuperSourceBox, - index: 0 // 0 = SS - }), - [AtemLLayer.AtemMP1]: literal({ - device: TSR.DeviceType.ATEM, - deviceId: 'atem0', - lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingAtemType.MediaPlayer, - index: 0 - }) -} +export const MAPPINGS_TRICASTER: Record = prefixLayers( + TRICASTER_LAYER_PREFIX, + { + [SwitcherMixEffectLLayer.Program]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.ME, + name: 'main' + }, + [SwitcherMixEffectLLayer.Clean]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.ME, + name: TRICASTER_CLEAN_ME + }, + [SwitcherMixEffectLLayer.CleanUSKEffect]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.ME, + name: TRICASTER_CLEAN_ME + }, + [SwitcherAuxLLayer.AuxProgram]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix1' + }, + [SwitcherAuxLLayer.AuxClean]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix2' + }, + [SwitcherAuxLLayer.AuxAR]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix4' + }, + [SwitcherAuxLLayer.AuxVizOvlIn1]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix5' + }, + [SwitcherAuxLLayer.AuxVideoMixMinus]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix7' + }, + [SwitcherAuxLLayer.AuxLookahead]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix8' + }, + [SwitcherAuxLLayer.AuxDve]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix8' // @todo: do we have too few auxes?! + }, + [SwitcherDveLLayer.Dve]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.ME, + name: TRICASTER_DVE_ME + }, + [SwitcherDveLLayer.DveBoxes]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.ME, + name: TRICASTER_DVE_ME + }, + ...getTriCasterDskMappings() + // @todo: are we using media players in the TriCaster? + // [AtemLLayer.AtemMP1]: { + // device: TSR.DeviceType.TRICASTER, + // deviceId: TRICASTER_DEVICE_ID, + // lookahead: LookaheadMode.NONE, + // mappingType: TSR.MappingAtemType.MediaPlayer, + // index: 0 + // } + } +) export const MAPPINGS_TELEMETRICS: BlueprintMappings = { [RobotCameraLayer.TELEMETRICS]: literal({ diff --git a/src/tv2_afvd_studio/onTimelineGenerate.ts b/src/tv2_afvd_studio/onTimelineGenerate.ts index 08729670..33302a58 100644 --- a/src/tv2_afvd_studio/onTimelineGenerate.ts +++ b/src/tv2_afvd_studio/onTimelineGenerate.ts @@ -8,6 +8,7 @@ import { } from 'blueprints-integration' import { ExtendedTimelineContext, onTimelineGenerate, PieceMetaData } from 'tv2-common' import { CasparLLayer, SisyfosLLAyer } from './layers' +import { GALLERY_UNIFORM_CONFIG } from './uniformConfig' export function onTimelineGenerateAFVD( coreContext: ITimelineEventContext, @@ -16,7 +17,7 @@ export function onTimelineGenerateAFVD( previousPartEndState: PartEndState | undefined, resolvedPieces: Array> ): Promise { - const context = new ExtendedTimelineContext(coreContext) + const context = new ExtendedTimelineContext(coreContext, GALLERY_UNIFORM_CONFIG) return onTimelineGenerate(context, timeline, previousPersistentState, previousPartEndState, resolvedPieces, { Caspar: { ClipPending: CasparLLayer.CasparPlayerClipPending diff --git a/src/tv2_afvd_studio/uniformConfig.ts b/src/tv2_afvd_studio/uniformConfig.ts index f2519bc5..6a2c5068 100644 --- a/src/tv2_afvd_studio/uniformConfig.ts +++ b/src/tv2_afvd_studio/uniformConfig.ts @@ -1,8 +1,10 @@ -import { UniformConfig } from "tv2-common"; -import { SwitcherMixEffectLLayer } from "tv2-constants"; +import { UniformConfig } from 'tv2-common' +import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' export const GALLERY_UNIFORM_CONFIG: UniformConfig = { - SwitcherLLayers: { - PrimaryMixEffect: SwitcherMixEffectLLayer.Program - } + SwitcherLLayers: { + PrimaryMixEffect: SwitcherMixEffectLLayer.Program, + JingleUskMixEffect: SwitcherMixEffectLLayer.CleanUSKEffect, + ProgramAux: SwitcherAuxLLayer.AuxProgram + } } diff --git a/src/tv2_offtube_showstyle/actions.ts b/src/tv2_offtube_showstyle/actions.ts index 00f950b3..a5f81232 100644 --- a/src/tv2_offtube_showstyle/actions.ts +++ b/src/tv2_offtube_showstyle/actions.ts @@ -1,9 +1,8 @@ import { ActionUserData, IActionExecutionContext } from 'blueprints-integration' -import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' import { executeAction, ServerSelectMode } from 'tv2-common' import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' +import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' import { OFFTUBE_DVE_GENERATOR_OPTIONS } from './content/OfftubeDVEContent' -import { pilotGeneratorSettingsOfftube } from './cues/OfftubeGraphics' import { createJingleContentOfftube } from './cues/OfftubeJingle' import { OfftubeEvaluateCues } from './helpers/EvaluateCues' import { OfftubeOutputLayers, OfftubeSourceLayer } from './layers' @@ -50,7 +49,7 @@ export async function executeActionOfftube( ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending, Effekt: OfftubeSisyfosLLayer.SisyfosSourceJingle, StudioMics: OfftubeSisyfosLLayer.SisyfosGroupStudioMics - }, + } }, SelectedAdlibs: { SourceLayer: { @@ -63,7 +62,6 @@ export async function executeActionOfftube( SELECTED_ADLIB_LAYERS }, createJingleContent: createJingleContentOfftube, - pilotGraphicSettings: pilotGeneratorSettingsOfftube, serverActionSettings: { defaultTriggerMode: ServerSelectMode.RESET } diff --git a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts index d6d5ee92..892c9fd4 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts @@ -60,7 +60,7 @@ export async function OfftubeEvaluateAdLib( }, Sisyfos: { ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending - }, + } }, true ) diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts index 23be27af..8cfd5f58 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts @@ -8,16 +8,10 @@ import { GraphicInternalOrPilot, GraphicIsInternal, GraphicIsPilot, - PartDefinition, - PilotGeneratorSettings + PartDefinition } from 'tv2-common' -import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeBlueprintConfig } from '../helpers/config' -export const pilotGeneratorSettingsOfftube: PilotGeneratorSettings = { - ProgramLayer: OfftubeAtemLLayer.AtemMEClean -} - export function OfftubeEvaluateGrafikCaspar( context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], @@ -33,7 +27,6 @@ export function OfftubeEvaluateGrafikCaspar( context, partId, parsedCue, - settings: pilotGeneratorSettingsOfftube, adlib, segmentExternalId: partDefinition.segmentExternalId }) diff --git a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts index 7d93ffca..47fd70e3 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts @@ -7,7 +7,7 @@ import { WithTimeline } from 'blueprints-integration' import { CueDefinitionPgmClean, ExtendedSegmentContext, findSourceInfo, literal, SourceInfo } from 'tv2-common' -import { SharedOutputLayers, SourceType } from 'tv2-constants' +import { SharedOutputLayers, SourceType, SwitcherAuxLLayer } from 'tv2-constants' import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeSourceLayer } from '../layers' @@ -43,17 +43,11 @@ export function OfftubeEvaluatePgmClean( lifespan: PieceLifespan.OutOnShowStyleEnd, content: literal>({ timelineObjects: literal([ - literal({ - id: '', + context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - priority: 0, - layer: OfftubeAtemLLayer.AtemAuxClean, + layer: SwitcherAuxLLayer.AuxClean, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: sourceInfo.port - } + input: sourceInfo.port } }) ]) diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 9dbafef7..3b4b1932 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -11,7 +11,6 @@ import { PlaylistTimingType, TSR } from 'blueprints-integration' -import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' import { ActionClearGraphics, ActionCommentatorSelectDVE, @@ -56,12 +55,15 @@ import { SharedSisyfosLLayer, SharedSourceLayers, SourceType, + SwitcherAuxLLayer, + SwitcherMixEffectLLayer, TallyTags } from 'tv2-constants' import * as _ from 'underscore' import { OfftubeBlueprintConfig } from '../tv2_offtube_showstyle/helpers/config' import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' import { SisyfosChannel, sisyfosChannels } from '../tv2_offtube_studio/sisyfosChannels' +import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' import { AtemSourceIndex } from '../types/atem' import { NUMBER_OF_DVE_BOXES } from './content/OfftubeDVEContent' import { OfftubeOutputLayers, OfftubeSourceLayer } from './layers' @@ -586,7 +588,7 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche ...CreateGraphicBaseline(config), // Default timeline videoSwitcher.getMixEffectTimelineObject({ - layer: OfftubeAtemLLayer.AtemMEClean, + layer: SwitcherMixEffectLLayer.Clean, enable: { while: '1' }, content: { input: config.studio.SwitcherSource.Default, @@ -595,37 +597,25 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche }), videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - layer: OfftubeAtemLLayer.AtemMENext, + layer: SwitcherMixEffectLLayer.Next, content: { previewInput: config.studio.SwitcherSource.Default } }), // route default outputs - literal({ - id: '', + videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - priority: 0, - layer: OfftubeAtemLLayer.AtemAuxClean, + layer: SwitcherAuxLLayer.AuxClean, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: AtemSourceIndex.Prg2 - } + input: SpecialInput.ME2_PROGRAM } }), - literal({ - id: '', + videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - priority: 0, - layer: OfftubeAtemLLayer.AtemAuxScreen, + layer: SwitcherAuxLLayer.AuxScreen, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: config.studio.SwitcherSource.Loop - } + input: config.studio.SwitcherSource.Loop } }), literal({ @@ -789,7 +779,7 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche // Route ME 2 PGM to ME 1 PGM videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - layer: OfftubeAtemLLayer.AtemMEProgram, + layer: SwitcherMixEffectLLayer.Program, content: { input: SpecialInput.ME2_PROGRAM } diff --git a/src/tv2_offtube_showstyle/getSegment.ts b/src/tv2_offtube_showstyle/getSegment.ts index 5574d7e9..db213172 100644 --- a/src/tv2_offtube_showstyle/getSegment.ts +++ b/src/tv2_offtube_showstyle/getSegment.ts @@ -7,7 +7,6 @@ import { PieceLifespan, WithTimeline } from 'blueprints-integration' -import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' import { ExtendedSegmentContextImpl, ExtendedShowStyleContext, @@ -17,6 +16,7 @@ import { } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import * as _ from 'underscore' +import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' import { OfftubeBlueprintConfig } from './helpers/config' import { OfftubeSourceLayer } from './layers' import { OfftubeCreatePartDVE } from './parts/OfftubeDVE' diff --git a/src/tv2_offtube_showstyle/onTimelineGenerate.ts b/src/tv2_offtube_showstyle/onTimelineGenerate.ts index 09327c8a..a64d0f0d 100644 --- a/src/tv2_offtube_showstyle/onTimelineGenerate.ts +++ b/src/tv2_offtube_showstyle/onTimelineGenerate.ts @@ -7,7 +7,6 @@ import { TimelinePersistentState, TSR } from 'blueprints-integration' -import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' import { disablePilotWipeAfterJingle, ExtendedTimelineContext, @@ -18,6 +17,7 @@ import { } from 'tv2-common' import { SharedGraphicLLayer, TallyTags } from 'tv2-constants' import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' +import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' export function onTimelineGenerateOfftube( coreContext: ITimelineEventContext, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index 8fe8af6c..04182a7e 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -23,7 +23,6 @@ import { TransitionStyle } from 'tv2-common' import { SharedOutputLayers, TallyTags } from 'tv2-constants' -import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' @@ -66,7 +65,7 @@ export async function OfftubeCreatePartKam( start: 0 }, priority: 1, - layer: OfftubeAtemLLayer.AtemMEClean, + layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: jingleDSK.Fill, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, @@ -109,7 +108,7 @@ export async function OfftubeCreatePartKam( start: 0 }, priority: 1, - layer: OfftubeAtemLLayer.AtemMEClean, + layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: Number(switcherInput), transition: partDefinition.transition?.style ?? TransitionStyle.CUT, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts index 90920e83..a2f6fb18 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts @@ -28,7 +28,7 @@ export async function OfftubeCreatePartServer( }, Sisyfos: { ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending - }, + } }) if (basePartProps.invalid) { @@ -63,7 +63,7 @@ export async function OfftubeCreatePartServer( }, Sisyfos: { ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending - }, + } }, false ) diff --git a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts b/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts index 5d12b955..afe70c9d 100644 --- a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts @@ -40,7 +40,10 @@ export function postProcessPieceTimelineObjects( (obj.content.type === TSR.TimelineContentTypeAtem.ME || obj.content.type === TSR.TimelineContentTypeAtem.DSK) ) _.each(atemMeObjs, tlObj => { - if (tlObj.layer === OfftubeAtemLLayer.AtemMEClean || tlObj.classes?.includes(ControlClasses.MixMinusOverrideDsk)) { + if ( + tlObj.layer === OfftubeAtemLLayer.AtemMEClean || + tlObj.classes?.includes(ControlClasses.MixMinusOverrideDsk) + ) { if (!tlObj.id) { tlObj.id = context.core.getHashId(OfftubeAtemLLayer.AtemMEClean, true) } diff --git a/src/tv2_offtube_studio/getBaseline.ts b/src/tv2_offtube_studio/getBaseline.ts index 6a339b4f..da2a8fd9 100644 --- a/src/tv2_offtube_studio/getBaseline.ts +++ b/src/tv2_offtube_studio/getBaseline.ts @@ -6,11 +6,13 @@ import { TSR } from 'blueprints-integration' import { ExtendedStudioContext, literal, SpecialInput, TransitionStyle } from 'tv2-common' +import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' import * as _ from 'underscore' import { AtemSourceIndex } from '../types/atem' import { OfftubeStudioBlueprintConfig } from './helpers/config' import { OfftubeAtemLLayer, OfftubeSisyfosLLayer } from './layers' import { sisyfosChannels } from './sisyfosChannels' +import { QBOX_UNIFORM_CONFIG } from './uniformConfig' function filterMappings( input: BlueprintMappings, @@ -29,7 +31,7 @@ function filterMappings( } export function getBaseline(coreContext: IStudioContext): BlueprintResultBaseline { - const context = new ExtendedStudioContext(coreContext) + const context = new ExtendedStudioContext(coreContext, QBOX_UNIFORM_CONFIG) const mappings = coreContext.getStudioMappings() const sisyfosMappings = filterMappings(mappings, (_id, v) => v.device === TSR.DeviceType.SISYFOS) @@ -75,7 +77,7 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin // have ATEM output default still image context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - layer: OfftubeAtemLLayer.AtemMEClean, + layer: SwitcherMixEffectLLayer.Clean, content: { input: context.config.studio.IdleSource, transition: TransitionStyle.CUT @@ -85,22 +87,16 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin // Route ME 2 PGM to ME 1 PGM context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - layer: OfftubeAtemLLayer.AtemMEProgram, + layer: SwitcherMixEffectLLayer.Program, content: { input: SpecialInput.ME2_PROGRAM } }), - literal({ - id: '', + context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - priority: 0, - layer: OfftubeAtemLLayer.AtemAuxClean, + layer: SwitcherAuxLLayer.AuxClean, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: AtemSourceIndex.Prg2 - } + input: SpecialInput.ME2_PROGRAM } }) ] diff --git a/src/tv2_offtube_studio/layers.ts b/src/tv2_offtube_studio/layers.ts index 21268e3e..d21fff02 100644 --- a/src/tv2_offtube_studio/layers.ts +++ b/src/tv2_offtube_studio/layers.ts @@ -59,7 +59,7 @@ export enum AtemLLayer { AtemSSrcDefault = 'atem_supersource_default', AtemAuxClean = 'atem_aux_clean', AtemAuxScreen = 'atem_aux_screen', - AtemAuxServerLookahead = 'atem_aux_server_lookahead', + AtemAuxServerLookahead = 'atem_aux_server_lookahead' } // tslint:disable-next-line: variable-name diff --git a/src/tv2_offtube_studio/migrations/mappings-defaults.ts b/src/tv2_offtube_studio/migrations/mappings-defaults.ts index a16a908c..b59eba1f 100644 --- a/src/tv2_offtube_studio/migrations/mappings-defaults.ts +++ b/src/tv2_offtube_studio/migrations/mappings-defaults.ts @@ -3,7 +3,7 @@ import { AbstractLLayerServerEnable, CasparPlayerClip, CasparPlayerClipLoadingLoop, - GetDSKMappings, + getAtemDskMappings, literal } from 'tv2-common' import { AbstractLLayer } from 'tv2-constants' @@ -486,7 +486,7 @@ const MAPPINGS_ATEM: BlueprintMappings = { mappingType: TSR.MappingAtemType.MixEffect, index: 0 // 0 = ME1 }), - ...GetDSKMappings(ATEMModel.PRODUCTION_STUDIO_4K_2ME), + ...getAtemDskMappings(ATEMModel.PRODUCTION_STUDIO_4K_2ME), [OfftubeAtemLLayer.AtemAuxClean]: literal({ device: TSR.DeviceType.ATEM, deviceId: 'atem0', diff --git a/src/tv2_offtube_studio/uniformConfig.ts b/src/tv2_offtube_studio/uniformConfig.ts index 70f9ba21..7f8e3480 100644 --- a/src/tv2_offtube_studio/uniformConfig.ts +++ b/src/tv2_offtube_studio/uniformConfig.ts @@ -1,9 +1,10 @@ -import { UniformConfig } from "tv2-common"; -import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from "tv2-constants"; +import { UniformConfig } from 'tv2-common' +import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' export const QBOX_UNIFORM_CONFIG: UniformConfig = { - SwitcherLLayers: { - PrimaryMixEffect: SwitcherMixEffectLLayer.Clean, - ServerLookaheadAux: SwitcherAuxLLayer.AuxServerLookahead - } + SwitcherLLayers: { + PrimaryMixEffect: SwitcherMixEffectLLayer.Clean, + ServerLookaheadAux: SwitcherAuxLLayer.AuxServerLookahead, + JingleNextMixEffect: SwitcherMixEffectLLayer.NextJingle + } } From a0b2b7e1031c82096f07a5a30d52c3b9160a83c6 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 7 Feb 2023 09:22:08 +0100 Subject: [PATCH 15/86] wip: SOF-1260 implement getOnAirTimelineObjects and do more teardown --- src/__mocks__/context.ts | 4 +- src/tv2-common/actions/executeAction.ts | 60 ++---- src/tv2-common/content/dve.ts | 12 +- src/tv2-common/content/jingle.ts | 26 +-- src/tv2-common/content/server.ts | 18 +- src/tv2-common/cues/ekstern.ts | 12 +- src/tv2-common/cues/lyd.ts | 6 +- src/tv2-common/cues/mixMinus.ts | 2 +- src/tv2-common/helpers/abPlayback.ts | 17 +- src/tv2-common/helpers/dsk.ts | 76 +++++--- .../graphics/caspar/HtmlInternalGraphic.ts | 5 +- .../htmlPilotGraphicGenerator.spec.ts | 4 +- .../caspar/htmlPilotGraphicGenerator.ts | 10 +- .../graphics/viz/VizInternalGraphic.ts | 5 +- .../graphics/viz/VizPilotGraphicGenerator.ts | 12 +- src/tv2-common/layers/timelineLayers.ts | 4 +- src/tv2-common/onTimelineGenerate.ts | 27 --- src/tv2-common/parts/effekt.ts | 8 +- src/tv2-common/pieces/adlibServer.ts | 5 - src/tv2-common/showstyle/context.ts | 2 +- src/tv2-common/studio/context.ts | 2 +- src/tv2-common/uniformConfig.ts | 10 +- src/tv2-common/videoSwitchers/Atem.ts | 12 +- src/tv2-common/videoSwitchers/TriCaster.ts | 10 +- .../videoSwitchers/VideoSwitcher.ts | 84 +++++++- src/tv2-common/videoSwitchers/types.ts | 6 +- src/tv2-constants/enums.ts | 13 +- src/tv2_afvd_showstyle/actions.ts | 3 - src/tv2_afvd_showstyle/getRundown.ts | 11 +- src/tv2_afvd_showstyle/getSegment.ts | 7 +- src/tv2_afvd_showstyle/helpers/content/dve.ts | 3 +- .../pieces/__tests__/grafikViz.spec.ts | 8 +- .../helpers/pieces/__tests__/telefon.spec.ts | 7 +- .../helpers/pieces/adlib.ts | 2 +- .../helpers/pieces/graphicPilot.ts | 16 +- .../helpers/pieces/jingle.ts | 2 +- .../helpers/pieces/routing.ts | 7 +- src/tv2_afvd_showstyle/parts/evs.ts | 4 +- src/tv2_afvd_showstyle/parts/kam.ts | 7 +- .../postProcessTimelineObjects.ts | 182 ------------------ .../__tests__/graphics.spec.ts | 4 +- src/tv2_afvd_studio/uniformConfig.ts | 4 +- src/tv2_offtube_showstyle/actions.ts | 2 - .../content/OfftubeDVEContent.ts | 3 +- .../cues/OfftubeJingle.ts | 2 +- .../cues/OfftubePgmClean.ts | 2 - src/tv2_offtube_showstyle/getRundown.ts | 5 - src/tv2_offtube_showstyle/getSegment.ts | 6 +- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 32 +-- .../postProcessTimelineObjects.ts | 110 ----------- src/tv2_offtube_studio/layers.ts | 9 +- .../migrations/mappings-defaults.ts | 13 +- src/tv2_offtube_studio/uniformConfig.ts | 3 +- 53 files changed, 266 insertions(+), 640 deletions(-) delete mode 100644 src/tv2_afvd_showstyle/postProcessTimelineObjects.ts delete mode 100644 src/tv2_offtube_showstyle/postProcessTimelineObjects.ts diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index 79a15ff5..e058cf2f 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -49,6 +49,7 @@ import { } from '../tv2_afvd_showstyle/helpers/config' import { preprocessConfig as parseStudioConfigAFVD, StudioConfig } from '../tv2_afvd_studio/helpers/config' import mappingsDefaultsAFVD from '../tv2_afvd_studio/migrations/mappings-defaults' +import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' export function getHash(str: string): string { const hash = crypto.createHash('sha1') @@ -672,7 +673,8 @@ export function makeMockGalleryContext(overrides?: ConfigOverrides) { core: mockCoreContext, // @todo: this is awful, fix it perhaps by replacing defaultShowStyleConfig and defaultStudioConfig with preparsed config?! config, - videoSwitcher: VideoSwitcherImpl.getVideoSwitcher(config) // new MockVideoSwitcher() + uniformConfig: GALLERY_UNIFORM_CONFIG, + videoSwitcher: VideoSwitcherImpl.getVideoSwitcher(mockCoreContext, config, GALLERY_UNIFORM_CONFIG) // new MockVideoSwitcher() } return mockContext } diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 7dc0912b..40af01a9 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -8,10 +8,10 @@ import { IBlueprintPart, IBlueprintPiece, IBlueprintPieceDB, - IBlueprintPieceGeneric, IBlueprintPieceInstance, PieceLifespan, SplitsContent, + TimelineObjectCoreExt, TSR, VTContent, WithTimeline @@ -105,11 +105,6 @@ export interface ActionExecutionSettings< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase > { - postProcessPieceTimelineObjects: ( - context: ExtendedShowStyleContext, - piece: IBlueprintPieceGeneric, - isAdlib: boolean - ) => void EvaluateCues: ( context: ExtendedShowStyleContext, part: IBlueprintPart, @@ -474,10 +469,6 @@ async function executeActionSelectServerClip< return } - if (activeServerPiece.content && activeServerPiece.content.timelineObjects) { - settings.postProcessPieceTimelineObjects(context, activeServerPiece, false) - } - await context.core.queuePart(part, [ activeServerPiece as IBlueprintPiece, // @todo: get rid of these casts serverDataStore as IBlueprintPiece, @@ -659,17 +650,14 @@ async function cutServerToBox< const existingSisyfosObj = (currentServer.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( obj => obj.layer === settings.LLayer.Sisyfos.ClipPending ) as TSR.TimelineObjSisyfosChannel & TimelineBlueprintExt - // Find SSRC object in DVE piece - const ssrcObjIndex = newDvePiece.content?.timelineObjects - ? (newDvePiece.content?.timelineObjects as TSR.TSRTimelineObj[]).findIndex( - obj => obj.layer === settings.LLayer.VideoSwitcher.Dve - ) - : -1 - + // Find DVE Boxes object in DVE piece + const dveBoxesObj = currentServer.piece.content.timelineObjects.find(context.videoSwitcher.isDveBoxes) as + | TimelineBlueprintExt + | undefined if ( !existingCasparObj || !existingSisyfosObj || - ssrcObjIndex === -1 || + !dveBoxesObj || !existingCasparObj.metaData || !existingCasparObj.metaData.mediaPlayerSession ) { @@ -677,14 +665,11 @@ async function cutServerToBox< return newDvePiece } - const ssrcObj = newDvePiece.content.timelineObjects[ssrcObjIndex] as TSR.TSRTimelineObj & TimelineBlueprintExt - - ssrcObj.metaData = { - ...ssrcObj.metaData, + dveBoxesObj.metaData = { + ...dveBoxesObj.metaData, mediaPlayerSession: existingCasparObj.metaData.mediaPlayerSession } - newDvePiece.content.timelineObjects[ssrcObjIndex] = ssrcObj newDvePiece.content.timelineObjects.push(EnableServer(existingCasparObj.metaData.mediaPlayerSession)) newDvePiece.metaData.mediaPlayerSessions = [existingCasparObj.metaData.mediaPlayerSession] @@ -861,8 +846,6 @@ async function startNewDVELayout< replacePieceInstancesOrQueue: { activeDVE?: string; dataStore?: string } | 'queue', nextTag: string ) { - settings.postProcessPieceTimelineObjects(context, dvePiece, false) - const dveDataStore: IBlueprintPiece | undefined = settings.SelectedAdlibs.SourceLayer.DVE ? { externalId, @@ -998,8 +981,6 @@ async function executeActionSelectJingle< ] } - settings.postProcessPieceTimelineObjects(context, piece, false) - const part: IBlueprintPart = { externalId, title: `JINGLE ${userData.clip}`, @@ -1072,22 +1053,19 @@ async function executeActionCutToCamera< }, tags: [GetTagForKam(userData.sourceDefinition)], content: { - timelineObjects: _.compact([ - context.videoSwitcher.getMixEffectTimelineObject({ + timelineObjects: [ + ...context.videoSwitcher.getOnAirTimelineObjects({ priority: 1, - layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: sourceInfoCam.port, transition: TransitionStyle.CUT } }), ...camSisyfos - ]) + ] } } - settings.postProcessPieceTimelineObjects(context, kamPiece, false) - if (userData.queue || serverInCurrentPart) { await context.core.queuePart(part, [ kamPiece, @@ -1207,22 +1185,20 @@ async function executeActionCutToRemote< tags: [GetTagForLive(userData.sourceDefinition)], content: { timelineObjects: _.compact([ - context.videoSwitcher.getMixEffectTimelineObject({ + ...context.videoSwitcher.getOnAirTimelineObjects({ enable: { while: '1' }, priority: 1, - layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: sourceInfo.port, transition: TransitionStyle.CUT - } + }, + mixMinusInput: null }), ...eksternSisyfos ]) } } - settings.postProcessPieceTimelineObjects(context, remotePiece, false) - await context.core.queuePart(part, [ remotePiece, ...(settings.SelectedAdlibs @@ -1434,9 +1410,7 @@ async function executeActionTakeWithTransition< return } - const mixEffectTimelineObject = context.videoSwitcher.findMixEffectTimelineObject( - primaryPiece.piece.content.timelineObjects - ) + const mixEffectTimelineObject = primaryPiece.piece.content.timelineObjects.find(context.videoSwitcher.isMixEffect) if (!mixEffectTimelineObject) { return @@ -1550,7 +1524,7 @@ async function executeActionTakeWithTransition< async function updateTransition( context: ExtendedActionExecutionContext, - timelineObject: TSR.TSRTimelineObj, + timelineObject: TimelineObjectCoreExt, pieceInstance: IBlueprintPieceInstance, transitionStyle: TransitionStyle, transitionDuration?: number @@ -1941,8 +1915,6 @@ async function executeActionSelectFull< const fullPiece = generator.createPiece() - settings.postProcessPieceTimelineObjects(context, fullPiece, false) - const fullDataStore = generator.createFullDataStore() const part: IBlueprintPart = { diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index c8a4ae5d..9177b403 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -89,7 +89,6 @@ export interface DVELayers { ATEM: { SSrcDefault: string SSrcArt: string - MEProgram: string } CASPAR: { CGDVEKey: string @@ -104,10 +103,6 @@ export interface DVELayers { } } -export interface DVEMetaData { - mediaPlayerSession?: string -} - export interface DVEPieceMetaData extends PieceMetaData { config: DVEConfigInput sources: DVESources @@ -322,9 +317,9 @@ export function MakeContentDVE2< type: TSR.TimelineContentTypeAtem.SSRC, ssrc: { boxes } }, - metaData: literal({ + metaData: { mediaPlayerSession: hasServer ? mediaPlayerSessionId ?? MEDIA_PLAYER_AUTO : undefined - }) + } }), literal({ id: '', @@ -354,11 +349,10 @@ export function MakeContentDVE2< } } }), - context.videoSwitcher.getMixEffectTimelineObject({ + ...context.videoSwitcher.getOnAirTimelineObjects({ id: '', enable: getDVEEnable(Number(context.config.studio.CasparPrerollDuration)), priority: 1, - layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: SpecialInput.DVE, transition: TransitionStyle.CUT diff --git a/src/tv2-common/content/jingle.ts b/src/tv2-common/content/jingle.ts index 97e37963..9ccccb7b 100644 --- a/src/tv2-common/content/jingle.ts +++ b/src/tv2-common/content/jingle.ts @@ -1,5 +1,6 @@ import { TimelineObjectCoreExt, TSR, VTContent, WithTimeline } from 'blueprints-integration' -import { EnableDSK, ExtendedShowStyleContext, FindDSKJingle, TimeFromFrames } from 'tv2-common' +import { ExtendedShowStyleContext, FindDSKJingle, getDskOnAirTimelineObjects, TimeFromFrames } from 'tv2-common' +import { DSKRoles } from 'tv2-constants' import { TV2BlueprintConfigBase, TV2ShowStyleConfig, TV2StudioConfigBase } from '../blueprintConfig' import { TimelineBlueprintExt } from '../onTimelineGenerate' import { joinAssetToFolder, joinAssetToNetworkPath, literal } from '../util' @@ -62,7 +63,7 @@ export function CreateJingleContentBase< timelineObjects: literal([ CreateJingleCasparTimelineObject(fileName, loadFirstFrame, layers), - ...EnableDSK(context, 'JINGLE', { start: Number(config.studio.CasparPrerollDuration) }), + ...getDskOnAirTimelineObjects(context, DSKRoles.JINGLE, { start: Number(config.studio.CasparPrerollDuration) }), // @todo: this is a Qbox-only feature, should be refactored at some point not to use ATEM object directly ...(context.uniformConfig.SwitcherLLayers.JingleNextMixEffect @@ -118,27 +119,6 @@ export function CreateJingleContentBase< ] : []), - ...(context.uniformConfig.SwitcherLLayers.JingleUskMixEffect - ? [ - context.videoSwitcher.getMixEffectTimelineObject({ - enable: { - start: Number(config.studio.CasparPrerollDuration) - }, - priority: 1, - layer: context.uniformConfig.SwitcherLLayers.JingleUskMixEffect, - content: { - keyers: [ - { - id: 0, - onAir: true, - config: jingleDSK - } - ] - } - }) - ] - : []), - literal({ id: '', enable: { diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index e590e83a..b9951369 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -1,4 +1,4 @@ -import { IShowStyleUserContext, TimelineObjectCoreExt, TSR, VTContent, WithTimeline } from 'blueprints-integration' +import { TimelineObjectCoreExt, TSR, VTContent, WithTimeline } from 'blueprints-integration' import { ExtendedShowStyleContext, GetSisyfosTimelineObjForServer, @@ -6,11 +6,10 @@ import { PartDefinition, TransitionStyle } from 'tv2-common' -import { AbstractLLayer, ControlClasses, GetEnableClassForServer } from 'tv2-constants' +import { AbstractLLayer, GetEnableClassForServer } from 'tv2-constants' import { TV2ShowStyleConfig } from '../blueprintConfig' import { TimelineBlueprintExt } from '../onTimelineGenerate' import { ServerContentProps, ServerPartProps } from '../parts' -import { AdlibServerOfftubeOptions } from '../pieces' import { joinAssetToNetworkPath } from '../util' // TODO: These are TSR layers, not sourcelayers @@ -109,10 +108,10 @@ function GetServerTimeline( contentProps.mediaPlayerSession, audioEnable ), - ...(context.uniformConfig.SwitcherLLayers.ServerLookaheadAux + ...(context.uniformConfig.SwitcherLLayers.NextServerAux ? [ context.videoSwitcher.getAuxTimelineObject({ - layer: context.uniformConfig.SwitcherLLayers.ServerLookaheadAux, + layer: context.uniformConfig.SwitcherLLayers.NextServerAux, content: { input: -1 }, @@ -128,17 +127,15 @@ function GetServerTimeline( export function CutToServer( context: ExtendedShowStyleContext, mediaPlayerSessionId: string, - partDefinition: PartDefinition, - offtubeOptions?: AdlibServerOfftubeOptions + partDefinition: PartDefinition ): TimelineBlueprintExt[] { return [ EnableServer(mediaPlayerSessionId), - context.videoSwitcher.getMixEffectTimelineObject({ + ...context.videoSwitcher.getOnAirTimelineObjects({ enable: { start: context.config.studio.CasparPrerollDuration }, priority: 1, - layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: -1, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, @@ -146,8 +143,7 @@ export function CutToServer( }, metaData: { mediaPlayerSession: mediaPlayerSessionId - }, - classes: [...(offtubeOptions?.isOfftube ? [ControlClasses.AbstractLookahead] : [])] + } }) ] } diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index 564b4397..57155f2a 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -74,15 +74,15 @@ export function EvaluateEksternBase< studioLabel: '', switcherInput, timelineObjects: literal([ - context.videoSwitcher.getMixEffectTimelineObject({ + ...context.videoSwitcher.getOnAirTimelineObjects({ priority: 1, - layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: switcherInput, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration }, - classes: [ControlClasses.LiveSourceOnAir] + classes: [ControlClasses.LIVE_SOURCE_ON_AIR], // @todo: this should not be here probably + mixMinusInput: null }), ...GetSisyfosTimelineObjForRemote(context.config, sourceInfoEkstern) @@ -112,14 +112,14 @@ export function EvaluateEksternBase< studioLabel: '', switcherInput, timelineObjects: literal([ - context.videoSwitcher.getMixEffectTimelineObject({ + ...context.videoSwitcher.getOnAirTimelineObjects({ priority: 1, - layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: switcherInput, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration - } + }, + mixMinusInput: null // @todo: should it be here? }), ...GetSisyfosTimelineObjForRemote(context.config, sourceInfoEkstern) diff --git a/src/tv2-common/cues/lyd.ts b/src/tv2-common/cues/lyd.ts index 6bf1df7a..3e849e2d 100644 --- a/src/tv2-common/cues/lyd.ts +++ b/src/tv2-common/cues/lyd.ts @@ -158,7 +158,7 @@ function LydContent( } } }, - classes: [ControlClasses.LYDOnAir] + classes: [ControlClasses.LYD_ON_AIR] }), literal({ id: '', @@ -182,7 +182,7 @@ export function CreateLYDBaseline(studio: string): TSR.TSRTimelineObj[] { literal({ id: `${studio}_lyd_baseline`, enable: { - while: `!.${ControlClasses.LYDOnAir}` + while: `!.${ControlClasses.LYD_ON_AIR}` }, priority: 0, layer: AbstractLLayer.AudioBedBaseline, @@ -194,7 +194,7 @@ export function CreateLYDBaseline(studio: string): TSR.TSRTimelineObj[] { literal({ id: '', // Q: Why start 10s? A: It needs to be longer than the longest fade out, a 10s fade out is probably more than we will ever use. - enable: { start: `#${studio}_lyd_baseline.start + 10000`, end: `.${ControlClasses.LYDOnAir}` }, + enable: { start: `#${studio}_lyd_baseline.start + 10000`, end: `.${ControlClasses.LYD_ON_AIR}` }, priority: 0, layer: SharedCasparLLayer.CasparCGLYD, content: { diff --git a/src/tv2-common/cues/mixMinus.ts b/src/tv2-common/cues/mixMinus.ts index c174a455..698057ba 100644 --- a/src/tv2-common/cues/mixMinus.ts +++ b/src/tv2-common/cues/mixMinus.ts @@ -45,7 +45,7 @@ function MixMinusContent(context: ExtendedShowStyleContext, switcherInput: numbe input: switcherInput }, enable: { - while: `.${ControlClasses.LiveSourceOnAir}` + while: `.${ControlClasses.LIVE_SOURCE_ON_AIR}` }, layer: SwitcherAuxLLayer.AuxVideoMixMinus, priority: 1 diff --git a/src/tv2-common/helpers/abPlayback.ts b/src/tv2-common/helpers/abPlayback.ts index 58b69472..04816d07 100644 --- a/src/tv2-common/helpers/abPlayback.ts +++ b/src/tv2-common/helpers/abPlayback.ts @@ -47,7 +47,6 @@ export interface ActiveRequest { end: number | undefined type: MediaPlayerClaimType player?: string - optional?: boolean } function maxUndefined(a: number | undefined, b: number | undefined): number | undefined { @@ -63,7 +62,6 @@ function maxUndefined(a: number | undefined, b: number | undefined): number | un interface SessionTime { start: number end: number | undefined - optional: boolean duration: number | undefined } function calculateSessionTimeRanges(resolvedPieces: Array>) { @@ -96,14 +94,12 @@ function calculateSessionTimeRanges(resolvedPieces: Array !r.optional)) + const res = tryForInUse(inUse) if (res !== undefined) { return res } @@ -213,8 +203,7 @@ export function resolveMediaPlayerAssignments< start: r.start, end: r.end, player: prev ? prev.playerId.toString() : undefined, // Persist previous assignments - type: prev && prev.lookahead ? MediaPlayerClaimType.Preloaded : MediaPlayerClaimType.Active, - optional: r.optional + type: prev && prev.lookahead ? MediaPlayerClaimType.Preloaded : MediaPlayerClaimType.Active }) } } @@ -286,7 +275,7 @@ function updateObjectsToMediaPlayer< } const input = Number(switcherInput.val) || 0 if (context.videoSwitcher.isMixEffect(obj)) { - if (obj.classes?.includes('ab_on_preview')) { + if (context.uniformConfig.SwitcherLLayers.NextPreviewMixEffect) { context.videoSwitcher.updatePreviewInput(obj, input) } else { context.videoSwitcher.updateInput(obj, input) diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index 12e64998..d8493df9 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -6,7 +6,7 @@ import { TableConfigItemValue, TSR } from 'blueprints-integration' -import { AtemLLayerDSK, ExtendedShowStyleContext, literal, SourceLayerAtemDSK, VideoSwitcher } from 'tv2-common' +import { ExtendedShowStyleContext, literal, LLayerDSK, SourceLayerAtemDSK, VideoSwitcher } from 'tv2-common' import { AdlibTags, DSKRoles, SharedOutputLayers } from 'tv2-constants' import { ATEMModel } from '../../types/atem' import { TV2BlueprintConfigBase, TV2ShowStyleConfig, TV2StudioConfigBase } from '../blueprintConfig' @@ -41,37 +41,53 @@ export function GetDSKCount(atemModel: ATEMModel) { } } -export function EnableDSK( +export function getDskOnAirTimelineObjects( context: ExtendedShowStyleContext, - dsk: 'FULL' | 'OVL' | 'JINGLE', + dskRole: DSKRoles, enable?: TSR.TSRTimelineObj['enable'] ): TSR.TSRTimelineObj[] { - const dskConf = - dsk === 'FULL' - ? FindDSKFullGFX(context.config) - : dsk === 'OVL' - ? FindDSKOverlayGFX(context.config) - : FindDSKJingle(context.config) - - return context.videoSwitcher.getDskTimelineObjects({ - id: '', - enable: enable ?? { - start: 0 - }, - priority: 1, - layer: AtemLLayerDSK(dskConf.Number), - content: { - onAir: true, - sources: { - fillSource: dskConf.Fill, - cutSource: dskConf.Key + const dskConf = FindDSKWithRoles(context.config, [dskRole]) + return [ + ...context.videoSwitcher.getDskTimelineObjects({ + id: '', + enable: enable ?? { + start: 0 }, - properties: { - clip: Number(dskConf.Clip) * 10, - gain: Number(dskConf.Gain) * 10 + priority: 1, + layer: LLayerDSK(dskConf.Number), + content: { + onAir: true, + sources: { + fillSource: dskConf.Fill, + cutSource: dskConf.Key + }, + properties: { + clip: Number(dskConf.Clip) * 10, + gain: Number(dskConf.Gain) * 10 + } } - } - }) + }), + ...(dskRole === DSKRoles.JINGLE && context.uniformConfig.SwitcherLLayers.JingleUskMixEffect + ? [ + context.videoSwitcher.getMixEffectTimelineObject({ + enable: enable ?? { + start: 0 + }, + priority: 1, + layer: context.uniformConfig.SwitcherLLayers.JingleUskMixEffect, + content: { + keyers: [ + { + id: 0, + onAir: true, + config: dskConf + } + ] + } + }) + ] + : []) + ] } export function CreateDSKBaselineAdlibs( @@ -97,7 +113,7 @@ export function CreateDSKBaselineAdlibs( id: '', enable: { while: '1' }, priority: 10, - layer: AtemLLayerDSK(dsk.Number), + layer: LLayerDSK(dsk.Number), content: { onAir: false } @@ -118,7 +134,7 @@ export function CreateDSKBaselineAdlibs( id: '', enable: { while: '1' }, priority: 10, - layer: AtemLLayerDSK(dsk.Number), // @todo + layer: LLayerDSK(dsk.Number), // @todo content: { onAir: true, sources: { @@ -151,7 +167,7 @@ export function CreateDSKBaseline( id: '', enable: { while: '1' }, priority: 0, - layer: AtemLLayerDSK(dsk.Number), // @todo + layer: LLayerDSK(dsk.Number), // @todo content: { onAir: dsk.DefaultOn, sources: { diff --git a/src/tv2-common/helpers/graphics/caspar/HtmlInternalGraphic.ts b/src/tv2-common/helpers/graphics/caspar/HtmlInternalGraphic.ts index a508409c..45da5ff7 100644 --- a/src/tv2-common/helpers/graphics/caspar/HtmlInternalGraphic.ts +++ b/src/tv2-common/helpers/graphics/caspar/HtmlInternalGraphic.ts @@ -1,5 +1,6 @@ import { SomeContent, TSR, WithTimeline } from 'blueprints-integration' -import { CreateHTMLRendererContent, EnableDSK, GetTimelineLayerForGraphic, literal } from 'tv2-common' +import { CreateHTMLRendererContent, getDskOnAirTimelineObjects, GetTimelineLayerForGraphic, literal } from 'tv2-common' +import { DSKRoles } from 'tv2-constants' import { InternalGraphic } from '../internal' @@ -20,7 +21,7 @@ export class HtmlInternalGraphic extends InternalGraphic { content: CreateHTMLRendererContent(this.config, this.templateName, { ...this.cue.graphic.textFields }) }), // Assume DSK is off by default (config table) - ...EnableDSK(this.context, 'OVL') + ...getDskOnAirTimelineObjects(this.context, DSKRoles.OVERLAYGFX) ] } } diff --git a/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts b/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts index 41d66d68..db85ca2f 100644 --- a/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts +++ b/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts @@ -2,7 +2,6 @@ import { PieceLifespan, TSR } from 'blueprints-integration' import { CueDefinitionGraphic, GraphicPilot, HtmlPilotGraphicGenerator, literal } from 'tv2-common' import { CueType, SharedGraphicLLayer } from 'tv2-constants' import { makeMockGalleryContext } from '../../../../../__mocks__/context' -import { pilotGeneratorSettingsOfftube } from '../../../../../tv2_offtube_showstyle/cues/OfftubeGraphics' function makeMockContext() { // @todo: perhaps make the tests run with two contexts @@ -15,8 +14,7 @@ function makeGenerator(cue: CueDefinitionGraphic) { context, partId: 'part01', parsedCue: cue, - segmentExternalId: '', - settings: pilotGeneratorSettingsOfftube + segmentExternalId: '' }) return generator } diff --git a/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts index 4e55eafc..efedea28 100644 --- a/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts @@ -1,7 +1,7 @@ import { GraphicsContent, TSR, WithTimeline } from 'blueprints-integration' import { - EnableDSK, FindDSKFullGFX, + getDskOnAirTimelineObjects, getHtmlTemplateName, GetSisyfosTimelineObjForFull, IsTargetingFull, @@ -13,6 +13,7 @@ import { TimelineBlueprintExt, TransitionStyle } from 'tv2-common' +import { DSKRoles } from 'tv2-constants' import { PilotGraphicGenerator } from '../pilot' @@ -81,7 +82,9 @@ export class HtmlPilotGraphicGenerator extends PilotGraphicGenerator { } } }), - ...(IsTargetingFull(this.engine) ? this.getFullPilotTimeline() : EnableDSK(this.context, 'OVL')) + ...(IsTargetingFull(this.engine) + ? this.getFullPilotTimeline() + : getDskOnAirTimelineObjects(this.context, DSKRoles.OVERLAYGFX)) ] } } @@ -89,12 +92,11 @@ export class HtmlPilotGraphicGenerator extends PilotGraphicGenerator { protected getFullPilotTimeline(): TSR.TSRTimelineObj[] { const fullDSK = FindDSKFullGFX(this.config) return [ - this.context.videoSwitcher.getMixEffectTimelineObject({ + ...this.context.videoSwitcher.getOnAirTimelineObjects({ enable: { start: Number(this.config.studio.CasparPrerollDuration) }, priority: 1, - layer: this.context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: fullDSK.Fill, transition: TransitionStyle.WIPE_FOR_GFX diff --git a/src/tv2-common/helpers/graphics/viz/VizInternalGraphic.ts b/src/tv2-common/helpers/graphics/viz/VizInternalGraphic.ts index 713bfa87..1eed50dc 100644 --- a/src/tv2-common/helpers/graphics/viz/VizInternalGraphic.ts +++ b/src/tv2-common/helpers/graphics/viz/VizInternalGraphic.ts @@ -1,5 +1,6 @@ import { SomeContent, TSR, WithTimeline } from 'blueprints-integration' -import { EnableDSK, GetTimelineLayerForGraphic, literal } from 'tv2-common' +import { getDskOnAirTimelineObjects, GetTimelineLayerForGraphic, literal } from 'tv2-common' +import { DSKRoles } from 'tv2-constants' import { InternalGraphic } from '../internal' @@ -25,7 +26,7 @@ export class VizInternalGraphic extends InternalGraphic { } }), // Assume DSK is off by default (config table) - ...EnableDSK(this.context, 'OVL') + ...getDskOnAirTimelineObjects(this.context, DSKRoles.OVERLAYGFX) ]) } } diff --git a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts index 8f85da7f..8955e9cc 100644 --- a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts @@ -1,8 +1,8 @@ import { GraphicsContent, TSR, WithTimeline } from 'blueprints-integration' import { assertUnreachable, - EnableDSK, FindDSKFullGFX, + getDskOnAirTimelineObjects, GetSisyfosTimelineObjForFull, IsTargetingFull, IsTargetingOVL, @@ -11,7 +11,7 @@ import { PilotGraphicProps, TransitionStyle } from 'tv2-common' -import { ControlClasses } from 'tv2-constants' +import { DSKRoles } from 'tv2-constants' import { PilotGraphicGenerator } from '../pilot' @@ -82,19 +82,18 @@ export class VizPilotGraphicGenerator extends PilotGraphicGenerator { private getFullPilotTimeline() { const fullDSK = FindDSKFullGFX(this.config) const timelineObjects = [ - this.context.videoSwitcher.getMixEffectTimelineObject({ + ...this.context.videoSwitcher.getOnAirTimelineObjects({ enable: { start: this.config.studio.VizPilotGraphics.CutToMediaPlayer }, priority: 1, - layer: this.context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: this.config.studio.VizPilotGraphics.FullGraphicBackground, transition: TransitionStyle.CUT } }), // Assume DSK is off by default (config table) - ...EnableDSK(this.context, 'FULL'), + ...getDskOnAirTimelineObjects(this.context, DSKRoles.FULLGFX), ...GetSisyfosTimelineObjForFull(this.config) ] if (this.context.uniformConfig.SwitcherLLayers.ProgramAux) { @@ -107,8 +106,7 @@ export class VizPilotGraphicGenerator extends PilotGraphicGenerator { layer: this.context.uniformConfig.SwitcherLLayers.ProgramAux, content: { input: fullDSK.Fill - }, - classes: [ControlClasses.MixMinusOverrideDsk, ControlClasses.Placeholder] + } }) ) } diff --git a/src/tv2-common/layers/timelineLayers.ts b/src/tv2-common/layers/timelineLayers.ts index 0d57d76e..d506fbe1 100644 --- a/src/tv2-common/layers/timelineLayers.ts +++ b/src/tv2-common/layers/timelineLayers.ts @@ -29,7 +29,7 @@ export function SisyfosPlayerClip(i: number | string) { * Created layer mapping name for a DSK * @param i DSK number starting from 0 */ -export function AtemLLayerDSK(i: number) { +export function LLayerDSK(i: number) { return `dsk_${i + 1}` } @@ -37,7 +37,7 @@ export function GetDSKMappingNames(atemModel: ATEMModel): string[] { const names: string[] = [] for (let i = 0; i < GetDSKCount(atemModel); i++) { - names.push(AtemLLayerDSK(i)) + names.push(LLayerDSK(i)) } return names diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index 38e94b5c..ece5a0f7 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -50,7 +50,6 @@ export interface TimelinePersistentStateExt { export interface TimelineObjectMetaData { context?: string mediaPlayerSession?: string - dveAdlibEnabler?: string // Used to restore the original while rule after lookahead templateData?: any fileName?: string } @@ -62,7 +61,6 @@ export type TimelineBlueprintExt = TSR.TSRTimelineObjBase & { export interface PieceMetaData { sisyfosPersistMetaData?: SisyfosPersistMetaData mediaPlayerSessions?: string[] - mediaPlayerOptional?: boolean modifiedByAction?: boolean } @@ -134,8 +132,6 @@ export function onTimelineGenerate< sourceLayers ) - dveBoxLookaheadUseOriginalEnable(timeline) - return Promise.resolve({ timeline, persistentState @@ -274,29 +270,6 @@ export function getEndStateForPart( return endState } -/** - * DVE box lookahead uses classes to select the correct object. - * Lookahead is replacing this selector rule with a '1' which causes every box to show the same. - * This simply restores the original enable, which gets put into metaData for this purpose. - */ -function dveBoxLookaheadUseOriginalEnable(timeline: OnGenerateTimelineObj[]) { - // DVE_box lookahead class - for (const obj of timeline) { - const obj2 = obj as TSR.TimelineObjAtemSsrc & TimelineBlueprintExt - if ( - obj2.isLookahead && - obj2.content.deviceType === TSR.DeviceType.ATEM && - obj2.content.type === TSR.TimelineContentTypeAtem.SSRC - ) { - const origClass = obj2.metaData ? obj2.metaData.dveAdlibEnabler : undefined - if (origClass) { - // Restore the original enable rule - obj2.enable = { while: origClass } - } - } - } -} - export function createSisyfosPersistedLevelsTimelineObject( resolvedPieces: Array>, previousSisyfosLayersThatWantsToBePersisted: SisyfosPersistMetaData['sisyfosLayers'] diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index f2d484f7..d65cf532 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -11,8 +11,8 @@ import { import { ActionTakeWithTransitionVariantDip, ActionTakeWithTransitionVariantMix, - EnableDSK, ExtendedShowStyleContext, + getDskOnAirTimelineObjects, GetTagForTransition, literal, PartDefinition, @@ -23,7 +23,7 @@ import { TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' +import { DSKRoles, SharedOutputLayers } from 'tv2-constants' import { TV2ShowStyleConfig } from '../blueprintConfig' import { joinAssetToFolder, joinAssetToNetworkPath } from '../util' @@ -151,7 +151,9 @@ export function CreateEffektForPartInner< file: fileName } }), - ...EnableDSK(context, 'JINGLE', { start: Number(context.config.studio.CasparPrerollDuration) }), + ...getDskOnAirTimelineObjects(context, DSKRoles.JINGLE, { + start: Number(context.config.studio.CasparPrerollDuration) + }), literal({ id: '', enable: { diff --git a/src/tv2-common/pieces/adlibServer.ts b/src/tv2-common/pieces/adlibServer.ts index 94d5a4bb..09bce116 100644 --- a/src/tv2-common/pieces/adlibServer.ts +++ b/src/tv2-common/pieces/adlibServer.ts @@ -15,11 +15,6 @@ import { import { AdlibActionType, AdlibTags, SharedOutputLayers } from 'tv2-constants' import { getServerAdLibTriggerModes, t } from '../helpers' -export interface AdlibServerOfftubeOptions { - /** By passing in this object, you're creating a server according to the OFFTUBE showstyle. */ - isOfftube: boolean -} - export async function CreateAdlibServer< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase diff --git a/src/tv2-common/showstyle/context.ts b/src/tv2-common/showstyle/context.ts index 8b90fc34..bdbc11d7 100644 --- a/src/tv2-common/showstyle/context.ts +++ b/src/tv2-common/showstyle/context.ts @@ -17,7 +17,7 @@ export class ExtendedShowStyleContextImpl< constructor(readonly core: CoreContext, public readonly uniformConfig: UniformConfig) { this.config = this.makeConfig() - this.videoSwitcher = VideoSwitcherImpl.getVideoSwitcher(this.config) + this.videoSwitcher = VideoSwitcherImpl.getVideoSwitcher(core, this.config, uniformConfig) } private makeConfig(): BlueprintConfig { diff --git a/src/tv2-common/studio/context.ts b/src/tv2-common/studio/context.ts index 9bf27785..cbe85c23 100644 --- a/src/tv2-common/studio/context.ts +++ b/src/tv2-common/studio/context.ts @@ -8,7 +8,7 @@ export class ExtendedStudioContext { return ( this.isVideoSwitcherTimelineObject(timelineObject) && @@ -155,7 +151,7 @@ export class Atem extends VideoSwitcherImpl { timelineObject.content.type === TSR.TimelineContentTypeAtem.AUX ) } - public updateAuxInput(timelineObject: TSR.TSRTimelineObj, input: number | SpecialInput): TSR.TSRTimelineObj { + public updateAuxInput(_timelineObject: TSR.TSRTimelineObj, _input: number | SpecialInput): TSR.TSRTimelineObj { throw new Error('Method not implemented.') } public isDveBoxes = (timelineObject: TSR.TSRTimelineObj): timelineObject is TSR.TimelineObjAtemSsrc => { @@ -164,12 +160,12 @@ export class Atem extends VideoSwitcherImpl { timelineObject.content.type === TSR.TimelineContentTypeAtem.SSRC ) } - public getDveTimelineObject(properties: AuxProps): TSR.TSRTimelineObj { + public getDveTimelineObject(_properties: AuxProps): TSR.TSRTimelineObj { throw new Error('Method not implemented.') } public updateUnpopulatedDveBoxes( - timelineObject: TimelineObjectCoreExt, - input: number | SpecialInput + _timelineObject: TimelineObjectCoreExt, + _input: number | SpecialInput ): TSR.TSRTimelineObj { throw new Error('Method not implemented.') } diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 9b6375ac..4477c434 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -63,10 +63,6 @@ export class TriCaster extends VideoSwitcherImpl { } } - public findMixEffectTimelineObject(timelineObjects: TSR.TSRTimelineObj[]): TSR.TSRTimelineObj | undefined { - return timelineObjects.find(this.isMixEffect) - } - public updateTransition( timelineObject: TSR.TSRTimelineObj, transition: TransitionStyle, @@ -131,12 +127,12 @@ export class TriCaster extends VideoSwitcherImpl { !!(timelineObject.content.me as TSR.TriCasterMixEffectInEffectMode).layers ) } - public getDveTimelineObject(properties: AuxProps): TSR.TSRTimelineObj { + public getDveTimelineObject(_properties: AuxProps): TSR.TSRTimelineObj { throw new Error('Method not implemented.') } public updateUnpopulatedDveBoxes( - timelineObject: TSR.TSRTimelineObj, - input: number | SpecialInput + _timelineObject: TSR.TSRTimelineObj, + _input: number | SpecialInput ): TSR.TSRTimelineObj { throw new Error('Method not implemented.') } diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts index 3c265f03..e30f264e 100644 --- a/src/tv2-common/videoSwitchers/VideoSwitcher.ts +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -1,36 +1,103 @@ -import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' +import { IStudioContext, TimelineObjectCoreExt, TSR } from 'blueprints-integration' import { Atem, AuxProps, DskProps, MixEffectProps, + OnAirMixEffectProps, SpecialInput, SwitcherType, TransitionStyle, TriCaster, TV2StudioConfig, + UniformConfig, VideoSwitcher } from 'tv2-common' +import _ = require('underscore') export abstract class VideoSwitcherImpl implements VideoSwitcher { public static videoSwitcherSingleton: VideoSwitcherImpl | undefined = undefined - public static getVideoSwitcher(config: TV2StudioConfig): VideoSwitcherImpl { + public static getVideoSwitcher( + core: IStudioContext, + config: TV2StudioConfig, + uniformConfig: UniformConfig + ): VideoSwitcherImpl { if (!this.videoSwitcherSingleton || this.videoSwitcherSingleton.type !== config.studio.SwitcherType) { this.videoSwitcherSingleton = - config.studio.SwitcherType === SwitcherType.ATEM ? new Atem(config) : new TriCaster(config) + config.studio.SwitcherType === SwitcherType.ATEM + ? new Atem(core, config, uniformConfig) + : new TriCaster(core, config, uniformConfig) } return this.videoSwitcherSingleton } public abstract readonly type: SwitcherType - public abstract isDsk: (timelineObject: TimelineObjectCoreExt) => boolean - public abstract isAux: (timelineObject: TimelineObjectCoreExt) => boolean - public abstract isDveBoxes: (timelineObject: TimelineObjectCoreExt) => boolean - public abstract isVideoSwitcherTimelineObject: (timelineObject: TimelineObjectCoreExt) => boolean + public abstract isDsk: (timelineObject: TimelineObjectCoreExt) => boolean + public abstract isAux: (timelineObject: TimelineObjectCoreExt) => boolean + public abstract isDveBoxes: (timelineObject: TimelineObjectCoreExt) => boolean + public abstract isVideoSwitcherTimelineObject: (timelineObject: TimelineObjectCoreExt) => boolean public abstract isMixEffect: (timelineObject: TSR.TSRTimelineObj) => boolean protected readonly config: TV2StudioConfig + protected readonly core: IStudioContext + protected readonly uniformConfig: UniformConfig - protected constructor(config: TV2StudioConfig) { + protected constructor(core: IStudioContext, config: TV2StudioConfig, uniformConfig: UniformConfig) { this.config = config + this.core = core + this.uniformConfig = uniformConfig + } + public getOnAirTimelineObjects(properties: OnAirMixEffectProps): TSR.TSRTimelineObj[] { + const result: TSR.TSRTimelineObj[] = [] + const primaryId = properties.id ?? this.core.getHashId(this.uniformConfig.SwitcherLLayers.PrimaryMixEffect, true) + result.push( + this.getMixEffectTimelineObject({ + ...properties, + id: primaryId, + layer: this.uniformConfig.SwitcherLLayers.PrimaryMixEffect + }) + ) + if (this.uniformConfig.SwitcherLLayers.PrimaryMixEffectClone) { + result.push( + this.getMixEffectTimelineObject({ + ...properties, + layer: this.uniformConfig.SwitcherLLayers.PrimaryMixEffectClone, + metaData: { ...properties.metaData, context: `Clone of Primary MixEffect timeline object ${primaryId}` } + }) + ) + } + if (this.uniformConfig.SwitcherLLayers.NextPreviewMixEffect && properties.content.input) { + result.push( + this.getMixEffectTimelineObject({ + ..._.omit(properties, 'content'), + content: { previewInput: properties.content.input }, + layer: this.uniformConfig.SwitcherLLayers.NextPreviewMixEffect, + metaData: { ...properties.metaData, context: `Preview Lookahead for ${primaryId}` } + }) + ) + } + if (this.uniformConfig.SwitcherLLayers.NextAux && properties.content.input) { + result.push( + this.getAuxTimelineObject({ + ..._.omit(properties, 'content'), + content: { input: properties.content.input }, + layer: this.uniformConfig.SwitcherLLayers.NextAux, + metaData: { ...properties.metaData, context: `Aux Lookahead for ${primaryId}` } + }) + ) + } + if (this.uniformConfig.SwitcherLLayers.MixMinusAux) { + const input = properties.mixMinusInput || properties.content.input + if (input) { + result.push( + this.getAuxTimelineObject({ + ..._.omit(properties, 'content'), + content: { input }, + layer: this.uniformConfig.SwitcherLLayers.MixMinusAux, + metaData: { ...properties.metaData, context: `Mix-minus for ${primaryId}` } + }) + ) + } + } + return result } public abstract updateAuxInput( timelineObject: TimelineObjectCoreExt, @@ -42,7 +109,6 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { input: number | SpecialInput ): TSR.TSRTimelineObj public abstract getMixEffectTimelineObject(properties: MixEffectProps): TSR.TSRTimelineObj - public abstract findMixEffectTimelineObject(timelineObjects: TSR.TSRTimelineObj[]): TSR.TSRTimelineObj | undefined public abstract updateTransition( timelineObjects: TSR.TSRTimelineObj, transition: TransitionStyle, diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index 50c239c4..c0df86e3 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -63,6 +63,10 @@ export interface MixEffectProps extends TimelineObjectProps { } } +export interface OnAirMixEffectProps extends Omit { + mixMinusInput?: number | SpecialInput | null +} + export interface Keyer { // id starting from 0 id: number @@ -96,7 +100,7 @@ export interface AuxProps extends TimelineObjectProps { export interface VideoSwitcher { isMixEffect(timelineObject: TimelineObjectCoreExt): boolean getMixEffectTimelineObject(properties: MixEffectProps): TSR.TSRTimelineObj - findMixEffectTimelineObject(timelineObjects: TimelineObjectCoreExt[]): TSR.TSRTimelineObj | undefined + getOnAirTimelineObjects(properties: OnAirMixEffectProps): TSR.TSRTimelineObj[] isVideoSwitcherTimelineObject(timelineObject: TimelineObjectCoreExt): boolean updateTransition( timelineObject: TimelineObjectCoreExt, diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index a135951c..79a95447 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -113,16 +113,15 @@ export function AdlibTagCutToBox(box: number): AdlibTags { } export enum ControlClasses { - ServerOnAir = 'server_on_air', - LYDOnAir = 'lyd_on_air', - LiveSourceOnAir = 'live_source_on_air', - AbstractLookahead = 'abstract_lookahead', - MixMinusOverrideDsk = 'MIX_MINUS_OVERRIDE_DSK', - Placeholder = 'PLACEHOLDER_OBJECT_REMOVEME' + SERVER_ON_AIR = 'server_on_air', + LYD_ON_AIR = 'lyd_on_air', + LIVE_SOURCE_ON_AIR = 'live_source_on_air', + ABSTRACT_LOOKAHEAD = 'abstract_lookahead', + PLACEHOLDER = 'placeholder' } export function GetEnableClassForServer(mediaPlayerSessionId: string) { - return `${ControlClasses.ServerOnAir}_${mediaPlayerSessionId}` + return `${ControlClasses.SERVER_ON_AIR}_${mediaPlayerSessionId}` } export enum AdlibActionType { diff --git a/src/tv2_afvd_showstyle/actions.ts b/src/tv2_afvd_showstyle/actions.ts index 53f62135..c8f106a0 100644 --- a/src/tv2_afvd_showstyle/actions.ts +++ b/src/tv2_afvd_showstyle/actions.ts @@ -4,10 +4,8 @@ import { CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { AFVD_DVE_GENERATOR_OPTIONS } from './helpers/content/dve' import { EvaluateCues } from './helpers/pieces/evaluateCues' -import { pilotGeneratorSettingsAFVD } from './helpers/pieces/graphicPilot' import { createJingleContentAFVD } from './helpers/pieces/jingle' import { SourceLayer } from './layers' -import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' export async function executeActionAFVD( context: IActionExecutionContext, @@ -19,7 +17,6 @@ export async function executeActionAFVD( context, GALLERY_UNIFORM_CONFIG, { - postProcessPieceTimelineObjects, EvaluateCues, DVEGeneratorOptions: AFVD_DVE_GENERATOR_OPTIONS, SourceLayers: { diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index beb0099d..df822cc7 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -66,7 +66,6 @@ import { AtemSourceIndex } from '../types/atem' import { GalleryBlueprintConfig } from './helpers/config' import { NUMBER_OF_DVE_BOXES } from './helpers/content/dve' import { SourceLayer } from './layers' -import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: IngestRundown): BlueprintResultRundown { const context = new ExtendedShowStyleContextImpl(coreContext, GALLERY_UNIFORM_CONFIG) @@ -122,7 +121,6 @@ class GlobalAdLibPiecesGenerator { adLibPieces.push(...this.makeSisyfosAdLibs()) adLibPieces.push(this.makeAudioBedAdLib()) - adLibPieces.forEach(p => postProcessPieceTimelineObjects(this.context, p, true)) return adLibPieces } @@ -198,10 +196,9 @@ class GlobalAdLibPiecesGenerator { content: { ignoreMediaObjectStatus: true, timelineObjects: [ - this.context.videoSwitcher.getMixEffectTimelineObject({ + ...this.context.videoSwitcher.getOnAirTimelineObjects({ enable: { while: '1' }, priority: 1, - layer: this.context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: info.port, transition: TransitionStyle.CUT @@ -285,14 +282,14 @@ class GlobalAdLibPiecesGenerator { tags: [AdlibTags.ADLIB_QUEUE_NEXT], content: { timelineObjects: [ - this.context.videoSwitcher.getMixEffectTimelineObject({ + ...this.context.videoSwitcher.getOnAirTimelineObjects({ enable: { while: '1' }, priority: 1, - layer: this.context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: info.port, transition: TransitionStyle.CUT - } + }, + mixMinusInput: null // @should it be here? }), ...eksternSisyfos ] diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index 11751182..e6e8ed5b 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -18,7 +18,6 @@ import { } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import * as _ from 'underscore' -import { AtemLLayer } from '../tv2_afvd_studio/layers' import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { GalleryBlueprintConfig } from './helpers/config' import { CreateShowLifecyclePieces } from './helpers/pieces/showLifecycle' @@ -31,7 +30,6 @@ import { CreatePartLive } from './parts/live' import { CreatePartServer } from './parts/server' import { CreatePartTeknik } from './parts/teknik' import { CreatePartUnknown } from './parts/unknown' -import { postProcessPartTimelineObjects } from './postProcessTimelineObjects' export async function getSegment( coreContext: ISegmentUserContext, @@ -60,8 +58,6 @@ export async function getSegment( insertSpecialPieces(context.config, blueprintParts, segmentPayload) } - postProcessPartTimelineObjects(context, blueprintParts) - return { segment: result.segment, parts: blueprintParts @@ -92,9 +88,8 @@ export function CreatePartContinuity( studioLabel: '', switcherInput: context.config.studio.SwitcherSource.Continuity, timelineObjects: [ - context.videoSwitcher.getMixEffectTimelineObject({ + ...context.videoSwitcher.getOnAirTimelineObjects({ priority: 1, - layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: context.config.studio.SwitcherSource.Continuity, transition: TransitionStyle.CUT diff --git a/src/tv2_afvd_showstyle/helpers/content/dve.ts b/src/tv2_afvd_showstyle/helpers/content/dve.ts index bb7c2479..7d1f38e6 100644 --- a/src/tv2_afvd_showstyle/helpers/content/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/content/dve.ts @@ -16,8 +16,7 @@ export const AFVD_DVE_GENERATOR_OPTIONS: DVEOptions = { dveLayers: { ATEM: { SSrcDefault: AtemLLayer.AtemSSrcDefault, - SSrcArt: AtemLLayer.AtemSSrcArt, - MEProgram: AtemLLayer.AtemMEProgram + SSrcArt: AtemLLayer.AtemSSrcArt }, CASPAR: { CGDVEKey: CasparLLayer.CasparCGDVEKey, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts index 6c9c90e1..9da5f5ab 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -8,13 +8,13 @@ import { WithTimeline } from 'blueprints-integration' import { - AtemLLayerDSK, CueDefinitionGraphic, CueTime, GraphicInternal, GraphicPieceMetaData, GraphicPilot, literal, + LLayerDSK, PartDefinitionKam, PieceMetaData } from 'tv2-common' @@ -63,7 +63,7 @@ const dskEnableObj = literal({ start: 0 }, priority: 1, - layer: AtemLLayerDSK(0), + layer: prefixLayer(LLayerDSK(0)), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.DSK, @@ -946,3 +946,7 @@ describe('grafik piece', () => { expect(tlObj?.enable).toEqual({ while: '1' }) }) }) + +function prefixLayer(layerName: string) { + return 'atem_' + layerName +} diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts index 21d4283e..c8fb6c1d 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -8,12 +8,12 @@ import { WithTimeline } from 'blueprints-integration' import { - AtemLLayerDSK, CueDefinitionGraphic, CueDefinitionTelefon, GraphicInternal, GraphicPieceMetaData, literal, + LLayerDSK, PartDefinitionKam } from 'tv2-common' import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayers, SourceType } from 'tv2-constants' @@ -114,7 +114,7 @@ describe('telefon', () => { start: 0 }, priority: 1, - layer: AtemLLayerDSK(0), + layer: prefixLayer(LLayerDSK(0)), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.DSK, @@ -192,3 +192,6 @@ describe('telefon', () => { ]) }) }) +function prefixLayer(name: string): string | number { + return 'atem_' + name +} diff --git a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts index bc4086bd..f9215cfc 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts @@ -14,7 +14,7 @@ import { } from 'tv2-common' import { AdlibActionType, AdlibTags, CueType, SharedOutputLayers } from 'tv2-constants' import { GalleryBlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' -import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' +import { CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' import { MakeContentDVE } from '../content/dve' diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts index 615d7614..58fb195c 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts @@ -1,18 +1,5 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' -import { - Adlib, - CreatePilotGraphic, - CueDefinitionGraphic, - ExtendedShowStyleContext, - GraphicPilot, - PilotGeneratorSettings -} from 'tv2-common' -import { AtemLLayer } from '../../../tv2_afvd_studio/layers' - -export const pilotGeneratorSettingsAFVD: PilotGeneratorSettings = { - ProgramLayer: AtemLLayer.AtemMEProgram, - AuxProgramLayer: AtemLLayer.AtemAuxPGM -} +import { Adlib, CreatePilotGraphic, CueDefinitionGraphic, ExtendedShowStyleContext, GraphicPilot } from 'tv2-common' export function EvaluateCueGraphicPilot( context: ExtendedShowStyleContext, @@ -28,7 +15,6 @@ export function EvaluateCueGraphicPilot( context, partId, parsedCue, - settings: pilotGeneratorSettingsAFVD, adlib, segmentExternalId }) diff --git a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts index f0f69092..87c397e5 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts @@ -13,7 +13,7 @@ import { } from 'tv2-common' import { AdlibActionType, AdlibTags, SharedOutputLayers, TallyTags } from 'tv2-constants' import { SourceLayer } from '../../../tv2_afvd_showstyle/layers' -import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' +import { CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' import { GalleryBlueprintConfig } from '../config' export function EvaluateJingle( diff --git a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts index 36f55655..24f74f08 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts @@ -2,7 +2,6 @@ import { CameraContent, IBlueprintPiece, PieceLifespan, TSR, WithTimeline } from import { CalculateTime, CueDefinitionRouting, ExtendedShowStyleContext, findSourceInfo, literal } from 'tv2-common' import { SharedOutputLayers, SwitcherAuxLLayer } from 'tv2-constants' import _ = require('underscore') -import { AtemLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' export function EvaluateCueRouting( @@ -42,11 +41,7 @@ export function EvaluateCueRouting( priority: 100, layer: SwitcherAuxLLayer.AuxVizOvlIn1, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: sourceInfo.port - } + input: sourceInfo.port } }) ]) diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index 271e4179..b635fa14 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -23,7 +23,6 @@ import { TransitionStyle } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' -import { AtemLLayer } from '../../tv2_afvd_studio/layers' import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' @@ -110,9 +109,8 @@ function makeContentEVS( switcherInput, ignoreMediaObjectStatus: true, timelineObjects: literal([ - context.videoSwitcher.getMixEffectTimelineObject({ + ...context.videoSwitcher.getOnAirTimelineObjects({ priority: 1, - layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: switcherInput, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index 01fbbfe6..c17f6030 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -23,7 +23,6 @@ import { TransitionStyle } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' -import { AtemLLayer } from '../../tv2_afvd_studio/layers' import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' @@ -64,9 +63,8 @@ export async function CreatePartKam( fileName: '', path: '', timelineObjects: [ - context.videoSwitcher.getMixEffectTimelineObject({ + ...context.videoSwitcher.getOnAirTimelineObjects({ priority: 1, - layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: jingleDSK.Fill, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, @@ -104,9 +102,8 @@ export async function CreatePartKam( studioLabel: '', switcherInput, timelineObjects: [ - context.videoSwitcher.getMixEffectTimelineObject({ + ...context.videoSwitcher.getOnAirTimelineObjects({ priority: 1, - layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: Number(switcherInput), transition: partDefinition.transition?.style ?? TransitionStyle.CUT, diff --git a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts deleted file mode 100644 index 7bdc1a7b..00000000 --- a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts +++ /dev/null @@ -1,182 +0,0 @@ -import { - BlueprintResultPart, - IBlueprintPieceGeneric, - SourceLayerType, - SplitsContent, - TimelineObjectCoreExt, - TSR -} from 'blueprints-integration' -import { AtemLLayerDSK, ExtendedShowStyleContext, FindDSKJingle, TimelineBlueprintExt } from 'tv2-common' -import { ControlClasses } from 'tv2-constants' -import * as _ from 'underscore' -import { AtemLLayer } from '../tv2_afvd_studio/layers' -import { GalleryBlueprintConfig } from './helpers/config' -import { SourceLayer } from './layers' - -export function postProcessPartTimelineObjects( - context: ExtendedShowStyleContext, - parts: BlueprintResultPart[] -) { - _.each(parts, part => { - _.each(part.pieces, p => postProcessPieceTimelineObjects(context, p, false)) - _.each(part.adLibPieces, p => postProcessPieceTimelineObjects(context, p, true)) - }) -} - -// Do any post-process of timeline objects -export function postProcessPieceTimelineObjects( - context: ExtendedShowStyleContext, - piece: IBlueprintPieceGeneric, - isAdlib: boolean -) { - const jingleDSK = FindDSKJingle(context.config) - const jingleDSKLayer = AtemLLayerDSK(jingleDSK.Number) - - if (piece.content?.timelineObjects) { - const extraObjs: TimelineObjectCoreExt[] = [] - - const atemMeObjs = piece.content.timelineObjects.filter( - obj => context.videoSwitcher.isMixEffect(obj) || context.videoSwitcher.isDsk(obj) - ) - _.each(atemMeObjs, tlObj => { - if (tlObj.layer === AtemLLayer.AtemMEProgram || tlObj.classes?.includes(ControlClasses.MixMinusOverrideDsk)) { - if (!tlObj.id) { - tlObj.id = context.core.getHashId(AtemLLayer.AtemMEProgram, true) - } - if (!tlObj.metaData) { - tlObj.metaData = {} - } - - // Basic clone of every object to AtemMEClean - // @todo: this can probably be replaced by some TriCaster feature(?) - const cleanObj = _.clone(tlObj) // Note: shallow clone - cleanObj.layer = AtemLLayer.AtemMEClean - cleanObj.id = '' // Force new id - cleanObj.metaData = _.clone(tlObj.metaData) - cleanObj.metaData.context = `Clean for ${tlObj.id}` - cleanObj.classes = cleanObj.classes?.filter(c => !c.match(`studio0_parent_`)) - extraObjs.push(cleanObj) - - if ( - (!isAdlib || piece.toBeQueued) && - (tlObj.content.me.input !== -1 || tlObj.metaData?.mediaPlayerSession !== undefined) - ) { - // Create a lookahead-lookahead object for this me-program - const lookaheadObj: TSR.TimelineObjAtemAUX & TimelineBlueprintExt = { - id: '', - enable: { start: 0 }, - priority: 0, // Must be below lookahead, except when forced by hold - layer: AtemLLayer.AtemAuxLookahead, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: - tlObj.content.me.input !== -1 - ? tlObj.content.me.input ?? context.config.studio.SwitcherSource.Default - : context.config.studio.SwitcherSource.Default - } - }, - metaData: { - context: `Lookahead-lookahead for ${tlObj.id}`, - mediaPlayerSession: tlObj.metaData?.mediaPlayerSession // TODO - does this work the same? - } - } - extraObjs.push(lookaheadObj) - } - - // mix minus - let mixMinusSource: number | undefined | null // TODO - what about clips? - // tslint:disable-next-line:prefer-conditional-expression - if (tlObj.classes?.includes(ControlClasses.MixMinusOverrideDsk)) { - mixMinusSource = (tlObj as TSR.TimelineObjAtemDSK).content.dsk.sources?.fillSource - } else { - mixMinusSource = (tlObj as TSR.TimelineObjAtemME).content.me.input - } - - if (piece.sourceLayerId === SourceLayer.PgmLive && !piece.name.match(/EVS ?\d+/i)) { - // Never show live sources - mixMinusSource = null - } - if (piece.sourceLayerId === SourceLayer.PgmDVE) { - // If the dve has a single kam, show that. Otherwise fallback to default - const pieceContent = piece.content as SplitsContent - const kamSources = _.filter( - pieceContent.boxSourceConfiguration || [], - box => box.type === SourceLayerType.CAMERA - ) - - mixMinusSource = kamSources.length === 1 ? Number(kamSources[0].switcherInput) : null - } - if (mixMinusSource !== null && mixMinusSource !== -1) { - const mixMinusObj: TSR.TimelineObjAtemAUX & TimelineBlueprintExt = { - ..._.omit(tlObj, 'content'), - id: '', - layer: AtemLLayer.AtemAuxVideoMixMinus, - priority: tlObj.classes?.includes(ControlClasses.MixMinusOverrideDsk) ? 10 : tlObj.priority, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: - mixMinusSource !== undefined && mixMinusSource !== -1 - ? mixMinusSource - : context.config.studio.SwitcherSource.MixMinusDefault - } - }, - metaData: { - ...tlObj.metaData, - context: `Mix-minus for ${tlObj.id}` - } - } - mixMinusObj.classes = mixMinusObj.classes?.filter( - c => !c.match(`studio0_parent_`) && !c.match(ControlClasses.Placeholder) - ) - extraObjs.push(mixMinusObj) - } - } - }) - - const atemDskObjs = (piece.content.timelineObjects as TSR.TimelineObjAtemDSK[]).filter( - obj => - obj.content && - obj.content.deviceType === TSR.DeviceType.ATEM && - obj.content.type === TSR.TimelineContentTypeAtem.DSK - ) - _.each(atemDskObjs, tlObj => { - if (tlObj.layer === jingleDSKLayer) { - const newProps = _.pick(tlObj.content.dsk, 'onAir') - if (_.isEqual(newProps, tlObj.content.dsk)) { - context.core.notifyUserWarning(`Unhandled Keyer properties for Clean keyer, it may look wrong`) - } - - const cleanObj: TSR.TimelineObjAtemME & TimelineBlueprintExt = { - ..._.omit(tlObj, 'content', 'keyframes'), - id: '', - layer: AtemLLayer.AtemCleanUSKEffect, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - upstreamKeyers: [ - { - upstreamKeyerId: 0 - }, - { - upstreamKeyerId: 1, - ...newProps - } - ] - } - } - } - extraObjs.push(cleanObj) - } - }) - - piece.content.timelineObjects = piece.content.timelineObjects.concat(extraObjs) - piece.content.timelineObjects = piece.content.timelineObjects.filter( - (obj: TSR.TSRTimelineObjBase) => !obj.classes?.includes(ControlClasses.Placeholder) - ) - } -} diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index 0904fd3d..38c702d5 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -146,7 +146,7 @@ describe('Graphics', () => { expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] - expect(timeline).toHaveLength(5) + expect(timeline).toHaveLength(7) const vizObj = timeline.find( t => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT @@ -318,7 +318,7 @@ describe('Graphics', () => { expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] - expect(timeline).toHaveLength(5) + expect(timeline).toHaveLength(7) const vizObj = timeline.find( t => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT diff --git a/src/tv2_afvd_studio/uniformConfig.ts b/src/tv2_afvd_studio/uniformConfig.ts index 6a2c5068..dee264b5 100644 --- a/src/tv2_afvd_studio/uniformConfig.ts +++ b/src/tv2_afvd_studio/uniformConfig.ts @@ -4,7 +4,9 @@ import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' export const GALLERY_UNIFORM_CONFIG: UniformConfig = { SwitcherLLayers: { PrimaryMixEffect: SwitcherMixEffectLLayer.Program, + PrimaryMixEffectClone: SwitcherMixEffectLLayer.Clean, JingleUskMixEffect: SwitcherMixEffectLLayer.CleanUSKEffect, - ProgramAux: SwitcherAuxLLayer.AuxProgram + ProgramAux: SwitcherAuxLLayer.AuxProgram, + MixMinusAux: SwitcherAuxLLayer.AuxVideoMixMinus } } diff --git a/src/tv2_offtube_showstyle/actions.ts b/src/tv2_offtube_showstyle/actions.ts index a5f81232..ea49fb71 100644 --- a/src/tv2_offtube_showstyle/actions.ts +++ b/src/tv2_offtube_showstyle/actions.ts @@ -6,7 +6,6 @@ import { OFFTUBE_DVE_GENERATOR_OPTIONS } from './content/OfftubeDVEContent' import { createJingleContentOfftube } from './cues/OfftubeJingle' import { OfftubeEvaluateCues } from './helpers/EvaluateCues' import { OfftubeOutputLayers, OfftubeSourceLayer } from './layers' -import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' const SELECTED_ADLIB_LAYERS = [ OfftubeSourceLayer.SelectedAdLibDVE, @@ -25,7 +24,6 @@ export async function executeActionOfftube( context, QBOX_UNIFORM_CONFIG, { - postProcessPieceTimelineObjects, EvaluateCues: OfftubeEvaluateCues, DVEGeneratorOptions: OFFTUBE_DVE_GENERATOR_OPTIONS, SourceLayers: { diff --git a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts index dbb07f6d..f2758518 100644 --- a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts +++ b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts @@ -16,8 +16,7 @@ export const OFFTUBE_DVE_GENERATOR_OPTIONS: DVEOptions = { dveLayers: { ATEM: { SSrcDefault: OfftubeAtemLLayer.AtemSSrcDefault, - SSrcArt: OfftubeAtemLLayer.AtemSSrcArt, - MEProgram: OfftubeAtemLLayer.AtemMEClean + SSrcArt: OfftubeAtemLLayer.AtemSSrcArt }, CASPAR: { CGDVEKey: OfftubeCasparLLayer.CasparCGDVEKey, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index f79eb610..e5711ed2 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -14,7 +14,7 @@ import { TimeFromFrames } from 'tv2-common' import { AdlibActionType, AdlibTags, SharedOutputLayers, TallyTags } from 'tv2-constants' -import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' +import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeOutputLayers, OfftubeSourceLayer } from '../layers' diff --git a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts index 47fd70e3..18b642be 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts @@ -3,12 +3,10 @@ import { IBlueprintPiece, PieceLifespan, TimelineObjectCoreExt, - TSR, WithTimeline } from 'blueprints-integration' import { CueDefinitionPgmClean, ExtendedSegmentContext, findSourceInfo, literal, SourceInfo } from 'tv2-common' import { SharedOutputLayers, SourceType, SwitcherAuxLLayer } from 'tv2-constants' -import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeSourceLayer } from '../layers' diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 3b4b1932..dbafafd2 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -64,10 +64,8 @@ import { OfftubeBlueprintConfig } from '../tv2_offtube_showstyle/helpers/config' import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' import { SisyfosChannel, sisyfosChannels } from '../tv2_offtube_studio/sisyfosChannels' import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' -import { AtemSourceIndex } from '../types/atem' import { NUMBER_OF_DVE_BOXES } from './content/OfftubeDVEContent' import { OfftubeOutputLayers, OfftubeSourceLayer } from './layers' -import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: IngestRundown): BlueprintResultRundown { const context = new ExtendedShowStyleContextImpl(coreContext, QBOX_UNIFORM_CONFIG) @@ -113,8 +111,6 @@ function getGlobalAdLibPiecesOfftube( ): IBlueprintAdLibPiece[] { const adlibItems: IBlueprintAdLibPiece[] = [] - adlibItems.forEach(p => postProcessPieceTimelineObjects(context, p, true)) - adlibItems.push(...CreateDSKBaselineAdlibs(context.config, 500, context.videoSwitcher)) adlibItems.push({ @@ -232,7 +228,6 @@ function getGlobalAdLibPiecesOfftube( } }) - adlibItems.forEach(p => postProcessPieceTimelineObjects(context, p, true)) return adlibItems } diff --git a/src/tv2_offtube_showstyle/getSegment.ts b/src/tv2_offtube_showstyle/getSegment.ts index db213172..cf7cb1bb 100644 --- a/src/tv2_offtube_showstyle/getSegment.ts +++ b/src/tv2_offtube_showstyle/getSegment.ts @@ -24,7 +24,6 @@ import { OfftubeCreatePartGrafik } from './parts/OfftubeGrafik' import { OfftubeCreatePartKam } from './parts/OfftubeKam' import { OfftubeCreatePartServer } from './parts/OfftubeServer' import { CreatePartUnknown } from './parts/OfftubeUnknown' -import { postProcessPartTimelineObjects } from './postProcessTimelineObjects' export async function getSegment( coreContext: ISegmentUserContext, @@ -48,8 +47,6 @@ export async function getSegment( const blueprintParts = result.parts - postProcessPartTimelineObjects(context, blueprintParts) - return { segment: result.segment, parts: blueprintParts @@ -80,9 +77,8 @@ function CreatePartContinuity( studioLabel: '', switcherInput: context.config.studio.SwitcherSource.Continuity, timelineObjects: [ - context.videoSwitcher.getMixEffectTimelineObject({ + ...context.videoSwitcher.getOnAirTimelineObjects({ priority: 1, - layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { input: context.config.studio.SwitcherSource.Continuity, transition: TransitionStyle.CUT diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index 04182a7e..a7d6aba3 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -58,21 +58,14 @@ export async function OfftubeCreatePartKam( ignoreMediaObjectStatus: true, fileName: '', path: '', - timelineObjects: [ - context.videoSwitcher.getMixEffectTimelineObject({ - id: ``, - enable: { - start: 0 - }, - priority: 1, - layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, - content: { - input: jingleDSK.Fill, - transition: partDefinition.transition?.style ?? TransitionStyle.CUT, - transitionDuration: partDefinition.transition?.duration - } - }) - ] + timelineObjects: context.videoSwitcher.getOnAirTimelineObjects({ + priority: 1, + content: { + input: jingleDSK.Fill, + transition: partDefinition.transition?.style ?? TransitionStyle.CUT, + transitionDuration: partDefinition.transition?.duration + } + }) }) }) } else { @@ -102,15 +95,10 @@ export async function OfftubeCreatePartKam( studioLabel: '', switcherInput, timelineObjects: [ - context.videoSwitcher.getMixEffectTimelineObject({ - id: ``, - enable: { - start: 0 - }, + ...context.videoSwitcher.getOnAirTimelineObjects({ priority: 1, - layer: context.uniformConfig.SwitcherLLayers.PrimaryMixEffect, content: { - input: Number(switcherInput), + input: switcherInput, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration } diff --git a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts b/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts deleted file mode 100644 index afe70c9d..00000000 --- a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { - BlueprintResultPart, - IBlueprintPieceGeneric, - OnGenerateTimelineObj, - TimelineObjectCoreExt, - TSR -} from 'blueprints-integration' -import { ExtendedShowStyleContext, TimelineBlueprintExt } from 'tv2-common' -import { ControlClasses } from 'tv2-constants' -import _ = require('underscore') -import { OfftubeAbstractLLayer, OfftubeAtemLLayer } from '../tv2_offtube_studio/layers' -import { OfftubeBlueprintConfig } from './helpers/config' - -export function postProcessPartTimelineObjects( - context: ExtendedShowStyleContext, - parts: BlueprintResultPart[] -) { - _.each(parts, part => { - _.each(part.pieces, p => postProcessPieceTimelineObjects(context, p, false)) - _.each(part.adLibPieces, p => postProcessPieceTimelineObjects(context, p, true)) - }) -} - -// Do any post-process of timeline objects -export function postProcessPieceTimelineObjects( - context: ExtendedShowStyleContext, - piece: IBlueprintPieceGeneric, - isAdlib: boolean -) { - if (piece.content?.timelineObjects) { - const extraObjs: TimelineObjectCoreExt[] = [] - - const atemMeObjs = (piece.content.timelineObjects as Array< - | (TSR.TimelineObjAtemME & TimelineBlueprintExt & OnGenerateTimelineObj) - | (TSR.TimelineObjAtemDSK & TimelineBlueprintExt & OnGenerateTimelineObj) - >).filter( - obj => - obj.content && - obj.content.deviceType === TSR.DeviceType.ATEM && - (obj.content.type === TSR.TimelineContentTypeAtem.ME || obj.content.type === TSR.TimelineContentTypeAtem.DSK) - ) - _.each(atemMeObjs, tlObj => { - if ( - tlObj.layer === OfftubeAtemLLayer.AtemMEClean || - tlObj.classes?.includes(ControlClasses.MixMinusOverrideDsk) - ) { - if (!tlObj.id) { - tlObj.id = context.core.getHashId(OfftubeAtemLLayer.AtemMEClean, true) - } - if (!tlObj.metaData) { - tlObj.metaData = {} - } - - if ( - (!isAdlib || piece.toBeQueued) && - 'me' in tlObj.content && - (tlObj.content.me.input !== -1 || tlObj.metaData?.mediaPlayerSession !== undefined) - ) { - if (tlObj.classes?.includes(ControlClasses.AbstractLookahead)) { - // Create a lookahead-lookahead object for this me-program - const lookaheadObj: TSR.TimelineObjAbstractAny & TimelineBlueprintExt = { - id: '', - enable: { start: 0 }, - priority: 0, - layer: OfftubeAbstractLLayer.OfftubeAbstractLLayerAbstractLookahead, - content: { - deviceType: TSR.DeviceType.ABSTRACT - }, - metaData: { - context: `Lookahead-lookahead for ${tlObj.id}`, - mediaPlayerSession: tlObj.metaData?.mediaPlayerSession - }, - classes: ['ab_on_preview'] - } - extraObjs.push(lookaheadObj) - } else { - // Create a lookahead-lookahead object for this me-program - const lookaheadObj: TSR.TimelineObjAtemME & TimelineBlueprintExt = { - id: '', - enable: { start: 0 }, - priority: 0, // Must be below lookahead, except when forced by hold - layer: OfftubeAtemLLayer.AtemMENext, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - previewInput: - tlObj.content.me.input !== -1 - ? tlObj.content.me.input - : context.config.studio.SwitcherSource.Default - } - }, - metaData: { - context: `Lookahead-lookahead for ${tlObj.id}`, - mediaPlayerSession: tlObj.metaData?.mediaPlayerSession - }, - classes: ['ab_on_preview'] - } - extraObjs.push(lookaheadObj) - } - } - } - }) - - piece.content.timelineObjects = piece.content.timelineObjects.concat(extraObjs) - piece.content.timelineObjects = piece.content.timelineObjects.filter( - (obj: TSR.TSRTimelineObjBase) => !obj.classes?.includes(ControlClasses.Placeholder) - ) - } -} diff --git a/src/tv2_offtube_studio/layers.ts b/src/tv2_offtube_studio/layers.ts index d21fff02..51991893 100644 --- a/src/tv2_offtube_studio/layers.ts +++ b/src/tv2_offtube_studio/layers.ts @@ -10,9 +10,7 @@ import * as _ from 'underscore' /** Get all the Real LLayers (map to devices). Note: Does not include some which are dynamically generated */ export function RealLLayers(): string[] { return ( - _.values(OfftubeAbstractLLayer) - // @ts-ignore - .concat(_.values(OfftubeSisyfosLLayer)) + _.values(OfftubeSisyfosLLayer) // @ts-ignore .concat(_.values(OfftubeAtemLLayer)) // @ts-ignore @@ -24,11 +22,6 @@ export function RealLLayers(): string[] { ) } -export enum OfftubeAbstractLLayer { - /** Contains the classes to enable infinites */ - OfftubeAbstractLLayerAbstractLookahead = 'offtube_abstract_layer_abstract_lookahead' -} - enum SisyfosLLayer { SisyfosConfig = 'sisyfos_config', SisyfosGroupServer = 'sisyfos_group_server', diff --git a/src/tv2_offtube_studio/migrations/mappings-defaults.ts b/src/tv2_offtube_studio/migrations/mappings-defaults.ts index b59eba1f..a328d443 100644 --- a/src/tv2_offtube_studio/migrations/mappings-defaults.ts +++ b/src/tv2_offtube_studio/migrations/mappings-defaults.ts @@ -8,13 +8,7 @@ import { } from 'tv2-common' import { AbstractLLayer } from 'tv2-constants' import { ATEMModel } from '../../types/atem' -import { - OfftubeAbstractLLayer, - OfftubeAtemLLayer, - OfftubeCasparLLayer, - OfftubeGraphicLLayer, - OfftubeSisyfosLLayer -} from '../layers' +import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeGraphicLLayer, OfftubeSisyfosLLayer } from '../layers' const MAPPINGS_ABSTRACT: BlueprintMappings = { core_abstract: literal({ @@ -37,11 +31,6 @@ const MAPPINGS_ABSTRACT: BlueprintMappings = { deviceId: 'abstract0', lookahead: LookaheadMode.NONE }), - [OfftubeAbstractLLayer.OfftubeAbstractLLayerAbstractLookahead]: literal({ - device: TSR.DeviceType.ABSTRACT, - deviceId: 'abstract0', - lookahead: LookaheadMode.WHEN_CLEAR - }), [AbstractLLayer.IdentMarker]: literal({ device: TSR.DeviceType.ABSTRACT, deviceId: 'abstract0', diff --git a/src/tv2_offtube_studio/uniformConfig.ts b/src/tv2_offtube_studio/uniformConfig.ts index 7f8e3480..16dcafd7 100644 --- a/src/tv2_offtube_studio/uniformConfig.ts +++ b/src/tv2_offtube_studio/uniformConfig.ts @@ -4,7 +4,8 @@ import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' export const QBOX_UNIFORM_CONFIG: UniformConfig = { SwitcherLLayers: { PrimaryMixEffect: SwitcherMixEffectLLayer.Clean, - ServerLookaheadAux: SwitcherAuxLLayer.AuxServerLookahead, + NextServerAux: SwitcherAuxLLayer.AuxServerLookahead, + NextPreviewMixEffect: SwitcherMixEffectLLayer.Next, JingleNextMixEffect: SwitcherMixEffectLLayer.NextJingle } } From 22accbcaac4891a979e890f2279214f6c24cb282 Mon Sep 17 00:00:00 2001 From: ianshade Date: Fri, 10 Feb 2023 11:18:00 +0100 Subject: [PATCH 16/86] wip: SOF-1260 implement some atem tests, remove stale code, refactor more --- src/__mocks__/context.ts | 5 +- .../__tests__/rundownDuration.spec.ts | 2 +- src/tv2-common/__tests__/testUtil.ts | 3 + src/tv2-common/__tests__/util.spec.ts | 36 +- src/tv2-common/content/dve.ts | 65 +-- src/tv2-common/cues/ekstern.ts | 3 - src/tv2-common/helpers/dsk.ts | 100 ++-- src/tv2-common/layers/timelineLayers.ts | 1 + src/tv2-common/types/config.ts | 13 +- src/tv2-common/util.ts | 10 +- src/tv2-common/videoSwitchers/Atem.ts | 62 ++- src/tv2-common/videoSwitchers/TriCaster.ts | 16 +- .../videoSwitchers/VideoSwitcher.ts | 16 +- .../videoSwitchers/__tests__/Atem.spec.ts | 478 ++++++++++++++++++ src/tv2-common/videoSwitchers/types.ts | 19 +- src/tv2-constants/enums.ts | 4 +- .../__tests__/actions.spec.ts | 18 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 7 - .../__tests__/transitions.spec.ts | 5 +- src/tv2_afvd_showstyle/getRundown.ts | 7 +- src/tv2_afvd_showstyle/helpers/content/dve.ts | 9 +- .../pieces/__tests__/grafikViz.spec.ts | 5 +- .../helpers/pieces/__tests__/telefon.spec.ts | 4 +- .../helpers/pieces/ekstern.ts | 4 - src/tv2_afvd_showstyle/migrations/index.ts | 2 - src/tv2_afvd_showstyle/migrations/util.ts | 37 -- .../migrations/variants-defaults.ts | 52 -- .../__tests__/graphics.spec.ts | 14 +- src/tv2_afvd_studio/getBaseline.ts | 11 +- src/tv2_afvd_studio/layers.ts | 32 +- .../migrations/mappings-defaults.ts | 39 +- src/tv2_afvd_studio/migrations/util.ts | 28 - .../__tests__/actions.spec.ts | 17 +- .../content/OfftubeDVEContent.ts | 9 +- .../cues/OfftubeAdlib.ts | 41 +- .../cues/OfftubeEkstern.ts | 4 - src/tv2_offtube_showstyle/getRundown.ts | 7 +- src/tv2_offtube_showstyle/migrations/index.ts | 2 - src/tv2_offtube_showstyle/migrations/util.ts | 37 -- .../migrations/variants-defaults.ts | 52 -- .../parts/OfftubeServer.ts | 2 +- src/tv2_offtube_studio/getBaseline.ts | 3 +- src/tv2_offtube_studio/layers.ts | 30 +- .../migrations/mappings-defaults.ts | 56 +- src/tv2_offtube_studio/migrations/util.ts | 28 - 45 files changed, 748 insertions(+), 647 deletions(-) create mode 100644 src/tv2-common/__tests__/testUtil.ts create mode 100644 src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts delete mode 100644 src/tv2_afvd_showstyle/migrations/variants-defaults.ts delete mode 100644 src/tv2_offtube_showstyle/migrations/variants-defaults.ts diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index e058cf2f..472b1a7d 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -37,6 +37,7 @@ import { ITV2ActionExecutionContext, MixEffectProps, PieceMetaData, + TV2StudioConfigBase, VideoSwitcher, VideoSwitcherImpl } from 'tv2-common' @@ -47,7 +48,7 @@ import { GalleryShowStyleConfig, preprocessConfig as parseShowStyleConfigAFVD } from '../tv2_afvd_showstyle/helpers/config' -import { preprocessConfig as parseStudioConfigAFVD, StudioConfig } from '../tv2_afvd_studio/helpers/config' +import { preprocessConfig as parseStudioConfigAFVD } from '../tv2_afvd_studio/helpers/config' import mappingsDefaultsAFVD from '../tv2_afvd_studio/migrations/mappings-defaults' import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' @@ -650,7 +651,7 @@ class MockVideoSwitcher implements VideoSwitcher { } interface ConfigOverrides { - studioConfig?: Partial + studioConfig?: Partial showStyleConfig?: Partial } diff --git a/src/inews-mixins/__tests__/rundownDuration.spec.ts b/src/inews-mixins/__tests__/rundownDuration.spec.ts index 5a143397..1a5e9207 100644 --- a/src/inews-mixins/__tests__/rundownDuration.spec.ts +++ b/src/inews-mixins/__tests__/rundownDuration.spec.ts @@ -2,7 +2,7 @@ import { IngestSegment } from 'blueprints-integration' import { literal } from 'tv2-common' import { getRundownDuration } from '../rundownDuration' -export function makeSegmentWithoutTime(externalId: string, rank: number): IngestSegment { +function makeSegmentWithoutTime(externalId: string, rank: number): IngestSegment { return literal({ externalId, name: externalId, diff --git a/src/tv2-common/__tests__/testUtil.ts b/src/tv2-common/__tests__/testUtil.ts new file mode 100644 index 00000000..608b8566 --- /dev/null +++ b/src/tv2-common/__tests__/testUtil.ts @@ -0,0 +1,3 @@ +export function prefixLayer(layerName: string) { + return 'atem_' + layerName +} diff --git a/src/tv2-common/__tests__/util.spec.ts b/src/tv2-common/__tests__/util.spec.ts index 2093e440..580fc2bb 100644 --- a/src/tv2-common/__tests__/util.spec.ts +++ b/src/tv2-common/__tests__/util.spec.ts @@ -1,6 +1,4 @@ -import { PieceLifespan } from 'blueprints-integration' -import { SharedOutputLayers } from 'tv2-constants' -import { assertUnreachable, isAdLibPiece, joinAssetToFolder, joinAssetToNetworkPath } from '../util' +import { assertUnreachable, joinAssetToFolder, joinAssetToNetworkPath } from '../util' const JOIN_ASSET_FOLDER_TESTS: Array<{ name: string @@ -151,38 +149,6 @@ const JOIN_ASSET_NETWORK_PATH_TESTS: Array<{ ] describe('util', () => { - it('Detects AdLib piece', () => { - expect( - isAdLibPiece({ - _rank: 0, - externalId: '-', - name: 'test adlib', - sourceLayerId: 'Cam', - outputLayerId: SharedOutputLayers.PGM, - lifespan: PieceLifespan.WithinPart, - content: { - timelineObjects: [] - } - }) - ).toBeTruthy() - - expect( - isAdLibPiece({ - externalId: '-', - name: 'test non-adlib', - sourceLayerId: 'Cam', - outputLayerId: SharedOutputLayers.PGM, - lifespan: PieceLifespan.WithinPart, - enable: { - start: 0 - }, - content: { - timelineObjects: [] - } - }) - ).toBeFalsy() - }) - it('Asserts Unreachable', () => { expect(() => { // @ts-ignore diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 9177b403..ad9a858e 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -22,7 +22,6 @@ import { PartDefinition, PieceMetaData, SpecialInput, - TimelineBlueprintExt, TransitionStyle, TV2BlueprintConfigBase, TV2StudioConfigBase @@ -86,10 +85,6 @@ export interface DVEConfig { } export interface DVELayers { - ATEM: { - SSrcDefault: string - SSrcArt: string - } CASPAR: { CGDVEKey: string CGDVEFrame: string @@ -113,8 +108,6 @@ export interface DVEPieceMetaData extends PieceMetaData { export interface DVEOptions { dveLayers: DVELayers - /** All audio layers */ - AUDIO_LAYERS: string[] } type BoxConfig = DVEConfigBox & { source: number } @@ -305,53 +298,20 @@ export function MakeContentDVE2< boxSourceConfiguration: boxSources, timelineObjects: _.compact([ // setup ssrc - literal({ - id: '', - enable: { - while: '1' - }, + ...context.videoSwitcher.getDveTimelineObjects({ priority: 1, - layer: dveGeneratorOptions.dveLayers.ATEM.SSrcDefault, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.SSRC, - ssrc: { boxes } + boxes, + template, + artFillSource: context.config.studio.SwitcherSource.SplitArtF, + artCutSource: context.config.studio.SwitcherSource.SplitArtK }, metaData: { mediaPlayerSession: hasServer ? mediaPlayerSessionId ?? MEDIA_PLAYER_AUTO : undefined } }), - literal({ - id: '', - enable: getDVEEnable(Number(context.config.studio.CasparPrerollDuration) - 10), // TODO - why 10ms? - priority: 1, - layer: dveGeneratorOptions.dveLayers.ATEM.SSrcArt, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.SSRCPROPS, - ssrcProps: { - artFillSource: context.config.studio.SwitcherSource.SplitArtF, - artCutSource: context.config.studio.SwitcherSource.SplitArtK, - artOption: 1, - ...(template.properties && template.properties?.artPreMultiplied === false - ? { - artPreMultiplied: false, - artInvertKey: template.properties.artInvertKey, - artClip: template.properties.artClip * 10, - artGain: template.properties.artGain * 10 - } - : { artPreMultiplied: true }), - ...(template.border?.borderEnabled - ? { - ...template.border - } - : { borderEnabled: false }) - } - } - }), ...context.videoSwitcher.getOnAirTimelineObjects({ - id: '', - enable: getDVEEnable(Number(context.config.studio.CasparPrerollDuration)), + enable: { start: context.config.studio.CasparPrerollDuration }, priority: 1, content: { input: SpecialInput.DVE, @@ -360,7 +320,7 @@ export function MakeContentDVE2< }), literal({ id: '', - enable: getDVEEnable(), + enable: { start: 0 }, priority: 1, layer: SharedGraphicLLayer.GraphicLLayerLocators, content: CreateHTMLRendererContent(context.config, 'locators', { @@ -372,7 +332,7 @@ export function MakeContentDVE2< ? [ literal({ id: '', - enable: getDVEEnable(), + enable: { start: 0 }, priority: 1, layer: dveGeneratorOptions.dveLayers.CASPAR.CGDVEKey, content: { @@ -391,7 +351,7 @@ export function MakeContentDVE2< ? [ literal({ id: '', - enable: getDVEEnable(), + enable: { start: 0 }, priority: 1, layer: dveGeneratorOptions.dveLayers.CASPAR.CGDVEFrame, content: { @@ -478,13 +438,6 @@ function boxSource(info: { } } -function getDVEEnable(offsetFromStart?: number, media?: boolean): TSR.TSRTimelineObj['enable'] { - if (offsetFromStart) { - return { start: offsetFromStart ?? 0 } - } - return media ? { while: '1' } : { start: offsetFromStart ?? 0 } -} - export function getUniquenessIdDVE(parsedCue: CueDefinitionDVE) { return `dve_${parsedCue.template}_${parsedCue.labels.join('')}_${ parsedCue.sources diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index 57155f2a..98ac0dc1 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -26,9 +26,6 @@ interface EksternLayers { SourceLayer: { PgmLive: string } - ATEM: { - MEProgram: string - } } export function EvaluateEksternBase< diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index d8493df9..232301a5 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -48,7 +48,7 @@ export function getDskOnAirTimelineObjects( ): TSR.TSRTimelineObj[] { const dskConf = FindDSKWithRoles(context.config, [dskRole]) return [ - ...context.videoSwitcher.getDskTimelineObjects({ + context.videoSwitcher.getDskTimelineObject({ id: '', enable: enable ?? { start: 0 @@ -109,15 +109,17 @@ export function CreateDSKBaselineAdlibs( tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_NO_NEXT_HIGHLIGHT, AdlibTags.ADLIB_DSK_OFF], invertOnAirState: true, content: { - timelineObjects: videoSwitcher.getDskTimelineObjects({ - id: '', - enable: { while: '1' }, - priority: 10, - layer: LLayerDSK(dsk.Number), - content: { - onAir: false - } - }) + timelineObjects: [ + videoSwitcher.getDskTimelineObject({ + id: '', + enable: { while: '1' }, + priority: 10, + layer: LLayerDSK(dsk.Number), + content: { + onAir: false + } + }) + ] } }) } else { @@ -130,25 +132,27 @@ export function CreateDSKBaselineAdlibs( lifespan: PieceLifespan.OutOnRundownChange, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_NO_NEXT_HIGHLIGHT, AdlibTags.ADLIB_DSK_ON], content: { - timelineObjects: videoSwitcher.getDskTimelineObjects({ - id: '', - enable: { while: '1' }, - priority: 10, - layer: LLayerDSK(dsk.Number), // @todo - content: { - onAir: true, - sources: { - fillSource: dsk.Fill, - cutSource: dsk.Key - }, - properties: { - tie: false, - preMultiply: false, - clip: Number(dsk.Clip) * 10, // input is percents (0-100), atem uses 1-000, - gain: Number(dsk.Gain) * 10 // input is percents (0-100), atem uses 1-000, + timelineObjects: [ + videoSwitcher.getDskTimelineObject({ + id: '', + enable: { while: '1' }, + priority: 10, + layer: LLayerDSK(dsk.Number), // @todo + content: { + onAir: true, + sources: { + fillSource: dsk.Fill, + cutSource: dsk.Key + }, + properties: { + tie: false, + preMultiply: false, + clip: Number(dsk.Clip) * 10, // input is percents (0-100), atem uses 1-000, + gain: Number(dsk.Gain) * 10 // input is percents (0-100), atem uses 1-000, + } } - } - }) + }) + ] } }) } @@ -161,29 +165,27 @@ export function CreateDSKBaseline( config: TV2BlueprintConfigBase, videoSwitcher: VideoSwitcher ): TSR.TSRTimelineObj[] { - return config.dsk - .map(dsk => { - return videoSwitcher.getDskTimelineObjects({ - id: '', - enable: { while: '1' }, - priority: 0, - layer: LLayerDSK(dsk.Number), // @todo - content: { - onAir: dsk.DefaultOn, - sources: { - fillSource: dsk.Fill, - cutSource: dsk.Key - }, - properties: { - tie: false, - preMultiply: false, - clip: Number(dsk.Clip) * 10, // input is percents (0-100), atem uses 1-000, - gain: Number(dsk.Gain) * 10 // input is percents (0-100), atem uses 1-000, - } + return config.dsk.map(dsk => { + return videoSwitcher.getDskTimelineObject({ + id: '', + enable: { while: '1' }, + priority: 0, + layer: LLayerDSK(dsk.Number), // @todo + content: { + onAir: dsk.DefaultOn, + sources: { + fillSource: dsk.Fill, + cutSource: dsk.Key + }, + properties: { + tie: false, + preMultiply: false, + clip: Number(dsk.Clip) * 10, // input is percents (0-100), atem uses 1-000, + gain: Number(dsk.Gain) * 10 // input is percents (0-100), atem uses 1-000, } - }) + } }) - .flat() + }) } export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { diff --git a/src/tv2-common/layers/timelineLayers.ts b/src/tv2-common/layers/timelineLayers.ts index d506fbe1..81fb446b 100644 --- a/src/tv2-common/layers/timelineLayers.ts +++ b/src/tv2-common/layers/timelineLayers.ts @@ -6,6 +6,7 @@ export const TRICASTER_DEVICE_ID = 'tricaster0' export const TRICASTER_CLEAN_ME = 'v1' export const TRICASTER_DVE_ME = 'v2' +export const ATEM_DEVICE_ID = 'atem0' export const ATEM_LAYER_PREFIX = 'atem_' export const TRICASTER_LAYER_PREFIX = 'tricaster_' diff --git a/src/tv2-common/types/config.ts b/src/tv2-common/types/config.ts index c192cbac..2a174033 100644 --- a/src/tv2-common/types/config.ts +++ b/src/tv2-common/types/config.ts @@ -12,14 +12,17 @@ export type TableConfigItemSourceMappingWithSisyfos = { AcceptPersistAudio?: boolean } & TableConfigItemSourceMapping -export interface TableConfigItemDSK { - /** 0-based */ - Number: number +export interface SwitcherDskProps { Fill: number Key: number + Clip: string + Gain: string +} + +export interface TableConfigItemDSK extends SwitcherDskProps { + /** 0-based */ + Number: number Toggle: boolean DefaultOn: boolean Roles?: DSKRoles[] - Clip: string - Gain: string } diff --git a/src/tv2-common/util.ts b/src/tv2-common/util.ts index 129c4fea..61edcf21 100644 --- a/src/tv2-common/util.ts +++ b/src/tv2-common/util.ts @@ -1,4 +1,4 @@ -import { IBlueprintAdLibPiece, IBlueprintPiece, ICommonContext, TSR } from 'blueprints-integration' +import { ICommonContext, TSR } from 'blueprints-integration' import { ActionBase } from './actions' export function literal(o: T) { @@ -24,14 +24,6 @@ export function createEmptyObject(obj: EmptyBaseObj): TSR.TimelineObjEmpty { } } -/** - * Returs true if the piece is interface IBlueprintAdLibPiece - * @param {IBlueprintPiece | IBlueprintAdLibPiece} piece Piece to check - */ -export function isAdLibPiece(piece: IBlueprintPiece | IBlueprintAdLibPiece) { - return '_rank' in piece -} - export function SanitizeString(str: string) { return str.replace(/\W/g, '_') } diff --git a/src/tv2-common/videoSwitchers/Atem.ts b/src/tv2-common/videoSwitchers/Atem.ts index b6a6589d..f6a68bdf 100644 --- a/src/tv2-common/videoSwitchers/Atem.ts +++ b/src/tv2-common/videoSwitchers/Atem.ts @@ -1,4 +1,6 @@ import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' +import { literal } from 'tv2-common' +import { SwitcherDveLLayer } from 'tv2-constants' import _ = require('underscore') import { AtemSourceIndex } from '../../types/atem' import { ATEM_LAYER_PREFIX } from '../layers' @@ -6,6 +8,7 @@ import { TimelineBlueprintExt } from '../onTimelineGenerate' import { AuxProps, DskProps, + DveProps, Keyer, MixEffectProps, SpecialInput, @@ -52,7 +55,7 @@ export class Atem extends VideoSwitcherImpl { me.upstreamKeyers = upstreamKeyers } return { - ...this.getBaseProperties(props), + ...this.getBaseProperties(props, props.layer), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.ME, @@ -101,10 +104,10 @@ export class Atem extends VideoSwitcherImpl { return timelineObject } - public getDskTimelineObjects(props: DskProps) { + public getDskTimelineObject(props: DskProps) { const { content } = props const timelineObject: TSR.TimelineObjAtemDSK = { - ...this.getBaseProperties(props), + ...this.getBaseProperties(props, props.layer), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.DSK, @@ -123,12 +126,12 @@ export class Atem extends VideoSwitcherImpl { } } } - return [timelineObject] + return timelineObject } public getAuxTimelineObject(props: AuxProps): TSR.TimelineObjAtemAUX { return { - ...this.getBaseProperties(props), + ...this.getBaseProperties(props, props.layer), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.AUX, @@ -151,6 +154,43 @@ export class Atem extends VideoSwitcherImpl { timelineObject.content.type === TSR.TimelineContentTypeAtem.AUX ) } + public getDveTimelineObjects(props: DveProps): TSR.TSRTimelineObj[] { + return [ + literal({ + ...this.getBaseProperties(props, SwitcherDveLLayer.DveBoxes), + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.SSRC, + ssrc: { boxes: props.content.boxes } + } + }), + literal({ + ...this.getBaseProperties(props, SwitcherDveLLayer.Dve), + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.SSRCPROPS, + ssrcProps: { + artFillSource: props.content.artFillSource, + artCutSource: props.content.artCutSource, + artOption: 1, + ...(props.content.template.properties && props.content.template.properties?.artPreMultiplied === false + ? { + artPreMultiplied: false, + artInvertKey: props.content.template.properties.artInvertKey, + artClip: props.content.template.properties.artClip * 10, + artGain: props.content.template.properties.artGain * 10 + } + : { artPreMultiplied: true }), + ...(props.content.template.border?.borderEnabled + ? { + ...props.content.template.border + } + : { borderEnabled: false }) + } + } + }) + ] + } public updateAuxInput(_timelineObject: TSR.TSRTimelineObj, _input: number | SpecialInput): TSR.TSRTimelineObj { throw new Error('Method not implemented.') } @@ -160,9 +200,6 @@ export class Atem extends VideoSwitcherImpl { timelineObject.content.type === TSR.TimelineContentTypeAtem.SSRC ) } - public getDveTimelineObject(_properties: AuxProps): TSR.TSRTimelineObj { - throw new Error('Method not implemented.') - } public updateUnpopulatedDveBoxes( _timelineObject: TimelineObjectCoreExt, _input: number | SpecialInput @@ -170,11 +207,14 @@ export class Atem extends VideoSwitcherImpl { throw new Error('Method not implemented.') } - private getBaseProperties(props: TimelineObjectProps): Omit { + private getBaseProperties( + props: TimelineObjectProps, + layer: string + ): Omit { return { ...TIMELINE_OBJECT_DEFAULTS, ..._.omit(props, 'content'), - layer: ATEM_LAYER_PREFIX + props.layer + layer: ATEM_LAYER_PREFIX + layer } } @@ -205,7 +245,7 @@ export class Atem extends VideoSwitcherImpl { case TransitionStyle.WIPE_FOR_GFX: return { wipe: { - rate: Number(this.config.studio.HTMLGraphics.TransitionSettings.wipeRate), + rate: this.config.studio.HTMLGraphics.TransitionSettings.wipeRate, pattern: 1, reverseDirection: true, borderSoftness: this.config.studio.HTMLGraphics.TransitionSettings.borderSoftness diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 4477c434..a81a6350 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -4,6 +4,7 @@ import { TRICASTER_CLEAN_ME, TRICASTER_DVE_ME, TRICASTER_LAYER_PREFIX } from '.. import { AuxProps, DskProps, + DveProps, Keyer, MixEffectProps, SpecialInput, @@ -46,7 +47,7 @@ export class TriCaster extends VideoSwitcherImpl { public getMixEffectTimelineObject(props: MixEffectProps): TSR.TimelineObjTriCasterME { const { content } = props return { - ...this.getBaseProperties(props), + ...this.getBaseProperties(props, props.layer), content: { deviceType: TSR.DeviceType.TRICASTER, type: TSR.TimelineContentTypeTriCaster.ME, @@ -98,12 +99,12 @@ export class TriCaster extends VideoSwitcherImpl { return timelineObject } - public getDskTimelineObjects(_properties: DskProps): TSR.TSRTimelineObj[] { + public getDskTimelineObject(_properties: DskProps): TSR.TSRTimelineObj { throw new Error('Method not implemented.') } public getAuxTimelineObject(props: AuxProps): TSR.TimelineObjTriCasterMixOutput { return { - ...this.getBaseProperties(props), + ...this.getBaseProperties(props, props.layer), content: { deviceType: TSR.DeviceType.TRICASTER, type: TSR.TimelineContentTypeTriCaster.MIX_OUTPUT, @@ -127,7 +128,7 @@ export class TriCaster extends VideoSwitcherImpl { !!(timelineObject.content.me as TSR.TriCasterMixEffectInEffectMode).layers ) } - public getDveTimelineObject(_properties: AuxProps): TSR.TSRTimelineObj { + public getDveTimelineObjects(_properties: DveProps): TSR.TSRTimelineObj[] { throw new Error('Method not implemented.') } public updateUnpopulatedDveBoxes( @@ -137,11 +138,14 @@ export class TriCaster extends VideoSwitcherImpl { throw new Error('Method not implemented.') } - private getBaseProperties(props: TimelineObjectProps): Omit { + private getBaseProperties( + props: TimelineObjectProps, + layer: string + ): Omit { return { ...TIMELINE_OBJECT_DEFAULTS, ..._.omit(props, 'content'), - layer: TRICASTER_LAYER_PREFIX + props.layer + layer: TRICASTER_LAYER_PREFIX + layer } } diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts index e30f264e..86bb9d89 100644 --- a/src/tv2-common/videoSwitchers/VideoSwitcher.ts +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -3,6 +3,7 @@ import { Atem, AuxProps, DskProps, + DveProps, MixEffectProps, OnAirMixEffectProps, SpecialInput, @@ -16,19 +17,14 @@ import { import _ = require('underscore') export abstract class VideoSwitcherImpl implements VideoSwitcher { - public static videoSwitcherSingleton: VideoSwitcherImpl | undefined = undefined public static getVideoSwitcher( core: IStudioContext, config: TV2StudioConfig, uniformConfig: UniformConfig ): VideoSwitcherImpl { - if (!this.videoSwitcherSingleton || this.videoSwitcherSingleton.type !== config.studio.SwitcherType) { - this.videoSwitcherSingleton = - config.studio.SwitcherType === SwitcherType.ATEM - ? new Atem(core, config, uniformConfig) - : new TriCaster(core, config, uniformConfig) - } - return this.videoSwitcherSingleton + return config.studio.SwitcherType === SwitcherType.ATEM + ? new Atem(core, config, uniformConfig) + : new TriCaster(core, config, uniformConfig) } public abstract readonly type: SwitcherType public abstract isDsk: (timelineObject: TimelineObjectCoreExt) => boolean @@ -103,7 +99,7 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { timelineObject: TimelineObjectCoreExt, input: number | SpecialInput ): TSR.TSRTimelineObj - public abstract getDveTimelineObject(properties: AuxProps): TSR.TSRTimelineObj + public abstract getDveTimelineObjects(properties: DveProps): TSR.TSRTimelineObj[] public abstract updateUnpopulatedDveBoxes( timelineObject: TimelineObjectCoreExt, input: number | SpecialInput @@ -120,6 +116,6 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { ): TSR.TSRTimelineObj public abstract updateInput(timelineObject: TSR.TSRTimelineObj, input: number | SpecialInput): TSR.TSRTimelineObj - public abstract getDskTimelineObjects(properties: DskProps): TSR.TSRTimelineObj[] + public abstract getDskTimelineObject(properties: DskProps): TSR.TSRTimelineObj public abstract getAuxTimelineObject(properties: AuxProps): TSR.TSRTimelineObj } diff --git a/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts new file mode 100644 index 00000000..d490357a --- /dev/null +++ b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts @@ -0,0 +1,478 @@ +import { TSR } from 'blueprints-integration' +import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' +import { makeMockGalleryContext } from '../../../__mocks__/context' +import { prefixLayer } from '../../../tv2-common/__tests__/testUtil' +import { TV2StudioConfigBase } from '../../../tv2-common/blueprintConfig' +import { AtemSourceIndex } from '../../../types/atem' +import { SwitcherType, TransitionStyle } from '../types' +import { VideoSwitcherImpl } from '../VideoSwitcher' + +const DURATION: number = 50 + +function setupAtem(studioConfigOverrides?: Partial) { + // @todo: is this the correct way? + const context = makeMockGalleryContext({ + studioConfig: { SwitcherType: SwitcherType.ATEM, ...studioConfigOverrides } + }) + return VideoSwitcherImpl.getVideoSwitcher(context.core, context.config, context.uniformConfig) +} + +describe('ATEM', () => { + describe('Mix Effect', () => { + test('sets timeline object defaults', () => { + const atem = setupAtem() + const timelineObject = atem.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5 + } + }) + expect(timelineObject).toMatchObject({ + id: '', + enable: { start: 0 }, + priority: 0, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.ME + } + }) + }) + + test('sets classes', () => { + const atem = setupAtem() + const timelineObject = atem.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5 + }, + classes: ['classA', 'classB'] + }) + expect(timelineObject).toMatchObject({ + classes: ['classA', 'classB'] + }) + }) + + test('sets metaData', () => { + const atem = setupAtem() + const timelineObject = atem.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5 + }, + metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } + }) + expect(timelineObject).toMatchObject({ + metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } + }) + }) + + test('sets layer prefix', () => { + const atem = setupAtem() + const timelineObject = atem.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5 + } + }) + expect(timelineObject).toMatchObject({ + layer: prefixLayer(SwitcherMixEffectLLayer.Program) + }) + }) + + test('sets programInput when no transition provided', () => { + const atem = setupAtem() + const timelineObject = atem.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5 + } + }) + expect(timelineObject).toMatchObject({ + content: { + me: { + programInput: 5 + } + } + }) + }) + + test('sets input when CUT transition provided', () => { + const atem = setupAtem() + const timelineObject = atem.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5, + transition: TransitionStyle.CUT + } + }) + expect(timelineObject).toMatchObject({ + content: { + me: { + input: 5, + transition: TSR.AtemTransitionStyle.CUT + } + } + }) + }) + + test('sets previewInput', () => { + const atem = setupAtem() + const timelineObject = atem.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + previewInput: 5 + } + }) + expect(timelineObject).toMatchObject({ + content: { + me: { + previewInput: 5 + } + } + }) + }) + + test('supports MIX', () => { + const atem = setupAtem() + const timelineObject = atem.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5, + transition: TransitionStyle.MIX, + transitionDuration: DURATION + } + }) + expect(timelineObject).toMatchObject({ + content: { + me: { + input: 5, + transition: TSR.AtemTransitionStyle.MIX, + transitionSettings: { + mix: { + rate: DURATION + } + } + } + } + }) + }) + + test('supports WIPE', () => { + const atem = setupAtem() + const timelineObject = atem.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5, + transition: TransitionStyle.WIPE, + transitionDuration: DURATION + } + }) + expect(timelineObject).toMatchObject({ + content: { + me: { + input: 5, + transition: TSR.AtemTransitionStyle.WIPE, + transitionSettings: { + wipe: { + rate: DURATION + } + } + } + } + }) + }) + + test('supports WIPE for GFX', () => { + const atem = setupAtem() + const timelineObject = atem.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5, + transition: TransitionStyle.WIPE_FOR_GFX + } + }) + expect(timelineObject).toMatchObject({ + content: { + me: { + input: 5, + transition: TSR.AtemTransitionStyle.WIPE, + transitionSettings: { + wipe: { + rate: 20, + pattern: 1, + reverseDirection: true, + borderSoftness: 7500 + } + } + } + } + }) + }) + + test('supports DIP', () => { + const atem = setupAtem() + const timelineObject = atem.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5, + transition: TransitionStyle.DIP, + transitionDuration: DURATION + } + }) + expect(timelineObject).toMatchObject({ + content: { + me: { + input: 5, + transition: TSR.AtemTransitionStyle.DIP, + transitionSettings: { + dip: { + rate: DURATION, + input: AtemSourceIndex.Col2 + } + } + } + } + }) + }) + + test('DIP input is 100 when SwitcherSource.Dip config value is 100', () => { + assertDipInputValueFromConfig(100) + }) + + test('DIP input is 4 when SwitcherSource.Dip config value is 4', () => { + assertDipInputValueFromConfig(4) + }) + + function assertDipInputValueFromConfig(dipInputSource: number) { + const atem = setupAtem({ + SwitcherSource: { + Dip: dipInputSource, + Default: 1, + SplitArtF: 1, + SplitArtK: 1, + DSK: [] + } + }) + const timelineObject = atem.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5, + transition: TransitionStyle.DIP, + transitionDuration: DURATION + } + }) + expect(timelineObject).toMatchObject({ + content: { + me: { + input: 5, + transition: TSR.AtemTransitionStyle.DIP, + transitionSettings: { + dip: { + rate: DURATION, + input: dipInputSource + } + } + } + } + }) + } + + test('supports keyers', () => { + const atem = setupAtem() + const timelineObject = atem.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + keyers: [ + { + id: 2, + onAir: true, + config: { + + } + } + ] + } + }) + expect(timelineObject).toMatchObject({ + content: { + me: { + transitionSettings: { + wipe: { + rate: 20, + pattern: 1, + reverseDirection: true, + borderSoftness: 7500 + } + } + } + } + }) + }) + }) + + describe('Aux', () => { + test('sets timeline object defaults', () => { + const atem = setupAtem() + const timelineObject = atem.getAuxTimelineObject({ + layer: SwitcherAuxLLayer.AuxClean, + content: { + input: 5 + } + }) + expect(timelineObject).toMatchObject({ + id: '', + enable: { start: 0 }, + priority: 0, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.AUX + } + }) + }) + + test('sets classes', () => { + const atem = setupAtem() + const timelineObject = atem.getAuxTimelineObject({ + layer: SwitcherAuxLLayer.AuxClean, + content: { + input: 5 + }, + classes: ['classA', 'classB'] + }) + expect(timelineObject).toMatchObject({ + classes: ['classA', 'classB'] + }) + }) + + test('sets metaData', () => { + const atem = setupAtem() + const timelineObject = atem.getAuxTimelineObject({ + layer: SwitcherAuxLLayer.AuxClean, + content: { + input: 5 + }, + metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } + }) + expect(timelineObject).toMatchObject({ + metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } + }) + }) + + test('sets layer prefix', () => { + const atem = setupAtem() + const timelineObject = atem.getAuxTimelineObject({ + layer: SwitcherAuxLLayer.AuxClean, + content: { + input: 5 + } + }) + expect(timelineObject).toMatchObject({ + layer: prefixLayer(SwitcherAuxLLayer.AuxClean) + }) + }) + + test('sets aux', () => { + const atem = setupAtem() + + const timelineObject = atem.getAuxTimelineObject({ + layer: SwitcherAuxLLayer.AuxClean, + content: { + input: 5 + } + }) + + expect(timelineObject).toMatchObject({ + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.AUX, + aux: { + input: 5 + } + } + }) + }) + }) + + describe('DSK', () => { + test('sets timeline object defaults', () => { + const atem = setupAtem() + const timelineObject = atem.getDskTimelineObject({ + layer: 'dsk_1', + content: { + onAir: true + } + }) + expect(timelineObject).toMatchObject({ + id: '', + enable: { start: 0 }, + priority: 0, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.DSK + } + }) + }) + + test('sets classes', () => { + const atem = setupAtem() + const timelineObject = atem.getDskTimelineObject({ + layer: 'dsk_1', + content: { + onAir: true + }, + classes: ['classA', 'classB'] + }) + expect(timelineObject).toMatchObject({ + classes: ['classA', 'classB'] + }) + }) + + test('sets metaData', () => { + const atem = setupAtem() + const timelineObject = atem.getDskTimelineObject({ + layer: 'dsk_1', + content: { + onAir: true + }, + metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } + }) + expect(timelineObject).toMatchObject({ + metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } + }) + }) + + test('sets layer prefix', () => { + const atem = setupAtem() + const timelineObject = atem.getDskTimelineObject({ + layer: 'dsk_1', + content: { + onAir: true + } + }) + expect(timelineObject).toMatchObject({ + layer: prefixLayer('dsk_1') + }) + }) + + test('enables DSK', () => { + const atem = setupAtem() + + const timelineObject = atem.getDskTimelineObject({ + layer: 'dsk_1', + content: { + onAir: true + } + }) + + expect(timelineObject).toMatchObject({ + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.DSK, + dsk: { + onAir: true + } + } + }) + }) + }) +}) diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index c0df86e3..c03640fe 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -1,5 +1,5 @@ import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' -import { TableConfigItemDSK, TimelineObjectMetaData } from 'tv2-common' +import { TimelineObjectMetaData, SwitcherDskProps } from 'tv2-common' import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' import { AtemSourceIndex } from '../../types/atem' @@ -45,7 +45,6 @@ export interface TimelineObjectProps { enable?: TimelineObjectEnable // Default: 0 priority?: number - layer: string metaData?: TimelineObjectMetaData classes?: string[] } @@ -71,10 +70,11 @@ export interface Keyer { // id starting from 0 id: number onAir: boolean - config: TableConfigItemDSK + config: SwitcherDskProps } export interface DskProps extends TimelineObjectProps { + layer: string // @todo: better type content: { onAir: boolean sources?: { @@ -97,6 +97,15 @@ export interface AuxProps extends TimelineObjectProps { } } +export interface DveProps extends TimelineObjectProps { + content: { + boxes: any // @todo + template: any // @todo + artFillSource: number | SpecialInput + artCutSource: number | SpecialInput + } +} + export interface VideoSwitcher { isMixEffect(timelineObject: TimelineObjectCoreExt): boolean getMixEffectTimelineObject(properties: MixEffectProps): TSR.TSRTimelineObj @@ -111,13 +120,13 @@ export interface VideoSwitcher { updateInput(timelineObject: TimelineObjectCoreExt, input: number | SpecialInput): TSR.TSRTimelineObj isDsk(timelineObject: TimelineObjectCoreExt): boolean - getDskTimelineObjects(properties: DskProps): TSR.TSRTimelineObj[] + getDskTimelineObject(properties: DskProps): TSR.TSRTimelineObj isAux(timelineObject: TimelineObjectCoreExt): boolean getAuxTimelineObject(properties: AuxProps): TSR.TSRTimelineObj updateAuxInput(timelineObject: TimelineObjectCoreExt, input: number | SpecialInput): TSR.TSRTimelineObj isDveBoxes(timelineObject: TimelineObjectCoreExt): boolean - getDveTimelineObject(properties: AuxProps): TSR.TSRTimelineObj + getDveTimelineObjects(properties: DveProps): TSR.TSRTimelineObj[] updateUnpopulatedDveBoxes(timelineObject: TimelineObjectCoreExt, input: number | SpecialInput): TSR.TSRTimelineObj } diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index 79a95447..69287227 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -217,8 +217,8 @@ export enum SwitcherDveLLayer { DveBoxes = 'dve_boxes' } -export enum SharedATEMLLayer { - AtemAuxVideoMixMinus = 'atem_aux_video_mix_minus' +export enum SwitcherMediaPlayerLLayer { + Mp1 = 'mp1' } export enum SharedCasparLLayer { diff --git a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts index fe3e48a3..406ebd65 100644 --- a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts @@ -8,10 +8,10 @@ import { TSR } from 'blueprints-integration' import { ActionCutToCamera, ActionTakeWithTransition, literal, SourceDefinitionKam } from 'tv2-common' -import { AdlibActionType, NoteType, SharedOutputLayers, SourceType } from 'tv2-constants' +import { AdlibActionType, NoteType, SharedOutputLayers, SourceType, SwitcherMixEffectLLayer } from 'tv2-constants' import { ActionExecutionContext } from '../../__mocks__/context' +import { prefixLayer } from '../../tv2-common/__tests__/testUtil' import { preprocessConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' -import { AtemLLayer } from '../../tv2_afvd_studio/layers' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' import { executeActionAFVD } from '../actions' import { preprocessConfig as parseShowStyleConfig } from '../helpers/config' @@ -139,7 +139,7 @@ const kamPieceInstance_Cut: IBlueprintPieceInstance = { timelineObjects: [ literal({ id: '', - layer: AtemLLayer.AtemMEProgram, + layer: prefixLayer(SwitcherMixEffectLLayer.Program), enable: { start: 0 }, @@ -175,7 +175,7 @@ const kamPieceInstance_Mix: IBlueprintPieceInstance = { timelineObjects: [ literal({ id: '', - layer: AtemLLayer.AtemMEProgram, + layer: prefixLayer(SwitcherMixEffectLLayer.Program), enable: { start: 0 }, @@ -216,7 +216,7 @@ const kamPieceInstance_Effekt: IBlueprintPieceInstance = { timelineObjects: [ literal({ id: '', - layer: AtemLLayer.AtemMEProgram, + layer: prefixLayer(SwitcherMixEffectLLayer.Program), enable: { start: 0 }, @@ -273,7 +273,7 @@ const evsPieceInstance_Cut: IBlueprintPieceInstance = { timelineObjects: [ literal({ id: '', - layer: AtemLLayer.AtemMEProgram, + layer: prefixLayer(SwitcherMixEffectLLayer.Program), enable: { start: 0 }, @@ -309,7 +309,7 @@ const evsPieceInstance_Mix: IBlueprintPieceInstance = { timelineObjects: [ literal({ id: '', - layer: AtemLLayer.AtemMEProgram, + layer: prefixLayer(SwitcherMixEffectLLayer.Program), enable: { start: 0 }, @@ -350,7 +350,7 @@ const evsPieceInstance_Effekt: IBlueprintPieceInstance = { timelineObjects: [ literal({ id: '', - layer: AtemLLayer.AtemMEProgram, + layer: prefixLayer(SwitcherMixEffectLLayer.Program), enable: { start: 0 }, @@ -408,7 +408,7 @@ async function getTransitionPiece( function getATEMMEObj(piece: IBlueprintPieceInstance): TSR.TimelineObjAtemME { const atemObj = (piece.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( obj => - obj.layer === AtemLLayer.AtemMEProgram && + obj.layer === prefixLayer(SwitcherMixEffectLLayer.Program) && obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.ME ) as TSR.TimelineObjAtemME | undefined diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index db4d356e..35f0d56d 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -278,10 +278,3 @@ export const defaultShowStyleConfig: GalleryShowStyleConfig = { GfxSchemaTemplates: [], GfxShowMapping: [] } - -export const EMPTY_SOURCE_CONFIG = { - cameras: [], - lives: [], - feeds: [], - replays: [] -} diff --git a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts index 164215dc..f7782d1a 100644 --- a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts @@ -1,10 +1,11 @@ import { fail } from 'assert' import { BlueprintResultSegment, IBlueprintPart, IBlueprintPiece, IngestSegment, TSR } from 'blueprints-integration' import { TimeFromFrames } from 'tv2-common' +import { SwitcherMixEffectLLayer } from 'tv2-constants' import * as _ from 'underscore' import { SegmentUserContext } from '../../__mocks__/context' +import { prefixLayer } from '../../tv2-common/__tests__/testUtil' import { preprocessConfig } from '../../tv2_afvd_studio/helpers/config' -import { AtemLLayer } from '../../tv2_afvd_studio/layers' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' import { getSegment } from '../getSegment' import { GalleryShowStyleConfig, preprocessConfig as parseShowStyleConfig } from '../helpers/config' @@ -110,7 +111,7 @@ function getPieceOnLayerFromPart(segment: BlueprintResultSegment, layer: SourceL function getATEMMEObj(piece: IBlueprintPiece): TSR.TimelineObjAtemME { const atemMEObj = (piece!.content!.timelineObjects as TSR.TSRTimelineObj[]).find( obj => - obj.layer === AtemLLayer.AtemMEProgram && + obj.layer === prefixLayer(SwitcherMixEffectLLayer.Program) && obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.ME ) as TSR.TimelineObjAtemME diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index df822cc7..9efc6bd0 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -55,11 +55,12 @@ import { SharedOutputLayers, SourceType, SwitcherAuxLLayer, + SwitcherDveLLayer, SwitcherMixEffectLLayer, TallyTags } from 'tv2-constants' import * as _ from 'underscore' -import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' +import { CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' import { SisyfosChannel, sisyfosChannels } from '../tv2_afvd_studio/sisyfosChannels' import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { AtemSourceIndex } from '../types/atem' @@ -924,7 +925,7 @@ function getBaseline( id: '', enable: { while: '1' }, priority: 0, - layer: AtemLLayer.AtemSSrcArt, + layer: SwitcherDveLLayer.Dve, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRCPROPS, @@ -940,7 +941,7 @@ function getBaseline( id: '', enable: { while: '1' }, priority: 0, - layer: AtemLLayer.AtemSSrcDefault, + layer: SwitcherDveLLayer.DveBoxes, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRC, diff --git a/src/tv2_afvd_showstyle/helpers/content/dve.ts b/src/tv2_afvd_showstyle/helpers/content/dve.ts index 7d1f38e6..772b2c8d 100644 --- a/src/tv2_afvd_showstyle/helpers/content/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/content/dve.ts @@ -8,16 +8,12 @@ import { PartDefinition } from 'tv2-common' import { GalleryBlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' -import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' +import { CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' export const NUMBER_OF_DVE_BOXES = 4 export const AFVD_DVE_GENERATOR_OPTIONS: DVEOptions = { dveLayers: { - ATEM: { - SSrcDefault: AtemLLayer.AtemSSrcDefault, - SSrcArt: AtemLLayer.AtemSSrcArt - }, CASPAR: { CGDVEKey: CasparLLayer.CasparCGDVEKey, CGDVEFrame: CasparLLayer.CasparCGDVEFrame @@ -29,8 +25,7 @@ export const AFVD_DVE_GENERATOR_OPTIONS: DVEOptions = { CasparLLayer: { ClipPending: CasparLLayer.CasparPlayerClipPending } - }, - AUDIO_LAYERS: Object.keys(SisyfosLLAyer) + } } export function MakeContentDVE( diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts index 9da5f5ab..d4f6a0a0 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -20,6 +20,7 @@ import { } from 'tv2-common' import { AdlibTags, CueType, PartType, SharedGraphicLLayer, SharedOutputLayers, SourceType } from 'tv2-constants' import { makeMockGalleryContext } from '../../../../__mocks__/context' +import { prefixLayer } from '../../../../tv2-common/__tests__/testUtil' import { OVL_SHOW_NAME } from '../../../__tests__/configs' import { SourceLayer } from '../../../layers' import { EvaluateCueGraphic } from '../graphic' @@ -946,7 +947,3 @@ describe('grafik piece', () => { expect(tlObj?.enable).toEqual({ while: '1' }) }) }) - -function prefixLayer(layerName: string) { - return 'atem_' + layerName -} diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts index c8fb6c1d..0a164ca4 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -18,6 +18,7 @@ import { } from 'tv2-common' import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayers, SourceType } from 'tv2-constants' import { makeMockGalleryContext } from '../../../../__mocks__/context' +import { prefixLayer } from '../../../../tv2-common/__tests__/testUtil' import { OVL_SHOW_NAME } from '../../../../tv2_afvd_showstyle/__tests__/configs' import { SourceLayer } from '../../../../tv2_afvd_showstyle/layers' import { SisyfosLLAyer } from '../../../../tv2_afvd_studio/layers' @@ -192,6 +193,3 @@ describe('telefon', () => { ]) }) }) -function prefixLayer(name: string): string | number { - return 'atem_' + name -} diff --git a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts index a31efac6..38df9f48 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts @@ -7,7 +7,6 @@ import { PieceMetaData, TV2ShowStyleConfig } from 'tv2-common' -import { AtemLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' export function EvaluateEkstern( @@ -33,9 +32,6 @@ export function EvaluateEkstern( { SourceLayer: { PgmLive: SourceLayer.PgmLive - }, - ATEM: { - MEProgram: AtemLLayer.AtemMEProgram } }, adlib, diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 8fef3da8..11974570 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -32,7 +32,6 @@ import { getOutputLayerDefaultsMigrationSteps, getSourceLayerDefaultsMigrationSteps } from './util' -import { getCreateVariantMigrationSteps } from './variants-defaults' declare const VERSION: string // Injected by webpack @@ -44,7 +43,6 @@ const SHOW_STYLE_ID = 'tv2_afvd_showstyle' */ export const showStyleMigrations: MigrationStepShowStyle[] = [ - ...getCreateVariantMigrationSteps(), remapTableColumnValues('0.1.0', 'GFXTemplates', 'LayerMapping', remapVizLLayer), // Rename "viz-d-ovl" to "OVL1" remapTableColumnValues('0.1.0', 'GFXTemplates', 'VizDestination', remapVizDOvl), diff --git a/src/tv2_afvd_showstyle/migrations/util.ts b/src/tv2_afvd_showstyle/migrations/util.ts index 0c0f93b1..f5aff3af 100644 --- a/src/tv2_afvd_showstyle/migrations/util.ts +++ b/src/tv2_afvd_showstyle/migrations/util.ts @@ -46,43 +46,6 @@ export function forceSourceLayerToDefaults( return forceSourceLayerToDefaultsBase(SourcelayerDefaults, versionStr, 'AFVD', layer, overrideSteps) } -export function forceSettingToDefaults(versionStr: string, setting: string): MigrationStepShowStyle { - return { - id: `${versionStr}.sourcelayer.defaults.${setting}.forced`, - version: versionStr, - canBeRunAutomatically: true, - validate: (context: MigrationContextShowStyle) => { - const existing = context.getBaseConfig(setting) - if (!existing) { - return `Setting "${setting}" doesn't exist on ShowBaseStyle` - } - - const defaultVal = showStyleConfigManifest.find(l => l.id === setting) - - if (!defaultVal) { - return false - } - - return !_.isEqual(existing, defaultVal.defaultVal) - }, - migrate: (context: MigrationContextShowStyle) => { - if (context.getBaseConfig(setting)) { - context.removeBaseConfig(setting) - } - - const defaultVal = showStyleConfigManifest.find(l => l.id === setting) - - if (!defaultVal) { - return - } - - if (!context.getBaseConfig(setting)) { - context.setBaseConfig(setting, defaultVal.defaultVal) - } - } - } -} - export function getOutputLayerDefaultsMigrationSteps(versionStr: string): MigrationStepShowStyle[] { return _.compact( _.map(OutputlayerDefaults, (defaultVal: IOutputLayer): MigrationStepShowStyle | null => { diff --git a/src/tv2_afvd_showstyle/migrations/variants-defaults.ts b/src/tv2_afvd_showstyle/migrations/variants-defaults.ts deleted file mode 100644 index 90827f88..00000000 --- a/src/tv2_afvd_showstyle/migrations/variants-defaults.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { MigrationContextShowStyle, MigrationStepShowStyle } from 'blueprints-integration' -import { literal } from 'tv2-common' -import * as _ from 'underscore' - -declare const VERSION: string // Injected by webpack - -/** - * Variants can be used to configure small variants in how running orders are generated from the input data. - * This can be useful when there are multiple studios producing a very similar show. - */ - -export interface VariantRegion { - [key: string]: { - name: string - } -} - -export const showVariants = literal({ - oddasat: { - name: 'Main' - } -}) - -export function getCreateVariantMigrationSteps() { - return _.keys(showVariants).map(key => { - return literal({ - id: `variant.${key}`, - version: VERSION, - canBeRunAutomatically: true, - validate: (context: MigrationContextShowStyle) => { - const variant = context.getVariant(key) - if (!variant) { - return `Variant "${key}" doesn't exist` - } - return false - }, - migrate: (context: MigrationContextShowStyle) => { - const variant = context.getVariant(key) - if (!variant) { - const region = showVariants[key] - - context.insertVariant(key, { - name: region.name - }) - - // Set/update config fields here - // context.setVariantConfig(key, 'RegionCode', region.regionCode) - } - } - }) - }) -} diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index 38c702d5..237acb48 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -12,12 +12,20 @@ import { PartDefinition, RemoteType } from 'tv2-common' -import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayers, SourceType } from 'tv2-constants' +import { + CueType, + PartType, + SharedGraphicLLayer, + SharedOutputLayers, + SourceType, + SwitcherAuxLLayer +} from 'tv2-constants' import { makeMockGalleryContext, SegmentUserContext } from '../../__mocks__/context' +import { prefixLayer } from '../../tv2-common/__tests__/testUtil' import { SourceLayer } from '../../tv2_afvd_showstyle/layers' import { CreatePartGrafik } from '../../tv2_afvd_showstyle/parts/grafik' import { CreatePartUnknown } from '../../tv2_afvd_showstyle/parts/unknown' -import { AtemLLayer, CasparLLayer } from '../layers' +import { CasparLLayer } from '../layers' const SEGMENT_EXTERNAL_ID = '00000000' @@ -382,7 +390,7 @@ describe('Graphics', () => { ) as TSR.TimelineObjAtemAUX | undefined expect(auxObj).toBeTruthy() expect(auxObj?.enable).toEqual({ start: 0 }) - expect(auxObj?.layer).toBe(AtemLLayer.AtemAuxVizOvlIn1) + expect(auxObj?.layer).toBe(prefixLayer(SwitcherAuxLLayer.AuxVizOvlIn1)) expect(auxObj?.content.aux.input).toBe(1) }) diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index 462dacd7..3e61628f 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -7,10 +7,15 @@ import { } from 'blueprints-integration' import { ExtendedStudioContext, literal, SpecialInput, TransitionStyle } from 'tv2-common' import * as _ from 'underscore' -import { SharedGraphicLLayer, SwitcherAuxLLayer, SwitcherMixEffectLLayer } from '../tv2-constants' +import { + SharedGraphicLLayer, + SwitcherAuxLLayer, + SwitcherMediaPlayerLLayer, + SwitcherMixEffectLLayer +} from '../tv2-constants' import { AtemSourceIndex } from '../types/atem' import { GalleryStudioConfig } from './helpers/config' -import { AtemLLayer, SisyfosLLAyer } from './layers' +import { SisyfosLLAyer } from './layers' import { sisyfosChannels } from './sisyfosChannels' import { GALLERY_UNIFORM_CONFIG } from './uniformConfig' @@ -103,7 +108,7 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin id: '', enable: { while: '1' }, priority: 0, - layer: AtemLLayer.AtemMP1, + layer: SwitcherMediaPlayerLLayer.Mp1, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.MEDIAPLAYER, diff --git a/src/tv2_afvd_studio/layers.ts b/src/tv2_afvd_studio/layers.ts index 12d8f25d..635ee5a7 100644 --- a/src/tv2_afvd_studio/layers.ts +++ b/src/tv2_afvd_studio/layers.ts @@ -1,21 +1,16 @@ import { AbstractLLayer, RobotCameraLayer, - SharedATEMLLayer, SharedCasparLLayer, SharedGraphicLLayer, SharedSisyfosLLayer } from 'tv2-constants' import * as _ from 'underscore' -export type LLayer = VirtualAbstractLLayer | AtemLLayer | CasparLLayer | SisyfosLLAyer - /** Get all the Real LLayers (map to devices). Note: Does not include some which are dynamically generated */ export function RealLLayers(): string[] { return ( - _.values(AtemLLayer) - // @ts-ignore - .concat(_.values(CasparLLayer)) + _.values(CasparLLayer) // @ts-ignore .concat(_.values(SisyfosLLAyer)) // @ts-ignore @@ -31,31 +26,6 @@ export function RealLLayers(): string[] { export enum VirtualAbstractLLayer {} -export enum AFVDAtemLLayer { - AtemMEProgram = 'atem_me_program', - AtemMEClean = 'atem_me_clean', - AtemCleanUSKEffect = 'atem_clean_usk_effect', - AtemSSrcArt = 'atem_supersource_art', - AtemSSrcDefault = 'atem_supersource_default', - AtemMP1 = 'atem_mp_1', - - AtemAuxPGM = 'atem_aux_pgm', - AtemAuxClean = 'atem_aux_clean', - AtemAuxAR = 'atem_aux_ar', - AtemAuxVizOvlIn1 = 'atem_aux_viz_ovl_in_1', - // AtemAuxVizFullIn1 = 'atem_aux_viz_full_in_1', - AtemAuxLookahead = 'atem_aux_lookahead', - AtemAuxSSrc = 'atem_aux_ssrc' -} - -// tslint:disable-next-line: variable-name -export const AtemLLayer = { - ...AFVDAtemLLayer, - ...SharedATEMLLayer -} - -export type AtemLLayer = AFVDAtemLLayer | SharedATEMLLayer - enum AFVDCasparLLayer { CasparCGDVELoop = 'casparcg_dve_loop', CasparCGFullBg = 'casparcg_full_bg', diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index 7cdc69e7..e546b326 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -1,6 +1,7 @@ import { BlueprintMapping, BlueprintMappings, LookaheadMode, TSR } from 'blueprints-integration' import { AbstractLLayerServerEnable, + ATEM_DEVICE_ID, ATEM_LAYER_PREFIX, CasparPlayerClip, CasparPlayerClipLoadingLoop, @@ -19,11 +20,12 @@ import { RobotCameraLayer, SwitcherAuxLLayer, SwitcherDveLLayer, + SwitcherMediaPlayerLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' import { ATEMModel } from '../../types/atem' import { GalleryStudioConfig } from '../helpers/config' -import { AtemLLayer, CasparLLayer, GraphicLLayer, SisyfosLLAyer } from '../layers' +import { CasparLLayer, GraphicLLayer, SisyfosLLAyer } from '../layers' export const MAPPINGS_ABSTRACT: BlueprintMappings = { core_abstract: literal({ @@ -581,97 +583,96 @@ export const MAPPINGS_GRAPHICS: BlueprintMappings = { export const MAPPINGS_ATEM: Record = prefixLayers(ATEM_LAYER_PREFIX, { [SwitcherMixEffectLLayer.Program]: { device: TSR.DeviceType.ATEM, - deviceId: 'atem0', + deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 0 // 0 = ME1 }, [SwitcherMixEffectLLayer.Clean]: { device: TSR.DeviceType.ATEM, - deviceId: 'atem0', + deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 3 // 3 = ME4 }, [SwitcherMixEffectLLayer.CleanUSKEffect]: { device: TSR.DeviceType.ATEM, - deviceId: 'atem0', + deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 3 // 3 = ME4 }, [SwitcherAuxLLayer.AuxProgram]: { device: TSR.DeviceType.ATEM, - deviceId: 'atem0', + deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.Auxilliary, index: 0 // 0 = out 1 }, [SwitcherAuxLLayer.AuxClean]: { device: TSR.DeviceType.ATEM, - deviceId: 'atem0', + deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.Auxilliary, index: 1 // 1 = out 2 }, [SwitcherAuxLLayer.AuxAR]: { device: TSR.DeviceType.ATEM, - deviceId: 'atem0', + deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 3 // 3 = out 4 }, [SwitcherAuxLLayer.AuxVizOvlIn1]: { device: TSR.DeviceType.ATEM, - deviceId: 'atem0', + deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 4 // 4 = out 5 }, [SwitcherAuxLLayer.AuxVideoMixMinus]: { device: TSR.DeviceType.ATEM, - deviceId: 'atem0', + deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 6 // 6 = out 7 }, [SwitcherAuxLLayer.AuxLookahead]: { device: TSR.DeviceType.ATEM, - deviceId: 'atem0', + deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 10 // 10 = out 11 }, [SwitcherAuxLLayer.AuxDve]: { device: TSR.DeviceType.ATEM, - deviceId: 'atem0', + deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 11 // 11 = out 12 }, - ...getAtemDskMappings(ATEMModel.CONSTELLATION_8K_UHD_MODE), [SwitcherDveLLayer.Dve]: { device: TSR.DeviceType.ATEM, - deviceId: 'atem0', + deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.SuperSourceProperties, index: 0 // 0 = SS }, [SwitcherDveLLayer.DveBoxes]: { device: TSR.DeviceType.ATEM, - deviceId: 'atem0', + deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, // TODO - verify mappingType: TSR.MappingAtemType.SuperSourceBox, index: 0 // 0 = SS }, - [AtemLLayer.AtemMP1]: { - // @todo + [SwitcherMediaPlayerLLayer.Mp1]: { device: TSR.DeviceType.ATEM, - deviceId: 'atem0', + deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MediaPlayer, index: 0 - } + }, + ...getAtemDskMappings(ATEMModel.CONSTELLATION_8K_UHD_MODE) }) export const MAPPINGS_TRICASTER: Record = prefixLayers( @@ -763,7 +764,7 @@ export const MAPPINGS_TRICASTER: Record ConfigItemValue -): MigrationStepStudio { - return { - id: `${version}.studioConfig.${oldConfigName}`, - version, - canBeRunAutomatically: true, - validate: (context: MigrationContextStudio) => { - const configVal = context.getConfig(oldConfigName) - if (configVal !== undefined) { - return `${oldConfigName} is defined` - } - - return false - }, - migrate: (context: MigrationContextStudio) => { - const configVal = context.getConfig(oldConfigName) - if (configVal !== undefined) { - context.setConfig(newConfigName, updateValue ? updateValue(configVal) : configVal) - context.removeConfig(oldConfigName) - } - } - } -} - export function renameMapping(version: string, oldMappingName: string, newMappingName: string): MigrationStepStudio { return { id: `${version}.studioMapping.${oldMappingName}`, diff --git a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts index 935d6fff..af34ca44 100644 --- a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts @@ -20,12 +20,19 @@ import { SourceDefinitionKam, SourceDefinitionRemote } from 'tv2-common' -import { AdlibActionType, CueType, NoteType, PartType, SharedSourceLayers, SourceType } from 'tv2-constants' +import { + AdlibActionType, + CueType, + NoteType, + PartType, + SharedSourceLayers, + SourceType, + SwitcherMixEffectLLayer +} from 'tv2-constants' import { ActionExecutionContext } from '../../__mocks__/context' +import { prefixLayer } from '../../tv2-common/__tests__/testUtil' import { defaultShowStyleConfig, defaultStudioConfig } from '../../tv2_afvd_showstyle/__tests__/configs' -import { AtemLLayer } from '../../tv2_afvd_studio/layers' import { OfftubeStudioConfig, preprocessConfig as parseStudioConfig } from '../../tv2_offtube_studio/helpers/config' -import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' import mappingsDefaults from '../../tv2_offtube_studio/migrations/mappings-defaults' import { executeActionOfftube } from '../actions' import { preprocessConfig as parseShowStyleConfig } from '../helpers/config' @@ -86,7 +93,7 @@ const kamPieceInstance: IBlueprintPieceInstance = { enable: { start: 0 }, - layer: AtemLLayer.AtemMEClean, + layer: prefixLayer(SwitcherMixEffectLLayer.Clean), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.ME, @@ -375,7 +382,7 @@ function validateNextPartExistsWithPreviousPartKeepaliveDuration(context: Action function getATEMMEObj(piece: IBlueprintPieceInstance): TSR.TimelineObjAtemME { const atemObj = (piece.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( obj => - obj.layer === OfftubeAtemLLayer.AtemMEClean && + obj.layer === prefixLayer(SwitcherMixEffectLLayer.Clean) && obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.ME ) as TSR.TimelineObjAtemME | undefined diff --git a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts index f2758518..126ab384 100644 --- a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts +++ b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts @@ -7,17 +7,13 @@ import { MakeContentDVEBase, PartDefinition } from 'tv2-common' -import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' +import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeBlueprintConfig } from '../helpers/config' export const NUMBER_OF_DVE_BOXES = 4 export const OFFTUBE_DVE_GENERATOR_OPTIONS: DVEOptions = { dveLayers: { - ATEM: { - SSrcDefault: OfftubeAtemLLayer.AtemSSrcDefault, - SSrcArt: OfftubeAtemLLayer.AtemSSrcArt - }, CASPAR: { CGDVEKey: OfftubeCasparLLayer.CasparCGDVEKey, CGDVEFrame: OfftubeCasparLLayer.CasparCGDVEFrame @@ -29,8 +25,7 @@ export const OFFTUBE_DVE_GENERATOR_OPTIONS: DVEOptions = { CasparLLayer: { ClipPending: OfftubeCasparLLayer.CasparPlayerClipPending } - }, - AUDIO_LAYERS: [] // TODO + } } export function OfftubeMakeContentDVE( diff --git a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts index 892c9fd4..419fd41c 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts @@ -1,10 +1,4 @@ -import { - HackPartMediaObjectSubscription, - IBlueprintActionManifest, - SplitsContent, - TimelineObjectCoreExt, - TSR -} from 'blueprints-integration' +import { HackPartMediaObjectSubscription, IBlueprintActionManifest, SplitsContent } from 'blueprints-integration' import { ActionSelectDVE, CreateAdlibServer, @@ -20,8 +14,7 @@ import { TemplateIsValid } from 'tv2-common' import { AdlibActionType, AdlibTags, CueType } from 'tv2-constants' -import _ = require('underscore') -import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' +import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeMakeContentDVE } from '../content/OfftubeDVEContent' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeOutputLayers, OfftubeSourceLayer } from '../layers' @@ -119,33 +112,3 @@ export async function OfftubeEvaluateAdLib( }) } } - -export function makeofftubeDVEIDsUniqueForFlow(timeline: TimelineObjectCoreExt[]): TimelineObjectCoreExt[] { - const startIdObj = timeline.find(tlObj => tlObj.layer === OfftubeAtemLLayer.AtemSSrcDefault) - - if (!startIdObj) { - return timeline - } - - const startId = startIdObj.id - - if (!startId.length) { - return timeline - } - - const newId = `${startId}_flow` - - return timeline.map(tlObj => { - const enable = _.clone(tlObj.enable) as TSR.Timeline.TimelineEnable - - if (enable.start && typeof enable.start === 'string') { - enable.start = enable.start.replace(startId, newId) - } - - return { - ...tlObj, - id: tlObj.id.replace(startId, newId), - enable - } - }) -} diff --git a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts index 41302122..7eeb1c1f 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts @@ -6,7 +6,6 @@ import { PartDefinition, PieceMetaData } from 'tv2-common' -import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeSourceLayer } from '../layers' @@ -33,9 +32,6 @@ export function OfftubeEvaluateEkstern( { SourceLayer: { PgmLive: OfftubeSourceLayer.PgmLive - }, - ATEM: { - MEProgram: OfftubeAtemLLayer.AtemMEClean } }, adlib, diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index dbafafd2..49533b46 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -56,12 +56,13 @@ import { SharedSourceLayers, SourceType, SwitcherAuxLLayer, + SwitcherDveLLayer, SwitcherMixEffectLLayer, TallyTags } from 'tv2-constants' import * as _ from 'underscore' import { OfftubeBlueprintConfig } from '../tv2_offtube_showstyle/helpers/config' -import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' +import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' import { SisyfosChannel, sisyfosChannels } from '../tv2_offtube_studio/sisyfosChannels' import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' import { NUMBER_OF_DVE_BOXES } from './content/OfftubeDVEContent' @@ -632,7 +633,7 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche id: '', enable: { while: '1' }, priority: 0, - layer: OfftubeAtemLLayer.AtemSSrcArt, + layer: SwitcherDveLLayer.Dve, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRCPROPS, @@ -648,7 +649,7 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche id: '', enable: { while: '1' }, priority: 0, - layer: OfftubeAtemLLayer.AtemSSrcDefault, + layer: SwitcherDveLLayer.DveBoxes, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRC, diff --git a/src/tv2_offtube_showstyle/migrations/index.ts b/src/tv2_offtube_showstyle/migrations/index.ts index ac39bdec..bce8c56a 100644 --- a/src/tv2_offtube_showstyle/migrations/index.ts +++ b/src/tv2_offtube_showstyle/migrations/index.ts @@ -31,7 +31,6 @@ import { getSourceLayerDefaultsMigrationSteps, remapTableColumnValues } from './util' -import { getCreateVariantMigrationSteps } from './variants-defaults' declare const VERSION: string // Injected by webpack @@ -78,7 +77,6 @@ const SHOW_STYLE_ID = 'tv2_offtube_showstyle' export const showStyleMigrations: MigrationStepShowStyle[] = [ // Fill in any layers that did not exist before // Note: These should only be run as the very final step of all migrations. otherwise they will add items too early, and confuse old migrations - ...getCreateVariantMigrationSteps(), remapTableColumnValues('0.1.0', 'GFXTemplates', 'LayerMapping', remapVizLLayer), ...getSourceLayerDefaultsMigrationSteps('1.3.0', true), diff --git a/src/tv2_offtube_showstyle/migrations/util.ts b/src/tv2_offtube_showstyle/migrations/util.ts index 5830ed17..5bc1a81a 100644 --- a/src/tv2_offtube_showstyle/migrations/util.ts +++ b/src/tv2_offtube_showstyle/migrations/util.ts @@ -44,43 +44,6 @@ export function getSourceLayerDefaultsMigrationSteps(versionStr: string, force?: ) } -export function forceSettingToDefaults(versionStr: string, setting: string): MigrationStepShowStyle { - return { - id: `${versionStr}.sourcelayer.defaults.${setting}.forced`, - version: versionStr, - canBeRunAutomatically: true, - validate: (context: MigrationContextShowStyle) => { - const existing = context.getBaseConfig(setting) - if (!existing) { - return `Setting "${setting}" doesn't exist on ShowBaseStyle` - } - - const defaultVal = showStyleConfigManifest.find(l => l.id === setting) - - if (!defaultVal) { - return false - } - - return !_.isEqual(existing, defaultVal.defaultVal) - }, - migrate: (context: MigrationContextShowStyle) => { - if (context.getBaseConfig(setting)) { - context.removeBaseConfig(setting) - } - - const defaultVal = showStyleConfigManifest.find(l => l.id === setting) - - if (!defaultVal) { - return - } - - if (!context.getBaseConfig(setting)) { - context.setBaseConfig(setting, defaultVal.defaultVal) - } - } - } -} - export function getOutputLayerDefaultsMigrationSteps(versionStr: string): MigrationStepShowStyle[] { return _.compact( _.map(OutputlayerDefaults, (defaultVal: IOutputLayer): MigrationStepShowStyle | null => { diff --git a/src/tv2_offtube_showstyle/migrations/variants-defaults.ts b/src/tv2_offtube_showstyle/migrations/variants-defaults.ts deleted file mode 100644 index 90827f88..00000000 --- a/src/tv2_offtube_showstyle/migrations/variants-defaults.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { MigrationContextShowStyle, MigrationStepShowStyle } from 'blueprints-integration' -import { literal } from 'tv2-common' -import * as _ from 'underscore' - -declare const VERSION: string // Injected by webpack - -/** - * Variants can be used to configure small variants in how running orders are generated from the input data. - * This can be useful when there are multiple studios producing a very similar show. - */ - -export interface VariantRegion { - [key: string]: { - name: string - } -} - -export const showVariants = literal({ - oddasat: { - name: 'Main' - } -}) - -export function getCreateVariantMigrationSteps() { - return _.keys(showVariants).map(key => { - return literal({ - id: `variant.${key}`, - version: VERSION, - canBeRunAutomatically: true, - validate: (context: MigrationContextShowStyle) => { - const variant = context.getVariant(key) - if (!variant) { - return `Variant "${key}" doesn't exist` - } - return false - }, - migrate: (context: MigrationContextShowStyle) => { - const variant = context.getVariant(key) - if (!variant) { - const region = showVariants[key] - - context.insertVariant(key, { - name: region.name - }) - - // Set/update config fields here - // context.setVariantConfig(key, 'RegionCode', region.regionCode) - } - } - }) - }) -} diff --git a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts index a2f6fb18..61814de2 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts @@ -7,7 +7,7 @@ import { PartDefinition, ServerPartProps } from 'tv2-common' -import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' +import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' diff --git a/src/tv2_offtube_studio/getBaseline.ts b/src/tv2_offtube_studio/getBaseline.ts index da2a8fd9..43169d1b 100644 --- a/src/tv2_offtube_studio/getBaseline.ts +++ b/src/tv2_offtube_studio/getBaseline.ts @@ -8,9 +8,8 @@ import { import { ExtendedStudioContext, literal, SpecialInput, TransitionStyle } from 'tv2-common' import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' import * as _ from 'underscore' -import { AtemSourceIndex } from '../types/atem' import { OfftubeStudioBlueprintConfig } from './helpers/config' -import { OfftubeAtemLLayer, OfftubeSisyfosLLayer } from './layers' +import { OfftubeSisyfosLLayer } from './layers' import { sisyfosChannels } from './sisyfosChannels' import { QBOX_UNIFORM_CONFIG } from './uniformConfig' diff --git a/src/tv2_offtube_studio/layers.ts b/src/tv2_offtube_studio/layers.ts index 51991893..1042cd60 100644 --- a/src/tv2_offtube_studio/layers.ts +++ b/src/tv2_offtube_studio/layers.ts @@ -1,18 +1,10 @@ -import { - AbstractLLayer, - SharedATEMLLayer, - SharedCasparLLayer, - SharedGraphicLLayer, - SharedSisyfosLLayer -} from 'tv2-constants' +import { AbstractLLayer, SharedCasparLLayer, SharedGraphicLLayer, SharedSisyfosLLayer } from 'tv2-constants' import * as _ from 'underscore' /** Get all the Real LLayers (map to devices). Note: Does not include some which are dynamically generated */ export function RealLLayers(): string[] { return ( _.values(OfftubeSisyfosLLayer) - // @ts-ignore - .concat(_.values(OfftubeAtemLLayer)) // @ts-ignore .concat(_.values(OfftubeCasparLLayer)) // @ts-ignore @@ -43,26 +35,6 @@ enum SisyfosLLayer { SisyfosSourceDisp2 = 'sisyfos_source_disp_2' } -export enum AtemLLayer { - AtemMEClean = 'atem_me_clean', - AtemMEProgram = 'atem_me_program', - AtemMENext = 'atem_me_next', - AtemMENextJingle = 'atem_me_next_jingle', - AtemSSrcArt = 'atem_supersource_art', - AtemSSrcDefault = 'atem_supersource_default', - AtemAuxClean = 'atem_aux_clean', - AtemAuxScreen = 'atem_aux_screen', - AtemAuxServerLookahead = 'atem_aux_server_lookahead' -} - -// tslint:disable-next-line: variable-name -export const OfftubeAtemLLayer = { - ...AtemLLayer, - ...SharedATEMLLayer -} - -export type OfftubeAtemLLayer = AtemLLayer | SharedATEMLLayer - enum CasparLLayer { /** Maps to the same Caspar layer as CasparPlayerJingle but its lookahead preloads the first frame */ CasparPlayerJinglePreload = 'casparcg_player_jingle_preload', diff --git a/src/tv2_offtube_studio/migrations/mappings-defaults.ts b/src/tv2_offtube_studio/migrations/mappings-defaults.ts index a328d443..68f0d818 100644 --- a/src/tv2_offtube_studio/migrations/mappings-defaults.ts +++ b/src/tv2_offtube_studio/migrations/mappings-defaults.ts @@ -1,14 +1,16 @@ import { BlueprintMapping, BlueprintMappings, LookaheadMode, TSR } from 'blueprints-integration' import { AbstractLLayerServerEnable, + ATEM_LAYER_PREFIX, CasparPlayerClip, CasparPlayerClipLoadingLoop, getAtemDskMappings, - literal + literal, + prefixLayers } from 'tv2-common' -import { AbstractLLayer } from 'tv2-constants' +import { AbstractLLayer, SwitcherAuxLLayer, SwitcherDveLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' import { ATEMModel } from '../../types/atem' -import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeGraphicLLayer, OfftubeSisyfosLLayer } from '../layers' +import { OfftubeCasparLLayer, OfftubeGraphicLLayer, OfftubeSisyfosLLayer } from '../layers' const MAPPINGS_ABSTRACT: BlueprintMappings = { core_abstract: literal({ @@ -444,82 +446,76 @@ const MAPPINGS_GRAPHICS: BlueprintMappings = { }) } -const MAPPINGS_ATEM: BlueprintMappings = { - [OfftubeAtemLLayer.AtemMEClean]: literal({ +const MAPPINGS_ATEM: Record = prefixLayers(ATEM_LAYER_PREFIX, { + [SwitcherMixEffectLLayer.Clean]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 1 // 1 = ME2 - }), - [OfftubeAtemLLayer.AtemMEProgram]: literal({ + }, + [SwitcherMixEffectLLayer.Program]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 0 // 0 = ME1 - }), - [OfftubeAtemLLayer.AtemMENext]: literal({ + }, + [SwitcherMixEffectLLayer.Next]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.MixEffect, index: 0, // 0 = ME1 lookaheadDepth: 1 - }), - [OfftubeAtemLLayer.AtemMENextJingle]: literal({ + }, + [SwitcherMixEffectLLayer.NextJingle]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.PRELOAD, lookaheadMaxSearchDistance: 1, mappingType: TSR.MappingAtemType.MixEffect, index: 0 // 0 = ME1 - }), - ...getAtemDskMappings(ATEMModel.PRODUCTION_STUDIO_4K_2ME), - [OfftubeAtemLLayer.AtemAuxClean]: literal({ + }, + [SwitcherAuxLLayer.AuxClean]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.Auxilliary, index: 0 // 0 = out 1 - }), - [OfftubeAtemLLayer.AtemAuxScreen]: literal({ + }, + [SwitcherAuxLLayer.AuxScreen]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.Auxilliary, index: 1 // 1 = out 2 - }), - [OfftubeAtemLLayer.AtemAuxServerLookahead]: literal({ + }, + [SwitcherAuxLLayer.AuxServerLookahead]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 2 // 2 = out 3 - }), - [OfftubeAtemLLayer.AtemSSrcArt]: literal({ + }, + [SwitcherDveLLayer.Dve]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, lookaheadMaxSearchDistance: 1, mappingType: TSR.MappingAtemType.SuperSourceProperties, index: 0 // 0 = SS - }), - [OfftubeAtemLLayer.AtemSSrcDefault]: literal({ + }, + [SwitcherDveLLayer.DveBoxes]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, lookaheadMaxSearchDistance: 1, mappingType: TSR.MappingAtemType.SuperSourceBox, index: 0 // 0 = SS - }), - // TODO: Future: Mix Minus in Offtubes - [OfftubeAtemLLayer.AtemAuxVideoMixMinus]: literal({ - device: TSR.DeviceType.ABSTRACT, - deviceId: 'abstract0', - lookahead: LookaheadMode.NONE - }) -} + }, + ...getAtemDskMappings(ATEMModel.PRODUCTION_STUDIO_4K_2ME) +}) export default literal({ ...MAPPINGS_ABSTRACT, diff --git a/src/tv2_offtube_studio/migrations/util.ts b/src/tv2_offtube_studio/migrations/util.ts index 4444c91c..bd2a422e 100644 --- a/src/tv2_offtube_studio/migrations/util.ts +++ b/src/tv2_offtube_studio/migrations/util.ts @@ -56,34 +56,6 @@ export function ensureStudioConfig( } } -export function renameStudioConfig( - version: string, - oldConfigName: string, - newConfigName: string, - updateValue?: (val: any) => ConfigItemValue -): MigrationStepStudio { - return { - id: `${version}.${oldConfigName}`, - version, - canBeRunAutomatically: true, - validate: (context: MigrationContextStudio) => { - const configVal = context.getConfig(oldConfigName) - if (configVal !== undefined) { - return `${oldConfigName} is defined` - } - - return false - }, - migrate: (context: MigrationContextStudio) => { - const configVal = context.getConfig(oldConfigName) - if (configVal !== undefined) { - context.setConfig(newConfigName, updateValue ? updateValue(configVal) : configVal) - context.removeConfig(oldConfigName) - } - } - } -} - export function renameMapping(version: string, oldMappingName: string, newMappingName: string): MigrationStepStudio { return { id: `${version}.studioMapping.${oldMappingName}`, From ed57b1ff7bacaca7a6732f18db05e1387a8fc351 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 14 Feb 2023 23:16:07 +0100 Subject: [PATCH 17/86] wip: SOF-1260 some migrations, tests, and fixes --- package.json | 2 +- .../__tests__/transitionSettings.spec.ts | 169 -------- src/tv2-common/content/jingle.ts | 1 - src/tv2-common/helpers/dsk.ts | 43 +- .../caspar/htmlPilotGraphicGenerator.ts | 3 +- src/tv2-common/layers/timelineLayers.ts | 7 +- src/tv2-common/migrations/index.ts | 32 ++ src/tv2-common/types/config.ts | 8 +- src/tv2-common/videoSwitchers/Atem.ts | 18 +- src/tv2-common/videoSwitchers/TriCaster.ts | 43 +- .../videoSwitchers/__tests__/Atem.spec.ts | 179 ++++---- .../__tests__/TriCaster.spec.ts | 391 ++++++++++++++++++ src/tv2-common/videoSwitchers/types.ts | 16 +- src/tv2_afvd_showstyle/getRundown.ts | 3 +- src/tv2_afvd_showstyle/migrations/util.ts | 1 - src/tv2_afvd_studio/config-manifests.ts | 2 +- src/tv2_afvd_studio/helpers/config.ts | 6 +- src/tv2_afvd_studio/migrations/index.ts | 9 +- src/tv2_afvd_studio/migrations/util.ts | 1 - src/tv2_afvd_studio/uniformConfig.ts | 1 + src/tv2_offtube_showstyle/migrations/util.ts | 1 - src/tv2_offtube_studio/helpers/config.ts | 8 +- src/tv2_offtube_studio/migrations/index.ts | 4 +- src/tv2_offtube_studio/migrations/util.ts | 1 - 24 files changed, 587 insertions(+), 362 deletions(-) delete mode 100644 src/tv2-common/__tests__/transitionSettings.spec.ts create mode 100644 src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts diff --git a/package.json b/package.json index 5cbd39d3..b6227d1a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tv2-sofie-blueprints-inews", - "version": "1.7.9", + "version": "1.8.0", "repository": "https://github.com/olzzon/tv2-sofie-blueprints-inews", "license": "MIT", "private": true, diff --git a/src/tv2-common/__tests__/transitionSettings.spec.ts b/src/tv2-common/__tests__/transitionSettings.spec.ts deleted file mode 100644 index f9c280f0..00000000 --- a/src/tv2-common/__tests__/transitionSettings.spec.ts +++ /dev/null @@ -1,169 +0,0 @@ -// @todo: rewrite for Atem and TriCaster -/*import { TSR } from 'blueprints-integration' -import { PartType } from '../../tv2-constants' -import { AtemSourceIndex } from '../../types/atem' -import { TV2BlueprintConfigBase, TV2ShowStyleConfig, TV2StudioConfigBase } from '../blueprintConfig' -import { PartDefinition, PartTransition } from '../inewsConversion' - -const DURATION: number = 50 - -describe('transitionsSettingsSuite', () => { - let mockConfig: TV2ShowStyleConfig - - beforeEach(() => { - mockConfig = ({} as unknown) as TV2ShowStyleConfig - }) - - describe('TransitionSettings', () => { - it('return empty when no transition', () => { - const partDefinition: PartDefinition = createPartDefinition() - - const result = TransitionSettings(mockConfig, partDefinition) - - expect(result).toEqual({}) - }) - - it('should return empty when no duration on transition', () => { - const transition: PartTransition = { - duration: undefined, - style: TSR.AtemTransitionStyle.DUMMY - } - const partDefinition: PartDefinition = createPartDefinition(transition) - const result = TransitionSettings(mockConfig, partDefinition) - - expect(result).toEqual({}) - }) - - it('should return Wipe when transition is style Wip', () => { - const transition: PartTransition = { - style: TSR.AtemTransitionStyle.WIPE, - duration: DURATION - } - const partDefinition: PartDefinition = createPartDefinition(transition) - - const result = TransitionSettings(mockConfig, partDefinition) - const expectedResult: TSR.AtemTransitionSettings = { - wipe: { - rate: DURATION - } - } - expect(result).toEqual(expectedResult) - }) - - it('should return Mix when transition is style Mix', () => { - const transition: PartTransition = { - style: TSR.AtemTransitionStyle.MIX, - duration: DURATION - } - const partDefinition: PartDefinition = createPartDefinition(transition) - - const result = TransitionSettings(mockConfig, partDefinition) - const expectedResult: TSR.AtemTransitionSettings = { - mix: { - rate: DURATION - } - } - expect(result).toEqual(expectedResult) - }) - - it('should return Dip when style is Dip', () => { - const transition: PartTransition = { - style: TSR.AtemTransitionStyle.DIP, - duration: DURATION - } - const partDefinition: PartDefinition = createPartDefinition(transition) - - const result = TransitionSettings(mockConfig, partDefinition) - const expectedResult: TSR.AtemTransitionSettings = { - dip: { - rate: DURATION, - input: AtemSourceIndex.Col2 - } - } - expect(result).toEqual(expectedResult) - }) - - it('should return 100 in Dip.input when AtemSource.Dip config value is 100', () => { - const dipConfigInputSource = 100 - assertDipInputValueFromConfig(mockConfig, dipConfigInputSource) - }) - - it('should return 4 in Dip.input when AtemSource.Dip config value is 4', () => { - const dipConfigInputSource = 4 - assertDipInputValueFromConfig(mockConfig, dipConfigInputSource) - }) - - it('should return 150 in Dip.input when AtemSource.Dip config value is 150', () => { - const dipConfigInputSource = 150 - assertDipInputValueFromConfig(mockConfig, dipConfigInputSource) - }) - }) - - describe('DipTransitionSettings', () => { - it('should return AtemSourceIndex.Col2 when no AtemSource.Dip is configured', () => { - const transition: PartTransition = { - style: TSR.AtemTransitionStyle.DIP, - duration: DURATION - } - const partDefinition: PartDefinition = createPartDefinition(transition) - - const result = TransitionSettings(mockConfig, partDefinition) - const expectedResult: TSR.AtemTransitionSettings = { - dip: { - rate: DURATION, - input: AtemSourceIndex.Col2 - } - } - expect(result).toEqual(expectedResult) - }) - }) -}) - -function createPartDefinition(transition?: PartTransition): PartDefinition { - return { - externalId: `externalId_${Math.random() * 1000}`, - cues: [], - type: PartType.REMOTE, - script: '', - fields: {}, - modified: 123, - storyName: 'someName', - segmentExternalId: `segmentExternalId_${Math.random() * 1000}`, - rawType: '', - transition - } -} - -function assertDipInputValueFromConfig( - mockConfig: TV2BlueprintConfigBase, - dipInputSource: number -) { - mockConfig.studio = ({ - SwitcherSource: createAtemSourceConfig(dipInputSource) - } as any) as TV2StudioConfigBase - const transition: PartTransition = { - style: TSR.AtemTransitionStyle.DIP, - duration: DURATION - } - const partDefinition: PartDefinition = createPartDefinition(transition) - - const result = TransitionSettings(mockConfig, partDefinition) - const expectedResult: TSR.AtemTransitionSettings = { - dip: { - rate: DURATION, - input: dipInputSource - } - } - expect(result).toEqual(expectedResult) -} - -function createAtemSourceConfig(dip: number) { - return { - Dip: dip, - Default: 1, - SplitArtF: 1, - SplitArtK: 1, - DSK: [] - } -} -*/ diff --git a/src/tv2-common/content/jingle.ts b/src/tv2-common/content/jingle.ts index 9ccccb7b..b024be60 100644 --- a/src/tv2-common/content/jingle.ts +++ b/src/tv2-common/content/jingle.ts @@ -93,7 +93,6 @@ export function CreateJingleContentBase< cutSource: jingleDSK.Clip, maskEnabled: false, lumaSettings: { - preMultiplied: false, clip: Number(jingleDSK.Clip) * 10, // input is percents (0-100), atem uses 1-000 gain: Number(jingleDSK.Gain) * 10 // input is percents (0-100), atem uses 1-000 } diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index 232301a5..5c04e243 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -57,14 +57,7 @@ export function getDskOnAirTimelineObjects( layer: LLayerDSK(dskConf.Number), content: { onAir: true, - sources: { - fillSource: dskConf.Fill, - cutSource: dskConf.Key - }, - properties: { - clip: Number(dskConf.Clip) * 10, - gain: Number(dskConf.Gain) * 10 - } + config: dskConf } }), ...(dskRole === DSKRoles.JINGLE && context.uniformConfig.SwitcherLLayers.JingleUskMixEffect @@ -78,7 +71,6 @@ export function getDskOnAirTimelineObjects( content: { keyers: [ { - id: 0, onAir: true, config: dskConf } @@ -116,7 +108,8 @@ export function CreateDSKBaselineAdlibs( priority: 10, layer: LLayerDSK(dsk.Number), content: { - onAir: false + onAir: false, + config: dsk } }) ] @@ -140,16 +133,7 @@ export function CreateDSKBaselineAdlibs( layer: LLayerDSK(dsk.Number), // @todo content: { onAir: true, - sources: { - fillSource: dsk.Fill, - cutSource: dsk.Key - }, - properties: { - tie: false, - preMultiply: false, - clip: Number(dsk.Clip) * 10, // input is percents (0-100), atem uses 1-000, - gain: Number(dsk.Gain) * 10 // input is percents (0-100), atem uses 1-000, - } + config: dsk } }) ] @@ -173,16 +157,7 @@ export function CreateDSKBaseline( layer: LLayerDSK(dsk.Number), // @todo content: { onAir: dsk.DefaultOn, - sources: { - fillSource: dsk.Fill, - cutSource: dsk.Key - }, - properties: { - tie: false, - preMultiply: false, - clip: Number(dsk.Clip) * 10, // input is percents (0-100), atem uses 1-000, - gain: Number(dsk.Gain) * 10 // input is percents (0-100), atem uses 1-000, - } + config: dsk } }) }) @@ -260,18 +235,18 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { id: 'Clip', name: 'ATEM Clip', description: 'DSK Clip (0-100)', - type: ConfigManifestEntryType.STRING, + type: ConfigManifestEntryType.FLOAT, // @todo: this needs a migration required: true, - defaultVal: '50', + defaultVal: 50, rank: 6 }, { id: 'Gain', name: 'ATEM Gain', description: 'DSK Gain (0-100)', - type: ConfigManifestEntryType.STRING, + type: ConfigManifestEntryType.FLOAT, // @todo: this needs a migration required: true, - defaultVal: '12.5', + defaultVal: 12.5, rank: 7 } ] diff --git a/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts index efedea28..82b455e8 100644 --- a/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts @@ -99,7 +99,8 @@ export class HtmlPilotGraphicGenerator extends PilotGraphicGenerator { priority: 1, content: { input: fullDSK.Fill, - transition: TransitionStyle.WIPE_FOR_GFX + transition: TransitionStyle.WIPE_FOR_GFX, + transitionDuration: 20 } }), ...GetSisyfosTimelineObjForFull(this.config) diff --git a/src/tv2-common/layers/timelineLayers.ts b/src/tv2-common/layers/timelineLayers.ts index 81fb446b..4a746dbf 100644 --- a/src/tv2-common/layers/timelineLayers.ts +++ b/src/tv2-common/layers/timelineLayers.ts @@ -3,7 +3,8 @@ import { ATEMModel } from '../../types/atem' import { GetDSKCount } from '../helpers' export const TRICASTER_DEVICE_ID = 'tricaster0' -export const TRICASTER_CLEAN_ME = 'v1' +export const TRICASTER_PROGRAM_ME = 'v1' +export const TRICASTER_CLEAN_ME = 'v4' export const TRICASTER_DVE_ME = 'v2' export const ATEM_DEVICE_ID = 'atem0' @@ -65,8 +66,8 @@ export function getTriCasterDskMappings(): BlueprintMappings { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingTriCasterType.DSK, - name: `dsk${index}` + mappingType: TSR.MappingTriCasterType.ME, + name: TRICASTER_PROGRAM_ME } return prev }, base) diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index 2086cd88..2e7ecc9b 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -417,6 +417,38 @@ export function PrefixEvsWithEvs( } } +export function renameStudioTableColumn( + versionStr: string, + tableId: string, + oldColumnId: string, + newColumnId: string +): MigrationStepStudio { + return { + id: `${versionStr}.renameStudioTableColumn.${tableId}.${oldColumnId}`, + version: versionStr, + canBeRunAutomatically: true, + validate: (context: MigrationContextStudio) => { + const config = (context.getConfig(tableId) as unknown) as TableConfigItemValue + + if (!config || !Array.isArray(config)) { + return false + } + + return config.find(row => oldColumnId in row) !== undefined + }, + migrate: (context: MigrationContextStudio) => { + let config = (context.getConfig(tableId) as unknown) as TableConfigItemValue + config = config.map(row => { + const value = row[oldColumnId] + delete row[oldColumnId] + row[newColumnId] = value + return row + }) + context.setConfig(tableId, (config as unknown) as ConfigItemValue) + } + } +} + export function renameTableColumn( versionStr: string, tableId: string, diff --git a/src/tv2-common/types/config.ts b/src/tv2-common/types/config.ts index 2a174033..9f5d4381 100644 --- a/src/tv2-common/types/config.ts +++ b/src/tv2-common/types/config.ts @@ -13,15 +13,15 @@ export type TableConfigItemSourceMappingWithSisyfos = { } & TableConfigItemSourceMapping export interface SwitcherDskProps { + /** 0-based */ + Number: number Fill: number Key: number - Clip: string - Gain: string + Clip: number + Gain: number } export interface TableConfigItemDSK extends SwitcherDskProps { - /** 0-based */ - Number: number Toggle: boolean DefaultOn: boolean Roles?: DSKRoles[] diff --git a/src/tv2-common/videoSwitchers/Atem.ts b/src/tv2-common/videoSwitchers/Atem.ts index f6a68bdf..334306e5 100644 --- a/src/tv2-common/videoSwitchers/Atem.ts +++ b/src/tv2-common/videoSwitchers/Atem.ts @@ -113,12 +113,13 @@ export class Atem extends VideoSwitcherImpl { type: TSR.TimelineContentTypeAtem.DSK, dsk: { onAir: content.onAir, - sources: content.sources && { - fillSource: this.getInputNumber(content.sources.fillSource), - cutSource: this.getInputNumber(content.sources.cutSource) + sources: { + fillSource: this.getInputNumber(content.config.Fill), + cutSource: this.getInputNumber(content.config.Key) }, - properties: content.properties && { - ...content.properties, + properties: { + clip: content.config.Clip * 10, // input is percents (0-100), atem uses 1-000, + gain: content.config.Gain * 10, // input is percents (0-100), atem uses 1-000, mask: { enabled: false } @@ -258,7 +259,7 @@ export class Atem extends VideoSwitcherImpl { return } return keyers.map(keyer => ({ - upstreamKeyerId: keyer.id, + upstreamKeyerId: keyer.config.Number, onAir: keyer.onAir, mixEffectKeyType: 0, flyEnabled: false, @@ -266,9 +267,8 @@ export class Atem extends VideoSwitcherImpl { cutSource: keyer.config.Key, maskEnabled: false, lumaSettings: { - preMultiplied: false, - clip: Number(keyer.config.Clip) * 10, // input is percents (0-100), atem uses 1-000 - gain: Number(keyer.config.Gain) * 10 // input is percents (0-100), atem uses 1-000 + clip: keyer.config.Clip * 10, // input is percents (0-100), atem uses 1-000 + gain: keyer.config.Gain * 10 // input is percents (0-100), atem uses 1-000 } })) } diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index a81a6350..02426c90 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -1,6 +1,7 @@ import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' +import { TimeFromFrames } from 'tv2-common' import _ = require('underscore') -import { TRICASTER_CLEAN_ME, TRICASTER_DVE_ME, TRICASTER_LAYER_PREFIX } from '../layers' +import { TRICASTER_DVE_ME, TRICASTER_LAYER_PREFIX } from '../layers' import { AuxProps, DskProps, @@ -16,10 +17,10 @@ import { import { VideoSwitcherImpl } from './VideoSwitcher' const SPECIAL_INPUT_MAP: Record = { - [SpecialInput.ME1_PROGRAM]: 'main', - [SpecialInput.ME2_PROGRAM]: 'v1', - [SpecialInput.ME3_PROGRAM]: 'v2', - [SpecialInput.ME4_PROGRAM]: TRICASTER_CLEAN_ME, // @todo: fixme, I'm a hack because with TriCaster we're using a different M/E for Clean + [SpecialInput.ME1_PROGRAM]: 'v1', + [SpecialInput.ME2_PROGRAM]: 'v2', + [SpecialInput.ME3_PROGRAM]: 'v3', + [SpecialInput.ME4_PROGRAM]: 'v4', [SpecialInput.DVE]: TRICASTER_DVE_ME, [SpecialInput.COLOR_GENERATOR1]: 'bfr1', [SpecialInput.COLOR_GENERATOR2]: 'bfr2' @@ -56,7 +57,7 @@ export class TriCaster extends VideoSwitcherImpl { previewInput: this.getInputName(content.previewInput), transition: { effect: this.getTransition(content.transition), - duration: content.transitionDuration ?? 1000 // @todo defaults and ranges + duration: this.getTransitionDuration(content.transition, content.transitionDuration) }, keyers: content.keyers && this.getKeyers(content.keyers) } @@ -75,7 +76,7 @@ export class TriCaster extends VideoSwitcherImpl { } timelineObject.content.me.transition = { effect: this.getTransition(transition), - duration: transitionDuration ?? 1000 // @todo defaults and ranges + duration: this.getTransitionDuration(transition, transitionDuration) } return timelineObject } @@ -99,8 +100,23 @@ export class TriCaster extends VideoSwitcherImpl { return timelineObject } - public getDskTimelineObject(_properties: DskProps): TSR.TSRTimelineObj { - throw new Error('Method not implemented.') + public getDskTimelineObject(props: DskProps): TSR.TimelineObjTriCasterME { + // we chose to use an ME (not the main switcher) as the PGM ME, hence this returns just an ME object + return { + ...this.getBaseProperties(props, props.layer), + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME, + me: { + keyers: { + [`dsk${props.content.config.Number + 1}`]: { + onAir: props.content.onAir, + input: this.getInputName(props.content.config.Fill) + } + } + } + } + } } public getAuxTimelineObject(props: AuxProps): TSR.TimelineObjTriCasterMixOutput { return { @@ -138,6 +154,13 @@ export class TriCaster extends VideoSwitcherImpl { throw new Error('Method not implemented.') } + private getTransitionDuration(transition?: TransitionStyle, durationInFrames?: number): number { + if (transition === TransitionStyle.WIPE_FOR_GFX) { + durationInFrames = this.config.studio.HTMLGraphics.TransitionSettings.wipeRate + } + return TimeFromFrames(durationInFrames ?? 25) / 1000 + } + private getBaseProperties( props: TimelineObjectProps, layer: string @@ -154,7 +177,7 @@ export class TriCaster extends VideoSwitcherImpl { return } return keyers.reduce>((accumulator, keyer) => { - accumulator[`dsk${keyer.id + 1}`] = { + accumulator[`dsk${keyer.config.Number + 1}`] = { onAir: keyer.onAir, input: this.getInputName(keyer.config.Fill) } diff --git a/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts index d490357a..7071737a 100644 --- a/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts @@ -4,7 +4,7 @@ import { makeMockGalleryContext } from '../../../__mocks__/context' import { prefixLayer } from '../../../tv2-common/__tests__/testUtil' import { TV2StudioConfigBase } from '../../../tv2-common/blueprintConfig' import { AtemSourceIndex } from '../../../types/atem' -import { SwitcherType, TransitionStyle } from '../types' +import { AuxProps, DskProps, MixEffectProps, SwitcherType, TransitionStyle } from '../types' import { VideoSwitcherImpl } from '../VideoSwitcher' const DURATION: number = 50 @@ -19,14 +19,15 @@ function setupAtem(studioConfigOverrides?: Partial) { describe('ATEM', () => { describe('Mix Effect', () => { + const DEFAULT_ME: MixEffectProps = { + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5 + } + } test('sets timeline object defaults', () => { const atem = setupAtem() - const timelineObject = atem.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, - content: { - input: 5 - } - }) + const timelineObject = atem.getMixEffectTimelineObject(DEFAULT_ME) expect(timelineObject).toMatchObject({ id: '', enable: { start: 0 }, @@ -41,10 +42,7 @@ describe('ATEM', () => { test('sets classes', () => { const atem = setupAtem() const timelineObject = atem.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, - content: { - input: 5 - }, + ...DEFAULT_ME, classes: ['classA', 'classB'] }) expect(timelineObject).toMatchObject({ @@ -55,10 +53,7 @@ describe('ATEM', () => { test('sets metaData', () => { const atem = setupAtem() const timelineObject = atem.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, - content: { - input: 5 - }, + ...DEFAULT_ME, metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } }) expect(timelineObject).toMatchObject({ @@ -68,12 +63,7 @@ describe('ATEM', () => { test('sets layer prefix', () => { const atem = setupAtem() - const timelineObject = atem.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, - content: { - input: 5 - } - }) + const timelineObject = atem.getMixEffectTimelineObject(DEFAULT_ME) expect(timelineObject).toMatchObject({ layer: prefixLayer(SwitcherMixEffectLLayer.Program) }) @@ -81,12 +71,7 @@ describe('ATEM', () => { test('sets programInput when no transition provided', () => { const atem = setupAtem() - const timelineObject = atem.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, - content: { - input: 5 - } - }) + const timelineObject = atem.getMixEffectTimelineObject(DEFAULT_ME) expect(timelineObject).toMatchObject({ content: { me: { @@ -183,7 +168,14 @@ describe('ATEM', () => { }) test('supports WIPE for GFX', () => { - const atem = setupAtem() + const wipeRate = 22 + const atem = setupAtem({ + HTMLGraphics: { + GraphicURL: 'donotcare', + TransitionSettings: { wipeRate, borderSoftness: 7500, loopOutTransitionDuration: 15 }, + KeepAliveDuration: 120 + } + }) const timelineObject = atem.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.Program, content: { @@ -198,7 +190,7 @@ describe('ATEM', () => { transition: TSR.AtemTransitionStyle.WIPE, transitionSettings: { wipe: { - rate: 20, + rate: wipeRate, pattern: 1, reverseDirection: true, borderSoftness: 7500 @@ -277,48 +269,59 @@ describe('ATEM', () => { }) } - test('supports keyers', () => { - const atem = setupAtem() + test('supports keyers', () => { + const atem = setupAtem() const timelineObject = atem.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.Program, content: { - keyers: [ - { - id: 2, - onAir: true, - config: { - - } - } - ] + keyers: [ + { + onAir: true, + config: { + Number: 0, + Fill: 5, + Key: 6, + Clip: 125, + Gain: 1 + } + } + ] } }) expect(timelineObject).toMatchObject({ content: { me: { - transitionSettings: { - wipe: { - rate: 20, - pattern: 1, - reverseDirection: true, - borderSoftness: 7500 + upstreamKeyers: [ + { + upstreamKeyerId: 0, + onAir: true, + mixEffectKeyType: 0, + flyEnabled: false, + fillSource: 5, + cutSource: 6, + maskEnabled: false, + lumaSettings: { + clip: 1250, + gain: 10 + } } - } + ] } } }) - }) + }) }) describe('Aux', () => { + const DEFAULT_AUX: AuxProps = { + layer: SwitcherAuxLLayer.AuxClean, + content: { + input: 5 + } + } test('sets timeline object defaults', () => { const atem = setupAtem() - const timelineObject = atem.getAuxTimelineObject({ - layer: SwitcherAuxLLayer.AuxClean, - content: { - input: 5 - } - }) + const timelineObject = atem.getAuxTimelineObject(DEFAULT_AUX) expect(timelineObject).toMatchObject({ id: '', enable: { start: 0 }, @@ -333,10 +336,7 @@ describe('ATEM', () => { test('sets classes', () => { const atem = setupAtem() const timelineObject = atem.getAuxTimelineObject({ - layer: SwitcherAuxLLayer.AuxClean, - content: { - input: 5 - }, + ...DEFAULT_AUX, classes: ['classA', 'classB'] }) expect(timelineObject).toMatchObject({ @@ -347,10 +347,7 @@ describe('ATEM', () => { test('sets metaData', () => { const atem = setupAtem() const timelineObject = atem.getAuxTimelineObject({ - layer: SwitcherAuxLLayer.AuxClean, - content: { - input: 5 - }, + ...DEFAULT_AUX, metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } }) expect(timelineObject).toMatchObject({ @@ -360,12 +357,7 @@ describe('ATEM', () => { test('sets layer prefix', () => { const atem = setupAtem() - const timelineObject = atem.getAuxTimelineObject({ - layer: SwitcherAuxLLayer.AuxClean, - content: { - input: 5 - } - }) + const timelineObject = atem.getAuxTimelineObject(DEFAULT_AUX) expect(timelineObject).toMatchObject({ layer: prefixLayer(SwitcherAuxLLayer.AuxClean) }) @@ -374,12 +366,7 @@ describe('ATEM', () => { test('sets aux', () => { const atem = setupAtem() - const timelineObject = atem.getAuxTimelineObject({ - layer: SwitcherAuxLLayer.AuxClean, - content: { - input: 5 - } - }) + const timelineObject = atem.getAuxTimelineObject(DEFAULT_AUX) expect(timelineObject).toMatchObject({ content: { @@ -394,14 +381,22 @@ describe('ATEM', () => { }) describe('DSK', () => { + const DEFAULT_DSK: DskProps = { + layer: 'dsk_1', + content: { + onAir: true, + config: { + Number: 0, + Fill: 5, + Key: 6, + Clip: 125, + Gain: 1 + } + } + } test('sets timeline object defaults', () => { const atem = setupAtem() - const timelineObject = atem.getDskTimelineObject({ - layer: 'dsk_1', - content: { - onAir: true - } - }) + const timelineObject = atem.getDskTimelineObject(DEFAULT_DSK) expect(timelineObject).toMatchObject({ id: '', enable: { start: 0 }, @@ -416,10 +411,7 @@ describe('ATEM', () => { test('sets classes', () => { const atem = setupAtem() const timelineObject = atem.getDskTimelineObject({ - layer: 'dsk_1', - content: { - onAir: true - }, + ...DEFAULT_DSK, classes: ['classA', 'classB'] }) expect(timelineObject).toMatchObject({ @@ -430,10 +422,7 @@ describe('ATEM', () => { test('sets metaData', () => { const atem = setupAtem() const timelineObject = atem.getDskTimelineObject({ - layer: 'dsk_1', - content: { - onAir: true - }, + ...DEFAULT_DSK, metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } }) expect(timelineObject).toMatchObject({ @@ -443,12 +432,7 @@ describe('ATEM', () => { test('sets layer prefix', () => { const atem = setupAtem() - const timelineObject = atem.getDskTimelineObject({ - layer: 'dsk_1', - content: { - onAir: true - } - }) + const timelineObject = atem.getDskTimelineObject(DEFAULT_DSK) expect(timelineObject).toMatchObject({ layer: prefixLayer('dsk_1') }) @@ -457,12 +441,7 @@ describe('ATEM', () => { test('enables DSK', () => { const atem = setupAtem() - const timelineObject = atem.getDskTimelineObject({ - layer: 'dsk_1', - content: { - onAir: true - } - }) + const timelineObject = atem.getDskTimelineObject(DEFAULT_DSK) expect(timelineObject).toMatchObject({ content: { diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts new file mode 100644 index 00000000..729da2c4 --- /dev/null +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -0,0 +1,391 @@ +import { TSR } from 'blueprints-integration' +import { literal } from 'tv2-common' +import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' +import { makeMockGalleryContext } from '../../../__mocks__/context' +import { TV2StudioConfigBase } from '../../../tv2-common/blueprintConfig' +import { AuxProps, DskProps, MixEffectProps, SwitcherType, TransitionStyle } from '../types' +import { VideoSwitcherImpl } from '../VideoSwitcher' + +const DURATION_FRAMES: number = 50 +const DURATION_SECONDS: number = DURATION_FRAMES / 25 + +function setupTriCaster(studioConfigOverrides?: Partial) { + // @todo: is this the correct way? + const context = makeMockGalleryContext({ + studioConfig: { SwitcherType: SwitcherType.TRICASTER, ...studioConfigOverrides } + }) + return VideoSwitcherImpl.getVideoSwitcher(context.core, context.config, context.uniformConfig) +} + +describe('TriCaster', () => { + describe('Mix Effect', () => { + const DEFAULT_ME: MixEffectProps = { + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5 + } + } + test('sets timeline object defaults', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getMixEffectTimelineObject(DEFAULT_ME) + expect(timelineObject).toMatchObject({ + id: '', + enable: { start: 0 }, + priority: 0, + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME + } + }) + }) + + test('sets classes', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getMixEffectTimelineObject({ + ...DEFAULT_ME, + classes: ['classA', 'classB'] + }) + expect(timelineObject).toMatchObject({ + classes: ['classA', 'classB'] + }) + }) + + test('sets metaData', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getMixEffectTimelineObject({ + ...DEFAULT_ME, + metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } + }) + expect(timelineObject).toMatchObject({ + metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } + }) + }) + + test('sets layer prefix', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getMixEffectTimelineObject(DEFAULT_ME) + expect(timelineObject).toMatchObject({ + layer: prefixLayer(SwitcherMixEffectLLayer.Program) + }) + }) + + test('sets programInput', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getMixEffectTimelineObject(DEFAULT_ME) + expect(timelineObject).toMatchObject({ + content: { + me: { + programInput: 'input5' + } + } + }) + }) + + test('sets previewInput', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + previewInput: 5 + } + }) + expect(timelineObject).toMatchObject({ + content: { + me: { + previewInput: 'input5' + } + } + }) + }) + + test('supports MIX', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5, + transition: TransitionStyle.MIX, + transitionDuration: DURATION_FRAMES + } + }) + expect(timelineObject).toMatchObject({ + content: literal({ + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME, + me: { + programInput: 'input5', + transition: { + effect: 'fade', + duration: DURATION_SECONDS + } + } + }) + }) + }) + + test('supports WIPE', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 3, + transition: TransitionStyle.WIPE, + transitionDuration: DURATION_FRAMES + } + }) + expect(timelineObject).toMatchObject({ + content: literal({ + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME, + me: { + programInput: 'input3', + transition: { + effect: 3, + duration: DURATION_SECONDS + } + } + }) + }) + }) + + test('supports WIPE for GFX', () => { + const wipeRate = 22 + const triCaster = setupTriCaster({ + HTMLGraphics: { + GraphicURL: 'donotcare', + TransitionSettings: { wipeRate, borderSoftness: 20, loopOutTransitionDuration: 15 }, + KeepAliveDuration: 120 + } + }) + const timelineObject = triCaster.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5, + transition: TransitionStyle.WIPE_FOR_GFX + } + }) + expect(timelineObject).toMatchObject({ + content: literal({ + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME, + me: { + programInput: 'input5', + transition: { + effect: 4, + duration: wipeRate / 25 + } + } + }) + }) + }) + + test('supports DIP', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + input: 5, + transition: TransitionStyle.DIP, + transitionDuration: DURATION_FRAMES + } + }) + expect(timelineObject).toMatchObject({ + content: literal({ + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME, + me: { + programInput: 'input5', + transition: { + effect: 2, + duration: DURATION_SECONDS + } + } + }) + }) + }) + + test('supports keyers', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getMixEffectTimelineObject({ + layer: SwitcherMixEffectLLayer.Program, + content: { + keyers: [ + { + onAir: true, + config: { + Number: 0, + Fill: 5, + Key: 6, + Clip: 125, + Gain: 1 + } + } + ] + } + }) + expect(timelineObject).toMatchObject({ + content: literal({ + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME, + me: { + keyers: { + dsk1: { + onAir: true, + input: 'input5' + } + } + } + }) + }) + }) + }) + + describe('Aux', () => { + const DEFAULT_AUX: AuxProps = { + layer: SwitcherAuxLLayer.AuxClean, + content: { + input: 5 + } + } + test('sets timeline object defaults', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getAuxTimelineObject(DEFAULT_AUX) + expect(timelineObject).toMatchObject({ + id: '', + enable: { start: 0 }, + priority: 0, + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.MIX_OUTPUT + } + }) + }) + + test('sets classes', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getAuxTimelineObject({ + ...DEFAULT_AUX, + classes: ['classA', 'classB'] + }) + expect(timelineObject).toMatchObject({ + classes: ['classA', 'classB'] + }) + }) + + test('sets metaData', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getAuxTimelineObject({ + ...DEFAULT_AUX, + metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } + }) + expect(timelineObject).toMatchObject({ + metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } + }) + }) + + test('sets layer prefix', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getAuxTimelineObject(DEFAULT_AUX) + expect(timelineObject).toMatchObject({ + layer: prefixLayer(SwitcherAuxLLayer.AuxClean) + }) + }) + + test('sets aux source', () => { + const triCaster = setupTriCaster() + + const timelineObject = triCaster.getAuxTimelineObject(DEFAULT_AUX) + + expect(timelineObject).toMatchObject({ + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.MIX_OUTPUT, + source: 'input5' + } + }) + }) + }) + + describe('DSK', () => { + const DEFAULT_DSK: DskProps = { + layer: 'dsk_1', + content: { + onAir: true, + config: { + Number: 0, + Fill: 5, + Key: 6, + Clip: 125, + Gain: 1 + } + } + } + test('sets timeline object defaults', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getDskTimelineObject(DEFAULT_DSK) + expect(timelineObject).toMatchObject({ + id: '', + enable: { start: 0 }, + priority: 0, + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME + } + }) + }) + + test('sets classes', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getDskTimelineObject({ + ...DEFAULT_DSK, + classes: ['classA', 'classB'] + }) + expect(timelineObject).toMatchObject({ + classes: ['classA', 'classB'] + }) + }) + + test('sets metaData', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getDskTimelineObject({ + ...DEFAULT_DSK, + metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } + }) + expect(timelineObject).toMatchObject({ + metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } + }) + }) + + test('sets layer prefix', () => { + const triCaster = setupTriCaster() + const timelineObject = triCaster.getDskTimelineObject(DEFAULT_DSK) + expect(timelineObject).toMatchObject({ + layer: prefixLayer('dsk_1') + }) + }) + + test('enables DSK', () => { + const triCaster = setupTriCaster() + + const timelineObject = triCaster.getDskTimelineObject(DEFAULT_DSK) + + expect(timelineObject).toMatchObject({ + content: literal({ + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME, + me: { + keyers: { + dsk1: { + onAir: true + } + } + } + }) + }) + }) + }) +}) + +export function prefixLayer(layerName: string) { + return 'tricaster_' + layerName +} diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index c03640fe..c6e26365 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -1,5 +1,5 @@ import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' -import { TimelineObjectMetaData, SwitcherDskProps } from 'tv2-common' +import { SwitcherDskProps, TimelineObjectMetaData } from 'tv2-common' import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' import { AtemSourceIndex } from '../../types/atem' @@ -57,6 +57,7 @@ export interface MixEffectProps extends TimelineObjectProps { input?: number | SpecialInput previewInput?: number | SpecialInput transition?: TransitionStyle + /** Transition duration (frames) */ transitionDuration?: number keyers?: Keyer[] } @@ -67,8 +68,6 @@ export interface OnAirMixEffectProps extends Omit { } export interface Keyer { - // id starting from 0 - id: number onAir: boolean config: SwitcherDskProps } @@ -77,16 +76,7 @@ export interface DskProps extends TimelineObjectProps { layer: string // @todo: better type content: { onAir: boolean - sources?: { - fillSource: number | SpecialInput - cutSource: number | SpecialInput - } - properties?: { - tie?: boolean - preMultiply?: boolean - clip?: number // percents (0-100), atem uses 1-000, - gain?: number // percents (0-100), atem uses 1-000, - } + config: SwitcherDskProps } } diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 9efc6bd0..ece607a4 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -864,7 +864,7 @@ function getBaseline( enable: { while: '1' }, layer: SwitcherAuxLLayer.AuxClean, content: { - input: SpecialInput.ME4_PROGRAM // @todo: this is incorrect - how to get the parity + input: SpecialInput.ME4_PROGRAM } }), videoSwitcher.getAuxTimelineObject({ @@ -914,7 +914,6 @@ function getBaseline( content: { keyers: [ { - id: 0, onAir: false, config: jingleDSK } diff --git a/src/tv2_afvd_showstyle/migrations/util.ts b/src/tv2_afvd_showstyle/migrations/util.ts index f5aff3af..62daeee0 100644 --- a/src/tv2_afvd_showstyle/migrations/util.ts +++ b/src/tv2_afvd_showstyle/migrations/util.ts @@ -1,7 +1,6 @@ import { IOutputLayer, ISourceLayer, MigrationContextShowStyle, MigrationStepShowStyle } from 'blueprints-integration' import { forceSourceLayerToDefaultsBase, literal } from 'tv2-common' import * as _ from 'underscore' -import { showStyleConfigManifest } from '../config-manifests' import OutputlayerDefaults from './outputlayer-defaults' import SourcelayerDefaults from './sourcelayer-defaults' diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index 3f42f4fd..3f2aafa0 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -249,7 +249,7 @@ export const manifestAFVDSourcesABMediaPlayers: ConfigManifestEntryTable = { rank: 0 }, { - id: 'SwicherSource', + id: 'SwitcherSource', name: 'Switcher input', description: 'Video Switcher input for Media player', type: ConfigManifestEntryType.INT, diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index 336fc246..fa591556 100644 --- a/src/tv2_afvd_studio/helpers/config.ts +++ b/src/tv2_afvd_studio/helpers/config.ts @@ -65,8 +65,8 @@ export const defaultDSKConfig: TableConfigItemDSK[] = [ Toggle: true, DefaultOn: true, Roles: [DSKRoles.FULLGFX, DSKRoles.OVERLAYGFX], - Clip: '50', - Gain: '12.5' + Clip: 50, + Gain: 12.5 }, - { Number: 1, Key: 31, Fill: 29, Toggle: true, DefaultOn: false, Roles: [DSKRoles.JINGLE], Clip: '50', Gain: '12.5' } + { Number: 1, Key: 31, Fill: 29, Toggle: true, DefaultOn: false, Roles: [DSKRoles.JINGLE], Clip: 50, Gain: 12.5 } ] diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index 51e90f5c..aa288579 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -7,6 +7,7 @@ import { PrefixEvsWithEvs, RemoveConfig, RenameStudioConfig, + renameStudioTableColumn, SetConfigTo, SetLayerNamesToDefaults } from 'tv2-common' @@ -181,7 +182,7 @@ export const studioMigrations: MigrationStepStudio[] = [ removeMapping('1.6.1', 'atem_dsk_graphics'), removeMapping('1.6.1', 'atem_dsk_efect'), - RenameStudioConfig('1.6.2', 'AFVD', 'SourcesRM.KeepAudioInStudio', 'SourcesRM.WantsToPersistAudio'), + RenameStudioConfig('1.6.2', 'AFVD', 'SourcesRM.KeepAudioInStudio', 'SourcesRM.WantsToPersistAudio'), // @todo: check what this does because it does not seem right RemoveConfig('1.6.2', 'AFVD', 'SourcesSkype'), RenameStudioConfig('1.7.4', 'AFVD', 'SourcesDelayedPlayback', 'SourcesReplay'), @@ -201,6 +202,12 @@ export const studioMigrations: MigrationStepStudio[] = [ */ renameMapping('1.7.8', 'graphic_pilot_overlay', 'graphic_overlay_pilot'), + /** + * 1.8.0 (@todo version) + */ + ...['SourcesCam', 'SourcesRM', 'SourcesReplay', 'SourcesFeed', 'ABMediaPlayers'].map((tableName) => renameStudioTableColumn('1.8.0', tableName, 'AtemSource', 'SwitcherSource')), + RenameStudioConfig('1.8.0', 'AFVD', 'AtemSource', 'SwitcherSource'), + // Fill in any mappings that did not exist before // Note: These should only be run as the very final step of all migrations. otherwise they will add items too early, and confuse old migrations ...getMappingsDefaultsMigrationSteps(VERSION) diff --git a/src/tv2_afvd_studio/migrations/util.ts b/src/tv2_afvd_studio/migrations/util.ts index 17bcba7c..5df2845b 100644 --- a/src/tv2_afvd_studio/migrations/util.ts +++ b/src/tv2_afvd_studio/migrations/util.ts @@ -1,6 +1,5 @@ import { BlueprintMapping, - ConfigItemValue, MigrationContextStudio, MigrationStepInput, MigrationStepInputFilteredResult, diff --git a/src/tv2_afvd_studio/uniformConfig.ts b/src/tv2_afvd_studio/uniformConfig.ts index dee264b5..6c2b4657 100644 --- a/src/tv2_afvd_studio/uniformConfig.ts +++ b/src/tv2_afvd_studio/uniformConfig.ts @@ -7,6 +7,7 @@ export const GALLERY_UNIFORM_CONFIG: UniformConfig = { PrimaryMixEffectClone: SwitcherMixEffectLLayer.Clean, JingleUskMixEffect: SwitcherMixEffectLLayer.CleanUSKEffect, ProgramAux: SwitcherAuxLLayer.AuxProgram, + NextAux: SwitcherAuxLLayer.AuxLookahead, MixMinusAux: SwitcherAuxLLayer.AuxVideoMixMinus } } diff --git a/src/tv2_offtube_showstyle/migrations/util.ts b/src/tv2_offtube_showstyle/migrations/util.ts index 5bc1a81a..1cb248e3 100644 --- a/src/tv2_offtube_showstyle/migrations/util.ts +++ b/src/tv2_offtube_showstyle/migrations/util.ts @@ -7,7 +7,6 @@ import { } from 'blueprints-integration' import { forceSourceLayerToDefaultsBase } from 'tv2-common' import * as _ from 'underscore' -import { showStyleConfigManifest } from '../config-manifests' import OutputlayerDefaults from './outputlayer-defaults' import SourcelayerDefaults from './sourcelayer-defaults' diff --git a/src/tv2_offtube_studio/helpers/config.ts b/src/tv2_offtube_studio/helpers/config.ts index 24c238e8..0466721f 100644 --- a/src/tv2_offtube_studio/helpers/config.ts +++ b/src/tv2_offtube_studio/helpers/config.ts @@ -69,8 +69,8 @@ export const defaultDSKConfig: TableConfigItemDSK[] = [ Toggle: true, DefaultOn: true, Roles: [DSKRoles.JINGLE, DSKRoles.OVERLAYGFX], - Clip: '50.0', - Gain: '12.5' + Clip: 50.0, + Gain: 12.5 }, // Offtube doesn't use DSK for fulls, but this prevents duplicate studio configs + easy switchover to Viz engine { @@ -80,7 +80,7 @@ export const defaultDSKConfig: TableConfigItemDSK[] = [ Toggle: false, DefaultOn: false, Roles: [DSKRoles.FULLGFX], - Clip: '50.0', - Gain: '12.5' + Clip: 50.0, + Gain: 12.5 } ] diff --git a/src/tv2_offtube_studio/migrations/index.ts b/src/tv2_offtube_studio/migrations/index.ts index 8d9ab9f3..222f171c 100644 --- a/src/tv2_offtube_studio/migrations/index.ts +++ b/src/tv2_offtube_studio/migrations/index.ts @@ -275,7 +275,7 @@ export const studioMigrations: MigrationStepStudio[] = [ RenameStudioConfig('1.4.6', 'Offtube', 'GraphicBasePath', 'NetworkBasePathGraphic'), RenameStudioConfig('1.4.6', 'Offtube', 'GraphicFlowId', 'GraphicMediaFlowId'), - GetMappingDefaultMigrationStepForLayer('1.4.8', 'casparcg_player_jingle_looakhead', true), +// GetMappingDefaultMigrationStepForLayer('1.4.8', 'casparcg_player_jingle_looakhead', true), RenameStudioConfig('1.5.0', 'Offtube', 'NetworkBasePathJingle', 'JingleNetworkBasePath'), RenameStudioConfig('1.5.0', 'Offtube', 'NetworkBasePathClip', 'ClipNetworkBasePath'), @@ -362,7 +362,7 @@ export const studioMigrations: MigrationStepStudio[] = [ * - Rename the GraphicLLayerOverlayPilot, because alphabetical order matters for deeply extending the Caspar Objects targeting the same channel:layer * - Change lookahead properties and channel on GraphicLLayerOverlayPilot */ - renameMapping('1.7.8', 'graphic_pilot_overlay', 'graphic_overlay_pilot'), + removeMapping('1.7.8', 'graphic_pilot_overlay'), GetMappingDefaultMigrationStepForLayer('1.7.8', 'graphic_overlay_pilot', true), // Fill in any mappings that did not exist before diff --git a/src/tv2_offtube_studio/migrations/util.ts b/src/tv2_offtube_studio/migrations/util.ts index bd2a422e..05cb76aa 100644 --- a/src/tv2_offtube_studio/migrations/util.ts +++ b/src/tv2_offtube_studio/migrations/util.ts @@ -1,6 +1,5 @@ import { BlueprintMapping, - ConfigItemValue, MigrationContextStudio, MigrationStepInput, MigrationStepInputFilteredResult, From 9aa141ada5966faa8f822472b877ffde585b41bd Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 15 Feb 2023 13:01:36 +0100 Subject: [PATCH 18/86] wip: SOF-1260 TSR type change --- src/tv2-common/helpers/abPlayback.ts | 6 +++- src/tv2-common/videoSwitchers/TriCaster.ts | 29 ++++++++++++------- .../__tests__/TriCaster.spec.ts | 24 +++++---------- src/tv2_afvd_studio/migrations/index.ts | 4 ++- 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/tv2-common/helpers/abPlayback.ts b/src/tv2-common/helpers/abPlayback.ts index 04816d07..ae681add 100644 --- a/src/tv2-common/helpers/abPlayback.ts +++ b/src/tv2-common/helpers/abPlayback.ts @@ -275,7 +275,11 @@ function updateObjectsToMediaPlayer< } const input = Number(switcherInput.val) || 0 if (context.videoSwitcher.isMixEffect(obj)) { - if (context.uniformConfig.SwitcherLLayers.NextPreviewMixEffect) { + // the `endsWith` below is a nasty hack, but this will be gone after AB refactor + if ( + context.uniformConfig.SwitcherLLayers.NextPreviewMixEffect && + obj.layer.toString().endsWith(context.uniformConfig.SwitcherLLayers.NextPreviewMixEffect) + ) { context.videoSwitcher.updatePreviewInput(obj, input) } else { context.videoSwitcher.updateInput(obj, input) diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 02426c90..51cc0b78 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -47,22 +47,24 @@ export class TriCaster extends VideoSwitcherImpl { public getMixEffectTimelineObject(props: MixEffectProps): TSR.TimelineObjTriCasterME { const { content } = props - return { + const transition = this.getTransition(content.transition) + const result: TSR.TimelineObjTriCasterME = { ...this.getBaseProperties(props, props.layer), content: { deviceType: TSR.DeviceType.TRICASTER, type: TSR.TimelineContentTypeTriCaster.ME, me: { programInput: this.getInputName(content.input), - previewInput: this.getInputName(content.previewInput), - transition: { - effect: this.getTransition(content.transition), - duration: this.getTransitionDuration(content.transition, content.transitionDuration) - }, + ...(content.previewInput !== undefined && transition === 'cut' + ? { previewInput: this.getInputName(content.previewInput) } + : {}), + transitionEffect: transition, + transitionDuration: this.getTransitionDuration(content.transition, content.transitionDuration), keyers: content.keyers && this.getKeyers(content.keyers) } } } + return result } public updateTransition( @@ -74,12 +76,14 @@ export class TriCaster extends VideoSwitcherImpl { // @todo: log error or throw return timelineObject } - timelineObject.content.me.transition = { - effect: this.getTransition(transition), - duration: this.getTransitionDuration(transition, transitionDuration) - } + timelineObject.content.me.transitionEffect = this.getTransition(transition) + ;(timelineObject.content.me as TSR.TriCasterMixEffectInMixMode).transitionDuration = this.getTransitionDuration( + transition, + transitionDuration + ) return timelineObject } + public updatePreviewInput( timelineObject: TSR.TSRTimelineObj, previewInput: number | SpecialInput @@ -91,6 +95,7 @@ export class TriCaster extends VideoSwitcherImpl { ;(timelineObject.content.me as TSR.TriCasterMixEffectWithPreview).previewInput = this.getInputName(previewInput) return timelineObject } + public updateInput(timelineObject: TSR.TSRTimelineObj, input: number | SpecialInput): TSR.TSRTimelineObj { if (!this.isMixEffect(timelineObject)) { // @todo: log error or throw @@ -118,6 +123,7 @@ export class TriCaster extends VideoSwitcherImpl { } } } + public getAuxTimelineObject(props: AuxProps): TSR.TimelineObjTriCasterMixOutput { return { ...this.getBaseProperties(props, props.layer), @@ -137,6 +143,7 @@ export class TriCaster extends VideoSwitcherImpl { timelineObject.content.source = this.getInputName(input) return timelineObject } + public isDveBoxes = (timelineObject: TimelineObjectCoreExt): boolean => { // @todo: this is ugly return ( @@ -144,9 +151,11 @@ export class TriCaster extends VideoSwitcherImpl { !!(timelineObject.content.me as TSR.TriCasterMixEffectInEffectMode).layers ) } + public getDveTimelineObjects(_properties: DveProps): TSR.TSRTimelineObj[] { throw new Error('Method not implemented.') } + public updateUnpopulatedDveBoxes( _timelineObject: TSR.TSRTimelineObj, _input: number | SpecialInput diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index 729da2c4..febb7491 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -114,10 +114,8 @@ describe('TriCaster', () => { type: TSR.TimelineContentTypeTriCaster.ME, me: { programInput: 'input5', - transition: { - effect: 'fade', - duration: DURATION_SECONDS - } + transitionEffect: 'fade', + transitionDuration: DURATION_SECONDS } }) }) @@ -139,10 +137,8 @@ describe('TriCaster', () => { type: TSR.TimelineContentTypeTriCaster.ME, me: { programInput: 'input3', - transition: { - effect: 3, - duration: DURATION_SECONDS - } + transitionEffect: 3, + transitionDuration: DURATION_SECONDS } }) }) @@ -170,10 +166,8 @@ describe('TriCaster', () => { type: TSR.TimelineContentTypeTriCaster.ME, me: { programInput: 'input5', - transition: { - effect: 4, - duration: wipeRate / 25 - } + transitionEffect: 4, + transitionDuration: wipeRate / 25 } }) }) @@ -195,10 +189,8 @@ describe('TriCaster', () => { type: TSR.TimelineContentTypeTriCaster.ME, me: { programInput: 'input5', - transition: { - effect: 2, - duration: DURATION_SECONDS - } + transitionEffect: 2, + transitionDuration: DURATION_SECONDS } }) }) diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index aa288579..84d7db64 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -205,7 +205,9 @@ export const studioMigrations: MigrationStepStudio[] = [ /** * 1.8.0 (@todo version) */ - ...['SourcesCam', 'SourcesRM', 'SourcesReplay', 'SourcesFeed', 'ABMediaPlayers'].map((tableName) => renameStudioTableColumn('1.8.0', tableName, 'AtemSource', 'SwitcherSource')), + ...['SourcesCam', 'SourcesRM', 'SourcesReplay', 'SourcesFeed', 'ABMediaPlayers'].map(tableName => + renameStudioTableColumn('1.8.0', tableName, 'AtemSource', 'SwitcherSource') + ), RenameStudioConfig('1.8.0', 'AFVD', 'AtemSource', 'SwitcherSource'), // Fill in any mappings that did not exist before From 2aac7ae51f52090cf7fbb8d5533489ef30e520d2 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 15 Feb 2023 22:40:36 +0100 Subject: [PATCH 19/86] fix: SOF-1260 lookahead and ME assignment --- src/tv2-common/videoSwitchers/VideoSwitcher.ts | 1 + src/tv2_afvd_studio/migrations/mappings-defaults.ts | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts index 86bb9d89..666f0279 100644 --- a/src/tv2-common/videoSwitchers/VideoSwitcher.ts +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -74,6 +74,7 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { result.push( this.getAuxTimelineObject({ ..._.omit(properties, 'content'), + priority: 0, // lower than lookahead-lookahead content: { input: properties.content.input }, layer: this.uniformConfig.SwitcherLLayers.NextAux, metaData: { ...properties.metaData, context: `Aux Lookahead for ${primaryId}` } diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index e546b326..3962537d 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -13,7 +13,8 @@ import { TRICASTER_CLEAN_ME, TRICASTER_DEVICE_ID, TRICASTER_DVE_ME, - TRICASTER_LAYER_PREFIX + TRICASTER_LAYER_PREFIX, + TRICASTER_PROGRAM_ME } from 'tv2-common' import { AbstractLLayer, @@ -683,7 +684,7 @@ export const MAPPINGS_TRICASTER: Record Date: Mon, 20 Feb 2023 11:08:51 +0100 Subject: [PATCH 20/86] wip: SOF-1260 add Matrix Outputs support --- src/__mocks__/context.ts | 13 +- src/tv2-common/helpers/dsk.ts | 2 +- .../graphics/viz/VizPilotGraphicGenerator.ts | 4 +- src/tv2-common/uniformConfig.ts | 27 ++- src/tv2-common/videoSwitchers/TriCaster.ts | 59 ++++- .../__tests__/TriCaster.spec.ts | 104 +++++++-- src/tv2_afvd_showstyle/getRundown.ts | 64 +++--- .../__tests__/graphics.spec.ts | 4 +- .../migrations/mappings-defaults.ts | 209 +++++++++--------- src/tv2_afvd_studio/uniformConfig.ts | 25 ++- src/tv2_offtube_showstyle/getRundown.ts | 4 +- src/tv2_offtube_studio/uniformConfig.ts | 19 +- 12 files changed, 359 insertions(+), 175 deletions(-) diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index 472b1a7d..17f21442 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -38,6 +38,7 @@ import { MixEffectProps, PieceMetaData, TV2StudioConfigBase, + UniformConfig, VideoSwitcher, VideoSwitcherImpl } from 'tv2-common' @@ -650,15 +651,17 @@ class MockVideoSwitcher implements VideoSwitcher { public getAuxTimelineObject = (properties: AuxProps) => (properties as any) as TSR.TSRTimelineObj } -interface ConfigOverrides { +export interface MockConfigOverrides { studioConfig?: Partial showStyleConfig?: Partial + mappingDefaults?: BlueprintMappings + uniformConfig?: Partial } -export function makeMockCoreGalleryContext(overrides?: ConfigOverrides) { +export function makeMockCoreGalleryContext(overrides?: MockConfigOverrides) { const mockCoreContext = new SegmentUserContext( 'test', - mappingsDefaultsAFVD, + { ...mappingsDefaultsAFVD, ...overrides?.mappingDefaults }, parseStudioConfigAFVD, parseShowStyleConfigAFVD ) @@ -667,14 +670,14 @@ export function makeMockCoreGalleryContext(overrides?: ConfigOverrides) { return mockCoreContext } -export function makeMockGalleryContext(overrides?: ConfigOverrides) { +export function makeMockGalleryContext(overrides?: MockConfigOverrides) { const mockCoreContext = makeMockCoreGalleryContext(overrides) const config = { ...(mockCoreContext.getStudioConfig() as any), ...(mockCoreContext.getShowStyleConfig() as any) } const mockContext: ExtendedSegmentContext = { core: mockCoreContext, // @todo: this is awful, fix it perhaps by replacing defaultShowStyleConfig and defaultStudioConfig with preparsed config?! config, - uniformConfig: GALLERY_UNIFORM_CONFIG, + uniformConfig: { ...GALLERY_UNIFORM_CONFIG, ...overrides?.uniformConfig }, videoSwitcher: VideoSwitcherImpl.getVideoSwitcher(mockCoreContext, config, GALLERY_UNIFORM_CONFIG) // new MockVideoSwitcher() } return mockContext diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index 5c04e243..67f3befc 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -145,7 +145,7 @@ export function CreateDSKBaselineAdlibs( return adlibItems } -export function CreateDSKBaseline( +export function createDskBaseline( config: TV2BlueprintConfigBase, videoSwitcher: VideoSwitcher ): TSR.TSRTimelineObj[] { diff --git a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts index 8955e9cc..a0aa90f4 100644 --- a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts @@ -96,14 +96,14 @@ export class VizPilotGraphicGenerator extends PilotGraphicGenerator { ...getDskOnAirTimelineObjects(this.context, DSKRoles.FULLGFX), ...GetSisyfosTimelineObjForFull(this.config) ] - if (this.context.uniformConfig.SwitcherLLayers.ProgramAux) { + if (this.context.uniformConfig.MixEffects.Program.auxLayer) { timelineObjects.push( this.context.videoSwitcher.getAuxTimelineObject({ enable: { start: this.config.studio.VizPilotGraphics.CutToMediaPlayer }, priority: 1, - layer: this.context.uniformConfig.SwitcherLLayers.ProgramAux, + layer: this.context.uniformConfig.MixEffects.Program.auxLayer, content: { input: fullDSK.Fill } diff --git a/src/tv2-common/uniformConfig.ts b/src/tv2-common/uniformConfig.ts index 5fff92aa..308a54be 100644 --- a/src/tv2-common/uniformConfig.ts +++ b/src/tv2-common/uniformConfig.ts @@ -1,4 +1,5 @@ import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' +import { SpecialInput } from './videoSwitchers' /** This config contains hardcoded values that differ between Gallery and Qbox Blueprints */ export interface UniformConfig { @@ -17,14 +18,26 @@ export interface UniformConfig { JingleNextMixEffect?: SwitcherMixEffectLLayer /** Optional layer to preview servers on Aux */ NextServerAux?: SwitcherAuxLLayer - /** Optional layer to output Program on */ - ProgramAux?: SwitcherAuxLLayer /** Optional mix-minus layer */ MixMinusAux?: SwitcherAuxLLayer } - // @todo: implement this - // SwitcherMixEffects: { - // TriCasterClean: SpecialInput - // AtemClean: SpecialInput - // } + /** + * MixEffects grouped by their roles (note Program !== Primary) + * Relevant mostly for baseline + */ + MixEffects: { + Program: MixEffect + Clean: MixEffect + } + /** + * Auxes on which certain inputs appear + * It allows associating TriCaster's MEs to mix outputs in order to route MEs to matrix outs + */ + SpecialInputAuxLLayers: Partial> +} + +export interface MixEffect { + input: SpecialInput + mixEffectLayer: SwitcherMixEffectLLayer + auxLayer?: SwitcherAuxLLayer } diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 51cc0b78..20dc5da6 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -16,6 +16,8 @@ import { } from './types' import { VideoSwitcherImpl } from './VideoSwitcher' +const MAX_REGULAR_INPUT_NUMBER = 1000 // everything >= is assumed a special input + const SPECIAL_INPUT_MAP: Record = { [SpecialInput.ME1_PROGRAM]: 'v1', [SpecialInput.ME2_PROGRAM]: 'v2', @@ -42,8 +44,11 @@ export class TriCaster extends VideoSwitcherImpl { public isMixEffect = TSR.isTimelineObjTriCasterME public isDsk = TSR.isTimelineObjTriCasterDSK - public isAux = TSR.isTimelineObjTriCasterMixOutput public isVideoSwitcherTimelineObject = TSR.isTimelineObjTriCaster + public isAux = ( + timelineObject: TSR.TSRTimelineObj + ): timelineObject is TSR.TimelineObjTriCasterMixOutput | TSR.TimelineObjTriCasterMatrixOutput => + TSR.isTimelineObjTriCasterMixOutput(timelineObject) || TSR.isTimelineObjTriCasterMatrixOutput(timelineObject) public getMixEffectTimelineObject(props: MixEffectProps): TSR.TimelineObjTriCasterME { const { content } = props @@ -124,7 +129,25 @@ export class TriCaster extends VideoSwitcherImpl { } } - public getAuxTimelineObject(props: AuxProps): TSR.TimelineObjTriCasterMixOutput { + public getAuxTimelineObject( + props: AuxProps + ): TSR.TimelineObjTriCasterMixOutput | TSR.TimelineObjTriCasterMatrixOutput { + const layerName = this.prefixLayer(props.layer) + const mapping = this.core.getStudioMappings()[layerName] + if (!mapping || mapping.device !== TSR.DeviceType.TRICASTER) { + this.core.logWarning(`Unable to find TriCaster mapping for layer ${layerName}`) + } else if (((mapping as unknown) as TSR.MappingTriCaster).mappingType === TSR.MappingTriCasterType.MATRIX_OUTPUT) { + if (props.content.input) { + return { + ...this.getBaseProperties(props, props.layer), + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.MATRIX_OUTPUT, + source: this.getInputNameForMatrix(props.content.input) + } + } + } + } return { ...this.getBaseProperties(props, props.layer), content: { @@ -177,10 +200,14 @@ export class TriCaster extends VideoSwitcherImpl { return { ...TIMELINE_OBJECT_DEFAULTS, ..._.omit(props, 'content'), - layer: TRICASTER_LAYER_PREFIX + layer + layer: this.prefixLayer(layer) } } + private prefixLayer(layer: string): string { + return TRICASTER_LAYER_PREFIX + layer + } + private getKeyers(keyers: Keyer[]): Record | undefined { if (!keyers?.length) { return @@ -204,12 +231,30 @@ export class TriCaster extends VideoSwitcherImpl { if (typeof input === 'undefined') { return undefined } - if (input < 1000) { + if (input < MAX_REGULAR_INPUT_NUMBER) { return `input${input as number}` } - const specialInput = SPECIAL_INPUT_MAP[input] - if (specialInput) { - return specialInput + return SPECIAL_INPUT_MAP[input] ?? 'black' + } + + private getInputNameForMatrix(input: number | SpecialInput): TSR.TriCasterSourceName | TSR.TriCasterMixOutputName { + if (input < MAX_REGULAR_INPUT_NUMBER) { + return `input${input as number}` + } + const auxLayer = this.uniformConfig.SpecialInputAuxLLayers[input] + if (!auxLayer) { + this.core.logWarning(`Unable to find TriCaster AUX layer for input ${input}`) + return 'black' + } + const layerName = this.prefixLayer(auxLayer) + const mapping = this.core.getStudioMappings()[layerName] + + if (!mapping || mapping.device !== TSR.DeviceType.TRICASTER) { + this.core.logWarning(`Unable to find TriCaster mapping for layer ${layerName}`) + return 'black' + } + if (((mapping as unknown) as TSR.MappingTriCaster).mappingType === TSR.MappingTriCasterType.MIX_OUTPUT) { + return ((mapping as unknown) as TSR.MappingTriCasterMixOutput).name } return 'black' } diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index febb7491..21c1d852 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -1,18 +1,18 @@ -import { TSR } from 'blueprints-integration' -import { literal } from 'tv2-common' +import { BlueprintMapping, LookaheadMode, TSR } from 'blueprints-integration' +import { literal, TRICASTER_DEVICE_ID } from 'tv2-common' import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' -import { makeMockGalleryContext } from '../../../__mocks__/context' -import { TV2StudioConfigBase } from '../../../tv2-common/blueprintConfig' -import { AuxProps, DskProps, MixEffectProps, SwitcherType, TransitionStyle } from '../types' +import { makeMockGalleryContext, MockConfigOverrides } from '../../../__mocks__/context' +import { AuxProps, DskProps, MixEffectProps, SpecialInput, SwitcherType, TransitionStyle } from '../types' import { VideoSwitcherImpl } from '../VideoSwitcher' const DURATION_FRAMES: number = 50 const DURATION_SECONDS: number = DURATION_FRAMES / 25 -function setupTriCaster(studioConfigOverrides?: Partial) { +function setupTriCaster(mockConfigOverrides?: MockConfigOverrides) { // @todo: is this the correct way? const context = makeMockGalleryContext({ - studioConfig: { SwitcherType: SwitcherType.TRICASTER, ...studioConfigOverrides } + ...mockConfigOverrides, + studioConfig: { SwitcherType: SwitcherType.TRICASTER, ...mockConfigOverrides?.studioConfig } }) return VideoSwitcherImpl.getVideoSwitcher(context.core, context.config, context.uniformConfig) } @@ -147,10 +147,12 @@ describe('TriCaster', () => { test('supports WIPE for GFX', () => { const wipeRate = 22 const triCaster = setupTriCaster({ - HTMLGraphics: { - GraphicURL: 'donotcare', - TransitionSettings: { wipeRate, borderSoftness: 20, loopOutTransitionDuration: 15 }, - KeepAliveDuration: 120 + studioConfig: { + HTMLGraphics: { + GraphicURL: 'donotcare', + TransitionSettings: { wipeRate, borderSoftness: 20, loopOutTransitionDuration: 15 }, + KeepAliveDuration: 120 + } } }) const timelineObject = triCaster.getMixEffectTimelineObject({ @@ -283,8 +285,18 @@ describe('TriCaster', () => { }) }) - test('sets aux source', () => { - const triCaster = setupTriCaster() + test('sets Mix Output when layer mapping is MIX_OUTPUT', () => { + const triCaster = setupTriCaster({ + mappingDefaults: { + [prefixLayer(DEFAULT_AUX.layer)]: literal({ + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix2' + }) + } + }) const timelineObject = triCaster.getAuxTimelineObject(DEFAULT_AUX) @@ -296,6 +308,72 @@ describe('TriCaster', () => { } }) }) + + test('sets Matrix Output when layer mapping is MATRIX_OUTPUT', () => { + const triCaster = setupTriCaster({ + mappingDefaults: { + [prefixLayer(DEFAULT_AUX.layer)]: literal({ + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MATRIX_OUTPUT, + name: 'out2' + }) + } + }) + + const timelineObject = triCaster.getAuxTimelineObject(DEFAULT_AUX) + + expect(timelineObject).toMatchObject({ + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.MATRIX_OUTPUT, + source: 'input5' + } + }) + }) + + test('resolves Special Input for Matrix Output', () => { + const triCaster = setupTriCaster({ + mappingDefaults: { + [prefixLayer(SwitcherAuxLLayer.AuxClean)]: literal({ + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix5' + }), + [prefixLayer(SwitcherAuxLLayer.AuxVideoMixMinus)]: literal({ + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MATRIX_OUTPUT, + name: 'out2' + }) + }, + uniformConfig: { + SpecialInputAuxLLayers: { + [SpecialInput.ME1_PROGRAM]: SwitcherAuxLLayer.AuxProgram, + [SpecialInput.ME3_PROGRAM]: SwitcherAuxLLayer.AuxClean + } + } + }) + + const timelineObject = triCaster.getAuxTimelineObject({ + layer: SwitcherAuxLLayer.AuxVideoMixMinus, + content: { + input: SpecialInput.ME3_PROGRAM + } + }) + + expect(timelineObject).toMatchObject({ + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.MATRIX_OUTPUT, + source: 'mix5' + } + }) + }) }) describe('DSK', () => { diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index ece607a4..498c5c07 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -23,7 +23,7 @@ import { ActionRecallLastLive, ActionSelectDVELayout, CasparPlayerClipLoadingLoop, - CreateDSKBaseline, + createDskBaseline, CreateDSKBaselineAdlibs, CreateGraphicBaseline, CreateLYDBaseline, @@ -834,39 +834,8 @@ function getBaseline( timelineObjects: [ ...CreateGraphicBaseline(context.config), // Default timeline - videoSwitcher.getMixEffectTimelineObject({ - enable: { while: '1' }, - layer: SwitcherMixEffectLLayer.Program, - content: { - input: context.config.studio.SwitcherSource.Default, - transition: TransitionStyle.CUT - } - }), - videoSwitcher.getMixEffectTimelineObject({ - enable: { while: '1' }, - layer: SwitcherMixEffectLLayer.Clean, - content: { - input: context.config.studio.SwitcherSource.Default, - transition: TransitionStyle.CUT - } - }), + ...getMixEffectBaseline(context, videoSwitcher), - // route default outputs - videoSwitcher.getAuxTimelineObject({ - enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxProgram, - content: { - input: SpecialInput.ME1_PROGRAM - } - }), - videoSwitcher.getAuxTimelineObject({ - id: '', - enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxClean, - content: { - input: SpecialInput.ME4_PROGRAM - } - }), videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, layer: SwitcherAuxLLayer.AuxLookahead, @@ -905,7 +874,7 @@ function getBaseline( }), // keyers - ...CreateDSKBaseline(context.config, videoSwitcher), + ...createDskBaseline(context.config, videoSwitcher), // ties the DSK for jingles to ME4 USK1 to have effects on CLEAN (ME4) videoSwitcher.getMixEffectTimelineObject({ @@ -1126,3 +1095,30 @@ function getBaseline( ] } } + +function getMixEffectBaseline( + context: ExtendedShowStyleContext, + videoSwitcher: VideoSwitcher +): TSR.TSRTimelineObj[] { + return Object.values(context.uniformConfig.MixEffects).flatMap(mixEffect => + _.compact([ + videoSwitcher.getMixEffectTimelineObject({ + enable: { while: '1' }, + layer: SwitcherMixEffectLLayer.Program, + content: { + input: context.config.studio.SwitcherSource.Default, + transition: TransitionStyle.CUT + } + }), + mixEffect.auxLayer + ? videoSwitcher.getAuxTimelineObject({ + enable: { while: '1' }, + layer: mixEffect.auxLayer, + content: { + input: mixEffect.input + } + }) + : undefined + ]) + ) +} diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index 237acb48..bfda99b5 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -154,7 +154,7 @@ describe('Graphics', () => { expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] - expect(timeline).toHaveLength(7) + expect(timeline).toHaveLength(8) // @todo: this depends on unrelated configuration const vizObj = timeline.find( t => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT @@ -326,7 +326,7 @@ describe('Graphics', () => { expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] - expect(timeline).toHaveLength(7) + expect(timeline).toHaveLength(8) const vizObj = timeline.find( t => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index 3962537d..4c7e8f9b 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -581,7 +581,7 @@ export const MAPPINGS_GRAPHICS: BlueprintMappings = { }) } -export const MAPPINGS_ATEM: Record = prefixLayers(ATEM_LAYER_PREFIX, { +export const MAPPINGS_ATEM = prefixLayers(ATEM_LAYER_PREFIX, { [SwitcherMixEffectLLayer.Program]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, @@ -676,104 +676,115 @@ export const MAPPINGS_ATEM: Record = ...getAtemDskMappings(ATEMModel.CONSTELLATION_8K_UHD_MODE) }) -export const MAPPINGS_TRICASTER: Record = prefixLayers( - TRICASTER_LAYER_PREFIX, - { - [SwitcherMixEffectLLayer.Program]: { - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingTriCasterType.ME, - name: TRICASTER_PROGRAM_ME - }, - [SwitcherMixEffectLLayer.Clean]: { - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingTriCasterType.ME, - name: TRICASTER_CLEAN_ME - }, - [SwitcherMixEffectLLayer.CleanUSKEffect]: { - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingTriCasterType.ME, - name: TRICASTER_CLEAN_ME - }, - [SwitcherAuxLLayer.AuxProgram]: { - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, - name: 'mix1' - }, - [SwitcherAuxLLayer.AuxClean]: { - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, - name: 'mix2' - }, - [SwitcherAuxLLayer.AuxAR]: { - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, - name: 'mix4' - }, - [SwitcherAuxLLayer.AuxVizOvlIn1]: { - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, - name: 'mix5' - }, - [SwitcherAuxLLayer.AuxVideoMixMinus]: { - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, - name: 'mix7' - }, - [SwitcherAuxLLayer.AuxLookahead]: { - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, - name: 'mix8' - }, - [SwitcherAuxLLayer.AuxDve]: { - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, - name: 'mix8' // @todo: do we have too few auxes?! - }, - [SwitcherDveLLayer.Dve]: { - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.NONE, - mappingType: TSR.MappingTriCasterType.ME, - name: TRICASTER_DVE_ME - }, - [SwitcherDveLLayer.DveBoxes]: { - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingTriCasterType.ME, - name: TRICASTER_DVE_ME - }, - ...getTriCasterDskMappings() - // @todo: are we using media players in the TriCaster? - // [SwitcherMediaPlayerLLayer.Mp1]: { - // device: TSR.DeviceType.TRICASTER, - // deviceId: TRICASTER_DEVICE_ID, - // lookahead: LookaheadMode.NONE, - // mappingType: TSR.MappingAtemType.MediaPlayer, - // index: 0 - // } - } -) +export const MAPPINGS_TRICASTER = prefixLayers(TRICASTER_LAYER_PREFIX, { + [SwitcherMixEffectLLayer.Program]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.ME, + name: TRICASTER_PROGRAM_ME + }, + [SwitcherMixEffectLLayer.Clean]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.ME, + name: TRICASTER_CLEAN_ME + }, + [SwitcherMixEffectLLayer.CleanUSKEffect]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.ME, + name: TRICASTER_CLEAN_ME + }, + [SwitcherAuxLLayer.AuxProgram]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix1' + }, + [SwitcherAuxLLayer.AuxClean]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix2' + }, + [SwitcherAuxLLayer.AuxWall]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix3' + }, + [SwitcherAuxLLayer.AuxAR]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix4' + }, + [SwitcherAuxLLayer.AuxVizOvlIn1]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix5' + }, + [SwitcherAuxLLayer.AuxLookahead]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix6' + }, + [SwitcherAuxLLayer.AuxDve]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix7' + }, + // [SwitcherAuxLLayer.AuxMixEffect3]: { + // device: TSR.DeviceType.TRICASTER, + // deviceId: TRICASTER_DEVICE_ID, + // lookahead: LookaheadMode.WHEN_CLEAR, + // mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + // name: 'mix8' + // }, + [SwitcherAuxLLayer.AuxVideoMixMinus]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MATRIX_OUTPUT, + name: 'out1' + }, + [SwitcherDveLLayer.Dve]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingTriCasterType.ME, + name: TRICASTER_DVE_ME + }, + [SwitcherDveLLayer.DveBoxes]: { + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.ME, + name: TRICASTER_DVE_ME + }, + ...getTriCasterDskMappings() + // @todo: are we using media players in the TriCaster? + // [SwitcherMediaPlayerLLayer.Mp1]: { + // device: TSR.DeviceType.TRICASTER, + // deviceId: TRICASTER_DEVICE_ID, + // lookahead: LookaheadMode.NONE, + // mappingType: TSR.MappingAtemType.MediaPlayer, + // index: 0 + // } +}) export const MAPPINGS_TELEMETRICS: BlueprintMappings = { [RobotCameraLayer.TELEMETRICS]: literal({ diff --git a/src/tv2_afvd_studio/uniformConfig.ts b/src/tv2_afvd_studio/uniformConfig.ts index 6c2b4657..73b3e200 100644 --- a/src/tv2_afvd_studio/uniformConfig.ts +++ b/src/tv2_afvd_studio/uniformConfig.ts @@ -1,13 +1,34 @@ -import { UniformConfig } from 'tv2-common' +import { SpecialInput, UniformConfig } from 'tv2-common' import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' +const MIX_EFFECTS: UniformConfig['MixEffects'] = { + Program: { + input: SpecialInput.ME1_PROGRAM, + mixEffectLayer: SwitcherMixEffectLLayer.Program, + auxLayer: SwitcherAuxLLayer.AuxProgram + }, + Clean: { + input: SpecialInput.ME4_PROGRAM, + mixEffectLayer: SwitcherMixEffectLLayer.Clean, + auxLayer: SwitcherAuxLLayer.AuxClean + } +} + export const GALLERY_UNIFORM_CONFIG: UniformConfig = { SwitcherLLayers: { PrimaryMixEffect: SwitcherMixEffectLLayer.Program, PrimaryMixEffectClone: SwitcherMixEffectLLayer.Clean, JingleUskMixEffect: SwitcherMixEffectLLayer.CleanUSKEffect, - ProgramAux: SwitcherAuxLLayer.AuxProgram, NextAux: SwitcherAuxLLayer.AuxLookahead, MixMinusAux: SwitcherAuxLLayer.AuxVideoMixMinus + }, + MixEffects: MIX_EFFECTS, + SpecialInputAuxLLayers: { + ...Object.fromEntries( + Object.values(MIX_EFFECTS) + .filter(mixEffect => mixEffect.auxLayer) + .map(mixEffect => [mixEffect.input, mixEffect.auxLayer]) + ), + [SpecialInput.DVE]: SwitcherAuxLLayer.AuxDve } } diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 49533b46..853ebffc 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -24,7 +24,7 @@ import { ActionRecallLastLive, ActionSelectDVELayout, CasparPlayerClipLoadingLoop, - CreateDSKBaseline, + createDskBaseline, CreateDSKBaselineAdlibs, CreateGraphicBaseline, CreateLYDBaseline, @@ -627,7 +627,7 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche }), // keyers - ...CreateDSKBaseline(config, videoSwitcher), + ...createDskBaseline(config, videoSwitcher), literal({ id: '', diff --git a/src/tv2_offtube_studio/uniformConfig.ts b/src/tv2_offtube_studio/uniformConfig.ts index 16dcafd7..4fc962c5 100644 --- a/src/tv2_offtube_studio/uniformConfig.ts +++ b/src/tv2_offtube_studio/uniformConfig.ts @@ -1,11 +1,28 @@ -import { UniformConfig } from 'tv2-common' +import { SpecialInput, UniformConfig } from 'tv2-common' import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' +const MIX_EFFECTS: UniformConfig['MixEffects'] = { + Program: { input: SpecialInput.ME1_PROGRAM, mixEffectLayer: SwitcherMixEffectLLayer.Program }, + Clean: { + input: SpecialInput.ME4_PROGRAM, + mixEffectLayer: SwitcherMixEffectLLayer.Clean, + auxLayer: SwitcherAuxLLayer.AuxClean + } +} + export const QBOX_UNIFORM_CONFIG: UniformConfig = { SwitcherLLayers: { PrimaryMixEffect: SwitcherMixEffectLLayer.Clean, NextServerAux: SwitcherAuxLLayer.AuxServerLookahead, NextPreviewMixEffect: SwitcherMixEffectLLayer.Next, JingleNextMixEffect: SwitcherMixEffectLLayer.NextJingle + }, + MixEffects: MIX_EFFECTS, + SpecialInputAuxLLayers: { + ...Object.fromEntries( + Object.values(MIX_EFFECTS) + .filter(mixEffect => mixEffect.auxLayer) + .map(mixEffect => [mixEffect.input, mixEffect.auxLayer]) + ) } } From 9ab633b84da7c0f1d6c0fd92acfb4ab58b12f9f1 Mon Sep 17 00:00:00 2001 From: ianshade Date: Mon, 20 Feb 2023 21:55:19 +0100 Subject: [PATCH 21/86] wip: SOF-1260 fix telefon piece and start refactoring cue evaluation --- src/tv2-common/cues/ekstern.ts | 86 +++++------ src/tv2-common/evaluateCues.ts | 80 +++++----- .../helpers/graphics/internal/create.ts | 26 ++-- .../helpers/graphics/pilot/create.ts | 28 ++-- .../pieces/__tests__/grafikViz.spec.ts | 145 ++++-------------- .../helpers/pieces/__tests__/telefon.spec.ts | 17 +- .../helpers/pieces/ekstern.ts | 13 +- .../helpers/pieces/graphic.ts | 25 +-- .../helpers/pieces/graphicPilot.ts | 17 +- .../helpers/pieces/routing.ts | 22 ++- .../helpers/pieces/telefon.ts | 43 +++--- .../__tests__/graphics.spec.ts | 4 +- .../cues/OfftubeEkstern.ts | 15 +- .../cues/OfftubeGraphics.ts | 12 +- 14 files changed, 217 insertions(+), 316 deletions(-) diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index 98ac0dc1..1f48e0c0 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -1,7 +1,5 @@ import { - IBlueprintAdLibPiece, IBlueprintPart, - IBlueprintPiece, PieceLifespan, RemoteContent, TimelineObjectCoreExt, @@ -9,10 +7,10 @@ import { } from 'blueprints-integration' import { CueDefinitionEkstern, + EvaluateCueResult, ExtendedShowStyleContext, literal, PartDefinition, - PieceMetaData, TransitionStyle, TV2BlueprintConfigBase, TV2StudioConfigBase @@ -34,25 +32,24 @@ export function EvaluateEksternBase< >( context: ExtendedShowStyleContext, part: IBlueprintPart, - pieces: Array>, - adlibPieces: Array>, partId: string, parsedCue: CueDefinitionEkstern, partDefinition: PartDefinition, layersEkstern: EksternLayers, adlib?: boolean, rank?: number -) { +): EvaluateCueResult { + const result = new EvaluateCueResult() const sourceInfoEkstern = findSourceInfo(context.config.sources, parsedCue.sourceDefinition) if (parsedCue.sourceDefinition.sourceType !== SourceType.REMOTE || sourceInfoEkstern === undefined) { context.core.notifyUserWarning(`EKSTERN source is not valid: "${parsedCue.sourceDefinition.raw}"`) part.invalid = true - return + return result } const switcherInput = sourceInfoEkstern.port if (adlib) { - adlibPieces.push({ + result.adlibPieces.push({ _rank: rank || 0, externalId: partId, name: parsedCue.sourceDefinition.name, @@ -86,42 +83,43 @@ export function EvaluateEksternBase< ]) }) }) - } else { - pieces.push({ - externalId: partId, - name: parsedCue.sourceDefinition.name, - enable: { - start: 0 - }, - outputLayerId: SharedOutputLayers.PGM, - sourceLayerId: layersEkstern.SourceLayer.PgmLive, - lifespan: PieceLifespan.WithinPart, - toBeQueued: true, - metaData: { - sisyfosPersistMetaData: { - sisyfosLayers: sourceInfoEkstern.sisyfosLayers ?? [], - wantsToPersistAudio: sourceInfoEkstern.wantsToPersistAudio, - acceptPersistAudio: sourceInfoEkstern.acceptPersistAudio - } - }, - tags: [GetTagForLive(parsedCue.sourceDefinition)], - content: literal>({ - studioLabel: '', - switcherInput, - timelineObjects: literal([ - ...context.videoSwitcher.getOnAirTimelineObjects({ - priority: 1, - content: { - input: switcherInput, - transition: partDefinition.transition?.style ?? TransitionStyle.CUT, - transitionDuration: partDefinition.transition?.duration - }, - mixMinusInput: null // @todo: should it be here? - }), + return result + } + result.pieces.push({ + externalId: partId, + name: parsedCue.sourceDefinition.name, + enable: { + start: 0 + }, + outputLayerId: SharedOutputLayers.PGM, + sourceLayerId: layersEkstern.SourceLayer.PgmLive, + lifespan: PieceLifespan.WithinPart, + toBeQueued: true, + metaData: { + sisyfosPersistMetaData: { + sisyfosLayers: sourceInfoEkstern.sisyfosLayers ?? [], + wantsToPersistAudio: sourceInfoEkstern.wantsToPersistAudio, + acceptPersistAudio: sourceInfoEkstern.acceptPersistAudio + } + }, + tags: [GetTagForLive(parsedCue.sourceDefinition)], + content: literal>({ + studioLabel: '', + switcherInput, + timelineObjects: literal([ + ...context.videoSwitcher.getOnAirTimelineObjects({ + priority: 1, + content: { + input: switcherInput, + transition: partDefinition.transition?.style ?? TransitionStyle.CUT, + transitionDuration: partDefinition.transition?.duration + }, + mixMinusInput: null // @todo: should it be here? + }), - ...GetSisyfosTimelineObjForRemote(context.config, sourceInfoEkstern) - ]) - }) + ...GetSisyfosTimelineObjForRemote(context.config, sourceInfoEkstern) + ]) }) - } + }) + return result } diff --git a/src/tv2-common/evaluateCues.ts b/src/tv2-common/evaluateCues.ts index 7611b161..3c58d97d 100644 --- a/src/tv2-common/evaluateCues.ts +++ b/src/tv2-common/evaluateCues.ts @@ -38,17 +38,27 @@ import { export interface Adlib { rank: number } + +export class EvaluateCueResult { + public readonly pieces: IBlueprintPiece[] = [] + public readonly adlibPieces: IBlueprintAdLibPiece[] = [] + public readonly actions: IBlueprintActionManifest[] = [] + + public push(source: EvaluateCueResult): EvaluateCueResult { + this.pieces.push(...source.pieces) + this.adlibPieces.push(...source.adlibPieces) + this.actions.push(...source.actions) + return this + } +} export interface EvaluateCuesShowstyleOptions { EvaluateCueGraphic?: ( context: ExtendedShowStyleContext, - pieces: IBlueprintPiece[], - adlibPieces: IBlueprintAdLibPiece[], - actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionGraphic, partDefinition: PartDefinition, adlib?: Adlib - ) => void + ) => EvaluateCueResult EvaluateCueBackgroundLoop?: ( context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], @@ -71,22 +81,18 @@ export interface EvaluateCuesShowstyleOptions { ) => void EvaluateCueRouting?: ( context: ExtendedShowStyleContext, - pieces: IBlueprintPiece[], partId: string, parsedCue: CueDefinitionRouting - ) => void + ) => EvaluateCueResult EvaluateCueEkstern?: ( context: ExtendedShowStyleContext, part: IBlueprintPart, - pieces: IBlueprintPiece[], - adlibPieces: IBlueprintAdLibPiece[], - actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionEkstern, partDefinition: PartDefinition, adlib?: boolean, rank?: number - ) => void + ) => EvaluateCueResult EvaluateCueDVE?: ( context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], @@ -106,14 +112,11 @@ export interface EvaluateCuesShowstyleOptions { ) => Promise EvaluateCueTelefon?: ( context: ExtendedShowStyleContext, - pieces: IBlueprintPiece[], - adlibPieces: IBlueprintAdLibPiece[], - actions: IBlueprintActionManifest[], partId: string, partDefinition: PartDefinition, parsedCue: CueDefinitionTelefon, adlib?: Adlib - ) => void + ) => EvaluateCueResult EvaluateCueJingle?: ( context: ExtendedShowStyleContext, pieces: IBlueprintPiece[], @@ -189,6 +192,7 @@ export async function EvaluateCuesBase( options: EvaluateCuesOptions ) { let adLibRank = 0 + const result = new EvaluateCueResult() for (const cue of cues) { if (cue && !SkipCue(cue, options.selectedCueTypes, options.excludeAdlibs, options.adlibsOnly)) { @@ -207,31 +211,23 @@ export async function EvaluateCuesBase( context.core.notifyUserWarning(`Cannot create overlay graphic with FULL`) break } - showStyleOptions.EvaluateCueGraphic( - context, - pieces, - adLibPieces, - actions, - partDefinition.externalId, - cue, - partDefinition, - adlib + result.push( + showStyleOptions.EvaluateCueGraphic(context, partDefinition.externalId, cue, partDefinition, adlib) ) } break case CueType.Ekstern: if (showStyleOptions.EvaluateCueEkstern) { - showStyleOptions.EvaluateCueEkstern( - context, - part, - pieces, - adLibPieces, - actions, - partDefinition.externalId, - cue, - partDefinition, - shouldAdlib, - adLibRank + result.push( + showStyleOptions.EvaluateCueEkstern( + context, + part, + partDefinition.externalId, + cue, + partDefinition, + shouldAdlib, + adLibRank + ) ) } break @@ -258,15 +254,8 @@ export async function EvaluateCuesBase( break case CueType.Telefon: if (showStyleOptions.EvaluateCueTelefon) { - showStyleOptions.EvaluateCueTelefon( - context, - pieces, - adLibPieces, - actions, - partDefinition.externalId, - partDefinition, - cue, - adlib + result.push( + showStyleOptions.EvaluateCueTelefon(context, partDefinition.externalId, partDefinition, cue, adlib) ) } break @@ -341,7 +330,7 @@ export async function EvaluateCuesBase( break case CueType.Routing: if (showStyleOptions.EvaluateCueRouting) { - showStyleOptions.EvaluateCueRouting(context, pieces, partDefinition.externalId, cue) + result.push(showStyleOptions.EvaluateCueRouting(context, partDefinition.externalId, cue)) } break case CueType.PgmClean: @@ -380,6 +369,9 @@ export async function EvaluateCuesBase( } } + pieces.push(...result.pieces) + adLibPieces.push(...result.adlibPieces) + actions.push(...result.actions) ;[...pieces, ...adLibPieces].forEach(piece => { if (piece.content && piece.content.timelineObjects) { piece.content.timelineObjects.forEach((obj: TSR.TSRTimelineObj) => { diff --git a/src/tv2-common/helpers/graphics/internal/create.ts b/src/tv2-common/helpers/graphics/internal/create.ts index 74358aed..f23de9cc 100644 --- a/src/tv2-common/helpers/graphics/internal/create.ts +++ b/src/tv2-common/helpers/graphics/internal/create.ts @@ -1,7 +1,7 @@ -import { IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' import { Adlib, CueDefinitionGraphic, + EvaluateCueResult, ExtendedShowStyleContext, GraphicInternal, InternalGraphic, @@ -11,26 +11,28 @@ import { export function CreateInternalGraphic( context: ExtendedShowStyleContext, - pieces: IBlueprintPiece[], - adlibPieces: IBlueprintAdLibPiece[], partId: string, parsedCue: CueDefinitionGraphic, partDefinition: PartDefinition, adlib?: Adlib -) { +): EvaluateCueResult { + const result = new EvaluateCueResult() const internalGraphic = InternalGraphic.createInternalGraphicGenerator({ context, parsedCue, partId, partDefinition }) if (!internalGraphic.templateName || !internalGraphic.templateName.length) { context.core.notifyUserWarning(`No valid template found for ${parsedCue.graphic.template}`) - return + return result } - if (adlib) { - if (IsTargetingOVL(parsedCue.target)) { - adlibPieces.push(internalGraphic.createCommentatorAdlib()) - } - adlibPieces.push(internalGraphic.createAdlib()) - } else { - pieces.push(internalGraphic.createPiece()) + if (!adlib) { + result.pieces.push(internalGraphic.createPiece()) + return result } + + if (IsTargetingOVL(parsedCue.target)) { + result.adlibPieces.push(internalGraphic.createCommentatorAdlib()) + } + result.adlibPieces.push(internalGraphic.createAdlib()) + + return result } diff --git a/src/tv2-common/helpers/graphics/pilot/create.ts b/src/tv2-common/helpers/graphics/pilot/create.ts index 8e384d4f..5cb4a61d 100644 --- a/src/tv2-common/helpers/graphics/pilot/create.ts +++ b/src/tv2-common/helpers/graphics/pilot/create.ts @@ -1,28 +1,30 @@ -import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' -import { IsTargetingFull, IsTargetingOVL, PilotGraphicGenerator, PilotGraphicProps } from 'tv2-common' +import { + EvaluateCueResult, + IsTargetingFull, + IsTargetingOVL, + PilotGraphicGenerator, + PilotGraphicProps +} from 'tv2-common' -export function CreatePilotGraphic( - pieces: IBlueprintPiece[], - adlibPieces: IBlueprintAdLibPiece[], - actions: IBlueprintActionManifest[], - pilotGraphicProps: PilotGraphicProps -) { +export function CreatePilotGraphic(pilotGraphicProps: PilotGraphicProps): EvaluateCueResult { + const result = new EvaluateCueResult() const { context, adlib, parsedCue } = pilotGraphicProps if (parsedCue.graphic.vcpid < 0) { context.core.notifyUserWarning('No valid VCPID provided') - return + return result } const generator = PilotGraphicGenerator.createPilotGraphicGenerator(pilotGraphicProps) if (IsTargetingOVL(parsedCue.target) && adlib) { - adlibPieces.push(generator.createAdlibPiece()) + result.adlibPieces.push(generator.createAdlibPiece()) } else { - pieces.push(generator.createPiece()) + result.pieces.push(generator.createPiece()) } if (IsTargetingFull(parsedCue.target)) { - actions.push(generator.createFullPilotAdLibAction()) - pieces.push(generator.createFullDataStore()) + result.actions.push(generator.createFullPilotAdLibAction()) + result.pieces.push(generator.createFullDataStore()) } + return result } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts index d4f6a0a0..0dc4bdf9 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -1,6 +1,5 @@ import { GraphicsContent, - IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece, PieceLifespan, @@ -101,22 +100,16 @@ describe('grafik piece', () => { }, iNewsCommand: 'kg' } - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateCueGraphic( + const result = EvaluateCueGraphic( makeMockGalleryContext(), - pieces, - adLibPieces, - actions, partId, cue, dummyPart, cue.adlib ? { rank: 0 } : undefined ) - expect(pieces).toEqual([ + expect(result.pieces).toEqual([ literal>({ externalId: partId, name: 'bund - Odense\n - Copenhagen', @@ -175,22 +168,16 @@ describe('grafik piece', () => { adlib: true, iNewsCommand: 'kg' } - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateCueGraphic( + const result = EvaluateCueGraphic( makeMockGalleryContext(), - pieces, - adLibPieces, - actions, partId, cue, dummyPart, cue.adlib ? { rank: 0 } : undefined ) - expect(adLibPieces).toEqual([ + expect(result.adlibPieces).toEqual([ literal({ _rank: 0, externalId: partId, @@ -287,22 +274,16 @@ describe('grafik piece', () => { adlib: true, iNewsCommand: 'kg' } - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateCueGraphic( + const result = EvaluateCueGraphic( makeMockGalleryContext({ studioConfig: { PreventOverlayWithFull: false } }), - pieces, - adLibPieces, - actions, partId, cue, dummyPart, cue.adlib ? { rank: 0 } : undefined ) - expect(adLibPieces).toEqual([ + expect(result.adlibPieces).toEqual([ literal({ _rank: 0, externalId: partId, @@ -401,22 +382,16 @@ describe('grafik piece', () => { }, iNewsCommand: 'kg' } - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateCueGraphic( + const result = EvaluateCueGraphic( makeMockGalleryContext(), - pieces, - adLibPieces, - actions, partId, cue, dummyPart, cue.adlib ? { rank: 0 } : undefined ) - expect(pieces).toEqual([ + expect(result.pieces).toEqual([ literal>({ externalId: partId, name: 'bund - Odense\n - Copenhagen', @@ -464,30 +439,24 @@ describe('grafik piece', () => { test('kg bund infinite (B) has piece and object timing', () => { const cue = makeTestBundCue('B') - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateCueGraphic( + const result = EvaluateCueGraphic( makeMockGalleryContext(), - pieces, - adLibPieces, - actions, partId, cue, dummyPart, cue.adlib ? { rank: 0 } : undefined ) - expect(pieces.length).toBe(1) - expect(pieces[0]).toMatchObject({ + expect(result.pieces.length).toBe(1) + expect(result.pieces[0]).toMatchObject({ enable: { start: 10000 }, lifespan: PieceLifespan.WithinPart }) expect( - pieces[0].content.timelineObjects.find(tlObject => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) + result.pieces[0].content.timelineObjects.find(tlObject => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) ).toMatchObject({ enable: { while: `!.full` @@ -497,30 +466,24 @@ describe('grafik piece', () => { test('kg bund infinite (S) has piece and object timing', () => { const cue = makeTestBundCue('S') - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateCueGraphic( + const result = EvaluateCueGraphic( makeMockGalleryContext(), - pieces, - adLibPieces, - actions, partId, cue, dummyPart, cue.adlib ? { rank: 0 } : undefined ) - expect(pieces.length).toBe(1) - expect(pieces[0]).toMatchObject({ + expect(result.pieces.length).toBe(1) + expect(result.pieces[0]).toMatchObject({ enable: { start: 10000 }, lifespan: PieceLifespan.OutOnSegmentEnd }) expect( - pieces[0].content.timelineObjects.find(tlObject => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) + result.pieces[0].content.timelineObjects.find(tlObject => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) ).toMatchObject({ enable: { while: `!.full` @@ -530,31 +493,25 @@ describe('grafik piece', () => { test('kg bund infinite (O)', () => { const cue = makeTestBundCue('O') - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateCueGraphic( + const result = EvaluateCueGraphic( makeMockGalleryContext(), - pieces, - adLibPieces, - actions, partId, cue, dummyPart, cue.adlib ? { rank: 0 } : undefined ) - expect(pieces.length).toBe(1) - expect(pieces[0]).toMatchObject({ + expect(result.pieces.length).toBe(1) + expect(result.pieces[0]).toMatchObject({ enable: { start: 10000 }, lifespan: PieceLifespan.OutOnShowStyleEnd }) expect( - pieces[0].content.timelineObjects.find(tlObject => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) + result.pieces[0].content.timelineObjects.find(tlObject => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) ).toMatchObject({ enable: { while: `!.full` @@ -577,22 +534,16 @@ describe('grafik piece', () => { }, iNewsCommand: '#kg' }) - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateCueGraphic( + const result = EvaluateCueGraphic( makeMockGalleryContext(), - pieces, - adLibPieces, - actions, partId, cue, dummyPart, cue.adlib ? { rank: 0 } : undefined ) - expect(pieces).toEqual([ + expect(result.pieces).toEqual([ literal>({ externalId: partId, name: 'direkte - KØBENHAVN', @@ -652,22 +603,16 @@ describe('grafik piece', () => { }, iNewsCommand: '#kg' }) - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateCueGraphic( + const result = EvaluateCueGraphic( makeMockGalleryContext(), - pieces, - adLibPieces, - actions, partId, cue, dummyPart, cue.adlib ? { rank: 0 } : undefined ) - expect(pieces).toEqual([ + expect(result.pieces).toEqual([ literal>({ externalId: partId, name: 'arkiv - unnamed org', @@ -726,22 +671,16 @@ describe('grafik piece', () => { adlib: true, iNewsCommand: '#kg' }) - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateCueGraphic( + const result = EvaluateCueGraphic( makeMockGalleryContext(), - pieces, - adLibPieces, - actions, partId, cue, dummyPart, cue.adlib ? { rank: 0 } : undefined ) - expect(adLibPieces).toEqual([ + expect(result.adlibPieces).toEqual([ literal({ _rank: 0, externalId: partId, @@ -842,24 +781,18 @@ describe('grafik piece', () => { }, iNewsCommand: 'kg' }) - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateCueGraphic( + const result = EvaluateCueGraphic( makeMockGalleryContext(), - pieces, - adLibPieces, - actions, partId, cue, dummyPart, cue.adlib ? { rank: 0 } : undefined ) - expect(pieces.length).toBe(1) - expect(pieces[0]).toMatchObject({ + expect(result.pieces.length).toBe(1) + expect(result.pieces[0]).toMatchObject({ enable: { start: 5000, duration: 5000 @@ -884,23 +817,17 @@ describe('grafik piece', () => { adlib: true, iNewsCommand: 'kg' }) - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateCueGraphic( + const result = EvaluateCueGraphic( makeMockGalleryContext(), - pieces, - adLibPieces, - actions, partId, cue, dummyPart, cue.adlib ? { rank: 0 } : undefined ) - const adlibPiece = adLibPieces.find(piece => piece.tags?.includes('flow_producer')) + const adlibPiece = result.adlibPieces.find(piece => piece.tags?.includes('flow_producer')) expect(adlibPiece).toBeDefined() expect(adlibPiece).toMatchObject({ expectedDuration: 10000, @@ -921,22 +848,16 @@ describe('grafik piece', () => { iNewsCommand: 'GRAFIK' } - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateCueGraphic( + const result = EvaluateCueGraphic( makeMockGalleryContext(), - pieces, - adLibPieces, - actions, partId, cue, dummyPart, cue.adlib ? { rank: 0 } : undefined ) - const piece = pieces[0] + const piece = result.pieces[0] expect(piece).toBeTruthy() const tlObj = (piece.content?.timelineObjects as TSR.TSRTimelineObj[]).find( obj => diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts index 0a164ca4..e9530df6 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -1,12 +1,4 @@ -import { - GraphicsContent, - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPiece, - PieceLifespan, - TSR, - WithTimeline -} from 'blueprints-integration' +import { GraphicsContent, IBlueprintPiece, PieceLifespan, TSR, WithTimeline } from 'blueprints-integration' import { CueDefinitionGraphic, CueDefinitionTelefon, @@ -66,12 +58,9 @@ describe('telefon', () => { }, iNewsCommand: 'TELEFON' } - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] const partId = '0000000001' - EvaluateTelefon(mockContext, pieces, adLibPieces, actions, partId, dummyPart, cue) - expect(pieces).toEqual([ + const result = EvaluateTelefon(mockContext, partId, dummyPart, cue) + expect(result.pieces).toEqual([ literal>({ externalId: partId, name: 'TLF 1', diff --git a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts index 38df9f48..5a1dc038 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts @@ -1,10 +1,10 @@ -import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, IBlueprintPiece } from 'blueprints-integration' +import { IBlueprintPart } from 'blueprints-integration' import { CueDefinitionEkstern, + EvaluateCueResult, EvaluateEksternBase, ExtendedShowStyleContext, PartDefinition, - PieceMetaData, TV2ShowStyleConfig } from 'tv2-common' import { SourceLayer } from '../../layers' @@ -12,20 +12,15 @@ import { SourceLayer } from '../../layers' export function EvaluateEkstern( context: ExtendedShowStyleContext, part: IBlueprintPart, - pieces: Array>, - adlibPieces: Array>, - _actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionEkstern, partDefinition: PartDefinition, adlib?: boolean, rank?: number -) { - EvaluateEksternBase( +): EvaluateCueResult { + return EvaluateEksternBase( context, part, - pieces, - adlibPieces, partId, parsedCue, partDefinition, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts index 0badea54..e845f09b 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts @@ -1,8 +1,8 @@ -import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' import { Adlib, CreateInternalGraphic, CueDefinitionGraphic, + EvaluateCueResult, ExtendedShowStyleContext, GraphicInternalOrPilot, GraphicIsInternal, @@ -15,30 +15,21 @@ import { EvaluateCueRouting } from './routing' export function EvaluateCueGraphic( context: ExtendedShowStyleContext, - pieces: IBlueprintPiece[], - adlibPieces: IBlueprintAdLibPiece[], - actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionGraphic, partDefinition: PartDefinition, adlib?: Adlib -) { +): EvaluateCueResult { + const result = new EvaluateCueResult() if (parsedCue.routing) { - EvaluateCueRouting(context, pieces, partId, parsedCue.routing) + result.push(EvaluateCueRouting(context, partId, parsedCue.routing)) } if (GraphicIsInternal(parsedCue)) { - CreateInternalGraphic(context, pieces, adlibPieces, partId, parsedCue, partDefinition, adlib) + result.push(CreateInternalGraphic(context, partId, parsedCue, partDefinition, adlib)) } else if (GraphicIsPilot(parsedCue)) { - EvaluateCueGraphicPilot( - context, - pieces, - adlibPieces, - actions, - partId, - parsedCue, - partDefinition.segmentExternalId, - adlib - ) + result.push(EvaluateCueGraphicPilot(context, partId, parsedCue, partDefinition.segmentExternalId, adlib)) } + + return result } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts index 58fb195c..10998ff1 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts @@ -1,17 +1,20 @@ -import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' -import { Adlib, CreatePilotGraphic, CueDefinitionGraphic, ExtendedShowStyleContext, GraphicPilot } from 'tv2-common' +import { + Adlib, + CreatePilotGraphic, + CueDefinitionGraphic, + EvaluateCueResult, + ExtendedShowStyleContext, + GraphicPilot +} from 'tv2-common' export function EvaluateCueGraphicPilot( context: ExtendedShowStyleContext, - pieces: IBlueprintPiece[], - adlibPieces: IBlueprintAdLibPiece[], - actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionGraphic, segmentExternalId: string, adlib?: Adlib -) { - CreatePilotGraphic(pieces, adlibPieces, actions, { +): EvaluateCueResult { + return CreatePilotGraphic({ context, partId, parsedCue, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts index 24f74f08..4fafe980 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts @@ -1,30 +1,37 @@ -import { CameraContent, IBlueprintPiece, PieceLifespan, TSR, WithTimeline } from 'blueprints-integration' -import { CalculateTime, CueDefinitionRouting, ExtendedShowStyleContext, findSourceInfo, literal } from 'tv2-common' +import { CameraContent, PieceLifespan, TSR, WithTimeline } from 'blueprints-integration' +import { + CalculateTime, + CueDefinitionRouting, + EvaluateCueResult, + ExtendedShowStyleContext, + findSourceInfo, + literal +} from 'tv2-common' import { SharedOutputLayers, SwitcherAuxLLayer } from 'tv2-constants' import _ = require('underscore') import { SourceLayer } from '../../layers' export function EvaluateCueRouting( context: ExtendedShowStyleContext, - pieces: IBlueprintPiece[], partId: string, parsedCue: CueDefinitionRouting -) { +): EvaluateCueResult { + const result = new EvaluateCueResult() const time = (parsedCue.start ? CalculateTime(parsedCue.start) : 0) ?? 0 const sourceDefinition = parsedCue.INP1 ?? parsedCue.INP if (!sourceDefinition) { context.core.notifyUserWarning(`No input provided for viz engine aux`) - return + return result } const sourceInfo = findSourceInfo(context.config.sources, sourceDefinition) const name = sourceDefinition.name || sourceDefinition.sourceType if (!sourceInfo) { context.core.notifyUserWarning(`Could not find source ${name}`) - return + return result } - pieces.push({ + result.pieces.push({ externalId: partId, enable: { start: time @@ -47,4 +54,5 @@ export function EvaluateCueRouting( ]) }) }) + return result } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts index dc0ab47f..02dd65ab 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts @@ -1,39 +1,46 @@ -import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' import { Adlib, CueDefinitionTelefon, + EvaluateCueResult, ExtendedShowStyleContext, GetSisyfosTimelineObjForTelefon, - GraphicDisplayName, PartDefinition } from 'tv2-common' +import { SharedOutputLayers } from 'tv2-constants' import { SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' import { GalleryBlueprintConfig } from '../config' import { EvaluateCueGraphic } from './graphic' export function EvaluateTelefon( context: ExtendedShowStyleContext, - pieces: IBlueprintPiece[], - adlibPieces: IBlueprintAdLibPiece[], - actions: IBlueprintActionManifest[], partId: string, partDefinition: PartDefinition, parsedCue: CueDefinitionTelefon, adlib?: Adlib -) { - if (parsedCue.graphic) { - EvaluateCueGraphic(context, pieces, adlibPieces, actions, partId, parsedCue.graphic, partDefinition, adlib) +): EvaluateCueResult { + if (!parsedCue.graphic) { + return new EvaluateCueResult() + } + + const result = EvaluateCueGraphic(context, partId, parsedCue.graphic, partDefinition, adlib) - if ((!adlib && pieces.length) || (adlib && adlibPieces.length)) { - if (!adlib) { - const graphicPiece = pieces.find(p => p.name === GraphicDisplayName(context.config, parsedCue.graphic!)) - if (graphicPiece && graphicPiece.content && graphicPiece.content.timelineObjects) { - graphicPiece.content.timelineObjects.push( - ...GetSisyfosTimelineObjForTelefon(context.config, SisyfosLLAyer.SisyfosSourceTLF) - ) - graphicPiece.name = `${parsedCue.source}` - } - } + if (!adlib && result.pieces.length) { + const graphicPiece = findTelefonPiece(result) + if (graphicPiece && graphicPiece.content && graphicPiece.content.timelineObjects) { + graphicPiece.content.timelineObjects.push( + ...GetSisyfosTimelineObjForTelefon(context.config, SisyfosLLAyer.SisyfosSourceTLF) + ) + graphicPiece.name = `${parsedCue.source}` } } + return result +} + +function findTelefonPiece(result: EvaluateCueResult) { + return result.pieces.find( + p => + p.outputLayerId === SharedOutputLayers.OVERLAY || + p.outputLayerId === SharedOutputLayers.PGM || + p.outputLayerId === SharedOutputLayers.SEC + ) } diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index bfda99b5..901e29c7 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -154,7 +154,7 @@ describe('Graphics', () => { expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] - expect(timeline).toHaveLength(8) // @todo: this depends on unrelated configuration + expect(timeline).toHaveLength(7) // @todo: this depends on unrelated configuration const vizObj = timeline.find( t => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT @@ -326,7 +326,7 @@ describe('Graphics', () => { expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] - expect(timeline).toHaveLength(8) + expect(timeline).toHaveLength(7) const vizObj = timeline.find( t => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT diff --git a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts index 7eeb1c1f..8cd1dd91 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts @@ -1,10 +1,10 @@ -import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, IBlueprintPiece } from 'blueprints-integration' +import { IBlueprintPart } from 'blueprints-integration' import { CueDefinitionEkstern, + EvaluateCueResult, EvaluateEksternBase, ExtendedSegmentContext, - PartDefinition, - PieceMetaData + PartDefinition } from 'tv2-common' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeSourceLayer } from '../layers' @@ -12,20 +12,15 @@ import { OfftubeSourceLayer } from '../layers' export function OfftubeEvaluateEkstern( context: ExtendedSegmentContext, part: IBlueprintPart, - pieces: Array>, - _adlibPieces: Array>, - _actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionEkstern, partDefinition: PartDefinition, adlib?: boolean, rank?: number -) { - EvaluateEksternBase( +): EvaluateCueResult { + return EvaluateEksternBase( context, part, - pieces, - [], partId, parsedCue, partDefinition, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts index 8cfd5f58..371b034d 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts @@ -1,9 +1,9 @@ -import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' import { Adlib, CreateInternalGraphic, CreatePilotGraphic, CueDefinitionGraphic, + EvaluateCueResult, ExtendedShowStyleContext, GraphicInternalOrPilot, GraphicIsInternal, @@ -14,16 +14,13 @@ import { OfftubeBlueprintConfig } from '../helpers/config' export function OfftubeEvaluateGrafikCaspar( context: ExtendedShowStyleContext, - pieces: IBlueprintPiece[], - adlibPieces: IBlueprintAdLibPiece[], - actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionGraphic, partDefinition: PartDefinition, adlib?: Adlib -) { +): EvaluateCueResult { if (GraphicIsPilot(parsedCue)) { - CreatePilotGraphic(pieces, adlibPieces, actions, { + return CreatePilotGraphic({ context, partId, parsedCue, @@ -31,6 +28,7 @@ export function OfftubeEvaluateGrafikCaspar( segmentExternalId: partDefinition.segmentExternalId }) } else if (GraphicIsInternal(parsedCue)) { - CreateInternalGraphic(context, pieces, adlibPieces, partId, parsedCue, partDefinition, adlib) + return CreateInternalGraphic(context, partId, parsedCue, partDefinition, adlib) } + return new EvaluateCueResult() } From 75f0abe7a7e8879925f418522ad000afbe1865a8 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 21 Feb 2023 09:15:16 +0100 Subject: [PATCH 22/86] wip: SOF-1260 implement updateAuxInput --- src/tv2-common/videoSwitchers/Atem.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/videoSwitchers/Atem.ts b/src/tv2-common/videoSwitchers/Atem.ts index 334306e5..fdffb41e 100644 --- a/src/tv2-common/videoSwitchers/Atem.ts +++ b/src/tv2-common/videoSwitchers/Atem.ts @@ -192,8 +192,13 @@ export class Atem extends VideoSwitcherImpl { }) ] } - public updateAuxInput(_timelineObject: TSR.TSRTimelineObj, _input: number | SpecialInput): TSR.TSRTimelineObj { - throw new Error('Method not implemented.') + public updateAuxInput(timelineObject: TSR.TSRTimelineObj, input: number | SpecialInput): TSR.TSRTimelineObj { + if (!this.isAux(timelineObject)) { + // @todo: log error or throw + return timelineObject + } + timelineObject.content.aux.input = this.getInputNumber(input) + return timelineObject } public isDveBoxes = (timelineObject: TSR.TSRTimelineObj): timelineObject is TSR.TimelineObjAtemSsrc => { return ( From 3ff9e646634ab144859ed3b57529994c28c08f32 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 21 Feb 2023 09:24:28 +0100 Subject: [PATCH 23/86] wip: SOF-1260 update aux config --- src/tv2-constants/enums.ts | 1 + src/tv2_afvd_showstyle/getRundown.ts | 7 +++++++ src/tv2_afvd_studio/migrations/mappings-defaults.ts | 13 +++---------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index 69287227..3e3e4869 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -201,6 +201,7 @@ export enum SwitcherMixEffectLLayer { export enum SwitcherAuxLLayer { AuxProgram = 'aux_pgm', AuxClean = 'aux_clean', + AuxMixEffect3 = 'aux_mix_effect_3', // AUX set by Sofie, but the M/E is uncontrolled by Sofie AuxWall = 'aux_wall', AuxAR = 'aux_ar', AuxVizOvlIn1 = 'aux_viz_ovl_in_1', diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 498c5c07..6e4cfe8b 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -850,6 +850,13 @@ function getBaseline( input: SpecialInput.DVE } }), + videoSwitcher.getAuxTimelineObject({ + enable: { while: '1' }, + layer: SwitcherAuxLLayer.AuxMixEffect3, + content: { + input: SpecialInput.ME3_PROGRAM + } + }), videoSwitcher.getAuxTimelineObject({ id: '', enable: { while: '1' }, diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index 4c7e8f9b..0e7b52d9 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -740,26 +740,19 @@ export const MAPPINGS_TRICASTER = prefixLayers Date: Tue, 21 Feb 2023 23:43:26 +0100 Subject: [PATCH 24/86] wip: SOF-1260 fix mix-minus --- src/tv2-common/actions/executeAction.ts | 24 +++++---- src/tv2-common/content/dve.ts | 16 ++++-- src/tv2-common/cues/ekstern.ts | 5 +- src/tv2-common/cues/mixMinus.ts | 54 ++++++++++--------- .../graphics/pilot/PilotGraphicGenerator.ts | 1 + .../videoSwitchers/VideoSwitcher.ts | 19 ++----- src/tv2-common/videoSwitchers/types.ts | 1 - src/tv2-constants/enums.ts | 2 +- src/tv2_afvd_showstyle/getRundown.ts | 14 +++-- src/tv2_afvd_showstyle/parts/kam.ts | 2 +- .../migrations/mappings-defaults.ts | 4 +- 11 files changed, 75 insertions(+), 67 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 40af01a9..91a4b9db 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -62,6 +62,7 @@ import { } from 'tv2-common' import { AdlibActionType, + ControlClasses, CueType, PartType, SharedGraphicLLayer, @@ -865,7 +866,7 @@ async function startNewDVELayout< .filter( tlObj => !( - tlObj.content.deviceType === TSR.DeviceType.ATEM && + tlObj.content.deviceType === TSR.DeviceType.ATEM && // @todo: tricaster (tlObj as TSR.TimelineObjAtemAny).content.type === TSR.TimelineContentTypeAtem.ME ) && tlObj.content.deviceType !== TSR.DeviceType.SISYFOS ) @@ -1192,7 +1193,7 @@ async function executeActionCutToRemote< input: sourceInfo.port, transition: TransitionStyle.CUT }, - mixMinusInput: null + classes: [ControlClasses.OVERRIDEN_ON_MIX_MINUS] }), ...eksternSisyfos ]) @@ -1410,9 +1411,9 @@ async function executeActionTakeWithTransition< return } - const mixEffectTimelineObject = primaryPiece.piece.content.timelineObjects.find(context.videoSwitcher.isMixEffect) + const mixEffectTimelineObjects = primaryPiece.piece.content.timelineObjects.filter(context.videoSwitcher.isMixEffect) - if (!mixEffectTimelineObject) { + if (!mixEffectTimelineObjects.length) { return } @@ -1427,7 +1428,7 @@ async function executeActionTakeWithTransition< switch (userData.variant.type) { case 'cut': { - await updateTransition(context, mixEffectTimelineObject, primaryPiece, TransitionStyle.CUT) + await updateTransition(context, mixEffectTimelineObjects, primaryPiece, TransitionStyle.CUT) const cutTransitionPiece: IBlueprintPiece = { enable: { start: 0, @@ -1454,7 +1455,7 @@ async function executeActionTakeWithTransition< } break case 'breaker': { - await updateTransition(context, mixEffectTimelineObject, primaryPiece, TransitionStyle.CUT) + await updateTransition(context, mixEffectTimelineObjects, primaryPiece, TransitionStyle.CUT) const pieces: Array> = [] partProps = CreateEffektForPartInner( context, @@ -1478,7 +1479,7 @@ async function executeActionTakeWithTransition< case 'mix': { await updateTransition( context, - mixEffectTimelineObject, + mixEffectTimelineObjects, primaryPiece, TransitionStyle.MIX, userData.variant.frames @@ -1499,7 +1500,7 @@ async function executeActionTakeWithTransition< case 'dip': { await updateTransition( context, - mixEffectTimelineObject, + mixEffectTimelineObjects, primaryPiece, TransitionStyle.DIP, userData.variant.frames @@ -1524,13 +1525,14 @@ async function executeActionTakeWithTransition< async function updateTransition( context: ExtendedActionExecutionContext, - timelineObject: TimelineObjectCoreExt, + timelineObjects: TimelineObjectCoreExt[], pieceInstance: IBlueprintPieceInstance, transitionStyle: TransitionStyle, transitionDuration?: number ): Promise { - context.videoSwitcher.updateTransition(timelineObject, transitionStyle, transitionDuration) - + for (const timelineObject of timelineObjects) { + context.videoSwitcher.updateTransition(timelineObject, transitionStyle, transitionDuration) + } await context.core.updatePieceInstance(pieceInstance._id, pieceInstance.piece) } diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index ad9a858e..d07a20a2 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -17,8 +17,10 @@ import { ExtendedShowStyleContext, FindDSKFullGFX, findSourceInfo, + getMixMinusTimelineObject, joinAssetToFolder, literal, + MixMinusPriority, PartDefinition, PieceMetaData, SpecialInput, @@ -26,7 +28,7 @@ import { TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' -import { MEDIA_PLAYER_AUTO, SharedGraphicLLayer, SourceType } from 'tv2-constants' +import { ControlClasses, MEDIA_PLAYER_AUTO, SharedGraphicLLayer, SourceType } from 'tv2-constants' import * as _ from 'underscore' import { AtemSourceIndex } from '../../types/atem' import { ActionSelectDVE } from '../actions' @@ -186,6 +188,7 @@ export function MakeContentDVE2< })) const dveTimeline: TSR.TSRTimelineObj[] = [] const boxSources: BoxSources = [] + const cameraSources: number[] = [] let valid = true let hasServer = false @@ -221,6 +224,7 @@ export function MakeContentDVE2< } setBoxSource(box, boxSources, sourceInfoCam) + cameraSources.push(box.source) dveTimeline.push( ...GetSisyfosTimelineObjForCamera(context.config, sourceInfoCam, mappingFrom.minusMic, audioEnable) ) @@ -292,6 +296,10 @@ export function MakeContentDVE2< frameFile = joinAssetToFolder(context.config.studio.DVEFolder, frameFile) } + if (cameraSources.length === 1) { + dveTimeline.push(getMixMinusTimelineObject(context, cameraSources[0], MixMinusPriority.CUSTOM_INPUT)) + } + return { valid, content: literal>({ @@ -308,7 +316,7 @@ export function MakeContentDVE2< }, metaData: { mediaPlayerSession: hasServer ? mediaPlayerSessionId ?? MEDIA_PLAYER_AUTO : undefined - } + }, }), ...context.videoSwitcher.getOnAirTimelineObjects({ enable: { start: context.config.studio.CasparPrerollDuration }, @@ -316,7 +324,8 @@ export function MakeContentDVE2< content: { input: SpecialInput.DVE, transition: TransitionStyle.CUT - } + }, + classes: [ControlClasses.OVERRIDEN_ON_MIX_MINUS] }), literal({ id: '', @@ -379,7 +388,6 @@ const setBoxSource = ( boxConfig.source = sourceInfo.port boxSources.push({ - // TODO - draw box geometry ...boxSource(sourceInfo), ...literal({ studioLabel: '', diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index 1f48e0c0..fc6db7b1 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -75,8 +75,7 @@ export function EvaluateEksternBase< transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration }, - classes: [ControlClasses.LIVE_SOURCE_ON_AIR], // @todo: this should not be here probably - mixMinusInput: null + classes: [ControlClasses.OVERRIDEN_ON_MIX_MINUS] }), ...GetSisyfosTimelineObjForRemote(context.config, sourceInfoEkstern) @@ -114,7 +113,7 @@ export function EvaluateEksternBase< transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration }, - mixMinusInput: null // @todo: should it be here? + classes: [ControlClasses.OVERRIDEN_ON_MIX_MINUS] }), ...GetSisyfosTimelineObjForRemote(context.config, sourceInfoEkstern) diff --git a/src/tv2-common/cues/mixMinus.ts b/src/tv2-common/cues/mixMinus.ts index 698057ba..4b5486ec 100644 --- a/src/tv2-common/cues/mixMinus.ts +++ b/src/tv2-common/cues/mixMinus.ts @@ -1,11 +1,5 @@ -import { - BaseContent, - IBlueprintPiece, - PieceLifespan, - TimelineObjectCoreExt, - WithTimeline -} from 'blueprints-integration' -import { CueDefinitionMixMinus, ExtendedShowStyleContext, findSourceInfo, literal, PartDefinition } from 'tv2-common' +import { IBlueprintPiece, PieceLifespan, TSR } from 'blueprints-integration' +import { CueDefinitionMixMinus, ExtendedShowStyleContext, findSourceInfo, PartDefinition } from 'tv2-common' import { ControlClasses, SharedOutputLayers, SharedSourceLayers, SwitcherAuxLLayer } from 'tv2-constants' export function EvaluateCueMixMinus( @@ -14,6 +8,10 @@ export function EvaluateCueMixMinus( part: PartDefinition, parsedCue: CueDefinitionMixMinus ) { + if (!context.uniformConfig.SwitcherLLayers.MixMinusAux) { + context.core.notifyUserWarning(`Mix-Minus out not available in this studio (MINUSKAM)`) + return + } const sourceInfo = findSourceInfo(context.config.sources, parsedCue.sourceDefinition) const name = parsedCue.sourceDefinition.name || parsedCue.sourceDefinition.sourceType @@ -33,23 +31,31 @@ export function EvaluateCueMixMinus( lifespan: PieceLifespan.OutOnShowStyleEnd, sourceLayerId: SharedSourceLayers.AuxMixMinus, outputLayerId: SharedOutputLayers.AUX, - content: MixMinusContent(context, switcherInput) + content: { + timelineObjects: [getMixMinusTimelineObject(context, switcherInput, MixMinusPriority.MINUSKAM_CUE)] + } }) } -function MixMinusContent(context: ExtendedShowStyleContext, switcherInput: number): WithTimeline { - return { - timelineObjects: literal([ - context.videoSwitcher.getAuxTimelineObject({ - content: { - input: switcherInput - }, - enable: { - while: `.${ControlClasses.LIVE_SOURCE_ON_AIR}` - }, - layer: SwitcherAuxLLayer.AuxVideoMixMinus, - priority: 1 - }) - ]) - } +export enum MixMinusPriority { + STUDIO_CONFIG = 1, + MINUSKAM_CUE = 2, + CUSTOM_INPUT = 3 +} + +export function getMixMinusTimelineObject( + context: ExtendedShowStyleContext, + switcherInput: number, + priority: MixMinusPriority +): TSR.TSRTimelineObj { + return context.videoSwitcher.getAuxTimelineObject({ + content: { + input: switcherInput + }, + enable: { + while: `.${ControlClasses.OVERRIDEN_ON_MIX_MINUS}` + }, + layer: SwitcherAuxLLayer.AuxVideoMixMinus, + priority + }) } diff --git a/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts index ea5ce53c..09edfaf4 100644 --- a/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts @@ -150,6 +150,7 @@ export abstract class PilotGraphicGenerator extends Graphic { content.timelineObjects = content.timelineObjects.filter( o => o.content.deviceType !== TSR.DeviceType.ATEM && + o.content.deviceType !== TSR.DeviceType.TRICASTER && o.content.deviceType !== TSR.DeviceType.SISYFOS && o.content.deviceType !== TSR.DeviceType.VIZMSE && o.content.deviceType !== TSR.DeviceType.CASPARCG diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts index 666f0279..a21168f2 100644 --- a/src/tv2-common/videoSwitchers/VideoSwitcher.ts +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -54,7 +54,7 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { if (this.uniformConfig.SwitcherLLayers.PrimaryMixEffectClone) { result.push( this.getMixEffectTimelineObject({ - ...properties, + ..._.omit(properties, 'classes'), layer: this.uniformConfig.SwitcherLLayers.PrimaryMixEffectClone, metaData: { ...properties.metaData, context: `Clone of Primary MixEffect timeline object ${primaryId}` } }) @@ -63,7 +63,7 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { if (this.uniformConfig.SwitcherLLayers.NextPreviewMixEffect && properties.content.input) { result.push( this.getMixEffectTimelineObject({ - ..._.omit(properties, 'content'), + ..._.omit(properties, 'content', 'classes'), content: { previewInput: properties.content.input }, layer: this.uniformConfig.SwitcherLLayers.NextPreviewMixEffect, metaData: { ...properties.metaData, context: `Preview Lookahead for ${primaryId}` } @@ -73,7 +73,7 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { if (this.uniformConfig.SwitcherLLayers.NextAux && properties.content.input) { result.push( this.getAuxTimelineObject({ - ..._.omit(properties, 'content'), + ..._.omit(properties, 'content', 'classes'), priority: 0, // lower than lookahead-lookahead content: { input: properties.content.input }, layer: this.uniformConfig.SwitcherLLayers.NextAux, @@ -81,19 +81,6 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { }) ) } - if (this.uniformConfig.SwitcherLLayers.MixMinusAux) { - const input = properties.mixMinusInput || properties.content.input - if (input) { - result.push( - this.getAuxTimelineObject({ - ..._.omit(properties, 'content'), - content: { input }, - layer: this.uniformConfig.SwitcherLLayers.MixMinusAux, - metaData: { ...properties.metaData, context: `Mix-minus for ${primaryId}` } - }) - ) - } - } return result } public abstract updateAuxInput( diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index c6e26365..c8f8b292 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -64,7 +64,6 @@ export interface MixEffectProps extends TimelineObjectProps { } export interface OnAirMixEffectProps extends Omit { - mixMinusInput?: number | SpecialInput | null } export interface Keyer { diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index 3e3e4869..9b070a50 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -115,7 +115,7 @@ export function AdlibTagCutToBox(box: number): AdlibTags { export enum ControlClasses { SERVER_ON_AIR = 'server_on_air', LYD_ON_AIR = 'lyd_on_air', - LIVE_SOURCE_ON_AIR = 'live_source_on_air', + OVERRIDEN_ON_MIX_MINUS = 'overriden_on_mix_minus', ABSTRACT_LOOKAHEAD = 'abstract_lookahead', PLACEHOLDER = 'placeholder' } diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 6e4cfe8b..bd4db926 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -31,10 +31,12 @@ import { ExtendedShowStyleContextImpl, FindDSKJingle, generateExternalId, + getMixMinusTimelineObject, GetSisyfosTimelineObjForRemote, GetSisyfosTimelineObjForReplay, GetTransitionAdLibActions, literal, + MixMinusPriority, PieceMetaData, replaySourceName, SourceDefinitionKam, @@ -51,6 +53,7 @@ import { AdlibTagCutToBox, AdlibTags, CONSTANTS, + ControlClasses, SharedGraphicLLayer, SharedOutputLayers, SourceType, @@ -290,7 +293,7 @@ class GlobalAdLibPiecesGenerator { input: info.port, transition: TransitionStyle.CUT }, - mixMinusInput: null // @should it be here? + classes: [ControlClasses.OVERRIDEN_ON_MIX_MINUS] }), ...eksternSisyfos ] @@ -858,14 +861,17 @@ function getBaseline( } }), videoSwitcher.getAuxTimelineObject({ - id: '', enable: { while: '1' }, - priority: 0, layer: SwitcherAuxLLayer.AuxVideoMixMinus, content: { - input: context.config.studio.SwitcherSource.MixMinusDefault + input: context.uniformConfig.MixEffects.Program.input } }), + getMixMinusTimelineObject( + context, + context.config.studio.SwitcherSource.MixMinusDefault, + MixMinusPriority.STUDIO_CONFIG + ), // render presenter screen literal({ diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index c17f6030..5f4e22c7 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -105,7 +105,7 @@ export async function CreatePartKam( ...context.videoSwitcher.getOnAirTimelineObjects({ priority: 1, content: { - input: Number(switcherInput), + input: switcherInput, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration } diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index 0e7b52d9..6f500b0b 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -634,7 +634,7 @@ export const MAPPINGS_ATEM = prefixLayers(AT [SwitcherAuxLLayer.AuxVideoMixMinus]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, - lookahead: LookaheadMode.WHEN_CLEAR, + lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.Auxilliary, index: 6 // 6 = out 7 }, @@ -750,7 +750,7 @@ export const MAPPINGS_TRICASTER = prefixLayers Date: Wed, 22 Feb 2023 13:52:32 +0100 Subject: [PATCH 25/86] SOF-1264 Create DVE timelineObjects for Tricaster --- src/tv2-common/blueprintConfig.ts | 4 +- src/tv2-common/content/dve.ts | 4 +- src/tv2-common/videoSwitchers/TriCaster.ts | 134 +++++++++++++++++- .../videoSwitchers/__tests__/Atem.spec.ts | 4 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 4 +- src/tv2_afvd_showstyle/getRundown.ts | 4 +- .../__tests__/config-manifest.spec.ts | 4 +- src/tv2_afvd_studio/helpers/config.ts | 4 +- src/tv2_offtube_showstyle/getRundown.ts | 4 +- .../__tests__/config-manifest.spec.ts | 4 +- src/tv2_offtube_studio/helpers/config.ts | 4 +- src/tv2_offtube_studio/migrations/index.ts | 2 +- 12 files changed, 151 insertions(+), 25 deletions(-) diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 74d27bd8..6f0ce804 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -101,8 +101,8 @@ export interface TV2StudioConfigBase { SwitcherType: SwitcherType SwitcherSource: { Default: number - SplitArtF: number - SplitArtK: number + SplitArtFill: number + SplitArtKey: number DSK: TableConfigItemDSK[] Dip: number } diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index ad9a858e..f1431c1b 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -303,8 +303,8 @@ export function MakeContentDVE2< content: { boxes, template, - artFillSource: context.config.studio.SwitcherSource.SplitArtF, - artCutSource: context.config.studio.SwitcherSource.SplitArtK + artFillSource: context.config.studio.SwitcherSource.SplitArtFill, + artCutSource: context.config.studio.SwitcherSource.SplitArtKey }, metaData: { mediaPlayerSession: hasServer ? mediaPlayerSessionId ?? MEDIA_PLAYER_AUTO : undefined diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 51cc0b78..7027738c 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -1,5 +1,6 @@ import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' -import { TimeFromFrames } from 'tv2-common' +import { literal, TimeFromFrames } from 'tv2-common' +import { SwitcherDveLLayer } from 'tv2-constants' import _ = require('underscore') import { TRICASTER_DVE_ME, TRICASTER_LAYER_PREFIX } from '../layers' import { @@ -36,6 +37,8 @@ const TRANSITION_MAP: Record = { [TransitionStyle.STING]: 5 // not really supported?? } +const SOURCE_INPUT_PREFIX: string = 'input' + export class TriCaster extends VideoSwitcherImpl { public readonly type = SwitcherType.ATEM @@ -151,9 +154,30 @@ export class TriCaster extends VideoSwitcherImpl { !!(timelineObject.content.me as TSR.TriCasterMixEffectInEffectMode).layers ) } - - public getDveTimelineObjects(_properties: DveProps): TSR.TSRTimelineObj[] { - throw new Error('Method not implemented.') + public getDveTimelineObjects(dveProps: DveProps): TSR.TSRTimelineObj[] { + return [ + literal({ + id: '', + enable: dveProps.enable ?? { start: 0 }, + layer: TRICASTER_LAYER_PREFIX + SwitcherDveLLayer.DveBoxes, + priority: 1, + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME, + me: literal({ + transitionEffect: 8, + layers: this.generateDveBoxLayers(dveProps.content.boxes), + keyers: { + dsk1: { + input: `${SOURCE_INPUT_PREFIX}${5}`, + onAir: true, + transitionEffect: 'cut' + } + } + }) + } + }) + ] } public updateUnpopulatedDveBoxes( @@ -163,6 +187,108 @@ export class TriCaster extends VideoSwitcherImpl { throw new Error('Method not implemented.') } + private generateDveBoxLayers(boxes: any[]): Partial> { + return { + a: boxes[0].enabled ? this.generateDveBoxLayout(boxes[0]) : this.generateInvisibleBoxLayer(), + b: boxes[1].enabled ? this.generateDveBoxLayout(boxes[1]) : this.generateInvisibleBoxLayer(), + c: boxes[2].enabled ? this.generateDveBoxLayout(boxes[2]) : this.generateInvisibleBoxLayer(), + d: boxes[3].enabled ? this.generateDveBoxLayout(boxes[3]) : this.generateInvisibleBoxLayer() + } + } + + private generateDveBoxLayout(box: any): TSR.TriCasterLayer { + return { + input: `${SOURCE_INPUT_PREFIX}${box.source}`, + positioningAndCropEnabled: true, + position: this.convertPosition(box), + scale: this.convertScale(box), + crop: this.convertCrop(box) + } + } + + private convertPosition(box: any): TSR.TriCasterLayer['position'] { + return { + x: this.convertPositionX(box), + y: this.convertPositionY(box) + } + } + + /** + * The x-position needs an offset added depending on the scale. + * It seems to be a linear progression that for every 48 'size', that we are from 100% scale, an offset of 0.009 needs to be added. + * If the x is negative we need to subtract the offset instead of adding it. + * The division by a 1000 is to convert from the value we receive to the value TriCaster accepts + */ + private convertPositionX(box: { x: number; size: number }): number { + // 1000 comes ATEM scale upper bound. 48 comes from ATEM x position upper bound divided by 100 + const offset = ((1000 - box.size) / 48) * 0.009 + return box.x / 1000 + (box.x < 0 ? offset * -1 : offset) + } + + /** + * The y-position needs an offset that depend on the percentage y is compared to the height of the screen + * If y is negative we need to subtract the offset instead of adding it. + * The division by a 1000 is to convert from the value we receive to the value TriCaster accepts + */ + private convertPositionY(box: { y: number }): number { + const positiveValue = box.y < 0 ? box.y * -1 : box.y + const percentageToBeAdded = (positiveValue / 2700) * 100 + const offset = (percentageToBeAdded * positiveValue) / 100 + const position = box.y < 0 ? box.y - offset : box.y + offset + return (position / 1000) * -1 + } + + private convertScale(box: any): TSR.TriCasterLayer['scale'] { + return { + x: box.size / 1000, + y: box.size / 1000 + } + } + + private convertCrop(box: any): TSR.TriCasterLayer['crop'] { + if (!box.cropped || this.isAllCropZero(box)) { + return { + down: 0, + up: 0, + left: 0, + right: 0 + } + } + const atemCropTopBottomMaxValue = 18000 + const atemCropLeftRightMaxValue = 32000 + return { + down: this.getPercentage(box.cropBottom, atemCropTopBottomMaxValue), + up: this.getPercentage(box.cropTop, atemCropTopBottomMaxValue), + left: this.getPercentage(box.cropLeft, atemCropLeftRightMaxValue), + right: this.getPercentage(box.cropRight, atemCropLeftRightMaxValue) + } + } + + private isAllCropZero(box: any): boolean { + return box.cropTop === 0 && box.cropBottom === 0 && box.cropLeft === 0 && box.cropRight === 0 + } + + private getPercentage(part: number, whole: number): number { + return (part / whole) * 100 + } + + private generateInvisibleBoxLayer(): TSR.TriCasterLayer { + return { + input: 'Black', + positioningAndCropEnabled: true, + position: { + x: -3.555, + y: -2 + }, + crop: { + down: 0, + up: 0, + left: 0, + right: 0 + } + } + } + private getTransitionDuration(transition?: TransitionStyle, durationInFrames?: number): number { if (transition === TransitionStyle.WIPE_FOR_GFX) { durationInFrames = this.config.studio.HTMLGraphics.TransitionSettings.wipeRate diff --git a/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts index 7071737a..88a2287d 100644 --- a/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts @@ -240,8 +240,8 @@ describe('ATEM', () => { SwitcherSource: { Dip: dipInputSource, Default: 1, - SplitArtF: 1, - SplitArtK: 1, + SplitArtFill: 1, + SplitArtKey: 1, DSK: [] } }) diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index 35f0d56d..5c36cd45 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -104,8 +104,8 @@ export const defaultStudioConfig: StudioConfig = { SwitcherSource: { MixMinusDefault: 2, DSK: defaultDSKConfig, - SplitArtF: 30, - SplitArtK: 32, + SplitArtFill: 30, + SplitArtKey: 32, Default: 2001, Continuity: 2002, Dip: 2002 diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index ece607a4..91d79aa1 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -929,8 +929,8 @@ function getBaseline( deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRCPROPS, ssrcProps: { - artFillSource: context.config.studio.SwitcherSource.SplitArtF, - artCutSource: context.config.studio.SwitcherSource.SplitArtK, + artFillSource: context.config.studio.SwitcherSource.SplitArtFill, + artCutSource: context.config.studio.SwitcherSource.SplitArtKey, artOption: 1, artPreMultiplied: true } diff --git a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts index ae888902..7063c9c7 100644 --- a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts @@ -42,8 +42,8 @@ const blankStudioConfig: StudioConfig = { SwitcherSource: { DSK: defaultDSKConfig, - SplitArtF: 0, - SplitArtK: 0, + SplitArtFill: 0, + SplitArtKey: 0, Default: 0, MixMinusDefault: 0, Continuity: 0, diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index fa591556..6797c60d 100644 --- a/src/tv2_afvd_studio/helpers/config.ts +++ b/src/tv2_afvd_studio/helpers/config.ts @@ -26,8 +26,8 @@ export interface StudioConfig extends TV2StudioConfigBase { ABPlaybackDebugLogging: boolean StudioMics: string[] SwitcherSource: { - SplitArtF: number // Atem MP1 Fill - SplitArtK: number // Atem MP1 Key + SplitArtFill: number // Atem MP1 Fill + SplitArtKey: number // Atem MP1 Key DSK: TableConfigItemDSK[] Default: number diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 49533b46..159d6870 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -638,8 +638,8 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRCPROPS, ssrcProps: { - artFillSource: config.studio.SwitcherSource.SplitArtF, - artCutSource: config.studio.SwitcherSource.SplitArtK, + artFillSource: config.studio.SwitcherSource.SplitArtFill, + artCutSource: config.studio.SwitcherSource.SplitArtKey, artOption: 1, // foreground artPreMultiplied: true } diff --git a/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts b/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts index 0e4b477c..024f8dcd 100644 --- a/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts @@ -32,8 +32,8 @@ const blankStudioConfig: OfftubeStudioConfig = { SwitcherSource: { DSK: defaultDSKConfig, - SplitArtF: 0, - SplitArtK: 0, + SplitArtFill: 0, + SplitArtKey: 0, Default: 0, Continuity: 0, SplitBackground: 0, diff --git a/src/tv2_offtube_studio/helpers/config.ts b/src/tv2_offtube_studio/helpers/config.ts index 0466721f..b5b7bae6 100644 --- a/src/tv2_offtube_studio/helpers/config.ts +++ b/src/tv2_offtube_studio/helpers/config.ts @@ -24,8 +24,8 @@ export interface OfftubeStudioConfig extends TV2StudioConfigBase { ABMediaPlayers: TableConfigItemSourceMapping[] ABPlaybackDebugLogging: boolean SwitcherSource: { - SplitArtF: number - SplitArtK: number + SplitArtFill: number + SplitArtKey: number SplitBackground: number Loop: number DSK: TableConfigItemDSK[] diff --git a/src/tv2_offtube_studio/migrations/index.ts b/src/tv2_offtube_studio/migrations/index.ts index 222f171c..6157b81b 100644 --- a/src/tv2_offtube_studio/migrations/index.ts +++ b/src/tv2_offtube_studio/migrations/index.ts @@ -275,7 +275,7 @@ export const studioMigrations: MigrationStepStudio[] = [ RenameStudioConfig('1.4.6', 'Offtube', 'GraphicBasePath', 'NetworkBasePathGraphic'), RenameStudioConfig('1.4.6', 'Offtube', 'GraphicFlowId', 'GraphicMediaFlowId'), -// GetMappingDefaultMigrationStepForLayer('1.4.8', 'casparcg_player_jingle_looakhead', true), + // GetMappingDefaultMigrationStepForLayer('1.4.8', 'casparcg_player_jingle_looakhead', true), RenameStudioConfig('1.5.0', 'Offtube', 'NetworkBasePathJingle', 'JingleNetworkBasePath'), RenameStudioConfig('1.5.0', 'Offtube', 'NetworkBasePathClip', 'ClipNetworkBasePath'), From 17668e172f9ff96478673ec8605737a4e62cd71d Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Thu, 23 Feb 2023 07:59:17 +0100 Subject: [PATCH 26/86] SOF-1264 Migrate SplitArtF and SplitArtK to SplitArtFill and SplitArtKey --- src/tv2_afvd_studio/config-manifests.ts | 4 ++-- src/tv2_afvd_studio/migrations/index.ts | 2 ++ src/tv2_offtube_studio/config-manifests.ts | 4 ++-- src/tv2_offtube_studio/migrations/index.ts | 11 +++++++++++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index 3f2aafa0..717fb653 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -306,7 +306,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ defaultVal: false }, { - id: 'SwitcherSource.SplitArtF', + id: 'SwitcherSource.SplitArtFill', name: 'Switcher Split Screen Art Fill', description: 'Video Switcher input for Split Screen Art Fill', type: ConfigManifestEntryType.INT, @@ -314,7 +314,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ defaultVal: 30 }, { - id: 'SwitcherSource.SplitArtK', + id: 'SwitcherSource.SplitArtKey', name: 'Switcher Split Screen Art Key', description: 'Video Switcher input for Split Screen Art Key', type: ConfigManifestEntryType.INT, diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index 84d7db64..1daf17f1 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -209,6 +209,8 @@ export const studioMigrations: MigrationStepStudio[] = [ renameStudioTableColumn('1.8.0', tableName, 'AtemSource', 'SwitcherSource') ), RenameStudioConfig('1.8.0', 'AFVD', 'AtemSource', 'SwitcherSource'), + RenameStudioConfig('1.8.0', 'AFVD', 'SwitcherSource.SplitArtF', 'SwitcherSource.SplitArtFill'), + RenameStudioConfig('1.8.0', 'AFVD', 'SwitcherSource.SplitArtK', 'SwitcherSource.SplitArtKey'), // Fill in any mappings that did not exist before // Note: These should only be run as the very final step of all migrations. otherwise they will add items too early, and confuse old migrations diff --git a/src/tv2_offtube_studio/config-manifests.ts b/src/tv2_offtube_studio/config-manifests.ts index cb7eacd8..1736627f 100644 --- a/src/tv2_offtube_studio/config-manifests.ts +++ b/src/tv2_offtube_studio/config-manifests.ts @@ -151,7 +151,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ defaultVal: false }, { - id: 'SwitcherSource.SplitArtF', + id: 'SwitcherSource.SplitArtFill', name: 'Switcher Split Screen Art Fill', description: 'Video Switcher input for Split Screen Art Fill', type: ConfigManifestEntryType.INT, @@ -159,7 +159,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ defaultVal: 10 }, { - id: 'SwitcherSource.SplitArtK', + id: 'SwitcherSource.SplitArtKey', name: 'Switcher Split Screen Art Key', description: 'Video Switcher input for Split Screen Art Key', type: ConfigManifestEntryType.INT, diff --git a/src/tv2_offtube_studio/migrations/index.ts b/src/tv2_offtube_studio/migrations/index.ts index 6157b81b..244f9104 100644 --- a/src/tv2_offtube_studio/migrations/index.ts +++ b/src/tv2_offtube_studio/migrations/index.ts @@ -5,6 +5,7 @@ import { MoveSourcesToTable, RemoveConfig, RenameStudioConfig, + renameStudioTableColumn, SetConfigTo, SetLayerNamesToDefaults } from 'tv2-common' @@ -365,6 +366,16 @@ export const studioMigrations: MigrationStepStudio[] = [ removeMapping('1.7.8', 'graphic_pilot_overlay'), GetMappingDefaultMigrationStepForLayer('1.7.8', 'graphic_overlay_pilot', true), + /** + * 1.8.0 + */ + ...['SourcesCam', 'SourcesRM', 'SourcesReplay', 'SourcesFeed', 'ABMediaPlayers'].map(tableName => + renameStudioTableColumn('1.8.0', tableName, 'AtemSource', 'SwitcherSource') + ), + RenameStudioConfig('1.8.0', 'Offtube', 'AtemSource', 'SwitcherSource'), + RenameStudioConfig('1.8.0', 'Offtube', 'SwitcherSource.SplitArtF', 'SwitcherSource.SplitArtFill'), + RenameStudioConfig('1.8.0', 'Offtube', 'SwitcherSource.SplitArtK', 'SwitcherSource.SplitArtKey'), + // Fill in any mappings that did not exist before // Note: These should only be run as the very final step of all migrations. otherwise they will add items too early, and confuse old migrations ...getMappingsDefaultsMigrationSteps(VERSION) From e7f1622cae2ed2912e29723a5d55e545b9eec503 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Thu, 23 Feb 2023 14:09:57 +0100 Subject: [PATCH 27/86] SOF-1264 Refactor ATEM to TriCaster DVE conversion. Seperate into own file --- src/tv2-common/videoSwitchers/TriCaster.ts | 113 +++++------------- .../videoSwitchers/TriCasterDveConverter.ts | 13 ++ .../atemToTricasterDveConverter.ts | 66 ++++++++++ tslint.json | 3 +- 4 files changed, 109 insertions(+), 86 deletions(-) create mode 100644 src/tv2-common/videoSwitchers/TriCasterDveConverter.ts create mode 100644 src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 7027738c..d23c8cad 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -3,6 +3,8 @@ import { literal, TimeFromFrames } from 'tv2-common' import { SwitcherDveLLayer } from 'tv2-constants' import _ = require('underscore') import { TRICASTER_DVE_ME, TRICASTER_LAYER_PREFIX } from '../layers' +import { AtemToTricasterDveConverter } from './atemToTricasterDveConverter' +import { TriCasterDveConverter } from './TriCasterDveConverter' import { AuxProps, DskProps, @@ -37,7 +39,7 @@ const TRANSITION_MAP: Record = { [TransitionStyle.STING]: 5 // not really supported?? } -const SOURCE_INPUT_PREFIX: string = 'input' +const DVE_OVERLAY_INPUT_NUMBER: number = 5 export class TriCaster extends VideoSwitcherImpl { public readonly type = SwitcherType.ATEM @@ -48,6 +50,8 @@ export class TriCaster extends VideoSwitcherImpl { public isAux = TSR.isTimelineObjTriCasterMixOutput public isVideoSwitcherTimelineObject = TSR.isTimelineObjTriCaster + private dveConverter: TriCasterDveConverter = new AtemToTricasterDveConverter() + public getMixEffectTimelineObject(props: MixEffectProps): TSR.TimelineObjTriCasterME { const { content } = props const transition = this.getTransition(content.transition) @@ -154,6 +158,14 @@ export class TriCaster extends VideoSwitcherImpl { !!(timelineObject.content.me as TSR.TriCasterMixEffectInEffectMode).layers ) } + + public updateUnpopulatedDveBoxes( + _timelineObject: TSR.TSRTimelineObj, + _input: number | SpecialInput + ): TSR.TSRTimelineObj { + throw new Error('Method not implemented.') + } + public getDveTimelineObjects(dveProps: DveProps): TSR.TSRTimelineObj[] { return [ literal({ @@ -167,26 +179,13 @@ export class TriCaster extends VideoSwitcherImpl { me: literal({ transitionEffect: 8, layers: this.generateDveBoxLayers(dveProps.content.boxes), - keyers: { - dsk1: { - input: `${SOURCE_INPUT_PREFIX}${5}`, - onAir: true, - transitionEffect: 'cut' - } - } + keyers: this.generateOverlayKeyer() }) } }) ] } - public updateUnpopulatedDveBoxes( - _timelineObject: TSR.TSRTimelineObj, - _input: number | SpecialInput - ): TSR.TSRTimelineObj { - throw new Error('Method not implemented.') - } - private generateDveBoxLayers(boxes: any[]): Partial> { return { a: boxes[0].enabled ? this.generateDveBoxLayout(boxes[0]) : this.generateInvisibleBoxLayer(), @@ -198,80 +197,14 @@ export class TriCaster extends VideoSwitcherImpl { private generateDveBoxLayout(box: any): TSR.TriCasterLayer { return { - input: `${SOURCE_INPUT_PREFIX}${box.source}`, + input: this.getInputName(box.source), positioningAndCropEnabled: true, - position: this.convertPosition(box), - scale: this.convertScale(box), - crop: this.convertCrop(box) - } - } - - private convertPosition(box: any): TSR.TriCasterLayer['position'] { - return { - x: this.convertPositionX(box), - y: this.convertPositionY(box) - } - } - - /** - * The x-position needs an offset added depending on the scale. - * It seems to be a linear progression that for every 48 'size', that we are from 100% scale, an offset of 0.009 needs to be added. - * If the x is negative we need to subtract the offset instead of adding it. - * The division by a 1000 is to convert from the value we receive to the value TriCaster accepts - */ - private convertPositionX(box: { x: number; size: number }): number { - // 1000 comes ATEM scale upper bound. 48 comes from ATEM x position upper bound divided by 100 - const offset = ((1000 - box.size) / 48) * 0.009 - return box.x / 1000 + (box.x < 0 ? offset * -1 : offset) - } - - /** - * The y-position needs an offset that depend on the percentage y is compared to the height of the screen - * If y is negative we need to subtract the offset instead of adding it. - * The division by a 1000 is to convert from the value we receive to the value TriCaster accepts - */ - private convertPositionY(box: { y: number }): number { - const positiveValue = box.y < 0 ? box.y * -1 : box.y - const percentageToBeAdded = (positiveValue / 2700) * 100 - const offset = (percentageToBeAdded * positiveValue) / 100 - const position = box.y < 0 ? box.y - offset : box.y + offset - return (position / 1000) * -1 - } - - private convertScale(box: any): TSR.TriCasterLayer['scale'] { - return { - x: box.size / 1000, - y: box.size / 1000 - } - } - - private convertCrop(box: any): TSR.TriCasterLayer['crop'] { - if (!box.cropped || this.isAllCropZero(box)) { - return { - down: 0, - up: 0, - left: 0, - right: 0 - } - } - const atemCropTopBottomMaxValue = 18000 - const atemCropLeftRightMaxValue = 32000 - return { - down: this.getPercentage(box.cropBottom, atemCropTopBottomMaxValue), - up: this.getPercentage(box.cropTop, atemCropTopBottomMaxValue), - left: this.getPercentage(box.cropLeft, atemCropLeftRightMaxValue), - right: this.getPercentage(box.cropRight, atemCropLeftRightMaxValue) + position: this.dveConverter.convertPosition(box.x, box.y), + scale: this.dveConverter.convertScale(box.size), + crop: this.dveConverter.convertCrop(box) } } - private isAllCropZero(box: any): boolean { - return box.cropTop === 0 && box.cropBottom === 0 && box.cropLeft === 0 && box.cropRight === 0 - } - - private getPercentage(part: number, whole: number): number { - return (part / whole) * 100 - } - private generateInvisibleBoxLayer(): TSR.TriCasterLayer { return { input: 'Black', @@ -289,6 +222,16 @@ export class TriCaster extends VideoSwitcherImpl { } } + private generateOverlayKeyer(): Record { + return { + dsk1: { + input: this.getInputName(DVE_OVERLAY_INPUT_NUMBER), + onAir: true, + transitionEffect: 'cut' + } + } + } + private getTransitionDuration(transition?: TransitionStyle, durationInFrames?: number): number { if (transition === TransitionStyle.WIPE_FOR_GFX) { durationInFrames = this.config.studio.HTMLGraphics.TransitionSettings.wipeRate diff --git a/src/tv2-common/videoSwitchers/TriCasterDveConverter.ts b/src/tv2-common/videoSwitchers/TriCasterDveConverter.ts new file mode 100644 index 00000000..c4d36cd3 --- /dev/null +++ b/src/tv2-common/videoSwitchers/TriCasterDveConverter.ts @@ -0,0 +1,13 @@ +import { TSR } from '../../../../tv-automation-server-core/packages/blueprints-integration' + +export interface TriCasterDveConverter { + convertPosition(x: number, y: number): TSR.TriCasterLayer['position'] + convertScale(scale: number): TSR.TriCasterLayer['scale'] + convertCrop(crop: { + cropped: boolean + cropTop: number + cropBottom: number + cropLeft: number + cropRight: number + }): TSR.TriCasterLayer['crop'] +} diff --git a/src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts b/src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts new file mode 100644 index 00000000..d6de02a5 --- /dev/null +++ b/src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts @@ -0,0 +1,66 @@ +import { TSR } from '../../../../tv-automation-server-core/packages/blueprints-integration/src' +import { TriCasterDveConverter } from './TriCasterDveConverter' + +const ATEM_WIDTH = 32 +const ATEM_HEIGHT = 18 + +const ATEM_CROP_LEFT_RIGHT_MAX_VALUE = 32000 +const ATEM_CROP_TOP_BOTTOM_MAX_VALUE = 18000 + +export class AtemToTricasterDveConverter implements TriCasterDveConverter { + public convertPosition(x: number, y: number): TSR.TriCasterLayer['position'] { + return { + x: this.convertPositionX(x), + y: this.convertPositionY(y) + } + } + + private convertPositionX(atemX: number): number { + const positionPercentage = atemX / ATEM_WIDTH + return (positionPercentage * ((2 / 9) * 16)) / 100 + } + + private convertPositionY(atemY: number): number { + const positionPercentage = atemY / ATEM_HEIGHT + return ((positionPercentage * 2) / 100) * -1 + } + + public convertScale(atemSize: number): TSR.TriCasterLayer['scale'] { + return { + x: atemSize / 1000, + y: atemSize / 1000 + } + } + + public convertCrop(crop: { + cropped: boolean + cropTop: number + cropBottom: number + cropLeft: number + cropRight: number + }): TSR.TriCasterLayer['crop'] { + if (!crop.cropped || this.isAllCropZero(crop)) { + return { + down: 0, + up: 0, + left: 0, + right: 0 + } + } + + return { + down: this.getPercentage(crop.cropBottom, ATEM_CROP_TOP_BOTTOM_MAX_VALUE), + up: this.getPercentage(crop.cropTop, ATEM_CROP_TOP_BOTTOM_MAX_VALUE), + left: this.getPercentage(crop.cropLeft, ATEM_CROP_LEFT_RIGHT_MAX_VALUE), + right: this.getPercentage(crop.cropRight, ATEM_CROP_LEFT_RIGHT_MAX_VALUE) + } + } + + private isAllCropZero(crop: { cropTop: number; cropBottom: number; cropLeft: number; cropRight: number }): boolean { + return crop.cropTop === 0 && crop.cropBottom === 0 && crop.cropLeft === 0 && crop.cropRight === 0 + } + + private getPercentage(part: number, whole: number): number { + return (part / whole) * 100 + } +} diff --git a/tslint.json b/tslint.json index 627f97d0..7bb1a398 100755 --- a/tslint.json +++ b/tslint.json @@ -7,6 +7,7 @@ "variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore", "require-const-for-all-caps"], "no-bitwise": false, "no-console": false, - "no-implicit-dependencies": [true, ["tv2-common", "tv2-constants", "inews-mixins", "blueprints-integration"]] + "no-implicit-dependencies": [true, ["tv2-common", "tv2-constants", "inews-mixins", "blueprints-integration"]], + "member-ordering": false } } From 3f8679497aeff1ce4791957ab59ea052bfe3d216 Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 23 Feb 2023 14:52:30 +0100 Subject: [PATCH 28/86] wip: SOF-1260 refactor leftovers also updated prettier and unfortunatelly some linting happened --- .prettierrc | 3 +- package.json | 2 +- src/__mocks__/context.ts | 20 +- src/inews-mixins/playlist.ts | 2 +- src/tv2-common/__tests__/frame-time.spec.ts | 24 +- .../__tests__/getshowStyleVariantId.spec.ts | 2 +- .../__tests__/onTimelineGenerate.spec.ts | 22 +- .../actions/CoreActionExecutionContext.ts | 4 +- src/tv2-common/actions/executeAction.ts | 124 ++--- src/tv2-common/blueprintConfig.ts | 1 - src/tv2-common/content/dve.ts | 9 +- src/tv2-common/content/jingle.ts | 6 +- src/tv2-common/content/server.ts | 4 +- src/tv2-common/cueTiming.ts | 17 +- src/tv2-common/cues/EvaluateCueRobotCamera.ts | 6 +- src/tv2-common/cues/dve.ts | 2 +- src/tv2-common/cues/lyd.ts | 12 +- src/tv2-common/cues/mixMinus.ts | 2 +- src/tv2-common/evaluateCues.ts | 4 +- src/tv2-common/getSegment.ts | 26 +- src/tv2-common/getShowStyleVariantId.ts | 4 +- .../helpers/__tests__/sisyfos.spec.ts | 10 +- src/tv2-common/helpers/abPlayback.ts | 46 +- src/tv2-common/helpers/config.ts | 2 +- src/tv2-common/helpers/dsk.ts | 38 +- src/tv2-common/helpers/graphics/Graphic.ts | 49 +- .../htmlPilotGraphicGenerator.spec.ts | 7 +- .../helpers/graphics/caspar/util.ts | 4 +- .../helpers/graphics/design/index.ts | 4 +- src/tv2-common/helpers/graphics/index.ts | 2 - .../graphics/internal/InternalGraphic.ts | 8 +- src/tv2-common/helpers/graphics/layers.ts | 2 +- src/tv2-common/helpers/graphics/name.ts | 24 - .../graphics/pilot/PilotGraphicGenerator.ts | 6 +- src/tv2-common/helpers/graphics/timing.ts | 8 - src/tv2-common/helpers/graphics/util.ts | 2 +- .../graphics/viz/VizPilotGraphicGenerator.ts | 4 +- .../helpers/postProcessDefinitions.ts | 4 +- src/tv2-common/helpers/rundownAdLibActions.ts | 4 +- src/tv2-common/helpers/serverResume.ts | 2 +- src/tv2-common/helpers/sisyfos.ts | 4 +- src/tv2-common/hotkeys/clear.ts | 2 +- .../inewsConversion/converters/ParseBody.ts | 48 +- .../inewsConversion/converters/ParseCue.ts | 24 +- .../converters/__tests__/body-parser.spec.ts | 6 +- src/tv2-common/jinglePartProperties.ts | 8 +- src/tv2-common/layers/timelineLayers.ts | 13 +- .../__tests__/dve-config-folder.spec.ts | 4 +- .../__tests__/migrationContext.mock.ts | 2 +- .../soundbed-config-audio-folder.spec.ts | 4 +- src/tv2-common/migrations/addKeepAudio.ts | 2 +- .../forceSourceLayerToDefaultsBase.ts | 4 +- src/tv2-common/migrations/hotkeys.ts | 6 +- src/tv2-common/migrations/index.ts | 125 +++-- .../migrations/renameConfigurationHelper.ts | 14 +- src/tv2-common/migrations/transitions.ts | 8 +- src/tv2-common/nextPartCue.ts | 2 +- src/tv2-common/onTimelineGenerate.ts | 20 +- src/tv2-common/parts/effekt.ts | 5 +- src/tv2-common/segment/context.ts | 3 +- src/tv2-common/sources.ts | 6 +- src/tv2-common/uniformConfig.ts | 47 +- src/tv2-common/updatePolicies/adlibs.ts | 4 +- .../updatePolicies/partProperties.ts | 2 +- src/tv2-common/updatePolicies/pieces.ts | 6 +- src/tv2-common/util.ts | 9 +- src/tv2-common/videoSwitchers/Atem.ts | 10 +- src/tv2-common/videoSwitchers/TriCaster.ts | 18 +- .../videoSwitchers/VideoSwitcher.ts | 24 +- .../videoSwitchers/__tests__/Atem.spec.ts | 1 - .../__tests__/TriCaster.spec.ts | 3 +- src/tv2-common/videoSwitchers/types.ts | 7 +- src/tv2-constants/enums.ts | 2 + .../GlobalAdlibActionsGenerator.ts | 354 ++++++++++++++ .../__tests__/actions.spec.ts | 14 +- .../__tests__/baseline.spec.ts | 15 +- .../__tests__/blueprint.spec.ts | 138 ++++-- .../__tests__/config-manifest.spec.ts | 2 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 5 +- .../__tests__/layers-check.ts | 27 +- .../__tests__/migrations-defaults.spec.ts | 4 +- .../__tests__/regressions.spec.ts | 10 +- .../__tests__/rundown_story_exception.spec.ts | 4 +- .../__tests__/transitions.spec.ts | 4 +- src/tv2_afvd_showstyle/config-manifests.ts | 4 +- src/tv2_afvd_showstyle/getRundown.ts | 446 +++--------------- src/tv2_afvd_showstyle/getSegment.ts | 4 +- src/tv2_afvd_showstyle/helpers/config.ts | 2 +- .../pieces/__tests__/grafikViz.spec.ts | 14 +- .../helpers/pieces/__tests__/telefon.spec.ts | 4 +- .../helpers/pieces/clearGrafiks.ts | 10 +- src/tv2_afvd_showstyle/helpers/pieces/dve.ts | 6 +- .../helpers/pieces/graphicBackgroundLoop.ts | 4 +- .../helpers/pieces/jingle.ts | 2 +- .../helpers/pieces/routing.ts | 4 +- .../helpers/pieces/telefon.ts | 2 +- src/tv2_afvd_showstyle/migrations/hotkeys.ts | 14 +- src/tv2_afvd_showstyle/migrations/index.ts | 2 +- src/tv2_afvd_showstyle/parts/grafik.ts | 4 +- src/tv2_afvd_showstyle/parts/intro.ts | 4 +- src/tv2_afvd_showstyle/parts/live.ts | 4 +- src/tv2_afvd_showstyle/parts/unknown.ts | 4 +- .../__tests__/config-manifest.spec.ts | 7 +- .../__tests__/graphics.spec.ts | 39 +- .../__tests__/migrations-defaults.spec.ts | 34 +- src/tv2_afvd_studio/config-manifests.ts | 8 - src/tv2_afvd_studio/getBaseline.ts | 47 +- src/tv2_afvd_studio/helpers/config.ts | 2 +- src/tv2_afvd_studio/helpers/sources.ts | 2 +- src/tv2_afvd_studio/layers.ts | 25 +- src/tv2_afvd_studio/migrations/devices.ts | 10 +- src/tv2_afvd_studio/migrations/index.ts | 41 +- .../migrations/mappings-defaults.ts | 47 -- src/tv2_afvd_studio/uniformConfig.ts | 31 +- .../__tests__/actions.spec.ts | 68 +-- .../__tests__/config-manifest.spec.ts | 2 +- .../__tests__/migrations-defaults.spec.ts | 4 +- src/tv2_offtube_showstyle/config-manifests.ts | 4 +- src/tv2_offtube_showstyle/cues/OfftubeDVE.ts | 6 +- .../cues/OfftubeGraphicBackgroundLoop.ts | 4 +- .../cues/OfftubeJingle.ts | 2 +- src/tv2_offtube_showstyle/getRundown.ts | 99 ++-- src/tv2_offtube_showstyle/helpers/config.ts | 6 +- .../migrations/hotkeys.ts | 12 +- src/tv2_offtube_showstyle/migrations/index.ts | 2 +- src/tv2_offtube_showstyle/migrations/util.ts | 2 +- .../onTimelineGenerate.ts | 2 +- .../parts/OfftubeUnknown.ts | 4 +- .../__tests__/config-manifest.spec.ts | 5 +- .../__tests__/migrations-defaults.spec.ts | 25 +- src/tv2_offtube_studio/getBaseline.ts | 31 +- src/tv2_offtube_studio/helpers/config.ts | 3 +- src/tv2_offtube_studio/helpers/sources.ts | 2 +- src/tv2_offtube_studio/layers.ts | 15 +- src/tv2_offtube_studio/migrations/devices.ts | 10 +- src/tv2_offtube_studio/migrations/index.ts | 48 +- src/tv2_offtube_studio/uniformConfig.ts | 28 +- src/tv2_system/migrations/hotkeys.ts | 2 +- yarn.lock | 8 +- 139 files changed, 1357 insertions(+), 1406 deletions(-) delete mode 100644 src/tv2-common/helpers/graphics/name.ts delete mode 100644 src/tv2-common/helpers/graphics/timing.ts create mode 100644 src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts diff --git a/.prettierrc b/.prettierrc index 875dbc23..455c22cb 100644 --- a/.prettierrc +++ b/.prettierrc @@ -2,5 +2,6 @@ "printWidth": 120, "semi": false, "singleQuote": true, - "useTabs": true + "useTabs": true, + "trailingComma": "none" } diff --git a/package.json b/package.json index b6227d1a..78a08677 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "jest-resolve": "^24.5.0", "license-checker": "^25.0.1", "moment": "^2.29.2", - "prettier": "^1.18.2", + "prettier": "^2.0.0", "standard-version": "9.1.1", "ts-jest": "^27.1.3", "ts-loader": "^6.2.1", diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index 17f21442..bf4bb8aa 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -309,8 +309,10 @@ export class SegmentUserContext extends RundownContext implements ISegmentUserCo } } -export class SyncIngestUpdateToPartInstanceContext extends RundownUserContext - implements ISyncIngestUpdateToPartInstanceContext { +export class SyncIngestUpdateToPartInstanceContext + extends RundownUserContext + implements ISyncIngestUpdateToPartInstanceContext +{ public syncedPieceInstances: string[] = [] public removedPieceInstances: string[] = [] public updatedPieceInstances: string[] = [] @@ -559,7 +561,7 @@ export class ActionExecutionContext extends ShowStyleUserContext implements ITV2 } this.nextPart = instance - this.nextPieceInstances = pieces.map>(p => ({ + this.nextPieceInstances = pieces.map>((p) => ({ _id: (Date.now() * Math.random()).toString(), piece: { _id: '', @@ -597,9 +599,9 @@ export class ActionExecutionContext extends ShowStyleUserContext implements ITV2 /** Remove piecesInstances by id. Returns ids of piecesInstances that were removed */ public async removePieceInstances(part: 'current' | 'next', pieceInstanceIds: string[]): Promise { if (part === 'current') { - this.currentPieceInstances = this.currentPieceInstances.filter(p => !pieceInstanceIds.includes(p._id)) + this.currentPieceInstances = this.currentPieceInstances.filter((p) => !pieceInstanceIds.includes(p._id)) } else if (this.nextPieceInstances) { - this.nextPieceInstances = this.nextPieceInstances.filter(p => !pieceInstanceIds.includes(p._id)) + this.nextPieceInstances = this.nextPieceInstances.filter((p) => !pieceInstanceIds.includes(p._id)) } return pieceInstanceIds @@ -646,9 +648,9 @@ export interface PartNote { // @ts-ignore class MockVideoSwitcher implements VideoSwitcher { - public getMixEffectTimelineObject = (properties: MixEffectProps) => (properties as any) as TSR.TSRTimelineObj - public getDskTimelineObjects = (properties: DskProps) => ([properties] as any) as TSR.TSRTimelineObj[] - public getAuxTimelineObject = (properties: AuxProps) => (properties as any) as TSR.TSRTimelineObj + public getMixEffectTimelineObject = (properties: MixEffectProps) => properties as any as TSR.TSRTimelineObj + public getDskTimelineObjects = (properties: DskProps) => [properties] as any as TSR.TSRTimelineObj[] + public getAuxTimelineObject = (properties: AuxProps) => properties as any as TSR.TSRTimelineObj } export interface MockConfigOverrides { @@ -672,10 +674,10 @@ export function makeMockCoreGalleryContext(overrides?: MockConfigOverrides) { export function makeMockGalleryContext(overrides?: MockConfigOverrides) { const mockCoreContext = makeMockCoreGalleryContext(overrides) + // @todo: this is not great, but it works const config = { ...(mockCoreContext.getStudioConfig() as any), ...(mockCoreContext.getShowStyleConfig() as any) } const mockContext: ExtendedSegmentContext = { core: mockCoreContext, - // @todo: this is awful, fix it perhaps by replacing defaultShowStyleConfig and defaultStudioConfig with preparsed config?! config, uniformConfig: { ...GALLERY_UNIFORM_CONFIG, ...overrides?.uniformConfig }, videoSwitcher: VideoSwitcherImpl.getVideoSwitcher(mockCoreContext, config, GALLERY_UNIFORM_CONFIG) // new MockVideoSwitcher() diff --git a/src/inews-mixins/playlist.ts b/src/inews-mixins/playlist.ts index fa8fb779..85ab1a33 100644 --- a/src/inews-mixins/playlist.ts +++ b/src/inews-mixins/playlist.ts @@ -42,7 +42,7 @@ export function getRundownWithBackTime( manifest: BlueprintResultRundown ): BlueprintResultRundown { const sortedSegments = ingestRundown.segments.sort((a, b) => a.rank - b.rank) - const firstContinuityStory = sortedSegments.find(segment => segment.name.match(/^\s*continuity\s*$/i)) + const firstContinuityStory = sortedSegments.find((segment) => segment.name.match(/^\s*continuity\s*$/i)) const backTime = firstContinuityStory ? firstContinuityStory.payload.iNewsStory.fields.backTime : undefined let expectedEnd: number | undefined diff --git a/src/tv2-common/__tests__/frame-time.spec.ts b/src/tv2-common/__tests__/frame-time.spec.ts index fc2bc24d..17d9a160 100644 --- a/src/tv2-common/__tests__/frame-time.spec.ts +++ b/src/tv2-common/__tests__/frame-time.spec.ts @@ -1,6 +1,6 @@ import { IBlueprintPiece, PieceLifespan } from 'blueprints-integration' import { CueType, SourceType } from 'tv2-constants' -import { CreateTimingEnable } from '../cueTiming' +import { getTimingEnable } from '../cueTiming' import { RemoteType, SourceDefinitionRemote } from '../inewsConversion' import { CueDefinitionEkstern } from '../inewsConversion/converters/ParseCue' import { literal } from '../util' @@ -23,7 +23,7 @@ describe('CreateTiming', () => { iNewsCommand: '', sourceDefinition: EKSTERN_SOURCE } - const result = CreateTimingEnable(time, 4000) + const result = getTimingEnable(time, 4000) expect(result).toEqual( literal>({ enable: { @@ -44,7 +44,7 @@ describe('CreateTiming', () => { iNewsCommand: '', sourceDefinition: EKSTERN_SOURCE } - const result = CreateTimingEnable(time, 4000) + const result = getTimingEnable(time, 4000) expect(result).toEqual( literal>({ enable: { @@ -66,7 +66,7 @@ describe('CreateTiming', () => { iNewsCommand: '', sourceDefinition: EKSTERN_SOURCE } - const result = CreateTimingEnable(time, 4000) + const result = getTimingEnable(time, 4000) expect(result).toEqual( literal>({ enable: { @@ -87,7 +87,7 @@ describe('CreateTiming', () => { iNewsCommand: '', sourceDefinition: EKSTERN_SOURCE } - const result = CreateTimingEnable(time, 4000) + const result = getTimingEnable(time, 4000) expect(result).toEqual( literal>({ enable: { @@ -108,7 +108,7 @@ describe('CreateTiming', () => { iNewsCommand: '', sourceDefinition: EKSTERN_SOURCE } - const result = CreateTimingEnable(time, 4000) + const result = getTimingEnable(time, 4000) expect(result).toEqual( literal>({ enable: { @@ -130,7 +130,7 @@ describe('CreateTiming', () => { iNewsCommand: '', sourceDefinition: EKSTERN_SOURCE } - const result = CreateTimingEnable(time, 4000) + const result = getTimingEnable(time, 4000) expect(result).toEqual( literal>({ enable: { @@ -151,7 +151,7 @@ describe('CreateTiming', () => { iNewsCommand: '', sourceDefinition: EKSTERN_SOURCE } - const result = CreateTimingEnable(time, 4000) + const result = getTimingEnable(time, 4000) expect(result).toEqual( literal>({ enable: { @@ -171,7 +171,7 @@ describe('CreateTiming', () => { iNewsCommand: '', sourceDefinition: EKSTERN_SOURCE } - const result = CreateTimingEnable(time, 4000) + const result = getTimingEnable(time, 4000) expect(result).toEqual( literal>({ enable: { @@ -191,7 +191,7 @@ describe('CreateTiming', () => { iNewsCommand: '', sourceDefinition: EKSTERN_SOURCE } - const result = CreateTimingEnable(time, 4000) + const result = getTimingEnable(time, 4000) expect(result).toEqual( literal>({ enable: { @@ -214,7 +214,7 @@ describe('CreateTiming', () => { iNewsCommand: '', sourceDefinition: EKSTERN_SOURCE } - const result = CreateTimingEnable(time, 4000) + const result = getTimingEnable(time, 4000) expect(result).toEqual( literal>({ enable: { @@ -238,7 +238,7 @@ describe('CreateTiming', () => { iNewsCommand: '', sourceDefinition: EKSTERN_SOURCE } - const result = CreateTimingEnable(time, 4000) + const result = getTimingEnable(time, 4000) expect(result).toEqual( literal>({ enable: { diff --git a/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts b/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts index 7c6f12d8..88f3265b 100644 --- a/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts +++ b/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts @@ -38,7 +38,7 @@ describe('getShowStyleVariantId', () => { ] if (variantNames) { variants.push( - ...variantNames.map(variantName => { + ...variantNames.map((variantName) => { return { _id: variantName, name: variantName, diff --git a/src/tv2-common/__tests__/onTimelineGenerate.spec.ts b/src/tv2-common/__tests__/onTimelineGenerate.spec.ts index 2ff4a58e..6e20cbed 100644 --- a/src/tv2-common/__tests__/onTimelineGenerate.spec.ts +++ b/src/tv2-common/__tests__/onTimelineGenerate.spec.ts @@ -22,7 +22,7 @@ describe('onTimelineGenerate', () => { const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) const indexOfLayerThatWantToBePersisted = result.content.channels.findIndex( - channel => channel.mappedLayer === LAYER_THAT_WANTS_TO_BE_PERSISTED + (channel) => channel.mappedLayer === LAYER_THAT_WANTS_TO_BE_PERSISTED ) expect(indexOfLayerThatWantToBePersisted).toBeGreaterThanOrEqual(0) }) @@ -108,13 +108,13 @@ describe('onTimelineGenerate', () => { const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, layersThatWantToBePersisted) expect( - result.content.channels.some(channel => channel.mappedLayer === firstLayerThatWantToBePersisted) + result.content.channels.some((channel) => channel.mappedLayer === firstLayerThatWantToBePersisted) ).toBeTruthy() expect( - result.content.channels.some(channel => channel.mappedLayer === secondLayerThatWantToBePersisted) + result.content.channels.some((channel) => channel.mappedLayer === secondLayerThatWantToBePersisted) ).toBeTruthy() expect( - result.content.channels.some(channel => channel.mappedLayer === thirdLayerThatWantToBePersisted) + result.content.channels.some((channel) => channel.mappedLayer === thirdLayerThatWantToBePersisted) ).toBeTruthy() }) @@ -138,9 +138,11 @@ describe('onTimelineGenerate', () => { const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) expect( - result.content.channels.some(channel => channel.mappedLayer === LAYER_THAT_WANTS_TO_BE_PERSISTED) + result.content.channels.some((channel) => channel.mappedLayer === LAYER_THAT_WANTS_TO_BE_PERSISTED) + ).toBeTruthy() + expect( + result.content.channels.some((channel) => channel.mappedLayer === resolvedPieces[0].piece.name) ).toBeTruthy() - expect(result.content.channels.some(channel => channel.mappedLayer === resolvedPieces[0].piece.name)).toBeTruthy() }) it('cuts to executionAction that accept from piece that dont accept, add persist timelineObject that only contain previous piece layers', () => { @@ -152,7 +154,9 @@ describe('onTimelineGenerate', () => { const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) expect(result.content.channels).toHaveLength(1) - expect(result.content.channels.some(channel => channel.mappedLayer === resolvedPieces[0].piece.name)).toBeTruthy() + expect( + result.content.channels.some((channel) => channel.mappedLayer === resolvedPieces[0].piece.name) + ).toBeTruthy() }) it('cuts to executeAction that accept persist from piece that dont want to persist and dont accept persist, dont persist any layers', () => { @@ -176,7 +180,7 @@ describe('onTimelineGenerate', () => { expect(result.content.channels).toHaveLength(1) expect( - result.content.channels.some(channel => channel.mappedLayer === LAYER_THAT_WANTS_TO_BE_PERSISTED) + result.content.channels.some((channel) => channel.mappedLayer === LAYER_THAT_WANTS_TO_BE_PERSISTED) ).toBeTruthy() }) @@ -259,7 +263,7 @@ describe('onTimelineGenerate', () => { const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, []) expect(result.content.channels).toHaveLength(1) - expect(result.content.channels.some(channel => channel.mappedLayer === 'firstPiece')).toBeTruthy() + expect(result.content.channels.some((channel) => channel.mappedLayer === 'firstPiece')).toBeTruthy() }) it('cuts from piece that wants to persist to executeAction that do not accept to another executeAction that accepts, dont persist any layers', () => { diff --git a/src/tv2-common/actions/CoreActionExecutionContext.ts b/src/tv2-common/actions/CoreActionExecutionContext.ts index a0cb8fd3..9d384ea2 100644 --- a/src/tv2-common/actions/CoreActionExecutionContext.ts +++ b/src/tv2-common/actions/CoreActionExecutionContext.ts @@ -190,11 +190,11 @@ export class CoreActionExecutionContext implements ITV2ActionExecutionContext { piece: Partial> ): Promise> { const currentPieceInstances = await this.core.getPieceInstances('current') - if (currentPieceInstances.map(p => p._id).includes(pieceInstanceId)) { + if (currentPieceInstances.map((p) => p._id).includes(pieceInstanceId)) { this.modifiedParts.add('current') } else { const nextPieceInstances = await this.core.getPieceInstances('next') - if (nextPieceInstances.map(p => p._id).includes(pieceInstanceId)) { + if (nextPieceInstances.map((p) => p._id).includes(pieceInstanceId)) { this.modifiedParts.add('next') } } diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 91a4b9db..182cae3d 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1,6 +1,5 @@ import { ActionUserData, - GraphicsContent, HackPartMediaObjectSubscription, IActionExecutionContext, IBlueprintActionManifest, @@ -25,7 +24,7 @@ import { ActionSelectDVELayout, ActionSelectFullGrafik, ActionSelectServerClip, - CalculateTime, + calculateTime, CreateDipTransitionBlueprintPieceForPart, CreateInTransitionForTransitionStyle, CreatePartServerBase, @@ -40,7 +39,6 @@ import { ExtendedActionExecutionContext, ExtendedShowStyleContext, GetDVETemplate, - GetEnableForWall, getServerPosition, GetSisyfosTimelineObjForCamera, GetSisyfosTimelineObjForRemote, @@ -181,7 +179,7 @@ export async function executeAction< userData: ActionUserData, triggerMode?: string ): Promise { - await executeWithContext(coreContext, uniformConfig, async context => { + await executeWithContext(coreContext, uniformConfig, async (context) => { const existingTransition = await getExistingTransition(context, settings, 'next') const actionId = actionIdStr as AdlibActionType @@ -289,7 +287,7 @@ async function getExistingTransition< ): Promise { const existingTransition = await context.core .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.Effekt)) + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === settings.SourceLayers.Effekt)) if (!existingTransition) { return @@ -359,8 +357,8 @@ export async function getPiecesToPreserve( ): Promise>> { const currentPartSegmentId = await context.core .getPartInstance('current') - .then(partInstance => partInstance?.segmentId) - const nextPartSegmentId = await context.core.getPartInstance('next').then(partInstance => partInstance?.segmentId) + .then((partInstance) => partInstance?.segmentId) + const nextPartSegmentId = await context.core.getPartInstance('next').then((partInstance) => partInstance?.segmentId) if (!currentPartSegmentId || !nextPartSegmentId) { return [] @@ -370,13 +368,13 @@ export async function getPiecesToPreserve( return [] } - return context.core.getPieceInstances('next').then(pieceInstances => { + return context.core.getPieceInstances('next').then((pieceInstances) => { return pieceInstances - .filter(p => adlibLayers.includes(p.piece.sourceLayerId) && !ignoreLayers.includes(p.piece.sourceLayerId)) - .filter(p => !p.infinite?.fromPreviousPart && !p.infinite?.fromPreviousPlayhead) - .map>(p => p.piece) - .map(p => sanitizePieceStart(p)) - .map(p => sanitizePieceId(p as IBlueprintPieceDB)) + .filter((p) => adlibLayers.includes(p.piece.sourceLayerId) && !ignoreLayers.includes(p.piece.sourceLayerId)) + .filter((p) => !p.infinite?.fromPreviousPart && !p.infinite?.fromPreviousPlayhead) + .map>((p) => p.piece) + .map((p) => sanitizePieceStart(p)) + .map((p) => sanitizePieceId(p as IBlueprintPieceDB)) }) } @@ -403,7 +401,7 @@ async function executeActionSelectServerClip< const currentPiece = settings.SelectedAdlibs ? await context.core .getPieceInstances('current') - .then(pieceInstances => pieceInstances.find(p => isServerOnPgm(p, settings, userData.voLayer))) + .then((pieceInstances) => pieceInstances.find((p) => isServerOnPgm(p, settings, userData.voLayer))) : undefined const basePart = await CreatePartServerBase( @@ -437,11 +435,11 @@ async function executeActionSelectServerClip< ) const activeServerPiece = basePart.part.pieces.find( - p => p.sourceLayerId === settings.SourceLayers.Server || p.sourceLayerId === settings.SourceLayers.VO + (p) => p.sourceLayerId === settings.SourceLayers.Server || p.sourceLayerId === settings.SourceLayers.VO ) const serverDataStore = basePart.part.pieces.find( - p => + (p) => p.sourceLayerId === settings.SelectedAdlibs.SourceLayer.Server || p.sourceLayerId === settings.SelectedAdlibs.SourceLayer.VO ) @@ -547,9 +545,9 @@ async function executeActionSelectDVE< externalId ) - let start = parsedCue.start ? CalculateTime(parsedCue.start) : 0 + let start = parsedCue.start ? calculateTime(parsedCue.start) : 0 start = start ? start : 0 - const end = parsedCue.end ? CalculateTime(parsedCue.end) : undefined + const end = parsedCue.end ? calculateTime(parsedCue.end) : undefined const metaData: DVEPieceMetaData = { mediaPlayerSessions: dveContainsServer(parsedCue.sources) ? [externalId] : [], @@ -630,9 +628,9 @@ async function cutServerToBox< if (newDvePiece.content?.timelineObjects) { const currentServer = await context.core .getPieceInstances('current') - .then(currentPieces => + .then((currentPieces) => currentPieces.find( - p => + (p) => p.piece.sourceLayerId === settings.SelectedAdlibs?.SourceLayer.Server || p.piece.sourceLayerId === settings.SelectedAdlibs?.SourceLayer.VO ) @@ -645,11 +643,11 @@ async function cutServerToBox< // Find existing CasparCG object const existingCasparObj = (currentServer.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => obj.layer === settings.LLayer.Caspar.ClipPending + (obj) => obj.layer === settings.LLayer.Caspar.ClipPending ) as TSR.TimelineObjCCGMedia & TimelineBlueprintExt // Find existing sisyfos object const existingSisyfosObj = (currentServer.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => obj.layer === settings.LLayer.Sisyfos.ClipPending + (obj) => obj.layer === settings.LLayer.Sisyfos.ClipPending ) as TSR.TimelineObjSisyfosChannel & TimelineBlueprintExt // Find DVE Boxes object in DVE piece const dveBoxesObj = currentServer.piece.content.timelineObjects.find(context.videoSwitcher.isDveBoxes) as @@ -726,9 +724,9 @@ async function executeActionSelectDVELayout< const nextDVE = (await context.core .getPieceInstances('next') - .then(nextPieceInstances => nextPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE))) as - | IBlueprintPieceInstance - | undefined + .then((nextPieceInstances) => + nextPieceInstances.find((p) => p.piece.sourceLayerId === settings.SourceLayers.DVE) + )) as IBlueprintPieceInstance | undefined const meta = nextDVE?.piece.metaData @@ -864,13 +862,13 @@ async function startNewDVELayout< // Take this timelineObjects: pieceContent.timelineObjects .filter( - tlObj => + (tlObj) => !( tlObj.content.deviceType === TSR.DeviceType.ATEM && // @todo: tricaster (tlObj as TSR.TimelineObjAtemAny).content.type === TSR.TimelineContentTypeAtem.ME ) && tlObj.content.deviceType !== TSR.DeviceType.SISYFOS ) - .map(obj => ({ ...obj, priority: obj.priority ?? 1 / 2 })) + .map((obj) => ({ ...obj, priority: obj.priority ?? 1 / 2 })) } } : undefined @@ -885,11 +883,11 @@ async function startNewDVELayout< const currentPieceInstances = await context.core.getPieceInstances('current') // If a DVE is not on air, but a layout is selected, stop the selected layout and replace with the new one. - const onAirPiece = currentPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE) + const onAirPiece = currentPieceInstances.find((p) => p.piece.sourceLayerId === settings.SourceLayers.DVE) const dataPiece = settings.SelectedAdlibs && - currentPieceInstances.find(p => p.piece.sourceLayerId === settings.SelectedAdlibs.SourceLayer.DVE) + currentPieceInstances.find((p) => p.piece.sourceLayerId === settings.SelectedAdlibs.SourceLayer.DVE) if (onAirPiece === undefined && dataPiece !== undefined) { await context.core.stopPieceInstances([dataPiece._id]) @@ -942,7 +940,7 @@ async function executeActionSelectJingle< const externalId = generateExternalId(context, actionId, [userData.clip]) - const jingle = context.config.showStyle.BreakerConfig.find(brkr => + const jingle = context.config.showStyle.BreakerConfig.find((brkr) => brkr.BreakerName ? brkr.BreakerName.toString().toUpperCase() === userData.clip.toUpperCase() : false ) if (!jingle) { @@ -1031,10 +1029,10 @@ async function executeActionCutToCamera< const currentPieceInstances = await context.core.getPieceInstances('current') const serverInCurrentPart = currentPieceInstances.some( - p => p.piece.sourceLayerId === settings.SourceLayers.Server || p.piece.sourceLayerId === settings.SourceLayers.VO + (p) => p.piece.sourceLayerId === settings.SourceLayers.Server || p.piece.sourceLayerId === settings.SourceLayers.VO ) - const currentKam = currentPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.Cam) + const currentKam = currentPieceInstances.find((p) => p.piece.sourceLayerId === settings.SourceLayers.Cam) const camSisyfos = GetSisyfosTimelineObjForCamera(context.config, sourceInfoCam, false) @@ -1091,7 +1089,7 @@ async function executeActionCutToCamera< } else { const currentExternalId = await context.core .getPartInstance('current') - .then(currentPartInstance => currentPartInstance?.part.externalId) + .then((currentPartInstance) => currentPartInstance?.part.externalId) if (currentExternalId) { kamPiece.externalId = currentExternalId @@ -1120,8 +1118,8 @@ async function stopGraphicPiecesThatShouldEndWithPart( ) { await context.core.stopPieceInstances( currentPieceInstances - .filter(pieceInstance => isGraphicThatShouldEndWithPart(pieceInstance)) - .map(pieceInstance => pieceInstance._id) + .filter((pieceInstance) => isGraphicThatShouldEndWithPart(pieceInstance)) + .map((pieceInstance) => pieceInstance._id) ) } @@ -1221,20 +1219,20 @@ async function executeActionCutSourceToBox< const nextPieces: IBlueprintPieceInstance[] = await context.core.getPieceInstances('next') const currentDVE = currentPieces.find( - p => + (p) => p.piece.sourceLayerId === settings.SourceLayers.DVE || (settings.SourceLayers.DVEAdLib && p.piece.sourceLayerId === settings.SourceLayers.DVEAdLib) ) const currentDataStore = currentPieces.find( - p => settings.SelectedAdlibs && p.piece.sourceLayerId === settings.SelectedAdlibs.SourceLayer.DVE + (p) => settings.SelectedAdlibs && p.piece.sourceLayerId === settings.SelectedAdlibs.SourceLayer.DVE ) const nextDVE = nextPieces.find( - p => + (p) => p.piece.sourceLayerId === settings.SourceLayers.DVE || (settings.SourceLayers.DVEAdLib && p.piece.sourceLayerId === settings.SourceLayers.DVEAdLib) ) const nextDataStore = nextPieces.find( - p => settings.SelectedAdlibs && p.piece.sourceLayerId === settings.SelectedAdlibs.SourceLayer.DVE + (p) => settings.SelectedAdlibs && p.piece.sourceLayerId === settings.SelectedAdlibs.SourceLayer.DVE ) let modify: undefined | 'current' | 'next' @@ -1321,7 +1319,7 @@ interface PiecesBySourceLayer { function groupPiecesBySourceLayer(pieceInstances: Array>): PiecesBySourceLayer { const piecesBySourceLayer: PiecesBySourceLayer = {} - pieceInstances.forEach(piece => { + pieceInstances.forEach((piece) => { if (!piecesBySourceLayer[piece.piece.sourceLayerId]) { piecesBySourceLayer[piece.piece.sourceLayerId] = [] } @@ -1353,38 +1351,6 @@ function findPrimaryPieceUsingPriority< return undefined } -async function applyPrerollToWallGraphics< - StudioConfig extends TV2StudioConfigBase, - ShowStyleConfig extends TV2BlueprintConfigBase ->( - context: ExtendedActionExecutionContext, - settings: ActionExecutionSettings, - piecesBySourceLayer: PiecesBySourceLayer -) { - const wallPieces = piecesBySourceLayer[settings.SourceLayers.Wall] - if (!wallPieces) { - return - } - const enable = GetEnableForWall() - for (const pieceInstance of wallPieces) { - if (pieceInstance.piece.content?.timelineObjects && !pieceInstance.infinite?.fromPreviousPart) { - const newPieceProps = { - content: pieceInstance.piece.content as WithTimeline - } - const timelineObjectsToUpdate = newPieceProps.content.timelineObjects.filter( - timelineObject => - timelineObject.layer === SharedGraphicLLayer.GraphicLLayerWall && - (timelineObject.content.deviceType === TSR.DeviceType.VIZMSE || - timelineObject.content.deviceType === TSR.DeviceType.CASPARCG) - ) - timelineObjectsToUpdate.forEach(timelineObject => { - timelineObject.enable = enable - }) - await context.core.updatePieceInstance(pieceInstance._id, newPieceProps) - } - } -} - async function executeActionTakeWithTransition< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase @@ -1417,7 +1383,7 @@ async function executeActionTakeWithTransition< return } - const existingEffektPiece = nextPieces.find(p => p.piece.sourceLayerId === settings.SourceLayers.Effekt) + const existingEffektPiece = nextPieces.find((p) => p.piece.sourceLayerId === settings.SourceLayers.Effekt) if (existingEffektPiece) { await context.core.removePieceInstances('next', [existingEffektPiece._id]) @@ -1472,7 +1438,7 @@ async function executeActionTakeWithTransition< if (partProps) { await context.core.updatePartInstance('next', partProps) - pieces.forEach(p => context.core.insertPiece('next', { ...p, tags: [GetTagForTransition(userData.variant)] })) + pieces.forEach((p) => context.core.insertPiece('next', { ...p, tags: [GetTagForTransition(userData.variant)] })) } break } @@ -1517,10 +1483,6 @@ async function executeActionTakeWithTransition< break } } - - if (partProps) { - await applyPrerollToWallGraphics(context, settings, nextPiecesBySourceLayer) - } } async function updateTransition( @@ -1544,9 +1506,9 @@ async function findPieceToRecoverDataFrom( const currentPieces = pieces[0] const nextPieces = pieces[1] - const currentServer = currentPieces.find(p => dataStoreLayers.includes(p.piece.sourceLayerId)) + const currentServer = currentPieces.find((p) => dataStoreLayers.includes(p.piece.sourceLayerId)) - const nextServer = nextPieces.find(p => dataStoreLayers.includes(p.piece.sourceLayerId)) + const nextServer = nextPieces.find((p) => dataStoreLayers.includes(p.piece.sourceLayerId)) let pieceToRecoverDataFrom: IBlueprintPieceInstance | undefined @@ -1842,7 +1804,7 @@ async function createFadeSisyfosLevelsMetaData(context: ExtendedActionExecutionC } const latestPiece = resolvedPieceInstances - .filter(piece => piece.piece.name !== FADE_SISYFOS_LEVELS_PIECE_NAME) + .filter((piece) => piece.piece.name !== FADE_SISYFOS_LEVELS_PIECE_NAME) .sort((a, b) => b.resolvedStart - a.resolvedStart)[0] const latestPieceMetaData = latestPiece.piece.metaData diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 74d27bd8..16c68346 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -106,7 +106,6 @@ export interface TV2StudioConfigBase { DSK: TableConfigItemDSK[] Dip: number } - TriCasterSettings: {} AtemSettings: {} StudioMics: string[] SourcesRM: TableConfigItemSourceMappingWithSisyfos[] diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index d07a20a2..8e676d9a 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -316,7 +316,7 @@ export function MakeContentDVE2< }, metaData: { mediaPlayerSession: hasServer ? mediaPlayerSessionId ?? MEDIA_PLAYER_AUTO : undefined - }, + } }), ...context.videoSwitcher.getOnAirTimelineObjects({ enable: { start: context.config.studio.CasparPrerollDuration }, @@ -406,7 +406,7 @@ const setBoxToBlack = (boxConfig: BoxConfig, boxSources: BoxSources) => { function makeBoxAssignments(inputs: string[], context: IShowStyleUserContext, sources: DVESources | undefined) { const boxAssignments: Array = [] - inputs.forEach(source => { + inputs.forEach((source) => { const sourceProps = source.split(':') const fromCue = sourceProps[1] const targetBox = Number(sourceProps[0]) @@ -433,10 +433,7 @@ function makeBoxAssignments(inputs: string[], context: IShowStyleUserContext, so return boxAssignments } -function boxSource(info: { - port: number - sourceLayerType: SourceLayerType -}): { +function boxSource(info: { port: number; sourceLayerType: SourceLayerType }): { switcherInput: number type: SourceLayerType } { diff --git a/src/tv2-common/content/jingle.ts b/src/tv2-common/content/jingle.ts index b024be60..97a8e1db 100644 --- a/src/tv2-common/content/jingle.ts +++ b/src/tv2-common/content/jingle.ts @@ -66,7 +66,7 @@ export function CreateJingleContentBase< ...getDskOnAirTimelineObjects(context, DSKRoles.JINGLE, { start: Number(config.studio.CasparPrerollDuration) }), // @todo: this is a Qbox-only feature, should be refactored at some point not to use ATEM object directly - ...(context.uniformConfig.SwitcherLLayers.JingleNextMixEffect + ...(context.uniformConfig.switcherLLayers.jingleNextMixEffect ? [ literal({ id: '', @@ -75,7 +75,7 @@ export function CreateJingleContentBase< duration: 1 }, priority: 1, - layer: context.uniformConfig.SwitcherLLayers.JingleNextMixEffect, + layer: context.uniformConfig.switcherLLayers.jingleNextMixEffect, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.ME, @@ -108,7 +108,7 @@ export function CreateJingleContentBase< start: 1 }, priority: 1, - layer: context.uniformConfig.SwitcherLLayers.JingleNextMixEffect, + layer: context.uniformConfig.switcherLLayers.jingleNextMixEffect, content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.ME, diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index b9951369..c8bd28bd 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -108,10 +108,10 @@ function GetServerTimeline( contentProps.mediaPlayerSession, audioEnable ), - ...(context.uniformConfig.SwitcherLLayers.NextServerAux + ...(context.uniformConfig.switcherLLayers.nextServerAux ? [ context.videoSwitcher.getAuxTimelineObject({ - layer: context.uniformConfig.SwitcherLLayers.NextServerAux, + layer: context.uniformConfig.switcherLLayers.nextServerAux, content: { input: -1 }, diff --git a/src/tv2-common/cueTiming.ts b/src/tv2-common/cueTiming.ts index f1056d28..add1e7d6 100644 --- a/src/tv2-common/cueTiming.ts +++ b/src/tv2-common/cueTiming.ts @@ -5,7 +5,7 @@ import { TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' const FRAME_TIME = 1000 / 25 // TODO: This should be pulled from config. -export function GetDefaultOut< +export function getDefaultOut< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >(config: ShowStyleConfig): number { @@ -16,10 +16,7 @@ export function GetDefaultOut< return 4 * 1000 } -export function CreateTimingEnable( - cue: CueDefinition, - defaultOut?: number -): Pick { +export function getTimingEnable(cue: CueDefinition, defaultOut?: number): Pick { const result: Pick = { enable: { start: 0 @@ -27,13 +24,13 @@ export function CreateTimingEnable( lifespan: PieceLifespan.WithinPart } - result.enable.start = (cue.start && CalculateTime(cue.start)) ?? 0 + result.enable.start = (cue.start && calculateTime(cue.start)) ?? 0 if (cue.end) { if (cue.end.infiniteMode) { - result.lifespan = LifeSpan(cue.end.infiniteMode) + result.lifespan = getLifeSpan(cue.end.infiniteMode) } else { - const end = CalculateTime(cue.end) + const end = calculateTime(cue.end) result.enable.duration = end ? end - result.enable.start : undefined } } else if (defaultOut !== undefined) { @@ -43,7 +40,7 @@ export function CreateTimingEnable( return result } -export function LifeSpan(mode: 'B' | 'S' | 'O'): PieceLifespan { +export function getLifeSpan(mode: 'B' | 'S' | 'O'): PieceLifespan { switch (mode) { case 'B': return PieceLifespan.WithinPart @@ -54,7 +51,7 @@ export function LifeSpan(mode: 'B' | 'S' | 'O'): PieceLifespan { } } -export function CalculateTime(time: CueTime): number | undefined { +export function calculateTime(time: CueTime): number | undefined { if (time.infiniteMode) { return } diff --git a/src/tv2-common/cues/EvaluateCueRobotCamera.ts b/src/tv2-common/cues/EvaluateCueRobotCamera.ts index 8cf731f2..2e24ac96 100644 --- a/src/tv2-common/cues/EvaluateCueRobotCamera.ts +++ b/src/tv2-common/cues/EvaluateCueRobotCamera.ts @@ -1,6 +1,6 @@ import { IBlueprintPiece, TSR } from 'blueprints-integration' import { SharedSourceLayers } from '../../tv2-constants' -import { CalculateTime } from '../cueTiming' +import { calculateTime } from '../cueTiming' import { CueDefinitionRobotCamera } from '../inewsConversion' import { createTelemetricsPieceForRobotCamera, ROBOT_CAMERA_NAME_PREFIX } from '../pieces/telemetric' @@ -9,7 +9,7 @@ export function EvaluateCueRobotCamera( pieces: IBlueprintPiece[], externalId: string ): void { - const startTime: number = cueDefinition.start ? CalculateTime(cueDefinition.start) ?? 0 : 0 + const startTime: number = cueDefinition.start ? calculateTime(cueDefinition.start) ?? 0 : 0 const existingPiece = findExistingPieceForRobotCameraLayerAndStartTime(pieces, startTime) if (!existingPiece) { @@ -28,7 +28,7 @@ function findExistingPieceForRobotCameraLayerAndStartTime( startTime: number ): IBlueprintPiece | undefined { return pieces.find( - piece => + (piece) => piece.sourceLayerId === SharedSourceLayers.RobotCamera && piece.name.startsWith(ROBOT_CAMERA_NAME_PREFIX) && piece.enable.start === startTime diff --git a/src/tv2-common/cues/dve.ts b/src/tv2-common/cues/dve.ts index 630ded0a..a39668c5 100644 --- a/src/tv2-common/cues/dve.ts +++ b/src/tv2-common/cues/dve.ts @@ -71,5 +71,5 @@ export function TemplateIsValid(templateRaw: string): boolean { } export function GetDVETemplate(config: DVEConfigInput[], templateName: string): DVEConfigInput | undefined { - return config ? config.find(c => c.DVEName.toString().toUpperCase() === templateName.toUpperCase()) : undefined + return config ? config.find((c) => c.DVEName.toString().toUpperCase() === templateName.toUpperCase()) : undefined } diff --git a/src/tv2-common/cues/lyd.ts b/src/tv2-common/cues/lyd.ts index 3e849e2d..22e7bc8b 100644 --- a/src/tv2-common/cues/lyd.ts +++ b/src/tv2-common/cues/lyd.ts @@ -9,9 +9,9 @@ import { WithTimeline } from 'blueprints-integration' import { - CreateTimingEnable, CueDefinitionLYD, ExtendedShowStyleContext, + getTimingEnable, joinAssetToFolder, literal, PartDefinition, @@ -38,7 +38,7 @@ export function EvaluateLYD( adlib?: boolean, rank?: number ) { - const conf = context.config.showStyle.LYDConfig.find(lyd => + const conf = context.config.showStyle.LYDConfig.find((lyd) => lyd.INewsName ? lyd.INewsName.toString().toUpperCase() === parsedCue.variant.toUpperCase() : false ) const stop = !!parsedCue.variant.match(/^[^_]*STOP[^_]*$/i) // TODO: STOP 1 / STOP 2 etc. @@ -69,7 +69,7 @@ export function EvaluateLYD( ? 2000 : fade ? Math.max(1000, fadeIn ? TimeFromFrames(fadeIn) : 0) - : CreateTimingEnable(parsedCue).enable.duration ?? undefined, + : getTimingEnable(parsedCue).enable.duration ?? undefined, content: LydContent(context.config, file, lydType, fadeIn, fadeOut), tags: [AdlibTags.ADLIB_FLOW_PRODUCER] }) @@ -78,15 +78,15 @@ export function EvaluateLYD( externalId: part.externalId, name: parsedCue.variant, ...(stop - ? { enable: { start: CreateTimingEnable(parsedCue).enable.start, duration: 2000 } } + ? { enable: { start: getTimingEnable(parsedCue).enable.start, duration: 2000 } } : fade ? { enable: { - start: CreateTimingEnable(parsedCue).enable.start, + start: getTimingEnable(parsedCue).enable.start, duration: Math.max(1000, fadeIn ? TimeFromFrames(fadeIn) : 0) } } - : CreateTimingEnable(parsedCue)), + : getTimingEnable(parsedCue)), outputLayerId: SharedOutputLayers.MUSIK, sourceLayerId: SharedSourceLayers.PgmAudioBed, lifespan, diff --git a/src/tv2-common/cues/mixMinus.ts b/src/tv2-common/cues/mixMinus.ts index 4b5486ec..4de582e9 100644 --- a/src/tv2-common/cues/mixMinus.ts +++ b/src/tv2-common/cues/mixMinus.ts @@ -8,7 +8,7 @@ export function EvaluateCueMixMinus( part: PartDefinition, parsedCue: CueDefinitionMixMinus ) { - if (!context.uniformConfig.SwitcherLLayers.MixMinusAux) { + if (!context.uniformConfig.switcherLLayers.mixMinusAux) { context.core.notifyUserWarning(`Mix-Minus out not available in this studio (MINUSKAM)`) return } diff --git a/src/tv2-common/evaluateCues.ts b/src/tv2-common/evaluateCues.ts index 3c58d97d..d7d27ab8 100644 --- a/src/tv2-common/evaluateCues.ts +++ b/src/tv2-common/evaluateCues.ts @@ -206,7 +206,7 @@ export async function EvaluateCuesBase( context.config.studio.PreventOverlayWithFull && GraphicIsPilot(cue) && IsTargetingOVL(cue.target) && - cues.some(c => c.type === CueType.Graphic && GraphicIsPilot(c) && IsTargetingFull(c.target)) + cues.some((c) => c.type === CueType.Graphic && GraphicIsPilot(c) && IsTargetingFull(c.target)) ) { context.core.notifyUserWarning(`Cannot create overlay graphic with FULL`) break @@ -372,7 +372,7 @@ export async function EvaluateCuesBase( pieces.push(...result.pieces) adLibPieces.push(...result.adlibPieces) actions.push(...result.actions) - ;[...pieces, ...adLibPieces].forEach(piece => { + ;[...pieces, ...adLibPieces].forEach((piece) => { if (piece.content && piece.content.timelineObjects) { piece.content.timelineObjects.forEach((obj: TSR.TSRTimelineObj) => { if (obj.content.deviceType === TSR.DeviceType.VIZMSE) { diff --git a/src/tv2-common/getSegment.ts b/src/tv2-common/getSegment.ts index 6bf6d6b0..b9c15ff6 100644 --- a/src/tv2-common/getSegment.ts +++ b/src/tv2-common/getSegment.ts @@ -149,18 +149,18 @@ export async function getSegmentBase if ( GetNextPartCue(part, -1) === -1 && part.type === PartType.Unknown && - part.cues.filter(cue => cue.type === CueType.Jingle || cue.type === CueType.AdLib).length === 0 + part.cues.filter((cue) => cue.type === CueType.Jingle || cue.type === CueType.AdLib).length === 0 ) { blueprintParts.push(await showStyleOptions.CreatePartUnknown(context, part, totalWords, true)) continue } const unpairedTargets = part.cues.filter( - c => c.type === CueType.UNPAIRED_TARGET && IsTargetingFull(c.target) + (c) => c.type === CueType.UNPAIRED_TARGET && IsTargetingFull(c.target) ) as CueDefinitionUnpairedTarget[] if (unpairedTargets.length) { blueprintParts.push(CreatePartInvalid(part)) - unpairedTargets.forEach(cue => { + unpairedTargets.forEach((cue) => { context.core.notifyUserWarning(`No graphic found after ${cue.iNewsCommand} cue`) }) continue @@ -245,7 +245,7 @@ export async function getSegmentBase break } - if (part.cues.filter(cue => cue.type === CueType.Jingle).length) { + if (part.cues.filter((cue) => cue.type === CueType.Jingle).length) { if (blueprintParts[blueprintParts.length - 1]) { const t = blueprintParts[blueprintParts.length - 1].part.expectedDuration if (t) { @@ -269,7 +269,7 @@ export async function getSegmentBase 0 ) - blueprintParts.forEach(part => { + blueprintParts.forEach((part) => { // part.part.displayDurationGroup = ingestSegment.externalId if (!part.part.expectedDuration && totalTimeMs > 0) { @@ -287,7 +287,7 @@ export async function getSegmentBase let extraTime = totalTimeMs - blueprintParts.forEach(part => { + blueprintParts.forEach((part) => { if (part.part.expectedDuration === undefined || part.part.expectedDuration < 0) { part.part.expectedDuration = extraTime > config.studio.DefaultPartDuration @@ -305,7 +305,7 @@ export async function getSegmentBase }) if ( - blueprintParts.filter(part => part.pieces.length === 0 && (part.adLibPieces.length || part.actions?.length)) + blueprintParts.filter((part) => part.pieces.length === 0 && (part.adLibPieces.length || part.actions?.length)) .length === blueprintParts.length ) { segment.isHidden = true @@ -314,7 +314,7 @@ export async function getSegmentBase } } - if (blueprintParts.find(part => part.adLibPieces.length || part.actions?.length)) { + if (blueprintParts.find((part) => part.adLibPieces.length || part.actions?.length)) { segment.showShelf = true } @@ -323,29 +323,29 @@ export async function getSegmentBase blueprintParts.length > 1 || (blueprintParts[blueprintParts.length - 1] && !blueprintParts[blueprintParts.length - 1].pieces.some( - piece => piece.sourceLayerId === SharedSourceLayers.PgmJingle + (piece) => piece.sourceLayerId === SharedSourceLayers.PgmJingle )) ) { blueprintParts[0].part.budgetDuration = totalTimeMs } - if (blueprintParts.every(part => part.part.invalid) && iNewsStory.cues.length === 0) { + if (blueprintParts.every((part) => part.part.invalid) && iNewsStory.cues.length === 0) { segment.isHidden = true } - blueprintParts.forEach(part => { + blueprintParts.forEach((part) => { if ( part.part.expectedDuration! < config.studio.DefaultPartDuration && // Jingle-only part, do not modify duration !part.pieces.some( - p => p.sourceLayerId === SharedSourceLayers.PgmJingle && p.tags?.some(tag => TallyTags.JINGLE === tag) + (p) => p.sourceLayerId === SharedSourceLayers.PgmJingle && p.tags?.some((tag) => TallyTags.JINGLE === tag) ) ) { part.part.expectedDuration = config.studio.DefaultPartDuration } }) - blueprintParts = blueprintParts.map(part => { + blueprintParts = blueprintParts.map((part) => { const actualPart = part.part actualPart.metaData = literal({ ...(actualPart.metaData as any), diff --git a/src/tv2-common/getShowStyleVariantId.ts b/src/tv2-common/getShowStyleVariantId.ts index 35a684b2..47c6ac10 100644 --- a/src/tv2-common/getShowStyleVariantId.ts +++ b/src/tv2-common/getShowStyleVariantId.ts @@ -9,8 +9,8 @@ export function getShowStyleVariantId( ): string | null { const ingestVariantName = ingestRundown.payload?.showstyleVariant?.trim().toLowerCase() const showStyleVariant = - showStyleVariants.find(variant => variant.name?.trim().toLowerCase() === ingestVariantName) ?? - showStyleVariants.find(variant => variant.name?.trim().toLowerCase() === DEFAULT_VARIANT_NAME) + showStyleVariants.find((variant) => variant.name?.trim().toLowerCase() === ingestVariantName) ?? + showStyleVariants.find((variant) => variant.name?.trim().toLowerCase() === DEFAULT_VARIANT_NAME) return showStyleVariant?._id ?? null } diff --git a/src/tv2-common/helpers/__tests__/sisyfos.spec.ts b/src/tv2-common/helpers/__tests__/sisyfos.spec.ts index 986a4560..9e47369a 100644 --- a/src/tv2-common/helpers/__tests__/sisyfos.spec.ts +++ b/src/tv2-common/helpers/__tests__/sisyfos.spec.ts @@ -37,7 +37,7 @@ describe('Sisyfos', () => { } const timelineObjects = GetSisyfosTimelineObjForCamera(config, sourceInfo, false) expect(timelineObjects.length).toBe(3) - const studioMicsTimelineObject = timelineObjects.find(t => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) + const studioMicsTimelineObject = timelineObjects.find((t) => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) expect(studioMicsTimelineObject).toBeDefined() }) it('Does not enable studio mics for "minus mic" cameras', () => { @@ -51,7 +51,7 @@ describe('Sisyfos', () => { } const timelineObjects = GetSisyfosTimelineObjForCamera(config, sourceInfo, true) expect(timelineObjects.length).toBe(2) - const studioMicsTimelineObject = timelineObjects.find(t => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) + const studioMicsTimelineObject = timelineObjects.find((t) => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) expect(studioMicsTimelineObject).toBeUndefined() }) it('Enables audio layers for remotes', () => { @@ -81,7 +81,7 @@ describe('Sisyfos', () => { } const timelineObjects = GetSisyfosTimelineObjForRemote(config, sourceInfo) expect(timelineObjects.length).toBe(3) - const studioMicsTimelineObject = timelineObjects.find(t => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) + const studioMicsTimelineObject = timelineObjects.find((t) => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) expect(studioMicsTimelineObject).toBeDefined() }) it('Enables audio layers for replay', () => { @@ -110,7 +110,7 @@ describe('Sisyfos', () => { useStudioMics: false } const timelineObjects = GetSisyfosTimelineObjForReplay(config, sourceInfo, true) - const layersTimelineObjects = timelineObjects.filter(t => t.layer !== SharedSisyfosLLayer.SisyfosGroupStudioMics) + const layersTimelineObjects = timelineObjects.filter((t) => t.layer !== SharedSisyfosLLayer.SisyfosGroupStudioMics) expect(layersTimelineObjects.length).toBe(2) expect(layersTimelineObjects[0].layer).toBe('some_layer') expect((layersTimelineObjects[0] as TSR.TimelineObjSisyfosChannel).content.isPgm).toBe(2) @@ -128,7 +128,7 @@ describe('Sisyfos', () => { } const timelineObjects = GetSisyfosTimelineObjForReplay(config, sourceInfo, true) expect(timelineObjects.length).toBe(3) - const studioMicsTimelineObject = timelineObjects.find(t => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) + const studioMicsTimelineObject = timelineObjects.find((t) => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) expect(studioMicsTimelineObject).toBeDefined() }) }) diff --git a/src/tv2-common/helpers/abPlayback.ts b/src/tv2-common/helpers/abPlayback.ts index ae681add..1e210e25 100644 --- a/src/tv2-common/helpers/abPlayback.ts +++ b/src/tv2-common/helpers/abPlayback.ts @@ -33,7 +33,7 @@ function reversePreviousAssignment( const previousAssignmentRev: { [sessionId: string]: MediaPlayerClaim | undefined } = {} for (const key of _.keys(previousAssignment)) { for (const v2 of previousAssignment[key] || []) { - if (timeline.some(obj => obj.metaData && (obj.metaData as any).mediaPlayerSession === v2.sessionId)) { + if (timeline.some((obj) => obj.metaData && (obj.metaData as any).mediaPlayerSession === v2.sessionId)) { previousAssignmentRev[v2.sessionId] = v2 } } @@ -65,7 +65,7 @@ interface SessionTime { duration: number | undefined } function calculateSessionTimeRanges(resolvedPieces: Array>) { - const piecesWantingMediaPlayers = _.filter(resolvedPieces, p => { + const piecesWantingMediaPlayers = _.filter(resolvedPieces, (p) => { if (!p.piece.metaData) { return false } @@ -73,14 +73,14 @@ function calculateSessionTimeRanges(resolvedPieces: Array { + _.each(piecesWantingMediaPlayers, (p) => { const metadata = p.piece.metaData! const start = p.resolvedStart const duration = p.resolvedDuration const end = duration !== undefined ? start + duration : undefined // Track the range of each session - _.each(metadata.mediaPlayerSessions || [], sessionId => { + _.each(metadata.mediaPlayerSessions || [], (sessionId) => { // TODO - will fixed ids ever be wanted? Is it reasonable to want to have the same session across multiple pieces? // Infinites are the exception here, but anything else? // Perhaps the id given should be prefixed with the piece(instance) id? And sharing sessions can be figured out when it becomes needed @@ -112,7 +112,7 @@ function findNextAvailablePlayer< ShowStyleConfig extends TV2BlueprintConfigBase >(config: ShowStyleConfig, inUse: ActiveRequest[], req: ActiveRequest) { const pickFirstNotInUse = (inUseRequests: ActiveRequest[]) => { - const inUseIds = _.compact(_.map(inUseRequests, r => r.player)) + const inUseIds = _.compact(_.map(inUseRequests, (r) => r.player)) for (const mp of config.mediaPlayers) { if (inUseIds.indexOf(mp.id) === -1) { return mp.id @@ -130,14 +130,14 @@ function findNextAvailablePlayer< } // Try reclaiming any lookahead - const allActiveUses = _.filter(filteredInUse, r => r.type !== MediaPlayerClaimType.Preloaded) + const allActiveUses = _.filter(filteredInUse, (r) => r.type !== MediaPlayerClaimType.Preloaded) mpId = pickFirstNotInUse(allActiveUses) if (mpId !== undefined) { return mpId } // Is there something ending at the same time this starts? - const activeUsesNotEndingNow = _.filter(filteredInUse, r => r.end === undefined || r.end > req.start) + const activeUsesNotEndingNow = _.filter(filteredInUse, (r) => r.end === undefined || r.end > req.start) mpId = pickFirstNotInUse(activeUsesNotEndingNow) if (mpId !== undefined) { return mpId @@ -207,7 +207,7 @@ export function resolveMediaPlayerAssignments< }) } } - _.sortBy(activeRequests, r => r.start) + _.sortBy(activeRequests, (r) => r.start) // Go through and assign players context.core.logDebug('all reqs' + JSON.stringify(activeRequests, undefined, 4)) @@ -219,7 +219,7 @@ export function resolveMediaPlayerAssignments< continue } - const otherActive = _.filter(activeRequests, r => doesRequestOverlap(req, r)) + const otherActive = _.filter(activeRequests, (r) => doesRequestOverlap(req, r)) context.core.logDebug(`for ${JSON.stringify(req)} there is: ${JSON.stringify(otherActive, undefined, 4)}`) @@ -268,7 +268,7 @@ function updateObjectsToMediaPlayer< // context.notifyUserWarning(obj) } } else if (context.videoSwitcher.isVideoSwitcherTimelineObject(obj)) { - let switcherInput = _.find(context.config.mediaPlayers, mp => mp.id === playerId.toString()) + let switcherInput = _.find(context.config.mediaPlayers, (mp) => mp.id === playerId.toString()) if (!switcherInput) { context.core.logWarning(`Trying to find atem input for unknown mediaPlayer: #${playerId}`) switcherInput = { id: playerId.toString(), val: context.config.studio.SwitcherSource.Default.toString() } @@ -277,8 +277,8 @@ function updateObjectsToMediaPlayer< if (context.videoSwitcher.isMixEffect(obj)) { // the `endsWith` below is a nasty hack, but this will be gone after AB refactor if ( - context.uniformConfig.SwitcherLLayers.NextPreviewMixEffect && - obj.layer.toString().endsWith(context.uniformConfig.SwitcherLLayers.NextPreviewMixEffect) + context.uniformConfig.switcherLLayers.nextPreviewMixEffect && + obj.layer.toString().endsWith(context.uniformConfig.switcherLLayers.nextPreviewMixEffect) ) { context.videoSwitcher.updatePreviewInput(obj, input) } else { @@ -366,12 +366,12 @@ export function applyMediaPlayersAssignments< // collect objects by their sessionId const labelledObjs = (timelineObjs as Array).filter( - o => o.metaData && o.metaData.mediaPlayerSession + (o) => o.metaData && o.metaData.mediaPlayerSession ) - const groupedObjs = _.groupBy(labelledObjs, o => { + const groupedObjs = _.groupBy(labelledObjs, (o) => { const sessionId = (o.metaData || {}).mediaPlayerSession if (sessionId === undefined || sessionId === '' || sessionId === MEDIA_PLAYER_AUTO) { - const piece = resolvedPieces.find(p => p._id === o.pieceInstanceId) + const piece = resolvedPieces.find((p) => p._id === o.pieceInstanceId) return piece?.infinite?.infinitePieceId || o.pieceInstanceId || MEDIA_PLAYER_AUTO } else { return sessionId @@ -382,7 +382,7 @@ export function applyMediaPlayersAssignments< const remainingGroups: Array<{ id: string; objs: Array }> = [] for (const groupId of Object.keys(groupedObjs)) { const group = groupedObjs[groupId] - const request = _.find(activeRequests, req => req.id === groupId) + const request = _.find(activeRequests, (req) => req.id === groupId) if (request) { if (request.player) { // TODO - what if player is undefined? @@ -403,7 +403,7 @@ export function applyMediaPlayersAssignments< // If this is lookahead for a future part (no end set on the object) const isFuturePartLookahead = _.some( grp.objs, - o => + (o) => !!o.isLookahead /*|| (o as any).wasLookahead*/ && (o.enable as TSR.Timeline.TimelineEnable).duration === undefined && (o.enable as TSR.Timeline.TimelineEnable).end === undefined @@ -417,7 +417,7 @@ export function applyMediaPlayersAssignments< // These are the groups that shouldn't exist, so are likely a bug. There isnt a lot we can do beyond warn about the potential bug for (const grp of unknownGroups) { - const objIds = _.map(grp.objs, o => o.id) + const objIds = _.map(grp.objs, (o) => o.id) const prev = previousAssignmentRev[grp.id] if (prev) { updateObjectsToMediaPlayer(context, prev.playerId, grp.objs, sourceLayers) @@ -441,10 +441,10 @@ export function applyMediaPlayersAssignments< for (const mp of context.config.mediaPlayers) { // Block players with an 'infinite' clip from being used for lookahead const endTimes = _.map( - _.filter(activeRequests, s => s.player === mp.id), - s => s.end + _.filter(activeRequests, (s) => s.player === mp.id), + (s) => s.end ) - const realEndTimes = _.filter(endTimes, e => e !== undefined) as number[] + const realEndTimes = _.filter(endTimes, (e) => e !== undefined) as number[] if (endTimes.length === realEndTimes.length) { // No infinite(undefined) ones, so find the highest end mediaPlayerUsageEnd.push({ @@ -454,7 +454,7 @@ export function applyMediaPlayersAssignments< } } // Sort by the end time - mediaPlayerUsageEnd = _.sortBy(mediaPlayerUsageEnd, u => u.end).reverse() + mediaPlayerUsageEnd = _.sortBy(mediaPlayerUsageEnd, (u) => u.end).reverse() // Finish up with allocating lookahead based on what is left. If there is no space left that is not a problem until playback is closer for (const grp of lookaheadGroups) { @@ -464,7 +464,7 @@ export function applyMediaPlayersAssignments< context.core.logDebug('Players are available at:' + JSON.stringify(mediaPlayerUsageEnd)) - const prevAssignment = prev ? _.find(mediaPlayerUsageEnd, mp => mp.playerId === prev.playerId) : undefined + const prevAssignment = prev ? _.find(mediaPlayerUsageEnd, (mp) => mp.playerId === prev.playerId) : undefined if (prevAssignment && (prevAssignment.end === 0 || false)) { // TODO - decide if the previous assignment is still suitable context.core.logDebug('lookahead can retain existing player') diff --git a/src/tv2-common/helpers/config.ts b/src/tv2-common/helpers/config.ts index fd9c2cb6..ca7d4151 100644 --- a/src/tv2-common/helpers/config.ts +++ b/src/tv2-common/helpers/config.ts @@ -18,7 +18,7 @@ export function findGfxSetup tableConfigGfxSetup.Name === config.SelectedGfxSetupName + (tableConfigGfxSetup) => tableConfigGfxSetup.Name === config.SelectedGfxSetupName ) if (!foundTableConfigGfxSetup) { context.logWarning(`No GFX setup found for profile: ${config.SelectedGfxSetupName}`) diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index 67f3befc..fbeaf5ed 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -6,7 +6,7 @@ import { TableConfigItemValue, TSR } from 'blueprints-integration' -import { ExtendedShowStyleContext, literal, LLayerDSK, SourceLayerAtemDSK, VideoSwitcher } from 'tv2-common' +import { ExtendedShowStyleContext, getDskLLayerName, literal, SourceLayerAtemDSK, VideoSwitcher } from 'tv2-common' import { AdlibTags, DSKRoles, SharedOutputLayers } from 'tv2-constants' import { ATEMModel } from '../../types/atem' import { TV2BlueprintConfigBase, TV2ShowStyleConfig, TV2StudioConfigBase } from '../blueprintConfig' @@ -25,7 +25,7 @@ export function FindDSKJingle(config: TV2ShowStyleConfig): TableConfigItemDSK { } function FindDSKWithRoles(config: TV2ShowStyleConfig, roles: DSKRoles[]): TableConfigItemDSK { - return config.dsk.find(dsk => dsk.Roles?.some(role => roles.includes(role))) ?? config.dsk[0] + return config.dsk.find((dsk) => dsk.Roles?.some((role) => roles.includes(role))) ?? config.dsk[0] } export function GetDSKCount(atemModel: ATEMModel) { @@ -49,25 +49,24 @@ export function getDskOnAirTimelineObjects( const dskConf = FindDSKWithRoles(context.config, [dskRole]) return [ context.videoSwitcher.getDskTimelineObject({ - id: '', enable: enable ?? { start: 0 }, priority: 1, - layer: LLayerDSK(dskConf.Number), + layer: getDskLLayerName(dskConf.Number), content: { onAir: true, config: dskConf } }), - ...(dskRole === DSKRoles.JINGLE && context.uniformConfig.SwitcherLLayers.JingleUskMixEffect + ...(dskRole === DSKRoles.JINGLE && context.uniformConfig.switcherLLayers.jingleUskMixEffect ? [ context.videoSwitcher.getMixEffectTimelineObject({ enable: enable ?? { start: 0 }, priority: 1, - layer: context.uniformConfig.SwitcherLLayers.JingleUskMixEffect, + layer: context.uniformConfig.switcherLLayers.jingleUskMixEffect, content: { keyers: [ { @@ -103,10 +102,9 @@ export function CreateDSKBaselineAdlibs( content: { timelineObjects: [ videoSwitcher.getDskTimelineObject({ - id: '', enable: { while: '1' }, priority: 10, - layer: LLayerDSK(dsk.Number), + layer: getDskLLayerName(dsk.Number), content: { onAir: false, config: dsk @@ -130,7 +128,7 @@ export function CreateDSKBaselineAdlibs( id: '', enable: { while: '1' }, priority: 10, - layer: LLayerDSK(dsk.Number), // @todo + layer: getDskLLayerName(dsk.Number), content: { onAir: true, config: dsk @@ -149,12 +147,12 @@ export function createDskBaseline( config: TV2BlueprintConfigBase, videoSwitcher: VideoSwitcher ): TSR.TSRTimelineObj[] { - return config.dsk.map(dsk => { + return config.dsk.map((dsk) => { return videoSwitcher.getDskTimelineObject({ id: '', enable: { while: '1' }, priority: 0, - layer: LLayerDSK(dsk.Number), // @todo + layer: getDskLLayerName(dsk.Number), content: { onAir: dsk.DefaultOn, config: dsk @@ -171,7 +169,7 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { type: ConfigManifestEntryType.TABLE, required: false, defaultVal: literal>( - defaultVal.map(dsk => ({ _id: '', ...dsk, Roles: dsk.Roles ?? [] })) + defaultVal.map((dsk) => ({ _id: '', ...dsk, Roles: dsk.Roles ?? [] })) ), columns: [ { @@ -186,8 +184,8 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { }, { id: 'Fill', - name: 'ATEM Fill', - description: 'ATEM vision mixer input for DSK Fill', + name: 'Switcher Fill', + description: 'Video Switcher input for DSK Fill', type: ConfigManifestEntryType.INT, required: true, defaultVal: 21, @@ -195,8 +193,8 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { }, { id: 'Key', - name: 'ATEM Key', - description: 'ATEM vision mixer input for DSK Key', + name: 'Switcher Key', + description: 'Video Switcher input for DSK Key', type: ConfigManifestEntryType.INT, required: true, defaultVal: 34, @@ -234,8 +232,8 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { { id: 'Clip', name: 'ATEM Clip', - description: 'DSK Clip (0-100)', - type: ConfigManifestEntryType.FLOAT, // @todo: this needs a migration + description: 'DSK Clip (0-100), only used in the ATEM', + type: ConfigManifestEntryType.FLOAT, required: true, defaultVal: 50, rank: 6 @@ -243,8 +241,8 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { { id: 'Gain', name: 'ATEM Gain', - description: 'DSK Gain (0-100)', - type: ConfigManifestEntryType.FLOAT, // @todo: this needs a migration + description: 'DSK Gain (0-100), only used in the ATEM', + type: ConfigManifestEntryType.FLOAT, required: true, defaultVal: 12.5, rank: 7 diff --git a/src/tv2-common/helpers/graphics/Graphic.ts b/src/tv2-common/helpers/graphics/Graphic.ts index 389207db..51306cd5 100644 --- a/src/tv2-common/helpers/graphics/Graphic.ts +++ b/src/tv2-common/helpers/graphics/Graphic.ts @@ -1,17 +1,15 @@ import { PieceLifespan, TSR } from 'blueprints-integration' import { - CalculateTime, - CreateTimingEnable, + calculateTime, CueDefinitionGraphic, ExtendedShowStyleContext, - GetDefaultOut, - GetEnableForWall, + getDefaultOut, + getLifeSpan, + getTimingEnable, GraphicInternalOrPilot, GraphicIsInternal, - GraphicIsPilot, IsTargetingTLF, IsTargetingWall, - LifeSpan, TableConfigItemGfxTemplate, TV2ShowStyleConfig } from 'tv2-common' @@ -28,6 +26,7 @@ export abstract class Graphic { this.engine = cue.target } + public abstract getTemplateId(): string public abstract getTemplateName(): string protected getGraphicDuration(): number | undefined { @@ -38,12 +37,12 @@ export abstract class Graphic { } } - return GetDefaultOut(this.config) + return getDefaultOut(this.config) } protected getSourceLayerForGraphic(name: string) { const conf = this.config.showStyle.GfxTemplates - ? this.config.showStyle.GfxTemplates.find(gfx => gfx.VizTemplate.toString() === name) + ? this.config.showStyle.GfxTemplates.find((gfx) => gfx.VizTemplate.toString() === name) : undefined if (!conf) { @@ -79,14 +78,14 @@ export abstract class Graphic { protected createTimingGraphic(): { start: number; duration?: number } { const ret: { start: number; duration?: number } = { start: 0, duration: 0 } - const start = this.cue.start ? CalculateTime(this.cue.start) : 0 + const start = this.cue.start ? calculateTime(this.cue.start) : 0 start !== undefined ? (ret.start = start) : (ret.start = 0) const duration = this.getGraphicDuration() const end = this.cue.end ? this.cue.end.infiniteMode ? undefined - : CalculateTime(this.cue.end) + : calculateTime(this.cue.end) : duration ? ret.start + duration : undefined @@ -97,10 +96,12 @@ export abstract class Graphic { protected GetEnableForGraphic(): TSR.TSRTimelineObj['enable'] { if (IsTargetingWall(this.engine)) { - return GetEnableForWall() + return { + while: '1' + } } - const timing = CreateTimingEnable(this.cue, GetDefaultOut(this.config)) + const timing = getTimingEnable(this.cue, getDefaultOut(this.config)) if (!timing.lifespan) { return timing.enable @@ -118,18 +119,10 @@ export abstract class Graphic { } protected findGfxTemplate(): TableConfigItemGfxTemplate | undefined { - let graphicId: string | undefined - // @todo: this should be implemented in derivatives - if (GraphicIsInternal(this.cue)) { - graphicId = this.cue.graphic.template - } else if (GraphicIsPilot(this.cue)) { - graphicId = this.cue.graphic.vcpid.toString() - } - if (graphicId === undefined) { - return undefined - } - return this.config.showStyle.GfxTemplates.find(templ => - templ.INewsName ? templ.INewsName.toString().toUpperCase() === graphicId?.toUpperCase() : false + const templateId = this.getTemplateId() + + return this.config.showStyle.GfxTemplates.find((templ) => + templ.INewsName ? templ.INewsName.toString().toUpperCase() === templateId?.toUpperCase() : false ) } @@ -141,9 +134,9 @@ export abstract class Graphic { return PieceLifespan.WithinPart } if (this.cue.end?.infiniteMode) { - return LifeSpan(this.cue.end.infiniteMode) + return getLifeSpan(this.cue.end.infiniteMode) } - if (this.cue.end && CalculateTime(this.cue.end)) { + if (this.cue.end && calculateTime(this.cue.end)) { return PieceLifespan.WithinPart } return this.FindInfiniteModeFromConfig() @@ -152,7 +145,7 @@ export abstract class Graphic { protected FindInfiniteModeFromConfig(): PieceLifespan { const template = this.getTemplateName() const iNewsName = GraphicIsInternal(this.cue) ? this.cue.graphic.template : undefined - const conf = this.config.showStyle.GfxTemplates.find(gfx => + const conf = this.config.showStyle.GfxTemplates.find((gfx) => gfx.VizTemplate ? gfx.VizTemplate.toString().toUpperCase() === template.toUpperCase() && (iNewsName ? gfx.INewsName.toUpperCase() === iNewsName.toUpperCase() : true) @@ -173,6 +166,6 @@ export abstract class Graphic { return PieceLifespan.WithinPart } - return LifeSpan(type) + return getLifeSpan(type) } } diff --git a/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts b/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts index db85ca2f..85db3644 100644 --- a/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts +++ b/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts @@ -4,7 +4,6 @@ import { CueType, SharedGraphicLLayer } from 'tv2-constants' import { makeMockGalleryContext } from '../../../../../__mocks__/context' function makeMockContext() { - // @todo: perhaps make the tests run with two contexts return makeMockGalleryContext() } @@ -63,7 +62,7 @@ describe('HtmlPilotGraphicGenerator', () => { const generator = makeGeneratorForOvl() const pilotContent = generator.getContent() const timelineObjects = pilotContent.timelineObjects.filter( - tlObject => + (tlObject) => tlObject.content.deviceType === TSR.DeviceType.CASPARCG && (tlObject as TSR.TimelineObjCCGTemplate).content.type === TSR.TimelineContentTypeCasparCg.TEMPLATE ) @@ -97,7 +96,7 @@ describe('HtmlPilotGraphicGenerator', () => { const generator = makeGeneratorForOvl() const pilotContent = generator.getContent() const timelineObjects = pilotContent.timelineObjects.filter( - tlObject => + (tlObject) => tlObject.content.deviceType === TSR.DeviceType.ATEM && (tlObject as TSR.TimelineObjAtemDSK).content.type === TSR.TimelineContentTypeAtem.DSK ) @@ -133,7 +132,7 @@ describe('HtmlPilotGraphicGenerator', () => { const generator = makeGeneratorForFull() const pilotContent = generator.getContent() const timelineObjects = pilotContent.timelineObjects.filter( - tlObject => + (tlObject) => tlObject.content.deviceType === TSR.DeviceType.CASPARCG && (tlObject as TSR.TimelineObjCCGTemplate).content.type === TSR.TimelineContentTypeCasparCg.TEMPLATE ) diff --git a/src/tv2-common/helpers/graphics/caspar/util.ts b/src/tv2-common/helpers/graphics/caspar/util.ts index ac8c6f43..c06e116d 100644 --- a/src/tv2-common/helpers/graphics/caspar/util.ts +++ b/src/tv2-common/helpers/graphics/caspar/util.ts @@ -77,8 +77,8 @@ function getSlotBaselineTimelineObjects( layerMappings: SharedGraphicLLayer[] ): TSR.TSRTimelineObj[] { return layerMappings - .filter(layer => layerToHTMLGraphicSlot[layer]) - .map(layer => ({ + .filter((layer) => layerToHTMLGraphicSlot[layer]) + .map((layer) => ({ id: '', enable: { while: '1' diff --git a/src/tv2-common/helpers/graphics/design/index.ts b/src/tv2-common/helpers/graphics/design/index.ts index f0311dca..c060a143 100644 --- a/src/tv2-common/helpers/graphics/design/index.ts +++ b/src/tv2-common/helpers/graphics/design/index.ts @@ -8,7 +8,7 @@ import { WithTimeline } from 'blueprints-integration' import { - CalculateTime, + calculateTime, CueDefinitionGraphicDesign, ExtendedShowStyleContext, getHtmlTemplateName, @@ -27,7 +27,7 @@ export function EvaluateDesignBase( adlib?: boolean, rank?: number ) { - const start = (parsedCue.start ? CalculateTime(parsedCue.start) : 0) ?? 0 + const start = (parsedCue.start ? calculateTime(parsedCue.start) : 0) ?? 0 if (!parsedCue.design || !parsedCue.design.length) { context.core.notifyUserWarning(`No valid design found for ${parsedCue.design}`) return diff --git a/src/tv2-common/helpers/graphics/index.ts b/src/tv2-common/helpers/graphics/index.ts index 0b478467..f299678c 100644 --- a/src/tv2-common/helpers/graphics/index.ts +++ b/src/tv2-common/helpers/graphics/index.ts @@ -4,8 +4,6 @@ export * from './caspar' export * from './viz' export * from './pilot' export * from './internal' -export * from './name' -export * from './timing' export * from './target' export * from './layers' export * from './internal' diff --git a/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts b/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts index fb3e0454..3e2822b2 100644 --- a/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts +++ b/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts @@ -117,7 +117,7 @@ export abstract class InternalGraphic extends Graphic { public getTemplateName(): string { const iNewsTemplateName = this.cue.graphic.template - const template = this.config.showStyle.GfxTemplates.find(templ => + const template = this.config.showStyle.GfxTemplates.find((templ) => templ.INewsName ? templ.INewsName.toString().toUpperCase() === iNewsTemplateName.toUpperCase() : false ) if (template && template.VizTemplate.toString().length) { @@ -128,10 +128,14 @@ export abstract class InternalGraphic extends Graphic { return iNewsTemplateName } + public getTemplateId(): string { + return this.cue.graphic.template + } + public getDisplayName(): string { return `${this.cue.graphic.template ? `${this.templateName}` : ''}${ this.cue.graphic.textFields.length ? ' - ' : '' - }${this.cue.graphic.textFields.filter(txt => !txt.match(/^;.\.../i)).join('\n - ')}` + }${this.cue.graphic.textFields.filter((txt) => !txt.match(/^;.\.../i)).join('\n - ')}` } protected abstract getContent(): IBlueprintPiece['content'] diff --git a/src/tv2-common/helpers/graphics/layers.ts b/src/tv2-common/helpers/graphics/layers.ts index 5eb1e28a..6a8ebd8e 100644 --- a/src/tv2-common/helpers/graphics/layers.ts +++ b/src/tv2-common/helpers/graphics/layers.ts @@ -3,7 +3,7 @@ import { SharedGraphicLLayer } from 'tv2-constants' export function GetTimelineLayerForGraphic(config: TV2ShowStyleConfig, name: string) { const conf = config.showStyle.GfxTemplates - ? config.showStyle.GfxTemplates.find(gfx => gfx.VizTemplate.toString() === name) + ? config.showStyle.GfxTemplates.find((gfx) => gfx.VizTemplate.toString() === name) : undefined if (!conf) { diff --git a/src/tv2-common/helpers/graphics/name.ts b/src/tv2-common/helpers/graphics/name.ts deleted file mode 100644 index bd13160d..00000000 --- a/src/tv2-common/helpers/graphics/name.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { - CueDefinitionGraphic, - GraphicInternalOrPilot, - // GraphicIsInternal, - // GraphicIsPilot, - TV2ShowStyleConfig -} from 'tv2-common' - -export function GraphicDisplayName( - _config: TV2ShowStyleConfig, - parsedCue: CueDefinitionGraphic -): string { - // @todo: bring this back - // if (GraphicIsInternal(parsedCue)) { - // return `${parsedCue.graphic.template ? `${GetFullGraphicTemplateNameFromCue(config, parsedCue)}` : ''}${ - // parsedCue.graphic.textFields.length ? ' - ' : '' - // }${parsedCue.graphic.textFields.filter(txt => !txt.match(/^;.\.../i)).join('\n - ')}` - // } else if (GraphicIsPilot(parsedCue)) { - // return `${parsedCue.graphic.name ? parsedCue.graphic.name : ''}` - // } - - // Shouldn't be possible - return parsedCue.iNewsCommand -} diff --git a/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts index 09edfaf4..d34471b5 100644 --- a/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts @@ -148,7 +148,7 @@ export abstract class PilotGraphicGenerator extends Graphic { public createFullDataStore(): IBlueprintPiece { const content = this.getContent() content.timelineObjects = content.timelineObjects.filter( - o => + (o) => o.content.deviceType !== TSR.DeviceType.ATEM && o.content.deviceType !== TSR.DeviceType.TRICASTER && o.content.deviceType !== TSR.DeviceType.SISYFOS && @@ -184,6 +184,10 @@ export abstract class PilotGraphicGenerator extends Graphic { return this.cue.graphic.name } + public getTemplateId(): string { + return this.cue.graphic.vcpid.toString() + } + protected getPrerollDuration(): number { return this.config.studio.GraphicsType === 'HTML' ? this.config.studio.CasparPrerollDuration diff --git a/src/tv2-common/helpers/graphics/timing.ts b/src/tv2-common/helpers/graphics/timing.ts deleted file mode 100644 index c26cb2d8..00000000 --- a/src/tv2-common/helpers/graphics/timing.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { TSR } from 'blueprints-integration' - -// @todo: this has to go somewhere -export function GetEnableForWall(): TSR.TSRTimelineObj['enable'] { - return { - while: '1' - } -} diff --git a/src/tv2-common/helpers/graphics/util.ts b/src/tv2-common/helpers/graphics/util.ts index bf29f3ed..ad954333 100644 --- a/src/tv2-common/helpers/graphics/util.ts +++ b/src/tv2-common/helpers/graphics/util.ts @@ -17,7 +17,7 @@ export function ApplyFullGraphicPropertiesToPart(config: TV2ShowStyleConfig, par } } -export function CreateGraphicBaseline(config: TV2ShowStyleConfig): TSR.TSRTimelineObj[] { +export function getGraphicBaseline(config: TV2ShowStyleConfig): TSR.TSRTimelineObj[] { if (config.studio.GraphicsType === 'VIZ') { return [] } else { diff --git a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts index a0aa90f4..37a0d553 100644 --- a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts @@ -96,14 +96,14 @@ export class VizPilotGraphicGenerator extends PilotGraphicGenerator { ...getDskOnAirTimelineObjects(this.context, DSKRoles.FULLGFX), ...GetSisyfosTimelineObjForFull(this.config) ] - if (this.context.uniformConfig.MixEffects.Program.auxLayer) { + if (this.context.uniformConfig.mixEffects.program.auxLayer) { timelineObjects.push( this.context.videoSwitcher.getAuxTimelineObject({ enable: { start: this.config.studio.VizPilotGraphics.CutToMediaPlayer }, priority: 1, - layer: this.context.uniformConfig.MixEffects.Program.auxLayer, + layer: this.context.uniformConfig.mixEffects.program.auxLayer, content: { input: fullDSK.Fill } diff --git a/src/tv2-common/helpers/postProcessDefinitions.ts b/src/tv2-common/helpers/postProcessDefinitions.ts index ff0db951..c6178180 100644 --- a/src/tv2-common/helpers/postProcessDefinitions.ts +++ b/src/tv2-common/helpers/postProcessDefinitions.ts @@ -6,7 +6,7 @@ export function PostProcessDefinitions(partDefinitions: PartDefinition[], segmen partDefinitions.forEach((part, i) => { setPartTitle(part) - part.cues = part.cues.map(c => { + part.cues = part.cues.map((c) => { if (c.type === CueType.Ekstern) { c.transition = undefined } @@ -56,7 +56,7 @@ function getExternalId(segmentId: string, partDefinition: PartDefinition, foundM break case PartType.INTRO: // Intro must have a jingle cue, if it doesn't then padId will handle - const jingle = partDefinition.cues.find(cue => cue.type === CueType.Jingle) as CueDefinitionJingle + const jingle = partDefinition.cues.find((cue) => cue.type === CueType.Jingle) as CueDefinitionJingle if (jingle) { id += `-${jingle.clip}` } diff --git a/src/tv2-common/helpers/rundownAdLibActions.ts b/src/tv2-common/helpers/rundownAdLibActions.ts index c0b31fca..8db52773 100644 --- a/src/tv2-common/helpers/rundownAdLibActions.ts +++ b/src/tv2-common/helpers/rundownAdLibActions.ts @@ -41,7 +41,7 @@ export function GetTransitionAdLibActions< if (config.showStyle.Transitions) { const transitionActions: IBlueprintActionManifest[] = config.showStyle.Transitions.filter( - transition => transition.Transition && transition.Transition.length + (transition) => transition.Transition && transition.Transition.length ).flatMap((transition, i) => createActionsForTransition(config, transition.Transition, startingRank + 0.01 * i)) blueprintActionManifests.push(...transitionActions) } @@ -54,7 +54,7 @@ function createActionsForTransition( transition: string, rank: number ): IBlueprintActionManifest[] { - const jingleConfig = config.showStyle.BreakerConfig.find(j => j.BreakerName === transition) + const jingleConfig = config.showStyle.BreakerConfig.find((j) => j.BreakerName === transition) const transitionValues: TransitionValues = { rank, label: transition, diff --git a/src/tv2-common/helpers/serverResume.ts b/src/tv2-common/helpers/serverResume.ts index b69c80bc..2957c937 100644 --- a/src/tv2-common/helpers/serverResume.ts +++ b/src/tv2-common/helpers/serverResume.ts @@ -81,7 +81,7 @@ export function getServerPositionForPartInstance( const previousPartEndState = partInstance.previousPartEndState as Partial | undefined const previousServerPosition = previousPartEndState?.serverPosition - const currentPiecesWithServer = _.sortBy(pieceInstances.filter(shouldPreservePosition), p => p.resolvedStart) + const currentPiecesWithServer = _.sortBy(pieceInstances.filter(shouldPreservePosition), (p) => p.resolvedStart) let currentServerPosition = previousPartEndState?.segmentId === partInstance.segmentId ? previousServerPosition : undefined diff --git a/src/tv2-common/helpers/sisyfos.ts b/src/tv2-common/helpers/sisyfos.ts index 52fcc8b5..b8909f1d 100644 --- a/src/tv2-common/helpers/sisyfos.ts +++ b/src/tv2-common/helpers/sisyfos.ts @@ -98,7 +98,7 @@ function GetSisyfosTimelineObjForSource( ): TSR.TimelineObjSisyfosAny[] { const result: TSR.TimelineObjSisyfosAny[] = [] const timelineEnable = getFallbackEnable(enable) - sourceInfo.sisyfosLayers?.forEach(layer => { + sourceInfo.sisyfosLayers?.forEach((layer) => { result.push( literal({ id: '', @@ -124,7 +124,7 @@ function getStudioMicsTimelineObj( timelineEnable: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosChannels { const studioMicsChannels: TSR.TimelineObjSisyfosChannels['content']['channels'] = [] - config.studio.StudioMics.forEach(layer => { + config.studio.StudioMics.forEach((layer) => { studioMicsChannels.push({ mappedLayer: layer, isPgm: 1 diff --git a/src/tv2-common/hotkeys/clear.ts b/src/tv2-common/hotkeys/clear.ts index b8e33f54..16275c41 100644 --- a/src/tv2-common/hotkeys/clear.ts +++ b/src/tv2-common/hotkeys/clear.ts @@ -20,7 +20,7 @@ export function MakeClearHotkeys( assignments: ClearLayerHotkeyAssignments, getNextRank: () => number ) { - return assignments.map(clearedSourceLayer => + return assignments.map((clearedSourceLayer) => literal({ _id: clearSourceLayerHotKeyId(showStyleId, clearedSourceLayer.sourceLayers), _rank: getNextRank(), diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index 4b190c86..5b684e02 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -201,7 +201,7 @@ export function ParseBody( externalId: `${segmentId}-${definitions.length}`, segmentExternalId: segmentId } - cues.forEach(cue => { + cues.forEach((cue) => { if (cue !== null) { const parsedCue = ParseCue(cue, config) @@ -220,9 +220,9 @@ export function ParseBody( for (let i = 0; i < lines.length; i++) { lines[i] = lines[i].replace(/(.*?)<\/cc>/gi, '') } - lines = lines.filter(line => line !== '

' && line !== '

') + lines = lines.filter((line) => line !== '

' && line !== '

') - lines.forEach(line => { + lines.forEach((line) => { const type = line.match(/(.*?)<\/pi>/i) if (type) { @@ -235,11 +235,11 @@ export function ParseBody( .replace(/<\/tab>/i, '') .trim() - if (typeStr && ACCEPTED_RED_TEXT.some(r => r.test(typeStr))) { + if (typeStr && ACCEPTED_RED_TEXT.some((r) => r.test(typeStr))) { const inlineCues = line .replace(/<\/?p>/g, '') .split(/(.*?)<\/pi>/i) - .filter(cue => cue !== '' && !/<\/a>/.test(cue)) + .filter((cue) => cue !== '' && !/<\/a>/.test(cue)) /** Hold any secondary cues in the form: `[] KAM 1` */ const secondaryInlineCues: CueDefinition[] = [] @@ -248,11 +248,11 @@ export function ParseBody( let pos = 0 let redTextFound = false while (pos < inlineCues.length && !redTextFound) { - if (ACCEPTED_RED_TEXT.some(r => r.test(inlineCues[pos]))) { + if (ACCEPTED_RED_TEXT.some((r) => r.test(inlineCues[pos]))) { redTextFound = true } else { const parsedCues = getCuesInLine(inlineCues[pos], cues, config) - parsedCues.forEach(cue => { + parsedCues.forEach((cue) => { // Create standalone parts for primary cues. if ( isPrimaryCue(cue) && @@ -316,7 +316,7 @@ export function ParseBody( if (cueInLine(line)) { const parsedCues = getCuesInLine(line, cues, config) - parsedCues.forEach(cue => { + parsedCues.forEach((cue) => { if (isPrimaryCue(cue)) { let storedScript = '' if (shouldPushDefinition(definition)) { @@ -350,7 +350,7 @@ export function ParseBody( } // Flatten cues such as targetEngine. - definitions.forEach(partDefinition => { + definitions.forEach((partDefinition) => { if (partDefinition.cues.length) { while (FindTargetPair(partDefinition)) { // NO-OP @@ -358,7 +358,7 @@ export function ParseBody( } // Discard UNKNOWN cues, we won't do anything with them - partDefinition.cues = partDefinition.cues.filter(c => c.type !== CueType.UNKNOWN) + partDefinition.cues = partDefinition.cues.filter((c) => c.type !== CueType.UNKNOWN) }) definitions = stripRedundantCuesWhenLayoutCueIsPresent(definitions) @@ -368,7 +368,7 @@ export function ParseBody( export function FindTargetPair(partDefinition: PartDefinition): boolean { const index = partDefinition.cues.findIndex( - cue => (cue.type === CueType.UNPAIRED_TARGET && cue.mergeable) || (cue.type === CueType.Telefon && !cue.graphic) + (cue) => (cue.type === CueType.UNPAIRED_TARGET && cue.mergeable) || (cue.type === CueType.Telefon && !cue.graphic) ) if (index === -1) { @@ -437,7 +437,7 @@ function getCuesInLine(line: string, cues: UnparsedCue[], config: TV2ShowStyleCo const definitions: CueDefinition[] = [] const cue = line.match(//gi) - cue?.forEach(c => { + cue?.forEach((c) => { const value = c.match(//i) if (value) { const realCue = cues[Number(value[1])] @@ -457,10 +457,7 @@ function getCuesInLine(line: string, cues: UnparsedCue[], config: TV2ShowStyleCo function addScript(line: string, definition: PartDefinition) { const script = line.match(/

(.*?)<\/p>/i) if (script && script[1] && !/.*?<\/pi>/i.test(script[1])) { - const trimscript = script[1] - .replace(/<.*?>/gi, '') - .replace('\n\r', '') - .trim() + const trimscript = script[1].replace(/<.*?>/gi, '').replace('\n\r', '').trim() if (trimscript) { definition.script += `${trimscript}\n` } @@ -478,7 +475,7 @@ function isPrimaryCue(cue: CueDefinition) { function shouldPushDefinition(definition: PartDefinition) { return ( - (definition.cues.filter(c => c.type !== CueType.UNKNOWN).length || + (definition.cues.filter((c) => c.type !== CueType.UNKNOWN).length || (definition.script.length && definition.cues.length) || definition.type !== PartType.Unknown) && !(definition.type === PartType.Grafik && definition.cues.length === 0) @@ -601,10 +598,7 @@ function extractTypeProperties(typeStr: string): PartdefinitionTypes { break } - const tokens = stripTransitionProperties(typeStr) - .replace(/100%/g, '') - .trim() - .split(' ') + const tokens = stripTransitionProperties(typeStr).replace(/100%/g, '').trim().split(' ') const firstToken = tokens[0] if (/SERVER|ATTACK/i.test(firstToken)) { @@ -636,9 +630,7 @@ function extractTypeProperties(typeStr: string): PartdefinitionTypes { } export function getSourceDefinition(typeStr: string): SourceDefinition | undefined { - const strippedTypeStr = stripTransitionProperties(typeStr) - .replace(/100%/g, '') - .trim() + const strippedTypeStr = stripTransitionProperties(typeStr).replace(/100%/g, '').trim() if (CAMERA_RED_TEXT.test(strippedTypeStr)) { const id = strippedTypeStr.match(CAMERA_RED_TEXT)![1].toUpperCase() return { @@ -706,8 +698,8 @@ export function isMinusMic(inputName: string): boolean { } export function stripRedundantCuesWhenLayoutCueIsPresent(partDefinitions: PartDefinition[]): PartDefinition[] { - const hasLayoutCue: boolean = partDefinitions.some(definition => - definition.cues.some(cue => { + const hasLayoutCue: boolean = partDefinitions.some((definition) => + definition.cues.some((cue) => { const cueFromLayout = cue as CueDefinitionFromLayout return cueFromLayout.isFromLayout }) @@ -717,8 +709,8 @@ export function stripRedundantCuesWhenLayoutCueIsPresent(partDefinitions: PartDe return partDefinitions } - return partDefinitions.map(definition => { - const cues = definition.cues.filter(cue => { + return partDefinitions.map((definition) => { + const cues = definition.cues.filter((cue) => { if (cue.type !== CueType.GraphicDesign && cue.type !== CueType.BackgroundLoop) { return true } diff --git a/src/tv2-common/inewsConversion/converters/ParseCue.ts b/src/tv2-common/inewsConversion/converters/ParseCue.ts index b74b4581..ad754901 100644 --- a/src/tv2-common/inewsConversion/converters/ParseCue.ts +++ b/src/tv2-common/inewsConversion/converters/ParseCue.ts @@ -203,9 +203,9 @@ export function ParseCue(cue: UnparsedCue, config: TV2ShowStyleConfig): CueDefin return undefined } - cue = cue.filter(c => c !== '') + cue = cue.filter((c) => c !== '') // Replace multiple spaces / tabs with a single space - cue = cue.map(c => c?.trim().replace(/\s+/g, ' ')) + cue = cue.map((c) => c?.trim().replace(/\s+/g, ' ')) if (cue.length === 0) { return undefined @@ -335,7 +335,7 @@ function parsekg( const graphicDesignConfig = code ? config.showStyle.GfxDesignTemplates.find( - template => template.INewsName.toUpperCase() === graphic.template.toUpperCase() + (template) => template.INewsName.toUpperCase() === graphic.template.toUpperCase() ) : undefined @@ -352,7 +352,7 @@ function parsekg( const graphicConfig = code ? config.showStyle.GfxTemplates.find( - template => + (template) => template.INewsCode.replace(/^KG=?/gi, '#KG').toUpperCase() === code.replace(/^KG=?/gi, '#KG').toUpperCase() && template.INewsName.toUpperCase() === graphic.template.toUpperCase() ) @@ -387,7 +387,7 @@ function parsePilot(cue: string[]): CueDefinitionUnpairedPilot | CueDefinitionGr iNewsCommand: 'VCP' } const realCue: string[] = [] - cue.forEach(line => { + cue.forEach((line) => { if ( !line.match(/[#|*]?cg\d+[ -]pilotdata/i) && !line.match(/^]] [a-z]\d\.\d [a-z] \d \[\[$/i) && @@ -472,7 +472,7 @@ function parseDVE(cue: string[]): CueDefinitionDVE { iNewsCommand: 'DVE' } - cue.forEach(c => { + cue.forEach((c) => { if (c.match(/^DVE=/i)) { const template = c.match(/^DVE=(.+)$/i) if (template) { @@ -561,7 +561,7 @@ function parseMic(cue: string[]): CueDefinitionMic { mics: {}, iNewsCommand: 'STUDIE' } - cue.forEach(c => { + cue.forEach((c) => { if (!c.match(/^STUDIE=MIC ON OFF$/i)) { if (isTime(c)) { micCue = { ...micCue, ...parseTime(c) } @@ -720,7 +720,9 @@ function parseTargetEngine( } const graphicDesignConfig = code - ? config.showStyle.GfxDesignTemplates.find(template => template.INewsName.toUpperCase() === iNewsName.toUpperCase()) + ? config.showStyle.GfxDesignTemplates.find( + (template) => template.INewsName.toUpperCase() === iNewsName.toUpperCase() + ) : undefined if (graphicDesignConfig) { @@ -735,7 +737,7 @@ function parseTargetEngine( } const graphicConfig = config.showStyle.GfxTemplates.find( - template => + (template) => template.INewsCode.toUpperCase() === code?.toUpperCase() && template.INewsName.toUpperCase() === iNewsName.toUpperCase() ) @@ -772,7 +774,7 @@ function parseAllOut(cue: string[]): CueDefinitionClearGrafiks { } let time = false - cue.forEach(c => { + cue.forEach((c) => { const command = c.match(/^([#* ]?kg)/i) if (command) { clearCue.iNewsCommand = command[1] @@ -920,7 +922,7 @@ function findGraphicDesignConfiguration( layout: string ): TableConfigItemGfxDesignTemplate | undefined { return config.showStyle.GfxDesignTemplates.find( - template => template.INewsStyleColumn && template.INewsStyleColumn.toUpperCase() === layout.toUpperCase() + (template) => template.INewsStyleColumn && template.INewsStyleColumn.toUpperCase() === layout.toUpperCase() ) } diff --git a/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts b/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts index a1da0c17..6521f593 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts @@ -3405,7 +3405,7 @@ describe('Body parser', () => { const cues = result[0].cues expect(cues).toHaveLength(3) - const regularDesignCue = cues.find(cue => { + const regularDesignCue = cues.find((cue) => { const designCue = cue as CueDefinitionGraphicDesign if (!designCue.design) { return false @@ -3424,7 +3424,7 @@ describe('Body parser', () => { const result: PartDefinition[] = stripRedundantCuesWhenLayoutCueIsPresent(definitions) - const cues: CueDefinition[] = result.flatMap(definition => definition.cues) + const cues: CueDefinition[] = result.flatMap((definition) => definition.cues) expect(cues).toHaveLength(1) const graphicCue = cues[0] as CueDefinitionGraphicDesign expect(graphicCue.design).toBe(layoutDesign) @@ -3538,7 +3538,7 @@ function createUnknownCueDefinition(): CueDefinition { } export function stripExternalId(definitions: PartDefinition[]) { - return definitions.map(def => { + return definitions.map((def) => { return { ...def, ...{ externalId: '' } } }) } diff --git a/src/tv2-common/jinglePartProperties.ts b/src/tv2-common/jinglePartProperties.ts index 1fb5967e..1499d6c9 100644 --- a/src/tv2-common/jinglePartProperties.ts +++ b/src/tv2-common/jinglePartProperties.ts @@ -10,13 +10,11 @@ export function GetJinglePartProperties( part: PartDefinition ): Pick | {} { if (part.cues) { - const cue = part.cues.find(c => c.type === CueType.Jingle) as CueDefinitionJingle + const cue = part.cues.find((c) => c.type === CueType.Jingle) as CueDefinitionJingle if (cue) { - const realBreaker = context.config.showStyle.BreakerConfig.find(conf => { + const realBreaker = context.config.showStyle.BreakerConfig.find((conf) => { return conf.BreakerName && typeof conf.BreakerName === 'string' - ? conf.BreakerName.toString() - .trim() - .toUpperCase() === cue.clip.toUpperCase() + ? conf.BreakerName.toString().trim().toUpperCase() === cue.clip.toUpperCase() : false }) diff --git a/src/tv2-common/layers/timelineLayers.ts b/src/tv2-common/layers/timelineLayers.ts index 4a746dbf..07612026 100644 --- a/src/tv2-common/layers/timelineLayers.ts +++ b/src/tv2-common/layers/timelineLayers.ts @@ -1,4 +1,5 @@ import { BlueprintMapping, BlueprintMappings, LookaheadMode, TSR } from 'blueprints-integration' +import { SwitcherDskLLayer } from 'tv2-constants' import { ATEMModel } from '../../types/atem' import { GetDSKCount } from '../helpers' @@ -23,23 +24,19 @@ export function CasparPlayerClipLoadingLoop(i: number | string) { return `casparcg_player_clip_${i}_loading_loop` } -export function SisyfosPlayerClip(i: number | string) { - return `sisyfos_player_clip_${i}` -} - /** * Created layer mapping name for a DSK * @param i DSK number starting from 0 */ -export function LLayerDSK(i: number) { +export function getDskLLayerName(i: number): SwitcherDskLLayer { return `dsk_${i + 1}` } -export function GetDSKMappingNames(atemModel: ATEMModel): string[] { +export function getDskMappingNames(atemModel: ATEMModel): string[] { const names: string[] = [] for (let i = 0; i < GetDSKCount(atemModel); i++) { - names.push(LLayerDSK(i)) + names.push(getDskLLayerName(i)) } return names @@ -47,7 +44,7 @@ export function GetDSKMappingNames(atemModel: ATEMModel): string[] { export function getAtemDskMappings(atemModel: ATEMModel): BlueprintMappings { const base: Record = {} - return GetDSKMappingNames(atemModel).reduce((prev, name, index) => { + return getDskMappingNames(atemModel).reduce((prev, name, index) => { prev[name] = { device: TSR.DeviceType.ATEM, deviceId: 'atem0', diff --git a/src/tv2-common/migrations/__tests__/dve-config-folder.spec.ts b/src/tv2-common/migrations/__tests__/dve-config-folder.spec.ts index e459b912..4b374464 100644 --- a/src/tv2-common/migrations/__tests__/dve-config-folder.spec.ts +++ b/src/tv2-common/migrations/__tests__/dve-config-folder.spec.ts @@ -29,7 +29,7 @@ function testDescriptionToConfig( ): ConfigItemValue { const preMigration = step === 'premigration' return literal( - description.map(item => ({ + description.map((item) => ({ _id: item.DVEName, DVEName: item.DVEName, DVEGraphicsKey: preMigration @@ -283,7 +283,7 @@ const normalizeSoundbedTests: StripDVEFolderMigrationTestCase[] = [ ] describe('Remove dve folder from dve config', () => { - normalizeSoundbedTests.forEach(testDescription => { + normalizeSoundbedTests.forEach((testDescription) => { test(testDescription.description, () => { const context = new MockShowstyleMigrationContext() context.configs.set(DVE_CONFIG_KEY, testDescriptionToConfig(testDescription.data, 'premigration')) diff --git a/src/tv2-common/migrations/__tests__/migrationContext.mock.ts b/src/tv2-common/migrations/__tests__/migrationContext.mock.ts index ec2a8a39..24d9fbbf 100644 --- a/src/tv2-common/migrations/__tests__/migrationContext.mock.ts +++ b/src/tv2-common/migrations/__tests__/migrationContext.mock.ts @@ -20,7 +20,7 @@ export class MockShowstyleMigrationContext implements MigrationContextShowStyle return variantId } public getVariant(variantId: string): IBlueprintShowStyleVariant | undefined { - return this.variants.find(variant => variant._id === variantId) + return this.variants.find((variant) => variant._id === variantId) } public insertVariant(variantId: string, variant: OmitId): string { throw new Error(`Function not implemented in mock: 'insertVariant' args: '${variantId}, ${JSON.stringify(variant)}`) diff --git a/src/tv2-common/migrations/__tests__/soundbed-config-audio-folder.spec.ts b/src/tv2-common/migrations/__tests__/soundbed-config-audio-folder.spec.ts index 7e0fb8f8..a76e347f 100644 --- a/src/tv2-common/migrations/__tests__/soundbed-config-audio-folder.spec.ts +++ b/src/tv2-common/migrations/__tests__/soundbed-config-audio-folder.spec.ts @@ -27,7 +27,7 @@ function testDescriptionToConfig( ): ConfigItemValue { const preMigration = step === 'premigration' return literal( - description.map(item => ({ + description.map((item) => ({ _id: item.iNewsName, INewsName: item.iNewsName, FileName: preMigration ? item.PreMigration : item.PostMigration ?? item.PreMigration @@ -235,7 +235,7 @@ const normalizeSoundbedTests: StripAudioFolderMigrationTestCase[] = [ ] describe('Remove audio folder from soundbed config', () => { - normalizeSoundbedTests.forEach(testDescription => { + normalizeSoundbedTests.forEach((testDescription) => { test(testDescription.description, () => { const context = new MockShowstyleMigrationContext() context.configs.set(AUDIO_BED_CONFIG_KEY, testDescriptionToConfig(testDescription.data, 'premigration')) diff --git a/src/tv2-common/migrations/addKeepAudio.ts b/src/tv2-common/migrations/addKeepAudio.ts index a36cb760..76e1acd7 100644 --- a/src/tv2-common/migrations/addKeepAudio.ts +++ b/src/tv2-common/migrations/addKeepAudio.ts @@ -22,7 +22,7 @@ export function AddKeepAudio(versionStr: string, configName: string): MigrationS migrate: (context: MigrationContextStudio) => { const configVal = context.getConfig(configName) if (Array.isArray(configVal) && configVal.length) { - _.each(configVal as TableConfigItemValue, source => { + _.each(configVal as TableConfigItemValue, (source) => { source.KeepAudioInStudio = source.KeepAudioInStudio !== undefined ? source.KeepAudioInStudio : true }) context.setConfig(configName, configVal) diff --git a/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts b/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts index 9e7dd804..9bf4d048 100644 --- a/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts +++ b/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts @@ -19,7 +19,7 @@ export function forceSourceLayerToDefaultsBase( return `SourceLayer "${layer}" doesn't exist on ShowBaseStyle` } - const defaultVal = sourcelayerDefaults.find(l => l._id === layer) + const defaultVal = sourcelayerDefaults.find((l) => l._id === layer) if (!defaultVal) { return false @@ -32,7 +32,7 @@ export function forceSourceLayerToDefaultsBase( context.removeSourceLayer(layer) } - const defaultVal = sourcelayerDefaults.find(l => l._id === layer) + const defaultVal = sourcelayerDefaults.find((l) => l._id === layer) if (!defaultVal) { return diff --git a/src/tv2-common/migrations/hotkeys.ts b/src/tv2-common/migrations/hotkeys.ts index fbb8961b..26393b4d 100644 --- a/src/tv2-common/migrations/hotkeys.ts +++ b/src/tv2-common/migrations/hotkeys.ts @@ -43,7 +43,7 @@ export function GetDefaultAdLibTriggers( sourceLayers ) - return shortcutsDefaults.some(defaultShortcut => { + return shortcutsDefaults.some((defaultShortcut) => { const existingShortcut = context.getTriggeredAction(defaultShortcut._id) if (!existingShortcut) { @@ -83,12 +83,12 @@ export function RemoveOldShortcuts( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const sourceLayers = sourceLayerDefaults.map(sourceLayer => context.getSourceLayer(sourceLayer._id)) as Array< + const sourceLayers = sourceLayerDefaults.map((sourceLayer) => context.getSourceLayer(sourceLayer._id)) as Array< ISourceLayerWithHotKeys | undefined > return sourceLayers.some( - sourceLayer => + (sourceLayer) => !!sourceLayer?.clearKeyboardHotkey || !!sourceLayer?.activateKeyboardHotkeys || !!sourceLayer?.activateStickyKeyboardHotkey || diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index 2e7ecc9b..d2730836 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -22,7 +22,7 @@ export * from './sourceLayers' export * from './forceSourceLayerToDefaultsBase' export * from './hotkeys' -export function RenameStudioConfig(versionStr: string, studio: string, from: string, to: string): MigrationStepStudio { +export function renameStudioConfig(versionStr: string, studio: string, from: string, to: string): MigrationStepStudio { return { id: `${versionStr}.studioConfig.rename.${from}.${studio}`, version: versionStr, @@ -105,7 +105,7 @@ export function AddGraphicToGfxTable( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const existing = (context.getBaseConfig('GFXTemplates') as unknown) as + const existing = context.getBaseConfig('GFXTemplates') as unknown as | TableConfigItemGfxTemplateWithDesign[] | undefined @@ -114,16 +114,16 @@ export function AddGraphicToGfxTable( } return !existing.some( - g => + (g) => g.INewsName === config.INewsName && g.INewsCode === config.INewsCode && g.VizTemplate === config.VizTemplate ) }, migrate: (context: MigrationContextShowStyle) => { - const existing = (context.getBaseConfig('GFXTemplates') as unknown) as TableConfigItemGfxTemplateWithDesign[] + const existing = context.getBaseConfig('GFXTemplates') as unknown as TableConfigItemGfxTemplateWithDesign[] existing.push(config) - context.setBaseConfig('GFXTemplates', (existing as unknown) as ConfigItemValue) + context.setBaseConfig('GFXTemplates', existing as unknown as ConfigItemValue) } } } @@ -139,11 +139,9 @@ export function mapGfxTemplateToDesignTemplateAndDeleteOriginals( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const gfxTemplates = (context.getBaseConfig(from) as unknown) as - | TableConfigItemGfxTemplateWithDesign[] - | undefined + const gfxTemplates = context.getBaseConfig(from) as unknown as TableConfigItemGfxTemplateWithDesign[] | undefined - const designTemplates = (context.getBaseConfig(to) as unknown) as TableConfigItemGfxDesignTemplate[] | undefined + const designTemplates = context.getBaseConfig(to) as unknown as TableConfigItemGfxDesignTemplate[] | undefined if (!gfxTemplates || !gfxTemplates.length) { return false @@ -153,22 +151,22 @@ export function mapGfxTemplateToDesignTemplateAndDeleteOriginals( return false } - return gfxTemplates.some(template => template.IsDesign) + return gfxTemplates.some((template) => template.IsDesign) }, migrate: (context: MigrationContextShowStyle) => { - const gfxTemplates = (context.getBaseConfig(from) as unknown) as TableConfigItemGfxTemplateWithDesign[] - const designTemplates = ((context.getBaseConfig(to) as unknown) as TableConfigItemGfxDesignTemplate[]) ?? [] + const gfxTemplates = context.getBaseConfig(from) as unknown as TableConfigItemGfxTemplateWithDesign[] + const designTemplates = (context.getBaseConfig(to) as unknown as TableConfigItemGfxDesignTemplate[]) ?? [] gfxTemplates - .filter(template => template.IsDesign) - .map(template => { + .filter((template) => template.IsDesign) + .map((template) => { designTemplates.push({ ...template, INewsStyleColumn: '' }) }) - const newGfxTemplates = gfxTemplates.filter(template => !template.IsDesign) + const newGfxTemplates = gfxTemplates.filter((template) => !template.IsDesign) - context.setBaseConfig(from, (newGfxTemplates as unknown) as ConfigItemValue) - context.setBaseConfig(to, (designTemplates as unknown) as ConfigItemValue) + context.setBaseConfig(from, newGfxTemplates as unknown as ConfigItemValue) + context.setBaseConfig(to, designTemplates as unknown as ConfigItemValue) } }) } @@ -184,17 +182,17 @@ export function addSourceToSourcesConfig( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextStudio) => { - const config = (context.getConfig(configId) as unknown) as TableConfigItemSourceMappingWithSisyfos[] + const config = context.getConfig(configId) as unknown as TableConfigItemSourceMappingWithSisyfos[] if (!config) { return false } - return !config.find(s => s.SourceName === source.SourceName) + return !config.find((s) => s.SourceName === source.SourceName) }, migrate: (context: MigrationContextStudio) => { - const config = (context.getConfig(configId) as unknown) as TableConfigItemSourceMappingWithSisyfos[] + const config = context.getConfig(configId) as unknown as TableConfigItemSourceMappingWithSisyfos[] config.push(source) - context.setConfig(configId, (config as unknown) as ConfigItemValue) + context.setConfig(configId, config as unknown as ConfigItemValue) } } } @@ -211,7 +209,7 @@ export function changeGfxTemplate( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const gfxTemplates = (context.getBaseConfig('GFXTemplates') as unknown) as + const gfxTemplates = context.getBaseConfig('GFXTemplates') as unknown as | TableConfigItemGfxTemplateWithDesign[] | undefined @@ -219,14 +217,14 @@ export function changeGfxTemplate( return false } - return gfxTemplates.some(g => isGfxTemplateSubset(g, oldConfig)) + return gfxTemplates.some((g) => isGfxTemplateSubset(g, oldConfig)) }, migrate: (context: MigrationContextShowStyle) => { - let existing = (context.getBaseConfig('GFXTemplates') as unknown) as TableConfigItemGfxTemplateWithDesign[] + let existing = context.getBaseConfig('GFXTemplates') as unknown as TableConfigItemGfxTemplateWithDesign[] - existing = existing.map(g => (isGfxTemplateSubset(g, oldConfig) ? { ...g, ...config } : g)) + existing = existing.map((g) => (isGfxTemplateSubset(g, oldConfig) ? { ...g, ...config } : g)) - context.setBaseConfig('GFXTemplates', (existing as unknown) as ConfigItemValue) + context.setBaseConfig('GFXTemplates', existing as unknown as ConfigItemValue) } } } @@ -350,9 +348,9 @@ export function StripFolderFromShowStyleConfig( } // Some entry in the table contains a field that needs migrating - return configTableValue.some(config => { - return configFields.some(field => { - return ((config[field] as unknown) as string | undefined)?.match(regex) + return configTableValue.some((config) => { + return configFields.some((field) => { + return (config[field] as unknown as string | undefined)?.match(regex) }) }) }, @@ -363,9 +361,9 @@ export function StripFolderFromShowStyleConfig( return } - configTableValue = configTableValue.map(config => { - configFields.forEach(field => { - const newConfig = (config[field] as unknown) as string + configTableValue = configTableValue.map((config) => { + configFields.forEach((field) => { + const newConfig = config[field] as unknown as string const matches = newConfig.match(regex) @@ -394,17 +392,17 @@ export function PrefixEvsWithEvs( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextStudio) => { - const config = (context.getConfig(configId) as unknown) as TableConfigItemSourceMappingWithSisyfos[] + const config = context.getConfig(configId) as unknown as TableConfigItemSourceMappingWithSisyfos[] - if (!config || config.find(value => value.SourceName === `EVS ${evsSourceNumber}`) !== undefined) { + if (!config || config.find((value) => value.SourceName === `EVS ${evsSourceNumber}`) !== undefined) { return false } - return config.find(value => value.SourceName === evsSourceNumber) !== undefined + return config.find((value) => value.SourceName === evsSourceNumber) !== undefined }, migrate: (context: MigrationContextStudio) => { - const config = (context.getConfig(configId) as unknown) as TableConfigItemSourceMappingWithSisyfos[] - const index: number = config.findIndex(value => value.SourceName === evsSourceNumber) + const config = context.getConfig(configId) as unknown as TableConfigItemSourceMappingWithSisyfos[] + const index: number = config.findIndex((value) => value.SourceName === evsSourceNumber) if (index === -1) { return } @@ -412,7 +410,38 @@ export function PrefixEvsWithEvs( evsSource.SourceName = `EVS ${evsSource.SourceName}` config[index] = evsSource - context.setConfig(configId, (config as unknown) as ConfigItemValue) + context.setConfig(configId, config as unknown as ConfigItemValue) + } + } +} + +export function convertStudioTableColumnToFloat( + versionStr: string, + tableId: string, + columnId: string, +): MigrationStepStudio { + return { + id: `${versionStr}.convertStudioTableColumnToFloat.${tableId}.${columnId}`, + version: versionStr, + canBeRunAutomatically: true, + validate: (context: MigrationContextStudio) => { + const config = context.getConfig(tableId) as unknown as TableConfigItemValue + + if (!config || !Array.isArray(config)) { + return false + } + + return config.find((row) => columnId in row && typeof row[columnId] === 'string') !== undefined + }, + migrate: (context: MigrationContextStudio) => { + let config = context.getConfig(tableId) as unknown as TableConfigItemValue + config = config.map((row) => { + const value = row[columnId] + if (typeof value === 'string') + row[columnId] = parseFloat(value) + return row + }) + context.setConfig(tableId, config as unknown as ConfigItemValue) } } } @@ -428,23 +457,23 @@ export function renameStudioTableColumn( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextStudio) => { - const config = (context.getConfig(tableId) as unknown) as TableConfigItemValue + const config = context.getConfig(tableId) as unknown as TableConfigItemValue if (!config || !Array.isArray(config)) { return false } - return config.find(row => oldColumnId in row) !== undefined + return config.find((row) => oldColumnId in row) !== undefined }, migrate: (context: MigrationContextStudio) => { - let config = (context.getConfig(tableId) as unknown) as TableConfigItemValue - config = config.map(row => { + let config = context.getConfig(tableId) as unknown as TableConfigItemValue + config = config.map((row) => { const value = row[oldColumnId] delete row[oldColumnId] row[newColumnId] = value return row }) - context.setConfig(tableId, (config as unknown) as ConfigItemValue) + context.setConfig(tableId, config as unknown as ConfigItemValue) } } } @@ -460,23 +489,23 @@ export function renameTableColumn( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const config = (context.getBaseConfig(tableId) as unknown) as TableConfigItemValue + const config = context.getBaseConfig(tableId) as unknown as TableConfigItemValue if (!config || !Array.isArray(config)) { return false } - return config.find(row => oldColumnId in row) !== undefined + return config.find((row) => oldColumnId in row) !== undefined }, migrate: (context: MigrationContextShowStyle) => { - let config = (context.getBaseConfig(tableId) as unknown) as TableConfigItemValue - config = config.map(row => { + let config = context.getBaseConfig(tableId) as unknown as TableConfigItemValue + config = config.map((row) => { const value = row[oldColumnId] delete row[oldColumnId] row[newColumnId] = value return row }) - context.setBaseConfig(tableId, (config as unknown) as ConfigItemValue) + context.setBaseConfig(tableId, config as unknown as ConfigItemValue) } } } diff --git a/src/tv2-common/migrations/renameConfigurationHelper.ts b/src/tv2-common/migrations/renameConfigurationHelper.ts index 64b6b7b4..3297af30 100644 --- a/src/tv2-common/migrations/renameConfigurationHelper.ts +++ b/src/tv2-common/migrations/renameConfigurationHelper.ts @@ -14,18 +14,18 @@ export function renameTableId(version: string, oldTableId: string, newTableId: s version, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const oldConfigTable = (context.getBaseConfig(oldTableId) as unknown) as TableConfigItemValue + const oldConfigTable = context.getBaseConfig(oldTableId) as unknown as TableConfigItemValue if (!oldConfigTable || oldConfigTable.length === 0) { return false } - const newConfigTable = (context.getBaseConfig(newTableId) as unknown) as TableConfigItemValue + const newConfigTable = context.getBaseConfig(newTableId) as unknown as TableConfigItemValue return !newConfigTable }, migrate: (context: MigrationContextShowStyle) => { - const oldConfigTable = (context.getBaseConfig(oldTableId) as unknown) as TableConfigItemValue - const newConfigTable = ((context.getBaseConfig(newTableId) as unknown) as TableConfigItemValue) ?? [] - oldConfigTable.map(value => newConfigTable.push(value)) + const oldConfigTable = context.getBaseConfig(oldTableId) as unknown as TableConfigItemValue + const newConfigTable = (context.getBaseConfig(newTableId) as unknown as TableConfigItemValue) ?? [] + oldConfigTable.map((value) => newConfigTable.push(value)) context.setBaseConfig(newTableId, newConfigTable) context.removeBaseConfig(oldTableId) @@ -46,11 +46,11 @@ export function renameBlueprintConfiguration( version, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const oldConfig = (context.getBaseConfig(oldConfigurationName) as unknown) as BasicConfigItemValue + const oldConfig = context.getBaseConfig(oldConfigurationName) as unknown as BasicConfigItemValue return oldConfig !== undefined }, migrate: (context: MigrationContextShowStyle) => { - const oldConfig = (context.getBaseConfig(oldConfigurationName) as unknown) as BasicConfigItemValue + const oldConfig = context.getBaseConfig(oldConfigurationName) as unknown as BasicConfigItemValue context.setBaseConfig(newConfigurationName, oldConfig) context.removeBaseConfig(oldConfigurationName) diff --git a/src/tv2-common/migrations/transitions.ts b/src/tv2-common/migrations/transitions.ts index d405548e..f8fa8aef 100644 --- a/src/tv2-common/migrations/transitions.ts +++ b/src/tv2-common/migrations/transitions.ts @@ -30,19 +30,19 @@ export function UpsertValuesIntoTransitionTable( ): MigrationStepShowStyle[] { const steps: MigrationStepShowStyle[] = [] - values.forEach(val => { + values.forEach((val) => { steps.push({ id: `${versionStr}.insertTransition.${val.Transition.replace(/[\s\W]/g, '_')}`, version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const table = (context.getBaseConfig('Transitions') as unknown) as TransitionsTableValue[] | undefined + const table = context.getBaseConfig('Transitions') as unknown as TransitionsTableValue[] | undefined if (!table) { return `Transitions table does not exists` } - const existingVal = table.find(v => v.Transition === val.Transition) + const existingVal = table.find((v) => v.Transition === val.Transition) if (!existingVal) { return `Transition "${val.Transition}" does not exist` @@ -51,7 +51,7 @@ export function UpsertValuesIntoTransitionTable( return existingVal.Transition !== val.Transition }, migrate: (context: MigrationContextShowStyle) => { - const table = (context.getBaseConfig('Transitions') as unknown) as TransitionsTableValue[] | undefined + const table = context.getBaseConfig('Transitions') as unknown as TransitionsTableValue[] | undefined if (!table) { context.setBaseConfig('Transitions', [ diff --git a/src/tv2-common/nextPartCue.ts b/src/tv2-common/nextPartCue.ts index d13cdc99..6669fde8 100644 --- a/src/tv2-common/nextPartCue.ts +++ b/src/tv2-common/nextPartCue.ts @@ -10,7 +10,7 @@ export function GetNextPartCue(partdefinition: PartDefinition, currentCue: numbe const index = partdefinition.cues .slice(currentCue + 1) .findIndex( - cue => + (cue) => cue.type === CueType.DVE || cue.type === CueType.Ekstern || (cue.type === CueType.Graphic && cue.target === 'FULL' && partdefinition.type !== PartType.Grafik) || diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index ece5a0f7..3e7d4435 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -145,7 +145,7 @@ function processServerLookaheads( sourceLayers: ABSourceLayers ): OnGenerateTimelineObj[] { // Includes any non-active servers present in current part - const serversInCurrentPart = timeline.filter(obj => { + const serversInCurrentPart = timeline.filter((obj) => { if (_.isArray(obj.enable)) { return false } @@ -160,7 +160,7 @@ function processServerLookaheads( [sourceLayers.Caspar.ClipPending, CasparPlayerClip(1), CasparPlayerClip(2)].includes(layer) && !obj.isLookahead && resolvedPieces.some( - p => p._id === obj.pieceInstanceId && p.partInstanceId === context.core.currentPartInstance?._id + (p) => p._id === obj.pieceInstanceId && p.partInstanceId === context.core.currentPartInstance?._id ) ) }) @@ -177,7 +177,7 @@ function processServerLookaheads( // Filter out lookaheads for servers that are currently in PGM. // Does not filter out AUX lookaheads. Should it? - return timeline.filter(obj => { + return timeline.filter((obj) => { if (_.isArray(obj.enable)) { return true } @@ -196,7 +196,7 @@ function processServerLookaheads( return !( [sourceLayers.Caspar.ClipPending, CasparPlayerClip(1), CasparPlayerClip(2)] - .map(l => `${l}_lookahead`) + .map((l) => `${l}_lookahead`) .includes(layer) && obj.isLookahead && sessionsInCurrentPart.includes(mediaPlayerSession) @@ -209,8 +209,8 @@ function isAnyPieceInjectedIntoPart( resolvedPieces: Array> ) { return resolvedPieces - .filter(piece => piece.partInstanceId === context.core.currentPartInstance?._id) - .some(piece => { + .filter((piece) => piece.partInstanceId === context.core.currentPartInstance?._id) + .some((piece) => { return piece.piece.metaData?.sisyfosPersistMetaData?.isPieceInjectedInPart }) } @@ -233,7 +233,7 @@ export function getEndStateForPart( const previousPartEndState = partInstance?.previousPartEndState as Partial const activePieces = resolvedPieces.filter( - p => + (p) => _.isNumber(p.piece.enable.start) && p.piece.enable && p.piece.enable.start <= time && @@ -285,7 +285,7 @@ export function createSisyfosPersistedLevelsTimelineObject( deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, overridePriority: 1, - channels: layersToPersist.map(layer => { + channels: layersToPersist.map((layer) => { return { mappedLayer: layer, isPgm: 1 @@ -300,7 +300,7 @@ function findLayersToPersist( sisyfosLayersThatWantsToBePersisted: string[] ): string[] { const sortedPieces = pieces - .filter(piece => piece.piece.metaData?.sisyfosPersistMetaData) + .filter((piece) => piece.piece.metaData?.sisyfosPersistMetaData) .sort((a, b) => b.resolvedStart - a.resolvedStart) if (sortedPieces.length === 0) { @@ -349,7 +349,7 @@ export function disablePilotWipeAfterJingle( previousPartEndState: PartEndStateExt | undefined, resolvedPieces: IBlueprintResolvedPieceInstance[] ) { - if (previousPartEndState?.isJingle && resolvedPieces.find(p => p.piece.tags?.includes(TallyTags.FULL_IS_LIVE))) { + if (previousPartEndState?.isJingle && resolvedPieces.find((p) => p.piece.tags?.includes(TallyTags.FULL_IS_LIVE))) { for (const obj of timeline) { if (obj.content.deviceType === TSR.DeviceType.ATEM && !obj.isLookahead) { const obj2 = obj as TSR.TimelineObjAtemAny diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index d65cf532..a19923d2 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -97,10 +97,7 @@ export function CreateEffektForPartInner< } const effektConfig = context.config.showStyle.BreakerConfig.find( - conf => - conf.BreakerName.toString() - .trim() - .toUpperCase() === effekt.toUpperCase() + (conf) => conf.BreakerName.toString().trim().toUpperCase() === effekt.toUpperCase() ) if (!effektConfig) { context.core.notifyUserWarning(`Could not find effekt ${effekt}`) diff --git a/src/tv2-common/segment/context.ts b/src/tv2-common/segment/context.ts index 4128b422..0293128a 100644 --- a/src/tv2-common/segment/context.ts +++ b/src/tv2-common/segment/context.ts @@ -16,7 +16,8 @@ export interface ExtendedSegmentContext extends ExtendedShowStyleContextImpl - implements ExtendedSegmentContext { + implements ExtendedSegmentContext +{ constructor(readonly core: ISegmentUserContext, readonly uniformConfig: UniformConfig) { super(core, uniformConfig) } diff --git a/src/tv2-common/sources.ts b/src/tv2-common/sources.ts index dce167c2..7e28e4e8 100644 --- a/src/tv2-common/sources.ts +++ b/src/tv2-common/sources.ts @@ -28,7 +28,7 @@ export function parseMapStr( const res: Array<{ id: string; val: number }> = [] const inputs = str.split(',') - inputs.forEach(i => { + inputs.forEach((i) => { if (i === '') { return } @@ -60,7 +60,7 @@ export function ParseMappingTable( type: SourceInfoType, sourceLayerType: SourceLayerType ): SourceInfo[] { - return studioConfig.map(conf => ({ + return studioConfig.map((conf) => ({ type, id: conf.SourceName, port: conf.SwitcherSource, @@ -109,7 +109,7 @@ export function findSourceInfo(sources: SourceMapping, sourceDefinition: SourceD default: return undefined } - return _.find(arrayToSearchIn, s => s.id === sourceDefinition.id) + return _.find(arrayToSearchIn, (s) => s.id === sourceDefinition.id) } export function SourceInfoToSourceDefinition( diff --git a/src/tv2-common/uniformConfig.ts b/src/tv2-common/uniformConfig.ts index 308a54be..cf1ebc68 100644 --- a/src/tv2-common/uniformConfig.ts +++ b/src/tv2-common/uniformConfig.ts @@ -1,39 +1,40 @@ import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' +import _ = require('underscore') import { SpecialInput } from './videoSwitchers' /** This config contains hardcoded values that differ between Gallery and Qbox Blueprints */ export interface UniformConfig { - SwitcherLLayers: { + switcherLLayers: { /** The layer where cuts and transitions between primary pieces are happening */ - PrimaryMixEffect: SwitcherMixEffectLLayer + primaryMixEffect: SwitcherMixEffectLLayer /** Optional layer where the same cuts and transitions as in `PrimaryMixEffect` are applied */ - PrimaryMixEffectClone?: SwitcherMixEffectLLayer + primaryMixEffectClone?: SwitcherMixEffectLLayer /** Optional layer where lookaheads are generated as Preview timeline objects */ - NextPreviewMixEffect?: SwitcherMixEffectLLayer + nextPreviewMixEffect?: SwitcherMixEffectLLayer /** Optional layer where lookaheads are generated as Aux timeline objects */ - NextAux?: SwitcherAuxLLayer + nextAux?: SwitcherAuxLLayer /** Optional layer to show the jingles on an USK */ - JingleUskMixEffect?: SwitcherMixEffectLLayer + jingleUskMixEffect?: SwitcherMixEffectLLayer /** Optional layer to show the jingles lookahead on */ - JingleNextMixEffect?: SwitcherMixEffectLLayer + jingleNextMixEffect?: SwitcherMixEffectLLayer /** Optional layer to preview servers on Aux */ - NextServerAux?: SwitcherAuxLLayer + nextServerAux?: SwitcherAuxLLayer /** Optional mix-minus layer */ - MixMinusAux?: SwitcherAuxLLayer + mixMinusAux?: SwitcherAuxLLayer } /** * MixEffects grouped by their roles (note Program !== Primary) * Relevant mostly for baseline */ - MixEffects: { - Program: MixEffect - Clean: MixEffect + mixEffects: { + program: MixEffect + clean: MixEffect } /** * Auxes on which certain inputs appear * It allows associating TriCaster's MEs to mix outputs in order to route MEs to matrix outs */ - SpecialInputAuxLLayers: Partial> + specialInputAuxLLayers: Partial> } export interface MixEffect { @@ -41,3 +42,23 @@ export interface MixEffect { mixEffectLayer: SwitcherMixEffectLLayer auxLayer?: SwitcherAuxLLayer } + +export function getSpecialLayers( + mixEffects: UniformConfig['mixEffects'] +): Partial> { + return Object.fromEntries( + Object.values(mixEffects) + .filter((mixEffect) => mixEffect.auxLayer) + .map((mixEffect) => [mixEffect.input, mixEffect.auxLayer]) + ) +} + +export function getUsedLayers(uniformConfig: UniformConfig): Array { + return _.uniq( + Object.values(uniformConfig.switcherLLayers).concat( + Object.values(uniformConfig.mixEffects).flatMap((mixeffect) => + _.compact([mixeffect.mixEffectLayer, mixeffect.auxLayer]) + ) + ) + ) +} diff --git a/src/tv2-common/updatePolicies/adlibs.ts b/src/tv2-common/updatePolicies/adlibs.ts index 7467c005..be6028be 100644 --- a/src/tv2-common/updatePolicies/adlibs.ts +++ b/src/tv2-common/updatePolicies/adlibs.ts @@ -26,11 +26,11 @@ export function updateAdLibInstances( const rawAdlibRefs = normalizeArrayToMap(newPart.referencedAdlibs, '_id') const groupedAdlibInstances = _.groupBy( existingPartInstance.pieceInstances, - p => p.adLibSourceId ?? defaultAdlibSourceId + (p) => p.adLibSourceId ?? defaultAdlibSourceId ) for (const [adlibId, adlibPieces] of Object.entries(groupedAdlibInstances)) { if (adlibId !== defaultAdlibSourceId) { - const updatableAdlibPieces = adlibPieces.filter(p => { + const updatableAdlibPieces = adlibPieces.filter((p) => { const metaData = p.piece.metaData as PieceMetaData return !metaData?.modifiedByAction }) diff --git a/src/tv2-common/updatePolicies/partProperties.ts b/src/tv2-common/updatePolicies/partProperties.ts index 3432a161..cbb99113 100644 --- a/src/tv2-common/updatePolicies/partProperties.ts +++ b/src/tv2-common/updatePolicies/partProperties.ts @@ -20,7 +20,7 @@ const partPropertiesToOmit = [ 'shouldNotifyCurrentPlayingPart' ] as const -const clearedMutatablePart: Complete> = { +const clearedMutatablePart: Complete> = { metaData: undefined, expectedDuration: undefined, budgetDuration: undefined, diff --git a/src/tv2-common/updatePolicies/pieces.ts b/src/tv2-common/updatePolicies/pieces.ts index 30e9bc31..7e045339 100644 --- a/src/tv2-common/updatePolicies/pieces.ts +++ b/src/tv2-common/updatePolicies/pieces.ts @@ -33,7 +33,7 @@ export function stopOrReplaceEditablePieces( let pieceInstancesOnLayersInExistingPart = existingPartInstance.pieceInstances if (allowedSourceLayers) { - pieceInstancesOnLayersInExistingPart = existingPartInstance.pieceInstances.filter(p => + pieceInstancesOnLayersInExistingPart = existingPartInstance.pieceInstances.filter((p) => allowedSourceLayers.has(p.piece.sourceLayerId) ) } @@ -41,7 +41,9 @@ export function stopOrReplaceEditablePieces( let pieceInstancesOnLayersInNewPart = newPart.pieceInstances if (allowedSourceLayers) { - pieceInstancesOnLayersInNewPart = newPart.pieceInstances.filter(p => allowedSourceLayers.has(p.piece.sourceLayerId)) + pieceInstancesOnLayersInNewPart = newPart.pieceInstances.filter((p) => + allowedSourceLayers.has(p.piece.sourceLayerId) + ) } const groupedPieceInstancesInNewPart = groupPieceInstances(pieceInstancesOnLayersInNewPart) diff --git a/src/tv2-common/util.ts b/src/tv2-common/util.ts index 61edcf21..2ef0406b 100644 --- a/src/tv2-common/util.ts +++ b/src/tv2-common/util.ts @@ -53,12 +53,7 @@ export function joinAssetToNetworkPath( // Replace every `\\` with `\`, then replace every `\` with `/` const folderWithForwardSlashes = folder?.replace(/\\\\/g, '/').replace(/\\/g, '/') const assetWithForwardSlashes = assetFile.replace(/\\\\/g, '/').replace(/\\/g, '/') - const networkPathWithForwardSlashes = - networkPath[0] + - networkPath - .slice(1) - .replace(/\\\\/g, '/') - .replace(/\\/g, '/') + const networkPathWithForwardSlashes = networkPath[0] + networkPath.slice(1).replace(/\\\\/g, '/').replace(/\\/g, '/') // Remove trailing/leading slash from folder and leading slash from asset const folderWithoutLeadingTrailingSlashes = folderWithForwardSlashes?.replace(/\/+$/, '').replace(/^\/+/, '') @@ -82,4 +77,4 @@ export function joinAssetToNetworkPath( export function generateExternalId(context: ICommonContext, action: ActionBase): string { return context.getHashId(JSON.stringify(action), false) -} \ No newline at end of file +} diff --git a/src/tv2-common/videoSwitchers/Atem.ts b/src/tv2-common/videoSwitchers/Atem.ts index fdffb41e..6a6f8c5d 100644 --- a/src/tv2-common/videoSwitchers/Atem.ts +++ b/src/tv2-common/videoSwitchers/Atem.ts @@ -77,7 +77,7 @@ export class Atem extends VideoSwitcherImpl { transitionDuration?: number | undefined ): TSR.TSRTimelineObj { if (!this.isMixEffect(timelineObject)) { - // @todo: log error or throw + this.logWrongTimelineObjectType(timelineObject, this.updateTransition.name) return timelineObject } timelineObject.content.me.transition = this.getTransition(transition) @@ -89,7 +89,7 @@ export class Atem extends VideoSwitcherImpl { previewInput: number | SpecialInput ): TSR.TSRTimelineObj { if (!this.isMixEffect(timelineObject)) { - // @todo: log error or throw + this.logWrongTimelineObjectType(timelineObject, this.updatePreviewInput.name) return timelineObject } timelineObject.content.me.previewInput = this.getInputNumber(previewInput) @@ -97,7 +97,7 @@ export class Atem extends VideoSwitcherImpl { } public updateInput(timelineObject: TSR.TSRTimelineObj, input: number | SpecialInput): TSR.TSRTimelineObj { if (!this.isMixEffect(timelineObject)) { - // @todo: log error or throw + this.logWrongTimelineObjectType(timelineObject, this.updateInput.name) return timelineObject } timelineObject.content.me.input = this.getInputNumber(input) @@ -194,7 +194,7 @@ export class Atem extends VideoSwitcherImpl { } public updateAuxInput(timelineObject: TSR.TSRTimelineObj, input: number | SpecialInput): TSR.TSRTimelineObj { if (!this.isAux(timelineObject)) { - // @todo: log error or throw + this.logWrongTimelineObjectType(timelineObject, this.updateAuxInput.name) return timelineObject } timelineObject.content.aux.input = this.getInputNumber(input) @@ -263,7 +263,7 @@ export class Atem extends VideoSwitcherImpl { if (!keyers?.length) { return } - return keyers.map(keyer => ({ + return keyers.map((keyer) => ({ upstreamKeyerId: keyer.config.Number, onAir: keyer.onAir, mixEffectKeyType: 0, diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 20dc5da6..5cb5122a 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -78,7 +78,7 @@ export class TriCaster extends VideoSwitcherImpl { transitionDuration?: number | undefined ): TSR.TSRTimelineObj { if (!this.isMixEffect(timelineObject)) { - // @todo: log error or throw + this.logWrongTimelineObjectType(timelineObject, this.updateTransition.name) return timelineObject } timelineObject.content.me.transitionEffect = this.getTransition(transition) @@ -94,7 +94,7 @@ export class TriCaster extends VideoSwitcherImpl { previewInput: number | SpecialInput ): TSR.TSRTimelineObj { if (!this.isMixEffect(timelineObject)) { - // @todo: log error or throw + this.logWrongTimelineObjectType(timelineObject, this.updatePreviewInput.name) return timelineObject } ;(timelineObject.content.me as TSR.TriCasterMixEffectWithPreview).previewInput = this.getInputName(previewInput) @@ -103,7 +103,7 @@ export class TriCaster extends VideoSwitcherImpl { public updateInput(timelineObject: TSR.TSRTimelineObj, input: number | SpecialInput): TSR.TSRTimelineObj { if (!this.isMixEffect(timelineObject)) { - // @todo: log error or throw + this.logWrongTimelineObjectType(timelineObject, this.updateInput.name) return timelineObject } ;(timelineObject.content.me as TSR.TriCasterMixEffectInMixMode).programInput = this.getInputName(input) @@ -136,7 +136,7 @@ export class TriCaster extends VideoSwitcherImpl { const mapping = this.core.getStudioMappings()[layerName] if (!mapping || mapping.device !== TSR.DeviceType.TRICASTER) { this.core.logWarning(`Unable to find TriCaster mapping for layer ${layerName}`) - } else if (((mapping as unknown) as TSR.MappingTriCaster).mappingType === TSR.MappingTriCasterType.MATRIX_OUTPUT) { + } else if ((mapping as unknown as TSR.MappingTriCaster).mappingType === TSR.MappingTriCasterType.MATRIX_OUTPUT) { if (props.content.input) { return { ...this.getBaseProperties(props, props.layer), @@ -160,7 +160,7 @@ export class TriCaster extends VideoSwitcherImpl { public updateAuxInput(timelineObject: TSR.TSRTimelineObj, input: number | SpecialInput): TSR.TSRTimelineObj { if (!this.isAux(timelineObject)) { - // @todo: log error or throw + this.logWrongTimelineObjectType(timelineObject, this.updateAuxInput.name) return timelineObject } timelineObject.content.source = this.getInputName(input) @@ -168,7 +168,7 @@ export class TriCaster extends VideoSwitcherImpl { } public isDveBoxes = (timelineObject: TimelineObjectCoreExt): boolean => { - // @todo: this is ugly + // @todo: this is ugly, but works return ( TSR.isTimelineObjTriCasterME(timelineObject) && !!(timelineObject.content.me as TSR.TriCasterMixEffectInEffectMode).layers @@ -241,7 +241,7 @@ export class TriCaster extends VideoSwitcherImpl { if (input < MAX_REGULAR_INPUT_NUMBER) { return `input${input as number}` } - const auxLayer = this.uniformConfig.SpecialInputAuxLLayers[input] + const auxLayer = this.uniformConfig.specialInputAuxLLayers[input] if (!auxLayer) { this.core.logWarning(`Unable to find TriCaster AUX layer for input ${input}`) return 'black' @@ -253,8 +253,8 @@ export class TriCaster extends VideoSwitcherImpl { this.core.logWarning(`Unable to find TriCaster mapping for layer ${layerName}`) return 'black' } - if (((mapping as unknown) as TSR.MappingTriCaster).mappingType === TSR.MappingTriCasterType.MIX_OUTPUT) { - return ((mapping as unknown) as TSR.MappingTriCasterMixOutput).name + if ((mapping as unknown as TSR.MappingTriCaster).mappingType === TSR.MappingTriCasterType.MIX_OUTPUT) { + return (mapping as unknown as TSR.MappingTriCasterMixOutput).name } return 'black' } diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts index a21168f2..d0f631bd 100644 --- a/src/tv2-common/videoSwitchers/VideoSwitcher.ts +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -43,40 +43,40 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { } public getOnAirTimelineObjects(properties: OnAirMixEffectProps): TSR.TSRTimelineObj[] { const result: TSR.TSRTimelineObj[] = [] - const primaryId = properties.id ?? this.core.getHashId(this.uniformConfig.SwitcherLLayers.PrimaryMixEffect, true) + const primaryId = properties.id ?? this.core.getHashId(this.uniformConfig.switcherLLayers.primaryMixEffect, true) result.push( this.getMixEffectTimelineObject({ ...properties, id: primaryId, - layer: this.uniformConfig.SwitcherLLayers.PrimaryMixEffect + layer: this.uniformConfig.switcherLLayers.primaryMixEffect }) ) - if (this.uniformConfig.SwitcherLLayers.PrimaryMixEffectClone) { + if (this.uniformConfig.switcherLLayers.primaryMixEffectClone) { result.push( this.getMixEffectTimelineObject({ ..._.omit(properties, 'classes'), - layer: this.uniformConfig.SwitcherLLayers.PrimaryMixEffectClone, + layer: this.uniformConfig.switcherLLayers.primaryMixEffectClone, metaData: { ...properties.metaData, context: `Clone of Primary MixEffect timeline object ${primaryId}` } }) ) } - if (this.uniformConfig.SwitcherLLayers.NextPreviewMixEffect && properties.content.input) { + if (this.uniformConfig.switcherLLayers.nextPreviewMixEffect && properties.content.input) { result.push( this.getMixEffectTimelineObject({ ..._.omit(properties, 'content', 'classes'), content: { previewInput: properties.content.input }, - layer: this.uniformConfig.SwitcherLLayers.NextPreviewMixEffect, + layer: this.uniformConfig.switcherLLayers.nextPreviewMixEffect, metaData: { ...properties.metaData, context: `Preview Lookahead for ${primaryId}` } }) ) } - if (this.uniformConfig.SwitcherLLayers.NextAux && properties.content.input) { + if (this.uniformConfig.switcherLLayers.nextAux && properties.content.input) { result.push( this.getAuxTimelineObject({ ..._.omit(properties, 'content', 'classes'), priority: 0, // lower than lookahead-lookahead content: { input: properties.content.input }, - layer: this.uniformConfig.SwitcherLLayers.NextAux, + layer: this.uniformConfig.switcherLLayers.nextAux, metaData: { ...properties.metaData, context: `Aux Lookahead for ${primaryId}` } }) ) @@ -106,4 +106,12 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { public abstract getDskTimelineObject(properties: DskProps): TSR.TSRTimelineObj public abstract getAuxTimelineObject(properties: AuxProps): TSR.TSRTimelineObj + + protected logWrongTimelineObjectType(timelineObject: TSR.TSRTimelineObj, functionName: string) { + this.core.logWarning( + `Modifying an incompatible timeline object (${JSON.stringify( + _.pick(timelineObject.content, 'deviceType', 'type') + )}) in ${functionName}` + ) + } } diff --git a/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts index 7071737a..1f166169 100644 --- a/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts @@ -10,7 +10,6 @@ import { VideoSwitcherImpl } from '../VideoSwitcher' const DURATION: number = 50 function setupAtem(studioConfigOverrides?: Partial) { - // @todo: is this the correct way? const context = makeMockGalleryContext({ studioConfig: { SwitcherType: SwitcherType.ATEM, ...studioConfigOverrides } }) diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index 21c1d852..ecef74b6 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -9,7 +9,6 @@ const DURATION_FRAMES: number = 50 const DURATION_SECONDS: number = DURATION_FRAMES / 25 function setupTriCaster(mockConfigOverrides?: MockConfigOverrides) { - // @todo: is this the correct way? const context = makeMockGalleryContext({ ...mockConfigOverrides, studioConfig: { SwitcherType: SwitcherType.TRICASTER, ...mockConfigOverrides?.studioConfig } @@ -352,7 +351,7 @@ describe('TriCaster', () => { }) }, uniformConfig: { - SpecialInputAuxLLayers: { + specialInputAuxLLayers: { [SpecialInput.ME1_PROGRAM]: SwitcherAuxLLayer.AuxProgram, [SpecialInput.ME3_PROGRAM]: SwitcherAuxLLayer.AuxClean } diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index c8f8b292..5417d97c 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -1,6 +1,6 @@ import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' import { SwitcherDskProps, TimelineObjectMetaData } from 'tv2-common' -import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' +import { SwitcherAuxLLayer, SwitcherDskLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' import { AtemSourceIndex } from '../../types/atem' export enum SwitcherType { @@ -63,8 +63,7 @@ export interface MixEffectProps extends TimelineObjectProps { } } -export interface OnAirMixEffectProps extends Omit { -} +export interface OnAirMixEffectProps extends Omit {} export interface Keyer { onAir: boolean @@ -72,7 +71,7 @@ export interface Keyer { } export interface DskProps extends TimelineObjectProps { - layer: string // @todo: better type + layer: SwitcherDskLLayer content: { onAir: boolean config: SwitcherDskProps diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index 9b070a50..e4b6c083 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -218,6 +218,8 @@ export enum SwitcherDveLLayer { DveBoxes = 'dve_boxes' } +export type SwitcherDskLLayer = `dsk_${number}` + export enum SwitcherMediaPlayerLLayer { Mp1 = 'mp1' } diff --git a/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts b/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts new file mode 100644 index 00000000..922abf94 --- /dev/null +++ b/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts @@ -0,0 +1,354 @@ +import { IBlueprintActionManifest } from 'blueprints-integration' +import { + ActionCallRobotPreset, + ActionClearGraphics, + ActionCutSourceToBox, + ActionCutToCamera, + ActionFadeDownPersistedAudioLevels, + ActionRecallLastDVE, + ActionRecallLastLive, + ActionSelectDVELayout, + ExtendedShowStyleContext, + generateExternalId, + GetTransitionAdLibActions, + replaySourceName, + SourceDefinitionKam, + SourceInfo, + SourceInfoToSourceDefinition, + SourceInfoType, + t +} from 'tv2-common' +import { AdlibActionType, AdlibTagCutToBox, AdlibTags, SharedOutputLayers, SourceType, TallyTags } from 'tv2-constants' +import * as _ from 'underscore' +import { GalleryBlueprintConfig } from './helpers/config' +import { NUMBER_OF_DVE_BOXES } from './helpers/content/dve' +import { SourceLayer } from './layers' + +export class GlobalAdlibActionsGenerator { + private config: GalleryBlueprintConfig + constructor(private readonly context: ExtendedShowStyleContext) { + this.config = context.config + } + + public generate(): IBlueprintActionManifest[] { + const blueprintActions: IBlueprintActionManifest[] = [] + let globalRank = 1000 + + this.config.sources.cameras + .slice(0, 5) // the first x cameras to create INP1/2/3 cam-adlibs from + .forEach((o) => { + blueprintActions.push(this.makeCutCameraAction(o, false, globalRank++)) + }) + + this.config.sources.cameras + .slice(0, 5) // the first x cameras to create preview cam-adlibs from + .forEach((o) => { + blueprintActions.push(this.makeCutCameraAction(o, true, globalRank++)) + }) + + this.config.sources.cameras + .slice(0, 5) // the first x cameras to dve actions from + .forEach((o) => { + blueprintActions.push(...this.makeAdlibBoxesActions(o, globalRank++)) + }) + + this.config.sources.lives + .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from + .forEach((o) => { + blueprintActions.push(...this.makeAdlibBoxesActions(o, globalRank++)) + }) + + this.config.sources.feeds + .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from + .forEach((o) => { + blueprintActions.push(...this.makeAdlibBoxesActions(o, globalRank++)) + }) + + this.config.sources.replays.forEach((o) => { + if (!/EPSIO/i.test(o.id)) { + blueprintActions.push(...this.makeAdlibBoxesActionsReplay(o, globalRank++, false)) + } + blueprintActions.push(...this.makeAdlibBoxesActionsReplay(o, globalRank++, true)) + }) + + blueprintActions.push(this.makeRecallLastLiveAction()) + + blueprintActions.push(...this.makeServerAdlibBoxesActions(globalRank++)) + + blueprintActions.push(this.makeClearGraphicsAction()) + blueprintActions.push(this.makeClearGraphicsAltudAction()) + + blueprintActions.push(...GetTransitionAdLibActions(this.config, 800)) + + blueprintActions.push(this.makeLastDveAction()) + blueprintActions.push(...this.makeDveLayoutActions()) + + blueprintActions.push(this.makePersistedAudioLevelsAction()) + + blueprintActions.push(this.makeRobotPresetAction()) + + return blueprintActions + } + + private makeCutCameraAction(info: SourceInfo, queue: boolean, rank: number): IBlueprintActionManifest { + const sourceDefinition = SourceInfoToSourceDefinition(info) as SourceDefinitionKam + const userData: ActionCutToCamera = { + type: AdlibActionType.CUT_TO_CAMERA, + queue, + sourceDefinition + } + return { + externalId: generateExternalId(this.context.core, userData), + actionId: AdlibActionType.CUT_TO_CAMERA, + userData, + userDataManifest: {}, + display: { + _rank: rank, + label: t(sourceDefinition.name), + sourceLayerId: SourceLayer.PgmCam, + outputLayerId: SharedOutputLayers.PGM, + content: {}, + tags: queue ? [AdlibTags.ADLIB_QUEUE_NEXT] : [AdlibTags.ADLIB_CUT_DIRECT] + } + } + } + + private makeRecallLastLiveAction(): IBlueprintActionManifest { + const userData: ActionRecallLastLive = { + type: AdlibActionType.RECALL_LAST_LIVE + } + return { + externalId: generateExternalId(this.context.core, userData), + actionId: AdlibActionType.RECALL_LAST_LIVE, + userData, + userDataManifest: {}, + display: { + _rank: 1, + label: t('Last Live'), + sourceLayerId: SourceLayer.PgmLive, + outputLayerId: SharedOutputLayers.PGM, + tags: [AdlibTags.ADLIB_RECALL_LAST_LIVE] + } + } + } + + private makeAdlibBoxesActions(info: SourceInfo, rank: number): IBlueprintActionManifest[] { + const blueprintActions: IBlueprintActionManifest[] = [] + for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { + const name = `${info.type} ${info.id}` + const layer = info.type === SourceInfoType.KAM ? SourceLayer.PgmCam : SourceLayer.PgmLive + + const userData: ActionCutSourceToBox = { + type: AdlibActionType.CUT_SOURCE_TO_BOX, + name, + box, + sourceDefinition: SourceInfoToSourceDefinition(info) + } + blueprintActions.push({ + externalId: generateExternalId(this.context.core, userData), + actionId: AdlibActionType.CUT_SOURCE_TO_BOX, + userData, + userDataManifest: {}, + display: { + _rank: rank + 0.1 * box, + label: t(`${name} inp ${box + 1}`), + sourceLayerId: layer, + outputLayerId: SharedOutputLayers.SEC, + content: {}, + tags: [AdlibTagCutToBox(box)] + } + }) + } + return blueprintActions + } + + private makeAdlibBoxesActionsReplay(info: SourceInfo, rank: number, vo: boolean): IBlueprintActionManifest[] { + const blueprintActions: IBlueprintActionManifest[] = [] + for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { + const name = replaySourceName(info.id, vo) + const userData: ActionCutSourceToBox = { + type: AdlibActionType.CUT_SOURCE_TO_BOX, + name, + box, + sourceDefinition: { + sourceType: SourceType.REPLAY, + id: info.id, + vo, + raw: '', + name + } + } + blueprintActions.push({ + externalId: generateExternalId(this.context.core, userData), + actionId: AdlibActionType.CUT_SOURCE_TO_BOX, + userData, + userDataManifest: {}, + display: { + _rank: rank + 0.1 * box, + label: t(`${name} inp ${box + 1}`), + sourceLayerId: SourceLayer.PgmLocal, + outputLayerId: SharedOutputLayers.SEC, + content: {}, + tags: [AdlibTagCutToBox(box), vo ? AdlibTags.ADLIB_VO_AUDIO_LEVEL : AdlibTags.ADLIB_FULL_AUDIO_LEVEL] + } + }) + } + return blueprintActions + } + + private makeServerAdlibBoxesActions(rank: number): IBlueprintActionManifest[] { + const blueprintActions: IBlueprintActionManifest[] = [] + for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { + const userData: ActionCutSourceToBox = { + type: AdlibActionType.CUT_SOURCE_TO_BOX, + name: `SERVER`, + box, + sourceDefinition: { sourceType: SourceType.SERVER } + } + blueprintActions.push({ + externalId: generateExternalId(this.context.core, userData), + actionId: AdlibActionType.CUT_SOURCE_TO_BOX, + userData, + userDataManifest: {}, + display: { + _rank: rank + 0.1 * box, + label: t(`Server inp ${box + 1}`), + sourceLayerId: SourceLayer.PgmServer, + outputLayerId: SharedOutputLayers.SEC, + content: {}, + tags: [AdlibTagCutToBox(box)] + } + }) + } + return blueprintActions + } + + private makeClearGraphicsAction(): IBlueprintActionManifest { + const userData: ActionClearGraphics = { + type: AdlibActionType.CLEAR_GRAPHICS, + sendCommands: true, + label: 'GFX Clear' + } + return { + externalId: generateExternalId(this.context.core, userData), + actionId: AdlibActionType.CLEAR_GRAPHICS, + userData, + userDataManifest: {}, + display: { + _rank: 300, + label: t(`GFX Clear`), + sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, + outputLayerId: SharedOutputLayers.SEC, + content: {}, + tags: [AdlibTags.ADLIB_STATIC_BUTTON], + currentPieceTags: [TallyTags.GFX_CLEAR], + nextPieceTags: [TallyTags.GFX_CLEAR] + } + } + } + + private makeClearGraphicsAltudAction(): IBlueprintActionManifest { + const userData: ActionClearGraphics = { + type: AdlibActionType.CLEAR_GRAPHICS, + sendCommands: false, + label: 'GFX Altud' + } + return { + externalId: generateExternalId(this.context.core, userData), + actionId: AdlibActionType.CLEAR_GRAPHICS, + userData, + userDataManifest: {}, + display: { + _rank: 400, + label: t(`GFX Altud`), + sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, + outputLayerId: SharedOutputLayers.SEC, + content: {}, + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_ALTUD], + currentPieceTags: [TallyTags.GFX_ALTUD], + nextPieceTags: [TallyTags.GFX_ALTUD] + } + } + } + + private makeLastDveAction(): IBlueprintActionManifest { + const recallLastLiveDveUserData: ActionRecallLastDVE = { + type: AdlibActionType.RECALL_LAST_DVE + } + return { + externalId: generateExternalId(this.context.core, recallLastLiveDveUserData), + actionId: AdlibActionType.RECALL_LAST_DVE, + userData: recallLastLiveDveUserData, + userDataManifest: {}, + display: { + _rank: 1, + label: t('Last DVE'), + sourceLayerId: SourceLayer.PgmDVEAdLib, + outputLayerId: 'pgm', + tags: [AdlibTags.ADLIB_RECALL_LAST_DVE] + } + } + } + + private makeRobotPresetAction(): IBlueprintActionManifest { + const callRobotPresetAction: ActionCallRobotPreset = { + type: AdlibActionType.CALL_ROBOT_PRESET + } + return { + externalId: generateExternalId(this.context.core, callRobotPresetAction), + actionId: AdlibActionType.CALL_ROBOT_PRESET, + userData: callRobotPresetAction, + userDataManifest: {}, + display: { + _rank: 400, + label: t(`Call Robot preset`), + sourceLayerId: SourceLayer.RobotCamera, + outputLayerId: SharedOutputLayers.SEC, + tags: [] + } + } + } + + private makeDveLayoutActions(): IBlueprintActionManifest[] { + const blueprintActions: IBlueprintActionManifest[] = [] + _.each(this.config.showStyle.DVEStyles, (dveConfig, i) => { + const userData: ActionSelectDVELayout = { + type: AdlibActionType.SELECT_DVE_LAYOUT, + config: dveConfig + } + blueprintActions.push({ + externalId: generateExternalId(this.context.core, userData), + actionId: AdlibActionType.SELECT_DVE_LAYOUT, + userData, + userDataManifest: {}, + display: { + _rank: 200 + i, + label: t(dveConfig.DVEName), + sourceLayerId: SourceLayer.PgmDVEAdLib, + outputLayerId: SharedOutputLayers.PGM, + tags: [AdlibTags.ADLIB_SELECT_DVE_LAYOUT, dveConfig.DVEName] + } + }) + }) + return blueprintActions + } + + private makePersistedAudioLevelsAction(): IBlueprintActionManifest { + const fadeDownPersistedAudioLevelsUserData: ActionFadeDownPersistedAudioLevels = { + type: AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS + } + return { + externalId: generateExternalId(this.context.core, fadeDownPersistedAudioLevelsUserData), + actionId: AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS, + userData: fadeDownPersistedAudioLevelsUserData, + userDataManifest: {}, + display: { + _rank: 300, + label: t('Fade down persisted audio levels'), + sourceLayerId: SourceLayer.PgmSisyfosAdlibs, + outputLayerId: SharedOutputLayers.SEC, + tags: [AdlibTags.ADLIB_FADE_DOWN_PERSISTED_AUDIO_LEVELS] + } + } + } +} diff --git a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts index 406ebd65..da1ee127 100644 --- a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts @@ -375,7 +375,7 @@ async function getCameraPiece( ): Promise { const piece = await context .getPieceInstances(part) - .then(pieceInstance => pieceInstance.find(p => p.piece.sourceLayerId === SourceLayer.PgmCam)) + .then((pieceInstance) => pieceInstance.find((p) => p.piece.sourceLayerId === SourceLayer.PgmCam)) expect(piece).toBeTruthy() return piece! @@ -387,7 +387,7 @@ async function getEVSPiece( ): Promise { const piece = await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === SourceLayer.PgmLocal)) + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === SourceLayer.PgmLocal)) expect(piece).toBeTruthy() return piece! @@ -399,7 +399,7 @@ async function getTransitionPiece( ): Promise { const piece = await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === SourceLayer.PgmJingle)) + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === SourceLayer.PgmJingle)) expect(piece).toBeTruthy() return piece! @@ -407,7 +407,7 @@ async function getTransitionPiece( function getATEMMEObj(piece: IBlueprintPieceInstance): TSR.TimelineObjAtemME { const atemObj = (piece.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => + (obj) => obj.layer === prefixLayer(SwitcherMixEffectLLayer.Program) && obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.ME @@ -435,9 +435,11 @@ function expectTakeAfterExecute(context: ActionExecutionContext) { } function expectNoWarningsOrErrors(context: ActionExecutionContext) { - expect(context.getNotes().filter(n => n.type === NoteType.ERROR || n.type === NoteType.NOTIFY_USER_ERROR)).toEqual([]) + expect(context.getNotes().filter((n) => n.type === NoteType.ERROR || n.type === NoteType.NOTIFY_USER_ERROR)).toEqual( + [] + ) expect( - context.getNotes().filter(n => n.type === NoteType.WARNING || n.type === NoteType.NOTIFY_USER_WARNING) + context.getNotes().filter((n) => n.type === NoteType.WARNING || n.type === NoteType.NOTIFY_USER_WARNING) ).toEqual([]) } diff --git a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts index 78db23c2..acda6396 100644 --- a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts @@ -8,6 +8,7 @@ global.VERSION_TSR = 'test' global.VERSION_INTEGRATION = 'test' import { ExtendedIngestRundown, IGetRundownContext, TSR } from 'blueprints-integration' +import { SwitcherType } from 'tv2-common' import { GetRundownContext } from '../../__mocks__/context' import { SharedGraphicLLayer } from '../../tv2-constants' import { preprocessConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' @@ -21,13 +22,13 @@ const configSpec = { id: 'default', studioConfig: defaultStudioConfig, showStyle const RUNDOWN_ID = 'test_rundown' const SEGMENT_ID = 'test_segment' const PART_ID = 'test_part' -describe('Baseline', () => { +describe.each([SwitcherType.ATEM, SwitcherType.TRICASTER])('Baseline', (switcherType: SwitcherType) => { test('Config: ' + configSpec.id, async () => { expect(configSpec.studioConfig).toBeTruthy() expect(configSpec.showStyleConfig).toBeTruthy() const mockRundown: ExtendedIngestRundown = createMockRundown() - const mockContext: GetRundownContext = createMockContext(mockRundown.name) + const mockContext: GetRundownContext = createMockContext(mockRundown.name, switcherType) const result = await Blueprints.getRundown(mockContext, mockRundown) if (result === null) { @@ -37,7 +38,7 @@ describe('Baseline', () => { expect(result.baseline.timelineObjects).not.toHaveLength(0) expect(result.globalAdLibPieces).not.toHaveLength(0) - checkAllLayers(mockContext, result.globalAdLibPieces, result.baseline.timelineObjects) + checkAllLayers(result.globalAdLibPieces, result.baseline.timelineObjects) // ensure there were no warnings expect(mockContext.getNotes()).toEqual([]) @@ -45,7 +46,7 @@ describe('Baseline', () => { test('SetConcept timeline object is created in base rundown', async () => { const mockRundown: ExtendedIngestRundown = createMockRundown() - const mockContext: IGetRundownContext = createMockContext(mockRundown.name) + const mockContext: IGetRundownContext = createMockContext(mockRundown.name, switcherType) const rundown = await Blueprints.getRundown(mockContext, mockRundown) if (rundown === null) { @@ -53,7 +54,7 @@ describe('Baseline', () => { } const result = rundown.baseline.timelineObjects.filter( - timelineObject => + (timelineObject) => timelineObject.layer === SharedGraphicLLayer.GraphicLLayerConcept && timelineObject.content.deviceType === TSR.DeviceType.VIZMSE ) @@ -73,7 +74,7 @@ function createMockRundown(): ExtendedIngestRundown { } } -function createMockContext(rundownName: string): GetRundownContext { +function createMockContext(rundownName: string, switcherType: SwitcherType): GetRundownContext { const mockContext = new GetRundownContext( rundownName, mappingsDefaults, @@ -83,7 +84,7 @@ function createMockContext(rundownName: string): GetRundownContext { SEGMENT_ID, PART_ID ) - mockContext.studioConfig = configSpec.studioConfig as any + mockContext.studioConfig = { ...configSpec.studioConfig, SwitcherType: switcherType } as any mockContext.showStyleConfig = configSpec.showStyleConfig as any return mockContext diff --git a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts index 4195a593..8dfdc905 100644 --- a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts @@ -38,11 +38,11 @@ function makeIngestSegment(cues: UnparsedCue[], body: string) { } function expectNotesToBe(context: SegmentUserContext, notes: string[]) { - expect(context.getNotes().map(msg => msg.message)).toEqual(notes) + expect(context.getNotes().map((msg) => msg.message)).toEqual(notes) } function expectAllPartsToBeValid(result: BlueprintResultSegment) { - const invalid = result.parts.filter(part => part.part.invalid === true) + const invalid = result.parts.filter((part) => part.part.invalid === true) expect(invalid).toHaveLength(0) } @@ -59,7 +59,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(1) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmJingle]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmJingle]) expect(kamPart.pieces[0].name).toEqual('CS 3 (JINGLE)') }) @@ -75,7 +75,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(1) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmJingle]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmJingle]) expect(kamPart.pieces[0].name).toEqual('CS 3 (JINGLE)') }) @@ -102,7 +102,10 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) }) @@ -121,7 +124,10 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -154,14 +160,17 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) const fullPart = result.parts[1] expect(fullPart).toBeTruthy() expect(fullPart.pieces).toHaveLength(2) - expect(fullPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmPilot, SharedSourceLayers.SelectedAdlibGraphicsFull ]) @@ -198,7 +207,10 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -239,7 +251,10 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -253,7 +268,7 @@ describe('AFVD Blueprint', () => { expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( SharedSourceLayers.PgmPilot ) - expect(fullPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmPilot, SharedSourceLayers.SelectedAdlibGraphicsFull ]) @@ -291,7 +306,10 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -305,7 +323,7 @@ describe('AFVD Blueprint', () => { expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( SharedSourceLayers.PgmPilot ) - expect(fullPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmPilot, SharedSourceLayers.SelectedAdlibGraphicsFull, SharedSourceLayers.PgmPilotOverlay @@ -337,14 +355,17 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) const fullPart = result.parts[1] expect(fullPart).toBeTruthy() expect(fullPart.pieces).toHaveLength(2) - expect(fullPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmPilot, SharedSourceLayers.SelectedAdlibGraphicsFull ]) @@ -382,7 +403,10 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -418,7 +442,10 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -453,7 +480,10 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) expect(kamPart1.adLibPieces).toHaveLength(0) expect(kamPart1.actions).toHaveLength(0) @@ -467,7 +497,7 @@ describe('AFVD Blueprint', () => { const kamPart2 = result.parts[2] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(1) - expect(kamPart2.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam]) + expect(kamPart2.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam]) expect(kamPart2.adLibPieces).toHaveLength(0) expect(kamPart2.actions).toHaveLength(0) }) @@ -496,7 +526,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(3) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmCam, SharedSourceLayers.PgmPilotOverlay, SharedSourceLayers.PgmScript @@ -529,7 +559,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(3) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmCam, SharedSourceLayers.WallGraphics, SharedSourceLayers.PgmScript @@ -562,7 +592,10 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -576,7 +609,7 @@ describe('AFVD Blueprint', () => { expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( SharedSourceLayers.PgmPilot ) - expect(fullPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmPilot, SharedSourceLayers.SelectedAdlibGraphicsFull ]) @@ -607,7 +640,7 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(3) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmCam, SharedSourceLayers.WallGraphics, SharedSourceLayers.PgmScript @@ -616,7 +649,7 @@ describe('AFVD Blueprint', () => { const kamPart2 = result.parts[1] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(2) - expect(kamPart2.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart2.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmCam, SharedSourceLayers.WallGraphics ]) @@ -640,12 +673,18 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) const kamPart2 = result.parts[1] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(2) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) }) it('Shows warning for missing wall graphic with MOSART=L', async () => { @@ -673,7 +712,7 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(3) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmCam, SharedSourceLayers.PgmPilotOverlay, SharedSourceLayers.PgmScript @@ -682,7 +721,7 @@ describe('AFVD Blueprint', () => { const kamPart2 = result.parts[1] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(2) - expect(kamPart2.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart2.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmCam, SharedSourceLayers.WallGraphics ]) @@ -713,12 +752,15 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmCam, + SharedSourceLayers.PgmScript + ]) const kamPart2 = result.parts[1] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(2) - expect(kamPart2.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart2.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmCam, SharedSourceLayers.WallGraphics ]) @@ -743,7 +785,7 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(5) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmCam, SharedSourceLayers.PgmDesign, SourceLayer.PgmDVEBackground, @@ -764,7 +806,7 @@ describe('AFVD Blueprint', () => { const livePart1 = result.parts[0] expect(livePart1).toBeTruthy() expect(livePart1.pieces).toHaveLength(1) - expect(livePart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) + expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) }) it('Creates Live 1', async () => { @@ -779,7 +821,7 @@ describe('AFVD Blueprint', () => { const livePart1 = result.parts[0] expect(livePart1).toBeTruthy() expect(livePart1.pieces).toHaveLength(1) - expect(livePart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) + expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) }) it('Creates Feed1', async () => { @@ -794,7 +836,7 @@ describe('AFVD Blueprint', () => { const feedPart1 = result.parts[0] expect(feedPart1).toBeTruthy() expect(feedPart1.pieces).toHaveLength(1) - expect(feedPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) + expect(feedPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) }) it('Creates Feed 1', async () => { @@ -809,7 +851,7 @@ describe('AFVD Blueprint', () => { const feedPart1 = result.parts[0] expect(feedPart1).toBeTruthy() expect(feedPart1.pieces).toHaveLength(1) - expect(feedPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) + expect(feedPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) }) it('Creates invalid part for EKSTERN=LIVE', async () => { @@ -838,7 +880,10 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmJingle, SharedSourceLayers.PgmCam]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmJingle, + SharedSourceLayers.PgmCam + ]) expect(kamPart1.pieces[0].name).toBe('EFFEKT 1') }) @@ -854,7 +899,10 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmJingle, SharedSourceLayers.PgmCam]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayers.PgmJingle, + SharedSourceLayers.PgmCam + ]) expect(kamPart1.pieces[0].name).toBe('MIX 5') }) @@ -873,7 +921,7 @@ describe('AFVD Blueprint', () => { const livePart1 = result.parts[0] expect(livePart1).toBeTruthy() expect(livePart1.pieces).toHaveLength(2) - expect(livePart1.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmJingle, SharedSourceLayers.PgmLive ]) @@ -895,7 +943,7 @@ describe('AFVD Blueprint', () => { const livePart1 = result.parts[0] expect(livePart1).toBeTruthy() expect(livePart1.pieces).toHaveLength(2) - expect(livePart1.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayers.PgmJingle, SharedSourceLayers.PgmLive ]) @@ -921,7 +969,7 @@ describe('AFVD Blueprint', () => { const livePart = result.parts[0] const livePiece = livePart.pieces[0] const studioMicsObject = livePiece.content.timelineObjects.find( - t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + (t) => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics ) expect(studioMicsObject).toBeDefined() }) @@ -945,7 +993,7 @@ describe('AFVD Blueprint', () => { const livePart = result.parts[0] const livePiece = livePart.pieces[0] const studioMicsObject = livePiece.content.timelineObjects.find( - t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + (t) => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics ) expect(studioMicsObject).toBeUndefined() }) @@ -969,7 +1017,7 @@ describe('AFVD Blueprint', () => { const livePart = result.parts[0] const livePiece = livePart.pieces[0] const studioMicsObject = livePiece.content.timelineObjects.find( - t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + (t) => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics ) expect(studioMicsObject).toBeDefined() }) @@ -993,7 +1041,7 @@ describe('AFVD Blueprint', () => { const livePart = result.parts[0] const livePiece = livePart.pieces[0] const studioMicsObject = livePiece.content.timelineObjects.find( - t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + (t) => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics ) expect(studioMicsObject).toBeUndefined() }) @@ -1017,7 +1065,7 @@ describe('AFVD Blueprint', () => { const livePart = result.parts[0] const livePiece = livePart.pieces[0] const studioMicsObject = livePiece.content.timelineObjects.find( - t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + (t) => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics ) expect(studioMicsObject).toBeUndefined() }) diff --git a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts index 6a5454be..39777bb8 100644 --- a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts @@ -22,7 +22,7 @@ const blankShowStyleConfig: GalleryShowStyleConfig = { describe('Config Manifest', () => { test('Exposed ShowStyle Keys', () => { - const showStyleManifestKeys = _.map(showStyleConfigManifest, e => e.id) + const showStyleManifestKeys = _.map(showStyleConfigManifest, (e) => e.id) const manifestKeys = showStyleManifestKeys.sort() const definedKeys = Object.keys(blankShowStyleConfig) diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index 35f0d56d..a790811e 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -31,7 +31,7 @@ function prepareConfig( StudioMics: boolean wantsToPersistAudio: boolean }> { - return parseMapStr(undefined, conf, true).map(c => { + return parseMapStr(undefined, conf, true).map((c) => { return { SourceName: c.id, SwitcherSource: c.val, @@ -123,9 +123,6 @@ export const defaultStudioConfig: StudioConfig = { Playing: true } }, - TriCasterSettings: { - DveMixEffect: 1 - }, AudioBedSettings: { fadeIn: 1000, fadeOut: 1000, diff --git a/src/tv2_afvd_showstyle/__tests__/layers-check.ts b/src/tv2_afvd_showstyle/__tests__/layers-check.ts index 55aed802..b597b4b5 100644 --- a/src/tv2_afvd_showstyle/__tests__/layers-check.ts +++ b/src/tv2_afvd_showstyle/__tests__/layers-check.ts @@ -1,42 +1,27 @@ import * as _ from 'underscore' -import { - BlueprintMappings, - IBlueprintPieceGeneric, - IShowStyleUserContext, - TimelineObjectCoreExt, - TSR -} from 'blueprints-integration' +import { BlueprintMappings, IBlueprintPieceGeneric, TimelineObjectCoreExt, TSR } from 'blueprints-integration' import { GetDSKSourceLayerNames } from 'tv2-common' -import { makeMockGalleryContext } from '../../__mocks__/context' -import mappingsDefaults, { getMediaPlayerMappings } from '../../tv2_afvd_studio/migrations/mappings-defaults' +import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' import { ATEMModel } from '../../types/atem' import { SourceLayer } from '../layers' import OutputlayerDefaults from '../migrations/outputlayer-defaults' -export function checkAllLayers( - _context: IShowStyleUserContext, - pieces: IBlueprintPieceGeneric[], - otherObjs?: TSR.TSRTimelineObjBase[] -) { +export function checkAllLayers(pieces: IBlueprintPieceGeneric[], otherObjs?: TSR.TSRTimelineObjBase[]) { const missingSourceLayers: string[] = [] const missingOutputLayers: string[] = [] const missingLayers: Array = [] const wrongDeviceLayers: Array = [] - // @todo: is this right? - const config = makeMockGalleryContext().config - const allSourceLayers: string[] = _.values(SourceLayer) - .map(l => l.toString()) + .map((l) => l.toString()) .concat(GetDSKSourceLayerNames(ATEMModel.CONSTELLATION_8K_UHD_MODE)) .sort() - const allOutputLayers = _.map(OutputlayerDefaults, m => m._id) + const allOutputLayers = _.map(OutputlayerDefaults, (m) => m._id) const allMappings: BlueprintMappings = { - ...mappingsDefaults, - ...getMediaPlayerMappings(config.mediaPlayers) + ...mappingsDefaults } const validateObject = (obj: TimelineObjectCoreExt) => { diff --git a/src/tv2_afvd_showstyle/__tests__/migrations-defaults.spec.ts b/src/tv2_afvd_showstyle/__tests__/migrations-defaults.spec.ts index e77810f3..1c5ca31b 100644 --- a/src/tv2_afvd_showstyle/__tests__/migrations-defaults.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/migrations-defaults.spec.ts @@ -7,9 +7,9 @@ import SourcelayerDefaults from '../migrations/sourcelayer-defaults' describe('Migration Defaults', () => { test('SourcelayerDefaults', () => { - const defaultsIds = _.map(SourcelayerDefaults, v => v._id).sort() + const defaultsIds = _.map(SourcelayerDefaults, (v) => v._id).sort() const layerIds = _.values(SourceLayer) - .map(l => l.toString()) + .map((l) => l.toString()) .concat(GetDSKSourceLayerNames(ATEMModel.CONSTELLATION_8K_UHD_MODE)) .sort() diff --git a/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts b/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts index 0f5b291b..10ebd623 100644 --- a/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts @@ -232,10 +232,10 @@ describe('regressions-migrations', () => { * @param reference Reference segment. */ function migrate(reference: BlueprintResultSegment) { - reference.parts = reference.parts.map(part => { - part.adLibPieces = part.adLibPieces.map(adlib => { + reference.parts = reference.parts.map((part) => { + part.adLibPieces = part.adLibPieces.map((adlib) => { if (adlib.content && adlib.content.timelineObjects) { - adlib.content.timelineObjects = (adlib.content.timelineObjects as TimelineObjectCoreExt[]).map(obj => { + adlib.content.timelineObjects = (adlib.content.timelineObjects as TimelineObjectCoreExt[]).map((obj) => { const remappedLayer = remapVizLLayer.get(obj.layer.toString()) if (remappedLayer) { @@ -249,9 +249,9 @@ function migrate(reference: BlueprintResultSegment) { return adlib }) - part.pieces = part.pieces.map(adlib => { + part.pieces = part.pieces.map((adlib) => { if (adlib.content && adlib.content.timelineObjects) { - adlib.content.timelineObjects = (adlib.content.timelineObjects as TimelineObjectCoreExt[]).map(obj => { + adlib.content.timelineObjects = (adlib.content.timelineObjects as TimelineObjectCoreExt[]).map((obj) => { const remappedLayer = remapVizLLayer.get(obj.layer.toString()) if (remappedLayer) { diff --git a/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts b/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts index da9a3c14..cd4ac6af 100644 --- a/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts @@ -50,12 +50,12 @@ describe('Generate rundowns without error', () => { expect(res.segment.name).toEqual(segment.name) const allPieces: IBlueprintPieceGeneric[] = [] - _.each(res.parts, part => { + _.each(res.parts, (part) => { allPieces.push(...part.pieces) allPieces.push(...part.adLibPieces) }) - checkAllLayers(mockContext, allPieces) + checkAllLayers(allPieces) // ensure there were no warnings // TODO: Re-enable when the time is right diff --git a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts index f7782d1a..50c42dd2 100644 --- a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts @@ -102,7 +102,7 @@ function getTransitionProperties(effekt: GalleryShowStyleConfig['BreakerConfig'] } function getPieceOnLayerFromPart(segment: BlueprintResultSegment, layer: SourceLayer): IBlueprintPiece { - const piece = segment.parts[0].pieces.find(p => p.sourceLayerId === layer) + const piece = segment.parts[0].pieces.find((p) => p.sourceLayerId === layer) expect(piece).toBeTruthy() return piece! @@ -110,7 +110,7 @@ function getPieceOnLayerFromPart(segment: BlueprintResultSegment, layer: SourceL function getATEMMEObj(piece: IBlueprintPiece): TSR.TimelineObjAtemME { const atemMEObj = (piece!.content!.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => + (obj) => obj.layer === prefixLayer(SwitcherMixEffectLLayer.Program) && obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.ME diff --git a/src/tv2_afvd_showstyle/config-manifests.ts b/src/tv2_afvd_showstyle/config-manifests.ts index 52f054a5..95ebbe48 100644 --- a/src/tv2_afvd_showstyle/config-manifests.ts +++ b/src/tv2_afvd_showstyle/config-manifests.ts @@ -190,7 +190,7 @@ export const gfxDesignTemplates: ConfigManifestEntry[] = [ description: '', type: ConfigManifestEntryType.TABLE, required: true, - defaultVal: DEFAULT_GRAPHICS.map(val => ({ _id: '', ...val })).filter(template => template.IsDesign), + defaultVal: DEFAULT_GRAPHICS.map((val) => ({ _id: '', ...val })).filter((template) => template.IsDesign), columns: [ { id: DESIGN_NAME_COLUMN_ID, @@ -338,7 +338,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ 'This table can contain info in two ways. Things marked (**) are always required. If you want to do the mapping from iNews-code, then all (*)-elements are also required. GFX Template Name is what the graphic is called in viz. Source layer is the ID of the Sofie Source layer in the UI (i.e. "studio0_graphicsTema"). Layer mapping is the Sofie studio layer mapping (i.e "viz_layer_tema"). iNews command can be something like "KG=", then iNews Name is the thing that follows in iNews i.e. "ident_nyhederne"', type: ConfigManifestEntryType.TABLE, required: true, - defaultVal: DEFAULT_GRAPHICS.map(val => ({ _id: '', ...val })).filter(template => !template.IsDesign), + defaultVal: DEFAULT_GRAPHICS.map((val) => ({ _id: '', ...val })).filter((template) => !template.IsDesign), columns: [ { id: 'INewsCode', diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index bd4db926..23149802 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -2,9 +2,7 @@ import { BlueprintResultBaseline, BlueprintResultRundown, GraphicsContent, - IBlueprintActionManifest, IBlueprintAdLibPiece, - ICommonContext, IngestRundown, IShowStyleUserContext, PieceLifespan, @@ -14,61 +12,42 @@ import { WithTimeline } from 'blueprints-integration' import { - ActionCallRobotPreset, - ActionClearGraphics, - ActionCutSourceToBox, - ActionCutToCamera, - ActionFadeDownPersistedAudioLevels, - ActionRecallLastDVE, - ActionRecallLastLive, - ActionSelectDVELayout, CasparPlayerClipLoadingLoop, createDskBaseline, CreateDSKBaselineAdlibs, - CreateGraphicBaseline, CreateLYDBaseline, ExtendedShowStyleContext, ExtendedShowStyleContextImpl, FindDSKJingle, - generateExternalId, + getGraphicBaseline, getMixMinusTimelineObject, GetSisyfosTimelineObjForRemote, GetSisyfosTimelineObjForReplay, - GetTransitionAdLibActions, literal, MixMinusPriority, PieceMetaData, replaySourceName, - SourceDefinitionKam, SourceInfo, - SourceInfoToSourceDefinition, - SourceInfoType, SpecialInput, - t, - TransitionStyle, - VideoSwitcher + SwitcherType, + TransitionStyle } from 'tv2-common' import { - AdlibActionType, - AdlibTagCutToBox, AdlibTags, CONSTANTS, ControlClasses, SharedGraphicLLayer, SharedOutputLayers, - SourceType, SwitcherAuxLLayer, - SwitcherDveLLayer, - SwitcherMixEffectLLayer, - TallyTags + SwitcherDveLLayer } from 'tv2-constants' import * as _ from 'underscore' import { CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' import { SisyfosChannel, sisyfosChannels } from '../tv2_afvd_studio/sisyfosChannels' import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { AtemSourceIndex } from '../types/atem' +import { GlobalAdlibActionsGenerator } from './GlobalAdlibActionsGenerator' import { GalleryBlueprintConfig } from './helpers/config' -import { NUMBER_OF_DVE_BOXES } from './helpers/content/dve' import { SourceLayer } from './layers' export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: IngestRundown): BlueprintResultRundown { @@ -82,8 +61,8 @@ export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: In } }, globalAdLibPieces: new GlobalAdLibPiecesGenerator(context).generate(), - globalActions: getGlobalAdlibActionsAFVD(context.core, context.config), // @todo - baseline: getBaseline(context, context.videoSwitcher) // @todo + globalActions: new GlobalAdlibActionsGenerator(context).generate(), + baseline: getBaseline(context) } } @@ -99,17 +78,17 @@ class GlobalAdLibPiecesGenerator { this.config.sources.lives .slice(0, 10) // the first x lives to create live-adlibs from - .forEach(info => { + .forEach((info) => { adLibPieces.push(...this.makeRemoteAdLibs(info, globalRank++)) }) this.config.sources.lives .slice(0, 10) // the first x lives to create AUX1 (studio) adlibs - .forEach(info => { + .forEach((info) => { adLibPieces.push(...this.makeRemoteAuxStudioAdLibs(info, globalRank++)) }) - this.config.sources.replays.forEach(info => { + this.config.sources.replays.forEach((info) => { if (!/EPSIO/i.test(info.id)) { adLibPieces.push(this.makeEvsAdLib(info, globalRank++, false)) } @@ -422,7 +401,7 @@ class GlobalAdLibPiecesGenerator { content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: this.config.studio.StudioMics.map(layer => ({ + channels: this.config.studio.StudioMics.map((layer) => ({ mappedLayer: layer, isPgm: 1 })), @@ -451,7 +430,7 @@ class GlobalAdLibPiecesGenerator { content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: this.config.studio.StudioMics.map(layer => ({ + channels: this.config.studio.StudioMics.map((layer) => ({ mappedLayer: layer, isPgm: 0 })), @@ -521,350 +500,46 @@ class GlobalAdLibPiecesGenerator { } } -function getGlobalAdlibActionsAFVD( - context: IShowStyleUserContext, - config: GalleryBlueprintConfig -): IBlueprintActionManifest[] { - const blueprintActions: IBlueprintActionManifest[] = [] - - let globalRank = 1000 - - function makeAdlibBoxesActions(info: SourceInfo, rank: number) { - for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { - const name = `${info.type} ${info.id}` - const layer = info.type === SourceInfoType.KAM ? SourceLayer.PgmCam : SourceLayer.PgmLive - - const userData: ActionCutSourceToBox = { - type: AdlibActionType.CUT_SOURCE_TO_BOX, - name, - box, - sourceDefinition: SourceInfoToSourceDefinition(info) - } - blueprintActions.push({ - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.CUT_SOURCE_TO_BOX, - userData, - userDataManifest: {}, - display: { - _rank: rank + 0.1 * box, - label: t(`${name} inp ${box + 1}`), - sourceLayerId: layer, - outputLayerId: SharedOutputLayers.SEC, - content: {}, - tags: [AdlibTagCutToBox(box)] - } - }) - } - } - - function makeAdlibBoxesActionsReplay(info: SourceInfo, rank: number, vo: boolean) { - for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { - const name = replaySourceName(info.id, vo) - const userData: ActionCutSourceToBox = { - type: AdlibActionType.CUT_SOURCE_TO_BOX, - name, - box, - sourceDefinition: { - sourceType: SourceType.REPLAY, - id: info.id, - vo, - raw: '', - name - } - } - blueprintActions.push({ - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.CUT_SOURCE_TO_BOX, - userData, - userDataManifest: {}, - display: { - _rank: rank + 0.1 * box, - label: t(`${name} inp ${box + 1}`), - sourceLayerId: SourceLayer.PgmLocal, - outputLayerId: SharedOutputLayers.SEC, - content: {}, - tags: [AdlibTagCutToBox(box), vo ? AdlibTags.ADLIB_VO_AUDIO_LEVEL : AdlibTags.ADLIB_FULL_AUDIO_LEVEL] - } - }) - } - } - - function makeServerAdlibBoxesActions(rank: number) { - for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { - const userData: ActionCutSourceToBox = { - type: AdlibActionType.CUT_SOURCE_TO_BOX, - name: `SERVER`, - box, - sourceDefinition: { sourceType: SourceType.SERVER } - } - blueprintActions.push({ - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.CUT_SOURCE_TO_BOX, - userData, - userDataManifest: {}, - display: { - _rank: rank + 0.1 * box, - label: t(`Server inp ${box + 1}`), - sourceLayerId: SourceLayer.PgmServer, - outputLayerId: SharedOutputLayers.SEC, - content: {}, - tags: [AdlibTagCutToBox(box)] - } - }) - } - } - - function makeCutCameraActions(info: SourceInfo, queue: boolean, rank: number) { - const sourceDefinition = SourceInfoToSourceDefinition(info) as SourceDefinitionKam - const userData: ActionCutToCamera = { - type: AdlibActionType.CUT_TO_CAMERA, - queue, - sourceDefinition - } - blueprintActions.push({ - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.CUT_TO_CAMERA, - userData, - userDataManifest: {}, - display: { - _rank: rank, - label: t(sourceDefinition.name), - sourceLayerId: SourceLayer.PgmCam, - outputLayerId: SharedOutputLayers.PGM, - content: {}, - tags: queue ? [AdlibTags.ADLIB_QUEUE_NEXT] : [AdlibTags.ADLIB_CUT_DIRECT] - } - }) - } - - config.sources.cameras - .slice(0, 5) // the first x cameras to create INP1/2/3 cam-adlibs from - .forEach(o => { - makeCutCameraActions(o, false, globalRank++) - }) - - config.sources.cameras - .slice(0, 5) // the first x cameras to create preview cam-adlibs from - .forEach(o => { - makeCutCameraActions(o, true, globalRank++) - }) - - config.sources.cameras - .slice(0, 5) // the first x cameras to dve actions from - .forEach(o => { - makeAdlibBoxesActions(o, globalRank++) - }) - - function makeRecallLastLiveAction() { - const userData: ActionRecallLastLive = { - type: AdlibActionType.RECALL_LAST_LIVE - } - blueprintActions.push({ - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.RECALL_LAST_LIVE, - userData, - userDataManifest: {}, - display: { - _rank: 1, - label: t('Last Live'), - sourceLayerId: SourceLayer.PgmLive, - outputLayerId: SharedOutputLayers.PGM, - tags: [AdlibTags.ADLIB_RECALL_LAST_LIVE] - } - }) - } - - makeRecallLastLiveAction() - - config.sources.lives - .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from - .forEach(o => { - makeAdlibBoxesActions(o, globalRank++) - }) - - config.sources.feeds - .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from - .forEach(o => { - makeAdlibBoxesActions(o, globalRank++) - }) - - config.sources.replays.forEach(o => { - if (!/EPSIO/i.test(o.id)) { - makeAdlibBoxesActionsReplay(o, globalRank++, false) - } - makeAdlibBoxesActionsReplay(o, globalRank++, true) - }) - - makeServerAdlibBoxesActions(globalRank++) - - function makeClearGraphicsAction(): IBlueprintActionManifest { - const userData: ActionClearGraphics = { - type: AdlibActionType.CLEAR_GRAPHICS, - sendCommands: true, - label: 'GFX Clear' - } - return { - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.CLEAR_GRAPHICS, - userData, - userDataManifest: {}, - display: { - _rank: 300, - label: t(`GFX Clear`), - sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, - outputLayerId: SharedOutputLayers.SEC, - content: {}, - tags: [AdlibTags.ADLIB_STATIC_BUTTON], - currentPieceTags: [TallyTags.GFX_CLEAR], - nextPieceTags: [TallyTags.GFX_CLEAR] - } - } - } - - function makeClearGraphicsAltudAction(): IBlueprintActionManifest { - const userData: ActionClearGraphics = { - type: AdlibActionType.CLEAR_GRAPHICS, - sendCommands: false, - label: 'GFX Altud' - } - return { - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.CLEAR_GRAPHICS, - userData, - userDataManifest: {}, - display: { - _rank: 400, - label: t(`GFX Altud`), - sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, - outputLayerId: SharedOutputLayers.SEC, - content: {}, - tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_ALTUD], - currentPieceTags: [TallyTags.GFX_ALTUD], - nextPieceTags: [TallyTags.GFX_ALTUD] - } - } - } - - blueprintActions.push(makeClearGraphicsAction(), makeClearGraphicsAltudAction()) - - blueprintActions.push(...GetTransitionAdLibActions(config, 800)) - - const recallLastLiveDveUserData: ActionRecallLastDVE = { - type: AdlibActionType.RECALL_LAST_DVE - } - blueprintActions.push({ - externalId: generateExternalId(context, recallLastLiveDveUserData), - actionId: AdlibActionType.RECALL_LAST_DVE, - userData: recallLastLiveDveUserData, - userDataManifest: {}, - display: { - _rank: 1, - label: t('Last DVE'), - sourceLayerId: SourceLayer.PgmDVEAdLib, - outputLayerId: 'pgm', - tags: [AdlibTags.ADLIB_RECALL_LAST_DVE] - } - }) - - _.each(config.showStyle.DVEStyles, (dveConfig, i) => { - const userData: ActionSelectDVELayout = { - type: AdlibActionType.SELECT_DVE_LAYOUT, - config: dveConfig - } - blueprintActions.push({ - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.SELECT_DVE_LAYOUT, - userData, - userDataManifest: {}, - display: { - _rank: 200 + i, - label: t(dveConfig.DVEName), - sourceLayerId: SourceLayer.PgmDVEAdLib, - outputLayerId: SharedOutputLayers.PGM, - tags: [AdlibTags.ADLIB_SELECT_DVE_LAYOUT, dveConfig.DVEName] - } - }) - }) - - const fadeDownPersistedAudioLevelsUserData: ActionFadeDownPersistedAudioLevels = { - type: AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS - } - blueprintActions.push({ - externalId: generateExternalId(context, fadeDownPersistedAudioLevelsUserData), - actionId: AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS, - userData: fadeDownPersistedAudioLevelsUserData, - userDataManifest: {}, - display: { - _rank: 300, - label: t('Fade down persisted audio levels'), - sourceLayerId: SourceLayer.PgmSisyfosAdlibs, - outputLayerId: SharedOutputLayers.SEC, - tags: [AdlibTags.ADLIB_FADE_DOWN_PERSISTED_AUDIO_LEVELS] - } - }) - - blueprintActions.push(createRobotPresetAction(context)) - - return blueprintActions -} - -function createRobotPresetAction(context: ICommonContext): IBlueprintActionManifest { - const callRobotPresetAction: ActionCallRobotPreset = { - type: AdlibActionType.CALL_ROBOT_PRESET - } - return { - externalId: generateExternalId(context, callRobotPresetAction), - actionId: AdlibActionType.CALL_ROBOT_PRESET, - userData: callRobotPresetAction, - userDataManifest: {}, - display: { - _rank: 400, - label: t(`Call Robot preset`), - sourceLayerId: SourceLayer.RobotCamera, - outputLayerId: SharedOutputLayers.SEC, - tags: [] - } - } -} - -function getBaseline( - context: ExtendedShowStyleContext, - videoSwitcher: VideoSwitcher -): BlueprintResultBaseline { +function getBaseline(context: ExtendedShowStyleContext): BlueprintResultBaseline { const jingleDSK = FindDSKJingle(context.config) return { - timelineObjects: [ - ...CreateGraphicBaseline(context.config), + timelineObjects: _.compact([ + ...getGraphicBaseline(context.config), // Default timeline - ...getMixEffectBaseline(context, videoSwitcher), + ...getMixEffectBaseline(context), - videoSwitcher.getAuxTimelineObject({ + context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, layer: SwitcherAuxLLayer.AuxLookahead, content: { input: context.config.studio.SwitcherSource.Default } }), - videoSwitcher.getAuxTimelineObject({ - enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxDve, - content: { - input: SpecialInput.DVE - } - }), - videoSwitcher.getAuxTimelineObject({ - enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxMixEffect3, - content: { - input: SpecialInput.ME3_PROGRAM - } - }), - videoSwitcher.getAuxTimelineObject({ + ...(context.config.studio.SwitcherType === SwitcherType.TRICASTER + ? [ + context.videoSwitcher.getAuxTimelineObject({ + enable: { while: '1' }, + layer: SwitcherAuxLLayer.AuxMixEffect3, + content: { + input: SpecialInput.ME3_PROGRAM + } + }) + ] + : [ + context.videoSwitcher.getAuxTimelineObject({ + enable: { while: '1' }, + layer: SwitcherAuxLLayer.AuxDve, + content: { + input: SpecialInput.DVE + } + }) + ]), + context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, layer: SwitcherAuxLLayer.AuxVideoMixMinus, content: { - input: context.uniformConfig.MixEffects.Program.input + input: context.uniformConfig.mixEffects.program.input } }), getMixMinusTimelineObject( @@ -887,21 +562,23 @@ function getBaseline( }), // keyers - ...createDskBaseline(context.config, videoSwitcher), + ...createDskBaseline(context.config, context.videoSwitcher), // ties the DSK for jingles to ME4 USK1 to have effects on CLEAN (ME4) - videoSwitcher.getMixEffectTimelineObject({ - enable: { while: '1' }, - layer: SwitcherMixEffectLLayer.CleanUSKEffect, - content: { - keyers: [ - { - onAir: false, - config: jingleDSK + context.uniformConfig.switcherLLayers.jingleUskMixEffect + ? context.videoSwitcher.getMixEffectTimelineObject({ + enable: { while: '1' }, + layer: context.uniformConfig.switcherLLayers.jingleUskMixEffect, + content: { + keyers: [ + { + onAir: false, + config: jingleDSK + } + ] } - ] - } - }), + }) + : undefined, literal({ id: '', enable: { while: '1' }, @@ -1063,7 +740,7 @@ function getBaseline( content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: Object.keys(sisyfosChannels).map(key => { + channels: Object.keys(sisyfosChannels).map((key) => { const llayer = key as SisyfosLLAyer const channel = sisyfosChannels[llayer] as SisyfosChannel return literal({ @@ -1079,7 +756,7 @@ function getBaseline( ...CreateLYDBaseline('afvd'), ...(context.config.showStyle.CasparCGLoadingClip && context.config.showStyle.CasparCGLoadingClip.length - ? [...context.config.mediaPlayers.map(mp => CasparPlayerClipLoadingLoop(mp.id))].map(layer => { + ? [...context.config.mediaPlayers.map((mp) => CasparPlayerClipLoadingLoop(mp.id))].map((layer) => { return literal({ id: '', enable: { while: '1' }, @@ -1105,26 +782,23 @@ function getBaseline( concept: context.config.selectedGfxSetup.VcpConcept } }) - ] + ]) } } -function getMixEffectBaseline( - context: ExtendedShowStyleContext, - videoSwitcher: VideoSwitcher -): TSR.TSRTimelineObj[] { - return Object.values(context.uniformConfig.MixEffects).flatMap(mixEffect => +function getMixEffectBaseline(context: ExtendedShowStyleContext): TSR.TSRTimelineObj[] { + return Object.values(context.uniformConfig.mixEffects).flatMap((mixEffect) => _.compact([ - videoSwitcher.getMixEffectTimelineObject({ + context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - layer: SwitcherMixEffectLLayer.Program, + layer: mixEffect.mixEffectLayer, content: { input: context.config.studio.SwitcherSource.Default, transition: TransitionStyle.CUT } }), mixEffect.auxLayer - ? videoSwitcher.getAuxTimelineObject({ + ? context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, layer: mixEffect.auxLayer, content: { diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index e6e8ed5b..ccc1c049 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -119,7 +119,7 @@ function insertSpecialPieces( if (gfxSetupsToInitialize) { const showsToInitialize = new Set() const allShows = new Set() - config.showStyle.GfxSetups.forEach(gfxSetup => { + config.showStyle.GfxSetups.forEach((gfxSetup) => { allShows.add(gfxSetup.FullShowName) allShows.add(gfxSetup.OvlShowName) if (gfxSetupsToInitialize.includes(gfxSetup.Name)) { @@ -127,7 +127,7 @@ function insertSpecialPieces( showsToInitialize.add(gfxSetup.OvlShowName) } }) - const showsToCleanup = Array.from(allShows).filter(show => !showsToInitialize.has(show)) + const showsToCleanup = Array.from(allShows).filter((show) => !showsToInitialize.has(show)) CreateShowLifecyclePieces(config, blueprintParts[0], Array.from(showsToInitialize), showsToCleanup) } } diff --git a/src/tv2_afvd_showstyle/helpers/config.ts b/src/tv2_afvd_showstyle/helpers/config.ts index f0aced4f..a39c7645 100644 --- a/src/tv2_afvd_showstyle/helpers/config.ts +++ b/src/tv2_afvd_showstyle/helpers/config.ts @@ -26,7 +26,7 @@ export interface GalleryShowStyleConfig extends TV2ShowstyleBlueprintConfigBase } export function preprocessConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { - const showstyleConfig = (rawConfig as unknown) as GalleryShowStyleConfig + const showstyleConfig = rawConfig as unknown as GalleryShowStyleConfig const selectedGfxSetup = findGfxSetup(context, showstyleConfig, { Name: '', VcpConcept: '', diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts index 0dc4bdf9..54901189 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -9,11 +9,11 @@ import { import { CueDefinitionGraphic, CueTime, + getDskLLayerName, GraphicInternal, GraphicPieceMetaData, GraphicPilot, literal, - LLayerDSK, PartDefinitionKam, PieceMetaData } from 'tv2-common' @@ -63,7 +63,7 @@ const dskEnableObj = literal({ start: 0 }, priority: 1, - layer: prefixLayer(LLayerDSK(0)), + layer: prefixLayer(getDskLLayerName(0)), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.DSK, @@ -456,7 +456,7 @@ describe('grafik piece', () => { lifespan: PieceLifespan.WithinPart }) expect( - result.pieces[0].content.timelineObjects.find(tlObject => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) + result.pieces[0].content.timelineObjects.find((tlObject) => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) ).toMatchObject({ enable: { while: `!.full` @@ -483,7 +483,7 @@ describe('grafik piece', () => { lifespan: PieceLifespan.OutOnSegmentEnd }) expect( - result.pieces[0].content.timelineObjects.find(tlObject => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) + result.pieces[0].content.timelineObjects.find((tlObject) => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) ).toMatchObject({ enable: { while: `!.full` @@ -511,7 +511,7 @@ describe('grafik piece', () => { lifespan: PieceLifespan.OutOnShowStyleEnd }) expect( - result.pieces[0].content.timelineObjects.find(tlObject => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) + result.pieces[0].content.timelineObjects.find((tlObject) => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) ).toMatchObject({ enable: { while: `!.full` @@ -827,7 +827,7 @@ describe('grafik piece', () => { cue.adlib ? { rank: 0 } : undefined ) - const adlibPiece = result.adlibPieces.find(piece => piece.tags?.includes('flow_producer')) + const adlibPiece = result.adlibPieces.find((piece) => piece.tags?.includes('flow_producer')) expect(adlibPiece).toBeDefined() expect(adlibPiece).toMatchObject({ expectedDuration: 10000, @@ -860,7 +860,7 @@ describe('grafik piece', () => { const piece = result.pieces[0] expect(piece).toBeTruthy() const tlObj = (piece.content?.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => + (obj) => obj.content.deviceType === TSR.DeviceType.VIZMSE && obj.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT ) as TSR.TimelineObjVIZMSEElementInternal | undefined diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts index e9530df6..0e4030a0 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -2,10 +2,10 @@ import { GraphicsContent, IBlueprintPiece, PieceLifespan, TSR, WithTimeline } fr import { CueDefinitionGraphic, CueDefinitionTelefon, + getDskLLayerName, GraphicInternal, GraphicPieceMetaData, literal, - LLayerDSK, PartDefinitionKam } from 'tv2-common' import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayers, SourceType } from 'tv2-constants' @@ -104,7 +104,7 @@ describe('telefon', () => { start: 0 }, priority: 1, - layer: prefixLayer(LLayerDSK(0)), + layer: prefixLayer(getDskLLayerName(0)), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.DSK, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts index edbd22fb..06c0721d 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts @@ -6,10 +6,10 @@ import { TSR } from 'blueprints-integration' import { - CreateTimingEnable, CueDefinitionClearGrafiks, ExtendedShowStyleContext, - GetDefaultOut, + getDefaultOut, + getTimingEnable, literal } from 'tv2-common' import { SharedGraphicLLayer, SharedOutputLayers } from 'tv2-constants' @@ -36,12 +36,12 @@ export function EvaluateClearGrafiks( SourceLayer.PgmGraphicsHeadline, SourceLayer.PgmGraphicsTema, SourceLayer.PgmGraphicsOverlay - ].forEach(sourceLayerId => { + ].forEach((sourceLayerId) => { pieces.push({ externalId: partId, name: `CLEAR ${sourceLayerId}`, enable: { - start: CreateTimingEnable(parsedCue, GetDefaultOut(context.config)).enable.start, + start: getTimingEnable(parsedCue, getDefaultOut(context.config)).enable.start, duration: 1000 }, outputLayerId: SharedOutputLayers.SEC, @@ -57,7 +57,7 @@ export function EvaluateClearGrafiks( pieces.push({ externalId: partId, name: 'CLEAR', - ...CreateTimingEnable(parsedCue, GetDefaultOut(context.config)), + ...getTimingEnable(parsedCue, getDefaultOut(context.config)), outputLayerId: SharedOutputLayers.SEC, sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, lifespan: PieceLifespan.WithinPart, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts index 6e88718e..9f5950c2 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts @@ -1,7 +1,7 @@ import { IBlueprintActionManifest, IBlueprintPiece, PieceLifespan } from 'blueprints-integration' import { ActionSelectDVE, - CalculateTime, + calculateTime, CueDefinitionDVE, DVEPieceMetaData, ExtendedShowStyleContext, @@ -69,9 +69,9 @@ export function EvaluateDVE( } }) } else { - let start = parsedCue.start ? CalculateTime(parsedCue.start) : 0 + let start = parsedCue.start ? calculateTime(parsedCue.start) : 0 start = start ? start : 0 - const end = parsedCue.end ? CalculateTime(parsedCue.end) : undefined + const end = parsedCue.end ? calculateTime(parsedCue.end) : undefined const pieceName = `DVE: ${parsedCue.template}` pieces.push( literal>({ diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts index a7e0af34..fe275bc2 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts @@ -8,7 +8,7 @@ import { WithTimeline } from 'blueprints-integration' import { - CalculateTime, + calculateTime, CueDefinitionBackgroundLoop, ExtendedShowStyleContext, literal, @@ -28,7 +28,7 @@ export function EvaluateCueBackgroundLoop( adlib?: boolean, rank?: number ) { - const start = (parsedCue.start ? CalculateTime(parsedCue.start) : 0) ?? 0 + const start = (parsedCue.start ? calculateTime(parsedCue.start) : 0) ?? 0 if (parsedCue.target === 'DVE') { const fileName = parsedCue.backgroundLoop diff --git a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts index 87c397e5..9f3e2033 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts @@ -34,7 +34,7 @@ export function EvaluateJingle( let file = '' - const jingle = context.config.showStyle.BreakerConfig.find(brkr => + const jingle = context.config.showStyle.BreakerConfig.find((brkr) => brkr.BreakerName ? brkr.BreakerName.toString().toUpperCase() === parsedCue.clip.toUpperCase() : false ) if (!jingle) { diff --git a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts index 4fafe980..7d9d2678 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts @@ -1,6 +1,6 @@ import { CameraContent, PieceLifespan, TSR, WithTimeline } from 'blueprints-integration' import { - CalculateTime, + calculateTime, CueDefinitionRouting, EvaluateCueResult, ExtendedShowStyleContext, @@ -17,7 +17,7 @@ export function EvaluateCueRouting( parsedCue: CueDefinitionRouting ): EvaluateCueResult { const result = new EvaluateCueResult() - const time = (parsedCue.start ? CalculateTime(parsedCue.start) : 0) ?? 0 + const time = (parsedCue.start ? calculateTime(parsedCue.start) : 0) ?? 0 const sourceDefinition = parsedCue.INP1 ?? parsedCue.INP if (!sourceDefinition) { context.core.notifyUserWarning(`No input provided for viz engine aux`) diff --git a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts index 02dd65ab..dd20c48f 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts @@ -38,7 +38,7 @@ export function EvaluateTelefon( function findTelefonPiece(result: EvaluateCueResult) { return result.pieces.find( - p => + (p) => p.outputLayerId === SharedOutputLayers.OVERLAY || p.outputLayerId === SharedOutputLayers.PGM || p.outputLayerId === SharedOutputLayers.SEC diff --git a/src/tv2_afvd_showstyle/migrations/hotkeys.ts b/src/tv2_afvd_showstyle/migrations/hotkeys.ts index 5c428b3f..37c5c195 100644 --- a/src/tv2_afvd_showstyle/migrations/hotkeys.ts +++ b/src/tv2_afvd_showstyle/migrations/hotkeys.ts @@ -12,17 +12,17 @@ export function GetDefaultStudioSourcesForAFVD(context: MigrationContextShowStyl const dveLayoutConfig = context.getBaseConfig('DVEStyles') as TableConfigItemValue | undefined let dveLayouts: string[] = [] if (dveLayoutConfig?.length) { - dveLayouts = dveLayoutConfig.map(dve => dve.DVEName).filter(name => name !== undefined) as string[] + dveLayouts = dveLayoutConfig.map((dve) => dve.DVEName).filter((name) => name !== undefined) as string[] } else { dveLayouts = (dveStylesManifest as ConfigManifestEntryTable).defaultVal - .map(dve => dve.DVEName) - .filter(name => name !== undefined) as string[] + .map((dve) => dve.DVEName) + .filter((name) => name !== undefined) as string[] } - const camera = manifestAFVDSourcesCam.defaultVal.map(source => source.SourceName) as string[] - const remote = manifestAFVDSourcesRM.defaultVal.map(source => source.SourceName) as string[] - const feed = manifestAFVDSourcesFeed.defaultVal.map(source => source.SourceName) as string[] - const replay = manifestAFVDSourcesReplay.defaultVal.map(source => source.SourceName) as string[] + const camera = manifestAFVDSourcesCam.defaultVal.map((source) => source.SourceName) as string[] + const remote = manifestAFVDSourcesRM.defaultVal.map((source) => source.SourceName) as string[] + const feed = manifestAFVDSourcesFeed.defaultVal.map((source) => source.SourceName) as string[] + const replay = manifestAFVDSourcesReplay.defaultVal.map((source) => source.SourceName) as string[] return { camera, diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 11974570..cda9f211 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -112,7 +112,7 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ * 1.6.3 * - Hide DSK toggle layers */ - ...GetDSKSourceLayerNames(ATEMModel.CONSTELLATION_8K_UHD_MODE).map(layerName => + ...GetDSKSourceLayerNames(ATEMModel.CONSTELLATION_8K_UHD_MODE).map((layerName) => forceSourceLayerToDefaults('1.6.3', layerName) ), diff --git a/src/tv2_afvd_showstyle/parts/grafik.ts b/src/tv2_afvd_showstyle/parts/grafik.ts index 0c24017d..4b2a5658 100644 --- a/src/tv2_afvd_showstyle/parts/grafik.ts +++ b/src/tv2_afvd_showstyle/parts/grafik.ts @@ -36,7 +36,9 @@ export async function CreatePartGrafik( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - if (partDefinition.cues.filter(c => c.type === CueType.Graphic && GraphicIsPilot(c) && c.target === 'FULL').length) { + if ( + partDefinition.cues.filter((c) => c.type === CueType.Graphic && GraphicIsPilot(c) && c.target === 'FULL').length + ) { ApplyFullGraphicPropertiesToPart(context.config, part) } diff --git a/src/tv2_afvd_showstyle/parts/intro.ts b/src/tv2_afvd_showstyle/parts/intro.ts index 99dccdcf..a8ad2bb0 100644 --- a/src/tv2_afvd_showstyle/parts/intro.ts +++ b/src/tv2_afvd_showstyle/parts/intro.ts @@ -27,7 +27,7 @@ export async function CreatePartIntro( ): Promise { const partTime = PartTime(context.config, partDefinition, totalWords, false) - const jingleCue = partDefinition.cues.find(cue => { + const jingleCue = partDefinition.cues.find((cue) => { const parsedCue = cue return parsedCue.type === CueType.Jingle }) @@ -44,7 +44,7 @@ export async function CreatePartIntro( return CreatePartInvalid(partDefinition) } - const jingle = context.config.showStyle.BreakerConfig.find(jngl => + const jingle = context.config.showStyle.BreakerConfig.find((jngl) => jngl.BreakerName ? jngl.BreakerName.toString().toUpperCase() === parsedJingle.clip.toString().toUpperCase() : false ) if (!jingle) { diff --git a/src/tv2_afvd_showstyle/parts/live.ts b/src/tv2_afvd_showstyle/parts/live.ts index 91cd5f70..5cef06f6 100644 --- a/src/tv2_afvd_showstyle/parts/live.ts +++ b/src/tv2_afvd_showstyle/parts/live.ts @@ -48,8 +48,8 @@ export async function CreatePartLive( part.hackListenToMediaObjectUpdates = mediaSubscriptions - const liveCue = partDefinition.cues.find(c => c.type === CueType.Ekstern) as CueDefinitionEkstern - const livePiece = pieces.find(p => p.sourceLayerId === SourceLayer.PgmLive) + const liveCue = partDefinition.cues.find((c) => c.type === CueType.Ekstern) as CueDefinitionEkstern + const livePiece = pieces.find((p) => p.sourceLayerId === SourceLayer.PgmLive) if (pieces.length === 0 || !liveCue || !livePiece) { part.invalid = true diff --git a/src/tv2_afvd_showstyle/parts/unknown.ts b/src/tv2_afvd_showstyle/parts/unknown.ts index 96647bf0..12b747c2 100644 --- a/src/tv2_afvd_showstyle/parts/unknown.ts +++ b/src/tv2_afvd_showstyle/parts/unknown.ts @@ -45,8 +45,8 @@ export async function CreatePartUnknown( part = { ...part, ...GetJinglePartProperties(context, partDefinition) } if ( - partDefinition.cues.some(cue => cue.type === CueType.Graphic && GraphicIsPilot(cue) && cue.target === 'FULL') && - !partDefinition.cues.filter(c => c.type === CueType.Jingle).length + partDefinition.cues.some((cue) => cue.type === CueType.Graphic && GraphicIsPilot(cue) && cue.target === 'FULL') && + !partDefinition.cues.filter((c) => c.type === CueType.Jingle).length ) { ApplyFullGraphicPropertiesToPart(context.config, part) } diff --git a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts index ae888902..fbc3a11f 100644 --- a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts @@ -56,9 +56,6 @@ const blankStudioConfig: StudioConfig = { Playing: true } }, - TriCasterSettings: { - DveMixEffect: 1 - }, AudioBedSettings: { fadeIn: 0, fadeOut: 0, @@ -91,7 +88,7 @@ const blankStudioConfig: StudioConfig = { function getObjectKeys(obj: any): string[] { const definedKeys: string[] = [] const processObj = (prefix: string, o: any) => { - _.each(_.keys(o), k => { + _.each(_.keys(o), (k) => { if (_.isArray(o[k])) { definedKeys.push(prefix + k) } else if (_.isObject(o[k])) { @@ -107,7 +104,7 @@ function getObjectKeys(obj: any): string[] { describe('Config Manifest', () => { test('Exposed Studio Keys', () => { - const studioManifestKeys = _.map(studioConfigManifest, e => e.id) + const studioManifestKeys = _.map(studioConfigManifest, (e) => e.id) const manifestKeys = studioManifestKeys.concat(CORE_INJECTED_KEYS).sort() const definedKeys = getObjectKeys(blankStudioConfig) diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index 901e29c7..fd9a400f 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -29,25 +29,6 @@ import { CasparLLayer } from '../layers' const SEGMENT_EXTERNAL_ID = '00000000' -// function makeMockGalleryContext(): ExtendedSegmentContext { -// const mockCoreContext = new SegmentUserContext( -// 'mock_context', -// mappingsDefaults, -// parseStudioConfig, -// parseShowStyleConfig, -// rundown._id -// ) -// mockCoreContext.studioConfig = defaultStudioConfig as any -// mockCoreContext.showStyleConfig = defaultShowStyleConfig as any -// const mockContext: ExtendedSegmentContext = { -// core: mockCoreContext, -// // @todo: this is awful, fix it perhaps by replacing defaultShowStyleConfig and defaultStudioConfig with preparsed config?! -// config: { ...(mockCoreContext.getStudioConfig() as any), ...(mockCoreContext.getShowStyleConfig() as any) }, -// videoSwitcher: new MockSwitcher() -// } -// return mockContext -// } - describe('Graphics', () => { it('Throws warning for unpaired target and creates invalid part', async () => { const context = makeMockGalleryContext() @@ -74,7 +55,7 @@ describe('Graphics', () => { const result = await CreatePartGrafik(context, partDefintion, 0) - expect((context.core as SegmentUserContext).getNotes().map(msg => msg.message)).toEqual([ + expect((context.core as SegmentUserContext).getNotes().map((msg) => msg.message)).toEqual([ `No graphic found after GRAFIK cue` ]) expect(result.pieces).toHaveLength(0) @@ -110,7 +91,7 @@ describe('Graphics', () => { CreatePartGrafik(context, partDefinition, 0) - expect((context.core as SegmentUserContext).getNotes().map(msg => msg.message)).toEqual([ + expect((context.core as SegmentUserContext).getNotes().map((msg) => msg.message)).toEqual([ `Graphic found without target engine` ]) }) @@ -156,7 +137,7 @@ describe('Graphics', () => { const timeline = content.timelineObjects as TSR.TSRTimelineObj[] expect(timeline).toHaveLength(7) // @todo: this depends on unrelated configuration const vizObj = timeline.find( - t => + (t) => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT )! as TSR.TimelineObjVIZMSEElementPilot expect(vizObj.enable).toEqual({ start: 0 }) @@ -219,7 +200,7 @@ describe('Graphics', () => { const timeline = content.timelineObjects as TSR.TSRTimelineObj[] expect(timeline).toHaveLength(1) const vizObj = timeline.find( - t => + (t) => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT )! as TSR.TimelineObjVIZMSEElementPilot expect(vizObj.enable).toEqual({ while: '!.full' }) @@ -275,7 +256,7 @@ describe('Graphics', () => { const timeline = content.timelineObjects as TSR.TSRTimelineObj[] expect(timeline).toHaveLength(1) const vizObj = timeline.find( - t => + (t) => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT )! as TSR.TimelineObjVIZMSEElementPilot expect(vizObj.enable).toEqual({ while: '1' }) @@ -328,7 +309,7 @@ describe('Graphics', () => { const timeline = content.timelineObjects as TSR.TSRTimelineObj[] expect(timeline).toHaveLength(7) const vizObj = timeline.find( - t => + (t) => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT )! as TSR.TimelineObjVIZMSEElementPilot expect(vizObj.enable).toEqual({ start: 0 }) @@ -381,12 +362,12 @@ describe('Graphics', () => { const result = await CreatePartGrafik(context, partDefinition, 0) expect(result.pieces).toHaveLength(3) - const auxPiece = result.pieces.find(p => p.outputLayerId === SharedOutputLayers.AUX)! + const auxPiece = result.pieces.find((p) => p.outputLayerId === SharedOutputLayers.AUX)! expect(auxPiece.enable).toEqual({ start: 0 }) expect(auxPiece.sourceLayerId).toBe(SourceLayer.VizFullIn1) expect(auxPiece.lifespan).toBe(PieceLifespan.WithinPart) const auxObj = (auxPiece.content?.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.AUX + (obj) => obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.AUX ) as TSR.TimelineObjAtemAUX | undefined expect(auxObj).toBeTruthy() expect(auxObj?.enable).toEqual({ start: 0 }) @@ -460,7 +441,7 @@ describe('Graphics', () => { expect(piece.sourceLayerId).toBe(SourceLayer.PgmDVEBackground) expect(piece.lifespan).toBe(PieceLifespan.OutOnShowStyleEnd) const tlObj = (piece.content?.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => + (obj) => obj.content.deviceType === TSR.DeviceType.CASPARCG && obj.content.type === TSR.TimelineContentTypeCasparCg.MEDIA ) as TSR.TimelineObjCCGMedia | undefined expect(tlObj).toBeTruthy() @@ -510,7 +491,7 @@ describe('Graphics', () => { expect(piece.sourceLayerId).toBe(SourceLayer.PgmGraphicsLower) expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const tlObj = (piece.content?.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => + (obj) => obj.content.deviceType === TSR.DeviceType.VIZMSE && obj.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL ) as TSR.TimelineObjVIZMSEElementInternal | undefined diff --git a/src/tv2_afvd_studio/__tests__/migrations-defaults.spec.ts b/src/tv2_afvd_studio/__tests__/migrations-defaults.spec.ts index 1658483d..924fb5ec 100644 --- a/src/tv2_afvd_studio/__tests__/migrations-defaults.spec.ts +++ b/src/tv2_afvd_studio/__tests__/migrations-defaults.spec.ts @@ -1,21 +1,34 @@ import { AbstractLLayerServerEnable, + ATEM_LAYER_PREFIX, CasparPlayerClip, CasparPlayerClipLoadingLoop, - GetDSKMappingNames + getUsedLayers, + TRICASTER_LAYER_PREFIX } from 'tv2-common' +import { AbstractLLayer, RobotCameraLayer } from 'tv2-constants' import * as _ from 'underscore' -import { ATEMModel } from '../../types/atem' +import { CasparLLayer, GraphicLLayer, SisyfosLLAyer, VirtualAbstractLLayer } from '../layers' -import { RealLLayers } from '../layers' -import MappingsDefaults, { getMediaPlayerMappings } from '../migrations/mappings-defaults' +import MappingsDefaults from '../migrations/mappings-defaults' +import { GALLERY_UNIFORM_CONFIG } from '../uniformConfig' + +/** Get all the Real LLayers (map to devices). Note: Does not include some which are dynamically generated */ +export function getRealLLayers(): string[] { + return getUsedLayers(GALLERY_UNIFORM_CONFIG) + .flatMap((layer) => [TRICASTER_LAYER_PREFIX + layer, ATEM_LAYER_PREFIX + layer]) + .concat(_.values(CasparLLayer)) + .concat(_.values(SisyfosLLAyer)) + .concat(_.values(AbstractLLayer)) + .concat(_.values(GraphicLLayer)) + .concat(_.values(VirtualAbstractLLayer)) + .concat(_.values(RobotCameraLayer)) +} describe('Migration Defaults', () => { test('MappingsDefaults', () => { const allMappings = { - ...MappingsDefaults, - // Inject MediaPlayer ones, as they are used directly and part of the enum - ...getMediaPlayerMappings([]) + ...MappingsDefaults } const defaultsIds = _.map(allMappings, (v, id) => { v = v @@ -23,7 +36,7 @@ describe('Migration Defaults', () => { }).sort() // Inject core_abstract as it is required by core and so needs to be defined - const layerIds = RealLLayers() + const layerIds = getRealLLayers() .concat(['core_abstract']) .concat([ CasparPlayerClip(1), @@ -31,11 +44,10 @@ describe('Migration Defaults', () => { CasparPlayerClipLoadingLoop(1), CasparPlayerClipLoadingLoop(2), AbstractLLayerServerEnable(1), - AbstractLLayerServerEnable(2), - ...GetDSKMappingNames(ATEMModel.CONSTELLATION_8K_UHD_MODE) + AbstractLLayerServerEnable(2) ]) .sort() - expect(defaultsIds).toEqual(layerIds) + expect(defaultsIds).toEqual(expect.arrayContaining(layerIds)) }) }) diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index 3f2aafa0..39328139 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -377,14 +377,6 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ required: false, defaultVal: true }, - { - id: 'TriCasterSettings.DveMixEffect', - name: 'TriCaster DVE MixEffect', - description: 'TriCaster MixEffect used to make DVEs', - type: ConfigManifestEntryType.BOOLEAN, - required: false, - defaultVal: true - }, { id: 'AudioBedSettings.fadeIn', name: 'Bed Fade In', diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index 3e61628f..36816aa9 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -7,12 +7,7 @@ import { } from 'blueprints-integration' import { ExtendedStudioContext, literal, SpecialInput, TransitionStyle } from 'tv2-common' import * as _ from 'underscore' -import { - SharedGraphicLLayer, - SwitcherAuxLLayer, - SwitcherMediaPlayerLLayer, - SwitcherMixEffectLLayer -} from '../tv2-constants' +import { SharedGraphicLLayer, SwitcherMediaPlayerLLayer } from '../tv2-constants' import { AtemSourceIndex } from '../types/atem' import { GalleryStudioConfig } from './helpers/config' import { SisyfosLLAyer } from './layers' @@ -25,7 +20,7 @@ function filterMappings( ): BlueprintMappings { const result: BlueprintMappings = {} - _.each(_.keys(input), k => { + _.each(_.keys(input), (k) => { const v = input[k] if (filter(k, v)) { result[k] = v @@ -65,7 +60,7 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin } return { - timelineObjects: [ + timelineObjects: _.compact([ literal({ id: '', enable: { @@ -82,23 +77,27 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin }), // have ATEM output default still image - context.videoSwitcher.getAuxTimelineObject({ - enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxProgram, - content: { - input: SpecialInput.ME1_PROGRAM - } - }), - context.videoSwitcher.getAuxTimelineObject({ - enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxLookahead, - content: { - input: SpecialInput.ME1_PROGRAM - } - }), + context.uniformConfig.mixEffects.program.auxLayer + ? context.videoSwitcher.getAuxTimelineObject({ + enable: { while: '1' }, + layer: context.uniformConfig.mixEffects.program.auxLayer, + content: { + input: SpecialInput.ME1_PROGRAM + } + }) + : undefined, + context.uniformConfig.switcherLLayers.nextAux + ? context.videoSwitcher.getAuxTimelineObject({ + enable: { while: '1' }, + layer: context.uniformConfig.switcherLLayers.nextAux, + content: { + input: SpecialInput.ME1_PROGRAM + } + }) + : undefined, context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - layer: SwitcherMixEffectLLayer.Program, + layer: context.uniformConfig.mixEffects.program.mixEffectLayer, content: { input: AtemSourceIndex.MP1, transition: TransitionStyle.CUT @@ -133,6 +132,6 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin concept: '' } }) - ] + ]) } } diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index fa591556..074d3ec8 100644 --- a/src/tv2_afvd_studio/helpers/config.ts +++ b/src/tv2_afvd_studio/helpers/config.ts @@ -46,7 +46,7 @@ export interface StudioConfig extends TV2StudioConfigBase { } export function preprocessConfig(_context: ICommonContext, rawConfig: IBlueprintConfig): any { - const studioConfig = (rawConfig as unknown) as StudioConfig + const studioConfig = rawConfig as unknown as StudioConfig const config: GalleryStudioConfig = { studio: studioConfig, sources: parseSources(studioConfig), diff --git a/src/tv2_afvd_studio/helpers/sources.ts b/src/tv2_afvd_studio/helpers/sources.ts index 956fb140..e6d1553b 100644 --- a/src/tv2_afvd_studio/helpers/sources.ts +++ b/src/tv2_afvd_studio/helpers/sources.ts @@ -5,7 +5,7 @@ import { ParseMappingTable, SourceInfoType, SourceMapping } from 'tv2-common' import { StudioConfig } from './config' export function parseMediaPlayers(studioConfig: StudioConfig): Array<{ id: string; val: string }> { - return studioConfig.ABMediaPlayers.map(player => ({ + return studioConfig.ABMediaPlayers.map((player) => ({ id: player.SourceName, val: player.SwitcherSource.toString() })) diff --git a/src/tv2_afvd_studio/layers.ts b/src/tv2_afvd_studio/layers.ts index 635ee5a7..812eebaa 100644 --- a/src/tv2_afvd_studio/layers.ts +++ b/src/tv2_afvd_studio/layers.ts @@ -1,29 +1,6 @@ -import { - AbstractLLayer, - RobotCameraLayer, - SharedCasparLLayer, - SharedGraphicLLayer, - SharedSisyfosLLayer -} from 'tv2-constants' +import { SharedCasparLLayer, SharedGraphicLLayer, SharedSisyfosLLayer } from 'tv2-constants' import * as _ from 'underscore' -/** Get all the Real LLayers (map to devices). Note: Does not include some which are dynamically generated */ -export function RealLLayers(): string[] { - return ( - _.values(CasparLLayer) - // @ts-ignore - .concat(_.values(SisyfosLLAyer)) - // @ts-ignore - .concat(_.values(AbstractLLayer)) - // @ts-ignore - .concat(_.values(GraphicLLayer)) - // @ts-ignore - .concat(_.values(VirtualAbstractLLayer)) - // @ts-ignore - .concat(_.values(RobotCameraLayer)) - ) -} - export enum VirtualAbstractLLayer {} enum AFVDCasparLLayer { diff --git a/src/tv2_afvd_studio/migrations/devices.ts b/src/tv2_afvd_studio/migrations/devices.ts index dbf81e31..53f3d1e4 100644 --- a/src/tv2_afvd_studio/migrations/devices.ts +++ b/src/tv2_afvd_studio/migrations/devices.ts @@ -102,7 +102,7 @@ const devices: DeviceEntry[] = [ id: 'caspar01', firstVersion: '0.1.0', type: TSR.DeviceType.CASPARCG, - defaultValue: input => ({ + defaultValue: (input) => ({ type: TSR.DeviceType.CASPARCG, options: { host: input.host, @@ -120,7 +120,7 @@ const devices: DeviceEntry[] = [ defaultValue: undefined } ], - validate: device => { + validate: (device) => { if (!device.options) { return 'Missing options' } @@ -159,7 +159,7 @@ const devices: DeviceEntry[] = [ } return undefined }, - validate: device => { + validate: (device) => { if (!device.options) { return 'Missing options' } @@ -186,7 +186,7 @@ const devices: DeviceEntry[] = [ id: 'atem0', firstVersion: '0.1.0', type: TSR.DeviceType.ATEM, - defaultValue: input => ({ + defaultValue: (input) => ({ type: TSR.DeviceType.ATEM, options: { host: input.host, @@ -202,7 +202,7 @@ const devices: DeviceEntry[] = [ defaultValue: undefined } ], - validate: device => { + validate: (device) => { if (!device.options) { return 'Missing options' } diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index 84d7db64..04776d2c 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -2,11 +2,12 @@ import { MigrationStepStudio, TSR } from 'blueprints-integration' import { AddKeepAudio, addSourceToSourcesConfig, + convertStudioTableColumnToFloat, MoveClipSourcePath, MoveSourcesToTable, PrefixEvsWithEvs, RemoveConfig, - RenameStudioConfig, + renameStudioConfig, renameStudioTableColumn, SetConfigTo, SetLayerNamesToDefaults @@ -108,7 +109,7 @@ export const studioMigrations: MigrationStepStudio[] = [ 'viz_layer_pilot', 'viz_layer_pilot_overlay', 'viz_layer_wall' - ].map(layer => renameMapping('0.2.0', layer, layer.replace(/^viz_layer_/, 'graphic_'))), + ].map((layer) => renameMapping('0.2.0', layer, layer.replace(/^viz_layer_/, 'graphic_'))), AddKeepAudio('0.2.0', 'SourcesRM'), MoveClipSourcePath('0.2.0', 'AFVD'), ...[ @@ -142,24 +143,24 @@ export const studioMigrations: MigrationStepStudio[] = [ 'sisyfos_source_evs_1', 'sisyfos_source_evs_2', 'sisyfos_resync' - ].map(layer => EnsureSisyfosMappingHasType('1.3.0', layer, TSR.MappingSisyfosType.CHANNEL)), + ].map((layer) => EnsureSisyfosMappingHasType('1.3.0', layer, TSR.MappingSisyfosType.CHANNEL)), GetMappingDefaultMigrationStepForLayer('1.3.0', SisyfosLLAyer.SisyfosGroupStudioMics), GetMappingDefaultMigrationStepForLayer('1.3.2', CasparLLayer.CasparCGLYD, true), GetMappingDefaultMigrationStepForLayer('1.4.0', CasparLLayer.CasparPlayerClipPending, true), GetMappingDefaultMigrationStepForLayer('1.4.5', CasparLLayer.CasparPlayerClipPending, true), - RenameStudioConfig('1.4.6', 'AFVD', 'MediaFlowId', 'ClipMediaFlowId'), - RenameStudioConfig('1.4.6', 'AFVD', 'NetworkBasePath', 'NetworkBasePathClip'), - RenameStudioConfig('1.4.6', 'AFVD', 'JingleBasePath', 'NetworkBasePathJingle'), + renameStudioConfig('1.4.6', 'AFVD', 'MediaFlowId', 'ClipMediaFlowId'), + renameStudioConfig('1.4.6', 'AFVD', 'NetworkBasePath', 'NetworkBasePathClip'), + renameStudioConfig('1.4.6', 'AFVD', 'JingleBasePath', 'NetworkBasePathJingle'), - RenameStudioConfig('1.5.0', 'AFVD', 'NetworkBasePathJingle', 'JingleNetworkBasePath'), - RenameStudioConfig('1.5.0', 'AFVD', 'NetworkBasePathClip', 'ClipNetworkBasePath'), - RenameStudioConfig('1.5.0', 'AFVD', 'NetworkBasePathGraphic', 'GraphicNetworkBasePath'), - RenameStudioConfig('1.5.0', 'AFVD', 'PilotCutToMediaPlayer', 'VizPilotGraphics.CutToMediaPlayer'), - RenameStudioConfig('1.5.0', 'AFVD', 'PilotKeepaliveDuration', 'VizPilotGraphics.KeepAliveDuration'), - RenameStudioConfig('1.5.0', 'AFVD', 'PilotOutTransitionDuration', 'VizPilotGraphics.OutTransitionDuration'), - RenameStudioConfig('1.5.0', 'AFVD', 'PilotPrerollDuration', 'VizPilotGraphics.PrerollDuration'), - RenameStudioConfig('1.5.0', 'AFVD', 'FullFrameGrafikBackground', 'VizPilotGraphics.FullGraphicBackground'), + renameStudioConfig('1.5.0', 'AFVD', 'NetworkBasePathJingle', 'JingleNetworkBasePath'), + renameStudioConfig('1.5.0', 'AFVD', 'NetworkBasePathClip', 'ClipNetworkBasePath'), + renameStudioConfig('1.5.0', 'AFVD', 'NetworkBasePathGraphic', 'GraphicNetworkBasePath'), + renameStudioConfig('1.5.0', 'AFVD', 'PilotCutToMediaPlayer', 'VizPilotGraphics.CutToMediaPlayer'), + renameStudioConfig('1.5.0', 'AFVD', 'PilotKeepaliveDuration', 'VizPilotGraphics.KeepAliveDuration'), + renameStudioConfig('1.5.0', 'AFVD', 'PilotOutTransitionDuration', 'VizPilotGraphics.OutTransitionDuration'), + renameStudioConfig('1.5.0', 'AFVD', 'PilotPrerollDuration', 'VizPilotGraphics.PrerollDuration'), + renameStudioConfig('1.5.0', 'AFVD', 'FullFrameGrafikBackground', 'VizPilotGraphics.FullGraphicBackground'), renameMapping('1.5.1', 'studio0_adlib_viz_cmd', 'studio0_adlib_graphic_cmd'), @@ -182,10 +183,10 @@ export const studioMigrations: MigrationStepStudio[] = [ removeMapping('1.6.1', 'atem_dsk_graphics'), removeMapping('1.6.1', 'atem_dsk_efect'), - RenameStudioConfig('1.6.2', 'AFVD', 'SourcesRM.KeepAudioInStudio', 'SourcesRM.WantsToPersistAudio'), // @todo: check what this does because it does not seem right + renameStudioConfig('1.6.2', 'AFVD', 'SourcesRM.KeepAudioInStudio', 'SourcesRM.WantsToPersistAudio'), // @todo: check what this does because it does not seem right RemoveConfig('1.6.2', 'AFVD', 'SourcesSkype'), - RenameStudioConfig('1.7.4', 'AFVD', 'SourcesDelayedPlayback', 'SourcesReplay'), + renameStudioConfig('1.7.4', 'AFVD', 'SourcesDelayedPlayback', 'SourcesReplay'), addSourceToSourcesConfig('1.7.4', 'AFVD', 'SourcesReplay', { SourceName: 'EPSIO', SwitcherSource: 25, @@ -203,12 +204,14 @@ export const studioMigrations: MigrationStepStudio[] = [ renameMapping('1.7.8', 'graphic_pilot_overlay', 'graphic_overlay_pilot'), /** - * 1.8.0 (@todo version) + * 1.8.0 */ - ...['SourcesCam', 'SourcesRM', 'SourcesReplay', 'SourcesFeed', 'ABMediaPlayers'].map(tableName => + ...['SourcesCam', 'SourcesRM', 'SourcesReplay', 'SourcesFeed', 'ABMediaPlayers'].map((tableName) => renameStudioTableColumn('1.8.0', tableName, 'AtemSource', 'SwitcherSource') ), - RenameStudioConfig('1.8.0', 'AFVD', 'AtemSource', 'SwitcherSource'), + renameStudioConfig('1.8.0', 'AFVD', 'AtemSource', 'SwitcherSource'), + convertStudioTableColumnToFloat('1.8.0', 'SwitcherSource.DSK', 'Clip'), + convertStudioTableColumnToFloat('1.8.0', 'SwitcherSource.DSK', 'Gain'), // Fill in any mappings that did not exist before // Note: These should only be run as the very final step of all migrations. otherwise they will add items too early, and confuse old migrations diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index 6f500b0b..9e807235 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -9,7 +9,6 @@ import { getTriCasterDskMappings, literal, prefixLayers, - SisyfosPlayerClip, TRICASTER_CLEAN_ME, TRICASTER_DEVICE_ID, TRICASTER_DVE_ME, @@ -25,7 +24,6 @@ import { SwitcherMixEffectLLayer } from 'tv2-constants' import { ATEMModel } from '../../types/atem' -import { GalleryStudioConfig } from '../helpers/config' import { CasparLLayer, GraphicLLayer, SisyfosLLAyer } from '../layers' export const MAPPINGS_ABSTRACT: BlueprintMappings = { @@ -769,14 +767,6 @@ export const MAPPINGS_TRICASTER = prefixLayers({ ...MAPPINGS_TRICASTER, ...MAPPINGS_TELEMETRICS }) - -export function getMediaPlayerMappings(mediaPlayers: GalleryStudioConfig['mediaPlayers']) { - const res: BlueprintMappings = { - casparcg_player_clip_pending: literal({ - device: TSR.DeviceType.ABSTRACT, - deviceId: 'abstract0', - lookahead: LookaheadMode.PRELOAD, - lookaheadDepth: mediaPlayers.length // Number of players - }), - sisyfos_source_clip_pending: literal({ - device: TSR.DeviceType.ABSTRACT, - deviceId: 'abstract0', - lookahead: LookaheadMode.NONE - }) - } - - for (const mp of mediaPlayers) { - res[CasparPlayerClip(mp.id)] = literal({ - device: TSR.DeviceType.CASPARCG, - deviceId: 'caspar01', - lookahead: LookaheadMode.NONE, - channel: 0, // TODO? - layer: 110 - }) - res[SisyfosPlayerClip(mp.id)] = literal({ - device: TSR.DeviceType.SISYFOS, - deviceId: 'sisyfos0', - lookahead: LookaheadMode.NONE, - channel: Number(mp.id) || 0, - mappingType: TSR.MappingSisyfosType.CHANNEL, - layerName: `Server ${mp.id === '1' ? 'A' : 'B'}`, - setLabelToLayerName: true - }) - } - - return res -} diff --git a/src/tv2_afvd_studio/uniformConfig.ts b/src/tv2_afvd_studio/uniformConfig.ts index 73b3e200..4db645a2 100644 --- a/src/tv2_afvd_studio/uniformConfig.ts +++ b/src/tv2_afvd_studio/uniformConfig.ts @@ -1,13 +1,13 @@ -import { SpecialInput, UniformConfig } from 'tv2-common' +import { getSpecialLayers, SpecialInput, UniformConfig } from 'tv2-common' import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' -const MIX_EFFECTS: UniformConfig['MixEffects'] = { - Program: { +const MIX_EFFECTS: UniformConfig['mixEffects'] = { + program: { input: SpecialInput.ME1_PROGRAM, mixEffectLayer: SwitcherMixEffectLLayer.Program, auxLayer: SwitcherAuxLLayer.AuxProgram }, - Clean: { + clean: { input: SpecialInput.ME4_PROGRAM, mixEffectLayer: SwitcherMixEffectLLayer.Clean, auxLayer: SwitcherAuxLLayer.AuxClean @@ -15,20 +15,15 @@ const MIX_EFFECTS: UniformConfig['MixEffects'] = { } export const GALLERY_UNIFORM_CONFIG: UniformConfig = { - SwitcherLLayers: { - PrimaryMixEffect: SwitcherMixEffectLLayer.Program, - PrimaryMixEffectClone: SwitcherMixEffectLLayer.Clean, - JingleUskMixEffect: SwitcherMixEffectLLayer.CleanUSKEffect, - NextAux: SwitcherAuxLLayer.AuxLookahead, - MixMinusAux: SwitcherAuxLLayer.AuxVideoMixMinus + switcherLLayers: { + primaryMixEffect: SwitcherMixEffectLLayer.Program, + primaryMixEffectClone: SwitcherMixEffectLLayer.Clean, + jingleUskMixEffect: SwitcherMixEffectLLayer.CleanUSKEffect, + nextAux: SwitcherAuxLLayer.AuxLookahead, + mixMinusAux: SwitcherAuxLLayer.AuxVideoMixMinus }, - MixEffects: MIX_EFFECTS, - SpecialInputAuxLLayers: { - ...Object.fromEntries( - Object.values(MIX_EFFECTS) - .filter(mixEffect => mixEffect.auxLayer) - .map(mixEffect => [mixEffect.input, mixEffect.auxLayer]) - ), - [SpecialInput.DVE]: SwitcherAuxLLayer.AuxDve + mixEffects: MIX_EFFECTS, + specialInputAuxLLayers: { + ...getSpecialLayers(MIX_EFFECTS) } } diff --git a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts index af34ca44..e00c13d6 100644 --- a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts @@ -270,10 +270,10 @@ async function getActiveServerPieces( return { activePiece: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmServer)), + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.PgmServer)), dataStore: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedServer)) + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedServer)) } } @@ -281,10 +281,12 @@ async function getVOPieces(context: ActionExecutionContext, part: 'current' | 'n return { activePiece: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmVoiceOver)), + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.PgmVoiceOver)), dataStore: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedVoiceOver)) + .then((pieceInstances) => + pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedVoiceOver) + ) } } @@ -292,10 +294,12 @@ async function getDVEPieces(context: ActionExecutionContext, part: 'current' | ' return { activePiece: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmDVE)), + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.PgmDVE)), dataStore: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedAdLibDVE)) + .then((pieceInstances) => + pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedAdLibDVE) + ) } } @@ -306,11 +310,11 @@ async function getFullGrafikPieces( return { activePiece: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === SharedSourceLayers.PgmPilot)), + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === SharedSourceLayers.PgmPilot)), dataStore: await context .getPieceInstances(part) - .then(pieceInstances => - pieceInstances.find(p => p.piece.sourceLayerId === SharedSourceLayers.SelectedAdlibGraphicsFull) + .then((pieceInstances) => + pieceInstances.find((p) => p.piece.sourceLayerId === SharedSourceLayers.SelectedAdlibGraphicsFull) ) } } @@ -321,7 +325,7 @@ async function getCameraPiece( ): Promise { return context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmCam)) + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.PgmCam)) } async function getRemotePiece( @@ -330,7 +334,7 @@ async function getRemotePiece( ): Promise { return context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmLive)) + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.PgmLive)) } function validateSourcePiecesExist(pieces: ActivePiecesForSource) { @@ -364,9 +368,11 @@ function validateRemotePiece(piece: IBlueprintPieceInstance | undefined) { function validateNoWarningsOrErrors(context: ActionExecutionContext) { expect( - context.getNotes().filter(n => n.type === NoteType.WARNING || n.type === NoteType.NOTIFY_USER_WARNING) + context.getNotes().filter((n) => n.type === NoteType.WARNING || n.type === NoteType.NOTIFY_USER_WARNING) ).toEqual([]) - expect(context.getNotes().filter(n => n.type === NoteType.ERROR || n.type === NoteType.NOTIFY_USER_ERROR)).toEqual([]) + expect(context.getNotes().filter((n) => n.type === NoteType.ERROR || n.type === NoteType.NOTIFY_USER_ERROR)).toEqual( + [] + ) } function validateNextPartExistsWithDuration(context: ActionExecutionContext, duration: number) { @@ -381,7 +387,7 @@ function validateNextPartExistsWithPreviousPartKeepaliveDuration(context: Action function getATEMMEObj(piece: IBlueprintPieceInstance): TSR.TimelineObjAtemME { const atemObj = (piece.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => + (obj) => obj.layer === prefixLayer(SwitcherMixEffectLLayer.Clean) && obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.ME @@ -419,7 +425,7 @@ describe('Select Server Action', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -446,7 +452,7 @@ describe('Select Server Action', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -478,7 +484,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -511,7 +517,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -545,7 +551,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -579,7 +585,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -612,7 +618,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -645,7 +651,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) @@ -677,7 +683,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) @@ -710,7 +716,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) @@ -742,7 +748,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) @@ -774,7 +780,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) @@ -806,7 +812,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' // SERVER (A) await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -930,7 +936,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) @@ -973,7 +979,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) @@ -1016,7 +1022,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) @@ -1059,7 +1065,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) diff --git a/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts index d20508f4..a30a365a 100644 --- a/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts @@ -21,7 +21,7 @@ const blankShowStyleConfig: OfftubeShowStyleConfig = { describe('Config Manifest', () => { test('Exposed ShowStyle Keys', () => { - const showStyleManifestKeys = _.map(showStyleConfigManifest, e => e.id) + const showStyleManifestKeys = _.map(showStyleConfigManifest, (e) => e.id) const manifestKeys = showStyleManifestKeys.sort() const definedKeys = Object.keys(blankShowStyleConfig) diff --git a/src/tv2_offtube_showstyle/__tests__/migrations-defaults.spec.ts b/src/tv2_offtube_showstyle/__tests__/migrations-defaults.spec.ts index f541ea70..d119f798 100644 --- a/src/tv2_offtube_showstyle/__tests__/migrations-defaults.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/migrations-defaults.spec.ts @@ -7,9 +7,9 @@ import SourcelayerDefaults from '../migrations/sourcelayer-defaults' describe('Migration Defaults', () => { test('SourcelayerDefaults', () => { - const defaultsIds = _.map(SourcelayerDefaults, v => v._id).sort() + const defaultsIds = _.map(SourcelayerDefaults, (v) => v._id).sort() const layerIds = _.values(OfftubeSourceLayer) - .map(l => l.toString()) + .map((l) => l.toString()) .concat(GetDSKSourceLayerNames(ATEMModel.PRODUCTION_STUDIO_4K_2ME)) .sort() diff --git a/src/tv2_offtube_showstyle/config-manifests.ts b/src/tv2_offtube_showstyle/config-manifests.ts index 24ec9cb6..1b65794f 100644 --- a/src/tv2_offtube_showstyle/config-manifests.ts +++ b/src/tv2_offtube_showstyle/config-manifests.ts @@ -152,7 +152,7 @@ export const gfxDesignTemplates: ConfigManifestEntry[] = [ description: '', type: ConfigManifestEntryType.TABLE, required: true, - defaultVal: DEFAULT_GRAPHICS.map(val => ({ _id: '', ...val })).filter(template => template.IsDesign), + defaultVal: DEFAULT_GRAPHICS.map((val) => ({ _id: '', ...val })).filter((template) => template.IsDesign), columns: [ { id: DESIGN_NAME_COLUMN_ID, @@ -253,7 +253,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ 'This table can contain info in two ways. Things marked (**) are always required. If you want to do the mapping from iNews-code, then all (*)-elements are also required. GFX Template Name is what the graphic is called in the HTML package. Source layer is the ID of the Sofie Source layer in the UI (i.e. "studio0_graphicsTema"). Layer mapping is the Sofie studio layer mapping (i.e "viz_layer_tema"). iNews command can be something like "KG=", then iNews Name is the thing that follows in iNews i.e. "ident_nyhederne"', type: ConfigManifestEntryType.TABLE, required: false, - defaultVal: DEFAULT_GRAPHICS.map(val => ({ _id: '', ...val })).filter(template => !template.IsDesign), + defaultVal: DEFAULT_GRAPHICS.map((val) => ({ _id: '', ...val })).filter((template) => !template.IsDesign), columns: [ { id: 'INewsCode', diff --git a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts index c810ac00..983b9f8d 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts @@ -1,7 +1,7 @@ import { IBlueprintActionManifest, IBlueprintPiece, PieceLifespan, SplitsContent } from 'blueprints-integration' import { ActionSelectDVE, - CalculateTime, + calculateTime, CueDefinitionDVE, DVEPieceMetaData, ExtendedSegmentContext, @@ -48,9 +48,9 @@ export function OfftubeEvaluateDVE( const pieceContent = OfftubeMakeContentDVE(context, partDefinition, parsedCue, rawTemplate) if (adlibContent.valid && pieceContent.valid) { - let start = parsedCue.start ? CalculateTime(parsedCue.start) : 0 + let start = parsedCue.start ? calculateTime(parsedCue.start) : 0 start = start ? start : 0 - const end = parsedCue.end ? CalculateTime(parsedCue.end) : undefined + const end = parsedCue.end ? calculateTime(parsedCue.end) : undefined pieces.push({ externalId: partDefinition.externalId, name: parsedCue.template, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts index 40658cca..261a8d5e 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts @@ -7,7 +7,7 @@ import { TSR, WithTimeline } from 'blueprints-integration' -import { CalculateTime, CueDefinitionBackgroundLoop, ExtendedSegmentContext, literal } from 'tv2-common' +import { calculateTime, CueDefinitionBackgroundLoop, ExtendedSegmentContext, literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import _ = require('underscore') import { OfftubeCasparLLayer } from '../../tv2_offtube_studio/layers' @@ -26,7 +26,7 @@ export function OfftubeEvaluateCueBackgroundLoop( ) { const fileName = parsedCue.backgroundLoop const path = `dve/${fileName}` - const start = (parsedCue.start ? CalculateTime(parsedCue.start) : 0) ?? 0 + const start = (parsedCue.start ? calculateTime(parsedCue.start) : 0) ?? 0 if (adlib) { adlibPieces.push({ _rank: rank || 0, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index e5711ed2..a7565645 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -36,7 +36,7 @@ export function OfftubeEvaluateJingle( let file = '' - const jingle = context.config.showStyle.BreakerConfig.find(brkr => + const jingle = context.config.showStyle.BreakerConfig.find((brkr) => brkr.BreakerName ? brkr.BreakerName.toString().toUpperCase() === parsedCue.clip.toUpperCase() : false ) if (!jingle) { diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 853ebffc..3f952a41 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -26,11 +26,11 @@ import { CasparPlayerClipLoadingLoop, createDskBaseline, CreateDSKBaselineAdlibs, - CreateGraphicBaseline, CreateLYDBaseline, ExtendedShowStyleContext, ExtendedShowStyleContextImpl, generateExternalId, + getGraphicBaseline, GetTagForKam, GetTagForLive, GetTransitionAdLibActions, @@ -40,11 +40,9 @@ import { SourceInfo, SourceInfoToSourceDefinition, SourceInfoType, - SpecialInput, t, TimeFromINewsField, - TransitionStyle, - VideoSwitcher + TransitionStyle } from 'tv2-common' import { AdlibActionType, @@ -57,7 +55,6 @@ import { SourceType, SwitcherAuxLLayer, SwitcherDveLLayer, - SwitcherMixEffectLLayer, TallyTags } from 'tv2-constants' import * as _ from 'underscore' @@ -103,7 +100,7 @@ export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: In }), globalAdLibPieces: getGlobalAdLibPiecesOfftube(context), globalActions: getGlobalAdlibActionsOfftube(context.core, context.config), - baseline: getBaseline(context.config, context.videoSwitcher) + baseline: getBaseline(context) } } @@ -133,7 +130,7 @@ function getGlobalAdLibPiecesOfftube( content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: context.config.studio.StudioMics.map(layer => ({ + channels: context.config.studio.StudioMics.map((layer) => ({ mappedLayer: layer, isPgm: 1 })), @@ -163,7 +160,7 @@ function getGlobalAdLibPiecesOfftube( content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: context.config.studio.StudioMics.map(layer => ({ + channels: context.config.studio.StudioMics.map((layer) => ({ mappedLayer: layer, isPgm: 0 })), @@ -488,19 +485,19 @@ function getGlobalAdlibActionsOfftube( config.sources.cameras .slice(0, 5) // the first x cameras to create INP1/2/3 cam-adlibs from - .forEach(o => { + .forEach((o) => { makeCutCameraActions(o, false, globalRank++) }) config.sources.cameras .slice(0, 5) // the first x cameras to create preview cam-adlibs from - .forEach(o => { + .forEach((o) => { makeCutCameraActions(o, true, globalRank++) }) config.sources.cameras .slice(0, 5) // the first x cameras to create preview cam-adlibs from - .forEach(o => { + .forEach((o) => { makeAdlibBoxesActions(o, SourceInfoType.KAM, globalRank++) }) @@ -527,25 +524,25 @@ function getGlobalAdlibActionsOfftube( config.sources.feeds .slice(0, 10) // the first x sources to create feed-adlibs from - .forEach(o => { + .forEach((o) => { makeRemoteAction(o, globalRank++) }) config.sources.lives .slice(0, 10) // the first x sources to create live-adlibs from - .forEach(o => { + .forEach((o) => { makeRemoteAction(o, globalRank++) }) config.sources.feeds .slice(0, 10) // the first x remote to create INP1/2/3 feed-adlibs from - .forEach(o => { + .forEach((o) => { makeAdlibBoxesActions(o, SourceInfoType.FEED, globalRank++) }) config.sources.lives .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from - .forEach(o => { + .forEach((o) => { makeAdlibBoxesActions(o, SourceInfoType.LIVE, globalRank++) }) @@ -578,40 +575,44 @@ function getGlobalAdlibActionsOfftube( return blueprintActions } -function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitcher): BlueprintResultBaseline { +function getBaseline(context: ExtendedShowStyleContext): BlueprintResultBaseline { return { - timelineObjects: [ - ...CreateGraphicBaseline(config), + timelineObjects: _.compact([ + ...getGraphicBaseline(context.config), // Default timeline - videoSwitcher.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Clean, + context.videoSwitcher.getMixEffectTimelineObject({ + layer: context.uniformConfig.mixEffects.program.mixEffectLayer, enable: { while: '1' }, content: { - input: config.studio.SwitcherSource.Default, + input: context.config.studio.SwitcherSource.Default, transition: TransitionStyle.CUT } }), - videoSwitcher.getMixEffectTimelineObject({ - enable: { while: '1' }, - layer: SwitcherMixEffectLLayer.Next, - content: { - previewInput: config.studio.SwitcherSource.Default - } - }), + context.uniformConfig.switcherLLayers.nextPreviewMixEffect + ? context.videoSwitcher.getMixEffectTimelineObject({ + enable: { while: '1' }, + layer: context.uniformConfig.switcherLLayers.nextPreviewMixEffect, + content: { + previewInput: context.config.studio.SwitcherSource.Default + } + }) + : undefined, // route default outputs - videoSwitcher.getAuxTimelineObject({ - enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxClean, - content: { - input: SpecialInput.ME2_PROGRAM - } - }), - videoSwitcher.getAuxTimelineObject({ + context.uniformConfig.mixEffects.clean.auxLayer + ? context.videoSwitcher.getAuxTimelineObject({ + enable: { while: '1' }, + layer: context.uniformConfig.mixEffects.clean.auxLayer, + content: { + input: context.uniformConfig.mixEffects.clean.input + } + }) + : undefined, + context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, layer: SwitcherAuxLLayer.AuxScreen, content: { - input: config.studio.SwitcherSource.Loop + input: context.config.studio.SwitcherSource.Loop } }), literal({ @@ -627,7 +628,7 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche }), // keyers - ...createDskBaseline(config, videoSwitcher), + ...createDskBaseline(context.config, context.videoSwitcher), literal({ id: '', @@ -638,8 +639,8 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRCPROPS, ssrcProps: { - artFillSource: config.studio.SwitcherSource.SplitArtF, - artCutSource: config.studio.SwitcherSource.SplitArtK, + artFillSource: context.config.studio.SwitcherSource.SplitArtF, + artCutSource: context.config.studio.SwitcherSource.SplitArtK, artOption: 1, // foreground artPreMultiplied: true } @@ -658,7 +659,7 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche { // left enabled: true, - source: config.studio.SwitcherSource.SplitBackground, + source: context.config.studio.SwitcherSource.SplitBackground, size: 1000, x: 0, y: 0, @@ -759,7 +760,7 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: Object.keys(sisyfosChannels).map(key => { + channels: Object.keys(sisyfosChannels).map((key) => { const llayer = key as OfftubeSisyfosLLayer const channel = sisyfosChannels[llayer] as SisyfosChannel return literal({ @@ -773,18 +774,18 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche }), // Route ME 2 PGM to ME 1 PGM - videoSwitcher.getMixEffectTimelineObject({ + context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - layer: SwitcherMixEffectLLayer.Program, + layer: context.uniformConfig.mixEffects.program.mixEffectLayer, content: { - input: SpecialInput.ME2_PROGRAM + input: context.uniformConfig.mixEffects.clean.input } }), ...CreateLYDBaseline('offtube'), - ...(config.showStyle.CasparCGLoadingClip && config.showStyle.CasparCGLoadingClip.length - ? [...config.mediaPlayers.map(mp => CasparPlayerClipLoadingLoop(mp.id))].map(layer => { + ...(context.config.showStyle.CasparCGLoadingClip && context.config.showStyle.CasparCGLoadingClip.length + ? [...context.config.mediaPlayers.map((mp) => CasparPlayerClipLoadingLoop(mp.id))].map((layer) => { return literal({ id: '', enable: { while: '1' }, @@ -793,12 +794,12 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche content: { deviceType: TSR.DeviceType.CASPARCG, type: TSR.TimelineContentTypeCasparCg.MEDIA, - file: config.showStyle.CasparCGLoadingClip, + file: context.config.showStyle.CasparCGLoadingClip, loop: true } }) }) : []) - ] + ]) } } diff --git a/src/tv2_offtube_showstyle/helpers/config.ts b/src/tv2_offtube_showstyle/helpers/config.ts index 70979243..a790add0 100644 --- a/src/tv2_offtube_showstyle/helpers/config.ts +++ b/src/tv2_offtube_showstyle/helpers/config.ts @@ -40,7 +40,7 @@ export interface OfftubeShowStyleConfig extends TV2ShowstyleBlueprintConfigBase } export function preprocessConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { - const showstyleConfig = (rawConfig as unknown) as OfftubeShowStyleConfig + const showstyleConfig = rawConfig as unknown as OfftubeShowStyleConfig const selectedGfxSetup = findGfxSetup(context, showstyleConfig, { Name: '', HtmlPackageFolder: '' @@ -52,10 +52,10 @@ export function preprocessConfig(context: ICommonContext, rawConfig: IBlueprintC } export function getConfig(context: IShowStyleContext): OfftubeBlueprintConfig { - return ({ + return { ...(context.getStudioConfig() as any), ...(context.getShowStyleConfig() as any) - } as any) as OfftubeBlueprintConfig + } as any as OfftubeBlueprintConfig } export function getStudioConfig(context: IStudioContext): OfftubeBlueprintConfig { diff --git a/src/tv2_offtube_showstyle/migrations/hotkeys.ts b/src/tv2_offtube_showstyle/migrations/hotkeys.ts index 25c7771b..50350d0c 100644 --- a/src/tv2_offtube_showstyle/migrations/hotkeys.ts +++ b/src/tv2_offtube_showstyle/migrations/hotkeys.ts @@ -11,16 +11,16 @@ export function GetDefaultStudioSourcesForOfftube(context: MigrationContextShowS const dveLayoutConfig = context.getBaseConfig('DVEStyles') as TableConfigItemValue | undefined let dveLayouts: string[] = [] if (dveLayoutConfig?.length) { - dveLayouts = dveLayoutConfig.map(dve => dve.DVEName).filter(name => name !== undefined) as string[] + dveLayouts = dveLayoutConfig.map((dve) => dve.DVEName).filter((name) => name !== undefined) as string[] } else { dveLayouts = (dveStylesManifest as ConfigManifestEntryTable).defaultVal - .map(dve => dve.DVEName) - .filter(name => name !== undefined) as string[] + .map((dve) => dve.DVEName) + .filter((name) => name !== undefined) as string[] } - const camera = manifestOfftubeSourcesCam.defaultVal.map(source => source.SourceName) as string[] - const remote = manifestOfftubeSourcesRM.defaultVal.map(source => source.SourceName) as string[] - const feed = manifestOfftubeSourcesFeed.defaultVal.map(source => `F${source.SourceName}`) + const camera = manifestOfftubeSourcesCam.defaultVal.map((source) => source.SourceName) as string[] + const remote = manifestOfftubeSourcesRM.defaultVal.map((source) => source.SourceName) as string[] + const feed = manifestOfftubeSourcesFeed.defaultVal.map((source) => `F${source.SourceName}`) const local: string[] = [] return { diff --git a/src/tv2_offtube_showstyle/migrations/index.ts b/src/tv2_offtube_showstyle/migrations/index.ts index bce8c56a..fcb47eeb 100644 --- a/src/tv2_offtube_showstyle/migrations/index.ts +++ b/src/tv2_offtube_showstyle/migrations/index.ts @@ -147,7 +147,7 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ * 1.6.3 * - Hide DSK toggle layers */ - ...GetDSKSourceLayerNames(ATEMModel.PRODUCTION_STUDIO_4K_2ME).map(layerName => + ...GetDSKSourceLayerNames(ATEMModel.PRODUCTION_STUDIO_4K_2ME).map((layerName) => forceSourceLayerToDefaults('1.6.3', layerName) ), diff --git a/src/tv2_offtube_showstyle/migrations/util.ts b/src/tv2_offtube_showstyle/migrations/util.ts index 1cb248e3..0e7d452f 100644 --- a/src/tv2_offtube_showstyle/migrations/util.ts +++ b/src/tv2_offtube_showstyle/migrations/util.ts @@ -74,7 +74,7 @@ function remapTableColumnValuesInner( ): { changed: number; table: TableConfigItemValue } { let changed = 0 - table.forEach(row => { + table.forEach((row) => { const val = row[columnId] if (val) { diff --git a/src/tv2_offtube_showstyle/onTimelineGenerate.ts b/src/tv2_offtube_showstyle/onTimelineGenerate.ts index a64d0f0d..b71a3646 100644 --- a/src/tv2_offtube_showstyle/onTimelineGenerate.ts +++ b/src/tv2_offtube_showstyle/onTimelineGenerate.ts @@ -48,7 +48,7 @@ export function disableFirstPilotGFXAnimation( previousPartEndState: PartEndStateExt | undefined, resolvedPieces: IBlueprintResolvedPieceInstance[] ) { - const isFull = resolvedPieces.find(p => p.piece.tags?.includes(TallyTags.FULL_IS_LIVE)) + const isFull = resolvedPieces.find((p) => p.piece.tags?.includes(TallyTags.FULL_IS_LIVE)) for (const obj of timeline) { if ( obj.layer === SharedGraphicLLayer.GraphicLLayerPilot && diff --git a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts index ec22ec80..f063bc92 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts @@ -43,8 +43,8 @@ export async function CreatePartUnknown( part = { ...part, ...GetJinglePartProperties(context, partDefinition) } if ( - partDefinition.cues.some(cue => cue.type === CueType.Graphic && GraphicIsPilot(cue) && cue.target === 'FULL') && - !partDefinition.cues.filter(c => c.type === CueType.Jingle).length + partDefinition.cues.some((cue) => cue.type === CueType.Graphic && GraphicIsPilot(cue) && cue.target === 'FULL') && + !partDefinition.cues.filter((c) => c.type === CueType.Jingle).length ) { ApplyFullGraphicPropertiesToPart(context.config, part) } diff --git a/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts b/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts index 0e4b477c..bffd51f2 100644 --- a/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts @@ -41,7 +41,6 @@ const blankStudioConfig: OfftubeStudioConfig = { Dip: 0 }, AtemSettings: {}, - TriCasterSettings: {}, AudioBedSettings: { fadeIn: 0, fadeOut: 0, @@ -85,7 +84,7 @@ const blankStudioConfig: OfftubeStudioConfig = { function getObjectKeys(obj: any): string[] { const definedKeys: string[] = [] const processObj = (prefix: string, o: any) => { - _.each(_.keys(o), k => { + _.each(_.keys(o), (k) => { if (_.isArray(o[k])) { definedKeys.push(prefix + k) } else if (_.isObject(o[k])) { @@ -101,7 +100,7 @@ function getObjectKeys(obj: any): string[] { describe('Config Manifest', () => { test('Exposed Studio Keys', () => { - const studioManifestKeys = _.map(studioConfigManifest, e => e.id) + const studioManifestKeys = _.map(studioConfigManifest, (e) => e.id) const manifestKeys = studioManifestKeys.concat(CORE_INJECTED_KEYS).sort() const definedKeys = getObjectKeys(blankStudioConfig) diff --git a/src/tv2_offtube_studio/__tests__/migrations-defaults.spec.ts b/src/tv2_offtube_studio/__tests__/migrations-defaults.spec.ts index 0e507a15..4b466035 100644 --- a/src/tv2_offtube_studio/__tests__/migrations-defaults.spec.ts +++ b/src/tv2_offtube_studio/__tests__/migrations-defaults.spec.ts @@ -1,14 +1,26 @@ import { AbstractLLayerServerEnable, + ATEM_LAYER_PREFIX, CasparPlayerClip, CasparPlayerClipLoadingLoop, - GetDSKMappingNames + getUsedLayers } from 'tv2-common' +import { AbstractLLayer, SharedGraphicLLayer } from 'tv2-constants' import * as _ from 'underscore' -import { ATEMModel } from '../../types/atem' +import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../layers' -import { RealLLayers } from '../layers' import MappingsDefaults from '../migrations/mappings-defaults' +import { QBOX_UNIFORM_CONFIG } from '../uniformConfig' + +/** Get all the Real LLayers (map to devices). Note: Does not include some which are dynamically generated */ +export function getRealLLayers(): string[] { + return getUsedLayers(QBOX_UNIFORM_CONFIG) + .flatMap((layer) => [ATEM_LAYER_PREFIX + layer]) + .concat(_.values(OfftubeSisyfosLLayer)) + .concat(_.values(OfftubeCasparLLayer)) + .concat(_.values(AbstractLLayer)) + .concat(_.values(SharedGraphicLLayer)) +} describe('Migration Defaults', () => { test('MappingsDefaults', () => { @@ -22,7 +34,7 @@ describe('Migration Defaults', () => { }).sort() // Inject core_abstract as it is required by core and so needs to be defined - const layerIds = RealLLayers() + const layerIds = getRealLLayers() .concat(['core_abstract']) .concat([ CasparPlayerClip(1), @@ -30,11 +42,10 @@ describe('Migration Defaults', () => { CasparPlayerClipLoadingLoop(1), CasparPlayerClipLoadingLoop(2), AbstractLLayerServerEnable(1), - AbstractLLayerServerEnable(2), - ...GetDSKMappingNames(ATEMModel.PRODUCTION_STUDIO_4K_2ME) + AbstractLLayerServerEnable(2) ]) .sort() - expect(defaultsIds).toEqual(layerIds) + expect(defaultsIds).toEqual(expect.arrayContaining(layerIds)) }) }) diff --git a/src/tv2_offtube_studio/getBaseline.ts b/src/tv2_offtube_studio/getBaseline.ts index 43169d1b..56e90e05 100644 --- a/src/tv2_offtube_studio/getBaseline.ts +++ b/src/tv2_offtube_studio/getBaseline.ts @@ -5,8 +5,7 @@ import { IStudioContext, TSR } from 'blueprints-integration' -import { ExtendedStudioContext, literal, SpecialInput, TransitionStyle } from 'tv2-common' -import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' +import { ExtendedStudioContext, literal, TransitionStyle } from 'tv2-common' import * as _ from 'underscore' import { OfftubeStudioBlueprintConfig } from './helpers/config' import { OfftubeSisyfosLLayer } from './layers' @@ -19,7 +18,7 @@ function filterMappings( ): BlueprintMappings { const result: BlueprintMappings = {} - _.each(_.keys(input), k => { + _.each(_.keys(input), (k) => { const v = input[k] if (filter(k, v)) { result[k] = v @@ -57,7 +56,7 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin } return { - timelineObjects: [ + timelineObjects: _.compact([ literal({ id: '', enable: { @@ -76,7 +75,7 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin // have ATEM output default still image context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - layer: SwitcherMixEffectLLayer.Clean, + layer: context.uniformConfig.mixEffects.clean.mixEffectLayer, content: { input: context.config.studio.IdleSource, transition: TransitionStyle.CUT @@ -86,18 +85,20 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin // Route ME 2 PGM to ME 1 PGM context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, - layer: SwitcherMixEffectLLayer.Program, + layer: context.uniformConfig.mixEffects.program.mixEffectLayer, content: { - input: SpecialInput.ME2_PROGRAM + input: context.uniformConfig.mixEffects.clean.input } }), - context.videoSwitcher.getAuxTimelineObject({ - enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxClean, - content: { - input: SpecialInput.ME2_PROGRAM - } - }) - ] + context.uniformConfig.mixEffects.clean.auxLayer + ? context.videoSwitcher.getAuxTimelineObject({ + enable: { while: '1' }, + layer: context.uniformConfig.mixEffects.clean.auxLayer, + content: { + input: context.uniformConfig.mixEffects.clean.input + } + }) + : undefined + ]) } } diff --git a/src/tv2_offtube_studio/helpers/config.ts b/src/tv2_offtube_studio/helpers/config.ts index 0466721f..6b453be1 100644 --- a/src/tv2_offtube_studio/helpers/config.ts +++ b/src/tv2_offtube_studio/helpers/config.ts @@ -36,7 +36,6 @@ export interface OfftubeStudioConfig extends TV2StudioConfigBase { } AtemSettings: {} - TriCasterSettings: {} AudioBedSettings: { fadeIn: number @@ -50,7 +49,7 @@ export interface OfftubeStudioConfig extends TV2StudioConfigBase { } export function preprocessConfig(_context: ICommonContext, rawConfig: IBlueprintConfig): OfftubeStudioBlueprintConfig { - const studioConfig = (rawConfig as unknown) as OfftubeStudioConfig + const studioConfig = rawConfig as unknown as OfftubeStudioConfig const config: OfftubeStudioBlueprintConfig = { studio: rawConfig as any, // showStyle: {} as any, diff --git a/src/tv2_offtube_studio/helpers/sources.ts b/src/tv2_offtube_studio/helpers/sources.ts index 774dd7d0..8da41934 100644 --- a/src/tv2_offtube_studio/helpers/sources.ts +++ b/src/tv2_offtube_studio/helpers/sources.ts @@ -5,7 +5,7 @@ import { ParseMappingTable, SourceInfoType, SourceMapping } from 'tv2-common' import { OfftubeStudioConfig } from './config' export function parseMediaPlayers(studioConfig: OfftubeStudioConfig): Array<{ id: string; val: string }> { - return studioConfig.ABMediaPlayers.map(player => ({ id: player.SourceName, val: player.SwitcherSource.toString() })) + return studioConfig.ABMediaPlayers.map((player) => ({ id: player.SourceName, val: player.SwitcherSource.toString() })) } export function parseSources(studioConfig: OfftubeStudioConfig): SourceMapping { diff --git a/src/tv2_offtube_studio/layers.ts b/src/tv2_offtube_studio/layers.ts index 1042cd60..1f1ff004 100644 --- a/src/tv2_offtube_studio/layers.ts +++ b/src/tv2_offtube_studio/layers.ts @@ -1,19 +1,6 @@ -import { AbstractLLayer, SharedCasparLLayer, SharedGraphicLLayer, SharedSisyfosLLayer } from 'tv2-constants' +import { SharedCasparLLayer, SharedGraphicLLayer, SharedSisyfosLLayer } from 'tv2-constants' import * as _ from 'underscore' -/** Get all the Real LLayers (map to devices). Note: Does not include some which are dynamically generated */ -export function RealLLayers(): string[] { - return ( - _.values(OfftubeSisyfosLLayer) - // @ts-ignore - .concat(_.values(OfftubeCasparLLayer)) - // @ts-ignore - .concat(_.values(AbstractLLayer)) - // @ts-ignore - .concat(_.values(SharedGraphicLLayer)) - ) -} - enum SisyfosLLayer { SisyfosConfig = 'sisyfos_config', SisyfosGroupServer = 'sisyfos_group_server', diff --git a/src/tv2_offtube_studio/migrations/devices.ts b/src/tv2_offtube_studio/migrations/devices.ts index dbf81e31..53f3d1e4 100644 --- a/src/tv2_offtube_studio/migrations/devices.ts +++ b/src/tv2_offtube_studio/migrations/devices.ts @@ -102,7 +102,7 @@ const devices: DeviceEntry[] = [ id: 'caspar01', firstVersion: '0.1.0', type: TSR.DeviceType.CASPARCG, - defaultValue: input => ({ + defaultValue: (input) => ({ type: TSR.DeviceType.CASPARCG, options: { host: input.host, @@ -120,7 +120,7 @@ const devices: DeviceEntry[] = [ defaultValue: undefined } ], - validate: device => { + validate: (device) => { if (!device.options) { return 'Missing options' } @@ -159,7 +159,7 @@ const devices: DeviceEntry[] = [ } return undefined }, - validate: device => { + validate: (device) => { if (!device.options) { return 'Missing options' } @@ -186,7 +186,7 @@ const devices: DeviceEntry[] = [ id: 'atem0', firstVersion: '0.1.0', type: TSR.DeviceType.ATEM, - defaultValue: input => ({ + defaultValue: (input) => ({ type: TSR.DeviceType.ATEM, options: { host: input.host, @@ -202,7 +202,7 @@ const devices: DeviceEntry[] = [ defaultValue: undefined } ], - validate: device => { + validate: (device) => { if (!device.options) { return 'Missing options' } diff --git a/src/tv2_offtube_studio/migrations/index.ts b/src/tv2_offtube_studio/migrations/index.ts index 222f171c..c5e53a8f 100644 --- a/src/tv2_offtube_studio/migrations/index.ts +++ b/src/tv2_offtube_studio/migrations/index.ts @@ -1,10 +1,12 @@ import { MigrationContextStudio, MigrationStepStudio, TableConfigItemValue, TSR } from 'blueprints-integration' import { AddKeepAudio, + convertStudioTableColumnToFloat, MoveClipSourcePath, MoveSourcesToTable, RemoveConfig, - RenameStudioConfig, + renameStudioConfig, + renameStudioTableColumn, SetConfigTo, SetLayerNamesToDefaults } from 'tv2-common' @@ -97,7 +99,7 @@ function remapTableColumnValuesInner( ): { changed: number; table: TableConfigItemValue } { let changed = 0 - table.forEach(row => { + table.forEach((row) => { const val = row[columnId] if (val) { @@ -263,38 +265,38 @@ export const studioMigrations: MigrationStepStudio[] = [ 'sisyfos_source_live_3', 'sisyfos_source_server_a', 'sisyfos_source_server_b' - ].map(layer => EnsureSisyfosMappingHasType('1.3.0', layer, TSR.MappingSisyfosType.CHANNEL)), + ].map((layer) => EnsureSisyfosMappingHasType('1.3.0', layer, TSR.MappingSisyfosType.CHANNEL)), GetMappingDefaultMigrationStepForLayer('1.3.0', OfftubeSisyfosLLayer.SisyfosConfig), GetMappingDefaultMigrationStepForLayer('1.3.0', OfftubeSisyfosLLayer.SisyfosGroupStudioMics), GetMappingDefaultMigrationStepForLayer('1.4.0', OfftubeCasparLLayer.CasparPlayerClipPending, true), GetMappingDefaultMigrationStepForLayer('1.4.5', OfftubeCasparLLayer.CasparPlayerClipPending, true), - RenameStudioConfig('1.4.6', 'Offtube', 'MediaFlowId', 'ClipMediaFlowId'), - RenameStudioConfig('1.4.6', 'Offtube', 'NetworkBasePath', 'NetworkBasePathClip'), - RenameStudioConfig('1.4.6', 'Offtube', 'JingleBasePath', 'NetworkBasePathJingle'), - RenameStudioConfig('1.4.6', 'Offtube', 'GraphicBasePath', 'NetworkBasePathGraphic'), - RenameStudioConfig('1.4.6', 'Offtube', 'GraphicFlowId', 'GraphicMediaFlowId'), + renameStudioConfig('1.4.6', 'Offtube', 'MediaFlowId', 'ClipMediaFlowId'), + renameStudioConfig('1.4.6', 'Offtube', 'NetworkBasePath', 'NetworkBasePathClip'), + renameStudioConfig('1.4.6', 'Offtube', 'JingleBasePath', 'NetworkBasePathJingle'), + renameStudioConfig('1.4.6', 'Offtube', 'GraphicBasePath', 'NetworkBasePathGraphic'), + renameStudioConfig('1.4.6', 'Offtube', 'GraphicFlowId', 'GraphicMediaFlowId'), -// GetMappingDefaultMigrationStepForLayer('1.4.8', 'casparcg_player_jingle_looakhead', true), + GetMappingDefaultMigrationStepForLayer('1.4.8', 'casparcg_player_jingle_looakhead', true), - RenameStudioConfig('1.5.0', 'Offtube', 'NetworkBasePathJingle', 'JingleNetworkBasePath'), - RenameStudioConfig('1.5.0', 'Offtube', 'NetworkBasePathClip', 'ClipNetworkBasePath'), - RenameStudioConfig('1.5.0', 'Offtube', 'NetworkBasePathGraphic', 'GraphicNetworkBasePath'), - RenameStudioConfig('1.5.0', 'Offtube', 'FullGraphicURL', 'HTMLGraphics.GraphicURL'), - RenameStudioConfig('1.5.0', 'Offtube', 'FullKeepAliveDuration', 'HTMLGraphics.KeepAliveDuration'), - RenameStudioConfig( + renameStudioConfig('1.5.0', 'Offtube', 'NetworkBasePathJingle', 'JingleNetworkBasePath'), + renameStudioConfig('1.5.0', 'Offtube', 'NetworkBasePathClip', 'ClipNetworkBasePath'), + renameStudioConfig('1.5.0', 'Offtube', 'NetworkBasePathGraphic', 'GraphicNetworkBasePath'), + renameStudioConfig('1.5.0', 'Offtube', 'FullGraphicURL', 'HTMLGraphics.GraphicURL'), + renameStudioConfig('1.5.0', 'Offtube', 'FullKeepAliveDuration', 'HTMLGraphics.KeepAliveDuration'), + renameStudioConfig( '1.5.0', 'Offtube', 'FullTransitionSettings.borderSoftness', 'HTMLGraphics.TransitionSettings.borderSoftness' ), - RenameStudioConfig( + renameStudioConfig( '1.5.0', 'Offtube', 'FullTransitionSettings.loopOutTransitionDuration', 'HTMLGraphics.TransitionSettings.loopOutTransitionDuration' ), - RenameStudioConfig('1.5.0', 'Offtube', 'FullTransitionSettings.wipeRate', 'HTMLGraphics.TransitionSettings.wipeRate'), + renameStudioConfig('1.5.0', 'Offtube', 'FullTransitionSettings.wipeRate', 'HTMLGraphics.TransitionSettings.wipeRate'), removeMapping('1.5.0', 'casparcg_studio_screen_loop'), removeMapping('1.5.0', 'casparcg_graphics_overlay'), @@ -346,7 +348,7 @@ export const studioMigrations: MigrationStepStudio[] = [ */ GetMappingDefaultMigrationStepForLayer('1.6.10', OfftubeCasparLLayer.CasparCGLYD, true), - RenameStudioConfig('1.6.11', 'Offtube', 'SourcesRM.KeepAudioInStudio', 'SourcesRM.WantsToPersistAudio'), + renameStudioConfig('1.6.11', 'Offtube', 'SourcesRM.KeepAudioInStudio', 'SourcesRM.WantsToPersistAudio'), /** * 1.7.3 @@ -365,6 +367,16 @@ export const studioMigrations: MigrationStepStudio[] = [ removeMapping('1.7.8', 'graphic_pilot_overlay'), GetMappingDefaultMigrationStepForLayer('1.7.8', 'graphic_overlay_pilot', true), + /** + * 1.8.0 + */ + ...['SourcesCam', 'SourcesRM', 'SourcesReplay', 'SourcesFeed', 'ABMediaPlayers'].map((tableName) => + renameStudioTableColumn('1.8.0', tableName, 'AtemSource', 'SwitcherSource') + ), + renameStudioConfig('1.8.0', 'AFVD', 'AtemSource', 'SwitcherSource'), + convertStudioTableColumnToFloat('1.8.0', 'SwitcherSource.DSK', 'Clip'), + convertStudioTableColumnToFloat('1.8.0', 'SwitcherSource.DSK', 'Gain'), + // Fill in any mappings that did not exist before // Note: These should only be run as the very final step of all migrations. otherwise they will add items too early, and confuse old migrations ...getMappingsDefaultsMigrationSteps(VERSION) diff --git a/src/tv2_offtube_studio/uniformConfig.ts b/src/tv2_offtube_studio/uniformConfig.ts index 4fc962c5..1bdb86e3 100644 --- a/src/tv2_offtube_studio/uniformConfig.ts +++ b/src/tv2_offtube_studio/uniformConfig.ts @@ -1,9 +1,9 @@ -import { SpecialInput, UniformConfig } from 'tv2-common' +import { getSpecialLayers, SpecialInput, UniformConfig } from 'tv2-common' import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' -const MIX_EFFECTS: UniformConfig['MixEffects'] = { - Program: { input: SpecialInput.ME1_PROGRAM, mixEffectLayer: SwitcherMixEffectLLayer.Program }, - Clean: { +const MIX_EFFECTS: UniformConfig['mixEffects'] = { + program: { input: SpecialInput.ME1_PROGRAM, mixEffectLayer: SwitcherMixEffectLLayer.Program }, + clean: { input: SpecialInput.ME4_PROGRAM, mixEffectLayer: SwitcherMixEffectLLayer.Clean, auxLayer: SwitcherAuxLLayer.AuxClean @@ -11,18 +11,14 @@ const MIX_EFFECTS: UniformConfig['MixEffects'] = { } export const QBOX_UNIFORM_CONFIG: UniformConfig = { - SwitcherLLayers: { - PrimaryMixEffect: SwitcherMixEffectLLayer.Clean, - NextServerAux: SwitcherAuxLLayer.AuxServerLookahead, - NextPreviewMixEffect: SwitcherMixEffectLLayer.Next, - JingleNextMixEffect: SwitcherMixEffectLLayer.NextJingle + switcherLLayers: { + primaryMixEffect: SwitcherMixEffectLLayer.Clean, + nextServerAux: SwitcherAuxLLayer.AuxServerLookahead, + nextPreviewMixEffect: SwitcherMixEffectLLayer.Next, + jingleNextMixEffect: SwitcherMixEffectLLayer.NextJingle }, - MixEffects: MIX_EFFECTS, - SpecialInputAuxLLayers: { - ...Object.fromEntries( - Object.values(MIX_EFFECTS) - .filter(mixEffect => mixEffect.auxLayer) - .map(mixEffect => [mixEffect.input, mixEffect.auxLayer]) - ) + mixEffects: MIX_EFFECTS, + specialInputAuxLLayers: { + ...getSpecialLayers(MIX_EFFECTS) } } diff --git a/src/tv2_system/migrations/hotkeys.ts b/src/tv2_system/migrations/hotkeys.ts index 787f4416..9389aa11 100644 --- a/src/tv2_system/migrations/hotkeys.ts +++ b/src/tv2_system/migrations/hotkeys.ts @@ -8,7 +8,7 @@ import { } from 'blueprints-integration' export function RemoveDefaultCoreShortcuts(versionStr: string): MigrationStepSystem { - const defaultTriggerIds = DEFAULT_CORE_TRIGGERS.map(trigger => trigger._id) + const defaultTriggerIds = DEFAULT_CORE_TRIGGERS.map((trigger) => trigger._id) return { id: `${versionStr}.disableCoreDefaultTriggers`, diff --git a/yarn.lock b/yarn.lock index 7b0155bd..6b3774a8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4938,10 +4938,10 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prettier@^1.18.2: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== +prettier@^2.0.0: + version "2.8.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.4.tgz#34dd2595629bfbb79d344ac4a91ff948694463c3" + integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw== pretty-format@^27.0.0, pretty-format@^27.5.1: version "27.5.1" From 352f5c7af4aa1fc36eed9e54430d436968c5bfd6 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Fri, 24 Feb 2023 07:49:41 +0100 Subject: [PATCH 29/86] SOF-1264 getRundown now uses VideoSwitcher to create DVE timelineObjects instead of hardcoding ATEM objects --- src/tv2_afvd_showstyle/getRundown.ts | 91 ++++++++++--------------- src/tv2_offtube_showstyle/getRundown.ts | 80 +++++++++------------- 2 files changed, 68 insertions(+), 103 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 91d79aa1..0c9bc186 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -55,7 +55,6 @@ import { SharedOutputLayers, SourceType, SwitcherAuxLLayer, - SwitcherDveLLayer, SwitcherMixEffectLLayer, TallyTags } from 'tv2-constants' @@ -920,61 +919,45 @@ function getBaseline( ] } }), - literal({ - id: '', - enable: { while: '1' }, - priority: 0, - layer: SwitcherDveLLayer.Dve, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.SSRCPROPS, - ssrcProps: { - artFillSource: context.config.studio.SwitcherSource.SplitArtFill, - artCutSource: context.config.studio.SwitcherSource.SplitArtKey, - artOption: 1, - artPreMultiplied: true - } - } - }), - literal({ - id: '', + ...videoSwitcher.getDveTimelineObjects({ enable: { while: '1' }, - priority: 0, - layer: SwitcherDveLLayer.DveBoxes, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.SSRC, - ssrc: { - boxes: [ - { - // left - enabled: true, - source: AtemSourceIndex.Bars, - size: 580, - x: -800, - y: 50, - cropped: true, - cropRight: 2000 - }, - { - // right - enabled: true, - source: AtemSourceIndex.Bars, - size: 580, - x: 800, - y: 50 - // note: this sits behind box1, so don't crop it to ensure there is no gap between - }, - { - // box 3 - enabled: false - }, - { - // box 4 - enabled: false - } - ] - } + boxes: [ + { + // left + enabled: true, + source: AtemSourceIndex.Bars, + size: 580, + x: -800, + y: 50, + cropped: true, + cropRight: 2000 + }, + { + // right + enabled: true, + source: AtemSourceIndex.Bars, + size: 580, + x: 800, + y: 50 + // note: this sits behind box1, so don't crop it to ensure there is no gap between + }, + { + // box 3 + enabled: false + }, + { + // box 4 + enabled: false + } + ], + template: { + properties: { + artPreMultiplied: true + } + }, + artFillSource: context.config.studio.SwitcherSource.SplitArtFill, + artCutSource: context.config.studio.SwitcherSource.SplitArtKey } }), literal({ diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 159d6870..284d244f 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -56,7 +56,6 @@ import { SharedSourceLayers, SourceType, SwitcherAuxLLayer, - SwitcherDveLLayer, SwitcherMixEffectLLayer, TallyTags } from 'tv2-constants' @@ -628,56 +627,39 @@ function getBaseline(config: OfftubeBlueprintConfig, videoSwitcher: VideoSwitche // keyers ...CreateDSKBaseline(config, videoSwitcher), - - literal({ - id: '', + ...videoSwitcher.getDveTimelineObjects({ enable: { while: '1' }, - priority: 0, - layer: SwitcherDveLLayer.Dve, content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.SSRCPROPS, - ssrcProps: { - artFillSource: config.studio.SwitcherSource.SplitArtFill, - artCutSource: config.studio.SwitcherSource.SplitArtKey, - artOption: 1, // foreground - artPreMultiplied: true - } - } - }), - literal({ - id: '', - enable: { while: '1' }, - priority: 0, - layer: SwitcherDveLLayer.DveBoxes, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.SSRC, - ssrc: { - boxes: [ - { - // left - enabled: true, - source: config.studio.SwitcherSource.SplitBackground, - size: 1000, - x: 0, - y: 0, - cropped: false - }, - { - // right - enabled: false - }, - { - // box 3 - enabled: false - }, - { - // box 4 - enabled: false - } - ] - } + boxes: [ + { + // left + enabled: true, + source: config.studio.SwitcherSource.SplitBackground, + size: 1000, + x: 0, + y: 0, + cropped: false + }, + { + // right + enabled: false + }, + { + // box 3 + enabled: false + }, + { + // box 4 + enabled: false + } + ], + template: { + properties: { + artPreMultiplied: true + } + }, + artFillSource: config.studio.SwitcherSource.SplitArtFill, + artCutSource: config.studio.SwitcherSource.SplitArtKey } }), literal({ From b297350985b89683f984f2582b6d8b1b22bbae2c Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Fri, 24 Feb 2023 08:18:23 +0100 Subject: [PATCH 30/86] SOF-1264 Fix wrong imports --- src/tv2-common/videoSwitchers/TriCasterDveConverter.ts | 2 +- src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/videoSwitchers/TriCasterDveConverter.ts b/src/tv2-common/videoSwitchers/TriCasterDveConverter.ts index c4d36cd3..2489209c 100644 --- a/src/tv2-common/videoSwitchers/TriCasterDveConverter.ts +++ b/src/tv2-common/videoSwitchers/TriCasterDveConverter.ts @@ -1,4 +1,4 @@ -import { TSR } from '../../../../tv-automation-server-core/packages/blueprints-integration' +import { TSR } from 'blueprints-integration' export interface TriCasterDveConverter { convertPosition(x: number, y: number): TSR.TriCasterLayer['position'] diff --git a/src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts b/src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts index d6de02a5..fb560722 100644 --- a/src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts +++ b/src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts @@ -1,4 +1,4 @@ -import { TSR } from '../../../../tv-automation-server-core/packages/blueprints-integration/src' +import { TSR } from 'blueprints-integration' import { TriCasterDveConverter } from './TriCasterDveConverter' const ATEM_WIDTH = 32 From 9d32de94d1b145eee7ff59f14ee73bd74b58b1a9 Mon Sep 17 00:00:00 2001 From: ianshade Date: Fri, 24 Feb 2023 08:29:23 +0100 Subject: [PATCH 31/86] wip: SOF-1260 refactor and remove leftovers --- src/__mocks__/context.ts | 7 ------- src/tv2-common/helpers/dsk.ts | 9 +++------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index bf4bb8aa..af3cd130 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -646,13 +646,6 @@ export interface PartNote { message: string } -// @ts-ignore -class MockVideoSwitcher implements VideoSwitcher { - public getMixEffectTimelineObject = (properties: MixEffectProps) => properties as any as TSR.TSRTimelineObj - public getDskTimelineObjects = (properties: DskProps) => [properties] as any as TSR.TSRTimelineObj[] - public getAuxTimelineObject = (properties: AuxProps) => properties as any as TSR.TSRTimelineObj -} - export interface MockConfigOverrides { studioConfig?: Partial showStyleConfig?: Partial diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index fbeaf5ed..ec314073 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -47,11 +47,10 @@ export function getDskOnAirTimelineObjects( enable?: TSR.TSRTimelineObj['enable'] ): TSR.TSRTimelineObj[] { const dskConf = FindDSKWithRoles(context.config, [dskRole]) + enable = enable ?? { start: 0 } return [ context.videoSwitcher.getDskTimelineObject({ - enable: enable ?? { - start: 0 - }, + enable, priority: 1, layer: getDskLLayerName(dskConf.Number), content: { @@ -62,9 +61,7 @@ export function getDskOnAirTimelineObjects( ...(dskRole === DSKRoles.JINGLE && context.uniformConfig.switcherLLayers.jingleUskMixEffect ? [ context.videoSwitcher.getMixEffectTimelineObject({ - enable: enable ?? { - start: 0 - }, + enable, priority: 1, layer: context.uniformConfig.switcherLLayers.jingleUskMixEffect, content: { From e4d9f05cb36a5de4abc3d26e7c034bf1406b8df4 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Mon, 27 Feb 2023 08:46:20 +0100 Subject: [PATCH 32/86] SOF-1264 Tests for TriCaster DVE --- jest.config.js | 2 +- package.json | 3 +- src/tv2-common/videoSwitchers/TriCaster.ts | 17 +- .../videoSwitchers/VideoSwitcher.ts | 3 +- .../AtemToTricasterDveConverter.spec.ts | 199 +++++++++++++++ .../__tests__/TriCaster.spec.ts | 237 +++++++++++++----- tsconfig.test.json | 7 + yarn.lock | 9 +- 8 files changed, 412 insertions(+), 65 deletions(-) create mode 100644 src/tv2-common/videoSwitchers/__tests__/AtemToTricasterDveConverter.spec.ts create mode 100644 tsconfig.test.json diff --git a/jest.config.js b/jest.config.js index 03c247db..5ba160cd 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,7 +1,7 @@ module.exports = { globals: { 'ts-jest': { - tsconfig: 'tsconfig.json', + tsconfig: 'tsconfig.test.json', }, }, moduleFileExtensions: [ diff --git a/package.json b/package.json index b6227d1a..0300d137 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,8 @@ }, "dependencies": { "@sofie-automation/blueprints-integration": "npm:@tv2media/blueprints-integration@46.1.1", - "underscore": "^1.12.1" + "underscore": "^1.12.1", + "ts-mockito": "^2.6.1" }, "resolutions": { "moment": "^2.29.2" diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index d23c8cad..5fbe8f80 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -1,9 +1,8 @@ -import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' -import { literal, TimeFromFrames } from 'tv2-common' +import { IStudioContext, TimelineObjectCoreExt, TSR } from 'blueprints-integration' +import { literal, TimeFromFrames, TV2StudioConfig, UniformConfig } from 'tv2-common' import { SwitcherDveLLayer } from 'tv2-constants' import _ = require('underscore') import { TRICASTER_DVE_ME, TRICASTER_LAYER_PREFIX } from '../layers' -import { AtemToTricasterDveConverter } from './atemToTricasterDveConverter' import { TriCasterDveConverter } from './TriCasterDveConverter' import { AuxProps, @@ -50,7 +49,17 @@ export class TriCaster extends VideoSwitcherImpl { public isAux = TSR.isTimelineObjTriCasterMixOutput public isVideoSwitcherTimelineObject = TSR.isTimelineObjTriCaster - private dveConverter: TriCasterDveConverter = new AtemToTricasterDveConverter() + private dveConverter: TriCasterDveConverter + + constructor( + core: IStudioContext, + config: TV2StudioConfig, + uniformConfig: UniformConfig, + dveConverter: TriCasterDveConverter + ) { + super(core, config, uniformConfig) + this.dveConverter = dveConverter + } public getMixEffectTimelineObject(props: MixEffectProps): TSR.TimelineObjTriCasterME { const { content } = props diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts index 86bb9d89..0477b1e0 100644 --- a/src/tv2-common/videoSwitchers/VideoSwitcher.ts +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -15,6 +15,7 @@ import { VideoSwitcher } from 'tv2-common' import _ = require('underscore') +import { AtemToTricasterDveConverter } from './atemToTricasterDveConverter' export abstract class VideoSwitcherImpl implements VideoSwitcher { public static getVideoSwitcher( @@ -24,7 +25,7 @@ export abstract class VideoSwitcherImpl implements VideoSwitcher { ): VideoSwitcherImpl { return config.studio.SwitcherType === SwitcherType.ATEM ? new Atem(core, config, uniformConfig) - : new TriCaster(core, config, uniformConfig) + : new TriCaster(core, config, uniformConfig, new AtemToTricasterDveConverter()) } public abstract readonly type: SwitcherType public abstract isDsk: (timelineObject: TimelineObjectCoreExt) => boolean diff --git a/src/tv2-common/videoSwitchers/__tests__/AtemToTricasterDveConverter.spec.ts b/src/tv2-common/videoSwitchers/__tests__/AtemToTricasterDveConverter.spec.ts new file mode 100644 index 00000000..13af4282 --- /dev/null +++ b/src/tv2-common/videoSwitchers/__tests__/AtemToTricasterDveConverter.spec.ts @@ -0,0 +1,199 @@ +import { TSR } from '../../../../../tv-automation-server-core/packages/blueprints-integration/src' +import { AtemToTricasterDveConverter } from '../atemToTricasterDveConverter' + +describe('AtemToTricasterDveConverter', () => { + describe('convertPosition', () => { + it('receives x 800, x is set to 0.888', () => { + testConvertPositionX(800, 0.888) + }) + + function testConvertPositionX(testValue: number, expectedResult: number): void { + const testee = new AtemToTricasterDveConverter() + const result: TSR.TriCasterLayer['position'] = testee.convertPosition(testValue, 0) + expect(result!.x).toBeCloseTo(expectedResult, 2) + } + + it('receives x -800, x is set to -0.888', () => { + testConvertPositionX(-800, -0.888) + }) + + it('receives x 800, x is set to 0.888', () => { + testConvertPositionX(0, 0) + }) + + it('receives x 1055, x is set to 1.172', () => { + testConvertPositionX(1055, 1.172) + }) + + it('receives x -1055, x is set to -1.172', () => { + testConvertPositionX(-1055, -1.172) + }) + + it('receives x 500, x is set to 0.555', () => { + testConvertPositionX(500, 0.555) + }) + + it('receives x -500, x is set to -0.555', () => { + testConvertPositionX(-500, -0.555) + }) + + it('receives x 460, x is set to 0.511', () => { + testConvertPositionX(460, 0.511) + }) + + it('receives x -460, x is set to -0.511', () => { + testConvertPositionX(-460, -0.511) + }) + + it('receives y 100, y is set to -0.111', () => { + testConvertPositionY(100, -0.111) + }) + + function testConvertPositionY(testValue: number, expectedResult: number): void { + const testee = new AtemToTricasterDveConverter() + const result: TSR.TriCasterLayer['position'] = testee.convertPosition(0, testValue) + expect(result!.y).toBeCloseTo(expectedResult, 2) + } + + it('receives y -100, y is set to 0.111', () => { + testConvertPositionY(-100, 0.111) + }) + + it('receives y 0, y is set to 0', () => { + testConvertPositionY(0, 0) + }) + + it('receives y 400, y is set to -0.444', () => { + testConvertPositionY(400, -0.444) + }) + + it('receives y -400, y is set to 0.444', () => { + testConvertPositionY(-400, 0.444) + }) + + it('receives y 360, y is set to -0.4', () => { + testConvertPositionY(360, -0.4) + }) + + it('receives y -360, y is set to 0.4', () => { + testConvertPositionY(-360, 0.4) + }) + + it('receives y 250, y is set to -0.277', () => { + testConvertPositionY(250, -0.277) + }) + + it('receives y -250, y is set to 0.277', () => { + testConvertPositionY(-250, 0.277) + }) + }) + + describe('convertScale', () => { + it('receives values 1000, x and y is 1', () => { + testConvertScale(1000, 1) + }) + + function testConvertScale(testValue: number, expectedResult: number): void { + const testee = new AtemToTricasterDveConverter() + const result: TSR.TriCasterLayer['scale'] = testee.convertScale(testValue)! + expect(result.x).toBe(expectedResult) + expect(result.y).toBe(expectedResult) + } + + it('receives values 500, x and y is 0.5', () => { + testConvertScale(500, 0.5) + }) + + it('receives values 333, x and y is 0.333', () => { + testConvertScale(333, 0.333) + }) + + it('receives values 0, x and y is 0', () => { + testConvertScale(0, 0) + }) + }) + + describe('convertCrop', () => { + it('has cropped set to false, return 0 for all', () => { + const testee = new AtemToTricasterDveConverter() + const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(false, 12, 12, 12, 12))! + expect(result.up).toBe(0) + expect(result.down).toBe(0) + expect(result.left).toBe(0) + expect(result.right).toBe(0) + }) + + function createCropObject( + cropped: boolean, + cropTop: number, + cropBottom: number, + cropLeft: number, + cropRight: number + ) { + return { + cropped, + cropTop, + cropBottom, + cropLeft, + cropRight + } + } + + it('has cropped set to true, but no values, return 0 for all', () => { + const testee = new AtemToTricasterDveConverter() + const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 0, 0, 0))! + expect(result.up).toBe(0) + expect(result.down).toBe(0) + expect(result.left).toBe(0) + expect(result.right).toBe(0) + }) + + it('has crop top 100, return crop up 0.555', () => { + const testee = new AtemToTricasterDveConverter() + const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 100, 0, 0, 0))! + expect(result.up).toBeCloseTo(0.555) + }) + + it('has crop top 8500, return crop up 47.222', () => { + const testee = new AtemToTricasterDveConverter() + const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 8500, 0, 0, 0))! + expect(result.up).toBeCloseTo(47.222) + }) + + it('has crop bottom 100, return crop down 0.555', () => { + const testee = new AtemToTricasterDveConverter() + const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 100, 0, 0))! + expect(result.down).toBeCloseTo(0.555) + }) + + it('has crop bottom 8500, return crop down 47.222', () => { + const testee = new AtemToTricasterDveConverter() + const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 8500, 0, 0))! + expect(result.down).toBeCloseTo(47.222) + }) + + it('has crop left 100, return crop left 0.312', () => { + const testee = new AtemToTricasterDveConverter() + const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 0, 100, 0))! + expect(result.left).toBeCloseTo(0.312) + }) + + it('has crop left 6200, return crop left 19.375', () => { + const testee = new AtemToTricasterDveConverter() + const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 0, 6200, 0))! + expect(result.left).toBeCloseTo(19.375) + }) + + it('has crop right 100, return crop right 0.312', () => { + const testee = new AtemToTricasterDveConverter() + const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 0, 0, 100))! + expect(result.right).toBeCloseTo(0.312) + }) + + it('has crop right 6200, return crop right 19.375', () => { + const testee = new AtemToTricasterDveConverter() + const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 0, 0, 6200))! + expect(result.right).toBeCloseTo(19.375) + }) + }) +}) diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index febb7491..184383af 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -1,20 +1,20 @@ -import { TSR } from 'blueprints-integration' -import { literal } from 'tv2-common' -import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' -import { makeMockGalleryContext } from '../../../__mocks__/context' -import { TV2StudioConfigBase } from '../../../tv2-common/blueprintConfig' -import { AuxProps, DskProps, MixEffectProps, SwitcherType, TransitionStyle } from '../types' -import { VideoSwitcherImpl } from '../VideoSwitcher' +import { IStudioContext, TSR } from 'blueprints-integration' +import { instance, mock, when } from 'ts-mockito' +import { literal, TriCaster, TV2StudioConfig, TV2StudioConfigBase, UniformConfig } from 'tv2-common' +import { SwitcherAuxLLayer, SwitcherDveLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' +import { TriCasterDveConverter } from '../TriCasterDveConverter' +import { AuxProps, DskProps, MixEffectProps, TransitionStyle } from '../types' const DURATION_FRAMES: number = 50 const DURATION_SECONDS: number = DURATION_FRAMES / 25 -function setupTriCaster(studioConfigOverrides?: Partial) { - // @todo: is this the correct way? - const context = makeMockGalleryContext({ - studioConfig: { SwitcherType: SwitcherType.TRICASTER, ...studioConfigOverrides } - }) - return VideoSwitcherImpl.getVideoSwitcher(context.core, context.config, context.uniformConfig) +function createTestee(studioMock?: TV2StudioConfig): TriCaster { + const context = mock() + const config = studioMock ?? mock() + const uniformConfig = mock() + const dveConverter = mock() + + return new TriCaster(context, config, uniformConfig, dveConverter) } describe('TriCaster', () => { @@ -26,8 +26,8 @@ describe('TriCaster', () => { } } test('sets timeline object defaults', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getMixEffectTimelineObject(DEFAULT_ME) + const testee: TriCaster = createTestee() + const timelineObject = testee.getMixEffectTimelineObject(DEFAULT_ME) expect(timelineObject).toMatchObject({ id: '', enable: { start: 0 }, @@ -40,8 +40,8 @@ describe('TriCaster', () => { }) test('sets classes', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getMixEffectTimelineObject({ + const testee: TriCaster = createTestee() + const timelineObject = testee.getMixEffectTimelineObject({ ...DEFAULT_ME, classes: ['classA', 'classB'] }) @@ -51,8 +51,8 @@ describe('TriCaster', () => { }) test('sets metaData', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getMixEffectTimelineObject({ + const testee: TriCaster = createTestee() + const timelineObject = testee.getMixEffectTimelineObject({ ...DEFAULT_ME, metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } }) @@ -62,16 +62,16 @@ describe('TriCaster', () => { }) test('sets layer prefix', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getMixEffectTimelineObject(DEFAULT_ME) + const testee: TriCaster = createTestee() + const timelineObject = testee.getMixEffectTimelineObject(DEFAULT_ME) expect(timelineObject).toMatchObject({ layer: prefixLayer(SwitcherMixEffectLLayer.Program) }) }) test('sets programInput', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getMixEffectTimelineObject(DEFAULT_ME) + const testee: TriCaster = createTestee() + const timelineObject = testee.getMixEffectTimelineObject(DEFAULT_ME) expect(timelineObject).toMatchObject({ content: { me: { @@ -82,8 +82,8 @@ describe('TriCaster', () => { }) test('sets previewInput', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getMixEffectTimelineObject({ + const testee: TriCaster = createTestee() + const timelineObject = testee.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.Program, content: { previewInput: 5 @@ -99,8 +99,8 @@ describe('TriCaster', () => { }) test('supports MIX', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getMixEffectTimelineObject({ + const testee: TriCaster = createTestee() + const timelineObject = testee.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.Program, content: { input: 5, @@ -122,8 +122,8 @@ describe('TriCaster', () => { }) test('supports WIPE', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getMixEffectTimelineObject({ + const testee: TriCaster = createTestee() + const timelineObject = testee.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.Program, content: { input: 3, @@ -146,14 +146,16 @@ describe('TriCaster', () => { test('supports WIPE for GFX', () => { const wipeRate = 22 - const triCaster = setupTriCaster({ + const config = mock() + when(config.studio).thenReturn(({ HTMLGraphics: { GraphicURL: 'donotcare', TransitionSettings: { wipeRate, borderSoftness: 20, loopOutTransitionDuration: 15 }, KeepAliveDuration: 120 } - }) - const timelineObject = triCaster.getMixEffectTimelineObject({ + } as any) as TV2StudioConfigBase) + const testee: TriCaster = createTestee(instance(config)) + const timelineObject = testee.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.Program, content: { input: 5, @@ -174,8 +176,8 @@ describe('TriCaster', () => { }) test('supports DIP', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getMixEffectTimelineObject({ + const testee: TriCaster = createTestee() + const timelineObject = testee.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.Program, content: { input: 5, @@ -197,8 +199,8 @@ describe('TriCaster', () => { }) test('supports keyers', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getMixEffectTimelineObject({ + const testee: TriCaster = createTestee() + const timelineObject = testee.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.Program, content: { keyers: [ @@ -240,8 +242,8 @@ describe('TriCaster', () => { } } test('sets timeline object defaults', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getAuxTimelineObject(DEFAULT_AUX) + const testee: TriCaster = createTestee() + const timelineObject = testee.getAuxTimelineObject(DEFAULT_AUX) expect(timelineObject).toMatchObject({ id: '', enable: { start: 0 }, @@ -254,8 +256,8 @@ describe('TriCaster', () => { }) test('sets classes', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getAuxTimelineObject({ + const testee: TriCaster = createTestee() + const timelineObject = testee.getAuxTimelineObject({ ...DEFAULT_AUX, classes: ['classA', 'classB'] }) @@ -265,8 +267,8 @@ describe('TriCaster', () => { }) test('sets metaData', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getAuxTimelineObject({ + const testee: TriCaster = createTestee() + const timelineObject = testee.getAuxTimelineObject({ ...DEFAULT_AUX, metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } }) @@ -276,17 +278,17 @@ describe('TriCaster', () => { }) test('sets layer prefix', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getAuxTimelineObject(DEFAULT_AUX) + const testee: TriCaster = createTestee() + const timelineObject = testee.getAuxTimelineObject(DEFAULT_AUX) expect(timelineObject).toMatchObject({ layer: prefixLayer(SwitcherAuxLLayer.AuxClean) }) }) test('sets aux source', () => { - const triCaster = setupTriCaster() + const testee: TriCaster = createTestee() - const timelineObject = triCaster.getAuxTimelineObject(DEFAULT_AUX) + const timelineObject = testee.getAuxTimelineObject(DEFAULT_AUX) expect(timelineObject).toMatchObject({ content: { @@ -313,8 +315,8 @@ describe('TriCaster', () => { } } test('sets timeline object defaults', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getDskTimelineObject(DEFAULT_DSK) + const testee: TriCaster = createTestee() + const timelineObject = testee.getDskTimelineObject(DEFAULT_DSK) expect(timelineObject).toMatchObject({ id: '', enable: { start: 0 }, @@ -327,8 +329,8 @@ describe('TriCaster', () => { }) test('sets classes', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getDskTimelineObject({ + const testee: TriCaster = createTestee() + const timelineObject = testee.getDskTimelineObject({ ...DEFAULT_DSK, classes: ['classA', 'classB'] }) @@ -338,8 +340,8 @@ describe('TriCaster', () => { }) test('sets metaData', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getDskTimelineObject({ + const testee: TriCaster = createTestee() + const timelineObject = testee.getDskTimelineObject({ ...DEFAULT_DSK, metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } }) @@ -349,17 +351,17 @@ describe('TriCaster', () => { }) test('sets layer prefix', () => { - const triCaster = setupTriCaster() - const timelineObject = triCaster.getDskTimelineObject(DEFAULT_DSK) + const testee: TriCaster = createTestee() + const timelineObject = testee.getDskTimelineObject(DEFAULT_DSK) expect(timelineObject).toMatchObject({ layer: prefixLayer('dsk_1') }) }) test('enables DSK', () => { - const triCaster = setupTriCaster() + const testee: TriCaster = createTestee() - const timelineObject = triCaster.getDskTimelineObject(DEFAULT_DSK) + const timelineObject = testee.getDskTimelineObject(DEFAULT_DSK) expect(timelineObject).toMatchObject({ content: literal({ @@ -376,8 +378,129 @@ describe('TriCaster', () => { }) }) }) + + describe('getDveTimelineObjects', () => { + it('creates one TriCaster DVE timelineObject', () => { + const testee: TriCaster = createTestee() + const result: TSR.TSRTimelineObj[] = testee.getDveTimelineObjects(getBasicDveProps()) + + expect(result).toHaveLength(1) + expect(result[0].layer).toBe(prefixLayer(SwitcherDveLLayer.DveBoxes)) + }) + + // TODO: Replace with interface + function getBasicDveProps(boxes?: any[]) { + return { + content: { + boxes: boxes ?? [{ enabled: false }, { enabled: false }, { enabled: false }, { enabled: false }], + template: {}, + artFillSource: 0, + artCutSource: 0 + } + } + } + + it('creates timelineObject content for TriCaster MixEffect', () => { + const testee: TriCaster = createTestee() + const result: TSR.TimelineObjTriCasterME['content'] = testee.getDveTimelineObjects(getBasicDveProps())[0] + .content as TSR.TimelineObjTriCasterME['content'] + + expect(result.deviceType).toBe(TSR.DeviceType.TRICASTER) + expect(result.type).toBe(TSR.TimelineContentTypeTriCaster.ME) + expect(result.me).toBeTruthy() + }) + + it('generate overlay keyer', () => { + const testee: TriCaster = createTestee() + const content: TSR.TimelineObjTriCasterME['content'] = testee.getDveTimelineObjects(getBasicDveProps())[0] + .content as TSR.TimelineObjTriCasterME['content'] + const result: Record = content.me.keyers! + + expect(result).toBeTruthy() + expect(result.dsk1).toBeTruthy() + // TODO: Find value from config + expect(result.dsk1.input).toBe('input5') + expect(result.dsk1.onAir).toBeTruthy() + expect(result.dsk1.transitionEffect).toBe('cut') + }) + + it("has no enabled boxes, all layers are 'invisible'", () => { + const testee: TriCaster = createTestee() + const emptyBoxes = [{ enabled: false }, { enabled: false }, { enabled: false }, { enabled: false }] + const content = testee.getDveTimelineObjects(getBasicDveProps(emptyBoxes))[0] + .content as TSR.TimelineObjTriCasterME['content'] + const result: Partial> = (content.me as TSR.TriCasterMixEffectInEffectMode).layers! + + expect(result.a).toMatchObject(invisibleBox()) + expect(result.b).toMatchObject(invisibleBox()) + expect(result.c).toMatchObject(invisibleBox()) + expect(result.d).toMatchObject(invisibleBox()) + }) + + function invisibleBox(): TSR.TriCasterLayer { + return { + input: 'Black', + positioningAndCropEnabled: true, + position: { + x: -3.555, + y: -2 + }, + crop: { + down: 0, + up: 0, + left: 0, + right: 0 + } + } + } + + it('has enabled layer A, create box for A', () => { + const boxes = [{ enabled: true, source: 1 }, { enabled: false }, { enabled: false }, { enabled: false }] + const layers = getLayers(boxes) + assertLayer(layers.a!) + }) + + function getLayers( + boxes: Array<{ enabled: boolean; source?: number }> + ): Partial> { + const testee: TriCaster = createTestee() + const content = testee.getDveTimelineObjects(getBasicDveProps(boxes))[0] + .content as TSR.TimelineObjTriCasterME['content'] + return (content.me as TSR.TriCasterMixEffectInEffectMode).layers! + } + + function assertLayer(box: TSR.TriCasterLayer): void { + expect(box).toBeTruthy() + expect(box.input).toBeTruthy() + expect(box.positioningAndCropEnabled).toBeTruthy() + expect(box.position).toBeTruthy() + expect(box.scale).toBeTruthy() + expect(box.crop).toBeTruthy() + } + + it('has enabled layer B, create box for B', () => { + const boxes = [{ enabled: false }, { enabled: true, source: 1 }, { enabled: false }, { enabled: false }] + const layers = getLayers(boxes) + assertLayer(layers.b!) + }) + + it('has enabled layer C, create box for C', () => { + const boxes = [{ enabled: false }, { enabled: false }, { enabled: true, source: 1 }, { enabled: false }] + const layers = getLayers(boxes) + assertLayer(layers.c!) + }) + + it('has enabled layer D, create box for D', () => { + const boxes = [{ enabled: false }, { enabled: false }, { enabled: false }, { enabled: true, source: 1 }] + const layers = getLayers(boxes) + assertLayer(layers.d!) + }) + }) }) -export function prefixLayer(layerName: string) { +function prefixLayer(layerName: string) { return 'tricaster_' + layerName } diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 00000000..b49a8170 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noUnusedLocals": false, + "noUnusedParameters": false + } +} diff --git a/yarn.lock b/yarn.lock index 7b0155bd..e6251ebd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4175,7 +4175,7 @@ lodash.memoize@4.x: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= -lodash@^4.17.15, lodash@^4.7.0: +lodash@^4.17.15, lodash@^4.17.5, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -6068,6 +6068,13 @@ ts-loader@^6.2.1: micromatch "^4.0.0" semver "^6.0.0" +ts-mockito@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/ts-mockito/-/ts-mockito-2.6.1.tgz#bc9ee2619033934e6fad1c4455aca5b5ace34e73" + integrity sha512-qU9m/oEBQrKq5hwfbJ7MgmVN5Gu6lFnIGWvpxSjrqq6YYEVv+RwVFWySbZMBgazsWqv6ctAyVBpo9TmAxnOEKw== + dependencies: + lodash "^4.17.5" + ts-node@^8.0.3: version "8.10.2" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d" From 1e3891d56f171a954a74ae4d4b007aef529b127f Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Mon, 27 Feb 2023 08:58:23 +0100 Subject: [PATCH 33/86] SOF-1264 Tricaster DVE Fill source is now found through config. Defaults to 5 if no config is found --- src/tv2-common/videoSwitchers/TriCaster.ts | 2 +- .../videoSwitchers/__tests__/TriCaster.spec.ts | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 5fbe8f80..4c507b60 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -234,7 +234,7 @@ export class TriCaster extends VideoSwitcherImpl { private generateOverlayKeyer(): Record { return { dsk1: { - input: this.getInputName(DVE_OVERLAY_INPUT_NUMBER), + input: this.getInputName(this.config.studio.SwitcherSource?.SplitArtFill ?? DVE_OVERLAY_INPUT_NUMBER), onAir: true, transitionEffect: 'cut' } diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index 184383af..cb042ce1 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -411,15 +411,21 @@ describe('TriCaster', () => { }) it('generate overlay keyer', () => { - const testee: TriCaster = createTestee() + const config = mock() + const artFillSource = 10 + when(config.studio).thenReturn(({ + SwitcherSource: { + SplitArtFill: artFillSource + } + } as any) as TV2StudioConfigBase) + const testee: TriCaster = createTestee(instance(config)) const content: TSR.TimelineObjTriCasterME['content'] = testee.getDveTimelineObjects(getBasicDveProps())[0] .content as TSR.TimelineObjTriCasterME['content'] const result: Record = content.me.keyers! expect(result).toBeTruthy() expect(result.dsk1).toBeTruthy() - // TODO: Find value from config - expect(result.dsk1.input).toBe('input5') + expect(result.dsk1.input).toBe(`input${artFillSource}`) expect(result.dsk1.onAir).toBeTruthy() expect(result.dsk1.transitionEffect).toBe('cut') }) From 60a747f350ec5f6c54a44fd4d5e1d598bbd49d02 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 1 Mar 2023 07:28:58 +0100 Subject: [PATCH 34/86] SOF-1264 Refactor mock setup for TriCaster.spec. Fix wrong import --- src/tv2-common/migrations/index.ts | 7 +- .../AtemToTricasterDveConverter.spec.ts | 2 +- .../__tests__/TriCaster.spec.ts | 127 +++++++++--------- src/tv2_afvd_showstyle/getRundown.ts | 16 +-- src/tv2_offtube_studio/migrations/index.ts | 2 +- 5 files changed, 77 insertions(+), 77 deletions(-) diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index d2730836..7cfa82ba 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -418,7 +418,7 @@ export function PrefixEvsWithEvs( export function convertStudioTableColumnToFloat( versionStr: string, tableId: string, - columnId: string, + columnId: string ): MigrationStepStudio { return { id: `${versionStr}.convertStudioTableColumnToFloat.${tableId}.${columnId}`, @@ -437,8 +437,9 @@ export function convertStudioTableColumnToFloat( let config = context.getConfig(tableId) as unknown as TableConfigItemValue config = config.map((row) => { const value = row[columnId] - if (typeof value === 'string') - row[columnId] = parseFloat(value) + if (typeof value === 'string') { + row[columnId] = parseFloat(value) + } return row }) context.setConfig(tableId, config as unknown as ConfigItemValue) diff --git a/src/tv2-common/videoSwitchers/__tests__/AtemToTricasterDveConverter.spec.ts b/src/tv2-common/videoSwitchers/__tests__/AtemToTricasterDveConverter.spec.ts index 13af4282..c51ff67e 100644 --- a/src/tv2-common/videoSwitchers/__tests__/AtemToTricasterDveConverter.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/AtemToTricasterDveConverter.spec.ts @@ -1,4 +1,4 @@ -import { TSR } from '../../../../../tv-automation-server-core/packages/blueprints-integration/src' +import { TSR } from 'blueprints-integration' import { AtemToTricasterDveConverter } from '../atemToTricasterDveConverter' describe('AtemToTricasterDveConverter', () => { diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index 55f49d59..28f36162 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -15,10 +15,14 @@ import { AuxProps, DskProps, MixEffectProps, SpecialInput, TransitionStyle } fro const DURATION_FRAMES: number = 50 const DURATION_SECONDS: number = DURATION_FRAMES / 25 -function createTestee(studioMock?: TV2StudioConfig): TriCaster { - const context = mock() - const config = studioMock ?? mock() - const uniformConfig = mock() +function createTestee(mocks?: { + context?: IStudioContext + config?: TV2StudioConfig + uniformConfig?: UniformConfig +}): TriCaster { + const context = mocks?.context ?? mock() + const config = mocks?.config ?? mock() + const uniformConfig = mocks?.uniformConfig ?? mock() const dveConverter = mock() return new TriCaster(context, config, uniformConfig, dveConverter) @@ -154,16 +158,14 @@ describe('TriCaster', () => { test('supports WIPE for GFX', () => { const wipeRate = 22 const config = mock() - when(config.studio).thenReturn(({ - studioConfig: { - HTMLGraphics: { - GraphicURL: 'donotcare', - TransitionSettings: { wipeRate, borderSoftness: 20, loopOutTransitionDuration: 15 }, - KeepAliveDuration: 120 - } + when(config.studio).thenReturn({ + HTMLGraphics: { + GraphicURL: 'donotcare', + TransitionSettings: { wipeRate, borderSoftness: 20, loopOutTransitionDuration: 15 }, + KeepAliveDuration: 120 } - } as any) as TV2StudioConfigBase) - const testee: TriCaster = createTestee(instance(config)) + } as any as TV2StudioConfigBase) + const testee: TriCaster = createTestee({ config: instance(config) }) const timelineObject = testee.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.Program, content: { @@ -296,7 +298,7 @@ describe('TriCaster', () => { test('sets Mix Output when layer mapping is MIX_OUTPUT', () => { const config = mock() - when(config.studio).thenReturn(({ + when(config.studio).thenReturn({ studioConfig: { mappingDefaults: { [prefixLayer(DEFAULT_AUX.layer)]: literal({ @@ -308,8 +310,8 @@ describe('TriCaster', () => { }) } } - } as any) as TV2StudioConfigBase) - const testee: TriCaster = createTestee(instance(config)) + } as any as TV2StudioConfigBase) + const testee: TriCaster = createTestee({ config: instance(config) }) const timelineObject = testee.getAuxTimelineObject(DEFAULT_AUX) @@ -323,21 +325,20 @@ describe('TriCaster', () => { }) test('sets Matrix Output when layer mapping is MATRIX_OUTPUT', () => { - const config = mock() - when(config.studio).thenReturn(({ - studioConfig: { - mappingDefaults: { - [prefixLayer(DEFAULT_AUX.layer)]: literal({ - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingTriCasterType.MATRIX_OUTPUT, - name: 'out2' - }) - } + const context = mock() + when(context.getStudioMappings).thenReturn(() => { + return { + [prefixLayer(DEFAULT_AUX.layer)]: literal({ + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MATRIX_OUTPUT, + name: 'out2' + }) } - } as any) as TV2StudioConfigBase) - const testee = createTestee(instance(config)) + }) + + const testee = createTestee({ context: instance(context) }) const timelineObject = testee.getAuxTimelineObject(DEFAULT_AUX) @@ -351,34 +352,33 @@ describe('TriCaster', () => { }) test('resolves Special Input for Matrix Output', () => { - const config = mock() - when(config.studio).thenReturn(({ - studioConfig: { - mappingDefaults: { - [prefixLayer(SwitcherAuxLLayer.AuxClean)]: literal({ - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, - name: 'mix5' - }), - [prefixLayer(SwitcherAuxLLayer.AuxVideoMixMinus)]: literal({ - device: TSR.DeviceType.TRICASTER, - deviceId: TRICASTER_DEVICE_ID, - lookahead: LookaheadMode.WHEN_CLEAR, - mappingType: TSR.MappingTriCasterType.MATRIX_OUTPUT, - name: 'out2' - }) - }, - uniformConfig: { - specialInputAuxLLayers: { - [SpecialInput.ME1_PROGRAM]: SwitcherAuxLLayer.AuxProgram, - [SpecialInput.ME3_PROGRAM]: SwitcherAuxLLayer.AuxClean - } - } + const context = mock() + when(context.getStudioMappings).thenReturn(() => { + return { + [prefixLayer(SwitcherAuxLLayer.AuxClean)]: literal({ + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, + name: 'mix5' + }), + [prefixLayer(SwitcherAuxLLayer.AuxVideoMixMinus)]: literal({ + device: TSR.DeviceType.TRICASTER, + deviceId: TRICASTER_DEVICE_ID, + lookahead: LookaheadMode.WHEN_CLEAR, + mappingType: TSR.MappingTriCasterType.MATRIX_OUTPUT, + name: 'out2' + }) } - } as any) as TV2StudioConfigBase) - const testee = createTestee(instance(config)) + }) + + const uniformConfig = mock() + when(uniformConfig.specialInputAuxLLayers).thenReturn({ + [SpecialInput.ME1_PROGRAM]: SwitcherAuxLLayer.AuxProgram, + [SpecialInput.ME3_PROGRAM]: SwitcherAuxLLayer.AuxClean + }) + + const testee = createTestee({ context: instance(context), uniformConfig: instance(uniformConfig) }) const timelineObject = testee.getAuxTimelineObject({ layer: SwitcherAuxLLayer.AuxVideoMixMinus, @@ -510,12 +510,12 @@ describe('TriCaster', () => { it('generate overlay keyer', () => { const config = mock() const artFillSource = 10 - when(config.studio).thenReturn(({ + when(config.studio).thenReturn({ SwitcherSource: { SplitArtFill: artFillSource } - } as any) as TV2StudioConfigBase) - const testee: TriCaster = createTestee(instance(config)) + } as any as TV2StudioConfigBase) + const testee: TriCaster = createTestee({ config: instance(config) }) const content: TSR.TimelineObjTriCasterME['content'] = testee.getDveTimelineObjects(getBasicDveProps())[0] .content as TSR.TimelineObjTriCasterME['content'] const result: Record = content.me.keyers! @@ -532,10 +532,9 @@ describe('TriCaster', () => { const emptyBoxes = [{ enabled: false }, { enabled: false }, { enabled: false }, { enabled: false }] const content = testee.getDveTimelineObjects(getBasicDveProps(emptyBoxes))[0] .content as TSR.TimelineObjTriCasterME['content'] - const result: Partial> = (content.me as TSR.TriCasterMixEffectInEffectMode).layers! + const result: Partial> = ( + content.me as TSR.TriCasterMixEffectInEffectMode + ).layers! expect(result.a).toMatchObject(invisibleBox()) expect(result.b).toMatchObject(invisibleBox()) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 5e5bb001..89ed8141 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -77,17 +77,17 @@ class GlobalAdLibPiecesGenerator { this.config.sources.lives .slice(0, 10) // the first x lives to create live-adlibs from - .forEach(info => { + .forEach((info) => { adLibPieces.push(...this.makeRemoteAdLibs(info, globalRank++)) }) this.config.sources.lives .slice(0, 10) // the first x lives to create AUX1 (studio) adlibs - .forEach(info => { + .forEach((info) => { adLibPieces.push(...this.makeRemoteAuxStudioAdLibs(info, globalRank++)) }) - this.config.sources.replays.forEach(info => { + this.config.sources.replays.forEach((info) => { if (!/EPSIO/i.test(info.id)) { adLibPieces.push(this.makeEvsAdLib(info, globalRank++, false)) } @@ -400,7 +400,7 @@ class GlobalAdLibPiecesGenerator { content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: this.config.studio.StudioMics.map(layer => ({ + channels: this.config.studio.StudioMics.map((layer) => ({ mappedLayer: layer, isPgm: 1 })), @@ -429,7 +429,7 @@ class GlobalAdLibPiecesGenerator { content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: this.config.studio.StudioMics.map(layer => ({ + channels: this.config.studio.StudioMics.map((layer) => ({ mappedLayer: layer, isPgm: 0 })), @@ -723,7 +723,7 @@ function getBaseline(context: ExtendedShowStyleContext): content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: Object.keys(sisyfosChannels).map(key => { + channels: Object.keys(sisyfosChannels).map((key) => { const llayer = key as SisyfosLLAyer const channel = sisyfosChannels[llayer] as SisyfosChannel return literal({ @@ -739,7 +739,7 @@ function getBaseline(context: ExtendedShowStyleContext): ...CreateLYDBaseline('afvd'), ...(context.config.showStyle.CasparCGLoadingClip && context.config.showStyle.CasparCGLoadingClip.length - ? [...context.config.mediaPlayers.map(mp => CasparPlayerClipLoadingLoop(mp.id))].map(layer => { + ? [...context.config.mediaPlayers.map((mp) => CasparPlayerClipLoadingLoop(mp.id))].map((layer) => { return literal({ id: '', enable: { while: '1' }, @@ -770,7 +770,7 @@ function getBaseline(context: ExtendedShowStyleContext): } function getMixEffectBaseline(context: ExtendedShowStyleContext): TSR.TSRTimelineObj[] { - return Object.values(context.uniformConfig.mixEffects).flatMap(mixEffect => + return Object.values(context.uniformConfig.mixEffects).flatMap((mixEffect) => _.compact([ context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, diff --git a/src/tv2_offtube_studio/migrations/index.ts b/src/tv2_offtube_studio/migrations/index.ts index f6da40f3..d954578e 100644 --- a/src/tv2_offtube_studio/migrations/index.ts +++ b/src/tv2_offtube_studio/migrations/index.ts @@ -277,7 +277,7 @@ export const studioMigrations: MigrationStepStudio[] = [ renameStudioConfig('1.4.6', 'Offtube', 'GraphicBasePath', 'NetworkBasePathGraphic'), renameStudioConfig('1.4.6', 'Offtube', 'GraphicFlowId', 'GraphicMediaFlowId'), - GetMappingDefaultMigrationStepForLayer('1.4.8', 'casparcg_player_jingle_looakhead', true), + GetMappingDefaultMigrationStepForLayer('1.4.8', 'casparcg_player_jingle_looakhead', true), renameStudioConfig('1.5.0', 'Offtube', 'NetworkBasePathJingle', 'JingleNetworkBasePath'), renameStudioConfig('1.5.0', 'Offtube', 'NetworkBasePathClip', 'ClipNetworkBasePath'), From 583b00c8dc6007ccddbab0d74490526b47946665 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 1 Mar 2023 12:05:11 +0100 Subject: [PATCH 35/86] SOF-1264 startNewDveLayout now uses the configured VideoSwitcher to check for ME objects --- src/tv2-common/actions/executeAction.ts | 5 +---- src/tv2-common/videoSwitchers/TriCaster.ts | 2 +- src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts | 4 +++- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 182cae3d..d9110484 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -863,10 +863,7 @@ async function startNewDVELayout< timelineObjects: pieceContent.timelineObjects .filter( (tlObj) => - !( - tlObj.content.deviceType === TSR.DeviceType.ATEM && // @todo: tricaster - (tlObj as TSR.TimelineObjAtemAny).content.type === TSR.TimelineContentTypeAtem.ME - ) && tlObj.content.deviceType !== TSR.DeviceType.SISYFOS + !context.videoSwitcher.isMixEffect(tlObj) && tlObj.content.deviceType !== TSR.DeviceType.SISYFOS ) .map((obj) => ({ ...obj, priority: obj.priority ?? 1 / 2 })) } diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index c0aeee93..a5155020 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -40,7 +40,7 @@ const TRANSITION_MAP: Record = { [TransitionStyle.STING]: 5 // not really supported?? } -const DVE_OVERLAY_INPUT_NUMBER: number = 5 +const DVE_OVERLAY_INPUT_NUMBER = 5 export class TriCaster extends VideoSwitcherImpl { public readonly type = SwitcherType.ATEM diff --git a/src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts b/src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts index fb560722..b493afd2 100644 --- a/src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts +++ b/src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts @@ -7,6 +7,8 @@ const ATEM_HEIGHT = 18 const ATEM_CROP_LEFT_RIGHT_MAX_VALUE = 32000 const ATEM_CROP_TOP_BOTTOM_MAX_VALUE = 18000 +const TRICASTER_WIDTH = (2 / 9) * 16 + export class AtemToTricasterDveConverter implements TriCasterDveConverter { public convertPosition(x: number, y: number): TSR.TriCasterLayer['position'] { return { @@ -17,7 +19,7 @@ export class AtemToTricasterDveConverter implements TriCasterDveConverter { private convertPositionX(atemX: number): number { const positionPercentage = atemX / ATEM_WIDTH - return (positionPercentage * ((2 / 9) * 16)) / 100 + return (positionPercentage * TRICASTER_WIDTH) / 100 } private convertPositionY(atemY: number): number { From 47718858eb871748b3c5cdd339df15e9f8426a49 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 1 Mar 2023 20:54:17 +0100 Subject: [PATCH 36/86] refactor: SOF-1260 rename and refactor minor things based on the review comments --- docs/DVE.md | 2 +- src/__mocks__/context.ts | 38 ++-- src/inews-mixins/__tests__/playlist.spec.ts | 4 +- .../__tests__/EvaluateCueTelemetrics.spec.ts | 22 +-- src/tv2-common/actions/context.ts | 13 +- src/tv2-common/actions/executeAction.ts | 148 +++++++------- src/tv2-common/blueprintConfig.ts | 6 + src/tv2-common/content/dve.ts | 8 +- src/tv2-common/content/jingle.ts | 12 +- src/tv2-common/content/server.ts | 14 +- src/tv2-common/cueTiming.ts | 4 +- src/tv2-common/cues/EvaluateCueRobotCamera.ts | 4 +- src/tv2-common/cues/ekstern.ts | 14 +- src/tv2-common/cues/lyd.ts | 26 +-- src/tv2-common/cues/mixMinus.ts | 14 +- src/tv2-common/evaluateCues.ts | 32 +-- src/tv2-common/frameTime.ts | 6 +- src/tv2-common/getSegment.ts | 36 ++-- .../helpers/__tests__/serverResume.spec.ts | 10 +- src/tv2-common/helpers/abPlayback.ts | 14 +- src/tv2-common/helpers/dsk.ts | 30 +-- src/tv2-common/helpers/graphics/Graphic.ts | 110 +++++------ .../graphics/caspar/HtmlInternalGraphic.ts | 17 +- .../caspar/htmlPilotGraphicGenerator.ts | 4 +- .../helpers/graphics/caspar/util.ts | 4 +- .../helpers/graphics/design/index.ts | 14 +- .../graphics/internal/InternalGraphic.ts | 20 +- .../helpers/graphics/internal/create.ts | 6 +- src/tv2-common/helpers/graphics/layers.ts | 6 +- .../graphics/pilot/PilotGraphicGenerator.ts | 36 ++-- src/tv2-common/helpers/graphics/util.ts | 2 +- .../graphics/viz/VizInternalGraphic.ts | 10 +- .../graphics/viz/VizPilotGraphicGenerator.ts | 6 +- src/tv2-common/helpers/rundownAdLibActions.ts | 6 +- src/tv2-common/helpers/serverResume.ts | 14 +- src/tv2-common/hotkeys/global.ts | 28 +-- src/tv2-common/hotkeys/hotkey-defaults.ts | 28 +-- src/tv2-common/hotkeys/segment.ts | 6 +- src/tv2-common/jinglePartProperties.ts | 10 +- src/tv2-common/migrations/index.ts | 7 +- src/tv2-common/migrations/sourceManifest.ts | 2 +- src/tv2-common/onTimelineGenerate.ts | 10 +- src/tv2-common/parts/effekt.ts | 40 ++-- src/tv2-common/parts/kam.ts | 10 +- src/tv2-common/parts/server.ts | 18 +- src/tv2-common/pieces/adlibServer.ts | 8 +- src/tv2-common/pieces/script.ts | 4 +- src/tv2-common/pieces/telemetric.ts | 6 +- src/tv2-common/segment/context.ts | 17 +- src/tv2-common/showstyle/context.ts | 8 +- .../showstyle/timelineEventContext.ts | 6 +- src/tv2-common/studio/context.ts | 6 +- src/tv2-common/types/config.ts | 4 +- .../syncIngestUpdateToPartInstance.ts | 20 +- src/tv2-common/videoSwitchers/Atem.ts | 4 +- src/tv2-common/videoSwitchers/TriCaster.ts | 8 +- .../videoSwitchers/VideoSwitcher.ts | 4 +- .../videoSwitchers/__tests__/Atem.spec.ts | 4 +- .../__tests__/TriCaster.spec.ts | 8 +- src/tv2-constants/enums.ts | 8 +- .../GlobalAdlibActionsGenerator.ts | 26 +-- .../__tests__/actions.spec.ts | 50 ++--- .../__tests__/addScript.spec.ts | 6 +- .../__tests__/baseline.spec.ts | 8 +- .../__tests__/blueprint.spec.ts | 182 +++++++----------- .../__tests__/rundown_story_exception.spec.ts | 9 +- .../syncIngestChangesToPartInstance.spec.ts | 10 +- .../__tests__/transitions.spec.ts | 18 +- src/tv2_afvd_showstyle/getRundown.ts | 38 ++-- src/tv2_afvd_showstyle/getSegment.ts | 17 +- src/tv2_afvd_showstyle/helpers/content/dve.ts | 6 +- .../pieces/__tests__/grafikViz.spec.ts | 22 +-- .../helpers/pieces/__tests__/lyd.spec.ts | 12 +- .../helpers/pieces/__tests__/telefon.spec.ts | 4 +- .../helpers/pieces/adlib.ts | 8 +- .../helpers/pieces/clearGrafiks.ts | 16 +- .../helpers/pieces/design.ts | 4 +- src/tv2_afvd_showstyle/helpers/pieces/dve.ts | 10 +- .../helpers/pieces/ekstern.ts | 4 +- .../helpers/pieces/evaluateCues.ts | 6 +- .../helpers/pieces/graphic.ts | 6 +- .../helpers/pieces/graphicBackgroundLoop.ts | 20 +- .../helpers/pieces/graphicPilot.ts | 6 +- .../helpers/pieces/jingle.ts | 18 +- .../helpers/pieces/routing.ts | 10 +- .../helpers/pieces/showLifecycle.ts | 4 +- .../helpers/pieces/telefon.ts | 14 +- src/tv2_afvd_showstyle/layers.ts | 11 +- .../migrations/outputlayer-defaults.ts | 18 +- .../migrations/sourcelayer-defaults.ts | 6 +- src/tv2_afvd_showstyle/parts/effekt.ts | 4 +- src/tv2_afvd_showstyle/parts/evs.ts | 12 +- src/tv2_afvd_showstyle/parts/grafik.ts | 10 +- src/tv2_afvd_showstyle/parts/intro.ts | 6 +- src/tv2_afvd_showstyle/parts/kam.ts | 10 +- src/tv2_afvd_showstyle/parts/live.ts | 4 +- src/tv2_afvd_showstyle/parts/server.ts | 4 +- src/tv2_afvd_showstyle/parts/teknik.ts | 4 +- src/tv2_afvd_showstyle/parts/unknown.ts | 10 +- .../__tests__/graphics.spec.ts | 31 ++- src/tv2_afvd_studio/config-manifests.ts | 18 +- src/tv2_afvd_studio/getBaseline.ts | 4 +- src/tv2_afvd_studio/helpers/config.ts | 14 +- src/tv2_afvd_studio/onTimelineGenerate.ts | 4 +- .../__tests__/actions.spec.ts | 69 ++++--- .../content/OfftubeDVEContent.ts | 6 +- .../cues/OfftubeAdlib.ts | 4 +- src/tv2_offtube_showstyle/cues/OfftubeDVE.ts | 8 +- .../cues/OfftubeEkstern.ts | 6 +- .../cues/OfftubeGraphicBackgroundLoop.ts | 10 +- .../cues/OfftubeGraphicDesign.ts | 4 +- .../cues/OfftubeGraphics.ts | 6 +- .../cues/OfftubeJingle.ts | 16 +- .../cues/OfftubePgmClean.ts | 8 +- src/tv2_offtube_showstyle/getRundown.ts | 44 ++--- src/tv2_offtube_showstyle/getSegment.ts | 16 +- .../helpers/EvaluateCues.ts | 6 +- src/tv2_offtube_showstyle/layers.ts | 10 +- src/tv2_offtube_showstyle/migrations/index.ts | 12 +- .../migrations/outputlayer-defaults.ts | 18 +- .../migrations/sourcelayer-defaults.ts | 8 +- .../onTimelineGenerate.ts | 6 +- src/tv2_offtube_showstyle/parts/OfftubeDVE.ts | 4 +- .../parts/OfftubeEffekt.ts | 8 +- .../parts/OfftubeGrafik.ts | 12 +- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 10 +- .../parts/OfftubeServer.ts | 4 +- .../parts/OfftubeUnknown.ts | 10 +- src/tv2_offtube_studio/config-manifests.ts | 18 +- src/tv2_offtube_studio/getBaseline.ts | 4 +- src/tv2_offtube_studio/helpers/config.ts | 6 +- 131 files changed, 946 insertions(+), 1077 deletions(-) diff --git a/docs/DVE.md b/docs/DVE.md index ef91a3dc..256976e6 100644 --- a/docs/DVE.md +++ b/docs/DVE.md @@ -1,6 +1,6 @@ # DVE -To use DVEs, first add the studio settings `ATEM Split Screen Art Fill` and `ATEM Split Screen Art Key`. +To use DVEs, first add the studio settings `Video Switcher Split Screen Art Fill` and `Video Switcher Split Screen Art Key`. Then, go to your showstyle settings and add the setting `DVE Styles`. Here you can define all the DVEs for your show. diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index af3cd130..a56d73ca 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -27,20 +27,15 @@ import { PackageInfo, PieceLifespan, PlaylistTimingType, - Time, - TSR + Time } from 'blueprints-integration' import { - AuxProps, - DskProps, - ExtendedSegmentContext, ITV2ActionExecutionContext, - MixEffectProps, PieceMetaData, + SegmentContext, TV2StudioConfigBase, UniformConfig, - VideoSwitcher, - VideoSwitcherImpl + VideoSwitcherBase } from 'tv2-common' import { NoteType } from 'tv2-constants' import { defaultShowStyleConfig, defaultStudioConfig } from '../tv2_afvd_showstyle/__tests__/configs' @@ -170,7 +165,7 @@ export class StudioContext extends CommonContext implements IStudioContext { } } -export class ShowStyleContext extends StudioContext implements IShowStyleContext, IPackageInfoContext { +export class ShowStyleContextMock extends StudioContext implements IShowStyleContext, IPackageInfoContext { public studioConfig: { [key: string]: ConfigItemValue } = {} public showStyleConfig: { [key: string]: ConfigItemValue } = {} @@ -203,7 +198,7 @@ export class ShowStyleContext extends StudioContext implements IShowStyleContext } } -export class ShowStyleUserContext extends ShowStyleContext implements IUserNotesContext { +export class ShowStyleUserContextMock extends ShowStyleContextMock implements IUserNotesContext { public notifyUserError(message: string, _params?: { [key: string]: any }): void { this.pushNote(NoteType.NOTIFY_USER_ERROR, message) } @@ -216,7 +211,7 @@ export class ShowStyleUserContext extends ShowStyleContext implements IUserNotes } } -export class GetRundownContext extends ShowStyleUserContext implements IGetRundownContext { +export class GetRundownContextMock extends ShowStyleUserContextMock implements IGetRundownContext { public async getCurrentPlaylist(): Promise | undefined> { return undefined } @@ -230,7 +225,7 @@ export class GetRundownContext extends ShowStyleUserContext implements IGetRundo } } -export class RundownContext extends ShowStyleContext implements IRundownContext { +export class RundownContextMock extends ShowStyleContextMock implements IRundownContext { public readonly rundownId: string = 'rundown0' public readonly rundown: Readonly @@ -257,7 +252,7 @@ export class RundownContext extends ShowStyleContext implements IRundownContext } } -export class RundownUserContext extends RundownContext implements IRundownUserContext { +export class RundownUserContextMock extends RundownContextMock implements IRundownUserContext { public notifyUserError(message: string, _params?: { [key: string]: any }): void { this.pushNote(NoteType.NOTIFY_USER_ERROR, message) } @@ -270,7 +265,7 @@ export class RundownUserContext extends RundownContext implements IRundownUserCo } } -export class SegmentUserContext extends RundownContext implements ISegmentUserContext { +export class SegmentUserContextMock extends RundownContextMock implements ISegmentUserContext { constructor( contextName: string, mappingsDefaults: BlueprintMappings, @@ -309,8 +304,8 @@ export class SegmentUserContext extends RundownContext implements ISegmentUserCo } } -export class SyncIngestUpdateToPartInstanceContext - extends RundownUserContext +export class SyncIngestUpdateToPartInstanceContextMock + extends RundownUserContextMock implements ISyncIngestUpdateToPartInstanceContext { public syncedPieceInstances: string[] = [] @@ -415,14 +410,13 @@ export class SyncIngestUpdateToPartInstanceContext } } -export class ActionExecutionContext extends ShowStyleUserContext implements ITV2ActionExecutionContext { +export class ActionExecutionContextMock extends ShowStyleUserContextMock implements ITV2ActionExecutionContext { public currentPart: IBlueprintPartInstance public currentPieceInstances: Array> public nextPart: IBlueprintPartInstance | undefined public nextPieceInstances: Array> | undefined public takeAfterExecute: boolean = false - public isTV2Context: true = true constructor( contextName: string, @@ -654,7 +648,7 @@ export interface MockConfigOverrides { } export function makeMockCoreGalleryContext(overrides?: MockConfigOverrides) { - const mockCoreContext = new SegmentUserContext( + const mockCoreContext = new SegmentUserContextMock( 'test', { ...mappingsDefaultsAFVD, ...overrides?.mappingDefaults }, parseStudioConfigAFVD, @@ -668,12 +662,12 @@ export function makeMockCoreGalleryContext(overrides?: MockConfigOverrides) { export function makeMockGalleryContext(overrides?: MockConfigOverrides) { const mockCoreContext = makeMockCoreGalleryContext(overrides) // @todo: this is not great, but it works - const config = { ...(mockCoreContext.getStudioConfig() as any), ...(mockCoreContext.getShowStyleConfig() as any) } - const mockContext: ExtendedSegmentContext = { + const config = { ...mockCoreContext.getStudioConfig(), ...(mockCoreContext.getShowStyleConfig() as any) } + const mockContext: SegmentContext = { core: mockCoreContext, config, uniformConfig: { ...GALLERY_UNIFORM_CONFIG, ...overrides?.uniformConfig }, - videoSwitcher: VideoSwitcherImpl.getVideoSwitcher(mockCoreContext, config, GALLERY_UNIFORM_CONFIG) // new MockVideoSwitcher() + videoSwitcher: VideoSwitcherBase.getVideoSwitcher(mockCoreContext, config, GALLERY_UNIFORM_CONFIG) // new MockVideoSwitcher() } return mockContext } diff --git a/src/inews-mixins/__tests__/playlist.spec.ts b/src/inews-mixins/__tests__/playlist.spec.ts index f341807d..a11802f5 100644 --- a/src/inews-mixins/__tests__/playlist.spec.ts +++ b/src/inews-mixins/__tests__/playlist.spec.ts @@ -6,7 +6,7 @@ import { PlaylistTimingType } from 'blueprints-integration' import { getRundownWithBackTime } from 'inews-mixins' -import { ShowStyleUserContext } from '../../__mocks__/context' +import { ShowStyleUserContextMock } from '../../__mocks__/context' import { preprocessConfig as parseShowStyleConfig } from '../../tv2_afvd_showstyle/helpers/config' import { preprocessConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' @@ -18,7 +18,7 @@ const SEGMENT_ID = 'test_segment' const PART_ID = 'test_part' function getMockContext(): IShowStyleUserContext { - return new ShowStyleUserContext( + return new ShowStyleUserContextMock( RUNDOWN_NAME, mappingsDefaults, parseStudioConfig, diff --git a/src/tv2-common/__tests__/EvaluateCueTelemetrics.spec.ts b/src/tv2-common/__tests__/EvaluateCueTelemetrics.spec.ts index 76953e1c..276d1565 100644 --- a/src/tv2-common/__tests__/EvaluateCueTelemetrics.spec.ts +++ b/src/tv2-common/__tests__/EvaluateCueTelemetrics.spec.ts @@ -1,5 +1,5 @@ import { IBlueprintPiece, PieceLifespan, TSR } from 'blueprints-integration' -import { CueType, RobotCameraLayer, SharedOutputLayers, SharedSourceLayers } from '../../tv2-constants' +import { CueType, RobotCameraLayer, SharedOutputLayer, SharedSourceLayer } from '../../tv2-constants' import { EvaluateCueRobotCamera } from '../cues/EvaluateCueRobotCamera' import { CueDefinitionRobotCamera } from '../inewsConversion' @@ -70,7 +70,7 @@ describe('EvaluateCueRobotCamera', () => { EvaluateCueRobotCamera(cueDefinition, pieces, '') - expect(pieces[0].sourceLayerId).toEqual(SharedSourceLayers.RobotCamera) + expect(pieces[0].sourceLayerId).toEqual(SharedSourceLayer.RobotCamera) }) it('has SEC for output layer', () => { @@ -79,7 +79,7 @@ describe('EvaluateCueRobotCamera', () => { EvaluateCueRobotCamera(cueDefinition, pieces, '') - expect(pieces[0].outputLayerId).toEqual(SharedOutputLayers.SEC) + expect(pieces[0].outputLayerId).toEqual(SharedOutputLayer.SEC) }) it('receives cameraPreset 1, blueprint piece name is Robot[1]', () => { @@ -148,14 +148,14 @@ describe('EvaluateCueRobotCamera', () => { it('already has a piece with another sourceLayer, creates a new piece', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition() - const pieces: IBlueprintPiece[] = [createRobotCameraBlueprintPiece(SharedSourceLayers.PgmDesign)] + const pieces: IBlueprintPiece[] = [createRobotCameraBlueprintPiece(SharedSourceLayer.PgmDesign)] EvaluateCueRobotCamera(cueDefinition, pieces, 'someOtherExternalId') expect(pieces.length).toEqual(2) }) - function createRobotCameraBlueprintPiece(sourceLayer: SharedSourceLayers, startTimeInMs?: number): IBlueprintPiece { + function createRobotCameraBlueprintPiece(sourceLayer: SharedSourceLayer, startTimeInMs?: number): IBlueprintPiece { return { externalId: '', name: 'Robot', @@ -175,7 +175,7 @@ describe('EvaluateCueRobotCamera', () => { it('has another start time, creates another blueprint piece', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition(1, 20) - const existingPiece: IBlueprintPiece = createRobotCameraBlueprintPiece(SharedSourceLayers.RobotCamera, 10000) + const existingPiece: IBlueprintPiece = createRobotCameraBlueprintPiece(SharedSourceLayer.RobotCamera, 10000) existingPiece.content.timelineObjects.push(createTelemetricsTimelineObject(2)) const pieces: IBlueprintPiece[] = [existingPiece] @@ -203,7 +203,7 @@ describe('EvaluateCueRobotCamera', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition(1, startTime) const existingPiece: IBlueprintPiece = createRobotCameraBlueprintPiece( - SharedSourceLayers.RobotCamera, + SharedSourceLayer.RobotCamera, startTime * 1000 ) existingPiece.content.timelineObjects.push(createTelemetricsTimelineObject()) @@ -219,7 +219,7 @@ describe('EvaluateCueRobotCamera', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition(2, startTime) const existingPiece: IBlueprintPiece = createRobotCameraBlueprintPiece( - SharedSourceLayers.RobotCamera, + SharedSourceLayer.RobotCamera, startTime * 1000 ) existingPiece.content.timelineObjects.push(createTelemetricsTimelineObject(1)) @@ -235,7 +235,7 @@ describe('EvaluateCueRobotCamera', () => { it('has a blueprint piece with same start time and same presetIdentifier, no presetIdentifier is added', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition(1) - const existingPiece: IBlueprintPiece = createRobotCameraBlueprintPiece(SharedSourceLayers.RobotCamera) + const existingPiece: IBlueprintPiece = createRobotCameraBlueprintPiece(SharedSourceLayer.RobotCamera) existingPiece.name = 'Robot[1]' existingPiece.content.timelineObjects.push(createTelemetricsTimelineObject(1)) const pieces: IBlueprintPiece[] = [existingPiece] @@ -250,7 +250,7 @@ describe('EvaluateCueRobotCamera', () => { it('has a blueprint piece with same start time and same presetIdentifier, no new timeline object is created', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition(1) - const existingPiece: IBlueprintPiece = createRobotCameraBlueprintPiece(SharedSourceLayers.RobotCamera) + const existingPiece: IBlueprintPiece = createRobotCameraBlueprintPiece(SharedSourceLayer.RobotCamera) existingPiece.name = 'Robot[1]' existingPiece.content.timelineObjects.push(createTelemetricsTimelineObject(1)) const pieces: IBlueprintPiece[] = [existingPiece] @@ -263,7 +263,7 @@ describe('EvaluateCueRobotCamera', () => { it('has a blueprint piece with same start time, name is updated to reflect presets in the piece', () => { const cueDefinition: CueDefinitionRobotCamera = createRobotCameraCueDefinition(2) - const existingPiece: IBlueprintPiece = createRobotCameraBlueprintPiece(SharedSourceLayers.RobotCamera) + const existingPiece: IBlueprintPiece = createRobotCameraBlueprintPiece(SharedSourceLayer.RobotCamera) existingPiece.name = 'Robot[1]' existingPiece.content.timelineObjects.push(createTelemetricsTimelineObject(1)) const pieces: IBlueprintPiece[] = [existingPiece] diff --git a/src/tv2-common/actions/context.ts b/src/tv2-common/actions/context.ts index 8ae60032..bb4e0d49 100644 --- a/src/tv2-common/actions/context.ts +++ b/src/tv2-common/actions/context.ts @@ -8,13 +8,10 @@ import { IBlueprintPieceInstance, IBlueprintResolvedPieceInstance } from 'blueprints-integration' -import { ExtendedShowStyleContextImpl, PieceMetaData, TV2ShowStyleConfig, UniformConfig } from 'tv2-common' +import { PieceMetaData, ShowStyleContextImpl, TV2ShowStyleConfig, UniformConfig } from 'tv2-common' import { CoreActionExecutionContext } from './CoreActionExecutionContext' export interface ITV2ActionExecutionContext extends IActionExecutionContext { - /** To prompt type errors for wrong context type */ - isTV2Context: true - getPieceInstances(part: 'current' | 'next'): Promise>> getResolvedPieceInstances(part: 'current' | 'next'): Promise>> @@ -47,9 +44,9 @@ export interface ITV2ActionExecutionContext extends IActionExecutionContext { updatePartInstance(part: 'current' | 'next', props: Partial): Promise } -export class ExtendedActionExecutionContext< +export class ActionExecutionContext< BlueprintConfig extends TV2ShowStyleConfig = TV2ShowStyleConfig -> extends ExtendedShowStyleContextImpl { +> extends ShowStyleContextImpl { constructor(readonly core: CoreActionExecutionContext, uniformConfig: UniformConfig) { super(core, uniformConfig) this.core = core @@ -59,10 +56,10 @@ export class ExtendedActionExecutionContext< export async function executeWithContext( coreContext: IActionExecutionContext, uniformConfig: UniformConfig, - func: (context: ExtendedActionExecutionContext) => Promise + func: (context: ActionExecutionContext) => Promise ): Promise { const coreContextWrapped = new CoreActionExecutionContext(coreContext) - const context = new ExtendedActionExecutionContext(coreContextWrapped, uniformConfig) + const context = new ActionExecutionContext(coreContextWrapped, uniformConfig) await func(context) await coreContextWrapped.afterActions() } diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 182cae3d..49315992 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -20,13 +20,14 @@ import { ActionCutSourceToBox, ActionCutToCamera, ActionCutToRemote, + ActionExecutionContext, ActionSelectDVE, ActionSelectDVELayout, ActionSelectFullGrafik, ActionSelectServerClip, calculateTime, - CreateDipTransitionBlueprintPieceForPart, - CreateInTransitionForTransitionStyle, + createDipTransitionBlueprintPieceForPart, + createInTransitionForTransitionStyle, CreatePartServerBase, CueDefinition, CueDefinitionDVE, @@ -36,12 +37,11 @@ import { DVESources, EvaluateCuesOptions, executeWithContext, - ExtendedActionExecutionContext, - ExtendedShowStyleContext, GetDVETemplate, getServerPosition, GetSisyfosTimelineObjForCamera, GetSisyfosTimelineObjForRemote, + getTimeFromFrames, GraphicPilot, literal, MakeContentDVE2, @@ -49,8 +49,8 @@ import { PieceMetaData, PilotGraphicGenerator, ServerSelectMode, + ShowStyleContext, SisyfosPersistMetaData, - TimeFromFrames, TimelineBlueprintExt, TransitionStyle, TV2AdlibAction, @@ -64,8 +64,8 @@ import { CueType, PartType, SharedGraphicLLayer, - SharedOutputLayers, - SharedSourceLayers, + SharedOutputLayer, + SharedSourceLayer, SourceType, TallyTags } from 'tv2-constants' @@ -88,14 +88,14 @@ import { assertUnreachable } from '../util' import { ActionSelectJingle, ActionTakeWithTransition } from './actionTypes' const STOPPABLE_GRAPHICS_LAYERS = [ - SharedSourceLayers.PgmGraphicsIdent, - SharedSourceLayers.PgmGraphicsTop, - SharedSourceLayers.PgmGraphicsLower, - SharedSourceLayers.PgmGraphicsHeadline, - SharedSourceLayers.PgmGraphicsTema, - SharedSourceLayers.PgmGraphicsOverlay, - SharedSourceLayers.PgmPilotOverlay, - SharedSourceLayers.PgmGraphicsTLF + SharedSourceLayer.PgmGraphicsIdent, + SharedSourceLayer.PgmGraphicsTop, + SharedSourceLayer.PgmGraphicsLower, + SharedSourceLayer.PgmGraphicsHeadline, + SharedSourceLayer.PgmGraphicsTema, + SharedSourceLayer.PgmGraphicsOverlay, + SharedSourceLayer.PgmPilotOverlay, + SharedSourceLayer.PgmGraphicsTLF ] const FADE_SISYFOS_LEVELS_PIECE_NAME = 'fadeDown' @@ -105,7 +105,7 @@ export interface ActionExecutionSettings< ShowStyleConfig extends TV2BlueprintConfigBase > { EvaluateCues: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, part: IBlueprintPart, pieces: IBlueprintPiece[], adLibPieces: IBlueprintAdLibPiece[], @@ -154,7 +154,7 @@ export interface ActionExecutionSettings< SELECTED_ADLIB_LAYERS: string[] } createJingleContent: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, file: string, alphaAtStart: number, loadFirstFrame: boolean, @@ -281,7 +281,7 @@ async function getExistingTransition< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, part: 'current' | 'next' ): Promise { @@ -351,7 +351,7 @@ function sanitizePieceId(piece: IBlueprintPieceDB): IBlueprintPie } export async function getPiecesToPreserve( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, adlibLayers: string[], ignoreLayers: string[] ): Promise>> { @@ -378,7 +378,7 @@ export async function getPiecesToPreserve( }) } -function generateExternalId(context: ExtendedActionExecutionContext, actionId: string, args: string[]): string { +function generateExternalId(context: ActionExecutionContext, actionId: string, args: string[]): string { return `adlib_action_${actionId}_${context.core.getHashId(args.join('_'), true)}` } @@ -386,7 +386,7 @@ async function executeActionSelectServerClip< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionSelectServerClip, @@ -516,7 +516,7 @@ async function executeActionSelectDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionSelectDVE @@ -566,7 +566,7 @@ async function executeActionSelectDVE< start, ...(end ? { duration: end - start } : {}) }, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, sourceLayerId: settings.SourceLayers.DVE, lifespan: PieceLifespan.WithinPart, toBeQueued: true, @@ -602,7 +602,7 @@ async function cutServerToBox< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, newDvePiece: IBlueprintPiece, containedServerBefore?: boolean, @@ -680,18 +680,14 @@ async function cutServerToBox< return newDvePiece } -function stopServerMetaData(context: ExtendedActionExecutionContext, metaData: DVEPieceMetaData) { +function stopServerMetaData(context: ActionExecutionContext, metaData: DVEPieceMetaData) { const length = metaData.serverPlaybackTiming?.length if (metaData.serverPlaybackTiming && length) { metaData.serverPlaybackTiming[length - 1].end = context.core.getCurrentTime() } } -function startServerMetaData( - context: ExtendedActionExecutionContext, - metaData: DVEPieceMetaData, - modifiesCurrent?: boolean -) { +function startServerMetaData(context: ActionExecutionContext, metaData: DVEPieceMetaData, modifiesCurrent?: boolean) { if (!metaData.serverPlaybackTiming) { metaData.serverPlaybackTiming = [] } @@ -702,7 +698,7 @@ async function executeActionSelectDVELayout< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionSelectDVELayout @@ -771,7 +767,7 @@ async function executeActionSelectDVELayout< lifespan: PieceLifespan.WithinPart, name: userData.config.DVEName, sourceLayerId: settings.SourceLayers.DVEAdLib, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, metaData: newMetaData, content: content.content } @@ -834,7 +830,7 @@ async function startNewDVELayout< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, dvePiece: IBlueprintPiece, pieceContent: WithTimeline, @@ -926,7 +922,7 @@ async function executeActionSelectJingle< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionSelectJingle @@ -968,9 +964,9 @@ async function executeActionSelectJingle< start: 0 }, lifespan: PieceLifespan.WithinPart, - outputLayerId: SharedOutputLayers.JINGLE, + outputLayerId: SharedOutputLayer.JINGLE, sourceLayerId: settings.SourceLayers.Effekt, - prerollDuration: context.config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), + prerollDuration: context.config.studio.CasparPrerollDuration + getTimeFromFrames(Number(jingle.StartAlpha)), content: pieceContent, tags: [ GetTagForJingle(userData.segmentExternalId, userData.clip), @@ -1007,7 +1003,7 @@ async function executeActionCutToCamera< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionCutToCamera @@ -1040,7 +1036,7 @@ async function executeActionCutToCamera< externalId, name: part.title, enable: { start: 0 }, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, sourceLayerId: settings.SourceLayers.Cam, lifespan: PieceLifespan.WithinPart, metaData: { @@ -1113,7 +1109,7 @@ async function executeActionCutToCamera< } async function stopGraphicPiecesThatShouldEndWithPart( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, currentPieceInstances: Array> ) { await context.core.stopPieceInstances( @@ -1135,7 +1131,7 @@ async function executeActionCutToRemote< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionCutToRemote @@ -1175,7 +1171,7 @@ async function executeActionCutToRemote< start: 0 }, sourceLayerId: settings.SourceLayers.Live, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, toBeQueued: true, metaData: { @@ -1191,7 +1187,7 @@ async function executeActionCutToRemote< input: sourceInfo.port, transition: TransitionStyle.CUT }, - classes: [ControlClasses.OVERRIDEN_ON_MIX_MINUS] + classes: [ControlClasses.OVERRIDDEN_ON_MIX_MINUS] }), ...eksternSisyfos ]) @@ -1210,7 +1206,7 @@ async function executeActionCutSourceToBox< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, _actionId: string, userData: ActionCutSourceToBox @@ -1355,7 +1351,7 @@ async function executeActionTakeWithTransition< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, actionId: string, userData: ActionTakeWithTransition @@ -1403,7 +1399,7 @@ async function executeActionTakeWithTransition< externalId, name: 'CUT', sourceLayerId: settings.SourceLayers.Effekt, - outputLayerId: SharedOutputLayers.JINGLE, + outputLayerId: SharedOutputLayer.JINGLE, lifespan: PieceLifespan.WithinPart, tags: [GetTagForTransition(userData.variant)], content: { @@ -1457,7 +1453,7 @@ async function executeActionTakeWithTransition< settings.SourceLayers.Effekt ) - partProps = CreateInTransitionForTransitionStyle(userData.variant.frames) + partProps = createInTransitionForTransitionStyle(userData.variant.frames) await context.core.updatePartInstance('next', partProps) await context.core.insertPiece('next', { ...blueprintPiece, tags: [GetTagForTransition(userData.variant)] }) @@ -1471,13 +1467,13 @@ async function executeActionTakeWithTransition< TransitionStyle.DIP, userData.variant.frames ) - const blueprintPiece = CreateDipTransitionBlueprintPieceForPart( + const blueprintPiece = createDipTransitionBlueprintPieceForPart( externalId, userData.variant.frames, settings.SourceLayers.Effekt ) - partProps = CreateInTransitionForTransitionStyle(userData.variant.frames) + partProps = createInTransitionForTransitionStyle(userData.variant.frames) await context.core.updatePartInstance('next', partProps) await context.core.insertPiece('next', { ...blueprintPiece, tags: [GetTagForTransition(userData.variant)] }) break @@ -1486,7 +1482,7 @@ async function executeActionTakeWithTransition< } async function updateTransition( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, timelineObjects: TimelineObjectCoreExt[], pieceInstance: IBlueprintPieceInstance, transitionStyle: TransitionStyle, @@ -1499,7 +1495,7 @@ async function updateTransition( } async function findPieceToRecoverDataFrom( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, dataStoreLayers: string[] ): Promise<{ piece: IBlueprintPieceInstance; part: 'current' | 'next' } | undefined> { const pieces = await Promise.all([context.core.getPieceInstances('current'), context.core.getPieceInstances('next')]) @@ -1532,7 +1528,7 @@ async function findPieceToRecoverDataFrom( } async function findDataStore( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, dataStoreLayers: string[] ): Promise { const dataStorePiece = await findPieceToRecoverDataFrom(context, dataStoreLayers) @@ -1545,7 +1541,7 @@ async function findDataStore( } async function findMediaPlayerSessions( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, sessionLayers: string[] ): Promise<{ session: string | undefined; part: 'current' | 'next' | undefined }> { const mediaPlayerSessionPiece = await findPieceToRecoverDataFrom(context, sessionLayers) @@ -1569,10 +1565,7 @@ async function findMediaPlayerSessions( async function executeActionCommentatorSelectServer< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase ->( - context: ExtendedActionExecutionContext, - settings: ActionExecutionSettings -) { +>(context: ActionExecutionContext, settings: ActionExecutionSettings) { const data = await findDataStore(context, [ settings.SelectedAdlibs.SourceLayer.Server, settings.SelectedAdlibs.SourceLayer.VO @@ -1605,10 +1598,7 @@ async function executeActionCommentatorSelectServer< async function executeActionCommentatorSelectDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase ->( - context: ExtendedActionExecutionContext, - settings: ActionExecutionSettings -) { +>(context: ActionExecutionContext, settings: ActionExecutionSettings) { if (!settings.SelectedAdlibs.SourceLayer.DVE) { return } @@ -1625,11 +1615,8 @@ async function executeActionCommentatorSelectDVE< async function executeActionCommentatorSelectFull< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase ->( - context: ExtendedActionExecutionContext, - settings: ActionExecutionSettings -) { - const data = await findDataStore(context, [SharedSourceLayers.SelectedAdlibGraphicsFull]) +>(context: ActionExecutionContext, settings: ActionExecutionSettings) { + const data = await findDataStore(context, [SharedSourceLayer.SelectedAdlibGraphicsFull]) if (!data) { return @@ -1641,10 +1628,7 @@ async function executeActionCommentatorSelectFull< async function executeActionCommentatorSelectJingle< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase ->( - context: ExtendedActionExecutionContext, - settings: ActionExecutionSettings -) { +>(context: ActionExecutionContext, settings: ActionExecutionSettings) { if (!settings.SelectedAdlibs.SourceLayer.Effekt) { return } @@ -1662,7 +1646,7 @@ async function executeActionRecallLastLive< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, actionId: string ) { @@ -1716,7 +1700,7 @@ async function executeActionRecallLastDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, actionId: string ) { @@ -1738,7 +1722,7 @@ async function executeActionRecallLastDVE< } async function addLatestPieceOnLayerForDve( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, layer: string, actionId: string, dvePiece: IBlueprintPiece @@ -1766,7 +1750,7 @@ async function addLatestPieceOnLayerForDve( await context.core.insertPiece('next', newIdentPiece) } -async function executeActionFadeDownPersistedAudioLevels(context: ExtendedActionExecutionContext) { +async function executeActionFadeDownPersistedAudioLevels(context: ActionExecutionContext) { const fadeSisyfosMetaData = await createFadeSisyfosLevelsMetaData(context) const resetSisyfosPersistedLevelsPiece: IBlueprintPiece = { externalId: 'fadeSisyfosPersistedLevelsDown', @@ -1785,7 +1769,7 @@ async function executeActionFadeDownPersistedAudioLevels(context: ExtendedAction await context.core.insertPiece('current', resetSisyfosPersistedLevelsPiece) } -async function executeActionCallRobotPreset(context: ExtendedActionExecutionContext, preset: number): Promise { +async function executeActionCallRobotPreset(context: ActionExecutionContext, preset: number): Promise { const robotCameraPiece: IBlueprintPiece = createTelemetricsPieceForRobotCamera( `callRobotPreset${preset}`, preset, @@ -1794,7 +1778,7 @@ async function executeActionCallRobotPreset(context: ExtendedActionExecutionCont await context.core.insertPiece('current', robotCameraPiece) } -async function createFadeSisyfosLevelsMetaData(context: ExtendedActionExecutionContext) { +async function createFadeSisyfosLevelsMetaData(context: ActionExecutionContext) { const resolvedPieceInstances = await context.core.getResolvedPieceInstances('current') const emptySisyfosMetaData: SisyfosPersistMetaData = { sisyfosLayers: [] @@ -1824,7 +1808,7 @@ async function scheduleLastPlayedDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, actionId: string, lastPlayedDVE: IBlueprintPieceInstance @@ -1845,7 +1829,7 @@ async function executeActionSelectFull< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, settings: ActionExecutionSettings, userData: ActionSelectFullGrafik ) { @@ -1897,17 +1881,17 @@ async function executeActionSelectFull< fullPiece, fullDataStore, ...(await getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, [ - SharedSourceLayers.SelectedAdlibGraphicsFull + SharedSourceLayer.SelectedAdlibGraphicsFull ])) ]) - await context.core.stopPiecesOnLayers([SharedSourceLayers.SelectedAdlibGraphicsFull]) + await context.core.stopPiecesOnLayers([SharedSourceLayer.SelectedAdlibGraphicsFull]) } async function executeActionClearGraphics< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase ->(context: ExtendedActionExecutionContext, userData: ActionClearGraphics) { +>(context: ActionExecutionContext, userData: ActionClearGraphics) { await context.core.stopPiecesOnLayers(STOPPABLE_GRAPHICS_LAYERS) await context.core.insertPiece('current', { enable: { @@ -1916,8 +1900,8 @@ async function executeActionClearGraphics< }, externalId: 'clearAllGFX', name: userData.label, - sourceLayerId: SharedSourceLayers.PgmAdlibGraphicCmd, - outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SharedSourceLayer.PgmAdlibGraphicCmd, + outputLayerId: SharedOutputLayer.SEC, lifespan: PieceLifespan.WithinPart, content: context.config.studio.GraphicsType === 'HTML' diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 16c68346..25988c42 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -60,6 +60,12 @@ export interface TableConfigGfxSetup { FullShowName?: string } +export interface ProcessedStudioConfig { + sources: SourceMapping + mediaPlayers: MediaPlayerConfig // Atem Input Ids + dsk: TableConfigItemDSK[] +} + export interface TV2StudioConfigBase { MaximumPartDuration: number DefaultPartDuration: number diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 8e676d9a..ac612fb4 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -14,7 +14,6 @@ import { CueDefinitionDVE, DVEConfigInput, DVESources, - ExtendedShowStyleContext, FindDSKFullGFX, findSourceInfo, getMixMinusTimelineObject, @@ -23,6 +22,7 @@ import { MixMinusPriority, PartDefinition, PieceMetaData, + ShowStyleContext, SpecialInput, TransitionStyle, TV2BlueprintConfigBase, @@ -119,7 +119,7 @@ export function MakeContentDVEBase< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, parsedCue: CueDefinitionDVE, dveConfig: DVEConfigInput | undefined, @@ -155,7 +155,7 @@ export function MakeContentDVE2< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedShowStyleContext, + context: ShowStyleContext, dveConfig: DVEConfigInput, graphicsTemplateContent: { [key: string]: string }, sources: DVESources | undefined, @@ -325,7 +325,7 @@ export function MakeContentDVE2< input: SpecialInput.DVE, transition: TransitionStyle.CUT }, - classes: [ControlClasses.OVERRIDEN_ON_MIX_MINUS] + classes: [ControlClasses.OVERRIDDEN_ON_MIX_MINUS] }), literal({ id: '', diff --git a/src/tv2-common/content/jingle.ts b/src/tv2-common/content/jingle.ts index 97a8e1db..947209c2 100644 --- a/src/tv2-common/content/jingle.ts +++ b/src/tv2-common/content/jingle.ts @@ -1,6 +1,6 @@ import { TimelineObjectCoreExt, TSR, VTContent, WithTimeline } from 'blueprints-integration' -import { ExtendedShowStyleContext, FindDSKJingle, getDskOnAirTimelineObjects, TimeFromFrames } from 'tv2-common' -import { DSKRoles } from 'tv2-constants' +import { FindDSKJingle, getDskOnAirTimelineObjects, getTimeFromFrames, ShowStyleContext } from 'tv2-common' +import { DskRole } from 'tv2-constants' import { TV2BlueprintConfigBase, TV2ShowStyleConfig, TV2StudioConfigBase } from '../blueprintConfig' import { TimelineBlueprintExt } from '../onTimelineGenerate' import { joinAssetToFolder, joinAssetToNetworkPath, literal } from '../util' @@ -37,8 +37,8 @@ export function CreateJingleExpectedMedia( ignoreMediaObjectStatus: config.studio.JingleIgnoreStatus, ignoreBlackFrames: true, ignoreFreezeFrame: true, - sourceDuration: TimeFromFrames(Number(duration) - Number(alphaAtEnd)), - postrollDuration: TimeFromFrames(Number(alphaAtEnd)), + sourceDuration: getTimeFromFrames(Number(duration) - Number(alphaAtEnd)), + postrollDuration: getTimeFromFrames(Number(alphaAtEnd)), timelineObjects: [] }) } @@ -47,7 +47,7 @@ export function CreateJingleContentBase< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedShowStyleContext, + context: ShowStyleContext, file: string, alphaAtStart: number, loadFirstFrame: boolean, @@ -63,7 +63,7 @@ export function CreateJingleContentBase< timelineObjects: literal([ CreateJingleCasparTimelineObject(fileName, loadFirstFrame, layers), - ...getDskOnAirTimelineObjects(context, DSKRoles.JINGLE, { start: Number(config.studio.CasparPrerollDuration) }), + ...getDskOnAirTimelineObjects(context, DskRole.JINGLE, { start: Number(config.studio.CasparPrerollDuration) }), // @todo: this is a Qbox-only feature, should be refactored at some point not to use ATEM object directly ...(context.uniformConfig.switcherLLayers.jingleNextMixEffect diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index c8bd28bd..325e843f 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -1,11 +1,5 @@ import { TimelineObjectCoreExt, TSR, VTContent, WithTimeline } from 'blueprints-integration' -import { - ExtendedShowStyleContext, - GetSisyfosTimelineObjForServer, - literal, - PartDefinition, - TransitionStyle -} from 'tv2-common' +import { GetSisyfosTimelineObjForServer, literal, PartDefinition, ShowStyleContext, TransitionStyle } from 'tv2-common' import { AbstractLLayer, GetEnableClassForServer } from 'tv2-constants' import { TV2ShowStyleConfig } from '../blueprintConfig' import { TimelineBlueprintExt } from '../onTimelineGenerate' @@ -48,7 +42,7 @@ export function GetVTContentProperties( } export function MakeContentServer( - context: ExtendedShowStyleContext, + context: ShowStyleContext, sourceLayers: MakeContentServerSourceLayers, partProps: ServerPartProps, contentProps: ServerContentProps @@ -61,7 +55,7 @@ export function MakeContentServer( } function GetServerTimeline( - context: ExtendedShowStyleContext, + context: ShowStyleContext, sourceLayers: MakeContentServerSourceLayers, partProps: ServerPartProps, contentProps: ServerContentProps @@ -125,7 +119,7 @@ function GetServerTimeline( } export function CutToServer( - context: ExtendedShowStyleContext, + context: ShowStyleContext, mediaPlayerSessionId: string, partDefinition: PartDefinition ): TimelineBlueprintExt[] { diff --git a/src/tv2-common/cueTiming.ts b/src/tv2-common/cueTiming.ts index add1e7d6..d2378b95 100644 --- a/src/tv2-common/cueTiming.ts +++ b/src/tv2-common/cueTiming.ts @@ -1,9 +1,9 @@ import { CueDefinition, CueTime } from './inewsConversion/converters/ParseCue' import { IBlueprintPiece, PieceLifespan } from 'blueprints-integration' -import { TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' +import { FRAME_RATE, TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' -const FRAME_TIME = 1000 / 25 // TODO: This should be pulled from config. +const FRAME_TIME = 1000 / FRAME_RATE // TODO: This should be pulled from config. export function getDefaultOut< StudioConfig extends TV2StudioConfigBase, diff --git a/src/tv2-common/cues/EvaluateCueRobotCamera.ts b/src/tv2-common/cues/EvaluateCueRobotCamera.ts index 2e24ac96..d626706d 100644 --- a/src/tv2-common/cues/EvaluateCueRobotCamera.ts +++ b/src/tv2-common/cues/EvaluateCueRobotCamera.ts @@ -1,5 +1,5 @@ import { IBlueprintPiece, TSR } from 'blueprints-integration' -import { SharedSourceLayers } from '../../tv2-constants' +import { SharedSourceLayer } from '../../tv2-constants' import { calculateTime } from '../cueTiming' import { CueDefinitionRobotCamera } from '../inewsConversion' import { createTelemetricsPieceForRobotCamera, ROBOT_CAMERA_NAME_PREFIX } from '../pieces/telemetric' @@ -29,7 +29,7 @@ function findExistingPieceForRobotCameraLayerAndStartTime( ): IBlueprintPiece | undefined { return pieces.find( (piece) => - piece.sourceLayerId === SharedSourceLayers.RobotCamera && + piece.sourceLayerId === SharedSourceLayer.RobotCamera && piece.name.startsWith(ROBOT_CAMERA_NAME_PREFIX) && piece.enable.start === startTime ) diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index fc6db7b1..e4efd72c 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -8,14 +8,14 @@ import { import { CueDefinitionEkstern, EvaluateCueResult, - ExtendedShowStyleContext, literal, PartDefinition, + ShowStyleContext, TransitionStyle, TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' -import { ControlClasses, SharedOutputLayers, SourceType } from 'tv2-constants' +import { ControlClasses, SharedOutputLayer, SourceType } from 'tv2-constants' import { GetSisyfosTimelineObjForRemote } from '../helpers' import { GetTagForLive } from '../pieces' import { findSourceInfo } from '../sources' @@ -30,7 +30,7 @@ export function EvaluateEksternBase< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedShowStyleContext, + context: ShowStyleContext, part: IBlueprintPart, partId: string, parsedCue: CueDefinitionEkstern, @@ -53,7 +53,7 @@ export function EvaluateEksternBase< _rank: rank || 0, externalId: partId, name: parsedCue.sourceDefinition.name, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, sourceLayerId: layersEkstern.SourceLayer.PgmLive, toBeQueued: true, lifespan: PieceLifespan.WithinPart, @@ -75,7 +75,7 @@ export function EvaluateEksternBase< transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration }, - classes: [ControlClasses.OVERRIDEN_ON_MIX_MINUS] + classes: [ControlClasses.OVERRIDDEN_ON_MIX_MINUS] }), ...GetSisyfosTimelineObjForRemote(context.config, sourceInfoEkstern) @@ -90,7 +90,7 @@ export function EvaluateEksternBase< enable: { start: 0 }, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, sourceLayerId: layersEkstern.SourceLayer.PgmLive, lifespan: PieceLifespan.WithinPart, toBeQueued: true, @@ -113,7 +113,7 @@ export function EvaluateEksternBase< transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration }, - classes: [ControlClasses.OVERRIDEN_ON_MIX_MINUS] + classes: [ControlClasses.OVERRIDDEN_ON_MIX_MINUS] }), ...GetSisyfosTimelineObjForRemote(context.config, sourceInfoEkstern) diff --git a/src/tv2-common/cues/lyd.ts b/src/tv2-common/cues/lyd.ts index 22e7bc8b..b0a9c5c9 100644 --- a/src/tv2-common/cues/lyd.ts +++ b/src/tv2-common/cues/lyd.ts @@ -10,26 +10,26 @@ import { } from 'blueprints-integration' import { CueDefinitionLYD, - ExtendedShowStyleContext, + getTimeFromFrames, getTimingEnable, joinAssetToFolder, literal, PartDefinition, - TimeFromFrames + ShowStyleContext } from 'tv2-common' import { AbstractLLayer, AdlibTags, ControlClasses, SharedCasparLLayer, - SharedOutputLayers, + SharedOutputLayer, SharedSisyfosLLayer, - SharedSourceLayers + SharedSourceLayer } from 'tv2-constants' import { TV2ShowStyleConfig } from '../blueprintConfig' export function EvaluateLYD( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], _actions: IBlueprintActionManifest[], @@ -62,13 +62,13 @@ export function EvaluateLYD( _rank: rank || 0, externalId: part.externalId, name: parsedCue.variant, - outputLayerId: SharedOutputLayers.MUSIK, - sourceLayerId: SharedSourceLayers.PgmAudioBed, + outputLayerId: SharedOutputLayer.MUSIK, + sourceLayerId: SharedSourceLayer.PgmAudioBed, lifespan, expectedDuration: stop ? 2000 : fade - ? Math.max(1000, fadeIn ? TimeFromFrames(fadeIn) : 0) + ? Math.max(1000, fadeIn ? getTimeFromFrames(fadeIn) : 0) : getTimingEnable(parsedCue).enable.duration ?? undefined, content: LydContent(context.config, file, lydType, fadeIn, fadeOut), tags: [AdlibTags.ADLIB_FLOW_PRODUCER] @@ -83,12 +83,12 @@ export function EvaluateLYD( ? { enable: { start: getTimingEnable(parsedCue).enable.start, - duration: Math.max(1000, fadeIn ? TimeFromFrames(fadeIn) : 0) + duration: Math.max(1000, fadeIn ? getTimeFromFrames(fadeIn) : 0) } } : getTimingEnable(parsedCue)), - outputLayerId: SharedOutputLayers.MUSIK, - sourceLayerId: SharedSourceLayers.PgmAudioBed, + outputLayerId: SharedOutputLayer.MUSIK, + sourceLayerId: SharedSourceLayer.PgmAudioBed, lifespan, content: LydContent(context.config, file, lydType, fadeIn, fadeOut) }) @@ -148,13 +148,13 @@ function LydContent( type: TSR.Transition.MIX, easing: TSR.Ease.LINEAR, direction: TSR.Direction.LEFT, - duration: TimeFromFrames(fadeIn ?? config.studio.AudioBedSettings.fadeIn ?? 0) + duration: getTimeFromFrames(fadeIn ?? config.studio.AudioBedSettings.fadeIn ?? 0) }, outTransition: { type: TSR.Transition.MIX, easing: TSR.Ease.LINEAR, direction: TSR.Direction.LEFT, - duration: TimeFromFrames(fadeOut ?? config.studio.AudioBedSettings.fadeOut ?? 0) + duration: getTimeFromFrames(fadeOut ?? config.studio.AudioBedSettings.fadeOut ?? 0) } } }, diff --git a/src/tv2-common/cues/mixMinus.ts b/src/tv2-common/cues/mixMinus.ts index 4de582e9..1de79865 100644 --- a/src/tv2-common/cues/mixMinus.ts +++ b/src/tv2-common/cues/mixMinus.ts @@ -1,9 +1,9 @@ import { IBlueprintPiece, PieceLifespan, TSR } from 'blueprints-integration' -import { CueDefinitionMixMinus, ExtendedShowStyleContext, findSourceInfo, PartDefinition } from 'tv2-common' -import { ControlClasses, SharedOutputLayers, SharedSourceLayers, SwitcherAuxLLayer } from 'tv2-constants' +import { CueDefinitionMixMinus, findSourceInfo, PartDefinition, ShowStyleContext } from 'tv2-common' +import { ControlClasses, SharedOutputLayer, SharedSourceLayer, SwitcherAuxLLayer } from 'tv2-constants' export function EvaluateCueMixMinus( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], part: PartDefinition, parsedCue: CueDefinitionMixMinus @@ -29,8 +29,8 @@ export function EvaluateCueMixMinus( start: 0 }, lifespan: PieceLifespan.OutOnShowStyleEnd, - sourceLayerId: SharedSourceLayers.AuxMixMinus, - outputLayerId: SharedOutputLayers.AUX, + sourceLayerId: SharedSourceLayer.AuxMixMinus, + outputLayerId: SharedOutputLayer.AUX, content: { timelineObjects: [getMixMinusTimelineObject(context, switcherInput, MixMinusPriority.MINUSKAM_CUE)] } @@ -44,7 +44,7 @@ export enum MixMinusPriority { } export function getMixMinusTimelineObject( - context: ExtendedShowStyleContext, + context: ShowStyleContext, switcherInput: number, priority: MixMinusPriority ): TSR.TSRTimelineObj { @@ -53,7 +53,7 @@ export function getMixMinusTimelineObject( input: switcherInput }, enable: { - while: `.${ControlClasses.OVERRIDEN_ON_MIX_MINUS}` + while: `.${ControlClasses.OVERRIDDEN_ON_MIX_MINUS}` }, layer: SwitcherAuxLLayer.AuxVideoMixMinus, priority diff --git a/src/tv2-common/evaluateCues.ts b/src/tv2-common/evaluateCues.ts index d7d27ab8..4e13eca1 100644 --- a/src/tv2-common/evaluateCues.ts +++ b/src/tv2-common/evaluateCues.ts @@ -17,10 +17,10 @@ import { CueDefinitionLYD, CueDefinitionRobotCamera, CueDefinitionTelefon, - ExtendedShowStyleContext, IsTargetingFull, IsTargetingOVL, - PartDefinition + PartDefinition, + ShowStyleContext } from 'tv2-common' import { CueType } from 'tv2-constants' import { TV2ShowStyleConfig } from './blueprintConfig' @@ -53,14 +53,14 @@ export class EvaluateCueResult { } export interface EvaluateCuesShowstyleOptions { EvaluateCueGraphic?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partId: string, parsedCue: CueDefinitionGraphic, partDefinition: PartDefinition, adlib?: Adlib ) => EvaluateCueResult EvaluateCueBackgroundLoop?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -70,7 +70,7 @@ export interface EvaluateCuesShowstyleOptions { rank?: number ) => void EvaluateCueGraphicDesign?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -80,12 +80,12 @@ export interface EvaluateCuesShowstyleOptions { rank?: number ) => void EvaluateCueRouting?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partId: string, parsedCue: CueDefinitionRouting ) => EvaluateCueResult EvaluateCueEkstern?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, part: IBlueprintPart, partId: string, parsedCue: CueDefinitionEkstern, @@ -94,7 +94,7 @@ export interface EvaluateCuesShowstyleOptions { rank?: number ) => EvaluateCueResult EvaluateCueDVE?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], actions: IBlueprintActionManifest[], partDefinition: PartDefinition, @@ -103,7 +103,7 @@ export interface EvaluateCuesShowstyleOptions { rank?: number ) => void EvaluateCueAdLib?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, actions: IBlueprintActionManifest[], mediaSubscriptions: HackPartMediaObjectSubscription[], parsedCue: CueDefinitionAdLib, @@ -111,14 +111,14 @@ export interface EvaluateCuesShowstyleOptions { rank: number ) => Promise EvaluateCueTelefon?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partId: string, partDefinition: PartDefinition, parsedCue: CueDefinitionTelefon, adlib?: Adlib ) => EvaluateCueResult EvaluateCueJingle?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -129,7 +129,7 @@ export interface EvaluateCuesShowstyleOptions { effekt?: boolean ) => void EvaluateCueLYD?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -139,7 +139,7 @@ export interface EvaluateCuesShowstyleOptions { rank?: number ) => void EvaluateCueClearGrafiks?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -148,13 +148,13 @@ export interface EvaluateCuesShowstyleOptions { shouldAdlib: boolean ) => void EvaluateCuePgmClean?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], partId: string, parsedCue: CueDefinitionPgmClean ) => void EvaluateCueMixMinus?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], part: PartDefinition, parsedCue: CueDefinitionMixMinus @@ -181,7 +181,7 @@ export interface EvaluateCuesOptions { export async function EvaluateCuesBase( showStyleOptions: EvaluateCuesShowstyleOptions, - context: ExtendedShowStyleContext, + context: ShowStyleContext, part: IBlueprintPart, pieces: IBlueprintPiece[], adLibPieces: IBlueprintAdLibPiece[], diff --git a/src/tv2-common/frameTime.ts b/src/tv2-common/frameTime.ts index 351c7e75..c015c6a4 100644 --- a/src/tv2-common/frameTime.ts +++ b/src/tv2-common/frameTime.ts @@ -1,3 +1,5 @@ -export function TimeFromFrames(frames: number): number { - return (1000 / 25) * frames +export const FRAME_RATE = 25 + +export function getTimeFromFrames(frames: number): number { + return (1000 / FRAME_RATE) * frames } diff --git a/src/tv2-common/getSegment.ts b/src/tv2-common/getSegment.ts index b9c15ff6..5aaa4d8e 100644 --- a/src/tv2-common/getSegment.ts +++ b/src/tv2-common/getSegment.ts @@ -1,8 +1,6 @@ import { BlueprintResultPart, BlueprintResultSegment, IBlueprintSegment, IngestSegment } from 'blueprints-integration' import { assertUnreachable, - ExtendedSegmentContext, - ExtendedShowStyleContext, GetNextPartCue, INewsPayload, IsTargetingFull, @@ -11,9 +9,11 @@ import { PartDefinition, PartDefinitionEVS, PartDefinitionKam, - PartMetaData + PartMetaData, + SegmentContext, + ShowStyleContext } from 'tv2-common' -import { CueType, PartType, SharedSourceLayers, TallyTags } from 'tv2-constants' +import { CueType, PartType, SharedSourceLayer, TallyTags } from 'tv2-constants' import { TV2ShowStyleConfig } from './blueprintConfig' import { CueDefinitionUnpairedTarget, @@ -28,64 +28,64 @@ import { CreatePartInvalid, ServerPartProps } from './parts' export interface GetSegmentShowstyleOptions { CreatePartContinuity: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, ingestSegment: IngestSegment ) => BlueprintResultPart CreatePartUnknown: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, totalWords: number, asAdlibs?: boolean ) => BlueprintResultPart | Promise CreatePartIntro?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, totalWords: number ) => BlueprintResultPart | Promise CreatePartKam?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinitionKam, totalWords: number ) => BlueprintResultPart | Promise CreatePartServer?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, partProps: ServerPartProps ) => BlueprintResultPart | Promise CreatePartTeknik?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinitionTeknik, totalWords: number ) => BlueprintResultPart | Promise CreatePartGrafik?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinitionGrafik, totalWords: number ) => BlueprintResultPart | Promise CreatePartEkstern?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinitionEkstern, totalWords: number ) => BlueprintResultPart | Promise CreatePartTelefon?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinitionTelefon, totalWords: number ) => BlueprintResultPart | Promise CreatePartDVE?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinitionDVE, totalWords: number ) => BlueprintResultPart | Promise CreatePartEVS?: ( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinitionEVS, totalWords: number ) => BlueprintResultPart | Promise } export async function getSegmentBase( - context: ExtendedSegmentContext, + context: SegmentContext, ingestSegment: IngestSegment, showStyleOptions: GetSegmentShowstyleOptions ): Promise { @@ -323,7 +323,7 @@ export async function getSegmentBase blueprintParts.length > 1 || (blueprintParts[blueprintParts.length - 1] && !blueprintParts[blueprintParts.length - 1].pieces.some( - (piece) => piece.sourceLayerId === SharedSourceLayers.PgmJingle + (piece) => piece.sourceLayerId === SharedSourceLayer.PgmJingle )) ) { blueprintParts[0].part.budgetDuration = totalTimeMs @@ -338,7 +338,7 @@ export async function getSegmentBase part.part.expectedDuration! < config.studio.DefaultPartDuration && // Jingle-only part, do not modify duration !part.pieces.some( - (p) => p.sourceLayerId === SharedSourceLayers.PgmJingle && p.tags?.some((tag) => TallyTags.JINGLE === tag) + (p) => p.sourceLayerId === SharedSourceLayer.PgmJingle && p.tags?.some((tag) => TallyTags.JINGLE === tag) ) ) { part.part.expectedDuration = config.studio.DefaultPartDuration diff --git a/src/tv2-common/helpers/__tests__/serverResume.spec.ts b/src/tv2-common/helpers/__tests__/serverResume.spec.ts index d96f25f2..742be1c7 100644 --- a/src/tv2-common/helpers/__tests__/serverResume.spec.ts +++ b/src/tv2-common/helpers/__tests__/serverResume.spec.ts @@ -7,7 +7,7 @@ import { WithTimeline } from 'blueprints-integration' import { DVEPieceMetaData, literal, PieceMetaData, RemoteType, SourceDefinitionRemote } from 'tv2-common' -import { SharedSourceLayers, SourceType } from 'tv2-constants' +import { SharedSourceLayer, SourceType } from 'tv2-constants' import { getServerPositionForPartInstance } from '../serverResume' const EKSTERN_SOURCE: SourceDefinitionRemote = { @@ -48,7 +48,7 @@ describe('Server Resume', () => { externalId: '', name: '', lifespan: PieceLifespan.WithinPart, - sourceLayerId: SharedSourceLayers.PgmServer, + sourceLayerId: SharedSourceLayer.PgmServer, outputLayerId: '', content: literal>({ fileName: '123456', @@ -76,7 +76,7 @@ describe('Server Resume', () => { externalId: '', name: '', lifespan: PieceLifespan.WithinPart, - sourceLayerId: SharedSourceLayers.PgmServer, + sourceLayerId: SharedSourceLayer.PgmServer, outputLayerId: '', content: literal>({ fileName: '123456', @@ -116,7 +116,7 @@ describe('Server Resume', () => { externalId: '', name: '', lifespan: PieceLifespan.WithinPart, - sourceLayerId: SharedSourceLayers.PgmDVEAdLib, + sourceLayerId: SharedSourceLayer.PgmDVEAdLib, outputLayerId: '', content: literal>({ boxSourceConfiguration: [], @@ -162,7 +162,7 @@ describe('Server Resume', () => { externalId: '', name: '', lifespan: PieceLifespan.WithinPart, - sourceLayerId: SharedSourceLayers.PgmDVEAdLib, + sourceLayerId: SharedSourceLayer.PgmDVEAdLib, outputLayerId: '', content: literal>({ boxSourceConfiguration: [], diff --git a/src/tv2-common/helpers/abPlayback.ts b/src/tv2-common/helpers/abPlayback.ts index 1e210e25..94db9c30 100644 --- a/src/tv2-common/helpers/abPlayback.ts +++ b/src/tv2-common/helpers/abPlayback.ts @@ -9,7 +9,7 @@ import { TimelineBlueprintExt, TimelinePersistentStateExt } from '../onTimelineGenerate' -import { ExtendedTimelineContext } from '../showstyle' +import { TimelineContext } from '../showstyle' export interface SessionToPlayerMap { [sessionId: string]: MediaPlayerClaim | undefined @@ -184,7 +184,7 @@ export function resolveMediaPlayerAssignments< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedTimelineContext, + context: TimelineContext, previousAssignmentRev: SessionToPlayerMap, resolvedPieces: Array> ) { @@ -248,7 +248,7 @@ function updateObjectsToMediaPlayer< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedTimelineContext, + context: TimelineContext, playerId: number, objs: OnGenerateTimelineObj[], sourceLayers: ABSourceLayers @@ -290,7 +290,9 @@ function updateObjectsToMediaPlayer< context.videoSwitcher.updateUnpopulatedDveBoxes(obj, input) } else { context.core.logWarning( - `Trying to move ATEM object of unknown type (${(obj.content as any).type}) for media player assignment` + `Trying to move Video Switcher object of unknown type (${ + (obj.content as any).type + }) for media player assignment` ) } } else if (obj.content.deviceType === TSR.DeviceType.SISYFOS) { @@ -326,7 +328,7 @@ export function assignMediaPlayers< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedTimelineContext, + context: TimelineContext, timelineObjs: OnGenerateTimelineObj[], previousAssignment: TimelinePersistentStateExt['activeMediaPlayers'], resolvedPieces: Array>, @@ -348,7 +350,7 @@ export function applyMediaPlayersAssignments< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedTimelineContext, + context: TimelineContext, timelineObjs: OnGenerateTimelineObj[], previousAssignmentRev: SessionToPlayerMap, activeRequests: ActiveRequest[], diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index ec314073..56ff5769 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -6,25 +6,25 @@ import { TableConfigItemValue, TSR } from 'blueprints-integration' -import { ExtendedShowStyleContext, getDskLLayerName, literal, SourceLayerAtemDSK, VideoSwitcher } from 'tv2-common' -import { AdlibTags, DSKRoles, SharedOutputLayers } from 'tv2-constants' +import { getDskLLayerName, literal, ShowStyleContext, SourceLayerAtemDSK, VideoSwitcher } from 'tv2-common' +import { AdlibTags, DskRole, SharedOutputLayer } from 'tv2-constants' import { ATEMModel } from '../../types/atem' import { TV2BlueprintConfigBase, TV2ShowStyleConfig, TV2StudioConfigBase } from '../blueprintConfig' import { TableConfigItemDSK } from '../types' export function FindDSKFullGFX(config: TV2ShowStyleConfig): TableConfigItemDSK { - return FindDSKWithRoles(config, [DSKRoles.FULLGFX]) + return FindDSKWithRoles(config, [DskRole.FULLGFX]) } export function FindDSKOverlayGFX(config: TV2ShowStyleConfig): TableConfigItemDSK { - return FindDSKWithRoles(config, [DSKRoles.OVERLAYGFX]) + return FindDSKWithRoles(config, [DskRole.OVERLAYGFX]) } export function FindDSKJingle(config: TV2ShowStyleConfig): TableConfigItemDSK { - return FindDSKWithRoles(config, [DSKRoles.JINGLE]) + return FindDSKWithRoles(config, [DskRole.JINGLE]) } -function FindDSKWithRoles(config: TV2ShowStyleConfig, roles: DSKRoles[]): TableConfigItemDSK { +function FindDSKWithRoles(config: TV2ShowStyleConfig, roles: DskRole[]): TableConfigItemDSK { return config.dsk.find((dsk) => dsk.Roles?.some((role) => roles.includes(role))) ?? config.dsk[0] } @@ -42,8 +42,8 @@ export function GetDSKCount(atemModel: ATEMModel) { } export function getDskOnAirTimelineObjects( - context: ExtendedShowStyleContext, - dskRole: DSKRoles, + context: ShowStyleContext, + dskRole: DskRole, enable?: TSR.TSRTimelineObj['enable'] ): TSR.TSRTimelineObj[] { const dskConf = FindDSKWithRoles(context.config, [dskRole]) @@ -58,7 +58,7 @@ export function getDskOnAirTimelineObjects( config: dskConf } }), - ...(dskRole === DSKRoles.JINGLE && context.uniformConfig.switcherLLayers.jingleUskMixEffect + ...(dskRole === DskRole.JINGLE && context.uniformConfig.switcherLLayers.jingleUskMixEffect ? [ context.videoSwitcher.getMixEffectTimelineObject({ enable, @@ -92,7 +92,7 @@ export function CreateDSKBaselineAdlibs( name: `DSK ${dsk.Number + 1} ON`, _rank: baseRank + dsk.Number, sourceLayerId: SourceLayerAtemDSK(dsk.Number), - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, lifespan: PieceLifespan.OutOnRundownChange, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_NO_NEXT_HIGHLIGHT, AdlibTags.ADLIB_DSK_OFF], invertOnAirState: true, @@ -116,7 +116,7 @@ export function CreateDSKBaselineAdlibs( name: `DSK ${dsk.Number + 1} ON`, _rank: baseRank + dsk.Number, sourceLayerId: SourceLayerAtemDSK(dsk.Number), - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, lifespan: PieceLifespan.OutOnRundownChange, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_NO_NEXT_HIGHLIGHT, AdlibTags.ADLIB_DSK_ON], content: { @@ -161,7 +161,7 @@ export function createDskBaseline( export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { return literal({ id: 'SwitcherSource.DSK', - name: 'Switcher DSK', + name: 'Video Switcher DSK', description: 'Video Switcher Downstream Keyers Fill and Key', type: ConfigManifestEntryType.TABLE, required: false, @@ -181,7 +181,7 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { }, { id: 'Fill', - name: 'Switcher Fill', + name: 'Video Switcher Fill', description: 'Video Switcher input for DSK Fill', type: ConfigManifestEntryType.INT, required: true, @@ -190,7 +190,7 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { }, { id: 'Key', - name: 'Switcher Key', + name: 'Video Switcher Key', description: 'Video Switcher input for DSK Key', type: ConfigManifestEntryType.INT, required: true, @@ -222,7 +222,7 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { type: ConfigManifestEntryType.SELECT, required: true, multiple: true, - options: [DSKRoles.FULLGFX, DSKRoles.OVERLAYGFX, DSKRoles.JINGLE], + options: [DskRole.FULLGFX, DskRole.OVERLAYGFX, DskRole.JINGLE], defaultVal: [], rank: 5 }, diff --git a/src/tv2-common/helpers/graphics/Graphic.ts b/src/tv2-common/helpers/graphics/Graphic.ts index 51306cd5..077f7bf5 100644 --- a/src/tv2-common/helpers/graphics/Graphic.ts +++ b/src/tv2-common/helpers/graphics/Graphic.ts @@ -1,8 +1,7 @@ -import { PieceLifespan, TSR } from 'blueprints-integration' +import { IBlueprintPiece, PieceLifespan, TSR } from 'blueprints-integration' import { calculateTime, CueDefinitionGraphic, - ExtendedShowStyleContext, getDefaultOut, getLifeSpan, getTimingEnable, @@ -10,18 +9,27 @@ import { GraphicIsInternal, IsTargetingTLF, IsTargetingWall, + ShowStyleContext, TableConfigItemGfxTemplate, TV2ShowStyleConfig } from 'tv2-common' -import { GraphicEngine, SharedSourceLayers } from 'tv2-constants' +import { GraphicEngine, SharedSourceLayer } from 'tv2-constants' + +const GFX_LAYERS = new Set([ + SharedSourceLayer.PgmGraphicsHeadline, + SharedSourceLayer.PgmGraphicsIdent, + SharedSourceLayer.PgmGraphicsLower, + SharedSourceLayer.PgmGraphicsOverlay, + SharedSourceLayer.PgmGraphicsTLF, + SharedSourceLayer.PgmGraphicsTema, + SharedSourceLayer.PgmGraphicsTop, + SharedSourceLayer.WallGraphics +]) export abstract class Graphic { protected readonly config: TV2ShowStyleConfig protected readonly engine: GraphicEngine - constructor( - protected context: ExtendedShowStyleContext, - protected cue: CueDefinitionGraphic - ) { + constructor(protected context: ShowStyleContext, protected cue: CueDefinitionGraphic) { this.config = context.config this.engine = cue.target } @@ -30,71 +38,41 @@ export abstract class Graphic { public abstract getTemplateName(): string protected getGraphicDuration(): number | undefined { - if (this.config.showStyle.GfxTemplates) { - const template = this.findGfxTemplate() - if (template && template.OutType && !template.OutType.toString().match(/default/i)) { - return undefined - } + const template = this.findGfxTemplate() + if (template && template.OutType && !template.OutType.toString().match(/default/i)) { + return undefined } return getDefaultOut(this.config) } - protected getSourceLayerForGraphic(name: string) { - const conf = this.config.showStyle.GfxTemplates - ? this.config.showStyle.GfxTemplates.find((gfx) => gfx.VizTemplate.toString() === name) - : undefined + protected getSourceLayer(name: string): SharedSourceLayer { + const template = this.config.showStyle.GfxTemplates.find((gfx) => gfx.VizTemplate.toString() === name) - if (!conf) { - return SharedSourceLayers.PgmGraphicsOverlay + if (template && GFX_LAYERS.has(template.SourceLayer as SharedSourceLayer)) { + return this.getSubstituteLayer(template.SourceLayer as SharedSourceLayer) } - switch (conf.SourceLayer) { - // TODO: When adding more sourcelayers - // This is here to guard against bad user input - case SharedSourceLayers.PgmGraphicsHeadline: - if (this.config.studio.GraphicsType === 'HTML') { - return SharedSourceLayers.PgmGraphicsLower - } - return SharedSourceLayers.PgmGraphicsHeadline - case SharedSourceLayers.PgmGraphicsIdent: - return SharedSourceLayers.PgmGraphicsIdent - case SharedSourceLayers.PgmGraphicsLower: - return SharedSourceLayers.PgmGraphicsLower - case SharedSourceLayers.PgmGraphicsOverlay: - return SharedSourceLayers.PgmGraphicsOverlay - case SharedSourceLayers.PgmGraphicsTLF: - return SharedSourceLayers.PgmGraphicsTLF - case SharedSourceLayers.PgmGraphicsTema: - return SharedSourceLayers.PgmGraphicsTema - case SharedSourceLayers.PgmGraphicsTop: - return SharedSourceLayers.PgmGraphicsTop - case SharedSourceLayers.WallGraphics: - return SharedSourceLayers.WallGraphics - default: - return SharedSourceLayers.PgmGraphicsOverlay - } + return SharedSourceLayer.PgmGraphicsOverlay + } + + protected getSubstituteLayer(sourceLayer: SharedSourceLayer): SharedSourceLayer { + return sourceLayer } - protected createTimingGraphic(): { start: number; duration?: number } { - const ret: { start: number; duration?: number } = { start: 0, duration: 0 } - const start = this.cue.start ? calculateTime(this.cue.start) : 0 - start !== undefined ? (ret.start = start) : (ret.start = 0) - - const duration = this.getGraphicDuration() - const end = this.cue.end - ? this.cue.end.infiniteMode - ? undefined - : calculateTime(this.cue.end) - : duration - ? ret.start + duration - : undefined - ret.duration = end ? end - ret.start : undefined - - return ret + protected getPieceEnable(): IBlueprintPiece['enable'] { + const start = this.cue.start ? calculateTime(this.cue.start) ?? 0 : 0 + let duration + if (this.cue.end) { + const end = calculateTime(this.cue.end) + duration = end ? end - start : undefined + } else { + duration = this.getGraphicDuration() + } + return { start, duration } } - protected GetEnableForGraphic(): TSR.TSRTimelineObj['enable'] { + protected getTimelineObjectEnable(): TSR.TSRTimelineObj['enable'] { if (IsTargetingWall(this.engine)) { return { while: '1' @@ -143,24 +121,24 @@ export abstract class Graphic { } protected FindInfiniteModeFromConfig(): PieceLifespan { - const template = this.getTemplateName() + const templateName = this.getTemplateName() const iNewsName = GraphicIsInternal(this.cue) ? this.cue.graphic.template : undefined - const conf = this.config.showStyle.GfxTemplates.find((gfx) => + const template = this.config.showStyle.GfxTemplates.find((gfx) => gfx.VizTemplate - ? gfx.VizTemplate.toString().toUpperCase() === template.toUpperCase() && + ? gfx.VizTemplate.toString().toUpperCase() === templateName.toUpperCase() && (iNewsName ? gfx.INewsName.toUpperCase() === iNewsName.toUpperCase() : true) : false ) - if (!conf) { + if (!template) { return PieceLifespan.WithinPart } - if (!conf.OutType || !conf.OutType.toString().length) { + if (!template.OutType || !template.OutType.toString().length) { return PieceLifespan.WithinPart } - const type = conf.OutType.toString().toUpperCase() + const type = template.OutType.toString().toUpperCase() if (type !== 'B' && type !== 'S' && type !== 'O') { return PieceLifespan.WithinPart diff --git a/src/tv2-common/helpers/graphics/caspar/HtmlInternalGraphic.ts b/src/tv2-common/helpers/graphics/caspar/HtmlInternalGraphic.ts index 45da5ff7..03b96e0d 100644 --- a/src/tv2-common/helpers/graphics/caspar/HtmlInternalGraphic.ts +++ b/src/tv2-common/helpers/graphics/caspar/HtmlInternalGraphic.ts @@ -1,6 +1,6 @@ import { SomeContent, TSR, WithTimeline } from 'blueprints-integration' -import { CreateHTMLRendererContent, getDskOnAirTimelineObjects, GetTimelineLayerForGraphic, literal } from 'tv2-common' -import { DSKRoles } from 'tv2-constants' +import { CreateHTMLRendererContent, getDskOnAirTimelineObjects, getTimelineLayerForGraphic, literal } from 'tv2-common' +import { DskRole, SharedSourceLayer } from 'tv2-constants' import { InternalGraphic } from '../internal' @@ -11,17 +11,24 @@ export class HtmlInternalGraphic extends InternalGraphic { } } + protected getSubstituteLayer(sourceLayer: SharedSourceLayer): SharedSourceLayer { + if (sourceLayer === SharedSourceLayer.PgmGraphicsHeadline) { + return SharedSourceLayer.PgmGraphicsLower + } + return sourceLayer + } + protected getTimeline(): TSR.TSRTimelineObj[] { return [ literal({ id: '', - enable: this.GetEnableForGraphic(), + enable: this.getTimelineObjectEnable(), priority: 1, - layer: GetTimelineLayerForGraphic(this.config, this.templateName), + layer: getTimelineLayerForGraphic(this.config, this.templateName), content: CreateHTMLRendererContent(this.config, this.templateName, { ...this.cue.graphic.textFields }) }), // Assume DSK is off by default (config table) - ...getDskOnAirTimelineObjects(this.context, DSKRoles.OVERLAYGFX) + ...getDskOnAirTimelineObjects(this.context, DskRole.OVERLAYGFX) ] } } diff --git a/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts index 82b455e8..24e6469e 100644 --- a/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts @@ -13,7 +13,7 @@ import { TimelineBlueprintExt, TransitionStyle } from 'tv2-common' -import { DSKRoles } from 'tv2-constants' +import { DskRole } from 'tv2-constants' import { PilotGraphicGenerator } from '../pilot' @@ -84,7 +84,7 @@ export class HtmlPilotGraphicGenerator extends PilotGraphicGenerator { }), ...(IsTargetingFull(this.engine) ? this.getFullPilotTimeline() - : getDskOnAirTimelineObjects(this.context, DSKRoles.OVERLAYGFX)) + : getDskOnAirTimelineObjects(this.context, DskRole.OVERLAYGFX)) ] } } diff --git a/src/tv2-common/helpers/graphics/caspar/util.ts b/src/tv2-common/helpers/graphics/caspar/util.ts index c06e116d..8ca061db 100644 --- a/src/tv2-common/helpers/graphics/caspar/util.ts +++ b/src/tv2-common/helpers/graphics/caspar/util.ts @@ -1,6 +1,6 @@ import { TSR } from 'blueprints-integration' import { - GetTimelineLayerForGraphic, + getTimelineLayerForGraphic, joinAssetToFolder, layerToHTMLGraphicSlot, Slots, @@ -35,7 +35,7 @@ export function getHtmlTemplateContent( graphicTemplate: string, data: object ): Partial { - const layer = GetTimelineLayerForGraphic(config, graphicTemplate) + const layer = getTimelineLayerForGraphic(config, graphicTemplate) const slot = layerToHTMLGraphicSlot[layer] diff --git a/src/tv2-common/helpers/graphics/design/index.ts b/src/tv2-common/helpers/graphics/design/index.ts index c060a143..93c6d5db 100644 --- a/src/tv2-common/helpers/graphics/design/index.ts +++ b/src/tv2-common/helpers/graphics/design/index.ts @@ -10,15 +10,15 @@ import { import { calculateTime, CueDefinitionGraphicDesign, - ExtendedShowStyleContext, getHtmlTemplateName, literal, + ShowStyleContext, TV2ShowStyleConfig } from 'tv2-common' -import { SharedGraphicLLayer, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' +import { SharedGraphicLLayer, SharedOutputLayer, SharedSourceLayer } from 'tv2-constants' export function EvaluateDesignBase( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], _actions: IBlueprintActionManifest[], @@ -38,8 +38,8 @@ export function EvaluateDesignBase( _rank: rank || 0, externalId: partId, name: parsedCue.design, - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: SharedSourceLayers.PgmDesign, + outputLayerId: SharedOutputLayer.SEC, + sourceLayerId: SharedSourceLayer.PgmDesign, lifespan: PieceLifespan.OutOnShowStyleEnd, content: literal>({ fileName: parsedCue.design, @@ -55,8 +55,8 @@ export function EvaluateDesignBase( enable: { start }, - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: SharedSourceLayers.PgmDesign, + outputLayerId: SharedOutputLayer.SEC, + sourceLayerId: SharedSourceLayer.PgmDesign, lifespan: PieceLifespan.OutOnShowStyleEnd, content: literal>({ fileName: parsedCue.design, diff --git a/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts b/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts index 3e2822b2..e32a132e 100644 --- a/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts +++ b/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts @@ -1,7 +1,6 @@ import { IBlueprintAdLibPiece, IBlueprintPiece, IShowStyleUserContext, PieceLifespan } from 'blueprints-integration' import { CueDefinitionGraphic, - ExtendedShowStyleContext, GraphicInternal, GraphicPieceMetaData, HtmlInternalGraphic, @@ -9,9 +8,10 @@ import { IsTargetingWall, PartDefinition, PieceMetaData, + ShowStyleContext, VizInternalGraphic } from 'tv2-common' -import { AdlibTags, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' +import { AdlibTags, SharedOutputLayer, SharedSourceLayer } from 'tv2-constants' import * as _ from 'underscore' import { Graphic } from '../Graphic' @@ -28,8 +28,8 @@ export abstract class InternalGraphic extends Graphic { protected readonly core: IShowStyleUserContext private readonly partDefinition?: PartDefinition private readonly displayName: string - private readonly sourceLayerId: SharedSourceLayers - private readonly outputLayerId: SharedOutputLayers + private readonly sourceLayerId: SharedSourceLayer + private readonly outputLayerId: SharedOutputLayer private readonly partId?: string private readonly rank?: number private readonly content: IBlueprintPiece['content'] @@ -37,13 +37,13 @@ export abstract class InternalGraphic extends Graphic { protected constructor(graphicProps: InternalGraphicProps) { super(graphicProps.context, graphicProps.parsedCue) this.templateName = this.getTemplateName() - this.sourceLayerId = this.getSourceLayerForGraphic(this.templateName) + this.sourceLayerId = this.getSourceLayer(this.templateName) this.core = graphicProps.context.core this.context = graphicProps.context this.cue = graphicProps.parsedCue this.partDefinition = graphicProps.partDefinition this.displayName = this.getDisplayName() - this.outputLayerId = IsTargetingWall(this.engine) ? SharedOutputLayers.SEC : SharedOutputLayers.OVERLAY + this.outputLayerId = IsTargetingWall(this.engine) ? SharedOutputLayer.SEC : SharedOutputLayer.OVERLAY this.partId = graphicProps.partId this.content = this.getContent() } @@ -55,7 +55,7 @@ export abstract class InternalGraphic extends Graphic { name: this.displayName, uniquenessId: `gfx_${this.displayName}_${this.sourceLayerId}_${this.outputLayerId}_commentator`, sourceLayerId: this.sourceLayerId, - outputLayerId: SharedOutputLayers.OVERLAY, + outputLayerId: SharedOutputLayer.OVERLAY, lifespan: PieceLifespan.WithinPart, metaData: { sisyfosPersistMetaData: { @@ -80,7 +80,7 @@ export abstract class InternalGraphic extends Graphic { ...(IsTargetingTLF(this.engine) || (this.cue.end && this.cue.end.infiniteMode) ? {} : { - expectedDuration: this.createTimingGraphic().duration + expectedDuration: this.getPieceEnable().duration }), lifespan: this.getPieceLifespan(), metaData: { @@ -99,7 +99,7 @@ export abstract class InternalGraphic extends Graphic { ...(IsTargetingTLF(this.engine) || IsTargetingWall(this.engine) ? { enable: { start: 0 } } : { - enable: this.createTimingGraphic() + enable: this.getPieceEnable() }), outputLayerId: this.outputLayerId, sourceLayerId: this.sourceLayerId, @@ -142,7 +142,7 @@ export abstract class InternalGraphic extends Graphic { } export interface InternalGraphicProps { - context: ExtendedShowStyleContext + context: ShowStyleContext parsedCue: CueDefinitionGraphic partId?: string partDefinition?: PartDefinition diff --git a/src/tv2-common/helpers/graphics/internal/create.ts b/src/tv2-common/helpers/graphics/internal/create.ts index f23de9cc..faf90e81 100644 --- a/src/tv2-common/helpers/graphics/internal/create.ts +++ b/src/tv2-common/helpers/graphics/internal/create.ts @@ -2,15 +2,15 @@ import { Adlib, CueDefinitionGraphic, EvaluateCueResult, - ExtendedShowStyleContext, GraphicInternal, InternalGraphic, IsTargetingOVL, - PartDefinition + PartDefinition, + ShowStyleContext } from 'tv2-common' export function CreateInternalGraphic( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partId: string, parsedCue: CueDefinitionGraphic, partDefinition: PartDefinition, diff --git a/src/tv2-common/helpers/graphics/layers.ts b/src/tv2-common/helpers/graphics/layers.ts index 6a8ebd8e..8c8bd839 100644 --- a/src/tv2-common/helpers/graphics/layers.ts +++ b/src/tv2-common/helpers/graphics/layers.ts @@ -1,10 +1,8 @@ import { TV2ShowStyleConfig } from 'tv2-common' import { SharedGraphicLLayer } from 'tv2-constants' -export function GetTimelineLayerForGraphic(config: TV2ShowStyleConfig, name: string) { - const conf = config.showStyle.GfxTemplates - ? config.showStyle.GfxTemplates.find((gfx) => gfx.VizTemplate.toString() === name) - : undefined +export function getTimelineLayerForGraphic(config: TV2ShowStyleConfig, name: string) { + const conf = config.showStyle.GfxTemplates.find((gfx) => gfx.VizTemplate.toString() === name) if (!conf) { return SharedGraphicLLayer.GraphicLLayerOverlay diff --git a/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts index d34471b5..4becf094 100644 --- a/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts @@ -13,7 +13,6 @@ import { Adlib, assertUnreachable, CueDefinitionGraphic, - ExtendedShowStyleContext, FullPieceMetaData, generateExternalId, GetTagForFull, @@ -24,6 +23,7 @@ import { IsTargetingWall, literal, PieceMetaData, + ShowStyleContext, SisyfosPersistMetaData, t, TV2ShowStyleConfig, @@ -34,14 +34,14 @@ import { AdlibTags, GraphicEngine, SharedGraphicLLayer, - SharedOutputLayers, - SharedSourceLayers, + SharedOutputLayer, + SharedSourceLayer, TallyTags } from 'tv2-constants' import { Graphic } from '../index' export interface PilotGraphicProps { - context: ExtendedShowStyleContext + context: ShowStyleContext partId: string parsedCue: CueDefinitionGraphic adlib?: Adlib @@ -95,8 +95,8 @@ export abstract class PilotGraphicGenerator extends Graphic { display: { _rank: (this.adlib && this.adlib.rank) || 0, label: t(this.getTemplateName()), - sourceLayerId: SharedSourceLayers.PgmPilot, - outputLayerId: SharedOutputLayers.PGM, + sourceLayerId: SharedSourceLayer.PgmPilot, + outputLayerId: SharedOutputLayer.PGM, content: this.getContent(), uniquenessId: `gfx_${name}_${sourceLayerId}_${outputLayerId}`, tags: [ @@ -118,7 +118,7 @@ export abstract class PilotGraphicGenerator extends Graphic { ...(IsTargetingFull(this.engine) || IsTargetingWall(this.engine) ? { enable: { start: 0 } } : { - enable: this.createTimingGraphic() + enable: this.getPieceEnable() }), outputLayerId: this.getOutputLayer(), sourceLayerId: this.getSourceLayer(), @@ -161,8 +161,8 @@ export abstract class PilotGraphicGenerator extends Graphic { enable: { start: 0 }, - outputLayerId: SharedOutputLayers.SELECTED_ADLIB, - sourceLayerId: SharedSourceLayers.SelectedAdlibGraphicsFull, + outputLayerId: SharedOutputLayer.SELECTED_ADLIB, + sourceLayerId: SharedSourceLayer.SelectedAdlibGraphicsFull, lifespan: PieceLifespan.OutOnSegmentEnd, metaData: { userData: { @@ -194,30 +194,30 @@ export abstract class PilotGraphicGenerator extends Graphic { : this.config.studio.VizPilotGraphics.PrerollDuration } - protected getSourceLayer(): SharedSourceLayers { + protected getSourceLayer(): SharedSourceLayer { switch (this.engine) { case 'WALL': - return SharedSourceLayers.WallGraphics + return SharedSourceLayer.WallGraphics case 'TLF': - return SharedSourceLayers.PgmGraphicsTLF + return SharedSourceLayer.PgmGraphicsTLF case 'OVL': - return SharedSourceLayers.PgmPilotOverlay + return SharedSourceLayer.PgmPilotOverlay case 'FULL': - return SharedSourceLayers.PgmPilot + return SharedSourceLayer.PgmPilot default: assertUnreachable(this.engine) } } - protected getOutputLayer(): SharedOutputLayers { + protected getOutputLayer(): SharedOutputLayer { switch (this.engine) { case 'WALL': - return SharedOutputLayers.SEC + return SharedOutputLayer.SEC case 'OVL': - return SharedOutputLayers.OVERLAY + return SharedOutputLayer.OVERLAY case 'FULL': case 'TLF': - return SharedOutputLayers.PGM + return SharedOutputLayer.PGM default: assertUnreachable(this.engine) } diff --git a/src/tv2-common/helpers/graphics/util.ts b/src/tv2-common/helpers/graphics/util.ts index ad954333..1c661ff7 100644 --- a/src/tv2-common/helpers/graphics/util.ts +++ b/src/tv2-common/helpers/graphics/util.ts @@ -1,7 +1,7 @@ import { IBlueprintPart, TSR } from 'blueprints-integration' import { getHtmlGraphicBaseline, TV2ShowStyleConfig } from 'tv2-common' -export function ApplyFullGraphicPropertiesToPart(config: TV2ShowStyleConfig, part: IBlueprintPart) { +export function applyFullGraphicPropertiesToPart(config: TV2ShowStyleConfig, part: IBlueprintPart) { const keepAliveDuration = config.studio.GraphicsType === 'HTML' ? config.studio.HTMLGraphics.KeepAliveDuration diff --git a/src/tv2-common/helpers/graphics/viz/VizInternalGraphic.ts b/src/tv2-common/helpers/graphics/viz/VizInternalGraphic.ts index 1eed50dc..ad11cfb1 100644 --- a/src/tv2-common/helpers/graphics/viz/VizInternalGraphic.ts +++ b/src/tv2-common/helpers/graphics/viz/VizInternalGraphic.ts @@ -1,6 +1,6 @@ import { SomeContent, TSR, WithTimeline } from 'blueprints-integration' -import { getDskOnAirTimelineObjects, GetTimelineLayerForGraphic, literal } from 'tv2-common' -import { DSKRoles } from 'tv2-constants' +import { getDskOnAirTimelineObjects, getTimelineLayerForGraphic, literal } from 'tv2-common' +import { DskRole } from 'tv2-constants' import { InternalGraphic } from '../internal' @@ -13,9 +13,9 @@ export class VizInternalGraphic extends InternalGraphic { timelineObjects: literal([ literal({ id: '', - enable: this.GetEnableForGraphic(), + enable: this.getTimelineObjectEnable(), priority: 1, - layer: GetTimelineLayerForGraphic(this.config, this.templateName), + layer: getTimelineLayerForGraphic(this.config, this.templateName), content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, @@ -26,7 +26,7 @@ export class VizInternalGraphic extends InternalGraphic { } }), // Assume DSK is off by default (config table) - ...getDskOnAirTimelineObjects(this.context, DSKRoles.OVERLAYGFX) + ...getDskOnAirTimelineObjects(this.context, DskRole.OVERLAYGFX) ]) } } diff --git a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts index 37a0d553..94483d21 100644 --- a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts @@ -11,7 +11,7 @@ import { PilotGraphicProps, TransitionStyle } from 'tv2-common' -import { DSKRoles } from 'tv2-constants' +import { DskRole } from 'tv2-constants' import { PilotGraphicGenerator } from '../pilot' @@ -47,7 +47,7 @@ export class VizPilotGraphicGenerator extends PilotGraphicGenerator { private getEnable() { if (IsTargetingOVL(this.engine) || IsTargetingWall(this.engine)) { - return this.GetEnableForGraphic() + return this.getTimelineObjectEnable() } return { start: 0 } } @@ -93,7 +93,7 @@ export class VizPilotGraphicGenerator extends PilotGraphicGenerator { } }), // Assume DSK is off by default (config table) - ...getDskOnAirTimelineObjects(this.context, DSKRoles.FULLGFX), + ...getDskOnAirTimelineObjects(this.context, DskRole.FULLGFX), ...GetSisyfosTimelineObjForFull(this.config) ] if (this.context.uniformConfig.mixEffects.program.auxLayer) { diff --git a/src/tv2-common/helpers/rundownAdLibActions.ts b/src/tv2-common/helpers/rundownAdLibActions.ts index 8db52773..0da6c1c2 100644 --- a/src/tv2-common/helpers/rundownAdLibActions.ts +++ b/src/tv2-common/helpers/rundownAdLibActions.ts @@ -11,7 +11,7 @@ import { TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' -import { AdlibActionType, AdlibTags, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' +import { AdlibActionType, AdlibTags, SharedOutputLayer, SharedSourceLayer } from 'tv2-constants' import { TV2ShowStyleConfig } from '../blueprintConfig' import { CreateJingleExpectedMedia } from '../content' import { t } from './translation' @@ -146,8 +146,8 @@ function makeTransitionAction( display: { _rank: transitionValues.rank, label: t(`${isEffekt ? 'EFFEKT ' : ''}${transitionValues.label}`), - sourceLayerId: SharedSourceLayers.PgmAdlibJingle, - outputLayerId: SharedOutputLayers.PGM, + sourceLayerId: SharedSourceLayer.PgmAdlibJingle, + outputLayerId: SharedOutputLayer.PGM, tags: [AdlibTags.ADLIB_STATIC_BUTTON, adlibTag], currentPieceTags: [tag], nextPieceTags: [tag], diff --git a/src/tv2-common/helpers/serverResume.ts b/src/tv2-common/helpers/serverResume.ts index 2957c937..20858dc5 100644 --- a/src/tv2-common/helpers/serverResume.ts +++ b/src/tv2-common/helpers/serverResume.ts @@ -4,8 +4,8 @@ import { IBlueprintResolvedPieceInstance, VTContent } from 'blueprints-integration' -import { ExtendedActionExecutionContext, PartEndStateExt, PieceMetaData, t, TV2ShowStyleConfig } from 'tv2-common' -import { SharedSourceLayers } from 'tv2-constants' +import { ActionExecutionContext, PartEndStateExt, PieceMetaData, t, TV2ShowStyleConfig } from 'tv2-common' +import { SharedSourceLayer } from 'tv2-constants' import _ = require('underscore') import { DVEPieceMetaData } from '../content' @@ -47,7 +47,7 @@ export function getServerSeek( } export async function getServerPosition( - context: ExtendedActionExecutionContext, + context: ActionExecutionContext, replacingCurrentPieceWithOffset?: number ): Promise { const partInstance = await context.core.getPartInstance('current') @@ -92,7 +92,7 @@ export function getServerPositionForPartInstance( (currentPieceEnd !== undefined ? currentPieceEnd - pieceInstance.resolvedStart : undefined) const content = pieceInstance.piece.content as VTContent | undefined - if (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmServer && content) { + if (pieceInstance.piece.sourceLayerId === SharedSourceLayer.PgmServer && content) { currentServerPosition = getCurrentPositionFromServerPiece( content, pieceDuration, @@ -101,7 +101,7 @@ export function getServerPositionForPartInstance( currentPieceEnd, partInstance ) - } else if (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmDVEAdLib) { + } else if (pieceInstance.piece.sourceLayerId === SharedSourceLayer.PgmDVEAdLib) { updateServerPositionFromDVEPiece( pieceInstance as IBlueprintResolvedPieceInstance, partInstance, @@ -205,8 +205,8 @@ function getCurrentPositionFromServerPiece( export function shouldPreservePosition(pieceInstance: IBlueprintResolvedPieceInstance): boolean { return ( !!pieceInstance.dynamicallyInserted && - (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmServer || - (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmDVEAdLib && + (pieceInstance.piece.sourceLayerId === SharedSourceLayer.PgmServer || + (pieceInstance.piece.sourceLayerId === SharedSourceLayer.PgmDVEAdLib && !!(pieceInstance.piece.metaData as DVEPieceMetaData | undefined)?.serverPlaybackTiming)) ) } diff --git a/src/tv2-common/hotkeys/global.ts b/src/tv2-common/hotkeys/global.ts index 8a9e2bb7..dd9be2f3 100644 --- a/src/tv2-common/hotkeys/global.ts +++ b/src/tv2-common/hotkeys/global.ts @@ -8,7 +8,7 @@ import { TriggerType } from 'blueprints-integration' import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' -import { AdlibTags, SharedSourceLayers } from 'tv2-constants' +import { AdlibTags, SharedSourceLayer } from 'tv2-constants' import { CameraHotkeyAssignments, MakeCameraHotkeys } from './camera' import { ClearLayerHotkeyAssignments, MakeClearHotkeys } from './clear' import { DVEHotkeyAssignments, MakeDVELayoutHotkeys } from './dve' @@ -56,14 +56,14 @@ export function MakeGlobalTriggers( ): IBlueprintTriggeredActions[] { const cameraTriggers = MakeCameraHotkeys( showStyleId, - SharedSourceLayers.PgmCam, + SharedSourceLayer.PgmCam, sources.camera, assignments.camera, getNextRank ) const remoteTriggers = MakeRemoteHotkeys( showStyleId, - SharedSourceLayers.PgmLive, + SharedSourceLayer.PgmLive, sources.remote, assignments.remote, getNextRank, @@ -71,7 +71,7 @@ export function MakeGlobalTriggers( ) const feedTriggers = MakeRemoteHotkeys( showStyleId, - SharedSourceLayers.PgmLive, + SharedSourceLayer.PgmLive, sources.feed, assignments.feed, getNextRank, @@ -83,15 +83,15 @@ export function MakeGlobalTriggers( const dveTriggers = MakeDVELayoutHotkeys( showStyleId, - SharedSourceLayers.PgmDVEAdLib, + SharedSourceLayer.PgmDVEAdLib, sources.dveLayouts, assignments.dve, getNextRank ) - const serverTriggers = MakeServerHotkeys(showStyleId, SharedSourceLayers.PgmServer, getNextRank) + const serverTriggers = MakeServerHotkeys(showStyleId, SharedSourceLayer.PgmServer, getNextRank) const graphicsTriggers = MakeGraphicsHotkeys( showStyleId, - SharedSourceLayers.PgmAdlibGraphicCmd, + SharedSourceLayer.PgmAdlibGraphicCmd, assignments.graphics, getNextRank ) @@ -99,23 +99,23 @@ export function MakeGlobalTriggers( const clearTriggers = MakeClearHotkeys(showStyleId, assignments.clear, getNextRank) const sisyfosTriggers = MakeSisyfosHotkeys( showStyleId, - SharedSourceLayers.PgmSisyfosAdlibs, + SharedSourceLayer.PgmSisyfosAdlibs, assignments.sisyfos, getNextRank ) const recallLastTriggers = [ makeRecallLastTrigger( - SharedSourceLayers.PgmDVEAdLib, + SharedSourceLayer.PgmDVEAdLib, getNextRank, - recallLastHotkeyId(showStyleId, SharedSourceLayers.PgmDVE, 'dve', 0), + recallLastHotkeyId(showStyleId, SharedSourceLayer.PgmDVE, 'dve', 0), 'Last DVE', assignments.recallLast.DVE, [AdlibTags.ADLIB_RECALL_LAST_DVE] ), makeRecallLastTrigger( - SharedSourceLayers.PgmLive, + SharedSourceLayer.PgmLive, getNextRank, - recallLastHotkeyId(showStyleId, SharedSourceLayers.PgmLive, 'live', 0), + recallLastHotkeyId(showStyleId, SharedSourceLayer.PgmLive, 'live', 0), 'Last Live', assignments.recallLast.Live, [AdlibTags.ADLIB_RECALL_LAST_LIVE] @@ -123,9 +123,9 @@ export function MakeGlobalTriggers( ] const takeWithTransitionTriggers = assignments.takeWithTransition.map((key, index) => makeTakeWithTransitionTrigger( - SharedSourceLayers.PgmAdlibJingle, + SharedSourceLayer.PgmAdlibJingle, getNextRank, - takeWithTransitionHotkeyId(showStyleId, SharedSourceLayers.PgmAdlibJingle, key, index), + takeWithTransitionHotkeyId(showStyleId, SharedSourceLayer.PgmAdlibJingle, key, index), `Take with transition ${index + 1}`, key, index diff --git a/src/tv2-common/hotkeys/hotkey-defaults.ts b/src/tv2-common/hotkeys/hotkey-defaults.ts index e6da72e0..c73c1484 100644 --- a/src/tv2-common/hotkeys/hotkey-defaults.ts +++ b/src/tv2-common/hotkeys/hotkey-defaults.ts @@ -1,4 +1,4 @@ -import { SharedSourceLayers } from 'tv2-constants' +import { SharedSourceLayer } from 'tv2-constants' import { literal } from '../util' import { GlobalHotkeyAssignments } from './global' import { RundownViewHotkeyAssignments } from './rundownView' @@ -35,44 +35,44 @@ export const defaultHotkeys: TV2Hotkeys = { clear: [ { sourceLayers: [ - SharedSourceLayers.PgmGraphicsIdent, - SharedSourceLayers.PgmGraphicsTop, - SharedSourceLayers.PgmGraphicsLower, - SharedSourceLayers.PgmGraphicsHeadline, - SharedSourceLayers.PgmGraphicsTema, - SharedSourceLayers.PgmGraphicsOverlay, - SharedSourceLayers.PgmPilotOverlay + SharedSourceLayer.PgmGraphicsIdent, + SharedSourceLayer.PgmGraphicsTop, + SharedSourceLayer.PgmGraphicsLower, + SharedSourceLayer.PgmGraphicsHeadline, + SharedSourceLayer.PgmGraphicsTema, + SharedSourceLayer.PgmGraphicsOverlay, + SharedSourceLayer.PgmPilotOverlay ], key: 'KeyQ', name: 'overlay ALT UD' }, { - sourceLayers: [SharedSourceLayers.PgmGraphicsIdent], + sourceLayers: [SharedSourceLayer.PgmGraphicsIdent], key: 'Ctrl+Shift+KeyA', name: 'ovl: ident OUT' }, { - sourceLayers: [SharedSourceLayers.PgmGraphicsTop], + sourceLayers: [SharedSourceLayer.PgmGraphicsTop], key: 'Ctrl+Shift+KeyS', name: 'ovl: top OUT' }, { - sourceLayers: [SharedSourceLayers.PgmGraphicsLower], + sourceLayers: [SharedSourceLayer.PgmGraphicsLower], key: 'Ctrl+Shift+KeyD', name: 'ovl:lower OUT' }, { - sourceLayers: [SharedSourceLayers.PgmGraphicsHeadline], + sourceLayers: [SharedSourceLayer.PgmGraphicsHeadline], key: 'Ctrl+Shift+KeyF', name: 'ovl: headline OUT' }, { - sourceLayers: [SharedSourceLayers.PgmGraphicsTema], + sourceLayers: [SharedSourceLayer.PgmGraphicsTema], key: 'Ctrl+Shift+KeyG', name: 'ovl: tema OUT' }, { - sourceLayers: [SharedSourceLayers.PgmAudioBed], + sourceLayers: [SharedSourceLayer.PgmAudioBed], key: 'Minus', name: 'STOP soundpl.' } diff --git a/src/tv2-common/hotkeys/segment.ts b/src/tv2-common/hotkeys/segment.ts index 621d9d52..7f0fcf8d 100644 --- a/src/tv2-common/hotkeys/segment.ts +++ b/src/tv2-common/hotkeys/segment.ts @@ -8,7 +8,7 @@ import { TriggerType } from 'blueprints-integration' import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' -import { AdlibTags, SharedSourceLayers } from 'tv2-constants' +import { AdlibTags, SharedSourceLayer } from 'tv2-constants' export interface ActiveSegmentHotketAssignments { lowerThirds: string[] @@ -25,9 +25,9 @@ export function MakeActiveSegmentTriggers( ) { return assignments.lowerThirds.map((key, index) => makeSegmentHotKey( - SharedSourceLayers.PgmGraphicsLower, + SharedSourceLayer.PgmGraphicsLower, getNextRank, - activeSegmentAdLibHotkeyId(showStyleId, SharedSourceLayers.PgmGraphicsLower, key, index), + activeSegmentAdLibHotkeyId(showStyleId, SharedSourceLayer.PgmGraphicsLower, key, index), `Lower GFX AdLib ${index + 1}`, key, index diff --git a/src/tv2-common/jinglePartProperties.ts b/src/tv2-common/jinglePartProperties.ts index 1499d6c9..b886c5e4 100644 --- a/src/tv2-common/jinglePartProperties.ts +++ b/src/tv2-common/jinglePartProperties.ts @@ -1,12 +1,12 @@ import { IBlueprintPart } from 'blueprints-integration' import { CueType } from 'tv2-constants' import { TableConfigItemBreakers } from './blueprintConfig' -import { TimeFromFrames } from './frameTime' +import { getTimeFromFrames } from './frameTime' import { CueDefinitionJingle, PartDefinition } from './inewsConversion' -import { ExtendedShowStyleContext } from './showstyle' +import { ShowStyleContext } from './showstyle' export function GetJinglePartProperties( - context: ExtendedShowStyleContext, + context: ShowStyleContext, part: PartDefinition ): Pick | {} { if (part.cues) { @@ -29,8 +29,8 @@ export function GetJinglePartProperties( export function GetJinglePartPropertiesFromTableValue( realBreaker: TableConfigItemBreakers ): Pick { - const expectedDuration = Math.max(0, TimeFromFrames(Number(realBreaker.Duration) - Number(realBreaker.StartAlpha))) - const autoNextOverlap = Math.min(expectedDuration, TimeFromFrames(Number(realBreaker.EndAlpha))) + const expectedDuration = Math.max(0, getTimeFromFrames(Number(realBreaker.Duration) - Number(realBreaker.StartAlpha))) + const autoNextOverlap = Math.min(expectedDuration, getTimeFromFrames(Number(realBreaker.EndAlpha))) return { expectedDuration, autoNextOverlap, diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index d2730836..7cfa82ba 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -418,7 +418,7 @@ export function PrefixEvsWithEvs( export function convertStudioTableColumnToFloat( versionStr: string, tableId: string, - columnId: string, + columnId: string ): MigrationStepStudio { return { id: `${versionStr}.convertStudioTableColumnToFloat.${tableId}.${columnId}`, @@ -437,8 +437,9 @@ export function convertStudioTableColumnToFloat( let config = context.getConfig(tableId) as unknown as TableConfigItemValue config = config.map((row) => { const value = row[columnId] - if (typeof value === 'string') - row[columnId] = parseFloat(value) + if (typeof value === 'string') { + row[columnId] = parseFloat(value) + } return row }) context.setConfig(tableId, config as unknown as ConfigItemValue) diff --git a/src/tv2-common/migrations/sourceManifest.ts b/src/tv2-common/migrations/sourceManifest.ts index 2b34e626..f2d245d1 100644 --- a/src/tv2-common/migrations/sourceManifest.ts +++ b/src/tv2-common/migrations/sourceManifest.ts @@ -27,7 +27,7 @@ export function MakeConfigForSources( }, { id: 'SwitcherSource', - name: 'Switcher input', + name: 'Video Switcher input', description: `Video Switcher input for ${displayName} input`, type: ConfigManifestEntryType.INT, required: true, diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index 3e7d4435..346f899f 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -16,9 +16,9 @@ import { ActionSelectServerClip, assignMediaPlayers, CasparPlayerClip, - ExtendedTimelineContext, getServerPositionForPartInstance, - ServerPosition + ServerPosition, + TimelineContext } from 'tv2-common' import { AbstractLLayer, PartType, TallyTags } from 'tv2-constants' import * as _ from 'underscore' @@ -99,7 +99,7 @@ export function onTimelineGenerate< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedTimelineContext, + context: TimelineContext, timeline: OnGenerateTimelineObj[], previousPersistentState: TimelinePersistentState | undefined, previousPartEndState: PartEndState | undefined, @@ -139,7 +139,7 @@ export function onTimelineGenerate< } function processServerLookaheads( - context: ExtendedTimelineContext, + context: TimelineContext, timeline: OnGenerateTimelineObj[], resolvedPieces: IBlueprintResolvedPieceInstance[], sourceLayers: ABSourceLayers @@ -205,7 +205,7 @@ function processServerLookaheads( } function isAnyPieceInjectedIntoPart( - context: ExtendedTimelineContext, + context: TimelineContext, resolvedPieces: Array> ) { return resolvedPieces diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index a19923d2..7027bf27 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -11,25 +11,25 @@ import { import { ActionTakeWithTransitionVariantDip, ActionTakeWithTransitionVariantMix, - ExtendedShowStyleContext, getDskOnAirTimelineObjects, GetTagForTransition, + getTimeFromFrames, literal, PartDefinition, PieceMetaData, - TimeFromFrames, + ShowStyleContext, TimelineBlueprintExt, TransitionStyle, TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' -import { DSKRoles, SharedOutputLayers } from 'tv2-constants' +import { DskRole, SharedOutputLayer } from 'tv2-constants' import { TV2ShowStyleConfig } from '../blueprintConfig' import { joinAssetToFolder, joinAssetToNetworkPath } from '../util' /** Has to be executed before calling EvaluateCues, as some cues may depend on it */ export function CreateEffektForPartBase( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, pieces: IBlueprintPiece[], layers: { @@ -63,14 +63,14 @@ export function CreateEffektForPartBase( CreateMixTransitionBlueprintPieceForPart(partDefinition.externalId, transition.duration, layers.sourceLayer) ?? {} pieces.push(blueprintPiece) - return CreateInTransitionForTransitionStyle(transition.duration) + return createInTransitionForTransitionStyle(transition.duration) } if (transition.style === TransitionStyle.DIP) { const blueprintPiece: IBlueprintPiece = - CreateDipTransitionBlueprintPieceForPart(partDefinition.externalId, transition.duration, layers.sourceLayer) ?? {} + createDipTransitionBlueprintPieceForPart(partDefinition.externalId, transition.duration, layers.sourceLayer) ?? {} pieces.push(blueprintPiece) - return CreateInTransitionForTransitionStyle(transition.duration) + return createInTransitionForTransitionStyle(transition.duration) } return {} @@ -80,7 +80,7 @@ export function CreateEffektForPartInner< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], effekt: string, externalId: string, @@ -116,8 +116,8 @@ export function CreateEffektForPartInner< pieces.push({ externalId, name: label, - enable: { start: 0, duration: TimeFromFrames(Number(effektConfig.Duration)) }, - outputLayerId: SharedOutputLayers.JINGLE, + enable: { start: 0, duration: getTimeFromFrames(Number(effektConfig.Duration)) }, + outputLayerId: SharedOutputLayer.JINGLE, sourceLayerId: layers.sourceLayer, lifespan: PieceLifespan.WithinPart, pieceType: IBlueprintPieceType.InTransition, @@ -148,7 +148,7 @@ export function CreateEffektForPartInner< file: fileName } }), - ...getDskOnAirTimelineObjects(context, DSKRoles.JINGLE, { + ...getDskOnAirTimelineObjects(context, DskRole.JINGLE, { start: Number(context.config.studio.CasparPrerollDuration) }), literal({ @@ -170,12 +170,12 @@ export function CreateEffektForPartInner< return { inTransition: { - blockTakeDuration: TimeFromFrames(Number(effektConfig.Duration)) + context.config.studio.CasparPrerollDuration, + blockTakeDuration: getTimeFromFrames(Number(effektConfig.Duration)) + context.config.studio.CasparPrerollDuration, previousPartKeepaliveDuration: - TimeFromFrames(Number(effektConfig.StartAlpha)) + context.config.studio.CasparPrerollDuration, + getTimeFromFrames(Number(effektConfig.StartAlpha)) + context.config.studio.CasparPrerollDuration, partContentDelayDuration: - TimeFromFrames(Number(effektConfig.Duration)) - - TimeFromFrames(Number(effektConfig.EndAlpha)) + + getTimeFromFrames(Number(effektConfig.Duration)) - + getTimeFromFrames(Number(effektConfig.EndAlpha)) + context.config.studio.CasparPrerollDuration }, autoNext: false @@ -209,12 +209,12 @@ function createEffectBlueprintPiece( return { enable: { start: 0, - duration: Math.max(TimeFromFrames(durationInFrames), 1000) + duration: Math.max(getTimeFromFrames(durationInFrames), 1000) }, externalId, name: `${name.toUpperCase()} ${durationInFrames}`, sourceLayerId: sourceLayer, - outputLayerId: SharedOutputLayers.JINGLE, + outputLayerId: SharedOutputLayer.JINGLE, lifespan: PieceLifespan.WithinPart, tags, content: { @@ -224,8 +224,8 @@ function createEffectBlueprintPiece( } } -export function CreateInTransitionForTransitionStyle(durationInFrames: number): Pick { - const transitionDuration = TimeFromFrames(durationInFrames) +export function createInTransitionForTransitionStyle(durationInFrames: number): Pick { + const transitionDuration = getTimeFromFrames(durationInFrames) return { inTransition: { previousPartKeepaliveDuration: transitionDuration, @@ -235,7 +235,7 @@ export function CreateInTransitionForTransitionStyle(durationInFrames: number): } } -export function CreateDipTransitionBlueprintPieceForPart( +export function createDipTransitionBlueprintPieceForPart( externalId: string, durationInFrames: number, sourceLayer: string diff --git a/src/tv2-common/parts/kam.ts b/src/tv2-common/parts/kam.ts index ce288b38..51dc723a 100644 --- a/src/tv2-common/parts/kam.ts +++ b/src/tv2-common/parts/kam.ts @@ -1,17 +1,11 @@ import { BlueprintResultPart, IBlueprintPart } from 'blueprints-integration' -import { - ExtendedShowStyleContext, - PartDefinition, - PartTime, - TV2BlueprintConfigBase, - TV2StudioConfigBase -} from 'tv2-common' +import { PartDefinition, PartTime, ShowStyleContext, TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' export function CreatePartKamBase< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, totalWords: number ): { part: BlueprintResultPart; duration: number; invalid?: true } { diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index 5de556a6..986ac9ae 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -8,15 +8,15 @@ import { } from 'blueprints-integration' import { CutToServer, - ExtendedShowStyleContext, GetTagForServer, GetTagForServerNext, MakeContentServer, MakeContentServerSourceLayers, PieceMetaData, - ServerPieceMetaData + ServerPieceMetaData, + ShowStyleContext } from 'tv2-common' -import { AdlibActionType, PartType, SharedOutputLayers, TallyTags } from 'tv2-constants' +import { AdlibActionType, PartType, SharedOutputLayer, TallyTags } from 'tv2-constants' import { ActionSelectServerClip } from '../actions' import { TV2BlueprintConfigBase, TV2StudioConfigBase } from '../blueprintConfig' import { getSourceDuration, GetVTContentProperties } from '../content' @@ -58,7 +58,7 @@ export async function CreatePartServerBase< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, partProps: ServerPartProps, layers: ServerPartLayers @@ -188,7 +188,7 @@ function getUserData( } function getContentServerElement( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partProps: ServerPartProps, contentProps: ServerContentProps, layers: ServerPartLayers @@ -209,7 +209,7 @@ function getContentServerElement( } function getServerSelectionBlueprintPiece( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, actualDuration: number, partProps: ServerPartProps, @@ -224,7 +224,7 @@ function getServerSelectionBlueprintPiece( externalId: partDefinition.externalId, name: contentProps.file, enable: { start: 0 }, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, sourceLayerId: layers.SourceLayer.SelectedServer, lifespan: PieceLifespan.OutOnSegmentEnd, metaData: { @@ -245,7 +245,7 @@ function getPgmBlueprintPiece< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, partProps: ServerPartProps, contentProps: ServerContentProps, @@ -255,7 +255,7 @@ function getPgmBlueprintPiece< externalId: partDefinition.externalId, name: contentProps.file, enable: { start: 0 }, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, sourceLayerId: layers.SourceLayer.PgmServer, lifespan: PieceLifespan.WithinPart, metaData: { diff --git a/src/tv2-common/pieces/adlibServer.ts b/src/tv2-common/pieces/adlibServer.ts index 09bce116..27a81351 100644 --- a/src/tv2-common/pieces/adlibServer.ts +++ b/src/tv2-common/pieces/adlibServer.ts @@ -1,7 +1,6 @@ import { IBlueprintActionManifest } from 'blueprints-integration' import { ActionSelectServerClip, - ExtendedShowStyleContext, getSourceDuration, GetTagForServer, GetTagForServerNext, @@ -9,17 +8,18 @@ import { literal, PartDefinition, ServerPartLayers, + ShowStyleContext, TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' -import { AdlibActionType, AdlibTags, SharedOutputLayers } from 'tv2-constants' +import { AdlibActionType, AdlibTags, SharedOutputLayer } from 'tv2-constants' import { getServerAdLibTriggerModes, t } from '../helpers' export async function CreateAdlibServer< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( - context: ExtendedShowStyleContext, + context: ShowStyleContext, rank: number, partDefinition: PartDefinition, file: string, @@ -49,7 +49,7 @@ export async function CreateAdlibServer< _rank: rank, label: t(`${partDefinition.storyName}`), sourceLayerId: sourceLayers.SourceLayer.PgmServer, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, content: GetVTContentProperties(context.config, { file, clipDuration: mediaObjectDuration, diff --git a/src/tv2-common/pieces/script.ts b/src/tv2-common/pieces/script.ts index db2198ca..1ff4c994 100644 --- a/src/tv2-common/pieces/script.ts +++ b/src/tv2-common/pieces/script.ts @@ -1,6 +1,6 @@ import { IBlueprintPiece, PieceLifespan, ScriptContent, WithTimeline } from 'blueprints-integration' import { literal, PartDefinition } from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' +import { SharedOutputLayer } from 'tv2-constants' const PREVIEW_CHARACTERS = 30 @@ -21,7 +21,7 @@ export function AddScript(part: PartDefinition, pieces: IBlueprintPiece[], durat enable: { start: 0 }, - outputLayerId: SharedOutputLayers.MANUS, + outputLayerId: SharedOutputLayer.MANUS, sourceLayerId, lifespan: PieceLifespan.WithinPart, content: literal>({ diff --git a/src/tv2-common/pieces/telemetric.ts b/src/tv2-common/pieces/telemetric.ts index 6f97da89..38ac4ec5 100644 --- a/src/tv2-common/pieces/telemetric.ts +++ b/src/tv2-common/pieces/telemetric.ts @@ -1,5 +1,5 @@ import { IBlueprintPiece, PieceLifespan, TSR } from 'blueprints-integration' -import { RobotCameraLayer, SharedOutputLayers, SharedSourceLayers } from '../../tv2-constants' +import { RobotCameraLayer, SharedOutputLayer, SharedSourceLayer } from '../../tv2-constants' import { PieceMetaData } from '../onTimelineGenerate' import { literal } from '../util' @@ -18,8 +18,8 @@ export function createTelemetricsPieceForRobotCamera( duration: 100 }, lifespan: PieceLifespan.WithinPart, - sourceLayerId: SharedSourceLayers.RobotCamera, - outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SharedSourceLayer.RobotCamera, + outputLayerId: SharedOutputLayer.SEC, content: { timelineObjects: [createTelemetricsTimelineObject(preset)] } diff --git a/src/tv2-common/segment/context.ts b/src/tv2-common/segment/context.ts index 0293128a..f20a9ea6 100644 --- a/src/tv2-common/segment/context.ts +++ b/src/tv2-common/segment/context.ts @@ -1,22 +1,15 @@ import { ISegmentUserContext } from 'blueprints-integration' -import { - ExtendedShowStyleContext, - ExtendedShowStyleContextImpl, - TV2ShowStyleConfig, - UniformConfig, - VideoSwitcher -} from 'tv2-common' +import { ShowStyleContext, ShowStyleContextImpl, TV2ShowStyleConfig, UniformConfig, VideoSwitcher } from 'tv2-common' -export interface ExtendedSegmentContext - extends ExtendedShowStyleContext { +export interface SegmentContext extends ShowStyleContext { readonly core: ISegmentUserContext readonly config: BlueprintConfig readonly videoSwitcher: VideoSwitcher } -export class ExtendedSegmentContextImpl - extends ExtendedShowStyleContextImpl - implements ExtendedSegmentContext +export class SegmentContextImpl + extends ShowStyleContextImpl + implements SegmentContext { constructor(readonly core: ISegmentUserContext, readonly uniformConfig: UniformConfig) { super(core, uniformConfig) diff --git a/src/tv2-common/showstyle/context.ts b/src/tv2-common/showstyle/context.ts index bdbc11d7..d996695c 100644 --- a/src/tv2-common/showstyle/context.ts +++ b/src/tv2-common/showstyle/context.ts @@ -1,14 +1,14 @@ import { IShowStyleContext, IShowStyleUserContext } from 'blueprints-integration' -import { TV2ShowStyleConfig, UniformConfig, VideoSwitcher, VideoSwitcherImpl } from 'tv2-common' +import { TV2ShowStyleConfig, UniformConfig, VideoSwitcher, VideoSwitcherBase } from 'tv2-common' -export interface ExtendedShowStyleContext { +export interface ShowStyleContext { readonly core: IShowStyleUserContext readonly config: BlueprintConfig readonly uniformConfig: UniformConfig readonly videoSwitcher: VideoSwitcher } -export class ExtendedShowStyleContextImpl< +export class ShowStyleContextImpl< BlueprintConfig extends TV2ShowStyleConfig = TV2ShowStyleConfig, CoreContext extends IShowStyleUserContext | IShowStyleContext = IShowStyleUserContext > { @@ -17,7 +17,7 @@ export class ExtendedShowStyleContextImpl< constructor(readonly core: CoreContext, public readonly uniformConfig: UniformConfig) { this.config = this.makeConfig() - this.videoSwitcher = VideoSwitcherImpl.getVideoSwitcher(core, this.config, uniformConfig) + this.videoSwitcher = VideoSwitcherBase.getVideoSwitcher(core, this.config, uniformConfig) } private makeConfig(): BlueprintConfig { diff --git a/src/tv2-common/showstyle/timelineEventContext.ts b/src/tv2-common/showstyle/timelineEventContext.ts index aeda56b0..7cfdec67 100644 --- a/src/tv2-common/showstyle/timelineEventContext.ts +++ b/src/tv2-common/showstyle/timelineEventContext.ts @@ -1,11 +1,11 @@ import { ITimelineEventContext } from 'blueprints-integration' import { TV2ShowStyleConfig } from '../blueprintConfig' import { UniformConfig } from '../uniformConfig' -import { ExtendedShowStyleContextImpl } from './context' +import { ShowStyleContextImpl } from './context' -export class ExtendedTimelineContext< +export class TimelineContext< BlueprintConfig extends TV2ShowStyleConfig = TV2ShowStyleConfig -> extends ExtendedShowStyleContextImpl { +> extends ShowStyleContextImpl { constructor(readonly core: ITimelineEventContext, uniformConfig: UniformConfig) { super(core, uniformConfig) } diff --git a/src/tv2-common/studio/context.ts b/src/tv2-common/studio/context.ts index cbe85c23..5a3bad0e 100644 --- a/src/tv2-common/studio/context.ts +++ b/src/tv2-common/studio/context.ts @@ -1,14 +1,14 @@ import { IStudioContext } from 'blueprints-integration' -import { UniformConfig, VideoSwitcher, VideoSwitcherImpl } from 'tv2-common' +import { UniformConfig, VideoSwitcher, VideoSwitcherBase } from 'tv2-common' import { TV2StudioConfig } from '../blueprintConfig' -export class ExtendedStudioContext { +export class StudioContext { public readonly config: BlueprintConfig public readonly videoSwitcher: VideoSwitcher constructor(readonly core: IStudioContext, public readonly uniformConfig: UniformConfig) { this.config = this.makeConfig() - this.videoSwitcher = VideoSwitcherImpl.getVideoSwitcher(core, this.config, uniformConfig) + this.videoSwitcher = VideoSwitcherBase.getVideoSwitcher(core, this.config, uniformConfig) } private makeConfig(): BlueprintConfig { diff --git a/src/tv2-common/types/config.ts b/src/tv2-common/types/config.ts index 9f5d4381..cdd0f2e1 100644 --- a/src/tv2-common/types/config.ts +++ b/src/tv2-common/types/config.ts @@ -1,4 +1,4 @@ -import { DSKRoles } from 'tv2-constants' +import { DskRole } from 'tv2-constants' export interface TableConfigItemSourceMapping { SourceName: string @@ -24,5 +24,5 @@ export interface SwitcherDskProps { export interface TableConfigItemDSK extends SwitcherDskProps { Toggle: boolean DefaultOn: boolean - Roles?: DSKRoles[] + Roles?: DskRole[] } diff --git a/src/tv2-common/updatePolicies/syncIngestUpdateToPartInstance.ts b/src/tv2-common/updatePolicies/syncIngestUpdateToPartInstance.ts index 258c5bc7..9f27f295 100644 --- a/src/tv2-common/updatePolicies/syncIngestUpdateToPartInstance.ts +++ b/src/tv2-common/updatePolicies/syncIngestUpdateToPartInstance.ts @@ -3,7 +3,7 @@ import { BlueprintSyncIngestPartInstance, ISyncIngestUpdateToPartInstanceContext } from 'blueprints-integration' -import { SharedSourceLayers } from 'tv2-constants' +import { SharedSourceLayer } from 'tv2-constants' import * as _ from 'underscore' import { stopOrReplaceEditablePieces, updateAdLibInstances } from './index' import { updatePartProperties } from './partProperties' @@ -20,15 +20,15 @@ export function syncIngestUpdateToPartInstanceBase( playoutStatus === 'current' ? new Set([ ...freelyEditableLayers, - SharedSourceLayers.PgmGraphicsHeadline, - SharedSourceLayers.PgmGraphicsIdent, - SharedSourceLayers.PgmGraphicsLower, - SharedSourceLayers.PgmGraphicsOverlay, - SharedSourceLayers.PgmGraphicsTLF, - SharedSourceLayers.PgmGraphicsTema, - SharedSourceLayers.PgmGraphicsTop, - SharedSourceLayers.PgmPilot, - SharedSourceLayers.PgmPilotOverlay + SharedSourceLayer.PgmGraphicsHeadline, + SharedSourceLayer.PgmGraphicsIdent, + SharedSourceLayer.PgmGraphicsLower, + SharedSourceLayer.PgmGraphicsOverlay, + SharedSourceLayer.PgmGraphicsTLF, + SharedSourceLayer.PgmGraphicsTema, + SharedSourceLayer.PgmGraphicsTop, + SharedSourceLayer.PgmPilot, + SharedSourceLayer.PgmPilotOverlay ]) : undefined diff --git a/src/tv2-common/videoSwitchers/Atem.ts b/src/tv2-common/videoSwitchers/Atem.ts index 6a6f8c5d..2d589749 100644 --- a/src/tv2-common/videoSwitchers/Atem.ts +++ b/src/tv2-common/videoSwitchers/Atem.ts @@ -16,7 +16,7 @@ import { TIMELINE_OBJECT_DEFAULTS, TimelineObjectProps, TransitionStyle, - VideoSwitcherImpl + VideoSwitcherBase } from './index' const TRANSITION_MAP = { @@ -28,7 +28,7 @@ const TRANSITION_MAP = { [TransitionStyle.WIPE_FOR_GFX]: TSR.AtemTransitionStyle.WIPE } -export class Atem extends VideoSwitcherImpl { +export class Atem extends VideoSwitcherBase { public readonly type = SwitcherType.ATEM public isVideoSwitcherTimelineObject = ( diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 5cb5122a..241ca16f 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -1,5 +1,5 @@ import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' -import { TimeFromFrames } from 'tv2-common' +import { FRAME_RATE, getTimeFromFrames } from 'tv2-common' import _ = require('underscore') import { TRICASTER_DVE_ME, TRICASTER_LAYER_PREFIX } from '../layers' import { @@ -14,7 +14,7 @@ import { TimelineObjectProps, TransitionStyle } from './types' -import { VideoSwitcherImpl } from './VideoSwitcher' +import { VideoSwitcherBase } from './VideoSwitcher' const MAX_REGULAR_INPUT_NUMBER = 1000 // everything >= is assumed a special input @@ -38,7 +38,7 @@ const TRANSITION_MAP: Record = { [TransitionStyle.STING]: 5 // not really supported?? } -export class TriCaster extends VideoSwitcherImpl { +export class TriCaster extends VideoSwitcherBase { public readonly type = SwitcherType.ATEM public isMixEffect = TSR.isTimelineObjTriCasterME @@ -190,7 +190,7 @@ export class TriCaster extends VideoSwitcherImpl { if (transition === TransitionStyle.WIPE_FOR_GFX) { durationInFrames = this.config.studio.HTMLGraphics.TransitionSettings.wipeRate } - return TimeFromFrames(durationInFrames ?? 25) / 1000 + return getTimeFromFrames(durationInFrames ?? FRAME_RATE) / 1000 } private getBaseProperties( diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts index d0f631bd..cb332209 100644 --- a/src/tv2-common/videoSwitchers/VideoSwitcher.ts +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -16,12 +16,12 @@ import { } from 'tv2-common' import _ = require('underscore') -export abstract class VideoSwitcherImpl implements VideoSwitcher { +export abstract class VideoSwitcherBase implements VideoSwitcher { public static getVideoSwitcher( core: IStudioContext, config: TV2StudioConfig, uniformConfig: UniformConfig - ): VideoSwitcherImpl { + ): VideoSwitcherBase { return config.studio.SwitcherType === SwitcherType.ATEM ? new Atem(core, config, uniformConfig) : new TriCaster(core, config, uniformConfig) diff --git a/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts index 1f166169..ab664432 100644 --- a/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts @@ -5,7 +5,7 @@ import { prefixLayer } from '../../../tv2-common/__tests__/testUtil' import { TV2StudioConfigBase } from '../../../tv2-common/blueprintConfig' import { AtemSourceIndex } from '../../../types/atem' import { AuxProps, DskProps, MixEffectProps, SwitcherType, TransitionStyle } from '../types' -import { VideoSwitcherImpl } from '../VideoSwitcher' +import { VideoSwitcherBase } from '../VideoSwitcher' const DURATION: number = 50 @@ -13,7 +13,7 @@ function setupAtem(studioConfigOverrides?: Partial) { const context = makeMockGalleryContext({ studioConfig: { SwitcherType: SwitcherType.ATEM, ...studioConfigOverrides } }) - return VideoSwitcherImpl.getVideoSwitcher(context.core, context.config, context.uniformConfig) + return VideoSwitcherBase.getVideoSwitcher(context.core, context.config, context.uniformConfig) } describe('ATEM', () => { diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index ecef74b6..d8624069 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -1,19 +1,19 @@ import { BlueprintMapping, LookaheadMode, TSR } from 'blueprints-integration' -import { literal, TRICASTER_DEVICE_ID } from 'tv2-common' +import { FRAME_RATE, literal, TRICASTER_DEVICE_ID } from 'tv2-common' import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' import { makeMockGalleryContext, MockConfigOverrides } from '../../../__mocks__/context' import { AuxProps, DskProps, MixEffectProps, SpecialInput, SwitcherType, TransitionStyle } from '../types' -import { VideoSwitcherImpl } from '../VideoSwitcher' +import { VideoSwitcherBase } from '../VideoSwitcher' const DURATION_FRAMES: number = 50 -const DURATION_SECONDS: number = DURATION_FRAMES / 25 +const DURATION_SECONDS: number = DURATION_FRAMES / FRAME_RATE function setupTriCaster(mockConfigOverrides?: MockConfigOverrides) { const context = makeMockGalleryContext({ ...mockConfigOverrides, studioConfig: { SwitcherType: SwitcherType.TRICASTER, ...mockConfigOverrides?.studioConfig } }) - return VideoSwitcherImpl.getVideoSwitcher(context.core, context.config, context.uniformConfig) + return VideoSwitcherBase.getVideoSwitcher(context.core, context.config, context.uniformConfig) } describe('TriCaster', () => { diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index e4b6c083..75cbf932 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -115,7 +115,7 @@ export function AdlibTagCutToBox(box: number): AdlibTags { export enum ControlClasses { SERVER_ON_AIR = 'server_on_air', LYD_ON_AIR = 'lyd_on_air', - OVERRIDEN_ON_MIX_MINUS = 'overriden_on_mix_minus', + OVERRIDDEN_ON_MIX_MINUS = 'overridden_on_mix_minus', ABSTRACT_LOOKAHEAD = 'abstract_lookahead', PLACEHOLDER = 'placeholder' } @@ -240,7 +240,7 @@ export enum RobotCameraLayer { TELEMETRICS = 'telemetrics_layer' } -export enum SharedOutputLayers { +export enum SharedOutputLayer { OVERLAY = 'overlay', SEC = 'sec', PGM = 'pgm', @@ -251,7 +251,7 @@ export enum SharedOutputLayers { SELECTED_ADLIB = 'selectedAdlib' } -export enum SharedSourceLayers { +export enum SharedSourceLayer { PgmCam = 'studio0_camera', PgmLive = 'studio0_live', PgmDVE = 'studio0_dve', @@ -297,7 +297,7 @@ export enum SharedSourceLayers { RobotCamera = 'studio0_robot_camera' } -export enum DSKRoles { +export enum DskRole { FULLGFX = 'full_graphics', OVERLAYGFX = 'overlay_graphics', JINGLE = 'jingle' diff --git a/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts b/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts index 922abf94..6401fffe 100644 --- a/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts +++ b/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts @@ -8,17 +8,17 @@ import { ActionRecallLastDVE, ActionRecallLastLive, ActionSelectDVELayout, - ExtendedShowStyleContext, generateExternalId, GetTransitionAdLibActions, replaySourceName, + ShowStyleContext, SourceDefinitionKam, SourceInfo, SourceInfoToSourceDefinition, SourceInfoType, t } from 'tv2-common' -import { AdlibActionType, AdlibTagCutToBox, AdlibTags, SharedOutputLayers, SourceType, TallyTags } from 'tv2-constants' +import { AdlibActionType, AdlibTagCutToBox, AdlibTags, SharedOutputLayer, SourceType, TallyTags } from 'tv2-constants' import * as _ from 'underscore' import { GalleryBlueprintConfig } from './helpers/config' import { NUMBER_OF_DVE_BOXES } from './helpers/content/dve' @@ -26,7 +26,7 @@ import { SourceLayer } from './layers' export class GlobalAdlibActionsGenerator { private config: GalleryBlueprintConfig - constructor(private readonly context: ExtendedShowStyleContext) { + constructor(private readonly context: ShowStyleContext) { this.config = context.config } @@ -106,7 +106,7 @@ export class GlobalAdlibActionsGenerator { _rank: rank, label: t(sourceDefinition.name), sourceLayerId: SourceLayer.PgmCam, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, content: {}, tags: queue ? [AdlibTags.ADLIB_QUEUE_NEXT] : [AdlibTags.ADLIB_CUT_DIRECT] } @@ -126,7 +126,7 @@ export class GlobalAdlibActionsGenerator { _rank: 1, label: t('Last Live'), sourceLayerId: SourceLayer.PgmLive, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, tags: [AdlibTags.ADLIB_RECALL_LAST_LIVE] } } @@ -153,7 +153,7 @@ export class GlobalAdlibActionsGenerator { _rank: rank + 0.1 * box, label: t(`${name} inp ${box + 1}`), sourceLayerId: layer, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, content: {}, tags: [AdlibTagCutToBox(box)] } @@ -187,7 +187,7 @@ export class GlobalAdlibActionsGenerator { _rank: rank + 0.1 * box, label: t(`${name} inp ${box + 1}`), sourceLayerId: SourceLayer.PgmLocal, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, content: {}, tags: [AdlibTagCutToBox(box), vo ? AdlibTags.ADLIB_VO_AUDIO_LEVEL : AdlibTags.ADLIB_FULL_AUDIO_LEVEL] } @@ -214,7 +214,7 @@ export class GlobalAdlibActionsGenerator { _rank: rank + 0.1 * box, label: t(`Server inp ${box + 1}`), sourceLayerId: SourceLayer.PgmServer, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, content: {}, tags: [AdlibTagCutToBox(box)] } @@ -238,7 +238,7 @@ export class GlobalAdlibActionsGenerator { _rank: 300, label: t(`GFX Clear`), sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, content: {}, tags: [AdlibTags.ADLIB_STATIC_BUTTON], currentPieceTags: [TallyTags.GFX_CLEAR], @@ -262,7 +262,7 @@ export class GlobalAdlibActionsGenerator { _rank: 400, label: t(`GFX Altud`), sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, content: {}, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_ALTUD], currentPieceTags: [TallyTags.GFX_ALTUD], @@ -303,7 +303,7 @@ export class GlobalAdlibActionsGenerator { _rank: 400, label: t(`Call Robot preset`), sourceLayerId: SourceLayer.RobotCamera, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, tags: [] } } @@ -325,7 +325,7 @@ export class GlobalAdlibActionsGenerator { _rank: 200 + i, label: t(dveConfig.DVEName), sourceLayerId: SourceLayer.PgmDVEAdLib, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, tags: [AdlibTags.ADLIB_SELECT_DVE_LAYOUT, dveConfig.DVEName] } }) @@ -346,7 +346,7 @@ export class GlobalAdlibActionsGenerator { _rank: 300, label: t('Fade down persisted audio levels'), sourceLayerId: SourceLayer.PgmSisyfosAdlibs, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, tags: [AdlibTags.ADLIB_FADE_DOWN_PERSISTED_AUDIO_LEVELS] } } diff --git a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts index da1ee127..6eef4984 100644 --- a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts @@ -8,8 +8,8 @@ import { TSR } from 'blueprints-integration' import { ActionCutToCamera, ActionTakeWithTransition, literal, SourceDefinitionKam } from 'tv2-common' -import { AdlibActionType, NoteType, SharedOutputLayers, SourceType, SwitcherMixEffectLLayer } from 'tv2-constants' -import { ActionExecutionContext } from '../../__mocks__/context' +import { AdlibActionType, NoteType, SharedOutputLayer, SourceType, SwitcherMixEffectLLayer } from 'tv2-constants' +import { ActionExecutionContextMock } from '../../__mocks__/context' import { prefixLayer } from '../../tv2-common/__tests__/testUtil' import { preprocessConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' @@ -55,7 +55,7 @@ const kamPieceInstance: IBlueprintPieceInstance = { externalId: CURRENT_PART_EXTERNAL_ID, name: 'KAM 1', sourceLayerId: SourceLayer.PgmCam, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: { timelineObjects: [] @@ -74,7 +74,7 @@ const evsPieceInstance: IBlueprintPieceInstance = { externalId: CURRENT_PART_EXTERNAL_ID, name: 'EVS 1', sourceLayerId: SourceLayer.PgmLocal, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: { timelineObjects: [] @@ -133,7 +133,7 @@ const kamPieceInstance_Cut: IBlueprintPieceInstance = { externalId: NEXT_PART_EXTERNAL_ID, name: 'KAM 1', sourceLayerId: SourceLayer.PgmCam, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: { timelineObjects: [ @@ -169,7 +169,7 @@ const kamPieceInstance_Mix: IBlueprintPieceInstance = { externalId: NEXT_PART_EXTERNAL_ID, name: 'KAM 1', sourceLayerId: SourceLayer.PgmCam, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: { timelineObjects: [ @@ -210,7 +210,7 @@ const kamPieceInstance_Effekt: IBlueprintPieceInstance = { externalId: NEXT_PART_EXTERNAL_ID, name: 'KAM 1', sourceLayerId: SourceLayer.PgmCam, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: { timelineObjects: [ @@ -247,7 +247,7 @@ const effektPieceInstance_1: IBlueprintPieceInstance = { externalId: NEXT_PART_EXTERNAL_ID, name: 'EFFEKT 1', sourceLayerId: SourceLayer.PgmJingle, - outputLayerId: SharedOutputLayers.JINGLE, + outputLayerId: SharedOutputLayer.JINGLE, lifespan: PieceLifespan.WithinPart, content: { timelineObjects: [] @@ -267,7 +267,7 @@ const evsPieceInstance_Cut: IBlueprintPieceInstance = { externalId: NEXT_PART_EXTERNAL_ID, name: 'EVS 1', sourceLayerId: SourceLayer.PgmLocal, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: { timelineObjects: [ @@ -303,7 +303,7 @@ const evsPieceInstance_Mix: IBlueprintPieceInstance = { externalId: NEXT_PART_EXTERNAL_ID, name: 'EVS 1', sourceLayerId: SourceLayer.PgmLocal, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: { timelineObjects: [ @@ -344,7 +344,7 @@ const evsPieceInstance_Effekt: IBlueprintPieceInstance = { externalId: NEXT_PART_EXTERNAL_ID, name: 'EVS 1', sourceLayerId: SourceLayer.PgmLocal, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: { timelineObjects: [ @@ -370,7 +370,7 @@ const evsPieceInstance_Effekt: IBlueprintPieceInstance = { } async function getCameraPiece( - context: ActionExecutionContext, + context: ActionExecutionContextMock, part: 'current' | 'next' ): Promise { const piece = await context @@ -382,7 +382,7 @@ async function getCameraPiece( } async function getEVSPiece( - context: ActionExecutionContext, + context: ActionExecutionContextMock, part: 'current' | 'next' ): Promise { const piece = await context @@ -394,7 +394,7 @@ async function getEVSPiece( } async function getTransitionPiece( - context: ActionExecutionContext, + context: ActionExecutionContextMock, part: 'current' | 'next' ): Promise { const piece = await context @@ -430,11 +430,11 @@ function expectATEMToMixOver(piece: IBlueprintPieceInstance, frames: number) { expect(atemObj.content.me.transitionSettings?.mix).toStrictEqual({ rate: frames }) } -function expectTakeAfterExecute(context: ActionExecutionContext) { +function expectTakeAfterExecute(context: ActionExecutionContextMock) { expect(context.takeAfterExecute).toBe(true) } -function expectNoWarningsOrErrors(context: ActionExecutionContext) { +function expectNoWarningsOrErrors(context: ActionExecutionContextMock) { expect(context.getNotes().filter((n) => n.type === NoteType.ERROR || n.type === NoteType.NOTIFY_USER_ERROR)).toEqual( [] ) @@ -447,10 +447,10 @@ function makeMockContext( defaultTransition: 'cut' | 'mix' | 'effekt', currentPiece: 'cam' | 'evs', nextPiece: 'cam' | 'evs' -): ActionExecutionContext { +): ActionExecutionContextMock { switch (defaultTransition) { case 'cut': { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -468,7 +468,7 @@ function makeMockContext( return context } case 'mix': { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -486,7 +486,7 @@ function makeMockContext( return context } case 'effekt': { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -510,7 +510,7 @@ function makeMockContext( } async function checkPartExistsWithProperties( - context: ActionExecutionContext, + context: ActionExecutionContextMock, part: 'current' | 'next', props: Partial ) { @@ -804,7 +804,7 @@ describe('Camera shortcuts on server', () => { externalId: CURRENT_PART_EXTERNAL_ID, name: 'SERVER', sourceLayerId: SourceLayer.PgmServer, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: { timelineObjects: [] @@ -847,7 +847,7 @@ describe('Camera shortcuts on server', () => { externalId: CURRENT_PART_EXTERNAL_ID, name: 'SERVER', sourceLayerId: SourceLayer.PgmServer, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: { timelineObjects: [] @@ -892,7 +892,7 @@ describe('Camera shortcuts on VO', () => { externalId: CURRENT_PART_EXTERNAL_ID, name: 'VO', sourceLayerId: SourceLayer.PgmVoiceOver, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: { timelineObjects: [] @@ -935,7 +935,7 @@ describe('Camera shortcuts on VO', () => { externalId: CURRENT_PART_EXTERNAL_ID, name: 'VO', sourceLayerId: SourceLayer.PgmVoiceOver, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: { timelineObjects: [] diff --git a/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts b/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts index 160a6bb7..bc5e7ab0 100644 --- a/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts @@ -1,6 +1,6 @@ import { IBlueprintPiece, PieceLifespan, ScriptContent, WithTimeline } from 'blueprints-integration' import { AddScript, literal, PartDefinitionKam } from 'tv2-common' -import { PartType, SharedOutputLayers, SourceType } from 'tv2-constants' +import { PartType, SharedOutputLayer, SourceType } from 'tv2-constants' import { SourceLayer } from '../layers' describe('addScript', () => { @@ -32,7 +32,7 @@ describe('addScript', () => { name: 'Kam 2', lifespan: PieceLifespan.WithinPart, sourceLayerId: SourceLayer.PgmCam, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, content: { timelineObjects: [] } @@ -46,7 +46,7 @@ describe('addScript', () => { enable: { start: 0 }, - outputLayerId: SharedOutputLayers.MANUS, + outputLayerId: SharedOutputLayer.MANUS, sourceLayerId: SourceLayer.PgmScript, lifespan: PieceLifespan.WithinPart, content: literal>({ diff --git a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts index acda6396..d79e322e 100644 --- a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts @@ -9,7 +9,7 @@ global.VERSION_INTEGRATION = 'test' import { ExtendedIngestRundown, IGetRundownContext, TSR } from 'blueprints-integration' import { SwitcherType } from 'tv2-common' -import { GetRundownContext } from '../../__mocks__/context' +import { GetRundownContextMock } from '../../__mocks__/context' import { SharedGraphicLLayer } from '../../tv2-constants' import { preprocessConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' @@ -28,7 +28,7 @@ describe.each([SwitcherType.ATEM, SwitcherType.TRICASTER])('Baseline', (switcher expect(configSpec.showStyleConfig).toBeTruthy() const mockRundown: ExtendedIngestRundown = createMockRundown() - const mockContext: GetRundownContext = createMockContext(mockRundown.name, switcherType) + const mockContext: GetRundownContextMock = createMockContext(mockRundown.name, switcherType) const result = await Blueprints.getRundown(mockContext, mockRundown) if (result === null) { @@ -74,8 +74,8 @@ function createMockRundown(): ExtendedIngestRundown { } } -function createMockContext(rundownName: string, switcherType: SwitcherType): GetRundownContext { - const mockContext = new GetRundownContext( +function createMockContext(rundownName: string, switcherType: SwitcherType): GetRundownContextMock { + const mockContext = new GetRundownContextMock( rundownName, mappingsDefaults, parseStudioConfig, diff --git a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts index 8dfdc905..1dc2e5a2 100644 --- a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts @@ -1,7 +1,7 @@ import { BlueprintResultSegment, IBlueprintActionManifestDisplayContent, IngestSegment } from 'blueprints-integration' import { INewsStory, literal, UnparsedCue } from 'tv2-common' -import { SharedSourceLayers } from 'tv2-constants' -import { makeMockCoreGalleryContext, SegmentUserContext } from '../../__mocks__/context' +import { SharedSourceLayer } from 'tv2-constants' +import { makeMockCoreGalleryContext, SegmentUserContextMock } from '../../__mocks__/context' import { SisyfosLLAyer } from '../../tv2_afvd_studio/layers' import { getSegment } from '../getSegment' import { SourceLayer } from '../layers' @@ -37,7 +37,7 @@ function makeIngestSegment(cues: UnparsedCue[], body: string) { }) } -function expectNotesToBe(context: SegmentUserContext, notes: string[]) { +function expectNotesToBe(context: SegmentUserContextMock, notes: string[]) { expect(context.getNotes().map((msg) => msg.message)).toEqual(notes) } @@ -59,7 +59,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(1) - expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmJingle]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle]) expect(kamPart.pieces[0].name).toEqual('CS 3 (JINGLE)') }) @@ -75,7 +75,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(1) - expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmJingle]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle]) expect(kamPart.pieces[0].name).toEqual('CS 3 (JINGLE)') }) @@ -102,10 +102,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) }) @@ -124,10 +121,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -160,10 +154,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -171,15 +162,15 @@ describe('AFVD Blueprint', () => { expect(fullPart).toBeTruthy() expect(fullPart.pieces).toHaveLength(2) expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmPilot, - SharedSourceLayers.SelectedAdlibGraphicsFull + SharedSourceLayer.PgmPilot, + SharedSourceLayer.SelectedAdlibGraphicsFull ]) expect(fullPart.adLibPieces).toHaveLength(0) expect(fullPart.actions).toHaveLength(1) const fullAdlibAction = fullPart.actions[0] expect(fullAdlibAction).toBeTruthy() expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( - SharedSourceLayers.PgmPilot + SharedSourceLayer.PgmPilot ) }) @@ -207,10 +198,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -251,10 +239,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -266,11 +251,11 @@ describe('AFVD Blueprint', () => { const fullAdlibAction = fullPart.actions[0] expect(fullAdlibAction).toBeTruthy() expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( - SharedSourceLayers.PgmPilot + SharedSourceLayer.PgmPilot ) expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmPilot, - SharedSourceLayers.SelectedAdlibGraphicsFull + SharedSourceLayer.PgmPilot, + SharedSourceLayer.SelectedAdlibGraphicsFull ]) }) @@ -306,10 +291,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -321,12 +303,12 @@ describe('AFVD Blueprint', () => { const fullAdlibAction = fullPart.actions[0] expect(fullAdlibAction).toBeTruthy() expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( - SharedSourceLayers.PgmPilot + SharedSourceLayer.PgmPilot ) expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmPilot, - SharedSourceLayers.SelectedAdlibGraphicsFull, - SharedSourceLayers.PgmPilotOverlay + SharedSourceLayer.PgmPilot, + SharedSourceLayer.SelectedAdlibGraphicsFull, + SharedSourceLayer.PgmPilotOverlay ]) }) @@ -355,10 +337,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -366,8 +345,8 @@ describe('AFVD Blueprint', () => { expect(fullPart).toBeTruthy() expect(fullPart.pieces).toHaveLength(2) expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmPilot, - SharedSourceLayers.SelectedAdlibGraphicsFull + SharedSourceLayer.PgmPilot, + SharedSourceLayer.SelectedAdlibGraphicsFull ]) expect(fullPart.adLibPieces).toHaveLength(0) expect(fullPart.actions).toHaveLength(1) @@ -375,7 +354,7 @@ describe('AFVD Blueprint', () => { const fullAdlibAction = fullPart.actions[0] expect(fullAdlibAction).toBeTruthy() expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( - SharedSourceLayers.PgmPilot + SharedSourceLayer.PgmPilot ) }) @@ -403,10 +382,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -442,10 +418,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -480,10 +453,7 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart1.adLibPieces).toHaveLength(0) expect(kamPart1.actions).toHaveLength(0) @@ -497,7 +467,7 @@ describe('AFVD Blueprint', () => { const kamPart2 = result.parts[2] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(1) - expect(kamPart2.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam]) + expect(kamPart2.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam]) expect(kamPart2.adLibPieces).toHaveLength(0) expect(kamPart2.actions).toHaveLength(0) }) @@ -527,9 +497,9 @@ describe('AFVD Blueprint', () => { expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(3) expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmPilotOverlay, - SharedSourceLayers.PgmScript + SharedSourceLayer.PgmCam, + SharedSourceLayer.PgmPilotOverlay, + SharedSourceLayer.PgmScript ]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -560,9 +530,9 @@ describe('AFVD Blueprint', () => { expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(3) expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.WallGraphics, - SharedSourceLayers.PgmScript + SharedSourceLayer.PgmCam, + SharedSourceLayer.WallGraphics, + SharedSourceLayer.PgmScript ]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -592,10 +562,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -607,11 +574,11 @@ describe('AFVD Blueprint', () => { const fullAdlibAction = fullPart.actions[0] expect(fullAdlibAction).toBeTruthy() expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( - SharedSourceLayers.PgmPilot + SharedSourceLayer.PgmPilot ) expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmPilot, - SharedSourceLayers.SelectedAdlibGraphicsFull + SharedSourceLayer.PgmPilot, + SharedSourceLayer.SelectedAdlibGraphicsFull ]) }) @@ -641,17 +608,17 @@ describe('AFVD Blueprint', () => { expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(3) expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.WallGraphics, - SharedSourceLayers.PgmScript + SharedSourceLayer.PgmCam, + SharedSourceLayer.WallGraphics, + SharedSourceLayer.PgmScript ]) const kamPart2 = result.parts[1] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(2) expect(kamPart2.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.WallGraphics + SharedSourceLayer.PgmCam, + SharedSourceLayer.WallGraphics ]) }) @@ -673,18 +640,12 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) const kamPart2 = result.parts[1] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(2) - expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) }) it('Shows warning for missing wall graphic with MOSART=L', async () => { @@ -713,17 +674,17 @@ describe('AFVD Blueprint', () => { expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(3) expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmPilotOverlay, - SharedSourceLayers.PgmScript + SharedSourceLayer.PgmCam, + SharedSourceLayer.PgmPilotOverlay, + SharedSourceLayer.PgmScript ]) const kamPart2 = result.parts[1] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(2) expect(kamPart2.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.WallGraphics + SharedSourceLayer.PgmCam, + SharedSourceLayer.WallGraphics ]) }) @@ -752,17 +713,14 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmScript - ]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) const kamPart2 = result.parts[1] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(2) expect(kamPart2.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.WallGraphics + SharedSourceLayer.PgmCam, + SharedSourceLayer.WallGraphics ]) }) @@ -786,11 +744,11 @@ describe('AFVD Blueprint', () => { expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(5) expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmCam, - SharedSourceLayers.PgmDesign, + SharedSourceLayer.PgmCam, + SharedSourceLayer.PgmDesign, SourceLayer.PgmDVEBackground, SourceLayer.PgmFullBackground, - SharedSourceLayers.PgmScript + SharedSourceLayer.PgmScript ]) }) @@ -806,7 +764,7 @@ describe('AFVD Blueprint', () => { const livePart1 = result.parts[0] expect(livePart1).toBeTruthy() expect(livePart1.pieces).toHaveLength(1) - expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) + expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmLive]) }) it('Creates Live 1', async () => { @@ -821,7 +779,7 @@ describe('AFVD Blueprint', () => { const livePart1 = result.parts[0] expect(livePart1).toBeTruthy() expect(livePart1.pieces).toHaveLength(1) - expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) + expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmLive]) }) it('Creates Feed1', async () => { @@ -836,7 +794,7 @@ describe('AFVD Blueprint', () => { const feedPart1 = result.parts[0] expect(feedPart1).toBeTruthy() expect(feedPart1.pieces).toHaveLength(1) - expect(feedPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) + expect(feedPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmLive]) }) it('Creates Feed 1', async () => { @@ -851,7 +809,7 @@ describe('AFVD Blueprint', () => { const feedPart1 = result.parts[0] expect(feedPart1).toBeTruthy() expect(feedPart1.pieces).toHaveLength(1) - expect(feedPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) + expect(feedPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmLive]) }) it('Creates invalid part for EKSTERN=LIVE', async () => { @@ -880,10 +838,7 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmJingle, - SharedSourceLayers.PgmCam - ]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle, SharedSourceLayer.PgmCam]) expect(kamPart1.pieces[0].name).toBe('EFFEKT 1') }) @@ -899,10 +854,7 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmJingle, - SharedSourceLayers.PgmCam - ]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle, SharedSourceLayer.PgmCam]) expect(kamPart1.pieces[0].name).toBe('MIX 5') }) @@ -922,8 +874,8 @@ describe('AFVD Blueprint', () => { expect(livePart1).toBeTruthy() expect(livePart1.pieces).toHaveLength(2) expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmJingle, - SharedSourceLayers.PgmLive + SharedSourceLayer.PgmJingle, + SharedSourceLayer.PgmLive ]) expect(livePart1.pieces[0].name).toBe('EFFEKT 1') }) @@ -944,8 +896,8 @@ describe('AFVD Blueprint', () => { expect(livePart1).toBeTruthy() expect(livePart1.pieces).toHaveLength(2) expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([ - SharedSourceLayers.PgmJingle, - SharedSourceLayers.PgmLive + SharedSourceLayer.PgmJingle, + SharedSourceLayer.PgmLive ]) expect(livePart1.pieces[0].name).toBe('MIX 10') }) diff --git a/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts b/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts index cd4ac6af..b4b74215 100644 --- a/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts @@ -12,7 +12,7 @@ global.VERSION_TSR = 'test' global.VERSION_INTEGRATION = 'test' import { INewsStory } from 'tv2-common' -import { SegmentUserContext } from '../../__mocks__/context' +import { SegmentUserContextMock } from '../../__mocks__/context' import { preprocessConfig as parseStudioConfig, StudioConfig } from '../../tv2_afvd_studio/helpers/config' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' import { GalleryShowStyleConfig, preprocessConfig as parseShowStyleConfig } from '../helpers/config' @@ -36,7 +36,12 @@ describe('Generate rundowns without error', () => { for (const segment of roData.segments) { test(`Rundown segment: ${segment.name} - ${roSpec.ro} - ${roData.externalId}`, async () => { - const mockContext = new SegmentUserContext('test', mappingsDefaults, parseStudioConfig, parseShowStyleConfig) + const mockContext = new SegmentUserContextMock( + 'test', + mappingsDefaults, + parseStudioConfig, + parseShowStyleConfig + ) mockContext.studioConfig = roSpec.studioConfig as any mockContext.showStyleConfig = roSpec.showStyleConfig as any diff --git a/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts b/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts index a92771d6..98aaf38b 100644 --- a/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts @@ -9,8 +9,8 @@ import { PlaylistTimingType } from 'blueprints-integration' import { literal } from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' -import { SyncIngestUpdateToPartInstanceContext } from '../../__mocks__/context' +import { SharedOutputLayer } from 'tv2-constants' +import { SyncIngestUpdateToPartInstanceContextMock } from '../../__mocks__/context' import { preprocessConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' import { preprocessConfig as parseShowStyleConfig } from '../helpers/config' @@ -19,7 +19,7 @@ import { syncIngestUpdateToPartInstance } from '../syncIngestUpdateToPartInstanc const RUNDOWN_EXTERNAL_ID = 'TEST.SOFIE.JEST' -function makeMockContext(): SyncIngestUpdateToPartInstanceContext { +function makeMockContext(): SyncIngestUpdateToPartInstanceContextMock { const rundown = literal({ externalId: RUNDOWN_EXTERNAL_ID, name: RUNDOWN_EXTERNAL_ID, @@ -29,7 +29,7 @@ function makeMockContext(): SyncIngestUpdateToPartInstanceContext { type: PlaylistTimingType.None } }) - return new SyncIngestUpdateToPartInstanceContext( + return new SyncIngestUpdateToPartInstanceContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -75,7 +75,7 @@ function makeSoundBed( name, lifespan: PieceLifespan.OutOnShowStyleEnd, sourceLayerId: SourceLayer.PgmAudioBed, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, content: { timelineObjects: [] } diff --git a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts index 50c42dd2..cd2840a2 100644 --- a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts @@ -1,9 +1,9 @@ import { fail } from 'assert' import { BlueprintResultSegment, IBlueprintPart, IBlueprintPiece, IngestSegment, TSR } from 'blueprints-integration' -import { TimeFromFrames } from 'tv2-common' +import { getTimeFromFrames } from 'tv2-common' import { SwitcherMixEffectLLayer } from 'tv2-constants' import * as _ from 'underscore' -import { SegmentUserContext } from '../../__mocks__/context' +import { SegmentUserContextMock } from '../../__mocks__/context' import { prefixLayer } from '../../tv2-common/__tests__/testUtil' import { preprocessConfig } from '../../tv2_afvd_studio/helpers/config' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' @@ -58,7 +58,7 @@ const templateSegment: IngestSegment = { parts: [] } -function makeMockContextWithoutTransitionsConfig(): SegmentUserContext { +function makeMockContextWithoutTransitionsConfig(): SegmentUserContextMock { const context = makeMockContext() // context.showStyleConfig.DefaultTransitions = [] @@ -66,10 +66,10 @@ function makeMockContextWithoutTransitionsConfig(): SegmentUserContext { return context } -function makeMockContext(): SegmentUserContext { +function makeMockContext(): SegmentUserContextMock { const config = { id: 'default', studioConfig: defaultStudioConfig, showStyleConfig: defaultShowStyleConfig } - const mockContext = new SegmentUserContext('test', mappingsDefaults, preprocessConfig, parseShowStyleConfig) + const mockContext = new SegmentUserContextMock('test', mappingsDefaults, preprocessConfig, parseShowStyleConfig) mockContext.studioConfig = config.studioConfig as any mockContext.showStyleConfig = config.showStyleConfig as any @@ -93,10 +93,10 @@ function getTransitionProperties(effekt: GalleryShowStyleConfig['BreakerConfig'] const preroll = defaultStudioConfig.CasparPrerollDuration as number return { inTransition: { - blockTakeDuration: TimeFromFrames(Number(effekt.Duration)) + preroll, - previousPartKeepaliveDuration: TimeFromFrames(Number(effekt.StartAlpha)) + preroll, + blockTakeDuration: getTimeFromFrames(Number(effekt.Duration)) + preroll, + previousPartKeepaliveDuration: getTimeFromFrames(Number(effekt.StartAlpha)) + preroll, partContentDelayDuration: - TimeFromFrames(Number(effekt.Duration)) - TimeFromFrames(Number(effekt.EndAlpha)) + preroll + getTimeFromFrames(Number(effekt.Duration)) - getTimeFromFrames(Number(effekt.EndAlpha)) + preroll } } } @@ -120,7 +120,7 @@ function getATEMMEObj(piece: IBlueprintPiece): TSR.TimelineObjAtemME { return atemMEObj } -function testNotes(context: SegmentUserContext) { +function testNotes(context: SegmentUserContextMock) { expect(context.getNotes()).toStrictEqual([]) } diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 23149802..89254543 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -16,8 +16,6 @@ import { createDskBaseline, CreateDSKBaselineAdlibs, CreateLYDBaseline, - ExtendedShowStyleContext, - ExtendedShowStyleContextImpl, FindDSKJingle, getGraphicBaseline, getMixMinusTimelineObject, @@ -27,6 +25,8 @@ import { MixMinusPriority, PieceMetaData, replaySourceName, + ShowStyleContext, + ShowStyleContextImpl, SourceInfo, SpecialInput, SwitcherType, @@ -37,7 +37,7 @@ import { CONSTANTS, ControlClasses, SharedGraphicLLayer, - SharedOutputLayers, + SharedOutputLayer, SwitcherAuxLLayer, SwitcherDveLLayer } from 'tv2-constants' @@ -51,7 +51,7 @@ import { GalleryBlueprintConfig } from './helpers/config' import { SourceLayer } from './layers' export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: IngestRundown): BlueprintResultRundown { - const context = new ExtendedShowStyleContextImpl(coreContext, GALLERY_UNIFORM_CONFIG) + const context = new ShowStyleContextImpl(coreContext, GALLERY_UNIFORM_CONFIG) return { rundown: { externalId: ingestRundown.externalId, @@ -68,7 +68,7 @@ export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: In class GlobalAdLibPiecesGenerator { private config: GalleryBlueprintConfig - constructor(private readonly context: ExtendedShowStyleContext) { + constructor(private readonly context: ShowStyleContext) { this.config = context.config } @@ -145,7 +145,7 @@ class GlobalAdLibPiecesGenerator { _rank: 301, externalId: 'dve-design-sc', name: 'DVE Design SC', - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, sourceLayerId: SourceLayer.PgmDesign, lifespan: PieceLifespan.OutOnShowStyleEnd, tags: [AdlibTags.ADLIB_DESIGN_STYLE_SC], @@ -165,7 +165,7 @@ class GlobalAdLibPiecesGenerator { name: replaySourceName(info.id, vo), _rank: rank, sourceLayerId: SourceLayer.PgmLocal, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, expectedDuration: 0, lifespan: PieceLifespan.WithinPart, toBeQueued: true, @@ -199,7 +199,7 @@ class GlobalAdLibPiecesGenerator { name: `EVS in studio aux`, _rank: rank, sourceLayerId: SourceLayer.AuxStudioScreen, - outputLayerId: SharedOutputLayers.AUX, + outputLayerId: SharedOutputLayer.AUX, expectedDuration: 0, lifespan: PieceLifespan.OutOnShowStyleEnd, tags: [AdlibTags.ADLIB_TO_STUDIO_SCREEN_AUX], @@ -224,7 +224,7 @@ class GlobalAdLibPiecesGenerator { name: `EVS in viz aux`, _rank: rank, sourceLayerId: SourceLayer.VizFullIn1, - outputLayerId: SharedOutputLayers.AUX, + outputLayerId: SharedOutputLayer.AUX, expectedDuration: 0, lifespan: PieceLifespan.OutOnShowStyleEnd, tags: [AdlibTags.ADLIB_TO_GRAPHICS_ENGINE_AUX], @@ -251,7 +251,7 @@ class GlobalAdLibPiecesGenerator { name: `LIVE ${info.id}`, _rank: rank, sourceLayerId: SourceLayer.PgmLive, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, expectedDuration: 0, lifespan: PieceLifespan.WithinPart, toBeQueued: true, @@ -272,7 +272,7 @@ class GlobalAdLibPiecesGenerator { input: info.port, transition: TransitionStyle.CUT }, - classes: [ControlClasses.OVERRIDEN_ON_MIX_MINUS] + classes: [ControlClasses.OVERRIDDEN_ON_MIX_MINUS] }), ...eksternSisyfos ] @@ -290,7 +290,7 @@ class GlobalAdLibPiecesGenerator { name: info.id + '', _rank: rank, sourceLayerId: SourceLayer.AuxStudioScreen, - outputLayerId: SharedOutputLayers.AUX, + outputLayerId: SharedOutputLayer.AUX, expectedDuration: 0, lifespan: PieceLifespan.OutOnShowStyleEnd, metaData: { @@ -326,7 +326,7 @@ class GlobalAdLibPiecesGenerator { name: 'OVL INIT', _rank: 100, sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, expectedDuration: 1000, lifespan: PieceLifespan.WithinPart, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_LOAD], @@ -353,7 +353,7 @@ class GlobalAdLibPiecesGenerator { name: 'GFX Continue', _rank: 200, sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, expectedDuration: 1000, lifespan: PieceLifespan.WithinPart, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_CONTINUE_FORWARD], @@ -387,7 +387,7 @@ class GlobalAdLibPiecesGenerator { name: 'Mics Up', _rank: 600, sourceLayerId: SourceLayer.PgmSisyfosAdlibs, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, lifespan: PieceLifespan.WithinPart, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_MICS_UP], expectedDuration: 0, @@ -416,7 +416,7 @@ class GlobalAdLibPiecesGenerator { name: 'Mics Down', _rank: 650, sourceLayerId: SourceLayer.PgmSisyfosAdlibs, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, lifespan: PieceLifespan.WithinPart, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_MICS_DOWN], expectedDuration: 0, @@ -445,7 +445,7 @@ class GlobalAdLibPiecesGenerator { name: 'Resync Sisyfos', _rank: 700, sourceLayerId: SourceLayer.PgmSisyfosAdlibs, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, lifespan: PieceLifespan.WithinPart, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIBS_RESYNC_SISYFOS], expectedDuration: 1000, @@ -500,7 +500,7 @@ class GlobalAdLibPiecesGenerator { } } -function getBaseline(context: ExtendedShowStyleContext): BlueprintResultBaseline { +function getBaseline(context: ShowStyleContext): BlueprintResultBaseline { const jingleDSK = FindDSKJingle(context.config) return { @@ -786,7 +786,7 @@ function getBaseline(context: ExtendedShowStyleContext): } } -function getMixEffectBaseline(context: ExtendedShowStyleContext): TSR.TSRTimelineObj[] { +function getMixEffectBaseline(context: ShowStyleContext): TSR.TSRTimelineObj[] { return Object.values(context.uniformConfig.mixEffects).flatMap((mixEffect) => _.compact([ context.videoSwitcher.getMixEffectTimelineObject({ diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index ccc1c049..ff1acf52 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -8,15 +8,8 @@ import { PieceLifespan, WithTimeline } from 'blueprints-integration' -import { - ExtendedSegmentContext, - ExtendedSegmentContextImpl, - getSegmentBase, - INewsPayload, - literal, - TransitionStyle -} from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' +import { getSegmentBase, INewsPayload, literal, SegmentContext, SegmentContextImpl, TransitionStyle } from 'tv2-common' +import { SharedOutputLayer } from 'tv2-constants' import * as _ from 'underscore' import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' import { GalleryBlueprintConfig } from './helpers/config' @@ -36,7 +29,7 @@ export async function getSegment( ingestSegment: IngestSegment ): Promise { const segmentPayload = ingestSegment.payload as INewsPayload | undefined - const context = new ExtendedSegmentContextImpl(coreContext, GALLERY_UNIFORM_CONFIG) + const context = new SegmentContextImpl(coreContext, GALLERY_UNIFORM_CONFIG) const result: BlueprintResultSegment = await getSegmentBase(context, ingestSegment, { CreatePartContinuity, @@ -65,7 +58,7 @@ export async function getSegment( } export function CreatePartContinuity( - context: ExtendedSegmentContext, + context: SegmentContext, ingestSegment: IngestSegment ): BlueprintResultPart { return { @@ -82,7 +75,7 @@ export function CreatePartContinuity( }, name: 'CONTINUITY', sourceLayerId: SourceLayer.PgmContinuity, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: literal>({ studioLabel: '', diff --git a/src/tv2_afvd_showstyle/helpers/content/dve.ts b/src/tv2_afvd_showstyle/helpers/content/dve.ts index 772b2c8d..ea8efc0a 100644 --- a/src/tv2_afvd_showstyle/helpers/content/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/content/dve.ts @@ -3,9 +3,9 @@ import { CueDefinitionDVE, DVEConfigInput, DVEOptions, - ExtendedShowStyleContext, MakeContentDVEBase, - PartDefinition + PartDefinition, + ShowStyleContext } from 'tv2-common' import { GalleryBlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' @@ -29,7 +29,7 @@ export const AFVD_DVE_GENERATOR_OPTIONS: DVEOptions = { } export function MakeContentDVE( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, parsedCue: CueDefinitionDVE, dveConfig: DVEConfigInput | undefined diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts index 54901189..88555a87 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -17,7 +17,7 @@ import { PartDefinitionKam, PieceMetaData } from 'tv2-common' -import { AdlibTags, CueType, PartType, SharedGraphicLLayer, SharedOutputLayers, SourceType } from 'tv2-constants' +import { AdlibTags, CueType, PartType, SharedGraphicLLayer, SharedOutputLayer, SourceType } from 'tv2-constants' import { makeMockGalleryContext } from '../../../../__mocks__/context' import { prefixLayer } from '../../../../tv2-common/__tests__/testUtil' import { OVL_SHOW_NAME } from '../../../__tests__/configs' @@ -125,7 +125,7 @@ describe('grafik piece', () => { partType: PartType.Kam, pieceExternalId: dummyPart.externalId }, - outputLayerId: SharedOutputLayers.OVERLAY, + outputLayerId: SharedOutputLayer.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, content: literal>({ fileName: 'bund', @@ -188,7 +188,7 @@ describe('grafik piece', () => { sisyfosLayers: [] } }), - outputLayerId: SharedOutputLayers.OVERLAY, + outputLayerId: SharedOutputLayer.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, uniquenessId: 'gfx_bund - Odense\n - Copenhagen_studio0_graphicsLower_overlay_commentator', expectedDuration: 5000, @@ -228,7 +228,7 @@ describe('grafik piece', () => { sisyfosLayers: [] } }), - outputLayerId: SharedOutputLayers.OVERLAY, + outputLayerId: SharedOutputLayer.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, uniquenessId: 'gfx_bund - Odense\n - Copenhagen_studio0_graphicsLower_overlay_flow', expectedDuration: 4000, @@ -294,7 +294,7 @@ describe('grafik piece', () => { sisyfosLayers: [] } }), - outputLayerId: SharedOutputLayers.OVERLAY, + outputLayerId: SharedOutputLayer.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, uniquenessId: 'gfx_bund - Odense\n - Copenhagen_studio0_graphicsLower_overlay_commentator', tags: [AdlibTags.ADLIB_KOMMENTATOR], @@ -334,7 +334,7 @@ describe('grafik piece', () => { sisyfosLayers: [] } }), - outputLayerId: SharedOutputLayers.OVERLAY, + outputLayerId: SharedOutputLayer.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, uniquenessId: 'gfx_bund - Odense\n - Copenhagen_studio0_graphicsLower_overlay_flow', tags: [AdlibTags.ADLIB_FLOW_PRODUCER], @@ -407,7 +407,7 @@ describe('grafik piece', () => { partType: PartType.Kam, pieceExternalId: dummyPart.externalId }, - outputLayerId: SharedOutputLayers.OVERLAY, + outputLayerId: SharedOutputLayer.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, content: literal>({ fileName: 'bund', @@ -558,7 +558,7 @@ describe('grafik piece', () => { partType: PartType.Kam, pieceExternalId: dummyPart.externalId }, - outputLayerId: SharedOutputLayers.OVERLAY, + outputLayerId: SharedOutputLayer.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsIdent, content: literal>({ fileName: 'direkte', @@ -628,7 +628,7 @@ describe('grafik piece', () => { partType: PartType.Kam, pieceExternalId: dummyPart.externalId }, - outputLayerId: SharedOutputLayers.OVERLAY, + outputLayerId: SharedOutputLayer.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsIdent, content: literal>({ fileName: 'arkiv', @@ -691,7 +691,7 @@ describe('grafik piece', () => { sisyfosLayers: [] } }), - outputLayerId: SharedOutputLayers.OVERLAY, + outputLayerId: SharedOutputLayer.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsTop, expectedDuration: 5000, tags: ['kommentator'], @@ -731,7 +731,7 @@ describe('grafik piece', () => { sisyfosLayers: [] } }), - outputLayerId: SharedOutputLayers.OVERLAY, + outputLayerId: SharedOutputLayer.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsTop, tags: ['flow_producer'], uniquenessId: 'gfx_tlftoptlive - Line 1\n - Line 2_studio0_graphicsTop_overlay_flow', diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts index c5958427..b7c060ce 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts @@ -6,8 +6,8 @@ import { TSR } from 'blueprints-integration' import { CueDefinitionLYD, EvaluateLYD, literal, ParseCue, PartDefinitionKam } from 'tv2-common' -import { AdlibTags, NoteType, PartType, SharedOutputLayers, SharedSourceLayers, SourceType } from 'tv2-constants' -import { makeMockGalleryContext, SegmentUserContext } from '../../../../__mocks__/context' +import { AdlibTags, NoteType, PartType, SharedOutputLayer, SharedSourceLayer, SourceType } from 'tv2-constants' +import { makeMockGalleryContext, SegmentUserContextMock } from '../../../../__mocks__/context' const CONFIG = makeMockGalleryContext().config const MOCK_PART = literal({ @@ -70,8 +70,8 @@ describe('lyd', () => { EvaluateLYD(context, pieces, adlibPieces, actions, parsedCue, MOCK_PART) expect(pieces.length).toEqual(0) - expect((context.core as SegmentUserContext).getNotes().length).toEqual(1) - expect((context.core as SegmentUserContext).getNotes()[0].type).toEqual(NoteType.NOTIFY_USER_WARNING) + expect((context.core as SegmentUserContextMock).getNotes().length).toEqual(1) + expect((context.core as SegmentUserContextMock).getNotes()[0].type).toEqual(NoteType.NOTIFY_USER_WARNING) }) test('Lyd adlib', () => { @@ -86,8 +86,8 @@ describe('lyd', () => { expect(adlibPieces[0]).toMatchObject( literal>({ name: 'SN_INTRO', - outputLayerId: SharedOutputLayers.MUSIK, - sourceLayerId: SharedSourceLayers.PgmAudioBed, + outputLayerId: SharedOutputLayer.MUSIK, + sourceLayerId: SharedSourceLayer.PgmAudioBed, lifespan: PieceLifespan.OutOnRundownChange, tags: [AdlibTags.ADLIB_FLOW_PRODUCER] }) diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts index 0e4030a0..2280a97e 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -8,7 +8,7 @@ import { literal, PartDefinitionKam } from 'tv2-common' -import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayers, SourceType } from 'tv2-constants' +import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayer, SourceType } from 'tv2-constants' import { makeMockGalleryContext } from '../../../../__mocks__/context' import { prefixLayer } from '../../../../tv2-common/__tests__/testUtil' import { OVL_SHOW_NAME } from '../../../../tv2_afvd_showstyle/__tests__/configs' @@ -67,7 +67,7 @@ describe('telefon', () => { enable: { start: 0 }, - outputLayerId: SharedOutputLayers.OVERLAY, + outputLayerId: SharedOutputLayer.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, lifespan: PieceLifespan.WithinPart, metaData: { diff --git a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts index f9215cfc..e614c0ef 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts @@ -4,22 +4,22 @@ import { CreateAdlibServer, CueDefinitionAdLib, CueDefinitionDVE, - ExtendedShowStyleContext, generateExternalId, GetDVETemplate, getUniquenessIdDVE, PartDefinition, + ShowStyleContext, t, TemplateIsValid } from 'tv2-common' -import { AdlibActionType, AdlibTags, CueType, SharedOutputLayers } from 'tv2-constants' +import { AdlibActionType, AdlibTags, CueType, SharedOutputLayer } from 'tv2-constants' import { GalleryBlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' import { MakeContentDVE } from '../content/dve' export async function EvaluateAdLib( - context: ExtendedShowStyleContext, + context: ShowStyleContext, actions: IBlueprintActionManifest[], mediaSubscriptions: HackPartMediaObjectSubscription[], parsedCue: CueDefinitionAdLib, @@ -100,7 +100,7 @@ export async function EvaluateAdLib( userDataManifest: {}, display: { sourceLayerId: SourceLayer.PgmDVE, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, uniquenessId: getUniquenessIdDVE(cueDVE), label: t(`${partDefinition.storyName}`), tags: [AdlibTags.ADLIB_FLOW_PRODUCER], diff --git a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts index 06c0721d..65be3807 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts @@ -5,19 +5,13 @@ import { PieceLifespan, TSR } from 'blueprints-integration' -import { - CueDefinitionClearGrafiks, - ExtendedShowStyleContext, - getDefaultOut, - getTimingEnable, - literal -} from 'tv2-common' -import { SharedGraphicLLayer, SharedOutputLayers } from 'tv2-constants' +import { CueDefinitionClearGrafiks, getDefaultOut, getTimingEnable, literal, ShowStyleContext } from 'tv2-common' +import { SharedGraphicLLayer, SharedOutputLayer } from 'tv2-constants' import { GalleryBlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { SourceLayer } from '../../../tv2_afvd_showstyle/layers' export function EvaluateClearGrafiks( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], _adLibPieces: IBlueprintAdLibPiece[], _actions: IBlueprintActionManifest[], @@ -44,7 +38,7 @@ export function EvaluateClearGrafiks( start: getTimingEnable(parsedCue, getDefaultOut(context.config)).enable.start, duration: 1000 }, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, sourceLayerId, lifespan: PieceLifespan.WithinPart, virtual: true, @@ -58,7 +52,7 @@ export function EvaluateClearGrafiks( externalId: partId, name: 'CLEAR', ...getTimingEnable(parsedCue, getDefaultOut(context.config)), - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, lifespan: PieceLifespan.WithinPart, content: { diff --git a/src/tv2_afvd_showstyle/helpers/pieces/design.ts b/src/tv2_afvd_showstyle/helpers/pieces/design.ts index d94c3edc..a9015fee 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/design.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/design.ts @@ -1,9 +1,9 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' -import { CueDefinitionGraphicDesign, EvaluateDesignBase, ExtendedShowStyleContext } from 'tv2-common' +import { CueDefinitionGraphicDesign, EvaluateDesignBase, ShowStyleContext } from 'tv2-common' import * as _ from 'underscore' export function EvaluateCueDesign( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], diff --git a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts index 9f5950c2..bd3a2764 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts @@ -4,22 +4,22 @@ import { calculateTime, CueDefinitionDVE, DVEPieceMetaData, - ExtendedShowStyleContext, generateExternalId, GetDVETemplate, getUniquenessIdDVE, literal, PartDefinition, + ShowStyleContext, t, TemplateIsValid } from 'tv2-common' -import { AdlibActionType, AdlibTags, SharedOutputLayers } from 'tv2-constants' +import { AdlibActionType, AdlibTags, SharedOutputLayer } from 'tv2-constants' import { GalleryBlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { SourceLayer } from '../../../tv2_afvd_showstyle/layers' import { MakeContentDVE } from '../content/dve' export function EvaluateDVE( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], actions: IBlueprintActionManifest[], partDefinition: PartDefinition, @@ -60,7 +60,7 @@ export function EvaluateDVE( userDataManifest: {}, display: { _rank: rank, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, sourceLayerId: SourceLayer.PgmDVE, label: t(`${partDefinition.storyName} DVE: ${parsedCue.template}`), tags: [AdlibTags.ADLIB_FLOW_PRODUCER], @@ -81,7 +81,7 @@ export function EvaluateDVE( start, ...(end ? { duration: end - start } : {}) }, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, sourceLayerId: SourceLayer.PgmDVE, lifespan: PieceLifespan.WithinPart, toBeQueued: true, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts index 5a1dc038..627cbdd6 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts @@ -3,14 +3,14 @@ import { CueDefinitionEkstern, EvaluateCueResult, EvaluateEksternBase, - ExtendedShowStyleContext, PartDefinition, + ShowStyleContext, TV2ShowStyleConfig } from 'tv2-common' import { SourceLayer } from '../../layers' export function EvaluateEkstern( - context: ExtendedShowStyleContext, + context: ShowStyleContext, part: IBlueprintPart, partId: string, parsedCue: CueDefinitionEkstern, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts b/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts index e7092114..fbfc1a15 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts @@ -12,8 +12,8 @@ import { EvaluateCuesBase, EvaluateCuesOptions, EvaluateLYD, - ExtendedShowStyleContext, - PartDefinition + PartDefinition, + ShowStyleContext } from 'tv2-common' import { GalleryBlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { EvaluateAdLib } from './adlib' @@ -28,7 +28,7 @@ import { EvaluateCueRouting } from './routing' import { EvaluateTelefon } from './telefon' export async function EvaluateCues( - context: ExtendedShowStyleContext, + context: ShowStyleContext, part: IBlueprintPart, pieces: IBlueprintPiece[], adLibPieces: IBlueprintAdLibPiece[], diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts index e845f09b..fd800382 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts @@ -3,18 +3,18 @@ import { CreateInternalGraphic, CueDefinitionGraphic, EvaluateCueResult, - ExtendedShowStyleContext, GraphicInternalOrPilot, GraphicIsInternal, GraphicIsPilot, - PartDefinition + PartDefinition, + ShowStyleContext } from 'tv2-common' import { GalleryBlueprintConfig } from '../config' import { EvaluateCueGraphicPilot } from './graphicPilot' import { EvaluateCueRouting } from './routing' export function EvaluateCueGraphic( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partId: string, parsedCue: CueDefinitionGraphic, partDefinition: PartDefinition, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts index fe275bc2..84682cd8 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts @@ -7,19 +7,13 @@ import { TSR, WithTimeline } from 'blueprints-integration' -import { - calculateTime, - CueDefinitionBackgroundLoop, - ExtendedShowStyleContext, - literal, - TV2ShowStyleConfig -} from 'tv2-common' -import { SharedGraphicLLayer, SharedOutputLayers } from 'tv2-constants' +import { calculateTime, CueDefinitionBackgroundLoop, literal, ShowStyleContext, TV2ShowStyleConfig } from 'tv2-common' +import { SharedGraphicLLayer, SharedOutputLayer } from 'tv2-constants' import { CasparLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' export function EvaluateCueBackgroundLoop( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], _actions: IBlueprintActionManifest[], @@ -38,7 +32,7 @@ export function EvaluateCueBackgroundLoop( _rank: rank || 0, externalId: partId, name: fileName, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, sourceLayerId: SourceLayer.PgmDVEBackground, lifespan: PieceLifespan.OutOnShowStyleEnd, content: literal>({ @@ -55,7 +49,7 @@ export function EvaluateCueBackgroundLoop( enable: { start }, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, sourceLayerId: SourceLayer.PgmDVEBackground, lifespan: PieceLifespan.OutOnShowStyleEnd, content: literal>({ @@ -73,7 +67,7 @@ export function EvaluateCueBackgroundLoop( _rank: rank || 0, externalId: partId, name: parsedCue.backgroundLoop, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, sourceLayerId: SourceLayer.PgmFullBackground, lifespan: PieceLifespan.OutOnShowStyleEnd, content: literal>({ @@ -90,7 +84,7 @@ export function EvaluateCueBackgroundLoop( enable: { start }, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, sourceLayerId: SourceLayer.PgmFullBackground, lifespan: PieceLifespan.OutOnShowStyleEnd, content: literal>({ diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts index 10998ff1..184c5d08 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts @@ -3,12 +3,12 @@ import { CreatePilotGraphic, CueDefinitionGraphic, EvaluateCueResult, - ExtendedShowStyleContext, - GraphicPilot + GraphicPilot, + ShowStyleContext } from 'tv2-common' export function EvaluateCueGraphicPilot( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partId: string, parsedCue: CueDefinitionGraphic, segmentExternalId: string, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts index 9f3e2033..9af9bc25 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts @@ -3,21 +3,21 @@ import { ActionSelectJingle, CreateJingleContentBase, CueDefinitionJingle, - ExtendedShowStyleContext, generateExternalId, GetTagForJingle, GetTagForJingleNext, + getTimeFromFrames, PartDefinition, - t, - TimeFromFrames + ShowStyleContext, + t } from 'tv2-common' -import { AdlibActionType, AdlibTags, SharedOutputLayers, TallyTags } from 'tv2-constants' +import { AdlibActionType, AdlibTags, SharedOutputLayer, TallyTags } from 'tv2-constants' import { SourceLayer } from '../../../tv2_afvd_showstyle/layers' import { CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' import { GalleryBlueprintConfig } from '../config' export function EvaluateJingle( - context: ExtendedShowStyleContext, + context: ShowStyleContext, pieces: IBlueprintPiece[], _adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -59,7 +59,7 @@ export function EvaluateJingle( _rank: rank ?? 0, label: t(effekt ? `EFFEKT ${parsedCue.clip}` : parsedCue.clip), sourceLayerId: SourceLayer.PgmJingle, - outputLayerId: SharedOutputLayers.JINGLE, + outputLayerId: SharedOutputLayer.JINGLE, content: { ...createJingleContentAFVD( context, @@ -83,9 +83,9 @@ export function EvaluateJingle( start: 0 }, lifespan: PieceLifespan.WithinPart, - outputLayerId: SharedOutputLayers.JINGLE, + outputLayerId: SharedOutputLayer.JINGLE, sourceLayerId: SourceLayer.PgmJingle, - prerollDuration: context.config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), + prerollDuration: context.config.studio.CasparPrerollDuration + getTimeFromFrames(Number(jingle.StartAlpha)), tags: [!effekt ? TallyTags.JINGLE : ''], content: createJingleContentAFVD( context, @@ -100,7 +100,7 @@ export function EvaluateJingle( } export function createJingleContentAFVD( - context: ExtendedShowStyleContext, + context: ShowStyleContext, file: string, alphaAtStart: number, loadFirstFrame: boolean, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts index 7d9d2678..bb18f4d6 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts @@ -3,16 +3,16 @@ import { calculateTime, CueDefinitionRouting, EvaluateCueResult, - ExtendedShowStyleContext, findSourceInfo, - literal + literal, + ShowStyleContext } from 'tv2-common' -import { SharedOutputLayers, SwitcherAuxLLayer } from 'tv2-constants' +import { SharedOutputLayer, SwitcherAuxLLayer } from 'tv2-constants' import _ = require('underscore') import { SourceLayer } from '../../layers' export function EvaluateCueRouting( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partId: string, parsedCue: CueDefinitionRouting ): EvaluateCueResult { @@ -37,7 +37,7 @@ export function EvaluateCueRouting( start: time }, name, - outputLayerId: SharedOutputLayers.AUX, + outputLayerId: SharedOutputLayer.AUX, sourceLayerId: SourceLayer.VizFullIn1, lifespan: PieceLifespan.WithinPart, content: literal>({ diff --git a/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts b/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts index 5bccb8bb..933c7044 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts @@ -1,6 +1,6 @@ import { BlueprintResultPart, PieceLifespan, TSR } from 'blueprints-integration' import { literal, TV2ShowStyleConfig } from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' +import { SharedOutputLayer } from 'tv2-constants' import { GraphicLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' @@ -15,7 +15,7 @@ export function CreateShowLifecyclePieces( externalId: part.part.externalId, name: 'GFX Show Init', enable: { start: 0 }, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, sourceLayerId: SourceLayer.GraphicsShowLifecycle, lifespan: PieceLifespan.OutOnSegmentChange, content: { diff --git a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts index dd20c48f..ec52ee5c 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts @@ -2,17 +2,17 @@ import { Adlib, CueDefinitionTelefon, EvaluateCueResult, - ExtendedShowStyleContext, GetSisyfosTimelineObjForTelefon, - PartDefinition + PartDefinition, + ShowStyleContext } from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' +import { SharedOutputLayer } from 'tv2-constants' import { SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' import { GalleryBlueprintConfig } from '../config' import { EvaluateCueGraphic } from './graphic' export function EvaluateTelefon( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partId: string, partDefinition: PartDefinition, parsedCue: CueDefinitionTelefon, @@ -39,8 +39,8 @@ export function EvaluateTelefon( function findTelefonPiece(result: EvaluateCueResult) { return result.pieces.find( (p) => - p.outputLayerId === SharedOutputLayers.OVERLAY || - p.outputLayerId === SharedOutputLayers.PGM || - p.outputLayerId === SharedOutputLayers.SEC + p.outputLayerId === SharedOutputLayer.OVERLAY || + p.outputLayerId === SharedOutputLayer.PGM || + p.outputLayerId === SharedOutputLayer.SEC ) } diff --git a/src/tv2_afvd_showstyle/layers.ts b/src/tv2_afvd_showstyle/layers.ts index 2af817cd..91d8599a 100644 --- a/src/tv2_afvd_showstyle/layers.ts +++ b/src/tv2_afvd_showstyle/layers.ts @@ -1,4 +1,4 @@ -import { SharedSourceLayers } from 'tv2-constants' +import { SharedSourceLayer } from 'tv2-constants' export enum AFVDSourceLayer { // Pgm @@ -8,15 +8,12 @@ export enum AFVDSourceLayer { AuxStudioScreen = 'studio0_aux_studio_screen', PgmDVEBackground = 'studio0_dve_back', PgmFullBackground = 'studio0_full_back', - GraphicsShowLifecycle = 'studio0_graphic_show_lifecycle', - - // Wall - WallGraphics = 'studio0_wall_graphics' + GraphicsShowLifecycle = 'studio0_graphic_show_lifecycle' } // tslint:disable-next-line: variable-name export const SourceLayer = { ...AFVDSourceLayer, - ...SharedSourceLayers + ...SharedSourceLayer } -export type SourceLayer = AFVDSourceLayer | SharedSourceLayers +export type SourceLayer = AFVDSourceLayer | SharedSourceLayer diff --git a/src/tv2_afvd_showstyle/migrations/outputlayer-defaults.ts b/src/tv2_afvd_showstyle/migrations/outputlayer-defaults.ts index 1c01fad8..9283ee6e 100644 --- a/src/tv2_afvd_showstyle/migrations/outputlayer-defaults.ts +++ b/src/tv2_afvd_showstyle/migrations/outputlayer-defaults.ts @@ -1,56 +1,56 @@ import { IOutputLayer } from 'blueprints-integration' import { literal } from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' +import { SharedOutputLayer } from 'tv2-constants' export default literal([ { - _id: SharedOutputLayers.OVERLAY, + _id: SharedOutputLayer.OVERLAY, name: 'OVERLAY', isPGM: false, _rank: 10, isDefaultCollapsed: true }, { - _id: SharedOutputLayers.JINGLE, + _id: SharedOutputLayer.JINGLE, name: 'JINGLE', isPGM: false, _rank: 19 }, { - _id: SharedOutputLayers.PGM, + _id: SharedOutputLayer.PGM, name: 'PGM', isPGM: true, _rank: 20, isFlattened: true }, { - _id: SharedOutputLayers.SELECTED_ADLIB, + _id: SharedOutputLayer.SELECTED_ADLIB, name: 'ADLIB', isPGM: false, _rank: 30, isDefaultCollapsed: true }, { - _id: SharedOutputLayers.MUSIK, + _id: SharedOutputLayer.MUSIK, name: 'MUSIK', isPGM: false, _rank: 22 }, { - _id: SharedOutputLayers.MANUS, + _id: SharedOutputLayer.MANUS, name: 'MANUS', isPGM: false, _rank: 23 }, { - _id: SharedOutputLayers.SEC, + _id: SharedOutputLayer.SEC, name: 'SEC', isPGM: false, _rank: 30, isDefaultCollapsed: true }, { - _id: SharedOutputLayers.AUX, + _id: SharedOutputLayer.AUX, name: 'AUX', isPGM: false, _rank: 40, diff --git a/src/tv2_afvd_showstyle/migrations/sourcelayer-defaults.ts b/src/tv2_afvd_showstyle/migrations/sourcelayer-defaults.ts index d8705698..9d7a98c4 100644 --- a/src/tv2_afvd_showstyle/migrations/sourcelayer-defaults.ts +++ b/src/tv2_afvd_showstyle/migrations/sourcelayer-defaults.ts @@ -1,6 +1,6 @@ import { ISourceLayer, SourceLayerType } from 'blueprints-integration' import { GetDSKSourceLayerDefaults, literal } from 'tv2-common' -import { SharedSourceLayers } from 'tv2-constants' +import { SharedSourceLayer } from 'tv2-constants' import { ATEMModel } from '../../types/atem' import { SourceLayer } from '../layers' @@ -519,7 +519,7 @@ const SEC: ISourceLayer[] = [ onPresenterScreen: false }, { - _id: SharedSourceLayers.RobotCamera, + _id: SharedSourceLayer.RobotCamera, _rank: 70, name: 'Robot Camera', abbreviation: '', @@ -631,7 +631,7 @@ const SELECTED_ADLIB: ISourceLayer[] = [ onPresenterScreen: true }, { - _id: SharedSourceLayers.SelectedAdlibGraphicsFull, + _id: SharedSourceLayer.SelectedAdlibGraphicsFull, _rank: 0, name: 'GFX Full (selected)', abbreviation: 'GFX Full', diff --git a/src/tv2_afvd_showstyle/parts/effekt.ts b/src/tv2_afvd_showstyle/parts/effekt.ts index 49686a32..a780de60 100644 --- a/src/tv2_afvd_showstyle/parts/effekt.ts +++ b/src/tv2_afvd_showstyle/parts/effekt.ts @@ -1,11 +1,11 @@ import { IBlueprintPiece } from 'blueprints-integration' -import { CreateEffektForPartBase, ExtendedShowStyleContext, PartDefinition } from 'tv2-common' +import { CreateEffektForPartBase, PartDefinition, ShowStyleContext } from 'tv2-common' import { CasparLLayer, SisyfosLLAyer } from '../../tv2_afvd_studio/layers' import { GalleryBlueprintConfig } from '../helpers/config' import { SourceLayer } from '../layers' export function CreateEffektForpart( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, pieces: IBlueprintPiece[] ) { diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index b635fa14..ea6b1f3a 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -11,25 +11,25 @@ import { import { AddScript, CreatePartInvalid, - ExtendedSegmentContext, - ExtendedShowStyleContext, findSourceInfo, GetSisyfosTimelineObjForReplay, literal, PartDefinitionEVS, PartTime, PieceMetaData, + SegmentContext, + ShowStyleContext, SourceInfo, TransitionStyle } from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' +import { SharedOutputLayer } from 'tv2-constants' import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' export async function CreatePartEVS( - context: ExtendedSegmentContext, + context: SegmentContext, partDefinition: PartDefinitionEVS, totalWords: number ): Promise { @@ -60,7 +60,7 @@ export async function CreatePartEVS( externalId: partDefinition.externalId, name: part.title, enable: { start: 0 }, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, sourceLayerId: SourceLayer.PgmLocal, lifespan: PieceLifespan.WithinPart, metaData: { @@ -99,7 +99,7 @@ export async function CreatePartEVS( } function makeContentEVS( - context: ExtendedShowStyleContext, + context: ShowStyleContext, switcherInput: number, partDefinition: PartDefinitionEVS, sourceInfoReplay: SourceInfo diff --git a/src/tv2_afvd_showstyle/parts/grafik.ts b/src/tv2_afvd_showstyle/parts/grafik.ts index 4b2a5658..f2de5f92 100644 --- a/src/tv2_afvd_showstyle/parts/grafik.ts +++ b/src/tv2_afvd_showstyle/parts/grafik.ts @@ -8,11 +8,11 @@ import { } from 'blueprints-integration' import { AddScript, - ApplyFullGraphicPropertiesToPart, - ExtendedShowStyleContext, + applyFullGraphicPropertiesToPart, GraphicIsPilot, PartDefinition, - PartTime + PartTime, + ShowStyleContext } from 'tv2-common' import { CueType } from 'tv2-constants' import { GalleryBlueprintConfig } from '../helpers/config' @@ -20,7 +20,7 @@ import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' export async function CreatePartGrafik( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, totalWords: number ): Promise { @@ -39,7 +39,7 @@ export async function CreatePartGrafik( if ( partDefinition.cues.filter((c) => c.type === CueType.Graphic && GraphicIsPilot(c) && c.target === 'FULL').length ) { - ApplyFullGraphicPropertiesToPart(context.config, part) + applyFullGraphicPropertiesToPart(context.config, part) } await EvaluateCues( diff --git a/src/tv2_afvd_showstyle/parts/intro.ts b/src/tv2_afvd_showstyle/parts/intro.ts index a8ad2bb0..3fbde791 100644 --- a/src/tv2_afvd_showstyle/parts/intro.ts +++ b/src/tv2_afvd_showstyle/parts/intro.ts @@ -10,10 +10,10 @@ import { AddScript, CreatePartInvalid, CueDefinitionJingle, - ExtendedShowStyleContext, GetJinglePartProperties, PartDefinition, - PartTime + PartTime, + ShowStyleContext } from 'tv2-common' import { CueType } from 'tv2-constants' import { GalleryBlueprintConfig } from '../helpers/config' @@ -21,7 +21,7 @@ import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' export async function CreatePartIntro( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, totalWords: number ): Promise { diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index 5f4e22c7..0cb2e8d0 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -12,24 +12,24 @@ import { AddScript, CreatePartInvalid, CreatePartKamBase, - ExtendedSegmentContext, FindDSKJingle, findSourceInfo, GetSisyfosTimelineObjForCamera, literal, PartDefinitionKam, PieceMetaData, + SegmentContext, TimeFromINewsField, TransitionStyle } from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' +import { SharedOutputLayer } from 'tv2-constants' import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' export async function CreatePartKam( - context: ExtendedSegmentContext, + context: SegmentContext, partDefinition: PartDefinitionKam, totalWords: number ): Promise { @@ -50,7 +50,7 @@ export async function CreatePartKam( externalId: partDefinition.externalId, name: 'CS 3 (JINGLE)', enable: { start: 0 }, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, sourceLayerId: SourceLayer.PgmJingle, lifespan: PieceLifespan.WithinPart, metaData: { @@ -89,7 +89,7 @@ export async function CreatePartKam( externalId: partDefinition.externalId, name: part.title, enable: { start: 0 }, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, sourceLayerId: SourceLayer.PgmCam, lifespan: PieceLifespan.WithinPart, metaData: { diff --git a/src/tv2_afvd_showstyle/parts/live.ts b/src/tv2_afvd_showstyle/parts/live.ts index 5cef06f6..86d1d29e 100644 --- a/src/tv2_afvd_showstyle/parts/live.ts +++ b/src/tv2_afvd_showstyle/parts/live.ts @@ -6,7 +6,7 @@ import { IBlueprintPart, IBlueprintPiece } from 'blueprints-integration' -import { AddScript, CueDefinitionEkstern, ExtendedSegmentContext, PartDefinition, PartTime } from 'tv2-common' +import { AddScript, CueDefinitionEkstern, PartDefinition, PartTime, SegmentContext } from 'tv2-common' import { CueType } from 'tv2-constants' import { GalleryBlueprintConfig } from '../../tv2_afvd_showstyle/helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' @@ -14,7 +14,7 @@ import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' export async function CreatePartLive( - context: ExtendedSegmentContext, + context: SegmentContext, partDefinition: PartDefinition, totalWords: number ): Promise { diff --git a/src/tv2_afvd_showstyle/parts/server.ts b/src/tv2_afvd_showstyle/parts/server.ts index 8d687240..57cd4388 100644 --- a/src/tv2_afvd_showstyle/parts/server.ts +++ b/src/tv2_afvd_showstyle/parts/server.ts @@ -1,5 +1,5 @@ import { BlueprintResultPart, HackPartMediaObjectSubscription, IBlueprintActionManifest } from 'blueprints-integration' -import { AddScript, CreatePartServerBase, ExtendedSegmentContext, PartDefinition, ServerPartProps } from 'tv2-common' +import { AddScript, CreatePartServerBase, PartDefinition, SegmentContext, ServerPartProps } from 'tv2-common' import { CasparLLayer, SisyfosLLAyer } from '../../tv2_afvd_studio/layers' import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' @@ -7,7 +7,7 @@ import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' export async function CreatePartServer( - context: ExtendedSegmentContext, + context: SegmentContext, partDefinition: PartDefinition, partProps: ServerPartProps ): Promise { diff --git a/src/tv2_afvd_showstyle/parts/teknik.ts b/src/tv2_afvd_showstyle/parts/teknik.ts index 0d9f179f..0263bac8 100644 --- a/src/tv2_afvd_showstyle/parts/teknik.ts +++ b/src/tv2_afvd_showstyle/parts/teknik.ts @@ -6,13 +6,13 @@ import { IBlueprintPart, IBlueprintPiece } from 'blueprints-integration' -import { AddScript, ExtendedSegmentContext, PartDefinition, PartTime } from 'tv2-common' +import { AddScript, PartDefinition, PartTime, SegmentContext } from 'tv2-common' import { GalleryBlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' export async function CreatePartTeknik( - context: ExtendedSegmentContext, + context: SegmentContext, partDefinition: PartDefinition, totalWords: number ): Promise { diff --git a/src/tv2_afvd_showstyle/parts/unknown.ts b/src/tv2_afvd_showstyle/parts/unknown.ts index 12b747c2..d8aff93d 100644 --- a/src/tv2_afvd_showstyle/parts/unknown.ts +++ b/src/tv2_afvd_showstyle/parts/unknown.ts @@ -7,12 +7,12 @@ import { } from 'blueprints-integration' import { AddScript, - ApplyFullGraphicPropertiesToPart, - ExtendedShowStyleContext, + applyFullGraphicPropertiesToPart, GetJinglePartProperties, GraphicIsPilot, PartDefinition, - PartTime + PartTime, + ShowStyleContext } from 'tv2-common' import { CueType } from 'tv2-constants' import { GalleryBlueprintConfig } from '../helpers/config' @@ -21,7 +21,7 @@ import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' export async function CreatePartUnknown( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, totalWords: number, asAdlibs?: boolean @@ -48,7 +48,7 @@ export async function CreatePartUnknown( partDefinition.cues.some((cue) => cue.type === CueType.Graphic && GraphicIsPilot(cue) && cue.target === 'FULL') && !partDefinition.cues.filter((c) => c.type === CueType.Jingle).length ) { - ApplyFullGraphicPropertiesToPart(context.config, part) + applyFullGraphicPropertiesToPart(context.config, part) } await EvaluateCues( diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index fd9a400f..c0fad5ee 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -12,15 +12,8 @@ import { PartDefinition, RemoteType } from 'tv2-common' -import { - CueType, - PartType, - SharedGraphicLLayer, - SharedOutputLayers, - SourceType, - SwitcherAuxLLayer -} from 'tv2-constants' -import { makeMockGalleryContext, SegmentUserContext } from '../../__mocks__/context' +import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayer, SourceType, SwitcherAuxLLayer } from 'tv2-constants' +import { makeMockGalleryContext, SegmentUserContextMock } from '../../__mocks__/context' import { prefixLayer } from '../../tv2-common/__tests__/testUtil' import { SourceLayer } from '../../tv2_afvd_showstyle/layers' import { CreatePartGrafik } from '../../tv2_afvd_showstyle/parts/grafik' @@ -55,7 +48,7 @@ describe('Graphics', () => { const result = await CreatePartGrafik(context, partDefintion, 0) - expect((context.core as SegmentUserContext).getNotes().map((msg) => msg.message)).toEqual([ + expect((context.core as SegmentUserContextMock).getNotes().map((msg) => msg.message)).toEqual([ `No graphic found after GRAFIK cue` ]) expect(result.pieces).toHaveLength(0) @@ -91,7 +84,7 @@ describe('Graphics', () => { CreatePartGrafik(context, partDefinition, 0) - expect((context.core as SegmentUserContext).getNotes().map((msg) => msg.message)).toEqual([ + expect((context.core as SegmentUserContextMock).getNotes().map((msg) => msg.message)).toEqual([ `Graphic found without target engine` ]) }) @@ -129,7 +122,7 @@ describe('Graphics', () => { expect(result.pieces).toHaveLength(2) const piece = result.pieces[0] expect(piece.sourceLayerId).toBe(SourceLayer.PgmPilot) - expect(piece.outputLayerId).toBe(SharedOutputLayers.PGM) + expect(piece.outputLayerId).toBe(SharedOutputLayer.PGM) expect(piece.enable).toEqual({ start: 0 }) // expect(piece.prerollDuration).toBe(config.studio.VizPilotGraphics.PrerollDuration) expect(piece.lifespan).toBe(PieceLifespan.WithinPart) @@ -192,7 +185,7 @@ describe('Graphics', () => { expect(result.pieces).toHaveLength(1) const piece = result.pieces[0] expect(piece.sourceLayerId).toBe(SourceLayer.PgmPilotOverlay) - expect(piece.outputLayerId).toBe(SharedOutputLayers.OVERLAY) + expect(piece.outputLayerId).toBe(SharedOutputLayer.OVERLAY) expect(piece.enable).toEqual({ start: 2000 }) expect(piece.prerollDuration).toBe(context.config.studio.VizPilotGraphics.PrerollDuration) expect(piece.lifespan).toBe(PieceLifespan.OutOnShowStyleEnd) @@ -248,7 +241,7 @@ describe('Graphics', () => { expect(result.pieces).toHaveLength(1) const piece = result.pieces[0] expect(piece.sourceLayerId).toBe(SourceLayer.WallGraphics) - expect(piece.outputLayerId).toBe(SharedOutputLayers.SEC) + expect(piece.outputLayerId).toBe(SharedOutputLayer.SEC) expect(piece.enable).toEqual({ start: 0 }) expect(piece.prerollDuration).toBe(context.config.studio.VizPilotGraphics.PrerollDuration) expect(piece.lifespan).toBe(PieceLifespan.OutOnShowStyleEnd) @@ -301,7 +294,7 @@ describe('Graphics', () => { expect(result.pieces).toHaveLength(2) const piece = result.pieces[0] expect(piece.sourceLayerId).toBe(SourceLayer.PgmGraphicsTLF) - expect(piece.outputLayerId).toBe(SharedOutputLayers.PGM) + expect(piece.outputLayerId).toBe(SharedOutputLayer.PGM) expect(piece.enable).toEqual({ start: 0 }) expect(piece.prerollDuration).toBe(context.config.studio.VizPilotGraphics.PrerollDuration) expect(piece.lifespan).toBe(PieceLifespan.WithinPart) @@ -362,7 +355,7 @@ describe('Graphics', () => { const result = await CreatePartGrafik(context, partDefinition, 0) expect(result.pieces).toHaveLength(3) - const auxPiece = result.pieces.find((p) => p.outputLayerId === SharedOutputLayers.AUX)! + const auxPiece = result.pieces.find((p) => p.outputLayerId === SharedOutputLayer.AUX)! expect(auxPiece.enable).toEqual({ start: 0 }) expect(auxPiece.sourceLayerId).toBe(SourceLayer.VizFullIn1) expect(auxPiece.lifespan).toBe(PieceLifespan.WithinPart) @@ -402,7 +395,7 @@ describe('Graphics', () => { expect(result.pieces).toHaveLength(1) const piece = result.pieces[0] expect(piece).toBeTruthy() - expect(piece.outputLayerId).toBe(SharedOutputLayers.SEC) + expect(piece.outputLayerId).toBe(SharedOutputLayer.SEC) expect(piece.sourceLayerId).toBe(SourceLayer.PgmDesign) expect(piece.lifespan).toBe(PieceLifespan.OutOnShowStyleEnd) expect(piece.enable).toEqual({ start: 0 }) @@ -437,7 +430,7 @@ describe('Graphics', () => { const piece = result.pieces[0] expect(piece).toBeTruthy() expect(piece.name).toBe('DESIGN_SC') - expect(piece.outputLayerId).toBe(SharedOutputLayers.SEC) + expect(piece.outputLayerId).toBe(SharedOutputLayer.SEC) expect(piece.sourceLayerId).toBe(SourceLayer.PgmDVEBackground) expect(piece.lifespan).toBe(PieceLifespan.OutOnShowStyleEnd) const tlObj = (piece.content?.timelineObjects as TSR.TSRTimelineObj[]).find( @@ -487,7 +480,7 @@ describe('Graphics', () => { const piece = result.pieces[0] expect(piece).toBeTruthy() expect(piece.enable).toEqual({ start: 5000, duration: 4000 }) - expect(piece.outputLayerId).toBe(SharedOutputLayers.OVERLAY) + expect(piece.outputLayerId).toBe(SharedOutputLayer.OVERLAY) expect(piece.sourceLayerId).toBe(SourceLayer.PgmGraphicsLower) expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const tlObj = (piece.content?.timelineObjects as TSR.TSRTimelineObj[]).find( diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index 39328139..c03d61e1 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -223,7 +223,7 @@ export const manifestAFVDSourcesReplay = MakeConfigForSources('Replay', 'Replay' export const manifestAFVDSourcesABMediaPlayers: ConfigManifestEntryTable = { id: 'ABMediaPlayers', name: 'Media Players inputs', - description: 'ATEM inputs for A/B media players', + description: 'Video Switcher inputs for A/B media players', type: ConfigManifestEntryType.TABLE, required: false, defaultVal: literal>([ @@ -250,7 +250,7 @@ export const manifestAFVDSourcesABMediaPlayers: ConfigManifestEntryTable = { }, { id: 'SwitcherSource', - name: 'Switcher input', + name: 'Video Switcher input', description: 'Video Switcher input for Media player', type: ConfigManifestEntryType.INT, required: true, @@ -307,7 +307,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.SplitArtF', - name: 'Switcher Split Screen Art Fill', + name: 'Video Switcher Split Screen Art Fill', description: 'Video Switcher input for Split Screen Art Fill', type: ConfigManifestEntryType.INT, required: true, @@ -315,7 +315,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.SplitArtK', - name: 'Switcher Split Screen Art Key', + name: 'Video Switcher Split Screen Art Key', description: 'Video Switcher input for Split Screen Art Key', type: ConfigManifestEntryType.INT, required: true, @@ -323,7 +323,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.Default', - name: 'Switcher Default source', + name: 'Video Switcher Default source', description: 'Video Switcher default source', type: ConfigManifestEntryType.INT, required: true, @@ -331,7 +331,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.MixMinusDefault', - name: 'Switcher Mix-minus default source', + name: 'Video Switcher Mix-minus default source', description: 'Video Switcher default source for mix-minus', type: ConfigManifestEntryType.INT, required: true, @@ -339,7 +339,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.Continuity', - name: 'Switcher continuity source', + name: 'Video Switcher continuity source', description: 'Video Switcher input for continuity', type: ConfigManifestEntryType.INT, required: true, @@ -347,7 +347,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.Dip', - name: 'Switcher Dip Source', + name: 'Video Switcher Dip Source', description: 'Video Switcher source for the Dip - should match the desired input in the Video Switcher', type: ConfigManifestEntryType.INT, required: true, @@ -495,7 +495,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ { id: 'VizPilotGraphics.FullGraphicBackground', name: 'Full frame grafik background source', - description: 'ATEM source for mos full-frame grafik background source', + description: 'Video Switcher source for mos full-frame grafik background source', type: ConfigManifestEntryType.INT, required: false, defaultVal: 36 diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index 36816aa9..5e0d2852 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -5,7 +5,7 @@ import { IStudioContext, TSR } from 'blueprints-integration' -import { ExtendedStudioContext, literal, SpecialInput, TransitionStyle } from 'tv2-common' +import { literal, SpecialInput, StudioContext, TransitionStyle } from 'tv2-common' import * as _ from 'underscore' import { SharedGraphicLLayer, SwitcherMediaPlayerLLayer } from '../tv2-constants' import { AtemSourceIndex } from '../types/atem' @@ -31,7 +31,7 @@ function filterMappings( } export function getBaseline(coreContext: IStudioContext): BlueprintResultBaseline { - const context = new ExtendedStudioContext(coreContext, GALLERY_UNIFORM_CONFIG) + const context = new StudioContext(coreContext, GALLERY_UNIFORM_CONFIG) const mappings = coreContext.getStudioMappings() const sisyfosMappings = filterMappings( diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index 074d3ec8..8bbb3ef9 100644 --- a/src/tv2_afvd_studio/helpers/config.ts +++ b/src/tv2_afvd_studio/helpers/config.ts @@ -1,20 +1,16 @@ import { IBlueprintConfig, ICommonContext } from 'blueprints-integration' import { - MediaPlayerConfig, - SourceMapping, + ProcessedStudioConfig, TableConfigItemDSK, TableConfigItemSourceMapping, TableConfigItemSourceMappingWithSisyfos, TV2StudioConfigBase } from 'tv2-common' -import { DSKRoles } from 'tv2-constants' +import { DskRole } from 'tv2-constants' import { parseMediaPlayers, parseSources } from './sources' -export interface GalleryStudioConfig { +export interface GalleryStudioConfig extends ProcessedStudioConfig { studio: StudioConfig - sources: SourceMapping - mediaPlayers: MediaPlayerConfig // Atem Input Ids - dsk: TableConfigItemDSK[] } export interface StudioConfig extends TV2StudioConfigBase { @@ -64,9 +60,9 @@ export const defaultDSKConfig: TableConfigItemDSK[] = [ Fill: 21, Toggle: true, DefaultOn: true, - Roles: [DSKRoles.FULLGFX, DSKRoles.OVERLAYGFX], + Roles: [DskRole.FULLGFX, DskRole.OVERLAYGFX], Clip: 50, Gain: 12.5 }, - { Number: 1, Key: 31, Fill: 29, Toggle: true, DefaultOn: false, Roles: [DSKRoles.JINGLE], Clip: 50, Gain: 12.5 } + { Number: 1, Key: 31, Fill: 29, Toggle: true, DefaultOn: false, Roles: [DskRole.JINGLE], Clip: 50, Gain: 12.5 } ] diff --git a/src/tv2_afvd_studio/onTimelineGenerate.ts b/src/tv2_afvd_studio/onTimelineGenerate.ts index 33302a58..48552df2 100644 --- a/src/tv2_afvd_studio/onTimelineGenerate.ts +++ b/src/tv2_afvd_studio/onTimelineGenerate.ts @@ -6,7 +6,7 @@ import { PartEndState, TimelinePersistentState } from 'blueprints-integration' -import { ExtendedTimelineContext, onTimelineGenerate, PieceMetaData } from 'tv2-common' +import { onTimelineGenerate, PieceMetaData, TimelineContext } from 'tv2-common' import { CasparLLayer, SisyfosLLAyer } from './layers' import { GALLERY_UNIFORM_CONFIG } from './uniformConfig' @@ -17,7 +17,7 @@ export function onTimelineGenerateAFVD( previousPartEndState: PartEndState | undefined, resolvedPieces: Array> ): Promise { - const context = new ExtendedTimelineContext(coreContext, GALLERY_UNIFORM_CONFIG) + const context = new TimelineContext(coreContext, GALLERY_UNIFORM_CONFIG) return onTimelineGenerate(context, timeline, previousPersistentState, previousPartEndState, resolvedPieces, { Caspar: { ClipPending: CasparLLayer.CasparPlayerClipPending diff --git a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts index e00c13d6..cf57ad22 100644 --- a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts @@ -25,11 +25,11 @@ import { CueType, NoteType, PartType, - SharedSourceLayers, + SharedSourceLayer, SourceType, SwitcherMixEffectLLayer } from 'tv2-constants' -import { ActionExecutionContext } from '../../__mocks__/context' +import { ActionExecutionContextMock } from '../../__mocks__/context' import { prefixLayer } from '../../tv2-common/__tests__/testUtil' import { defaultShowStyleConfig, defaultStudioConfig } from '../../tv2_afvd_showstyle/__tests__/configs' import { OfftubeStudioConfig, preprocessConfig as parseStudioConfig } from '../../tv2_offtube_studio/helpers/config' @@ -264,7 +264,7 @@ interface ActivePiecesForSource { } async function getActiveServerPieces( - context: ActionExecutionContext, + context: ActionExecutionContextMock, part: 'current' | 'next' ): Promise { return { @@ -277,7 +277,10 @@ async function getActiveServerPieces( } } -async function getVOPieces(context: ActionExecutionContext, part: 'current' | 'next'): Promise { +async function getVOPieces( + context: ActionExecutionContextMock, + part: 'current' | 'next' +): Promise { return { activePiece: await context .getPieceInstances(part) @@ -290,7 +293,10 @@ async function getVOPieces(context: ActionExecutionContext, part: 'current' | 'n } } -async function getDVEPieces(context: ActionExecutionContext, part: 'current' | 'next'): Promise { +async function getDVEPieces( + context: ActionExecutionContextMock, + part: 'current' | 'next' +): Promise { return { activePiece: await context .getPieceInstances(part) @@ -304,23 +310,23 @@ async function getDVEPieces(context: ActionExecutionContext, part: 'current' | ' } async function getFullGrafikPieces( - context: ActionExecutionContext, + context: ActionExecutionContextMock, part: 'current' | 'next' ): Promise { return { activePiece: await context .getPieceInstances(part) - .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === SharedSourceLayers.PgmPilot)), + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === SharedSourceLayer.PgmPilot)), dataStore: await context .getPieceInstances(part) .then((pieceInstances) => - pieceInstances.find((p) => p.piece.sourceLayerId === SharedSourceLayers.SelectedAdlibGraphicsFull) + pieceInstances.find((p) => p.piece.sourceLayerId === SharedSourceLayer.SelectedAdlibGraphicsFull) ) } } async function getCameraPiece( - context: ActionExecutionContext, + context: ActionExecutionContextMock, part: 'current' | 'next' ): Promise { return context @@ -329,7 +335,7 @@ async function getCameraPiece( } async function getRemotePiece( - context: ActionExecutionContext, + context: ActionExecutionContextMock, part: 'current' | 'next' ): Promise { return context @@ -366,7 +372,7 @@ function validateRemotePiece(piece: IBlueprintPieceInstance | undefined) { expect(piece).toBeTruthy() } -function validateNoWarningsOrErrors(context: ActionExecutionContext) { +function validateNoWarningsOrErrors(context: ActionExecutionContextMock) { expect( context.getNotes().filter((n) => n.type === NoteType.WARNING || n.type === NoteType.NOTIFY_USER_WARNING) ).toEqual([]) @@ -375,12 +381,15 @@ function validateNoWarningsOrErrors(context: ActionExecutionContext) { ) } -function validateNextPartExistsWithDuration(context: ActionExecutionContext, duration: number) { +function validateNextPartExistsWithDuration(context: ActionExecutionContextMock, duration: number) { expect(context.nextPart).toBeTruthy() expect(context.nextPart?.part.expectedDuration).toEqual(duration) } -function validateNextPartExistsWithPreviousPartKeepaliveDuration(context: ActionExecutionContext, duration: number) { +function validateNextPartExistsWithPreviousPartKeepaliveDuration( + context: ActionExecutionContextMock, + duration: number +) { expect(context.nextPart).toBeTruthy() expect(context.nextPart?.part.inTransition?.previousPartKeepaliveDuration).toEqual(duration) } @@ -412,7 +421,7 @@ function expectATEMToMixOver(piece: IBlueprintPieceInstance, frames: number) { describe('Select Server Action', () => { it('Inserts a new part when no next part is present', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -439,7 +448,7 @@ describe('Select Server Action', () => { }) it('Leaves current part unaffected when a clip is currently playing', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -471,7 +480,7 @@ describe('Select Server Action', () => { describe('Combination Actions', () => { it('Server -> DVE', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -504,7 +513,7 @@ describe('Combination Actions', () => { }) it('Server -> Full', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -538,7 +547,7 @@ describe('Combination Actions', () => { }) it('Server -> VO', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -572,7 +581,7 @@ describe('Combination Actions', () => { }) it('Server -> CAM', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -605,7 +614,7 @@ describe('Combination Actions', () => { }) it('Server -> LIVE', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -638,7 +647,7 @@ describe('Combination Actions', () => { }) it('DVE -> Server', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -670,7 +679,7 @@ describe('Combination Actions', () => { }) it('DVE -> Full', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -703,7 +712,7 @@ describe('Combination Actions', () => { }) it('DVE -> VO', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -735,7 +744,7 @@ describe('Combination Actions', () => { }) it('DVE -> CAM', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -767,7 +776,7 @@ describe('Combination Actions', () => { }) it('DVE -> LIVE', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -799,7 +808,7 @@ describe('Combination Actions', () => { }) it('Server (01234A) -> DVE (morbarn) -> VO (VOVOA) -> DVE (barnmor) -> CAM (1) -> LIVE (2) -> SERVER (01234A) -> Commentator Select DVE', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -923,7 +932,7 @@ describe('Combination Actions', () => { }) it('CAM -> MIX 20 (No Take) -> LIVE (2)', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -966,7 +975,7 @@ describe('Combination Actions', () => { }) it('CAM -> MIX 20 (No Take) -> SERVER', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -1009,7 +1018,7 @@ describe('Combination Actions', () => { }) it('CAM -> MIX 20 (No Take) -> VO', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, @@ -1052,7 +1061,7 @@ describe('Combination Actions', () => { }) it('CAM -> MIX 20 (No Take) -> DVE', async () => { - const context = new ActionExecutionContext( + const context = new ActionExecutionContextMock( 'test', mappingsDefaults, parseStudioConfig, diff --git a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts index 126ab384..827b724a 100644 --- a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts +++ b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts @@ -3,9 +3,9 @@ import { CueDefinitionDVE, DVEConfigInput, DVEOptions, - ExtendedShowStyleContext, MakeContentDVEBase, - PartDefinition + PartDefinition, + ShowStyleContext } from 'tv2-common' import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeBlueprintConfig } from '../helpers/config' @@ -29,7 +29,7 @@ export const OFFTUBE_DVE_GENERATOR_OPTIONS: DVEOptions = { } export function OfftubeMakeContentDVE( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, parsedCue: CueDefinitionDVE, dveConfig: DVEConfigInput | undefined diff --git a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts index 419fd41c..7b503ef6 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts @@ -4,12 +4,12 @@ import { CreateAdlibServer, CueDefinitionAdLib, CueDefinitionDVE, - ExtendedSegmentContext, generateExternalId, GetDVETemplate, getUniquenessIdDVE, literal, PartDefinition, + SegmentContext, t, TemplateIsValid } from 'tv2-common' @@ -20,7 +20,7 @@ import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeOutputLayers, OfftubeSourceLayer } from '../layers' export async function OfftubeEvaluateAdLib( - context: ExtendedSegmentContext, + context: SegmentContext, actions: IBlueprintActionManifest[], mediaSubscriptions: HackPartMediaObjectSubscription[], parsedCue: CueDefinitionAdLib, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts index 983b9f8d..456e0e77 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts @@ -4,23 +4,23 @@ import { calculateTime, CueDefinitionDVE, DVEPieceMetaData, - ExtendedSegmentContext, generateExternalId, GetDVETemplate, GetTagForDVE, GetTagForDVENext, literal, PartDefinition, + SegmentContext, t, TemplateIsValid } from 'tv2-common' -import { AdlibActionType, AdlibTags, SharedOutputLayers, TallyTags } from 'tv2-constants' +import { AdlibActionType, AdlibTags, SharedOutputLayer, TallyTags } from 'tv2-constants' import { OfftubeMakeContentDVE } from '../content/OfftubeDVEContent' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeOutputLayers, OfftubeSourceLayer } from '../layers' export function OfftubeEvaluateDVE( - context: ExtendedSegmentContext, + context: SegmentContext, pieces: IBlueprintPiece[], actions: IBlueprintActionManifest[], partDefinition: PartDefinition, @@ -58,7 +58,7 @@ export function OfftubeEvaluateDVE( start, ...(end ? { duration: end - start } : {}) }, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, sourceLayerId: OfftubeSourceLayer.PgmDVE, lifespan: PieceLifespan.WithinPart, toBeQueued: true, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts index 8cd1dd91..58d89939 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts @@ -3,14 +3,14 @@ import { CueDefinitionEkstern, EvaluateCueResult, EvaluateEksternBase, - ExtendedSegmentContext, - PartDefinition + PartDefinition, + SegmentContext } from 'tv2-common' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeSourceLayer } from '../layers' export function OfftubeEvaluateEkstern( - context: ExtendedSegmentContext, + context: SegmentContext, part: IBlueprintPart, partId: string, parsedCue: CueDefinitionEkstern, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts index 261a8d5e..57db7ea1 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts @@ -7,15 +7,15 @@ import { TSR, WithTimeline } from 'blueprints-integration' -import { calculateTime, CueDefinitionBackgroundLoop, ExtendedSegmentContext, literal } from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' +import { calculateTime, CueDefinitionBackgroundLoop, literal, SegmentContext } from 'tv2-common' +import { SharedOutputLayer } from 'tv2-constants' import _ = require('underscore') import { OfftubeCasparLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeSourceLayer } from '../layers' export function OfftubeEvaluateCueBackgroundLoop( - _context: ExtendedSegmentContext, + _context: SegmentContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], _actions: IBlueprintActionManifest[], @@ -32,7 +32,7 @@ export function OfftubeEvaluateCueBackgroundLoop( _rank: rank || 0, externalId: partId, name: fileName, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, sourceLayerId: OfftubeSourceLayer.PgmDVEBackground, lifespan: PieceLifespan.OutOnShowStyleEnd, content: literal>({ @@ -62,7 +62,7 @@ export function OfftubeEvaluateCueBackgroundLoop( enable: { start }, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, sourceLayerId: OfftubeSourceLayer.PgmDVEBackground, lifespan: PieceLifespan.OutOnShowStyleEnd, content: literal>({ diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphicDesign.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphicDesign.ts index 16c54e3a..2b75fe10 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphicDesign.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphicDesign.ts @@ -1,9 +1,9 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece } from 'blueprints-integration' -import { CueDefinitionGraphicDesign, EvaluateDesignBase, ExtendedSegmentContext } from 'tv2-common' +import { CueDefinitionGraphicDesign, EvaluateDesignBase, SegmentContext } from 'tv2-common' import { OfftubeBlueprintConfig } from '../helpers/config' export function OfftubeEvaluateGraphicDesign( - context: ExtendedSegmentContext, + context: SegmentContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts index 371b034d..34d865a9 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts @@ -4,16 +4,16 @@ import { CreatePilotGraphic, CueDefinitionGraphic, EvaluateCueResult, - ExtendedShowStyleContext, GraphicInternalOrPilot, GraphicIsInternal, GraphicIsPilot, - PartDefinition + PartDefinition, + ShowStyleContext } from 'tv2-common' import { OfftubeBlueprintConfig } from '../helpers/config' export function OfftubeEvaluateGrafikCaspar( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partId: string, parsedCue: CueDefinitionGraphic, partDefinition: PartDefinition, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index a7565645..f876abb0 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -3,23 +3,23 @@ import { ActionSelectJingle, CreateJingleContentBase, CueDefinitionJingle, - ExtendedSegmentContext, generateExternalId, GetJinglePartProperties, GetTagForJingle, GetTagForJingleNext, + getTimeFromFrames, PartDefinition, PieceMetaData, - t, - TimeFromFrames + SegmentContext, + t } from 'tv2-common' -import { AdlibActionType, AdlibTags, SharedOutputLayers, TallyTags } from 'tv2-constants' +import { AdlibActionType, AdlibTags, SharedOutputLayer, TallyTags } from 'tv2-constants' import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeOutputLayers, OfftubeSourceLayer } from '../layers' export function OfftubeEvaluateJingle( - context: ExtendedSegmentContext, + context: SegmentContext, pieces: Array>, _adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -90,14 +90,14 @@ export function OfftubeEvaluateJingle( start: 0 }, lifespan: PieceLifespan.WithinPart, - outputLayerId: SharedOutputLayers.JINGLE, + outputLayerId: SharedOutputLayer.JINGLE, sourceLayerId: OfftubeSourceLayer.PgmJingle, metaData: { sisyfosPersistMetaData: { sisyfosLayers: [] } }, - prerollDuration: context.config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), + prerollDuration: context.config.studio.CasparPrerollDuration + getTimeFromFrames(Number(jingle.StartAlpha)), content: createJingleContentOfftube( context, file, @@ -116,7 +116,7 @@ export function OfftubeEvaluateJingle( } export function createJingleContentOfftube( - context: ExtendedSegmentContext, + context: SegmentContext, file: string, alphaAtStart: number, loadFirstFrame: boolean, diff --git a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts index 18b642be..cb46e8b0 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts @@ -5,13 +5,13 @@ import { TimelineObjectCoreExt, WithTimeline } from 'blueprints-integration' -import { CueDefinitionPgmClean, ExtendedSegmentContext, findSourceInfo, literal, SourceInfo } from 'tv2-common' -import { SharedOutputLayers, SourceType, SwitcherAuxLLayer } from 'tv2-constants' +import { CueDefinitionPgmClean, findSourceInfo, literal, SegmentContext, SourceInfo } from 'tv2-common' +import { SharedOutputLayer, SourceType, SwitcherAuxLLayer } from 'tv2-constants' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeSourceLayer } from '../layers' export function OfftubeEvaluatePgmClean( - context: ExtendedSegmentContext, + context: SegmentContext, pieces: IBlueprintPiece[], partId: string, parsedCue: CueDefinitionPgmClean @@ -36,7 +36,7 @@ export function OfftubeEvaluatePgmClean( enable: { start: 0 }, - outputLayerId: SharedOutputLayers.AUX, + outputLayerId: SharedOutputLayer.AUX, sourceLayerId: OfftubeSourceLayer.AuxPgmClean, lifespan: PieceLifespan.OutOnShowStyleEnd, content: literal>({ diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 3f952a41..8ab37e6d 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -27,14 +27,14 @@ import { createDskBaseline, CreateDSKBaselineAdlibs, CreateLYDBaseline, - ExtendedShowStyleContext, - ExtendedShowStyleContextImpl, generateExternalId, getGraphicBaseline, GetTagForKam, GetTagForLive, GetTransitionAdLibActions, literal, + ShowStyleContext, + ShowStyleContextImpl, SourceDefinitionKam, SourceDefinitionRemote, SourceInfo, @@ -49,9 +49,9 @@ import { AdlibTagCutToBox, AdlibTags, CONSTANTS, - SharedOutputLayers, + SharedOutputLayer, SharedSisyfosLLayer, - SharedSourceLayers, + SharedSourceLayer, SourceType, SwitcherAuxLLayer, SwitcherDveLLayer, @@ -66,7 +66,7 @@ import { NUMBER_OF_DVE_BOXES } from './content/OfftubeDVEContent' import { OfftubeOutputLayers, OfftubeSourceLayer } from './layers' export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: IngestRundown): BlueprintResultRundown { - const context = new ExtendedShowStyleContextImpl(coreContext, QBOX_UNIFORM_CONFIG) + const context = new ShowStyleContextImpl(coreContext, QBOX_UNIFORM_CONFIG) let startTime: number = 0 let endTime: number = 0 @@ -104,9 +104,7 @@ export function getRundown(coreContext: IShowStyleUserContext, ingestRundown: In } } -function getGlobalAdLibPiecesOfftube( - context: ExtendedShowStyleContext -): IBlueprintAdLibPiece[] { +function getGlobalAdLibPiecesOfftube(context: ShowStyleContext): IBlueprintAdLibPiece[] { const adlibItems: IBlueprintAdLibPiece[] = [] adlibItems.push(...CreateDSKBaselineAdlibs(context.config, 500, context.videoSwitcher)) @@ -115,8 +113,8 @@ function getGlobalAdLibPiecesOfftube( externalId: 'micUp', name: 'Mics Up', _rank: 600, - sourceLayerId: SharedSourceLayers.PgmSisyfosAdlibs, - outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SharedSourceLayer.PgmSisyfosAdlibs, + outputLayerId: SharedOutputLayer.SEC, lifespan: PieceLifespan.WithinPart, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_MICS_UP], expectedDuration: 0, @@ -145,8 +143,8 @@ function getGlobalAdLibPiecesOfftube( externalId: 'micDown', name: 'Mics Down', _rank: 650, - sourceLayerId: SharedSourceLayers.PgmSisyfosAdlibs, - outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SharedSourceLayer.PgmSisyfosAdlibs, + outputLayerId: SharedOutputLayer.SEC, lifespan: PieceLifespan.WithinPart, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_MICS_DOWN], expectedDuration: 0, @@ -175,8 +173,8 @@ function getGlobalAdLibPiecesOfftube( externalId: 'resyncSisyfos', name: 'Resync Sisyfos', _rank: 700, - sourceLayerId: SharedSourceLayers.PgmSisyfosAdlibs, - outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SharedSourceLayer.PgmSisyfosAdlibs, + outputLayerId: SharedOutputLayer.SEC, lifespan: PieceLifespan.WithinPart, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIBS_RESYNC_SISYFOS], expectedDuration: 1000, @@ -201,7 +199,7 @@ function getGlobalAdLibPiecesOfftube( externalId: 'stopAudioBed', name: 'Stop Soundplayer', _rank: 700, - sourceLayerId: SharedSourceLayers.PgmAudioBed, + sourceLayerId: SharedSourceLayer.PgmAudioBed, outputLayerId: 'musik', expectedDuration: 1000, lifespan: PieceLifespan.WithinPart, @@ -253,7 +251,7 @@ function getGlobalAdlibActionsOfftube( _rank: rank, label: t(sourceDefinition.name), sourceLayerId: OfftubeSourceLayer.PgmCam, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, content: {}, tags: queue ? [AdlibTags.OFFTUBE_SET_CAM_NEXT, AdlibTags.ADLIB_QUEUE_NEXT] : [AdlibTags.ADLIB_CUT_DIRECT], currentPieceTags: [GetTagForKam(sourceDefinition)], @@ -334,7 +332,7 @@ function getGlobalAdlibActionsOfftube( _rank: rank + 0.1 * box, label: t(`Server inp ${box + 1}`), sourceLayerId: OfftubeSourceLayer.PgmServer, - outputLayerId: SharedOutputLayers.SEC, + outputLayerId: SharedOutputLayer.SEC, content: {}, tags: [AdlibTagCutToBox(box)] } @@ -402,7 +400,7 @@ function getGlobalAdlibActionsOfftube( display: { _rank: globalRank++, label: t('GFX FULL'), - sourceLayerId: SharedSourceLayers.PgmPilot, + sourceLayerId: SharedSourceLayer.PgmPilot, outputLayerId: OfftubeOutputLayers.PGM, content: {}, tags: [AdlibTags.OFFTUBE_SET_FULL_NEXT], @@ -428,8 +426,8 @@ function getGlobalAdlibActionsOfftube( display: { _rank: 400, label: t(`GFX Altud`), - sourceLayerId: SharedSourceLayers.PgmAdlibGraphicCmd, - outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SharedSourceLayer.PgmAdlibGraphicCmd, + outputLayerId: SharedOutputLayer.SEC, content: {}, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_ALTUD], currentPieceTags: [TallyTags.GFX_ALTUD], @@ -477,7 +475,7 @@ function getGlobalAdlibActionsOfftube( _rank: 200 + i, label: t(dveConfig.DVEName), sourceLayerId: OfftubeSourceLayer.PgmDVEAdLib, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, tags: [AdlibTags.ADLIB_SELECT_DVE_LAYOUT, dveConfig.DVEName] } }) @@ -514,7 +512,7 @@ function getGlobalAdlibActionsOfftube( _rank: 1, label: t('Last Live'), sourceLayerId: OfftubeSourceLayer.PgmLive, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, tags: [AdlibTags.ADLIB_RECALL_LAST_LIVE] } } @@ -575,7 +573,7 @@ function getGlobalAdlibActionsOfftube( return blueprintActions } -function getBaseline(context: ExtendedShowStyleContext): BlueprintResultBaseline { +function getBaseline(context: ShowStyleContext): BlueprintResultBaseline { return { timelineObjects: _.compact([ ...getGraphicBaseline(context.config), diff --git a/src/tv2_offtube_showstyle/getSegment.ts b/src/tv2_offtube_showstyle/getSegment.ts index cf7cb1bb..a466fc45 100644 --- a/src/tv2_offtube_showstyle/getSegment.ts +++ b/src/tv2_offtube_showstyle/getSegment.ts @@ -7,14 +7,8 @@ import { PieceLifespan, WithTimeline } from 'blueprints-integration' -import { - ExtendedSegmentContextImpl, - ExtendedShowStyleContext, - getSegmentBase, - literal, - TransitionStyle -} from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' +import { getSegmentBase, literal, SegmentContextImpl, ShowStyleContext, TransitionStyle } from 'tv2-common' +import { SharedOutputLayer } from 'tv2-constants' import * as _ from 'underscore' import { QBOX_UNIFORM_CONFIG } from '../tv2_offtube_studio/uniformConfig' import { OfftubeBlueprintConfig } from './helpers/config' @@ -29,7 +23,7 @@ export async function getSegment( coreContext: ISegmentUserContext, ingestSegment: IngestSegment ): Promise { - const context = new ExtendedSegmentContextImpl(coreContext, QBOX_UNIFORM_CONFIG) + const context = new SegmentContextImpl(coreContext, QBOX_UNIFORM_CONFIG) const result: BlueprintResultSegment = await getSegmentBase(context, ingestSegment, { CreatePartContinuity, @@ -54,7 +48,7 @@ export async function getSegment( } function CreatePartContinuity( - context: ExtendedShowStyleContext, + context: ShowStyleContext, ingestSegment: IngestSegment ): BlueprintResultPart { return { @@ -71,7 +65,7 @@ function CreatePartContinuity( }, name: 'CONTINUITY', sourceLayerId: OfftubeSourceLayer.PgmContinuity, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, lifespan: PieceLifespan.WithinPart, content: literal>({ studioLabel: '', diff --git a/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts b/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts index f981b851..afa2a007 100644 --- a/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts +++ b/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts @@ -10,8 +10,8 @@ import { EvaluateCuesBase, EvaluateCuesOptions, EvaluateLYD, - ExtendedSegmentContext, - PartDefinition + PartDefinition, + SegmentContext } from 'tv2-common' import { OfftubeEvaluateAdLib } from '../cues/OfftubeAdlib' import { OfftubeEvaluateDVE } from '../cues/OfftubeDVE' @@ -24,7 +24,7 @@ import { OfftubeEvaluatePgmClean } from '../cues/OfftubePgmClean' import { OfftubeBlueprintConfig } from './config' export async function OfftubeEvaluateCues( - context: ExtendedSegmentContext, + context: SegmentContext, part: IBlueprintPart, pieces: IBlueprintPiece[], adLibPieces: IBlueprintAdLibPiece[], diff --git a/src/tv2_offtube_showstyle/layers.ts b/src/tv2_offtube_showstyle/layers.ts index 51844594..378b1f36 100644 --- a/src/tv2_offtube_showstyle/layers.ts +++ b/src/tv2_offtube_showstyle/layers.ts @@ -1,4 +1,4 @@ -import { SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' +import { SharedOutputLayer, SharedSourceLayer } from 'tv2-constants' export enum SourceLayer { // Pgm @@ -16,16 +16,16 @@ export enum SourceLayer { // tslint:disable-next-line: variable-name export const OfftubeSourceLayer = { ...SourceLayer, - ...SharedSourceLayers + ...SharedSourceLayer } -export type OfftubeSourceLayer = SourceLayer | SharedSourceLayers +export type OfftubeSourceLayer = SourceLayer | SharedSourceLayer enum OutputLayers {} // tslint:disable-next-line: variable-name export const OfftubeOutputLayers = { ...OutputLayers, - ...SharedOutputLayers + ...SharedOutputLayer } -export type OfftubeOutputLayers = OutputLayers | SharedOutputLayers +export type OfftubeOutputLayers = OutputLayers | SharedOutputLayer diff --git a/src/tv2_offtube_showstyle/migrations/index.ts b/src/tv2_offtube_showstyle/migrations/index.ts index fcb47eeb..507d4c98 100644 --- a/src/tv2_offtube_showstyle/migrations/index.ts +++ b/src/tv2_offtube_showstyle/migrations/index.ts @@ -15,7 +15,7 @@ import { StripFolderFromDVEConfig, UpsertValuesIntoTransitionTable } from 'tv2-common' -import { SharedGraphicLLayer, SharedSourceLayers } from 'tv2-constants' +import { SharedGraphicLLayer, SharedSourceLayer } from 'tv2-constants' import { renameBlueprintConfiguration, renameBlueprintsConfigurationForAllVariants, @@ -107,9 +107,9 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ */ forceSourceLayerToDefaults('1.4.6', OfftubeSourceLayer.PgmLive), - renameSourceLayer('1.5.0', 'Offtube', 'studio0_offtube_graphicsFull', SharedSourceLayers.SelectedAdlibGraphicsFull), - renameSourceLayer('1.5.0', 'Offtube', 'studio0_full', SharedSourceLayers.PgmPilot), - renameSourceLayer('1.5.0', 'Offtube', 'studio0_offtube_continuity', SharedSourceLayers.PgmContinuity), + renameSourceLayer('1.5.0', 'Offtube', 'studio0_offtube_graphicsFull', SharedSourceLayer.SelectedAdlibGraphicsFull), + renameSourceLayer('1.5.0', 'Offtube', 'studio0_full', SharedSourceLayer.PgmPilot), + renameSourceLayer('1.5.0', 'Offtube', 'studio0_offtube_continuity', SharedSourceLayer.PgmContinuity), removeSourceLayer('1.5.0', 'Offtube', 'studio0_offtube_pgm_source_select'), forceSourceLayerToDefaults('1.5.1', OfftubeSourceLayer.PgmDVE), @@ -165,7 +165,7 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ SetSourceLayerName('1.6.9', OfftubeSourceLayer.PgmGraphicsTLF, 'GFX Telefon'), SetSourceLayerName('1.6.9', OfftubeSourceLayer.PgmGraphicsTema, 'GFX Tema'), SetSourceLayerName('1.6.9', OfftubeSourceLayer.WallGraphics, 'GFX Wall'), - SetSourceLayerName('1.6.9', SharedSourceLayers.PgmPilotOverlay, 'GFX overlay (VCP)(shared)'), + SetSourceLayerName('1.6.9', SharedSourceLayer.PgmPilotOverlay, 'GFX overlay (VCP)(shared)'), // PGM group SetSourceLayerName('1.6.9', OfftubeSourceLayer.PgmCam, 'Camera'), SetSourceLayerName('1.6.9', OfftubeSourceLayer.PgmDVEAdLib, 'DVE (adlib)'), @@ -173,7 +173,7 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ SetSourceLayerName('1.6.9', OfftubeSourceLayer.PgmPilot, 'GFX FULL (VCP)'), SetSourceLayerName('1.6.9', OfftubeSourceLayer.PgmContinuity, 'Continuity'), // MUSIK group - SetSourceLayerName('1.6.9', SharedSourceLayers.PgmAudioBed, 'Audiobed (shared)'), + SetSourceLayerName('1.6.9', SharedSourceLayer.PgmAudioBed, 'Audiobed (shared)'), // SEC group SetSourceLayerName('1.6.9', OfftubeSourceLayer.PgmAdlibGraphicCmd, 'GFX Cmd (adlib)'), SetSourceLayerName('1.6.9', OfftubeSourceLayer.PgmSisyfosAdlibs, 'Sisyfos (adlib)'), diff --git a/src/tv2_offtube_showstyle/migrations/outputlayer-defaults.ts b/src/tv2_offtube_showstyle/migrations/outputlayer-defaults.ts index 80aa0106..53279bcf 100644 --- a/src/tv2_offtube_showstyle/migrations/outputlayer-defaults.ts +++ b/src/tv2_offtube_showstyle/migrations/outputlayer-defaults.ts @@ -1,56 +1,56 @@ import { IOutputLayer } from 'blueprints-integration' import { literal } from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' +import { SharedOutputLayer } from 'tv2-constants' export default literal([ { - _id: SharedOutputLayers.OVERLAY, + _id: SharedOutputLayer.OVERLAY, name: 'OVERLAY', isPGM: false, _rank: 10, isDefaultCollapsed: true }, { - _id: SharedOutputLayers.JINGLE, + _id: SharedOutputLayer.JINGLE, name: 'JINGLE', isPGM: false, _rank: 19 }, { - _id: SharedOutputLayers.PGM, + _id: SharedOutputLayer.PGM, name: 'PGM', isPGM: true, _rank: 20, isFlattened: true }, { - _id: SharedOutputLayers.SELECTED_ADLIB, + _id: SharedOutputLayer.SELECTED_ADLIB, name: 'ADLIB', isPGM: false, _rank: 30, isDefaultCollapsed: true }, { - _id: SharedOutputLayers.MUSIK, + _id: SharedOutputLayer.MUSIK, name: 'MUSIK', isPGM: false, _rank: 22 }, { - _id: SharedOutputLayers.MANUS, + _id: SharedOutputLayer.MANUS, name: 'MANUS', isPGM: false, _rank: 23 }, { - _id: SharedOutputLayers.SEC, + _id: SharedOutputLayer.SEC, name: 'SEC', isPGM: false, _rank: 40, isDefaultCollapsed: true }, { - _id: SharedOutputLayers.AUX, + _id: SharedOutputLayer.AUX, name: 'AUX', isPGM: false, _rank: 50, diff --git a/src/tv2_offtube_showstyle/migrations/sourcelayer-defaults.ts b/src/tv2_offtube_showstyle/migrations/sourcelayer-defaults.ts index 93530a58..0de7574b 100644 --- a/src/tv2_offtube_showstyle/migrations/sourcelayer-defaults.ts +++ b/src/tv2_offtube_showstyle/migrations/sourcelayer-defaults.ts @@ -1,6 +1,6 @@ import { ISourceLayer, SourceLayerType } from 'blueprints-integration' import { GetDSKSourceLayerDefaults, literal } from 'tv2-common' -import { SharedSourceLayers } from 'tv2-constants' +import { SharedSourceLayer } from 'tv2-constants' import { ATEMModel } from '../../types/atem' import { OfftubeSourceLayer } from '../layers' @@ -127,7 +127,7 @@ const OVERLAY: ISourceLayer[] = [ onPresenterScreen: false }, { - _id: SharedSourceLayers.PgmPilotOverlay, + _id: SharedSourceLayer.PgmPilotOverlay, _rank: 60, name: 'GFX overlay (VCP)(shared)', abbreviation: 'O', @@ -310,7 +310,7 @@ const PGM: ISourceLayer[] = [ // MUSIK group const MUSIK: ISourceLayer[] = [ { - _id: SharedSourceLayers.PgmAudioBed, + _id: SharedSourceLayer.PgmAudioBed, _rank: 30, name: 'Audiobed (shared)', abbreviation: 'VO', @@ -411,7 +411,7 @@ const SEC: ISourceLayer[] = [ onPresenterScreen: false }, { - _id: SharedSourceLayers.RobotCamera, + _id: SharedSourceLayer.RobotCamera, _rank: 70, name: 'Robot Camera', abbreviation: '', diff --git a/src/tv2_offtube_showstyle/onTimelineGenerate.ts b/src/tv2_offtube_showstyle/onTimelineGenerate.ts index b71a3646..569bfe62 100644 --- a/src/tv2_offtube_showstyle/onTimelineGenerate.ts +++ b/src/tv2_offtube_showstyle/onTimelineGenerate.ts @@ -9,11 +9,11 @@ import { } from 'blueprints-integration' import { disablePilotWipeAfterJingle, - ExtendedTimelineContext, onTimelineGenerate, PartEndStateExt, PieceMetaData, - TimelineBlueprintExt + TimelineBlueprintExt, + TimelineContext } from 'tv2-common' import { SharedGraphicLLayer, TallyTags } from 'tv2-constants' import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' @@ -29,7 +29,7 @@ export function onTimelineGenerateOfftube( const previousPartEndState2 = previousPartEndState as PartEndStateExt | undefined disablePilotWipeAfterJingle(timeline, previousPartEndState2, resolvedPieces) disableFirstPilotGFXAnimation(coreContext, timeline, previousPartEndState2, resolvedPieces) - const context = new ExtendedTimelineContext(coreContext, QBOX_UNIFORM_CONFIG) + const context = new TimelineContext(coreContext, QBOX_UNIFORM_CONFIG) return onTimelineGenerate(context, timeline, previousPersistentState, previousPartEndState, resolvedPieces, { Caspar: { ClipPending: OfftubeCasparLLayer.CasparPlayerClipPending diff --git a/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts b/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts index 4fc6ca98..366f68f0 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts @@ -6,13 +6,13 @@ import { IBlueprintPart, IBlueprintPiece } from 'blueprints-integration' -import { AddScript, ExtendedSegmentContext, PartDefinitionDVE, PartTime } from 'tv2-common' +import { AddScript, PartDefinitionDVE, PartTime, SegmentContext } from 'tv2-common' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' export async function OfftubeCreatePartDVE( - context: ExtendedSegmentContext, + context: SegmentContext, partDefinition: PartDefinitionDVE, totalWords: number ): Promise { diff --git a/src/tv2_offtube_showstyle/parts/OfftubeEffekt.ts b/src/tv2_offtube_showstyle/parts/OfftubeEffekt.ts index 0224ec94..a2961524 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeEffekt.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeEffekt.ts @@ -1,16 +1,16 @@ import { IBlueprintPiece } from 'blueprints-integration' -import { CreateEffektForPartBase, ExtendedShowStyleContext, PartDefinition } from 'tv2-common' -import { SharedSourceLayers } from 'tv2-constants' +import { CreateEffektForPartBase, PartDefinition, ShowStyleContext } from 'tv2-common' +import { SharedSourceLayer } from 'tv2-constants' import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeBlueprintConfig } from '../helpers/config' export function CreateEffektForpart( - context: ExtendedShowStyleContext, + context: ShowStyleContext, partDefinition: PartDefinition, pieces: IBlueprintPiece[] ) { return CreateEffektForPartBase(context, partDefinition, pieces, { - sourceLayer: SharedSourceLayers.PgmJingle, + sourceLayer: SharedSourceLayer.PgmJingle, casparLayer: OfftubeCasparLLayer.CasparPlayerJingle, sisyfosLayer: OfftubeSisyfosLLayer.SisyfosSourceJingle }) diff --git a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts index 2e5125be..2bf66ea3 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts @@ -5,19 +5,13 @@ import { IBlueprintPart, IBlueprintPiece } from 'blueprints-integration' -import { - AddScript, - ApplyFullGraphicPropertiesToPart, - ExtendedSegmentContext, - PartDefinition, - PartTime -} from 'tv2-common' +import { AddScript, applyFullGraphicPropertiesToPart, PartDefinition, PartTime, SegmentContext } from 'tv2-common' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' export async function OfftubeCreatePartGrafik( - context: ExtendedSegmentContext, + context: SegmentContext, partDefinition: PartDefinition, totalWords: number, asAdlibs?: boolean @@ -37,7 +31,7 @@ export async function OfftubeCreatePartGrafik( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - ApplyFullGraphicPropertiesToPart(context.config, part) + applyFullGraphicPropertiesToPart(context.config, part) await OfftubeEvaluateCues( context, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index a7d6aba3..f104489c 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -12,7 +12,6 @@ import { AddScript, CreatePartInvalid, CreatePartKamBase, - ExtendedSegmentContext, FindDSKJingle, findSourceInfo, GetSisyfosTimelineObjForCamera, @@ -20,16 +19,17 @@ import { literal, PartDefinitionKam, PieceMetaData, + SegmentContext, TransitionStyle } from 'tv2-common' -import { SharedOutputLayers, TallyTags } from 'tv2-constants' +import { SharedOutputLayer, TallyTags } from 'tv2-constants' import { OfftubeBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' import { CreateEffektForpart } from './OfftubeEffekt' export async function OfftubeCreatePartKam( - context: ExtendedSegmentContext, + context: SegmentContext, partDefinition: PartDefinitionKam, totalWords: number ): Promise { @@ -50,7 +50,7 @@ export async function OfftubeCreatePartKam( externalId: partDefinition.externalId, name: 'CS 3 (JINGLE)', enable: { start: 0 }, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, sourceLayerId: OfftubeSourceLayer.PgmJingle, lifespan: PieceLifespan.WithinPart, tags: [GetTagForKam(partDefinition.sourceDefinition), TallyTags.JINGLE_IS_LIVE], @@ -81,7 +81,7 @@ export async function OfftubeCreatePartKam( externalId: partDefinition.externalId, name: part.title, enable: { start: 0 }, - outputLayerId: SharedOutputLayers.PGM, + outputLayerId: SharedOutputLayer.PGM, sourceLayerId: OfftubeSourceLayer.PgmCam, lifespan: PieceLifespan.WithinPart, metaData: { diff --git a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts index 61814de2..99d792e7 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts @@ -3,8 +3,8 @@ import { AddScript, CreateAdlibServer, CreatePartServerBase, - ExtendedSegmentContext, PartDefinition, + SegmentContext, ServerPartProps } from 'tv2-common' import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' @@ -14,7 +14,7 @@ import { OfftubeSourceLayer } from '../layers' import { CreateEffektForpart } from './OfftubeEffekt' export async function OfftubeCreatePartServer( - context: ExtendedSegmentContext, + context: SegmentContext, partDefinition: PartDefinition, partProps: ServerPartProps ): Promise { diff --git a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts index f063bc92..1c17e62f 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts @@ -7,12 +7,12 @@ import { } from 'blueprints-integration' import { AddScript, - ApplyFullGraphicPropertiesToPart, - ExtendedSegmentContext, + applyFullGraphicPropertiesToPart, GetJinglePartProperties, GraphicIsPilot, PartDefinition, - PartTime + PartTime, + SegmentContext } from 'tv2-common' import { CueType } from 'tv2-constants' import { OfftubeBlueprintConfig } from '../helpers/config' @@ -20,7 +20,7 @@ import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' export async function CreatePartUnknown( - context: ExtendedSegmentContext, + context: SegmentContext, partDefinition: PartDefinition, totalWords: number, asAdlibs?: boolean @@ -46,7 +46,7 @@ export async function CreatePartUnknown( partDefinition.cues.some((cue) => cue.type === CueType.Graphic && GraphicIsPilot(cue) && cue.target === 'FULL') && !partDefinition.cues.filter((c) => c.type === CueType.Jingle).length ) { - ApplyFullGraphicPropertiesToPart(context.config, part) + applyFullGraphicPropertiesToPart(context.config, part) } await OfftubeEvaluateCues( diff --git a/src/tv2_offtube_studio/config-manifests.ts b/src/tv2_offtube_studio/config-manifests.ts index cb7eacd8..452d77b6 100644 --- a/src/tv2_offtube_studio/config-manifests.ts +++ b/src/tv2_offtube_studio/config-manifests.ts @@ -69,7 +69,7 @@ export const manifestOfftubeSourcesFeed = MakeConfigForSources('Feed', 'Feed', t export const manifestOfftubeSourcesABMediaPlayers: ConfigManifestEntryTable = { id: 'ABMediaPlayers', name: 'Media Players inputs', - description: 'Switcher inputs for A/B media players', + description: 'Video Switcher inputs for A/B media players', type: ConfigManifestEntryType.TABLE, required: false, defaultVal: literal>([ @@ -96,7 +96,7 @@ export const manifestOfftubeSourcesABMediaPlayers: ConfigManifestEntryTable = { }, { id: 'SwitcherSource', - name: 'Switcher input', + name: 'Video Switcher input', description: 'Video Switcher input for Media player', type: ConfigManifestEntryType.INT, required: true, @@ -152,7 +152,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.SplitArtF', - name: 'Switcher Split Screen Art Fill', + name: 'Video Switcher Split Screen Art Fill', description: 'Video Switcher input for Split Screen Art Fill', type: ConfigManifestEntryType.INT, required: true, @@ -160,7 +160,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.SplitArtK', - name: 'Switcher Split Screen Art Key', + name: 'Video Switcher Split Screen Art Key', description: 'Video Switcher input for Split Screen Art Key', type: ConfigManifestEntryType.INT, required: true, @@ -168,7 +168,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.SplitBackground', - name: 'Switcher split screen background loop source', + name: 'Video Switcher split screen background loop source', description: 'Video Switcher source for mos full-frame grafik background source', type: ConfigManifestEntryType.INT, required: false, @@ -184,7 +184,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.Default', - name: 'Switcher Default source', + name: 'Video Switcher Default source', description: 'Video Switcher default source', type: ConfigManifestEntryType.INT, required: true, @@ -192,7 +192,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.Continuity', - name: 'Switcher continuity source', + name: 'Video Switcher continuity source', description: 'Video Switcher input for continuity', type: ConfigManifestEntryType.INT, required: true, @@ -200,7 +200,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.Dip', - name: 'Switcher Dip Source', + name: 'Video Switcher Dip Source', description: 'Video Switcher source for the Dip - should match the desired input in the Video Switcher', type: ConfigManifestEntryType.INT, required: true, @@ -368,7 +368,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ { id: 'VizPilotGraphics.FullGraphicBackground', name: 'Full frame grafik background source', - description: 'ATEM source for mos full-frame grafik background source', + description: 'Video Switcher source for mos full-frame grafik background source', type: ConfigManifestEntryType.INT, required: false, defaultVal: 0 diff --git a/src/tv2_offtube_studio/getBaseline.ts b/src/tv2_offtube_studio/getBaseline.ts index 56e90e05..cc73f502 100644 --- a/src/tv2_offtube_studio/getBaseline.ts +++ b/src/tv2_offtube_studio/getBaseline.ts @@ -5,7 +5,7 @@ import { IStudioContext, TSR } from 'blueprints-integration' -import { ExtendedStudioContext, literal, TransitionStyle } from 'tv2-common' +import { literal, StudioContext, TransitionStyle } from 'tv2-common' import * as _ from 'underscore' import { OfftubeStudioBlueprintConfig } from './helpers/config' import { OfftubeSisyfosLLayer } from './layers' @@ -29,7 +29,7 @@ function filterMappings( } export function getBaseline(coreContext: IStudioContext): BlueprintResultBaseline { - const context = new ExtendedStudioContext(coreContext, QBOX_UNIFORM_CONFIG) + const context = new StudioContext(coreContext, QBOX_UNIFORM_CONFIG) const mappings = coreContext.getStudioMappings() const sisyfosMappings = filterMappings(mappings, (_id, v) => v.device === TSR.DeviceType.SISYFOS) diff --git a/src/tv2_offtube_studio/helpers/config.ts b/src/tv2_offtube_studio/helpers/config.ts index 6b453be1..f2000456 100644 --- a/src/tv2_offtube_studio/helpers/config.ts +++ b/src/tv2_offtube_studio/helpers/config.ts @@ -6,7 +6,7 @@ import { TableConfigItemSourceMapping, TV2StudioConfigBase } from 'tv2-common' -import { DSKRoles } from 'tv2-constants' +import { DskRole } from 'tv2-constants' import * as _ from 'underscore' import { parseMediaPlayers, parseSources } from './sources' @@ -67,7 +67,7 @@ export const defaultDSKConfig: TableConfigItemDSK[] = [ Fill: 7, Toggle: true, DefaultOn: true, - Roles: [DSKRoles.JINGLE, DSKRoles.OVERLAYGFX], + Roles: [DskRole.JINGLE, DskRole.OVERLAYGFX], Clip: 50.0, Gain: 12.5 }, @@ -78,7 +78,7 @@ export const defaultDSKConfig: TableConfigItemDSK[] = [ Fill: 12, Toggle: false, DefaultOn: false, - Roles: [DSKRoles.FULLGFX], + Roles: [DskRole.FULLGFX], Clip: 50.0, Gain: 12.5 } From f921b76e1526ec3c92bf460f7ce3643a626c8e83 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 1 Mar 2023 21:03:56 +0100 Subject: [PATCH 37/86] refactor: SOF-1260 remove dead code --- src/tv2-common/actions/executeAction.ts | 5 ----- src/tv2-common/evaluateCues.ts | 12 +----------- src/tv2-common/parts/effekt.ts | 5 ----- src/tv2_afvd_showstyle/helpers/pieces/jingle.ts | 8 +------- src/tv2_afvd_showstyle/parts/intro.ts | 5 ----- src/tv2_offtube_showstyle/cues/OfftubeJingle.ts | 8 +------- 6 files changed, 3 insertions(+), 40 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 49315992..95ffeb0c 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -929,11 +929,6 @@ async function executeActionSelectJingle< ) { let file = '' - if (!context.config.showStyle.BreakerConfig) { - context.core.notifyUserWarning(`Jingles have not been configured`) - return - } - const externalId = generateExternalId(context, actionId, [userData.clip]) const jingle = context.config.showStyle.BreakerConfig.find((brkr) => diff --git a/src/tv2-common/evaluateCues.ts b/src/tv2-common/evaluateCues.ts index 4e13eca1..d9255f3d 100644 --- a/src/tv2-common/evaluateCues.ts +++ b/src/tv2-common/evaluateCues.ts @@ -120,7 +120,6 @@ export interface EvaluateCuesShowstyleOptions { EvaluateCueJingle?: ( context: ShowStyleContext, pieces: IBlueprintPiece[], - adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], parsedCue: CueDefinitionJingle, part: PartDefinition, @@ -261,16 +260,7 @@ export async function EvaluateCuesBase( break case CueType.Jingle: if (showStyleOptions.EvaluateCueJingle) { - showStyleOptions.EvaluateCueJingle( - context, - pieces, - adLibPieces, - actions, - cue, - partDefinition, - shouldAdlib, - adLibRank - ) + showStyleOptions.EvaluateCueJingle(context, pieces, actions, cue, partDefinition, shouldAdlib, adLibRank) } break case CueType.LYD: diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index 7027bf27..b5b78763 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -91,11 +91,6 @@ export function CreateEffektForPartInner< }, label: string ): Pick | false { - if (!context.config.showStyle.BreakerConfig) { - context.core.notifyUserWarning(`Jingles have not been configured`) - return false - } - const effektConfig = context.config.showStyle.BreakerConfig.find( (conf) => conf.BreakerName.toString().trim().toUpperCase() === effekt.toUpperCase() ) diff --git a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts index 9af9bc25..616d46fb 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts @@ -1,4 +1,4 @@ -import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece, PieceLifespan } from 'blueprints-integration' +import { IBlueprintActionManifest, IBlueprintPiece, PieceLifespan } from 'blueprints-integration' import { ActionSelectJingle, CreateJingleContentBase, @@ -19,7 +19,6 @@ import { GalleryBlueprintConfig } from '../config' export function EvaluateJingle( context: ShowStyleContext, pieces: IBlueprintPiece[], - _adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], parsedCue: CueDefinitionJingle, part: PartDefinition, @@ -27,11 +26,6 @@ export function EvaluateJingle( rank?: number, effekt?: boolean ) { - if (!context.config.showStyle.BreakerConfig) { - context.core.notifyUserWarning(`Jingles have not been configured`) - return - } - let file = '' const jingle = context.config.showStyle.BreakerConfig.find((brkr) => diff --git a/src/tv2_afvd_showstyle/parts/intro.ts b/src/tv2_afvd_showstyle/parts/intro.ts index 3fbde791..3bcf33c1 100644 --- a/src/tv2_afvd_showstyle/parts/intro.ts +++ b/src/tv2_afvd_showstyle/parts/intro.ts @@ -39,11 +39,6 @@ export async function CreatePartIntro( const parsedJingle = jingleCue as CueDefinitionJingle - if (!context.config.showStyle.BreakerConfig) { - context.core.notifyUserWarning(`Jingles have not been configured`) - return CreatePartInvalid(partDefinition) - } - const jingle = context.config.showStyle.BreakerConfig.find((jngl) => jngl.BreakerName ? jngl.BreakerName.toString().toUpperCase() === parsedJingle.clip.toString().toUpperCase() : false ) diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index f876abb0..72c15818 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -1,4 +1,4 @@ -import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece, PieceLifespan } from 'blueprints-integration' +import { IBlueprintActionManifest, IBlueprintPiece, PieceLifespan } from 'blueprints-integration' import { ActionSelectJingle, CreateJingleContentBase, @@ -21,7 +21,6 @@ import { OfftubeOutputLayers, OfftubeSourceLayer } from '../layers' export function OfftubeEvaluateJingle( context: SegmentContext, pieces: Array>, - _adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], parsedCue: CueDefinitionJingle, part: PartDefinition, @@ -29,11 +28,6 @@ export function OfftubeEvaluateJingle( _rank?: number, effekt?: boolean ) { - if (!context.config.showStyle.BreakerConfig) { - context.core.notifyUserWarning(`Jingles have not been configured`) - return - } - let file = '' const jingle = context.config.showStyle.BreakerConfig.find((brkr) => From e44fe1560c9e4242591f3933a17fa458e59ada81 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 1 Mar 2023 21:48:43 +0100 Subject: [PATCH 38/86] refactor: SOF-1260 remove useless property and rename a function --- .../__tests__/transition-from-string.spec.ts | 24 +++++++++---------- .../actions/CoreActionExecutionContext.ts | 1 - .../inewsConversion/converters/ParseBody.ts | 4 ++-- src/tv2-common/transitionStyleFromString.ts | 2 +- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/tv2-common/__tests__/transition-from-string.spec.ts b/src/tv2-common/__tests__/transition-from-string.spec.ts index 18bf30cd..c7af1cf4 100644 --- a/src/tv2-common/__tests__/transition-from-string.spec.ts +++ b/src/tv2-common/__tests__/transition-from-string.spec.ts @@ -1,18 +1,18 @@ import { TransitionStyle } from 'tv2-common' -import { TransitionStyleFromString } from '../transitionStyleFromString' +import { parseTransitionStyle } from '../transitionStyleFromString' describe('Transition From String', () => { it('Converts strings', () => { - expect(TransitionStyleFromString('mix')).toEqual(TransitionStyle.MIX) - expect(TransitionStyleFromString('MIX')).toEqual(TransitionStyle.MIX) - expect(TransitionStyleFromString('dip')).toEqual(TransitionStyle.DIP) - expect(TransitionStyleFromString('DIP')).toEqual(TransitionStyle.DIP) - expect(TransitionStyleFromString('wipe')).toEqual(TransitionStyle.WIPE) - expect(TransitionStyleFromString('WIPE')).toEqual(TransitionStyle.WIPE) - expect(TransitionStyleFromString('sting')).toEqual(TransitionStyle.STING) - expect(TransitionStyleFromString('STING')).toEqual(TransitionStyle.STING) - expect(TransitionStyleFromString('cut')).toEqual(TransitionStyle.CUT) - expect(TransitionStyleFromString('CUT')).toEqual(TransitionStyle.CUT) - expect(TransitionStyleFromString('unknown')).toEqual(TransitionStyle.CUT) + expect(parseTransitionStyle('mix')).toEqual(TransitionStyle.MIX) + expect(parseTransitionStyle('MIX')).toEqual(TransitionStyle.MIX) + expect(parseTransitionStyle('dip')).toEqual(TransitionStyle.DIP) + expect(parseTransitionStyle('DIP')).toEqual(TransitionStyle.DIP) + expect(parseTransitionStyle('wipe')).toEqual(TransitionStyle.WIPE) + expect(parseTransitionStyle('WIPE')).toEqual(TransitionStyle.WIPE) + expect(parseTransitionStyle('sting')).toEqual(TransitionStyle.STING) + expect(parseTransitionStyle('STING')).toEqual(TransitionStyle.STING) + expect(parseTransitionStyle('cut')).toEqual(TransitionStyle.CUT) + expect(parseTransitionStyle('CUT')).toEqual(TransitionStyle.CUT) + expect(parseTransitionStyle('unknown')).toEqual(TransitionStyle.CUT) }) }) diff --git a/src/tv2-common/actions/CoreActionExecutionContext.ts b/src/tv2-common/actions/CoreActionExecutionContext.ts index 9d384ea2..4ba153c0 100644 --- a/src/tv2-common/actions/CoreActionExecutionContext.ts +++ b/src/tv2-common/actions/CoreActionExecutionContext.ts @@ -16,7 +16,6 @@ import { ITV2ActionExecutionContext } from './context' export class CoreActionExecutionContext implements ITV2ActionExecutionContext { public studioId: string - public isTV2Context: true = true private modifiedParts: Set<'current' | 'next'> = new Set() diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index 5b684e02..711ad6f9 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -2,7 +2,7 @@ import { CueDefinitionFromLayout, PostProcessDefinitions, TransitionStyle, - TransitionStyleFromString, + parseTransitionStyle, TV2ShowStyleConfig, UnparsedCue } from 'tv2-common' @@ -564,7 +564,7 @@ export function getTransitionProperties(typeStr: string): Pick Date: Thu, 2 Mar 2023 09:08:59 +0100 Subject: [PATCH 39/86] SOF-1264 Minor import refactor --- src/tv2-common/inewsConversion/converters/ParseBody.ts | 2 +- src/tv2-common/videoSwitchers/TriCaster.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index 711ad6f9..52e72aa8 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -1,8 +1,8 @@ import { CueDefinitionFromLayout, + parseTransitionStyle, PostProcessDefinitions, TransitionStyle, - parseTransitionStyle, TV2ShowStyleConfig, UnparsedCue } from 'tv2-common' diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 92fee9ee..8bab0216 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -1,5 +1,5 @@ import { IStudioContext, TimelineObjectCoreExt, TSR } from 'blueprints-integration' -import { FRAME_RATE, getTimeFromFrames, literal, TimeFromFrames, TV2StudioConfig, UniformConfig } from 'tv2-common' +import { FRAME_RATE, getTimeFromFrames, literal, TV2StudioConfig, UniformConfig } from 'tv2-common' import { SwitcherDveLLayer } from 'tv2-constants' import _ = require('underscore') import { TRICASTER_DVE_ME, TRICASTER_LAYER_PREFIX } from '../layers' From 66db70155cb32fbf546467a39ad079678541c143 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Thu, 2 Mar 2023 10:57:59 +0100 Subject: [PATCH 40/86] SOF-1264 Able to play server in DVE --- src/tv2-common/actions/executeAction.ts | 10 ++++---- src/tv2-common/helpers/abPlayback.ts | 6 ++--- src/tv2-common/videoSwitchers/TriCaster.ts | 30 +++++++++++++++++----- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index e4868165..ec9f46ee 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -488,7 +488,7 @@ async function executeActionSelectServerClip< } } -function dveContainsServer(sources: DVESources) { +function dveContainsServer(sources: DVESources): boolean { return ( sources.INP1?.sourceType === SourceType.SERVER || sources.INP2?.sourceType === SourceType.SERVER || @@ -616,7 +616,7 @@ async function cutServerToBox< const meta = newDvePiece.metaData - const containsServer = dveContainsServer(meta.sources) + const containsServer: boolean = dveContainsServer(meta.sources) if (!containsServer) { if (containedServerBefore) { @@ -650,7 +650,7 @@ async function cutServerToBox< (obj) => obj.layer === settings.LLayer.Sisyfos.ClipPending ) as TSR.TimelineObjSisyfosChannel & TimelineBlueprintExt // Find DVE Boxes object in DVE piece - const dveBoxesObj = currentServer.piece.content.timelineObjects.find(context.videoSwitcher.isDveBoxes) as + const dveBoxesObj = newDvePiece.content.timelineObjects.find(context.videoSwitcher.isDveBoxes) as | TimelineBlueprintExt | undefined if ( @@ -1253,11 +1253,11 @@ async function executeActionCutSourceToBox< sisyfosLayers: [] } - const containsServerBefore = dveContainsServer(meta.sources) + const containsServerBefore: boolean = dveContainsServer(meta.sources) meta.sources[`INP${userData.box + 1}` as keyof DVEPieceMetaData['sources']] = userData.sourceDefinition - const containsServerAfter = dveContainsServer(meta.sources) + const containsServerAfter: boolean = dveContainsServer(meta.sources) const graphicsTemplateContent: { [key: string]: string } = {} diff --git a/src/tv2-common/helpers/abPlayback.ts b/src/tv2-common/helpers/abPlayback.ts index 94db9c30..3fe705c0 100644 --- a/src/tv2-common/helpers/abPlayback.ts +++ b/src/tv2-common/helpers/abPlayback.ts @@ -274,7 +274,9 @@ function updateObjectsToMediaPlayer< switcherInput = { id: playerId.toString(), val: context.config.studio.SwitcherSource.Default.toString() } } const input = Number(switcherInput.val) || 0 - if (context.videoSwitcher.isMixEffect(obj)) { + if (context.videoSwitcher.isDveBoxes(obj)) { + context.videoSwitcher.updateUnpopulatedDveBoxes(obj, input) + } else if (context.videoSwitcher.isMixEffect(obj)) { // the `endsWith` below is a nasty hack, but this will be gone after AB refactor if ( context.uniformConfig.switcherLLayers.nextPreviewMixEffect && @@ -286,8 +288,6 @@ function updateObjectsToMediaPlayer< } } else if (context.videoSwitcher.isAux(obj)) { context.videoSwitcher.updateAuxInput(obj, input) - } else if (context.videoSwitcher.isDveBoxes(obj)) { - context.videoSwitcher.updateUnpopulatedDveBoxes(obj, input) } else { context.core.logWarning( `Trying to move Video Switcher object of unknown type (${ diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 8bab0216..56dffabd 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -192,19 +192,35 @@ export class TriCaster extends VideoSwitcherBase { } public updateUnpopulatedDveBoxes( - _timelineObject: TSR.TSRTimelineObj, - _input: number | SpecialInput + timelineObject: TSR.TSRTimelineObj, + input: number | SpecialInput ): TSR.TSRTimelineObj { - throw new Error('Method not implemented.') + if (!this.isDveBoxes(timelineObject)) { + this.logWrongTimelineObjectType(timelineObject, this.updateUnpopulatedDveBoxes.name) + return timelineObject + } + const layers: Partial> = ( + (timelineObject as TSR.TimelineObjTriCasterME).content.me as TSR.TriCasterMixEffectInEffectMode + ).layers! + + this.assignInputIfPlaceholder(layers.a!, input) + this.assignInputIfPlaceholder(layers.b!, input) + this.assignInputIfPlaceholder(layers.c!, input) + this.assignInputIfPlaceholder(layers.d!, input) + return timelineObject + } + + public assignInputIfPlaceholder(layer: TSR.TriCasterLayer, input: number | SpecialInput): void { + const dveServerPlaceholder = 'input-1' + if (layer.input && layer.input === dveServerPlaceholder) { + layer.input = this.getInputName(input) + } } public getDveTimelineObjects(dveProps: DveProps): TSR.TSRTimelineObj[] { return [ literal({ - id: '', - enable: dveProps.enable ?? { start: 0 }, - layer: TRICASTER_LAYER_PREFIX + SwitcherDveLLayer.DveBoxes, - priority: 1, + ...this.getBaseProperties(dveProps, SwitcherDveLLayer.DveBoxes), content: { deviceType: TSR.DeviceType.TRICASTER, type: TSR.TimelineContentTypeTriCaster.ME, From 5b68ab1e6c1078a77d9f5ea9b2e2f68a065aa67f Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Thu, 2 Mar 2023 13:52:58 +0100 Subject: [PATCH 41/86] SOF-1264 tests for updateUnpopulatedDves --- src/tv2-common/videoSwitchers/TriCaster.ts | 3 +- .../__tests__/TriCaster.spec.ts | 107 ++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 56dffabd..9c174da0 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -199,6 +199,7 @@ export class TriCaster extends VideoSwitcherBase { this.logWrongTimelineObjectType(timelineObject, this.updateUnpopulatedDveBoxes.name) return timelineObject } + const layers: Partial> = ( (timelineObject as TSR.TimelineObjTriCasterME).content.me as TSR.TriCasterMixEffectInEffectMode ).layers! @@ -212,7 +213,7 @@ export class TriCaster extends VideoSwitcherBase { public assignInputIfPlaceholder(layer: TSR.TriCasterLayer, input: number | SpecialInput): void { const dveServerPlaceholder = 'input-1' - if (layer.input && layer.input === dveServerPlaceholder) { + if (layer && layer.input === dveServerPlaceholder) { layer.input = this.getInputName(input) } } diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index 42c3d3f1..b85eea39 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -477,6 +477,113 @@ describe('TriCaster', () => { }) }) + describe('updateUnpopulatedDveBoxes', () => { + it('receives unpopulated box for A with input 5, it populates A with input5', () => { + assertPopulateUnpopulatedBox(5, 'a') + }) + + function assertPopulateUnpopulatedBox(inputToUpdate: number, layerName: TSR.TriCasterLayerName): void { + const testee: TriCaster = createTestee() + const timelineObject: TSR.TimelineObjTriCasterME = { + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME, + me: { + layers: { + [layerName]: { + input: 'input-1' + } + } + } + } + } as any as TSR.TimelineObjTriCasterME + + const timelineObjTriCasterME: TSR.TimelineObjTriCasterME = testee.updateUnpopulatedDveBoxes( + timelineObject, + inputToUpdate + ) as TSR.TimelineObjTriCasterME + const result: TSR.TriCasterMixEffectInEffectMode = timelineObjTriCasterME.content + .me as TSR.TriCasterMixEffectInEffectMode + + expect(result.layers![layerName]!.input).toBe(`input${inputToUpdate}`) + } + + it('receives unpopulated box for A with input 7, it populates A with input7', () => { + assertPopulateUnpopulatedBox(7, 'a') + }) + + it('receives populated box for A, it does not populate A', () => { + assertPopulatedBoxIsNotReassigned('a', 10, 2) + }) + + function assertPopulatedBoxIsNotReassigned( + layerName: TSR.TriCasterLayerName, + alreadyPopulatedInputSource: number, + otherInputSource: number + ): void { + const testee: TriCaster = createTestee() + const timelineObject: TSR.TimelineObjTriCasterME = { + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME, + me: { + layers: { + [layerName]: { + input: `input${alreadyPopulatedInputSource}` + } + } + } + } + } as any as TSR.TimelineObjTriCasterME + + const timelineObjTriCasterME: TSR.TimelineObjTriCasterME = testee.updateUnpopulatedDveBoxes( + timelineObject, + otherInputSource + ) as TSR.TimelineObjTriCasterME + const result: TSR.TriCasterMixEffectInEffectMode = timelineObjTriCasterME.content + .me as TSR.TriCasterMixEffectInEffectMode + + expect(result.layers![layerName]!.input).toBe(`input${alreadyPopulatedInputSource}`) + expect(result.layers![layerName]!.input).not.toBe(otherInputSource.toString()) + } + + it('receives unpopulated box for B with input 5, it populates B with input5', () => { + assertPopulateUnpopulatedBox(5, 'b') + }) + + it('receives unpopulated box for B with input 7, it populates B with input7', () => { + assertPopulateUnpopulatedBox(7, 'b') + }) + + it('receives populated box for B, it does not populate C', () => { + assertPopulatedBoxIsNotReassigned('b', 10, 2) + }) + + it('receives unpopulated box for C with input 5, it populates C with input5', () => { + assertPopulateUnpopulatedBox(5, 'c') + }) + + it('receives unpopulated box for C with input 7, it populates C with input7', () => { + assertPopulateUnpopulatedBox(7, 'c') + }) + + it('receives populated box for C, it does not populate C', () => { + assertPopulatedBoxIsNotReassigned('c', 10, 2) + }) + + it('receives unpopulated box for D with input 5, it populates D with input5', () => { + assertPopulateUnpopulatedBox(5, 'd') + }) + + it('receives unpopulated box for D with input 7, it populates D with input7', () => { + assertPopulateUnpopulatedBox(7, 'd') + }) + + it('receives populated box for D, it does not populate D', () => { + assertPopulatedBoxIsNotReassigned('d', 10, 2) + }) + }) + describe('getDveTimelineObjects', () => { it('creates one TriCaster DVE timelineObject', () => { const testee: TriCaster = createTestee() From ad5dc677f290723b8c21591fb367f3ea7bf7d527 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Thu, 2 Mar 2023 14:02:59 +0100 Subject: [PATCH 42/86] SOF-1264 Generating overlayKeyer now uses DveProps for finding source --- src/tv2-common/videoSwitchers/TriCaster.ts | 10 +++++----- .../videoSwitchers/__tests__/TriCaster.spec.ts | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 9c174da0..d2b1dad5 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -40,8 +40,6 @@ const TRANSITION_MAP: Record = { [TransitionStyle.STING]: 5 // not really supported?? } -const DVE_OVERLAY_INPUT_NUMBER = 5 - export class TriCaster extends VideoSwitcherBase { public readonly type = SwitcherType.ATEM @@ -228,7 +226,7 @@ export class TriCaster extends VideoSwitcherBase { me: literal({ transitionEffect: 8, layers: this.generateDveBoxLayers(dveProps.content.boxes), - keyers: this.generateOverlayKeyer() + keyers: this.generateOverlayKeyer(dveProps.content.artFillSource) }) } }) @@ -271,10 +269,12 @@ export class TriCaster extends VideoSwitcherBase { } } - private generateOverlayKeyer(): Record { + private generateOverlayKeyer( + overlaySource: number | SpecialInput + ): Record { return { dsk1: { - input: this.getInputName(this.config.studio.SwitcherSource?.SplitArtFill ?? DVE_OVERLAY_INPUT_NUMBER), + input: this.getInputName(overlaySource), onAir: true, transitionEffect: 'cut' } diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index b85eea39..45f199ce 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -624,13 +624,14 @@ describe('TriCaster', () => { } } as any as TV2StudioConfigBase) const testee: TriCaster = createTestee({ config: instance(config) }) - const content: TSR.TimelineObjTriCasterME['content'] = testee.getDveTimelineObjects(getBasicDveProps())[0] + const basicDveProps = getBasicDveProps() + const content: TSR.TimelineObjTriCasterME['content'] = testee.getDveTimelineObjects(basicDveProps)[0] .content as TSR.TimelineObjTriCasterME['content'] const result: Record = content.me.keyers! expect(result).toBeTruthy() expect(result.dsk1).toBeTruthy() - expect(result.dsk1.input).toBe(`input${artFillSource}`) + expect(result.dsk1.input).toBe(`input${basicDveProps.content.artFillSource}`) expect(result.dsk1.onAir).toBeTruthy() expect(result.dsk1.transitionEffect).toBe('cut') }) From ec4099e7d5a6b41446942530c1d3128f4577efd0 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Tue, 7 Mar 2023 12:59:13 +0100 Subject: [PATCH 43/86] SOF-1264 Minor refactors --- src/tv2-common/videoSwitchers/TriCaster.ts | 20 ++++++------- .../videoSwitchers/VideoSwitcher.ts | 4 +-- .../AtemToTricasterDveConverter.spec.ts | 28 +++++++++---------- ...rter.ts => atemToTriCasterDveConverter.ts} | 9 +++--- 4 files changed, 30 insertions(+), 31 deletions(-) rename src/tv2-common/videoSwitchers/{atemToTricasterDveConverter.ts => atemToTriCasterDveConverter.ts} (83%) diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index d2b1dad5..c4ee066c 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -181,7 +181,9 @@ export class TriCaster extends VideoSwitcherBase { return timelineObject } - public isDveBoxes = (timelineObject: TimelineObjectCoreExt): boolean => { + public isDveBoxes = ( + timelineObject: TimelineObjectCoreExt + ): timelineObject is TSR.TimelineObjTriCasterME => { // @todo: this is ugly, but works return ( TSR.isTimelineObjTriCasterME(timelineObject) && @@ -198,22 +200,18 @@ export class TriCaster extends VideoSwitcherBase { return timelineObject } - const layers: Partial> = ( - (timelineObject as TSR.TimelineObjTriCasterME).content.me as TSR.TriCasterMixEffectInEffectMode - ).layers! - - this.assignInputIfPlaceholder(layers.a!, input) - this.assignInputIfPlaceholder(layers.b!, input) - this.assignInputIfPlaceholder(layers.c!, input) - this.assignInputIfPlaceholder(layers.d!, input) + const dveMixEffect = timelineObject.content.me as TSR.TriCasterMixEffectInEffectMode + const layers = dveMixEffect.layers as NonNullable + Object.values(layers).forEach((layer) => this.assignInputIfPlaceholder(layer, input)) return timelineObject } public assignInputIfPlaceholder(layer: TSR.TriCasterLayer, input: number | SpecialInput): void { const dveServerPlaceholder = 'input-1' - if (layer && layer.input === dveServerPlaceholder) { - layer.input = this.getInputName(input) + if (layer.input !== dveServerPlaceholder) { + return } + layer.input = this.getInputName(input) } public getDveTimelineObjects(dveProps: DveProps): TSR.TSRTimelineObj[] { diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts index 63edecbb..0dddd256 100644 --- a/src/tv2-common/videoSwitchers/VideoSwitcher.ts +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -15,7 +15,7 @@ import { VideoSwitcher } from 'tv2-common' import _ = require('underscore') -import { AtemToTricasterDveConverter } from './atemToTricasterDveConverter' +import { AtemToTriCasterDveConverter } from './atemToTriCasterDveConverter' export abstract class VideoSwitcherBase implements VideoSwitcher { public static getVideoSwitcher( @@ -25,7 +25,7 @@ export abstract class VideoSwitcherBase implements VideoSwitcher { ): VideoSwitcherBase { return config.studio.SwitcherType === SwitcherType.ATEM ? new Atem(core, config, uniformConfig) - : new TriCaster(core, config, uniformConfig, new AtemToTricasterDveConverter()) + : new TriCaster(core, config, uniformConfig, new AtemToTriCasterDveConverter()) } public abstract readonly type: SwitcherType public abstract isDsk: (timelineObject: TimelineObjectCoreExt) => boolean diff --git a/src/tv2-common/videoSwitchers/__tests__/AtemToTricasterDveConverter.spec.ts b/src/tv2-common/videoSwitchers/__tests__/AtemToTricasterDveConverter.spec.ts index c51ff67e..e735e840 100644 --- a/src/tv2-common/videoSwitchers/__tests__/AtemToTricasterDveConverter.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/AtemToTricasterDveConverter.spec.ts @@ -1,5 +1,5 @@ import { TSR } from 'blueprints-integration' -import { AtemToTricasterDveConverter } from '../atemToTricasterDveConverter' +import { AtemToTriCasterDveConverter } from '../atemToTriCasterDveConverter' describe('AtemToTricasterDveConverter', () => { describe('convertPosition', () => { @@ -8,7 +8,7 @@ describe('AtemToTricasterDveConverter', () => { }) function testConvertPositionX(testValue: number, expectedResult: number): void { - const testee = new AtemToTricasterDveConverter() + const testee = new AtemToTriCasterDveConverter() const result: TSR.TriCasterLayer['position'] = testee.convertPosition(testValue, 0) expect(result!.x).toBeCloseTo(expectedResult, 2) } @@ -50,7 +50,7 @@ describe('AtemToTricasterDveConverter', () => { }) function testConvertPositionY(testValue: number, expectedResult: number): void { - const testee = new AtemToTricasterDveConverter() + const testee = new AtemToTriCasterDveConverter() const result: TSR.TriCasterLayer['position'] = testee.convertPosition(0, testValue) expect(result!.y).toBeCloseTo(expectedResult, 2) } @@ -94,7 +94,7 @@ describe('AtemToTricasterDveConverter', () => { }) function testConvertScale(testValue: number, expectedResult: number): void { - const testee = new AtemToTricasterDveConverter() + const testee = new AtemToTriCasterDveConverter() const result: TSR.TriCasterLayer['scale'] = testee.convertScale(testValue)! expect(result.x).toBe(expectedResult) expect(result.y).toBe(expectedResult) @@ -115,7 +115,7 @@ describe('AtemToTricasterDveConverter', () => { describe('convertCrop', () => { it('has cropped set to false, return 0 for all', () => { - const testee = new AtemToTricasterDveConverter() + const testee = new AtemToTriCasterDveConverter() const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(false, 12, 12, 12, 12))! expect(result.up).toBe(0) expect(result.down).toBe(0) @@ -140,7 +140,7 @@ describe('AtemToTricasterDveConverter', () => { } it('has cropped set to true, but no values, return 0 for all', () => { - const testee = new AtemToTricasterDveConverter() + const testee = new AtemToTriCasterDveConverter() const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 0, 0, 0))! expect(result.up).toBe(0) expect(result.down).toBe(0) @@ -149,49 +149,49 @@ describe('AtemToTricasterDveConverter', () => { }) it('has crop top 100, return crop up 0.555', () => { - const testee = new AtemToTricasterDveConverter() + const testee = new AtemToTriCasterDveConverter() const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 100, 0, 0, 0))! expect(result.up).toBeCloseTo(0.555) }) it('has crop top 8500, return crop up 47.222', () => { - const testee = new AtemToTricasterDveConverter() + const testee = new AtemToTriCasterDveConverter() const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 8500, 0, 0, 0))! expect(result.up).toBeCloseTo(47.222) }) it('has crop bottom 100, return crop down 0.555', () => { - const testee = new AtemToTricasterDveConverter() + const testee = new AtemToTriCasterDveConverter() const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 100, 0, 0))! expect(result.down).toBeCloseTo(0.555) }) it('has crop bottom 8500, return crop down 47.222', () => { - const testee = new AtemToTricasterDveConverter() + const testee = new AtemToTriCasterDveConverter() const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 8500, 0, 0))! expect(result.down).toBeCloseTo(47.222) }) it('has crop left 100, return crop left 0.312', () => { - const testee = new AtemToTricasterDveConverter() + const testee = new AtemToTriCasterDveConverter() const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 0, 100, 0))! expect(result.left).toBeCloseTo(0.312) }) it('has crop left 6200, return crop left 19.375', () => { - const testee = new AtemToTricasterDveConverter() + const testee = new AtemToTriCasterDveConverter() const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 0, 6200, 0))! expect(result.left).toBeCloseTo(19.375) }) it('has crop right 100, return crop right 0.312', () => { - const testee = new AtemToTricasterDveConverter() + const testee = new AtemToTriCasterDveConverter() const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 0, 0, 100))! expect(result.right).toBeCloseTo(0.312) }) it('has crop right 6200, return crop right 19.375', () => { - const testee = new AtemToTricasterDveConverter() + const testee = new AtemToTriCasterDveConverter() const result: TSR.TriCasterLayer['crop'] = testee.convertCrop(createCropObject(true, 0, 0, 0, 6200))! expect(result.right).toBeCloseTo(19.375) }) diff --git a/src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts b/src/tv2-common/videoSwitchers/atemToTriCasterDveConverter.ts similarity index 83% rename from src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts rename to src/tv2-common/videoSwitchers/atemToTriCasterDveConverter.ts index b493afd2..f6cdd2f7 100644 --- a/src/tv2-common/videoSwitchers/atemToTricasterDveConverter.ts +++ b/src/tv2-common/videoSwitchers/atemToTriCasterDveConverter.ts @@ -7,10 +7,11 @@ const ATEM_HEIGHT = 18 const ATEM_CROP_LEFT_RIGHT_MAX_VALUE = 32000 const ATEM_CROP_TOP_BOTTOM_MAX_VALUE = 18000 -const TRICASTER_WIDTH = (2 / 9) * 16 +const TRICASTER_HEIGHT = 2 +const TRICASTER_WIDTH = TRICASTER_HEIGHT * (16 / 9) -export class AtemToTricasterDveConverter implements TriCasterDveConverter { - public convertPosition(x: number, y: number): TSR.TriCasterLayer['position'] { +export class AtemToTriCasterDveConverter implements TriCasterDveConverter { + public convertPosition(x: number, y: number): NonNullable { return { x: this.convertPositionX(x), y: this.convertPositionY(y) @@ -27,7 +28,7 @@ export class AtemToTricasterDveConverter implements TriCasterDveConverter { return ((positionPercentage * 2) / 100) * -1 } - public convertScale(atemSize: number): TSR.TriCasterLayer['scale'] { + public convertScale(atemSize: number): NonNullable { return { x: atemSize / 1000, y: atemSize / 1000 From d0255c7e4d5728fd42363a1a18ce53a6ae758581 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 7 Mar 2023 14:09:48 +0100 Subject: [PATCH 44/86] chore: SOF-1260 update blueprints-integration to 46.2.0 --- package.json | 2 +- yarn.lock | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 08a18266..1d996e8a 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "webpack-cli": "^3.1.2" }, "dependencies": { - "@sofie-automation/blueprints-integration": "npm:@tv2media/blueprints-integration@46.1.1", + "@sofie-automation/blueprints-integration": "npm:@tv2media/blueprints-integration@46.2.0", "underscore": "^1.12.1", "ts-mockito": "^2.6.1" }, diff --git a/yarn.lock b/yarn.lock index 2043b527..51fa795f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -560,20 +560,20 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@sofie-automation/blueprints-integration@npm:@tv2media/blueprints-integration@46.1.1": - version "46.1.1" - resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-46.1.1.tgz#21a6eda0a1635f59f680cc868e50195bf700caf1" - integrity sha512-xep0lLLblQmCEzUy5S/MQZ1YsRVjwThAu+6HFyi/A++IKkGLTQRX7Pk1lAA3W2TB+vqcBSw+65YSHVSsiYqUNA== +"@sofie-automation/blueprints-integration@npm:@tv2media/blueprints-integration@46.2.0": + version "46.2.0" + resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-46.2.0.tgz#ff2cf16e6350510b8083e7b2781a17d1b1141c4d" + integrity sha512-hWKDVEQo1stlMNtxkumEy+PwM99ZAffBWkgSzBMJyIneb5pR/Dkm/3vl5f3LHWnFVZGuwISq5LvpPkNEdv+Nvg== dependencies: - "@sofie-automation/shared-lib" "npm:@tv2media/shared-lib@46.1.0" - timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@3.0.3" + "@sofie-automation/shared-lib" "npm:@tv2media/shared-lib@46.2.0" + timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@3.3.0" tslib "^2.4.0" type-fest "^2.19.0" -"@sofie-automation/shared-lib@npm:@tv2media/shared-lib@46.1.0": - version "46.1.0" - resolved "https://registry.yarnpkg.com/@tv2media/shared-lib/-/shared-lib-46.1.0.tgz#ea13b33b0be2feb5cc3d821a6fe992c865f73c5f" - integrity sha512-87h3/w/9vuP6fafH3If8S5j6PlLDSwZGJ1vghpXHHSMtqMV5pm5KZPuT80hGITxXO5GNF1JizaX52Lvb3L6iWw== +"@sofie-automation/shared-lib@npm:@tv2media/shared-lib@46.2.0": + version "46.2.0" + resolved "https://registry.yarnpkg.com/@tv2media/shared-lib/-/shared-lib-46.2.0.tgz#934f14339330bd0064d7a0c3046dae10e2754099" + integrity sha512-ojW4qHQ+dfQDzFotqq4kEJNb6nVSDk/KU2u1S2fzXkZzgXW4Xq2hNUyk5lfUMcd7nBsiRVnPzmVSqxbRfUd1MQ== dependencies: tslib "^2.4.0" type-fest "^2.19.0" @@ -5956,10 +5956,10 @@ through@2, "through@>=2.2.7 <3": resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -"timeline-state-resolver-types@npm:@tv2media/timeline-state-resolver-types@3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-3.0.3.tgz#cb22a1dee460403c2a306e666003a1d57af7f8d2" - integrity sha512-PqqV2EFCfhQyphngRFh0K7UcO+pptB5e6vk73uT+gz0S+j/aV2uAtOKA3PPeEc7W37ov4KCsP10T4KVTntNkAw== +"timeline-state-resolver-types@npm:@tv2media/timeline-state-resolver-types@3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-3.3.0.tgz#08e5b700d59a92855f27e80e98830307f0e50ead" + integrity sha512-2fnXgtg3H1mZwQNz1ax7kHPXhcMmp3ak7qVf8WIPysodtBXExP4LoRypv6fgOzX15og+gmgR3YYQGLrqiw14QA== dependencies: tslib "^2.3.1" From 5728aa430bbc93ac9a44b3c28d68fae1dbe405b5 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 8 Mar 2023 09:36:16 +0100 Subject: [PATCH 45/86] fix: SOF-1260 fix duration of effects adds the preroll to the piece duration in order to prevent cutting off frames at the end --- src/tv2-common/parts/effekt.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index b5b78763..528ca6fe 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -111,7 +111,10 @@ export function CreateEffektForPartInner< pieces.push({ externalId, name: label, - enable: { start: 0, duration: getTimeFromFrames(Number(effektConfig.Duration)) }, + enable: { + start: 0, + duration: getTimeFromFrames(effektConfig.Duration) + context.config.studio.CasparPrerollDuration + }, outputLayerId: SharedOutputLayer.JINGLE, sourceLayerId: layers.sourceLayer, lifespan: PieceLifespan.WithinPart, @@ -125,7 +128,7 @@ export function CreateEffektForPartInner< context.config.studio.JingleFileExtension ), // full path on the source network storage mediaFlowIds: [context.config.studio.JingleMediaFlowId], - previewFrame: Number(effektConfig.StartAlpha), + previewFrame: effektConfig.StartAlpha, ignoreMediaObjectStatus: context.config.studio.JingleIgnoreStatus, ignoreBlackFrames: true, ignoreFreezeFrame: true, @@ -144,7 +147,7 @@ export function CreateEffektForPartInner< } }), ...getDskOnAirTimelineObjects(context, DskRole.JINGLE, { - start: Number(context.config.studio.CasparPrerollDuration) + start: context.config.studio.CasparPrerollDuration }), literal({ id: '', From db03baec0addbf4e9707d893919f4b39b8654341 Mon Sep 17 00:00:00 2001 From: ianshade Date: Mon, 13 Mar 2023 07:51:55 +0100 Subject: [PATCH 46/86] fix: SOF-1260 reorder DVE and mix-minus commands DVE - after other commands, to avoid desync between Program and Clean outs; mix-minus (the overrides) - before other commands, to cut away from M/Es before their transition starts --- src/tv2-common/cues/mixMinus.ts | 5 ++-- src/tv2-common/videoSwitchers/TriCaster.ts | 32 +++++++++++----------- src/tv2-common/videoSwitchers/types.ts | 12 ++++++++ 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/tv2-common/cues/mixMinus.ts b/src/tv2-common/cues/mixMinus.ts index 1de79865..fd48b2a3 100644 --- a/src/tv2-common/cues/mixMinus.ts +++ b/src/tv2-common/cues/mixMinus.ts @@ -1,5 +1,5 @@ import { IBlueprintPiece, PieceLifespan, TSR } from 'blueprints-integration' -import { CueDefinitionMixMinus, findSourceInfo, PartDefinition, ShowStyleContext } from 'tv2-common' +import { CueDefinitionMixMinus, findSourceInfo, PartDefinition, ShowStyleContext, TemporalPriority } from 'tv2-common' import { ControlClasses, SharedOutputLayer, SharedSourceLayer, SwitcherAuxLLayer } from 'tv2-constants' export function EvaluateCueMixMinus( @@ -56,6 +56,7 @@ export function getMixMinusTimelineObject( while: `.${ControlClasses.OVERRIDDEN_ON_MIX_MINUS}` }, layer: SwitcherAuxLLayer.AuxVideoMixMinus, - priority + priority, + temporalPriority: TemporalPriority.AUX_MIX_MINUS_OVERRIDE }) } diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index c4ee066c..d59aa2bf 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -14,7 +14,8 @@ import { SwitcherType, TIMELINE_OBJECT_DEFAULTS, TimelineObjectProps, - TransitionStyle + TransitionStyle, + TemporalPriority } from './types' import { VideoSwitcherBase } from './VideoSwitcher' @@ -214,21 +215,20 @@ export class TriCaster extends VideoSwitcherBase { layer.input = this.getInputName(input) } - public getDveTimelineObjects(dveProps: DveProps): TSR.TSRTimelineObj[] { - return [ - literal({ - ...this.getBaseProperties(dveProps, SwitcherDveLLayer.DveBoxes), - content: { - deviceType: TSR.DeviceType.TRICASTER, - type: TSR.TimelineContentTypeTriCaster.ME, - me: literal({ - transitionEffect: 8, - layers: this.generateDveBoxLayers(dveProps.content.boxes), - keyers: this.generateOverlayKeyer(dveProps.content.artFillSource) - }) - } - }) - ] + public getDveTimelineObjects(dveProps: DveProps): TSR.TimelineObjTriCasterME[] { + return [{ + ...this.getBaseProperties(dveProps, SwitcherDveLLayer.DveBoxes), + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME, + me: literal({ + transitionEffect: 7, + layers: this.generateDveBoxLayers(dveProps.content.boxes), + keyers: this.generateOverlayKeyer(dveProps.content.artFillSource) + }), + temporalPriority: TemporalPriority.DVE + } + }] } private generateDveBoxLayers(boxes: any[]): Partial> { diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index 5417d97c..e8f9876c 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -30,6 +30,12 @@ export enum TransitionStyle { // ... } +export enum TemporalPriority { + AUX_MIX_MINUS_OVERRIDE = -1, // to make the overriding timelineobjects act before the cut on an M/E + DEFAULT = 0, // the default (does not have to be explicitly set) + DVE = 1, // to place DVE commands afer regular M/E and AUX commands (ATEM integration does that by default) +} + export enum SwitcherLLayer {} export const TIMELINE_OBJECT_DEFAULTS = { @@ -45,6 +51,12 @@ export interface TimelineObjectProps { enable?: TimelineObjectEnable // Default: 0 priority?: number + /** + * Currently a TriCaster-only feature allowing reordering of commands in a single batch + * Lower means the command will execue faster + * Default: 0 + */ + temporalPriority?: number metaData?: TimelineObjectMetaData classes?: string[] } From 583e66137d7fcf3d8d3e190532e2f9ef120bf6cd Mon Sep 17 00:00:00 2001 From: ianshade Date: Mon, 13 Mar 2023 08:07:01 +0100 Subject: [PATCH 47/86] fix: SOF-1260 relabel atem-only input settings --- docs/DVE.md | 2 +- src/tv2-common/helpers/dsk.ts | 4 ++-- src/tv2_afvd_studio/config-manifests.ts | 8 ++++---- src/tv2_offtube_studio/config-manifests.ts | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/DVE.md b/docs/DVE.md index 256976e6..39155992 100644 --- a/docs/DVE.md +++ b/docs/DVE.md @@ -1,6 +1,6 @@ # DVE -To use DVEs, first add the studio settings `Video Switcher Split Screen Art Fill` and `Video Switcher Split Screen Art Key`. +To use DVEs, first add the studio settings `Video Switcher Split Screen Art Fill` and `ATEM Split Screen Art Key`. For TriCaster only the Fill source is configurable. The pairing with a Key source may need to be set up in the switcher if the Fill source does not have its alpha channel already embedded. Then, go to your showstyle settings and add the setting `DVE Styles`. Here you can define all the DVEs for your show. diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index 56ff5769..60046e62 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -190,8 +190,8 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { }, { id: 'Key', - name: 'Video Switcher Key', - description: 'Video Switcher input for DSK Key', + name: 'ATEM Key', + description: 'ATEM input for DSK Key (for TriCaster see documentation)', type: ConfigManifestEntryType.INT, required: true, defaultVal: 34, diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index 137636e6..b0e9ce50 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -315,8 +315,8 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.SplitArtKey', - name: 'Video Switcher Split Screen Art Key', - description: 'Video Switcher input for Split Screen Art Key', + name: 'ATEM Split Screen Art Key', + description: 'ATEM input for Split Screen Art Key (for TriCaster see documentation)', type: ConfigManifestEntryType.INT, required: true, defaultVal: 32 @@ -347,8 +347,8 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.Dip', - name: 'Video Switcher Dip Source', - description: 'Video Switcher source for the Dip - should match the desired input in the Video Switcher', + name: 'ATEM Dip Source', + description: 'ATEM source for the Dip - should match the desired input in the Video Switcher', type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col2 diff --git a/src/tv2_offtube_studio/config-manifests.ts b/src/tv2_offtube_studio/config-manifests.ts index 8afd1866..1d66bee6 100644 --- a/src/tv2_offtube_studio/config-manifests.ts +++ b/src/tv2_offtube_studio/config-manifests.ts @@ -160,8 +160,8 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.SplitArtKey', - name: 'Video Switcher Split Screen Art Key', - description: 'Video Switcher input for Split Screen Art Key', + name: 'ATEM Split Screen Art Key', + description: 'ATEM input for Split Screen Art Key', type: ConfigManifestEntryType.INT, required: true, defaultVal: 9 @@ -200,8 +200,8 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ }, { id: 'SwitcherSource.Dip', - name: 'Video Switcher Dip Source', - description: 'Video Switcher source for the Dip - should match the desired input in the Video Switcher', + name: 'ATEM Dip Source', + description: 'ATEM source for the Dip - should match the desired input in the Video Switcher', type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col2 From c871bed46a147cd00d60b7b87fe115472e79da7d Mon Sep 17 00:00:00 2001 From: Rasmus Date: Mon, 13 Mar 2023 16:20:00 +0100 Subject: [PATCH 48/86] feat: Adds the GFX Defaults table to the config and removes the old single GFX Setups Name from the config. Also refactors blueprints to have an enum for common config IDs --- src/tv2-common/actions/executeAction.ts | 10 +-- src/tv2-common/blueprintConfig.ts | 6 ++ src/tv2-common/showstyle/config-manifests.ts | 82 ++++++++++++++++---- src/tv2_afvd_showstyle/__tests__/configs.ts | 3 +- src/tv2_afvd_showstyle/config-manifests.ts | 20 +++-- src/tv2_afvd_showstyle/helpers/config.ts | 2 + 6 files changed, 88 insertions(+), 35 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 945a5db5..6312797d 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -251,10 +251,7 @@ export async function executeAction< await executeActionCommentatorSelectDVE(context, settings, actionId, userData as ActionCommentatorSelectDVE) break case AdlibActionType.COMMENTATOR_SELECT_SERVER: - await executeActionCommentatorSelectServer( - context, - settings - ) + await executeActionCommentatorSelectServer(context, settings) break case AdlibActionType.COMMENTATOR_SELECT_FULL: await executeActionCommentatorSelectFull(context, settings, actionId, userData as ActionCommentatorSelectFull) @@ -1738,10 +1735,7 @@ async function findMediaPlayerSessions( async function executeActionCommentatorSelectServer< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase ->( - context: ITV2ActionExecutionContext, - settings: ActionExecutionSettings -) { +>(context: ITV2ActionExecutionContext, settings: ActionExecutionSettings) { const data = await findDataStore(context, [ settings.SelectedAdlibs.SourceLayer.Server, settings.SelectedAdlibs.SourceLayer.VO diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index b988457b..dfe25e83 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -39,6 +39,12 @@ export interface TableConfigItemGfxShowMapping { Schema: string[] } +export interface TableConfigItemGfxDefaults { + GfxSetup: string + DefaultSchema: string[] + DefaultDesign: string[] +} + export interface TableConfigItemAdLibTransitions { Transition: string } diff --git a/src/tv2-common/showstyle/config-manifests.ts b/src/tv2-common/showstyle/config-manifests.ts index 12aab46f..f055a835 100644 --- a/src/tv2-common/showstyle/config-manifests.ts +++ b/src/tv2-common/showstyle/config-manifests.ts @@ -1,11 +1,21 @@ import { ConfigManifestEntry, ConfigManifestEntryTable, ConfigManifestEntryType } from 'blueprints-integration' -export const GRAPHICS_SETUPS_TABLE_ID = 'GfxSetups' -export const GRAPHICS_SETUPS_NAME_COLUMN_ID = 'Name' +export enum CommonConfigId { + GRAPHICS_SETUPS_TABLE_ID = 'GfxSetups', + GRAPHICS_SETUPS_NAME_COLUMN_ID = 'Name', + GFX_DEFAULTS_TABLE_ID = 'GfxDefaults', + DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID = 'SelectedGfxSetupName', + DEFAULTS_SCHEMA_COLUMN_ID = 'DefaultSkema', + DEFAULTS_DESIGN_COLUMN_ID = 'DefaultDesign', + GFX_SHOW_MAPPING_TABLE_ID = 'GfxShowMapping', + GFX_SHOW_MAPPING_DESIGN_COLUMN_ID = 'Design', + GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID = 'GfxSetup', + GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID = 'Schema' +} export const getGfxSetupsEntries = (columns: ConfigManifestEntryTable['columns']): ConfigManifestEntry[] => [ { - id: GRAPHICS_SETUPS_TABLE_ID, + id: CommonConfigId.GRAPHICS_SETUPS_TABLE_ID, name: 'GFX Setups', description: 'Possible GFX setups', type: ConfigManifestEntryType.TABLE, @@ -13,7 +23,7 @@ export const getGfxSetupsEntries = (columns: ConfigManifestEntryTable['columns'] defaultVal: [], columns: [ { - id: GRAPHICS_SETUPS_NAME_COLUMN_ID, + id: CommonConfigId.GRAPHICS_SETUPS_NAME_COLUMN_ID, name: 'Name', description: 'The code as it will appear in iNews', type: ConfigManifestEntryType.STRING, @@ -34,16 +44,58 @@ export const getGfxSetupsEntries = (columns: ConfigManifestEntryTable['columns'] ...columns ], hint: '' - }, - { - id: 'SelectedGfxSetupName', - name: 'GFX Setup name', - description: 'Name of the GFX Setup that should be used', - type: ConfigManifestEntryType.SELECT_FROM_COLUMN, - tableId: GRAPHICS_SETUPS_TABLE_ID, - columnId: GRAPHICS_SETUPS_NAME_COLUMN_ID, - multiple: false, - required: false, - defaultVal: '' } ] + +export const getGfxDefaults: ConfigManifestEntry = { + id: CommonConfigId.GFX_DEFAULTS_TABLE_ID, + name: 'GFX Defaults', + description: 'The possible defaults available for the GFX setup', + type: ConfigManifestEntryType.TABLE, + required: false, + defaultVal: [], + columns: [ + { + id: CommonConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, + name: 'GFX Setup', + rank: 0, + description: 'Name of the GFX Setup', + type: ConfigManifestEntryType.SELECT_FROM_COLUMN, + tableId: CommonConfigId.GRAPHICS_SETUPS_TABLE_ID, + columnId: CommonConfigId.GRAPHICS_SETUPS_NAME_COLUMN_ID, + multiple: false, + required: true, + defaultVal: '' + }, + { + id: CommonConfigId.DEFAULTS_SCHEMA_COLUMN_ID, + name: 'Default Skema', + rank: 1, + description: 'The Skema options based on the GFX Setup', + type: ConfigManifestEntryType.SELECT_PICKED_FROM_COLUMN, + toTableId: CommonConfigId.GFX_DEFAULTS_TABLE_ID, + toColumnId: CommonConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, + fromTableId: CommonConfigId.GFX_SHOW_MAPPING_TABLE_ID, + fromColumnId: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, + compareId: CommonConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID, + multiple: false, + required: false, + defaultVal: '' + }, + { + id: CommonConfigId.DEFAULTS_DESIGN_COLUMN_ID, + name: 'Default Design', + rank: 2, + description: 'The Design options based on the Default Skema', + type: ConfigManifestEntryType.SELECT_PICKED_FROM_COLUMN, + toTableId: CommonConfigId.GFX_DEFAULTS_TABLE_ID, + toColumnId: CommonConfigId.DEFAULTS_SCHEMA_COLUMN_ID, + fromTableId: CommonConfigId.GFX_SHOW_MAPPING_TABLE_ID, + fromColumnId: CommonConfigId.GFX_SHOW_MAPPING_DESIGN_COLUMN_ID, + compareId: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, + multiple: false, + required: false, + defaultVal: '' + } + ] +} diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index c47d368f..4cc5f2fa 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -272,7 +272,8 @@ export const defaultShowStyleConfig: ShowStyleConfig = { Transitions: [{ Transition: '1' }, { Transition: '2' }], ShowstyleTransition: 'CUT', GfxSchemaTemplates: [], - GfxShowMapping: [] + GfxShowMapping: [], + GfxDefaults: [] } export const EMPTY_SOURCE_CONFIG = { diff --git a/src/tv2_afvd_showstyle/config-manifests.ts b/src/tv2_afvd_showstyle/config-manifests.ts index 52f054a5..3f9e408e 100644 --- a/src/tv2_afvd_showstyle/config-manifests.ts +++ b/src/tv2_afvd_showstyle/config-manifests.ts @@ -1,10 +1,5 @@ import { ConfigManifestEntry, ConfigManifestEntryType, TSR } from 'blueprints-integration' -import { - DEFAULT_GRAPHICS, - getGfxSetupsEntries, - GRAPHICS_SETUPS_NAME_COLUMN_ID, - GRAPHICS_SETUPS_TABLE_ID -} from 'tv2-common' +import { CommonConfigId, DEFAULT_GRAPHICS, getGfxDefaults, getGfxSetupsEntries } from 'tv2-common' export const dveStylesManifest: ConfigManifestEntry = { id: 'DVEStyles', @@ -180,6 +175,8 @@ const gfxSetups = getGfxSetupsEntries([ } ]) +const gfxDefaults = getGfxDefaults + const DESIGN_TABLE_ID = 'GfxDesignTemplates' const DESIGN_NAME_COLUMN_ID = 'INewsName' @@ -275,7 +272,7 @@ export const gfxShowMapping: ConfigManifestEntry = { defaultVal: [], columns: [ { - id: 'Design', + id: CommonConfigId.GFX_SHOW_MAPPING_DESIGN_COLUMN_ID, name: 'Design', rank: 0, description: 'Name of the Design from the GFX Design table', @@ -287,19 +284,19 @@ export const gfxShowMapping: ConfigManifestEntry = { defaultVal: '' }, { - id: 'GfxSetup', + id: CommonConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID, name: 'GFX Setup', rank: 1, description: 'Names of the GFX Setups', type: ConfigManifestEntryType.SELECT_FROM_COLUMN, - tableId: GRAPHICS_SETUPS_TABLE_ID, - columnId: GRAPHICS_SETUPS_NAME_COLUMN_ID, + tableId: CommonConfigId.GRAPHICS_SETUPS_TABLE_ID, + columnId: CommonConfigId.GRAPHICS_SETUPS_NAME_COLUMN_ID, multiple: true, required: false, defaultVal: [] }, { - id: 'Schema', + id: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, name: 'GFX Skema Templates', rank: 2, description: 'Names of the Skemas', @@ -417,6 +414,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ ...gfxSetups, ...gfxSchemaTemplates, gfxShowMapping, + gfxDefaults, { /* Wipes Config diff --git a/src/tv2_afvd_showstyle/helpers/config.ts b/src/tv2_afvd_showstyle/helpers/config.ts index 586f9bf0..ee93f424 100644 --- a/src/tv2_afvd_showstyle/helpers/config.ts +++ b/src/tv2_afvd_showstyle/helpers/config.ts @@ -2,6 +2,7 @@ import { IBlueprintConfig, ICommonContext, IShowStyleContext, TableConfigItemVal import { findGfxSetup, TableConfigGfxSetup, + TableConfigItemGfxDefaults, TableConfigItemGfxShowMapping, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' @@ -23,6 +24,7 @@ export interface ShowStyleConfig extends TV2ShowstyleBlueprintConfigBase { SelectedGfxSetupName: string GfxSetups: GalleryTableConfigGfxSetup[] GfxShowMapping: TableConfigItemGfxShowMapping[] + GfxDefaults: TableConfigItemGfxDefaults[] } export function parseConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { From 8c9a0efc923925468733bb3afb515221bc84c091 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 14 Mar 2023 09:16:24 +0100 Subject: [PATCH 49/86] chore: bump blueprints-integration some linting happened too - where was the pre-commit hook before? --- package.json | 2 +- src/tv2-common/videoSwitchers/TriCaster.ts | 30 ++++++++++++---------- src/tv2-common/videoSwitchers/types.ts | 2 +- yarn.lock | 18 ++++++------- 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 1d996e8a..0888e96f 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "webpack-cli": "^3.1.2" }, "dependencies": { - "@sofie-automation/blueprints-integration": "npm:@tv2media/blueprints-integration@46.2.0", + "@sofie-automation/blueprints-integration": "npm:@tv2media/blueprints-integration@46.2.1", "underscore": "^1.12.1", "ts-mockito": "^2.6.1" }, diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index d59aa2bf..84909bab 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -12,10 +12,10 @@ import { MixEffectProps, SpecialInput, SwitcherType, + TemporalPriority, TIMELINE_OBJECT_DEFAULTS, TimelineObjectProps, - TransitionStyle, - TemporalPriority + TransitionStyle } from './types' import { VideoSwitcherBase } from './VideoSwitcher' @@ -216,19 +216,21 @@ export class TriCaster extends VideoSwitcherBase { } public getDveTimelineObjects(dveProps: DveProps): TSR.TimelineObjTriCasterME[] { - return [{ - ...this.getBaseProperties(dveProps, SwitcherDveLLayer.DveBoxes), - content: { - deviceType: TSR.DeviceType.TRICASTER, - type: TSR.TimelineContentTypeTriCaster.ME, - me: literal({ - transitionEffect: 7, - layers: this.generateDveBoxLayers(dveProps.content.boxes), - keyers: this.generateOverlayKeyer(dveProps.content.artFillSource) - }), - temporalPriority: TemporalPriority.DVE + return [ + { + ...this.getBaseProperties(dveProps, SwitcherDveLLayer.DveBoxes), + content: { + deviceType: TSR.DeviceType.TRICASTER, + type: TSR.TimelineContentTypeTriCaster.ME, + me: literal({ + transitionEffect: 7, + layers: this.generateDveBoxLayers(dveProps.content.boxes), + keyers: this.generateOverlayKeyer(dveProps.content.artFillSource) + }), + temporalPriority: TemporalPriority.DVE + } } - }] + ] } private generateDveBoxLayers(boxes: any[]): Partial> { diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index e8f9876c..da17ec10 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -33,7 +33,7 @@ export enum TransitionStyle { export enum TemporalPriority { AUX_MIX_MINUS_OVERRIDE = -1, // to make the overriding timelineobjects act before the cut on an M/E DEFAULT = 0, // the default (does not have to be explicitly set) - DVE = 1, // to place DVE commands afer regular M/E and AUX commands (ATEM integration does that by default) + DVE = 1 // to place DVE commands afer regular M/E and AUX commands (ATEM integration does that by default) } export enum SwitcherLLayer {} diff --git a/yarn.lock b/yarn.lock index 51fa795f..1eec4076 100644 --- a/yarn.lock +++ b/yarn.lock @@ -560,13 +560,13 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@sofie-automation/blueprints-integration@npm:@tv2media/blueprints-integration@46.2.0": - version "46.2.0" - resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-46.2.0.tgz#ff2cf16e6350510b8083e7b2781a17d1b1141c4d" - integrity sha512-hWKDVEQo1stlMNtxkumEy+PwM99ZAffBWkgSzBMJyIneb5pR/Dkm/3vl5f3LHWnFVZGuwISq5LvpPkNEdv+Nvg== +"@sofie-automation/blueprints-integration@npm:@tv2media/blueprints-integration@46.2.1": + version "46.2.1" + resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-46.2.1.tgz#adfa9818481546cb8b472a35835277f020fc20d5" + integrity sha512-3bqG/XVHWoxSJ20wGADT3Z1wIc3i5O5ZtN0JYwKu8H+DzVaVOyGjZTvzSP6nzBGr3dOX1acm3q7A3fZC4tAX0Q== dependencies: "@sofie-automation/shared-lib" "npm:@tv2media/shared-lib@46.2.0" - timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@3.3.0" + timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@3.4.0" tslib "^2.4.0" type-fest "^2.19.0" @@ -5956,10 +5956,10 @@ through@2, "through@>=2.2.7 <3": resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -"timeline-state-resolver-types@npm:@tv2media/timeline-state-resolver-types@3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-3.3.0.tgz#08e5b700d59a92855f27e80e98830307f0e50ead" - integrity sha512-2fnXgtg3H1mZwQNz1ax7kHPXhcMmp3ak7qVf8WIPysodtBXExP4LoRypv6fgOzX15og+gmgR3YYQGLrqiw14QA== +"timeline-state-resolver-types@npm:@tv2media/timeline-state-resolver-types@3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-3.4.0.tgz#179b66c64616fec2ec541fd9dd5a73517d8706fc" + integrity sha512-P174WyTAa6PVAotOJOEw8Dsqu1L3Cx/jEDmikLDLfFgRgmsYNSjtmgLzuzBY/O39iAxcqXs0ItM7QKcnX+ilwg== dependencies: tslib "^2.3.1" From 50a14c695eef54f7e52135758b2e2865a20e6809 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 14 Mar 2023 12:39:52 +0100 Subject: [PATCH 50/86] chore: bump integration version in webpack config --- config/webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/webpack.config.js b/config/webpack.config.js index 3a906fb0..03dc7248 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -30,7 +30,7 @@ module.exports = env => { // versionIntegration = versionIntegration.replace(/[^\d.]/g, '') || '0.0.0' versionTSRTypes = '1.3.0' - versionIntegration = '46.1.0' + versionIntegration = '46.2.0' const entrypoints = env.bundle ? GetEntrypointsForBundle(env.bundle) : BlueprintEntrypoints From 5f6bbe23e60100f0be04efc74bb4670b1ac35450 Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 16 Mar 2023 11:32:04 +0100 Subject: [PATCH 51/86] fix: use lowercase input names for consistency TSR uses lowercase and currently is case sensitive (probably shouldn't) this change may or may not prevent some unnecessary commands being sent --- src/tv2-common/videoSwitchers/TriCaster.ts | 2 +- src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 84909bab..5ebb41a9 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -254,7 +254,7 @@ export class TriCaster extends VideoSwitcherBase { private generateInvisibleBoxLayer(): TSR.TriCasterLayer { return { - input: 'Black', + input: 'black', positioningAndCropEnabled: true, position: { x: -3.555, diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index 45f199ce..fe9fdb6a 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -653,7 +653,7 @@ describe('TriCaster', () => { function invisibleBox(): TSR.TriCasterLayer { return { - input: 'Black', + input: 'black', positioningAndCropEnabled: true, position: { x: -3.555, From 72f980e50e4b34f11ec5edd8455f558219c6bd84 Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 16 Mar 2023 14:12:26 +0100 Subject: [PATCH 52/86] fix: SOF-1260 do not cut to full gfx on Pgm aux It was a bug due to misunderstanding of legacy hacks --- .../graphics/viz/VizPilotGraphicGenerator.ts | 21 ++----------------- src/tv2-constants/enums.ts | 1 - 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts index 94483d21..608292bd 100644 --- a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts @@ -1,7 +1,6 @@ import { GraphicsContent, TSR, WithTimeline } from 'blueprints-integration' import { assertUnreachable, - FindDSKFullGFX, getDskOnAirTimelineObjects, GetSisyfosTimelineObjForFull, IsTargetingFull, @@ -79,9 +78,8 @@ export class VizPilotGraphicGenerator extends PilotGraphicGenerator { } } - private getFullPilotTimeline() { - const fullDSK = FindDSKFullGFX(this.config) - const timelineObjects = [ + private getFullPilotTimeline(): TSR.TSRTimelineObj[] { + return [ ...this.context.videoSwitcher.getOnAirTimelineObjects({ enable: { start: this.config.studio.VizPilotGraphics.CutToMediaPlayer @@ -96,20 +94,5 @@ export class VizPilotGraphicGenerator extends PilotGraphicGenerator { ...getDskOnAirTimelineObjects(this.context, DskRole.FULLGFX), ...GetSisyfosTimelineObjForFull(this.config) ] - if (this.context.uniformConfig.mixEffects.program.auxLayer) { - timelineObjects.push( - this.context.videoSwitcher.getAuxTimelineObject({ - enable: { - start: this.config.studio.VizPilotGraphics.CutToMediaPlayer - }, - priority: 1, - layer: this.context.uniformConfig.mixEffects.program.auxLayer, - content: { - input: fullDSK.Fill - } - }) - ) - } - return timelineObjects } } diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index 75cbf932..54f279fb 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -117,7 +117,6 @@ export enum ControlClasses { LYD_ON_AIR = 'lyd_on_air', OVERRIDDEN_ON_MIX_MINUS = 'overridden_on_mix_minus', ABSTRACT_LOOKAHEAD = 'abstract_lookahead', - PLACEHOLDER = 'placeholder' } export function GetEnableClassForServer(mediaPlayerSessionId: string) { From 5a8c74b97b8835e710441bb7c714bad29baff51c Mon Sep 17 00:00:00 2001 From: Rasmus Date: Thu, 16 Mar 2023 14:17:50 +0100 Subject: [PATCH 53/86] fix: accomodates the mew table feature disableRowManipulation and now has default values upon creation --- src/tv2-common/showstyle/config-manifests.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/tv2-common/showstyle/config-manifests.ts b/src/tv2-common/showstyle/config-manifests.ts index f055a835..5173a510 100644 --- a/src/tv2-common/showstyle/config-manifests.ts +++ b/src/tv2-common/showstyle/config-manifests.ts @@ -1,4 +1,5 @@ import { ConfigManifestEntry, ConfigManifestEntryTable, ConfigManifestEntryType } from 'blueprints-integration' +import {TableConfigItemGfxDefaults} from "../blueprintConfig"; export enum CommonConfigId { GRAPHICS_SETUPS_TABLE_ID = 'GfxSetups', @@ -47,13 +48,22 @@ export const getGfxSetupsEntries = (columns: ConfigManifestEntryTable['columns'] } ] +const GFX_DEFAULT_VALUES: TableConfigItemGfxDefaults[] = [ + { + GfxSetup: '', + DefaultSchema: [''], + DefaultDesign: [''] + } +] + export const getGfxDefaults: ConfigManifestEntry = { id: CommonConfigId.GFX_DEFAULTS_TABLE_ID, name: 'GFX Defaults', description: 'The possible defaults available for the GFX setup', type: ConfigManifestEntryType.TABLE, required: false, - defaultVal: [], + defaultVal: GFX_DEFAULT_VALUES.map(gfxDefaultValue => ({ _id: '', ...gfxDefaultValue })), + disableRowManipulation: true, columns: [ { id: CommonConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, From ab26060cbeeced45ecf5e1979c23af76035a3283 Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 16 Mar 2023 20:08:42 +0100 Subject: [PATCH 54/86] fix: SOF-1260 show Default source on Pgm in studio baseline --- src/tv2_afvd_showstyle/getRundown.ts | 27 ++------------- src/tv2_afvd_studio/getBaseline.ts | 52 ++++++++++++++++++---------- 2 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index e2139e3f..97ee54dd 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -41,6 +41,7 @@ import { SwitcherAuxLLayer } from 'tv2-constants' import * as _ from 'underscore' +import { getMixEffectBaseline } from '../tv2_afvd_studio/getBaseline' import { CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' import { SisyfosChannel, sisyfosChannels } from '../tv2_afvd_studio/sisyfosChannels' import { GALLERY_UNIFORM_CONFIG } from '../tv2_afvd_studio/uniformConfig' @@ -506,7 +507,7 @@ function getBaseline(context: ShowStyleContext): Bluepri timelineObjects: _.compact([ ...getGraphicBaseline(context.config), // Default timeline - ...getMixEffectBaseline(context), + ...getMixEffectBaseline(context, context.config.studio.SwitcherSource.Default), context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, @@ -768,27 +769,3 @@ function getBaseline(context: ShowStyleContext): Bluepri ]) } } - -function getMixEffectBaseline(context: ShowStyleContext): TSR.TSRTimelineObj[] { - return Object.values(context.uniformConfig.mixEffects).flatMap((mixEffect) => - _.compact([ - context.videoSwitcher.getMixEffectTimelineObject({ - enable: { while: '1' }, - layer: mixEffect.mixEffectLayer, - content: { - input: context.config.studio.SwitcherSource.Default, - transition: TransitionStyle.CUT - } - }), - mixEffect.auxLayer - ? context.videoSwitcher.getAuxTimelineObject({ - enable: { while: '1' }, - layer: mixEffect.auxLayer, - content: { - input: mixEffect.input - } - }) - : undefined - ]) - ) -} diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index 5e0d2852..53229f84 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -5,7 +5,7 @@ import { IStudioContext, TSR } from 'blueprints-integration' -import { literal, SpecialInput, StudioContext, TransitionStyle } from 'tv2-common' +import { literal, ShowStyleContext, SpecialInput, StudioContext, SwitcherType, TransitionStyle } from 'tv2-common' import * as _ from 'underscore' import { SharedGraphicLLayer, SwitcherMediaPlayerLLayer } from '../tv2-constants' import { AtemSourceIndex } from '../types/atem' @@ -59,6 +59,11 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin } } + const defaultInput = + context.config.studio.SwitcherType === SwitcherType.TRICASTER + ? context.config.studio.SwitcherSource.Default + : AtemSourceIndex.MP1 + return { timelineObjects: _.compact([ literal({ @@ -77,15 +82,7 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin }), // have ATEM output default still image - context.uniformConfig.mixEffects.program.auxLayer - ? context.videoSwitcher.getAuxTimelineObject({ - enable: { while: '1' }, - layer: context.uniformConfig.mixEffects.program.auxLayer, - content: { - input: SpecialInput.ME1_PROGRAM - } - }) - : undefined, + ...getMixEffectBaseline(context, defaultInput), context.uniformConfig.switcherLLayers.nextAux ? context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, @@ -95,14 +92,6 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin } }) : undefined, - context.videoSwitcher.getMixEffectTimelineObject({ - enable: { while: '1' }, - layer: context.uniformConfig.mixEffects.program.mixEffectLayer, - content: { - input: AtemSourceIndex.MP1, - transition: TransitionStyle.CUT - } - }), literal({ id: '', enable: { while: '1' }, @@ -135,3 +124,30 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin ]) } } + +export function getMixEffectBaseline( + context: StudioContext | ShowStyleContext, + input: number | SpecialInput +): TSR.TSRTimelineObj[] { + return Object.values(context.uniformConfig.mixEffects).flatMap((mixEffect) => + _.compact([ + context.videoSwitcher.getMixEffectTimelineObject({ + enable: { while: '1' }, + layer: mixEffect.mixEffectLayer, + content: { + input, + transition: TransitionStyle.CUT + } + }), + mixEffect.auxLayer + ? context.videoSwitcher.getAuxTimelineObject({ + enable: { while: '1' }, + layer: mixEffect.auxLayer, + content: { + input: mixEffect.input + } + }) + : undefined + ]) + ) +} From a1b4fb16e5b0fc15130302815c6888a52680f258 Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 16 Mar 2023 20:28:27 +0100 Subject: [PATCH 55/86] fix: SOF-1260 make jingles cut to jingle fill when fully opaque before, there was a slight risk of showing the default source underneath when comands would not execute in a timely manner --- src/tv2-common/actions/executeAction.ts | 19 ++--- src/tv2-common/blueprintConfig.ts | 4 +- src/tv2-common/content/dve.ts | 6 +- src/tv2-common/content/jingle.ts | 69 +++++++++++++------ src/tv2-common/content/server.ts | 2 +- src/tv2-common/cues/ekstern.ts | 4 +- src/tv2-common/helpers/dsk.ts | 16 ++--- .../caspar/htmlPilotGraphicGenerator.ts | 8 +-- .../graphics/viz/VizPilotGraphicGenerator.ts | 2 +- src/tv2-common/helpers/rundownAdLibActions.ts | 28 +++----- src/tv2-common/jinglePartProperties.ts | 8 +-- src/tv2-common/parts/effekt.ts | 12 ++++ .../videoSwitchers/VideoSwitcher.ts | 8 +++ src/tv2-common/videoSwitchers/types.ts | 11 +++ src/tv2-constants/enums.ts | 2 +- src/tv2_afvd_showstyle/getRundown.ts | 8 +-- src/tv2_afvd_showstyle/getSegment.ts | 2 +- .../helpers/pieces/jingle.ts | 30 ++------ src/tv2_afvd_showstyle/parts/evs.ts | 2 +- src/tv2_afvd_showstyle/parts/kam.ts | 10 +-- .../__tests__/graphics.spec.ts | 4 +- .../cues/OfftubeJingle.ts | 28 ++------ src/tv2_offtube_showstyle/getSegment.ts | 2 +- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 10 +-- 24 files changed, 149 insertions(+), 146 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index ec9f46ee..87afa4cd 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -51,6 +51,7 @@ import { ServerSelectMode, ShowStyleContext, SisyfosPersistMetaData, + TableConfigItemBreaker, TimelineBlueprintExt, TransitionStyle, TV2AdlibAction, @@ -156,10 +157,7 @@ export interface ActionExecutionSettings< createJingleContent: ( context: ShowStyleContext, file: string, - alphaAtStart: number, - loadFirstFrame: boolean, - duration: number, - alphaAtEnd: number + breakerConfig: TableConfigItemBreaker ) => WithTimeline serverActionSettings: ServerActionSettings } @@ -940,14 +938,7 @@ async function executeActionSelectJingle< const props = GetJinglePartPropertiesFromTableValue(jingle) - const pieceContent = settings.createJingleContent( - context, - file, - jingle.StartAlpha, - jingle.LoadFirstFrame, - jingle.Duration, - jingle.EndAlpha - ) + const pieceContent = settings.createJingleContent(context, file, jingle) const piece: IBlueprintPiece = { externalId: `${externalId}-JINGLE`, @@ -1041,7 +1032,7 @@ async function executeActionCutToCamera< tags: [GetTagForKam(userData.sourceDefinition)], content: { timelineObjects: [ - ...context.videoSwitcher.getOnAirTimelineObjects({ + ...context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ priority: 1, content: { input: sourceInfoCam.port, @@ -1172,7 +1163,7 @@ async function executeActionCutToRemote< tags: [GetTagForLive(userData.sourceDefinition)], content: { timelineObjects: _.compact([ - ...context.videoSwitcher.getOnAirTimelineObjects({ + ...context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ enable: { while: '1' }, priority: 1, content: { diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 12561cab..36e67afd 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -9,7 +9,7 @@ import { export type MediaPlayerConfig = Array<{ id: string; val: string }> -export interface TableConfigItemBreakers { +export interface TableConfigItemBreaker { BreakerName: string ClipName: string Duration: number @@ -161,7 +161,7 @@ export interface TV2StudioBlueprintConfigBase( context: ShowStyleContext, file: string, - alphaAtStart: number, - loadFirstFrame: boolean, - duration: number, - alphaAtEnd: number, + breakerConfig: TableConfigItemBreaker, layers: JingleLayers ) { const { config } = context const fileName = joinAssetToFolder(config.studio.JingleFolder, file) - const jingleDSK = FindDSKJingle(config) + const jingleDsk = findDskJingle(config) return literal>({ - ...CreateJingleExpectedMedia(config, file, alphaAtStart, duration, alphaAtEnd), + ...createJingleExpectedMedia(config, file, breakerConfig), timelineObjects: literal([ - CreateJingleCasparTimelineObject(fileName, loadFirstFrame, layers), - - ...getDskOnAirTimelineObjects(context, DskRole.JINGLE, { start: Number(config.studio.CasparPrerollDuration) }), + CreateJingleCasparTimelineObject(fileName, breakerConfig.LoadFirstFrame, layers), + ...context.videoSwitcher.getOnAirTimelineObjects({ + enable: getBreakerMixEffectCutEnable(breakerConfig, config.studio.CasparPrerollDuration), + priority: 1, + content: { + input: jingleDsk.Fill, + transition: TransitionStyle.CUT + } + }), + ...getDskOnAirTimelineObjects(context, DskRole.JINGLE, { start: config.studio.CasparPrerollDuration }), // @todo: this is a Qbox-only feature, should be refactored at some point not to use ATEM object directly ...(context.uniformConfig.switcherLLayers.jingleNextMixEffect @@ -89,12 +102,12 @@ export function CreateJingleContentBase< onAir: false, mixEffectKeyType: 0, flyEnabled: false, - fillSource: jingleDSK.Fill, - cutSource: jingleDSK.Clip, + fillSource: jingleDsk.Fill, + cutSource: jingleDsk.Clip, maskEnabled: false, lumaSettings: { - clip: Number(jingleDSK.Clip) * 10, // input is percents (0-100), atem uses 1-000 - gain: Number(jingleDSK.Gain) * 10 // input is percents (0-100), atem uses 1-000 + clip: jingleDsk.Clip * 10, // input is percents (0-100), atem uses 1-000 + gain: jingleDsk.Gain * 10 // input is percents (0-100), atem uses 1-000 } } ] @@ -155,3 +168,15 @@ function CreateJingleCasparTimelineObject( } } } + +export function getBreakerMixEffectCutEnable( + breakerConfig: TableConfigItemBreaker, + casparPrerollDuration: number +): TSR.TSRTimelineObj['enable'] { + return { + start: getTimeFromFrames(breakerConfig.StartAlpha) + casparPrerollDuration, + duration: + getTimeFromFrames(breakerConfig.Duration - breakerConfig.StartAlpha - breakerConfig.EndAlpha) + + casparPrerollDuration + } +} diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 325e843f..75d66fdf 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -125,7 +125,7 @@ export function CutToServer( ): TimelineBlueprintExt[] { return [ EnableServer(mediaPlayerSessionId), - ...context.videoSwitcher.getOnAirTimelineObjects({ + ...context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ enable: { start: context.config.studio.CasparPrerollDuration }, diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index e4efd72c..cb5d86a1 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -68,7 +68,7 @@ export function EvaluateEksternBase< studioLabel: '', switcherInput, timelineObjects: literal([ - ...context.videoSwitcher.getOnAirTimelineObjects({ + ...context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ priority: 1, content: { input: switcherInput, @@ -106,7 +106,7 @@ export function EvaluateEksternBase< studioLabel: '', switcherInput, timelineObjects: literal([ - ...context.videoSwitcher.getOnAirTimelineObjects({ + ...context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ priority: 1, content: { input: switcherInput, diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index 60046e62..e432f956 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -12,19 +12,19 @@ import { ATEMModel } from '../../types/atem' import { TV2BlueprintConfigBase, TV2ShowStyleConfig, TV2StudioConfigBase } from '../blueprintConfig' import { TableConfigItemDSK } from '../types' -export function FindDSKFullGFX(config: TV2ShowStyleConfig): TableConfigItemDSK { - return FindDSKWithRoles(config, [DskRole.FULLGFX]) +export function findDskFullGfx(config: TV2ShowStyleConfig): TableConfigItemDSK { + return findDskWithRoles(config, [DskRole.FULLGFX]) } -export function FindDSKOverlayGFX(config: TV2ShowStyleConfig): TableConfigItemDSK { - return FindDSKWithRoles(config, [DskRole.OVERLAYGFX]) +export function findDskOverlayGfx(config: TV2ShowStyleConfig): TableConfigItemDSK { + return findDskWithRoles(config, [DskRole.OVERLAYGFX]) } -export function FindDSKJingle(config: TV2ShowStyleConfig): TableConfigItemDSK { - return FindDSKWithRoles(config, [DskRole.JINGLE]) +export function findDskJingle(config: TV2ShowStyleConfig): TableConfigItemDSK { + return findDskWithRoles(config, [DskRole.JINGLE]) } -function FindDSKWithRoles(config: TV2ShowStyleConfig, roles: DskRole[]): TableConfigItemDSK { +function findDskWithRoles(config: TV2ShowStyleConfig, roles: DskRole[]): TableConfigItemDSK { return config.dsk.find((dsk) => dsk.Roles?.some((role) => roles.includes(role))) ?? config.dsk[0] } @@ -46,7 +46,7 @@ export function getDskOnAirTimelineObjects( dskRole: DskRole, enable?: TSR.TSRTimelineObj['enable'] ): TSR.TSRTimelineObj[] { - const dskConf = FindDSKWithRoles(context.config, [dskRole]) + const dskConf = findDskWithRoles(context.config, [dskRole]) enable = enable ?? { start: 0 } return [ context.videoSwitcher.getDskTimelineObject({ diff --git a/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts index 24e6469e..2d2b46b7 100644 --- a/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/caspar/htmlPilotGraphicGenerator.ts @@ -1,6 +1,6 @@ import { GraphicsContent, TSR, WithTimeline } from 'blueprints-integration' import { - FindDSKFullGFX, + findDskFullGfx, getDskOnAirTimelineObjects, getHtmlTemplateName, GetSisyfosTimelineObjForFull, @@ -90,15 +90,15 @@ export class HtmlPilotGraphicGenerator extends PilotGraphicGenerator { } protected getFullPilotTimeline(): TSR.TSRTimelineObj[] { - const fullDSK = FindDSKFullGFX(this.config) + const fullDsk = findDskFullGfx(this.config) return [ - ...this.context.videoSwitcher.getOnAirTimelineObjects({ + ...this.context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ enable: { start: Number(this.config.studio.CasparPrerollDuration) }, priority: 1, content: { - input: fullDSK.Fill, + input: fullDsk.Fill, transition: TransitionStyle.WIPE_FOR_GFX, transitionDuration: 20 } diff --git a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts index 608292bd..15e49115 100644 --- a/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/viz/VizPilotGraphicGenerator.ts @@ -80,7 +80,7 @@ export class VizPilotGraphicGenerator extends PilotGraphicGenerator { private getFullPilotTimeline(): TSR.TSRTimelineObj[] { return [ - ...this.context.videoSwitcher.getOnAirTimelineObjects({ + ...this.context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ enable: { start: this.config.studio.VizPilotGraphics.CutToMediaPlayer }, diff --git a/src/tv2-common/helpers/rundownAdLibActions.ts b/src/tv2-common/helpers/rundownAdLibActions.ts index 0da6c1c2..ba8906e2 100644 --- a/src/tv2-common/helpers/rundownAdLibActions.ts +++ b/src/tv2-common/helpers/rundownAdLibActions.ts @@ -12,17 +12,15 @@ import { TV2StudioConfigBase } from 'tv2-common' import { AdlibActionType, AdlibTags, SharedOutputLayer, SharedSourceLayer } from 'tv2-constants' -import { TV2ShowStyleConfig } from '../blueprintConfig' -import { CreateJingleExpectedMedia } from '../content' +import { TableConfigItemBreaker, TV2ShowStyleConfig } from '../blueprintConfig' +import { createJingleExpectedMedia } from '../content' import { t } from './translation' interface TransitionValues { rank: number label: string jingle: string - alphaAtStart?: number - duration?: number - alphaAtEnd?: number + breakerConfig?: TableConfigItemBreaker } export function GetTransitionAdLibActions< @@ -58,13 +56,8 @@ function createActionsForTransition( const transitionValues: TransitionValues = { rank, label: transition, - jingle: jingleConfig?.ClipName ?? transition - } - - if (jingleConfig) { - transitionValues.alphaAtStart = jingleConfig.StartAlpha - transitionValues.duration = jingleConfig.Duration - transitionValues.alphaAtEnd = jingleConfig.EndAlpha + jingle: jingleConfig?.ClipName ?? transition, + breakerConfig: jingleConfig } const variant: ActionTakeWithTransitionVariant = ParseTransitionString(transition) @@ -154,15 +147,10 @@ function makeTransitionAction( content: /^MIX ?\d+$/i.test(transitionValues.label) || /^CUT$/i.test(transitionValues.label) || - /^DIP ?\d+$/i.test(transitionValues.label) + /^DIP ?\d+$/i.test(transitionValues.label) || + !transitionValues.breakerConfig ? {} - : CreateJingleExpectedMedia( - config, - transitionValues.jingle, - transitionValues.alphaAtStart ?? 0, - transitionValues.duration ?? 0, - transitionValues.alphaAtEnd ?? 0 - ) + : createJingleExpectedMedia(config, transitionValues.jingle, transitionValues.breakerConfig) } } } diff --git a/src/tv2-common/jinglePartProperties.ts b/src/tv2-common/jinglePartProperties.ts index b886c5e4..924d7798 100644 --- a/src/tv2-common/jinglePartProperties.ts +++ b/src/tv2-common/jinglePartProperties.ts @@ -1,6 +1,6 @@ import { IBlueprintPart } from 'blueprints-integration' import { CueType } from 'tv2-constants' -import { TableConfigItemBreakers } from './blueprintConfig' +import { TableConfigItemBreaker } from './blueprintConfig' import { getTimeFromFrames } from './frameTime' import { CueDefinitionJingle, PartDefinition } from './inewsConversion' import { ShowStyleContext } from './showstyle' @@ -27,10 +27,10 @@ export function GetJinglePartProperties( } export function GetJinglePartPropertiesFromTableValue( - realBreaker: TableConfigItemBreakers + realBreaker: TableConfigItemBreaker ): Pick { - const expectedDuration = Math.max(0, getTimeFromFrames(Number(realBreaker.Duration) - Number(realBreaker.StartAlpha))) - const autoNextOverlap = Math.min(expectedDuration, getTimeFromFrames(Number(realBreaker.EndAlpha))) + const expectedDuration = Math.max(0, getTimeFromFrames(realBreaker.Duration - realBreaker.StartAlpha)) + const autoNextOverlap = Math.min(expectedDuration, getTimeFromFrames(realBreaker.EndAlpha)) return { expectedDuration, autoNextOverlap, diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index 528ca6fe..d680f0ee 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -11,6 +11,8 @@ import { import { ActionTakeWithTransitionVariantDip, ActionTakeWithTransitionVariantMix, + findDskJingle, + getBreakerMixEffectCutEnable, getDskOnAirTimelineObjects, GetTagForTransition, getTimeFromFrames, @@ -108,6 +110,8 @@ export function CreateEffektForPartInner< const fileName = joinAssetToFolder(context.config.studio.JingleFolder, file) + const jingleDsk = findDskJingle(context.config) + pieces.push({ externalId, name: label, @@ -146,6 +150,14 @@ export function CreateEffektForPartInner< file: fileName } }), + ...context.videoSwitcher.getOnAirTimelineObjects({ + enable: getBreakerMixEffectCutEnable(effektConfig, context.config.studio.CasparPrerollDuration), + priority: 1, + content: { + input: jingleDsk.Fill, + transition: TransitionStyle.CUT + } + }), ...getDskOnAirTimelineObjects(context, DskRole.JINGLE, { start: context.config.studio.CasparPrerollDuration }), diff --git a/src/tv2-common/videoSwitchers/VideoSwitcher.ts b/src/tv2-common/videoSwitchers/VideoSwitcher.ts index 0dddd256..cab4fdb7 100644 --- a/src/tv2-common/videoSwitchers/VideoSwitcher.ts +++ b/src/tv2-common/videoSwitchers/VideoSwitcher.ts @@ -42,6 +42,7 @@ export abstract class VideoSwitcherBase implements VideoSwitcher { this.core = core this.uniformConfig = uniformConfig } + public getOnAirTimelineObjects(properties: OnAirMixEffectProps): TSR.TSRTimelineObj[] { const result: TSR.TSRTimelineObj[] = [] const primaryId = properties.id ?? this.core.getHashId(this.uniformConfig.switcherLLayers.primaryMixEffect, true) @@ -61,6 +62,12 @@ export abstract class VideoSwitcherBase implements VideoSwitcher { }) ) } + return result + } + + public getOnAirTimelineObjectsWithLookahead(properties: OnAirMixEffectProps): TSR.TSRTimelineObj[] { + const result: TSR.TSRTimelineObj[] = this.getOnAirTimelineObjects(properties) + const primaryId = result[0].id if (this.uniformConfig.switcherLLayers.nextPreviewMixEffect && properties.content.input) { result.push( this.getMixEffectTimelineObject({ @@ -84,6 +91,7 @@ export abstract class VideoSwitcherBase implements VideoSwitcher { } return result } + public abstract updateAuxInput( timelineObject: TimelineObjectCoreExt, input: number | SpecialInput diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index da17ec10..d5d3fa6c 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -109,7 +109,18 @@ export interface DveProps extends TimelineObjectProps { export interface VideoSwitcher { isMixEffect(timelineObject: TimelineObjectCoreExt): boolean getMixEffectTimelineObject(properties: MixEffectProps): TSR.TSRTimelineObj + + /** + * Returns timeline objects that cut (or transition) to a given input on Program and Clean M/Es + * @param properties OnAirMixEffectProps + */ getOnAirTimelineObjects(properties: OnAirMixEffectProps): TSR.TSRTimelineObj[] + /** + * Returns timeline objects that cut (or transition) to a given input on Program and Clean M/Es + * and objects letting lookahead logic show given input as Next + * @param properties OnAirMixEffectProps + */ + getOnAirTimelineObjectsWithLookahead(properties: OnAirMixEffectProps): TSR.TSRTimelineObj[] isVideoSwitcherTimelineObject(timelineObject: TimelineObjectCoreExt): boolean updateTransition( timelineObject: TimelineObjectCoreExt, diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index 54f279fb..d732370e 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -116,7 +116,7 @@ export enum ControlClasses { SERVER_ON_AIR = 'server_on_air', LYD_ON_AIR = 'lyd_on_air', OVERRIDDEN_ON_MIX_MINUS = 'overridden_on_mix_minus', - ABSTRACT_LOOKAHEAD = 'abstract_lookahead', + ABSTRACT_LOOKAHEAD = 'abstract_lookahead' } export function GetEnableClassForServer(mediaPlayerSessionId: string) { diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 97ee54dd..169a1164 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -16,7 +16,7 @@ import { createDskBaseline, CreateDSKBaselineAdlibs, CreateLYDBaseline, - FindDSKJingle, + findDskJingle, getGraphicBaseline, getMixMinusTimelineObject, GetSisyfosTimelineObjForRemote, @@ -179,7 +179,7 @@ class GlobalAdLibPiecesGenerator { content: { ignoreMediaObjectStatus: true, timelineObjects: [ - ...this.context.videoSwitcher.getOnAirTimelineObjects({ + ...this.context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ enable: { while: '1' }, priority: 1, content: { @@ -265,7 +265,7 @@ class GlobalAdLibPiecesGenerator { tags: [AdlibTags.ADLIB_QUEUE_NEXT], content: { timelineObjects: [ - ...this.context.videoSwitcher.getOnAirTimelineObjects({ + ...this.context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ enable: { while: '1' }, priority: 1, content: { @@ -501,7 +501,7 @@ class GlobalAdLibPiecesGenerator { } function getBaseline(context: ShowStyleContext): BlueprintResultBaseline { - const jingleDSK = FindDSKJingle(context.config) + const jingleDSK = findDskJingle(context.config) return { timelineObjects: _.compact([ diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index ff1acf52..5c26a32a 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -81,7 +81,7 @@ export function CreatePartContinuity( studioLabel: '', switcherInput: context.config.studio.SwitcherSource.Continuity, timelineObjects: [ - ...context.videoSwitcher.getOnAirTimelineObjects({ + ...context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ priority: 1, content: { input: context.config.studio.SwitcherSource.Continuity, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts index 616d46fb..3ae2a377 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts @@ -9,7 +9,8 @@ import { getTimeFromFrames, PartDefinition, ShowStyleContext, - t + t, + TableConfigItemBreaker } from 'tv2-common' import { AdlibActionType, AdlibTags, SharedOutputLayer, TallyTags } from 'tv2-constants' import { SourceLayer } from '../../../tv2_afvd_showstyle/layers' @@ -55,14 +56,7 @@ export function EvaluateJingle( sourceLayerId: SourceLayer.PgmJingle, outputLayerId: SharedOutputLayer.JINGLE, content: { - ...createJingleContentAFVD( - context, - file, - jingle.StartAlpha, - jingle.LoadFirstFrame, - jingle.Duration, - jingle.EndAlpha - ) + ...createJingleContentAFVD(context, file, jingle) }, tags: [AdlibTags.ADLIB_FLOW_PRODUCER], currentPieceTags: [GetTagForJingle(part.segmentExternalId, parsedCue.clip)], @@ -79,16 +73,9 @@ export function EvaluateJingle( lifespan: PieceLifespan.WithinPart, outputLayerId: SharedOutputLayer.JINGLE, sourceLayerId: SourceLayer.PgmJingle, - prerollDuration: context.config.studio.CasparPrerollDuration + getTimeFromFrames(Number(jingle.StartAlpha)), + prerollDuration: context.config.studio.CasparPrerollDuration + getTimeFromFrames(jingle.StartAlpha), tags: [!effekt ? TallyTags.JINGLE : ''], - content: createJingleContentAFVD( - context, - file, - jingle.StartAlpha, - jingle.LoadFirstFrame, - jingle.Duration, - jingle.EndAlpha - ) + content: createJingleContentAFVD(context, file, jingle) }) } } @@ -96,12 +83,9 @@ export function EvaluateJingle( export function createJingleContentAFVD( context: ShowStyleContext, file: string, - alphaAtStart: number, - loadFirstFrame: boolean, - duration: number, - alphaAtEnd: number + breakerConfig: TableConfigItemBreaker ) { - return CreateJingleContentBase(context, file, alphaAtStart, loadFirstFrame, duration, alphaAtEnd, { + return CreateJingleContentBase(context, file, breakerConfig, { Caspar: { PlayerJingle: CasparLLayer.CasparPlayerJingle }, diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index ea6b1f3a..633a1de7 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -109,7 +109,7 @@ function makeContentEVS( switcherInput, ignoreMediaObjectStatus: true, timelineObjects: literal([ - ...context.videoSwitcher.getOnAirTimelineObjects({ + ...context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ priority: 1, content: { input: switcherInput, diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index 0cb2e8d0..ee7d598c 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -12,7 +12,7 @@ import { AddScript, CreatePartInvalid, CreatePartKamBase, - FindDSKJingle, + findDskJingle, findSourceInfo, GetSisyfosTimelineObjForCamera, literal, @@ -43,7 +43,7 @@ export async function CreatePartKam( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - const jingleDSK = FindDSKJingle(context.config) + const jingleDsk = findDskJingle(context.config) if (/\bcs *\d*/i.test(partDefinition.sourceDefinition.id)) { pieces.push({ @@ -63,10 +63,10 @@ export async function CreatePartKam( fileName: '', path: '', timelineObjects: [ - ...context.videoSwitcher.getOnAirTimelineObjects({ + ...context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ priority: 1, content: { - input: jingleDSK.Fill, + input: jingleDsk.Fill, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration } @@ -102,7 +102,7 @@ export async function CreatePartKam( studioLabel: '', switcherInput, timelineObjects: [ - ...context.videoSwitcher.getOnAirTimelineObjects({ + ...context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ priority: 1, content: { input: switcherInput, diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index c0fad5ee..1fc3c1b6 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -128,7 +128,7 @@ describe('Graphics', () => { expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] - expect(timeline).toHaveLength(7) // @todo: this depends on unrelated configuration + expect(timeline).toHaveLength(6) // @todo: this depends on unrelated configuration const vizObj = timeline.find( (t) => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT @@ -300,7 +300,7 @@ describe('Graphics', () => { expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] - expect(timeline).toHaveLength(7) + expect(timeline).toHaveLength(6) const vizObj = timeline.find( (t) => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index 72c15818..f0383e25 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -11,7 +11,8 @@ import { PartDefinition, PieceMetaData, SegmentContext, - t + t, + TableConfigItemBreaker } from 'tv2-common' import { AdlibActionType, AdlibTags, SharedOutputLayer, TallyTags } from 'tv2-constants' import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' @@ -62,14 +63,7 @@ export function OfftubeEvaluateJingle( sourceLayerId: OfftubeSourceLayer.PgmJingle, outputLayerId: OfftubeOutputLayers.JINGLE, content: { - ...createJingleContentOfftube( - context, - file, - jingle.StartAlpha, - jingle.LoadFirstFrame, - jingle.Duration, - jingle.EndAlpha - ) + ...createJingleContentOfftube(context, file, jingle) }, tags: [AdlibTags.OFFTUBE_100pc_SERVER, AdlibTags.ADLIB_KOMMENTATOR], currentPieceTags: [GetTagForJingle(part.segmentExternalId, parsedCue.clip)], @@ -92,14 +86,7 @@ export function OfftubeEvaluateJingle( } }, prerollDuration: context.config.studio.CasparPrerollDuration + getTimeFromFrames(Number(jingle.StartAlpha)), - content: createJingleContentOfftube( - context, - file, - jingle.StartAlpha, - jingle.LoadFirstFrame, - jingle.Duration, - jingle.EndAlpha - ), + content: createJingleContentOfftube(context, file, jingle), tags: [ GetTagForJingle(part.segmentExternalId, parsedCue.clip), GetTagForJingleNext(part.segmentExternalId, parsedCue.clip), @@ -112,12 +99,9 @@ export function OfftubeEvaluateJingle( export function createJingleContentOfftube( context: SegmentContext, file: string, - alphaAtStart: number, - loadFirstFrame: boolean, - duration: number, - alphaAtEnd: number + breakerConfig: TableConfigItemBreaker ) { - return CreateJingleContentBase(context, file, alphaAtStart, loadFirstFrame, duration, alphaAtEnd, { + return CreateJingleContentBase(context, file, breakerConfig, { Caspar: { PlayerJingle: OfftubeCasparLLayer.CasparPlayerJingle, PlayerJinglePreload: OfftubeCasparLLayer.CasparPlayerJinglePreload diff --git a/src/tv2_offtube_showstyle/getSegment.ts b/src/tv2_offtube_showstyle/getSegment.ts index a466fc45..1b39ef3b 100644 --- a/src/tv2_offtube_showstyle/getSegment.ts +++ b/src/tv2_offtube_showstyle/getSegment.ts @@ -71,7 +71,7 @@ function CreatePartContinuity( studioLabel: '', switcherInput: context.config.studio.SwitcherSource.Continuity, timelineObjects: [ - ...context.videoSwitcher.getOnAirTimelineObjects({ + ...context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ priority: 1, content: { input: context.config.studio.SwitcherSource.Continuity, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index f104489c..06ed859e 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -12,7 +12,7 @@ import { AddScript, CreatePartInvalid, CreatePartKamBase, - FindDSKJingle, + findDskJingle, findSourceInfo, GetSisyfosTimelineObjForCamera, GetTagForKam, @@ -43,7 +43,7 @@ export async function OfftubeCreatePartKam( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - const jingleDSK = FindDSKJingle(context.config) + const jingleDsk = findDskJingle(context.config) if (/\bcs *\d*/i.test(partDefinition.sourceDefinition.id)) { pieces.push({ @@ -58,10 +58,10 @@ export async function OfftubeCreatePartKam( ignoreMediaObjectStatus: true, fileName: '', path: '', - timelineObjects: context.videoSwitcher.getOnAirTimelineObjects({ + timelineObjects: context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ priority: 1, content: { - input: jingleDSK.Fill, + input: jingleDsk.Fill, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration } @@ -95,7 +95,7 @@ export async function OfftubeCreatePartKam( studioLabel: '', switcherInput, timelineObjects: [ - ...context.videoSwitcher.getOnAirTimelineObjects({ + ...context.videoSwitcher.getOnAirTimelineObjectsWithLookahead({ priority: 1, content: { input: switcherInput, From ddeefabee06228c56feb2a327a38256f3ba859da Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 16 Mar 2023 20:34:47 +0100 Subject: [PATCH 56/86] fix: prevent dot from appearing in timeline object id this would cause an error in superfly-timeline --- src/tv2-common/pieces/telemetric.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv2-common/pieces/telemetric.ts b/src/tv2-common/pieces/telemetric.ts index 38ac4ec5..fe8f9596 100644 --- a/src/tv2-common/pieces/telemetric.ts +++ b/src/tv2-common/pieces/telemetric.ts @@ -28,7 +28,7 @@ export function createTelemetricsPieceForRobotCamera( function createTelemetricsTimelineObject(preset: number): TSR.TimelineObjTelemetrics { return literal({ - id: `telemetrics_preset_${preset}_${Math.random() * 1000}`, + id: `telemetrics_preset_${preset}_${Math.floor(Math.random() * 1000)}`, enable: { start: 0 }, From 0ce3b16fae6da5409169086b6a81475ca51f6bf3 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Mon, 20 Mar 2023 13:49:46 +0100 Subject: [PATCH 57/86] SOF-1374 Able to create ActionTriggers for Live that cuts directly to program --- src/tv2-common/actions/actionTypes.ts | 1 + src/tv2-common/actions/executeAction.ts | 64 +++++++++++-------- .../GlobalAdlibActionsGenerator.ts | 54 ++++++++++++---- .../__tests__/actions.spec.ts | 1 + src/tv2_offtube_showstyle/getRundown.ts | 1 + 5 files changed, 80 insertions(+), 41 deletions(-) diff --git a/src/tv2-common/actions/actionTypes.ts b/src/tv2-common/actions/actionTypes.ts index cf234bc1..cea269b6 100644 --- a/src/tv2-common/actions/actionTypes.ts +++ b/src/tv2-common/actions/actionTypes.ts @@ -60,6 +60,7 @@ export interface ActionCutToCamera extends ActionBase { export interface ActionCutToRemote extends ActionBase { type: AdlibActionType.CUT_TO_REMOTE + cutDirectly: boolean sourceDefinition: SourceDefinitionRemote } diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index ec9f46ee..78037033 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1014,14 +1014,6 @@ async function executeActionCutToCamera< return } - const currentPieceInstances = await context.core.getPieceInstances('current') - - const serverInCurrentPart = currentPieceInstances.some( - (p) => p.piece.sourceLayerId === settings.SourceLayers.Server || p.piece.sourceLayerId === settings.SourceLayers.VO - ) - - const currentKam = currentPieceInstances.find((p) => p.piece.sourceLayerId === settings.SourceLayers.Cam) - const camSisyfos = GetSisyfosTimelineObjForCamera(context.config, sourceInfoCam, false) const kamPiece: IBlueprintPiece = { @@ -1053,34 +1045,57 @@ async function executeActionCutToCamera< } } - if (userData.queue || serverInCurrentPart) { - await context.core.queuePart(part, [ - kamPiece, + await executePiece(context, settings, kamPiece, userData.queue, part) +} + +async function executePiece< + StudioConfig extends TV2StudioConfigBase, + ShowStyleConfig extends TV2BlueprintConfigBase +>( + context: ActionExecutionContext, + settings: ActionExecutionSettings, + pieceToExecute: IBlueprintPiece, + shouldBeQueued: boolean, + partToQueue: IBlueprintPart +) { + const currentPieceInstances = await context.core.getPieceInstances('current') + const serverInCurrentPart = currentPieceInstances.some( + (p) => p.piece.sourceLayerId === settings.SourceLayers.Server || p.piece.sourceLayerId === settings.SourceLayers.VO + ) + + const layersWithCutDirect: string[] = [settings.SourceLayers.Live, settings.SourceLayers.Cam] + const currentPiece: IBlueprintPieceInstance | undefined = currentPieceInstances.find((p) => + layersWithCutDirect.includes(p.piece.sourceLayerId) + ) + + if (shouldBeQueued || serverInCurrentPart) { + await context.core.queuePart(partToQueue, [ + pieceToExecute, ...(settings.SelectedAdlibs ? await getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, []) : []) ]) - if (serverInCurrentPart && !userData.queue) { + if (serverInCurrentPart && !shouldBeQueued) { await context.core.takeAfterExecuteAction(true) } - } else if (currentKam) { - kamPiece.externalId = currentKam.piece.externalId - kamPiece.enable = currentKam.piece.enable - const currentMetaData = currentKam.piece.metaData! - const metaData = kamPiece.metaData! + } else if (currentPiece) { + pieceToExecute.externalId = currentPiece.piece.externalId + pieceToExecute.enable = currentPiece.piece.enable + const currentMetaData = currentPiece.piece.metaData! + const metaData = pieceToExecute.metaData! metaData.sisyfosPersistMetaData!.previousPersistMetaDataForCurrentPiece = currentMetaData.sisyfosPersistMetaData await stopGraphicPiecesThatShouldEndWithPart(context, currentPieceInstances) - await context.core.updatePieceInstance(currentKam._id, kamPiece) + await context.core.updatePieceInstance(currentPiece._id, pieceToExecute) } else { const currentExternalId = await context.core .getPartInstance('current') .then((currentPartInstance) => currentPartInstance?.part.externalId) if (currentExternalId) { - kamPiece.externalId = currentExternalId + pieceToExecute.externalId = currentExternalId } await context.core.stopPiecesOnLayers([ @@ -1095,8 +1110,8 @@ async function executeActionCutToCamera< ]) await stopGraphicPiecesThatShouldEndWithPart(context, currentPieceInstances) - kamPiece.enable = { start: 'now' } - await context.core.insertPiece('current', kamPiece) + pieceToExecute.enable = { start: 'now' } + await context.core.insertPiece('current', pieceToExecute) } } @@ -1186,12 +1201,7 @@ async function executeActionCutToRemote< } } - await context.core.queuePart(part, [ - remotePiece, - ...(settings.SelectedAdlibs - ? await getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, []) - : []) - ]) + await executePiece(context, settings, remotePiece, !userData.cutDirectly, part) } async function executeActionCutSourceToBox< diff --git a/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts b/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts index 6401fffe..927a3ecd 100644 --- a/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts +++ b/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts @@ -4,6 +4,7 @@ import { ActionClearGraphics, ActionCutSourceToBox, ActionCutToCamera, + ActionCutToRemote, ActionFadeDownPersistedAudioLevels, ActionRecallLastDVE, ActionRecallLastLive, @@ -13,6 +14,7 @@ import { replaySourceName, ShowStyleContext, SourceDefinitionKam, + SourceDefinitionRemote, SourceInfo, SourceInfoToSourceDefinition, SourceInfoType, @@ -36,39 +38,40 @@ export class GlobalAdlibActionsGenerator { this.config.sources.cameras .slice(0, 5) // the first x cameras to create INP1/2/3 cam-adlibs from - .forEach((o) => { - blueprintActions.push(this.makeCutCameraAction(o, false, globalRank++)) + .forEach((camera) => { + blueprintActions.push(this.makeCutCameraAction(camera, false, globalRank++)) }) this.config.sources.cameras .slice(0, 5) // the first x cameras to create preview cam-adlibs from - .forEach((o) => { - blueprintActions.push(this.makeCutCameraAction(o, true, globalRank++)) + .forEach((camera) => { + blueprintActions.push(this.makeCutCameraAction(camera, true, globalRank++)) }) this.config.sources.cameras .slice(0, 5) // the first x cameras to dve actions from - .forEach((o) => { - blueprintActions.push(...this.makeAdlibBoxesActions(o, globalRank++)) + .forEach((camera) => { + blueprintActions.push(...this.makeAdlibBoxesActions(camera, globalRank++)) }) this.config.sources.lives .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from - .forEach((o) => { - blueprintActions.push(...this.makeAdlibBoxesActions(o, globalRank++)) + .forEach((live) => { + blueprintActions.push(...this.makeAdlibBoxesActions(live, globalRank++)) + blueprintActions.push(this.makeCutDirectLiveAction(live, globalRank++)) }) this.config.sources.feeds .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from - .forEach((o) => { - blueprintActions.push(...this.makeAdlibBoxesActions(o, globalRank++)) + .forEach((feed) => { + blueprintActions.push(...this.makeAdlibBoxesActions(feed, globalRank++)) }) - this.config.sources.replays.forEach((o) => { - if (!/EPSIO/i.test(o.id)) { - blueprintActions.push(...this.makeAdlibBoxesActionsReplay(o, globalRank++, false)) + this.config.sources.replays.forEach((replay) => { + if (!/EPSIO/i.test(replay.id)) { + blueprintActions.push(...this.makeAdlibBoxesActionsReplay(replay, globalRank++, false)) } - blueprintActions.push(...this.makeAdlibBoxesActionsReplay(o, globalRank++, true)) + blueprintActions.push(...this.makeAdlibBoxesActionsReplay(replay, globalRank++, true)) }) blueprintActions.push(this.makeRecallLastLiveAction()) @@ -113,6 +116,29 @@ export class GlobalAdlibActionsGenerator { } } + private makeCutDirectLiveAction(info: SourceInfo, rank: number): IBlueprintActionManifest { + const sourceDefinition = SourceInfoToSourceDefinition(info) as SourceDefinitionRemote + const userData: ActionCutToRemote = { + type: AdlibActionType.CUT_TO_REMOTE, + cutDirectly: true, + sourceDefinition + } + return { + externalId: generateExternalId(this.context.core, userData), + actionId: AdlibActionType.CUT_TO_REMOTE, + userData, + userDataManifest: {}, + display: { + _rank: rank, + label: t(sourceDefinition.name), + sourceLayerId: SourceLayer.PgmLive, + outputLayerId: SharedOutputLayer.PGM, + content: {}, + tags: [AdlibTags.ADLIB_CUT_DIRECT] + } + } + } + private makeRecallLastLiveAction(): IBlueprintActionManifest { const userData: ActionRecallLastLive = { type: AdlibActionType.RECALL_LAST_LIVE diff --git a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts index cf57ad22..2b3cbb65 100644 --- a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts @@ -239,6 +239,7 @@ const selectCameraAction = literal({ const selectLiveAction = literal({ type: AdlibActionType.CUT_TO_REMOTE, + cutDirectly: false, sourceDefinition: SOURCE_DEFINITION_LIVE_2 }) diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 29cf74dc..04d4a503 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -263,6 +263,7 @@ function getGlobalAdlibActionsOfftube( const sourceDefinition = SourceInfoToSourceDefinition(sourceInfo) as SourceDefinitionRemote const userData: ActionCutToRemote = { type: AdlibActionType.CUT_TO_REMOTE, + cutDirectly: false, sourceDefinition } blueprintActions.push({ From b927cd576df8aa7c311faf2c9b11c92812c7eaee Mon Sep 17 00:00:00 2001 From: ianshade Date: Mon, 20 Mar 2023 16:24:49 +0100 Subject: [PATCH 58/86] feat: SOF-1386 show Fullscreen gfx on the Clean Feed --- package.json | 2 +- src/tv2-common/blueprintConfig.ts | 1 + src/tv2-common/helpers/dsk.ts | 17 ++++++++++++++++ src/tv2-common/uniformConfig.ts | 2 ++ src/tv2-common/videoSwitchers/TriCaster.ts | 1 + src/tv2-constants/enums.ts | 3 ++- src/tv2_afvd_showstyle/__tests__/configs.ts | 3 ++- src/tv2_afvd_showstyle/getRundown.ts | 20 +++++++++++++++++-- .../__tests__/config-manifest.spec.ts | 3 ++- .../__tests__/graphics.spec.ts | 4 ++-- src/tv2_afvd_studio/config-manifests.ts | 8 ++++++++ src/tv2_afvd_studio/getBaseline.ts | 2 +- .../migrations/mappings-defaults.ts | 18 +++++++++++++++-- src/tv2_afvd_studio/uniformConfig.ts | 3 ++- .../__tests__/config-manifest.spec.ts | 3 ++- src/tv2_offtube_studio/config-manifests.ts | 8 ++++++++ 16 files changed, 85 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 0888e96f..e17ccf3b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tv2-sofie-blueprints-inews", - "version": "1.8.0", + "version": "1.8.1", "repository": "https://github.com/olzzon/tv2-sofie-blueprints-inews", "license": "MIT", "private": true, diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 36e67afd..0be2d018 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -131,6 +131,7 @@ export interface TV2StudioConfigBase { } VizPilotGraphics: { KeepAliveDuration: number + CleanFeedPrerollDuration: number PrerollDuration: number OutTransitionDuration: number CutToMediaPlayer: number diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index e432f956..7ec8856f 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -74,6 +74,23 @@ export function getDskOnAirTimelineObjects( } }) ] + : []), + ...(dskRole === DskRole.FULLGFX && context.uniformConfig.switcherLLayers.fullUskMixEffect + ? [ + context.videoSwitcher.getMixEffectTimelineObject({ + enable: { start: context.config.studio.VizPilotGraphics.CleanFeedPrerollDuration }, + priority: 1, + layer: context.uniformConfig.switcherLLayers.fullUskMixEffect, + content: { + keyers: [ + { + onAir: true, + config: dskConf + } + ] + } + }) + ] : []) ] } diff --git a/src/tv2-common/uniformConfig.ts b/src/tv2-common/uniformConfig.ts index cf1ebc68..b2804891 100644 --- a/src/tv2-common/uniformConfig.ts +++ b/src/tv2-common/uniformConfig.ts @@ -15,6 +15,8 @@ export interface UniformConfig { nextAux?: SwitcherAuxLLayer /** Optional layer to show the jingles on an USK */ jingleUskMixEffect?: SwitcherMixEffectLLayer + /** Optional layer to show Fullscreen graphics on an USK */ + fullUskMixEffect?: SwitcherMixEffectLLayer /** Optional layer to show the jingles lookahead on */ jingleNextMixEffect?: SwitcherMixEffectLLayer /** Optional layer to preview servers on Aux */ diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 5ebb41a9..9ba3ae60 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -78,6 +78,7 @@ export class TriCaster extends VideoSwitcherBase { ...(content.previewInput !== undefined && transition === 'cut' ? { previewInput: this.getInputName(content.previewInput) } : {}), + // @todo: fix transitionEffect and transitionDuration being set when not needed transitionEffect: transition, transitionDuration: this.getTransitionDuration(content.transition, content.transitionDuration), keyers: content.keyers && this.getKeyers(content.keyers) diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index d732370e..65696cc7 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -192,7 +192,8 @@ export enum AbstractLLayer { export enum SwitcherMixEffectLLayer { Program = 'me_program', Clean = 'me_clean', - CleanUSKEffect = 'clean_usk_effect', + CleanUskFull = 'clean_usk_full', + CleanUskEffect = 'clean_usk_effect', Next = 'me_next', NextJingle = 'me_next_jingle' } diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index a36f49e2..940eef81 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -135,7 +135,8 @@ export const defaultStudioConfig: StudioConfig = { PrerollDuration: 2000, OutTransitionDuration: 280, CutToMediaPlayer: 1500, - FullGraphicBackground: 36 + FullGraphicBackground: 36, + CleanFeedPrerollDuration: 320 }, HTMLGraphics: { GraphicURL: 'E:/somepath', diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 169a1164..8aae58d8 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -16,6 +16,7 @@ import { createDskBaseline, CreateDSKBaselineAdlibs, CreateLYDBaseline, + findDskFullGfx, findDskJingle, getGraphicBaseline, getMixMinusTimelineObject, @@ -501,7 +502,8 @@ class GlobalAdLibPiecesGenerator { } function getBaseline(context: ShowStyleContext): BlueprintResultBaseline { - const jingleDSK = findDskJingle(context.config) + const jingleDsk = findDskJingle(context.config) + const fullGfxDsk = findDskFullGfx(context.config) return { timelineObjects: _.compact([ @@ -573,7 +575,21 @@ function getBaseline(context: ShowStyleContext): Bluepri keyers: [ { onAir: false, - config: jingleDSK + config: jingleDsk + } + ] + } + }) + : undefined, + context.uniformConfig.switcherLLayers.fullUskMixEffect + ? context.videoSwitcher.getMixEffectTimelineObject({ + enable: { while: '1' }, + layer: context.uniformConfig.switcherLLayers.fullUskMixEffect, + content: { + keyers: [ + { + onAir: false, + config: fullGfxDsk } ] } diff --git a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts index 05ed4748..f8947a85 100644 --- a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts @@ -72,7 +72,8 @@ const blankStudioConfig: StudioConfig = { PrerollDuration: 1000, OutTransitionDuration: 1000, CutToMediaPlayer: 1000, - FullGraphicBackground: 36 + FullGraphicBackground: 36, + CleanFeedPrerollDuration: 320 }, HTMLGraphics: { GraphicURL: '', diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index 1fc3c1b6..c0fad5ee 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -128,7 +128,7 @@ describe('Graphics', () => { expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] - expect(timeline).toHaveLength(6) // @todo: this depends on unrelated configuration + expect(timeline).toHaveLength(7) // @todo: this depends on unrelated configuration const vizObj = timeline.find( (t) => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT @@ -300,7 +300,7 @@ describe('Graphics', () => { expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] - expect(timeline).toHaveLength(6) + expect(timeline).toHaveLength(7) const vizObj = timeline.find( (t) => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index b0e9ce50..33eb18ba 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -524,6 +524,14 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ required: false, defaultVal: 2000 }, + { + id: 'VizPilotGraphics.CleanFeedPrerollDuration', + name: 'Fullscreen Pilot Preroll Duration for Clean Feed', + description: 'ms of preroll before showing Pilot elements on the Clean Feed', + type: ConfigManifestEntryType.INT, + required: false, + defaultVal: 320 + }, { id: 'PreventOverlayWithFull', name: 'Prevent Overlay with Full', diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index 53229f84..4986c26b 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -59,7 +59,7 @@ export function getBaseline(coreContext: IStudioContext): BlueprintResultBaselin } } - const defaultInput = + const defaultInput: number = context.config.studio.SwitcherType === SwitcherType.TRICASTER ? context.config.studio.SwitcherSource.Default : AtemSourceIndex.MP1 diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index 9e807235..3aa43c82 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -594,7 +594,14 @@ export const MAPPINGS_ATEM = prefixLayers(AT mappingType: TSR.MappingAtemType.MixEffect, index: 3 // 3 = ME4 }, - [SwitcherMixEffectLLayer.CleanUSKEffect]: { + [SwitcherMixEffectLLayer.CleanUskFull]: { + device: TSR.DeviceType.ATEM, + deviceId: ATEM_DEVICE_ID, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingAtemType.MixEffect, + index: 3 // 3 = ME4 + }, + [SwitcherMixEffectLLayer.CleanUskEffect]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, @@ -689,7 +696,14 @@ export const MAPPINGS_TRICASTER = prefixLayers Date: Tue, 21 Mar 2023 10:14:47 +0100 Subject: [PATCH 59/86] refactor: SOF-1386 use snake case for some enums --- src/tv2-common/content/server.ts | 2 +- src/tv2-common/cues/lyd.ts | 2 +- src/tv2-common/cues/mixMinus.ts | 2 +- src/tv2-common/helpers/abPlayback.ts | 2 +- src/tv2-common/onTimelineGenerate.ts | 2 +- src/tv2-common/videoSwitchers/Atem.ts | 4 +- src/tv2-common/videoSwitchers/TriCaster.ts | 2 +- .../videoSwitchers/__tests__/Atem.spec.ts | 24 ++++---- .../__tests__/TriCaster.spec.ts | 32 +++++----- src/tv2-constants/enums.ts | 46 +++++++------- .../__tests__/actions.spec.ts | 14 ++--- .../__tests__/transitions.spec.ts | 2 +- src/tv2_afvd_showstyle/getRundown.ts | 14 ++--- .../helpers/pieces/routing.ts | 2 +- .../__tests__/graphics.spec.ts | 2 +- .../migrations/mappings-defaults.ts | 60 +++++++++---------- src/tv2_afvd_studio/uniformConfig.ts | 20 +++---- .../__tests__/actions.spec.ts | 4 +- .../cues/OfftubePgmClean.ts | 2 +- src/tv2_offtube_showstyle/getRundown.ts | 2 +- .../migrations/mappings-defaults.ts | 24 ++++---- src/tv2_offtube_studio/uniformConfig.ts | 14 ++--- 22 files changed, 139 insertions(+), 139 deletions(-) diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 75d66fdf..4f1088b5 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -148,7 +148,7 @@ export function EnableServer(mediaPlayerSessionId: string) { enable: { start: 0 }, - layer: AbstractLLayer.ServerEnablePending, + layer: AbstractLLayer.SERVER_ENABLE_PENDING, content: { deviceType: TSR.DeviceType.ABSTRACT }, diff --git a/src/tv2-common/cues/lyd.ts b/src/tv2-common/cues/lyd.ts index b0a9c5c9..0cec4474 100644 --- a/src/tv2-common/cues/lyd.ts +++ b/src/tv2-common/cues/lyd.ts @@ -185,7 +185,7 @@ export function CreateLYDBaseline(studio: string): TSR.TSRTimelineObj[] { while: `!.${ControlClasses.LYD_ON_AIR}` }, priority: 0, - layer: AbstractLLayer.AudioBedBaseline, + layer: AbstractLLayer.AUDIO_BED_BASELINE, content: { deviceType: TSR.DeviceType.ABSTRACT } diff --git a/src/tv2-common/cues/mixMinus.ts b/src/tv2-common/cues/mixMinus.ts index fd48b2a3..d40d93f2 100644 --- a/src/tv2-common/cues/mixMinus.ts +++ b/src/tv2-common/cues/mixMinus.ts @@ -55,7 +55,7 @@ export function getMixMinusTimelineObject( enable: { while: `.${ControlClasses.OVERRIDDEN_ON_MIX_MINUS}` }, - layer: SwitcherAuxLLayer.AuxVideoMixMinus, + layer: SwitcherAuxLLayer.VIDEO_MIX_MINUS, priority, temporalPriority: TemporalPriority.AUX_MIX_MINUS_OVERRIDE }) diff --git a/src/tv2-common/helpers/abPlayback.ts b/src/tv2-common/helpers/abPlayback.ts index 3fe705c0..65171737 100644 --- a/src/tv2-common/helpers/abPlayback.ts +++ b/src/tv2-common/helpers/abPlayback.ts @@ -313,7 +313,7 @@ function updateObjectsToMediaPlayer< // context.notifyUserWarning(obj) } } else if (obj.content.deviceType === TSR.DeviceType.ABSTRACT) { - if (obj.layer === AbstractLLayer.ServerEnablePending) { + if (obj.layer === AbstractLLayer.SERVER_ENABLE_PENDING) { obj.layer = AbstractLLayerServerEnable(playerId) } } else { diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index 346f899f..8614d70e 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -190,7 +190,7 @@ function processServerLookaheads( return true } - if (obj.layer === AbstractLLayer.ServerEnablePending && obj.isLookahead) { + if (obj.layer === AbstractLLayer.SERVER_ENABLE_PENDING && obj.isLookahead) { return false } diff --git a/src/tv2-common/videoSwitchers/Atem.ts b/src/tv2-common/videoSwitchers/Atem.ts index 2d589749..ba769af2 100644 --- a/src/tv2-common/videoSwitchers/Atem.ts +++ b/src/tv2-common/videoSwitchers/Atem.ts @@ -158,7 +158,7 @@ export class Atem extends VideoSwitcherBase { public getDveTimelineObjects(props: DveProps): TSR.TSRTimelineObj[] { return [ literal({ - ...this.getBaseProperties(props, SwitcherDveLLayer.DveBoxes), + ...this.getBaseProperties(props, SwitcherDveLLayer.DVE_BOXES), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRC, @@ -166,7 +166,7 @@ export class Atem extends VideoSwitcherBase { } }), literal({ - ...this.getBaseProperties(props, SwitcherDveLLayer.Dve), + ...this.getBaseProperties(props, SwitcherDveLLayer.DVE), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.SSRCPROPS, diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 9ba3ae60..222f025b 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -219,7 +219,7 @@ export class TriCaster extends VideoSwitcherBase { public getDveTimelineObjects(dveProps: DveProps): TSR.TimelineObjTriCasterME[] { return [ { - ...this.getBaseProperties(dveProps, SwitcherDveLLayer.DveBoxes), + ...this.getBaseProperties(dveProps, SwitcherDveLLayer.DVE_BOXES), content: { deviceType: TSR.DeviceType.TRICASTER, type: TSR.TimelineContentTypeTriCaster.ME, diff --git a/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts index 3ad25436..f5f6548f 100644 --- a/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts @@ -19,7 +19,7 @@ function setupAtem(studioConfigOverrides?: Partial) { describe('ATEM', () => { describe('Mix Effect', () => { const DEFAULT_ME: MixEffectProps = { - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { input: 5 } @@ -64,7 +64,7 @@ describe('ATEM', () => { const atem = setupAtem() const timelineObject = atem.getMixEffectTimelineObject(DEFAULT_ME) expect(timelineObject).toMatchObject({ - layer: prefixLayer(SwitcherMixEffectLLayer.Program) + layer: prefixLayer(SwitcherMixEffectLLayer.PROGRAM) }) }) @@ -83,7 +83,7 @@ describe('ATEM', () => { test('sets input when CUT transition provided', () => { const atem = setupAtem() const timelineObject = atem.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { input: 5, transition: TransitionStyle.CUT @@ -102,7 +102,7 @@ describe('ATEM', () => { test('sets previewInput', () => { const atem = setupAtem() const timelineObject = atem.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { previewInput: 5 } @@ -119,7 +119,7 @@ describe('ATEM', () => { test('supports MIX', () => { const atem = setupAtem() const timelineObject = atem.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { input: 5, transition: TransitionStyle.MIX, @@ -144,7 +144,7 @@ describe('ATEM', () => { test('supports WIPE', () => { const atem = setupAtem() const timelineObject = atem.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { input: 5, transition: TransitionStyle.WIPE, @@ -176,7 +176,7 @@ describe('ATEM', () => { } }) const timelineObject = atem.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { input: 5, transition: TransitionStyle.WIPE_FOR_GFX @@ -203,7 +203,7 @@ describe('ATEM', () => { test('supports DIP', () => { const atem = setupAtem() const timelineObject = atem.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { input: 5, transition: TransitionStyle.DIP, @@ -245,7 +245,7 @@ describe('ATEM', () => { } }) const timelineObject = atem.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { input: 5, transition: TransitionStyle.DIP, @@ -271,7 +271,7 @@ describe('ATEM', () => { test('supports keyers', () => { const atem = setupAtem() const timelineObject = atem.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { keyers: [ { @@ -313,7 +313,7 @@ describe('ATEM', () => { describe('Aux', () => { const DEFAULT_AUX: AuxProps = { - layer: SwitcherAuxLLayer.AuxClean, + layer: SwitcherAuxLLayer.CLEAN, content: { input: 5 } @@ -358,7 +358,7 @@ describe('ATEM', () => { const atem = setupAtem() const timelineObject = atem.getAuxTimelineObject(DEFAULT_AUX) expect(timelineObject).toMatchObject({ - layer: prefixLayer(SwitcherAuxLLayer.AuxClean) + layer: prefixLayer(SwitcherAuxLLayer.CLEAN) }) }) diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index fe9fdb6a..8a049f5f 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -32,7 +32,7 @@ function createTestee(mocks?: { describe('TriCaster', () => { describe('Mix Effect', () => { const DEFAULT_ME: MixEffectProps = { - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { input: 5 } @@ -77,7 +77,7 @@ describe('TriCaster', () => { const testee: TriCaster = createTestee() const timelineObject = testee.getMixEffectTimelineObject(DEFAULT_ME) expect(timelineObject).toMatchObject({ - layer: prefixLayer(SwitcherMixEffectLLayer.Program) + layer: prefixLayer(SwitcherMixEffectLLayer.PROGRAM) }) }) @@ -96,7 +96,7 @@ describe('TriCaster', () => { test('sets previewInput', () => { const testee: TriCaster = createTestee() const timelineObject = testee.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { previewInput: 5 } @@ -113,7 +113,7 @@ describe('TriCaster', () => { test('supports MIX', () => { const testee: TriCaster = createTestee() const timelineObject = testee.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { input: 5, transition: TransitionStyle.MIX, @@ -136,7 +136,7 @@ describe('TriCaster', () => { test('supports WIPE', () => { const testee: TriCaster = createTestee() const timelineObject = testee.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { input: 3, transition: TransitionStyle.WIPE, @@ -168,7 +168,7 @@ describe('TriCaster', () => { } as any as TV2StudioConfigBase) const testee: TriCaster = createTestee({ config: instance(config) }) const timelineObject = testee.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { input: 5, transition: TransitionStyle.WIPE_FOR_GFX @@ -190,7 +190,7 @@ describe('TriCaster', () => { test('supports DIP', () => { const testee: TriCaster = createTestee() const timelineObject = testee.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { input: 5, transition: TransitionStyle.DIP, @@ -213,7 +213,7 @@ describe('TriCaster', () => { test('supports keyers', () => { const testee: TriCaster = createTestee() const timelineObject = testee.getMixEffectTimelineObject({ - layer: SwitcherMixEffectLLayer.Program, + layer: SwitcherMixEffectLLayer.PROGRAM, content: { keyers: [ { @@ -248,7 +248,7 @@ describe('TriCaster', () => { describe('Aux', () => { const DEFAULT_AUX: AuxProps = { - layer: SwitcherAuxLLayer.AuxClean, + layer: SwitcherAuxLLayer.CLEAN, content: { input: 5 } @@ -293,7 +293,7 @@ describe('TriCaster', () => { const testee: TriCaster = createTestee() const timelineObject = testee.getAuxTimelineObject(DEFAULT_AUX) expect(timelineObject).toMatchObject({ - layer: prefixLayer(SwitcherAuxLLayer.AuxClean) + layer: prefixLayer(SwitcherAuxLLayer.CLEAN) }) }) @@ -356,14 +356,14 @@ describe('TriCaster', () => { const context = mock() when(context.getStudioMappings).thenReturn(() => { return { - [prefixLayer(SwitcherAuxLLayer.AuxClean)]: literal({ + [prefixLayer(SwitcherAuxLLayer.CLEAN)]: literal({ device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, name: 'mix5' }), - [prefixLayer(SwitcherAuxLLayer.AuxVideoMixMinus)]: literal({ + [prefixLayer(SwitcherAuxLLayer.VIDEO_MIX_MINUS)]: literal({ device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, @@ -375,14 +375,14 @@ describe('TriCaster', () => { const uniformConfig = mock() when(uniformConfig.specialInputAuxLLayers).thenReturn({ - [SpecialInput.ME1_PROGRAM]: SwitcherAuxLLayer.AuxProgram, - [SpecialInput.ME3_PROGRAM]: SwitcherAuxLLayer.AuxClean + [SpecialInput.ME1_PROGRAM]: SwitcherAuxLLayer.PROGRAM, + [SpecialInput.ME3_PROGRAM]: SwitcherAuxLLayer.CLEAN }) const testee = createTestee({ context: instance(context), uniformConfig: instance(uniformConfig) }) const timelineObject = testee.getAuxTimelineObject({ - layer: SwitcherAuxLLayer.AuxVideoMixMinus, + layer: SwitcherAuxLLayer.VIDEO_MIX_MINUS, content: { input: SpecialInput.ME3_PROGRAM } @@ -590,7 +590,7 @@ describe('TriCaster', () => { const result: TSR.TSRTimelineObj[] = testee.getDveTimelineObjects(getBasicDveProps()) expect(result).toHaveLength(1) - expect(result[0].layer).toBe(prefixLayer(SwitcherDveLLayer.DveBoxes)) + expect(result[0].layer).toBe(prefixLayer(SwitcherDveLLayer.DVE_BOXES)) }) // TODO: Replace with interface diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index 65696cc7..128d521f 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -183,39 +183,39 @@ export enum SharedGraphicLLayer { } export enum AbstractLLayer { - ServerEnablePending = 'server_enable_pending', + SERVER_ENABLE_PENDING = 'server_enable_pending', /* Exists to give the Ident UI marker a timeline object so that it gets the startedPlayback callback */ - IdentMarker = 'ident_marker', - AudioBedBaseline = 'audio_bed_baseline' + IDENT_MARKER = 'ident_marker', + AUDIO_BED_BASELINE = 'audio_bed_baseline' } export enum SwitcherMixEffectLLayer { - Program = 'me_program', - Clean = 'me_clean', - CleanUskFull = 'clean_usk_full', - CleanUskEffect = 'clean_usk_effect', - Next = 'me_next', - NextJingle = 'me_next_jingle' + PROGRAM = 'me_program', + CLEAN = 'me_clean', + CLEAN_USK_FULL = 'clean_usk_full', + CLEAN_USK_EFFECT = 'clean_usk_effect', + NEXT = 'me_next', + NEXT_JINGLE = 'me_next_jingle' } export enum SwitcherAuxLLayer { - AuxProgram = 'aux_pgm', - AuxClean = 'aux_clean', - AuxMixEffect3 = 'aux_mix_effect_3', // AUX set by Sofie, but the M/E is uncontrolled by Sofie - AuxWall = 'aux_wall', - AuxAR = 'aux_ar', - AuxVizOvlIn1 = 'aux_viz_ovl_in_1', - AuxVenue = 'aux_venue', - AuxLookahead = 'aux_lookahead', - AuxDve = 'aux_dve', - AuxVideoMixMinus = 'aux_video_mix_minus', - AuxScreen = 'aux_screen', - AuxServerLookahead = 'aux_server_lookahead' + PROGRAM = 'aux_pgm', + CLEAN = 'aux_clean', + MIX_EFFECT_3 = 'aux_mix_effect_3', // AUX set by Sofie, but the M/E is uncontrolled by Sofie + WALL = 'aux_wall', + AR = 'aux_ar', + VIZ_OVL_IN_1 = 'aux_viz_ovl_in_1', + VENUE = 'aux_venue', + LOOKAHEAD = 'aux_lookahead', + DVE = 'aux_dve', + VIDEO_MIX_MINUS = 'aux_video_mix_minus', + SCREEN = 'aux_screen', + SERVER_LOOKAHEAD = 'aux_server_lookahead' } export enum SwitcherDveLLayer { - Dve = 'dve', - DveBoxes = 'dve_boxes' + DVE = 'dve', + DVE_BOXES = 'dve_boxes' } export type SwitcherDskLLayer = `dsk_${number}` diff --git a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts index 6eef4984..c20eff5d 100644 --- a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts @@ -139,7 +139,7 @@ const kamPieceInstance_Cut: IBlueprintPieceInstance = { timelineObjects: [ literal({ id: '', - layer: prefixLayer(SwitcherMixEffectLLayer.Program), + layer: prefixLayer(SwitcherMixEffectLLayer.PROGRAM), enable: { start: 0 }, @@ -175,7 +175,7 @@ const kamPieceInstance_Mix: IBlueprintPieceInstance = { timelineObjects: [ literal({ id: '', - layer: prefixLayer(SwitcherMixEffectLLayer.Program), + layer: prefixLayer(SwitcherMixEffectLLayer.PROGRAM), enable: { start: 0 }, @@ -216,7 +216,7 @@ const kamPieceInstance_Effekt: IBlueprintPieceInstance = { timelineObjects: [ literal({ id: '', - layer: prefixLayer(SwitcherMixEffectLLayer.Program), + layer: prefixLayer(SwitcherMixEffectLLayer.PROGRAM), enable: { start: 0 }, @@ -273,7 +273,7 @@ const evsPieceInstance_Cut: IBlueprintPieceInstance = { timelineObjects: [ literal({ id: '', - layer: prefixLayer(SwitcherMixEffectLLayer.Program), + layer: prefixLayer(SwitcherMixEffectLLayer.PROGRAM), enable: { start: 0 }, @@ -309,7 +309,7 @@ const evsPieceInstance_Mix: IBlueprintPieceInstance = { timelineObjects: [ literal({ id: '', - layer: prefixLayer(SwitcherMixEffectLLayer.Program), + layer: prefixLayer(SwitcherMixEffectLLayer.PROGRAM), enable: { start: 0 }, @@ -350,7 +350,7 @@ const evsPieceInstance_Effekt: IBlueprintPieceInstance = { timelineObjects: [ literal({ id: '', - layer: prefixLayer(SwitcherMixEffectLLayer.Program), + layer: prefixLayer(SwitcherMixEffectLLayer.PROGRAM), enable: { start: 0 }, @@ -408,7 +408,7 @@ async function getTransitionPiece( function getATEMMEObj(piece: IBlueprintPieceInstance): TSR.TimelineObjAtemME { const atemObj = (piece.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( (obj) => - obj.layer === prefixLayer(SwitcherMixEffectLLayer.Program) && + obj.layer === prefixLayer(SwitcherMixEffectLLayer.PROGRAM) && obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.ME ) as TSR.TimelineObjAtemME | undefined diff --git a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts index cd2840a2..cadac354 100644 --- a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts @@ -111,7 +111,7 @@ function getPieceOnLayerFromPart(segment: BlueprintResultSegment, layer: SourceL function getATEMMEObj(piece: IBlueprintPiece): TSR.TimelineObjAtemME { const atemMEObj = (piece!.content!.timelineObjects as TSR.TSRTimelineObj[]).find( (obj) => - obj.layer === prefixLayer(SwitcherMixEffectLLayer.Program) && + obj.layer === prefixLayer(SwitcherMixEffectLLayer.PROGRAM) && obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.ME ) as TSR.TimelineObjAtemME diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 8aae58d8..82d180b2 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -209,7 +209,7 @@ class GlobalAdLibPiecesGenerator { this.context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, priority: 1, - layer: SwitcherAuxLLayer.AuxAR, + layer: SwitcherAuxLLayer.AR, content: { input: info.port } @@ -234,7 +234,7 @@ class GlobalAdLibPiecesGenerator { this.context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, priority: 1, - layer: SwitcherAuxLLayer.AuxVizOvlIn1, + layer: SwitcherAuxLLayer.VIZ_OVL_IN_1, content: { input: info.port } @@ -307,7 +307,7 @@ class GlobalAdLibPiecesGenerator { this.context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, priority: 1, - layer: SwitcherAuxLLayer.AuxAR, + layer: SwitcherAuxLLayer.AR, content: { input: info.port } @@ -513,7 +513,7 @@ function getBaseline(context: ShowStyleContext): Bluepri context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxLookahead, + layer: SwitcherAuxLLayer.LOOKAHEAD, content: { input: context.config.studio.SwitcherSource.Default } @@ -522,7 +522,7 @@ function getBaseline(context: ShowStyleContext): Bluepri ? [ context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxMixEffect3, + layer: SwitcherAuxLLayer.MIX_EFFECT_3, content: { input: SpecialInput.ME3_PROGRAM } @@ -531,7 +531,7 @@ function getBaseline(context: ShowStyleContext): Bluepri : [ context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxDve, + layer: SwitcherAuxLLayer.DVE, content: { input: SpecialInput.DVE } @@ -539,7 +539,7 @@ function getBaseline(context: ShowStyleContext): Bluepri ]), context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxVideoMixMinus, + layer: SwitcherAuxLLayer.VIDEO_MIX_MINUS, content: { input: context.uniformConfig.mixEffects.program.input } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts index bb18f4d6..0b6b632d 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts @@ -46,7 +46,7 @@ export function EvaluateCueRouting( timelineObjects: _.compact([ context.videoSwitcher.getAuxTimelineObject({ priority: 100, - layer: SwitcherAuxLLayer.AuxVizOvlIn1, + layer: SwitcherAuxLLayer.VIZ_OVL_IN_1, content: { input: sourceInfo.port } diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index c0fad5ee..309f81ab 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -364,7 +364,7 @@ describe('Graphics', () => { ) as TSR.TimelineObjAtemAUX | undefined expect(auxObj).toBeTruthy() expect(auxObj?.enable).toEqual({ start: 0 }) - expect(auxObj?.layer).toBe(prefixLayer(SwitcherAuxLLayer.AuxVizOvlIn1)) + expect(auxObj?.layer).toBe(prefixLayer(SwitcherAuxLLayer.VIZ_OVL_IN_1)) expect(auxObj?.content.aux.input).toBe(1) }) diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index 3aa43c82..acf90db0 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -32,7 +32,7 @@ export const MAPPINGS_ABSTRACT: BlueprintMappings = { deviceId: 'abstract0', lookahead: LookaheadMode.NONE }), - [AbstractLLayer.ServerEnablePending]: literal({ + [AbstractLLayer.SERVER_ENABLE_PENDING]: literal({ device: TSR.DeviceType.ABSTRACT, deviceId: 'abstract0', lookahead: LookaheadMode.NONE @@ -47,12 +47,12 @@ export const MAPPINGS_ABSTRACT: BlueprintMappings = { deviceId: 'abstract0', lookahead: LookaheadMode.NONE }), - [AbstractLLayer.IdentMarker]: literal({ + [AbstractLLayer.IDENT_MARKER]: literal({ device: TSR.DeviceType.ABSTRACT, deviceId: 'abstract0', lookahead: LookaheadMode.NONE }), - [AbstractLLayer.AudioBedBaseline]: literal({ + [AbstractLLayer.AUDIO_BED_BASELINE]: literal({ device: TSR.DeviceType.ABSTRACT, deviceId: 'abstract0', lookahead: LookaheadMode.NONE @@ -580,91 +580,91 @@ export const MAPPINGS_GRAPHICS: BlueprintMappings = { } export const MAPPINGS_ATEM = prefixLayers(ATEM_LAYER_PREFIX, { - [SwitcherMixEffectLLayer.Program]: { + [SwitcherMixEffectLLayer.PROGRAM]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 0 // 0 = ME1 }, - [SwitcherMixEffectLLayer.Clean]: { + [SwitcherMixEffectLLayer.CLEAN]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 3 // 3 = ME4 }, - [SwitcherMixEffectLLayer.CleanUskFull]: { + [SwitcherMixEffectLLayer.CLEAN_USK_FULL]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 3 // 3 = ME4 }, - [SwitcherMixEffectLLayer.CleanUskEffect]: { + [SwitcherMixEffectLLayer.CLEAN_USK_EFFECT]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 3 // 3 = ME4 }, - [SwitcherAuxLLayer.AuxProgram]: { + [SwitcherAuxLLayer.PROGRAM]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.Auxilliary, index: 0 // 0 = out 1 }, - [SwitcherAuxLLayer.AuxClean]: { + [SwitcherAuxLLayer.CLEAN]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.Auxilliary, index: 1 // 1 = out 2 }, - [SwitcherAuxLLayer.AuxAR]: { + [SwitcherAuxLLayer.AR]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 3 // 3 = out 4 }, - [SwitcherAuxLLayer.AuxVizOvlIn1]: { + [SwitcherAuxLLayer.VIZ_OVL_IN_1]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 4 // 4 = out 5 }, - [SwitcherAuxLLayer.AuxVideoMixMinus]: { + [SwitcherAuxLLayer.VIDEO_MIX_MINUS]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.Auxilliary, index: 6 // 6 = out 7 }, - [SwitcherAuxLLayer.AuxLookahead]: { + [SwitcherAuxLLayer.LOOKAHEAD]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 10 // 10 = out 11 }, - [SwitcherAuxLLayer.AuxDve]: { + [SwitcherAuxLLayer.DVE]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 11 // 11 = out 12 }, - [SwitcherDveLLayer.Dve]: { + [SwitcherDveLLayer.DVE]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.SuperSourceProperties, index: 0 // 0 = SS }, - [SwitcherDveLLayer.DveBoxes]: { + [SwitcherDveLLayer.DVE_BOXES]: { device: TSR.DeviceType.ATEM, deviceId: ATEM_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, // TODO - verify @@ -682,98 +682,98 @@ export const MAPPINGS_ATEM = prefixLayers(AT }) export const MAPPINGS_TRICASTER = prefixLayers(TRICASTER_LAYER_PREFIX, { - [SwitcherMixEffectLLayer.Program]: { + [SwitcherMixEffectLLayer.PROGRAM]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingTriCasterType.ME, name: TRICASTER_PROGRAM_ME }, - [SwitcherMixEffectLLayer.Clean]: { + [SwitcherMixEffectLLayer.CLEAN]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingTriCasterType.ME, name: TRICASTER_CLEAN_ME }, - [SwitcherMixEffectLLayer.CleanUskFull]: { + [SwitcherMixEffectLLayer.CLEAN_USK_FULL]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingTriCasterType.ME, name: TRICASTER_CLEAN_ME }, - [SwitcherMixEffectLLayer.CleanUskEffect]: { + [SwitcherMixEffectLLayer.CLEAN_USK_EFFECT]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingTriCasterType.ME, name: TRICASTER_CLEAN_ME }, - [SwitcherAuxLLayer.AuxProgram]: { + [SwitcherAuxLLayer.PROGRAM]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, name: 'mix1' }, - [SwitcherAuxLLayer.AuxClean]: { + [SwitcherAuxLLayer.CLEAN]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, name: 'mix2' }, - [SwitcherAuxLLayer.AuxWall]: { + [SwitcherAuxLLayer.WALL]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, name: 'mix3' }, - [SwitcherAuxLLayer.AuxAR]: { + [SwitcherAuxLLayer.AR]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, name: 'mix4' }, - [SwitcherAuxLLayer.AuxVizOvlIn1]: { + [SwitcherAuxLLayer.VIZ_OVL_IN_1]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, name: 'mix5' }, - [SwitcherAuxLLayer.AuxLookahead]: { + [SwitcherAuxLLayer.LOOKAHEAD]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, name: 'mix6' }, - [SwitcherAuxLLayer.AuxMixEffect3]: { + [SwitcherAuxLLayer.MIX_EFFECT_3]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, name: 'mix7' }, - [SwitcherAuxLLayer.AuxVideoMixMinus]: { + [SwitcherAuxLLayer.VIDEO_MIX_MINUS]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingTriCasterType.MIX_OUTPUT, name: 'mix8' }, - [SwitcherDveLLayer.Dve]: { + [SwitcherDveLLayer.DVE]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.NONE, mappingType: TSR.MappingTriCasterType.ME, name: TRICASTER_DVE_ME }, - [SwitcherDveLLayer.DveBoxes]: { + [SwitcherDveLLayer.DVE_BOXES]: { device: TSR.DeviceType.TRICASTER, deviceId: TRICASTER_DEVICE_ID, lookahead: LookaheadMode.WHEN_CLEAR, diff --git a/src/tv2_afvd_studio/uniformConfig.ts b/src/tv2_afvd_studio/uniformConfig.ts index 9c7c3187..79a393da 100644 --- a/src/tv2_afvd_studio/uniformConfig.ts +++ b/src/tv2_afvd_studio/uniformConfig.ts @@ -4,24 +4,24 @@ import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' const MIX_EFFECTS: UniformConfig['mixEffects'] = { program: { input: SpecialInput.ME1_PROGRAM, - mixEffectLayer: SwitcherMixEffectLLayer.Program, - auxLayer: SwitcherAuxLLayer.AuxProgram + mixEffectLayer: SwitcherMixEffectLLayer.PROGRAM, + auxLayer: SwitcherAuxLLayer.PROGRAM }, clean: { input: SpecialInput.ME4_PROGRAM, - mixEffectLayer: SwitcherMixEffectLLayer.Clean, - auxLayer: SwitcherAuxLLayer.AuxClean + mixEffectLayer: SwitcherMixEffectLLayer.CLEAN, + auxLayer: SwitcherAuxLLayer.CLEAN } } export const GALLERY_UNIFORM_CONFIG: UniformConfig = { switcherLLayers: { - primaryMixEffect: SwitcherMixEffectLLayer.Program, - primaryMixEffectClone: SwitcherMixEffectLLayer.Clean, - jingleUskMixEffect: SwitcherMixEffectLLayer.CleanUskEffect, - fullUskMixEffect: SwitcherMixEffectLLayer.CleanUskFull, - nextAux: SwitcherAuxLLayer.AuxLookahead, - mixMinusAux: SwitcherAuxLLayer.AuxVideoMixMinus + primaryMixEffect: SwitcherMixEffectLLayer.PROGRAM, + primaryMixEffectClone: SwitcherMixEffectLLayer.CLEAN, + jingleUskMixEffect: SwitcherMixEffectLLayer.CLEAN_USK_EFFECT, + fullUskMixEffect: SwitcherMixEffectLLayer.CLEAN_USK_FULL, + nextAux: SwitcherAuxLLayer.LOOKAHEAD, + mixMinusAux: SwitcherAuxLLayer.VIDEO_MIX_MINUS }, mixEffects: MIX_EFFECTS, specialInputAuxLLayers: { diff --git a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts index cf57ad22..d170f85f 100644 --- a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts @@ -93,7 +93,7 @@ const kamPieceInstance: IBlueprintPieceInstance = { enable: { start: 0 }, - layer: prefixLayer(SwitcherMixEffectLLayer.Clean), + layer: prefixLayer(SwitcherMixEffectLLayer.CLEAN), content: { deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.ME, @@ -397,7 +397,7 @@ function validateNextPartExistsWithPreviousPartKeepaliveDuration( function getATEMMEObj(piece: IBlueprintPieceInstance): TSR.TimelineObjAtemME { const atemObj = (piece.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( (obj) => - obj.layer === prefixLayer(SwitcherMixEffectLLayer.Clean) && + obj.layer === prefixLayer(SwitcherMixEffectLLayer.CLEAN) && obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.ME ) as TSR.TimelineObjAtemME | undefined diff --git a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts index cb46e8b0..e8e02410 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts @@ -43,7 +43,7 @@ export function OfftubeEvaluatePgmClean( timelineObjects: literal([ context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxClean, + layer: SwitcherAuxLLayer.CLEAN, content: { input: sourceInfo.port } diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 29cf74dc..cb30d66b 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -607,7 +607,7 @@ function getBaseline(context: ShowStyleContext): Bluepri : undefined, context.videoSwitcher.getAuxTimelineObject({ enable: { while: '1' }, - layer: SwitcherAuxLLayer.AuxScreen, + layer: SwitcherAuxLLayer.SCREEN, content: { input: context.config.studio.SwitcherSource.Loop } diff --git a/src/tv2_offtube_studio/migrations/mappings-defaults.ts b/src/tv2_offtube_studio/migrations/mappings-defaults.ts index 68f0d818..87108ab3 100644 --- a/src/tv2_offtube_studio/migrations/mappings-defaults.ts +++ b/src/tv2_offtube_studio/migrations/mappings-defaults.ts @@ -18,7 +18,7 @@ const MAPPINGS_ABSTRACT: BlueprintMappings = { deviceId: 'abstract0', lookahead: LookaheadMode.NONE }), - [AbstractLLayer.ServerEnablePending]: literal({ + [AbstractLLayer.SERVER_ENABLE_PENDING]: literal({ device: TSR.DeviceType.ABSTRACT, deviceId: 'abstract0', lookahead: LookaheadMode.NONE @@ -33,12 +33,12 @@ const MAPPINGS_ABSTRACT: BlueprintMappings = { deviceId: 'abstract0', lookahead: LookaheadMode.NONE }), - [AbstractLLayer.IdentMarker]: literal({ + [AbstractLLayer.IDENT_MARKER]: literal({ device: TSR.DeviceType.ABSTRACT, deviceId: 'abstract0', lookahead: LookaheadMode.NONE }), - [AbstractLLayer.AudioBedBaseline]: literal({ + [AbstractLLayer.AUDIO_BED_BASELINE]: literal({ device: TSR.DeviceType.ABSTRACT, deviceId: 'abstract0', lookahead: LookaheadMode.NONE @@ -447,21 +447,21 @@ const MAPPINGS_GRAPHICS: BlueprintMappings = { } const MAPPINGS_ATEM: Record = prefixLayers(ATEM_LAYER_PREFIX, { - [SwitcherMixEffectLLayer.Clean]: { + [SwitcherMixEffectLLayer.CLEAN]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 1 // 1 = ME2 }, - [SwitcherMixEffectLLayer.Program]: { + [SwitcherMixEffectLLayer.PROGRAM]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.MixEffect, index: 0 // 0 = ME1 }, - [SwitcherMixEffectLLayer.Next]: { + [SwitcherMixEffectLLayer.NEXT]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, @@ -469,7 +469,7 @@ const MAPPINGS_ATEM: Record = prefix index: 0, // 0 = ME1 lookaheadDepth: 1 }, - [SwitcherMixEffectLLayer.NextJingle]: { + [SwitcherMixEffectLLayer.NEXT_JINGLE]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.PRELOAD, @@ -477,28 +477,28 @@ const MAPPINGS_ATEM: Record = prefix mappingType: TSR.MappingAtemType.MixEffect, index: 0 // 0 = ME1 }, - [SwitcherAuxLLayer.AuxClean]: { + [SwitcherAuxLLayer.CLEAN]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.Auxilliary, index: 0 // 0 = out 1 }, - [SwitcherAuxLLayer.AuxScreen]: { + [SwitcherAuxLLayer.SCREEN]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.NONE, mappingType: TSR.MappingAtemType.Auxilliary, index: 1 // 1 = out 2 }, - [SwitcherAuxLLayer.AuxServerLookahead]: { + [SwitcherAuxLLayer.SERVER_LOOKAHEAD]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, mappingType: TSR.MappingAtemType.Auxilliary, index: 2 // 2 = out 3 }, - [SwitcherDveLLayer.Dve]: { + [SwitcherDveLLayer.DVE]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, @@ -506,7 +506,7 @@ const MAPPINGS_ATEM: Record = prefix mappingType: TSR.MappingAtemType.SuperSourceProperties, index: 0 // 0 = SS }, - [SwitcherDveLLayer.DveBoxes]: { + [SwitcherDveLLayer.DVE_BOXES]: { device: TSR.DeviceType.ATEM, deviceId: 'atem0', lookahead: LookaheadMode.WHEN_CLEAR, diff --git a/src/tv2_offtube_studio/uniformConfig.ts b/src/tv2_offtube_studio/uniformConfig.ts index 1bdb86e3..1951bf83 100644 --- a/src/tv2_offtube_studio/uniformConfig.ts +++ b/src/tv2_offtube_studio/uniformConfig.ts @@ -2,20 +2,20 @@ import { getSpecialLayers, SpecialInput, UniformConfig } from 'tv2-common' import { SwitcherAuxLLayer, SwitcherMixEffectLLayer } from 'tv2-constants' const MIX_EFFECTS: UniformConfig['mixEffects'] = { - program: { input: SpecialInput.ME1_PROGRAM, mixEffectLayer: SwitcherMixEffectLLayer.Program }, + program: { input: SpecialInput.ME1_PROGRAM, mixEffectLayer: SwitcherMixEffectLLayer.PROGRAM }, clean: { input: SpecialInput.ME4_PROGRAM, - mixEffectLayer: SwitcherMixEffectLLayer.Clean, - auxLayer: SwitcherAuxLLayer.AuxClean + mixEffectLayer: SwitcherMixEffectLLayer.CLEAN, + auxLayer: SwitcherAuxLLayer.CLEAN } } export const QBOX_UNIFORM_CONFIG: UniformConfig = { switcherLLayers: { - primaryMixEffect: SwitcherMixEffectLLayer.Clean, - nextServerAux: SwitcherAuxLLayer.AuxServerLookahead, - nextPreviewMixEffect: SwitcherMixEffectLLayer.Next, - jingleNextMixEffect: SwitcherMixEffectLLayer.NextJingle + primaryMixEffect: SwitcherMixEffectLLayer.CLEAN, + nextServerAux: SwitcherAuxLLayer.SERVER_LOOKAHEAD, + nextPreviewMixEffect: SwitcherMixEffectLLayer.NEXT, + jingleNextMixEffect: SwitcherMixEffectLLayer.NEXT_JINGLE }, mixEffects: MIX_EFFECTS, specialInputAuxLLayers: { From f39a8b1ef41489d37e6a4e273fc246bd6d21ce86 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 21 Mar 2023 13:31:52 +0100 Subject: [PATCH 60/86] fix: SOF-1403 make layout selection and cutting to boxes work on dynamically inserted DVEs piece name is changed; new layout may have more boxes than the previous, so the defaults are used to fill extra boxes --- src/tv2-common/actions/executeAction.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 87afa4cd..d36d165a 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -788,6 +788,7 @@ async function executeActionSelectDVELayout< const newMetaData2: DVEPieceMetaData = { ...meta, + sources: { ...sources, ...meta.sources }, config: userData.config, sisyfosPersistMetaData: { sisyfosLayers: [] @@ -799,6 +800,7 @@ async function executeActionSelectDVELayout< ...nextDVE.piece, content: pieceContent.content, metaData: newMetaData2, + name: userData.config.DVEName, tags: [ GetTagForDVE('', userData.config.DVEName, sources), GetTagForDVENext('', userData.config.DVEName, sources), From 84fcc4da06b1f785b68178a721fdeb3387ba166f Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 21 Mar 2023 13:35:59 +0100 Subject: [PATCH 61/86] fix: SOF-1403 make input 0 be `black` in TriCaster 0 is Black in ATEM, makes TriCaster behave identically --- src/tv2-common/content/dve.ts | 3 +-- src/tv2-common/videoSwitchers/TriCaster.ts | 7 ++++++- src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts | 2 +- src/tv2-common/videoSwitchers/types.ts | 1 + 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index ddd91d88..e2b2184c 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -30,7 +30,6 @@ import { } from 'tv2-common' import { ControlClasses, MEDIA_PLAYER_AUTO, SharedGraphicLLayer, SourceType } from 'tv2-constants' import * as _ from 'underscore' -import { AtemSourceIndex } from '../../types/atem' import { ActionSelectDVE } from '../actions' import { CreateHTMLRendererContent, @@ -399,7 +398,7 @@ const setBoxSource = ( const setBoxToBlack = (boxConfig: BoxConfig, boxSources: BoxSources) => { setBoxSource(boxConfig, boxSources, { - port: AtemSourceIndex.Blk, + port: SpecialInput.BLACK, sourceLayerType: SourceLayerType.UNKNOWN }) } diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 222f025b..eeefbfb2 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -22,6 +22,7 @@ import { VideoSwitcherBase } from './VideoSwitcher' const MAX_REGULAR_INPUT_NUMBER = 1000 // everything >= is assumed a special input const SPECIAL_INPUT_MAP: Record = { + [SpecialInput.BLACK]: 'black', [SpecialInput.ME1_PROGRAM]: 'v1', [SpecialInput.ME2_PROGRAM]: 'v2', [SpecialInput.ME3_PROGRAM]: 'v3', @@ -327,10 +328,14 @@ export class TriCaster extends VideoSwitcherBase { if (typeof input === 'undefined') { return undefined } + const specialSourceName = SPECIAL_INPUT_MAP[input] + if (specialSourceName) { + return specialSourceName + } if (input < MAX_REGULAR_INPUT_NUMBER) { return `input${input as number}` } - return SPECIAL_INPUT_MAP[input] ?? 'black' + return 'black' } private getInputNameForMatrix(input: number | SpecialInput): TSR.TriCasterSourceName | TSR.TriCasterMixOutputName { diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index 8a049f5f..0df24862 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -599,7 +599,7 @@ describe('TriCaster', () => { content: { boxes: boxes ?? [{ enabled: false }, { enabled: false }, { enabled: false }, { enabled: false }], template: {}, - artFillSource: 0, + artFillSource: 5, artCutSource: 0 } } diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index d5d3fa6c..d4e09642 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -10,6 +10,7 @@ export enum SwitcherType { /** Using Atem values for compatibility */ export enum SpecialInput { + BLACK = AtemSourceIndex.Blk, ME1_PROGRAM = AtemSourceIndex.Prg1, ME2_PROGRAM = AtemSourceIndex.Prg2, ME3_PROGRAM = AtemSourceIndex.Prg3, From bbd09b15513ca23da0a38ec47146a0cf1266da1e Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 22 Mar 2023 13:08:46 +0100 Subject: [PATCH 62/86] fix: SOF-1403 disallow layout change on planned DVE queue a new DVE part instead --- src/tv2-common/actions/executeAction.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index d36d165a..69636da3 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -727,6 +727,7 @@ async function executeActionSelectDVELayout< if ( !nextPart || !nextDVE || + !nextDVE.dynamicallyInserted || !meta || nextPart.segmentId !== (await context.core.getPartInstance('current'))?.segmentId ) { From 099c7f32b0c6ece4e5e98cdff17f5ee88982188c Mon Sep 17 00:00:00 2001 From: Rasmus Date: Wed, 22 Mar 2023 14:04:07 +0100 Subject: [PATCH 63/86] fix: Accomodates the refactoring done in blueprint-integration --- src/tv2-common/showstyle/config-manifests.ts | 30 +++++++++---------- .../__tests__/config-manifest.spec.ts | 3 +- src/tv2_afvd_showstyle/config-manifests.ts | 3 +- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/tv2-common/showstyle/config-manifests.ts b/src/tv2-common/showstyle/config-manifests.ts index 5173a510..66556dd9 100644 --- a/src/tv2-common/showstyle/config-manifests.ts +++ b/src/tv2-common/showstyle/config-manifests.ts @@ -1,12 +1,12 @@ import { ConfigManifestEntry, ConfigManifestEntryTable, ConfigManifestEntryType } from 'blueprints-integration' -import {TableConfigItemGfxDefaults} from "../blueprintConfig"; +import { TableConfigItemGfxDefaults } from '../blueprintConfig' export enum CommonConfigId { GRAPHICS_SETUPS_TABLE_ID = 'GfxSetups', GRAPHICS_SETUPS_NAME_COLUMN_ID = 'Name', GFX_DEFAULTS_TABLE_ID = 'GfxDefaults', DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID = 'SelectedGfxSetupName', - DEFAULTS_SCHEMA_COLUMN_ID = 'DefaultSkema', + DEFAULTS_SCHEMA_COLUMN_ID = 'DefaultSchema', DEFAULTS_DESIGN_COLUMN_ID = 'DefaultDesign', GFX_SHOW_MAPPING_TABLE_ID = 'GfxShowMapping', GFX_SHOW_MAPPING_DESIGN_COLUMN_ID = 'Design', @@ -82,12 +82,12 @@ export const getGfxDefaults: ConfigManifestEntry = { name: 'Default Skema', rank: 1, description: 'The Skema options based on the GFX Setup', - type: ConfigManifestEntryType.SELECT_PICKED_FROM_COLUMN, - toTableId: CommonConfigId.GFX_DEFAULTS_TABLE_ID, - toColumnId: CommonConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, - fromTableId: CommonConfigId.GFX_SHOW_MAPPING_TABLE_ID, - fromColumnId: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, - compareId: CommonConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID, + type: ConfigManifestEntryType.FILTER_SELECTED_FROM_COLUMN, + targetTableId: CommonConfigId.GFX_DEFAULTS_TABLE_ID, + targetCompareColumnId: CommonConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, + sourceTableId: CommonConfigId.GFX_SHOW_MAPPING_TABLE_ID, + sourceCompareColumnId: CommonConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID, + sourceCollectColumnId: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, multiple: false, required: false, defaultVal: '' @@ -96,13 +96,13 @@ export const getGfxDefaults: ConfigManifestEntry = { id: CommonConfigId.DEFAULTS_DESIGN_COLUMN_ID, name: 'Default Design', rank: 2, - description: 'The Design options based on the Default Skema', - type: ConfigManifestEntryType.SELECT_PICKED_FROM_COLUMN, - toTableId: CommonConfigId.GFX_DEFAULTS_TABLE_ID, - toColumnId: CommonConfigId.DEFAULTS_SCHEMA_COLUMN_ID, - fromTableId: CommonConfigId.GFX_SHOW_MAPPING_TABLE_ID, - fromColumnId: CommonConfigId.GFX_SHOW_MAPPING_DESIGN_COLUMN_ID, - compareId: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, + description: 'The Design options based on the Default Skema or GFX Setup', + type: ConfigManifestEntryType.FILTER_SELECTED_FROM_COLUMN, + targetTableId: CommonConfigId.GFX_DEFAULTS_TABLE_ID, + targetCompareColumnId: CommonConfigId.DEFAULTS_SCHEMA_COLUMN_ID, + sourceTableId: CommonConfigId.GFX_SHOW_MAPPING_TABLE_ID, + sourceCompareColumnId: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, + sourceCollectColumnId: CommonConfigId.GFX_SHOW_MAPPING_DESIGN_COLUMN_ID, multiple: false, required: false, defaultVal: '' diff --git a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts index 23e4ff81..563f9494 100644 --- a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts @@ -17,7 +17,8 @@ const blankShowStyleConfig: ShowStyleConfig = { SelectedGfxSetupName: '', GfxSetups: [], GfxSchemaTemplates: [], - GfxShowMapping: [] + GfxShowMapping: [], + GfxDefaults: [{ GfxSetup: '', DefaultSchema: [''], DefaultDesign: [''] }] } describe('Config Manifest', () => { diff --git a/src/tv2_afvd_showstyle/config-manifests.ts b/src/tv2_afvd_showstyle/config-manifests.ts index 3f9e408e..5a7cbc6e 100644 --- a/src/tv2_afvd_showstyle/config-manifests.ts +++ b/src/tv2_afvd_showstyle/config-manifests.ts @@ -266,7 +266,8 @@ export const gfxSchemaTemplates: ConfigManifestEntry[] = [ export const gfxShowMapping: ConfigManifestEntry = { id: 'GfxShowMapping', name: 'GFX Show mapping', - description: 'Maps Overlay Shows to the variety of Skemas and Designs', + description: + 'Maps Overlay Shows to the variety of Skemas and Designs. If a Setup does not have a corresponding Design/Skema, it should be left out of this table.', type: ConfigManifestEntryType.TABLE, required: false, defaultVal: [], From abb067396ceedaffad19f6fa17bd8349f9c85f5a Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Fri, 24 Mar 2023 11:53:37 +0100 Subject: [PATCH 64/86] SOF-1374 More clear variable name --- src/tv2-common/actions/executeAction.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 78037033..94acbacb 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1059,7 +1059,7 @@ async function executePiece< partToQueue: IBlueprintPart ) { const currentPieceInstances = await context.core.getPieceInstances('current') - const serverInCurrentPart = currentPieceInstances.some( + const isServerInCurrentPart = currentPieceInstances.some( (p) => p.piece.sourceLayerId === settings.SourceLayers.Server || p.piece.sourceLayerId === settings.SourceLayers.VO ) @@ -1068,7 +1068,7 @@ async function executePiece< layersWithCutDirect.includes(p.piece.sourceLayerId) ) - if (shouldBeQueued || serverInCurrentPart) { + if (shouldBeQueued || isServerInCurrentPart) { await context.core.queuePart(partToQueue, [ pieceToExecute, ...(settings.SelectedAdlibs @@ -1076,7 +1076,7 @@ async function executePiece< : []) ]) - if (serverInCurrentPart && !shouldBeQueued) { + if (isServerInCurrentPart && !shouldBeQueued) { await context.core.takeAfterExecuteAction(true) } } else if (currentPiece) { From 2d768fcf32499ccee280dd98376233c5d9a3ca8b Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Fri, 24 Mar 2023 12:20:59 +0100 Subject: [PATCH 65/86] SOF-1374 Refactor 'queue' to 'cutDirectly' for ActionCutCamera --- src/tv2-common/actions/actionTypes.ts | 2 +- src/tv2-common/actions/executeAction.ts | 2 +- .../GlobalAdlibActionsGenerator.ts | 29 +++++++++------ .../__tests__/actions.spec.ts | 8 ++--- .../__tests__/actions.spec.ts | 2 +- src/tv2_offtube_showstyle/getRundown.ts | 35 +++++++++++-------- 6 files changed, 46 insertions(+), 32 deletions(-) diff --git a/src/tv2-common/actions/actionTypes.ts b/src/tv2-common/actions/actionTypes.ts index cea269b6..b69062d9 100644 --- a/src/tv2-common/actions/actionTypes.ts +++ b/src/tv2-common/actions/actionTypes.ts @@ -54,7 +54,7 @@ export interface ActionCallRobotPreset extends ActionBase { export interface ActionCutToCamera extends ActionBase { type: AdlibActionType.CUT_TO_CAMERA - queue: boolean + cutDirectly: boolean sourceDefinition: SourceDefinitionKam } diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 94acbacb..8a9bdf3a 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1045,7 +1045,7 @@ async function executeActionCutToCamera< } } - await executePiece(context, settings, kamPiece, userData.queue, part) + await executePiece(context, settings, kamPiece, !userData.cutDirectly, part) } async function executePiece< diff --git a/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts b/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts index 927a3ecd..db72624e 100644 --- a/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts +++ b/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts @@ -39,13 +39,8 @@ export class GlobalAdlibActionsGenerator { this.config.sources.cameras .slice(0, 5) // the first x cameras to create INP1/2/3 cam-adlibs from .forEach((camera) => { - blueprintActions.push(this.makeCutCameraAction(camera, false, globalRank++)) - }) - - this.config.sources.cameras - .slice(0, 5) // the first x cameras to create preview cam-adlibs from - .forEach((camera) => { - blueprintActions.push(this.makeCutCameraAction(camera, true, globalRank++)) + blueprintActions.push(this.makeCutDirectlyCameraAction(camera, globalRank++)) + blueprintActions.push(this.makeQueueAsNextCameraAction(camera, globalRank++)) }) this.config.sources.cameras @@ -93,11 +88,23 @@ export class GlobalAdlibActionsGenerator { return blueprintActions } - private makeCutCameraAction(info: SourceInfo, queue: boolean, rank: number): IBlueprintActionManifest { - const sourceDefinition = SourceInfoToSourceDefinition(info) as SourceDefinitionKam + private makeCutDirectlyCameraAction(cameraSourceInfo: SourceInfo, rank: number): IBlueprintActionManifest { + return this.makeCutCameraAction(cameraSourceInfo, true, rank) + } + + private makeQueueAsNextCameraAction(cameraSourceInfo: SourceInfo, rank: number): IBlueprintActionManifest { + return this.makeCutCameraAction(cameraSourceInfo, false, rank) + } + + private makeCutCameraAction( + cameraSourceInfo: SourceInfo, + cutDirectly: boolean, + rank: number + ): IBlueprintActionManifest { + const sourceDefinition = SourceInfoToSourceDefinition(cameraSourceInfo) as SourceDefinitionKam const userData: ActionCutToCamera = { type: AdlibActionType.CUT_TO_CAMERA, - queue, + cutDirectly, sourceDefinition } return { @@ -111,7 +118,7 @@ export class GlobalAdlibActionsGenerator { sourceLayerId: SourceLayer.PgmCam, outputLayerId: SharedOutputLayer.PGM, content: {}, - tags: queue ? [AdlibTags.ADLIB_QUEUE_NEXT] : [AdlibTags.ADLIB_CUT_DIRECT] + tags: cutDirectly ? [AdlibTags.ADLIB_CUT_DIRECT] : [AdlibTags.ADLIB_QUEUE_NEXT] } } } diff --git a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts index 6eef4984..618f4f25 100644 --- a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts @@ -822,7 +822,7 @@ describe('Camera shortcuts on server', () => { AdlibActionType.CUT_TO_CAMERA, literal({ type: AdlibActionType.CUT_TO_CAMERA, - queue: false, + cutDirectly: true, sourceDefinition: SOURCE_DEFINITION_KAM_1 }) ) @@ -865,7 +865,7 @@ describe('Camera shortcuts on server', () => { AdlibActionType.CUT_TO_CAMERA, literal({ type: AdlibActionType.CUT_TO_CAMERA, - queue: true, + cutDirectly: false, sourceDefinition: SOURCE_DEFINITION_KAM_1 }) ) @@ -910,7 +910,7 @@ describe('Camera shortcuts on VO', () => { AdlibActionType.CUT_TO_CAMERA, literal({ type: AdlibActionType.CUT_TO_CAMERA, - queue: false, + cutDirectly: true, sourceDefinition: SOURCE_DEFINITION_KAM_1 }) ) @@ -953,7 +953,7 @@ describe('Camera shortcuts on VO', () => { AdlibActionType.CUT_TO_CAMERA, literal({ type: AdlibActionType.CUT_TO_CAMERA, - queue: true, + cutDirectly: false, sourceDefinition: SOURCE_DEFINITION_KAM_1 }) ) diff --git a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts index 2b3cbb65..8bc34f34 100644 --- a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts @@ -234,7 +234,7 @@ const commentatorSelectDVE = literal({ const selectCameraAction = literal({ type: AdlibActionType.CUT_TO_CAMERA, sourceDefinition: SOURCE_DEFINITION_KAM_1, - queue: true + cutDirectly: false }) const selectLiveAction = literal({ diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 04d4a503..1f5331f6 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -234,14 +234,26 @@ function getGlobalAdlibActionsOfftube( let globalRank = 2000 - function makeCutCameraActions(info: SourceInfo, queue: boolean, rank: number) { - const sourceDefinition = SourceInfoToSourceDefinition(info) as SourceDefinitionKam + function makeCutDirectlyCameraAction(cameraSourceInfo: SourceInfo, rank: number): IBlueprintActionManifest { + return makeCutCameraAction(cameraSourceInfo, true, rank) + } + + function makeQueueAsNextCameraAction(cameraSourceInfo: SourceInfo, rank: number): IBlueprintActionManifest { + return makeCutCameraAction(cameraSourceInfo, false, rank) + } + + function makeCutCameraAction( + cameraSourceInfo: SourceInfo, + cutDirectly: boolean, + rank: number + ): IBlueprintActionManifest { + const sourceDefinition = SourceInfoToSourceDefinition(cameraSourceInfo) as SourceDefinitionKam const userData: ActionCutToCamera = { type: AdlibActionType.CUT_TO_CAMERA, - queue, + cutDirectly, sourceDefinition } - blueprintActions.push({ + return { externalId: generateExternalId(context, userData), actionId: AdlibActionType.CUT_TO_CAMERA, userData, @@ -252,11 +264,11 @@ function getGlobalAdlibActionsOfftube( sourceLayerId: OfftubeSourceLayer.PgmCam, outputLayerId: SharedOutputLayer.PGM, content: {}, - tags: queue ? [AdlibTags.OFFTUBE_SET_CAM_NEXT, AdlibTags.ADLIB_QUEUE_NEXT] : [AdlibTags.ADLIB_CUT_DIRECT], + tags: cutDirectly ? [AdlibTags.ADLIB_CUT_DIRECT] : [AdlibTags.OFFTUBE_SET_CAM_NEXT, AdlibTags.ADLIB_QUEUE_NEXT], currentPieceTags: [GetTagForKam(sourceDefinition)], nextPieceTags: [GetTagForKam(sourceDefinition)] } - }) + } } function makeRemoteAction(sourceInfo: SourceInfo, rank: number) { @@ -483,14 +495,9 @@ function getGlobalAdlibActionsOfftube( config.sources.cameras .slice(0, 5) // the first x cameras to create INP1/2/3 cam-adlibs from - .forEach((o) => { - makeCutCameraActions(o, false, globalRank++) - }) - - config.sources.cameras - .slice(0, 5) // the first x cameras to create preview cam-adlibs from - .forEach((o) => { - makeCutCameraActions(o, true, globalRank++) + .forEach((cameraSourceInfo) => { + blueprintActions.push(makeCutDirectlyCameraAction(cameraSourceInfo, globalRank++)) + blueprintActions.push(makeQueueAsNextCameraAction(cameraSourceInfo, globalRank++)) }) config.sources.cameras From 2984fb783fe7f1cb0c9e94ad5169ecc45003b4b4 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Mon, 27 Mar 2023 08:49:51 +0200 Subject: [PATCH 66/86] fix: Refactors the use of SelectedGfxSetupName to use GfxDefaults and includes a migration to move the values --- src/tv2-common/blueprintConfig.ts | 2 +- src/tv2-common/helpers/config.ts | 6 +-- src/tv2-common/migrations/index.ts | 37 ++++++++++++++++++- .../__tests__/config-manifest.spec.ts | 1 - src/tv2_afvd_showstyle/__tests__/configs.ts | 1 - src/tv2_afvd_showstyle/helpers/config.ts | 1 - src/tv2_afvd_showstyle/migrations/index.ts | 6 +++ .../__tests__/config-manifest.spec.ts | 2 +- 8 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index dfe25e83..29985df8 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -166,7 +166,7 @@ export interface TV2ShowstyleBlueprintConfigBase { LYDConfig: TableConfigItemValue GfxSchemaTemplates: TableConfigGfxSchema[] GfxSetups: TableConfigGfxSetup[] - SelectedGfxSetupName: string + GfxDefaults: TableConfigItemGfxDefaults[] } export interface TV2BlueprintConfigBase diff --git a/src/tv2-common/helpers/config.ts b/src/tv2-common/helpers/config.ts index fd9c2cb6..fc101571 100644 --- a/src/tv2-common/helpers/config.ts +++ b/src/tv2-common/helpers/config.ts @@ -1,5 +1,5 @@ import { ICommonContext } from 'blueprints-integration' -import { TableConfigGfxSetup, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' +import { TableConfigGfxSetup, TV2ShowstyleBlueprintConfigBase} from 'tv2-common' export interface DVEConfigInput { // _id: string @@ -18,10 +18,10 @@ export function findGfxSetup tableConfigGfxSetup.Name === config.SelectedGfxSetupName + tableConfigGfxSetup => tableConfigGfxSetup.Name === config.GfxDefaults[0].GfxSetup ) if (!foundTableConfigGfxSetup) { - context.logWarning(`No GFX setup found for profile: ${config.SelectedGfxSetupName}`) + context.logWarning(`No GFX setup found for profile: ${config.GfxDefaults[0].GfxSetup}`) return fallbackGfxSetup } return foundTableConfigGfxSetup diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index 2086cd88..4df6890a 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -7,7 +7,11 @@ import { MigrationStepStudio, TableConfigItemValue } from 'blueprints-integration' -import { TableConfigItemGfxDesignTemplate, TableConfigItemSourceMappingWithSisyfos } from 'tv2-common' +import { + TableConfigItemGfxDefaults, + TableConfigItemGfxDesignTemplate, + TableConfigItemSourceMappingWithSisyfos +} from 'tv2-common' import _ = require('underscore') import { literal } from '../util' import { TableConfigItemGfxTemplateWithDesign } from './graphic-defaults' @@ -173,6 +177,37 @@ export function mapGfxTemplateToDesignTemplateAndDeleteOriginals( }) } +export function moveSelectedGfxSetupNameToGfxDefaults( + versionStr: string, + standaloneValue: string, + targetTable: string +) { + return literal({ + id: `${versionStr}.moveStandaloneValueToTableValue.${standaloneValue}`, + version: versionStr, + canBeRunAutomatically: true, + validate: (context: MigrationContextShowStyle) => { + const singleValue = (context.getBaseConfig(standaloneValue) as unknown) as string | undefined + const designatedTable = (context.getBaseConfig(targetTable) as unknown) as TableConfigItemGfxDefaults | undefined + + if (!singleValue || !designatedTable) { + return false + } + + return singleValue && !designatedTable.GfxSetup + }, + migrate: (context: MigrationContextShowStyle) => { + const singleValue = (context.getBaseConfig(standaloneValue) as unknown) as string + const designatedTable = (context.getBaseConfig(targetTable) as unknown) as TableConfigItemGfxDefaults + + const table = designatedTable + table.GfxSetup = singleValue + + context.setBaseConfig(targetTable, (table as unknown) as ConfigItemValue) + } + }) +} + export function addSourceToSourcesConfig( versionStr: string, studio: string, diff --git a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts index 563f9494..d8fedfec 100644 --- a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts @@ -14,7 +14,6 @@ const blankShowStyleConfig: ShowStyleConfig = { CasparCGLoadingClip: '', Transitions: [{ Transition: '1' }, { Transition: '2' }], ShowstyleTransition: 'CUT', - SelectedGfxSetupName: '', GfxSetups: [], GfxSchemaTemplates: [], GfxShowMapping: [], diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index 4cc5f2fa..ada47f03 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -267,7 +267,6 @@ export const defaultShowStyleConfig: ShowStyleConfig = { FadeOut: 0 } ], - SelectedGfxSetupName: 'SomeProfile', GfxSetups: [DEFAULT_GFX_SETUP], Transitions: [{ Transition: '1' }, { Transition: '2' }], ShowstyleTransition: 'CUT', diff --git a/src/tv2_afvd_showstyle/helpers/config.ts b/src/tv2_afvd_showstyle/helpers/config.ts index ee93f424..7e545eb8 100644 --- a/src/tv2_afvd_showstyle/helpers/config.ts +++ b/src/tv2_afvd_showstyle/helpers/config.ts @@ -21,7 +21,6 @@ export interface BlueprintConfig extends BlueprintConfigBase { export interface ShowStyleConfig extends TV2ShowstyleBlueprintConfigBase { WipesConfig: TableConfigItemValue - SelectedGfxSetupName: string GfxSetups: GalleryTableConfigGfxSetup[] GfxShowMapping: TableConfigItemGfxShowMapping[] GfxDefaults: TableConfigItemGfxDefaults[] diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 8fef3da8..60177f74 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -5,6 +5,7 @@ import { GetDefaultAdLibTriggers, GetDSKSourceLayerNames, mapGfxTemplateToDesignTemplateAndDeleteOriginals, + moveSelectedGfxSetupNameToGfxDefaults, RemoveOldShortcuts, removeSourceLayer, renameTableColumn, @@ -265,6 +266,11 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ renameTableColumn('1.7.9', 'OverlayShowMapping', 'GraphicsSetup', 'GfxSetup'), renameTableId('1.7.9', 'OverlayShowMapping', 'GfxShowMapping'), + /** + * 1.8.0 Move SelectedGfxSetupName to GFX Defaults + */ + moveSelectedGfxSetupNameToGfxDefaults('1.8.0', 'SelectedGfxSetupName', 'GfxDefaults'), + // Fill in any layers that did not exist before // Note: These should only be run as the very final step of all migrations. otherwise they will add items too early, and confuse old migrations ...getSourceLayerDefaultsMigrationSteps(VERSION), diff --git a/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts index d20508f4..9ebd6535 100644 --- a/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts @@ -16,7 +16,7 @@ const blankShowStyleConfig: OfftubeShowStyleConfig = { MakeAdlibsForFulls: true, GfxSchemaTemplates: [], GfxSetups: [], - SelectedGfxSetupName: '' + GfxDefaults: [] } describe('Config Manifest', () => { From d819e689bc7ade78de88bec1489ec77b323350c8 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Mon, 27 Mar 2023 10:23:11 +0200 Subject: [PATCH 67/86] SOF-1374 Update Sisyfos metadata for cutting a live directly --- src/tv2-common/actions/executeAction.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 8a9bdf3a..e8c7060d 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1167,7 +1167,8 @@ async function executeActionCutToRemote< ? { sisyfosLayers: sourceInfo.sisyfosLayers ?? [], wantsToPersistAudio: sourceInfo.wantsToPersistAudio, - acceptPersistAudio: sourceInfo.acceptPersistAudio + acceptPersistAudio: sourceInfo.acceptPersistAudio, + isPieceInjectedInPart: userData.cutDirectly } : { sisyfosLayers: [] } From e17cbe058a833562207107fa135f67d13b967c7c Mon Sep 17 00:00:00 2001 From: Krzysztof Zegzula Date: Tue, 28 Mar 2023 08:51:39 +0200 Subject: [PATCH 68/86] fix: SOF-1407 implement missing Atem.updateUnpopulatedDveBoxes (#197) * fix: SOF-1404 controlling ATEM's USK above 1 * fix: SOF-1407 implement missing Atem.updateUnpopulatedDveBoxes servers in DVEs would not work without it * Revert "fix: SOF-1404 controlling ATEM's USK above 1" This reverts commit 5cf772ac7eae9cefefab90b20c2045f768bb6e95. --- src/tv2-common/content/dve.ts | 2 +- src/tv2-common/content/server.ts | 13 ++- src/tv2-common/videoSwitchers/Atem.ts | 17 ++- src/tv2-common/videoSwitchers/TriCaster.ts | 2 +- .../videoSwitchers/__tests__/Atem.spec.ts | 110 ++++++++++++++---- .../__tests__/TriCaster.spec.ts | 2 +- src/tv2-common/videoSwitchers/types.ts | 5 +- 7 files changed, 114 insertions(+), 37 deletions(-) diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index e2b2184c..493e3cd7 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -268,7 +268,7 @@ export function MakeContentDVE2< hasServer = true setBoxSource(box, boxSources, { sourceLayerType: SourceLayerType.VT, - port: -1 + port: SpecialInput.AB_PLACEHOLDER }) break } diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 4f1088b5..c8c1c557 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -1,5 +1,12 @@ import { TimelineObjectCoreExt, TSR, VTContent, WithTimeline } from 'blueprints-integration' -import { GetSisyfosTimelineObjForServer, literal, PartDefinition, ShowStyleContext, TransitionStyle } from 'tv2-common' +import { + GetSisyfosTimelineObjForServer, + literal, + PartDefinition, + ShowStyleContext, + SpecialInput, + TransitionStyle +} from 'tv2-common' import { AbstractLLayer, GetEnableClassForServer } from 'tv2-constants' import { TV2ShowStyleConfig } from '../blueprintConfig' import { TimelineBlueprintExt } from '../onTimelineGenerate' @@ -107,7 +114,7 @@ function GetServerTimeline( context.videoSwitcher.getAuxTimelineObject({ layer: context.uniformConfig.switcherLLayers.nextServerAux, content: { - input: -1 + input: SpecialInput.AB_PLACEHOLDER }, metaData: { mediaPlayerSession: contentProps.mediaPlayerSession @@ -131,7 +138,7 @@ export function CutToServer( }, priority: 1, content: { - input: -1, + input: SpecialInput.AB_PLACEHOLDER, transition: partDefinition.transition?.style ?? TransitionStyle.CUT, transitionDuration: partDefinition.transition?.duration }, diff --git a/src/tv2-common/videoSwitchers/Atem.ts b/src/tv2-common/videoSwitchers/Atem.ts index ba769af2..59802b3d 100644 --- a/src/tv2-common/videoSwitchers/Atem.ts +++ b/src/tv2-common/videoSwitchers/Atem.ts @@ -1,4 +1,4 @@ -import { TimelineObjectCoreExt, TSR } from 'blueprints-integration' +import { TSR } from 'blueprints-integration' import { literal } from 'tv2-common' import { SwitcherDveLLayer } from 'tv2-constants' import _ = require('underscore') @@ -207,10 +207,19 @@ export class Atem extends VideoSwitcherBase { ) } public updateUnpopulatedDveBoxes( - _timelineObject: TimelineObjectCoreExt, - _input: number | SpecialInput + timelineObject: TSR.TSRTimelineObj, + input: number | SpecialInput ): TSR.TSRTimelineObj { - throw new Error('Method not implemented.') + if (!this.isDveBoxes(timelineObject)) { + this.logWrongTimelineObjectType(timelineObject, this.updateUnpopulatedDveBoxes.name) + return timelineObject + } + for (const box of timelineObject.content.ssrc.boxes) { + if (box.source === SpecialInput.AB_PLACEHOLDER) { + box.source = this.getInputNumber(input) + } + } + return timelineObject } private getBaseProperties( diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index eeefbfb2..e367467d 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -210,7 +210,7 @@ export class TriCaster extends VideoSwitcherBase { } public assignInputIfPlaceholder(layer: TSR.TriCasterLayer, input: number | SpecialInput): void { - const dveServerPlaceholder = 'input-1' + const dveServerPlaceholder = this.getInputName(SpecialInput.AB_PLACEHOLDER) if (layer.input !== dveServerPlaceholder) { return } diff --git a/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts index f5f6548f..92331b2b 100644 --- a/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/Atem.spec.ts @@ -4,12 +4,12 @@ import { makeMockGalleryContext } from '../../../__mocks__/context' import { prefixLayer } from '../../../tv2-common/__tests__/testUtil' import { TV2StudioConfigBase } from '../../../tv2-common/blueprintConfig' import { AtemSourceIndex } from '../../../types/atem' -import { AuxProps, DskProps, MixEffectProps, SwitcherType, TransitionStyle } from '../types' +import { AuxProps, DskProps, MixEffectProps, SpecialInput, SwitcherType, TransitionStyle } from '../types' import { VideoSwitcherBase } from '../VideoSwitcher' const DURATION: number = 50 -function setupAtem(studioConfigOverrides?: Partial) { +function createTestee(studioConfigOverrides?: Partial) { const context = makeMockGalleryContext({ studioConfig: { SwitcherType: SwitcherType.ATEM, ...studioConfigOverrides } }) @@ -25,7 +25,7 @@ describe('ATEM', () => { } } test('sets timeline object defaults', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getMixEffectTimelineObject(DEFAULT_ME) expect(timelineObject).toMatchObject({ id: '', @@ -39,7 +39,7 @@ describe('ATEM', () => { }) test('sets classes', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getMixEffectTimelineObject({ ...DEFAULT_ME, classes: ['classA', 'classB'] @@ -50,7 +50,7 @@ describe('ATEM', () => { }) test('sets metaData', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getMixEffectTimelineObject({ ...DEFAULT_ME, metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } @@ -61,7 +61,7 @@ describe('ATEM', () => { }) test('sets layer prefix', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getMixEffectTimelineObject(DEFAULT_ME) expect(timelineObject).toMatchObject({ layer: prefixLayer(SwitcherMixEffectLLayer.PROGRAM) @@ -69,7 +69,7 @@ describe('ATEM', () => { }) test('sets programInput when no transition provided', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getMixEffectTimelineObject(DEFAULT_ME) expect(timelineObject).toMatchObject({ content: { @@ -81,7 +81,7 @@ describe('ATEM', () => { }) test('sets input when CUT transition provided', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.PROGRAM, content: { @@ -100,7 +100,7 @@ describe('ATEM', () => { }) test('sets previewInput', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.PROGRAM, content: { @@ -117,7 +117,7 @@ describe('ATEM', () => { }) test('supports MIX', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.PROGRAM, content: { @@ -142,7 +142,7 @@ describe('ATEM', () => { }) test('supports WIPE', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.PROGRAM, content: { @@ -168,7 +168,7 @@ describe('ATEM', () => { test('supports WIPE for GFX', () => { const wipeRate = 22 - const atem = setupAtem({ + const atem = createTestee({ HTMLGraphics: { GraphicURL: 'donotcare', TransitionSettings: { wipeRate, borderSoftness: 7500, loopOutTransitionDuration: 15 }, @@ -201,7 +201,7 @@ describe('ATEM', () => { }) test('supports DIP', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.PROGRAM, content: { @@ -235,7 +235,7 @@ describe('ATEM', () => { }) function assertDipInputValueFromConfig(dipInputSource: number) { - const atem = setupAtem({ + const atem = createTestee({ SwitcherSource: { Dip: dipInputSource, Default: 1, @@ -269,7 +269,7 @@ describe('ATEM', () => { } test('supports keyers', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.PROGRAM, content: { @@ -319,7 +319,7 @@ describe('ATEM', () => { } } test('sets timeline object defaults', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getAuxTimelineObject(DEFAULT_AUX) expect(timelineObject).toMatchObject({ id: '', @@ -333,7 +333,7 @@ describe('ATEM', () => { }) test('sets classes', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getAuxTimelineObject({ ...DEFAULT_AUX, classes: ['classA', 'classB'] @@ -344,7 +344,7 @@ describe('ATEM', () => { }) test('sets metaData', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getAuxTimelineObject({ ...DEFAULT_AUX, metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } @@ -355,7 +355,7 @@ describe('ATEM', () => { }) test('sets layer prefix', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getAuxTimelineObject(DEFAULT_AUX) expect(timelineObject).toMatchObject({ layer: prefixLayer(SwitcherAuxLLayer.CLEAN) @@ -363,7 +363,7 @@ describe('ATEM', () => { }) test('sets aux', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getAuxTimelineObject(DEFAULT_AUX) @@ -394,7 +394,7 @@ describe('ATEM', () => { } } test('sets timeline object defaults', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getDskTimelineObject(DEFAULT_DSK) expect(timelineObject).toMatchObject({ id: '', @@ -408,7 +408,7 @@ describe('ATEM', () => { }) test('sets classes', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getDskTimelineObject({ ...DEFAULT_DSK, classes: ['classA', 'classB'] @@ -419,7 +419,7 @@ describe('ATEM', () => { }) test('sets metaData', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getDskTimelineObject({ ...DEFAULT_DSK, metaData: { context: 'Some Context', mediaPlayerSession: 'mySession' } @@ -430,7 +430,7 @@ describe('ATEM', () => { }) test('sets layer prefix', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getDskTimelineObject(DEFAULT_DSK) expect(timelineObject).toMatchObject({ layer: prefixLayer('dsk_1') @@ -438,7 +438,7 @@ describe('ATEM', () => { }) test('enables DSK', () => { - const atem = setupAtem() + const atem = createTestee() const timelineObject = atem.getDskTimelineObject(DEFAULT_DSK) @@ -453,4 +453,64 @@ describe('ATEM', () => { }) }) }) + + describe('updateUnpopulatedDveBoxes', () => { + it('updates only unpopulated boxes', () => { + const testee = createTestee() + const timelineObject: TSR.TimelineObjAtemSsrc = { + id: '', + enable: {}, + layer: '', + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.SSRC, + ssrc: { + boxes: [ + { + enabled: false, + source: 5 + }, + { + enabled: true, + source: SpecialInput.AB_PLACEHOLDER + }, + { + enabled: false, + source: SpecialInput.AB_PLACEHOLDER + }, + { + enabled: true, + source: 2 + } + ] + } + } + } + const updatedTimelineObject = testee.updateUnpopulatedDveBoxes(timelineObject, 8) + expect(updatedTimelineObject).toMatchObject({ + content: { + ssrc: { + boxes: [ + { + enabled: false, + source: 5 + }, + { + enabled: true, + source: 8 + }, + { + enabled: false, + source: 8 + }, + { + enabled: true, + source: 2 + } + ] + } + } + }) + }) + }) }) diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index 0df24862..3d0caedf 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -491,7 +491,7 @@ describe('TriCaster', () => { me: { layers: { [layerName]: { - input: 'input-1' + input: `input${SpecialInput.AB_PLACEHOLDER}` } } } diff --git a/src/tv2-common/videoSwitchers/types.ts b/src/tv2-common/videoSwitchers/types.ts index d4e09642..74d8abba 100644 --- a/src/tv2-common/videoSwitchers/types.ts +++ b/src/tv2-common/videoSwitchers/types.ts @@ -10,6 +10,9 @@ export enum SwitcherType { /** Using Atem values for compatibility */ export enum SpecialInput { + /** AB input awaiting assignment in onTimelineGenerate */ + AB_PLACEHOLDER = -1, + BLACK = AtemSourceIndex.Blk, ME1_PROGRAM = AtemSourceIndex.Prg1, ME2_PROGRAM = AtemSourceIndex.Prg2, @@ -37,8 +40,6 @@ export enum TemporalPriority { DVE = 1 // to place DVE commands afer regular M/E and AUX commands (ATEM integration does that by default) } -export enum SwitcherLLayer {} - export const TIMELINE_OBJECT_DEFAULTS = { id: '', enable: { start: 0 }, From 379f0cf7a4c44151fd963a032d8f8a867b13fa90 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Tue, 28 Mar 2023 13:16:25 +0200 Subject: [PATCH 69/86] fix: Creates migrations for blueprint and variant blueprints to transfer the SelectedGfxSetupName to GfxDefaults --- package.json | 2 +- src/tv2-common/helpers/config.ts | 2 +- src/tv2-common/migrations/index.ts | 70 ++++++++++++++----- src/tv2-common/showstyle/config-manifests.ts | 4 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 2 +- src/tv2_afvd_showstyle/migrations/index.ts | 2 + src/tv2_offtube_showstyle/config-manifests.ts | 5 +- 7 files changed, 61 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 5cbd39d3..b6227d1a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tv2-sofie-blueprints-inews", - "version": "1.7.9", + "version": "1.8.0", "repository": "https://github.com/olzzon/tv2-sofie-blueprints-inews", "license": "MIT", "private": true, diff --git a/src/tv2-common/helpers/config.ts b/src/tv2-common/helpers/config.ts index fc101571..22d47067 100644 --- a/src/tv2-common/helpers/config.ts +++ b/src/tv2-common/helpers/config.ts @@ -1,5 +1,5 @@ import { ICommonContext } from 'blueprints-integration' -import { TableConfigGfxSetup, TV2ShowstyleBlueprintConfigBase} from 'tv2-common' +import { TableConfigGfxSetup, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' export interface DVEConfigInput { // _id: string diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index 4df6890a..d4e448fe 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -1,3 +1,4 @@ +import { BasicConfigItemValue, IBlueprintShowStyleVariant } from '@sofie-automation/blueprints-integration' import { BlueprintMappings, ConfigItemValue, @@ -7,11 +8,7 @@ import { MigrationStepStudio, TableConfigItemValue } from 'blueprints-integration' -import { - TableConfigItemGfxDefaults, - TableConfigItemGfxDesignTemplate, - TableConfigItemSourceMappingWithSisyfos -} from 'tv2-common' +import { TableConfigItemGfxDesignTemplate, TableConfigItemSourceMappingWithSisyfos } from 'tv2-common' import _ = require('underscore') import { literal } from '../util' import { TableConfigItemGfxTemplateWithDesign } from './graphic-defaults' @@ -177,33 +174,68 @@ export function mapGfxTemplateToDesignTemplateAndDeleteOriginals( }) } -export function moveSelectedGfxSetupNameToGfxDefaults( +export function moveSelectedGfxSetupNameToGfxDefaults(versionStr: string, fromValue: string, targetTable: string) { + return literal({ + id: `${versionStr}.moveSelectedGfxSetupName.${fromValue}.ToTable.${targetTable}`, + version: versionStr, + canBeRunAutomatically: true, + validate: (context: MigrationContextShowStyle) => { + const singleValue = (context.getBaseConfig(fromValue) as unknown) as string + const designatedTable = (context.getBaseConfig(targetTable) as unknown) as TableConfigItemValue | undefined + + if (!singleValue || !Array.isArray(designatedTable)) { + return false + } + + return singleValue + }, + migrate: (context: MigrationContextShowStyle) => { + const singleValue = context.getBaseConfig(fromValue) as BasicConfigItemValue + const designatedTable = (context.getBaseConfig(targetTable) as unknown) as TableConfigItemValue + const setupName = 'DefaultSetupName' + + designatedTable[0][setupName] = singleValue + + context.setBaseConfig(targetTable, (designatedTable as unknown) as ConfigItemValue) + context.removeBaseConfig(fromValue) + } + }) +} + +export function moveSelectedGfxSetupNameToGfxDefaultsInVariants( versionStr: string, standaloneValue: string, targetTable: string ) { return literal({ - id: `${versionStr}.moveStandaloneValueToTableValue.${standaloneValue}`, + id: `${versionStr}.moveSelectedGfxSetupNameToGfxDefaultsInVariants.${standaloneValue}.ToTable.${targetTable}`, version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const singleValue = (context.getBaseConfig(standaloneValue) as unknown) as string | undefined - const designatedTable = (context.getBaseConfig(targetTable) as unknown) as TableConfigItemGfxDefaults | undefined - - if (!singleValue || !designatedTable) { - return false - } + const allVariants = context.getAllVariants() + const checkVariants = allVariants.some((variant: IBlueprintShowStyleVariant) => { + return context.getVariantConfig(variant._id, targetTable) as TableConfigItemValue + }) - return singleValue && !designatedTable.GfxSetup + return checkVariants }, migrate: (context: MigrationContextShowStyle) => { - const singleValue = (context.getBaseConfig(standaloneValue) as unknown) as string - const designatedTable = (context.getBaseConfig(targetTable) as unknown) as TableConfigItemGfxDefaults + const allVariants = context.getAllVariants() + allVariants.forEach((variant: IBlueprintShowStyleVariant) => { + const singleValue = context.getVariantConfig(variant._id, standaloneValue) as BasicConfigItemValue + let designatedTable = context.getVariantConfig(variant._id, targetTable) as TableConfigItemValue + const setupName = 'DefaultSetupName' + + if (designatedTable === undefined) { + designatedTable = [{ ['']: singleValue, _id: '' }] + } - const table = designatedTable - table.GfxSetup = singleValue + designatedTable[0][setupName] = singleValue + const updatedVariant = variant - context.setBaseConfig(targetTable, (table as unknown) as ConfigItemValue) + updatedVariant.blueprintConfig[targetTable] = designatedTable + context.updateVariant(variant._id, updatedVariant) + }) } }) } diff --git a/src/tv2-common/showstyle/config-manifests.ts b/src/tv2-common/showstyle/config-manifests.ts index 66556dd9..34c8316c 100644 --- a/src/tv2-common/showstyle/config-manifests.ts +++ b/src/tv2-common/showstyle/config-manifests.ts @@ -5,7 +5,7 @@ export enum CommonConfigId { GRAPHICS_SETUPS_TABLE_ID = 'GfxSetups', GRAPHICS_SETUPS_NAME_COLUMN_ID = 'Name', GFX_DEFAULTS_TABLE_ID = 'GfxDefaults', - DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID = 'SelectedGfxSetupName', + DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID = 'DefaultSetupName', DEFAULTS_SCHEMA_COLUMN_ID = 'DefaultSchema', DEFAULTS_DESIGN_COLUMN_ID = 'DefaultDesign', GFX_SHOW_MAPPING_TABLE_ID = 'GfxShowMapping', @@ -48,7 +48,7 @@ export const getGfxSetupsEntries = (columns: ConfigManifestEntryTable['columns'] } ] -const GFX_DEFAULT_VALUES: TableConfigItemGfxDefaults[] = [ +export const GFX_DEFAULT_VALUES: TableConfigItemGfxDefaults[] = [ { GfxSetup: '', DefaultSchema: [''], diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index ada47f03..738cdcfc 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -272,7 +272,7 @@ export const defaultShowStyleConfig: ShowStyleConfig = { ShowstyleTransition: 'CUT', GfxSchemaTemplates: [], GfxShowMapping: [], - GfxDefaults: [] + GfxDefaults: [{ GfxSetup: 'SomeProfile', DefaultDesign: [], DefaultSchema: [] }] } export const EMPTY_SOURCE_CONFIG = { diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 60177f74..61655007 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -6,6 +6,7 @@ import { GetDSKSourceLayerNames, mapGfxTemplateToDesignTemplateAndDeleteOriginals, moveSelectedGfxSetupNameToGfxDefaults, + moveSelectedGfxSetupNameToGfxDefaultsInVariants, RemoveOldShortcuts, removeSourceLayer, renameTableColumn, @@ -270,6 +271,7 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ * 1.8.0 Move SelectedGfxSetupName to GFX Defaults */ moveSelectedGfxSetupNameToGfxDefaults('1.8.0', 'SelectedGfxSetupName', 'GfxDefaults'), + moveSelectedGfxSetupNameToGfxDefaultsInVariants('1.8.0', 'SelectedGfxSetupName', 'GfxDefaults'), // Fill in any layers that did not exist before // Note: These should only be run as the very final step of all migrations. otherwise they will add items too early, and confuse old migrations diff --git a/src/tv2_offtube_showstyle/config-manifests.ts b/src/tv2_offtube_showstyle/config-manifests.ts index 24ec9cb6..9f6ba643 100644 --- a/src/tv2_offtube_showstyle/config-manifests.ts +++ b/src/tv2_offtube_showstyle/config-manifests.ts @@ -1,5 +1,5 @@ import { ConfigManifestEntry, ConfigManifestEntryType, TSR } from 'blueprints-integration' -import { DEFAULT_GRAPHICS, getGfxSetupsEntries } from 'tv2-common' +import { DEFAULT_GRAPHICS, getGfxDefaults, getGfxSetupsEntries } from 'tv2-common' export const dveStylesManifest: ConfigManifestEntry = { id: 'DVEStyles', @@ -583,5 +583,6 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ ] }, ...gfxSchemaTemplates, - ...getGfxSetupsEntries([]) + ...getGfxSetupsEntries([]), + getGfxDefaults ] From 859455102cda40f3a844659e47d05233a42671e0 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Tue, 28 Mar 2023 13:25:43 +0200 Subject: [PATCH 70/86] refactor: Uses new naming for blueprints-integration method --- src/tv2-common/showstyle/config-manifests.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/showstyle/config-manifests.ts b/src/tv2-common/showstyle/config-manifests.ts index 34c8316c..d2be5718 100644 --- a/src/tv2-common/showstyle/config-manifests.ts +++ b/src/tv2-common/showstyle/config-manifests.ts @@ -82,7 +82,7 @@ export const getGfxDefaults: ConfigManifestEntry = { name: 'Default Skema', rank: 1, description: 'The Skema options based on the GFX Setup', - type: ConfigManifestEntryType.FILTER_SELECTED_FROM_COLUMN, + type: ConfigManifestEntryType.FILTER_DEFAULTS_FROM_SHOW_MAPPING, targetTableId: CommonConfigId.GFX_DEFAULTS_TABLE_ID, targetCompareColumnId: CommonConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, sourceTableId: CommonConfigId.GFX_SHOW_MAPPING_TABLE_ID, @@ -97,7 +97,7 @@ export const getGfxDefaults: ConfigManifestEntry = { name: 'Default Design', rank: 2, description: 'The Design options based on the Default Skema or GFX Setup', - type: ConfigManifestEntryType.FILTER_SELECTED_FROM_COLUMN, + type: ConfigManifestEntryType.FILTER_DEFAULTS_FROM_SHOW_MAPPING, targetTableId: CommonConfigId.GFX_DEFAULTS_TABLE_ID, targetCompareColumnId: CommonConfigId.DEFAULTS_SCHEMA_COLUMN_ID, sourceTableId: CommonConfigId.GFX_SHOW_MAPPING_TABLE_ID, From cff736ba9cd66eeb5ef0703368d5f35616362d7b Mon Sep 17 00:00:00 2001 From: Rasmus Date: Wed, 29 Mar 2023 12:30:08 +0200 Subject: [PATCH 71/86] fix: Makes changes to the variant migraiont validation to accomodate the bug fix made in core --- src/tv2-common/migrations/index.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index d4e448fe..743d5efd 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -204,25 +204,27 @@ export function moveSelectedGfxSetupNameToGfxDefaults(versionStr: string, fromVa export function moveSelectedGfxSetupNameToGfxDefaultsInVariants( versionStr: string, - standaloneValue: string, + fromValue: string, targetTable: string ) { return literal({ - id: `${versionStr}.moveSelectedGfxSetupNameToGfxDefaultsInVariants.${standaloneValue}.ToTable.${targetTable}`, + id: `${versionStr}.moveSelectedGfxSetupNameToGfxDefaultsInVariants.${fromValue}.ToTable.${targetTable}`, version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { const allVariants = context.getAllVariants() - const checkVariants = allVariants.some((variant: IBlueprintShowStyleVariant) => { - return context.getVariantConfig(variant._id, targetTable) as TableConfigItemValue + const checkForDefaultsTransfer = allVariants.some((variant: IBlueprintShowStyleVariant) => { + const defaultsTable = context.getVariantConfig(variant._id, targetTable) as TableConfigItemValue + const setupNameTable = context.getVariantConfig(variant._id, fromValue) as ConfigItemValue + return setupNameTable && !defaultsTable }) - return checkVariants + return checkForDefaultsTransfer }, migrate: (context: MigrationContextShowStyle) => { const allVariants = context.getAllVariants() allVariants.forEach((variant: IBlueprintShowStyleVariant) => { - const singleValue = context.getVariantConfig(variant._id, standaloneValue) as BasicConfigItemValue + const singleValue = context.getVariantConfig(variant._id, fromValue) as BasicConfigItemValue let designatedTable = context.getVariantConfig(variant._id, targetTable) as TableConfigItemValue const setupName = 'DefaultSetupName' From 4ef6a2dba0823fc5dabcb8fbc0d2f2332be8c717 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Thu, 30 Mar 2023 14:52:42 +0200 Subject: [PATCH 72/86] fix: Changed to accomodate the refactor in the core-PR --- package.json | 2 +- src/tv2-common/migrations/index.ts | 2 +- src/tv2-common/showstyle/config-manifests.ts | 30 ++++++++++++------- src/tv2_afvd_showstyle/migrations/index.ts | 4 +-- src/tv2_offtube_showstyle/migrations/index.ts | 8 +++++ 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index b6227d1a..be3502cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tv2-sofie-blueprints-inews", - "version": "1.8.0", + "version": "1.8.2", "repository": "https://github.com/olzzon/tv2-sofie-blueprints-inews", "license": "MIT", "private": true, diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index 743d5efd..70b4dbfd 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -229,7 +229,7 @@ export function moveSelectedGfxSetupNameToGfxDefaultsInVariants( const setupName = 'DefaultSetupName' if (designatedTable === undefined) { - designatedTable = [{ ['']: singleValue, _id: '' }] + designatedTable = [{ [setupName]: singleValue, _id: '' }] } designatedTable[0][setupName] = singleValue diff --git a/src/tv2-common/showstyle/config-manifests.ts b/src/tv2-common/showstyle/config-manifests.ts index d2be5718..5bf566f5 100644 --- a/src/tv2-common/showstyle/config-manifests.ts +++ b/src/tv2-common/showstyle/config-manifests.ts @@ -82,12 +82,15 @@ export const getGfxDefaults: ConfigManifestEntry = { name: 'Default Skema', rank: 1, description: 'The Skema options based on the GFX Setup', - type: ConfigManifestEntryType.FILTER_DEFAULTS_FROM_SHOW_MAPPING, - targetTableId: CommonConfigId.GFX_DEFAULTS_TABLE_ID, - targetCompareColumnId: CommonConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, + type: ConfigManifestEntryType.SELECT_FROM_TABLE_ENTRY_WITH_COMPARISON_MAPPINGS, + comparisonMappings: [ + { + targetColumnId: CommonConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, + sourceColumnId: CommonConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID + } + ], sourceTableId: CommonConfigId.GFX_SHOW_MAPPING_TABLE_ID, - sourceCompareColumnId: CommonConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID, - sourceCollectColumnId: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, + sourceColumnIdWithValue: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, multiple: false, required: false, defaultVal: '' @@ -97,12 +100,19 @@ export const getGfxDefaults: ConfigManifestEntry = { name: 'Default Design', rank: 2, description: 'The Design options based on the Default Skema or GFX Setup', - type: ConfigManifestEntryType.FILTER_DEFAULTS_FROM_SHOW_MAPPING, - targetTableId: CommonConfigId.GFX_DEFAULTS_TABLE_ID, - targetCompareColumnId: CommonConfigId.DEFAULTS_SCHEMA_COLUMN_ID, + type: ConfigManifestEntryType.SELECT_FROM_TABLE_ENTRY_WITH_COMPARISON_MAPPINGS, + comparisonMappings: [ + { + targetColumnId: CommonConfigId.DEFAULTS_SCHEMA_COLUMN_ID, + sourceColumnId: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID + }, + { + targetColumnId: CommonConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, + sourceColumnId: CommonConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID + } + ], sourceTableId: CommonConfigId.GFX_SHOW_MAPPING_TABLE_ID, - sourceCompareColumnId: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, - sourceCollectColumnId: CommonConfigId.GFX_SHOW_MAPPING_DESIGN_COLUMN_ID, + sourceColumnIdWithValue: CommonConfigId.GFX_SHOW_MAPPING_DESIGN_COLUMN_ID, multiple: false, required: false, defaultVal: '' diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 61655007..978293a3 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -270,8 +270,8 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ /** * 1.8.0 Move SelectedGfxSetupName to GFX Defaults */ - moveSelectedGfxSetupNameToGfxDefaults('1.8.0', 'SelectedGfxSetupName', 'GfxDefaults'), - moveSelectedGfxSetupNameToGfxDefaultsInVariants('1.8.0', 'SelectedGfxSetupName', 'GfxDefaults'), + moveSelectedGfxSetupNameToGfxDefaults('1.8.2', 'SelectedGfxSetupName', 'GfxDefaults'), + moveSelectedGfxSetupNameToGfxDefaultsInVariants('1.8.2', 'SelectedGfxSetupName', 'GfxDefaults'), // Fill in any layers that did not exist before // Note: These should only be run as the very final step of all migrations. otherwise they will add items too early, and confuse old migrations diff --git a/src/tv2_offtube_showstyle/migrations/index.ts b/src/tv2_offtube_showstyle/migrations/index.ts index ac39bdec..6471684e 100644 --- a/src/tv2_offtube_showstyle/migrations/index.ts +++ b/src/tv2_offtube_showstyle/migrations/index.ts @@ -5,6 +5,8 @@ import { GetDefaultAdLibTriggers, GetDSKSourceLayerNames, mapGfxTemplateToDesignTemplateAndDeleteOriginals, + moveSelectedGfxSetupNameToGfxDefaults, + moveSelectedGfxSetupNameToGfxDefaultsInVariants, RemoveOldShortcuts, removeSourceLayer, renameSourceLayer, @@ -291,6 +293,12 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ renameBlueprintConfiguration('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), renameBlueprintsConfigurationForAllVariants('1.7.9', 'SelectedGraphicsSetupName', 'SelectedGfxSetupName'), + /** + * 1.8.2 Move SelectedGfxSetupName to GFX Defaults + */ + moveSelectedGfxSetupNameToGfxDefaults('1.8.2', 'SelectedGfxSetupName', 'GfxDefaults'), + moveSelectedGfxSetupNameToGfxDefaultsInVariants('1.8.2', 'SelectedGfxSetupName', 'GfxDefaults'), + ...getSourceLayerDefaultsMigrationSteps(VERSION), ...getOutputLayerDefaultsMigrationSteps(VERSION), GetDefaultAdLibTriggers(VERSION, SHOW_STYLE_ID, {}, GetDefaultStudioSourcesForOfftube, false) From 6e9e5bd04a4e77bc70fb39d9c0df81e63bce3a4b Mon Sep 17 00:00:00 2001 From: Rasmus Date: Fri, 31 Mar 2023 14:06:41 +0200 Subject: [PATCH 73/86] fix: Removes unnecessary parameter for migration methods, removes arrays from the interface for Defaults, effeciency and structure changes to migration methods and hopefully removing the accidental linter changes --- src/__mocks__/context.ts | 12 +- src/inews-mixins/playlist.ts | 2 +- .../__tests__/getshowStyleVariantId.spec.ts | 2 +- .../__tests__/onTimelineGenerate.spec.ts | 22 +-- .../actions/CoreActionExecutionContext.ts | 4 +- src/tv2-common/actions/executeAction.ts | 81 +++++----- src/tv2-common/blueprintConfig.ts | 4 +- src/tv2-common/content/dve.ts | 7 +- src/tv2-common/cues/EvaluateCueRobotCamera.ts | 2 +- src/tv2-common/cues/dve.ts | 2 +- src/tv2-common/cues/lyd.ts | 2 +- src/tv2-common/evaluateCues.ts | 4 +- src/tv2-common/getSegment.ts | 26 +-- src/tv2-common/getShowStyleVariantId.ts | 4 +- .../helpers/__tests__/sisyfos.spec.ts | 10 +- src/tv2-common/helpers/abPlayback.ts | 42 ++--- src/tv2-common/helpers/config.ts | 2 +- src/tv2-common/helpers/dsk.ts | 6 +- src/tv2-common/helpers/graphics/Graphic.ts | 6 +- .../htmlPilotGraphicGenerator.spec.ts | 6 +- .../helpers/graphics/caspar/util.ts | 4 +- .../graphics/internal/InternalGraphic.ts | 4 +- src/tv2-common/helpers/graphics/layers.ts | 2 +- .../graphics/pilot/PilotGraphicGenerator.ts | 2 +- .../helpers/postProcessDefinitions.ts | 4 +- src/tv2-common/helpers/rundownAdLibActions.ts | 4 +- src/tv2-common/helpers/serverResume.ts | 2 +- src/tv2-common/helpers/sisyfos.ts | 4 +- src/tv2-common/hotkeys/clear.ts | 2 +- .../inewsConversion/converters/ParseBody.ts | 48 +++--- .../inewsConversion/converters/ParseCue.ts | 24 +-- .../converters/__tests__/body-parser.spec.ts | 6 +- src/tv2-common/jinglePartProperties.ts | 8 +- .../__tests__/dve-config-folder.spec.ts | 4 +- .../__tests__/migrationContext.mock.ts | 2 +- .../soundbed-config-audio-folder.spec.ts | 4 +- src/tv2-common/migrations/addKeepAudio.ts | 2 +- .../forceSourceLayerToDefaultsBase.ts | 4 +- src/tv2-common/migrations/hotkeys.ts | 6 +- src/tv2-common/migrations/index.ts | 151 ++++++++---------- .../migrations/renameConfigurationHelper.ts | 14 +- src/tv2-common/migrations/transitions.ts | 8 +- src/tv2-common/nextPartCue.ts | 2 +- src/tv2-common/onTimelineGenerate.ts | 20 +-- src/tv2-common/parts/effekt.ts | 5 +- src/tv2-common/segment/context.ts | 3 +- src/tv2-common/showstyle/config-manifests.ts | 44 ++--- src/tv2-common/sources.ts | 6 +- src/tv2-common/uniformConfig.ts | 6 +- src/tv2-common/updatePolicies/adlibs.ts | 4 +- .../updatePolicies/partProperties.ts | 2 +- src/tv2-common/updatePolicies/pieces.ts | 6 +- src/tv2-common/videoSwitchers/Atem.ts | 2 +- src/tv2-common/videoSwitchers/TriCaster.ts | 8 +- .../__tests__/TriCaster.spec.ts | 27 ++-- .../GlobalAdlibActionsGenerator.ts | 10 +- .../__tests__/actions.spec.ts | 14 +- .../__tests__/baseline.spec.ts | 2 +- .../__tests__/blueprint.spec.ts | 96 +++++------ .../__tests__/config-manifest.spec.ts | 4 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 4 +- .../__tests__/layers-check.ts | 4 +- .../__tests__/migrations-defaults.spec.ts | 4 +- .../__tests__/regressions.spec.ts | 10 +- .../__tests__/rundown_story_exception.spec.ts | 2 +- .../__tests__/transitions.spec.ts | 4 +- src/tv2_afvd_showstyle/config-manifests.ts | 16 +- src/tv2_afvd_showstyle/getRundown.ts | 14 +- src/tv2_afvd_showstyle/getSegment.ts | 4 +- src/tv2_afvd_showstyle/helpers/config.ts | 2 +- .../pieces/__tests__/grafikViz.spec.ts | 10 +- .../helpers/pieces/clearGrafiks.ts | 2 +- .../helpers/pieces/jingle.ts | 2 +- .../helpers/pieces/telefon.ts | 2 +- src/tv2_afvd_showstyle/migrations/hotkeys.ts | 14 +- src/tv2_afvd_showstyle/migrations/index.ts | 6 +- src/tv2_afvd_showstyle/parts/grafik.ts | 4 +- src/tv2_afvd_showstyle/parts/intro.ts | 4 +- src/tv2_afvd_showstyle/parts/live.ts | 4 +- src/tv2_afvd_showstyle/parts/unknown.ts | 4 +- .../__tests__/config-manifest.spec.ts | 4 +- .../__tests__/graphics.spec.ts | 20 +-- .../__tests__/migrations-defaults.spec.ts | 2 +- src/tv2_afvd_studio/getBaseline.ts | 4 +- src/tv2_afvd_studio/helpers/config.ts | 2 +- src/tv2_afvd_studio/helpers/sources.ts | 2 +- src/tv2_afvd_studio/migrations/devices.ts | 10 +- src/tv2_afvd_studio/migrations/index.ts | 6 +- .../__tests__/actions.spec.ts | 68 ++++---- .../__tests__/config-manifest.spec.ts | 2 +- .../__tests__/migrations-defaults.spec.ts | 4 +- src/tv2_offtube_showstyle/config-manifests.ts | 4 +- .../cues/OfftubeJingle.ts | 2 +- src/tv2_offtube_showstyle/getRundown.ts | 20 +-- src/tv2_offtube_showstyle/helpers/config.ts | 6 +- .../migrations/hotkeys.ts | 12 +- src/tv2_offtube_showstyle/migrations/index.ts | 6 +- src/tv2_offtube_showstyle/migrations/util.ts | 2 +- .../onTimelineGenerate.ts | 2 +- .../parts/OfftubeUnknown.ts | 4 +- .../__tests__/config-manifest.spec.ts | 4 +- .../__tests__/migrations-defaults.spec.ts | 2 +- src/tv2_offtube_studio/getBaseline.ts | 2 +- src/tv2_offtube_studio/helpers/config.ts | 2 +- src/tv2_offtube_studio/helpers/sources.ts | 2 +- src/tv2_offtube_studio/migrations/devices.ts | 10 +- src/tv2_offtube_studio/migrations/index.ts | 6 +- src/tv2_system/migrations/hotkeys.ts | 2 +- 108 files changed, 573 insertions(+), 571 deletions(-) diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index 2b81c713..a56d73ca 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -304,8 +304,10 @@ export class SegmentUserContextMock extends RundownContextMock implements ISegme } } -export class SyncIngestUpdateToPartInstanceContextMock extends RundownUserContextMock - implements ISyncIngestUpdateToPartInstanceContext { +export class SyncIngestUpdateToPartInstanceContextMock + extends RundownUserContextMock + implements ISyncIngestUpdateToPartInstanceContext +{ public syncedPieceInstances: string[] = [] public removedPieceInstances: string[] = [] public updatedPieceInstances: string[] = [] @@ -553,7 +555,7 @@ export class ActionExecutionContextMock extends ShowStyleUserContextMock impleme } this.nextPart = instance - this.nextPieceInstances = pieces.map>(p => ({ + this.nextPieceInstances = pieces.map>((p) => ({ _id: (Date.now() * Math.random()).toString(), piece: { _id: '', @@ -591,9 +593,9 @@ export class ActionExecutionContextMock extends ShowStyleUserContextMock impleme /** Remove piecesInstances by id. Returns ids of piecesInstances that were removed */ public async removePieceInstances(part: 'current' | 'next', pieceInstanceIds: string[]): Promise { if (part === 'current') { - this.currentPieceInstances = this.currentPieceInstances.filter(p => !pieceInstanceIds.includes(p._id)) + this.currentPieceInstances = this.currentPieceInstances.filter((p) => !pieceInstanceIds.includes(p._id)) } else if (this.nextPieceInstances) { - this.nextPieceInstances = this.nextPieceInstances.filter(p => !pieceInstanceIds.includes(p._id)) + this.nextPieceInstances = this.nextPieceInstances.filter((p) => !pieceInstanceIds.includes(p._id)) } return pieceInstanceIds diff --git a/src/inews-mixins/playlist.ts b/src/inews-mixins/playlist.ts index fa8fb779..85ab1a33 100644 --- a/src/inews-mixins/playlist.ts +++ b/src/inews-mixins/playlist.ts @@ -42,7 +42,7 @@ export function getRundownWithBackTime( manifest: BlueprintResultRundown ): BlueprintResultRundown { const sortedSegments = ingestRundown.segments.sort((a, b) => a.rank - b.rank) - const firstContinuityStory = sortedSegments.find(segment => segment.name.match(/^\s*continuity\s*$/i)) + const firstContinuityStory = sortedSegments.find((segment) => segment.name.match(/^\s*continuity\s*$/i)) const backTime = firstContinuityStory ? firstContinuityStory.payload.iNewsStory.fields.backTime : undefined let expectedEnd: number | undefined diff --git a/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts b/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts index 7c6f12d8..88f3265b 100644 --- a/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts +++ b/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts @@ -38,7 +38,7 @@ describe('getShowStyleVariantId', () => { ] if (variantNames) { variants.push( - ...variantNames.map(variantName => { + ...variantNames.map((variantName) => { return { _id: variantName, name: variantName, diff --git a/src/tv2-common/__tests__/onTimelineGenerate.spec.ts b/src/tv2-common/__tests__/onTimelineGenerate.spec.ts index 2ff4a58e..6e20cbed 100644 --- a/src/tv2-common/__tests__/onTimelineGenerate.spec.ts +++ b/src/tv2-common/__tests__/onTimelineGenerate.spec.ts @@ -22,7 +22,7 @@ describe('onTimelineGenerate', () => { const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) const indexOfLayerThatWantToBePersisted = result.content.channels.findIndex( - channel => channel.mappedLayer === LAYER_THAT_WANTS_TO_BE_PERSISTED + (channel) => channel.mappedLayer === LAYER_THAT_WANTS_TO_BE_PERSISTED ) expect(indexOfLayerThatWantToBePersisted).toBeGreaterThanOrEqual(0) }) @@ -108,13 +108,13 @@ describe('onTimelineGenerate', () => { const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, layersThatWantToBePersisted) expect( - result.content.channels.some(channel => channel.mappedLayer === firstLayerThatWantToBePersisted) + result.content.channels.some((channel) => channel.mappedLayer === firstLayerThatWantToBePersisted) ).toBeTruthy() expect( - result.content.channels.some(channel => channel.mappedLayer === secondLayerThatWantToBePersisted) + result.content.channels.some((channel) => channel.mappedLayer === secondLayerThatWantToBePersisted) ).toBeTruthy() expect( - result.content.channels.some(channel => channel.mappedLayer === thirdLayerThatWantToBePersisted) + result.content.channels.some((channel) => channel.mappedLayer === thirdLayerThatWantToBePersisted) ).toBeTruthy() }) @@ -138,9 +138,11 @@ describe('onTimelineGenerate', () => { const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) expect( - result.content.channels.some(channel => channel.mappedLayer === LAYER_THAT_WANTS_TO_BE_PERSISTED) + result.content.channels.some((channel) => channel.mappedLayer === LAYER_THAT_WANTS_TO_BE_PERSISTED) + ).toBeTruthy() + expect( + result.content.channels.some((channel) => channel.mappedLayer === resolvedPieces[0].piece.name) ).toBeTruthy() - expect(result.content.channels.some(channel => channel.mappedLayer === resolvedPieces[0].piece.name)).toBeTruthy() }) it('cuts to executionAction that accept from piece that dont accept, add persist timelineObject that only contain previous piece layers', () => { @@ -152,7 +154,9 @@ describe('onTimelineGenerate', () => { const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) expect(result.content.channels).toHaveLength(1) - expect(result.content.channels.some(channel => channel.mappedLayer === resolvedPieces[0].piece.name)).toBeTruthy() + expect( + result.content.channels.some((channel) => channel.mappedLayer === resolvedPieces[0].piece.name) + ).toBeTruthy() }) it('cuts to executeAction that accept persist from piece that dont want to persist and dont accept persist, dont persist any layers', () => { @@ -176,7 +180,7 @@ describe('onTimelineGenerate', () => { expect(result.content.channels).toHaveLength(1) expect( - result.content.channels.some(channel => channel.mappedLayer === LAYER_THAT_WANTS_TO_BE_PERSISTED) + result.content.channels.some((channel) => channel.mappedLayer === LAYER_THAT_WANTS_TO_BE_PERSISTED) ).toBeTruthy() }) @@ -259,7 +263,7 @@ describe('onTimelineGenerate', () => { const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, []) expect(result.content.channels).toHaveLength(1) - expect(result.content.channels.some(channel => channel.mappedLayer === 'firstPiece')).toBeTruthy() + expect(result.content.channels.some((channel) => channel.mappedLayer === 'firstPiece')).toBeTruthy() }) it('cuts from piece that wants to persist to executeAction that do not accept to another executeAction that accepts, dont persist any layers', () => { diff --git a/src/tv2-common/actions/CoreActionExecutionContext.ts b/src/tv2-common/actions/CoreActionExecutionContext.ts index d6150910..4ba153c0 100644 --- a/src/tv2-common/actions/CoreActionExecutionContext.ts +++ b/src/tv2-common/actions/CoreActionExecutionContext.ts @@ -189,11 +189,11 @@ export class CoreActionExecutionContext implements ITV2ActionExecutionContext { piece: Partial> ): Promise> { const currentPieceInstances = await this.core.getPieceInstances('current') - if (currentPieceInstances.map(p => p._id).includes(pieceInstanceId)) { + if (currentPieceInstances.map((p) => p._id).includes(pieceInstanceId)) { this.modifiedParts.add('current') } else { const nextPieceInstances = await this.core.getPieceInstances('next') - if (nextPieceInstances.map(p => p._id).includes(pieceInstanceId)) { + if (nextPieceInstances.map((p) => p._id).includes(pieceInstanceId)) { this.modifiedParts.add('next') } } diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index f728621c..0b7340c8 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -177,7 +177,7 @@ export async function executeAction< userData: ActionUserData, triggerMode?: string ): Promise { - await executeWithContext(coreContext, uniformConfig, async context => { + await executeWithContext(coreContext, uniformConfig, async (context) => { const existingTransition = await getExistingTransition(context, settings, 'next') const actionId = actionIdStr as AdlibActionType @@ -285,7 +285,7 @@ async function getExistingTransition< ): Promise { const existingTransition = await context.core .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.Effekt)) + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === settings.SourceLayers.Effekt)) if (!existingTransition) { return @@ -355,8 +355,8 @@ export async function getPiecesToPreserve( ): Promise>> { const currentPartSegmentId = await context.core .getPartInstance('current') - .then(partInstance => partInstance?.segmentId) - const nextPartSegmentId = await context.core.getPartInstance('next').then(partInstance => partInstance?.segmentId) + .then((partInstance) => partInstance?.segmentId) + const nextPartSegmentId = await context.core.getPartInstance('next').then((partInstance) => partInstance?.segmentId) if (!currentPartSegmentId || !nextPartSegmentId) { return [] @@ -366,13 +366,13 @@ export async function getPiecesToPreserve( return [] } - return context.core.getPieceInstances('next').then(pieceInstances => { + return context.core.getPieceInstances('next').then((pieceInstances) => { return pieceInstances - .filter(p => adlibLayers.includes(p.piece.sourceLayerId) && !ignoreLayers.includes(p.piece.sourceLayerId)) - .filter(p => !p.infinite?.fromPreviousPart && !p.infinite?.fromPreviousPlayhead) - .map>(p => p.piece) - .map(p => sanitizePieceStart(p)) - .map(p => sanitizePieceId(p as IBlueprintPieceDB)) + .filter((p) => adlibLayers.includes(p.piece.sourceLayerId) && !ignoreLayers.includes(p.piece.sourceLayerId)) + .filter((p) => !p.infinite?.fromPreviousPart && !p.infinite?.fromPreviousPlayhead) + .map>((p) => p.piece) + .map((p) => sanitizePieceStart(p)) + .map((p) => sanitizePieceId(p as IBlueprintPieceDB)) }) } @@ -399,7 +399,7 @@ async function executeActionSelectServerClip< const currentPiece = settings.SelectedAdlibs ? await context.core .getPieceInstances('current') - .then(pieceInstances => pieceInstances.find(p => isServerOnPgm(p, settings, userData.voLayer))) + .then((pieceInstances) => pieceInstances.find((p) => isServerOnPgm(p, settings, userData.voLayer))) : undefined const basePart = await CreatePartServerBase( @@ -433,11 +433,11 @@ async function executeActionSelectServerClip< ) const activeServerPiece = basePart.part.pieces.find( - p => p.sourceLayerId === settings.SourceLayers.Server || p.sourceLayerId === settings.SourceLayers.VO + (p) => p.sourceLayerId === settings.SourceLayers.Server || p.sourceLayerId === settings.SourceLayers.VO ) const serverDataStore = basePart.part.pieces.find( - p => + (p) => p.sourceLayerId === settings.SelectedAdlibs.SourceLayer.Server || p.sourceLayerId === settings.SelectedAdlibs.SourceLayer.VO ) @@ -626,9 +626,9 @@ async function cutServerToBox< if (newDvePiece.content?.timelineObjects) { const currentServer = await context.core .getPieceInstances('current') - .then(currentPieces => + .then((currentPieces) => currentPieces.find( - p => + (p) => p.piece.sourceLayerId === settings.SelectedAdlibs?.SourceLayer.Server || p.piece.sourceLayerId === settings.SelectedAdlibs?.SourceLayer.VO ) @@ -641,11 +641,11 @@ async function cutServerToBox< // Find existing CasparCG object const existingCasparObj = (currentServer.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => obj.layer === settings.LLayer.Caspar.ClipPending + (obj) => obj.layer === settings.LLayer.Caspar.ClipPending ) as TSR.TimelineObjCCGMedia & TimelineBlueprintExt // Find existing sisyfos object const existingSisyfosObj = (currentServer.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => obj.layer === settings.LLayer.Sisyfos.ClipPending + (obj) => obj.layer === settings.LLayer.Sisyfos.ClipPending ) as TSR.TimelineObjSisyfosChannel & TimelineBlueprintExt // Find DVE Boxes object in DVE piece const dveBoxesObj = newDvePiece.content.timelineObjects.find(context.videoSwitcher.isDveBoxes) as @@ -718,9 +718,9 @@ async function executeActionSelectDVELayout< const nextDVE = (await context.core .getPieceInstances('next') - .then(nextPieceInstances => nextPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE))) as - | IBlueprintPieceInstance - | undefined + .then((nextPieceInstances) => + nextPieceInstances.find((p) => p.piece.sourceLayerId === settings.SourceLayers.DVE) + )) as IBlueprintPieceInstance | undefined const meta = nextDVE?.piece.metaData @@ -859,9 +859,10 @@ async function startNewDVELayout< // Take this timelineObjects: pieceContent.timelineObjects .filter( - tlObj => !context.videoSwitcher.isMixEffect(tlObj) && tlObj.content.deviceType !== TSR.DeviceType.SISYFOS + (tlObj) => + !context.videoSwitcher.isMixEffect(tlObj) && tlObj.content.deviceType !== TSR.DeviceType.SISYFOS ) - .map(obj => ({ ...obj, priority: obj.priority ?? 1 / 2 })) + .map((obj) => ({ ...obj, priority: obj.priority ?? 1 / 2 })) } } : undefined @@ -876,11 +877,11 @@ async function startNewDVELayout< const currentPieceInstances = await context.core.getPieceInstances('current') // If a DVE is not on air, but a layout is selected, stop the selected layout and replace with the new one. - const onAirPiece = currentPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE) + const onAirPiece = currentPieceInstances.find((p) => p.piece.sourceLayerId === settings.SourceLayers.DVE) const dataPiece = settings.SelectedAdlibs && - currentPieceInstances.find(p => p.piece.sourceLayerId === settings.SelectedAdlibs.SourceLayer.DVE) + currentPieceInstances.find((p) => p.piece.sourceLayerId === settings.SelectedAdlibs.SourceLayer.DVE) if (onAirPiece === undefined && dataPiece !== undefined) { await context.core.stopPieceInstances([dataPiece._id]) @@ -928,7 +929,7 @@ async function executeActionSelectJingle< const externalId = generateExternalId(context, actionId, [userData.clip]) - const jingle = context.config.showStyle.BreakerConfig.find(brkr => + const jingle = context.config.showStyle.BreakerConfig.find((brkr) => brkr.BreakerName ? brkr.BreakerName.toString().toUpperCase() === userData.clip.toUpperCase() : false ) if (!jingle) { @@ -1053,11 +1054,11 @@ async function executePiece< ) { const currentPieceInstances = await context.core.getPieceInstances('current') const isServerInCurrentPart = currentPieceInstances.some( - p => p.piece.sourceLayerId === settings.SourceLayers.Server || p.piece.sourceLayerId === settings.SourceLayers.VO + (p) => p.piece.sourceLayerId === settings.SourceLayers.Server || p.piece.sourceLayerId === settings.SourceLayers.VO ) const layersWithCutDirect: string[] = [settings.SourceLayers.Live, settings.SourceLayers.Cam] - const currentPiece: IBlueprintPieceInstance | undefined = currentPieceInstances.find(p => + const currentPiece: IBlueprintPieceInstance | undefined = currentPieceInstances.find((p) => layersWithCutDirect.includes(p.piece.sourceLayerId) ) @@ -1085,7 +1086,7 @@ async function executePiece< } else { const currentExternalId = await context.core .getPartInstance('current') - .then(currentPartInstance => currentPartInstance?.part.externalId) + .then((currentPartInstance) => currentPartInstance?.part.externalId) if (currentExternalId) { pieceToExecute.externalId = currentExternalId @@ -1114,8 +1115,8 @@ async function stopGraphicPiecesThatShouldEndWithPart( ) { await context.core.stopPieceInstances( currentPieceInstances - .filter(pieceInstance => isGraphicThatShouldEndWithPart(pieceInstance)) - .map(pieceInstance => pieceInstance._id) + .filter((pieceInstance) => isGraphicThatShouldEndWithPart(pieceInstance)) + .map((pieceInstance) => pieceInstance._id) ) } @@ -1211,20 +1212,20 @@ async function executeActionCutSourceToBox< const nextPieces: IBlueprintPieceInstance[] = await context.core.getPieceInstances('next') const currentDVE = currentPieces.find( - p => + (p) => p.piece.sourceLayerId === settings.SourceLayers.DVE || (settings.SourceLayers.DVEAdLib && p.piece.sourceLayerId === settings.SourceLayers.DVEAdLib) ) const currentDataStore = currentPieces.find( - p => settings.SelectedAdlibs && p.piece.sourceLayerId === settings.SelectedAdlibs.SourceLayer.DVE + (p) => settings.SelectedAdlibs && p.piece.sourceLayerId === settings.SelectedAdlibs.SourceLayer.DVE ) const nextDVE = nextPieces.find( - p => + (p) => p.piece.sourceLayerId === settings.SourceLayers.DVE || (settings.SourceLayers.DVEAdLib && p.piece.sourceLayerId === settings.SourceLayers.DVEAdLib) ) const nextDataStore = nextPieces.find( - p => settings.SelectedAdlibs && p.piece.sourceLayerId === settings.SelectedAdlibs.SourceLayer.DVE + (p) => settings.SelectedAdlibs && p.piece.sourceLayerId === settings.SelectedAdlibs.SourceLayer.DVE ) let modify: undefined | 'current' | 'next' @@ -1311,7 +1312,7 @@ interface PiecesBySourceLayer { function groupPiecesBySourceLayer(pieceInstances: Array>): PiecesBySourceLayer { const piecesBySourceLayer: PiecesBySourceLayer = {} - pieceInstances.forEach(piece => { + pieceInstances.forEach((piece) => { if (!piecesBySourceLayer[piece.piece.sourceLayerId]) { piecesBySourceLayer[piece.piece.sourceLayerId] = [] } @@ -1375,7 +1376,7 @@ async function executeActionTakeWithTransition< return } - const existingEffektPiece = nextPieces.find(p => p.piece.sourceLayerId === settings.SourceLayers.Effekt) + const existingEffektPiece = nextPieces.find((p) => p.piece.sourceLayerId === settings.SourceLayers.Effekt) if (existingEffektPiece) { await context.core.removePieceInstances('next', [existingEffektPiece._id]) @@ -1430,7 +1431,7 @@ async function executeActionTakeWithTransition< if (partProps) { await context.core.updatePartInstance('next', partProps) - pieces.forEach(p => context.core.insertPiece('next', { ...p, tags: [GetTagForTransition(userData.variant)] })) + pieces.forEach((p) => context.core.insertPiece('next', { ...p, tags: [GetTagForTransition(userData.variant)] })) } break } @@ -1498,9 +1499,9 @@ async function findPieceToRecoverDataFrom( const currentPieces = pieces[0] const nextPieces = pieces[1] - const currentServer = currentPieces.find(p => dataStoreLayers.includes(p.piece.sourceLayerId)) + const currentServer = currentPieces.find((p) => dataStoreLayers.includes(p.piece.sourceLayerId)) - const nextServer = nextPieces.find(p => dataStoreLayers.includes(p.piece.sourceLayerId)) + const nextServer = nextPieces.find((p) => dataStoreLayers.includes(p.piece.sourceLayerId)) let pieceToRecoverDataFrom: IBlueprintPieceInstance | undefined @@ -1784,7 +1785,7 @@ async function createFadeSisyfosLevelsMetaData(context: ActionExecutionContext) } const latestPiece = resolvedPieceInstances - .filter(piece => piece.piece.name !== FADE_SISYFOS_LEVELS_PIECE_NAME) + .filter((piece) => piece.piece.name !== FADE_SISYFOS_LEVELS_PIECE_NAME) .sort((a, b) => b.resolvedStart - a.resolvedStart)[0] const latestPieceMetaData = latestPiece.piece.metaData diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 4e46072c..1d76bef4 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -45,8 +45,8 @@ export interface TableConfigItemGfxShowMapping { export interface TableConfigItemGfxDefaults { GfxSetup: string - DefaultSchema: string[] - DefaultDesign: string[] + DefaultSchema: string + DefaultDesign: string } export interface TableConfigItemAdLibTransitions { diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 7226a0ae..493e3cd7 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -405,7 +405,7 @@ const setBoxToBlack = (boxConfig: BoxConfig, boxSources: BoxSources) => { function makeBoxAssignments(inputs: string[], context: IShowStyleUserContext, sources: DVESources | undefined) { const boxAssignments: Array = [] - inputs.forEach(source => { + inputs.forEach((source) => { const sourceProps = source.split(':') const fromCue = sourceProps[1] const targetBox = Number(sourceProps[0]) @@ -432,10 +432,7 @@ function makeBoxAssignments(inputs: string[], context: IShowStyleUserContext, so return boxAssignments } -function boxSource(info: { - port: number - sourceLayerType: SourceLayerType -}): { +function boxSource(info: { port: number; sourceLayerType: SourceLayerType }): { switcherInput: number type: SourceLayerType } { diff --git a/src/tv2-common/cues/EvaluateCueRobotCamera.ts b/src/tv2-common/cues/EvaluateCueRobotCamera.ts index a8262a7b..d626706d 100644 --- a/src/tv2-common/cues/EvaluateCueRobotCamera.ts +++ b/src/tv2-common/cues/EvaluateCueRobotCamera.ts @@ -28,7 +28,7 @@ function findExistingPieceForRobotCameraLayerAndStartTime( startTime: number ): IBlueprintPiece | undefined { return pieces.find( - piece => + (piece) => piece.sourceLayerId === SharedSourceLayer.RobotCamera && piece.name.startsWith(ROBOT_CAMERA_NAME_PREFIX) && piece.enable.start === startTime diff --git a/src/tv2-common/cues/dve.ts b/src/tv2-common/cues/dve.ts index 630ded0a..a39668c5 100644 --- a/src/tv2-common/cues/dve.ts +++ b/src/tv2-common/cues/dve.ts @@ -71,5 +71,5 @@ export function TemplateIsValid(templateRaw: string): boolean { } export function GetDVETemplate(config: DVEConfigInput[], templateName: string): DVEConfigInput | undefined { - return config ? config.find(c => c.DVEName.toString().toUpperCase() === templateName.toUpperCase()) : undefined + return config ? config.find((c) => c.DVEName.toString().toUpperCase() === templateName.toUpperCase()) : undefined } diff --git a/src/tv2-common/cues/lyd.ts b/src/tv2-common/cues/lyd.ts index 7a3dd189..0cec4474 100644 --- a/src/tv2-common/cues/lyd.ts +++ b/src/tv2-common/cues/lyd.ts @@ -38,7 +38,7 @@ export function EvaluateLYD( adlib?: boolean, rank?: number ) { - const conf = context.config.showStyle.LYDConfig.find(lyd => + const conf = context.config.showStyle.LYDConfig.find((lyd) => lyd.INewsName ? lyd.INewsName.toString().toUpperCase() === parsedCue.variant.toUpperCase() : false ) const stop = !!parsedCue.variant.match(/^[^_]*STOP[^_]*$/i) // TODO: STOP 1 / STOP 2 etc. diff --git a/src/tv2-common/evaluateCues.ts b/src/tv2-common/evaluateCues.ts index 63948ada..d9255f3d 100644 --- a/src/tv2-common/evaluateCues.ts +++ b/src/tv2-common/evaluateCues.ts @@ -205,7 +205,7 @@ export async function EvaluateCuesBase( context.config.studio.PreventOverlayWithFull && GraphicIsPilot(cue) && IsTargetingOVL(cue.target) && - cues.some(c => c.type === CueType.Graphic && GraphicIsPilot(c) && IsTargetingFull(c.target)) + cues.some((c) => c.type === CueType.Graphic && GraphicIsPilot(c) && IsTargetingFull(c.target)) ) { context.core.notifyUserWarning(`Cannot create overlay graphic with FULL`) break @@ -362,7 +362,7 @@ export async function EvaluateCuesBase( pieces.push(...result.pieces) adLibPieces.push(...result.adlibPieces) actions.push(...result.actions) - ;[...pieces, ...adLibPieces].forEach(piece => { + ;[...pieces, ...adLibPieces].forEach((piece) => { if (piece.content && piece.content.timelineObjects) { piece.content.timelineObjects.forEach((obj: TSR.TSRTimelineObj) => { if (obj.content.deviceType === TSR.DeviceType.VIZMSE) { diff --git a/src/tv2-common/getSegment.ts b/src/tv2-common/getSegment.ts index 5f516132..5aaa4d8e 100644 --- a/src/tv2-common/getSegment.ts +++ b/src/tv2-common/getSegment.ts @@ -149,18 +149,18 @@ export async function getSegmentBase if ( GetNextPartCue(part, -1) === -1 && part.type === PartType.Unknown && - part.cues.filter(cue => cue.type === CueType.Jingle || cue.type === CueType.AdLib).length === 0 + part.cues.filter((cue) => cue.type === CueType.Jingle || cue.type === CueType.AdLib).length === 0 ) { blueprintParts.push(await showStyleOptions.CreatePartUnknown(context, part, totalWords, true)) continue } const unpairedTargets = part.cues.filter( - c => c.type === CueType.UNPAIRED_TARGET && IsTargetingFull(c.target) + (c) => c.type === CueType.UNPAIRED_TARGET && IsTargetingFull(c.target) ) as CueDefinitionUnpairedTarget[] if (unpairedTargets.length) { blueprintParts.push(CreatePartInvalid(part)) - unpairedTargets.forEach(cue => { + unpairedTargets.forEach((cue) => { context.core.notifyUserWarning(`No graphic found after ${cue.iNewsCommand} cue`) }) continue @@ -245,7 +245,7 @@ export async function getSegmentBase break } - if (part.cues.filter(cue => cue.type === CueType.Jingle).length) { + if (part.cues.filter((cue) => cue.type === CueType.Jingle).length) { if (blueprintParts[blueprintParts.length - 1]) { const t = blueprintParts[blueprintParts.length - 1].part.expectedDuration if (t) { @@ -269,7 +269,7 @@ export async function getSegmentBase 0 ) - blueprintParts.forEach(part => { + blueprintParts.forEach((part) => { // part.part.displayDurationGroup = ingestSegment.externalId if (!part.part.expectedDuration && totalTimeMs > 0) { @@ -287,7 +287,7 @@ export async function getSegmentBase let extraTime = totalTimeMs - blueprintParts.forEach(part => { + blueprintParts.forEach((part) => { if (part.part.expectedDuration === undefined || part.part.expectedDuration < 0) { part.part.expectedDuration = extraTime > config.studio.DefaultPartDuration @@ -305,7 +305,7 @@ export async function getSegmentBase }) if ( - blueprintParts.filter(part => part.pieces.length === 0 && (part.adLibPieces.length || part.actions?.length)) + blueprintParts.filter((part) => part.pieces.length === 0 && (part.adLibPieces.length || part.actions?.length)) .length === blueprintParts.length ) { segment.isHidden = true @@ -314,7 +314,7 @@ export async function getSegmentBase } } - if (blueprintParts.find(part => part.adLibPieces.length || part.actions?.length)) { + if (blueprintParts.find((part) => part.adLibPieces.length || part.actions?.length)) { segment.showShelf = true } @@ -323,29 +323,29 @@ export async function getSegmentBase blueprintParts.length > 1 || (blueprintParts[blueprintParts.length - 1] && !blueprintParts[blueprintParts.length - 1].pieces.some( - piece => piece.sourceLayerId === SharedSourceLayer.PgmJingle + (piece) => piece.sourceLayerId === SharedSourceLayer.PgmJingle )) ) { blueprintParts[0].part.budgetDuration = totalTimeMs } - if (blueprintParts.every(part => part.part.invalid) && iNewsStory.cues.length === 0) { + if (blueprintParts.every((part) => part.part.invalid) && iNewsStory.cues.length === 0) { segment.isHidden = true } - blueprintParts.forEach(part => { + blueprintParts.forEach((part) => { if ( part.part.expectedDuration! < config.studio.DefaultPartDuration && // Jingle-only part, do not modify duration !part.pieces.some( - p => p.sourceLayerId === SharedSourceLayer.PgmJingle && p.tags?.some(tag => TallyTags.JINGLE === tag) + (p) => p.sourceLayerId === SharedSourceLayer.PgmJingle && p.tags?.some((tag) => TallyTags.JINGLE === tag) ) ) { part.part.expectedDuration = config.studio.DefaultPartDuration } }) - blueprintParts = blueprintParts.map(part => { + blueprintParts = blueprintParts.map((part) => { const actualPart = part.part actualPart.metaData = literal({ ...(actualPart.metaData as any), diff --git a/src/tv2-common/getShowStyleVariantId.ts b/src/tv2-common/getShowStyleVariantId.ts index 35a684b2..47c6ac10 100644 --- a/src/tv2-common/getShowStyleVariantId.ts +++ b/src/tv2-common/getShowStyleVariantId.ts @@ -9,8 +9,8 @@ export function getShowStyleVariantId( ): string | null { const ingestVariantName = ingestRundown.payload?.showstyleVariant?.trim().toLowerCase() const showStyleVariant = - showStyleVariants.find(variant => variant.name?.trim().toLowerCase() === ingestVariantName) ?? - showStyleVariants.find(variant => variant.name?.trim().toLowerCase() === DEFAULT_VARIANT_NAME) + showStyleVariants.find((variant) => variant.name?.trim().toLowerCase() === ingestVariantName) ?? + showStyleVariants.find((variant) => variant.name?.trim().toLowerCase() === DEFAULT_VARIANT_NAME) return showStyleVariant?._id ?? null } diff --git a/src/tv2-common/helpers/__tests__/sisyfos.spec.ts b/src/tv2-common/helpers/__tests__/sisyfos.spec.ts index 986a4560..9e47369a 100644 --- a/src/tv2-common/helpers/__tests__/sisyfos.spec.ts +++ b/src/tv2-common/helpers/__tests__/sisyfos.spec.ts @@ -37,7 +37,7 @@ describe('Sisyfos', () => { } const timelineObjects = GetSisyfosTimelineObjForCamera(config, sourceInfo, false) expect(timelineObjects.length).toBe(3) - const studioMicsTimelineObject = timelineObjects.find(t => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) + const studioMicsTimelineObject = timelineObjects.find((t) => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) expect(studioMicsTimelineObject).toBeDefined() }) it('Does not enable studio mics for "minus mic" cameras', () => { @@ -51,7 +51,7 @@ describe('Sisyfos', () => { } const timelineObjects = GetSisyfosTimelineObjForCamera(config, sourceInfo, true) expect(timelineObjects.length).toBe(2) - const studioMicsTimelineObject = timelineObjects.find(t => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) + const studioMicsTimelineObject = timelineObjects.find((t) => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) expect(studioMicsTimelineObject).toBeUndefined() }) it('Enables audio layers for remotes', () => { @@ -81,7 +81,7 @@ describe('Sisyfos', () => { } const timelineObjects = GetSisyfosTimelineObjForRemote(config, sourceInfo) expect(timelineObjects.length).toBe(3) - const studioMicsTimelineObject = timelineObjects.find(t => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) + const studioMicsTimelineObject = timelineObjects.find((t) => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) expect(studioMicsTimelineObject).toBeDefined() }) it('Enables audio layers for replay', () => { @@ -110,7 +110,7 @@ describe('Sisyfos', () => { useStudioMics: false } const timelineObjects = GetSisyfosTimelineObjForReplay(config, sourceInfo, true) - const layersTimelineObjects = timelineObjects.filter(t => t.layer !== SharedSisyfosLLayer.SisyfosGroupStudioMics) + const layersTimelineObjects = timelineObjects.filter((t) => t.layer !== SharedSisyfosLLayer.SisyfosGroupStudioMics) expect(layersTimelineObjects.length).toBe(2) expect(layersTimelineObjects[0].layer).toBe('some_layer') expect((layersTimelineObjects[0] as TSR.TimelineObjSisyfosChannel).content.isPgm).toBe(2) @@ -128,7 +128,7 @@ describe('Sisyfos', () => { } const timelineObjects = GetSisyfosTimelineObjForReplay(config, sourceInfo, true) expect(timelineObjects.length).toBe(3) - const studioMicsTimelineObject = timelineObjects.find(t => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) + const studioMicsTimelineObject = timelineObjects.find((t) => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) expect(studioMicsTimelineObject).toBeDefined() }) }) diff --git a/src/tv2-common/helpers/abPlayback.ts b/src/tv2-common/helpers/abPlayback.ts index a4d32fde..65171737 100644 --- a/src/tv2-common/helpers/abPlayback.ts +++ b/src/tv2-common/helpers/abPlayback.ts @@ -33,7 +33,7 @@ function reversePreviousAssignment( const previousAssignmentRev: { [sessionId: string]: MediaPlayerClaim | undefined } = {} for (const key of _.keys(previousAssignment)) { for (const v2 of previousAssignment[key] || []) { - if (timeline.some(obj => obj.metaData && (obj.metaData as any).mediaPlayerSession === v2.sessionId)) { + if (timeline.some((obj) => obj.metaData && (obj.metaData as any).mediaPlayerSession === v2.sessionId)) { previousAssignmentRev[v2.sessionId] = v2 } } @@ -65,7 +65,7 @@ interface SessionTime { duration: number | undefined } function calculateSessionTimeRanges(resolvedPieces: Array>) { - const piecesWantingMediaPlayers = _.filter(resolvedPieces, p => { + const piecesWantingMediaPlayers = _.filter(resolvedPieces, (p) => { if (!p.piece.metaData) { return false } @@ -73,14 +73,14 @@ function calculateSessionTimeRanges(resolvedPieces: Array { + _.each(piecesWantingMediaPlayers, (p) => { const metadata = p.piece.metaData! const start = p.resolvedStart const duration = p.resolvedDuration const end = duration !== undefined ? start + duration : undefined // Track the range of each session - _.each(metadata.mediaPlayerSessions || [], sessionId => { + _.each(metadata.mediaPlayerSessions || [], (sessionId) => { // TODO - will fixed ids ever be wanted? Is it reasonable to want to have the same session across multiple pieces? // Infinites are the exception here, but anything else? // Perhaps the id given should be prefixed with the piece(instance) id? And sharing sessions can be figured out when it becomes needed @@ -112,7 +112,7 @@ function findNextAvailablePlayer< ShowStyleConfig extends TV2BlueprintConfigBase >(config: ShowStyleConfig, inUse: ActiveRequest[], req: ActiveRequest) { const pickFirstNotInUse = (inUseRequests: ActiveRequest[]) => { - const inUseIds = _.compact(_.map(inUseRequests, r => r.player)) + const inUseIds = _.compact(_.map(inUseRequests, (r) => r.player)) for (const mp of config.mediaPlayers) { if (inUseIds.indexOf(mp.id) === -1) { return mp.id @@ -130,14 +130,14 @@ function findNextAvailablePlayer< } // Try reclaiming any lookahead - const allActiveUses = _.filter(filteredInUse, r => r.type !== MediaPlayerClaimType.Preloaded) + const allActiveUses = _.filter(filteredInUse, (r) => r.type !== MediaPlayerClaimType.Preloaded) mpId = pickFirstNotInUse(allActiveUses) if (mpId !== undefined) { return mpId } // Is there something ending at the same time this starts? - const activeUsesNotEndingNow = _.filter(filteredInUse, r => r.end === undefined || r.end > req.start) + const activeUsesNotEndingNow = _.filter(filteredInUse, (r) => r.end === undefined || r.end > req.start) mpId = pickFirstNotInUse(activeUsesNotEndingNow) if (mpId !== undefined) { return mpId @@ -207,7 +207,7 @@ export function resolveMediaPlayerAssignments< }) } } - _.sortBy(activeRequests, r => r.start) + _.sortBy(activeRequests, (r) => r.start) // Go through and assign players context.core.logDebug('all reqs' + JSON.stringify(activeRequests, undefined, 4)) @@ -219,7 +219,7 @@ export function resolveMediaPlayerAssignments< continue } - const otherActive = _.filter(activeRequests, r => doesRequestOverlap(req, r)) + const otherActive = _.filter(activeRequests, (r) => doesRequestOverlap(req, r)) context.core.logDebug(`for ${JSON.stringify(req)} there is: ${JSON.stringify(otherActive, undefined, 4)}`) @@ -268,7 +268,7 @@ function updateObjectsToMediaPlayer< // context.notifyUserWarning(obj) } } else if (context.videoSwitcher.isVideoSwitcherTimelineObject(obj)) { - let switcherInput = _.find(context.config.mediaPlayers, mp => mp.id === playerId.toString()) + let switcherInput = _.find(context.config.mediaPlayers, (mp) => mp.id === playerId.toString()) if (!switcherInput) { context.core.logWarning(`Trying to find atem input for unknown mediaPlayer: #${playerId}`) switcherInput = { id: playerId.toString(), val: context.config.studio.SwitcherSource.Default.toString() } @@ -368,12 +368,12 @@ export function applyMediaPlayersAssignments< // collect objects by their sessionId const labelledObjs = (timelineObjs as Array).filter( - o => o.metaData && o.metaData.mediaPlayerSession + (o) => o.metaData && o.metaData.mediaPlayerSession ) - const groupedObjs = _.groupBy(labelledObjs, o => { + const groupedObjs = _.groupBy(labelledObjs, (o) => { const sessionId = (o.metaData || {}).mediaPlayerSession if (sessionId === undefined || sessionId === '' || sessionId === MEDIA_PLAYER_AUTO) { - const piece = resolvedPieces.find(p => p._id === o.pieceInstanceId) + const piece = resolvedPieces.find((p) => p._id === o.pieceInstanceId) return piece?.infinite?.infinitePieceId || o.pieceInstanceId || MEDIA_PLAYER_AUTO } else { return sessionId @@ -384,7 +384,7 @@ export function applyMediaPlayersAssignments< const remainingGroups: Array<{ id: string; objs: Array }> = [] for (const groupId of Object.keys(groupedObjs)) { const group = groupedObjs[groupId] - const request = _.find(activeRequests, req => req.id === groupId) + const request = _.find(activeRequests, (req) => req.id === groupId) if (request) { if (request.player) { // TODO - what if player is undefined? @@ -405,7 +405,7 @@ export function applyMediaPlayersAssignments< // If this is lookahead for a future part (no end set on the object) const isFuturePartLookahead = _.some( grp.objs, - o => + (o) => !!o.isLookahead /*|| (o as any).wasLookahead*/ && (o.enable as TSR.Timeline.TimelineEnable).duration === undefined && (o.enable as TSR.Timeline.TimelineEnable).end === undefined @@ -419,7 +419,7 @@ export function applyMediaPlayersAssignments< // These are the groups that shouldn't exist, so are likely a bug. There isnt a lot we can do beyond warn about the potential bug for (const grp of unknownGroups) { - const objIds = _.map(grp.objs, o => o.id) + const objIds = _.map(grp.objs, (o) => o.id) const prev = previousAssignmentRev[grp.id] if (prev) { updateObjectsToMediaPlayer(context, prev.playerId, grp.objs, sourceLayers) @@ -443,10 +443,10 @@ export function applyMediaPlayersAssignments< for (const mp of context.config.mediaPlayers) { // Block players with an 'infinite' clip from being used for lookahead const endTimes = _.map( - _.filter(activeRequests, s => s.player === mp.id), - s => s.end + _.filter(activeRequests, (s) => s.player === mp.id), + (s) => s.end ) - const realEndTimes = _.filter(endTimes, e => e !== undefined) as number[] + const realEndTimes = _.filter(endTimes, (e) => e !== undefined) as number[] if (endTimes.length === realEndTimes.length) { // No infinite(undefined) ones, so find the highest end mediaPlayerUsageEnd.push({ @@ -456,7 +456,7 @@ export function applyMediaPlayersAssignments< } } // Sort by the end time - mediaPlayerUsageEnd = _.sortBy(mediaPlayerUsageEnd, u => u.end).reverse() + mediaPlayerUsageEnd = _.sortBy(mediaPlayerUsageEnd, (u) => u.end).reverse() // Finish up with allocating lookahead based on what is left. If there is no space left that is not a problem until playback is closer for (const grp of lookaheadGroups) { @@ -466,7 +466,7 @@ export function applyMediaPlayersAssignments< context.core.logDebug('Players are available at:' + JSON.stringify(mediaPlayerUsageEnd)) - const prevAssignment = prev ? _.find(mediaPlayerUsageEnd, mp => mp.playerId === prev.playerId) : undefined + const prevAssignment = prev ? _.find(mediaPlayerUsageEnd, (mp) => mp.playerId === prev.playerId) : undefined if (prevAssignment && (prevAssignment.end === 0 || false)) { // TODO - decide if the previous assignment is still suitable context.core.logDebug('lookahead can retain existing player') diff --git a/src/tv2-common/helpers/config.ts b/src/tv2-common/helpers/config.ts index 22d47067..0e223259 100644 --- a/src/tv2-common/helpers/config.ts +++ b/src/tv2-common/helpers/config.ts @@ -18,7 +18,7 @@ export function findGfxSetup tableConfigGfxSetup.Name === config.GfxDefaults[0].GfxSetup + (tableConfigGfxSetup) => tableConfigGfxSetup.Name === config.GfxDefaults[0].GfxSetup ) if (!foundTableConfigGfxSetup) { context.logWarning(`No GFX setup found for profile: ${config.GfxDefaults[0].GfxSetup}`) diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index aa48f3d8..7ec8856f 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -25,7 +25,7 @@ export function findDskJingle(config: TV2ShowStyleConfig): TableConfigItemDSK { } function findDskWithRoles(config: TV2ShowStyleConfig, roles: DskRole[]): TableConfigItemDSK { - return config.dsk.find(dsk => dsk.Roles?.some(role => roles.includes(role))) ?? config.dsk[0] + return config.dsk.find((dsk) => dsk.Roles?.some((role) => roles.includes(role))) ?? config.dsk[0] } export function GetDSKCount(atemModel: ATEMModel) { @@ -161,7 +161,7 @@ export function createDskBaseline( config: TV2BlueprintConfigBase, videoSwitcher: VideoSwitcher ): TSR.TSRTimelineObj[] { - return config.dsk.map(dsk => { + return config.dsk.map((dsk) => { return videoSwitcher.getDskTimelineObject({ id: '', enable: { while: '1' }, @@ -183,7 +183,7 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { type: ConfigManifestEntryType.TABLE, required: false, defaultVal: literal>( - defaultVal.map(dsk => ({ _id: '', ...dsk, Roles: dsk.Roles ?? [] })) + defaultVal.map((dsk) => ({ _id: '', ...dsk, Roles: dsk.Roles ?? [] })) ), columns: [ { diff --git a/src/tv2-common/helpers/graphics/Graphic.ts b/src/tv2-common/helpers/graphics/Graphic.ts index 367ccdd4..077f7bf5 100644 --- a/src/tv2-common/helpers/graphics/Graphic.ts +++ b/src/tv2-common/helpers/graphics/Graphic.ts @@ -47,7 +47,7 @@ export abstract class Graphic { } protected getSourceLayer(name: string): SharedSourceLayer { - const template = this.config.showStyle.GfxTemplates.find(gfx => gfx.VizTemplate.toString() === name) + const template = this.config.showStyle.GfxTemplates.find((gfx) => gfx.VizTemplate.toString() === name) if (template && GFX_LAYERS.has(template.SourceLayer as SharedSourceLayer)) { return this.getSubstituteLayer(template.SourceLayer as SharedSourceLayer) @@ -99,7 +99,7 @@ export abstract class Graphic { protected findGfxTemplate(): TableConfigItemGfxTemplate | undefined { const templateId = this.getTemplateId() - return this.config.showStyle.GfxTemplates.find(templ => + return this.config.showStyle.GfxTemplates.find((templ) => templ.INewsName ? templ.INewsName.toString().toUpperCase() === templateId?.toUpperCase() : false ) } @@ -123,7 +123,7 @@ export abstract class Graphic { protected FindInfiniteModeFromConfig(): PieceLifespan { const templateName = this.getTemplateName() const iNewsName = GraphicIsInternal(this.cue) ? this.cue.graphic.template : undefined - const template = this.config.showStyle.GfxTemplates.find(gfx => + const template = this.config.showStyle.GfxTemplates.find((gfx) => gfx.VizTemplate ? gfx.VizTemplate.toString().toUpperCase() === templateName.toUpperCase() && (iNewsName ? gfx.INewsName.toUpperCase() === iNewsName.toUpperCase() : true) diff --git a/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts b/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts index f52d54c0..85db3644 100644 --- a/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts +++ b/src/tv2-common/helpers/graphics/caspar/__tests__/htmlPilotGraphicGenerator.spec.ts @@ -62,7 +62,7 @@ describe('HtmlPilotGraphicGenerator', () => { const generator = makeGeneratorForOvl() const pilotContent = generator.getContent() const timelineObjects = pilotContent.timelineObjects.filter( - tlObject => + (tlObject) => tlObject.content.deviceType === TSR.DeviceType.CASPARCG && (tlObject as TSR.TimelineObjCCGTemplate).content.type === TSR.TimelineContentTypeCasparCg.TEMPLATE ) @@ -96,7 +96,7 @@ describe('HtmlPilotGraphicGenerator', () => { const generator = makeGeneratorForOvl() const pilotContent = generator.getContent() const timelineObjects = pilotContent.timelineObjects.filter( - tlObject => + (tlObject) => tlObject.content.deviceType === TSR.DeviceType.ATEM && (tlObject as TSR.TimelineObjAtemDSK).content.type === TSR.TimelineContentTypeAtem.DSK ) @@ -132,7 +132,7 @@ describe('HtmlPilotGraphicGenerator', () => { const generator = makeGeneratorForFull() const pilotContent = generator.getContent() const timelineObjects = pilotContent.timelineObjects.filter( - tlObject => + (tlObject) => tlObject.content.deviceType === TSR.DeviceType.CASPARCG && (tlObject as TSR.TimelineObjCCGTemplate).content.type === TSR.TimelineContentTypeCasparCg.TEMPLATE ) diff --git a/src/tv2-common/helpers/graphics/caspar/util.ts b/src/tv2-common/helpers/graphics/caspar/util.ts index 872be04d..8ca061db 100644 --- a/src/tv2-common/helpers/graphics/caspar/util.ts +++ b/src/tv2-common/helpers/graphics/caspar/util.ts @@ -77,8 +77,8 @@ function getSlotBaselineTimelineObjects( layerMappings: SharedGraphicLLayer[] ): TSR.TSRTimelineObj[] { return layerMappings - .filter(layer => layerToHTMLGraphicSlot[layer]) - .map(layer => ({ + .filter((layer) => layerToHTMLGraphicSlot[layer]) + .map((layer) => ({ id: '', enable: { while: '1' diff --git a/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts b/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts index ab0ab163..e32a132e 100644 --- a/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts +++ b/src/tv2-common/helpers/graphics/internal/InternalGraphic.ts @@ -117,7 +117,7 @@ export abstract class InternalGraphic extends Graphic { public getTemplateName(): string { const iNewsTemplateName = this.cue.graphic.template - const template = this.config.showStyle.GfxTemplates.find(templ => + const template = this.config.showStyle.GfxTemplates.find((templ) => templ.INewsName ? templ.INewsName.toString().toUpperCase() === iNewsTemplateName.toUpperCase() : false ) if (template && template.VizTemplate.toString().length) { @@ -135,7 +135,7 @@ export abstract class InternalGraphic extends Graphic { public getDisplayName(): string { return `${this.cue.graphic.template ? `${this.templateName}` : ''}${ this.cue.graphic.textFields.length ? ' - ' : '' - }${this.cue.graphic.textFields.filter(txt => !txt.match(/^;.\.../i)).join('\n - ')}` + }${this.cue.graphic.textFields.filter((txt) => !txt.match(/^;.\.../i)).join('\n - ')}` } protected abstract getContent(): IBlueprintPiece['content'] diff --git a/src/tv2-common/helpers/graphics/layers.ts b/src/tv2-common/helpers/graphics/layers.ts index bc58ca4e..8c8bd839 100644 --- a/src/tv2-common/helpers/graphics/layers.ts +++ b/src/tv2-common/helpers/graphics/layers.ts @@ -2,7 +2,7 @@ import { TV2ShowStyleConfig } from 'tv2-common' import { SharedGraphicLLayer } from 'tv2-constants' export function getTimelineLayerForGraphic(config: TV2ShowStyleConfig, name: string) { - const conf = config.showStyle.GfxTemplates.find(gfx => gfx.VizTemplate.toString() === name) + const conf = config.showStyle.GfxTemplates.find((gfx) => gfx.VizTemplate.toString() === name) if (!conf) { return SharedGraphicLLayer.GraphicLLayerOverlay diff --git a/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts b/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts index a3eb971f..4becf094 100644 --- a/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts +++ b/src/tv2-common/helpers/graphics/pilot/PilotGraphicGenerator.ts @@ -148,7 +148,7 @@ export abstract class PilotGraphicGenerator extends Graphic { public createFullDataStore(): IBlueprintPiece { const content = this.getContent() content.timelineObjects = content.timelineObjects.filter( - o => + (o) => o.content.deviceType !== TSR.DeviceType.ATEM && o.content.deviceType !== TSR.DeviceType.TRICASTER && o.content.deviceType !== TSR.DeviceType.SISYFOS && diff --git a/src/tv2-common/helpers/postProcessDefinitions.ts b/src/tv2-common/helpers/postProcessDefinitions.ts index ff0db951..c6178180 100644 --- a/src/tv2-common/helpers/postProcessDefinitions.ts +++ b/src/tv2-common/helpers/postProcessDefinitions.ts @@ -6,7 +6,7 @@ export function PostProcessDefinitions(partDefinitions: PartDefinition[], segmen partDefinitions.forEach((part, i) => { setPartTitle(part) - part.cues = part.cues.map(c => { + part.cues = part.cues.map((c) => { if (c.type === CueType.Ekstern) { c.transition = undefined } @@ -56,7 +56,7 @@ function getExternalId(segmentId: string, partDefinition: PartDefinition, foundM break case PartType.INTRO: // Intro must have a jingle cue, if it doesn't then padId will handle - const jingle = partDefinition.cues.find(cue => cue.type === CueType.Jingle) as CueDefinitionJingle + const jingle = partDefinition.cues.find((cue) => cue.type === CueType.Jingle) as CueDefinitionJingle if (jingle) { id += `-${jingle.clip}` } diff --git a/src/tv2-common/helpers/rundownAdLibActions.ts b/src/tv2-common/helpers/rundownAdLibActions.ts index 3c9a35d1..ba8906e2 100644 --- a/src/tv2-common/helpers/rundownAdLibActions.ts +++ b/src/tv2-common/helpers/rundownAdLibActions.ts @@ -39,7 +39,7 @@ export function GetTransitionAdLibActions< if (config.showStyle.Transitions) { const transitionActions: IBlueprintActionManifest[] = config.showStyle.Transitions.filter( - transition => transition.Transition && transition.Transition.length + (transition) => transition.Transition && transition.Transition.length ).flatMap((transition, i) => createActionsForTransition(config, transition.Transition, startingRank + 0.01 * i)) blueprintActionManifests.push(...transitionActions) } @@ -52,7 +52,7 @@ function createActionsForTransition( transition: string, rank: number ): IBlueprintActionManifest[] { - const jingleConfig = config.showStyle.BreakerConfig.find(j => j.BreakerName === transition) + const jingleConfig = config.showStyle.BreakerConfig.find((j) => j.BreakerName === transition) const transitionValues: TransitionValues = { rank, label: transition, diff --git a/src/tv2-common/helpers/serverResume.ts b/src/tv2-common/helpers/serverResume.ts index 9e99ed5b..20858dc5 100644 --- a/src/tv2-common/helpers/serverResume.ts +++ b/src/tv2-common/helpers/serverResume.ts @@ -81,7 +81,7 @@ export function getServerPositionForPartInstance( const previousPartEndState = partInstance.previousPartEndState as Partial | undefined const previousServerPosition = previousPartEndState?.serverPosition - const currentPiecesWithServer = _.sortBy(pieceInstances.filter(shouldPreservePosition), p => p.resolvedStart) + const currentPiecesWithServer = _.sortBy(pieceInstances.filter(shouldPreservePosition), (p) => p.resolvedStart) let currentServerPosition = previousPartEndState?.segmentId === partInstance.segmentId ? previousServerPosition : undefined diff --git a/src/tv2-common/helpers/sisyfos.ts b/src/tv2-common/helpers/sisyfos.ts index 52fcc8b5..b8909f1d 100644 --- a/src/tv2-common/helpers/sisyfos.ts +++ b/src/tv2-common/helpers/sisyfos.ts @@ -98,7 +98,7 @@ function GetSisyfosTimelineObjForSource( ): TSR.TimelineObjSisyfosAny[] { const result: TSR.TimelineObjSisyfosAny[] = [] const timelineEnable = getFallbackEnable(enable) - sourceInfo.sisyfosLayers?.forEach(layer => { + sourceInfo.sisyfosLayers?.forEach((layer) => { result.push( literal({ id: '', @@ -124,7 +124,7 @@ function getStudioMicsTimelineObj( timelineEnable: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosChannels { const studioMicsChannels: TSR.TimelineObjSisyfosChannels['content']['channels'] = [] - config.studio.StudioMics.forEach(layer => { + config.studio.StudioMics.forEach((layer) => { studioMicsChannels.push({ mappedLayer: layer, isPgm: 1 diff --git a/src/tv2-common/hotkeys/clear.ts b/src/tv2-common/hotkeys/clear.ts index b8e33f54..16275c41 100644 --- a/src/tv2-common/hotkeys/clear.ts +++ b/src/tv2-common/hotkeys/clear.ts @@ -20,7 +20,7 @@ export function MakeClearHotkeys( assignments: ClearLayerHotkeyAssignments, getNextRank: () => number ) { - return assignments.map(clearedSourceLayer => + return assignments.map((clearedSourceLayer) => literal({ _id: clearSourceLayerHotKeyId(showStyleId, clearedSourceLayer.sourceLayers), _rank: getNextRank(), diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index 7b0ca4af..52e72aa8 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -201,7 +201,7 @@ export function ParseBody( externalId: `${segmentId}-${definitions.length}`, segmentExternalId: segmentId } - cues.forEach(cue => { + cues.forEach((cue) => { if (cue !== null) { const parsedCue = ParseCue(cue, config) @@ -220,9 +220,9 @@ export function ParseBody( for (let i = 0; i < lines.length; i++) { lines[i] = lines[i].replace(/(.*?)<\/cc>/gi, '') } - lines = lines.filter(line => line !== '

' && line !== '

') + lines = lines.filter((line) => line !== '

' && line !== '

') - lines.forEach(line => { + lines.forEach((line) => { const type = line.match(/(.*?)<\/pi>/i) if (type) { @@ -235,11 +235,11 @@ export function ParseBody( .replace(/<\/tab>/i, '') .trim() - if (typeStr && ACCEPTED_RED_TEXT.some(r => r.test(typeStr))) { + if (typeStr && ACCEPTED_RED_TEXT.some((r) => r.test(typeStr))) { const inlineCues = line .replace(/<\/?p>/g, '') .split(/(.*?)<\/pi>/i) - .filter(cue => cue !== '' && !/<\/a>/.test(cue)) + .filter((cue) => cue !== '' && !/<\/a>/.test(cue)) /** Hold any secondary cues in the form: `[] KAM 1` */ const secondaryInlineCues: CueDefinition[] = [] @@ -248,11 +248,11 @@ export function ParseBody( let pos = 0 let redTextFound = false while (pos < inlineCues.length && !redTextFound) { - if (ACCEPTED_RED_TEXT.some(r => r.test(inlineCues[pos]))) { + if (ACCEPTED_RED_TEXT.some((r) => r.test(inlineCues[pos]))) { redTextFound = true } else { const parsedCues = getCuesInLine(inlineCues[pos], cues, config) - parsedCues.forEach(cue => { + parsedCues.forEach((cue) => { // Create standalone parts for primary cues. if ( isPrimaryCue(cue) && @@ -316,7 +316,7 @@ export function ParseBody( if (cueInLine(line)) { const parsedCues = getCuesInLine(line, cues, config) - parsedCues.forEach(cue => { + parsedCues.forEach((cue) => { if (isPrimaryCue(cue)) { let storedScript = '' if (shouldPushDefinition(definition)) { @@ -350,7 +350,7 @@ export function ParseBody( } // Flatten cues such as targetEngine. - definitions.forEach(partDefinition => { + definitions.forEach((partDefinition) => { if (partDefinition.cues.length) { while (FindTargetPair(partDefinition)) { // NO-OP @@ -358,7 +358,7 @@ export function ParseBody( } // Discard UNKNOWN cues, we won't do anything with them - partDefinition.cues = partDefinition.cues.filter(c => c.type !== CueType.UNKNOWN) + partDefinition.cues = partDefinition.cues.filter((c) => c.type !== CueType.UNKNOWN) }) definitions = stripRedundantCuesWhenLayoutCueIsPresent(definitions) @@ -368,7 +368,7 @@ export function ParseBody( export function FindTargetPair(partDefinition: PartDefinition): boolean { const index = partDefinition.cues.findIndex( - cue => (cue.type === CueType.UNPAIRED_TARGET && cue.mergeable) || (cue.type === CueType.Telefon && !cue.graphic) + (cue) => (cue.type === CueType.UNPAIRED_TARGET && cue.mergeable) || (cue.type === CueType.Telefon && !cue.graphic) ) if (index === -1) { @@ -437,7 +437,7 @@ function getCuesInLine(line: string, cues: UnparsedCue[], config: TV2ShowStyleCo const definitions: CueDefinition[] = [] const cue = line.match(/
/gi) - cue?.forEach(c => { + cue?.forEach((c) => { const value = c.match(//i) if (value) { const realCue = cues[Number(value[1])] @@ -457,10 +457,7 @@ function getCuesInLine(line: string, cues: UnparsedCue[], config: TV2ShowStyleCo function addScript(line: string, definition: PartDefinition) { const script = line.match(/

(.*?)<\/p>/i) if (script && script[1] && !/.*?<\/pi>/i.test(script[1])) { - const trimscript = script[1] - .replace(/<.*?>/gi, '') - .replace('\n\r', '') - .trim() + const trimscript = script[1].replace(/<.*?>/gi, '').replace('\n\r', '').trim() if (trimscript) { definition.script += `${trimscript}\n` } @@ -478,7 +475,7 @@ function isPrimaryCue(cue: CueDefinition) { function shouldPushDefinition(definition: PartDefinition) { return ( - (definition.cues.filter(c => c.type !== CueType.UNKNOWN).length || + (definition.cues.filter((c) => c.type !== CueType.UNKNOWN).length || (definition.script.length && definition.cues.length) || definition.type !== PartType.Unknown) && !(definition.type === PartType.Grafik && definition.cues.length === 0) @@ -601,10 +598,7 @@ function extractTypeProperties(typeStr: string): PartdefinitionTypes { break } - const tokens = stripTransitionProperties(typeStr) - .replace(/100%/g, '') - .trim() - .split(' ') + const tokens = stripTransitionProperties(typeStr).replace(/100%/g, '').trim().split(' ') const firstToken = tokens[0] if (/SERVER|ATTACK/i.test(firstToken)) { @@ -636,9 +630,7 @@ function extractTypeProperties(typeStr: string): PartdefinitionTypes { } export function getSourceDefinition(typeStr: string): SourceDefinition | undefined { - const strippedTypeStr = stripTransitionProperties(typeStr) - .replace(/100%/g, '') - .trim() + const strippedTypeStr = stripTransitionProperties(typeStr).replace(/100%/g, '').trim() if (CAMERA_RED_TEXT.test(strippedTypeStr)) { const id = strippedTypeStr.match(CAMERA_RED_TEXT)![1].toUpperCase() return { @@ -706,8 +698,8 @@ export function isMinusMic(inputName: string): boolean { } export function stripRedundantCuesWhenLayoutCueIsPresent(partDefinitions: PartDefinition[]): PartDefinition[] { - const hasLayoutCue: boolean = partDefinitions.some(definition => - definition.cues.some(cue => { + const hasLayoutCue: boolean = partDefinitions.some((definition) => + definition.cues.some((cue) => { const cueFromLayout = cue as CueDefinitionFromLayout return cueFromLayout.isFromLayout }) @@ -717,8 +709,8 @@ export function stripRedundantCuesWhenLayoutCueIsPresent(partDefinitions: PartDe return partDefinitions } - return partDefinitions.map(definition => { - const cues = definition.cues.filter(cue => { + return partDefinitions.map((definition) => { + const cues = definition.cues.filter((cue) => { if (cue.type !== CueType.GraphicDesign && cue.type !== CueType.BackgroundLoop) { return true } diff --git a/src/tv2-common/inewsConversion/converters/ParseCue.ts b/src/tv2-common/inewsConversion/converters/ParseCue.ts index b74b4581..ad754901 100644 --- a/src/tv2-common/inewsConversion/converters/ParseCue.ts +++ b/src/tv2-common/inewsConversion/converters/ParseCue.ts @@ -203,9 +203,9 @@ export function ParseCue(cue: UnparsedCue, config: TV2ShowStyleConfig): CueDefin return undefined } - cue = cue.filter(c => c !== '') + cue = cue.filter((c) => c !== '') // Replace multiple spaces / tabs with a single space - cue = cue.map(c => c?.trim().replace(/\s+/g, ' ')) + cue = cue.map((c) => c?.trim().replace(/\s+/g, ' ')) if (cue.length === 0) { return undefined @@ -335,7 +335,7 @@ function parsekg( const graphicDesignConfig = code ? config.showStyle.GfxDesignTemplates.find( - template => template.INewsName.toUpperCase() === graphic.template.toUpperCase() + (template) => template.INewsName.toUpperCase() === graphic.template.toUpperCase() ) : undefined @@ -352,7 +352,7 @@ function parsekg( const graphicConfig = code ? config.showStyle.GfxTemplates.find( - template => + (template) => template.INewsCode.replace(/^KG=?/gi, '#KG').toUpperCase() === code.replace(/^KG=?/gi, '#KG').toUpperCase() && template.INewsName.toUpperCase() === graphic.template.toUpperCase() ) @@ -387,7 +387,7 @@ function parsePilot(cue: string[]): CueDefinitionUnpairedPilot | CueDefinitionGr iNewsCommand: 'VCP' } const realCue: string[] = [] - cue.forEach(line => { + cue.forEach((line) => { if ( !line.match(/[#|*]?cg\d+[ -]pilotdata/i) && !line.match(/^]] [a-z]\d\.\d [a-z] \d \[\[$/i) && @@ -472,7 +472,7 @@ function parseDVE(cue: string[]): CueDefinitionDVE { iNewsCommand: 'DVE' } - cue.forEach(c => { + cue.forEach((c) => { if (c.match(/^DVE=/i)) { const template = c.match(/^DVE=(.+)$/i) if (template) { @@ -561,7 +561,7 @@ function parseMic(cue: string[]): CueDefinitionMic { mics: {}, iNewsCommand: 'STUDIE' } - cue.forEach(c => { + cue.forEach((c) => { if (!c.match(/^STUDIE=MIC ON OFF$/i)) { if (isTime(c)) { micCue = { ...micCue, ...parseTime(c) } @@ -720,7 +720,9 @@ function parseTargetEngine( } const graphicDesignConfig = code - ? config.showStyle.GfxDesignTemplates.find(template => template.INewsName.toUpperCase() === iNewsName.toUpperCase()) + ? config.showStyle.GfxDesignTemplates.find( + (template) => template.INewsName.toUpperCase() === iNewsName.toUpperCase() + ) : undefined if (graphicDesignConfig) { @@ -735,7 +737,7 @@ function parseTargetEngine( } const graphicConfig = config.showStyle.GfxTemplates.find( - template => + (template) => template.INewsCode.toUpperCase() === code?.toUpperCase() && template.INewsName.toUpperCase() === iNewsName.toUpperCase() ) @@ -772,7 +774,7 @@ function parseAllOut(cue: string[]): CueDefinitionClearGrafiks { } let time = false - cue.forEach(c => { + cue.forEach((c) => { const command = c.match(/^([#* ]?kg)/i) if (command) { clearCue.iNewsCommand = command[1] @@ -920,7 +922,7 @@ function findGraphicDesignConfiguration( layout: string ): TableConfigItemGfxDesignTemplate | undefined { return config.showStyle.GfxDesignTemplates.find( - template => template.INewsStyleColumn && template.INewsStyleColumn.toUpperCase() === layout.toUpperCase() + (template) => template.INewsStyleColumn && template.INewsStyleColumn.toUpperCase() === layout.toUpperCase() ) } diff --git a/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts b/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts index a1da0c17..6521f593 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts @@ -3405,7 +3405,7 @@ describe('Body parser', () => { const cues = result[0].cues expect(cues).toHaveLength(3) - const regularDesignCue = cues.find(cue => { + const regularDesignCue = cues.find((cue) => { const designCue = cue as CueDefinitionGraphicDesign if (!designCue.design) { return false @@ -3424,7 +3424,7 @@ describe('Body parser', () => { const result: PartDefinition[] = stripRedundantCuesWhenLayoutCueIsPresent(definitions) - const cues: CueDefinition[] = result.flatMap(definition => definition.cues) + const cues: CueDefinition[] = result.flatMap((definition) => definition.cues) expect(cues).toHaveLength(1) const graphicCue = cues[0] as CueDefinitionGraphicDesign expect(graphicCue.design).toBe(layoutDesign) @@ -3538,7 +3538,7 @@ function createUnknownCueDefinition(): CueDefinition { } export function stripExternalId(definitions: PartDefinition[]) { - return definitions.map(def => { + return definitions.map((def) => { return { ...def, ...{ externalId: '' } } }) } diff --git a/src/tv2-common/jinglePartProperties.ts b/src/tv2-common/jinglePartProperties.ts index d752d213..924d7798 100644 --- a/src/tv2-common/jinglePartProperties.ts +++ b/src/tv2-common/jinglePartProperties.ts @@ -10,13 +10,11 @@ export function GetJinglePartProperties( part: PartDefinition ): Pick | {} { if (part.cues) { - const cue = part.cues.find(c => c.type === CueType.Jingle) as CueDefinitionJingle + const cue = part.cues.find((c) => c.type === CueType.Jingle) as CueDefinitionJingle if (cue) { - const realBreaker = context.config.showStyle.BreakerConfig.find(conf => { + const realBreaker = context.config.showStyle.BreakerConfig.find((conf) => { return conf.BreakerName && typeof conf.BreakerName === 'string' - ? conf.BreakerName.toString() - .trim() - .toUpperCase() === cue.clip.toUpperCase() + ? conf.BreakerName.toString().trim().toUpperCase() === cue.clip.toUpperCase() : false }) diff --git a/src/tv2-common/migrations/__tests__/dve-config-folder.spec.ts b/src/tv2-common/migrations/__tests__/dve-config-folder.spec.ts index e459b912..4b374464 100644 --- a/src/tv2-common/migrations/__tests__/dve-config-folder.spec.ts +++ b/src/tv2-common/migrations/__tests__/dve-config-folder.spec.ts @@ -29,7 +29,7 @@ function testDescriptionToConfig( ): ConfigItemValue { const preMigration = step === 'premigration' return literal( - description.map(item => ({ + description.map((item) => ({ _id: item.DVEName, DVEName: item.DVEName, DVEGraphicsKey: preMigration @@ -283,7 +283,7 @@ const normalizeSoundbedTests: StripDVEFolderMigrationTestCase[] = [ ] describe('Remove dve folder from dve config', () => { - normalizeSoundbedTests.forEach(testDescription => { + normalizeSoundbedTests.forEach((testDescription) => { test(testDescription.description, () => { const context = new MockShowstyleMigrationContext() context.configs.set(DVE_CONFIG_KEY, testDescriptionToConfig(testDescription.data, 'premigration')) diff --git a/src/tv2-common/migrations/__tests__/migrationContext.mock.ts b/src/tv2-common/migrations/__tests__/migrationContext.mock.ts index ec2a8a39..24d9fbbf 100644 --- a/src/tv2-common/migrations/__tests__/migrationContext.mock.ts +++ b/src/tv2-common/migrations/__tests__/migrationContext.mock.ts @@ -20,7 +20,7 @@ export class MockShowstyleMigrationContext implements MigrationContextShowStyle return variantId } public getVariant(variantId: string): IBlueprintShowStyleVariant | undefined { - return this.variants.find(variant => variant._id === variantId) + return this.variants.find((variant) => variant._id === variantId) } public insertVariant(variantId: string, variant: OmitId): string { throw new Error(`Function not implemented in mock: 'insertVariant' args: '${variantId}, ${JSON.stringify(variant)}`) diff --git a/src/tv2-common/migrations/__tests__/soundbed-config-audio-folder.spec.ts b/src/tv2-common/migrations/__tests__/soundbed-config-audio-folder.spec.ts index 7e0fb8f8..a76e347f 100644 --- a/src/tv2-common/migrations/__tests__/soundbed-config-audio-folder.spec.ts +++ b/src/tv2-common/migrations/__tests__/soundbed-config-audio-folder.spec.ts @@ -27,7 +27,7 @@ function testDescriptionToConfig( ): ConfigItemValue { const preMigration = step === 'premigration' return literal( - description.map(item => ({ + description.map((item) => ({ _id: item.iNewsName, INewsName: item.iNewsName, FileName: preMigration ? item.PreMigration : item.PostMigration ?? item.PreMigration @@ -235,7 +235,7 @@ const normalizeSoundbedTests: StripAudioFolderMigrationTestCase[] = [ ] describe('Remove audio folder from soundbed config', () => { - normalizeSoundbedTests.forEach(testDescription => { + normalizeSoundbedTests.forEach((testDescription) => { test(testDescription.description, () => { const context = new MockShowstyleMigrationContext() context.configs.set(AUDIO_BED_CONFIG_KEY, testDescriptionToConfig(testDescription.data, 'premigration')) diff --git a/src/tv2-common/migrations/addKeepAudio.ts b/src/tv2-common/migrations/addKeepAudio.ts index a36cb760..76e1acd7 100644 --- a/src/tv2-common/migrations/addKeepAudio.ts +++ b/src/tv2-common/migrations/addKeepAudio.ts @@ -22,7 +22,7 @@ export function AddKeepAudio(versionStr: string, configName: string): MigrationS migrate: (context: MigrationContextStudio) => { const configVal = context.getConfig(configName) if (Array.isArray(configVal) && configVal.length) { - _.each(configVal as TableConfigItemValue, source => { + _.each(configVal as TableConfigItemValue, (source) => { source.KeepAudioInStudio = source.KeepAudioInStudio !== undefined ? source.KeepAudioInStudio : true }) context.setConfig(configName, configVal) diff --git a/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts b/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts index 9e7dd804..9bf4d048 100644 --- a/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts +++ b/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts @@ -19,7 +19,7 @@ export function forceSourceLayerToDefaultsBase( return `SourceLayer "${layer}" doesn't exist on ShowBaseStyle` } - const defaultVal = sourcelayerDefaults.find(l => l._id === layer) + const defaultVal = sourcelayerDefaults.find((l) => l._id === layer) if (!defaultVal) { return false @@ -32,7 +32,7 @@ export function forceSourceLayerToDefaultsBase( context.removeSourceLayer(layer) } - const defaultVal = sourcelayerDefaults.find(l => l._id === layer) + const defaultVal = sourcelayerDefaults.find((l) => l._id === layer) if (!defaultVal) { return diff --git a/src/tv2-common/migrations/hotkeys.ts b/src/tv2-common/migrations/hotkeys.ts index fbb8961b..26393b4d 100644 --- a/src/tv2-common/migrations/hotkeys.ts +++ b/src/tv2-common/migrations/hotkeys.ts @@ -43,7 +43,7 @@ export function GetDefaultAdLibTriggers( sourceLayers ) - return shortcutsDefaults.some(defaultShortcut => { + return shortcutsDefaults.some((defaultShortcut) => { const existingShortcut = context.getTriggeredAction(defaultShortcut._id) if (!existingShortcut) { @@ -83,12 +83,12 @@ export function RemoveOldShortcuts( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const sourceLayers = sourceLayerDefaults.map(sourceLayer => context.getSourceLayer(sourceLayer._id)) as Array< + const sourceLayers = sourceLayerDefaults.map((sourceLayer) => context.getSourceLayer(sourceLayer._id)) as Array< ISourceLayerWithHotKeys | undefined > return sourceLayers.some( - sourceLayer => + (sourceLayer) => !!sourceLayer?.clearKeyboardHotkey || !!sourceLayer?.activateKeyboardHotkeys || !!sourceLayer?.activateStickyKeyboardHotkey || diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index b47ed6c1..74c3e4fb 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -106,7 +106,7 @@ export function AddGraphicToGfxTable( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const existing = (context.getBaseConfig('GFXTemplates') as unknown) as + const existing = context.getBaseConfig('GFXTemplates') as unknown as | TableConfigItemGfxTemplateWithDesign[] | undefined @@ -115,16 +115,16 @@ export function AddGraphicToGfxTable( } return !existing.some( - g => + (g) => g.INewsName === config.INewsName && g.INewsCode === config.INewsCode && g.VizTemplate === config.VizTemplate ) }, migrate: (context: MigrationContextShowStyle) => { - const existing = (context.getBaseConfig('GFXTemplates') as unknown) as TableConfigItemGfxTemplateWithDesign[] + const existing = context.getBaseConfig('GFXTemplates') as unknown as TableConfigItemGfxTemplateWithDesign[] existing.push(config) - context.setBaseConfig('GFXTemplates', (existing as unknown) as ConfigItemValue) + context.setBaseConfig('GFXTemplates', existing as unknown as ConfigItemValue) } } } @@ -140,11 +140,9 @@ export function mapGfxTemplateToDesignTemplateAndDeleteOriginals( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const gfxTemplates = (context.getBaseConfig(from) as unknown) as - | TableConfigItemGfxTemplateWithDesign[] - | undefined + const gfxTemplates = context.getBaseConfig(from) as unknown as TableConfigItemGfxTemplateWithDesign[] | undefined - const designTemplates = (context.getBaseConfig(to) as unknown) as TableConfigItemGfxDesignTemplate[] | undefined + const designTemplates = context.getBaseConfig(to) as unknown as TableConfigItemGfxDesignTemplate[] | undefined if (!gfxTemplates || !gfxTemplates.length) { return false @@ -154,72 +152,69 @@ export function mapGfxTemplateToDesignTemplateAndDeleteOriginals( return false } - return gfxTemplates.some(template => template.IsDesign) + return gfxTemplates.some((template) => template.IsDesign) }, migrate: (context: MigrationContextShowStyle) => { - const gfxTemplates = (context.getBaseConfig(from) as unknown) as TableConfigItemGfxTemplateWithDesign[] - const designTemplates = ((context.getBaseConfig(to) as unknown) as TableConfigItemGfxDesignTemplate[]) ?? [] + const gfxTemplates = context.getBaseConfig(from) as unknown as TableConfigItemGfxTemplateWithDesign[] + const designTemplates = (context.getBaseConfig(to) as unknown as TableConfigItemGfxDesignTemplate[]) ?? [] gfxTemplates - .filter(template => template.IsDesign) - .map(template => { + .filter((template) => template.IsDesign) + .map((template) => { designTemplates.push({ ...template, INewsStyleColumn: '' }) }) - const newGfxTemplates = gfxTemplates.filter(template => !template.IsDesign) + const newGfxTemplates = gfxTemplates.filter((template) => !template.IsDesign) - context.setBaseConfig(from, (newGfxTemplates as unknown) as ConfigItemValue) - context.setBaseConfig(to, (designTemplates as unknown) as ConfigItemValue) + context.setBaseConfig(from, newGfxTemplates as unknown as ConfigItemValue) + context.setBaseConfig(to, designTemplates as unknown as ConfigItemValue) } }) } -export function moveSelectedGfxSetupNameToGfxDefaults(versionStr: string, fromValue: string, targetTable: string) { +export function moveSelectedGfxSetupNameToGfxDefaults(versionStr: string) { + const fromValue = 'SelectedGfxSetupName' + const targetTable = 'GfxDefaults' return literal({ - id: `${versionStr}.moveSelectedGfxSetupName.${fromValue}.ToTable.${targetTable}`, + id: `${versionStr}.moveSelectedGfxSetupName.${fromValue}.toTable.${targetTable}`, version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const singleValue = (context.getBaseConfig(fromValue) as unknown) as string - const designatedTable = (context.getBaseConfig(targetTable) as unknown) as TableConfigItemValue | undefined + const singleValue = context.getBaseConfig(fromValue) + const designatedTable = context.getBaseConfig(targetTable) if (!singleValue || !Array.isArray(designatedTable)) { return false } - return singleValue + return true }, migrate: (context: MigrationContextShowStyle) => { const singleValue = context.getBaseConfig(fromValue) as BasicConfigItemValue - const designatedTable = (context.getBaseConfig(targetTable) as unknown) as TableConfigItemValue + const designatedTable = context.getBaseConfig(targetTable) as unknown as TableConfigItemValue const setupName = 'DefaultSetupName' designatedTable[0][setupName] = singleValue - context.setBaseConfig(targetTable, (designatedTable as unknown) as ConfigItemValue) + context.setBaseConfig(targetTable, designatedTable) context.removeBaseConfig(fromValue) } }) } -export function moveSelectedGfxSetupNameToGfxDefaultsInVariants( - versionStr: string, - fromValue: string, - targetTable: string -) { +export function moveSelectedGfxSetupNameToGfxDefaultsInVariants(migrationVersion: string) { + const fromValue = 'SelectedGfxSetupName' + const targetTable = 'GfxDefaults' return literal({ - id: `${versionStr}.moveSelectedGfxSetupNameToGfxDefaultsInVariants.${fromValue}.ToTable.${targetTable}`, - version: versionStr, + id: `${migrationVersion}.moveSelectedGfxSetupNameToGfxDefaultsInVariants.${fromValue}.toTable.${targetTable}`, + version: migrationVersion, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { const allVariants = context.getAllVariants() - const checkForDefaultsTransfer = allVariants.some((variant: IBlueprintShowStyleVariant) => { - const defaultsTable = context.getVariantConfig(variant._id, targetTable) as TableConfigItemValue - const setupNameTable = context.getVariantConfig(variant._id, fromValue) as ConfigItemValue - return setupNameTable && !defaultsTable - }) - return checkForDefaultsTransfer + return allVariants.some((variant: IBlueprintShowStyleVariant) => { + return context.getVariantConfig(variant._id, fromValue) && !context.getVariantConfig(variant._id, targetTable) + }) }, migrate: (context: MigrationContextShowStyle) => { const allVariants = context.getAllVariants() @@ -232,38 +227,34 @@ export function moveSelectedGfxSetupNameToGfxDefaultsInVariants( designatedTable = [{ [setupName]: singleValue, _id: '' }] } - designatedTable[0][setupName] = singleValue - const updatedVariant = variant - - updatedVariant.blueprintConfig[targetTable] = designatedTable - context.updateVariant(variant._id, updatedVariant) + context.setVariantConfig(variant._id, targetTable, designatedTable) }) } }) } export function addSourceToSourcesConfig( - versionStr: string, + migrationVersion: string, studio: string, configId: string, source: TableConfigItemSourceMappingWithSisyfos ): MigrationStepStudio { return { - id: `${versionStr}.studioConfig.addReplaySource.${source.SourceName}.${studio}`, - version: versionStr, + id: `${migrationVersion}.studioConfig.addReplaySource.${source.SourceName}.${studio}`, + version: migrationVersion, canBeRunAutomatically: true, validate: (context: MigrationContextStudio) => { - const config = (context.getConfig(configId) as unknown) as TableConfigItemSourceMappingWithSisyfos[] + const config = context.getConfig(configId) as unknown as TableConfigItemSourceMappingWithSisyfos[] if (!config) { return false } - return !config.find(s => s.SourceName === source.SourceName) + return !config.find((s) => s.SourceName === source.SourceName) }, migrate: (context: MigrationContextStudio) => { - const config = (context.getConfig(configId) as unknown) as TableConfigItemSourceMappingWithSisyfos[] + const config = context.getConfig(configId) as unknown as TableConfigItemSourceMappingWithSisyfos[] config.push(source) - context.setConfig(configId, (config as unknown) as ConfigItemValue) + context.setConfig(configId, config as unknown as ConfigItemValue) } } } @@ -280,7 +271,7 @@ export function changeGfxTemplate( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const gfxTemplates = (context.getBaseConfig('GFXTemplates') as unknown) as + const gfxTemplates = context.getBaseConfig('GFXTemplates') as unknown as | TableConfigItemGfxTemplateWithDesign[] | undefined @@ -288,14 +279,14 @@ export function changeGfxTemplate( return false } - return gfxTemplates.some(g => isGfxTemplateSubset(g, oldConfig)) + return gfxTemplates.some((g) => isGfxTemplateSubset(g, oldConfig)) }, migrate: (context: MigrationContextShowStyle) => { - let existing = (context.getBaseConfig('GFXTemplates') as unknown) as TableConfigItemGfxTemplateWithDesign[] + let existing = context.getBaseConfig('GFXTemplates') as unknown as TableConfigItemGfxTemplateWithDesign[] - existing = existing.map(g => (isGfxTemplateSubset(g, oldConfig) ? { ...g, ...config } : g)) + existing = existing.map((g) => (isGfxTemplateSubset(g, oldConfig) ? { ...g, ...config } : g)) - context.setBaseConfig('GFXTemplates', (existing as unknown) as ConfigItemValue) + context.setBaseConfig('GFXTemplates', existing as unknown as ConfigItemValue) } } } @@ -419,9 +410,9 @@ export function StripFolderFromShowStyleConfig( } // Some entry in the table contains a field that needs migrating - return configTableValue.some(config => { - return configFields.some(field => { - return ((config[field] as unknown) as string | undefined)?.match(regex) + return configTableValue.some((config) => { + return configFields.some((field) => { + return (config[field] as unknown as string | undefined)?.match(regex) }) }) }, @@ -432,9 +423,9 @@ export function StripFolderFromShowStyleConfig( return } - configTableValue = configTableValue.map(config => { - configFields.forEach(field => { - const newConfig = (config[field] as unknown) as string + configTableValue = configTableValue.map((config) => { + configFields.forEach((field) => { + const newConfig = config[field] as unknown as string const matches = newConfig.match(regex) @@ -463,17 +454,17 @@ export function PrefixEvsWithEvs( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextStudio) => { - const config = (context.getConfig(configId) as unknown) as TableConfigItemSourceMappingWithSisyfos[] + const config = context.getConfig(configId) as unknown as TableConfigItemSourceMappingWithSisyfos[] - if (!config || config.find(value => value.SourceName === `EVS ${evsSourceNumber}`) !== undefined) { + if (!config || config.find((value) => value.SourceName === `EVS ${evsSourceNumber}`) !== undefined) { return false } - return config.find(value => value.SourceName === evsSourceNumber) !== undefined + return config.find((value) => value.SourceName === evsSourceNumber) !== undefined }, migrate: (context: MigrationContextStudio) => { - const config = (context.getConfig(configId) as unknown) as TableConfigItemSourceMappingWithSisyfos[] - const index: number = config.findIndex(value => value.SourceName === evsSourceNumber) + const config = context.getConfig(configId) as unknown as TableConfigItemSourceMappingWithSisyfos[] + const index: number = config.findIndex((value) => value.SourceName === evsSourceNumber) if (index === -1) { return } @@ -481,7 +472,7 @@ export function PrefixEvsWithEvs( evsSource.SourceName = `EVS ${evsSource.SourceName}` config[index] = evsSource - context.setConfig(configId, (config as unknown) as ConfigItemValue) + context.setConfig(configId, config as unknown as ConfigItemValue) } } } @@ -496,24 +487,24 @@ export function convertStudioTableColumnToFloat( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextStudio) => { - const config = (context.getConfig(tableId) as unknown) as TableConfigItemValue + const config = context.getConfig(tableId) as unknown as TableConfigItemValue if (!config || !Array.isArray(config)) { return false } - return config.find(row => columnId in row && typeof row[columnId] === 'string') !== undefined + return config.find((row) => columnId in row && typeof row[columnId] === 'string') !== undefined }, migrate: (context: MigrationContextStudio) => { - let config = (context.getConfig(tableId) as unknown) as TableConfigItemValue - config = config.map(row => { + let config = context.getConfig(tableId) as unknown as TableConfigItemValue + config = config.map((row) => { const value = row[columnId] if (typeof value === 'string') { row[columnId] = parseFloat(value) } return row }) - context.setConfig(tableId, (config as unknown) as ConfigItemValue) + context.setConfig(tableId, config as unknown as ConfigItemValue) } } } @@ -529,23 +520,23 @@ export function renameStudioTableColumn( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextStudio) => { - const config = (context.getConfig(tableId) as unknown) as TableConfigItemValue + const config = context.getConfig(tableId) as unknown as TableConfigItemValue if (!config || !Array.isArray(config)) { return false } - return config.find(row => oldColumnId in row) !== undefined + return config.find((row) => oldColumnId in row) !== undefined }, migrate: (context: MigrationContextStudio) => { - let config = (context.getConfig(tableId) as unknown) as TableConfigItemValue - config = config.map(row => { + let config = context.getConfig(tableId) as unknown as TableConfigItemValue + config = config.map((row) => { const value = row[oldColumnId] delete row[oldColumnId] row[newColumnId] = value return row }) - context.setConfig(tableId, (config as unknown) as ConfigItemValue) + context.setConfig(tableId, config as unknown as ConfigItemValue) } } } @@ -561,23 +552,23 @@ export function renameTableColumn( version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const config = (context.getBaseConfig(tableId) as unknown) as TableConfigItemValue + const config = context.getBaseConfig(tableId) as unknown as TableConfigItemValue if (!config || !Array.isArray(config)) { return false } - return config.find(row => oldColumnId in row) !== undefined + return config.find((row) => oldColumnId in row) !== undefined }, migrate: (context: MigrationContextShowStyle) => { - let config = (context.getBaseConfig(tableId) as unknown) as TableConfigItemValue - config = config.map(row => { + let config = context.getBaseConfig(tableId) as unknown as TableConfigItemValue + config = config.map((row) => { const value = row[oldColumnId] delete row[oldColumnId] row[newColumnId] = value return row }) - context.setBaseConfig(tableId, (config as unknown) as ConfigItemValue) + context.setBaseConfig(tableId, config as unknown as ConfigItemValue) } } } diff --git a/src/tv2-common/migrations/renameConfigurationHelper.ts b/src/tv2-common/migrations/renameConfigurationHelper.ts index 64b6b7b4..3297af30 100644 --- a/src/tv2-common/migrations/renameConfigurationHelper.ts +++ b/src/tv2-common/migrations/renameConfigurationHelper.ts @@ -14,18 +14,18 @@ export function renameTableId(version: string, oldTableId: string, newTableId: s version, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const oldConfigTable = (context.getBaseConfig(oldTableId) as unknown) as TableConfigItemValue + const oldConfigTable = context.getBaseConfig(oldTableId) as unknown as TableConfigItemValue if (!oldConfigTable || oldConfigTable.length === 0) { return false } - const newConfigTable = (context.getBaseConfig(newTableId) as unknown) as TableConfigItemValue + const newConfigTable = context.getBaseConfig(newTableId) as unknown as TableConfigItemValue return !newConfigTable }, migrate: (context: MigrationContextShowStyle) => { - const oldConfigTable = (context.getBaseConfig(oldTableId) as unknown) as TableConfigItemValue - const newConfigTable = ((context.getBaseConfig(newTableId) as unknown) as TableConfigItemValue) ?? [] - oldConfigTable.map(value => newConfigTable.push(value)) + const oldConfigTable = context.getBaseConfig(oldTableId) as unknown as TableConfigItemValue + const newConfigTable = (context.getBaseConfig(newTableId) as unknown as TableConfigItemValue) ?? [] + oldConfigTable.map((value) => newConfigTable.push(value)) context.setBaseConfig(newTableId, newConfigTable) context.removeBaseConfig(oldTableId) @@ -46,11 +46,11 @@ export function renameBlueprintConfiguration( version, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const oldConfig = (context.getBaseConfig(oldConfigurationName) as unknown) as BasicConfigItemValue + const oldConfig = context.getBaseConfig(oldConfigurationName) as unknown as BasicConfigItemValue return oldConfig !== undefined }, migrate: (context: MigrationContextShowStyle) => { - const oldConfig = (context.getBaseConfig(oldConfigurationName) as unknown) as BasicConfigItemValue + const oldConfig = context.getBaseConfig(oldConfigurationName) as unknown as BasicConfigItemValue context.setBaseConfig(newConfigurationName, oldConfig) context.removeBaseConfig(oldConfigurationName) diff --git a/src/tv2-common/migrations/transitions.ts b/src/tv2-common/migrations/transitions.ts index d405548e..f8fa8aef 100644 --- a/src/tv2-common/migrations/transitions.ts +++ b/src/tv2-common/migrations/transitions.ts @@ -30,19 +30,19 @@ export function UpsertValuesIntoTransitionTable( ): MigrationStepShowStyle[] { const steps: MigrationStepShowStyle[] = [] - values.forEach(val => { + values.forEach((val) => { steps.push({ id: `${versionStr}.insertTransition.${val.Transition.replace(/[\s\W]/g, '_')}`, version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const table = (context.getBaseConfig('Transitions') as unknown) as TransitionsTableValue[] | undefined + const table = context.getBaseConfig('Transitions') as unknown as TransitionsTableValue[] | undefined if (!table) { return `Transitions table does not exists` } - const existingVal = table.find(v => v.Transition === val.Transition) + const existingVal = table.find((v) => v.Transition === val.Transition) if (!existingVal) { return `Transition "${val.Transition}" does not exist` @@ -51,7 +51,7 @@ export function UpsertValuesIntoTransitionTable( return existingVal.Transition !== val.Transition }, migrate: (context: MigrationContextShowStyle) => { - const table = (context.getBaseConfig('Transitions') as unknown) as TransitionsTableValue[] | undefined + const table = context.getBaseConfig('Transitions') as unknown as TransitionsTableValue[] | undefined if (!table) { context.setBaseConfig('Transitions', [ diff --git a/src/tv2-common/nextPartCue.ts b/src/tv2-common/nextPartCue.ts index d13cdc99..6669fde8 100644 --- a/src/tv2-common/nextPartCue.ts +++ b/src/tv2-common/nextPartCue.ts @@ -10,7 +10,7 @@ export function GetNextPartCue(partdefinition: PartDefinition, currentCue: numbe const index = partdefinition.cues .slice(currentCue + 1) .findIndex( - cue => + (cue) => cue.type === CueType.DVE || cue.type === CueType.Ekstern || (cue.type === CueType.Graphic && cue.target === 'FULL' && partdefinition.type !== PartType.Grafik) || diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index 0b7ded77..8614d70e 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -145,7 +145,7 @@ function processServerLookaheads( sourceLayers: ABSourceLayers ): OnGenerateTimelineObj[] { // Includes any non-active servers present in current part - const serversInCurrentPart = timeline.filter(obj => { + const serversInCurrentPart = timeline.filter((obj) => { if (_.isArray(obj.enable)) { return false } @@ -160,7 +160,7 @@ function processServerLookaheads( [sourceLayers.Caspar.ClipPending, CasparPlayerClip(1), CasparPlayerClip(2)].includes(layer) && !obj.isLookahead && resolvedPieces.some( - p => p._id === obj.pieceInstanceId && p.partInstanceId === context.core.currentPartInstance?._id + (p) => p._id === obj.pieceInstanceId && p.partInstanceId === context.core.currentPartInstance?._id ) ) }) @@ -177,7 +177,7 @@ function processServerLookaheads( // Filter out lookaheads for servers that are currently in PGM. // Does not filter out AUX lookaheads. Should it? - return timeline.filter(obj => { + return timeline.filter((obj) => { if (_.isArray(obj.enable)) { return true } @@ -196,7 +196,7 @@ function processServerLookaheads( return !( [sourceLayers.Caspar.ClipPending, CasparPlayerClip(1), CasparPlayerClip(2)] - .map(l => `${l}_lookahead`) + .map((l) => `${l}_lookahead`) .includes(layer) && obj.isLookahead && sessionsInCurrentPart.includes(mediaPlayerSession) @@ -209,8 +209,8 @@ function isAnyPieceInjectedIntoPart( resolvedPieces: Array> ) { return resolvedPieces - .filter(piece => piece.partInstanceId === context.core.currentPartInstance?._id) - .some(piece => { + .filter((piece) => piece.partInstanceId === context.core.currentPartInstance?._id) + .some((piece) => { return piece.piece.metaData?.sisyfosPersistMetaData?.isPieceInjectedInPart }) } @@ -233,7 +233,7 @@ export function getEndStateForPart( const previousPartEndState = partInstance?.previousPartEndState as Partial const activePieces = resolvedPieces.filter( - p => + (p) => _.isNumber(p.piece.enable.start) && p.piece.enable && p.piece.enable.start <= time && @@ -285,7 +285,7 @@ export function createSisyfosPersistedLevelsTimelineObject( deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, overridePriority: 1, - channels: layersToPersist.map(layer => { + channels: layersToPersist.map((layer) => { return { mappedLayer: layer, isPgm: 1 @@ -300,7 +300,7 @@ function findLayersToPersist( sisyfosLayersThatWantsToBePersisted: string[] ): string[] { const sortedPieces = pieces - .filter(piece => piece.piece.metaData?.sisyfosPersistMetaData) + .filter((piece) => piece.piece.metaData?.sisyfosPersistMetaData) .sort((a, b) => b.resolvedStart - a.resolvedStart) if (sortedPieces.length === 0) { @@ -349,7 +349,7 @@ export function disablePilotWipeAfterJingle( previousPartEndState: PartEndStateExt | undefined, resolvedPieces: IBlueprintResolvedPieceInstance[] ) { - if (previousPartEndState?.isJingle && resolvedPieces.find(p => p.piece.tags?.includes(TallyTags.FULL_IS_LIVE))) { + if (previousPartEndState?.isJingle && resolvedPieces.find((p) => p.piece.tags?.includes(TallyTags.FULL_IS_LIVE))) { for (const obj of timeline) { if (obj.content.deviceType === TSR.DeviceType.ATEM && !obj.isLookahead) { const obj2 = obj as TSR.TimelineObjAtemAny diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index 8b236b6d..d680f0ee 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -94,10 +94,7 @@ export function CreateEffektForPartInner< label: string ): Pick | false { const effektConfig = context.config.showStyle.BreakerConfig.find( - conf => - conf.BreakerName.toString() - .trim() - .toUpperCase() === effekt.toUpperCase() + (conf) => conf.BreakerName.toString().trim().toUpperCase() === effekt.toUpperCase() ) if (!effektConfig) { context.core.notifyUserWarning(`Could not find effekt ${effekt}`) diff --git a/src/tv2-common/segment/context.ts b/src/tv2-common/segment/context.ts index 3ef196d1..f20a9ea6 100644 --- a/src/tv2-common/segment/context.ts +++ b/src/tv2-common/segment/context.ts @@ -9,7 +9,8 @@ export interface SegmentContext exte export class SegmentContextImpl extends ShowStyleContextImpl - implements SegmentContext { + implements SegmentContext +{ constructor(readonly core: ISegmentUserContext, readonly uniformConfig: UniformConfig) { super(core, uniformConfig) } diff --git a/src/tv2-common/showstyle/config-manifests.ts b/src/tv2-common/showstyle/config-manifests.ts index 5bf566f5..35507657 100644 --- a/src/tv2-common/showstyle/config-manifests.ts +++ b/src/tv2-common/showstyle/config-manifests.ts @@ -1,7 +1,7 @@ import { ConfigManifestEntry, ConfigManifestEntryTable, ConfigManifestEntryType } from 'blueprints-integration' import { TableConfigItemGfxDefaults } from '../blueprintConfig' -export enum CommonConfigId { +export enum ShowStyleConfigId { GRAPHICS_SETUPS_TABLE_ID = 'GfxSetups', GRAPHICS_SETUPS_NAME_COLUMN_ID = 'Name', GFX_DEFAULTS_TABLE_ID = 'GfxDefaults', @@ -16,7 +16,7 @@ export enum CommonConfigId { export const getGfxSetupsEntries = (columns: ConfigManifestEntryTable['columns']): ConfigManifestEntry[] => [ { - id: CommonConfigId.GRAPHICS_SETUPS_TABLE_ID, + id: ShowStyleConfigId.GRAPHICS_SETUPS_TABLE_ID, name: 'GFX Setups', description: 'Possible GFX setups', type: ConfigManifestEntryType.TABLE, @@ -24,7 +24,7 @@ export const getGfxSetupsEntries = (columns: ConfigManifestEntryTable['columns'] defaultVal: [], columns: [ { - id: CommonConfigId.GRAPHICS_SETUPS_NAME_COLUMN_ID, + id: ShowStyleConfigId.GRAPHICS_SETUPS_NAME_COLUMN_ID, name: 'Name', description: 'The code as it will appear in iNews', type: ConfigManifestEntryType.STRING, @@ -51,68 +51,68 @@ export const getGfxSetupsEntries = (columns: ConfigManifestEntryTable['columns'] export const GFX_DEFAULT_VALUES: TableConfigItemGfxDefaults[] = [ { GfxSetup: '', - DefaultSchema: [''], - DefaultDesign: [''] + DefaultSchema: '', + DefaultDesign: '' } ] export const getGfxDefaults: ConfigManifestEntry = { - id: CommonConfigId.GFX_DEFAULTS_TABLE_ID, + id: ShowStyleConfigId.GFX_DEFAULTS_TABLE_ID, name: 'GFX Defaults', description: 'The possible defaults available for the GFX setup', type: ConfigManifestEntryType.TABLE, required: false, - defaultVal: GFX_DEFAULT_VALUES.map(gfxDefaultValue => ({ _id: '', ...gfxDefaultValue })), + defaultVal: GFX_DEFAULT_VALUES.map((gfxDefaultValue) => ({ _id: '', ...gfxDefaultValue })), disableRowManipulation: true, columns: [ { - id: CommonConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, + id: ShowStyleConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, name: 'GFX Setup', rank: 0, description: 'Name of the GFX Setup', type: ConfigManifestEntryType.SELECT_FROM_COLUMN, - tableId: CommonConfigId.GRAPHICS_SETUPS_TABLE_ID, - columnId: CommonConfigId.GRAPHICS_SETUPS_NAME_COLUMN_ID, + tableId: ShowStyleConfigId.GRAPHICS_SETUPS_TABLE_ID, + columnId: ShowStyleConfigId.GRAPHICS_SETUPS_NAME_COLUMN_ID, multiple: false, required: true, defaultVal: '' }, { - id: CommonConfigId.DEFAULTS_SCHEMA_COLUMN_ID, + id: ShowStyleConfigId.DEFAULTS_SCHEMA_COLUMN_ID, name: 'Default Skema', rank: 1, description: 'The Skema options based on the GFX Setup', type: ConfigManifestEntryType.SELECT_FROM_TABLE_ENTRY_WITH_COMPARISON_MAPPINGS, comparisonMappings: [ { - targetColumnId: CommonConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, - sourceColumnId: CommonConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID + targetColumnId: ShowStyleConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, + sourceColumnId: ShowStyleConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID } ], - sourceTableId: CommonConfigId.GFX_SHOW_MAPPING_TABLE_ID, - sourceColumnIdWithValue: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, + sourceTableId: ShowStyleConfigId.GFX_SHOW_MAPPING_TABLE_ID, + sourceColumnIdWithValue: ShowStyleConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, multiple: false, required: false, defaultVal: '' }, { - id: CommonConfigId.DEFAULTS_DESIGN_COLUMN_ID, + id: ShowStyleConfigId.DEFAULTS_DESIGN_COLUMN_ID, name: 'Default Design', rank: 2, description: 'The Design options based on the Default Skema or GFX Setup', type: ConfigManifestEntryType.SELECT_FROM_TABLE_ENTRY_WITH_COMPARISON_MAPPINGS, comparisonMappings: [ { - targetColumnId: CommonConfigId.DEFAULTS_SCHEMA_COLUMN_ID, - sourceColumnId: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID + targetColumnId: ShowStyleConfigId.DEFAULTS_SCHEMA_COLUMN_ID, + sourceColumnId: ShowStyleConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID }, { - targetColumnId: CommonConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, - sourceColumnId: CommonConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID + targetColumnId: ShowStyleConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, + sourceColumnId: ShowStyleConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID } ], - sourceTableId: CommonConfigId.GFX_SHOW_MAPPING_TABLE_ID, - sourceColumnIdWithValue: CommonConfigId.GFX_SHOW_MAPPING_DESIGN_COLUMN_ID, + sourceTableId: ShowStyleConfigId.GFX_SHOW_MAPPING_TABLE_ID, + sourceColumnIdWithValue: ShowStyleConfigId.GFX_SHOW_MAPPING_DESIGN_COLUMN_ID, multiple: false, required: false, defaultVal: '' diff --git a/src/tv2-common/sources.ts b/src/tv2-common/sources.ts index dce167c2..7e28e4e8 100644 --- a/src/tv2-common/sources.ts +++ b/src/tv2-common/sources.ts @@ -28,7 +28,7 @@ export function parseMapStr( const res: Array<{ id: string; val: number }> = [] const inputs = str.split(',') - inputs.forEach(i => { + inputs.forEach((i) => { if (i === '') { return } @@ -60,7 +60,7 @@ export function ParseMappingTable( type: SourceInfoType, sourceLayerType: SourceLayerType ): SourceInfo[] { - return studioConfig.map(conf => ({ + return studioConfig.map((conf) => ({ type, id: conf.SourceName, port: conf.SwitcherSource, @@ -109,7 +109,7 @@ export function findSourceInfo(sources: SourceMapping, sourceDefinition: SourceD default: return undefined } - return _.find(arrayToSearchIn, s => s.id === sourceDefinition.id) + return _.find(arrayToSearchIn, (s) => s.id === sourceDefinition.id) } export function SourceInfoToSourceDefinition( diff --git a/src/tv2-common/uniformConfig.ts b/src/tv2-common/uniformConfig.ts index f977038d..b2804891 100644 --- a/src/tv2-common/uniformConfig.ts +++ b/src/tv2-common/uniformConfig.ts @@ -50,15 +50,15 @@ export function getSpecialLayers( ): Partial> { return Object.fromEntries( Object.values(mixEffects) - .filter(mixEffect => mixEffect.auxLayer) - .map(mixEffect => [mixEffect.input, mixEffect.auxLayer]) + .filter((mixEffect) => mixEffect.auxLayer) + .map((mixEffect) => [mixEffect.input, mixEffect.auxLayer]) ) } export function getUsedLayers(uniformConfig: UniformConfig): Array { return _.uniq( Object.values(uniformConfig.switcherLLayers).concat( - Object.values(uniformConfig.mixEffects).flatMap(mixeffect => + Object.values(uniformConfig.mixEffects).flatMap((mixeffect) => _.compact([mixeffect.mixEffectLayer, mixeffect.auxLayer]) ) ) diff --git a/src/tv2-common/updatePolicies/adlibs.ts b/src/tv2-common/updatePolicies/adlibs.ts index 7467c005..be6028be 100644 --- a/src/tv2-common/updatePolicies/adlibs.ts +++ b/src/tv2-common/updatePolicies/adlibs.ts @@ -26,11 +26,11 @@ export function updateAdLibInstances( const rawAdlibRefs = normalizeArrayToMap(newPart.referencedAdlibs, '_id') const groupedAdlibInstances = _.groupBy( existingPartInstance.pieceInstances, - p => p.adLibSourceId ?? defaultAdlibSourceId + (p) => p.adLibSourceId ?? defaultAdlibSourceId ) for (const [adlibId, adlibPieces] of Object.entries(groupedAdlibInstances)) { if (adlibId !== defaultAdlibSourceId) { - const updatableAdlibPieces = adlibPieces.filter(p => { + const updatableAdlibPieces = adlibPieces.filter((p) => { const metaData = p.piece.metaData as PieceMetaData return !metaData?.modifiedByAction }) diff --git a/src/tv2-common/updatePolicies/partProperties.ts b/src/tv2-common/updatePolicies/partProperties.ts index 3432a161..cbb99113 100644 --- a/src/tv2-common/updatePolicies/partProperties.ts +++ b/src/tv2-common/updatePolicies/partProperties.ts @@ -20,7 +20,7 @@ const partPropertiesToOmit = [ 'shouldNotifyCurrentPlayingPart' ] as const -const clearedMutatablePart: Complete> = { +const clearedMutatablePart: Complete> = { metaData: undefined, expectedDuration: undefined, budgetDuration: undefined, diff --git a/src/tv2-common/updatePolicies/pieces.ts b/src/tv2-common/updatePolicies/pieces.ts index 30e9bc31..7e045339 100644 --- a/src/tv2-common/updatePolicies/pieces.ts +++ b/src/tv2-common/updatePolicies/pieces.ts @@ -33,7 +33,7 @@ export function stopOrReplaceEditablePieces( let pieceInstancesOnLayersInExistingPart = existingPartInstance.pieceInstances if (allowedSourceLayers) { - pieceInstancesOnLayersInExistingPart = existingPartInstance.pieceInstances.filter(p => + pieceInstancesOnLayersInExistingPart = existingPartInstance.pieceInstances.filter((p) => allowedSourceLayers.has(p.piece.sourceLayerId) ) } @@ -41,7 +41,9 @@ export function stopOrReplaceEditablePieces( let pieceInstancesOnLayersInNewPart = newPart.pieceInstances if (allowedSourceLayers) { - pieceInstancesOnLayersInNewPart = newPart.pieceInstances.filter(p => allowedSourceLayers.has(p.piece.sourceLayerId)) + pieceInstancesOnLayersInNewPart = newPart.pieceInstances.filter((p) => + allowedSourceLayers.has(p.piece.sourceLayerId) + ) } const groupedPieceInstancesInNewPart = groupPieceInstances(pieceInstancesOnLayersInNewPart) diff --git a/src/tv2-common/videoSwitchers/Atem.ts b/src/tv2-common/videoSwitchers/Atem.ts index 20a56af5..59802b3d 100644 --- a/src/tv2-common/videoSwitchers/Atem.ts +++ b/src/tv2-common/videoSwitchers/Atem.ts @@ -272,7 +272,7 @@ export class Atem extends VideoSwitcherBase { if (!keyers?.length) { return } - return keyers.map(keyer => ({ + return keyers.map((keyer) => ({ upstreamKeyerId: keyer.config.Number, onAir: keyer.onAir, mixEffectKeyType: 0, diff --git a/src/tv2-common/videoSwitchers/TriCaster.ts b/src/tv2-common/videoSwitchers/TriCaster.ts index 799edadf..e367467d 100644 --- a/src/tv2-common/videoSwitchers/TriCaster.ts +++ b/src/tv2-common/videoSwitchers/TriCaster.ts @@ -153,7 +153,7 @@ export class TriCaster extends VideoSwitcherBase { const mapping = this.core.getStudioMappings()[layerName] if (!mapping || mapping.device !== TSR.DeviceType.TRICASTER) { this.core.logWarning(`Unable to find TriCaster mapping for layer ${layerName}`) - } else if (((mapping as unknown) as TSR.MappingTriCaster).mappingType === TSR.MappingTriCasterType.MATRIX_OUTPUT) { + } else if ((mapping as unknown as TSR.MappingTriCaster).mappingType === TSR.MappingTriCasterType.MATRIX_OUTPUT) { if (props.content.input) { return { ...this.getBaseProperties(props, props.layer), @@ -205,7 +205,7 @@ export class TriCaster extends VideoSwitcherBase { const dveMixEffect = timelineObject.content.me as TSR.TriCasterMixEffectInEffectMode const layers = dveMixEffect.layers as NonNullable - Object.values(layers).forEach(layer => this.assignInputIfPlaceholder(layer, input)) + Object.values(layers).forEach((layer) => this.assignInputIfPlaceholder(layer, input)) return timelineObject } @@ -354,8 +354,8 @@ export class TriCaster extends VideoSwitcherBase { this.core.logWarning(`Unable to find TriCaster mapping for layer ${layerName}`) return 'black' } - if (((mapping as unknown) as TSR.MappingTriCaster).mappingType === TSR.MappingTriCasterType.MIX_OUTPUT) { - return ((mapping as unknown) as TSR.MappingTriCasterMixOutput).name + if ((mapping as unknown as TSR.MappingTriCaster).mappingType === TSR.MappingTriCasterType.MIX_OUTPUT) { + return (mapping as unknown as TSR.MappingTriCasterMixOutput).name } return 'black' } diff --git a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts index 8197831f..3d0caedf 100644 --- a/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts +++ b/src/tv2-common/videoSwitchers/__tests__/TriCaster.spec.ts @@ -159,13 +159,13 @@ describe('TriCaster', () => { test('supports WIPE for GFX', () => { const wipeRate = 22 const config = mock() - when(config.studio).thenReturn(({ + when(config.studio).thenReturn({ HTMLGraphics: { GraphicURL: 'donotcare', TransitionSettings: { wipeRate, borderSoftness: 20, loopOutTransitionDuration: 15 }, KeepAliveDuration: 120 } - } as any) as TV2StudioConfigBase) + } as any as TV2StudioConfigBase) const testee: TriCaster = createTestee({ config: instance(config) }) const timelineObject = testee.getMixEffectTimelineObject({ layer: SwitcherMixEffectLLayer.PROGRAM, @@ -299,7 +299,7 @@ describe('TriCaster', () => { test('sets Mix Output when layer mapping is MIX_OUTPUT', () => { const config = mock() - when(config.studio).thenReturn(({ + when(config.studio).thenReturn({ studioConfig: { mappingDefaults: { [prefixLayer(DEFAULT_AUX.layer)]: literal({ @@ -311,7 +311,7 @@ describe('TriCaster', () => { }) } } - } as any) as TV2StudioConfigBase) + } as any as TV2StudioConfigBase) const testee: TriCaster = createTestee({ config: instance(config) }) const timelineObject = testee.getAuxTimelineObject(DEFAULT_AUX) @@ -484,7 +484,7 @@ describe('TriCaster', () => { function assertPopulateUnpopulatedBox(inputToUpdate: number, layerName: TSR.TriCasterLayerName): void { const testee: TriCaster = createTestee() - const timelineObject: TSR.TimelineObjTriCasterME = ({ + const timelineObject: TSR.TimelineObjTriCasterME = { content: { deviceType: TSR.DeviceType.TRICASTER, type: TSR.TimelineContentTypeTriCaster.ME, @@ -496,7 +496,7 @@ describe('TriCaster', () => { } } } - } as any) as TSR.TimelineObjTriCasterME + } as any as TSR.TimelineObjTriCasterME const timelineObjTriCasterME: TSR.TimelineObjTriCasterME = testee.updateUnpopulatedDveBoxes( timelineObject, @@ -522,7 +522,7 @@ describe('TriCaster', () => { otherInputSource: number ): void { const testee: TriCaster = createTestee() - const timelineObject: TSR.TimelineObjTriCasterME = ({ + const timelineObject: TSR.TimelineObjTriCasterME = { content: { deviceType: TSR.DeviceType.TRICASTER, type: TSR.TimelineContentTypeTriCaster.ME, @@ -534,7 +534,7 @@ describe('TriCaster', () => { } } } - } as any) as TSR.TimelineObjTriCasterME + } as any as TSR.TimelineObjTriCasterME const timelineObjTriCasterME: TSR.TimelineObjTriCasterME = testee.updateUnpopulatedDveBoxes( timelineObject, @@ -618,11 +618,11 @@ describe('TriCaster', () => { it('generate overlay keyer', () => { const config = mock() const artFillSource = 10 - when(config.studio).thenReturn(({ + when(config.studio).thenReturn({ SwitcherSource: { SplitArtFill: artFillSource } - } as any) as TV2StudioConfigBase) + } as any as TV2StudioConfigBase) const testee: TriCaster = createTestee({ config: instance(config) }) const basicDveProps = getBasicDveProps() const content: TSR.TimelineObjTriCasterME['content'] = testee.getDveTimelineObjects(basicDveProps)[0] @@ -641,10 +641,9 @@ describe('TriCaster', () => { const emptyBoxes = [{ enabled: false }, { enabled: false }, { enabled: false }, { enabled: false }] const content = testee.getDveTimelineObjects(getBasicDveProps(emptyBoxes))[0] .content as TSR.TimelineObjTriCasterME['content'] - const result: Partial> = (content.me as TSR.TriCasterMixEffectInEffectMode).layers! + const result: Partial> = ( + content.me as TSR.TriCasterMixEffectInEffectMode + ).layers! expect(result.a).toMatchObject(invisibleBox()) expect(result.b).toMatchObject(invisibleBox()) diff --git a/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts b/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts index f1d54ed8..db72624e 100644 --- a/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts +++ b/src/tv2_afvd_showstyle/GlobalAdlibActionsGenerator.ts @@ -38,31 +38,31 @@ export class GlobalAdlibActionsGenerator { this.config.sources.cameras .slice(0, 5) // the first x cameras to create INP1/2/3 cam-adlibs from - .forEach(camera => { + .forEach((camera) => { blueprintActions.push(this.makeCutDirectlyCameraAction(camera, globalRank++)) blueprintActions.push(this.makeQueueAsNextCameraAction(camera, globalRank++)) }) this.config.sources.cameras .slice(0, 5) // the first x cameras to dve actions from - .forEach(camera => { + .forEach((camera) => { blueprintActions.push(...this.makeAdlibBoxesActions(camera, globalRank++)) }) this.config.sources.lives .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from - .forEach(live => { + .forEach((live) => { blueprintActions.push(...this.makeAdlibBoxesActions(live, globalRank++)) blueprintActions.push(this.makeCutDirectLiveAction(live, globalRank++)) }) this.config.sources.feeds .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from - .forEach(feed => { + .forEach((feed) => { blueprintActions.push(...this.makeAdlibBoxesActions(feed, globalRank++)) }) - this.config.sources.replays.forEach(replay => { + this.config.sources.replays.forEach((replay) => { if (!/EPSIO/i.test(replay.id)) { blueprintActions.push(...this.makeAdlibBoxesActionsReplay(replay, globalRank++, false)) } diff --git a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts index 95a10490..3e5c9aaf 100644 --- a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts @@ -375,7 +375,7 @@ async function getCameraPiece( ): Promise { const piece = await context .getPieceInstances(part) - .then(pieceInstance => pieceInstance.find(p => p.piece.sourceLayerId === SourceLayer.PgmCam)) + .then((pieceInstance) => pieceInstance.find((p) => p.piece.sourceLayerId === SourceLayer.PgmCam)) expect(piece).toBeTruthy() return piece! @@ -387,7 +387,7 @@ async function getEVSPiece( ): Promise { const piece = await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === SourceLayer.PgmLocal)) + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === SourceLayer.PgmLocal)) expect(piece).toBeTruthy() return piece! @@ -399,7 +399,7 @@ async function getTransitionPiece( ): Promise { const piece = await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === SourceLayer.PgmJingle)) + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === SourceLayer.PgmJingle)) expect(piece).toBeTruthy() return piece! @@ -407,7 +407,7 @@ async function getTransitionPiece( function getATEMMEObj(piece: IBlueprintPieceInstance): TSR.TimelineObjAtemME { const atemObj = (piece.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => + (obj) => obj.layer === prefixLayer(SwitcherMixEffectLLayer.PROGRAM) && obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.ME @@ -435,9 +435,11 @@ function expectTakeAfterExecute(context: ActionExecutionContextMock) { } function expectNoWarningsOrErrors(context: ActionExecutionContextMock) { - expect(context.getNotes().filter(n => n.type === NoteType.ERROR || n.type === NoteType.NOTIFY_USER_ERROR)).toEqual([]) + expect(context.getNotes().filter((n) => n.type === NoteType.ERROR || n.type === NoteType.NOTIFY_USER_ERROR)).toEqual( + [] + ) expect( - context.getNotes().filter(n => n.type === NoteType.WARNING || n.type === NoteType.NOTIFY_USER_WARNING) + context.getNotes().filter((n) => n.type === NoteType.WARNING || n.type === NoteType.NOTIFY_USER_WARNING) ).toEqual([]) } diff --git a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts index 3e455685..d79e322e 100644 --- a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts @@ -54,7 +54,7 @@ describe.each([SwitcherType.ATEM, SwitcherType.TRICASTER])('Baseline', (switcher } const result = rundown.baseline.timelineObjects.filter( - timelineObject => + (timelineObject) => timelineObject.layer === SharedGraphicLLayer.GraphicLLayerConcept && timelineObject.content.deviceType === TSR.DeviceType.VIZMSE ) diff --git a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts index be78363d..1dc2e5a2 100644 --- a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts @@ -38,11 +38,11 @@ function makeIngestSegment(cues: UnparsedCue[], body: string) { } function expectNotesToBe(context: SegmentUserContextMock, notes: string[]) { - expect(context.getNotes().map(msg => msg.message)).toEqual(notes) + expect(context.getNotes().map((msg) => msg.message)).toEqual(notes) } function expectAllPartsToBeValid(result: BlueprintResultSegment) { - const invalid = result.parts.filter(part => part.part.invalid === true) + const invalid = result.parts.filter((part) => part.part.invalid === true) expect(invalid).toHaveLength(0) } @@ -59,7 +59,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(1) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle]) expect(kamPart.pieces[0].name).toEqual('CS 3 (JINGLE)') }) @@ -75,7 +75,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(1) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle]) expect(kamPart.pieces[0].name).toEqual('CS 3 (JINGLE)') }) @@ -102,7 +102,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) }) @@ -121,7 +121,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -154,14 +154,14 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) const fullPart = result.parts[1] expect(fullPart).toBeTruthy() expect(fullPart.pieces).toHaveLength(2) - expect(fullPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayer.PgmPilot, SharedSourceLayer.SelectedAdlibGraphicsFull ]) @@ -198,7 +198,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -239,7 +239,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -253,7 +253,7 @@ describe('AFVD Blueprint', () => { expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( SharedSourceLayer.PgmPilot ) - expect(fullPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayer.PgmPilot, SharedSourceLayer.SelectedAdlibGraphicsFull ]) @@ -291,7 +291,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -305,7 +305,7 @@ describe('AFVD Blueprint', () => { expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( SharedSourceLayer.PgmPilot ) - expect(fullPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayer.PgmPilot, SharedSourceLayer.SelectedAdlibGraphicsFull, SharedSourceLayer.PgmPilotOverlay @@ -337,14 +337,14 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) const fullPart = result.parts[1] expect(fullPart).toBeTruthy() expect(fullPart.pieces).toHaveLength(2) - expect(fullPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayer.PgmPilot, SharedSourceLayer.SelectedAdlibGraphicsFull ]) @@ -382,7 +382,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -418,7 +418,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -453,7 +453,7 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart1.adLibPieces).toHaveLength(0) expect(kamPart1.actions).toHaveLength(0) @@ -467,7 +467,7 @@ describe('AFVD Blueprint', () => { const kamPart2 = result.parts[2] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(1) - expect(kamPart2.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam]) + expect(kamPart2.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam]) expect(kamPart2.adLibPieces).toHaveLength(0) expect(kamPart2.actions).toHaveLength(0) }) @@ -496,7 +496,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(3) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayer.PgmCam, SharedSourceLayer.PgmPilotOverlay, SharedSourceLayer.PgmScript @@ -529,7 +529,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(3) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayer.PgmCam, SharedSourceLayer.WallGraphics, SharedSourceLayer.PgmScript @@ -562,7 +562,7 @@ describe('AFVD Blueprint', () => { const kamPart = result.parts[0] expect(kamPart).toBeTruthy() expect(kamPart.pieces).toHaveLength(2) - expect(kamPart.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) expect(kamPart.adLibPieces).toHaveLength(0) expect(kamPart.actions).toHaveLength(0) @@ -576,7 +576,7 @@ describe('AFVD Blueprint', () => { expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( SharedSourceLayer.PgmPilot ) - expect(fullPart.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(fullPart.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayer.PgmPilot, SharedSourceLayer.SelectedAdlibGraphicsFull ]) @@ -607,7 +607,7 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(3) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayer.PgmCam, SharedSourceLayer.WallGraphics, SharedSourceLayer.PgmScript @@ -616,7 +616,7 @@ describe('AFVD Blueprint', () => { const kamPart2 = result.parts[1] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(2) - expect(kamPart2.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart2.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayer.PgmCam, SharedSourceLayer.WallGraphics ]) @@ -640,12 +640,12 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) const kamPart2 = result.parts[1] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(2) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) }) it('Shows warning for missing wall graphic with MOSART=L', async () => { @@ -673,7 +673,7 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(3) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayer.PgmCam, SharedSourceLayer.PgmPilotOverlay, SharedSourceLayer.PgmScript @@ -682,7 +682,7 @@ describe('AFVD Blueprint', () => { const kamPart2 = result.parts[1] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(2) - expect(kamPart2.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart2.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayer.PgmCam, SharedSourceLayer.WallGraphics ]) @@ -713,12 +713,12 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmCam, SharedSourceLayer.PgmScript]) const kamPart2 = result.parts[1] expect(kamPart2).toBeTruthy() expect(kamPart2.pieces).toHaveLength(2) - expect(kamPart2.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart2.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayer.PgmCam, SharedSourceLayer.WallGraphics ]) @@ -743,7 +743,7 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(5) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([ + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([ SharedSourceLayer.PgmCam, SharedSourceLayer.PgmDesign, SourceLayer.PgmDVEBackground, @@ -764,7 +764,7 @@ describe('AFVD Blueprint', () => { const livePart1 = result.parts[0] expect(livePart1).toBeTruthy() expect(livePart1.pieces).toHaveLength(1) - expect(livePart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmLive]) + expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmLive]) }) it('Creates Live 1', async () => { @@ -779,7 +779,7 @@ describe('AFVD Blueprint', () => { const livePart1 = result.parts[0] expect(livePart1).toBeTruthy() expect(livePart1.pieces).toHaveLength(1) - expect(livePart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmLive]) + expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmLive]) }) it('Creates Feed1', async () => { @@ -794,7 +794,7 @@ describe('AFVD Blueprint', () => { const feedPart1 = result.parts[0] expect(feedPart1).toBeTruthy() expect(feedPart1.pieces).toHaveLength(1) - expect(feedPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmLive]) + expect(feedPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmLive]) }) it('Creates Feed 1', async () => { @@ -809,7 +809,7 @@ describe('AFVD Blueprint', () => { const feedPart1 = result.parts[0] expect(feedPart1).toBeTruthy() expect(feedPart1.pieces).toHaveLength(1) - expect(feedPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmLive]) + expect(feedPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmLive]) }) it('Creates invalid part for EKSTERN=LIVE', async () => { @@ -838,7 +838,7 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle, SharedSourceLayer.PgmCam]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle, SharedSourceLayer.PgmCam]) expect(kamPart1.pieces[0].name).toBe('EFFEKT 1') }) @@ -854,7 +854,7 @@ describe('AFVD Blueprint', () => { const kamPart1 = result.parts[0] expect(kamPart1).toBeTruthy() expect(kamPart1.pieces).toHaveLength(2) - expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle, SharedSourceLayer.PgmCam]) + expect(kamPart1.pieces.map((p) => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle, SharedSourceLayer.PgmCam]) expect(kamPart1.pieces[0].name).toBe('MIX 5') }) @@ -873,7 +873,10 @@ describe('AFVD Blueprint', () => { const livePart1 = result.parts[0] expect(livePart1).toBeTruthy() expect(livePart1.pieces).toHaveLength(2) - expect(livePart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle, SharedSourceLayer.PgmLive]) + expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayer.PgmJingle, + SharedSourceLayer.PgmLive + ]) expect(livePart1.pieces[0].name).toBe('EFFEKT 1') }) @@ -892,7 +895,10 @@ describe('AFVD Blueprint', () => { const livePart1 = result.parts[0] expect(livePart1).toBeTruthy() expect(livePart1.pieces).toHaveLength(2) - expect(livePart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayer.PgmJingle, SharedSourceLayer.PgmLive]) + expect(livePart1.pieces.map((p) => p.sourceLayerId)).toEqual([ + SharedSourceLayer.PgmJingle, + SharedSourceLayer.PgmLive + ]) expect(livePart1.pieces[0].name).toBe('MIX 10') }) @@ -915,7 +921,7 @@ describe('AFVD Blueprint', () => { const livePart = result.parts[0] const livePiece = livePart.pieces[0] const studioMicsObject = livePiece.content.timelineObjects.find( - t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + (t) => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics ) expect(studioMicsObject).toBeDefined() }) @@ -939,7 +945,7 @@ describe('AFVD Blueprint', () => { const livePart = result.parts[0] const livePiece = livePart.pieces[0] const studioMicsObject = livePiece.content.timelineObjects.find( - t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + (t) => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics ) expect(studioMicsObject).toBeUndefined() }) @@ -963,7 +969,7 @@ describe('AFVD Blueprint', () => { const livePart = result.parts[0] const livePiece = livePart.pieces[0] const studioMicsObject = livePiece.content.timelineObjects.find( - t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + (t) => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics ) expect(studioMicsObject).toBeDefined() }) @@ -987,7 +993,7 @@ describe('AFVD Blueprint', () => { const livePart = result.parts[0] const livePiece = livePart.pieces[0] const studioMicsObject = livePiece.content.timelineObjects.find( - t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + (t) => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics ) expect(studioMicsObject).toBeUndefined() }) @@ -1011,7 +1017,7 @@ describe('AFVD Blueprint', () => { const livePart = result.parts[0] const livePiece = livePart.pieces[0] const studioMicsObject = livePiece.content.timelineObjects.find( - t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + (t) => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics ) expect(studioMicsObject).toBeUndefined() }) diff --git a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts index 021874f6..460d47f6 100644 --- a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts @@ -17,12 +17,12 @@ const blankShowStyleConfig: GalleryShowStyleConfig = { GfxSetups: [], GfxSchemaTemplates: [], GfxShowMapping: [], - GfxDefaults: [{ GfxSetup: '', DefaultSchema: [''], DefaultDesign: [''] }] + GfxDefaults: [{ GfxSetup: '', DefaultSchema: '', DefaultDesign: '' }] } describe('Config Manifest', () => { test('Exposed ShowStyle Keys', () => { - const showStyleManifestKeys = _.map(showStyleConfigManifest, e => e.id) + const showStyleManifestKeys = _.map(showStyleConfigManifest, (e) => e.id) const manifestKeys = showStyleManifestKeys.sort() const definedKeys = Object.keys(blankShowStyleConfig) diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index 9e548f26..db0a7b10 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -31,7 +31,7 @@ function prepareConfig( StudioMics: boolean wantsToPersistAudio: boolean }> { - return parseMapStr(undefined, conf, true).map(c => { + return parseMapStr(undefined, conf, true).map((c) => { return { SourceName: c.id, SwitcherSource: c.val, @@ -274,5 +274,5 @@ export const defaultShowStyleConfig: GalleryShowStyleConfig = { ShowstyleTransition: 'CUT', GfxSchemaTemplates: [], GfxShowMapping: [], - GfxDefaults: [{ GfxSetup: 'SomeProfile', DefaultDesign: [], DefaultSchema: [] }] + GfxDefaults: [{ GfxSetup: 'SomeProfile', DefaultDesign: '', DefaultSchema: '' }] } diff --git a/src/tv2_afvd_showstyle/__tests__/layers-check.ts b/src/tv2_afvd_showstyle/__tests__/layers-check.ts index 064f33c5..b597b4b5 100644 --- a/src/tv2_afvd_showstyle/__tests__/layers-check.ts +++ b/src/tv2_afvd_showstyle/__tests__/layers-check.ts @@ -15,10 +15,10 @@ export function checkAllLayers(pieces: IBlueprintPieceGeneric[], otherObjs?: TSR const wrongDeviceLayers: Array = [] const allSourceLayers: string[] = _.values(SourceLayer) - .map(l => l.toString()) + .map((l) => l.toString()) .concat(GetDSKSourceLayerNames(ATEMModel.CONSTELLATION_8K_UHD_MODE)) .sort() - const allOutputLayers = _.map(OutputlayerDefaults, m => m._id) + const allOutputLayers = _.map(OutputlayerDefaults, (m) => m._id) const allMappings: BlueprintMappings = { ...mappingsDefaults diff --git a/src/tv2_afvd_showstyle/__tests__/migrations-defaults.spec.ts b/src/tv2_afvd_showstyle/__tests__/migrations-defaults.spec.ts index e77810f3..1c5ca31b 100644 --- a/src/tv2_afvd_showstyle/__tests__/migrations-defaults.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/migrations-defaults.spec.ts @@ -7,9 +7,9 @@ import SourcelayerDefaults from '../migrations/sourcelayer-defaults' describe('Migration Defaults', () => { test('SourcelayerDefaults', () => { - const defaultsIds = _.map(SourcelayerDefaults, v => v._id).sort() + const defaultsIds = _.map(SourcelayerDefaults, (v) => v._id).sort() const layerIds = _.values(SourceLayer) - .map(l => l.toString()) + .map((l) => l.toString()) .concat(GetDSKSourceLayerNames(ATEMModel.CONSTELLATION_8K_UHD_MODE)) .sort() diff --git a/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts b/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts index 0f5b291b..10ebd623 100644 --- a/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts @@ -232,10 +232,10 @@ describe('regressions-migrations', () => { * @param reference Reference segment. */ function migrate(reference: BlueprintResultSegment) { - reference.parts = reference.parts.map(part => { - part.adLibPieces = part.adLibPieces.map(adlib => { + reference.parts = reference.parts.map((part) => { + part.adLibPieces = part.adLibPieces.map((adlib) => { if (adlib.content && adlib.content.timelineObjects) { - adlib.content.timelineObjects = (adlib.content.timelineObjects as TimelineObjectCoreExt[]).map(obj => { + adlib.content.timelineObjects = (adlib.content.timelineObjects as TimelineObjectCoreExt[]).map((obj) => { const remappedLayer = remapVizLLayer.get(obj.layer.toString()) if (remappedLayer) { @@ -249,9 +249,9 @@ function migrate(reference: BlueprintResultSegment) { return adlib }) - part.pieces = part.pieces.map(adlib => { + part.pieces = part.pieces.map((adlib) => { if (adlib.content && adlib.content.timelineObjects) { - adlib.content.timelineObjects = (adlib.content.timelineObjects as TimelineObjectCoreExt[]).map(obj => { + adlib.content.timelineObjects = (adlib.content.timelineObjects as TimelineObjectCoreExt[]).map((obj) => { const remappedLayer = remapVizLLayer.get(obj.layer.toString()) if (remappedLayer) { diff --git a/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts b/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts index 9267e7c0..b4b74215 100644 --- a/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts @@ -55,7 +55,7 @@ describe('Generate rundowns without error', () => { expect(res.segment.name).toEqual(segment.name) const allPieces: IBlueprintPieceGeneric[] = [] - _.each(res.parts, part => { + _.each(res.parts, (part) => { allPieces.push(...part.pieces) allPieces.push(...part.adLibPieces) }) diff --git a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts index 36aacb28..cadac354 100644 --- a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts @@ -102,7 +102,7 @@ function getTransitionProperties(effekt: GalleryShowStyleConfig['BreakerConfig'] } function getPieceOnLayerFromPart(segment: BlueprintResultSegment, layer: SourceLayer): IBlueprintPiece { - const piece = segment.parts[0].pieces.find(p => p.sourceLayerId === layer) + const piece = segment.parts[0].pieces.find((p) => p.sourceLayerId === layer) expect(piece).toBeTruthy() return piece! @@ -110,7 +110,7 @@ function getPieceOnLayerFromPart(segment: BlueprintResultSegment, layer: SourceL function getATEMMEObj(piece: IBlueprintPiece): TSR.TimelineObjAtemME { const atemMEObj = (piece!.content!.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => + (obj) => obj.layer === prefixLayer(SwitcherMixEffectLLayer.PROGRAM) && obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.ME diff --git a/src/tv2_afvd_showstyle/config-manifests.ts b/src/tv2_afvd_showstyle/config-manifests.ts index 5a7cbc6e..0b071afa 100644 --- a/src/tv2_afvd_showstyle/config-manifests.ts +++ b/src/tv2_afvd_showstyle/config-manifests.ts @@ -1,5 +1,5 @@ import { ConfigManifestEntry, ConfigManifestEntryType, TSR } from 'blueprints-integration' -import { CommonConfigId, DEFAULT_GRAPHICS, getGfxDefaults, getGfxSetupsEntries } from 'tv2-common' +import { DEFAULT_GRAPHICS, getGfxDefaults, getGfxSetupsEntries, ShowStyleConfigId } from 'tv2-common' export const dveStylesManifest: ConfigManifestEntry = { id: 'DVEStyles', @@ -187,7 +187,7 @@ export const gfxDesignTemplates: ConfigManifestEntry[] = [ description: '', type: ConfigManifestEntryType.TABLE, required: true, - defaultVal: DEFAULT_GRAPHICS.map(val => ({ _id: '', ...val })).filter(template => template.IsDesign), + defaultVal: DEFAULT_GRAPHICS.map((val) => ({ _id: '', ...val })).filter((template) => template.IsDesign), columns: [ { id: DESIGN_NAME_COLUMN_ID, @@ -273,7 +273,7 @@ export const gfxShowMapping: ConfigManifestEntry = { defaultVal: [], columns: [ { - id: CommonConfigId.GFX_SHOW_MAPPING_DESIGN_COLUMN_ID, + id: ShowStyleConfigId.GFX_SHOW_MAPPING_DESIGN_COLUMN_ID, name: 'Design', rank: 0, description: 'Name of the Design from the GFX Design table', @@ -285,19 +285,19 @@ export const gfxShowMapping: ConfigManifestEntry = { defaultVal: '' }, { - id: CommonConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID, + id: ShowStyleConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID, name: 'GFX Setup', rank: 1, description: 'Names of the GFX Setups', type: ConfigManifestEntryType.SELECT_FROM_COLUMN, - tableId: CommonConfigId.GRAPHICS_SETUPS_TABLE_ID, - columnId: CommonConfigId.GRAPHICS_SETUPS_NAME_COLUMN_ID, + tableId: ShowStyleConfigId.GRAPHICS_SETUPS_TABLE_ID, + columnId: ShowStyleConfigId.GRAPHICS_SETUPS_NAME_COLUMN_ID, multiple: true, required: false, defaultVal: [] }, { - id: CommonConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, + id: ShowStyleConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID, name: 'GFX Skema Templates', rank: 2, description: 'Names of the Skemas', @@ -336,7 +336,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ 'This table can contain info in two ways. Things marked (**) are always required. If you want to do the mapping from iNews-code, then all (*)-elements are also required. GFX Template Name is what the graphic is called in viz. Source layer is the ID of the Sofie Source layer in the UI (i.e. "studio0_graphicsTema"). Layer mapping is the Sofie studio layer mapping (i.e "viz_layer_tema"). iNews command can be something like "KG=", then iNews Name is the thing that follows in iNews i.e. "ident_nyhederne"', type: ConfigManifestEntryType.TABLE, required: true, - defaultVal: DEFAULT_GRAPHICS.map(val => ({ _id: '', ...val })).filter(template => !template.IsDesign), + defaultVal: DEFAULT_GRAPHICS.map((val) => ({ _id: '', ...val })).filter((template) => !template.IsDesign), columns: [ { id: 'INewsCode', diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 40f768b5..82d180b2 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -79,17 +79,17 @@ class GlobalAdLibPiecesGenerator { this.config.sources.lives .slice(0, 10) // the first x lives to create live-adlibs from - .forEach(info => { + .forEach((info) => { adLibPieces.push(...this.makeRemoteAdLibs(info, globalRank++)) }) this.config.sources.lives .slice(0, 10) // the first x lives to create AUX1 (studio) adlibs - .forEach(info => { + .forEach((info) => { adLibPieces.push(...this.makeRemoteAuxStudioAdLibs(info, globalRank++)) }) - this.config.sources.replays.forEach(info => { + this.config.sources.replays.forEach((info) => { if (!/EPSIO/i.test(info.id)) { adLibPieces.push(this.makeEvsAdLib(info, globalRank++, false)) } @@ -402,7 +402,7 @@ class GlobalAdLibPiecesGenerator { content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: this.config.studio.StudioMics.map(layer => ({ + channels: this.config.studio.StudioMics.map((layer) => ({ mappedLayer: layer, isPgm: 1 })), @@ -431,7 +431,7 @@ class GlobalAdLibPiecesGenerator { content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: this.config.studio.StudioMics.map(layer => ({ + channels: this.config.studio.StudioMics.map((layer) => ({ mappedLayer: layer, isPgm: 0 })), @@ -740,7 +740,7 @@ function getBaseline(context: ShowStyleContext): Bluepri content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: Object.keys(sisyfosChannels).map(key => { + channels: Object.keys(sisyfosChannels).map((key) => { const llayer = key as SisyfosLLAyer const channel = sisyfosChannels[llayer] as SisyfosChannel return literal({ @@ -756,7 +756,7 @@ function getBaseline(context: ShowStyleContext): Bluepri ...CreateLYDBaseline('afvd'), ...(context.config.showStyle.CasparCGLoadingClip && context.config.showStyle.CasparCGLoadingClip.length - ? [...context.config.mediaPlayers.map(mp => CasparPlayerClipLoadingLoop(mp.id))].map(layer => { + ? [...context.config.mediaPlayers.map((mp) => CasparPlayerClipLoadingLoop(mp.id))].map((layer) => { return literal({ id: '', enable: { while: '1' }, diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index edea7c24..5c26a32a 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -112,7 +112,7 @@ function insertSpecialPieces( if (gfxSetupsToInitialize) { const showsToInitialize = new Set() const allShows = new Set() - config.showStyle.GfxSetups.forEach(gfxSetup => { + config.showStyle.GfxSetups.forEach((gfxSetup) => { allShows.add(gfxSetup.FullShowName) allShows.add(gfxSetup.OvlShowName) if (gfxSetupsToInitialize.includes(gfxSetup.Name)) { @@ -120,7 +120,7 @@ function insertSpecialPieces( showsToInitialize.add(gfxSetup.OvlShowName) } }) - const showsToCleanup = Array.from(allShows).filter(show => !showsToInitialize.has(show)) + const showsToCleanup = Array.from(allShows).filter((show) => !showsToInitialize.has(show)) CreateShowLifecyclePieces(config, blueprintParts[0], Array.from(showsToInitialize), showsToCleanup) } } diff --git a/src/tv2_afvd_showstyle/helpers/config.ts b/src/tv2_afvd_showstyle/helpers/config.ts index 818ed1f7..1b4df824 100644 --- a/src/tv2_afvd_showstyle/helpers/config.ts +++ b/src/tv2_afvd_showstyle/helpers/config.ts @@ -27,7 +27,7 @@ export interface GalleryShowStyleConfig extends TV2ShowstyleBlueprintConfigBase } export function preprocessConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { - const showstyleConfig = (rawConfig as unknown) as GalleryShowStyleConfig + const showstyleConfig = rawConfig as unknown as GalleryShowStyleConfig const selectedGfxSetup = findGfxSetup(context, showstyleConfig, { Name: '', VcpConcept: '', diff --git a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts index c972bb4d..88555a87 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -456,7 +456,7 @@ describe('grafik piece', () => { lifespan: PieceLifespan.WithinPart }) expect( - result.pieces[0].content.timelineObjects.find(tlObject => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) + result.pieces[0].content.timelineObjects.find((tlObject) => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) ).toMatchObject({ enable: { while: `!.full` @@ -483,7 +483,7 @@ describe('grafik piece', () => { lifespan: PieceLifespan.OutOnSegmentEnd }) expect( - result.pieces[0].content.timelineObjects.find(tlObject => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) + result.pieces[0].content.timelineObjects.find((tlObject) => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) ).toMatchObject({ enable: { while: `!.full` @@ -511,7 +511,7 @@ describe('grafik piece', () => { lifespan: PieceLifespan.OutOnShowStyleEnd }) expect( - result.pieces[0].content.timelineObjects.find(tlObject => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) + result.pieces[0].content.timelineObjects.find((tlObject) => tlObject.content.deviceType === TSR.DeviceType.VIZMSE) ).toMatchObject({ enable: { while: `!.full` @@ -827,7 +827,7 @@ describe('grafik piece', () => { cue.adlib ? { rank: 0 } : undefined ) - const adlibPiece = result.adlibPieces.find(piece => piece.tags?.includes('flow_producer')) + const adlibPiece = result.adlibPieces.find((piece) => piece.tags?.includes('flow_producer')) expect(adlibPiece).toBeDefined() expect(adlibPiece).toMatchObject({ expectedDuration: 10000, @@ -860,7 +860,7 @@ describe('grafik piece', () => { const piece = result.pieces[0] expect(piece).toBeTruthy() const tlObj = (piece.content?.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => + (obj) => obj.content.deviceType === TSR.DeviceType.VIZMSE && obj.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT ) as TSR.TimelineObjVIZMSEElementInternal | undefined diff --git a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts index a79ed514..65be3807 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts @@ -30,7 +30,7 @@ export function EvaluateClearGrafiks( SourceLayer.PgmGraphicsHeadline, SourceLayer.PgmGraphicsTema, SourceLayer.PgmGraphicsOverlay - ].forEach(sourceLayerId => { + ].forEach((sourceLayerId) => { pieces.push({ externalId: partId, name: `CLEAR ${sourceLayerId}`, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts index 6ab87340..3ae2a377 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts @@ -29,7 +29,7 @@ export function EvaluateJingle( ) { let file = '' - const jingle = context.config.showStyle.BreakerConfig.find(brkr => + const jingle = context.config.showStyle.BreakerConfig.find((brkr) => brkr.BreakerName ? brkr.BreakerName.toString().toUpperCase() === parsedCue.clip.toUpperCase() : false ) if (!jingle) { diff --git a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts index e5efd6af..ec52ee5c 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts @@ -38,7 +38,7 @@ export function EvaluateTelefon( function findTelefonPiece(result: EvaluateCueResult) { return result.pieces.find( - p => + (p) => p.outputLayerId === SharedOutputLayer.OVERLAY || p.outputLayerId === SharedOutputLayer.PGM || p.outputLayerId === SharedOutputLayer.SEC diff --git a/src/tv2_afvd_showstyle/migrations/hotkeys.ts b/src/tv2_afvd_showstyle/migrations/hotkeys.ts index 5c428b3f..37c5c195 100644 --- a/src/tv2_afvd_showstyle/migrations/hotkeys.ts +++ b/src/tv2_afvd_showstyle/migrations/hotkeys.ts @@ -12,17 +12,17 @@ export function GetDefaultStudioSourcesForAFVD(context: MigrationContextShowStyl const dveLayoutConfig = context.getBaseConfig('DVEStyles') as TableConfigItemValue | undefined let dveLayouts: string[] = [] if (dveLayoutConfig?.length) { - dveLayouts = dveLayoutConfig.map(dve => dve.DVEName).filter(name => name !== undefined) as string[] + dveLayouts = dveLayoutConfig.map((dve) => dve.DVEName).filter((name) => name !== undefined) as string[] } else { dveLayouts = (dveStylesManifest as ConfigManifestEntryTable).defaultVal - .map(dve => dve.DVEName) - .filter(name => name !== undefined) as string[] + .map((dve) => dve.DVEName) + .filter((name) => name !== undefined) as string[] } - const camera = manifestAFVDSourcesCam.defaultVal.map(source => source.SourceName) as string[] - const remote = manifestAFVDSourcesRM.defaultVal.map(source => source.SourceName) as string[] - const feed = manifestAFVDSourcesFeed.defaultVal.map(source => source.SourceName) as string[] - const replay = manifestAFVDSourcesReplay.defaultVal.map(source => source.SourceName) as string[] + const camera = manifestAFVDSourcesCam.defaultVal.map((source) => source.SourceName) as string[] + const remote = manifestAFVDSourcesRM.defaultVal.map((source) => source.SourceName) as string[] + const feed = manifestAFVDSourcesFeed.defaultVal.map((source) => source.SourceName) as string[] + const replay = manifestAFVDSourcesReplay.defaultVal.map((source) => source.SourceName) as string[] return { camera, diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index c11bd7ab..9bdfe15b 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -114,7 +114,7 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ * 1.6.3 * - Hide DSK toggle layers */ - ...GetDSKSourceLayerNames(ATEMModel.CONSTELLATION_8K_UHD_MODE).map(layerName => + ...GetDSKSourceLayerNames(ATEMModel.CONSTELLATION_8K_UHD_MODE).map((layerName) => forceSourceLayerToDefaults('1.6.3', layerName) ), @@ -268,8 +268,8 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ /** * 1.8.2 Move SelectedGfxSetupName to GFX Defaults */ - moveSelectedGfxSetupNameToGfxDefaults('1.8.2', 'SelectedGfxSetupName', 'GfxDefaults'), - moveSelectedGfxSetupNameToGfxDefaultsInVariants('1.8.2', 'SelectedGfxSetupName', 'GfxDefaults'), + moveSelectedGfxSetupNameToGfxDefaults('1.8.2'), + moveSelectedGfxSetupNameToGfxDefaultsInVariants('1.8.2'), // Fill in any layers that did not exist before // Note: These should only be run as the very final step of all migrations. otherwise they will add items too early, and confuse old migrations diff --git a/src/tv2_afvd_showstyle/parts/grafik.ts b/src/tv2_afvd_showstyle/parts/grafik.ts index 04a4f6e7..f2de5f92 100644 --- a/src/tv2_afvd_showstyle/parts/grafik.ts +++ b/src/tv2_afvd_showstyle/parts/grafik.ts @@ -36,7 +36,9 @@ export async function CreatePartGrafik( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - if (partDefinition.cues.filter(c => c.type === CueType.Graphic && GraphicIsPilot(c) && c.target === 'FULL').length) { + if ( + partDefinition.cues.filter((c) => c.type === CueType.Graphic && GraphicIsPilot(c) && c.target === 'FULL').length + ) { applyFullGraphicPropertiesToPart(context.config, part) } diff --git a/src/tv2_afvd_showstyle/parts/intro.ts b/src/tv2_afvd_showstyle/parts/intro.ts index 874765e6..3bcf33c1 100644 --- a/src/tv2_afvd_showstyle/parts/intro.ts +++ b/src/tv2_afvd_showstyle/parts/intro.ts @@ -27,7 +27,7 @@ export async function CreatePartIntro( ): Promise { const partTime = PartTime(context.config, partDefinition, totalWords, false) - const jingleCue = partDefinition.cues.find(cue => { + const jingleCue = partDefinition.cues.find((cue) => { const parsedCue = cue return parsedCue.type === CueType.Jingle }) @@ -39,7 +39,7 @@ export async function CreatePartIntro( const parsedJingle = jingleCue as CueDefinitionJingle - const jingle = context.config.showStyle.BreakerConfig.find(jngl => + const jingle = context.config.showStyle.BreakerConfig.find((jngl) => jngl.BreakerName ? jngl.BreakerName.toString().toUpperCase() === parsedJingle.clip.toString().toUpperCase() : false ) if (!jingle) { diff --git a/src/tv2_afvd_showstyle/parts/live.ts b/src/tv2_afvd_showstyle/parts/live.ts index 626c504e..86d1d29e 100644 --- a/src/tv2_afvd_showstyle/parts/live.ts +++ b/src/tv2_afvd_showstyle/parts/live.ts @@ -48,8 +48,8 @@ export async function CreatePartLive( part.hackListenToMediaObjectUpdates = mediaSubscriptions - const liveCue = partDefinition.cues.find(c => c.type === CueType.Ekstern) as CueDefinitionEkstern - const livePiece = pieces.find(p => p.sourceLayerId === SourceLayer.PgmLive) + const liveCue = partDefinition.cues.find((c) => c.type === CueType.Ekstern) as CueDefinitionEkstern + const livePiece = pieces.find((p) => p.sourceLayerId === SourceLayer.PgmLive) if (pieces.length === 0 || !liveCue || !livePiece) { part.invalid = true diff --git a/src/tv2_afvd_showstyle/parts/unknown.ts b/src/tv2_afvd_showstyle/parts/unknown.ts index ae3a8dc9..d8aff93d 100644 --- a/src/tv2_afvd_showstyle/parts/unknown.ts +++ b/src/tv2_afvd_showstyle/parts/unknown.ts @@ -45,8 +45,8 @@ export async function CreatePartUnknown( part = { ...part, ...GetJinglePartProperties(context, partDefinition) } if ( - partDefinition.cues.some(cue => cue.type === CueType.Graphic && GraphicIsPilot(cue) && cue.target === 'FULL') && - !partDefinition.cues.filter(c => c.type === CueType.Jingle).length + partDefinition.cues.some((cue) => cue.type === CueType.Graphic && GraphicIsPilot(cue) && cue.target === 'FULL') && + !partDefinition.cues.filter((c) => c.type === CueType.Jingle).length ) { applyFullGraphicPropertiesToPart(context.config, part) } diff --git a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts index 7735c205..f8947a85 100644 --- a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts @@ -89,7 +89,7 @@ const blankStudioConfig: StudioConfig = { function getObjectKeys(obj: any): string[] { const definedKeys: string[] = [] const processObj = (prefix: string, o: any) => { - _.each(_.keys(o), k => { + _.each(_.keys(o), (k) => { if (_.isArray(o[k])) { definedKeys.push(prefix + k) } else if (_.isObject(o[k])) { @@ -105,7 +105,7 @@ function getObjectKeys(obj: any): string[] { describe('Config Manifest', () => { test('Exposed Studio Keys', () => { - const studioManifestKeys = _.map(studioConfigManifest, e => e.id) + const studioManifestKeys = _.map(studioConfigManifest, (e) => e.id) const manifestKeys = studioManifestKeys.concat(CORE_INJECTED_KEYS).sort() const definedKeys = getObjectKeys(blankStudioConfig) diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index 3b2cd24d..309f81ab 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -48,7 +48,7 @@ describe('Graphics', () => { const result = await CreatePartGrafik(context, partDefintion, 0) - expect((context.core as SegmentUserContextMock).getNotes().map(msg => msg.message)).toEqual([ + expect((context.core as SegmentUserContextMock).getNotes().map((msg) => msg.message)).toEqual([ `No graphic found after GRAFIK cue` ]) expect(result.pieces).toHaveLength(0) @@ -84,7 +84,7 @@ describe('Graphics', () => { CreatePartGrafik(context, partDefinition, 0) - expect((context.core as SegmentUserContextMock).getNotes().map(msg => msg.message)).toEqual([ + expect((context.core as SegmentUserContextMock).getNotes().map((msg) => msg.message)).toEqual([ `Graphic found without target engine` ]) }) @@ -130,7 +130,7 @@ describe('Graphics', () => { const timeline = content.timelineObjects as TSR.TSRTimelineObj[] expect(timeline).toHaveLength(7) // @todo: this depends on unrelated configuration const vizObj = timeline.find( - t => + (t) => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT )! as TSR.TimelineObjVIZMSEElementPilot expect(vizObj.enable).toEqual({ start: 0 }) @@ -193,7 +193,7 @@ describe('Graphics', () => { const timeline = content.timelineObjects as TSR.TSRTimelineObj[] expect(timeline).toHaveLength(1) const vizObj = timeline.find( - t => + (t) => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT )! as TSR.TimelineObjVIZMSEElementPilot expect(vizObj.enable).toEqual({ while: '!.full' }) @@ -249,7 +249,7 @@ describe('Graphics', () => { const timeline = content.timelineObjects as TSR.TSRTimelineObj[] expect(timeline).toHaveLength(1) const vizObj = timeline.find( - t => + (t) => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT )! as TSR.TimelineObjVIZMSEElementPilot expect(vizObj.enable).toEqual({ while: '1' }) @@ -302,7 +302,7 @@ describe('Graphics', () => { const timeline = content.timelineObjects as TSR.TSRTimelineObj[] expect(timeline).toHaveLength(7) const vizObj = timeline.find( - t => + (t) => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT )! as TSR.TimelineObjVIZMSEElementPilot expect(vizObj.enable).toEqual({ start: 0 }) @@ -355,12 +355,12 @@ describe('Graphics', () => { const result = await CreatePartGrafik(context, partDefinition, 0) expect(result.pieces).toHaveLength(3) - const auxPiece = result.pieces.find(p => p.outputLayerId === SharedOutputLayer.AUX)! + const auxPiece = result.pieces.find((p) => p.outputLayerId === SharedOutputLayer.AUX)! expect(auxPiece.enable).toEqual({ start: 0 }) expect(auxPiece.sourceLayerId).toBe(SourceLayer.VizFullIn1) expect(auxPiece.lifespan).toBe(PieceLifespan.WithinPart) const auxObj = (auxPiece.content?.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.AUX + (obj) => obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.AUX ) as TSR.TimelineObjAtemAUX | undefined expect(auxObj).toBeTruthy() expect(auxObj?.enable).toEqual({ start: 0 }) @@ -434,7 +434,7 @@ describe('Graphics', () => { expect(piece.sourceLayerId).toBe(SourceLayer.PgmDVEBackground) expect(piece.lifespan).toBe(PieceLifespan.OutOnShowStyleEnd) const tlObj = (piece.content?.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => + (obj) => obj.content.deviceType === TSR.DeviceType.CASPARCG && obj.content.type === TSR.TimelineContentTypeCasparCg.MEDIA ) as TSR.TimelineObjCCGMedia | undefined expect(tlObj).toBeTruthy() @@ -484,7 +484,7 @@ describe('Graphics', () => { expect(piece.sourceLayerId).toBe(SourceLayer.PgmGraphicsLower) expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const tlObj = (piece.content?.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => + (obj) => obj.content.deviceType === TSR.DeviceType.VIZMSE && obj.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL ) as TSR.TimelineObjVIZMSEElementInternal | undefined diff --git a/src/tv2_afvd_studio/__tests__/migrations-defaults.spec.ts b/src/tv2_afvd_studio/__tests__/migrations-defaults.spec.ts index d077a90c..924fb5ec 100644 --- a/src/tv2_afvd_studio/__tests__/migrations-defaults.spec.ts +++ b/src/tv2_afvd_studio/__tests__/migrations-defaults.spec.ts @@ -16,7 +16,7 @@ import { GALLERY_UNIFORM_CONFIG } from '../uniformConfig' /** Get all the Real LLayers (map to devices). Note: Does not include some which are dynamically generated */ export function getRealLLayers(): string[] { return getUsedLayers(GALLERY_UNIFORM_CONFIG) - .flatMap(layer => [TRICASTER_LAYER_PREFIX + layer, ATEM_LAYER_PREFIX + layer]) + .flatMap((layer) => [TRICASTER_LAYER_PREFIX + layer, ATEM_LAYER_PREFIX + layer]) .concat(_.values(CasparLLayer)) .concat(_.values(SisyfosLLAyer)) .concat(_.values(AbstractLLayer)) diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index 3a0b5f64..4986c26b 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -20,7 +20,7 @@ function filterMappings( ): BlueprintMappings { const result: BlueprintMappings = {} - _.each(_.keys(input), k => { + _.each(_.keys(input), (k) => { const v = input[k] if (filter(k, v)) { result[k] = v @@ -129,7 +129,7 @@ export function getMixEffectBaseline( context: StudioContext | ShowStyleContext, input: number | SpecialInput ): TSR.TSRTimelineObj[] { - return Object.values(context.uniformConfig.mixEffects).flatMap(mixEffect => + return Object.values(context.uniformConfig.mixEffects).flatMap((mixEffect) => _.compact([ context.videoSwitcher.getMixEffectTimelineObject({ enable: { while: '1' }, diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index 84b30cf4..793f29c3 100644 --- a/src/tv2_afvd_studio/helpers/config.ts +++ b/src/tv2_afvd_studio/helpers/config.ts @@ -42,7 +42,7 @@ export interface StudioConfig extends TV2StudioConfigBase { } export function preprocessConfig(_context: ICommonContext, rawConfig: IBlueprintConfig): any { - const studioConfig = (rawConfig as unknown) as StudioConfig + const studioConfig = rawConfig as unknown as StudioConfig const config: GalleryStudioConfig = { studio: studioConfig, sources: parseSources(studioConfig), diff --git a/src/tv2_afvd_studio/helpers/sources.ts b/src/tv2_afvd_studio/helpers/sources.ts index 956fb140..e6d1553b 100644 --- a/src/tv2_afvd_studio/helpers/sources.ts +++ b/src/tv2_afvd_studio/helpers/sources.ts @@ -5,7 +5,7 @@ import { ParseMappingTable, SourceInfoType, SourceMapping } from 'tv2-common' import { StudioConfig } from './config' export function parseMediaPlayers(studioConfig: StudioConfig): Array<{ id: string; val: string }> { - return studioConfig.ABMediaPlayers.map(player => ({ + return studioConfig.ABMediaPlayers.map((player) => ({ id: player.SourceName, val: player.SwitcherSource.toString() })) diff --git a/src/tv2_afvd_studio/migrations/devices.ts b/src/tv2_afvd_studio/migrations/devices.ts index dbf81e31..53f3d1e4 100644 --- a/src/tv2_afvd_studio/migrations/devices.ts +++ b/src/tv2_afvd_studio/migrations/devices.ts @@ -102,7 +102,7 @@ const devices: DeviceEntry[] = [ id: 'caspar01', firstVersion: '0.1.0', type: TSR.DeviceType.CASPARCG, - defaultValue: input => ({ + defaultValue: (input) => ({ type: TSR.DeviceType.CASPARCG, options: { host: input.host, @@ -120,7 +120,7 @@ const devices: DeviceEntry[] = [ defaultValue: undefined } ], - validate: device => { + validate: (device) => { if (!device.options) { return 'Missing options' } @@ -159,7 +159,7 @@ const devices: DeviceEntry[] = [ } return undefined }, - validate: device => { + validate: (device) => { if (!device.options) { return 'Missing options' } @@ -186,7 +186,7 @@ const devices: DeviceEntry[] = [ id: 'atem0', firstVersion: '0.1.0', type: TSR.DeviceType.ATEM, - defaultValue: input => ({ + defaultValue: (input) => ({ type: TSR.DeviceType.ATEM, options: { host: input.host, @@ -202,7 +202,7 @@ const devices: DeviceEntry[] = [ defaultValue: undefined } ], - validate: device => { + validate: (device) => { if (!device.options) { return 'Missing options' } diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index 672bcd62..0e37782b 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -109,7 +109,7 @@ export const studioMigrations: MigrationStepStudio[] = [ 'viz_layer_pilot', 'viz_layer_pilot_overlay', 'viz_layer_wall' - ].map(layer => renameMapping('0.2.0', layer, layer.replace(/^viz_layer_/, 'graphic_'))), + ].map((layer) => renameMapping('0.2.0', layer, layer.replace(/^viz_layer_/, 'graphic_'))), AddKeepAudio('0.2.0', 'SourcesRM'), MoveClipSourcePath('0.2.0', 'AFVD'), ...[ @@ -143,7 +143,7 @@ export const studioMigrations: MigrationStepStudio[] = [ 'sisyfos_source_evs_1', 'sisyfos_source_evs_2', 'sisyfos_resync' - ].map(layer => EnsureSisyfosMappingHasType('1.3.0', layer, TSR.MappingSisyfosType.CHANNEL)), + ].map((layer) => EnsureSisyfosMappingHasType('1.3.0', layer, TSR.MappingSisyfosType.CHANNEL)), GetMappingDefaultMigrationStepForLayer('1.3.0', SisyfosLLAyer.SisyfosGroupStudioMics), GetMappingDefaultMigrationStepForLayer('1.3.2', CasparLLayer.CasparCGLYD, true), GetMappingDefaultMigrationStepForLayer('1.4.0', CasparLLayer.CasparPlayerClipPending, true), @@ -206,7 +206,7 @@ export const studioMigrations: MigrationStepStudio[] = [ /** * 1.8.0 */ - ...['SourcesCam', 'SourcesRM', 'SourcesReplay', 'SourcesFeed', 'ABMediaPlayers'].map(tableName => + ...['SourcesCam', 'SourcesRM', 'SourcesReplay', 'SourcesFeed', 'ABMediaPlayers'].map((tableName) => renameStudioTableColumn('1.8.0', tableName, 'AtemSource', 'SwitcherSource') ), renameStudioConfig('1.8.0', 'AFVD', 'AtemSource', 'SwitcherSource'), diff --git a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts index 0a6c5de3..846e592d 100644 --- a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts @@ -271,10 +271,10 @@ async function getActiveServerPieces( return { activePiece: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmServer)), + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.PgmServer)), dataStore: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedServer)) + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedServer)) } } @@ -285,10 +285,12 @@ async function getVOPieces( return { activePiece: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmVoiceOver)), + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.PgmVoiceOver)), dataStore: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedVoiceOver)) + .then((pieceInstances) => + pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedVoiceOver) + ) } } @@ -299,10 +301,12 @@ async function getDVEPieces( return { activePiece: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmDVE)), + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.PgmDVE)), dataStore: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedAdLibDVE)) + .then((pieceInstances) => + pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedAdLibDVE) + ) } } @@ -313,11 +317,11 @@ async function getFullGrafikPieces( return { activePiece: await context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === SharedSourceLayer.PgmPilot)), + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === SharedSourceLayer.PgmPilot)), dataStore: await context .getPieceInstances(part) - .then(pieceInstances => - pieceInstances.find(p => p.piece.sourceLayerId === SharedSourceLayer.SelectedAdlibGraphicsFull) + .then((pieceInstances) => + pieceInstances.find((p) => p.piece.sourceLayerId === SharedSourceLayer.SelectedAdlibGraphicsFull) ) } } @@ -328,7 +332,7 @@ async function getCameraPiece( ): Promise { return context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmCam)) + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.PgmCam)) } async function getRemotePiece( @@ -337,7 +341,7 @@ async function getRemotePiece( ): Promise { return context .getPieceInstances(part) - .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmLive)) + .then((pieceInstances) => pieceInstances.find((p) => p.piece.sourceLayerId === OfftubeSourceLayer.PgmLive)) } function validateSourcePiecesExist(pieces: ActivePiecesForSource) { @@ -371,9 +375,11 @@ function validateRemotePiece(piece: IBlueprintPieceInstance | undefined) { function validateNoWarningsOrErrors(context: ActionExecutionContextMock) { expect( - context.getNotes().filter(n => n.type === NoteType.WARNING || n.type === NoteType.NOTIFY_USER_WARNING) + context.getNotes().filter((n) => n.type === NoteType.WARNING || n.type === NoteType.NOTIFY_USER_WARNING) ).toEqual([]) - expect(context.getNotes().filter(n => n.type === NoteType.ERROR || n.type === NoteType.NOTIFY_USER_ERROR)).toEqual([]) + expect(context.getNotes().filter((n) => n.type === NoteType.ERROR || n.type === NoteType.NOTIFY_USER_ERROR)).toEqual( + [] + ) } function validateNextPartExistsWithDuration(context: ActionExecutionContextMock, duration: number) { @@ -391,7 +397,7 @@ function validateNextPartExistsWithPreviousPartKeepaliveDuration( function getATEMMEObj(piece: IBlueprintPieceInstance): TSR.TimelineObjAtemME { const atemObj = (piece.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => + (obj) => obj.layer === prefixLayer(SwitcherMixEffectLLayer.CLEAN) && obj.content.deviceType === TSR.DeviceType.ATEM && obj.content.type === TSR.TimelineContentTypeAtem.ME @@ -429,7 +435,7 @@ describe('Select Server Action', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -456,7 +462,7 @@ describe('Select Server Action', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -488,7 +494,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -521,7 +527,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -555,7 +561,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -589,7 +595,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -622,7 +628,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -655,7 +661,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) @@ -687,7 +693,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) @@ -720,7 +726,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) @@ -752,7 +758,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) @@ -784,7 +790,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) @@ -816,7 +822,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' // SERVER (A) await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) @@ -940,7 +946,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) @@ -983,7 +989,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) @@ -1026,7 +1032,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) @@ -1069,7 +1075,7 @@ describe('Combination Actions', () => { ) context.studioConfig = defaultStudioConfig as any context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' + ;(context.studioConfig as unknown as OfftubeStudioConfig).GraphicsType = 'HTML' await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) diff --git a/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts index 9ebd6535..ad83a326 100644 --- a/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts @@ -21,7 +21,7 @@ const blankShowStyleConfig: OfftubeShowStyleConfig = { describe('Config Manifest', () => { test('Exposed ShowStyle Keys', () => { - const showStyleManifestKeys = _.map(showStyleConfigManifest, e => e.id) + const showStyleManifestKeys = _.map(showStyleConfigManifest, (e) => e.id) const manifestKeys = showStyleManifestKeys.sort() const definedKeys = Object.keys(blankShowStyleConfig) diff --git a/src/tv2_offtube_showstyle/__tests__/migrations-defaults.spec.ts b/src/tv2_offtube_showstyle/__tests__/migrations-defaults.spec.ts index f541ea70..d119f798 100644 --- a/src/tv2_offtube_showstyle/__tests__/migrations-defaults.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/migrations-defaults.spec.ts @@ -7,9 +7,9 @@ import SourcelayerDefaults from '../migrations/sourcelayer-defaults' describe('Migration Defaults', () => { test('SourcelayerDefaults', () => { - const defaultsIds = _.map(SourcelayerDefaults, v => v._id).sort() + const defaultsIds = _.map(SourcelayerDefaults, (v) => v._id).sort() const layerIds = _.values(OfftubeSourceLayer) - .map(l => l.toString()) + .map((l) => l.toString()) .concat(GetDSKSourceLayerNames(ATEMModel.PRODUCTION_STUDIO_4K_2ME)) .sort() diff --git a/src/tv2_offtube_showstyle/config-manifests.ts b/src/tv2_offtube_showstyle/config-manifests.ts index 9f6ba643..b771d7ff 100644 --- a/src/tv2_offtube_showstyle/config-manifests.ts +++ b/src/tv2_offtube_showstyle/config-manifests.ts @@ -152,7 +152,7 @@ export const gfxDesignTemplates: ConfigManifestEntry[] = [ description: '', type: ConfigManifestEntryType.TABLE, required: true, - defaultVal: DEFAULT_GRAPHICS.map(val => ({ _id: '', ...val })).filter(template => template.IsDesign), + defaultVal: DEFAULT_GRAPHICS.map((val) => ({ _id: '', ...val })).filter((template) => template.IsDesign), columns: [ { id: DESIGN_NAME_COLUMN_ID, @@ -253,7 +253,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ 'This table can contain info in two ways. Things marked (**) are always required. If you want to do the mapping from iNews-code, then all (*)-elements are also required. GFX Template Name is what the graphic is called in the HTML package. Source layer is the ID of the Sofie Source layer in the UI (i.e. "studio0_graphicsTema"). Layer mapping is the Sofie studio layer mapping (i.e "viz_layer_tema"). iNews command can be something like "KG=", then iNews Name is the thing that follows in iNews i.e. "ident_nyhederne"', type: ConfigManifestEntryType.TABLE, required: false, - defaultVal: DEFAULT_GRAPHICS.map(val => ({ _id: '', ...val })).filter(template => !template.IsDesign), + defaultVal: DEFAULT_GRAPHICS.map((val) => ({ _id: '', ...val })).filter((template) => !template.IsDesign), columns: [ { id: 'INewsCode', diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index 9197e6ae..f0383e25 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -31,7 +31,7 @@ export function OfftubeEvaluateJingle( ) { let file = '' - const jingle = context.config.showStyle.BreakerConfig.find(brkr => + const jingle = context.config.showStyle.BreakerConfig.find((brkr) => brkr.BreakerName ? brkr.BreakerName.toString().toUpperCase() === parsedCue.clip.toUpperCase() : false ) if (!jingle) { diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 42ba1ed3..ac0ad6ae 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -127,7 +127,7 @@ function getGlobalAdLibPiecesOfftube(context: ShowStyleContext ({ + channels: context.config.studio.StudioMics.map((layer) => ({ mappedLayer: layer, isPgm: 1 })), @@ -157,7 +157,7 @@ function getGlobalAdLibPiecesOfftube(context: ShowStyleContext ({ + channels: context.config.studio.StudioMics.map((layer) => ({ mappedLayer: layer, isPgm: 0 })), @@ -495,14 +495,14 @@ function getGlobalAdlibActionsOfftube( config.sources.cameras .slice(0, 5) // the first x cameras to create INP1/2/3 cam-adlibs from - .forEach(cameraSourceInfo => { + .forEach((cameraSourceInfo) => { blueprintActions.push(makeCutDirectlyCameraAction(cameraSourceInfo, globalRank++)) blueprintActions.push(makeQueueAsNextCameraAction(cameraSourceInfo, globalRank++)) }) config.sources.cameras .slice(0, 5) // the first x cameras to create preview cam-adlibs from - .forEach(o => { + .forEach((o) => { makeAdlibBoxesActions(o, SourceInfoType.KAM, globalRank++) }) @@ -529,25 +529,25 @@ function getGlobalAdlibActionsOfftube( config.sources.feeds .slice(0, 10) // the first x sources to create feed-adlibs from - .forEach(o => { + .forEach((o) => { makeRemoteAction(o, globalRank++) }) config.sources.lives .slice(0, 10) // the first x sources to create live-adlibs from - .forEach(o => { + .forEach((o) => { makeRemoteAction(o, globalRank++) }) config.sources.feeds .slice(0, 10) // the first x remote to create INP1/2/3 feed-adlibs from - .forEach(o => { + .forEach((o) => { makeAdlibBoxesActions(o, SourceInfoType.FEED, globalRank++) }) config.sources.lives .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from - .forEach(o => { + .forEach((o) => { makeAdlibBoxesActions(o, SourceInfoType.LIVE, globalRank++) }) @@ -748,7 +748,7 @@ function getBaseline(context: ShowStyleContext): Bluepri content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: Object.keys(sisyfosChannels).map(key => { + channels: Object.keys(sisyfosChannels).map((key) => { const llayer = key as OfftubeSisyfosLLayer const channel = sisyfosChannels[llayer] as SisyfosChannel return literal({ @@ -773,7 +773,7 @@ function getBaseline(context: ShowStyleContext): Bluepri ...CreateLYDBaseline('offtube'), ...(context.config.showStyle.CasparCGLoadingClip && context.config.showStyle.CasparCGLoadingClip.length - ? [...context.config.mediaPlayers.map(mp => CasparPlayerClipLoadingLoop(mp.id))].map(layer => { + ? [...context.config.mediaPlayers.map((mp) => CasparPlayerClipLoadingLoop(mp.id))].map((layer) => { return literal({ id: '', enable: { while: '1' }, diff --git a/src/tv2_offtube_showstyle/helpers/config.ts b/src/tv2_offtube_showstyle/helpers/config.ts index 70979243..a790add0 100644 --- a/src/tv2_offtube_showstyle/helpers/config.ts +++ b/src/tv2_offtube_showstyle/helpers/config.ts @@ -40,7 +40,7 @@ export interface OfftubeShowStyleConfig extends TV2ShowstyleBlueprintConfigBase } export function preprocessConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { - const showstyleConfig = (rawConfig as unknown) as OfftubeShowStyleConfig + const showstyleConfig = rawConfig as unknown as OfftubeShowStyleConfig const selectedGfxSetup = findGfxSetup(context, showstyleConfig, { Name: '', HtmlPackageFolder: '' @@ -52,10 +52,10 @@ export function preprocessConfig(context: ICommonContext, rawConfig: IBlueprintC } export function getConfig(context: IShowStyleContext): OfftubeBlueprintConfig { - return ({ + return { ...(context.getStudioConfig() as any), ...(context.getShowStyleConfig() as any) - } as any) as OfftubeBlueprintConfig + } as any as OfftubeBlueprintConfig } export function getStudioConfig(context: IStudioContext): OfftubeBlueprintConfig { diff --git a/src/tv2_offtube_showstyle/migrations/hotkeys.ts b/src/tv2_offtube_showstyle/migrations/hotkeys.ts index 25c7771b..50350d0c 100644 --- a/src/tv2_offtube_showstyle/migrations/hotkeys.ts +++ b/src/tv2_offtube_showstyle/migrations/hotkeys.ts @@ -11,16 +11,16 @@ export function GetDefaultStudioSourcesForOfftube(context: MigrationContextShowS const dveLayoutConfig = context.getBaseConfig('DVEStyles') as TableConfigItemValue | undefined let dveLayouts: string[] = [] if (dveLayoutConfig?.length) { - dveLayouts = dveLayoutConfig.map(dve => dve.DVEName).filter(name => name !== undefined) as string[] + dveLayouts = dveLayoutConfig.map((dve) => dve.DVEName).filter((name) => name !== undefined) as string[] } else { dveLayouts = (dveStylesManifest as ConfigManifestEntryTable).defaultVal - .map(dve => dve.DVEName) - .filter(name => name !== undefined) as string[] + .map((dve) => dve.DVEName) + .filter((name) => name !== undefined) as string[] } - const camera = manifestOfftubeSourcesCam.defaultVal.map(source => source.SourceName) as string[] - const remote = manifestOfftubeSourcesRM.defaultVal.map(source => source.SourceName) as string[] - const feed = manifestOfftubeSourcesFeed.defaultVal.map(source => `F${source.SourceName}`) + const camera = manifestOfftubeSourcesCam.defaultVal.map((source) => source.SourceName) as string[] + const remote = manifestOfftubeSourcesRM.defaultVal.map((source) => source.SourceName) as string[] + const feed = manifestOfftubeSourcesFeed.defaultVal.map((source) => `F${source.SourceName}`) const local: string[] = [] return { diff --git a/src/tv2_offtube_showstyle/migrations/index.ts b/src/tv2_offtube_showstyle/migrations/index.ts index ae610125..0b8e97ec 100644 --- a/src/tv2_offtube_showstyle/migrations/index.ts +++ b/src/tv2_offtube_showstyle/migrations/index.ts @@ -149,7 +149,7 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ * 1.6.3 * - Hide DSK toggle layers */ - ...GetDSKSourceLayerNames(ATEMModel.PRODUCTION_STUDIO_4K_2ME).map(layerName => + ...GetDSKSourceLayerNames(ATEMModel.PRODUCTION_STUDIO_4K_2ME).map((layerName) => forceSourceLayerToDefaults('1.6.3', layerName) ), @@ -294,8 +294,8 @@ export const showStyleMigrations: MigrationStepShowStyle[] = [ /** * 1.8.2 Move SelectedGfxSetupName to GFX Defaults */ - moveSelectedGfxSetupNameToGfxDefaults('1.8.2', 'SelectedGfxSetupName', 'GfxDefaults'), - moveSelectedGfxSetupNameToGfxDefaultsInVariants('1.8.2', 'SelectedGfxSetupName', 'GfxDefaults'), + moveSelectedGfxSetupNameToGfxDefaults('1.8.2'), + moveSelectedGfxSetupNameToGfxDefaultsInVariants('1.8.2'), ...getSourceLayerDefaultsMigrationSteps(VERSION), ...getOutputLayerDefaultsMigrationSteps(VERSION), diff --git a/src/tv2_offtube_showstyle/migrations/util.ts b/src/tv2_offtube_showstyle/migrations/util.ts index 1cb248e3..0e7d452f 100644 --- a/src/tv2_offtube_showstyle/migrations/util.ts +++ b/src/tv2_offtube_showstyle/migrations/util.ts @@ -74,7 +74,7 @@ function remapTableColumnValuesInner( ): { changed: number; table: TableConfigItemValue } { let changed = 0 - table.forEach(row => { + table.forEach((row) => { const val = row[columnId] if (val) { diff --git a/src/tv2_offtube_showstyle/onTimelineGenerate.ts b/src/tv2_offtube_showstyle/onTimelineGenerate.ts index 0b8f55a7..569bfe62 100644 --- a/src/tv2_offtube_showstyle/onTimelineGenerate.ts +++ b/src/tv2_offtube_showstyle/onTimelineGenerate.ts @@ -48,7 +48,7 @@ export function disableFirstPilotGFXAnimation( previousPartEndState: PartEndStateExt | undefined, resolvedPieces: IBlueprintResolvedPieceInstance[] ) { - const isFull = resolvedPieces.find(p => p.piece.tags?.includes(TallyTags.FULL_IS_LIVE)) + const isFull = resolvedPieces.find((p) => p.piece.tags?.includes(TallyTags.FULL_IS_LIVE)) for (const obj of timeline) { if ( obj.layer === SharedGraphicLLayer.GraphicLLayerPilot && diff --git a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts index 1f423490..1c17e62f 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts @@ -43,8 +43,8 @@ export async function CreatePartUnknown( part = { ...part, ...GetJinglePartProperties(context, partDefinition) } if ( - partDefinition.cues.some(cue => cue.type === CueType.Graphic && GraphicIsPilot(cue) && cue.target === 'FULL') && - !partDefinition.cues.filter(c => c.type === CueType.Jingle).length + partDefinition.cues.some((cue) => cue.type === CueType.Graphic && GraphicIsPilot(cue) && cue.target === 'FULL') && + !partDefinition.cues.filter((c) => c.type === CueType.Jingle).length ) { applyFullGraphicPropertiesToPart(context.config, part) } diff --git a/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts b/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts index 074e9c3c..c72d76bc 100644 --- a/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts @@ -85,7 +85,7 @@ const blankStudioConfig: OfftubeStudioConfig = { function getObjectKeys(obj: any): string[] { const definedKeys: string[] = [] const processObj = (prefix: string, o: any) => { - _.each(_.keys(o), k => { + _.each(_.keys(o), (k) => { if (_.isArray(o[k])) { definedKeys.push(prefix + k) } else if (_.isObject(o[k])) { @@ -101,7 +101,7 @@ function getObjectKeys(obj: any): string[] { describe('Config Manifest', () => { test('Exposed Studio Keys', () => { - const studioManifestKeys = _.map(studioConfigManifest, e => e.id) + const studioManifestKeys = _.map(studioConfigManifest, (e) => e.id) const manifestKeys = studioManifestKeys.concat(CORE_INJECTED_KEYS).sort() const definedKeys = getObjectKeys(blankStudioConfig) diff --git a/src/tv2_offtube_studio/__tests__/migrations-defaults.spec.ts b/src/tv2_offtube_studio/__tests__/migrations-defaults.spec.ts index 643b3e92..4b466035 100644 --- a/src/tv2_offtube_studio/__tests__/migrations-defaults.spec.ts +++ b/src/tv2_offtube_studio/__tests__/migrations-defaults.spec.ts @@ -15,7 +15,7 @@ import { QBOX_UNIFORM_CONFIG } from '../uniformConfig' /** Get all the Real LLayers (map to devices). Note: Does not include some which are dynamically generated */ export function getRealLLayers(): string[] { return getUsedLayers(QBOX_UNIFORM_CONFIG) - .flatMap(layer => [ATEM_LAYER_PREFIX + layer]) + .flatMap((layer) => [ATEM_LAYER_PREFIX + layer]) .concat(_.values(OfftubeSisyfosLLayer)) .concat(_.values(OfftubeCasparLLayer)) .concat(_.values(AbstractLLayer)) diff --git a/src/tv2_offtube_studio/getBaseline.ts b/src/tv2_offtube_studio/getBaseline.ts index 0c7d2335..cc73f502 100644 --- a/src/tv2_offtube_studio/getBaseline.ts +++ b/src/tv2_offtube_studio/getBaseline.ts @@ -18,7 +18,7 @@ function filterMappings( ): BlueprintMappings { const result: BlueprintMappings = {} - _.each(_.keys(input), k => { + _.each(_.keys(input), (k) => { const v = input[k] if (filter(k, v)) { result[k] = v diff --git a/src/tv2_offtube_studio/helpers/config.ts b/src/tv2_offtube_studio/helpers/config.ts index d6b1a2a9..c6be4da9 100644 --- a/src/tv2_offtube_studio/helpers/config.ts +++ b/src/tv2_offtube_studio/helpers/config.ts @@ -49,7 +49,7 @@ export interface OfftubeStudioConfig extends TV2StudioConfigBase { } export function preprocessConfig(_context: ICommonContext, rawConfig: IBlueprintConfig): OfftubeStudioBlueprintConfig { - const studioConfig = (rawConfig as unknown) as OfftubeStudioConfig + const studioConfig = rawConfig as unknown as OfftubeStudioConfig const config: OfftubeStudioBlueprintConfig = { studio: rawConfig as any, // showStyle: {} as any, diff --git a/src/tv2_offtube_studio/helpers/sources.ts b/src/tv2_offtube_studio/helpers/sources.ts index 774dd7d0..8da41934 100644 --- a/src/tv2_offtube_studio/helpers/sources.ts +++ b/src/tv2_offtube_studio/helpers/sources.ts @@ -5,7 +5,7 @@ import { ParseMappingTable, SourceInfoType, SourceMapping } from 'tv2-common' import { OfftubeStudioConfig } from './config' export function parseMediaPlayers(studioConfig: OfftubeStudioConfig): Array<{ id: string; val: string }> { - return studioConfig.ABMediaPlayers.map(player => ({ id: player.SourceName, val: player.SwitcherSource.toString() })) + return studioConfig.ABMediaPlayers.map((player) => ({ id: player.SourceName, val: player.SwitcherSource.toString() })) } export function parseSources(studioConfig: OfftubeStudioConfig): SourceMapping { diff --git a/src/tv2_offtube_studio/migrations/devices.ts b/src/tv2_offtube_studio/migrations/devices.ts index dbf81e31..53f3d1e4 100644 --- a/src/tv2_offtube_studio/migrations/devices.ts +++ b/src/tv2_offtube_studio/migrations/devices.ts @@ -102,7 +102,7 @@ const devices: DeviceEntry[] = [ id: 'caspar01', firstVersion: '0.1.0', type: TSR.DeviceType.CASPARCG, - defaultValue: input => ({ + defaultValue: (input) => ({ type: TSR.DeviceType.CASPARCG, options: { host: input.host, @@ -120,7 +120,7 @@ const devices: DeviceEntry[] = [ defaultValue: undefined } ], - validate: device => { + validate: (device) => { if (!device.options) { return 'Missing options' } @@ -159,7 +159,7 @@ const devices: DeviceEntry[] = [ } return undefined }, - validate: device => { + validate: (device) => { if (!device.options) { return 'Missing options' } @@ -186,7 +186,7 @@ const devices: DeviceEntry[] = [ id: 'atem0', firstVersion: '0.1.0', type: TSR.DeviceType.ATEM, - defaultValue: input => ({ + defaultValue: (input) => ({ type: TSR.DeviceType.ATEM, options: { host: input.host, @@ -202,7 +202,7 @@ const devices: DeviceEntry[] = [ defaultValue: undefined } ], - validate: device => { + validate: (device) => { if (!device.options) { return 'Missing options' } diff --git a/src/tv2_offtube_studio/migrations/index.ts b/src/tv2_offtube_studio/migrations/index.ts index 4de24c0f..d954578e 100644 --- a/src/tv2_offtube_studio/migrations/index.ts +++ b/src/tv2_offtube_studio/migrations/index.ts @@ -99,7 +99,7 @@ function remapTableColumnValuesInner( ): { changed: number; table: TableConfigItemValue } { let changed = 0 - table.forEach(row => { + table.forEach((row) => { const val = row[columnId] if (val) { @@ -265,7 +265,7 @@ export const studioMigrations: MigrationStepStudio[] = [ 'sisyfos_source_live_3', 'sisyfos_source_server_a', 'sisyfos_source_server_b' - ].map(layer => EnsureSisyfosMappingHasType('1.3.0', layer, TSR.MappingSisyfosType.CHANNEL)), + ].map((layer) => EnsureSisyfosMappingHasType('1.3.0', layer, TSR.MappingSisyfosType.CHANNEL)), GetMappingDefaultMigrationStepForLayer('1.3.0', OfftubeSisyfosLLayer.SisyfosConfig), GetMappingDefaultMigrationStepForLayer('1.3.0', OfftubeSisyfosLLayer.SisyfosGroupStudioMics), GetMappingDefaultMigrationStepForLayer('1.4.0', OfftubeCasparLLayer.CasparPlayerClipPending, true), @@ -370,7 +370,7 @@ export const studioMigrations: MigrationStepStudio[] = [ /** * 1.8.0 */ - ...['SourcesCam', 'SourcesRM', 'SourcesReplay', 'SourcesFeed', 'ABMediaPlayers'].map(tableName => + ...['SourcesCam', 'SourcesRM', 'SourcesReplay', 'SourcesFeed', 'ABMediaPlayers'].map((tableName) => renameStudioTableColumn('1.8.0', tableName, 'AtemSource', 'SwitcherSource') ), renameStudioConfig('1.8.0', 'AFVD', 'AtemSource', 'SwitcherSource'), diff --git a/src/tv2_system/migrations/hotkeys.ts b/src/tv2_system/migrations/hotkeys.ts index 787f4416..9389aa11 100644 --- a/src/tv2_system/migrations/hotkeys.ts +++ b/src/tv2_system/migrations/hotkeys.ts @@ -8,7 +8,7 @@ import { } from 'blueprints-integration' export function RemoveDefaultCoreShortcuts(versionStr: string): MigrationStepSystem { - const defaultTriggerIds = DEFAULT_CORE_TRIGGERS.map(trigger => trigger._id) + const defaultTriggerIds = DEFAULT_CORE_TRIGGERS.map((trigger) => trigger._id) return { id: `${versionStr}.disableCoreDefaultTriggers`, From 365e57aeeea560a2fd6c2c34ebb0505bee15f51e Mon Sep 17 00:00:00 2001 From: Rasmus Date: Mon, 3 Apr 2023 09:40:48 +0200 Subject: [PATCH 74/86] refactor: Changes names for enum values to reflect they are for GFX Defaults --- src/tv2-common/showstyle/config-manifests.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tv2-common/showstyle/config-manifests.ts b/src/tv2-common/showstyle/config-manifests.ts index 35507657..a781e5c9 100644 --- a/src/tv2-common/showstyle/config-manifests.ts +++ b/src/tv2-common/showstyle/config-manifests.ts @@ -5,9 +5,9 @@ export enum ShowStyleConfigId { GRAPHICS_SETUPS_TABLE_ID = 'GfxSetups', GRAPHICS_SETUPS_NAME_COLUMN_ID = 'Name', GFX_DEFAULTS_TABLE_ID = 'GfxDefaults', - DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID = 'DefaultSetupName', - DEFAULTS_SCHEMA_COLUMN_ID = 'DefaultSchema', - DEFAULTS_DESIGN_COLUMN_ID = 'DefaultDesign', + GFX_DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID = 'DefaultSetupName', + GFX_DEFAULTS_SCHEMA_COLUMN_ID = 'DefaultSchema', + GFX_DEFAULTS_DESIGN_COLUMN_ID = 'DefaultDesign', GFX_SHOW_MAPPING_TABLE_ID = 'GfxShowMapping', GFX_SHOW_MAPPING_DESIGN_COLUMN_ID = 'Design', GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID = 'GfxSetup', @@ -66,7 +66,7 @@ export const getGfxDefaults: ConfigManifestEntry = { disableRowManipulation: true, columns: [ { - id: ShowStyleConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, + id: ShowStyleConfigId.GFX_DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, name: 'GFX Setup', rank: 0, description: 'Name of the GFX Setup', @@ -78,14 +78,14 @@ export const getGfxDefaults: ConfigManifestEntry = { defaultVal: '' }, { - id: ShowStyleConfigId.DEFAULTS_SCHEMA_COLUMN_ID, + id: ShowStyleConfigId.GFX_DEFAULTS_SCHEMA_COLUMN_ID, name: 'Default Skema', rank: 1, description: 'The Skema options based on the GFX Setup', type: ConfigManifestEntryType.SELECT_FROM_TABLE_ENTRY_WITH_COMPARISON_MAPPINGS, comparisonMappings: [ { - targetColumnId: ShowStyleConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, + targetColumnId: ShowStyleConfigId.GFX_DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, sourceColumnId: ShowStyleConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID } ], @@ -96,18 +96,18 @@ export const getGfxDefaults: ConfigManifestEntry = { defaultVal: '' }, { - id: ShowStyleConfigId.DEFAULTS_DESIGN_COLUMN_ID, + id: ShowStyleConfigId.GFX_DEFAULTS_DESIGN_COLUMN_ID, name: 'Default Design', rank: 2, description: 'The Design options based on the Default Skema or GFX Setup', type: ConfigManifestEntryType.SELECT_FROM_TABLE_ENTRY_WITH_COMPARISON_MAPPINGS, comparisonMappings: [ { - targetColumnId: ShowStyleConfigId.DEFAULTS_SCHEMA_COLUMN_ID, + targetColumnId: ShowStyleConfigId.GFX_DEFAULTS_SCHEMA_COLUMN_ID, sourceColumnId: ShowStyleConfigId.GFX_SHOW_MAPPING_SCHEMA_COLUMN_ID }, { - targetColumnId: ShowStyleConfigId.DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, + targetColumnId: ShowStyleConfigId.GFX_DEFAULTS_SELECTED_GFX_SETUP_NAME_COLUMN_ID, sourceColumnId: ShowStyleConfigId.GFX_SHOW_MAPPING_GFX_SETUP_COLUMN_ID } ], From 17f4671622d79ca1fb802af6ad36b7d1cc986cc1 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Mon, 3 Apr 2023 12:32:25 +0200 Subject: [PATCH 75/86] refactor: Better explains the GFX Defaults in the config-manifest, simplifies some conditional logic --- src/tv2-common/migrations/index.ts | 23 ++++++++------------ src/tv2-common/showstyle/config-manifests.ts | 2 +- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index 74c3e4fb..765a9c7e 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -183,11 +183,7 @@ export function moveSelectedGfxSetupNameToGfxDefaults(versionStr: string) { const singleValue = context.getBaseConfig(fromValue) const designatedTable = context.getBaseConfig(targetTable) - if (!singleValue || !Array.isArray(designatedTable)) { - return false - } - - return true + return !!singleValue && Array.isArray(designatedTable) }, migrate: (context: MigrationContextShowStyle) => { const singleValue = context.getBaseConfig(fromValue) as BasicConfigItemValue @@ -212,20 +208,19 @@ export function moveSelectedGfxSetupNameToGfxDefaultsInVariants(migrationVersion validate: (context: MigrationContextShowStyle) => { const allVariants = context.getAllVariants() - return allVariants.some((variant: IBlueprintShowStyleVariant) => { - return context.getVariantConfig(variant._id, fromValue) && !context.getVariantConfig(variant._id, targetTable) - }) + return allVariants.some( + (variant: IBlueprintShowStyleVariant) => + context.getVariantConfig(variant._id, fromValue) && !context.getVariantConfig(variant._id, targetTable) + ) }, migrate: (context: MigrationContextShowStyle) => { const allVariants = context.getAllVariants() allVariants.forEach((variant: IBlueprintShowStyleVariant) => { - const singleValue = context.getVariantConfig(variant._id, fromValue) as BasicConfigItemValue - let designatedTable = context.getVariantConfig(variant._id, targetTable) as TableConfigItemValue const setupName = 'DefaultSetupName' - - if (designatedTable === undefined) { - designatedTable = [{ [setupName]: singleValue, _id: '' }] - } + const singleValue = context.getVariantConfig(variant._id, fromValue) as BasicConfigItemValue + const designatedTable = (context.getVariantConfig(variant._id, targetTable) as TableConfigItemValue) ?? [ + { [setupName]: singleValue, _id: '' } + ] context.setVariantConfig(variant._id, targetTable, designatedTable) }) diff --git a/src/tv2-common/showstyle/config-manifests.ts b/src/tv2-common/showstyle/config-manifests.ts index a781e5c9..e2d0ba01 100644 --- a/src/tv2-common/showstyle/config-manifests.ts +++ b/src/tv2-common/showstyle/config-manifests.ts @@ -59,7 +59,7 @@ export const GFX_DEFAULT_VALUES: TableConfigItemGfxDefaults[] = [ export const getGfxDefaults: ConfigManifestEntry = { id: ShowStyleConfigId.GFX_DEFAULTS_TABLE_ID, name: 'GFX Defaults', - description: 'The possible defaults available for the GFX setup', + description: 'The default values available for the GFX setup', type: ConfigManifestEntryType.TABLE, required: false, defaultVal: GFX_DEFAULT_VALUES.map((gfxDefaultValue) => ({ _id: '', ...gfxDefaultValue })), From 58af5d17ffabb43ecc426418ace2a815629ccc11 Mon Sep 17 00:00:00 2001 From: Rasmus Date: Mon, 3 Apr 2023 14:02:25 +0200 Subject: [PATCH 76/86] feat: bump the blueprints-integration --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a0c3076a..ad0ffd4d 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "webpack-cli": "^3.1.2" }, "dependencies": { - "@sofie-automation/blueprints-integration": "npm:@tv2media/blueprints-integration@46.2.1", + "@sofie-automation/blueprints-integration": "npm:@tv2media/blueprints-integration@46.2.2", "underscore": "^1.12.1", "ts-mockito": "^2.6.1" }, diff --git a/yarn.lock b/yarn.lock index 1eec4076..e146ffb1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -560,10 +560,10 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@sofie-automation/blueprints-integration@npm:@tv2media/blueprints-integration@46.2.1": - version "46.2.1" - resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-46.2.1.tgz#adfa9818481546cb8b472a35835277f020fc20d5" - integrity sha512-3bqG/XVHWoxSJ20wGADT3Z1wIc3i5O5ZtN0JYwKu8H+DzVaVOyGjZTvzSP6nzBGr3dOX1acm3q7A3fZC4tAX0Q== +"@sofie-automation/blueprints-integration@npm:@tv2media/blueprints-integration@46.2.2": + version "46.2.2" + resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-46.2.2.tgz#74c0533e79585755cd61397b531689754fd2ef6d" + integrity sha512-IjHlVaE0IuLp7R8mxIWz5AbnlC8EExtHHWt/F8tbbjSyKYeBahxS0asnbMFnDYMlOZznNrunT4nBy8vwGfTHhg== dependencies: "@sofie-automation/shared-lib" "npm:@tv2media/shared-lib@46.2.0" timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@3.4.0" From caf0fc39ca91255cef659e40a1452d52bad911bb Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Tue, 4 Apr 2023 14:39:13 +0200 Subject: [PATCH 77/86] SOF-1374 Cutting directly now creates a new Part. Directly cut parts are not able to be recalled as last live --- src/tv2-common/actions/executeAction.ts | 2 +- yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 0b7340c8..7d2cf36b 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1073,7 +1073,7 @@ async function executePiece< if (isServerInCurrentPart && !shouldBeQueued) { await context.core.takeAfterExecuteAction(true) } - } else if (currentPiece) { + } else if (currentPiece && currentPiece.piece.sourceLayerId !== settings.SourceLayers.Live) { pieceToExecute.externalId = currentPiece.piece.externalId pieceToExecute.enable = currentPiece.piece.enable const currentMetaData = currentPiece.piece.metaData! diff --git a/yarn.lock b/yarn.lock index e146ffb1..0fc6e8f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -566,7 +566,7 @@ integrity sha512-IjHlVaE0IuLp7R8mxIWz5AbnlC8EExtHHWt/F8tbbjSyKYeBahxS0asnbMFnDYMlOZznNrunT4nBy8vwGfTHhg== dependencies: "@sofie-automation/shared-lib" "npm:@tv2media/shared-lib@46.2.0" - timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@3.4.0" + timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@3.5.0" tslib "^2.4.0" type-fest "^2.19.0" From 5af5531866ee9e9747b3f8259a6b4ad7510f8586 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 5 Apr 2023 07:57:14 +0200 Subject: [PATCH 78/86] SOF-964 Now uses DefaultSetupName in TableConfigItemGfxDefaults instead of GfxSetup --- src/tv2-common/blueprintConfig.ts | 2 +- src/tv2-common/helpers/config.ts | 5 +++-- src/tv2-common/showstyle/config-manifests.ts | 17 +++++++---------- .../__tests__/config-manifest.spec.ts | 8 +++++++- src/tv2_afvd_showstyle/__tests__/configs.ts | 8 +++++++- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 1d76bef4..e7fc7a49 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -44,7 +44,7 @@ export interface TableConfigItemGfxShowMapping { } export interface TableConfigItemGfxDefaults { - GfxSetup: string + DefaultSetupName: { value: string; label: string } DefaultSchema: string DefaultDesign: string } diff --git a/src/tv2-common/helpers/config.ts b/src/tv2-common/helpers/config.ts index 0e223259..004cd1b8 100644 --- a/src/tv2-common/helpers/config.ts +++ b/src/tv2-common/helpers/config.ts @@ -17,11 +17,12 @@ export function findGfxSetup tableConfigGfxSetup.Name === config.GfxDefaults[0].GfxSetup + (tableConfigGfxSetup) => tableConfigGfxSetup.Name === defaultSetupName?.label ) if (!foundTableConfigGfxSetup) { - context.logWarning(`No GFX setup found for profile: ${config.GfxDefaults[0].GfxSetup}`) + context.logWarning(`No GFX setup found for profile: ${defaultSetupName}`) return fallbackGfxSetup } return foundTableConfigGfxSetup diff --git a/src/tv2-common/showstyle/config-manifests.ts b/src/tv2-common/showstyle/config-manifests.ts index e2d0ba01..3b2f839e 100644 --- a/src/tv2-common/showstyle/config-manifests.ts +++ b/src/tv2-common/showstyle/config-manifests.ts @@ -1,5 +1,4 @@ import { ConfigManifestEntry, ConfigManifestEntryTable, ConfigManifestEntryType } from 'blueprints-integration' -import { TableConfigItemGfxDefaults } from '../blueprintConfig' export enum ShowStyleConfigId { GRAPHICS_SETUPS_TABLE_ID = 'GfxSetups', @@ -48,21 +47,19 @@ export const getGfxSetupsEntries = (columns: ConfigManifestEntryTable['columns'] } ] -export const GFX_DEFAULT_VALUES: TableConfigItemGfxDefaults[] = [ - { - GfxSetup: '', - DefaultSchema: '', - DefaultDesign: '' - } -] +const GFX_DEFAULT_VALUES = { + DefaultSetupName: '', + DefaultSchema: '', + DefaultDesign: '' +} -export const getGfxDefaults: ConfigManifestEntry = { +export const getGfxDefaults: ConfigManifestEntryTable = { id: ShowStyleConfigId.GFX_DEFAULTS_TABLE_ID, name: 'GFX Defaults', description: 'The default values available for the GFX setup', type: ConfigManifestEntryType.TABLE, required: false, - defaultVal: GFX_DEFAULT_VALUES.map((gfxDefaultValue) => ({ _id: '', ...gfxDefaultValue })), + defaultVal: [{ _id: '', ...GFX_DEFAULT_VALUES }], disableRowManipulation: true, columns: [ { diff --git a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts index 460d47f6..507701a3 100644 --- a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts @@ -17,7 +17,13 @@ const blankShowStyleConfig: GalleryShowStyleConfig = { GfxSetups: [], GfxSchemaTemplates: [], GfxShowMapping: [], - GfxDefaults: [{ GfxSetup: '', DefaultSchema: '', DefaultDesign: '' }] + GfxDefaults: [ + { + DefaultSetupName: { value: '', label: '' }, + DefaultDesign: '', + DefaultSchema: '' + } + ] } describe('Config Manifest', () => { diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index db0a7b10..73fa09be 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -274,5 +274,11 @@ export const defaultShowStyleConfig: GalleryShowStyleConfig = { ShowstyleTransition: 'CUT', GfxSchemaTemplates: [], GfxShowMapping: [], - GfxDefaults: [{ GfxSetup: 'SomeProfile', DefaultDesign: '', DefaultSchema: '' }] + GfxDefaults: [ + { + DefaultSetupName: { value: '', label: 'SomeProfile' }, + DefaultDesign: '', + DefaultSchema: '' + } + ] } From 44a8cb8ae55af38686838aae27483bff9f403864 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 5 Apr 2023 08:01:09 +0200 Subject: [PATCH 79/86] SOF-964 Stringify object in warning message to see actually values --- src/tv2-common/helpers/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv2-common/helpers/config.ts b/src/tv2-common/helpers/config.ts index 004cd1b8..ebf6d471 100644 --- a/src/tv2-common/helpers/config.ts +++ b/src/tv2-common/helpers/config.ts @@ -22,7 +22,7 @@ export function findGfxSetup tableConfigGfxSetup.Name === defaultSetupName?.label ) if (!foundTableConfigGfxSetup) { - context.logWarning(`No GFX setup found for profile: ${defaultSetupName}`) + context.logWarning(`No GFX setup found for profile: ${JSON.stringify(defaultSetupName)}`) return fallbackGfxSetup } return foundTableConfigGfxSetup From bf09e7a0c0c27feeb41dfdbc613a15ff6a65c0ab Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 5 Apr 2023 12:17:18 +0200 Subject: [PATCH 80/86] SOF-1374 executing a piece now only looks for the current piece on the layer of said piece --- src/tv2-common/actions/executeAction.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 7d2cf36b..44a348a3 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1039,7 +1039,7 @@ async function executeActionCutToCamera< } } - await executePiece(context, settings, kamPiece, !userData.cutDirectly, part) + await executePiece(context, settings, kamPiece, settings.SourceLayers.Cam, !userData.cutDirectly, part) } async function executePiece< @@ -1049,6 +1049,7 @@ async function executePiece< context: ActionExecutionContext, settings: ActionExecutionSettings, pieceToExecute: IBlueprintPiece, + sourceLayerToFindCurrentPieceOn: string, shouldBeQueued: boolean, partToQueue: IBlueprintPart ) { @@ -1057,9 +1058,8 @@ async function executePiece< (p) => p.piece.sourceLayerId === settings.SourceLayers.Server || p.piece.sourceLayerId === settings.SourceLayers.VO ) - const layersWithCutDirect: string[] = [settings.SourceLayers.Live, settings.SourceLayers.Cam] - const currentPiece: IBlueprintPieceInstance | undefined = currentPieceInstances.find((p) => - layersWithCutDirect.includes(p.piece.sourceLayerId) + const currentPiece: IBlueprintPieceInstance | undefined = currentPieceInstances.find( + (p) => sourceLayerToFindCurrentPieceOn === p.piece.sourceLayerId ) if (shouldBeQueued || isServerInCurrentPart) { @@ -1196,7 +1196,7 @@ async function executeActionCutToRemote< } } - await executePiece(context, settings, remotePiece, !userData.cutDirectly, part) + await executePiece(context, settings, remotePiece, settings.SourceLayers.Live, !userData.cutDirectly, part) } async function executeActionCutSourceToBox< From b28645dedbf378eef46698ad2ed90e39cc66f3a9 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 5 Apr 2023 12:30:07 +0200 Subject: [PATCH 81/86] SOF-964 now uses ids to find the selectedGfxSetup --- src/tv2-common/blueprintConfig.ts | 1 + src/tv2-common/helpers/config.ts | 2 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 3 ++- src/tv2_afvd_showstyle/helpers/config.ts | 1 + src/tv2_offtube_showstyle/helpers/config.ts | 1 + 5 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index e7fc7a49..64483d27 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -60,6 +60,7 @@ export interface TableConfigGfxSchema { } export interface TableConfigGfxSetup { + _id: string Name: string HtmlPackageFolder: string OvlShowName?: string diff --git a/src/tv2-common/helpers/config.ts b/src/tv2-common/helpers/config.ts index ebf6d471..dee3ec86 100644 --- a/src/tv2-common/helpers/config.ts +++ b/src/tv2-common/helpers/config.ts @@ -19,7 +19,7 @@ export function findGfxSetup tableConfigGfxSetup.Name === defaultSetupName?.label + (tableConfigGfxSetup) => tableConfigGfxSetup._id === defaultSetupName?.value ) if (!foundTableConfigGfxSetup) { context.logWarning(`No GFX setup found for profile: ${JSON.stringify(defaultSetupName)}`) diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index 73fa09be..a717fbc1 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -45,6 +45,7 @@ function prepareConfig( export const OVL_SHOW_NAME = 'ovl-show-id' export const FULL_SHOW_NAME = 'full-show-id' export const DEFAULT_GFX_SETUP: GalleryTableConfigGfxSetup = { + _id: 'SomeId', Name: 'SomeProfile', VcpConcept: 'SomeConcept', OvlShowName: OVL_SHOW_NAME, @@ -276,7 +277,7 @@ export const defaultShowStyleConfig: GalleryShowStyleConfig = { GfxShowMapping: [], GfxDefaults: [ { - DefaultSetupName: { value: '', label: 'SomeProfile' }, + DefaultSetupName: { value: 'SomeId', label: 'SomeProfile' }, DefaultDesign: '', DefaultSchema: '' } diff --git a/src/tv2_afvd_showstyle/helpers/config.ts b/src/tv2_afvd_showstyle/helpers/config.ts index 1b4df824..0e19d7ce 100644 --- a/src/tv2_afvd_showstyle/helpers/config.ts +++ b/src/tv2_afvd_showstyle/helpers/config.ts @@ -29,6 +29,7 @@ export interface GalleryShowStyleConfig extends TV2ShowstyleBlueprintConfigBase export function preprocessConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { const showstyleConfig = rawConfig as unknown as GalleryShowStyleConfig const selectedGfxSetup = findGfxSetup(context, showstyleConfig, { + _id: '', Name: '', VcpConcept: '', OvlShowName: '', diff --git a/src/tv2_offtube_showstyle/helpers/config.ts b/src/tv2_offtube_showstyle/helpers/config.ts index a790add0..8cbfddd1 100644 --- a/src/tv2_offtube_showstyle/helpers/config.ts +++ b/src/tv2_offtube_showstyle/helpers/config.ts @@ -42,6 +42,7 @@ export interface OfftubeShowStyleConfig extends TV2ShowstyleBlueprintConfigBase export function preprocessConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { const showstyleConfig = rawConfig as unknown as OfftubeShowStyleConfig const selectedGfxSetup = findGfxSetup(context, showstyleConfig, { + _id: '', Name: '', HtmlPackageFolder: '' }) From c987b53fed555859750059aad2e73d5451a470c4 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 5 Apr 2023 13:02:29 +0200 Subject: [PATCH 82/86] Revert "SOF-1374 executing a piece now only looks for the current piece on the layer of said piece" This reverts commit bf09e7a0c0c27feeb41dfdbc613a15ff6a65c0ab. --- src/tv2-common/actions/executeAction.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 44a348a3..7d2cf36b 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1039,7 +1039,7 @@ async function executeActionCutToCamera< } } - await executePiece(context, settings, kamPiece, settings.SourceLayers.Cam, !userData.cutDirectly, part) + await executePiece(context, settings, kamPiece, !userData.cutDirectly, part) } async function executePiece< @@ -1049,7 +1049,6 @@ async function executePiece< context: ActionExecutionContext, settings: ActionExecutionSettings, pieceToExecute: IBlueprintPiece, - sourceLayerToFindCurrentPieceOn: string, shouldBeQueued: boolean, partToQueue: IBlueprintPart ) { @@ -1058,8 +1057,9 @@ async function executePiece< (p) => p.piece.sourceLayerId === settings.SourceLayers.Server || p.piece.sourceLayerId === settings.SourceLayers.VO ) - const currentPiece: IBlueprintPieceInstance | undefined = currentPieceInstances.find( - (p) => sourceLayerToFindCurrentPieceOn === p.piece.sourceLayerId + const layersWithCutDirect: string[] = [settings.SourceLayers.Live, settings.SourceLayers.Cam] + const currentPiece: IBlueprintPieceInstance | undefined = currentPieceInstances.find((p) => + layersWithCutDirect.includes(p.piece.sourceLayerId) ) if (shouldBeQueued || isServerInCurrentPart) { @@ -1196,7 +1196,7 @@ async function executeActionCutToRemote< } } - await executePiece(context, settings, remotePiece, settings.SourceLayers.Live, !userData.cutDirectly, part) + await executePiece(context, settings, remotePiece, !userData.cutDirectly, part) } async function executeActionCutSourceToBox< From 2d70497c4c69195830a6a9455126dfcc5088ccea Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 5 Apr 2023 14:39:47 +0200 Subject: [PATCH 83/86] fix: SOF-1374 stop planned Live pieces when direct cutting to another Live ...in order to preserve the original piece, so that it can be re-used when queuing last live; in other cases do the fast update of existing piece on layersWithCutDirect --- .../actions/CoreActionExecutionContext.ts | 5 +++ src/tv2-common/actions/executeAction.ts | 38 +++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/tv2-common/actions/CoreActionExecutionContext.ts b/src/tv2-common/actions/CoreActionExecutionContext.ts index 4ba153c0..3a256188 100644 --- a/src/tv2-common/actions/CoreActionExecutionContext.ts +++ b/src/tv2-common/actions/CoreActionExecutionContext.ts @@ -198,6 +198,11 @@ export class CoreActionExecutionContext implements ITV2ActionExecutionContext { } } + piece.metaData = { + ...piece.metaData, + modifiedByAction: true + } + // Regardless of above, let core handle errors return this.core.updatePieceInstance(pieceInstanceId, piece) as Promise> } diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 7d2cf36b..78721f24 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1058,8 +1058,9 @@ async function executePiece< ) const layersWithCutDirect: string[] = [settings.SourceLayers.Live, settings.SourceLayers.Cam] - const currentPiece: IBlueprintPieceInstance | undefined = currentPieceInstances.find((p) => - layersWithCutDirect.includes(p.piece.sourceLayerId) + const currentPiece: IBlueprintPieceInstance | undefined = findLastPlayingPieceInstance( + currentPieceInstances, + layersWithCutDirect ) if (shouldBeQueued || isServerInCurrentPart) { @@ -1073,7 +1074,7 @@ async function executePiece< if (isServerInCurrentPart && !shouldBeQueued) { await context.core.takeAfterExecuteAction(true) } - } else if (currentPiece && currentPiece.piece.sourceLayerId !== settings.SourceLayers.Live) { + } else if (currentPiece && !isPlannedLivePiece(currentPiece, settings.SourceLayers.Live)) { pieceToExecute.externalId = currentPiece.piece.externalId pieceToExecute.enable = currentPiece.piece.enable const currentMetaData = currentPiece.piece.metaData! @@ -1109,6 +1110,32 @@ async function executePiece< } } +function isPlannedLivePiece(currentPiece: IBlueprintPieceInstance, liveSourceLayerId: string) { + return ( + currentPiece.piece.sourceLayerId === liveSourceLayerId && + !currentPiece.piece.metaData?.modifiedByAction && + !currentPiece?.dynamicallyInserted + ) +} + +function findLastPlayingPieceInstance( + currentPieceInstances: Array>, + sourceLayerIds: string[] +): IBlueprintPieceInstance | undefined { + const playingPiecesOnSelectedLayers = currentPieceInstances.filter( + (p) => !p.stoppedPlayback && sourceLayerIds.includes(p.piece.sourceLayerId) + ) + if (playingPiecesOnSelectedLayers.length < 2) { + return playingPiecesOnSelectedLayers[0] + } + return playingPiecesOnSelectedLayers.reduce((prev, current) => + (prev.startedPlayback ?? prev.dynamicallyInserted?.time ?? Infinity) > + (current.startedPlayback ?? current.dynamicallyInserted?.time ?? Infinity) + ? prev + : current + ) +} + async function stopGraphicPiecesThatShouldEndWithPart( context: ActionExecutionContext, currentPieceInstances: Array> @@ -1649,7 +1676,10 @@ async function executeActionRecallLastLive< ) { const lastLive = await context.core.findLastPieceOnLayer(settings.SourceLayers.Live, { originalOnly: true, - excludeCurrentPart: false + excludeCurrentPart: false, + pieceMetaDataFilter: { + modifiedByAction: { $ne: true } + } }) if (!lastLive) { From 2da86e2837beb1ddd0144777d80e86317888f380 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 11 Apr 2023 10:05:17 +0200 Subject: [PATCH 84/86] refactor: SOF-1374 changes based on PR comments --- src/tv2-common/actions/executeAction.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 78721f24..03edfa10 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1074,7 +1074,7 @@ async function executePiece< if (isServerInCurrentPart && !shouldBeQueued) { await context.core.takeAfterExecuteAction(true) } - } else if (currentPiece && !isPlannedLivePiece(currentPiece, settings.SourceLayers.Live)) { + } else if (currentPiece && !isPlannedPieceOnLayer(currentPiece, settings.SourceLayers.Live)) { pieceToExecute.externalId = currentPiece.piece.externalId pieceToExecute.enable = currentPiece.piece.enable const currentMetaData = currentPiece.piece.metaData! @@ -1110,9 +1110,9 @@ async function executePiece< } } -function isPlannedLivePiece(currentPiece: IBlueprintPieceInstance, liveSourceLayerId: string) { +function isPlannedPieceOnLayer(currentPiece: IBlueprintPieceInstance, sourceLayerId: string) { return ( - currentPiece.piece.sourceLayerId === liveSourceLayerId && + currentPiece.piece.sourceLayerId === sourceLayerId && !currentPiece.piece.metaData?.modifiedByAction && !currentPiece?.dynamicallyInserted ) @@ -1125,15 +1125,15 @@ function findLastPlayingPieceInstance( const playingPiecesOnSelectedLayers = currentPieceInstances.filter( (p) => !p.stoppedPlayback && sourceLayerIds.includes(p.piece.sourceLayerId) ) - if (playingPiecesOnSelectedLayers.length < 2) { + if (playingPiecesOnSelectedLayers.length <= 1) { return playingPiecesOnSelectedLayers[0] } - return playingPiecesOnSelectedLayers.reduce((prev, current) => - (prev.startedPlayback ?? prev.dynamicallyInserted?.time ?? Infinity) > - (current.startedPlayback ?? current.dynamicallyInserted?.time ?? Infinity) - ? prev - : current - ) + return playingPiecesOnSelectedLayers.reduce((prev, current) => { + const prevStartedPlayback = prev.startedPlayback ?? prev.dynamicallyInserted?.time ?? Infinity + const currentStartedPlayback = current.startedPlayback ?? current.dynamicallyInserted?.time ?? Infinity + + return prevStartedPlayback > currentStartedPlayback ? prev : current + }) } async function stopGraphicPiecesThatShouldEndWithPart( From 3283eeb70ade3f5324081f06453b831e0dafbef0 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Thu, 13 Apr 2023 12:25:57 +0200 Subject: [PATCH 85/86] SOF-1419 StudioMics now uses new datatype --- src/tv2-common/blueprintConfig.ts | 7 ++++++- src/tv2-common/helpers/sisyfos.ts | 4 ++-- src/tv2_afvd_showstyle/__tests__/configs.ts | 12 ++++++------ src/tv2_afvd_showstyle/getRundown.ts | 8 ++++---- src/tv2_afvd_studio/helpers/config.ts | 3 ++- src/tv2_offtube_showstyle/getRundown.ts | 8 ++++---- 6 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 64483d27..c31cc821 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -73,6 +73,11 @@ export interface ProcessedStudioConfig { dsk: TableConfigItemDSK[] } +export interface StudioMic { + label: string + value: string +} + export interface TV2StudioConfigBase { MaximumPartDuration: number DefaultPartDuration: number @@ -120,7 +125,7 @@ export interface TV2StudioConfigBase { Dip: number } AtemSettings: {} - StudioMics: string[] + StudioMics: StudioMic[] SourcesRM: TableConfigItemSourceMappingWithSisyfos[] SourcesFeed: TableConfigItemSourceMappingWithSisyfos[] SourcesCam: TableConfigItemSourceMappingWithSisyfos[] diff --git a/src/tv2-common/helpers/sisyfos.ts b/src/tv2-common/helpers/sisyfos.ts index b8909f1d..7f903c39 100644 --- a/src/tv2-common/helpers/sisyfos.ts +++ b/src/tv2-common/helpers/sisyfos.ts @@ -124,9 +124,9 @@ function getStudioMicsTimelineObj( timelineEnable: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosChannels { const studioMicsChannels: TSR.TimelineObjSisyfosChannels['content']['channels'] = [] - config.studio.StudioMics.forEach((layer) => { + config.studio.StudioMics.forEach((studioMic) => { studioMicsChannels.push({ - mappedLayer: layer, + mappedLayer: studioMic.value, isPgm: 1 }) }) diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index a717fbc1..58ae66fa 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -95,12 +95,12 @@ export const defaultStudioConfig: StudioConfig = { SourcesFeed: prepareConfig('1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,10:10', 'SourcesFeed', false, true), SourcesReplay: prepareConfig('EVS 1:5,EVS 2:5,EPSIO:5', 'SourcesDelayedPlayback', false), StudioMics: [ - 'sisyfos_source_Host_1_st_a', - 'sisyfos_source_Host_2_st_a', - 'sisyfos_source_Guest_1_st_a', - 'sisyfos_source_Guest_2_st_a', - 'sisyfos_source_Guest_3_st_a', - 'sisyfos_source_Guest_4_st_a' + { value: 'sisyfos_source_Host_1_st_a', label: 'Host1' }, + { value: 'sisyfos_source_Host_2_st_a', label: 'Host2' }, + { value: 'sisyfos_source_Guest_1_st_a', label: 'Guest1' }, + { value: 'sisyfos_source_Guest_2_st_a', label: 'Guest2' }, + { value: 'sisyfos_source_Guest_3_st_a', label: 'Guest3' }, + { value: 'sisyfos_source_Guest_4_st_a', label: 'Guest4' } ], SwitcherSource: { MixMinusDefault: 2, diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 82d180b2..a99ef31b 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -402,8 +402,8 @@ class GlobalAdLibPiecesGenerator { content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: this.config.studio.StudioMics.map((layer) => ({ - mappedLayer: layer, + channels: this.config.studio.StudioMics.map((studioMic) => ({ + mappedLayer: studioMic.value, isPgm: 1 })), overridePriority: 10 @@ -431,8 +431,8 @@ class GlobalAdLibPiecesGenerator { content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: this.config.studio.StudioMics.map((layer) => ({ - mappedLayer: layer, + channels: this.config.studio.StudioMics.map((studioMic) => ({ + mappedLayer: studioMic.value, isPgm: 0 })), overridePriority: 10 diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index 793f29c3..692b435c 100644 --- a/src/tv2_afvd_studio/helpers/config.ts +++ b/src/tv2_afvd_studio/helpers/config.ts @@ -1,6 +1,7 @@ import { IBlueprintConfig, ICommonContext } from 'blueprints-integration' import { ProcessedStudioConfig, + StudioMic, TableConfigItemDSK, TableConfigItemSourceMapping, TableConfigItemSourceMappingWithSisyfos, @@ -20,7 +21,7 @@ export interface StudioConfig extends TV2StudioConfigBase { SourcesReplay: TableConfigItemSourceMappingWithSisyfos[] ABMediaPlayers: TableConfigItemSourceMapping[] ABPlaybackDebugLogging: boolean - StudioMics: string[] + StudioMics: StudioMic[] SwitcherSource: { SplitArtFill: number // Atem MP1 Fill SplitArtKey: number // Atem MP1 Key diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index ac0ad6ae..d25621bb 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -127,8 +127,8 @@ function getGlobalAdLibPiecesOfftube(context: ShowStyleContext ({ - mappedLayer: layer, + channels: context.config.studio.StudioMics.map((studioMic) => ({ + mappedLayer: studioMic.value, isPgm: 1 })), overridePriority: 10 @@ -157,8 +157,8 @@ function getGlobalAdLibPiecesOfftube(context: ShowStyleContext ({ - mappedLayer: layer, + channels: context.config.studio.StudioMics.map((studioMic) => ({ + mappedLayer: studioMic.value, isPgm: 0 })), overridePriority: 10 From 71c981c8260fd1f28d147b8dafaa7065834c6f0d Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Fri, 14 Apr 2023 12:36:59 +0200 Subject: [PATCH 86/86] Revert "SOF-1419 StudioMics now uses new datatype" This reverts commit 3283eeb70ade3f5324081f06453b831e0dafbef0. --- src/tv2-common/blueprintConfig.ts | 7 +------ src/tv2-common/helpers/sisyfos.ts | 4 ++-- src/tv2_afvd_showstyle/__tests__/configs.ts | 12 ++++++------ src/tv2_afvd_showstyle/getRundown.ts | 8 ++++---- src/tv2_afvd_studio/helpers/config.ts | 3 +-- src/tv2_offtube_showstyle/getRundown.ts | 8 ++++---- 6 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index c31cc821..64483d27 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -73,11 +73,6 @@ export interface ProcessedStudioConfig { dsk: TableConfigItemDSK[] } -export interface StudioMic { - label: string - value: string -} - export interface TV2StudioConfigBase { MaximumPartDuration: number DefaultPartDuration: number @@ -125,7 +120,7 @@ export interface TV2StudioConfigBase { Dip: number } AtemSettings: {} - StudioMics: StudioMic[] + StudioMics: string[] SourcesRM: TableConfigItemSourceMappingWithSisyfos[] SourcesFeed: TableConfigItemSourceMappingWithSisyfos[] SourcesCam: TableConfigItemSourceMappingWithSisyfos[] diff --git a/src/tv2-common/helpers/sisyfos.ts b/src/tv2-common/helpers/sisyfos.ts index 7f903c39..b8909f1d 100644 --- a/src/tv2-common/helpers/sisyfos.ts +++ b/src/tv2-common/helpers/sisyfos.ts @@ -124,9 +124,9 @@ function getStudioMicsTimelineObj( timelineEnable: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosChannels { const studioMicsChannels: TSR.TimelineObjSisyfosChannels['content']['channels'] = [] - config.studio.StudioMics.forEach((studioMic) => { + config.studio.StudioMics.forEach((layer) => { studioMicsChannels.push({ - mappedLayer: studioMic.value, + mappedLayer: layer, isPgm: 1 }) }) diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index 58ae66fa..a717fbc1 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -95,12 +95,12 @@ export const defaultStudioConfig: StudioConfig = { SourcesFeed: prepareConfig('1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,10:10', 'SourcesFeed', false, true), SourcesReplay: prepareConfig('EVS 1:5,EVS 2:5,EPSIO:5', 'SourcesDelayedPlayback', false), StudioMics: [ - { value: 'sisyfos_source_Host_1_st_a', label: 'Host1' }, - { value: 'sisyfos_source_Host_2_st_a', label: 'Host2' }, - { value: 'sisyfos_source_Guest_1_st_a', label: 'Guest1' }, - { value: 'sisyfos_source_Guest_2_st_a', label: 'Guest2' }, - { value: 'sisyfos_source_Guest_3_st_a', label: 'Guest3' }, - { value: 'sisyfos_source_Guest_4_st_a', label: 'Guest4' } + 'sisyfos_source_Host_1_st_a', + 'sisyfos_source_Host_2_st_a', + 'sisyfos_source_Guest_1_st_a', + 'sisyfos_source_Guest_2_st_a', + 'sisyfos_source_Guest_3_st_a', + 'sisyfos_source_Guest_4_st_a' ], SwitcherSource: { MixMinusDefault: 2, diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index a99ef31b..82d180b2 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -402,8 +402,8 @@ class GlobalAdLibPiecesGenerator { content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: this.config.studio.StudioMics.map((studioMic) => ({ - mappedLayer: studioMic.value, + channels: this.config.studio.StudioMics.map((layer) => ({ + mappedLayer: layer, isPgm: 1 })), overridePriority: 10 @@ -431,8 +431,8 @@ class GlobalAdLibPiecesGenerator { content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: this.config.studio.StudioMics.map((studioMic) => ({ - mappedLayer: studioMic.value, + channels: this.config.studio.StudioMics.map((layer) => ({ + mappedLayer: layer, isPgm: 0 })), overridePriority: 10 diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index 692b435c..793f29c3 100644 --- a/src/tv2_afvd_studio/helpers/config.ts +++ b/src/tv2_afvd_studio/helpers/config.ts @@ -1,7 +1,6 @@ import { IBlueprintConfig, ICommonContext } from 'blueprints-integration' import { ProcessedStudioConfig, - StudioMic, TableConfigItemDSK, TableConfigItemSourceMapping, TableConfigItemSourceMappingWithSisyfos, @@ -21,7 +20,7 @@ export interface StudioConfig extends TV2StudioConfigBase { SourcesReplay: TableConfigItemSourceMappingWithSisyfos[] ABMediaPlayers: TableConfigItemSourceMapping[] ABPlaybackDebugLogging: boolean - StudioMics: StudioMic[] + StudioMics: string[] SwitcherSource: { SplitArtFill: number // Atem MP1 Fill SplitArtKey: number // Atem MP1 Key diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index d25621bb..ac0ad6ae 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -127,8 +127,8 @@ function getGlobalAdLibPiecesOfftube(context: ShowStyleContext ({ - mappedLayer: studioMic.value, + channels: context.config.studio.StudioMics.map((layer) => ({ + mappedLayer: layer, isPgm: 1 })), overridePriority: 10 @@ -157,8 +157,8 @@ function getGlobalAdLibPiecesOfftube(context: ShowStyleContext ({ - mappedLayer: studioMic.value, + channels: context.config.studio.StudioMics.map((layer) => ({ + mappedLayer: layer, isPgm: 0 })), overridePriority: 10