From f78e856dd4a64c9cd162e9c2bb42e049035f7a67 Mon Sep 17 00:00:00 2001 From: ianshade Date: Mon, 22 Nov 2021 11:02:11 +0100 Subject: [PATCH 001/184] chore(release): 1.6.9 --- CHANGELOG.md | 16 ++++++++++++++++ package.json | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b08a31705..8777bef3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,22 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [1.6.9](https://github.com/olzzon/tv2-sofie-blueprints-inews/compare/v1.6.8...v1.6.9) (2021-11-22) + + +### Bug Fixes + +* apply delayed enable to wall graphics when part has preroll ([b368090](https://github.com/olzzon/tv2-sofie-blueprints-inews/commit/b368090f7b18ae01c738eb1fd473186e02118448)) +* apply effekt part properties before evaluating cues ([a235267](https://github.com/olzzon/tv2-sofie-blueprints-inews/commit/a2352671f7e1b21362ebf0c1ba87c99cf11a2ffc)) +* apply full and dve part properties before evaluating cues ([cfd5ee5](https://github.com/olzzon/tv2-sofie-blueprints-inews/commit/cfd5ee585b2ad7a1ba289245fec9d51c85f654a9)) +* apply full graphic properties only when contains a full ([c1d0fa8](https://github.com/olzzon/tv2-sofie-blueprints-inews/commit/c1d0fa8d7fffbc8c753fa115d0ec3df0c78c3f71)) +* Apply jingle part properties before evaluating cues ([e187f60](https://github.com/olzzon/tv2-sofie-blueprints-inews/commit/e187f608706ad71a164a92bcc8de7b8d08fae2d7)) +* create parent class for VOs ([784df52](https://github.com/olzzon/tv2-sofie-blueprints-inews/commit/784df52cafd21734036593bedfe28fab13904bb0)) +* don't update infinites from previous part ([e2bfa83](https://github.com/olzzon/tv2-sofie-blueprints-inews/commit/e2bfa83cebd774bf5bb6496ef8408fcb10065dc9)) +* set enable for pilots targeting wall ([22a2a4c](https://github.com/olzzon/tv2-sofie-blueprints-inews/commit/22a2a4c7c2c26cba3bd52ee21a5d411e59d82d53)) +* set higher priority on WALL graphics to make them last during prerollDuration ([de6dbca](https://github.com/olzzon/tv2-sofie-blueprints-inews/commit/de6dbca531faf6a2af4eea994dd0625ac04e2819)) +* undefined properties not synced ([cf44d4e](https://github.com/olzzon/tv2-sofie-blueprints-inews/commit/cf44d4eac88f19e8eeda0de086f2d5d6d145e60f)) + ### [1.6.8](https://github.com/olzzon/tv2-sofie-blueprints-inews/compare/v1.6.7...v1.6.8) (2021-08-18) diff --git a/package.json b/package.json index b9cd9ec53..22aad3e47 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tv2-sofie-blueprints-inews", - "version": "1.6.8", + "version": "1.6.9", "repository": "https://github.com/olzzon/tv2-sofie-blueprints-inews", "license": "MIT", "private": true, From 253ef1adcc95250b914ed6a874f4869a20b4fe00 Mon Sep 17 00:00:00 2001 From: Jesper Leerberg Madsen Date: Mon, 22 Nov 2021 13:08:04 +0100 Subject: [PATCH 002/184] fix: fixed blueprint dependency @sofie-automation/blueprints-integration to use tv2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 22aad3e47..95410285b 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "webpack-cli": "^3.1.2" }, "dependencies": { - "@sofie-automation/blueprints-integration": "https://github.com/olzzon/tv-automation-server-core.git#dist_blueprints_integration20210525_2", + "@sofie-automation/blueprints-integration": "https://github.com/tv2/tv-automation-server-core.git#dist_blueprints_integration20210525_2", "underscore": "^1.12.1" } } From b4fdd4075d60556b6617e9b32ae53b0587f05b6c Mon Sep 17 00:00:00 2001 From: Jesper Leerberg Madsen Date: Mon, 22 Nov 2021 13:14:06 +0100 Subject: [PATCH 003/184] fix: yarn.lock --- yarn.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index ff3d21e46..f85071521 100644 --- a/yarn.lock +++ b/yarn.lock @@ -287,9 +287,9 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@sofie-automation/blueprints-integration@https://github.com/olzzon/tv-automation-server-core.git#dist_blueprints_integration20210525_2": +"@sofie-automation/blueprints-integration@https://github.com/tv2/tv-automation-server-core.git#dist_blueprints_integration20210525_2": version "1.16.1" - resolved "https://github.com/olzzon/tv-automation-server-core.git#e98dcba29abde53f6e4f47571776407bcb7f7517" + resolved "https://github.com/tv2/tv-automation-server-core.git#e98dcba29abde53f6e4f47571776407bcb7f7517" dependencies: moment "2.29.1" timeline-state-resolver-types "git+https://github.com/olzzon/tv-automation-state-timeline-resolver#dist_types20210323_1" From 5473ad5e3f50b3d0a1c03f91569c0eda33eadf43 Mon Sep 17 00:00:00 2001 From: ianshade Date: Mon, 22 Nov 2021 21:10:25 +0100 Subject: [PATCH 004/184] fix: exception in remapTableColumnValues migration return false if there's no table, otherwise it will try to migrate and throw on table.map() inside remapTableColumnValuesInner --- src/tv2_offtube_showstyle/migrations/util.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/tv2_offtube_showstyle/migrations/util.ts b/src/tv2_offtube_showstyle/migrations/util.ts index faa763198..fcbafa608 100644 --- a/src/tv2_offtube_showstyle/migrations/util.ts +++ b/src/tv2_offtube_showstyle/migrations/util.ts @@ -153,12 +153,8 @@ export function remapTableColumnValues( validate: (context: MigrationContextShowStyle) => { const table = context.getBaseConfig(tableId) as TableConfigItemValue | undefined - if (!table) { - return `Table "${tableId}" does not exist` - } - - if (!table.length) { - // No values, nothing to remap + if (!table || !table.length) { + // No table or no values, nothing to remap return false } From ba2e28ea862dec6415a75ae469ae09de07af79f8 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 23 Nov 2021 12:03:51 +0100 Subject: [PATCH 005/184] chore: remove pre-action-triggers code also use blueprints-integration from @tv2media to make yarn link work --- config/webpack.config.js | 4 +- package.json | 2 +- scripts/bundle.ts | 4 +- src/__mocks__/context.ts | 2 +- .../__tests__/rundownDuration.spec.ts | 2 +- src/inews-mixins/playlist.ts | 2 +- src/inews-mixins/rundownDuration.ts | 2 +- src/tv2-common/__tests__/frame-time.spec.ts | 2 +- .../__tests__/transition-from-string.spec.ts | 2 +- src/tv2-common/__tests__/util.spec.ts | 2 +- src/tv2-common/actions/actionTypes.ts | 2 +- src/tv2-common/actions/context.ts | 2 +- src/tv2-common/actions/executeAction.ts | 2 +- src/tv2-common/blueprintConfig.ts | 2 +- src/tv2-common/content/dve.ts | 2 +- src/tv2-common/content/jingle.ts | 2 +- src/tv2-common/content/server.ts | 2 +- src/tv2-common/cueTiming.ts | 2 +- src/tv2-common/cues/ekstern.ts | 2 +- src/tv2-common/cues/lyd.ts | 2 +- src/tv2-common/cues/mixMinus.ts | 2 +- src/tv2-common/evaluateCues.ts | 2 +- src/tv2-common/getSegment.ts | 2 +- src/tv2-common/helpers/abPlayback.ts | 2 +- src/tv2-common/helpers/dsk.ts | 2 +- .../helpers/graphics/caspar/index.ts | 2 +- .../helpers/graphics/design/index.ts | 2 +- src/tv2-common/helpers/graphics/index.ts | 2 +- .../helpers/graphics/internal/index.ts | 2 +- .../helpers/graphics/pilot/index.ts | 2 +- src/tv2-common/helpers/graphics/timing.ts | 2 +- src/tv2-common/helpers/graphics/viz/index.ts | 2 +- src/tv2-common/helpers/rundownAdLibActions.ts | 2 +- src/tv2-common/helpers/sisyfos.ts | 2 +- src/tv2-common/helpers/translation.ts | 2 +- .../converters/__tests__/body-parser.spec.ts | 2 +- .../converters/__tests__/cue-parser.spec.ts | 2 +- src/tv2-common/jinglePartProperties.ts | 2 +- src/tv2-common/layers/sourceLayers.ts | 7 +- src/tv2-common/layers/timelineLayers.ts | 2 +- src/tv2-common/migrations/addKeepAudio.ts | 6 +- .../forceSourceLayerToDefaultsBase.ts | 6 +- src/tv2-common/migrations/index.ts | 2 +- .../migrations/manifestWithMediaFlow.ts | 2 +- .../migrations/moveSourcesToTable.ts | 6 +- src/tv2-common/migrations/shortcuts.ts | 10 +- src/tv2-common/migrations/sourceManifest.ts | 2 +- src/tv2-common/migrations/transitions.ts | 2 +- src/tv2-common/onTimelineGenerate.ts | 2 +- src/tv2-common/parts/effekt.ts | 2 +- src/tv2-common/parts/invalid.ts | 2 +- src/tv2-common/parts/kam.ts | 2 +- src/tv2-common/parts/server.ts | 2 +- src/tv2-common/pieces/adlibServer.ts | 2 +- src/tv2-common/pieces/script.ts | 2 +- src/tv2-common/sources.ts | 2 +- src/tv2-common/transitionFromString.ts | 2 +- src/tv2-common/transitionSettings.ts | 2 +- src/tv2-common/updatePolicies/adlibs.ts | 2 +- .../updatePolicies/partProperties.ts | 2 +- src/tv2-common/updatePolicies/pieces.ts | 2 +- .../shouldRemoveOrphanedPartInstance.ts | 2 +- .../syncIngestUpdateToPartInstance.ts | 2 +- src/tv2-common/util.ts | 2 +- .../__tests__/actions.spec.ts | 2 +- .../__tests__/addScript.spec.ts | 2 +- .../__tests__/baseline.spec.ts | 2 +- .../__tests__/blueprint.spec.ts | 2 +- .../__tests__/layers-check.ts | 2 +- .../__tests__/regressions.spec.ts | 2 +- .../__tests__/rundown_story_exception.spec.ts | 6 +- .../syncIngestChangesToPartInstance.spec.ts | 2 +- .../__tests__/transitions.spec.ts | 2 +- src/tv2_afvd_showstyle/actions.ts | 2 +- src/tv2_afvd_showstyle/config-manifests.ts | 2 +- src/tv2_afvd_showstyle/getRundown.ts | 2 +- src/tv2_afvd_showstyle/getSegment.ts | 2 +- src/tv2_afvd_showstyle/helpers/config.ts | 2 +- src/tv2_afvd_showstyle/helpers/content/dve.ts | 2 +- .../pieces/__tests__/grafikViz.spec.ts | 2 +- .../helpers/pieces/__tests__/lyd.spec.ts | 2 +- .../helpers/pieces/__tests__/telefon.spec.ts | 2 +- .../helpers/pieces/adlib.ts | 2 +- .../helpers/pieces/clearGrafiks.ts | 2 +- .../helpers/pieces/design.ts | 2 +- src/tv2_afvd_showstyle/helpers/pieces/dve.ts | 2 +- .../helpers/pieces/ekstern.ts | 2 +- .../helpers/pieces/evaluateCues.ts | 2 +- .../helpers/pieces/graphic.ts | 2 +- .../helpers/pieces/graphicBackgroundLoop.ts | 2 +- .../helpers/pieces/graphicPilot.ts | 2 +- .../helpers/pieces/jingle.ts | 2 +- .../helpers/pieces/routing.ts | 2 +- .../helpers/pieces/telefon.ts | 2 +- src/tv2_afvd_showstyle/helpers/studio.ts | 2 +- src/tv2_afvd_showstyle/helpers/time.ts | 2 +- src/tv2_afvd_showstyle/index.ts | 2 +- src/tv2_afvd_showstyle/migrations/index.ts | 2 +- .../migrations/outputlayer-defaults.ts | 2 +- .../migrations/sourcelayer-defaults.ts | 247 +++++++----------- src/tv2_afvd_showstyle/migrations/util.ts | 2 +- .../migrations/variants-defaults.ts | 2 +- src/tv2_afvd_showstyle/parts/cueonly.ts | 2 +- src/tv2_afvd_showstyle/parts/effekt.ts | 2 +- src/tv2_afvd_showstyle/parts/evs.ts | 2 +- src/tv2_afvd_showstyle/parts/grafik.ts | 2 +- src/tv2_afvd_showstyle/parts/intro.ts | 2 +- src/tv2_afvd_showstyle/parts/kam.ts | 2 +- src/tv2_afvd_showstyle/parts/live.ts | 2 +- src/tv2_afvd_showstyle/parts/server.ts | 2 +- src/tv2_afvd_showstyle/parts/teknik.ts | 2 +- src/tv2_afvd_showstyle/parts/unknown.ts | 2 +- .../postProcessTimelineObjects.ts | 2 +- .../syncIngestUpdateToPartInstance.ts | 2 +- .../__tests__/graphics.spec.ts | 2 +- src/tv2_afvd_studio/config-manifests.ts | 2 +- src/tv2_afvd_studio/getBaseline.ts | 2 +- src/tv2_afvd_studio/getShowStyleId.ts | 2 +- src/tv2_afvd_studio/helpers/config.ts | 2 +- src/tv2_afvd_studio/helpers/sources.ts | 2 +- src/tv2_afvd_studio/index.ts | 2 +- src/tv2_afvd_studio/migrations/devices.ts | 2 +- src/tv2_afvd_studio/migrations/index.ts | 2 +- .../migrations/mappings-defaults.ts | 2 +- src/tv2_afvd_studio/migrations/util.ts | 2 +- src/tv2_afvd_studio/onTimelineGenerate.ts | 2 +- .../__tests__/actions.spec.ts | 2 +- src/tv2_offtube_showstyle/actions.ts | 2 +- src/tv2_offtube_showstyle/config-manifests.ts | 2 +- .../content/OfftubeDVEContent.ts | 2 +- .../cues/OfftubeAdlib.ts | 2 +- src/tv2_offtube_showstyle/cues/OfftubeDVE.ts | 2 +- .../cues/OfftubeEkstern.ts | 2 +- .../cues/OfftubeGraphicBackgroundLoop.ts | 2 +- .../cues/OfftubeGraphicDesign.ts | 2 +- .../cues/OfftubeGraphics.ts | 2 +- .../cues/OfftubeJingle.ts | 2 +- .../cues/OfftubePgmClean.ts | 2 +- src/tv2_offtube_showstyle/getRundown.ts | 2 +- src/tv2_offtube_showstyle/getSegment.ts | 2 +- .../helpers/EvaluateCues.ts | 2 +- src/tv2_offtube_showstyle/helpers/config.ts | 2 +- src/tv2_offtube_showstyle/index.ts | 2 +- src/tv2_offtube_showstyle/migrations/index.ts | 2 +- .../migrations/outputlayer-defaults.ts | 2 +- .../migrations/sourcelayer-defaults.ts | 162 +----------- src/tv2_offtube_showstyle/migrations/util.ts | 2 +- .../migrations/variants-defaults.ts | 2 +- .../onTimelineGenerate.ts | 2 +- src/tv2_offtube_showstyle/parts/OfftubeDVE.ts | 2 +- .../parts/OfftubeEffekt.ts | 2 +- .../parts/OfftubeGrafik.ts | 2 +- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 2 +- .../parts/OfftubeServer.ts | 2 +- .../parts/OfftubeUnknown.ts | 2 +- .../postProcessTimelineObjects.ts | 2 +- .../syncIngestUpdateToPartInstances.ts | 2 +- src/tv2_offtube_studio/config-manifests.ts | 2 +- src/tv2_offtube_studio/getBaseline.ts | 2 +- src/tv2_offtube_studio/getShowStyleId.ts | 2 +- src/tv2_offtube_studio/helpers/config.ts | 2 +- src/tv2_offtube_studio/helpers/sources.ts | 2 +- src/tv2_offtube_studio/index.ts | 2 +- src/tv2_offtube_studio/migrations/devices.ts | 2 +- src/tv2_offtube_studio/migrations/index.ts | 2 +- .../migrations/mappings-defaults.ts | 2 +- src/tv2_offtube_studio/migrations/util.ts | 2 +- src/tv2_system/index.ts | 5 +- yarn.lock | 2 +- 169 files changed, 273 insertions(+), 506 deletions(-) diff --git a/config/webpack.config.js b/config/webpack.config.js index e5a66014d..afd205eee 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -20,9 +20,9 @@ module.exports = env => { versionStr = () => JSON.stringify(pkg.version + '+dev-' + moment().format('YYYYMMDD-HHmm')) } - let versionIntegration = pkg.dependencies['@sofie-automation/blueprints-integration'] + let versionIntegration = pkg.dependencies['@tv2media/blueprints-integration'] - if (!versionIntegration) throw Error('@sofie-automation/blueprints-integration version missing!') + if (!versionIntegration) throw Error('@tv2media/blueprints-integration version missing!') // versionTSRTypes = versionTSRTypes.replace(/[^\d.]/g, '') || '0.0.0' // versionIntegration = versionIntegration.replace(/[^\d.]/g, '') || '0.0.0' diff --git a/package.json b/package.json index ab30629ce..e450cb5de 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "webpack-cli": "^3.1.2" }, "dependencies": { - "@sofie-automation/blueprints-integration": "npm:@tv2media/blueprints-integration@1.37.0-rc19", + "@tv2media/blueprints-integration": "1.37.0-rc19", "underscore": "^1.12.1" } } \ No newline at end of file diff --git a/scripts/bundle.ts b/scripts/bundle.ts index d1b36f261..a65782e18 100644 --- a/scripts/bundle.ts +++ b/scripts/bundle.ts @@ -1,7 +1,7 @@ +import { BlueprintManifestSet } from '@tv2media/blueprints-integration' import * as fs from 'fs' -import * as util from 'util' import * as _ from 'underscore' -import { BlueprintManifestSet } from '@sofie-automation/blueprints-integration' +import * as util from 'util' const { BlueprintBundles } = require('./blueprint-map') const readFile = util.promisify(fs.readFile) diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index a2350230c..75ff5ef2f 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -25,7 +25,7 @@ import { OmitId, PackageInfo, PieceLifespan -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import { NoteType } from 'tv2-constants' diff --git a/src/inews-mixins/__tests__/rundownDuration.spec.ts b/src/inews-mixins/__tests__/rundownDuration.spec.ts index 4c3d4bb82..81b462535 100644 --- a/src/inews-mixins/__tests__/rundownDuration.spec.ts +++ b/src/inews-mixins/__tests__/rundownDuration.spec.ts @@ -1,4 +1,4 @@ -import { IngestSegment } from '@sofie-automation/blueprints-integration' +import { IngestSegment } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import { getRundownDuration } from '../rundownDuration' diff --git a/src/inews-mixins/playlist.ts b/src/inews-mixins/playlist.ts index ad4792294..bab5ec01e 100644 --- a/src/inews-mixins/playlist.ts +++ b/src/inews-mixins/playlist.ts @@ -12,7 +12,7 @@ import { RundownPlaylistTiming, ShowStyleBlueprintManifest, StudioBlueprintManifest -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { assertUnreachable, literal, TimeFromINewsField } from 'tv2-common' import { getRundownDuration } from './rundownDuration' diff --git a/src/inews-mixins/rundownDuration.ts b/src/inews-mixins/rundownDuration.ts index e0726a5df..6340ddb02 100644 --- a/src/inews-mixins/rundownDuration.ts +++ b/src/inews-mixins/rundownDuration.ts @@ -1,4 +1,4 @@ -import { IngestSegment } from '@sofie-automation/blueprints-integration' +import { IngestSegment } from '@tv2media/blueprints-integration' import { INewsPayload, TimeFromINewsField } from 'tv2-common' export function getRundownDuration(segments: IngestSegment[]) { diff --git a/src/tv2-common/__tests__/frame-time.spec.ts b/src/tv2-common/__tests__/frame-time.spec.ts index b7ca40495..f0f630091 100644 --- a/src/tv2-common/__tests__/frame-time.spec.ts +++ b/src/tv2-common/__tests__/frame-time.spec.ts @@ -1,4 +1,4 @@ -import { IBlueprintPiece, PieceLifespan } from '@sofie-automation/blueprints-integration' +import { IBlueprintPiece, PieceLifespan } from '@tv2media/blueprints-integration' import { CueType } from 'tv2-constants' import { CreateTiming } from '../cueTiming' import { CueDefinitionEkstern } from '../inewsConversion/converters/ParseCue' diff --git a/src/tv2-common/__tests__/transition-from-string.spec.ts b/src/tv2-common/__tests__/transition-from-string.spec.ts index d5fb90b1f..614abde1a 100644 --- a/src/tv2-common/__tests__/transition-from-string.spec.ts +++ b/src/tv2-common/__tests__/transition-from-string.spec.ts @@ -1,4 +1,4 @@ -import { TSR } from '@sofie-automation/blueprints-integration' +import { TSR } from '@tv2media/blueprints-integration' import { TransitionFromString } from '../transitionFromString' describe('Transition From String', () => { diff --git a/src/tv2-common/__tests__/util.spec.ts b/src/tv2-common/__tests__/util.spec.ts index 61945d750..48989ddd3 100644 --- a/src/tv2-common/__tests__/util.spec.ts +++ b/src/tv2-common/__tests__/util.spec.ts @@ -1,4 +1,4 @@ -import { PieceLifespan } from '@sofie-automation/blueprints-integration' +import { PieceLifespan } from '@tv2media/blueprints-integration' import { SharedOutputLayers } from 'tv2-constants' import { assertUnreachable, isAdLibPiece } from '../util' diff --git a/src/tv2-common/actions/actionTypes.ts b/src/tv2-common/actions/actionTypes.ts index 1ba7b0b8e..307070ec2 100644 --- a/src/tv2-common/actions/actionTypes.ts +++ b/src/tv2-common/actions/actionTypes.ts @@ -1,4 +1,4 @@ -import { SourceLayerType } from '@sofie-automation/blueprints-integration' +import { SourceLayerType } from '@tv2media/blueprints-integration' import { AdlibActionType } from 'tv2-constants' import { DVEConfigInput } from '../helpers' import { CueDefinitionDVE, PartDefinition } from '../inewsConversion' diff --git a/src/tv2-common/actions/context.ts b/src/tv2-common/actions/context.ts index 5a6b89238..a45f1274c 100644 --- a/src/tv2-common/actions/context.ts +++ b/src/tv2-common/actions/context.ts @@ -9,7 +9,7 @@ import { IBlueprintPieceInstance, IBlueprintResolvedPieceInstance, PackageInfo -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { literal, PartMetaData } from 'tv2-common' export interface ITV2ActionExecutionContext extends IActionExecutionContext { diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 623cb05b6..37fbd300f 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -17,7 +17,7 @@ import { TSR, VTContent, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { ActionClearGraphics, ActionCommentatorSelectDVE, diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 80818b703..061ba4602 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -1,4 +1,4 @@ -import { TableConfigItemValue } from '@sofie-automation/blueprints-integration' +import { TableConfigItemValue } from '@tv2media/blueprints-integration' import { TableConfigItemDSK, TableConfigItemSourceMappingWithSisyfos, diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 2cae91994..75b080e07 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -10,7 +10,7 @@ import { TSR, VTContent, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { createEmptyObject, CueDefinitionDVE, diff --git a/src/tv2-common/content/jingle.ts b/src/tv2-common/content/jingle.ts index 95a8a3fa5..6af2bb31c 100644 --- a/src/tv2-common/content/jingle.ts +++ b/src/tv2-common/content/jingle.ts @@ -1,4 +1,4 @@ -import { TimelineObjectCoreExt, TSR, VTContent, WithTimeline } from '@sofie-automation/blueprints-integration' +import { TimelineObjectCoreExt, TSR, VTContent, WithTimeline } from '@tv2media/blueprints-integration' import { TimeFromFrames } from 'tv2-common' import { TV2BlueprintConfig, TV2BlueprintConfigBase, TV2StudioConfigBase } from '../blueprintConfig' import { EnableDSK, FindDSKJingle } from '../helpers' diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index eb5d7715e..2be58b220 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -4,7 +4,7 @@ import { TSR, VTContent, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddParentClass, GetSisyfosTimelineObjForCamera, diff --git a/src/tv2-common/cueTiming.ts b/src/tv2-common/cueTiming.ts index 0626fbc3d..ee935c288 100644 --- a/src/tv2-common/cueTiming.ts +++ b/src/tv2-common/cueTiming.ts @@ -1,6 +1,6 @@ import { CueDefinition, CueDefinitionBase, CueTime } from './inewsConversion/converters/ParseCue' -import { IBlueprintAdLibPiece, IBlueprintPiece, PieceLifespan } from '@sofie-automation/blueprints-integration' +import { IBlueprintAdLibPiece, IBlueprintPiece, PieceLifespan } from '@tv2media/blueprints-integration' import { TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' const FRAME_TIME = 1000 / 25 // TODO: This should be pulled from config. diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index e47399c58..a5b61485b 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -9,7 +9,7 @@ import { TimelineObjectCoreExt, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddParentClass, createEmptyObject, diff --git a/src/tv2-common/cues/lyd.ts b/src/tv2-common/cues/lyd.ts index cc733126b..a4a8e7e35 100644 --- a/src/tv2-common/cues/lyd.ts +++ b/src/tv2-common/cues/lyd.ts @@ -8,7 +8,7 @@ import { TimelineObjectCoreExt, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CreateTimingEnable, CueDefinitionLYD, literal, PartDefinition, TimeFromFrames } from 'tv2-common' import { AbstractLLayer, diff --git a/src/tv2-common/cues/mixMinus.ts b/src/tv2-common/cues/mixMinus.ts index c8a8b574e..85293c9e8 100644 --- a/src/tv2-common/cues/mixMinus.ts +++ b/src/tv2-common/cues/mixMinus.ts @@ -6,7 +6,7 @@ import { TimelineObjectCoreExt, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CueDefinitionMixMinus, FindSourceByName, literal, PartDefinition } from 'tv2-common' import { ControlClasses, SharedATEMLLayer, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' import { TV2BlueprintConfig } from '../blueprintConfig' diff --git a/src/tv2-common/evaluateCues.ts b/src/tv2-common/evaluateCues.ts index 9d5b7b138..6136660c3 100644 --- a/src/tv2-common/evaluateCues.ts +++ b/src/tv2-common/evaluateCues.ts @@ -6,7 +6,7 @@ import { IBlueprintPiece, ISegmentUserContext, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { assertUnreachable, CueDefinition, diff --git a/src/tv2-common/getSegment.ts b/src/tv2-common/getSegment.ts index 704bc431a..a559041ca 100644 --- a/src/tv2-common/getSegment.ts +++ b/src/tv2-common/getSegment.ts @@ -4,7 +4,7 @@ import { IBlueprintSegment, IngestSegment, IShowStyleUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { assertUnreachable, GetNextPartCue, diff --git a/src/tv2-common/helpers/abPlayback.ts b/src/tv2-common/helpers/abPlayback.ts index 8d5457053..c23c65d10 100644 --- a/src/tv2-common/helpers/abPlayback.ts +++ b/src/tv2-common/helpers/abPlayback.ts @@ -3,7 +3,7 @@ import { ITimelineEventContext, OnGenerateTimelineObj, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AbstractLLayer, MEDIA_PLAYER_AUTO, MediaPlayerClaimType } from 'tv2-constants' import * as _ from 'underscore' import { TV2BlueprintConfigBase, TV2StudioConfigBase } from '../blueprintConfig' diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index a969ea8cc..7d2d7e4ad 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -5,7 +5,7 @@ import { PieceLifespan, TableConfigItemValue, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AtemLLayerDSK, literal, SourceLayerAtemDSK } from 'tv2-common' import { AdlibTags, DSKRoles, SharedOutputLayers } from 'tv2-constants' import { ATEMModel } from '../../types/atem' diff --git a/src/tv2-common/helpers/graphics/caspar/index.ts b/src/tv2-common/helpers/graphics/caspar/index.ts index de727da34..beca5d326 100644 --- a/src/tv2-common/helpers/graphics/caspar/index.ts +++ b/src/tv2-common/helpers/graphics/caspar/index.ts @@ -7,7 +7,7 @@ import { IShowStyleUserContext, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CueDefinitionGraphic, GraphicInternal, diff --git a/src/tv2-common/helpers/graphics/design/index.ts b/src/tv2-common/helpers/graphics/design/index.ts index 255657936..8ae3e7a31 100644 --- a/src/tv2-common/helpers/graphics/design/index.ts +++ b/src/tv2-common/helpers/graphics/design/index.ts @@ -7,7 +7,7 @@ import { PieceLifespan, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CalculateTime, CueDefinitionGraphicDesign, literal, TV2BlueprintConfig } from 'tv2-common' import { GraphicLLayer, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' diff --git a/src/tv2-common/helpers/graphics/index.ts b/src/tv2-common/helpers/graphics/index.ts index 0e5b96cb7..e505d322f 100644 --- a/src/tv2-common/helpers/graphics/index.ts +++ b/src/tv2-common/helpers/graphics/index.ts @@ -1,4 +1,4 @@ -import { IBlueprintPart, TSR } from '@sofie-automation/blueprints-integration' +import { IBlueprintPart, TSR } from '@tv2media/blueprints-integration' import { layerToHTMLGraphicSlot, literal, TV2BlueprintConfig } from 'tv2-common' import { GraphicLLayer } from 'tv2-constants' diff --git a/src/tv2-common/helpers/graphics/internal/index.ts b/src/tv2-common/helpers/graphics/internal/index.ts index 85fa1cd16..b49967874 100644 --- a/src/tv2-common/helpers/graphics/internal/index.ts +++ b/src/tv2-common/helpers/graphics/internal/index.ts @@ -6,7 +6,7 @@ import { IShowStyleUserContext, PieceLifespan, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CueDefinitionGraphic, GetDefaultOut, diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index 273065dbb..e4c43bf69 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -8,7 +8,7 @@ import { PieceLifespan, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { ActionSelectFullGrafik, CreateTimingGraphic, diff --git a/src/tv2-common/helpers/graphics/timing.ts b/src/tv2-common/helpers/graphics/timing.ts index a4b8fbfb4..f3c677adb 100644 --- a/src/tv2-common/helpers/graphics/timing.ts +++ b/src/tv2-common/helpers/graphics/timing.ts @@ -1,4 +1,4 @@ -import { IBlueprintPart, PieceLifespan, TSR } from '@sofie-automation/blueprints-integration' +import { IBlueprintPart, PieceLifespan, TSR } from '@tv2media/blueprints-integration' import { CalculateTime, CreateTimingEnable, diff --git a/src/tv2-common/helpers/graphics/viz/index.ts b/src/tv2-common/helpers/graphics/viz/index.ts index c8c59acc6..2ff240b38 100644 --- a/src/tv2-common/helpers/graphics/viz/index.ts +++ b/src/tv2-common/helpers/graphics/viz/index.ts @@ -5,7 +5,7 @@ import { IShowStyleUserContext, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CueDefinitionGraphic, GetEnableForGraphic, diff --git a/src/tv2-common/helpers/rundownAdLibActions.ts b/src/tv2-common/helpers/rundownAdLibActions.ts index 918e25acf..45412f590 100644 --- a/src/tv2-common/helpers/rundownAdLibActions.ts +++ b/src/tv2-common/helpers/rundownAdLibActions.ts @@ -1,4 +1,4 @@ -import { IBlueprintActionManifest } from '@sofie-automation/blueprints-integration' +import { IBlueprintActionManifest } from '@tv2media/blueprints-integration' import { ActionTakeWithTransition, ActionTakeWithTransitionVariant, diff --git a/src/tv2-common/helpers/sisyfos.ts b/src/tv2-common/helpers/sisyfos.ts index 1e63075f4..9ef5ce48b 100644 --- a/src/tv2-common/helpers/sisyfos.ts +++ b/src/tv2-common/helpers/sisyfos.ts @@ -1,6 +1,6 @@ import * as _ from 'underscore' -import { IStudioUserContext, SourceLayerType, Timeline, TSR } from '@sofie-automation/blueprints-integration' +import { IStudioUserContext, SourceLayerType, Timeline, TSR } from '@tv2media/blueprints-integration' import { FindSourceInfoStrict, SisyfosEVSSource, diff --git a/src/tv2-common/helpers/translation.ts b/src/tv2-common/helpers/translation.ts index 913494931..c1ac374d8 100644 --- a/src/tv2-common/helpers/translation.ts +++ b/src/tv2-common/helpers/translation.ts @@ -1,4 +1,4 @@ -import { ITranslatableMessage } from '@sofie-automation/blueprints-integration' +import { ITranslatableMessage } from '@tv2media/blueprints-integration' export function t(key: string, args?: { [k: string]: any }): ITranslatableMessage { return { 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 448c42579..42e8f9378 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts @@ -1,4 +1,4 @@ -import { IBlueprintRundownDB, PlaylistTimingType } from '@sofie-automation/blueprints-integration' +import { IBlueprintRundownDB, PlaylistTimingType } from '@tv2media/blueprints-integration' import { UnparsedCue } from 'tv2-common' import { CueType, PartType } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' 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 562e92c25..cbd0c1afe 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts @@ -1,4 +1,4 @@ -import { IBlueprintRundownDB, PlaylistTimingType } from '@sofie-automation/blueprints-integration' +import { IBlueprintRundownDB, PlaylistTimingType } from '@tv2media/blueprints-integration' import { CueType } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' import { defaultShowStyleConfig, defaultStudioConfig } from '../../../../tv2_afvd_showstyle/__tests__/configs' diff --git a/src/tv2-common/jinglePartProperties.ts b/src/tv2-common/jinglePartProperties.ts index c55420213..a39b21631 100644 --- a/src/tv2-common/jinglePartProperties.ts +++ b/src/tv2-common/jinglePartProperties.ts @@ -1,4 +1,4 @@ -import { IBlueprintPart, IShowStyleUserContext } from '@sofie-automation/blueprints-integration' +import { IBlueprintPart, IShowStyleUserContext } from '@tv2media/blueprints-integration' import { CueType } from 'tv2-constants' import { TableConfigItemBreakers, TV2BlueprintConfigBase, TV2StudioConfigBase } from './blueprintConfig' import { TimeFromFrames } from './frameTime' diff --git a/src/tv2-common/layers/sourceLayers.ts b/src/tv2-common/layers/sourceLayers.ts index 6f747b444..f4746d8f0 100644 --- a/src/tv2-common/layers/sourceLayers.ts +++ b/src/tv2-common/layers/sourceLayers.ts @@ -1,4 +1,4 @@ -import { ISourceLayer, SourceLayerType } from '@sofie-automation/blueprints-integration' +import { ISourceLayer, SourceLayerType } from '@tv2media/blueprints-integration' import { ATEMModel } from '../../types/atem' import { GetDSKCount } from '../helpers' import { literal } from '../util' @@ -21,11 +21,8 @@ function GetSourceLayerDefaultsForDSK(i: number): ISourceLayer { exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',', - assignHotkeysToGlobalAdlibs: true, + isClearable: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: true, allowDisable: false, diff --git a/src/tv2-common/layers/timelineLayers.ts b/src/tv2-common/layers/timelineLayers.ts index 98c9da1eb..80183b873 100644 --- a/src/tv2-common/layers/timelineLayers.ts +++ b/src/tv2-common/layers/timelineLayers.ts @@ -1,4 +1,4 @@ -import { BlueprintMapping, BlueprintMappings, LookaheadMode, TSR } from '@sofie-automation/blueprints-integration' +import { BlueprintMapping, BlueprintMappings, LookaheadMode, TSR } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import { ATEMModel } from '../../types/atem' import { GetDSKCount } from '../helpers' diff --git a/src/tv2-common/migrations/addKeepAudio.ts b/src/tv2-common/migrations/addKeepAudio.ts index 618109282..18dcdc472 100644 --- a/src/tv2-common/migrations/addKeepAudio.ts +++ b/src/tv2-common/migrations/addKeepAudio.ts @@ -1,8 +1,4 @@ -import { - MigrationContextStudio, - MigrationStepStudio, - TableConfigItemValue -} from '@sofie-automation/blueprints-integration' +import { MigrationContextStudio, MigrationStepStudio, TableConfigItemValue } from '@tv2media/blueprints-integration' import * as _ from 'underscore' import { literal } from '../util' diff --git a/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts b/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts index bea898eb4..dbcba7ca8 100644 --- a/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts +++ b/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts @@ -1,8 +1,4 @@ -import { - ISourceLayer, - MigrationContextShowStyle, - MigrationStepShowStyle -} from '@sofie-automation/blueprints-integration' +import { ISourceLayer, MigrationContextShowStyle, MigrationStepShowStyle } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import _ = require('underscore') diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index 0fb410c56..6529d30b8 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -5,7 +5,7 @@ import { MigrationContextStudio, MigrationStepShowStyle, MigrationStepStudio -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { TableConfigItemGFXTemplates } from 'tv2-common' import _ = require('underscore') import { literal } from '../util' diff --git a/src/tv2-common/migrations/manifestWithMediaFlow.ts b/src/tv2-common/migrations/manifestWithMediaFlow.ts index 8bf70e218..5f3d4f112 100644 --- a/src/tv2-common/migrations/manifestWithMediaFlow.ts +++ b/src/tv2-common/migrations/manifestWithMediaFlow.ts @@ -1,4 +1,4 @@ -import { ConfigManifestEntry, ConfigManifestEntryType } from '@sofie-automation/blueprints-integration' +import { ConfigManifestEntry, ConfigManifestEntryType } from '@tv2media/blueprints-integration' export function MakeConfigWithMediaFlow( name: string, diff --git a/src/tv2-common/migrations/moveSourcesToTable.ts b/src/tv2-common/migrations/moveSourcesToTable.ts index 5c98637c6..9533835cb 100644 --- a/src/tv2-common/migrations/moveSourcesToTable.ts +++ b/src/tv2-common/migrations/moveSourcesToTable.ts @@ -1,8 +1,4 @@ -import { - MigrationContextStudio, - MigrationStepStudio, - TableConfigItemValue -} from '@sofie-automation/blueprints-integration' +import { MigrationContextStudio, MigrationStepStudio, TableConfigItemValue } from '@tv2media/blueprints-integration' import { parseMapStr, TableConfigItemSourceMapping, TableConfigItemSourceMappingWithSisyfos } from 'tv2-common' import * as _ from 'underscore' import { literal } from '../util' diff --git a/src/tv2-common/migrations/shortcuts.ts b/src/tv2-common/migrations/shortcuts.ts index ecd10b5f0..b950ae5af 100644 --- a/src/tv2-common/migrations/shortcuts.ts +++ b/src/tv2-common/migrations/shortcuts.ts @@ -1,8 +1,4 @@ -import { - ISourceLayer, - MigrationContextShowStyle, - MigrationStepShowStyle -} from '@sofie-automation/blueprints-integration' +import { ISourceLayer, MigrationContextShowStyle, MigrationStepShowStyle } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' export function SetShortcutListMigrationStep( @@ -21,11 +17,13 @@ export function SetShortcutListMigrationStep( return `Sourcelayer ${sourceLayerId} does not exists` } + // @ts-ignore: old property return sourceLayer.activateKeyboardHotkeys !== newValue }, migrate: (context: MigrationContextShowStyle) => { const sourceLayer = context.getSourceLayer(sourceLayerId) as ISourceLayer + // @ts-ignore: old property sourceLayer.activateKeyboardHotkeys = newValue context.updateSourceLayer(sourceLayerId, sourceLayer) @@ -78,11 +76,13 @@ export function SetClearShortcutListTransitionStep( return `Sourcelayer ${sourceLayerId} does not exists` } + // @ts-ignore: old property return sourceLayer.clearKeyboardHotkey !== newValue }, migrate: (context: MigrationContextShowStyle) => { const sourceLayer = context.getSourceLayer(sourceLayerId) as ISourceLayer + // @ts-ignore: old property sourceLayer.clearKeyboardHotkey = newValue context.updateSourceLayer(sourceLayerId, sourceLayer) diff --git a/src/tv2-common/migrations/sourceManifest.ts b/src/tv2-common/migrations/sourceManifest.ts index b96856b39..3871bc4ad 100644 --- a/src/tv2-common/migrations/sourceManifest.ts +++ b/src/tv2-common/migrations/sourceManifest.ts @@ -1,4 +1,4 @@ -import { ConfigManifestEntryTable, ConfigManifestEntryType, TSR } from '@sofie-automation/blueprints-integration' +import { ConfigManifestEntryTable, ConfigManifestEntryType, TSR } from '@tv2media/blueprints-integration' import { literal } from '../util' export function MakeConfigForSources( diff --git a/src/tv2-common/migrations/transitions.ts b/src/tv2-common/migrations/transitions.ts index fd283db50..e7abce264 100644 --- a/src/tv2-common/migrations/transitions.ts +++ b/src/tv2-common/migrations/transitions.ts @@ -1,4 +1,4 @@ -import { MigrationContextShowStyle, MigrationStepShowStyle } from '@sofie-automation/blueprints-integration' +import { MigrationContextShowStyle, MigrationStepShowStyle } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import { TableConfigItemAdLibTransitions } from '../blueprintConfig' diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index 9527fdf74..05bc864c7 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -10,7 +10,7 @@ import { TimelineObjectCoreExt, TimelinePersistentState, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CasparPlayerClip } from 'tv2-common' import { AbstractLLayer, TallyTags } from 'tv2-constants' import * as _ from 'underscore' diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index 3616e8936..9b738fd8d 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -7,7 +7,7 @@ import { TSR, VTContent, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { ActionTakeWithTransitionVariantMix, EnableDSK, diff --git a/src/tv2-common/parts/invalid.ts b/src/tv2-common/parts/invalid.ts index 7f717f73c..f9931def3 100644 --- a/src/tv2-common/parts/invalid.ts +++ b/src/tv2-common/parts/invalid.ts @@ -1,4 +1,4 @@ -import { BlueprintResultPart, IBlueprintPart } from '@sofie-automation/blueprints-integration' +import { BlueprintResultPart, IBlueprintPart } from '@tv2media/blueprints-integration' import { literal, PartDefinition } from 'tv2-common' export function CreatePartInvalid(ingestPart: PartDefinition, externalIdSuffix?: string): BlueprintResultPart { diff --git a/src/tv2-common/parts/kam.ts b/src/tv2-common/parts/kam.ts index 25a7625f9..d98aea37b 100644 --- a/src/tv2-common/parts/kam.ts +++ b/src/tv2-common/parts/kam.ts @@ -1,4 +1,4 @@ -import { BlueprintResultPart, IBlueprintPart, IShowStyleUserContext } from '@sofie-automation/blueprints-integration' +import { BlueprintResultPart, IBlueprintPart, IShowStyleUserContext } from '@tv2media/blueprints-integration' import { literal, PartDefinition, PartTime, TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' export function CreatePartKamBase< diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index 7b1d2e07b..fa57be34a 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -6,7 +6,7 @@ import { PieceLifespan, VTContent, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CutToServer, GetTagForServer, diff --git a/src/tv2-common/pieces/adlibServer.ts b/src/tv2-common/pieces/adlibServer.ts index 6fe83ea0d..f97c90749 100644 --- a/src/tv2-common/pieces/adlibServer.ts +++ b/src/tv2-common/pieces/adlibServer.ts @@ -1,4 +1,4 @@ -import { IBlueprintActionManifest } from '@sofie-automation/blueprints-integration' +import { IBlueprintActionManifest } from '@tv2media/blueprints-integration' import { ActionSelectServerClip, GetTagForServer, diff --git a/src/tv2-common/pieces/script.ts b/src/tv2-common/pieces/script.ts index 49cdb4bd4..63f93a124 100644 --- a/src/tv2-common/pieces/script.ts +++ b/src/tv2-common/pieces/script.ts @@ -1,4 +1,4 @@ -import { IBlueprintPiece, PieceLifespan, ScriptContent, WithTimeline } from '@sofie-automation/blueprints-integration' +import { IBlueprintPiece, PieceLifespan, ScriptContent, WithTimeline } from '@tv2media/blueprints-integration' import { literal, PartDefinition } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' diff --git a/src/tv2-common/sources.ts b/src/tv2-common/sources.ts index d1f702221..d09654572 100644 --- a/src/tv2-common/sources.ts +++ b/src/tv2-common/sources.ts @@ -1,6 +1,6 @@ import * as _ from 'underscore' -import { IStudioContext, SourceLayerType } from '@sofie-automation/blueprints-integration' +import { IStudioContext, SourceLayerType } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import { TableConfigItemSourceMappingWithSisyfos } from './types' diff --git a/src/tv2-common/transitionFromString.ts b/src/tv2-common/transitionFromString.ts index f34bb7a04..6d4028af4 100644 --- a/src/tv2-common/transitionFromString.ts +++ b/src/tv2-common/transitionFromString.ts @@ -1,4 +1,4 @@ -import { TSR } from '@sofie-automation/blueprints-integration' +import { TSR } from '@tv2media/blueprints-integration' export function TransitionFromString(str: string): TSR.AtemTransitionStyle { if (str.match(/MIX/i)) { diff --git a/src/tv2-common/transitionSettings.ts b/src/tv2-common/transitionSettings.ts index 9554fc813..ad740bd8e 100644 --- a/src/tv2-common/transitionSettings.ts +++ b/src/tv2-common/transitionSettings.ts @@ -1,4 +1,4 @@ -import { TSR } from '@sofie-automation/blueprints-integration' +import { TSR } from '@tv2media/blueprints-integration' import { PartDefinition } from 'tv2-common' export function TransitionSettings(part: PartDefinition): TSR.AtemTransitionSettings { diff --git a/src/tv2-common/updatePolicies/adlibs.ts b/src/tv2-common/updatePolicies/adlibs.ts index ce41d51a9..241113ee7 100644 --- a/src/tv2-common/updatePolicies/adlibs.ts +++ b/src/tv2-common/updatePolicies/adlibs.ts @@ -2,7 +2,7 @@ import { BlueprintSyncIngestNewData, BlueprintSyncIngestPartInstance, ISyncIngestUpdateToPartInstanceContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { PieceMetaData } from 'tv2-common' import _ = require('underscore') diff --git a/src/tv2-common/updatePolicies/partProperties.ts b/src/tv2-common/updatePolicies/partProperties.ts index a1796d54a..efedc72e6 100644 --- a/src/tv2-common/updatePolicies/partProperties.ts +++ b/src/tv2-common/updatePolicies/partProperties.ts @@ -3,7 +3,7 @@ import { BlueprintSyncIngestPartInstance, IBlueprintMutatablePart, ISyncIngestUpdateToPartInstanceContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import _ = require('underscore') type Complete = { diff --git a/src/tv2-common/updatePolicies/pieces.ts b/src/tv2-common/updatePolicies/pieces.ts index 1af0990a1..4fdeaadca 100644 --- a/src/tv2-common/updatePolicies/pieces.ts +++ b/src/tv2-common/updatePolicies/pieces.ts @@ -3,7 +3,7 @@ import { BlueprintSyncIngestPartInstance, IBlueprintPieceInstance, ISyncIngestUpdateToPartInstanceContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' function groupPieceInstances(pieceInstances: Array>) { return pieceInstances.reduce<{ diff --git a/src/tv2-common/updatePolicies/shouldRemoveOrphanedPartInstance.ts b/src/tv2-common/updatePolicies/shouldRemoveOrphanedPartInstance.ts index cc10dd1da..6eef025a0 100644 --- a/src/tv2-common/updatePolicies/shouldRemoveOrphanedPartInstance.ts +++ b/src/tv2-common/updatePolicies/shouldRemoveOrphanedPartInstance.ts @@ -1,7 +1,7 @@ import { BlueprintRemoveOrphanedPartInstance, IRemoveOrphanedPartInstanceContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { PartMetaData } from 'tv2-common' export function shouldRemoveOrphanedPartInstance( diff --git a/src/tv2-common/updatePolicies/syncIngestUpdateToPartInstance.ts b/src/tv2-common/updatePolicies/syncIngestUpdateToPartInstance.ts index f51a69f8f..b14d28d4b 100644 --- a/src/tv2-common/updatePolicies/syncIngestUpdateToPartInstance.ts +++ b/src/tv2-common/updatePolicies/syncIngestUpdateToPartInstance.ts @@ -2,7 +2,7 @@ import { BlueprintSyncIngestNewData, BlueprintSyncIngestPartInstance, ISyncIngestUpdateToPartInstanceContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { SharedSourceLayers } from 'tv2-constants' import * as _ from 'underscore' import { stopOrReplaceEditablePieces, updateAdLibInstances } from './index' diff --git a/src/tv2-common/util.ts b/src/tv2-common/util.ts index 431709744..af9d7ecbe 100644 --- a/src/tv2-common/util.ts +++ b/src/tv2-common/util.ts @@ -1,4 +1,4 @@ -import { IBlueprintAdLibPiece, IBlueprintPiece, TSR } from '@sofie-automation/blueprints-integration' +import { IBlueprintAdLibPiece, IBlueprintPiece, TSR } from '@tv2media/blueprints-integration' export function literal(o: T) { return o diff --git a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts index 830e01a09..b911831ce 100644 --- a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts @@ -6,7 +6,7 @@ import { IBlueprintPieceInstance, PieceLifespan, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { ActionCutToCamera, ActionTakeWithTransition, literal } from 'tv2-common' import { AdlibActionType, NoteType, SharedOutputLayers } from 'tv2-constants' import { ActionExecutionContext } from '../../__mocks__/context' diff --git a/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts b/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts index bb7db4c71..82bc49310 100644 --- a/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts @@ -1,4 +1,4 @@ -import { IBlueprintPiece, PieceLifespan, ScriptContent, WithTimeline } from '@sofie-automation/blueprints-integration' +import { IBlueprintPiece, PieceLifespan, ScriptContent, WithTimeline } from '@tv2media/blueprints-integration' import { AddScript, literal, PartDefinitionKam } from 'tv2-common' import { PartType, SharedOutputLayers } from 'tv2-constants' import { SourceLayer } from '../layers' diff --git a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts index fccd5041b..3e6f09519 100644 --- a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts @@ -1,4 +1,4 @@ -import { ExtendedIngestRundown } from '@sofie-automation/blueprints-integration' +import { ExtendedIngestRundown } from '@tv2media/blueprints-integration' import { ShowStyleUserContext } from '../../__mocks__/context' import { checkAllLayers } from './layers-check' diff --git a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts index ef71cb181..137ce3986 100644 --- a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts @@ -3,7 +3,7 @@ import { IBlueprintActionManifest, IBlueprintActionManifestDisplayContent, IngestSegment -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { INewsStory, literal, UnparsedCue } from 'tv2-common' import { SharedSourceLayers } from 'tv2-constants' import { SegmentUserContext } from '../../__mocks__/context' diff --git a/src/tv2_afvd_showstyle/__tests__/layers-check.ts b/src/tv2_afvd_showstyle/__tests__/layers-check.ts index 6b8e26c0d..fa0966dae 100644 --- a/src/tv2_afvd_showstyle/__tests__/layers-check.ts +++ b/src/tv2_afvd_showstyle/__tests__/layers-check.ts @@ -6,7 +6,7 @@ import { IShowStyleUserContext, TimelineObjectCoreExt, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { GetDSKSourceLayerNames, literal } from 'tv2-common' import mappingsDefaults, { getMediaPlayerMappings } from '../../tv2_afvd_studio/migrations/mappings-defaults' diff --git a/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts b/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts index debe1e12c..66b648ed1 100644 --- a/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts @@ -1,6 +1,6 @@ import * as _ from 'underscore' -import { BlueprintResultSegment, PieceLifespan, TimelineObjectCoreExt } from '@sofie-automation/blueprints-integration' +import { BlueprintResultSegment, PieceLifespan, TimelineObjectCoreExt } from '@tv2media/blueprints-integration' // @ts-ignore global.VERSION = 'test' 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 79415d52c..15b53b315 100644 --- a/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts @@ -1,10 +1,6 @@ import * as _ from 'underscore' -import { - ExtendedIngestRundown, - IBlueprintPieceGeneric, - IBlueprintRundownDB -} from '@sofie-automation/blueprints-integration' +import { ExtendedIngestRundown, IBlueprintPieceGeneric, IBlueprintRundownDB } from '@tv2media/blueprints-integration' import { defaultShowStyleConfig, defaultStudioConfig } from './configs' import { checkAllLayers } from './layers-check' diff --git a/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts b/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts index ed2e74107..3836e7c9a 100644 --- a/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts @@ -7,7 +7,7 @@ import { IBlueprintRundownDB, PieceLifespan, PlaylistTimingType -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import { SyncIngestUpdateToPartInstanceContext } from '../../__mocks__/context' diff --git a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts index 0c56de315..33661afce 100644 --- a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts @@ -4,7 +4,7 @@ import { IBlueprintPiece, IngestSegment, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { fail } from 'assert' import { TimeFromFrames } from 'tv2-common' import * as _ from 'underscore' diff --git a/src/tv2_afvd_showstyle/actions.ts b/src/tv2_afvd_showstyle/actions.ts index ad297d9c0..6d3b78d25 100644 --- a/src/tv2_afvd_showstyle/actions.ts +++ b/src/tv2_afvd_showstyle/actions.ts @@ -1,4 +1,4 @@ -import { ActionUserData, IActionExecutionContext } from '@sofie-automation/blueprints-integration' +import { ActionUserData, IActionExecutionContext } from '@tv2media/blueprints-integration' import { executeAction } from 'tv2-common' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' import { getConfig } from './helpers/config' diff --git a/src/tv2_afvd_showstyle/config-manifests.ts b/src/tv2_afvd_showstyle/config-manifests.ts index 9270ced2f..147abc556 100644 --- a/src/tv2_afvd_showstyle/config-manifests.ts +++ b/src/tv2_afvd_showstyle/config-manifests.ts @@ -1,4 +1,4 @@ -import { ConfigManifestEntry, ConfigManifestEntryType, TSR } from '@sofie-automation/blueprints-integration' +import { ConfigManifestEntry, ConfigManifestEntryType, TSR } from '@tv2media/blueprints-integration' import { DEFAULT_GRAPHICS } from 'tv2-common' export const showStyleConfigManifest: ConfigManifestEntry[] = [ diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index c063bcd16..c4867d481 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -14,7 +14,7 @@ import { SourceLayerType, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { ActionClearGraphics, ActionCutSourceToBox, diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index 3795bfeaf..85727b197 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -8,7 +8,7 @@ import { PieceLifespan, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { getSegmentBase, literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import * as _ from 'underscore' diff --git a/src/tv2_afvd_showstyle/helpers/config.ts b/src/tv2_afvd_showstyle/helpers/config.ts index 5b10e902c..1b26d37bf 100644 --- a/src/tv2_afvd_showstyle/helpers/config.ts +++ b/src/tv2_afvd_showstyle/helpers/config.ts @@ -3,7 +3,7 @@ import { ICommonContext, IShowStyleContext, TableConfigItemValue -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { TV2ShowstyleBlueprintConfigBase } from 'tv2-common' import * as _ from 'underscore' import { BlueprintConfig as BlueprintConfigBase } from '../../tv2_afvd_studio/helpers/config' diff --git a/src/tv2_afvd_showstyle/helpers/content/dve.ts b/src/tv2_afvd_showstyle/helpers/content/dve.ts index 1947b4afa..1892c193f 100644 --- a/src/tv2_afvd_showstyle/helpers/content/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/content/dve.ts @@ -1,4 +1,4 @@ -import { IShowStyleUserContext, SplitsContent, WithTimeline } from '@sofie-automation/blueprints-integration' +import { IShowStyleUserContext, SplitsContent, WithTimeline } from '@tv2media/blueprints-integration' import { CueDefinitionDVE, DVEConfigInput, 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 98519d22d..84c602471 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -7,7 +7,7 @@ import { PieceLifespan, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AtemLLayerDSK, CueDefinitionGraphic, 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 31eb9935a..233a26f05 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts @@ -3,7 +3,7 @@ import { IBlueprintAdLibPiece, IBlueprintPiece, PieceLifespan -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CueDefinitionLYD, EvaluateLYD, literal, ParseCue, PartDefinitionKam } from 'tv2-common' import { NoteType, PartType } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' 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 b2ea6cafe..7e07edbad 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -7,7 +7,7 @@ import { PieceLifespan, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AtemLLayerDSK, CueDefinitionGraphic, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts index e2c485f8e..df1163578 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts @@ -4,7 +4,7 @@ import { IBlueprintAdLibPiece, IShowStyleUserContext, PieceLifespan -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { ActionSelectDVE, CreateAdlibServer, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts index ff45dcc5f..da7465389 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts @@ -4,7 +4,7 @@ import { IBlueprintPiece, PieceLifespan, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CreateTimingEnable, CueDefinitionClearGrafiks, GetDefaultOut, literal } from 'tv2-common' import { GraphicLLayer, SharedOutputLayers } from 'tv2-constants' import { SourceLayer } from '../../../tv2_afvd_showstyle/layers' diff --git a/src/tv2_afvd_showstyle/helpers/pieces/design.ts b/src/tv2_afvd_showstyle/helpers/pieces/design.ts index 2208ad5ff..862e25e1a 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/design.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/design.ts @@ -3,7 +3,7 @@ import { IBlueprintAdLibPiece, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CueDefinitionGraphicDesign, EvaluateDesignBase } from 'tv2-common' import * as _ from 'underscore' import { BlueprintConfig } from '../../../tv2_afvd_studio/helpers/config' diff --git a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts index 9021e68c2..d165e30b4 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts @@ -4,7 +4,7 @@ import { IBlueprintPiece, ISegmentUserContext, PieceLifespan -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { ActionSelectDVE, AddParentClass, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts index e5ca36aae..1affab492 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts @@ -4,7 +4,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CueDefinitionEkstern, EvaluateEksternBase, PartDefinition } from 'tv2-common' import { BlueprintConfig } from '../../../tv2_afvd_studio/helpers/config' import { AtemLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' diff --git a/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts b/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts index 0d4200f1a..74089c556 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts @@ -5,7 +5,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CueDefinition, EvaluateCueMixMinus, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts index 3b69f4020..d55e81e7a 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts @@ -4,7 +4,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CreateInternalGraphic, CueDefinitionGraphic, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts index c0b45c8ef..cbc949e14 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts @@ -6,7 +6,7 @@ import { PieceLifespan, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CalculateTime, CueDefinitionBackgroundLoop, literal } from 'tv2-common' import { GraphicLLayer, SharedOutputLayers } from 'tv2-constants' import { CasparLLayer } from '../../../tv2_afvd_studio/layers' diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts index 2bd25bc82..0fad4ec5b 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts @@ -7,7 +7,7 @@ import { IStudioUserContext, SourceLayerType, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CreatePilotGraphic, CueDefinitionGraphic, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts index bbd65df1a..373f8cd36 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts @@ -4,7 +4,7 @@ import { IBlueprintPiece, ISegmentUserContext, PieceLifespan -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { ActionSelectJingle, CreateJingleContentBase, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts index 5bbe99712..ee035e889 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts @@ -8,7 +8,7 @@ import { SourceLayerType, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CalculateTime, CueDefinitionRouting, FindSourceInfoStrict, literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import _ = require('underscore') diff --git a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts index 7b6eafe75..440c3b1ba 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts @@ -5,7 +5,7 @@ import { IBlueprintPiece, ISegmentUserContext, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CueDefinitionTelefon, GetSisyfosTimelineObjForCamera, diff --git a/src/tv2_afvd_showstyle/helpers/studio.ts b/src/tv2_afvd_showstyle/helpers/studio.ts index c4e348b53..3113df726 100644 --- a/src/tv2_afvd_showstyle/helpers/studio.ts +++ b/src/tv2_afvd_showstyle/helpers/studio.ts @@ -1,4 +1,4 @@ -import { IStudioContext } from '@sofie-automation/blueprints-integration' +import { IStudioContext } from '@tv2media/blueprints-integration' /** * Gets the name of the studio this context belongs to. diff --git a/src/tv2_afvd_showstyle/helpers/time.ts b/src/tv2_afvd_showstyle/helpers/time.ts index fc6c8df2d..14164887c 100644 --- a/src/tv2_afvd_showstyle/helpers/time.ts +++ b/src/tv2_afvd_showstyle/helpers/time.ts @@ -1,4 +1,4 @@ -import { IBlueprintPart } from '@sofie-automation/blueprints-integration' +import { IBlueprintPart } from '@tv2media/blueprints-integration' import { INewsStory, TimeFromINewsField } from 'tv2-common' export function GetTimeFromPart(story: INewsStory): Partial { diff --git a/src/tv2_afvd_showstyle/index.ts b/src/tv2_afvd_showstyle/index.ts index 104a220ac..29d7dab6a 100644 --- a/src/tv2_afvd_showstyle/index.ts +++ b/src/tv2_afvd_showstyle/index.ts @@ -1,4 +1,4 @@ -import { BlueprintManifestType, ShowStyleBlueprintManifest } from '@sofie-automation/blueprints-integration' +import { BlueprintManifestType, ShowStyleBlueprintManifest } from '@tv2media/blueprints-integration' import { showStyleConfigManifest } from './config-manifests' import { showStyleMigrations } from './migrations' diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 6a45cb53f..99eab6f6a 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -1,4 +1,4 @@ -import { MigrationStepShowStyle } from '@sofie-automation/blueprints-integration' +import { MigrationStepShowStyle } from '@tv2media/blueprints-integration' import { AddGraphicToGFXTable, GetDSKSourceLayerNames, diff --git a/src/tv2_afvd_showstyle/migrations/outputlayer-defaults.ts b/src/tv2_afvd_showstyle/migrations/outputlayer-defaults.ts index 89eec7590..bc6709923 100644 --- a/src/tv2_afvd_showstyle/migrations/outputlayer-defaults.ts +++ b/src/tv2_afvd_showstyle/migrations/outputlayer-defaults.ts @@ -1,4 +1,4 @@ -import { IOutputLayer } from '@sofie-automation/blueprints-integration' +import { IOutputLayer } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' diff --git a/src/tv2_afvd_showstyle/migrations/sourcelayer-defaults.ts b/src/tv2_afvd_showstyle/migrations/sourcelayer-defaults.ts index fbaf89d47..495763d0f 100644 --- a/src/tv2_afvd_showstyle/migrations/sourcelayer-defaults.ts +++ b/src/tv2_afvd_showstyle/migrations/sourcelayer-defaults.ts @@ -1,4 +1,4 @@ -import { ISourceLayer, SourceLayerType } from '@sofie-automation/blueprints-integration' +import { ISourceLayer, SourceLayerType } from '@tv2media/blueprints-integration' import { GetDSKSourceLayerDefaults, literal } from 'tv2-common' import { SharedSourceLayers } from 'tv2-constants' import { ATEMModel } from '../../types/atem' @@ -15,11 +15,10 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',q,ctrl+shift+a', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -34,11 +33,10 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',q,ctrl+shift+a', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: true, allowDisable: false, @@ -53,11 +51,10 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',q,ctrl+shift+s', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: true, @@ -72,11 +69,10 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'a,s,d,f,g', - clearKeyboardHotkey: ',q,ctrl+shift+d', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: true, @@ -91,11 +87,10 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',q,ctrl+shift+f', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: true, @@ -110,11 +105,10 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',q,ctrl+shift+g', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: true, @@ -129,11 +123,10 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',q', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: true, @@ -148,11 +141,10 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',q', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: true, @@ -171,11 +163,10 @@ const JINGLE: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -194,12 +185,8 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me1', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: - 'f1,f2,f3,f4,ctrl+shift+alt+c,shift+ctrl+f1,shift+ctrl+f2,shift+ctrl+f3,shift+ctrl+f4,shift+ctrl+f5', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -214,12 +201,10 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me1', isRemoteInput: true, isGuestInput: false, - activateKeyboardHotkeys: 'ctrl+shift+alt+b,1,2,3,4,5,6,7,8,9,0', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, + isSticky: false, stickyOriginalOnly: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -234,11 +219,9 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me1', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'r,e,i,u', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -253,12 +236,10 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me1', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, + isSticky: false, stickyOriginalOnly: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -273,11 +254,9 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me1', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'f10,m,comma,.,n,c,b,v', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -292,12 +271,8 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: - 'shift+f1,shift+f2,shift+f3,shift+f4,shift+f5,shift+1,shift+2,shift+3,shift+4,shift+5,shift+6,shift+7,shift+8,shift+9,shift+0,shift+e,shift+d,shift+i,shift+u,shift+t', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: true, allowDisable: false, @@ -312,12 +287,8 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: - 'ctrl+f1,ctrl+f2,ctrl+f3,ctrl+shift+alt+a,ctrl+f5,ctrl+1,ctrl+2,ctrl+3,ctrl+4,ctrl+5,ctrl+6,ctrl+7,ctrl+8,ctrl+9,ctrl+0,ctrl+e,ctrl+d,ctrl+i,ctrl+shift+alt+i,ctrl+alt+shift+g', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: true, allowDisable: false, @@ -332,12 +303,8 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: - 'alt+shift+f1,alt+shift+f2,alt+shift+f3,alt+shift+f4,alt+shift+f5,alt+shift+1,alt+shift+2,alt+shift+3,alt+shift+4,alt+shift+5,alt+shift+6,alt+shift+7,alt+shift+8,alt+shift+9,alt+shift+0,alt+shift+e,alt+shift+d,alt+shift+g', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: true, allowDisable: false, @@ -352,11 +319,9 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: true, allowDisable: false, @@ -371,11 +336,9 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me1', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -390,11 +353,10 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -409,11 +371,9 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me1', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -428,11 +388,10 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me1', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'i', - clearKeyboardHotkey: ',q', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, + isSticky: true, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -447,11 +406,9 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me1', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -470,11 +427,10 @@ const MUSIK: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',minus', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -493,11 +449,9 @@ const MANUS: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -516,11 +470,10 @@ const SEC: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'NumpadDivide,NumpadSubtract,NumpadAdd', - clearKeyboardHotkey: ',', - assignHotkeysToGlobalAdlibs: true, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -535,11 +488,9 @@ const SEC: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: ',space,,q', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -555,11 +506,9 @@ const SEC: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'shift+a', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: true, allowDisable: false, @@ -574,11 +523,9 @@ const SEC: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: true, allowDisable: false, @@ -593,11 +540,9 @@ const SEC: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: true, allowDisable: false, @@ -612,11 +557,10 @@ const SEC: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'ctrl+shift+alt+e,ctrl+shift+alt+d', - clearKeyboardHotkey: ',', - assignHotkeysToGlobalAdlibs: true, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -631,11 +575,9 @@ const SEC: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -654,11 +596,10 @@ const AUX: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'ctrl+shift+alt+f', - clearKeyboardHotkey: ',', - assignHotkeysToGlobalAdlibs: true, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: true, allowDisable: false, @@ -673,12 +614,10 @@ const AUX: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: - 'shift+ctrl+1,shift+ctrl+2,shift+ctrl+3,shift+ctrl+4,shift+ctrl+5,shift+ctrl+6,shift+ctrl+7,shift+ctrl+8,shift+ctrl+9,shift+ctrl+0,shift+ctrl+e', - clearKeyboardHotkey: ',', - assignHotkeysToGlobalAdlibs: true, + isClearable: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: false, allowDisable: false, @@ -693,11 +632,9 @@ const AUX: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: false, isHidden: true, allowDisable: false, @@ -716,11 +653,9 @@ const SELECTED_ADLIB: ISourceLayer[] = [ exclusiveGroup: 'server', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: true, isHidden: true, allowDisable: false, @@ -735,11 +670,9 @@ const SELECTED_ADLIB: ISourceLayer[] = [ exclusiveGroup: 'server', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: true, isHidden: true, allowDisable: false, @@ -754,11 +687,9 @@ const SELECTED_ADLIB: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, + isSticky: false, - activateStickyKeyboardHotkey: '', + isQueueable: true, isHidden: true, allowDisable: false, diff --git a/src/tv2_afvd_showstyle/migrations/util.ts b/src/tv2_afvd_showstyle/migrations/util.ts index 1f93b2072..9253a5318 100644 --- a/src/tv2_afvd_showstyle/migrations/util.ts +++ b/src/tv2_afvd_showstyle/migrations/util.ts @@ -3,7 +3,7 @@ import { ISourceLayer, MigrationContextShowStyle, MigrationStepShowStyle -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { forceSourceLayerToDefaultsBase, literal } from 'tv2-common' import * as _ from 'underscore' import { showStyleConfigManifest } from '../config-manifests' diff --git a/src/tv2_afvd_showstyle/migrations/variants-defaults.ts b/src/tv2_afvd_showstyle/migrations/variants-defaults.ts index 24f45aa3c..2767d6458 100644 --- a/src/tv2_afvd_showstyle/migrations/variants-defaults.ts +++ b/src/tv2_afvd_showstyle/migrations/variants-defaults.ts @@ -1,4 +1,4 @@ -import { MigrationContextShowStyle, MigrationStepShowStyle } from '@sofie-automation/blueprints-integration' +import { MigrationContextShowStyle, MigrationStepShowStyle } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import * as _ from 'underscore' diff --git a/src/tv2_afvd_showstyle/parts/cueonly.ts b/src/tv2_afvd_showstyle/parts/cueonly.ts index a9227fb22..fa5f05f67 100644 --- a/src/tv2_afvd_showstyle/parts/cueonly.ts +++ b/src/tv2_afvd_showstyle/parts/cueonly.ts @@ -5,7 +5,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddScript, ApplyFullGraphicPropertiesToPart, diff --git a/src/tv2_afvd_showstyle/parts/effekt.ts b/src/tv2_afvd_showstyle/parts/effekt.ts index 67b2b49d0..8cd6b8be9 100644 --- a/src/tv2_afvd_showstyle/parts/effekt.ts +++ b/src/tv2_afvd_showstyle/parts/effekt.ts @@ -1,4 +1,4 @@ -import { IBlueprintPiece, ISegmentUserContext } from '@sofie-automation/blueprints-integration' +import { IBlueprintPiece, ISegmentUserContext } from '@tv2media/blueprints-integration' import { CreateEffektForPartBase, PartDefinition } from 'tv2-common' import { CasparLLayer, SisyfosLLAyer } from '../../tv2_afvd_studio/layers' import { BlueprintConfig } from '../helpers/config' diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index 4a2b3459e..209a7c24e 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -10,7 +10,7 @@ import { SourceLayerType, TimelineObjectCoreExt, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddScript, CreatePartInvalid, diff --git a/src/tv2_afvd_showstyle/parts/grafik.ts b/src/tv2_afvd_showstyle/parts/grafik.ts index 519211a11..da9b6040f 100644 --- a/src/tv2_afvd_showstyle/parts/grafik.ts +++ b/src/tv2_afvd_showstyle/parts/grafik.ts @@ -6,7 +6,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddScript, ApplyFullGraphicPropertiesToPart, diff --git a/src/tv2_afvd_showstyle/parts/intro.ts b/src/tv2_afvd_showstyle/parts/intro.ts index 9fbfc359d..ad9b560c2 100644 --- a/src/tv2_afvd_showstyle/parts/intro.ts +++ b/src/tv2_afvd_showstyle/parts/intro.ts @@ -6,7 +6,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddScript, CreatePartInvalid, diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index 67257c181..69244dcc4 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -11,7 +11,7 @@ import { TSR, VTContent, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddParentClass, AddScript, diff --git a/src/tv2_afvd_showstyle/parts/live.ts b/src/tv2_afvd_showstyle/parts/live.ts index 70ca72745..d901d3bf2 100644 --- a/src/tv2_afvd_showstyle/parts/live.ts +++ b/src/tv2_afvd_showstyle/parts/live.ts @@ -6,7 +6,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddScript, CueDefinitionEkstern, literal, PartDefinition, PartTime } from 'tv2-common' import { CueType } from 'tv2-constants' import { BlueprintConfig } from '../../tv2_afvd_showstyle/helpers/config' diff --git a/src/tv2_afvd_showstyle/parts/server.ts b/src/tv2_afvd_showstyle/parts/server.ts index 666528901..82d951b7c 100644 --- a/src/tv2_afvd_showstyle/parts/server.ts +++ b/src/tv2_afvd_showstyle/parts/server.ts @@ -3,7 +3,7 @@ import { HackPartMediaObjectSubscription, IBlueprintActionManifest, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddScript, CreatePartServerBase, PartDefinition, ServerPartProps } from 'tv2-common' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../../tv2_afvd_studio/layers' import { BlueprintConfig } from '../helpers/config' diff --git a/src/tv2_afvd_showstyle/parts/teknik.ts b/src/tv2_afvd_showstyle/parts/teknik.ts index 7277f5579..777b4b365 100644 --- a/src/tv2_afvd_showstyle/parts/teknik.ts +++ b/src/tv2_afvd_showstyle/parts/teknik.ts @@ -6,7 +6,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddScript, literal, PartDefinition, PartTime } from 'tv2-common' import { BlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' diff --git a/src/tv2_afvd_showstyle/parts/unknown.ts b/src/tv2_afvd_showstyle/parts/unknown.ts index 50186d077..eccf3a3ee 100644 --- a/src/tv2_afvd_showstyle/parts/unknown.ts +++ b/src/tv2_afvd_showstyle/parts/unknown.ts @@ -5,7 +5,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddScript, ApplyFullGraphicPropertiesToPart, diff --git a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts index b3b6405c4..73f97ab0b 100644 --- a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts @@ -8,7 +8,7 @@ import { TimelineObjectCoreExt, TimelineObjHoldMode, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AtemLLayerDSK, FindDSKJingle, literal, TimelineBlueprintExt } from 'tv2-common' import * as _ from 'underscore' import { BlueprintConfig } from '../tv2_afvd_studio/helpers/config' diff --git a/src/tv2_afvd_showstyle/syncIngestUpdateToPartInstance.ts b/src/tv2_afvd_showstyle/syncIngestUpdateToPartInstance.ts index 60a1e9ee0..2aa947b25 100644 --- a/src/tv2_afvd_showstyle/syncIngestUpdateToPartInstance.ts +++ b/src/tv2_afvd_showstyle/syncIngestUpdateToPartInstance.ts @@ -2,7 +2,7 @@ import { BlueprintSyncIngestNewData, BlueprintSyncIngestPartInstance, ISyncIngestUpdateToPartInstanceContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { syncIngestUpdateToPartInstanceBase } from 'tv2-common' import * as _ from 'underscore' import { SourceLayer } from './layers' diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index 02a8c65c5..bc5736403 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 '@sofie-automation/blueprints-integration' +import { IBlueprintRundownDB, PieceLifespan, PlaylistTimingType, TSR } from '@tv2media/blueprints-integration' import { CueDefinition, CueDefinitionBackgroundLoop, diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index a8ef8d587..eee23a22a 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -4,7 +4,7 @@ import { ConfigManifestEntryType, TableConfigItemValue, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { DSKConfigManifest, literal, diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index cf2021d7f..0d726e279 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -4,7 +4,7 @@ import { BlueprintResultBaseline, IStudioContext, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import * as _ from 'underscore' import { AtemSourceIndex } from '../types/atem' diff --git a/src/tv2_afvd_studio/getShowStyleId.ts b/src/tv2_afvd_studio/getShowStyleId.ts index 7848aeb8c..1c2406d12 100644 --- a/src/tv2_afvd_studio/getShowStyleId.ts +++ b/src/tv2_afvd_studio/getShowStyleId.ts @@ -1,4 +1,4 @@ -import { IBlueprintShowStyleBase, IngestRundown, IStudioContext } from '@sofie-automation/blueprints-integration' +import { IBlueprintShowStyleBase, IngestRundown, IStudioContext } from '@tv2media/blueprints-integration' import * as _ from 'underscore' export function getShowStyleId( diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index 4e2613fe3..51400b1a9 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 '@sofie-automation/blueprints-integration' +import { IBlueprintConfig, ICommonContext, IStudioContext } from '@tv2media/blueprints-integration' import { getLiveAudioLayers, getStickyLayers, diff --git a/src/tv2_afvd_studio/helpers/sources.ts b/src/tv2_afvd_studio/helpers/sources.ts index 4cd9a9ba5..733e51681 100644 --- a/src/tv2_afvd_studio/helpers/sources.ts +++ b/src/tv2_afvd_studio/helpers/sources.ts @@ -1,6 +1,6 @@ import * as _ from 'underscore' -import { SourceLayerType } from '@sofie-automation/blueprints-integration' +import { SourceLayerType } from '@tv2media/blueprints-integration' import { ParseMappingTable, SourceInfo } from 'tv2-common' import { StudioConfig } from './config' diff --git a/src/tv2_afvd_studio/index.ts b/src/tv2_afvd_studio/index.ts index 502c00a41..2c5ad9b55 100644 --- a/src/tv2_afvd_studio/index.ts +++ b/src/tv2_afvd_studio/index.ts @@ -1,4 +1,4 @@ -import { BlueprintManifestType, StudioBlueprintManifest } from '@sofie-automation/blueprints-integration' +import { BlueprintManifestType, StudioBlueprintManifest } from '@tv2media/blueprints-integration' import { GetStudioManifestWithMixins, StudioManifestMixinINews } from 'inews-mixins' import * as _ from 'underscore' import { studioConfigManifest } from './config-manifests' diff --git a/src/tv2_afvd_studio/migrations/devices.ts b/src/tv2_afvd_studio/migrations/devices.ts index 74dc8e7d1..d088ad397 100644 --- a/src/tv2_afvd_studio/migrations/devices.ts +++ b/src/tv2_afvd_studio/migrations/devices.ts @@ -4,7 +4,7 @@ import { MigrationStepInputFilteredResult, MigrationStepStudio, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import * as _ from 'underscore' diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index 7d82250c8..4cd202ac6 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -1,4 +1,4 @@ -import { MigrationStepStudio, TSR } from '@sofie-automation/blueprints-integration' +import { MigrationStepStudio, TSR } from '@tv2media/blueprints-integration' import { AddKeepAudio, literal, diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index fb0dc71a8..7708c933a 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -1,4 +1,4 @@ -import { BlueprintMapping, BlueprintMappings, LookaheadMode, TSR } from '@sofie-automation/blueprints-integration' +import { BlueprintMapping, BlueprintMappings, LookaheadMode, TSR } from '@tv2media/blueprints-integration' import { AbstractLLayerServerEnable, CasparPlayerClip, diff --git a/src/tv2_afvd_studio/migrations/util.ts b/src/tv2_afvd_studio/migrations/util.ts index b78f0a6ca..c24a1bdea 100644 --- a/src/tv2_afvd_studio/migrations/util.ts +++ b/src/tv2_afvd_studio/migrations/util.ts @@ -6,7 +6,7 @@ import { MigrationStepInputFilteredResult, MigrationStepStudio, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import * as _ from 'underscore' import { SisyfosLLAyer } from '../layers' diff --git a/src/tv2_afvd_studio/onTimelineGenerate.ts b/src/tv2_afvd_studio/onTimelineGenerate.ts index 8834d3391..3b877ce3e 100644 --- a/src/tv2_afvd_studio/onTimelineGenerate.ts +++ b/src/tv2_afvd_studio/onTimelineGenerate.ts @@ -5,7 +5,7 @@ import { OnGenerateTimelineObj, PartEndState, TimelinePersistentState -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { onTimelineGenerate } from 'tv2-common' import * as _ from 'underscore' import { getConfig } from '../tv2_afvd_showstyle/helpers/config' diff --git a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts index 1055c7de7..089600d10 100644 --- a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts @@ -5,7 +5,7 @@ import { IBlueprintPieceInstance, PieceLifespan, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { ActionCommentatorSelectDVE, ActionCutToCamera, diff --git a/src/tv2_offtube_showstyle/actions.ts b/src/tv2_offtube_showstyle/actions.ts index 1856fc934..9ef470da8 100644 --- a/src/tv2_offtube_showstyle/actions.ts +++ b/src/tv2_offtube_showstyle/actions.ts @@ -1,4 +1,4 @@ -import { ActionUserData, IActionExecutionContext } from '@sofie-automation/blueprints-integration' +import { ActionUserData, IActionExecutionContext } from '@tv2media/blueprints-integration' import { executeAction } from 'tv2-common' import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' import { OFFTUBE_DVE_GENERATOR_OPTIONS } from './content/OfftubeDVEContent' diff --git a/src/tv2_offtube_showstyle/config-manifests.ts b/src/tv2_offtube_showstyle/config-manifests.ts index 3afc7b40d..46e924af2 100644 --- a/src/tv2_offtube_showstyle/config-manifests.ts +++ b/src/tv2_offtube_showstyle/config-manifests.ts @@ -1,4 +1,4 @@ -import { ConfigManifestEntry, ConfigManifestEntryType, TSR } from '@sofie-automation/blueprints-integration' +import { ConfigManifestEntry, ConfigManifestEntryType, TSR } from '@tv2media/blueprints-integration' import { DEFAULT_GRAPHICS } from 'tv2-common' export const showStyleConfigManifest: ConfigManifestEntry[] = [ diff --git a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts index 05293f12a..d75af8c4c 100644 --- a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts +++ b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts @@ -1,4 +1,4 @@ -import { ISegmentUserContext, SplitsContent, WithTimeline } from '@sofie-automation/blueprints-integration' +import { ISegmentUserContext, SplitsContent, WithTimeline } from '@tv2media/blueprints-integration' import { CueDefinitionDVE, DVEConfigInput, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts index 9007900ab..6b957803a 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts @@ -6,7 +6,7 @@ import { SplitsContent, TimelineObjectCoreExt, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { ActionSelectDVE, CreateAdlibServer, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts index 9e2b15746..c9d3422c3 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts @@ -5,7 +5,7 @@ import { ISegmentUserContext, PieceLifespan, SplitsContent -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { ActionSelectDVE, AddParentClass, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts index 53dff5eb9..46dae6ef0 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts @@ -4,7 +4,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CueDefinitionEkstern, EvaluateEksternBase, PartDefinition } from 'tv2-common' import { OfftubeAtemLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts index e9f663e63..8761817ba 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts @@ -6,7 +6,7 @@ import { PieceLifespan, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CalculateTime, CueDefinitionBackgroundLoop, literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import _ = require('underscore') diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphicDesign.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphicDesign.ts index aa3221cc4..f524c7418 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphicDesign.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphicDesign.ts @@ -3,7 +3,7 @@ import { IBlueprintAdLibPiece, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CueDefinitionGraphicDesign, EvaluateDesignBase } from 'tv2-common' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts index b38e7f5b1..7e5e24733 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts @@ -5,7 +5,7 @@ import { IBlueprintPiece, IShowStyleUserContext, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CreateInternalGraphic, CreatePilotGraphic, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index faff60ba7..bdb0d57f7 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -4,7 +4,7 @@ import { IBlueprintPiece, ISegmentUserContext, PieceLifespan -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { ActionSelectJingle, CreateJingleContentBase, diff --git a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts index bbe605101..4b83543b9 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts @@ -7,7 +7,7 @@ import { TimelineObjectCoreExt, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CueDefinitionPgmClean, FindSourceInfoStrict, literal, SourceInfo, SourceInfoType } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 932cec8ba..9f4754f9f 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -13,7 +13,7 @@ import { PlaylistTimingType, SourceLayerType, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { ActionClearGraphics, ActionCommentatorSelectDVE, diff --git a/src/tv2_offtube_showstyle/getSegment.ts b/src/tv2_offtube_showstyle/getSegment.ts index efc766528..f5db63cfe 100644 --- a/src/tv2_offtube_showstyle/getSegment.ts +++ b/src/tv2_offtube_showstyle/getSegment.ts @@ -8,7 +8,7 @@ import { PieceLifespan, TSR, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { getSegmentBase, literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import * as _ from 'underscore' diff --git a/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts b/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts index de6afa96a..d9d234cde 100644 --- a/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts +++ b/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts @@ -5,7 +5,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { CueDefinition, EvaluateCuesBase, EvaluateCuesOptions, EvaluateLYD, PartDefinition } from 'tv2-common' import { OfftubeEvaluateAdLib } from '../cues/OfftubeAdlib' import { OfftubeEvaluateDVE } from '../cues/OfftubeDVE' diff --git a/src/tv2_offtube_showstyle/helpers/config.ts b/src/tv2_offtube_showstyle/helpers/config.ts index 32e3e4068..be441d409 100644 --- a/src/tv2_offtube_showstyle/helpers/config.ts +++ b/src/tv2_offtube_showstyle/helpers/config.ts @@ -4,7 +4,7 @@ import { IShowStyleContext, IStudioContext, TableConfigItemValue -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { TV2ShowstyleBlueprintConfigBase } from 'tv2-common' import * as _ from 'underscore' import { OfftubeStudioBlueprintConfig } from '../../tv2_offtube_studio/helpers/config' diff --git a/src/tv2_offtube_showstyle/index.ts b/src/tv2_offtube_showstyle/index.ts index 185f1ec6e..4f1e1ad78 100644 --- a/src/tv2_offtube_showstyle/index.ts +++ b/src/tv2_offtube_showstyle/index.ts @@ -1,4 +1,4 @@ -import { BlueprintManifestType, ShowStyleBlueprintManifest } from '@sofie-automation/blueprints-integration' +import { BlueprintManifestType, ShowStyleBlueprintManifest } from '@tv2media/blueprints-integration' import { showStyleConfigManifest } from './config-manifests' import { showStyleMigrations } from './migrations' diff --git a/src/tv2_offtube_showstyle/migrations/index.ts b/src/tv2_offtube_showstyle/migrations/index.ts index f812109d1..ecf212f32 100644 --- a/src/tv2_offtube_showstyle/migrations/index.ts +++ b/src/tv2_offtube_showstyle/migrations/index.ts @@ -1,4 +1,4 @@ -import { MigrationStepShowStyle } from '@sofie-automation/blueprints-integration' +import { MigrationStepShowStyle } from '@tv2media/blueprints-integration' import { AddGraphicToGFXTable, GetDSKSourceLayerNames, diff --git a/src/tv2_offtube_showstyle/migrations/outputlayer-defaults.ts b/src/tv2_offtube_showstyle/migrations/outputlayer-defaults.ts index d36c535ba..3191ee6bc 100644 --- a/src/tv2_offtube_showstyle/migrations/outputlayer-defaults.ts +++ b/src/tv2_offtube_showstyle/migrations/outputlayer-defaults.ts @@ -1,4 +1,4 @@ -import { IOutputLayer } from '@sofie-automation/blueprints-integration' +import { IOutputLayer } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' diff --git a/src/tv2_offtube_showstyle/migrations/sourcelayer-defaults.ts b/src/tv2_offtube_showstyle/migrations/sourcelayer-defaults.ts index c2f180214..d34345e2d 100644 --- a/src/tv2_offtube_showstyle/migrations/sourcelayer-defaults.ts +++ b/src/tv2_offtube_showstyle/migrations/sourcelayer-defaults.ts @@ -1,4 +1,4 @@ -import { ISourceLayer, SourceLayerType } from '@sofie-automation/blueprints-integration' +import { ISourceLayer, SourceLayerType } from '@tv2media/blueprints-integration' import { GetDSKSourceLayerDefaults, literal } from 'tv2-common' import { SharedSourceLayers } from 'tv2-constants' import { ATEMModel } from '../../types/atem' @@ -15,11 +15,7 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -34,11 +30,7 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: true, allowDisable: false, @@ -53,11 +45,7 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: true, @@ -72,11 +60,7 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: true, @@ -91,11 +75,7 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: true, @@ -110,11 +90,7 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -129,11 +105,7 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -148,11 +120,7 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -167,11 +135,7 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -186,11 +150,8 @@ const OVERLAY: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',q', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: true, @@ -209,11 +170,8 @@ const JINGLE: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -232,11 +190,7 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me2', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'f1,shift+ctrl+f1', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -251,12 +205,8 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me2', isRemoteInput: true, isGuestInput: false, - activateKeyboardHotkeys: 'ctrl+shift+alt+b,1,2,3', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, isSticky: false, stickyOriginalOnly: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -271,12 +221,8 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me2', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, stickyOriginalOnly: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -291,11 +237,7 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me1', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'f10,m,comma,.,n,c,b,v', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -310,11 +252,7 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me2', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -329,11 +267,8 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me2', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -348,11 +283,7 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: 'me2', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -367,11 +298,7 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -386,11 +313,7 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -405,11 +328,7 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'shift+f1,shift+1,shift+2,shift+3,shift+t', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: true, allowDisable: false, @@ -424,11 +343,7 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'ctrl+f1,ctrl+1,ctrl+2,ctrl+3,ctrl+alt+shift+g', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: true, allowDisable: false, @@ -443,11 +358,7 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: 'alt+shift+f1,alt+shift+1,alt+shift+2,alt+shift+3', isQueueable: false, isHidden: true, allowDisable: false, @@ -462,11 +373,7 @@ const PGM: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: true, allowDisable: false, @@ -486,11 +393,8 @@ const MUSIK: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: ',minus', - assignHotkeysToGlobalAdlibs: false, + isClearable: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -509,11 +413,7 @@ const MANUS: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -532,11 +432,7 @@ const SEC: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'q', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -551,11 +447,7 @@ const SEC: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'shift+a', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: true, allowDisable: false, @@ -570,11 +462,8 @@ const SEC: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'ctrl+shift+alt+e,ctrl+shift+alt+d', - clearKeyboardHotkey: ',', - assignHotkeysToGlobalAdlibs: true, + isClearable: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -589,11 +478,8 @@ const SEC: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: 'NumpadDivide,NumpadSubtract,NumpadAdd', - clearKeyboardHotkey: ',', - assignHotkeysToGlobalAdlibs: true, + isClearable: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -612,11 +498,7 @@ const SELECTED_ADLIB: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: true, isHidden: true, allowDisable: false, @@ -631,11 +513,7 @@ const SELECTED_ADLIB: ISourceLayer[] = [ exclusiveGroup: 'server', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: true, isHidden: true, allowDisable: false, @@ -650,11 +528,7 @@ const SELECTED_ADLIB: ISourceLayer[] = [ exclusiveGroup: 'server', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: true, isHidden: true, allowDisable: false, @@ -669,11 +543,7 @@ const SELECTED_ADLIB: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: true, isHidden: true, allowDisable: false, @@ -688,11 +558,7 @@ const SELECTED_ADLIB: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: false, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: true, isHidden: true, allowDisable: false, @@ -711,12 +577,8 @@ const AUX: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: - 'shift+ctrl+1,shift+ctrl+2,shift+ctrl+3,shift+ctrl+4,shift+ctrl+5,shift+ctrl+6,shift+ctrl+7,shift+ctrl+8,shift+ctrl+9,shift+ctrl+0,shift+ctrl+e', - clearKeyboardHotkey: ',', - assignHotkeysToGlobalAdlibs: true, + isClearable: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: false, allowDisable: false, @@ -731,11 +593,7 @@ const AUX: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: true, allowDisable: false, @@ -750,11 +608,7 @@ const AUX: ISourceLayer[] = [ exclusiveGroup: '', isRemoteInput: false, isGuestInput: false, - activateKeyboardHotkeys: '', - clearKeyboardHotkey: '', - assignHotkeysToGlobalAdlibs: true, isSticky: false, - activateStickyKeyboardHotkey: '', isQueueable: false, isHidden: true, allowDisable: false, diff --git a/src/tv2_offtube_showstyle/migrations/util.ts b/src/tv2_offtube_showstyle/migrations/util.ts index fcbafa608..08b14ee46 100644 --- a/src/tv2_offtube_showstyle/migrations/util.ts +++ b/src/tv2_offtube_showstyle/migrations/util.ts @@ -4,7 +4,7 @@ import { MigrationContextShowStyle, MigrationStepShowStyle, TableConfigItemValue -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { forceSourceLayerToDefaultsBase, literal } from 'tv2-common' import * as _ from 'underscore' import { showStyleConfigManifest } from '../config-manifests' diff --git a/src/tv2_offtube_showstyle/migrations/variants-defaults.ts b/src/tv2_offtube_showstyle/migrations/variants-defaults.ts index 24f45aa3c..2767d6458 100644 --- a/src/tv2_offtube_showstyle/migrations/variants-defaults.ts +++ b/src/tv2_offtube_showstyle/migrations/variants-defaults.ts @@ -1,4 +1,4 @@ -import { MigrationContextShowStyle, MigrationStepShowStyle } from '@sofie-automation/blueprints-integration' +import { MigrationContextShowStyle, MigrationStepShowStyle } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import * as _ from 'underscore' diff --git a/src/tv2_offtube_showstyle/onTimelineGenerate.ts b/src/tv2_offtube_showstyle/onTimelineGenerate.ts index 341980170..57411405b 100644 --- a/src/tv2_offtube_showstyle/onTimelineGenerate.ts +++ b/src/tv2_offtube_showstyle/onTimelineGenerate.ts @@ -6,7 +6,7 @@ import { PartEndState, TimelinePersistentState, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { disablePilotWipeAfterJingle, onTimelineGenerate, PartEndStateExt, TimelineBlueprintExt } from 'tv2-common' import { GraphicLLayer, TallyTags } from 'tv2-constants' import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' diff --git a/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts b/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts index b9c6f57c5..8f24745f2 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts @@ -6,7 +6,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddScript, literal, PartDefinitionDVE, PartTime } from 'tv2-common' import { CueType } from 'tv2-constants' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' diff --git a/src/tv2_offtube_showstyle/parts/OfftubeEffekt.ts b/src/tv2_offtube_showstyle/parts/OfftubeEffekt.ts index 55aff6753..b86c22f31 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeEffekt.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeEffekt.ts @@ -1,4 +1,4 @@ -import { IBlueprintPiece, IShowStyleUserContext } from '@sofie-automation/blueprints-integration' +import { IBlueprintPiece, IShowStyleUserContext } from '@tv2media/blueprints-integration' import { CreateEffektForPartBase, PartDefinition } from 'tv2-common' import { SharedSourceLayers } from 'tv2-constants' import { OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' diff --git a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts index 72eb7ce41..fa4867c0f 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts @@ -5,7 +5,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddScript, ApplyFullGraphicPropertiesToPart, literal, PartDefinition, PartTime } from 'tv2-common' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index 65adbd758..9a864c46f 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -11,7 +11,7 @@ import { TSR, VTContent, WithTimeline -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddParentClass, AddScript, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts index 778b54014..f3bd50ee3 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts @@ -3,7 +3,7 @@ import { HackPartMediaObjectSubscription, IBlueprintActionManifest, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddScript, CreateAdlibServer, CreatePartServerBase, PartDefinition, ServerPartProps } from 'tv2-common' import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' diff --git a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts index e377d3e83..8982511af 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts @@ -5,7 +5,7 @@ import { IBlueprintPart, IBlueprintPiece, ISegmentUserContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddScript, ApplyFullGraphicPropertiesToPart, diff --git a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts b/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts index 04e4437fd..fe1b658cb 100644 --- a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts @@ -6,7 +6,7 @@ import { TimelineObjectCoreExt, TimelineObjHoldMode, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { literal, TimelineBlueprintExt, TV2BlueprintConfig } from 'tv2-common' import { ControlClasses } from 'tv2-constants' import _ = require('underscore') diff --git a/src/tv2_offtube_showstyle/syncIngestUpdateToPartInstances.ts b/src/tv2_offtube_showstyle/syncIngestUpdateToPartInstances.ts index 5c15b7874..48a42652a 100644 --- a/src/tv2_offtube_showstyle/syncIngestUpdateToPartInstances.ts +++ b/src/tv2_offtube_showstyle/syncIngestUpdateToPartInstances.ts @@ -2,7 +2,7 @@ import { BlueprintSyncIngestNewData, BlueprintSyncIngestPartInstance, ISyncIngestUpdateToPartInstanceContext -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { syncIngestUpdateToPartInstanceBase } from 'tv2-common' import { OfftubeSourceLayer } from './layers' diff --git a/src/tv2_offtube_studio/config-manifests.ts b/src/tv2_offtube_studio/config-manifests.ts index a6ca0bf34..8bbd88cfb 100644 --- a/src/tv2_offtube_studio/config-manifests.ts +++ b/src/tv2_offtube_studio/config-manifests.ts @@ -4,7 +4,7 @@ import { ConfigManifestEntryType, TableConfigItemValue, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { DSKConfigManifest, literal, diff --git a/src/tv2_offtube_studio/getBaseline.ts b/src/tv2_offtube_studio/getBaseline.ts index 95de6e565..d20332296 100644 --- a/src/tv2_offtube_studio/getBaseline.ts +++ b/src/tv2_offtube_studio/getBaseline.ts @@ -4,7 +4,7 @@ import { BlueprintResultBaseline, IStudioContext, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import * as _ from 'underscore' import { AtemSourceIndex } from '../types/atem' diff --git a/src/tv2_offtube_studio/getShowStyleId.ts b/src/tv2_offtube_studio/getShowStyleId.ts index 7848aeb8c..1c2406d12 100644 --- a/src/tv2_offtube_studio/getShowStyleId.ts +++ b/src/tv2_offtube_studio/getShowStyleId.ts @@ -1,4 +1,4 @@ -import { IBlueprintShowStyleBase, IngestRundown, IStudioContext } from '@sofie-automation/blueprints-integration' +import { IBlueprintShowStyleBase, IngestRundown, IStudioContext } from '@tv2media/blueprints-integration' import * as _ from 'underscore' export function getShowStyleId( diff --git a/src/tv2_offtube_studio/helpers/config.ts b/src/tv2_offtube_studio/helpers/config.ts index 27623e342..d7be2b1c8 100644 --- a/src/tv2_offtube_studio/helpers/config.ts +++ b/src/tv2_offtube_studio/helpers/config.ts @@ -1,4 +1,4 @@ -import { IBlueprintConfig, ICommonContext } from '@sofie-automation/blueprints-integration' +import { IBlueprintConfig, ICommonContext } from '@tv2media/blueprints-integration' import { getLiveAudioLayers, getStickyLayers, diff --git a/src/tv2_offtube_studio/helpers/sources.ts b/src/tv2_offtube_studio/helpers/sources.ts index 2a1263efc..508aba378 100644 --- a/src/tv2_offtube_studio/helpers/sources.ts +++ b/src/tv2_offtube_studio/helpers/sources.ts @@ -1,6 +1,6 @@ import * as _ from 'underscore' -import { SourceLayerType } from '@sofie-automation/blueprints-integration' +import { SourceLayerType } from '@tv2media/blueprints-integration' import { ParseMappingTable, SourceInfo } from 'tv2-common' import { OfftubeStudioConfig } from './config' diff --git a/src/tv2_offtube_studio/index.ts b/src/tv2_offtube_studio/index.ts index 502c00a41..2c5ad9b55 100644 --- a/src/tv2_offtube_studio/index.ts +++ b/src/tv2_offtube_studio/index.ts @@ -1,4 +1,4 @@ -import { BlueprintManifestType, StudioBlueprintManifest } from '@sofie-automation/blueprints-integration' +import { BlueprintManifestType, StudioBlueprintManifest } from '@tv2media/blueprints-integration' import { GetStudioManifestWithMixins, StudioManifestMixinINews } from 'inews-mixins' import * as _ from 'underscore' import { studioConfigManifest } from './config-manifests' diff --git a/src/tv2_offtube_studio/migrations/devices.ts b/src/tv2_offtube_studio/migrations/devices.ts index 74dc8e7d1..d088ad397 100644 --- a/src/tv2_offtube_studio/migrations/devices.ts +++ b/src/tv2_offtube_studio/migrations/devices.ts @@ -4,7 +4,7 @@ import { MigrationStepInputFilteredResult, MigrationStepStudio, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import * as _ from 'underscore' diff --git a/src/tv2_offtube_studio/migrations/index.ts b/src/tv2_offtube_studio/migrations/index.ts index 1b722e8af..55274b6ca 100644 --- a/src/tv2_offtube_studio/migrations/index.ts +++ b/src/tv2_offtube_studio/migrations/index.ts @@ -3,7 +3,7 @@ import { MigrationStepStudio, TableConfigItemValue, TSR -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { AddKeepAudio, literal, diff --git a/src/tv2_offtube_studio/migrations/mappings-defaults.ts b/src/tv2_offtube_studio/migrations/mappings-defaults.ts index 7a29a8f41..a6a7884fc 100644 --- a/src/tv2_offtube_studio/migrations/mappings-defaults.ts +++ b/src/tv2_offtube_studio/migrations/mappings-defaults.ts @@ -1,4 +1,4 @@ -import { BlueprintMapping, BlueprintMappings, LookaheadMode, TSR } from '@sofie-automation/blueprints-integration' +import { BlueprintMapping, BlueprintMappings, LookaheadMode, TSR } from '@tv2media/blueprints-integration' import { AbstractLLayerServerEnable, CasparPlayerClip, diff --git a/src/tv2_offtube_studio/migrations/util.ts b/src/tv2_offtube_studio/migrations/util.ts index 27932bf3c..b2008b84d 100644 --- a/src/tv2_offtube_studio/migrations/util.ts +++ b/src/tv2_offtube_studio/migrations/util.ts @@ -5,7 +5,7 @@ import { MigrationStepInput, MigrationStepInputFilteredResult, MigrationStepStudio -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import * as _ from 'underscore' import { OfftubeSisyfosLLayer } from '../layers' diff --git a/src/tv2_system/index.ts b/src/tv2_system/index.ts index e23bbb70f..193a30923 100644 --- a/src/tv2_system/index.ts +++ b/src/tv2_system/index.ts @@ -1,4 +1,4 @@ -import { BlueprintManifestType, SystemBlueprintManifest } from '@sofie-automation/blueprints-integration' +import { BlueprintManifestType, SystemBlueprintManifest } from '@tv2media/blueprints-integration' import * as _ from 'underscore' declare const VERSION: string // Injected by webpack @@ -10,7 +10,8 @@ const manifest: SystemBlueprintManifest = { blueprintVersion: VERSION, integrationVersion: VERSION_INTEGRATION, - TSRVersion: VERSION_TSR + TSRVersion: VERSION_TSR, + coreMigrations: [] } export default manifest diff --git a/yarn.lock b/yarn.lock index 56f281d77..8d7fad741 100644 --- a/yarn.lock +++ b/yarn.lock @@ -287,7 +287,7 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@sofie-automation/blueprints-integration@npm:@tv2media/blueprints-integration@1.37.0-rc19": +"@tv2media/blueprints-integration@1.37.0-rc19": version "1.37.0-rc19" resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-1.37.0-rc19.tgz#b0899f1e017747dec24ab5f9188830345fe477eb" integrity sha512-ctKx/MHkHku4vINjw1mSqmEGHRBHl0nncGamPXgilLZhoSQDhAM0HOBTqZbznC22DATKK29Gh264VFTOKj6QJg== From 13059db8c26046ffeb4ca6002ad449818c532125 Mon Sep 17 00:00:00 2001 From: Tom Lee Date: Fri, 26 Nov 2021 16:34:25 +0000 Subject: [PATCH 006/184] feat: Action trigger migrations --- package.json | 2 +- src/tv2-common/content/dve.ts | 33 +- src/tv2-common/helpers/dsk.ts | 4 +- src/tv2-common/helpers/rundownAdLibActions.ts | 2 +- src/tv2-common/hotkeys/camera.ts | 30 ++ src/tv2-common/hotkeys/clear.ts | 57 +++ src/tv2-common/hotkeys/dve.ts | 83 ++++ src/tv2-common/hotkeys/global.ts | 262 +++++++++++ src/tv2-common/hotkeys/graphics.ts | 109 +++++ src/tv2-common/hotkeys/helpers/auxGraphics.ts | 65 +++ .../hotkeys/helpers/auxStudioScreen.ts | 65 +++ src/tv2-common/hotkeys/helpers/cutToBox.ts | 66 +++ src/tv2-common/hotkeys/helpers/directCut.ts | 65 +++ src/tv2-common/hotkeys/helpers/index.ts | 2 + src/tv2-common/hotkeys/helpers/queue.ts | 65 +++ .../hotkeys/helpers/studioSource.ts | 118 +++++ src/tv2-common/hotkeys/hotkey-defaults.ts | 226 +++++++++ src/tv2-common/hotkeys/index.ts | 45 ++ src/tv2-common/hotkeys/local.ts | 53 +++ src/tv2-common/hotkeys/remote.ts | 31 ++ src/tv2-common/hotkeys/rundownView.ts | 362 +++++++++++++++ src/tv2-common/hotkeys/segment.ts | 85 ++++ src/tv2-common/hotkeys/server.ts | 61 +++ src/tv2-common/hotkeys/sisyfos.ts | 100 ++++ src/tv2-common/index.ts | 29 +- src/tv2-common/migrations/hotkeys.ts | 117 +++++ src/tv2-common/migrations/index.ts | 3 +- src/tv2-constants/enums.ts | 39 +- src/tv2_afvd_showstyle/config-manifests.ts | 216 ++++++--- src/tv2_afvd_showstyle/getRundown.ts | 66 ++- src/tv2_afvd_showstyle/helpers/content/dve.ts | 16 +- src/tv2_afvd_showstyle/migrations/hotkeys.ts | 38 ++ src/tv2_afvd_showstyle/migrations/index.ts | 44 +- .../migrations/sourcelayer-defaults.ts | 65 --- src/tv2_offtube_showstyle/config-manifests.ts | 216 ++++++--- .../content/OfftubeDVEContent.ts | 9 +- src/tv2_offtube_showstyle/getRundown.ts | 75 +-- .../migrations/hotkeys.ts | 37 ++ src/tv2_offtube_showstyle/migrations/index.ts | 32 +- .../migrations/sourcelayer-defaults.ts | 60 --- src/tv2_system/index.ts | 3 +- src/tv2_system/migrations/hotkeys.ts | 432 ++++++++++++++++++ src/tv2_system/migrations/index.ts | 9 + 43 files changed, 3069 insertions(+), 428 deletions(-) create mode 100644 src/tv2-common/hotkeys/camera.ts create mode 100644 src/tv2-common/hotkeys/clear.ts create mode 100644 src/tv2-common/hotkeys/dve.ts create mode 100644 src/tv2-common/hotkeys/global.ts create mode 100644 src/tv2-common/hotkeys/graphics.ts create mode 100644 src/tv2-common/hotkeys/helpers/auxGraphics.ts create mode 100644 src/tv2-common/hotkeys/helpers/auxStudioScreen.ts create mode 100644 src/tv2-common/hotkeys/helpers/cutToBox.ts create mode 100644 src/tv2-common/hotkeys/helpers/directCut.ts create mode 100644 src/tv2-common/hotkeys/helpers/index.ts create mode 100644 src/tv2-common/hotkeys/helpers/queue.ts create mode 100644 src/tv2-common/hotkeys/helpers/studioSource.ts create mode 100644 src/tv2-common/hotkeys/hotkey-defaults.ts create mode 100644 src/tv2-common/hotkeys/index.ts create mode 100644 src/tv2-common/hotkeys/local.ts create mode 100644 src/tv2-common/hotkeys/remote.ts create mode 100644 src/tv2-common/hotkeys/rundownView.ts create mode 100644 src/tv2-common/hotkeys/segment.ts create mode 100644 src/tv2-common/hotkeys/server.ts create mode 100644 src/tv2-common/hotkeys/sisyfos.ts create mode 100644 src/tv2-common/migrations/hotkeys.ts create mode 100644 src/tv2_afvd_showstyle/migrations/hotkeys.ts create mode 100644 src/tv2_offtube_showstyle/migrations/hotkeys.ts create mode 100644 src/tv2_system/migrations/hotkeys.ts create mode 100644 src/tv2_system/migrations/index.ts diff --git a/package.json b/package.json index e450cb5de..a23be3059 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tv2-sofie-blueprints-inews", - "version": "1.6.9", + "version": "1.7.0", "repository": "https://github.com/olzzon/tv2-sofie-blueprints-inews", "license": "MIT", "private": true, diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 75b080e07..bd03e7f06 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -126,12 +126,6 @@ export interface DVEOptions { dveLayers: DVELayers dveTimelineGenerators: DVETimelineObjectGenerators boxMappings: [string, string, string, string] - boxLayers: { - INP1: string - INP2: string - INP3: string - INP4: string - } /** All audio layers */ AUDIO_LAYERS: string[] /** Layers to exclude from filter */ @@ -219,7 +213,7 @@ export function MakeContentDVE2< const inputs = dveConfig.DVEInputs ? dveConfig.DVEInputs.toString().split(';') : '1:INP1;2:INP2;3:INP3;4:INP4'.split(';') - const boxMap: Array<{ source: string; sourceLayer: string }> = [] + const boxMap: Array<{ source: string }> = [] const classes: string[] = [] @@ -232,8 +226,7 @@ export function MakeContentDVE2< return } - const sourceLayer = dveGeneratorOptions.boxLayers[fromCue as keyof DVESources] as string - classes.push(`${sourceLayer}_${dveGeneratorOptions.boxMappings[targetBox - 1]}`) + classes.push(`${fromCue.replace(/\s/g, '')}_${dveGeneratorOptions.boxMappings[targetBox - 1]}`) let usedServer = false @@ -242,42 +235,42 @@ export function MakeContentDVE2< if (prop?.match(/[K|C]AM(?:era)? ?.*/i)) { const match = prop.match(/[K|C]AM(?:era)? ?(.*)/i) as RegExpExecArray - boxMap[targetBox - 1] = { source: `KAM ${match[1]}`, sourceLayer } + boxMap[targetBox - 1] = { source: `KAM ${match[1]}` } } else if (prop?.match(/LIVE ?.*/i)) { const match = prop.match(/LIVE ?(.*)/i) as RegExpExecArray - boxMap[targetBox - 1] = { source: `LIVE ${match[1]}`, sourceLayer } + boxMap[targetBox - 1] = { source: `LIVE ${match[1]}` } } else if (prop?.match(/FEED ?.*/i)) { const match = prop.match(/FEED ?(.*)/i) as RegExpExecArray - boxMap[targetBox - 1] = { source: `FEED ${match[1]}`, sourceLayer } + boxMap[targetBox - 1] = { source: `FEED ${match[1]}` } } else if (prop?.match(/full/i)) { - boxMap[targetBox - 1] = { source: `ENGINE FULL`, sourceLayer } + boxMap[targetBox - 1] = { source: `ENGINE FULL` } } else if (prop?.match(/EVS ?(?:\d+)? ?.*/i)) { const match = prop.match(/EVS ?(\d+)? ?(.*)/i) as RegExpExecArray - boxMap[targetBox - 1] = { source: `EVS${match[1]} ${match[2]}`, sourceLayer } + boxMap[targetBox - 1] = { source: `EVS${match[1]} ${match[2]}` } } else if (prop?.match(/DEFAULT/)) { - boxMap[targetBox - 1] = { source: `DEFAULT SOURCE`, sourceLayer } + boxMap[targetBox - 1] = { source: `DEFAULT SOURCE` } } else if (prop) { if (videoId && !usedServer) { - boxMap[targetBox - 1] = { source: `SERVER ${videoId}`, sourceLayer } + boxMap[targetBox - 1] = { source: `SERVER ${videoId}` } usedServer = true } else { - boxMap[targetBox - 1] = { source: prop, sourceLayer } + boxMap[targetBox - 1] = { source: prop } } } else { if (videoId && !usedServer) { - boxMap[targetBox - 1] = { source: `SERVER ${videoId}`, sourceLayer } + boxMap[targetBox - 1] = { source: `SERVER ${videoId}` } usedServer = true } else { context.notifyUserWarning(`Missing mapping for ${targetBox}`) - boxMap[targetBox - 1] = { source: '', sourceLayer } + boxMap[targetBox - 1] = { source: '' } } } } else { // Need something to keep the layout etc - boxMap[targetBox - 1] = { source: '', sourceLayer } + boxMap[targetBox - 1] = { source: '' } } }) diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index 7d2d7e4ad..d84d33efc 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -94,7 +94,7 @@ export function CreateDSKBaselineAdlibs( sourceLayerId: SourceLayerAtemDSK(dsk.Number), outputLayerId: SharedOutputLayers.SEC, lifespan: PieceLifespan.OutOnRundownChange, - tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_NO_NEXT_HIGHLIGHT], + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_NO_NEXT_HIGHLIGHT, AdlibTags.ADLIB_DSK_OFF], invertOnAirState: true, content: { timelineObjects: [ @@ -122,7 +122,7 @@ export function CreateDSKBaselineAdlibs( sourceLayerId: SourceLayerAtemDSK(dsk.Number), outputLayerId: SharedOutputLayers.SEC, lifespan: PieceLifespan.OutOnRundownChange, - tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_NO_NEXT_HIGHLIGHT], + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_NO_NEXT_HIGHLIGHT, AdlibTags.ADLIB_DSK_ON], content: { timelineObjects: [ literal({ diff --git a/src/tv2-common/helpers/rundownAdLibActions.ts b/src/tv2-common/helpers/rundownAdLibActions.ts index 45412f590..ae1189b30 100644 --- a/src/tv2-common/helpers/rundownAdLibActions.ts +++ b/src/tv2-common/helpers/rundownAdLibActions.ts @@ -139,7 +139,7 @@ function makeTransitionAction( label: t(isEffekt ? `EFFEKT ${label}` : label), sourceLayerId: SharedSourceLayers.PgmAdlibJingle, outputLayerId: SharedOutputLayers.PGM, - tags: [AdlibTags.ADLIB_STATIC_BUTTON], + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_TAKE_WITH_TRANSITION], currentPieceTags: [tag], nextPieceTags: [tag], content: diff --git a/src/tv2-common/hotkeys/camera.ts b/src/tv2-common/hotkeys/camera.ts new file mode 100644 index 000000000..94139e9b0 --- /dev/null +++ b/src/tv2-common/hotkeys/camera.ts @@ -0,0 +1,30 @@ +import { IBlueprintTriggeredActions } from '@tv2media/blueprints-integration' +import { MakeStudioSourceHotkeys, SourceHotkeyTriggers } from './helpers' + +export type CameraHotkeyAssignments = SourceHotkeyTriggers + +function cameraHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { + return `${showStyleId}_${sourceLayer}_camera_${hotkeyType}_${index}` +} + +function cameraHotkeyName(camera: string) { + return `KAM ${camera}` +} + +export function MakeCameraHotkeys( + showStyleId: string, + sourceLayerId: string, + cameras: string[], + assignments: CameraHotkeyAssignments, + getNextRank: () => number +): IBlueprintTriggeredActions[] { + return MakeStudioSourceHotkeys( + showStyleId, + sourceLayerId, + cameras, + assignments, + getNextRank, + cameraHotkeyName, + cameraHotkeyId + ) +} diff --git a/src/tv2-common/hotkeys/clear.ts b/src/tv2-common/hotkeys/clear.ts new file mode 100644 index 000000000..0451c7a42 --- /dev/null +++ b/src/tv2-common/hotkeys/clear.ts @@ -0,0 +1,57 @@ +import { + IAdLibFilterLink, + IAdlibPlayoutAction, + IBlueprintHotkeyTrigger, + IBlueprintTriggeredActions, + IGUIContextFilterLink, + PlayoutActions, + TriggerType +} from '@tv2media/blueprints-integration' +import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' + +export type ClearLayerHotkeyAssignments = Array<{ sourceLayers: string[]; key: string; name: string }> + +function clearSourceLayerHotKeyId(showStyleId: string, sourceLayers: string[]) { + return `${showStyleId}_clear_sourcelayer_${sourceLayers.join(',')}` +} + +export function MakeClearHotkeys( + showStyleId: string, + assignments: ClearLayerHotkeyAssignments, + getNextRank: () => number +) { + return assignments.map(clearedSourceLayer => + literal({ + _id: clearSourceLayerHotKeyId(showStyleId, clearedSourceLayer.sourceLayers), + _rank: getNextRank(), + name: clearedSourceLayer.name, + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: clearedSourceLayer.key, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: PlayoutActions.adlib, + filterChain: [ + literal({ + object: 'view' + }), + literal({ + object: 'adLib', + field: 'sourceLayerId', + value: clearedSourceLayer.sourceLayers + }), + literal({ + object: 'adLib', + field: 'type', + value: 'clear' + }) + ] + }) + ] + }) + ) +} diff --git a/src/tv2-common/hotkeys/dve.ts b/src/tv2-common/hotkeys/dve.ts new file mode 100644 index 000000000..0e8e4f3ba --- /dev/null +++ b/src/tv2-common/hotkeys/dve.ts @@ -0,0 +1,83 @@ +import { + IAdLibFilterLink, + IAdlibPlayoutAction, + IBlueprintHotkeyTrigger, + IBlueprintTriggeredActions, + IGUIContextFilterLink, + PlayoutActions, + TriggerType +} from '@tv2media/blueprints-integration' +import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' +import { AdlibTags } from 'tv2-constants' + +export interface DVEHotkeyAssignments { + sommerfugl: string + morbarn: string + barnmor: string + barnMorIpad: string + '3split': string + '3barnMor': string + '2barnMor': string +} + +function dveHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { + return `${showStyleId}_${sourceLayer}_dve_layout_${hotkeyType}_${index}` +} + +export function MakeDVELayoutHotkeys( + showStyleId: string, + sourceLayerId: string, + dveLayouts: string[], + assignments: DVEHotkeyAssignments, + getNextRank: () => number +) { + return dveLayouts.map((layout, index) => { + // Try to fetch the hotkey by name, otherwise we'll create a blank trigger for unknown layouts + const hotkey = assignments[layout as keyof typeof assignments] as string | undefined + + return literal({ + _id: dveHotkeyId(showStyleId, sourceLayerId, layout, index), + _rank: getNextRank(), + name: layout, + triggers: hotkey + ? [ + literal({ + type: TriggerType.hotkey, + keys: hotkey, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ] + : [], + actions: [ + literal({ + action: PlayoutActions.adlib, + filterChain: [ + literal({ + object: 'view' + }), + literal({ + object: 'adLib', + field: 'sourceLayerId', + value: [sourceLayerId] + }), + literal({ + object: 'adLib', + field: 'global', + value: true + }), + literal({ + object: 'adLib', + field: 'tag', + value: [AdlibTags.ADLIB_SELECT_DVE_LAYOUT, layout] + }), + literal({ + object: 'adLib', + field: 'pick', + value: 0 + }) + ] + }) + ] + }) + }) +} diff --git a/src/tv2-common/hotkeys/global.ts b/src/tv2-common/hotkeys/global.ts new file mode 100644 index 000000000..f71735dd9 --- /dev/null +++ b/src/tv2-common/hotkeys/global.ts @@ -0,0 +1,262 @@ +import { + IAdLibFilterLink, + IAdlibPlayoutAction, + IBlueprintHotkeyTrigger, + IBlueprintTriggeredActions, + IGUIContextFilterLink, + PlayoutActions, + TriggerType +} from '@tv2media/blueprints-integration' +import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' +import { AdlibTags, SharedSourceLayers } from 'tv2-constants' +import { CameraHotkeyAssignments, MakeCameraHotkeys } from './camera' +import { ClearLayerHotkeyAssignments, MakeClearHotkeys } from './clear' +import { DVEHotkeyAssignments, MakeDVELayoutHotkeys } from './dve' +import { GraphicsHotkeyAssignemnts, MakeGraphicsHotkeys } from './graphics' +import { LocalSourceHotkeyAssignments, MakeLocalSourceHotkeys } from './local' +import { MakeRemoteHotkeys, RemoteSourceHotkeyAssignments } from './remote' +import { MakeServerHotkeys, ServerHotkeyAssignments } from './server' +import { MakeSisyfosHotkeys, SisyfosHotkeyAssignments } from './sisyfos' + +export interface GlobalHotkeyAssignments { + recallLast: { + DVE: string + Live: string + } + takeWithTransition: string[] + camera: CameraHotkeyAssignments + clear: ClearLayerHotkeyAssignments + dve: DVEHotkeyAssignments + graphics: GraphicsHotkeyAssignemnts + local: LocalSourceHotkeyAssignments + remote: RemoteSourceHotkeyAssignments + feed: RemoteSourceHotkeyAssignments + server: ServerHotkeyAssignments + sisyfos: SisyfosHotkeyAssignments +} + +export interface GlobalHotkeySourceLayers { + local?: string +} + +export interface GlobalHotkeySources { + camera: string[] + remote: string[] + feed: string[] + local: string[] + dveLayouts: string[] +} + +export function MakeGlobalTriggers( + showStyleId: string, + assignments: GlobalHotkeyAssignments, + sources: GlobalHotkeySources, + layers: GlobalHotkeySourceLayers, + getNextRank: () => number +): IBlueprintTriggeredActions[] { + const cameraTriggers = MakeCameraHotkeys( + showStyleId, + SharedSourceLayers.PgmCam, + sources.camera, + assignments.camera, + getNextRank + ) + const remoteTriggers = MakeRemoteHotkeys( + showStyleId, + SharedSourceLayers.PgmLive, + sources.remote, + assignments.remote, + getNextRank + ) + const feedTriggers = MakeRemoteHotkeys( + showStyleId, + SharedSourceLayers.PgmLive, + sources.feed, + assignments.feed, + getNextRank + ) + const localTriggers = layers.local + ? MakeLocalSourceHotkeys(showStyleId, layers.local, sources.local, assignments.local, getNextRank) + : [] + + const dveTriggers = MakeDVELayoutHotkeys( + showStyleId, + SharedSourceLayers.PgmDVEAdLib, + sources.dveLayouts, + assignments.dve, + getNextRank + ) + const serverTriggers = MakeServerHotkeys(showStyleId, SharedSourceLayers.PgmServer, getNextRank) + const graphicsTriggers = MakeGraphicsHotkeys( + showStyleId, + SharedSourceLayers.PgmAdlibGraphicCmd, + assignments.graphics, + getNextRank + ) + + const clearTriggers = MakeClearHotkeys(showStyleId, assignments.clear, getNextRank) + const sisyfosTriggers = MakeSisyfosHotkeys( + showStyleId, + SharedSourceLayers.PgmSisyfosAdlibs, + assignments.sisyfos, + getNextRank + ) + const recallLastTriggers = [ + makeRecallLastTrigger( + SharedSourceLayers.PgmDVE, + getNextRank, + recallLastHotkeyId(showStyleId, SharedSourceLayers.PgmDVE, 'dve', 0), + 'Last DVE', + assignments.recallLast.DVE, + [AdlibTags.ADLIB_RECALL_LAST_DVE] + ), + makeRecallLastTrigger( + SharedSourceLayers.PgmLive, + getNextRank, + recallLastHotkeyId(showStyleId, SharedSourceLayers.PgmLive, 'live', 0), + 'Last Live', + assignments.recallLast.DVE, + [AdlibTags.ADLIB_RECALL_LAST_LIVE] + ) + ] + const takeWithTransitionTriggers = assignments.takeWithTransition.map((key, index) => + makeTakeWithTransitionTrigger( + SharedSourceLayers.PgmAdlibJingle, + getNextRank, + takeWithTransitionHotkeyId(showStyleId, SharedSourceLayers.PgmAdlibJingle, key, index), + `Take with transition ${index + 1}`, + key, + index + ) + ) + + return [ + ...cameraTriggers, + ...remoteTriggers, + ...feedTriggers, + ...localTriggers, + ...dveTriggers, + ...serverTriggers, + ...graphicsTriggers, + ...clearTriggers, + ...sisyfosTriggers, + ...recallLastTriggers, + ...takeWithTransitionTriggers + ] +} + +function recallLastHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { + return `${showStyleId}_${sourceLayer}_recall_last_${hotkeyType}_${index}` +} + +function makeRecallLastTrigger( + sourceLayerId: string, + getNextRank: () => number, + id: string, + name: string, + hotkey: string | undefined, + tags: string[] +) { + return literal({ + _id: id, + _rank: getNextRank(), + name, + triggers: hotkey + ? [ + literal({ + type: TriggerType.hotkey, + keys: hotkey, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ] + : [], + actions: [ + literal({ + action: PlayoutActions.adlib, + filterChain: [ + literal({ + object: 'view' + }), + literal({ + object: 'adLib', + field: 'sourceLayerId', + value: [sourceLayerId] + }), + literal({ + object: 'adLib', + field: 'global', + value: true + }), + literal({ + object: 'adLib', + field: 'tag', + value: tags + }), + literal({ + object: 'adLib', + field: 'pick', + value: 0 + }) + ] + }) + ] + }) +} + +function takeWithTransitionHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { + return `${showStyleId}_${sourceLayer}_take_with_transition_${hotkeyType}_${index}` +} + +function makeTakeWithTransitionTrigger( + sourceLayerId: string, + getNextRank: () => number, + id: string, + name: string, + hotkey: string | undefined, + pick: number +) { + return literal({ + _id: id, + _rank: getNextRank(), + name, + triggers: hotkey + ? [ + literal({ + type: TriggerType.hotkey, + keys: hotkey, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ] + : [], + actions: [ + literal({ + action: PlayoutActions.adlib, + filterChain: [ + literal({ + object: 'view' + }), + literal({ + object: 'adLib', + field: 'sourceLayerId', + value: [sourceLayerId] + }), + literal({ + object: 'adLib', + field: 'global', + value: true + }), + literal({ + object: 'adLib', + field: 'tag', + value: [AdlibTags.ADLIB_TAKE_WITH_TRANSITION] + }), + literal({ + object: 'adLib', + field: 'pick', + value: pick + }) + ] + }) + ] + }) +} diff --git a/src/tv2-common/hotkeys/graphics.ts b/src/tv2-common/hotkeys/graphics.ts new file mode 100644 index 000000000..1c28e1d75 --- /dev/null +++ b/src/tv2-common/hotkeys/graphics.ts @@ -0,0 +1,109 @@ +import { + IAdLibFilterLink, + IAdlibPlayoutAction, + IBlueprintHotkeyTrigger, + IBlueprintTriggeredActions, + IGUIContextFilterLink, + PlayoutActions, + TriggerType +} from '@tv2media/blueprints-integration' +import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' +import { AdlibTags } from 'tv2-constants' + +export interface GraphicsHotkeyAssignemnts { + altud: string + designSc: string + gfxContinue: string +} + +function graphicsHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { + return `${showStyleId}_${sourceLayer}_graphics_${hotkeyType}_${index}` +} + +export function MakeGraphicsHotkeys( + showStyleId: string, + sourceLayerId: string, + assignments: GraphicsHotkeyAssignemnts, + getNextRank: () => number +) { + return [ + makeGraphicsGlobalHotKey( + sourceLayerId, + getNextRank, + graphicsHotkeyId(showStyleId, sourceLayerId, 'alt_ud', 0), + 'overlay ALT UD', + assignments.altud, + [AdlibTags.ADLIB_GFX_ALTUD] + ), + makeGraphicsGlobalHotKey( + sourceLayerId, + getNextRank, + graphicsHotkeyId(showStyleId, sourceLayerId, 'design_sc', 0), + 'Design Style SC', + assignments.designSc, + [AdlibTags.ADLIB_DESIGN_STYLE_SC] + ), + makeGraphicsGlobalHotKey( + sourceLayerId, + getNextRank, + graphicsHotkeyId(showStyleId, sourceLayerId, 'gfx_continue', 0), + 'GFX Continue', + assignments.gfxContinue, + [AdlibTags.ADLIB_GFX_CONTINUE_FORWARD] + ) + ] +} + +function makeGraphicsGlobalHotKey( + sourceLayerId: string, + getNextRank: () => number, + id: string, + name: string, + hotkey: string | undefined, + tags: string[] +) { + return literal({ + _id: id, + _rank: getNextRank(), + name, + triggers: hotkey + ? [ + literal({ + type: TriggerType.hotkey, + keys: hotkey, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ] + : [], + actions: [ + literal({ + action: PlayoutActions.adlib, + filterChain: [ + literal({ + object: 'view' + }), + literal({ + object: 'adLib', + field: 'sourceLayerId', + value: [sourceLayerId] + }), + literal({ + object: 'adLib', + field: 'global', + value: true + }), + literal({ + object: 'adLib', + field: 'tag', + value: tags + }), + literal({ + object: 'adLib', + field: 'pick', + value: 0 + }) + ] + }) + ] + }) +} diff --git a/src/tv2-common/hotkeys/helpers/auxGraphics.ts b/src/tv2-common/hotkeys/helpers/auxGraphics.ts new file mode 100644 index 000000000..18e20427c --- /dev/null +++ b/src/tv2-common/hotkeys/helpers/auxGraphics.ts @@ -0,0 +1,65 @@ +import { + IAdLibFilterLink, + IAdlibPlayoutAction, + IBlueprintHotkeyTrigger, + IBlueprintTriggeredActions, + IGUIContextFilterLink, + PlayoutActions, + TriggerType +} from '@tv2media/blueprints-integration' +import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' +import { AdlibTags } from 'tv2-constants' + +export function MakeRouteToGraphicsEngineTrigger( + id: string, + getNextRank: () => number, + name: string, + hotkey: string | undefined, + sourceLayerId: string, + pick: number +) { + return literal({ + _id: id, + _rank: getNextRank(), + name, + triggers: hotkey + ? [ + literal({ + type: TriggerType.hotkey, + keys: hotkey, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ] + : [], + actions: [ + literal({ + action: PlayoutActions.adlib, + filterChain: [ + literal({ + object: 'view' + }), + literal({ + object: 'adLib', + field: 'sourceLayerId', + value: [sourceLayerId] + }), + literal({ + object: 'adLib', + field: 'global', + value: true + }), + literal({ + object: 'adLib', + field: 'tag', + value: [AdlibTags.ADLIB_TO_GRAPHICS_ENGINE_AUX] + }), + literal({ + object: 'adLib', + field: 'pick', + value: pick + }) + ] + }) + ] + }) +} diff --git a/src/tv2-common/hotkeys/helpers/auxStudioScreen.ts b/src/tv2-common/hotkeys/helpers/auxStudioScreen.ts new file mode 100644 index 000000000..6fa970b58 --- /dev/null +++ b/src/tv2-common/hotkeys/helpers/auxStudioScreen.ts @@ -0,0 +1,65 @@ +import { + IAdLibFilterLink, + IAdlibPlayoutAction, + IBlueprintHotkeyTrigger, + IBlueprintTriggeredActions, + IGUIContextFilterLink, + PlayoutActions, + TriggerType +} from '@tv2media/blueprints-integration' +import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' +import { AdlibTags } from 'tv2-constants' + +export function MakeRouteToStudioScreenTrigger( + id: string, + getNextRank: () => number, + name: string, + hotkey: string | undefined, + sourceLayerId: string, + pick: number +) { + return literal({ + _id: id, + _rank: getNextRank(), + name, + triggers: hotkey + ? [ + literal({ + type: TriggerType.hotkey, + keys: hotkey, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ] + : [], + actions: [ + literal({ + action: PlayoutActions.adlib, + filterChain: [ + literal({ + object: 'view' + }), + literal({ + object: 'adLib', + field: 'sourceLayerId', + value: [sourceLayerId] + }), + literal({ + object: 'adLib', + field: 'global', + value: true + }), + literal({ + object: 'adLib', + field: 'tag', + value: [AdlibTags.ADLIB_TO_STUDIO_SCREEN_AUX] + }), + literal({ + object: 'adLib', + field: 'pick', + value: pick + }) + ] + }) + ] + }) +} diff --git a/src/tv2-common/hotkeys/helpers/cutToBox.ts b/src/tv2-common/hotkeys/helpers/cutToBox.ts new file mode 100644 index 000000000..455f98de2 --- /dev/null +++ b/src/tv2-common/hotkeys/helpers/cutToBox.ts @@ -0,0 +1,66 @@ +import { + IAdLibFilterLink, + IAdlibPlayoutAction, + IBlueprintHotkeyTrigger, + IBlueprintTriggeredActions, + IGUIContextFilterLink, + PlayoutActions, + TriggerType +} from '@tv2media/blueprints-integration' +import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' +import { AdlibTagCutToBox } from 'tv2-constants' + +export function MakeCutToBoxTrigger( + id: string, + getNextRank: () => number, + name: string, + hotkey: string | undefined, + sourceLayerId: string, + pick: number, + box: number +) { + return literal({ + _id: id, + _rank: getNextRank(), + name, + triggers: hotkey + ? [ + literal({ + type: TriggerType.hotkey, + keys: hotkey, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ] + : [], + actions: [ + literal({ + action: PlayoutActions.adlib, + filterChain: [ + literal({ + object: 'view' + }), + literal({ + object: 'adLib', + field: 'sourceLayerId', + value: [sourceLayerId] + }), + literal({ + object: 'adLib', + field: 'global', + value: true + }), + literal({ + object: 'adLib', + field: 'tag', + value: [AdlibTagCutToBox(box)] + }), + literal({ + object: 'adLib', + field: 'pick', + value: pick + }) + ] + }) + ] + }) +} diff --git a/src/tv2-common/hotkeys/helpers/directCut.ts b/src/tv2-common/hotkeys/helpers/directCut.ts new file mode 100644 index 000000000..25a251471 --- /dev/null +++ b/src/tv2-common/hotkeys/helpers/directCut.ts @@ -0,0 +1,65 @@ +import { + IAdLibFilterLink, + IAdlibPlayoutAction, + IBlueprintHotkeyTrigger, + IBlueprintTriggeredActions, + IGUIContextFilterLink, + PlayoutActions, + TriggerType +} from '@tv2media/blueprints-integration' +import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' +import { AdlibTags } from 'tv2-constants' + +export function MakeDirectCutTrigger( + id: string, + getNextRank: () => number, + name: string, + hotkey: string | undefined, + sourceLayerId: string, + pick: number +) { + return literal({ + _id: id, + _rank: getNextRank(), + name, + triggers: hotkey + ? [ + literal({ + type: TriggerType.hotkey, + keys: hotkey, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ] + : [], // Not enough known hotkeys -> create a blank trigger as a placeholder to be assigned later + actions: [ + literal({ + action: PlayoutActions.adlib, + filterChain: [ + literal({ + object: 'view' + }), + literal({ + object: 'adLib', + field: 'sourceLayerId', + value: [sourceLayerId] + }), + literal({ + object: 'adLib', + field: 'global', + value: true + }), + literal({ + object: 'adLib', + field: 'tag', + value: [AdlibTags.ADLIB_CUT_DIRECT] + }), + literal({ + object: 'adLib', + field: 'pick', + value: pick + }) + ] + }) + ] + }) +} diff --git a/src/tv2-common/hotkeys/helpers/index.ts b/src/tv2-common/hotkeys/helpers/index.ts new file mode 100644 index 000000000..3e6bc6165 --- /dev/null +++ b/src/tv2-common/hotkeys/helpers/index.ts @@ -0,0 +1,2 @@ +export * from './studioSource' +export { MakeCutToBoxTrigger } from './cutToBox' diff --git a/src/tv2-common/hotkeys/helpers/queue.ts b/src/tv2-common/hotkeys/helpers/queue.ts new file mode 100644 index 000000000..f728c66c2 --- /dev/null +++ b/src/tv2-common/hotkeys/helpers/queue.ts @@ -0,0 +1,65 @@ +import { + IAdLibFilterLink, + IAdlibPlayoutAction, + IBlueprintHotkeyTrigger, + IBlueprintTriggeredActions, + IGUIContextFilterLink, + PlayoutActions, + TriggerType +} from '@tv2media/blueprints-integration' +import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' +import { AdlibTags } from 'tv2-constants' + +export function MakeQueueTrigger( + id: string, + getNextRank: () => number, + name: string, + hotkey: string | undefined, + sourceLayerId: string, + pick: number +) { + return literal({ + _id: id, + _rank: getNextRank(), + name, + triggers: hotkey + ? [ + literal({ + type: TriggerType.hotkey, + keys: hotkey, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ] + : [], + actions: [ + literal({ + action: PlayoutActions.adlib, + filterChain: [ + literal({ + object: 'view' + }), + literal({ + object: 'adLib', + field: 'sourceLayerId', + value: [sourceLayerId] + }), + literal({ + object: 'adLib', + field: 'global', + value: true + }), + literal({ + object: 'adLib', + field: 'tag', + value: [AdlibTags.ADLIB_QUEUE_NEXT] + }), + literal({ + object: 'adLib', + field: 'pick', + value: pick + }) + ] + }) + ] + }) +} diff --git a/src/tv2-common/hotkeys/helpers/studioSource.ts b/src/tv2-common/hotkeys/helpers/studioSource.ts new file mode 100644 index 000000000..e4ee86d40 --- /dev/null +++ b/src/tv2-common/hotkeys/helpers/studioSource.ts @@ -0,0 +1,118 @@ +import { IBlueprintTriggeredActions } from '@tv2media/blueprints-integration' +import { MakeRouteToGraphicsEngineTrigger } from './auxGraphics' +import { MakeRouteToStudioScreenTrigger } from './auxStudioScreen' +import { MakeCutToBoxTrigger } from './cutToBox' +import { MakeDirectCutTrigger } from './directCut' +import { MakeQueueTrigger } from './queue' + +export interface SourceHotkeyTriggers { + directCut: string[] + queue: string[] + cutToBox: DVEBoxTriggers + routeToStudioScreen: string[] + routeToGraphicsEngine: string[] +} + +export type DVEBoxTriggers = [string[], string[], string[], string[]] + +export function MakeStudioSourceHotkeys( + showStyleId: string, + sourceLayerId: string, + sources: string[], + hotkeys: SourceHotkeyTriggers, + getNextRank: () => number, + nameFunc: (source: string) => string, + idFunc: (showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) => string +): IBlueprintTriggeredActions[] { + const directCutHotkeys: IBlueprintTriggeredActions[] = [] + const queueHotkeys: IBlueprintTriggeredActions[] = [] + const cutToBoxHotkeys: IBlueprintTriggeredActions[] = [] + const toAuxStudioScreenHotkeys: IBlueprintTriggeredActions[] = [] + const toAuxGraphicsEngineHotkeys: IBlueprintTriggeredActions[] = [] + + for (const [currentSourceIndex, source] of sources.entries()) { + const name = nameFunc(source) + + // If any are assigned, assign all + if (hotkeys.directCut.length) { + const directHotkey = hotkeys.directCut[currentSourceIndex] + directCutHotkeys.push( + MakeDirectCutTrigger( + idFunc(showStyleId, sourceLayerId, 'cut_direct', currentSourceIndex), + getNextRank, + name, + directHotkey, + sourceLayerId, + currentSourceIndex + ) + ) + } + + if (hotkeys.queue.length) { + const queueHotkey = hotkeys.queue[currentSourceIndex] + queueHotkeys.push( + MakeQueueTrigger( + idFunc(showStyleId, sourceLayerId, 'queue', currentSourceIndex), + getNextRank, + name, + queueHotkey, + sourceLayerId, + currentSourceIndex + ) + ) + } + + for (let box = 0; box < hotkeys.cutToBox.length; box++) { + if (hotkeys.cutToBox[box].length) { + const boxHotkey = hotkeys.cutToBox[box][currentSourceIndex] + cutToBoxHotkeys.push( + MakeCutToBoxTrigger( + idFunc(showStyleId, sourceLayerId, `cut_to_box_${box + 1}`, currentSourceIndex), + getNextRank, + name + ` inp ${box + 1}`, + boxHotkey, + sourceLayerId, + currentSourceIndex, + box + ) + ) + } + } + + if (hotkeys.routeToStudioScreen.length) { + const toStudioScreenHotkey = hotkeys.routeToStudioScreen[currentSourceIndex] + toAuxStudioScreenHotkeys.push( + MakeRouteToStudioScreenTrigger( + idFunc(showStyleId, sourceLayerId, `studio_screen`, currentSourceIndex), + getNextRank, + name + ` til SS`, + toStudioScreenHotkey, + sourceLayerId, + currentSourceIndex + ) + ) + } + + if (hotkeys.routeToGraphicsEngine.length) { + const toGraphicsEngineHotkey = hotkeys.routeToGraphicsEngine[currentSourceIndex] + toAuxGraphicsEngineHotkeys.push( + MakeRouteToGraphicsEngineTrigger( + idFunc(showStyleId, sourceLayerId, `graphics_engine`, currentSourceIndex), + getNextRank, + name, + toGraphicsEngineHotkey, + sourceLayerId, + currentSourceIndex + ) + ) + } + } + + return [ + ...directCutHotkeys, + ...queueHotkeys, + ...cutToBoxHotkeys, + ...toAuxStudioScreenHotkeys, + ...toAuxGraphicsEngineHotkeys + ] +} diff --git a/src/tv2-common/hotkeys/hotkey-defaults.ts b/src/tv2-common/hotkeys/hotkey-defaults.ts new file mode 100644 index 000000000..ee899ad3d --- /dev/null +++ b/src/tv2-common/hotkeys/hotkey-defaults.ts @@ -0,0 +1,226 @@ +import { SharedSourceLayers } from 'tv2-constants' +import { literal } from '../util' +import { GlobalHotkeyAssignments } from './global' +import { RundownViewHotkeyAssignments } from './rundownView' +import { ActiveSegmentHotketAssignments } from './segment' + +export interface TV2Hotkeys { + activeSegment: ActiveSegmentHotketAssignments + global: GlobalHotkeyAssignments + rundownView: RundownViewHotkeyAssignments +} + +export const defaultHotkeys: TV2Hotkeys = { + activeSegment: literal({ + lowerThirds: ['KeyA', 'KeyS', 'KeyD', 'KeyF', 'KeyG'] + }), + global: literal({ + recallLast: { + DVE: 'F10', + Live: 'Ctrl+Alt+Shift+KeyB' + }, + takeWithTransition: ['NumpadDivide', 'NumpadSubtract', 'NumpadAdd'], + camera: { + directCut: ['F1', 'F2', 'F3', 'F4', 'F5'], + queue: ['Ctrl+Shift+F1', 'Ctrl+Shift+F2', 'Ctrl+Shift+F3', 'Ctrl+Shift+F4', 'Ctrl+Shift+F5'], + cutToBox: [ + ['Shift+F1', 'Shift+F2', 'Shift+F3', 'Shift+F4', 'Shift+F5'], + ['Ctrl+F1', 'Crtl+F2', 'Ctrl+F3', 'Ctrl+Alt+Shift+KeyA', 'Ctrl+F5'], + ['Shift+Alt+F1', 'Shift+Alt+F2', 'Shift+Alt+F3', 'Shift+Alt+F4', 'Shift+Alt+F5'], + [] + ], + routeToStudioScreen: [], + routeToGraphicsEngine: [] + }, + clear: [ + { + sourceLayers: [ + SharedSourceLayers.PgmGraphicsIdent, + SharedSourceLayers.PgmGraphicsIdentPersistent, + SharedSourceLayers.PgmGraphicsTop, + SharedSourceLayers.PgmGraphicsLower, + SharedSourceLayers.PgmGraphicsHeadline, + SharedSourceLayers.PgmGraphicsTema, + SharedSourceLayers.PgmGraphicsOverlay, + SharedSourceLayers.PgmPilotOverlay, + SharedSourceLayers.PgmGraphicsTLF + ], + key: 'KeyQ', + name: 'overlay ALT UD' + }, + { + sourceLayers: [SharedSourceLayers.PgmGraphicsIdent, SharedSourceLayers.PgmGraphicsIdentPersistent], + key: 'Ctrl+Shift+KeyA', + name: 'ovl: ident OUT' + }, + { + sourceLayers: [SharedSourceLayers.PgmGraphicsTop], + key: 'Ctrl+Shift+KeyS', + name: 'ovl: top OUT' + }, + { + sourceLayers: [SharedSourceLayers.PgmGraphicsLower], + key: 'Ctrl+Shift+KeyD', + name: 'ovl:lower OUT' + }, + { + sourceLayers: [SharedSourceLayers.PgmGraphicsHeadline], + key: 'Ctrl+Shift+KeyF', + name: 'ovl: headline OUT' + }, + { + sourceLayers: [SharedSourceLayers.PgmGraphicsTema], + key: 'Ctrl+Shift+KeyG', + name: 'ovl: tema OUT' + }, + { + sourceLayers: [SharedSourceLayers.PgmAudioBed], + key: 'Minus', + name: 'STOP soundpl.' + } + ], + dve: { + sommerfugl: 'KeyM', + morbarn: 'Comma', + barnmor: 'Period', + barnMorIpad: 'KeyN', + '3split': 'KeyC', + '3barnMor': 'KeyB', + '2barnMor': 'KeyV' + }, + graphics: { + altud: 'KeyQ', + designSc: 'Shift+KeyA', + gfxContinue: 'Space' + }, + local: { + fullAudio: { + directCut: [], + queue: ['KeyR', 'KeyI'], + cutToBox: [['Shift+KeyE', 'Shift+KeyI'], ['Ctrl+KeyE', 'Ctrl+KeyI'], ['Alt+Shift+KeyE', 'Alt+Shift+KeyG'], []], + routeToStudioScreen: ['Shift+Ctrl+KeyE'], + routeToGraphicsEngine: ['Ctrl+Alt+Shift+KeyF'] + }, + voAudio: { + directCut: [], + queue: ['KeyE', 'KeyU'], + cutToBox: [['Shift+KeyD', 'Shift+KeyU'], ['Ctrl+KeyD', 'Ctrl+Alt+Shift+KeyI'], ['Alt+Shift+KeyD'], []], + routeToGraphicsEngine: [], + routeToStudioScreen: [] + } + }, + remote: { + directCut: [], + queue: ['Digit1', 'Digit2', 'Digit3', 'Digit4', 'Digit5', 'Digit6', 'Digit7', 'Digit8', 'Digit9', 'Digit0'], + cutToBox: [ + [ + 'Shift+Digit1', + 'Shift+Digit2', + 'Shift+Digit3', + 'Shift+Digit4', + 'Shift+Digit5', + 'Shift+Digit6', + 'Shift+Digit7', + 'Shift+Digit8', + 'Shift+Digit9', + 'Shift+Digit0' + ], + [ + 'Ctrl+Digit1', + 'Ctrl+Digit2', + 'Ctrl+Digit3', + 'Ctrl+Digit4', + 'Ctrl+Digit5', + 'Ctrl+Digit6', + 'Ctrl+Digit7', + 'Ctrl+Digit8', + 'Ctrl+Digit9', + 'Ctrl+Digit0' + ], + [ + 'Shift+Alt+Digit1', + 'Shift+Alt+Digit2', + 'Shift+Alt+Digit3', + 'Shift+Alt+Digit4', + 'Shift+Alt+Digit5', + 'Shift+Alt+Digit6', + 'Shift+Alt+Digit7', + 'Shift+Alt+Digit8', + 'Shift+Alt+Digit9', + 'Shift+Alt+Digit0' + ], + [] + ], + routeToStudioScreen: [], + routeToGraphicsEngine: [] + }, + feed: { + directCut: [], + queue: ['Digit1', 'Digit2', 'Digit3', 'Digit4', 'Digit5', 'Digit6', 'Digit7', 'Digit8', 'Digit9', 'Digit0'], + cutToBox: [ + [ + 'Shift+Digit1', + 'Shift+Digit2', + 'Shift+Digit3', + 'Shift+Digit4', + 'Shift+Digit5', + 'Shift+Digit6', + 'Shift+Digit7', + 'Shift+Digit8', + 'Shift+Digit9', + 'Shift+Digit0' + ], + [ + 'Ctrl+Digit1', + 'Ctrl+Digit2', + 'Ctrl+Digit3', + 'Ctrl+Digit4', + 'Ctrl+Digit5', + 'Ctrl+Digit6', + 'Ctrl+Digit7', + 'Ctrl+Digit8', + 'Ctrl+Digit9', + 'Ctrl+Digit0' + ], + [ + 'Shift+Alt+Digit1', + 'Shift+Alt+Digit2', + 'Shift+Alt+Digit3', + 'Shift+Alt+Digit4', + 'Shift+Alt+Digit5', + 'Shift+Alt+Digit6', + 'Shift+Alt+Digit7', + 'Shift+Alt+Digit8', + 'Shift+Alt+Digit9', + 'Shift+Alt+Digit0' + ], + [] + ], + routeToStudioScreen: [], + routeToGraphicsEngine: [] + }, + server: { + cutToBox: [['Shift+KeyT'], ['Ctrl+Alt+Shift+KeyG'], [], []] + }, + sisyfos: { + micsUp: 'Ctrl+Alt+Shift+KeyE', + micsDown: 'Ctrl+Alt+Shift+KeyD' + } + }), + rundownView: literal({ + activate: 'Backquote', + activateRehearsal: 'Ctrl+Backquote', + deactivate: 'Crtl+Shift+Backquote', + take: 'AnyEnter', + goToLiveLive: 'Shift+Home', + rewindSegments: 'Ctrl+Home', + resetRundown: 'Shift+Escape', + moveNextForward: 'Shift+ArrowRight', + moveNextDown: 'Shift+ArrowDown', + moveNextBack: 'Shift+ArrowLeft', + moveNextUp: 'Shift+ArrowUp', + takeSnapshot: 'Shift+Backspace', + queueNextMiniShelfAdLib: 'Tab', + queuePreviousMiniShelfAdLib: 'Shift+Tab' + }) +} diff --git a/src/tv2-common/hotkeys/index.ts b/src/tv2-common/hotkeys/index.ts new file mode 100644 index 000000000..572d5cd29 --- /dev/null +++ b/src/tv2-common/hotkeys/index.ts @@ -0,0 +1,45 @@ +import { ISourceLayer } from '@tv2media/blueprints-integration' +import { + GlobalHotkeySourceLayers, + GlobalHotkeySources, + MakeGlobalTriggers, + MakeRundownViewTriggers, + TV2Hotkeys +} from 'tv2-common' +import { MakeActiveSegmentTriggers } from './segment' + +export * from './rundownView' +export * from './global' +export * from './hotkey-defaults' + +export interface ISourceLayerWithHotKeys extends ISourceLayer { + clearKeyboardHotkey?: string + activateKeyboardHotkeys?: string + assignHotkeysToGlobalAdlibs?: boolean + activateStickyKeyboardHotkey?: string +} + +export const TRIGGER_HOTKEYS_ON_KEYUP = true + +export function MakeAllAdLibsTriggers( + showStyleId: string, + assignments: TV2Hotkeys, + globalSources: GlobalHotkeySources, + globalSourceLayers: GlobalHotkeySourceLayers +) { + let rank = 1000 + const getNextRank = () => ++rank + const rundownViewTriggers = MakeRundownViewTriggers(showStyleId, assignments.rundownView, getNextRank) + rank = 2000 + const globalTriggers = MakeGlobalTriggers( + showStyleId, + assignments.global, + globalSources, + globalSourceLayers, + getNextRank + ) + rank = 3000 + const segmentTriggers = MakeActiveSegmentTriggers(showStyleId, assignments.activeSegment, getNextRank) + + return [...rundownViewTriggers, ...globalTriggers, ...segmentTriggers] +} diff --git a/src/tv2-common/hotkeys/local.ts b/src/tv2-common/hotkeys/local.ts new file mode 100644 index 000000000..02dac2432 --- /dev/null +++ b/src/tv2-common/hotkeys/local.ts @@ -0,0 +1,53 @@ +import { IBlueprintTriggeredActions } from '@tv2media/blueprints-integration' +import { MakeStudioSourceHotkeys, SourceHotkeyTriggers } from './helpers' + +export interface LocalSourceHotkeyAssignments { + fullAudio: SourceHotkeyTriggers + voAudio: SourceHotkeyTriggers +} + +function localSourceFullAudioHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { + return `${showStyleId}_${sourceLayer}_local_full_audio_${hotkeyType}_${index}` +} + +function localSourceFullAudioHotkeyName(source: string) { + return `EVS ${source}` +} + +function localSourceVoAudioHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { + return `${showStyleId}_${sourceLayer}_local_vo_audio_${hotkeyType}_${index}` +} + +function localSourceVoAudioHotkeyName(source: string) { + return `EVS ${source}` +} + +export function MakeLocalSourceHotkeys( + showStyleId: string, + sourceLayerId: string, + localSources: string[], + assignemnts: LocalSourceHotkeyAssignments, + getNextRank: () => number +): IBlueprintTriggeredActions[] { + const fullAudioKeys = MakeStudioSourceHotkeys( + showStyleId, + sourceLayerId, + localSources, + assignemnts.fullAudio, + getNextRank, + localSourceFullAudioHotkeyName, + localSourceFullAudioHotkeyId + ) + + const voAudioKeys = MakeStudioSourceHotkeys( + showStyleId, + sourceLayerId, + localSources, + assignemnts.voAudio, + getNextRank, + localSourceVoAudioHotkeyName, + localSourceVoAudioHotkeyId + ) + + return [...fullAudioKeys, ...voAudioKeys] +} diff --git a/src/tv2-common/hotkeys/remote.ts b/src/tv2-common/hotkeys/remote.ts new file mode 100644 index 000000000..fda343d20 --- /dev/null +++ b/src/tv2-common/hotkeys/remote.ts @@ -0,0 +1,31 @@ +import { IBlueprintTriggeredActions } from '@tv2media/blueprints-integration' +import { MakeStudioSourceHotkeys, SourceHotkeyTriggers } from './helpers' + +export type RemoteSourceHotkeyAssignments = SourceHotkeyTriggers + +function remoteHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { + return `${showStyleId}_${sourceLayer}_remote_${hotkeyType}_${index}` +} + +function remoteHotkeyName(remote: string) { + const feed = remote.match(/^F(.+).*$/) // TODO: fix when refactoring FindSourceInfo + return feed ? `Feed ${feed[1]}` : `LIVE ${remote}` +} + +export function MakeRemoteHotkeys( + showStyleId: string, + sourceLayerId: string, + remotes: string[], + assignments: RemoteSourceHotkeyAssignments, + getNextRank: () => number +): IBlueprintTriggeredActions[] { + return MakeStudioSourceHotkeys( + showStyleId, + sourceLayerId, + remotes, + assignments, + getNextRank, + remoteHotkeyName, + remoteHotkeyId + ) +} diff --git a/src/tv2-common/hotkeys/rundownView.ts b/src/tv2-common/hotkeys/rundownView.ts new file mode 100644 index 000000000..cd5547977 --- /dev/null +++ b/src/tv2-common/hotkeys/rundownView.ts @@ -0,0 +1,362 @@ +import { + ClientActions, + IBlueprintHotkeyTrigger, + IBlueprintTriggeredActions, + IGUIContextFilterLink, + IRundownPlaylistActivateAction, + PlayoutActions, + SomeAction, + TriggerType +} from '@tv2media/blueprints-integration' +import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' + +export interface RundownViewHotkeyAssignments { + activate: string + activateRehearsal: string + deactivate: string + take: string + goToLiveLive: string + rewindSegments: string + resetRundown: string + moveNextForward: string + moveNextDown: string + moveNextBack: string + moveNextUp: string + takeSnapshot: string + queueNextMiniShelfAdLib: string + queuePreviousMiniShelfAdLib: string +} + +function rundownViewActionTriggerId(showStyleId: string, action: string) { + return `${showStyleId}_rundown_view_${action}` +} + +export function MakeRundownViewTriggers( + showStyleId: string, + assignments: RundownViewHotkeyAssignments, + getNextRank: () => number +): IBlueprintTriggeredActions[] { + return [ + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'activate_rundown'), + _rank: getNextRank(), + name: 'Activate Rundown', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.activate + }) + ], + actions: [ + literal({ + action: PlayoutActions.activateRundownPlaylist, + rehearsal: false, + force: true, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }), + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'activate_rundown_rehearsal'), + _rank: getNextRank(), + name: 'øve rundown', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.activateRehearsal, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: PlayoutActions.activateRundownPlaylist, + rehearsal: true, + force: true, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }), + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'deactivate_rundown'), + _rank: getNextRank(), + name: 'deaktivate rundown', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.deactivate, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: PlayoutActions.deactivateRundownPlaylist, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }), + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'take'), + _rank: getNextRank(), + name: 'Take', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.take, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: PlayoutActions.take, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }), + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'go_to_live'), + _rank: getNextRank(), + name: 'gå til aktiv linje', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.goToLiveLive, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: ClientActions.goToOnAirLine, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }), + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'rewind_segments'), + _rank: getNextRank(), + name: 'REW tidslinje', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.rewindSegments, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: ClientActions.rewindSegments, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }), + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'reset_rundown'), + _rank: getNextRank(), + name: 'Reload rundown', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.resetRundown, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: PlayoutActions.resetRundownPlaylist, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }), + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'move_next_forward'), + _rank: getNextRank(), + name: 'hist. højre SKIP', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.moveNextForward, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: PlayoutActions.moveNext, + segments: 0, + parts: 1, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }), + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'move_next_down'), + _rank: getNextRank(), + name: 'hist. ned SKIP', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.moveNextDown, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: PlayoutActions.moveNext, + segments: 1, + parts: 0, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }), + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'move_next_back'), + _rank: getNextRank(), + name: 'hist. venstre SKIP', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.moveNextBack, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: PlayoutActions.moveNext, + segments: 0, + parts: -1, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }), + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'move_next_up'), + _rank: getNextRank(), + name: 'hist. op SKIP', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.moveNextUp, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: PlayoutActions.moveNext, + segments: -1, + parts: 0, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }), + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'log_error'), + _rank: getNextRank(), + name: 'Take Snapshot', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.takeSnapshot, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: PlayoutActions.createSnapshotForDebug, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }), + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'queue_next_adlib'), + _rank: getNextRank(), + name: 'Queue Next AdLib', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.queueNextMiniShelfAdLib, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: ClientActions.miniShelfQueueAdLib, + forward: true, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }), + literal({ + _id: rundownViewActionTriggerId(showStyleId, 'queue_previous_adlib'), + _rank: getNextRank(), + name: 'Queue Previous AdLib', + triggers: [ + literal({ + type: TriggerType.hotkey, + keys: assignments.queuePreviousMiniShelfAdLib, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ], + actions: [ + literal({ + action: ClientActions.miniShelfQueueAdLib, + forward: false, + filterChain: [ + literal({ + object: 'view' + }) + ] + }) + ] + }) + ] +} diff --git a/src/tv2-common/hotkeys/segment.ts b/src/tv2-common/hotkeys/segment.ts new file mode 100644 index 000000000..d59a201bd --- /dev/null +++ b/src/tv2-common/hotkeys/segment.ts @@ -0,0 +1,85 @@ +import { + IAdLibFilterLink, + IAdlibPlayoutAction, + IBlueprintHotkeyTrigger, + IBlueprintTriggeredActions, + IGUIContextFilterLink, + PlayoutActions, + TriggerType +} from '@tv2media/blueprints-integration' +import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' +import { SharedSourceLayers } from 'tv2-constants' + +export interface ActiveSegmentHotketAssignments { + lowerThirds: string[] +} + +function activeSegmentAdLibHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { + return `${showStyleId}_${sourceLayer}_graphics_${hotkeyType}_${index}` +} + +export function MakeActiveSegmentTriggers( + showStyleId: string, + assignments: ActiveSegmentHotketAssignments, + getNextRank: () => number +) { + return assignments.lowerThirds.map((key, index) => + makeSegmentHotKey( + SharedSourceLayers.PgmGraphicsLower, + getNextRank, + activeSegmentAdLibHotkeyId(showStyleId, SharedSourceLayers.PgmGraphicsLower, key, index), + `Lower GFX AdLib ${index + 1}`, + key, + index + ) + ) +} + +function makeSegmentHotKey( + sourceLayerId: string, + getNextRank: () => number, + id: string, + name: string, + hotkey: string | undefined, + pick: number +) { + return literal({ + _id: id, + _rank: getNextRank(), + name, + triggers: hotkey + ? [ + literal({ + type: TriggerType.hotkey, + keys: hotkey, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ] + : [], + actions: [ + literal({ + action: PlayoutActions.adlib, + filterChain: [ + literal({ + object: 'view' + }), + literal({ + object: 'adLib', + field: 'segment', + value: 'current' + }), + literal({ + object: 'adLib', + field: 'sourceLayerId', + value: [sourceLayerId] + }), + literal({ + object: 'adLib', + field: 'pick', + value: pick + }) + ] + }) + ] + }) +} diff --git a/src/tv2-common/hotkeys/server.ts b/src/tv2-common/hotkeys/server.ts new file mode 100644 index 000000000..c451c58e0 --- /dev/null +++ b/src/tv2-common/hotkeys/server.ts @@ -0,0 +1,61 @@ +import { IBlueprintTriggeredActions } from '@tv2media/blueprints-integration' +import { DVEBoxTriggers, MakeCutToBoxTrigger } from './helpers' + +const SERVER_TO_BOX_1_HOTKEYS: string[] = ['Shift+KeyT'] + +const SERVER_TO_BOX_2_HOTKEYS: string[] = ['Ctrl+Alt+Shift+KeyG'] + +const SERVER_TO_BOX_3_HOTKEYS: string[] = [] + +const SERVER_TO_BOX_4_HOTKEYS: string[] = [] + +const CUT_TO_BOX_HOTKEYS: DVEBoxTriggers = [ + SERVER_TO_BOX_1_HOTKEYS, + SERVER_TO_BOX_2_HOTKEYS, + SERVER_TO_BOX_3_HOTKEYS, + SERVER_TO_BOX_4_HOTKEYS +] + +export interface ServerHotkeyAssignments { + cutToBox: DVEBoxTriggers +} + +function serverHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { + return `${showStyleId}_${sourceLayer}_server_${hotkeyType}_${index}` +} + +function serverHotkeyName() { + return `serv` +} + +const SERVER_SOURCES = ['casparcg'] + +export function MakeServerHotkeys( + showStyleId: string, + sourceLayerId: string, + getNextRank: () => number +): IBlueprintTriggeredActions[] { + const cutToBoxHotkeys: IBlueprintTriggeredActions[] = [] + for (let currentSourceIndex = 0; currentSourceIndex < SERVER_SOURCES.length; currentSourceIndex++) { + const name = serverHotkeyName() + + for (let box = 0; box < CUT_TO_BOX_HOTKEYS.length; box++) { + if (CUT_TO_BOX_HOTKEYS[box].length) { + const boxHotkey = CUT_TO_BOX_HOTKEYS[box][currentSourceIndex] + cutToBoxHotkeys.push( + MakeCutToBoxTrigger( + serverHotkeyId(showStyleId, sourceLayerId, `cut_to_box_${box + 1}`, currentSourceIndex), + getNextRank, + name + ` inp ${box + 1}`, + boxHotkey, + sourceLayerId, + currentSourceIndex, + box + ) + ) + } + } + } + + return cutToBoxHotkeys +} diff --git a/src/tv2-common/hotkeys/sisyfos.ts b/src/tv2-common/hotkeys/sisyfos.ts new file mode 100644 index 000000000..4b2f4af63 --- /dev/null +++ b/src/tv2-common/hotkeys/sisyfos.ts @@ -0,0 +1,100 @@ +import { + IAdLibFilterLink, + IAdlibPlayoutAction, + IBlueprintHotkeyTrigger, + IBlueprintTriggeredActions, + IGUIContextFilterLink, + PlayoutActions, + TriggerType +} from '@tv2media/blueprints-integration' +import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' +import { AdlibTags } from 'tv2-constants' + +export interface SisyfosHotkeyAssignments { + micsUp: string + micsDown: string +} + +function sisyfosHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { + return `${showStyleId}_${sourceLayer}_dve_layout_${hotkeyType}_${index}` +} + +export function MakeSisyfosHotkeys( + showStyleId: string, + sourceLayerId: string, + assignments: SisyfosHotkeyAssignments, + getNextRank: () => number +) { + return [ + makeSisyfosHotKey( + sourceLayerId, + getNextRank, + sisyfosHotkeyId(showStyleId, sourceLayerId, 'mics_up', 0), + 'mics OP', + assignments.micsUp, + [AdlibTags.ADLIB_MICS_UP] + ), + makeSisyfosHotKey( + sourceLayerId, + getNextRank, + sisyfosHotkeyId(showStyleId, sourceLayerId, 'mics_down', 0), + 'mics NED', + assignments.micsDown, + [AdlibTags.ADLIB_MICS_DOWN] + ) + ] +} + +function makeSisyfosHotKey( + sourceLayerId: string, + getNextRank: () => number, + id: string, + name: string, + hotkey: string | undefined, + tags: string[] +) { + return literal({ + _id: id, + _rank: getNextRank(), + name, + triggers: hotkey + ? [ + literal({ + type: TriggerType.hotkey, + keys: hotkey, + up: TRIGGER_HOTKEYS_ON_KEYUP + }) + ] + : [], + actions: [ + literal({ + action: PlayoutActions.adlib, + filterChain: [ + literal({ + object: 'view' + }), + literal({ + object: 'adLib', + field: 'sourceLayerId', + value: [sourceLayerId] + }), + literal({ + object: 'adLib', + field: 'global', + value: true + }), + literal({ + object: 'adLib', + field: 'tag', + value: tags + }), + literal({ + object: 'adLib', + field: 'pick', + value: 0 + }) + ] + }) + ] + }) +} diff --git a/src/tv2-common/index.ts b/src/tv2-common/index.ts index 382b2e3e7..96096ddf1 100644 --- a/src/tv2-common/index.ts +++ b/src/tv2-common/index.ts @@ -1,25 +1,26 @@ export * from './actions' +export * from './blueprintConfig' +export * from './content' +export * from './cues' export * from './cueTiming' +export * from './evaluateCues' export * from './frameTime' +export * from './getSegment' +export * from './helpers' +export * from './hotkeys' export * from './inewsConversion' -export * from './util' +export * from './jinglePartProperties' +export * from './layers' +export * from './migrations' +export * from './nextPartCue' +export * from './onTimelineGenerate' +export * from './parts' +export * from './pieces' export * from './sources' export * from './time/partTime' -export * from './getSegment' -export * from './blueprintConfig' -export * from './nextPartCue' -export * from './jinglePartProperties' -export * from './evaluateCues' export * from './transitionFromString' export * from './transitionSettings' -export * from './cues' -export * from './parts' -export * from './pieces' -export * from './content' -export * from './onTimelineGenerate' -export * from './helpers' export * from './translateEngine' -export * from './layers' export * from './types' -export * from './migrations' export * from './updatePolicies' +export * from './util' diff --git a/src/tv2-common/migrations/hotkeys.ts b/src/tv2-common/migrations/hotkeys.ts new file mode 100644 index 000000000..947a847d2 --- /dev/null +++ b/src/tv2-common/migrations/hotkeys.ts @@ -0,0 +1,117 @@ +import { + IBlueprintTriggeredActions, + ISourceLayer, + MigrationContextShowStyle, + MigrationStepShowStyle +} from '@tv2media/blueprints-integration' +import { + defaultHotkeys, + GlobalHotkeySourceLayers, + GlobalHotkeySources, + ISourceLayerWithHotKeys, + literal, + MakeAllAdLibsTriggers +} from 'tv2-common' +import _ = require('underscore') + +function shortcutsAreDifferent( + defaultShortcut: IBlueprintTriggeredActions, + existingShortcut: IBlueprintTriggeredActions +) { + let nameDiffers = existingShortcut.name !== defaultShortcut.name + let actionsDiffer = !_.isEqual(existingShortcut.actions, defaultShortcut.actions) + let triggersDiffer = !_.isEqual(existingShortcut.triggers, defaultShortcut.triggers) + return nameDiffers || actionsDiffer || triggersDiffer +} + +export function GetDefaultAdLibTriggers( + versionStr: string, + showStyleId: string, + sourceLayers: GlobalHotkeySourceLayers, + getGlobalHotkeySources: (context: MigrationContextShowStyle) => GlobalHotkeySources, + forceToDefaults: boolean +): MigrationStepShowStyle { + return literal({ + id: `${versionStr}.migrateShortcutsToAdLibTriggers${forceToDefaults ? '.defaults' : ''}.${showStyleId}`, + version: versionStr, + canBeRunAutomatically: true, + validate: (context: MigrationContextShowStyle) => { + const shortcutsDefaults = MakeAllAdLibsTriggers( + showStyleId, + defaultHotkeys, + getGlobalHotkeySources(context), + sourceLayers + ) + + let needsMigration = shortcutsDefaults.some(defaultShortcut => { + let existingShortcut = context.getTriggeredAction(defaultShortcut._id) + + if (!existingShortcut) { + return true + } + + return forceToDefaults && shortcutsAreDifferent(defaultShortcut, existingShortcut) + }) + return needsMigration + }, + migrate: (context: MigrationContextShowStyle) => { + const shortcutsDefaults = MakeAllAdLibsTriggers( + showStyleId, + defaultHotkeys, + getGlobalHotkeySources(context), + sourceLayers + ) + + for (const newShortcut of shortcutsDefaults) { + const existingShortcut = context.getTriggeredAction(newShortcut._id) + let needsMigration = + !existingShortcut || (forceToDefaults && shortcutsAreDifferent(existingShortcut, newShortcut)) + if (needsMigration) { + context.setTriggeredAction(newShortcut) + } + } + } + }) +} + +export function RemoveOldShortcuts( + versionStr: string, + showStyleId: string, + sourceLayerDefaults: ISourceLayer[] +): MigrationStepShowStyle { + return literal({ + id: `${versionStr}.migrateShortcutsToAdLibTriggers.${showStyleId}`, + version: versionStr, + canBeRunAutomatically: true, + validate: (context: MigrationContextShowStyle) => { + const sourceLayers = sourceLayerDefaults.map(sourceLayer => context.getSourceLayer(sourceLayer._id)) as Array< + ISourceLayerWithHotKeys | undefined + > + + const oldHotKeysExist = sourceLayers.some( + sourceLayer => + !!sourceLayer?.clearKeyboardHotkey || + !!sourceLayer?.activateKeyboardHotkeys || + !!sourceLayer?.activateStickyKeyboardHotkey || + sourceLayer?.assignHotkeysToGlobalAdlibs !== undefined + ) + + return oldHotKeysExist + }, + migrate: (context: MigrationContextShowStyle) => { + for (const sourceLayer of sourceLayerDefaults) { + const coreSourceLayer = context.getSourceLayer(sourceLayer._id) as ISourceLayerWithHotKeys | undefined + if (!coreSourceLayer) { + continue + } + + coreSourceLayer.clearKeyboardHotkey = undefined + coreSourceLayer.activateKeyboardHotkeys = undefined + coreSourceLayer.activateStickyKeyboardHotkey = undefined + coreSourceLayer.assignHotkeysToGlobalAdlibs = undefined + + context.updateSourceLayer(sourceLayer._id, coreSourceLayer) + } + } + }) +} diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index 6529d30b8..a7bea25f6 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -18,6 +18,7 @@ export * from './graphic-defaults' export * from './manifestWithMediaFlow' export * from './sourceManifest' export * from './forceSourceLayerToDefaultsBase' +export * from './hotkeys' export function RenameStudioConfig(versionStr: string, studio: string, from: string, to: string): MigrationStepStudio { return literal({ @@ -72,7 +73,7 @@ export function renameSourceLayer( export function removeSourceLayer(versionStr: string, studioId: string, layer: string) { return literal({ - id: `${versionStr}.renameSourceLayer.${studioId}.${layer}`, + id: `${versionStr}.removeSourceLayer.${studioId}.${layer}`, version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index e94757989..e50850fc8 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -66,7 +66,39 @@ export enum AdlibTags { ADLIB_FLOW_PRODUCER = 'flow_producer', ADLIB_STATIC_BUTTON = 'static_button', ADLIB_KOMMENTATOR = 'kommentator', - ADLIB_NO_NEXT_HIGHLIGHT = 'no_next_highlight' + ADLIB_NO_NEXT_HIGHLIGHT = 'no_next_highlight', + ADLIB_CUT_DIRECT = 'cut_direct', + ADLIB_QUEUE_NEXT = 'queue_next', + ADLIB_VO_AUDIO_LEVEL = 'vo_audio_level', + ADLIB_FULL_AUDIO_LEVEL = 'full_audio_level', + ADLIB_TO_STUDIO_SCREEN_AUX = 'to_studio_screen_aux', + ADLIB_TO_GRAPHICS_ENGINE_AUX = 'to_graphics_engine_aux', + ADLIB_CUT_TO_BOX_1 = 'cut_to_box_1', + ADLIB_CUT_TO_BOX_2 = 'cut_to_box_2', + ADLIB_CUT_TO_BOX_3 = 'cut_to_box_3', + ADLIB_CUT_TO_BOX_4 = 'cut_to_box_4', + ADLIB_GFX_ALTUD = 'gfx_altud', + ADLIB_GFX_LOAD = 'gfx_load', + ADLIB_GFX_CONTINUE_FORWARD = 'gfx_continue_forward', + ADLIB_DSK_ON = 'dsk_on', + ADLIB_DSK_OFF = 'dsk_off', + ADLIB_MICS_UP = 'mics_up', + ADLIB_MICS_DOWN = 'mics_down', + ADLIBS_RESYNC_SISYFOS = 'resync_sisyfos', + ADLIB_DESIGN_STYLE_SC = 'design_style_sc', + ADLIB_STOP_AUDIO_BED = 'stop_audio_bed', + ADLIB_RECALL_LAST_LIVE = 'recall_last_live', + ADLIB_RECALL_LAST_DVE = 'recall_last_dve', + ADLIB_SELECT_DVE_LAYOUT = 'select_dve_layout', + ADLIB_TAKE_WITH_TRANSITION = 'take_with_transition' +} + +/** + * Generates a tag for a 'cut to box' adlib + * @param box Box number (0-indexed) + */ +export function AdlibTagCutToBox(box: number): AdlibTags { + return `cut_to_box_${box + 1}` as AdlibTags } export enum ControlClasses { @@ -206,11 +238,6 @@ export enum SharedSourceLayers { PgmAdlibGraphicCmd = 'studio0_adlib_graphic_cmd', // shortcuts PgmAdlibJingle = 'studio0_adlib_jingle', - PgmDVEBox1 = 'studio0_dve_box1', - PgmDVEBox2 = 'studio0_dve_box2', - PgmDVEBox3 = 'studio0_dve_box3', - PgmDVEBox4 = 'studio0_dve_box4', - // Selected Sources SelectedServer = 'studio0_selected_clip', SelectedVoiceOver = 'studio0_selected_voiceover', diff --git a/src/tv2_afvd_showstyle/config-manifests.ts b/src/tv2_afvd_showstyle/config-manifests.ts index 147abc556..af2c6c582 100644 --- a/src/tv2_afvd_showstyle/config-manifests.ts +++ b/src/tv2_afvd_showstyle/config-manifests.ts @@ -1,6 +1,147 @@ import { ConfigManifestEntry, ConfigManifestEntryType, TSR } from '@tv2media/blueprints-integration' import { DEFAULT_GRAPHICS } from 'tv2-common' +export const dveStylesManifest: ConfigManifestEntry = { + id: 'DVEStyles', + name: 'DVE Layouts', + description: '', + type: ConfigManifestEntryType.TABLE, + required: false, + defaultVal: [ + { + _id: '', + DVEName: 'sommerfugl', + DVEInputs: '1:INP1;2:INP2', + DVEJSON: + '{"boxes":{"0":{"enabled":true,"source":11,"x":-800,"y":60,"size":500,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},"1":{"enabled":true,"source":1,"x":800,"y":60,"size":500,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},"2":{"enabled":false,"source":2001,"x":0,"y":0,"size":1000,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},"3":{"enabled":false,"source":2001,"x":0,"y":0,"size":1000,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0}},"index":0,"properties":{"artFillSource":30,"artCutSource":32,"artOption":1,"artPreMultiplied":false,"artClip":50,"artGain":12.5,"artInvertKey":false},"border":{"borderEnabled":false,"borderBevel":0,"borderOuterWidth":0,"borderInnerWidth":0,"borderOuterSoftness":0,"borderInnerSoftness":0,"borderBevelSoftness":0,"borderBevelPosition":0,"borderHue":0,"borderSaturation":0,"borderLuma":0,"borderLightSourceDirection":0,"borderLightSourceAltitude":10}}', + DVEGraphicsTemplateJSON: + '{ "common": { "font-family": "Alright Sans LT", "font-weight": "bold", "color": "#000000", "font-size": "30px", "background": "#FFFFFF", "height": "35px", "line-height": "35px", "width": "963px", "text-transform": "uppercase", "overflow": "hidden", "top": "764px" }, "locator1": { "left": "960px", "padding-left": "50px", "padding-right": "120px", "text-align": "right" }, "locator2": { "left": "0px", "padding-left": "120px", "padding-right": "50px" } }', + DVEGraphicsKey: 'dve/sommerfuglK', + DVEGraphicsFrame: 'dve/sommerfugl' + }, + { + _id: '', + DVEName: 'morbarn', + DVEInputs: '3:INP1;2:INP2', + DVEJSON: + '{"boxes":{"0":{"enabled":false,"source":12,"x":-500,"y":140,"size":760,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":1000},"1":{"enabled":true,"source":2001,"x":1080,"y":-240,"size":320,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},"2":{"enabled":true,"source":2,"x":-460,"y":100,"size":720,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},"3":{"enabled":false,"source":2001,"x":0,"y":0,"size":1000,"cropped":true,"cropTop":0,"cropBottom":119,"cropLeft":0,"cropRight":0}},"index":0,"properties":{"artFillSource":30,"artCutSource":32,"artOption":1,"artPreMultiplied":false,"artClip":50,"artGain":12.5,"artInvertKey":false},"border":{"borderEnabled":false,"borderBevel":0,"borderOuterWidth":0,"borderInnerWidth":0,"borderOuterSoftness":0,"borderInnerSoftness":0,"borderBevelSoftness":0,"borderBevelPosition":0,"borderHue":0,"borderSaturation":0,"borderLuma":0,"borderLightSourceDirection":0,"borderLightSourceAltitude":10}}', + DVEGraphicsTemplateJSON: + '{ "common": { "font-family": "Alright Sans LT", "font-weight": "bold", "color": "#000000", "font-size": "30px", "background": "#FFFFFF", "height": "35px", "line-height": "35px", "text-transform": "uppercase", "top": "848px", "overflow": "hidden" }, "locator1": { "left": "1300px", "padding-left": "50px", "padding-right": "120px", "text-align": "right", "width": "624px" }, "locator2": { "left": "0px", "padding-left": "120px", "padding-right": "50px", "width": "1300px" } }', + DVEGraphicsKey: 'dve/morbarnK', + DVEGraphicsFrame: 'dve/morbarn' + }, + { + _id: '', + DVEName: 'barnmor', + DVEInputs: '2:INP2;1:INP1', + DVEJSON: + '{"boxes":{"0":{"enabled":true,"source":13,"x":-1080,"y":-240,"size":320,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},"1":{"enabled":true,"source":3,"x":460,"y":100,"size":720,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},"2":{"enabled":false,"source":2001,"x":-460,"y":130,"size":760,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":1230},"3":{"enabled":false,"source":2001,"x":0,"y":0,"size":1000,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0}},"index":0,"properties":{"artFillSource":30,"artCutSource":32,"artOption":1,"artPreMultiplied":false,"artClip":50,"artGain":12.5,"artInvertKey":false},"border":{"borderEnabled":false,"borderBevel":0,"borderOuterWidth":0,"borderInnerWidth":0,"borderOuterSoftness":0,"borderInnerSoftness":0,"borderBevelSoftness":0,"borderBevelPosition":0,"borderHue":0,"borderSaturation":0,"borderLuma":0,"borderLightSourceDirection":0,"borderLightSourceAltitude":10}}', + DVEGraphicsTemplateJSON: + '{ "common": { "font-family": "Alright Sans LT", "font-weight": "bold", "color": "#000000", "font-size": "30px", "background": "#FFFFFF", "height": "35px", "line-height": "35px", "text-transform": "uppercase", "top": "848px", "overflow": "hidden" }, "locator1": { "left": "624px", "padding-left": "50px", "padding-right": "120px", "text-align": "right", "width": "1300px" }, "locator2": { "left": "0px", "padding-left": "120px", "padding-right": "50px", "width": "624px" } }', + DVEGraphicsKey: 'dve/barnmorK', + DVEGraphicsFrame: 'dve/barnmor' + }, + { + _id: '', + DVEName: 'barnMorIpad', + DVEInputs: '1:INP1;2:INP2', + DVEJSON: + '{"boxes":{"0":{"enabled":true,"source":11,"x":-850,"y":-250,"size":350,"cropped":true,"cropTop":240,"cropBottom":530,"cropLeft":550,"cropRight":2580},"1":{"enabled":true,"source":10,"x":507,"y":130,"size":800,"cropped":true,"cropTop":250,"cropBottom":0,"cropLeft":4380,"cropRight":4170},"2":{"enabled":false,"source":2001,"x":-460,"y":130,"size":760,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":1230},"3":{"enabled":false,"source":2001,"x":0,"y":0,"size":1000,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0}},"index":0,"properties":{"artFillSource":30,"artCutSource":32,"artOption":1,"artPreMultiplied":false,"artClip":50,"artGain":12.5,"artInvertKey":false},"border":{"borderEnabled":false,"borderBevel":0,"borderOuterWidth":0,"borderInnerWidth":0,"borderOuterSoftness":0,"borderInnerSoftness":0,"borderBevelSoftness":0,"borderBevelPosition":0,"borderHue":0,"borderSaturation":0,"borderLuma":0,"borderLightSourceDirection":0,"borderLightSourceAltitude":10}}', + DVEGraphicsTemplateJSON: + '{ "common": { "font-family": "Alright Sans LT", "font-weight": "bold", "color": "#000000", "font-size": "30px", "background": "#FFFFFF", "height": "35px", "line-height": "35px", "text-transform": "uppercase", "top": "848px", "overflow": "hidden" }, "locator1": { "left": "733px", "padding-left": "50px", "padding-right": "50px", "text-align": "right", "width": "1014px" }, "locator2": { "left": "118px", "padding-left": "50px", "padding-right": "50px", "width": "624px" } }', + DVEGraphicsKey: 'dve/barnipadK', + DVEGraphicsFrame: 'dve/barnipad' + }, + { + _id: '', + DVEName: '3split', + DVEInputs: '1:INP1;2:INP2;3:INP3', + DVEJSON: + '{"boxes":{"0":{"enabled":true,"source":2,"x":-1050,"y":100,"size":700,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":8500},"1":{"enabled":true,"source":3,"x":160,"y":100,"size":700,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":6200,"cropRight":10600},"2":{"enabled":true,"source":1000,"x":1080,"y":100,"size":700,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},"3":{"enabled":true,"source":2001,"x":758,"y":-425,"size":417,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0}},"index":0,"properties":{"artFillSource":30,"artCutSource":32,"artOption":1,"artPreMultiplied":false,"artClip":50,"artGain":12.5,"artInvertKey":false},"border":{"borderEnabled":false,"borderBevel":0,"borderOuterWidth":0,"borderInnerWidth":0,"borderOuterSoftness":0,"borderInnerSoftness":0,"borderBevelSoftness":0,"borderBevelPosition":0,"borderHue":0,"borderSaturation":0,"borderLuma":0,"borderLightSourceDirection":0,"borderLightSourceAltitude":10}}', + DVEGraphicsTemplateJSON: + '{ "common": { "font-family": "Alright Sans LT", "font-weight": "bold", "color": "#000000", "font-size": "30px", "background": "#FFFFFF", "height": "35px", "line-height": "35px", "width": "640px", "text-transform": "uppercase", "top": "848px" }, "locator1": { "left": "1280px", "padding-left": "50px", "padding-right": "120px", "text-align": "right", "overflow": "hidden" }, "locator2": { "left": "0px", "padding-left": "120px", "padding-right": "50px", "overflow": "hidden" } }', + DVEGraphicsKey: 'dve/3splitK', + DVEGraphicsFrame: 'dve/3split' + }, + { + _id: '', + DVEName: '3barnMor', + DVEInputs: '1:INP1;2:INP2;3:INP3;4:INP4', + DVEJSON: + '{"boxes":{"0":{"enabled":true,"source":2002,"x":-1055,"y":-390,"size":230,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":700},"1":{"enabled":true,"source":2,"x":358,"y":0,"size":680,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":400,"cropRight":0},"2":{"enabled":true,"source":4,"x":-1055,"y":10,"size":230,"cropped":true,"cropTop":500,"cropBottom":200,"cropLeft":0,"cropRight":700},"3":{"enabled":true,"source":1000,"x":-1055,"y":400,"size":230,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":700}},"index":0,"properties":{"artFillSource":30,"artCutSource":32,"artOption":1,"artPreMultiplied":false,"artClip":50,"artGain":12.5,"artInvertKey":false},"border":{"borderEnabled":false,"borderBevel":0,"borderOuterWidth":0,"borderInnerWidth":0,"borderOuterSoftness":0,"borderInnerSoftness":0,"borderBevelSoftness":0,"borderBevelPosition":0,"borderHue":0,"borderSaturation":0,"borderLuma":0,"borderLightSourceDirection":0,"borderLightSourceAltitude":10}}', + DVEGraphicsTemplateJSON: '{}', + DVEGraphicsKey: 'dve/3barnMorK', + DVEGraphicsFrame: 'dve/3barnMor' + }, + { + _id: '', + DVEName: '2barnMor', + DVEInputs: '1:INP1;2:INP2;3:INP3', + DVEJSON: + '{"boxes":{"0":{"enabled":true,"source":2,"x":-1050,"y":-200,"size":330,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},"1":{"enabled":true,"source":3,"x":540,"y":100,"size":670,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},"2":{"enabled":true,"source":2,"x":-1050,"y":400,"size":330,"cropped":true,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},"3":{"enabled":true,"source":2001,"x":758,"y":-425,"size":417,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0}},"index":0,"properties":{"artFillSource":30,"artCutSource":32,"artOption":1,"artPreMultiplied":false,"artClip":50,"artGain":12.5,"artInvertKey":false},"border":{"borderEnabled":false,"borderBevel":0,"borderOuterWidth":0,"borderInnerWidth":0,"borderOuterSoftness":0,"borderInnerSoftness":0,"borderBevelSoftness":0,"borderBevelPosition":0,"borderHue":0,"borderSaturation":0,"borderLuma":0,"borderLightSourceDirection":0,"borderLightSourceAltitude":10}}', + DVEGraphicsTemplateJSON: '{}', + DVEGraphicsKey: 'dve/2barnMorK', + DVEGraphicsFrame: 'dve/2barnMor' + } + ], + columns: [ + { + id: 'DVEName', + name: 'DVE name', + description: 'The name as it will appear in iNews', + type: ConfigManifestEntryType.STRING, + required: true, + defaultVal: '', + rank: 0 + }, + { + id: 'DVEInputs', + name: 'Box inputs', + description: 'I.e.: 1:INP1;2:INP3; as an example to chose which ATEM boxes to assign iNews inputs to', + type: ConfigManifestEntryType.STRING, + required: true, + defaultVal: '1:INP1;2:INP2;3:INP3;4:INP4', + rank: 1 + }, + { + id: 'DVEJSON', + name: 'DVE config', + description: 'DVE config pulled from ATEM', + type: ConfigManifestEntryType.JSON, + required: true, + defaultVal: '{}', + rank: 2 + }, + { + id: 'DVEGraphicsTemplateJSON', + name: 'CasparCG template config', + description: 'Position (and style) data for the boxes in the CasparCG template', + type: ConfigManifestEntryType.JSON, + required: true, + defaultVal: '{}', + rank: 4 + }, + { + id: 'DVEGraphicsKey', + name: 'CasparCG key file', + description: 'Key file for DVE', + type: ConfigManifestEntryType.STRING, + required: true, + defaultVal: '', + rank: 5 + }, + { + id: 'DVEGraphicsFrame', + name: 'CasparCG frame file', + description: 'Frames file for caspar', + type: ConfigManifestEntryType.STRING, + required: true, + defaultVal: '', + rank: 6 + } + ] +} + export const showStyleConfigManifest: ConfigManifestEntry[] = [ { id: 'MakeAdlibsForFulls', @@ -18,80 +159,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ defaultVal: 'LoadingLoop', required: true }, - { - id: 'DVEStyles', - name: 'DVE Layouts', - description: '', - type: ConfigManifestEntryType.TABLE, - required: false, - defaultVal: [ - { - _id: '', - DVEName: '', - DVEInputs: '', - DVEJSON: '{}', - DVEGraphicsTemplateJSON: '{}', - DVEGraphicsKey: '', - DVEGraphicsFrame: '' - } - ], - columns: [ - { - id: 'DVEName', - name: 'DVE name', - description: 'The name as it will appear in iNews', - type: ConfigManifestEntryType.STRING, - required: true, - defaultVal: '', - rank: 0 - }, - { - id: 'DVEInputs', - name: 'Box inputs', - description: 'I.e.: 1:INP1;2:INP3; as an example to chose which ATEM boxes to assign iNews inputs to', - type: ConfigManifestEntryType.STRING, - required: true, - defaultVal: '1:INP1;2:INP2;3:INP3;4:INP4', - rank: 1 - }, - { - id: 'DVEJSON', - name: 'DVE config', - description: 'DVE config pulled from ATEM', - type: ConfigManifestEntryType.JSON, - required: true, - defaultVal: '{}', - rank: 2 - }, - { - id: 'DVEGraphicsTemplateJSON', - name: 'CasparCG template config', - description: 'Position (and style) data for the boxes in the CasparCG template', - type: ConfigManifestEntryType.JSON, - required: true, - defaultVal: '{}', - rank: 4 - }, - { - id: 'DVEGraphicsKey', - name: 'CasparCG key file', - description: 'Key file for DVE', - type: ConfigManifestEntryType.STRING, - required: true, - defaultVal: '', - rank: 5 - }, - { - id: 'DVEGraphicsFrame', - name: 'CasparCG frame file', - description: 'Frames file for caspar', - type: ConfigManifestEntryType.STRING, - required: true, - defaultVal: '', - rank: 6 - } - ] - }, + dveStylesManifest, { /* Graphic template setup diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index c4867d481..2f276cf4d 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -38,13 +38,21 @@ import { t, TimelineBlueprintExt } from 'tv2-common' -import { AdlibActionType, AdlibTags, CONSTANTS, GraphicLLayer, SharedOutputLayers, TallyTags } from 'tv2-constants' +import { + AdlibActionType, + AdlibTagCutToBox, + AdlibTags, + CONSTANTS, + GraphicLLayer, + SharedOutputLayers, + 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 { AtemSourceIndex } from '../types/atem' import { BlueprintConfig, getConfig as getShowStyleConfig } from './helpers/config' -import { boxLayers } from './helpers/content/dve' +import { NUMBER_OF_DVE_BOXES } from './helpers/content/dve' import { SourceLayer } from './layers' import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' @@ -91,6 +99,7 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint lifespan: PieceLifespan.WithinPart, toBeQueued: true, metaData: GetEksternMetaData(config.stickyLayers, config.studio.StudioMics, info.sisyfosLayers), + tags: [AdlibTags.ADLIB_QUEUE_NEXT, vo ? AdlibTags.ADLIB_VO_AUDIO_LEVEL : AdlibTags.ADLIB_FULL_AUDIO_LEVEL], content: { ignoreMediaObjectStatus: true, timelineObjects: _.compact([ @@ -174,6 +183,7 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint config.studio.StudioMics, GetLayersForEkstern(context, config.sources, `Live ${info.id}`) ), + tags: [AdlibTags.ADLIB_QUEUE_NEXT], content: { timelineObjects: _.compact([ literal({ @@ -260,6 +270,7 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint config.studio.StudioMics, GetLayersForEkstern(context, config.sources, `Live ${info.id}`) ), + tags: [AdlibTags.ADLIB_TO_STUDIO_SCREEN_AUX], content: { timelineObjects: _.compact([ literal({ @@ -313,6 +324,7 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint outputLayerId: SharedOutputLayers.AUX, expectedDuration: 0, lifespan: PieceLifespan.OutOnShowStyleEnd, + tags: [AdlibTags.ADLIB_TO_STUDIO_SCREEN_AUX], content: { timelineObjects: _.compact([ literal({ @@ -339,6 +351,7 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint outputLayerId: SharedOutputLayers.AUX, expectedDuration: 0, lifespan: PieceLifespan.OutOnShowStyleEnd, + tags: [AdlibTags.ADLIB_TO_GRAPHICS_ENGINE_AUX], content: { timelineObjects: _.compact([ literal({ @@ -368,7 +381,7 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint outputLayerId: SharedOutputLayers.SEC, expectedDuration: 1000, lifespan: PieceLifespan.WithinPart, - tags: [AdlibTags.ADLIB_STATIC_BUTTON], + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_LOAD], content: { timelineObjects: _.compact([ literal({ @@ -396,7 +409,7 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint outputLayerId: SharedOutputLayers.SEC, expectedDuration: 1000, lifespan: PieceLifespan.WithinPart, - tags: [AdlibTags.ADLIB_STATIC_BUTTON], + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_CONTINUE_FORWARD], content: { timelineObjects: _.compact([ literal({ @@ -428,7 +441,7 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint sourceLayerId: SourceLayer.PgmSisyfosAdlibs, outputLayerId: SharedOutputLayers.SEC, lifespan: PieceLifespan.WithinPart, - tags: [AdlibTags.ADLIB_STATIC_BUTTON], + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_MICS_UP], expectedDuration: 0, content: { timelineObjects: [ @@ -458,7 +471,7 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint sourceLayerId: SourceLayer.PgmSisyfosAdlibs, outputLayerId: SharedOutputLayers.SEC, lifespan: PieceLifespan.WithinPart, - tags: [AdlibTags.ADLIB_STATIC_BUTTON], + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_MICS_DOWN], expectedDuration: 0, content: { timelineObjects: [ @@ -488,7 +501,7 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint sourceLayerId: SourceLayer.PgmSisyfosAdlibs, outputLayerId: SharedOutputLayers.SEC, lifespan: PieceLifespan.WithinPart, - tags: [AdlibTags.ADLIB_STATIC_BUTTON], + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIBS_RESYNC_SISYFOS], expectedDuration: 1000, content: { timelineObjects: _.compact([ @@ -516,6 +529,7 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint 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', @@ -558,6 +572,7 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint outputLayerId: 'musik', expectedDuration: 1000, lifespan: PieceLifespan.WithinPart, + tags: [AdlibTags.ADLIB_STOP_AUDIO_BED], content: { timelineObjects: [ literal({ @@ -588,9 +603,10 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri let globalRank = 1000 function makeAdlibBoxesActions(info: SourceInfo, type: 'Kamera' | 'Live' | 'Feed', rank: number) { - Object.values(boxLayers).forEach((layer, box) => { + for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { const feed = type === 'Live' && info.id.match(/^F(.+).*$/) // TODO: fix when refactoring FindSourceInfo const name = feed ? `Feed ${feed[1]}` : `${type} ${info.id}` + const layer = type === 'Kamera' ? SourceLayer.PgmCam : SourceLayer.PgmLive res.push( literal({ actionId: AdlibActionType.CUT_SOURCE_TO_BOX, @@ -608,15 +624,15 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri sourceLayerId: layer, outputLayerId: SharedOutputLayers.SEC, content: {}, - tags: [] + tags: [AdlibTagCutToBox(box)] } }) ) - }) + } } function makeAdlibBoxesActionsDirectPlayback(info: SourceInfo, vo: boolean, rank: number) { - Object.values(boxLayers).forEach((layer, box) => { + for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { res.push( literal({ actionId: AdlibActionType.CUT_SOURCE_TO_BOX, @@ -632,18 +648,18 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri display: { _rank: rank + 0.1 * box, label: t(`EVS ${info.id.replace(/dp/i, '')}${vo ? ' VO' : ''} to box ${box + 1}`), - sourceLayerId: layer, + sourceLayerId: SourceLayer.PgmLocal, outputLayerId: SharedOutputLayers.SEC, content: {}, - tags: [] + tags: [AdlibTagCutToBox(box)] } }) ) - }) + } } function makeServerAdlibBoxesActions(rank: number) { - Object.values(boxLayers).forEach((layer, box) => { + for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { res.push( literal({ actionId: AdlibActionType.CUT_SOURCE_TO_BOX, @@ -659,14 +675,14 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri display: { _rank: rank + 0.1 * box, label: t(`Server to box ${box + 1}`), - sourceLayerId: layer, + sourceLayerId: SourceLayer.PgmServer, outputLayerId: SharedOutputLayers.SEC, content: {}, - tags: [] + tags: [AdlibTagCutToBox(box)] } }) ) - }) + } } function makeCutCameraActions(info: SourceInfo, queue: boolean, rank: number) { @@ -684,7 +700,8 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri label: t(`KAM ${info.id}`), sourceLayerId: SourceLayer.PgmCam, outputLayerId: SharedOutputLayers.PGM, - content: {} + content: {}, + tags: queue ? [AdlibTags.ADLIB_QUEUE_NEXT] : [AdlibTags.ADLIB_CUT_DIRECT] } }) ) @@ -722,7 +739,8 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri _rank: 1, label: t('Last Live'), sourceLayerId: SourceLayer.PgmLive, - outputLayerId: SharedOutputLayers.PGM + outputLayerId: SharedOutputLayers.PGM, + tags: [AdlibTags.ADLIB_RECALL_LAST_LIVE] } }) ) @@ -778,7 +796,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, outputLayerId: SharedOutputLayers.SEC, content: {}, - tags: [AdlibTags.ADLIB_STATIC_BUTTON], + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_ALTUD], currentPieceTags: [TallyTags.GFX_ALTUD], nextPieceTags: [TallyTags.GFX_ALTUD] } @@ -798,7 +816,8 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri _rank: 1, label: t('Last DVE'), sourceLayerId: SourceLayer.PgmDVEAdLib, - outputLayerId: 'pgm' + outputLayerId: 'pgm', + tags: [AdlibTags.ADLIB_RECALL_LAST_DVE] } }) ) @@ -817,7 +836,8 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri _rank: 200 + i, label: t(dveConfig.DVEName), sourceLayerId: SourceLayer.PgmDVEAdLib, - outputLayerId: SharedOutputLayers.PGM + outputLayerId: SharedOutputLayers.PGM, + tags: [AdlibTags.ADLIB_SELECT_DVE_LAYOUT, dveConfig.DVEName] } }) ) diff --git a/src/tv2_afvd_showstyle/helpers/content/dve.ts b/src/tv2_afvd_showstyle/helpers/content/dve.ts index 1892c193f..4db7f0f0e 100644 --- a/src/tv2_afvd_showstyle/helpers/content/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/content/dve.ts @@ -3,7 +3,6 @@ import { CueDefinitionDVE, DVEConfigInput, DVEOptions, - DVESources, GetLayersForEkstern, GetSisyfosTimelineObjForEkstern, MakeContentDVEBase, @@ -12,14 +11,9 @@ import { import * as _ from 'underscore' import { BlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' -import { SourceLayer } from '../../layers' -export const boxLayers: DVESources = { - INP1: SourceLayer.PgmDVEBox1, - INP2: SourceLayer.PgmDVEBox2, - INP3: SourceLayer.PgmDVEBox3, - INP4: SourceLayer.PgmDVEBox4 -} +export const NUMBER_OF_DVE_BOXES = 4 + export const boxMappings = [AtemLLayer.AtemSSrcBox1, AtemLLayer.AtemSSrcBox2, AtemLLayer.AtemSSrcBox3] export const AFVD_DVE_GENERATOR_OPTIONS: DVEOptions = { @@ -46,12 +40,6 @@ export const AFVD_DVE_GENERATOR_OPTIONS: DVEOptions = { GetSisyfosTimelineObjForEkstern, GetLayersForEkstern }, - boxLayers: { - INP1: SourceLayer.PgmDVEBox1, - INP2: SourceLayer.PgmDVEBox2, - INP3: SourceLayer.PgmDVEBox3, - INP4: SourceLayer.PgmDVEBox4 - }, boxMappings: [AtemLLayer.AtemSSrcBox1, AtemLLayer.AtemSSrcBox2, AtemLLayer.AtemSSrcBox3, AtemLLayer.AtemSSrcBox4], AUDIO_LAYERS: Object.keys(SisyfosLLAyer), EXCLUDED_LAYERS: [ diff --git a/src/tv2_afvd_showstyle/migrations/hotkeys.ts b/src/tv2_afvd_showstyle/migrations/hotkeys.ts new file mode 100644 index 000000000..4468f0b3f --- /dev/null +++ b/src/tv2_afvd_showstyle/migrations/hotkeys.ts @@ -0,0 +1,38 @@ +import { + ConfigManifestEntryTable, + MigrationContextShowStyle, + TableConfigItemValue +} from '@tv2media/blueprints-integration' +import { GlobalHotkeySources } from 'tv2-common' +import { + manifestAFVDSourcesCam, + manifestAFVDSourcesDelayedPlayback, + manifestAFVDSourcesFeed, + manifestAFVDSourcesRM +} from '../../tv2_afvd_studio/config-manifests' +import { dveStylesManifest } from '../config-manifests' + +export function GetDefaultStudioSourcesForAFVD(context: MigrationContextShowStyle): GlobalHotkeySources { + 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[] + } else { + dveLayouts = (dveStylesManifest as ConfigManifestEntryTable).defaultVal + .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 local = manifestAFVDSourcesDelayedPlayback.defaultVal.map(source => source.SourceName) as string[] + + return { + camera, + remote, + feed, + local, + dveLayouts + } +} diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 99eab6f6a..a21d436ce 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -3,6 +3,8 @@ import { AddGraphicToGFXTable, GetDSKSourceLayerNames, literal, + GetDefaultAdLibTriggers, + RemoveOldShortcuts, removeSourceLayer, SetShortcutListMigrationStep, SetShowstyleTransitionMigrationStep, @@ -15,6 +17,8 @@ import { remapVizDOvl, remapVizLLayer } from '../../tv2_offtube_showstyle/migrat import { remapTableColumnValues } from '../../tv2_offtube_showstyle/migrations/util' import { ATEMModel } from '../../types/atem' import { SourceLayer } from '../layers' +import { GetDefaultStudioSourcesForAFVD } from './hotkeys' +import sourcelayerDefaults from './sourcelayer-defaults' import { forceSourceLayerToDefaults, getOutputLayerDefaultsMigrationSteps, @@ -28,6 +32,8 @@ declare const VERSION: string // Injected by webpack // 1.3.1 const jingle131 = SetShortcutListMigrationStep('1.3.1', SourceLayer.PgmJingle, 'NumpadDivide,NumpadSubtract,NumpadAdd') +const SHOW_STYLE_ID = 'tv2_afvd_showstyle' + /** * Versions: * 0.1.0: Core 0.24.0 @@ -57,7 +63,7 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal([ @@ -216,6 +217,7 @@ function getGlobalAdLibPiecesOfftube( outputLayerId: 'musik', expectedDuration: 1000, lifespan: PieceLifespan.WithinPart, + tags: [AdlibTags.ADLIB_STOP_AUDIO_BED], content: { timelineObjects: [ literal({ @@ -264,7 +266,7 @@ function getGlobalAdlibActionsOfftube( sourceLayerId: OfftubeSourceLayer.PgmCam, outputLayerId: SharedOutputLayers.PGM, content: {}, - tags: queue ? [AdlibTags.OFFTUBE_SET_CAM_NEXT] : [], + tags: queue ? [AdlibTags.OFFTUBE_SET_CAM_NEXT, AdlibTags.ADLIB_QUEUE_NEXT] : [AdlibTags.ADLIB_CUT_DIRECT], currentPieceTags: [GetTagForKam(info.id)], nextPieceTags: [GetTagForKam(info.id)] } @@ -288,7 +290,7 @@ function getGlobalAdlibActionsOfftube( sourceLayerId: OfftubeSourceLayer.PgmLive, outputLayerId: OfftubeOutputLayers.PGM, content: {}, - tags: [AdlibTags.OFFTUBE_SET_REMOTE_NEXT], + tags: [AdlibTags.OFFTUBE_SET_REMOTE_NEXT, AdlibTags.ADLIB_QUEUE_NEXT], currentPieceTags: [GetTagForLive(name)], nextPieceTags: [GetTagForLive(name)] } @@ -297,9 +299,10 @@ function getGlobalAdlibActionsOfftube( } function makeAdlibBoxesActions(info: SourceInfo, type: 'Kamera' | 'Live', rank: number) { - Object.values(boxLayers).forEach((layer, box) => { + for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { const feed = type === 'Live' && info.id.match(/^F(.+).*$/) const name = feed ? `Feed ${feed[1]}` : `${type} ${info.id}` + const layer = type === 'Kamera' ? OfftubeSourceLayer.PgmCam : OfftubeSourceLayer.PgmLive res.push( literal({ actionId: AdlibActionType.CUT_SOURCE_TO_BOX, @@ -317,42 +320,15 @@ function getGlobalAdlibActionsOfftube( sourceLayerId: layer, outputLayerId: OfftubeOutputLayers.PGM, content: {}, - tags: [] + tags: [AdlibTagCutToBox(box)] } }) ) - }) - } - - function makeAdlibBoxesActionsDirectPlayback(info: SourceInfo, vo: boolean, rank: number) { - Object.values(boxLayers).forEach((layer, box) => { - res.push( - literal({ - actionId: AdlibActionType.CUT_SOURCE_TO_BOX, - userData: literal({ - type: AdlibActionType.CUT_SOURCE_TO_BOX, - name: `EVS ${info.id.replace(/dp/i, '')}${vo ? ' VO' : ''}`, - port: info.port, - sourceType: info.type, - box, - vo - }), - userDataManifest: {}, - display: { - _rank: rank + 0.1 * box, - label: t(`EVS ${info.id.replace(/dp/i, '')}${vo ? ' VO' : ''} to box ${box + 1}`), - sourceLayerId: layer, - outputLayerId: SharedOutputLayers.SEC, - content: {}, - tags: [] - } - }) - ) - }) + } } function makeServerAdlibBoxesActions(rank: number) { - Object.values(boxLayers).forEach((layer, box) => { + for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { res.push( literal({ actionId: AdlibActionType.CUT_SOURCE_TO_BOX, @@ -368,14 +344,14 @@ function getGlobalAdlibActionsOfftube( display: { _rank: rank + 0.1 * box, label: t(`Server to box ${box + 1}`), - sourceLayerId: layer, + sourceLayerId: OfftubeSourceLayer.PgmServer, outputLayerId: SharedOutputLayers.SEC, content: {}, - tags: [] + tags: [AdlibTagCutToBox(box)] } }) ) - }) + } } res.push( @@ -453,7 +429,7 @@ function getGlobalAdlibActionsOfftube( sourceLayerId: SharedSourceLayers.PgmAdlibGraphicCmd, outputLayerId: SharedOutputLayers.SEC, content: {}, - tags: [AdlibTags.ADLIB_STATIC_BUTTON], + tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_ALTUD], currentPieceTags: [TallyTags.GFX_ALTUD], nextPieceTags: [TallyTags.GFX_ALTUD] } @@ -473,7 +449,8 @@ function getGlobalAdlibActionsOfftube( _rank: 1, label: t('Last DVE'), sourceLayerId: OfftubeSourceLayer.PgmDVEAdLib, - outputLayerId: 'pgm' + outputLayerId: 'pgm', + tags: [AdlibTags.ADLIB_RECALL_LAST_DVE] } }) ) @@ -491,7 +468,8 @@ function getGlobalAdlibActionsOfftube( _rank: 200 + i, label: t(dveConfig.DVEName), sourceLayerId: OfftubeSourceLayer.PgmDVEAdLib, - outputLayerId: SharedOutputLayers.PGM + outputLayerId: SharedOutputLayers.PGM, + tags: [AdlibTags.ADLIB_SELECT_DVE_LAYOUT, dveConfig.DVEName] } }) ) @@ -529,7 +507,8 @@ function getGlobalAdlibActionsOfftube( _rank: 1, label: t('Last Live'), sourceLayerId: OfftubeSourceLayer.PgmLive, - outputLayerId: SharedOutputLayers.PGM + outputLayerId: SharedOutputLayers.PGM, + tags: [AdlibTags.ADLIB_RECALL_LAST_LIVE] } }) ) @@ -548,14 +527,6 @@ function getGlobalAdlibActionsOfftube( makeAdlibBoxesActions(o, 'Live', globalRank++) }) - config.sources - .filter(u => u.type === SourceLayerType.LOCAL) - .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from - .forEach(o => { - makeAdlibBoxesActionsDirectPlayback(o, false, globalRank++) - makeAdlibBoxesActionsDirectPlayback(o, true, globalRank++) - }) - makeServerAdlibBoxesActions(globalRank++) res.push( diff --git a/src/tv2_offtube_showstyle/migrations/hotkeys.ts b/src/tv2_offtube_showstyle/migrations/hotkeys.ts new file mode 100644 index 000000000..4a3731ee4 --- /dev/null +++ b/src/tv2_offtube_showstyle/migrations/hotkeys.ts @@ -0,0 +1,37 @@ +import { + ConfigManifestEntryTable, + MigrationContextShowStyle, + TableConfigItemValue +} from '@tv2media/blueprints-integration' +import { GlobalHotkeySources } from 'tv2-common' +import { + manifestOfftubeSourcesCam, + manifestOfftubeSourcesFeed, + manifestOfftubeSourcesRM +} from '../../tv2_offtube_studio/config-manifests' +import { dveStylesManifest } from '../config-manifests' + +export function GetDefaultStudioSourcesForOfftube(context: MigrationContextShowStyle): GlobalHotkeySources { + 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[] + } else { + dveLayouts = (dveStylesManifest as ConfigManifestEntryTable).defaultVal + .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 => source.SourceName) as string[] + const local: string[] = [] + + return { + camera, + remote, + feed, + local, + dveLayouts + } +} diff --git a/src/tv2_offtube_showstyle/migrations/index.ts b/src/tv2_offtube_showstyle/migrations/index.ts index ecf212f32..c96fa12fd 100644 --- a/src/tv2_offtube_showstyle/migrations/index.ts +++ b/src/tv2_offtube_showstyle/migrations/index.ts @@ -3,6 +3,8 @@ import { AddGraphicToGFXTable, GetDSKSourceLayerNames, literal, + GetDefaultAdLibTriggers, + RemoveOldShortcuts, removeSourceLayer, renameSourceLayer, SetShortcutListMigrationStep, @@ -14,6 +16,8 @@ import * as _ from 'underscore' import { SetSourceLayerNameMigrationStep } from '../../tv2-common/migrations/shortcuts' import { ATEMModel } from '../../types/atem' import { OfftubeSourceLayer } from '../layers' +import { GetDefaultStudioSourcesForOfftube } from './hotkeys' +import sourcelayerDefaults from './sourcelayer-defaults' import { forceSourceLayerToDefaults, getOutputLayerDefaultsMigrationSteps, @@ -65,6 +69,8 @@ const jingle131 = SetShortcutListMigrationStep( 'NumpadDivide,NumpadSubtract,NumpadAdd' ) +const SHOW_STYLE_ID = 'tv2_offtube_showstyle' + /** * Versions: * 0.1.0: Core 0.24.0 @@ -91,7 +97,7 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal trigger._id) + + return literal({ + id: `${versionStr}.removeCoreDefaultTriggers`, + version: versionStr, + canBeRunAutomatically: true, + validate: (context: MigrationContextShowStyle) => { + const allTriggers = context.getAllTriggeredActions() + + return allTriggers.some(trigger => defaultTriggerIds.includes(trigger._id)) + }, + migrate: (context: MigrationContextShowStyle) => { + for (const trigger of defaultTriggerIds) { + context.removeTriggeredAction(trigger) + } + } + }) +} + +// copy-pasted from core migrations +const t = (text: string) => text +let j = 0 +const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ + { + _id: 'core_toggleShelf', + actions: [ + { + action: ClientActions.shelf, + filterChain: [ + { + object: 'view' + } + ], + state: 'toggle' + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'Tab', + up: true + } + ], + _rank: ++j * 1000, + name: t('Toggle Shelf') + }, + { + _id: 'core_activateRundownPlaylist', + actions: [ + { + action: PlayoutActions.activateRundownPlaylist, + rehearsal: false, + filterChain: [ + { + object: 'view' + } + ] + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'Backquote', + up: true + } + ], + _rank: ++j * 1000, + name: t('Activate (On-Air)') + }, + { + _id: 'core_activateRundownPlaylist_rehearsal', + actions: [ + { + action: PlayoutActions.activateRundownPlaylist, + rehearsal: true, + filterChain: [ + { + object: 'view' + } + ] + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'Control+Backquote', + up: true + } + ], + _rank: ++j * 1000, + name: t('Activate (Rehearsal)') + }, + { + _id: 'core_deactivateRundownPlaylist', + actions: [ + { + action: PlayoutActions.deactivateRundownPlaylist, + filterChain: [ + { + object: 'view' + } + ] + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'Control+Shift+Backquote', + up: true + } + ], + _rank: ++j * 1000, + name: t('Deactivate') + }, + { + _id: 'core_take', + actions: [ + { + action: PlayoutActions.take, + filterChain: [ + { + object: 'view' + } + ] + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'NumpadEnter', + up: true + }, + { + type: TriggerType.hotkey, + keys: 'F12', + up: true + } + ], + _rank: ++j * 1000, + name: t('Take') + }, + { + _id: 'core_hold', + actions: [ + { + action: PlayoutActions.hold, + filterChain: [ + { + object: 'view' + } + ] + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'KeyH', + up: true + } + ], + _rank: ++j * 1000, + name: t('Hold') + }, + { + _id: 'core_hold_undo', + actions: [ + { + action: PlayoutActions.hold, + undo: true, + filterChain: [ + { + object: 'view' + } + ] + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'Shift+KeyH', + up: true + } + ], + _rank: ++j * 1000, + name: t('Undo Hold') + }, + { + _id: 'core_reset_rundown_playlist', + actions: [ + { + action: PlayoutActions.resetRundownPlaylist, + filterChain: [ + { + object: 'view' + } + ] + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'Control+Shift+F12', + up: true + }, + { + type: TriggerType.hotkey, + keys: 'Control+Shift+AnyEnter', + up: true + } + ], + _rank: ++j * 1000, + name: t('Reset Rundown') + }, + { + _id: 'core_disable_next_piece', + actions: [ + { + action: PlayoutActions.disableNextPiece, + filterChain: [ + { + object: 'view' + } + ] + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'KeyG', + up: true + } + ], + _rank: ++j * 1000, + name: t('Disable the next element') + }, + { + _id: 'core_disable_next_piece_undo', + actions: [ + { + action: PlayoutActions.disableNextPiece, + filterChain: [ + { + object: 'view' + } + ], + undo: true + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'Shift+KeyG', + up: true + } + ], + _rank: ++j * 1000, + name: t('Undo Disable the next element') + }, + { + _id: 'core_create_snapshot_for_debug', + actions: [ + { + action: PlayoutActions.createSnapshotForDebug, + filterChain: [ + { + object: 'view' + } + ] + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'Backspace', + up: true + } + ], + _rank: ++j * 1000, + name: t('Store Snapshot') + }, + { + _id: 'core_move_next_part', + actions: [ + { + action: PlayoutActions.moveNext, + filterChain: [ + { + object: 'view' + } + ], + parts: 1, + segments: 0 + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'F9', + up: true + } + ], + _rank: ++j * 1000, + name: t('Move Next forwards') + }, + { + _id: 'core_move_next_segment', + actions: [ + { + action: PlayoutActions.moveNext, + filterChain: [ + { + object: 'view' + } + ], + parts: 0, + segments: 1 + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'F10', + up: true + } + ], + _rank: ++j * 1000, + name: t('Move Next to the following segment') + }, + { + _id: 'core_move_previous_part', + actions: [ + { + action: PlayoutActions.moveNext, + filterChain: [ + { + object: 'view' + } + ], + parts: -1, + segments: 0 + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'Shift+F9', + up: true + } + ], + _rank: ++j * 1000, + name: t('Move Next backwards') + }, + { + _id: 'core_move_previous_segment', + actions: [ + { + action: PlayoutActions.moveNext, + filterChain: [ + { + object: 'view' + } + ], + parts: 0, + segments: -1 + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'Shift+F10', + up: true + } + ], + _rank: ++j * 1000, + name: t('Move Next to the previous segment') + }, + { + _id: 'core_go_to_onAir_line', + actions: [ + { + action: ClientActions.goToOnAirLine, + filterChain: [ + { + object: 'view' + } + ] + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'Control+Home', + up: true + } + ], + _rank: ++j * 1000, + name: t('Go to On Air line') + }, + { + _id: 'core_rewind_segments', + actions: [ + { + action: ClientActions.rewindSegments, + filterChain: [ + { + object: 'view' + } + ] + } + ], + triggers: [ + { + type: TriggerType.hotkey, + keys: 'Shift+Home', + up: true + } + ], + _rank: ++j * 1000, + name: t('Rewind segments to start') + } +] diff --git a/src/tv2_system/migrations/index.ts b/src/tv2_system/migrations/index.ts new file mode 100644 index 000000000..a79e12524 --- /dev/null +++ b/src/tv2_system/migrations/index.ts @@ -0,0 +1,9 @@ +import { MigrationStepSystem } from '@tv2media/blueprints-integration' +import { literal } from 'tv2-common' +import { RemoveDefaultCoreShortcuts } from './hotkeys' + +declare const VERSION: string // Injected by webpack + +export const systemMigrations: MigrationStepSystem[] = literal([ + RemoveDefaultCoreShortcuts(VERSION) +]) From c4915fa20df4e0486894db19480021b098a87565 Mon Sep 17 00:00:00 2001 From: Tom Lee Date: Sat, 27 Nov 2021 17:32:58 +0000 Subject: [PATCH 007/184] fix: Generate hotkeys for Feed sources --- src/tv2_afvd_showstyle/migrations/hotkeys.ts | 2 +- src/tv2_offtube_showstyle/migrations/hotkeys.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tv2_afvd_showstyle/migrations/hotkeys.ts b/src/tv2_afvd_showstyle/migrations/hotkeys.ts index 4468f0b3f..0b83ffcea 100644 --- a/src/tv2_afvd_showstyle/migrations/hotkeys.ts +++ b/src/tv2_afvd_showstyle/migrations/hotkeys.ts @@ -25,7 +25,7 @@ export function GetDefaultStudioSourcesForAFVD(context: MigrationContextShowStyl 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 feed = manifestAFVDSourcesFeed.defaultVal.map(source => `F${source.SourceName}`) as string[] const local = manifestAFVDSourcesDelayedPlayback.defaultVal.map(source => source.SourceName) as string[] return { diff --git a/src/tv2_offtube_showstyle/migrations/hotkeys.ts b/src/tv2_offtube_showstyle/migrations/hotkeys.ts index 4a3731ee4..472ec9650 100644 --- a/src/tv2_offtube_showstyle/migrations/hotkeys.ts +++ b/src/tv2_offtube_showstyle/migrations/hotkeys.ts @@ -24,7 +24,7 @@ export function GetDefaultStudioSourcesForOfftube(context: MigrationContextShowS 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 => source.SourceName) as string[] + const feed = manifestOfftubeSourcesFeed.defaultVal.map(source => `F${source.SourceName}`) as string[] const local: string[] = [] return { From 1978ac83150682875e4e2fe7564efe8579b9bbcc Mon Sep 17 00:00:00 2001 From: Tom Lee Date: Mon, 6 Dec 2021 10:35:58 +0000 Subject: [PATCH 008/184] fix: System and Feed migrations --- src/tv2-common/hotkeys/global.ts | 6 ++-- src/tv2-common/hotkeys/remote.ts | 9 ++++-- src/tv2_system/migrations/hotkeys.ts | 42 +++++++++++++++------------- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/tv2-common/hotkeys/global.ts b/src/tv2-common/hotkeys/global.ts index f71735dd9..7f2e40c63 100644 --- a/src/tv2-common/hotkeys/global.ts +++ b/src/tv2-common/hotkeys/global.ts @@ -66,14 +66,16 @@ export function MakeGlobalTriggers( SharedSourceLayers.PgmLive, sources.remote, assignments.remote, - getNextRank + getNextRank, + false ) const feedTriggers = MakeRemoteHotkeys( showStyleId, SharedSourceLayers.PgmLive, sources.feed, assignments.feed, - getNextRank + getNextRank, + true ) const localTriggers = layers.local ? MakeLocalSourceHotkeys(showStyleId, layers.local, sources.local, assignments.local, getNextRank) diff --git a/src/tv2-common/hotkeys/remote.ts b/src/tv2-common/hotkeys/remote.ts index fda343d20..8092700e7 100644 --- a/src/tv2-common/hotkeys/remote.ts +++ b/src/tv2-common/hotkeys/remote.ts @@ -7,6 +7,10 @@ function remoteHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: st return `${showStyleId}_${sourceLayer}_remote_${hotkeyType}_${index}` } +function feedHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { + return `${showStyleId}_${sourceLayer}_feed_${hotkeyType}_${index}` +} + function remoteHotkeyName(remote: string) { const feed = remote.match(/^F(.+).*$/) // TODO: fix when refactoring FindSourceInfo return feed ? `Feed ${feed[1]}` : `LIVE ${remote}` @@ -17,7 +21,8 @@ export function MakeRemoteHotkeys( sourceLayerId: string, remotes: string[], assignments: RemoteSourceHotkeyAssignments, - getNextRank: () => number + getNextRank: () => number, + feed: boolean ): IBlueprintTriggeredActions[] { return MakeStudioSourceHotkeys( showStyleId, @@ -26,6 +31,6 @@ export function MakeRemoteHotkeys( assignments, getNextRank, remoteHotkeyName, - remoteHotkeyId + feed ? feedHotkeyId : remoteHotkeyId ) } diff --git a/src/tv2_system/migrations/hotkeys.ts b/src/tv2_system/migrations/hotkeys.ts index 2e476dea8..5f998fbda 100644 --- a/src/tv2_system/migrations/hotkeys.ts +++ b/src/tv2_system/migrations/hotkeys.ts @@ -16,9 +16,13 @@ export function RemoveDefaultCoreShortcuts(versionStr: string) { version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const allTriggers = context.getAllTriggeredActions() + for (const coreTrigger of DEFAULT_CORE_TRIGGERS) { + if (context.getTriggeredAction(coreTrigger._id)) { + return true + } + } - return allTriggers.some(trigger => defaultTriggerIds.includes(trigger._id)) + return false }, migrate: (context: MigrationContextShowStyle) => { for (const trigger of defaultTriggerIds) { @@ -33,7 +37,7 @@ const t = (text: string) => text let j = 0 const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ { - _id: 'core_toggleShelf', + _id: 'toggleShelf', actions: [ { action: ClientActions.shelf, @@ -56,7 +60,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Toggle Shelf') }, { - _id: 'core_activateRundownPlaylist', + _id: 'activateRundownPlaylist', actions: [ { action: PlayoutActions.activateRundownPlaylist, @@ -79,7 +83,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Activate (On-Air)') }, { - _id: 'core_activateRundownPlaylist_rehearsal', + _id: 'activateRundownPlaylist_rehearsal', actions: [ { action: PlayoutActions.activateRundownPlaylist, @@ -102,7 +106,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Activate (Rehearsal)') }, { - _id: 'core_deactivateRundownPlaylist', + _id: 'deactivateRundownPlaylist', actions: [ { action: PlayoutActions.deactivateRundownPlaylist, @@ -124,7 +128,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Deactivate') }, { - _id: 'core_take', + _id: 'take', actions: [ { action: PlayoutActions.take, @@ -151,7 +155,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Take') }, { - _id: 'core_hold', + _id: 'hold', actions: [ { action: PlayoutActions.hold, @@ -173,7 +177,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Hold') }, { - _id: 'core_hold_undo', + _id: 'hold_undo', actions: [ { action: PlayoutActions.hold, @@ -196,7 +200,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Undo Hold') }, { - _id: 'core_reset_rundown_playlist', + _id: 'reset_rundown_playlist', actions: [ { action: PlayoutActions.resetRundownPlaylist, @@ -223,7 +227,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Reset Rundown') }, { - _id: 'core_disable_next_piece', + _id: 'disable_next_piece', actions: [ { action: PlayoutActions.disableNextPiece, @@ -245,7 +249,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Disable the next element') }, { - _id: 'core_disable_next_piece_undo', + _id: 'disable_next_piece_undo', actions: [ { action: PlayoutActions.disableNextPiece, @@ -268,7 +272,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Undo Disable the next element') }, { - _id: 'core_create_snapshot_for_debug', + _id: 'create_snapshot_for_debug', actions: [ { action: PlayoutActions.createSnapshotForDebug, @@ -290,7 +294,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Store Snapshot') }, { - _id: 'core_move_next_part', + _id: 'move_next_part', actions: [ { action: PlayoutActions.moveNext, @@ -314,7 +318,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Move Next forwards') }, { - _id: 'core_move_next_segment', + _id: 'move_next_segment', actions: [ { action: PlayoutActions.moveNext, @@ -338,7 +342,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Move Next to the following segment') }, { - _id: 'core_move_previous_part', + _id: 'move_previous_part', actions: [ { action: PlayoutActions.moveNext, @@ -362,7 +366,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Move Next backwards') }, { - _id: 'core_move_previous_segment', + _id: 'move_previous_segment', actions: [ { action: PlayoutActions.moveNext, @@ -386,7 +390,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Move Next to the previous segment') }, { - _id: 'core_go_to_onAir_line', + _id: 'go_to_onAir_line', actions: [ { action: ClientActions.goToOnAirLine, @@ -408,7 +412,7 @@ const DEFAULT_CORE_TRIGGERS: IBlueprintTriggeredActions[] = [ name: t('Go to On Air line') }, { - _id: 'core_rewind_segments', + _id: 'rewind_segments', actions: [ { action: ClientActions.rewindSegments, From 3aedddf42e12c7116e4768b37397217e998f81c3 Mon Sep 17 00:00:00 2001 From: Tom Lee Date: Mon, 13 Dec 2021 14:53:25 +0000 Subject: [PATCH 009/184] fix: Add Jingle layers to presenter screen --- src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts | 3 ++- src/tv2_afvd_showstyle/migrations/index.ts | 2 ++ src/tv2_afvd_showstyle/migrations/sourcelayer-defaults.ts | 2 +- src/tv2_afvd_showstyle/migrations/util.ts | 2 +- src/tv2_offtube_showstyle/migrations/index.ts | 2 ++ src/tv2_offtube_showstyle/migrations/sourcelayer-defaults.ts | 2 +- src/tv2_offtube_showstyle/migrations/util.ts | 2 +- 7 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts b/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts index bea898eb4..8bc19baf2 100644 --- a/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts +++ b/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts @@ -9,11 +9,12 @@ import _ = require('underscore') export function forceSourceLayerToDefaultsBase( sourcelayerDefaults: ISourceLayer[], versionStr: string, + showStyleId: string, layer: string, overrideSteps?: string[] ): MigrationStepShowStyle { return literal({ - id: `${versionStr}.sourcelayer.defaults.${layer}.forced`, + id: `${versionStr}.${showStyleId}.sourcelayer.defaults.${layer}.forced`, version: versionStr, canBeRunAutomatically: true, overrideSteps, diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 7e30842de..dfa0ffc5e 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -166,9 +166,11 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal Date: Tue, 14 Dec 2021 18:37:43 +0100 Subject: [PATCH 010/184] fix: back-time valid only when on first continuity --- src/inews-mixins/__tests__/playlist.spec.ts | 88 +++++++++++++++++++ .../__tests__/rundownDuration.spec.ts | 8 +- src/inews-mixins/playlist.ts | 8 +- 3 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 src/inews-mixins/__tests__/playlist.spec.ts diff --git a/src/inews-mixins/__tests__/playlist.spec.ts b/src/inews-mixins/__tests__/playlist.spec.ts new file mode 100644 index 000000000..eea333578 --- /dev/null +++ b/src/inews-mixins/__tests__/playlist.spec.ts @@ -0,0 +1,88 @@ +import { + BlueprintResultRundown, + ExtendedIngestRundown, + IngestSegment, + PlaylistTimingType +} from '@sofie-automation/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 mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' +import { makeSegmentWithTime } from './rundownDuration.spec' + +const RUNDOWN_ID = 'test_rundown' +const RUNDOWN_NAME = 'Rundown 1' +const SEGMENT_ID = 'test_segment' +const PART_ID = 'test_part' + +function getMockContext() { + return new ShowStyleUserContext( + RUNDOWN_NAME, + mappingsDefaults, + parseStudioConfig, + parseShowStyleConfig, + RUNDOWN_ID, + SEGMENT_ID, + PART_ID + ) +} + +function getMockResult(): BlueprintResultRundown { + return { + rundown: { + externalId: RUNDOWN_ID, + name: RUNDOWN_NAME, + timing: { + type: PlaylistTimingType.None + } + }, + globalAdLibPieces: [], + baseline: { + timelineObjects: [] + } + } +} + +function getMockRundown(segments: IngestSegment[]): ExtendedIngestRundown { + return { + externalId: RUNDOWN_ID, + name: RUNDOWN_NAME, + type: 'mock', + payload: {}, + segments, + coreData: undefined + } +} +describe('Rundown BackTime', () => { + it('Discards back time if not on the first continuty', () => { + const segments = [ + makeSegmentWithTime('test-segment_1', 1, 0, {}), + makeSegmentWithTime('test-segment_2', 1, 1, { floated: true }), + makeSegmentWithTime('test-segment_3', 1, 1, {}), + makeSegmentWithTime('continuity', 2, 2, { untimed: true }), + makeSegmentWithTime('test-segment_4', 2, 3, { untimed: true }), + makeSegmentWithTime('continuity', 2, 4, { untimed: true, backTimeInHours: 2 }), + makeSegmentWithTime('test-segment_5', 3, 5, { untimed: true }) + ] + + const result = getRundownWithBackTime(getMockContext(), getMockRundown(segments), getMockResult()) + expect(result.rundown.timing.type).toEqual(PlaylistTimingType.None) + }) + + it('Takes back time if on the first continuty', () => { + const segments = [ + makeSegmentWithTime('test-segment_1', 1, 0, { floated: true }), + makeSegmentWithTime('test-segment_2', 1, 1, { floated: true }), + makeSegmentWithTime('test-segment_3', 1, 1, {}), + makeSegmentWithTime('continuity', 2, 2, { untimed: true, backTimeInHours: 2 }), + makeSegmentWithTime('test-segment_4', 2, 3, { untimed: true }), + makeSegmentWithTime('continuity', 2, 4, { untimed: true }), + makeSegmentWithTime('test-segment_5', 3, 5, { untimed: true }) + ] + + const result = getRundownWithBackTime(getMockContext(), getMockRundown(segments), getMockResult()) + expect(result.rundown.timing.type).toEqual(PlaylistTimingType.BackTime) + // @todo test for correct endTime value after merging the midnight fix + }) +}) diff --git a/src/inews-mixins/__tests__/rundownDuration.spec.ts b/src/inews-mixins/__tests__/rundownDuration.spec.ts index 4c3d4bb82..fd546afb6 100644 --- a/src/inews-mixins/__tests__/rundownDuration.spec.ts +++ b/src/inews-mixins/__tests__/rundownDuration.spec.ts @@ -2,7 +2,7 @@ import { IngestSegment } from '@sofie-automation/blueprints-integration' import { literal } from 'tv2-common' import { getRundownDuration } from '../rundownDuration' -function makeSegmentWithoutTime(externalId: string, rank: number): IngestSegment { +export function makeSegmentWithoutTime(externalId: string, rank: number): IngestSegment { return literal({ externalId, name: externalId, @@ -11,20 +11,22 @@ function makeSegmentWithoutTime(externalId: string, rank: number): IngestSegment }) } -function makeSegmentWithTime( +export function makeSegmentWithTime( externalId: string, time: number, rank: number, options: { floated?: boolean untimed?: boolean + backTimeInHours?: number } ): IngestSegment { const segment = makeSegmentWithoutTime(externalId, rank) segment.payload = { iNewsStory: { fields: { - totalTime: time + totalTime: time, + backTime: options.backTimeInHours ? `@${options.backTimeInHours * 3600}` : undefined }, meta: { float: options.floated ? 'float' : undefined diff --git a/src/inews-mixins/playlist.ts b/src/inews-mixins/playlist.ts index ad4792294..21ed36718 100644 --- a/src/inews-mixins/playlist.ts +++ b/src/inews-mixins/playlist.ts @@ -35,16 +35,14 @@ function getRundownWithINewsPlaylist( return manifest } -function getRundownWithBackTime( +export function getRundownWithBackTime( _context: IShowStyleUserContext, ingestRundown: ExtendedIngestRundown, manifest: BlueprintResultRundown ): BlueprintResultRundown { const sortedSegments = ingestRundown.segments.sort((a, b) => a.rank - b.rank) - const backTimeStory = sortedSegments.find( - segment => segment.name.match(/^\s*continuity\s*$/i) && segment.payload.iNewsStory.fields.backTime - ) - const backTime = backTimeStory ? backTimeStory.payload.iNewsStory.fields.backTime : undefined + 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 const expectedDuration = getRundownDuration(ingestRundown.segments) From b5cbc8610d66afd427490a772a131a61d4606fda Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 16 Dec 2021 19:17:29 +0100 Subject: [PATCH 011/184] fix: change layer type for some graphics to lower third affects non-pilot graphics --- package.json | 4 +- src/tv2-common/migrations/index.ts | 1 + src/tv2-common/migrations/shortcuts.ts | 45 +++-------- src/tv2-common/migrations/sourceLayers.ts | 43 ++++++++++ src/tv2-common/util.ts | 1 + src/tv2_afvd_showstyle/migrations/index.ts | 73 ++++++++++------- .../migrations/sourcelayer-defaults.ts | 10 +-- src/tv2_offtube_showstyle/migrations/index.ts | 80 +++++++++++-------- .../migrations/sourcelayer-defaults.ts | 12 +-- yarn.lock | 8 +- 10 files changed, 159 insertions(+), 118 deletions(-) create mode 100644 src/tv2-common/migrations/sourceLayers.ts diff --git a/package.json b/package.json index 142dca5d6..f646f5466 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tv2-sofie-blueprints-inews", - "version": "1.6.10", + "version": "1.7.1", "repository": "https://github.com/olzzon/tv2-sofie-blueprints-inews", "license": "MIT", "private": true, @@ -54,7 +54,7 @@ "tslint": "^5.12.1", "tslint-config-prettier": "^1.18.0", "tslint-plugin-prettier": "^2.0.1", - "typescript": "^3.3.3", + "typescript": "^4.1", "webpack": "^4.27.1", "webpack-cli": "^3.1.2" }, diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index e057e8153..a28df9771 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -18,6 +18,7 @@ export * from './transitions' export * from './graphic-defaults' export * from './manifestWithMediaFlow' export * from './sourceManifest' +export * from './sourceLayers' export * from './forceSourceLayerToDefaultsBase' export function RenameStudioConfig(versionStr: string, studio: string, from: string, to: string): MigrationStepStudio { diff --git a/src/tv2-common/migrations/shortcuts.ts b/src/tv2-common/migrations/shortcuts.ts index ecd10b5f0..a8f34b212 100644 --- a/src/tv2-common/migrations/shortcuts.ts +++ b/src/tv2-common/migrations/shortcuts.ts @@ -3,14 +3,13 @@ import { MigrationContextShowStyle, MigrationStepShowStyle } from '@sofie-automation/blueprints-integration' -import { literal } from 'tv2-common' export function SetShortcutListMigrationStep( versionStr: string, sourceLayerId: string, newValue: string ): MigrationStepShowStyle { - return literal({ + return { id: `${versionStr}.remapShortcuts.${sourceLayerId}`, version: versionStr, canBeRunAutomatically: true, @@ -18,7 +17,9 @@ export function SetShortcutListMigrationStep( const sourceLayer = context.getSourceLayer(sourceLayerId) if (!sourceLayer) { - return `Sourcelayer ${sourceLayerId} does not exists` + // nothing to migrate + // getSourceLayerDefaultsMigrationSteps should create this layer later + return false } return sourceLayer.activateKeyboardHotkeys !== newValue @@ -30,35 +31,7 @@ export function SetShortcutListMigrationStep( context.updateSourceLayer(sourceLayerId, sourceLayer) } - }) -} - -export function SetSourceLayerNameMigrationStep( - versionStr: string, - sourceLayerId: string, - newValue: string -): MigrationStepShowStyle { - return literal({ - id: `${versionStr}.remapSourceLayerName.${sourceLayerId}`, - version: versionStr, - canBeRunAutomatically: true, - validate: (context: MigrationContextShowStyle) => { - const sourceLayer = context.getSourceLayer(sourceLayerId) - - if (!sourceLayer) { - return `Sourcelayer ${sourceLayerId} does not exists` - } - - return sourceLayer.name !== newValue - }, - migrate: (context: MigrationContextShowStyle) => { - const sourceLayer = context.getSourceLayer(sourceLayerId) as ISourceLayer - - sourceLayer.name = newValue - - context.updateSourceLayer(sourceLayerId, sourceLayer) - } - }) + } } export function SetClearShortcutListTransitionStep( @@ -67,7 +40,7 @@ export function SetClearShortcutListTransitionStep( newValue: string ): MigrationStepShowStyle[] { return [ - literal({ + { id: `${versionStr}.remapClearShortcuts.${sourceLayerId}`, version: versionStr, canBeRunAutomatically: true, @@ -75,7 +48,9 @@ export function SetClearShortcutListTransitionStep( const sourceLayer = context.getSourceLayer(sourceLayerId) if (!sourceLayer) { - return `Sourcelayer ${sourceLayerId} does not exists` + // nothing to migrate + // getSourceLayerDefaultsMigrationSteps should create this layer later + return false } return sourceLayer.clearKeyboardHotkey !== newValue @@ -87,6 +62,6 @@ export function SetClearShortcutListTransitionStep( context.updateSourceLayer(sourceLayerId, sourceLayer) } - }) + } ] } diff --git a/src/tv2-common/migrations/sourceLayers.ts b/src/tv2-common/migrations/sourceLayers.ts new file mode 100644 index 000000000..8c26f321f --- /dev/null +++ b/src/tv2-common/migrations/sourceLayers.ts @@ -0,0 +1,43 @@ +import { + ISourceLayer, + MigrationContextShowStyle, + MigrationStepShowStyle +} from '@sofie-automation/blueprints-integration' +import { WithValuesOfTypes } from 'tv2-common' +import _ = require('underscore') + +export type WithPrimitiveValues = WithValuesOfTypes + +export function SetSourceLayerProperties( + versionStr: string, + sourceLayerId: string, + newValues: Omit>, '_id'> +): MigrationStepShowStyle { + return { + id: `${versionStr}.setSourceLayerProperties.${Object.keys(newValues).join('_')}.${sourceLayerId}`, + version: versionStr, + canBeRunAutomatically: true, + validate: (context: MigrationContextShowStyle) => { + const sourceLayer = context.getSourceLayer(sourceLayerId) + + if (!sourceLayer) { + // nothing to migrate + // getSourceLayerDefaultsMigrationSteps should create this layer later + return false + } + + return !_.isMatch(sourceLayer, newValues) + }, + migrate: (context: MigrationContextShowStyle) => { + context.updateSourceLayer(sourceLayerId, newValues) + } + } +} + +export function SetSourceLayerName( + versionStr: string, + sourceLayerId: string, + newValue: string +): MigrationStepShowStyle { + return SetSourceLayerProperties(versionStr, sourceLayerId, { name: newValue }) +} diff --git a/src/tv2-common/util.ts b/src/tv2-common/util.ts index fef6002fe..21af76fb8 100644 --- a/src/tv2-common/util.ts +++ b/src/tv2-common/util.ts @@ -7,6 +7,7 @@ export function assertUnreachable(_never: never): never { throw new Error('Switch validation failed, look for assertUnreachable(...)') } +export type WithValuesOfTypes = { [P in keyof T as T[P] extends Q | undefined ? P : never]: T[P] } export type OptionalExceptFor = Partial & Pick export type EmptyBaseObj = OptionalExceptFor, 'layer' | 'enable' | 'classes'> export function createEmptyObject(obj: EmptyBaseObj): TSR.TimelineObjEmpty { diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 7e30842de..3c00c39a0 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -1,4 +1,4 @@ -import { MigrationStepShowStyle } from '@sofie-automation/blueprints-integration' +import { MigrationStepShowStyle, SourceLayerType } from '@sofie-automation/blueprints-integration' import { AddGraphicToGFXTable, GetDSKSourceLayerNames, @@ -6,7 +6,8 @@ import { removeSourceLayer, SetShortcutListMigrationStep, SetShowstyleTransitionMigrationStep, - SetSourceLayerNameMigrationStep, + SetSourceLayerName, + SetSourceLayerProperties, StripFolderFromAudioBedConfig, StripFolderFromDVEConfig, UpsertValuesIntoTransitionTable @@ -127,40 +128,40 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal Date: Thu, 16 Dec 2021 19:42:03 +0100 Subject: [PATCH 012/184] chore: make linter happy should be good enough before w move to eslint --- src/tv2-common/util.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tv2-common/util.ts b/src/tv2-common/util.ts index 21af76fb8..057449956 100644 --- a/src/tv2-common/util.ts +++ b/src/tv2-common/util.ts @@ -7,6 +7,7 @@ export function assertUnreachable(_never: never): never { throw new Error('Switch validation failed, look for assertUnreachable(...)') } +// tslint:disable-next-line: prettier export type WithValuesOfTypes = { [P in keyof T as T[P] extends Q | undefined ? P : never]: T[P] } export type OptionalExceptFor = Partial & Pick export type EmptyBaseObj = OptionalExceptFor, 'layer' | 'enable' | 'classes'> From a2013a4d8acab56f594f19f9b04c1a914751d618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Tue, 18 Jan 2022 14:30:28 +0100 Subject: [PATCH 013/184] wip: Match graphicsprofile against showstyle variant name or fallback. --- src/tv2_afvd_showstyle/getRundown.ts | 7 ++++--- src/tv2_offtube_showstyle/getRundown.ts | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 2f276cf4d..26ab37d51 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -59,10 +59,11 @@ import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' export function getShowStyleVariantId( _context: IStudioUserContext, showStyleVariants: IBlueprintShowStyleVariant[], - _ingestRundown: IngestRundown + ingestRundown: IngestRundown ): string | null { - const variant = _.first(showStyleVariants) - + const graphicsProfile = ingestRundown.payload.graphicsProfile + const variant = showStyleVariants.find((v) => v.name === graphicsProfile) ?? _.first(showStyleVariants) + if (variant) { return variant._id } diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 2b3445411..6c61b3e64 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -64,9 +64,10 @@ import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' export function getShowStyleVariantId( _context: IStudioContext, showStyleVariants: IBlueprintShowStyleVariant[], - _ingestRundown: IngestRundown + ingestRundown: IngestRundown ): string | null { - const variant = _.first(showStyleVariants) + const graphicsProfile = ingestRundown.payload.graphicsProfile + const variant = showStyleVariants.find((v) => v.name === graphicsProfile) ?? _.first(showStyleVariants) if (variant) { return variant._id From f8f6ce9bd77ee0a75f5e09c396d9caad78aa1377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Wed, 19 Jan 2022 09:52:32 +0100 Subject: [PATCH 014/184] fix: renamed package import --- src/inews-mixins/__tests__/playlist.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inews-mixins/__tests__/playlist.spec.ts b/src/inews-mixins/__tests__/playlist.spec.ts index eea333578..9021c5559 100644 --- a/src/inews-mixins/__tests__/playlist.spec.ts +++ b/src/inews-mixins/__tests__/playlist.spec.ts @@ -3,7 +3,7 @@ import { ExtendedIngestRundown, IngestSegment, PlaylistTimingType -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { getRundownWithBackTime } from 'inews-mixins' import { ShowStyleUserContext } from '../../__mocks__/context' import { parseConfig as parseShowStyleConfig } from '../../tv2_afvd_showstyle/helpers/config' From ba031f7dd78a4b1fd9f89ff3f21511b52923d43c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Wed, 19 Jan 2022 14:37:23 +0100 Subject: [PATCH 015/184] fix: added flow producer filter to adlib hotkeys --- src/tv2-common/hotkeys/segment.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tv2-common/hotkeys/segment.ts b/src/tv2-common/hotkeys/segment.ts index d59a201bd..742d5832f 100644 --- a/src/tv2-common/hotkeys/segment.ts +++ b/src/tv2-common/hotkeys/segment.ts @@ -8,7 +8,7 @@ import { TriggerType } from '@tv2media/blueprints-integration' import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' -import { SharedSourceLayers } from 'tv2-constants' +import { AdlibTags, SharedSourceLayers } from 'tv2-constants' export interface ActiveSegmentHotketAssignments { lowerThirds: string[] @@ -68,6 +68,11 @@ function makeSegmentHotKey( field: 'segment', value: 'current' }), + literal({ + object: 'adLib', + field: 'tag', + value: [AdlibTags.ADLIB_FLOW_PRODUCER] + }), literal({ object: 'adLib', field: 'sourceLayerId', From 2f26e10eadd16ec48424c2bd0a08d010e6caa368 Mon Sep 17 00:00:00 2001 From: Krzysztof Zegzula Date: Thu, 20 Jan 2022 12:03:12 +0100 Subject: [PATCH 016/184] fix: update package import --- src/tv2-common/migrations/shortcuts.ts | 1 - src/tv2-common/migrations/sourceLayers.ts | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/tv2-common/migrations/shortcuts.ts b/src/tv2-common/migrations/shortcuts.ts index e47521dbd..a830b1d07 100644 --- a/src/tv2-common/migrations/shortcuts.ts +++ b/src/tv2-common/migrations/shortcuts.ts @@ -1,5 +1,4 @@ import { ISourceLayer, MigrationContextShowStyle, MigrationStepShowStyle } from '@tv2media/blueprints-integration' -import { literal } from 'tv2-common' export function SetShortcutListMigrationStep( versionStr: string, diff --git a/src/tv2-common/migrations/sourceLayers.ts b/src/tv2-common/migrations/sourceLayers.ts index 8c26f321f..84b613346 100644 --- a/src/tv2-common/migrations/sourceLayers.ts +++ b/src/tv2-common/migrations/sourceLayers.ts @@ -1,8 +1,4 @@ -import { - ISourceLayer, - MigrationContextShowStyle, - MigrationStepShowStyle -} from '@sofie-automation/blueprints-integration' +import { ISourceLayer, MigrationContextShowStyle, MigrationStepShowStyle } from '@tv2media/blueprints-integration' import { WithValuesOfTypes } from 'tv2-common' import _ = require('underscore') From cd5d3159f2f4928297187eb97f11be6701d5aba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Thu, 20 Jan 2022 14:32:53 +0100 Subject: [PATCH 017/184] fix: Renamed graphicsProfile to graphicProfile --- src/tv2_afvd_showstyle/getRundown.ts | 4 ++-- src/tv2_offtube_showstyle/getRundown.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 26ab37d51..91c85a1ec 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -61,8 +61,8 @@ export function getShowStyleVariantId( showStyleVariants: IBlueprintShowStyleVariant[], ingestRundown: IngestRundown ): string | null { - const graphicsProfile = ingestRundown.payload.graphicsProfile - const variant = showStyleVariants.find((v) => v.name === graphicsProfile) ?? _.first(showStyleVariants) + const graphicsprofile = ingestRundown.payload.graphicProfile + const variant = showStyleVariants.find((v) => v.name === graphicsprofile) ?? _.first(showStyleVariants) if (variant) { return variant._id diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 6c61b3e64..d1f86e488 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -66,8 +66,8 @@ export function getShowStyleVariantId( showStyleVariants: IBlueprintShowStyleVariant[], ingestRundown: IngestRundown ): string | null { - const graphicsProfile = ingestRundown.payload.graphicsProfile - const variant = showStyleVariants.find((v) => v.name === graphicsProfile) ?? _.first(showStyleVariants) + const graphicsprofile = ingestRundown.payload.graphicProfile + const variant = showStyleVariants.find((v) => v.name === graphicsprofile) ?? _.first(showStyleVariants) if (variant) { return variant._id From 3c68d9fc2c9ce6104baa211d1ffd127b5acdd772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Mon, 24 Jan 2022 09:03:19 +0100 Subject: [PATCH 018/184] fix: import --- src/inews-mixins/__tests__/playlist.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inews-mixins/__tests__/playlist.spec.ts b/src/inews-mixins/__tests__/playlist.spec.ts index eea333578..9021c5559 100644 --- a/src/inews-mixins/__tests__/playlist.spec.ts +++ b/src/inews-mixins/__tests__/playlist.spec.ts @@ -3,7 +3,7 @@ import { ExtendedIngestRundown, IngestSegment, PlaylistTimingType -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { getRundownWithBackTime } from 'inews-mixins' import { ShowStyleUserContext } from '../../__mocks__/context' import { parseConfig as parseShowStyleConfig } from '../../tv2_afvd_showstyle/helpers/config' From b8abb89b9bbae1758cf990ac5f0a6175f2761efa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Mon, 24 Jan 2022 12:44:39 +0100 Subject: [PATCH 019/184] lint: Formatting. --- src/tv2_afvd_showstyle/getRundown.ts | 4 ++-- src/tv2_offtube_showstyle/getRundown.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 91c85a1ec..e6672870a 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -62,8 +62,8 @@ export function getShowStyleVariantId( ingestRundown: IngestRundown ): string | null { const graphicsprofile = ingestRundown.payload.graphicProfile - const variant = showStyleVariants.find((v) => v.name === graphicsprofile) ?? _.first(showStyleVariants) - + const variant = showStyleVariants.find(v => v.name === graphicsprofile) ?? _.first(showStyleVariants) + if (variant) { return variant._id } diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index d1f86e488..e4dd5325a 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -67,7 +67,7 @@ export function getShowStyleVariantId( ingestRundown: IngestRundown ): string | null { const graphicsprofile = ingestRundown.payload.graphicProfile - const variant = showStyleVariants.find((v) => v.name === graphicsprofile) ?? _.first(showStyleVariants) + const variant = showStyleVariants.find(v => v.name === graphicsprofile) ?? _.first(showStyleVariants) if (variant) { return variant._id From b808e127121f1faff140f285ef7df2b091e01881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Mon, 24 Jan 2022 12:45:11 +0100 Subject: [PATCH 020/184] fix: Blueprints integration pointin to sofie-automation. --- src/inews-mixins/__tests__/playlist.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inews-mixins/__tests__/playlist.spec.ts b/src/inews-mixins/__tests__/playlist.spec.ts index eea333578..9021c5559 100644 --- a/src/inews-mixins/__tests__/playlist.spec.ts +++ b/src/inews-mixins/__tests__/playlist.spec.ts @@ -3,7 +3,7 @@ import { ExtendedIngestRundown, IngestSegment, PlaylistTimingType -} from '@sofie-automation/blueprints-integration' +} from '@tv2media/blueprints-integration' import { getRundownWithBackTime } from 'inews-mixins' import { ShowStyleUserContext } from '../../__mocks__/context' import { parseConfig as parseShowStyleConfig } from '../../tv2_afvd_showstyle/helpers/config' From 0ad138eddd2054a4ed795969b389759325d34a2c Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 25 Jan 2022 12:31:17 +0100 Subject: [PATCH 021/184] fix: inifnite loop in migrations disable default system-wide triggers instead of removing them, so that the core and system migrations don't fight with each other --- src/tv2_system/migrations/hotkeys.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/tv2_system/migrations/hotkeys.ts b/src/tv2_system/migrations/hotkeys.ts index ca1e74fae..ae6f98a45 100644 --- a/src/tv2_system/migrations/hotkeys.ts +++ b/src/tv2_system/migrations/hotkeys.ts @@ -1,8 +1,8 @@ import { ClientActions, IBlueprintTriggeredActions, - MigrationContextShowStyle, - MigrationStepShowStyle, + MigrationContextSystem, + MigrationStepSystem, PlayoutActions, TriggerType } from '@tv2media/blueprints-integration' @@ -11,22 +11,27 @@ import { literal } from 'tv2-common' export function RemoveDefaultCoreShortcuts(versionStr: string) { const defaultTriggerIds = DEFAULT_CORE_TRIGGERS.map(trigger => trigger._id) - return literal({ - id: `${versionStr}.removeCoreDefaultTriggers`, + return literal({ + id: `${versionStr}.disableCoreDefaultTriggers`, version: versionStr, canBeRunAutomatically: true, - validate: (context: MigrationContextShowStyle) => { + validate: (context: MigrationContextSystem) => { for (const coreTrigger of DEFAULT_CORE_TRIGGERS) { - if (context.getTriggeredAction(coreTrigger._id)) { + const defaultTrigger = context.getTriggeredAction(coreTrigger._id) + if (defaultTrigger && defaultTrigger.triggers.length) { return true } } return false }, - migrate: (context: MigrationContextShowStyle) => { + migrate: (context: MigrationContextSystem) => { for (const trigger of defaultTriggerIds) { - context.removeTriggeredAction(trigger) + const defaultTrigger = context.getTriggeredAction(trigger) + if (defaultTrigger) { + defaultTrigger.triggers = [] + context.setTriggeredAction(defaultTrigger) + } } } }) From 5fab05bc3a3749d6a5d9b5969e06e7c84cf67976 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 25 Jan 2022 12:33:57 +0100 Subject: [PATCH 022/184] fix: remove conflicting migrations some were for non-existing layers, some for non-existing properties --- src/tv2-common/migrations/shortcuts.ts | 62 ------------------- src/tv2_afvd_showstyle/migrations/index.ts | 23 +------ src/tv2_offtube_showstyle/migrations/index.ts | 23 +------ 3 files changed, 2 insertions(+), 106 deletions(-) diff --git a/src/tv2-common/migrations/shortcuts.ts b/src/tv2-common/migrations/shortcuts.ts index b950ae5af..22d51037b 100644 --- a/src/tv2-common/migrations/shortcuts.ts +++ b/src/tv2-common/migrations/shortcuts.ts @@ -1,36 +1,6 @@ import { ISourceLayer, MigrationContextShowStyle, MigrationStepShowStyle } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' -export function SetShortcutListMigrationStep( - versionStr: string, - sourceLayerId: string, - newValue: string -): MigrationStepShowStyle { - return literal({ - id: `${versionStr}.remapShortcuts.${sourceLayerId}`, - version: versionStr, - canBeRunAutomatically: true, - validate: (context: MigrationContextShowStyle) => { - const sourceLayer = context.getSourceLayer(sourceLayerId) - - if (!sourceLayer) { - return `Sourcelayer ${sourceLayerId} does not exists` - } - - // @ts-ignore: old property - return sourceLayer.activateKeyboardHotkeys !== newValue - }, - migrate: (context: MigrationContextShowStyle) => { - const sourceLayer = context.getSourceLayer(sourceLayerId) as ISourceLayer - - // @ts-ignore: old property - sourceLayer.activateKeyboardHotkeys = newValue - - context.updateSourceLayer(sourceLayerId, sourceLayer) - } - }) -} - export function SetSourceLayerNameMigrationStep( versionStr: string, sourceLayerId: string, @@ -58,35 +28,3 @@ export function SetSourceLayerNameMigrationStep( } }) } - -export function SetClearShortcutListTransitionStep( - versionStr: string, - sourceLayerId: string, - newValue: string -): MigrationStepShowStyle[] { - return [ - literal({ - id: `${versionStr}.remapClearShortcuts.${sourceLayerId}`, - version: versionStr, - canBeRunAutomatically: true, - validate: (context: MigrationContextShowStyle) => { - const sourceLayer = context.getSourceLayer(sourceLayerId) - - if (!sourceLayer) { - return `Sourcelayer ${sourceLayerId} does not exists` - } - - // @ts-ignore: old property - return sourceLayer.clearKeyboardHotkey !== newValue - }, - migrate: (context: MigrationContextShowStyle) => { - const sourceLayer = context.getSourceLayer(sourceLayerId) as ISourceLayer - - // @ts-ignore: old property - sourceLayer.clearKeyboardHotkey = newValue - - context.updateSourceLayer(sourceLayerId, sourceLayer) - } - }) - ] -} diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 62458bfa1..78a309df9 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -6,7 +6,6 @@ import { literal, RemoveOldShortcuts, removeSourceLayer, - SetShortcutListMigrationStep, SetShowstyleTransitionMigrationStep, SetSourceLayerNameMigrationStep, StripFolderFromAudioBedConfig, @@ -30,10 +29,6 @@ import { getCreateVariantMigrationSteps } from './variants-defaults' declare const VERSION: string // Injected by webpack -/** Migrations overriden later */ -// 1.3.1 -const jingle131 = SetShortcutListMigrationStep('1.3.1', SourceLayer.PgmJingle, 'NumpadDivide,NumpadSubtract,NumpadAdd') - const SHOW_STYLE_ID = 'tv2_afvd_showstyle' /** @@ -51,24 +46,12 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal = new Map([ export const remapVizDOvl: Map = new Map([['viz-d-ovl', 'OVL1']]) -/** Migrations overriden later */ -// 1.3.1 -const jingle131 = SetShortcutListMigrationStep( - '1.3.1', - OfftubeSourceLayer.PgmJingle, - 'NumpadDivide,NumpadSubtract,NumpadAdd' -) - const SHOW_STYLE_ID = 'tv2_offtube_showstyle' /** @@ -87,20 +78,12 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal Date: Tue, 25 Jan 2022 16:07:37 +0100 Subject: [PATCH 023/184] SOF-742 AFVD blueprint now creates objects to mute Sisyfos channels on all layers instead of just SisyfosLLAyer.SisyfosPersistedLevels --- .gitignore | 3 ++ src/tv2_afvd_showstyle/getRundown.ts | 41 ++++++++++++---------------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 7d5c53328..6456f91e3 100755 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ src/**.js wallaby.conf.js .DS_Store + +# Ignore JetBrains config files +.idea \ No newline at end of file diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 2f276cf4d..ca3c9a555 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -131,29 +131,24 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint } }) }), - literal({ - id: '', - enable: { - start: 0 - }, - priority: 1, - layer: SisyfosLLAyer.SisyfosPersistedLevels, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNELS, - overridePriority: 1, - channels: config.stickyLayers - .filter(layer => !info.sisyfosLayers || !info.sisyfosLayers.includes(layer)) - .map(layer => { - return { - mappedLayer: layer, - isPgm: 0 - } - }) - }, - metaData: { - sisyfosPersistLevel: true - } + ...config.stickyLayers.map(layer => { + return literal({ + id: '', + enable: { + start: 0 + }, + priority: 1, + layer, + content: { + deviceType: TSR.DeviceType.SISYFOS, + type: TSR.TimelineContentTypeSisyfos.CHANNEL, + overridePriority: 1, + isPgm: 0 + }, + metaData: { + sisyfosPersistLevel: true + } + }) }), GetSisyfosTimelineObjForCamera(context, config, 'evs', SisyfosLLAyer.SisyfosGroupStudioMics) ]) From 5860c3fb4fff5feba912c8ce00c29b25912168ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Wed, 26 Jan 2022 08:28:57 +0100 Subject: [PATCH 024/184] wip: Case insensitive graphic profile matching. --- src/tv2_afvd_showstyle/getRundown.ts | 4 ++-- src/tv2_offtube_showstyle/getRundown.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index e6672870a..bd8336934 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -61,8 +61,8 @@ export function getShowStyleVariantId( showStyleVariants: IBlueprintShowStyleVariant[], ingestRundown: IngestRundown ): string | null { - const graphicsprofile = ingestRundown.payload.graphicProfile - const variant = showStyleVariants.find(v => v.name === graphicsprofile) ?? _.first(showStyleVariants) + const graphicsprofile = ingestRundown.payload?.graphicProfile?.trim().toLowerCase(); + const variant = showStyleVariants.find(v => v.name.trim().toLowerCase() === graphicsprofile) ?? _.first(showStyleVariants) if (variant) { return variant._id diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index e4dd5325a..a39bdf2e3 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -66,8 +66,8 @@ export function getShowStyleVariantId( showStyleVariants: IBlueprintShowStyleVariant[], ingestRundown: IngestRundown ): string | null { - const graphicsprofile = ingestRundown.payload.graphicProfile - const variant = showStyleVariants.find(v => v.name === graphicsprofile) ?? _.first(showStyleVariants) + const graphicsprofile = ingestRundown.payload?.graphicProfile?.trim().toLowerCase(); + const variant = showStyleVariants.find(v => v.name.trim().toLowerCase() === graphicsprofile) ?? _.first(showStyleVariants) if (variant) { return variant._id From 1404200a66d08f80889676e02c5588fc08c9751d Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 26 Jan 2022 11:10:30 +0100 Subject: [PATCH 025/184] chore: remove stale files causing issues on Windows --- ...-test-afvd-341dd48e-011f7352:5da02370.json | 372 ------------ ...-test-afvd-341dd48e-011f7352:5da02371.json | 216 ------- ...-test-afvd-341dd48e-011f7352:5da02372.json | 538 ------------------ ...-test-afvd-341dd48e-011f7352:5da02373.json | 482 ---------------- ...-test-afvd-341dd48e-011f7352:5da02374.json | 487 ---------------- ...-test-afvd-341dd48e-011f7352:5da02375.json | 1 - ...-test-afvd-341dd48e-011f7352:5da02376.json | 1 - ...-test-afvd-341dd48e-011f7352:5da02377.json | 1 - 8 files changed, 2098 deletions(-) delete mode 100644 src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02370.json delete mode 100644 src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02371.json delete mode 100644 src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02372.json delete mode 100644 src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02373.json delete mode 100644 src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02374.json delete mode 100644 src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02375.json delete mode 100644 src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02376.json delete mode 100644 src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02377.json diff --git a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02370.json b/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02370.json deleted file mode 100644 index 031f8d401..000000000 --- a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02370.json +++ /dev/null @@ -1,372 +0,0 @@ -{ - "segment": { - "name": "KLAR ON-AIR", - "metaData": {}, - "identifier": "01", - "isHidden": false - }, - "parts": [ - { - "part": { - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "title": "KAM CS 3", - "metaData": {}, - "expectedDuration": 100000, - "displayDurationGroup": "341dd48e:011f7352:5da02370" - }, - "adLibPieces": [], - "pieces": [ - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "name": "CS 3 (JINGLE)", - "enable": { - "start": 0 - }, - "outputLayerId": "pgm", - "sourceLayerId": "studio0_jingle", - "infiniteMode": 1, - "content": { - "studioLabel": "", - "switcherInput": 6, - "timelineObjects": [ - { - "id": "N7k_5Hy6uHJj0_MrnSSBZcHKAmE_", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_me_program", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "input": 6, - "transition": 5, - "transitionSettings": {} - } - }, - "metaData": {} - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_me_clean", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "input": 6, - "transition": 5, - "transitionSettings": {} - } - }, - "metaData": { - "context": "Clean for N7k_5Hy6uHJj0_MrnSSBZcHKAmE_" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 0, - "layer": "atem_aux_lookahead", - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": 6 - } - }, - "metaData": { - "context": "Lookahead-lookahead for N7k_5Hy6uHJj0_MrnSSBZcHKAmE_" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_aux_video_mix_minus", - "metaData": { - "context": "Mix-minus for N7k_5Hy6uHJj0_MrnSSBZcHKAmE_" - }, - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": 6 - } - } - } - ] - } - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "name": "BG_LOADER_FODBOLD_20", - "enable": { - "start": 0 - }, - "outputLayerId": "sec", - "sourceLayerId": "studio0_dve_back", - "infiniteMode": 3, - "content": { - "fileName": "BG_LOADER_FODBOLD_20", - "path": "dve/BG_LOADER_FODBOLD_20", - "timelineObjects": [ - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 100, - "layer": "casparcg_dve_loop", - "content": { - "deviceType": 1, - "type": "media", - "file": "dve/BG_LOADER_FODBOLD_20", - "loop": true - } - } - ] - } - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "name": "BG_LOADER_FODBOLD_20", - "enable": { - "start": 40 - }, - "outputLayerId": "sec", - "sourceLayerId": "studio0_design", - "infiniteMode": 3, - "content": { - "fileName": "BG_LOADER_FODBOLD_20", - "path": "BG_LOADER_FODBOLD_20", - "timelineObjects": [ - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 100, - "layer": "viz_layer_design", - "content": { - "deviceType": 13, - "type": "element_internal", - "templateName": "BG_LOADER_FODBOLD_20", - "templateData": [] - } - } - ] - }, - "expectedPlayoutItems": [ - { - "deviceSubType": 13, - "content": { - "templateName": "BG_LOADER_FODBOLD_20", - "templateData": [], - "rundownId": "" - } - } - ] - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "name": "CLEAR studio0_graphicsIdent", - "enable": { - "start": 0, - "duration": 1000 - }, - "outputLayerId": "sec", - "sourceLayerId": "studio0_graphicsIdent", - "infiniteMode": 0, - "virtual": true - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "name": "CLEAR studio0_graphicsIdent_persistent", - "enable": { - "start": 0, - "duration": 1000 - }, - "outputLayerId": "sec", - "sourceLayerId": "studio0_graphicsIdent_persistent", - "infiniteMode": 0, - "virtual": true - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "name": "CLEAR studio0_graphicsTop", - "enable": { - "start": 0, - "duration": 1000 - }, - "outputLayerId": "sec", - "sourceLayerId": "studio0_graphicsTop", - "infiniteMode": 0, - "virtual": true - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "name": "CLEAR studio0_graphicsLower", - "enable": { - "start": 0, - "duration": 1000 - }, - "outputLayerId": "sec", - "sourceLayerId": "studio0_graphicsLower", - "infiniteMode": 0, - "virtual": true - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "name": "CLEAR studio0_graphicsHeadline", - "enable": { - "start": 0, - "duration": 1000 - }, - "outputLayerId": "sec", - "sourceLayerId": "studio0_graphicsHeadline", - "infiniteMode": 0, - "virtual": true - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "name": "CLEAR studio0_graphicsTema", - "enable": { - "start": 0, - "duration": 1000 - }, - "outputLayerId": "sec", - "sourceLayerId": "studio0_graphicsTema", - "infiniteMode": 0, - "virtual": true - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "name": "CLEAR studio0_overlay", - "enable": { - "start": 0, - "duration": 1000 - }, - "outputLayerId": "sec", - "sourceLayerId": "studio0_overlay", - "infiniteMode": 0, - "virtual": true - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "name": "CLEAR studio0_graphicsTelefon", - "enable": { - "start": 0, - "duration": 1000 - }, - "outputLayerId": "sec", - "sourceLayerId": "studio0_graphicsTelefon", - "infiniteMode": 0, - "virtual": true - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "name": "CLEAR", - "enable": { - "start": 0 - }, - "infiniteMode": 0, - "outputLayerId": "sec", - "sourceLayerId": "studio0_adlib_viz_cmd", - "content": { - "timelineObjects": [ - { - "id": "", - "enable": { - "start": 0, - "duration": 1000 - }, - "priority": 100, - "layer": "viz_layer_adlibs", - "content": { - "deviceType": 13, - "type": "clear_all_elements" - } - } - ] - }, - "expectedPlayoutItems": [ - { - "deviceSubType": 13, - "content": { - "templateName": "altud", - "channelName": "OVL1", - "templateData": [], - "rundownId": "" - } - } - ] - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02370-Kam-KAM-CS-3-CS-9", - "name": "DESIGN_FODBOLD_20", - "enable": { - "start": 40, - "duration": 4000 - }, - "outputLayerId": "overlay", - "sourceLayerId": "studio0_overlay", - "infiniteMode": 0, - "content": { - "fileName": "DESIGN_FODBOLD_20", - "path": "DESIGN_FODBOLD_20", - "timelineObjects": [ - { - "id": "", - "enable": { - "while": "!.full" - }, - "priority": 1, - "layer": "viz_layer_overlay", - "content": { - "deviceType": 13, - "type": "element_internal", - "templateName": "DESIGN_FODBOLD_20", - "templateData": [], - "channelName": "OVL1" - } - } - ] - }, - "expectedPlayoutItems": [ - { - "deviceSubType": 13, - "content": { - "templateName": "DESIGN_FODBOLD_20", - "templateData": [], - "channelName": "OVL1", - "rundownId": "" - } - } - ] - } - ] - } - ] -} \ No newline at end of file diff --git a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02371.json b/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02371.json deleted file mode 100644 index f67e29937..000000000 --- a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02371.json +++ /dev/null @@ -1,216 +0,0 @@ -{ - "segment": { - "name": "Test Segment 1", - "metaData": {}, - "identifier": "01", - "isHidden": false - }, - "parts": [ - { - "part": { - "externalId": "341dd48e:011f7352:5da02371-Unknown-SN_intro_19", - "title": "Unknown - ", - "metaData": {}, - "autoNext": true, - "expectedDuration": 8480, - "prerollDuration": 1160, - "autoNextOverlap": 240, - "disableOutTransition": true, - "displayDurationGroup": "341dd48e:011f7352:5da02371" - }, - "adLibPieces": [], - "pieces": [ - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02371-Unknown-SN_intro_19-JINGLE", - "name": "SN_intro_19", - "enable": { - "start": 0 - }, - "infiniteMode": 1, - "outputLayerId": "jingle", - "sourceLayerId": "studio0_jingle", - "content": { - "studioLabel": "", - "fileName": "SN_intro_19", - "path": "SN_intro_19", - "firstWords": "", - "lastWords": "", - "timelineObjects": [ - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "casparcg_player_jingle", - "content": { - "deviceType": 1, - "type": "media", - "file": "SN_intro_19" - } - }, - { - "id": "Ri5GnsQfBu_ZcXXbf_HOA_3TDYc_", - "enable": { - "start": 280 - }, - "priority": 1, - "layer": "atem_dsk_effect", - "content": { - "deviceType": 2, - "type": "dsk", - "dsk": { - "onAir": true, - "sources": { - "fillSource": 6, - "cutSource": 31 - }, - "properties": { - "tie": false, - "preMultiply": false, - "clip": 500, - "gain": 125, - "mask": { - "enabled": false - } - } - } - }, - "classes": [ - "MIX_MINUS_OVERRIDE_DSK" - ], - "metaData": {} - }, - { - "id": "", - "enable": { - "start": 280 - }, - "priority": 1, - "layer": "atem_clean_usk_effect", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "upstreamKeyers": [ - { - "upstreamKeyerId": 0, - "onAir": true, - "mixEffectKeyType": 0, - "flyEnabled": false, - "fillSource": 6, - "cutSource": 31, - "maskEnabled": false, - "lumaSettings": { - "preMultiplied": false, - "clip": 500, - "gain": 125 - } - } - ] - } - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_jingle", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 280 - }, - "priority": 1, - "layer": "atem_me_clean", - "content": { - "deviceType": 2, - "type": "dsk", - "dsk": { - "onAir": true, - "sources": { - "fillSource": 6, - "cutSource": 31 - }, - "properties": { - "tie": false, - "preMultiply": false, - "clip": 500, - "gain": 125, - "mask": { - "enabled": false - } - } - } - }, - "classes": [ - "MIX_MINUS_OVERRIDE_DSK" - ], - "metaData": { - "context": "Clean for Ri5GnsQfBu_ZcXXbf_HOA_3TDYc_" - } - }, - { - "id": "", - "enable": { - "start": 280 - }, - "priority": 10, - "layer": "atem_aux_video_mix_minus", - "classes": [ - "MIX_MINUS_OVERRIDE_DSK" - ], - "metaData": { - "context": "Mix-minus for Ri5GnsQfBu_ZcXXbf_HOA_3TDYc_" - }, - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": 6 - } - } - }, - { - "id": "", - "enable": { - "start": 280 - }, - "priority": 1, - "layer": "atem_clean_usk_effect", - "classes": [ - "MIX_MINUS_OVERRIDE_DSK" - ], - "metaData": {}, - "content": { - "deviceType": 2, - "type": "me", - "me": { - "upstreamKeyers": [ - { - "upstreamKeyerId": 0 - }, - { - "upstreamKeyerId": 1, - "onAir": true - } - ] - } - } - } - ] - } - } - ] - } - ] -} \ No newline at end of file diff --git a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02372.json b/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02372.json deleted file mode 100644 index 442fabb1b..000000000 --- a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02372.json +++ /dev/null @@ -1,538 +0,0 @@ -{ - "segment": { - "name": "Test Segment 2", - "metaData": {}, - "identifier": "02", - "isHidden": false - }, - "parts": [ - { - "part": { - "externalId": "341dd48e:011f7352:5da02372-Kam-KAM-1-1-0", - "title": "KAM 1", - "metaData": {}, - "expectedDuration": 7000, - "displayDurationGroup": "341dd48e:011f7352:5da02372" - }, - "adLibPieces": [], - "pieces": [ - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02372-Kam-KAM-1-1-0", - "name": "KAM 1", - "enable": { - "start": 0 - }, - "outputLayerId": "pgm", - "sourceLayerId": "studio0_camera", - "infiniteMode": 1, - "metaData": { - "stickySisyfosLevels": { - "sisyfos_source_Host_1_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Host_2_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_1_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_2_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_3_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_4_st_a": { - "value": 1, - "followsPrevious": false - } - } - }, - "content": { - "studioLabel": "", - "switcherInput": "1", - "timelineObjects": [ - { - "id": "V6OYyOnBiUrPpvNXAzRG9FHZzmk_", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_me_program", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "input": 1, - "transition": 5, - "transitionSettings": {} - } - }, - "metaData": {} - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Host_1_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Host_2_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_1_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_2_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_3_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_4_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_me_clean", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "input": 1, - "transition": 5, - "transitionSettings": {} - } - }, - "metaData": { - "context": "Clean for V6OYyOnBiUrPpvNXAzRG9FHZzmk_" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 0, - "layer": "atem_aux_lookahead", - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": 1 - } - }, - "metaData": { - "context": "Lookahead-lookahead for V6OYyOnBiUrPpvNXAzRG9FHZzmk_" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_aux_video_mix_minus", - "metaData": { - "context": "Mix-minus for V6OYyOnBiUrPpvNXAzRG9FHZzmk_" - }, - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": 1 - } - } - } - ] - } - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02372-Kam-KAM-1-1-0", - "name": "1111111", - "enable": { - "start": 0, - "duration": 7000 - }, - "outputLayerId": "manus", - "sourceLayerId": "studio0_script", - "infiniteMode": 1, - "content": { - "firstWords": "1111111", - "lastWords": "1111111", - "fullScript": "1111111", - "sourceDuration": 7000, - "lastModified": 1570775924000 - } - } - ] - }, - { - "part": { - "externalId": "341dd48e:011f7352:5da02372-EVS-1-false", - "title": "EVS1", - "metaData": {}, - "expectedDuration": 10000, - "displayDurationGroup": "341dd48e:011f7352:5da02372" - }, - "adLibPieces": [], - "pieces": [ - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02372-EVS-1-false", - "name": "EVS1", - "enable": { - "start": 0 - }, - "outputLayerId": "pgm", - "sourceLayerId": "studio0_live", - "infiniteMode": 1, - "content": { - "studioLabel": "", - "switcherInput": "5", - "timelineObjects": [ - { - "id": "4w12_sWFAqD_ta23nApWY8wQVw4_", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_me_program", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "input": "5", - "transition": 5, - "transitionSettings": {} - } - }, - "classes": [ - "studio0_parent_evs_1" - ], - "metaData": {} - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_evs_1", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_live_1", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 0 - }, - "metaData": { - "sisyfosPersistLevel": true - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_live_2", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 0 - }, - "metaData": { - "sisyfosPersistLevel": true - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_live_3", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 0 - }, - "metaData": { - "sisyfosPersistLevel": true - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_live_4", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 0 - }, - "metaData": { - "sisyfosPersistLevel": true - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_live_5", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 0 - }, - "metaData": { - "sisyfosPersistLevel": true - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_live_6", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 0 - }, - "metaData": { - "sisyfosPersistLevel": true - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_live_7", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 0 - }, - "metaData": { - "sisyfosPersistLevel": true - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_live_8", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 0 - }, - "metaData": { - "sisyfosPersistLevel": true - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_live_9", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 0 - }, - "metaData": { - "sisyfosPersistLevel": true - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_live_10", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 0 - }, - "metaData": { - "sisyfosPersistLevel": true - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_me_clean", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "input": "5", - "transition": 5, - "transitionSettings": {} - } - }, - "classes": [], - "metaData": { - "context": "Clean for 4w12_sWFAqD_ta23nApWY8wQVw4_" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 0, - "layer": "atem_aux_lookahead", - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": "5" - } - }, - "metaData": { - "context": "Lookahead-lookahead for 4w12_sWFAqD_ta23nApWY8wQVw4_" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_aux_video_mix_minus", - "classes": [], - "metaData": { - "context": "Mix-minus for 4w12_sWFAqD_ta23nApWY8wQVw4_" - }, - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": "5" - } - } - } - ] - } - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02372-EVS-1-false", - "name": "1111111111", - "enable": { - "start": 0, - "duration": 10000 - }, - "outputLayerId": "manus", - "sourceLayerId": "studio0_script", - "infiniteMode": 1, - "content": { - "firstWords": "1111111111", - "lastWords": "1111111111", - "fullScript": "1111111111", - "sourceDuration": 10000, - "lastModified": 1570775924000 - } - } - ] - } - ] -} \ No newline at end of file diff --git a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02373.json b/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02373.json deleted file mode 100644 index 1aa807ea2..000000000 --- a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02373.json +++ /dev/null @@ -1,482 +0,0 @@ -{ - "segment": { - "name": "Test Segment 3", - "metaData": {}, - "identifier": "03", - "isHidden": false - }, - "parts": [ - { - "part": { - "externalId": "341dd48e:011f7352:5da02373-Kam-KAM-2-2-0", - "title": "KAM 2", - "metaData": {}, - "expectedDuration": 7000, - "displayDurationGroup": "341dd48e:011f7352:5da02373" - }, - "adLibPieces": [], - "pieces": [ - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02373-Kam-KAM-2-2-0", - "name": "KAM 2", - "enable": { - "start": 0 - }, - "outputLayerId": "pgm", - "sourceLayerId": "studio0_camera", - "infiniteMode": 1, - "metaData": { - "stickySisyfosLevels": { - "sisyfos_source_Host_1_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Host_2_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_1_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_2_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_3_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_4_st_a": { - "value": 1, - "followsPrevious": false - } - } - }, - "content": { - "studioLabel": "", - "switcherInput": "2", - "timelineObjects": [ - { - "id": "UrCInIxCbogaZJVfeBdz3kiv1JY_", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_me_program", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "input": 2, - "transition": 5, - "transitionSettings": {} - } - }, - "metaData": {} - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Host_1_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Host_2_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_1_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_2_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_3_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_4_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_me_clean", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "input": 2, - "transition": 5, - "transitionSettings": {} - } - }, - "metaData": { - "context": "Clean for UrCInIxCbogaZJVfeBdz3kiv1JY_" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 0, - "layer": "atem_aux_lookahead", - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": 2 - } - }, - "metaData": { - "context": "Lookahead-lookahead for UrCInIxCbogaZJVfeBdz3kiv1JY_" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_aux_video_mix_minus", - "metaData": { - "context": "Mix-minus for UrCInIxCbogaZJVfeBdz3kiv1JY_" - }, - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": 2 - } - } - } - ] - } - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02373-Kam-KAM-2-2-0", - "name": "1111111", - "enable": { - "start": 0, - "duration": 7000 - }, - "outputLayerId": "manus", - "sourceLayerId": "studio0_script", - "infiniteMode": 1, - "content": { - "firstWords": "1111111", - "lastWords": "1111111", - "fullScript": "1111111", - "sourceDuration": 7000, - "lastModified": 1570775924000 - } - } - ] - }, - { - "part": { - "externalId": "341dd48e:011f7352:5da02373-Ekstern-LIVE-1", - "title": "Ekstern - ", - "metaData": {}, - "autoNext": false, - "expectedDuration": 10000, - "displayDurationGroup": "341dd48e:011f7352:5da02373" - }, - "adLibPieces": [], - "pieces": [ - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02373-Ekstern-LIVE-1", - "name": "LIVE 1", - "enable": { - "start": 0 - }, - "infiniteMode": 1, - "outputLayerId": "pgm", - "sourceLayerId": "studio0_live", - "toBeQueued": true, - "metaData": { - "stickySisyfosLevels": { - "sisyfos_source_live_1": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Host_1_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Host_2_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_1_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_2_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_3_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_4_st_a": { - "value": 1, - "followsPrevious": false - } - } - }, - "content": { - "studioLabel": "", - "switcherInput": "1", - "timelineObjects": [ - { - "id": "", - "priority": 0, - "enable": { - "start": 0 - }, - "layer": "ekstern_enable_ident", - "classes": [ - "show_ident_graphic" - ], - "content": { - "deviceType": 0, - "type": "empty" - } - }, - { - "id": "NwrJTkBu_xQL372U0XtKQmRvzIM_", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_me_program", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "input": "1", - "transition": 5, - "transitionSettings": {} - } - }, - "metaData": {} - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_live_1", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Host_1_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Host_2_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_1_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_2_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_3_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_4_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_me_clean", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "input": "1", - "transition": 5, - "transitionSettings": {} - } - }, - "metaData": { - "context": "Clean for NwrJTkBu_xQL372U0XtKQmRvzIM_" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 0, - "layer": "atem_aux_lookahead", - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": "1" - } - }, - "metaData": { - "context": "Lookahead-lookahead for NwrJTkBu_xQL372U0XtKQmRvzIM_" - } - } - ] - } - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02373-Ekstern-LIVE-1", - "name": "1111111111", - "enable": { - "start": 0, - "duration": 10000 - }, - "outputLayerId": "manus", - "sourceLayerId": "studio0_script", - "infiniteMode": 1, - "content": { - "firstWords": "1111111111", - "lastWords": "1111111111", - "fullScript": "1111111111", - "sourceDuration": 10000, - "lastModified": 1570775924000 - } - } - ] - } - ] -} \ No newline at end of file diff --git a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02374.json b/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02374.json deleted file mode 100644 index 62ba49bfc..000000000 --- a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02374.json +++ /dev/null @@ -1,487 +0,0 @@ -{ - "segment": { - "name": "Test Segment 4", - "metaData": {}, - "identifier": "04", - "isHidden": false - }, - "parts": [ - { - "part": { - "externalId": "341dd48e:011f7352:5da02374-Kam-KAM-1-1-0", - "title": "KAM 1", - "metaData": {}, - "expectedDuration": 8000, - "displayDurationGroup": "341dd48e:011f7352:5da02374" - }, - "adLibPieces": [], - "pieces": [ - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02374-Kam-KAM-1-1-0", - "name": "KAM 1", - "enable": { - "start": 0 - }, - "outputLayerId": "pgm", - "sourceLayerId": "studio0_camera", - "infiniteMode": 1, - "metaData": { - "stickySisyfosLevels": { - "sisyfos_source_Host_1_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Host_2_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_1_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_2_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_3_st_a": { - "value": 1, - "followsPrevious": false - }, - "sisyfos_source_Guest_4_st_a": { - "value": 1, - "followsPrevious": false - } - } - }, - "content": { - "studioLabel": "", - "switcherInput": "1", - "timelineObjects": [ - { - "id": "5gt4priNn0RyhMF2RUno3BV_U30_", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_me_program", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "input": 1, - "transition": 5, - "transitionSettings": {} - } - }, - "metaData": {} - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Host_1_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Host_2_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_1_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_2_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_3_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_4_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_me_clean", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "input": 1, - "transition": 5, - "transitionSettings": {} - } - }, - "metaData": { - "context": "Clean for 5gt4priNn0RyhMF2RUno3BV_U30_" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 0, - "layer": "atem_aux_lookahead", - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": 1 - } - }, - "metaData": { - "context": "Lookahead-lookahead for 5gt4priNn0RyhMF2RUno3BV_U30_" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "atem_aux_video_mix_minus", - "metaData": { - "context": "Mix-minus for 5gt4priNn0RyhMF2RUno3BV_U30_" - }, - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": 1 - } - } - } - ] - } - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02374-Kam-KAM-1-1-0", - "name": "11111111", - "enable": { - "start": 0, - "duration": 8000 - }, - "outputLayerId": "manus", - "sourceLayerId": "studio0_script", - "infiniteMode": 1, - "content": { - "firstWords": "11111111", - "lastWords": "11111111", - "fullScript": "11111111", - "sourceDuration": 8000, - "lastModified": 1570775924000 - } - } - ] - }, - { - "part": { - "externalId": "341dd48e:011f7352:5da02374-VO-01234A", - "title": "VO - 01234A", - "metaData": {}, - "expectedDuration": 20000, - "prerollDuration": 280, - "displayDurationGroup": "341dd48e:011f7352:5da02374" - }, - "adLibPieces": [], - "pieces": [ - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02374-VO-01234A", - "name": "VO - 01234A", - "enable": { - "start": 0 - }, - "outputLayerId": "pgm", - "sourceLayerId": "studio0_voiceover", - "infiniteMode": 1, - "metaData": { - "mediaPlayerSessions": [ - "341dd48e:011f7352:5da02374-VO-01234A" - ] - }, - "content": { - "studioLabel": "", - "fileName": "01234A", - "path": "/media\\01234A.mxf", - "mediaFlowIds": [ - "testflow0" - ], - "firstWords": "", - "lastWords": "", - "timelineObjects": [ - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "casparcg_player_clip_pending", - "content": { - "deviceType": 1, - "type": "media", - "file": "01234A", - "loop": false - }, - "metaData": { - "mediaPlayerSession": "341dd48e:011f7352:5da02374-VO-01234A" - } - }, - { - "id": "FuH_AGComJX2wl7gNEX6_uiyv80_", - "enable": { - "start": 280 - }, - "priority": 1, - "layer": "atem_me_program", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "transition": 5, - "transitionSettings": {} - } - }, - "metaData": { - "mediaPlayerSession": "341dd48e:011f7352:5da02374-VO-01234A" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_clip_pending", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - }, - "metaData": { - "mediaPlayerSession": "341dd48e:011f7352:5da02374-VO-01234A" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Host_1_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Host_2_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_1_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_2_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_3_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 1, - "layer": "sisyfos_source_Guest_4_st_a", - "content": { - "deviceType": 11, - "type": "sisyfos", - "isPgm": 1 - } - }, - { - "id": "", - "enable": { - "start": 280 - }, - "priority": 1, - "layer": "atem_me_clean", - "content": { - "deviceType": 2, - "type": "me", - "me": { - "transition": 5, - "transitionSettings": {} - } - }, - "metaData": { - "mediaPlayerSession": "341dd48e:011f7352:5da02374-VO-01234A", - "context": "Clean for FuH_AGComJX2wl7gNEX6_uiyv80_" - } - }, - { - "id": "", - "enable": { - "start": 0 - }, - "priority": 0, - "layer": "atem_aux_lookahead", - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": 2001 - } - }, - "metaData": { - "context": "Lookahead-lookahead for FuH_AGComJX2wl7gNEX6_uiyv80_", - "mediaPlayerSession": "341dd48e:011f7352:5da02374-VO-01234A" - } - }, - { - "id": "", - "enable": { - "start": 280 - }, - "priority": 1, - "layer": "atem_aux_video_mix_minus", - "metaData": { - "mediaPlayerSession": "341dd48e:011f7352:5da02374-VO-01234A", - "context": "Mix-minus for FuH_AGComJX2wl7gNEX6_uiyv80_" - }, - "content": { - "deviceType": 2, - "type": "aux", - "aux": { - "input": 2 - } - } - } - ] - }, - "adlibPreroll": 280 - }, - { - "_id": "", - "externalId": "341dd48e:011f7352:5da02374-VO-01234A", - "name": "11111111111111111111", - "enable": { - "start": 0, - "duration": 1000 - }, - "outputLayerId": "manus", - "sourceLayerId": "studio0_script", - "infiniteMode": 1, - "content": { - "firstWords": "11111111111111111111", - "lastWords": "11111111111111111111", - "fullScript": "11111111111111111111", - "sourceDuration": 1000, - "lastModified": 1570775924000 - } - } - ] - } - ] -} \ No newline at end of file diff --git a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02375.json b/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02375.json deleted file mode 100644 index e2ca1fcaa..000000000 --- a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02375.json +++ /dev/null @@ -1 +0,0 @@ -{"segment":{"name":"Test Segment 5","metaData":{},"identifier":"05","isHidden":false},"parts":[{"part":{"externalId":"341dd48e:011f7352:5da02375-Kam-KAM-1-1-1","title":"KAM 1","metaData":{},"typeVariant":"","expectedDuration":9000,"displayDurationGroup":"341dd48e:011f7352:5da02375"},"adLibPieces":[{"_rank":0,"externalId":"341dd48e:011f7352:5da02375-Kam-KAM-1-1-1","name":"Test Segment 5 Server: 01234A","sourceLayerId":"studio0_clip","outputLayerId":"pgm","infiniteMode":1,"toBeQueued":true,"metaData":{"mediaPlayerSessions":["auto"]},"content":{"studioLabel":"","fileName":"01234A","path":"/media\\01234A.mxf","mediaFlowIds":["testflow0"],"firstWords":"","lastWords":"","timelineObjects":[{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_player_clip_pending","content":{"deviceType":1,"type":"media","file":"01234A","loop":true},"metaData":{"mediaPlayerSession":"auto"}},{"id":"22BcIVbGSXJrAvaWDY2Kms4Gfek_","enable":{"start":280},"priority":1,"layer":"atem_me_program","content":{"deviceType":2,"type":"me","me":{"transition":5,"transitionSettings":{}}},"metaData":{"mediaPlayerSession":"auto"},"classes":["adlib_deparent"]},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_clip_pending","content":{"deviceType":11,"type":"sisyfos","isPgm":1},"metaData":{"mediaPlayerSession":"auto"}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Host_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Host_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_3_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_4_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_1","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_2","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_3","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_4","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_5","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_6","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_7","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_8","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_9","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_10","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":280},"priority":1,"layer":"atem_me_clean","content":{"deviceType":2,"type":"me","me":{"transition":5,"transitionSettings":{}}},"metaData":{"mediaPlayerSession":"auto","context":"Clean for 22BcIVbGSXJrAvaWDY2Kms4Gfek_"},"classes":["adlib_deparent"]},{"id":"","enable":{"start":0},"priority":0,"layer":"atem_aux_lookahead","content":{"deviceType":2,"type":"aux","aux":{"input":2001}},"metaData":{"context":"Lookahead-lookahead for 22BcIVbGSXJrAvaWDY2Kms4Gfek_","mediaPlayerSession":"auto"}},{"id":"","enable":{"start":280},"priority":1,"layer":"atem_aux_video_mix_minus","metaData":{"mediaPlayerSession":"auto","context":"Mix-minus for 22BcIVbGSXJrAvaWDY2Kms4Gfek_"},"classes":["adlib_deparent"],"content":{"deviceType":2,"type":"aux","aux":{"input":2}}}]},"adlibPreroll":280}],"pieces":[{"_id":"","externalId":"341dd48e:011f7352:5da02375-Kam-KAM-1-1-1","name":"KAM 1","enable":{"start":0},"outputLayerId":"pgm","sourceLayerId":"studio0_camera","infiniteMode":1,"metaData":{"stickySisyfosLevels":{"sisyfos_source_Host_1_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Host_2_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_1_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_2_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_3_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_4_st_a":{"value":1,"followsPrevious":false}}},"content":{"studioLabel":"","switcherInput":"1","timelineObjects":[{"id":"22BcIVbGSXJrAvaWDY2Kms4Gfek_","enable":{"start":0},"priority":1,"layer":"atem_me_program","content":{"deviceType":2,"type":"me","me":{"input":1,"transition":5,"transitionSettings":{}}},"metaData":{}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Host_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Host_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_3_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_4_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"atem_me_clean","content":{"deviceType":2,"type":"me","me":{"input":1,"transition":5,"transitionSettings":{}}},"metaData":{"context":"Clean for 22BcIVbGSXJrAvaWDY2Kms4Gfek_"}},{"id":"","enable":{"start":0},"priority":0,"layer":"atem_aux_lookahead","content":{"deviceType":2,"type":"aux","aux":{"input":1}},"metaData":{"context":"Lookahead-lookahead for 22BcIVbGSXJrAvaWDY2Kms4Gfek_"}},{"id":"","enable":{"start":0},"priority":1,"layer":"atem_aux_video_mix_minus","metaData":{"context":"Mix-minus for 22BcIVbGSXJrAvaWDY2Kms4Gfek_"},"content":{"deviceType":2,"type":"aux","aux":{"input":1}}}]}},{"_id":"","externalId":"341dd48e:011f7352:5da02375-Kam-KAM-1-1-1","name":"111111111","enable":{"start":0,"duration":9000},"outputLayerId":"manus","sourceLayerId":"studio0_script","infiniteMode":1,"content":{"firstWords":"111111111","lastWords":"111111111","fullScript":"111111111","sourceDuration":9000,"lastModified":1570775924000}}]},{"part":{"externalId":"341dd48e:011f7352:5da02375-VO-01234A","title":"VO - 01234A","metaData":{},"typeVariant":"","expectedDuration":25000,"prerollDuration":280,"displayDurationGroup":"341dd48e:011f7352:5da02375"},"adLibPieces":[],"pieces":[{"_id":"","externalId":"341dd48e:011f7352:5da02375-VO-01234A","name":"VO - 01234A","enable":{"start":0},"outputLayerId":"pgm","sourceLayerId":"studio0_voiceover","infiniteMode":1,"metaData":{"mediaPlayerSessions":["341dd48e:011f7352:5da02375-VO-01234A"]},"content":{"studioLabel":"","fileName":"01234A","path":"/media\\01234A.mxf","mediaFlowIds":["testflow0"],"firstWords":"","lastWords":"","timelineObjects":[{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_player_clip_pending","content":{"deviceType":1,"type":"media","file":"01234A","loop":false},"metaData":{"mediaPlayerSession":"341dd48e:011f7352:5da02375-VO-01234A"}},{"id":"FAgQVCZr_483RgZqOC2KBrx0_vo_","enable":{"start":280},"priority":1,"layer":"atem_me_program","content":{"deviceType":2,"type":"me","me":{"transition":5,"transitionSettings":{}}},"metaData":{"mediaPlayerSession":"341dd48e:011f7352:5da02375-VO-01234A"}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_clip_pending","content":{"deviceType":11,"type":"sisyfos","isPgm":1},"metaData":{"mediaPlayerSession":"341dd48e:011f7352:5da02375-VO-01234A"}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Host_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Host_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_3_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_4_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":280},"priority":1,"layer":"atem_me_clean","content":{"deviceType":2,"type":"me","me":{"transition":5,"transitionSettings":{}}},"metaData":{"mediaPlayerSession":"341dd48e:011f7352:5da02375-VO-01234A","context":"Clean for FAgQVCZr_483RgZqOC2KBrx0_vo_"}},{"id":"","enable":{"start":0},"priority":0,"layer":"atem_aux_lookahead","content":{"deviceType":2,"type":"aux","aux":{"input":2001}},"metaData":{"context":"Lookahead-lookahead for FAgQVCZr_483RgZqOC2KBrx0_vo_","mediaPlayerSession":"341dd48e:011f7352:5da02375-VO-01234A"}},{"id":"","enable":{"start":280},"priority":1,"layer":"atem_aux_video_mix_minus","metaData":{"mediaPlayerSession":"341dd48e:011f7352:5da02375-VO-01234A","context":"Mix-minus for FAgQVCZr_483RgZqOC2KBrx0_vo_"},"content":{"deviceType":2,"type":"aux","aux":{"input":2}}}]},"adlibPreroll":280},{"_id":"","externalId":"341dd48e:011f7352:5da02375-VO-01234A","name":"11111111111111111111","enable":{"start":0,"duration":5000},"outputLayerId":"manus","sourceLayerId":"studio0_script","infiniteMode":1,"content":{"firstWords":"11111111111111111111","lastWords":"11111111111111111111","fullScript":"11111111111111111111","sourceDuration":5000,"lastModified":1570775924000}}]}]} \ No newline at end of file diff --git a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02376.json b/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02376.json deleted file mode 100644 index 76240d42c..000000000 --- a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02376.json +++ /dev/null @@ -1 +0,0 @@ -{"segment":{"name":"Test Segment 6","metaData":{},"identifier":"06","isHidden":false},"parts":[{"part":{"externalId":"341dd48e:011f7352:5da02376-Kam-KAM-1-1-0","title":"KAM 1","metaData":{},"typeVariant":"","expectedDuration":10000,"displayDurationGroup":"341dd48e:011f7352:5da02376"},"adLibPieces":[],"pieces":[{"_id":"","externalId":"341dd48e:011f7352:5da02376-Kam-KAM-1-1-0","name":"KAM 1","enable":{"start":0},"outputLayerId":"pgm","sourceLayerId":"studio0_camera","infiniteMode":1,"metaData":{"stickySisyfosLevels":{"sisyfos_source_Host_1_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Host_2_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_1_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_2_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_3_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_4_st_a":{"value":1,"followsPrevious":false}}},"content":{"studioLabel":"","switcherInput":"1","timelineObjects":[{"id":"3YGVELhPsKui1dHclROCG3wIHzs_","enable":{"start":0},"priority":1,"layer":"atem_me_program","content":{"deviceType":2,"type":"me","me":{"input":1,"transition":5,"transitionSettings":{}}},"metaData":{}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Host_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Host_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_3_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_4_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"atem_me_clean","content":{"deviceType":2,"type":"me","me":{"input":1,"transition":5,"transitionSettings":{}}},"metaData":{"context":"Clean for 3YGVELhPsKui1dHclROCG3wIHzs_"}},{"id":"","enable":{"start":0},"priority":0,"layer":"atem_aux_lookahead","content":{"deviceType":2,"type":"aux","aux":{"input":1}},"metaData":{"context":"Lookahead-lookahead for 3YGVELhPsKui1dHclROCG3wIHzs_"}},{"id":"","enable":{"start":0},"priority":1,"layer":"atem_aux_video_mix_minus","metaData":{"context":"Mix-minus for 3YGVELhPsKui1dHclROCG3wIHzs_"},"content":{"deviceType":2,"type":"aux","aux":{"input":1}}}]}},{"_id":"","externalId":"341dd48e:011f7352:5da02376-Kam-KAM-1-1-0","name":"This is some text that should ","enable":{"start":0,"duration":10000},"outputLayerId":"manus","sourceLayerId":"studio0_script","infiniteMode":1,"content":{"firstWords":"This is some text that should ","lastWords":"uld be read in about 7 seconds","fullScript":"This is some text that should be read in about 7 seconds","sourceDuration":10000,"lastModified":1570775924000}}]},{"part":{"externalId":"341dd48e:011f7352:5da02376-DVE-SOMMERFUGL-2","title":"DVE - ","metaData":{},"typeVariant":"","autoNext":false,"expectedDuration":10000,"prerollDuration":280,"displayDurationGroup":"341dd48e:011f7352:5da02376"},"adLibPieces":[{"_rank":0,"externalId":"341dd48e:011f7352:5da02376-DVE-SOMMERFUGL-2","name":"Test Segment 6 DVE: SOMMERFUGL","outputLayerId":"pgm","sourceLayerId":"studio0_dve","infiniteMode":1,"toBeQueued":true,"content":{"boxSourceConfiguration":[{"studioLabel":"","switcherInput":1,"type":1,"timelineObjects":[]},{"studioLabel":"","switcherInput":2,"type":3,"timelineObjects":[]}],"dveConfiguration":{},"timelineObjects":[{"id":"","priority":0,"enable":{"start":0},"layer":"dve_lookahead_control","classes":["dve_on_air"],"content":{"deviceType":0,"type":"empty"}},{"id":"","enable":{"start":0},"priority":1,"layer":"atem_supersource_default","content":{"deviceType":2,"type":"ssrc","ssrc":{"boxes":[{"enabled":true,"source":1,"x":-800,"y":25,"size":550,"cropped":true,"cropTop":0,"cropBottom":150,"cropLeft":0,"cropRight":1500},{"enabled":true,"source":2,"x":800,"y":25,"size":550,"cropped":true,"cropTop":160,"cropBottom":150,"cropLeft":0,"cropRight":0},{"enabled":false,"source":2001,"x":0,"y":0,"size":1000,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},{"enabled":false,"source":2001,"x":0,"y":0,"size":1000,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0}]}},"classes":["studio0_dve_box1_atem_supersource_z_box1","studio0_dve_box2_atem_supersource_z_box2"],"metaData":{}},{"id":"","enable":{"start":270},"priority":1,"layer":"atem_supersource_art","content":{"deviceType":2,"type":"ssrcProps","ssrcProps":{"artFillSource":30,"artCutSource":32,"artOption":1,"artPreMultiplied":true}}},{"id":"0uqqboyrKnVBJFZnI3ixcChxkw8_","enable":{"start":200},"priority":1,"layer":"atem_me_program","content":{"deviceType":2,"type":"me","me":{"input":6000,"transition":5}},"metaData":{}},{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_cg_dve_template","content":{"deviceType":1,"type":"template","templateType":"html","name":"dve/locators","data":{"display":{"isPreview":false,"displayState":"locators"},"locators":{"style":{"common":{"font-family":"Alright Sans LT","font-weight":"bold","font-variant":"italic","color":"#ffffff","font-size":"35px","background":"rgba(0, 0, 0, 0.5)","height":"45px","line-height":"48px","padding-left":"13px","padding-right":"13px"},"locator1":{"left":"120px","top":"825px"},"locator2":{"right":"100px","top":"825px"}},"content":{"locator1":"Madrid"}}},"useStopCommand":false}},{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_dve_key","content":{"deviceType":1,"type":"media","file":"dve/sommerfuglK","mixer":{"keyer":true},"loop":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_dve_frame","content":{"deviceType":1,"type":"media","file":"dve/sommerfugl","loop":true}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Host_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Host_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_3_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_4_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box2"},"priority":1,"layer":"sisyfos_source_live_2","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":200},"priority":1,"layer":"atem_me_clean","content":{"deviceType":2,"type":"me","me":{"input":6000,"transition":5}},"metaData":{"context":"Clean for 0uqqboyrKnVBJFZnI3ixcChxkw8_"}},{"id":"","enable":{"start":0},"priority":0,"layer":"atem_aux_lookahead","content":{"deviceType":2,"type":"aux","aux":{"input":6000}},"metaData":{"context":"Lookahead-lookahead for 0uqqboyrKnVBJFZnI3ixcChxkw8_"}},{"id":"","enable":{"start":200},"priority":1,"layer":"atem_aux_video_mix_minus","metaData":{"context":"Mix-minus for 0uqqboyrKnVBJFZnI3ixcChxkw8_"},"content":{"deviceType":2,"type":"aux","aux":{"input":1}}}]},"adlibPreroll":280}],"pieces":[{"_id":"","externalId":"341dd48e:011f7352:5da02376-DVE-SOMMERFUGL-2","name":"DVE: SOMMERFUGL","enable":{"start":0},"outputLayerId":"pgm","sourceLayerId":"studio0_dve","infiniteMode":1,"toBeQueued":true,"content":{"boxSourceConfiguration":[{"studioLabel":"","switcherInput":1,"type":1,"timelineObjects":[]},{"studioLabel":"","switcherInput":2,"type":3,"timelineObjects":[]}],"dveConfiguration":{},"timelineObjects":[{"id":"","priority":0,"enable":{"start":0},"layer":"dve_lookahead_control","classes":["dve_on_air"],"content":{"deviceType":0,"type":"empty"}},{"id":"","enable":{"start":0},"priority":1,"layer":"atem_supersource_default","content":{"deviceType":2,"type":"ssrc","ssrc":{"boxes":[{"enabled":true,"source":1,"x":-800,"y":25,"size":550,"cropped":true,"cropTop":0,"cropBottom":150,"cropLeft":0,"cropRight":1500},{"enabled":true,"source":2,"x":800,"y":25,"size":550,"cropped":true,"cropTop":160,"cropBottom":150,"cropLeft":0,"cropRight":0},{"enabled":false,"source":2001,"x":0,"y":0,"size":1000,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},{"enabled":false,"source":2001,"x":0,"y":0,"size":1000,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0}]}},"classes":["studio0_dve_box1_atem_supersource_z_box1","studio0_dve_box2_atem_supersource_z_box2"],"metaData":{}},{"id":"","enable":{"start":270},"priority":1,"layer":"atem_supersource_art","content":{"deviceType":2,"type":"ssrcProps","ssrcProps":{"artFillSource":30,"artCutSource":32,"artOption":1,"artPreMultiplied":true}}},{"id":"0uqqboyrKnVBJFZnI3ixcChxkw8_","enable":{"start":200},"priority":1,"layer":"atem_me_program","content":{"deviceType":2,"type":"me","me":{"input":6000,"transition":5}},"metaData":{}},{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_cg_dve_template","content":{"deviceType":1,"type":"template","templateType":"html","name":"dve/locators","data":{"display":{"isPreview":false,"displayState":"locators"},"locators":{"style":{"common":{"font-family":"Alright Sans LT","font-weight":"bold","font-variant":"italic","color":"#ffffff","font-size":"35px","background":"rgba(0, 0, 0, 0.5)","height":"45px","line-height":"48px","padding-left":"13px","padding-right":"13px"},"locator1":{"left":"120px","top":"825px"},"locator2":{"right":"100px","top":"825px"}},"content":{"locator1":"Madrid"}}},"useStopCommand":false}},{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_dve_key","content":{"deviceType":1,"type":"media","file":"dve/sommerfuglK","mixer":{"keyer":true},"loop":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_dve_frame","content":{"deviceType":1,"type":"media","file":"dve/sommerfugl","loop":true}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Host_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Host_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_3_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_4_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box2"},"priority":1,"layer":"sisyfos_source_live_2","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":200},"priority":1,"layer":"atem_me_clean","content":{"deviceType":2,"type":"me","me":{"input":6000,"transition":5}},"metaData":{"context":"Clean for 0uqqboyrKnVBJFZnI3ixcChxkw8_"}},{"id":"","enable":{"start":0},"priority":0,"layer":"atem_aux_lookahead","content":{"deviceType":2,"type":"aux","aux":{"input":6000}},"metaData":{"context":"Lookahead-lookahead for 0uqqboyrKnVBJFZnI3ixcChxkw8_"}},{"id":"","enable":{"start":200},"priority":1,"layer":"atem_aux_video_mix_minus","metaData":{"context":"Mix-minus for 0uqqboyrKnVBJFZnI3ixcChxkw8_"},"content":{"deviceType":2,"type":"aux","aux":{"input":1}}}]},"adlibPreroll":280}]},{"part":{"externalId":"341dd48e:011f7352:5da02376-Ekstern-LIVE-2","title":"Ekstern - ","metaData":{},"typeVariant":"","autoNext":false,"expectedDuration":10000,"displayDurationGroup":"341dd48e:011f7352:5da02376"},"adLibPieces":[],"pieces":[{"_id":"","externalId":"341dd48e:011f7352:5da02376-Ekstern-LIVE-2","name":"LIVE 2","enable":{"start":0},"infiniteMode":1,"outputLayerId":"pgm","sourceLayerId":"studio0_live","toBeQueued":true,"metaData":{"stickySisyfosLevels":{"sisyfos_source_live_2":{"value":1,"followsPrevious":false},"sisyfos_source_Host_1_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Host_2_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_1_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_2_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_3_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_4_st_a":{"value":1,"followsPrevious":false}}},"content":{"studioLabel":"","switcherInput":"2","timelineObjects":[{"id":"","priority":0,"enable":{"start":0},"layer":"ekstern_enable_ident","classes":["show_ident_graphic"],"content":{"deviceType":0,"type":"empty"}},{"id":"PECI_rqLeh_uKI0IhsSpxL9H_o8_","enable":{"start":0},"priority":1,"layer":"atem_me_program","content":{"deviceType":2,"type":"me","me":{"input":"2","transition":5,"transitionSettings":{}}},"metaData":{}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_2","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Host_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Host_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_3_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_4_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"atem_me_clean","content":{"deviceType":2,"type":"me","me":{"input":"2","transition":5,"transitionSettings":{}}},"metaData":{"context":"Clean for PECI_rqLeh_uKI0IhsSpxL9H_o8_"}},{"id":"","enable":{"start":0},"priority":0,"layer":"atem_aux_lookahead","content":{"deviceType":2,"type":"aux","aux":{"input":"2"}},"metaData":{"context":"Lookahead-lookahead for PECI_rqLeh_uKI0IhsSpxL9H_o8_"}}]}}]},{"part":{"externalId":"341dd48e:011f7352:5da02376-GAP","title":"Adlib Gap","metaData":{},"typeVariant":"","gap":true,"invalid":true,"expectedDuration":157000,"displayDurationGroup":"341dd48e:011f7352:5da02376"},"pieces":[],"adLibPieces":[]}]} \ No newline at end of file diff --git a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02377.json b/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02377.json deleted file mode 100644 index 0afdd9784..000000000 --- a/src/tv2_afvd_showstyle/__tests__/regressions-afkd-reference/regression-test-afvd-341dd48e-011f7352:5da02377.json +++ /dev/null @@ -1 +0,0 @@ -{"segment":{"name":"Test Segment 7","metaData":{},"identifier":"06","isHidden":false},"parts":[{"part":{"externalId":"341dd48e:011f7352:5da02377-EVS-1-false","title":"EVS1","metaData":{},"typeVariant":"","expectedDuration":10000,"displayDurationGroup":"341dd48e:011f7352:5da02377"},"adLibPieces":[],"pieces":[{"_id":"","externalId":"341dd48e:011f7352:5da02377-EVS-1-false","name":"EVS1","enable":{"start":0},"outputLayerId":"pgm","sourceLayerId":"studio0_live","infiniteMode":1,"content":{"studioLabel":"","switcherInput":"5","timelineObjects":[{"id":"MYYEjnmFoaHRYbymqQdk5YgqkxE_","enable":{"start":0},"priority":1,"layer":"atem_me_program","content":{"deviceType":2,"type":"me","me":{"input":"5","transition":5,"transitionSettings":{}}},"classes":["studio0_parent_evs_1"],"metaData":{}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_evs_1","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_1","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_2","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_3","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_4","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_5","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_6","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_7","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_8","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_9","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_10","content":{"deviceType":11,"type":"sisyfos","isPgm":0},"metaData":{"sisyfosPersistLevel":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"atem_me_clean","content":{"deviceType":2,"type":"me","me":{"input":"5","transition":5,"transitionSettings":{}}},"classes":[],"metaData":{"context":"Clean for MYYEjnmFoaHRYbymqQdk5YgqkxE_"}},{"id":"","enable":{"start":0},"priority":0,"layer":"atem_aux_lookahead","content":{"deviceType":2,"type":"aux","aux":{"input":"5"}},"metaData":{"context":"Lookahead-lookahead for MYYEjnmFoaHRYbymqQdk5YgqkxE_"}},{"id":"","enable":{"start":0},"priority":1,"layer":"atem_aux_video_mix_minus","classes":[],"metaData":{"context":"Mix-minus for MYYEjnmFoaHRYbymqQdk5YgqkxE_"},"content":{"deviceType":2,"type":"aux","aux":{"input":"5"}}}]}},{"_id":"","externalId":"341dd48e:011f7352:5da02377-EVS-1-false","name":"This is some text that should ","enable":{"start":0,"duration":10000},"outputLayerId":"manus","sourceLayerId":"studio0_script","infiniteMode":1,"content":{"firstWords":"This is some text that should ","lastWords":"uld be read in about 7 seconds","fullScript":"This is some text that should be read in about 7 seconds","sourceDuration":10000,"lastModified":1570775924000}}]},{"part":{"externalId":"341dd48e:011f7352:5da02377-DVE-SOMMERFUGL-2","title":"DVE - ","metaData":{},"typeVariant":"","autoNext":false,"expectedDuration":10000,"prerollDuration":280,"displayDurationGroup":"341dd48e:011f7352:5da02377"},"adLibPieces":[{"_rank":0,"externalId":"341dd48e:011f7352:5da02377-DVE-SOMMERFUGL-2","name":"Test Segment 7 DVE: SOMMERFUGL","outputLayerId":"pgm","sourceLayerId":"studio0_dve","infiniteMode":1,"toBeQueued":true,"content":{"boxSourceConfiguration":[{"studioLabel":"","switcherInput":1,"type":1,"timelineObjects":[]},{"studioLabel":"","switcherInput":2,"type":3,"timelineObjects":[]}],"dveConfiguration":{},"timelineObjects":[{"id":"","priority":0,"enable":{"start":0},"layer":"dve_lookahead_control","classes":["dve_on_air"],"content":{"deviceType":0,"type":"empty"}},{"id":"","enable":{"start":0},"priority":1,"layer":"atem_supersource_default","content":{"deviceType":2,"type":"ssrc","ssrc":{"boxes":[{"enabled":true,"source":1,"x":-800,"y":25,"size":550,"cropped":true,"cropTop":0,"cropBottom":150,"cropLeft":0,"cropRight":1500},{"enabled":true,"source":2,"x":800,"y":25,"size":550,"cropped":true,"cropTop":160,"cropBottom":150,"cropLeft":0,"cropRight":0},{"enabled":false,"source":2001,"x":0,"y":0,"size":1000,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},{"enabled":false,"source":2001,"x":0,"y":0,"size":1000,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0}]}},"classes":["studio0_dve_box1_atem_supersource_z_box1","studio0_dve_box2_atem_supersource_z_box2"],"metaData":{}},{"id":"","enable":{"start":270},"priority":1,"layer":"atem_supersource_art","content":{"deviceType":2,"type":"ssrcProps","ssrcProps":{"artFillSource":30,"artCutSource":32,"artOption":1,"artPreMultiplied":true}}},{"id":"84LV_qIX_vagipRHJOLVJfAk4KE_","enable":{"start":200},"priority":1,"layer":"atem_me_program","content":{"deviceType":2,"type":"me","me":{"input":6000,"transition":5}},"metaData":{}},{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_cg_dve_template","content":{"deviceType":1,"type":"template","templateType":"html","name":"dve/locators","data":{"display":{"isPreview":false,"displayState":"locators"},"locators":{"style":{"common":{"font-family":"Alright Sans LT","font-weight":"bold","font-variant":"italic","color":"#ffffff","font-size":"35px","background":"rgba(0, 0, 0, 0.5)","height":"45px","line-height":"48px","padding-left":"13px","padding-right":"13px"},"locator1":{"left":"120px","top":"825px"},"locator2":{"right":"100px","top":"825px"}},"content":{"locator1":"Madrid"}}},"useStopCommand":false}},{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_dve_key","content":{"deviceType":1,"type":"media","file":"dve/sommerfuglK","mixer":{"keyer":true},"loop":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_dve_frame","content":{"deviceType":1,"type":"media","file":"dve/sommerfugl","loop":true}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Host_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Host_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_3_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_4_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box2"},"priority":1,"layer":"sisyfos_source_live_2","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":200},"priority":1,"layer":"atem_me_clean","content":{"deviceType":2,"type":"me","me":{"input":6000,"transition":5}},"metaData":{"context":"Clean for 84LV_qIX_vagipRHJOLVJfAk4KE_"}},{"id":"","enable":{"start":0},"priority":0,"layer":"atem_aux_lookahead","content":{"deviceType":2,"type":"aux","aux":{"input":6000}},"metaData":{"context":"Lookahead-lookahead for 84LV_qIX_vagipRHJOLVJfAk4KE_"}},{"id":"","enable":{"start":200},"priority":1,"layer":"atem_aux_video_mix_minus","metaData":{"context":"Mix-minus for 84LV_qIX_vagipRHJOLVJfAk4KE_"},"content":{"deviceType":2,"type":"aux","aux":{"input":1}}}]},"adlibPreroll":280}],"pieces":[{"_id":"","externalId":"341dd48e:011f7352:5da02377-DVE-SOMMERFUGL-2","name":"DVE: SOMMERFUGL","enable":{"start":0},"outputLayerId":"pgm","sourceLayerId":"studio0_dve","infiniteMode":1,"toBeQueued":true,"content":{"boxSourceConfiguration":[{"studioLabel":"","switcherInput":1,"type":1,"timelineObjects":[]},{"studioLabel":"","switcherInput":2,"type":3,"timelineObjects":[]}],"dveConfiguration":{},"timelineObjects":[{"id":"","priority":0,"enable":{"start":0},"layer":"dve_lookahead_control","classes":["dve_on_air"],"content":{"deviceType":0,"type":"empty"}},{"id":"","enable":{"start":0},"priority":1,"layer":"atem_supersource_default","content":{"deviceType":2,"type":"ssrc","ssrc":{"boxes":[{"enabled":true,"source":1,"x":-800,"y":25,"size":550,"cropped":true,"cropTop":0,"cropBottom":150,"cropLeft":0,"cropRight":1500},{"enabled":true,"source":2,"x":800,"y":25,"size":550,"cropped":true,"cropTop":160,"cropBottom":150,"cropLeft":0,"cropRight":0},{"enabled":false,"source":2001,"x":0,"y":0,"size":1000,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0},{"enabled":false,"source":2001,"x":0,"y":0,"size":1000,"cropped":false,"cropTop":0,"cropBottom":0,"cropLeft":0,"cropRight":0}]}},"classes":["studio0_dve_box1_atem_supersource_z_box1","studio0_dve_box2_atem_supersource_z_box2"],"metaData":{}},{"id":"","enable":{"start":270},"priority":1,"layer":"atem_supersource_art","content":{"deviceType":2,"type":"ssrcProps","ssrcProps":{"artFillSource":30,"artCutSource":32,"artOption":1,"artPreMultiplied":true}}},{"id":"84LV_qIX_vagipRHJOLVJfAk4KE_","enable":{"start":200},"priority":1,"layer":"atem_me_program","content":{"deviceType":2,"type":"me","me":{"input":6000,"transition":5}},"metaData":{}},{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_cg_dve_template","content":{"deviceType":1,"type":"template","templateType":"html","name":"dve/locators","data":{"display":{"isPreview":false,"displayState":"locators"},"locators":{"style":{"common":{"font-family":"Alright Sans LT","font-weight":"bold","font-variant":"italic","color":"#ffffff","font-size":"35px","background":"rgba(0, 0, 0, 0.5)","height":"45px","line-height":"48px","padding-left":"13px","padding-right":"13px"},"locator1":{"left":"120px","top":"825px"},"locator2":{"right":"100px","top":"825px"}},"content":{"locator1":"Madrid"}}},"useStopCommand":false}},{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_dve_key","content":{"deviceType":1,"type":"media","file":"dve/sommerfuglK","mixer":{"keyer":true},"loop":true}},{"id":"","enable":{"start":0},"priority":1,"layer":"casparcg_dve_frame","content":{"deviceType":1,"type":"media","file":"dve/sommerfugl","loop":true}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Host_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Host_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_3_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box1"},"priority":1,"layer":"sisyfos_source_Guest_4_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"while":"!$studio0_dve_box2"},"priority":1,"layer":"sisyfos_source_live_2","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":200},"priority":1,"layer":"atem_me_clean","content":{"deviceType":2,"type":"me","me":{"input":6000,"transition":5}},"metaData":{"context":"Clean for 84LV_qIX_vagipRHJOLVJfAk4KE_"}},{"id":"","enable":{"start":0},"priority":0,"layer":"atem_aux_lookahead","content":{"deviceType":2,"type":"aux","aux":{"input":6000}},"metaData":{"context":"Lookahead-lookahead for 84LV_qIX_vagipRHJOLVJfAk4KE_"}},{"id":"","enable":{"start":200},"priority":1,"layer":"atem_aux_video_mix_minus","metaData":{"context":"Mix-minus for 84LV_qIX_vagipRHJOLVJfAk4KE_"},"content":{"deviceType":2,"type":"aux","aux":{"input":1}}}]},"adlibPreroll":280}]},{"part":{"externalId":"341dd48e:011f7352:5da02377-Ekstern-LIVE-2","title":"Ekstern - ","metaData":{},"typeVariant":"","autoNext":false,"expectedDuration":10000,"displayDurationGroup":"341dd48e:011f7352:5da02377"},"adLibPieces":[],"pieces":[{"_id":"","externalId":"341dd48e:011f7352:5da02377-Ekstern-LIVE-2","name":"LIVE 2","enable":{"start":0},"infiniteMode":1,"outputLayerId":"pgm","sourceLayerId":"studio0_live","toBeQueued":true,"metaData":{"stickySisyfosLevels":{"sisyfos_source_live_2":{"value":1,"followsPrevious":false},"sisyfos_source_Host_1_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Host_2_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_1_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_2_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_3_st_a":{"value":1,"followsPrevious":false},"sisyfos_source_Guest_4_st_a":{"value":1,"followsPrevious":false}}},"content":{"studioLabel":"","switcherInput":"2","timelineObjects":[{"id":"","priority":0,"enable":{"start":0},"layer":"ekstern_enable_ident","classes":["show_ident_graphic"],"content":{"deviceType":0,"type":"empty"}},{"id":"TLKXtExrBJmztLfb0r7lhipO2kE_","enable":{"start":0},"priority":1,"layer":"atem_me_program","content":{"deviceType":2,"type":"me","me":{"input":"2","transition":5,"transitionSettings":{}}},"metaData":{}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_live_2","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Host_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Host_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_1_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_2_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_3_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"sisyfos_source_Guest_4_st_a","content":{"deviceType":11,"type":"sisyfos","isPgm":1}},{"id":"","enable":{"start":0},"priority":1,"layer":"atem_me_clean","content":{"deviceType":2,"type":"me","me":{"input":"2","transition":5,"transitionSettings":{}}},"metaData":{"context":"Clean for TLKXtExrBJmztLfb0r7lhipO2kE_"}},{"id":"","enable":{"start":0},"priority":0,"layer":"atem_aux_lookahead","content":{"deviceType":2,"type":"aux","aux":{"input":"2"}},"metaData":{"context":"Lookahead-lookahead for TLKXtExrBJmztLfb0r7lhipO2kE_"}}]}}]},{"part":{"externalId":"341dd48e:011f7352:5da02377-GAP","title":"Adlib Gap","metaData":{},"typeVariant":"","gap":true,"invalid":true,"expectedDuration":157000,"displayDurationGroup":"341dd48e:011f7352:5da02377"},"pieces":[],"adLibPieces":[]}]} \ No newline at end of file From 2e40702ecaecad941e80ba06ceb5c918ad04f855 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 26 Jan 2022 12:26:36 +0100 Subject: [PATCH 026/184] SOF-742 Include filtering sisofys layers --- src/tv2_afvd_showstyle/getRundown.ts | 40 +++++++++++++++------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index ca3c9a555..777c0d075 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -131,25 +131,27 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint } }) }), - ...config.stickyLayers.map(layer => { - return literal({ - id: '', - enable: { - start: 0 - }, - priority: 1, - layer, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - overridePriority: 1, - isPgm: 0 - }, - metaData: { - sisyfosPersistLevel: true - } - }) - }), + ...config.stickyLayers + .filter(layer => !info.sisyfosLayers || !info.sisyfosLayers.includes(layer)) + .map(layer => { + return literal({ + id: '', + enable: { + start: 0 + }, + priority: 1, + layer, + content: { + deviceType: TSR.DeviceType.SISYFOS, + type: TSR.TimelineContentTypeSisyfos.CHANNEL, + overridePriority: 1, + isPgm: 0 + }, + metaData: { + sisyfosPersistLevel: true + } + }) + }), GetSisyfosTimelineObjForCamera(context, config, 'evs', SisyfosLLAyer.SisyfosGroupStudioMics) ]) } From 862a2d808ca81667f6ce4d0397c46d11f0b2a948 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Thu, 27 Jan 2022 12:38:27 +0100 Subject: [PATCH 027/184] SOF-742 EVS AddLib no longer checks for layers to persist in Sisyfos --- src/tv2_afvd_showstyle/getRundown.ts | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 777c0d075..8b3b86fea 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -131,27 +131,6 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint } }) }), - ...config.stickyLayers - .filter(layer => !info.sisyfosLayers || !info.sisyfosLayers.includes(layer)) - .map(layer => { - return literal({ - id: '', - enable: { - start: 0 - }, - priority: 1, - layer, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - overridePriority: 1, - isPgm: 0 - }, - metaData: { - sisyfosPersistLevel: true - } - }) - }), GetSisyfosTimelineObjForCamera(context, config, 'evs', SisyfosLLAyer.SisyfosGroupStudioMics) ]) } From 90d40f6d3abe82ad1e244cd42b4577ef42308bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Thu, 27 Jan 2022 13:39:19 +0100 Subject: [PATCH 028/184] Automerge master to staging --- .github/workflows/automerge.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/automerge.yml diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml new file mode 100644 index 000000000..36882f2c3 --- /dev/null +++ b/.github/workflows/automerge.yml @@ -0,0 +1,20 @@ +name: Merge master to staging + +on: + schedule: + - cron: '23 45 * * *' # every night + workflow_dispatch: # on button click + +jobs: + sync: + + runs-on: ubuntu-latest + + steps: + - uses: tgymnich/fork-sync@v1.6 + with: + owner: tv2 + head: master + base: staging + pr_title: Automerge master + auto_merge: false \ No newline at end of file From 6add3fec6ae67a6f83ffb4a4922d5be5ce59dfd3 Mon Sep 17 00:00:00 2001 From: skon-tv2 <91883429+skon-tv2@users.noreply.github.com> Date: Fri, 28 Jan 2022 11:21:17 +0100 Subject: [PATCH 029/184] Update automerge.yml fix: invalid cron params --- .github/workflows/automerge.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 36882f2c3..51c1a33d8 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -2,7 +2,7 @@ name: Merge master to staging on: schedule: - - cron: '23 45 * * *' # every night + - cron: '45 23 * * *' # every night workflow_dispatch: # on button click jobs: @@ -17,4 +17,4 @@ jobs: head: master base: staging pr_title: Automerge master - auto_merge: false \ No newline at end of file + auto_merge: false From 3a29b4e2160f489b703b4748d319a586f4519aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Fri, 28 Jan 2022 11:23:17 +0100 Subject: [PATCH 030/184] chore: automerge staging to develop --- .github/workflows/automerge.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/automerge.yml diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml new file mode 100644 index 000000000..3b3b2da78 --- /dev/null +++ b/.github/workflows/automerge.yml @@ -0,0 +1,19 @@ +name: Merge staging to develop + +on: + schedule: + - cron: '15 0 * * *' # every night + workflow_dispatch: # on button click + +jobs: + sync: + + runs-on: ubuntu-latest + + steps: + - uses: tgymnich/fork-sync@v1.6 + with: + owner: tv2 + head: staging + base: develop + pr_title: Automerge staging From f4d2ecf0ed229071626644e77cc97860b0ce3b20 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Mon, 31 Jan 2022 12:23:34 +0100 Subject: [PATCH 031/184] SOF-742 EVS now behaves in accordance with JACH --- src/tv2_afvd_showstyle/getRundown.ts | 29 +++++++++++++++++++++++++++- src/tv2_afvd_showstyle/parts/evs.ts | 26 +------------------------ 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 8b3b86fea..f6c33ccba 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -131,7 +131,34 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint } }) }), - GetSisyfosTimelineObjForCamera(context, config, 'evs', SisyfosLLAyer.SisyfosGroupStudioMics) + ...(vo + ? [ + literal({ + id: '', + enable: { + start: 1 + }, + priority: 1, + layer: SisyfosLLAyer.SisyfosPersistedLevels, + content: { + deviceType: TSR.DeviceType.SISYFOS, + type: TSR.TimelineContentTypeSisyfos.CHANNELS, + overridePriority: 1, + channels: config.stickyLayers + .map(layer => { + return { + mappedLayer: layer, + isPgm: 0 + } + }) + }, + metaData: { + sisyfosPersistLevel: true + } + }), + GetSisyfosTimelineObjForCamera(context, config, 'evs', SisyfosLLAyer.SisyfosGroupStudioMics) + ] + : []) ]) } }) diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index 209a7c24e..51b5f9054 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -22,7 +22,6 @@ import { PartDefinitionEVS, PartTime, SourceInfo, - TimelineBlueprintExt, TransitionFromString, TransitionSettings } from 'tv2-common' @@ -141,30 +140,7 @@ function makeContentEVS( GetSisyfosTimelineObjForEVS(sourceInfoDelayedPlayback, partDefinition.variant.isVO), ...(partDefinition.variant.isVO ? [GetSisyfosTimelineObjForCamera(context, config, 'evs', SisyfosLLAyer.SisyfosGroupStudioMics)] - : [ - literal({ - id: '', - enable: { - start: 0 - }, - priority: 1, - layer: SisyfosLLAyer.SisyfosPersistedLevels, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNELS, - overridePriority: 1, - channels: config.liveAudio.map(layer => { - return literal({ - mappedLayer: layer, - isPgm: 0 - }) - }) - }, - metaData: { - sisyfosPersistLevel: true - } - }) - ]) + : []) ]) } } From f0962fb227ea30b3b3312e0d23c5d7ced95a768d Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Mon, 31 Jan 2022 12:41:34 +0100 Subject: [PATCH 032/184] Simplify commands for convert.js - Possible to specify another studioId for upload script --- .gitignore | 3 +++ rundowns/convert.js | 8 ++++---- rundowns/upload.sh | 8 +++++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 7d5c53328..31adfb104 100755 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ src/**.js wallaby.conf.js .DS_Store + +# Exclude JetBrains specific files +.idea \ No newline at end of file diff --git a/rundowns/convert.js b/rundowns/convert.js index 7a5fc161b..13624ff57 100644 --- a/rundowns/convert.js +++ b/rundowns/convert.js @@ -1,8 +1,8 @@ // this converts a snapshot into importable rundown data -// use with `node convert.js snapshot.json mock-rundown.json` -if (process.argv.length < 4) { +// use with `node convert.js snapshot.json` +if (process.argv.length < 3) { console.log(process.argv) - console.log(`Usage: node convert.js snapshot.json mock-rundown.json`) + console.log(`Usage: node convert.js snapshot.json`) process.exit(0) } const fs = require('fs') @@ -26,5 +26,5 @@ segments = segments.sort((a, b) => b.rank - a.rank) const rundown = rundownData[0].data rundown.segments = segments // console.log(JSON.stringify(rundown, undefined, 4)) -fs.writeFileSync(process.argv[3], JSON.stringify(rundown, undefined, 4)) +fs.writeFileSync('output.json', JSON.stringify(rundown, undefined, 4)) console.log('done') \ No newline at end of file diff --git a/rundowns/upload.sh b/rundowns/upload.sh index bbd612e60..4f44c3719 100755 --- a/rundowns/upload.sh +++ b/rundowns/upload.sh @@ -1,5 +1,11 @@ #!/bin/bash -curl -ks --data-binary @$1 --header 'Content-Type:application/json' http://localhost:3000/ingest/studio0 +STUDIO_ID=studio0 +if [[ $1 != "" ]] +then + STUDIO_ID=$1 +fi + +curl -ks --data-binary @output.json --header 'Content-Type:application/json' http://localhost:3000/ingest/${STUDIO_ID} echo "\n" From 5931904a76642051a6f3e07d7790bfd34cd82062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Mon, 31 Jan 2022 13:02:35 +0100 Subject: [PATCH 033/184] chore: changed automerge workflow --- .github/workflows/automerge.yml | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 51c1a33d8..e94e31c41 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -6,15 +6,18 @@ on: workflow_dispatch: # on button click jobs: - sync: - + merge-staging-to-dev: runs-on: ubuntu-latest - steps: - - uses: tgymnich/fork-sync@v1.6 - with: - owner: tv2 - head: master - base: staging - pr_title: Automerge master - auto_merge: false + - uses: actions/checkout@v2 + - name: Set Git config + run: | + git config --local user.email "actions@github.com" + git config --local user.name "Github Actions" + - name: Merge master to staging + run: | + git fetch --unshallow + git checkout staging + git pull + git merge --no-ff master -m "Auto-merge master to staging" + git push From 81b6d479b9b333ee3f83185ed139511f82db8230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Mon, 31 Jan 2022 13:28:43 +0100 Subject: [PATCH 034/184] chore: changed automerge workflow --- .github/workflows/automerge.yml | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 3b3b2da78..92688e9a0 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -6,14 +6,18 @@ on: workflow_dispatch: # on button click jobs: - sync: - + merge-staging-to-dev: runs-on: ubuntu-latest - steps: - - uses: tgymnich/fork-sync@v1.6 - with: - owner: tv2 - head: staging - base: develop - pr_title: Automerge staging + - uses: actions/checkout@v2 + - name: Set Git config + run: | + git config --local user.email "${GITHUB_ACTOR}" + git config --local user.name "${GITHUB_ACTOR}@users.noreply.github.com" + - name: Merge staging to develop + run: | + git fetch --unshallow + git checkout develop + git pull + git merge --no-ff staging -m "Auto-merge staging to develop" + git push From 779334e9b422c530698f6ce63e0b328a103a536a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Mon, 31 Jan 2022 13:31:21 +0100 Subject: [PATCH 035/184] chore: updated git config settings for automerge --- .github/workflows/automerge.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index e94e31c41..eec20bf4d 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -12,8 +12,8 @@ jobs: - uses: actions/checkout@v2 - name: Set Git config run: | - git config --local user.email "actions@github.com" - git config --local user.name "Github Actions" + git config --local user.email "${GITHUB_ACTOR}" + git config --local user.name "${GITHUB_ACTOR}@users.noreply.github.com" - name: Merge master to staging run: | git fetch --unshallow From aefa41d0c17feec93dafcb27d902d1d7eed76bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Mon, 31 Jan 2022 13:36:47 +0100 Subject: [PATCH 036/184] chore: changed name of automerge action --- .github/workflows/automerge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index eec20bf4d..dfa84fc22 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -1,4 +1,4 @@ -name: Merge master to staging +name: automerge on: schedule: From 39e8b99661567a8f6b0df97e0c31b0d052270f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Mon, 31 Jan 2022 13:37:13 +0100 Subject: [PATCH 037/184] chore: changed name of automerge action --- .github/workflows/automerge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 92688e9a0..9024df402 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -1,4 +1,4 @@ -name: Merge staging to develop +name: automerge on: schedule: From da8265d4080e4a38225ab98eff01865293d547ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Mon, 31 Jan 2022 13:42:53 +0100 Subject: [PATCH 038/184] chore: added origin to branch --- .github/workflows/automerge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 9024df402..c7d71434b 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -19,5 +19,5 @@ jobs: git fetch --unshallow git checkout develop git pull - git merge --no-ff staging -m "Auto-merge staging to develop" + git merge --no-ff origin/staging -m "Auto-merge staging to develop" git push From b995766aad59e6723f7c237d6fc3416e98877ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Mon, 31 Jan 2022 15:11:01 +0100 Subject: [PATCH 039/184] chore: merge from origin --- .github/workflows/automerge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index dfa84fc22..f868caf48 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -19,5 +19,5 @@ jobs: git fetch --unshallow git checkout staging git pull - git merge --no-ff master -m "Auto-merge master to staging" + git merge --no-ff origin/master -m "Auto-merge master to staging" git push From 97b73145af23335041d45edbb478cf42d2342b21 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Tue, 8 Feb 2022 15:12:01 +0100 Subject: [PATCH 040/184] SOF-699 afvd studio now includes a SetConcept TimelineObject in its baseline rundown --- src/tv2-common/blueprintConfig.ts | 7 ++ src/tv2-constants/enums.ts | 3 +- .../__tests__/baseline.spec.ts | 104 +++++++++++------- .../__tests__/config-manifest.spec.ts | 4 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 2 + src/tv2_afvd_showstyle/config-manifests.ts | 42 +++++++ src/tv2_afvd_showstyle/getRundown.ts | 29 ++++- .../migrations/mappings-defaults.ts | 8 +- .../migrations/mappings-defaults.ts | 7 +- 9 files changed, 158 insertions(+), 48 deletions(-) diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index b3ccb9e5c..cd4199faf 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -34,6 +34,11 @@ export interface TableConfigItemAdLibTransitions { Transition: string } +export interface TableConfigGraphicSetup { + INewsCode: string + Concept: string +} + export interface TV2StudioConfigBase { MaximumPartDuration: number DefaultPartDuration: number @@ -130,6 +135,8 @@ export interface TV2ShowstyleBlueprintConfigBase { ShowstyleTransition: string MakeAdlibsForFulls: boolean LYDConfig: TableConfigItemValue + GraphicINewsCode: string + GraphicSetups: TableConfigGraphicSetup[] } export interface TV2BlueprintConfigBase diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index e50850fc8..ea46f41d7 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -170,7 +170,8 @@ export enum GraphicLLayer { GraphicLLayerFullLoop = 'graphic_full_loop', GraphicLLayerAdLibs = 'graphic_adlibs', // <= viz_layer_adlibs GraphicLLayerWall = 'graphic_wall', // <= viz_layer_wall - GraphicLLayerLocators = 'graphic_locators' + GraphicLLayerLocators = 'graphic_locators', + GraphicLLayerConcept = 'graphic_concept' } export enum AbstractLLayer { diff --git a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts index 3e6f09519..cecc3ae5f 100644 --- a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts @@ -1,4 +1,4 @@ -import { ExtendedIngestRundown } from '@tv2media/blueprints-integration' +import { ExtendedIngestRundown, TSR } from '@tv2media/blueprints-integration' import { ShowStyleUserContext } from '../../__mocks__/context' import { checkAllLayers } from './layers-check' @@ -8,55 +8,79 @@ global.VERSION = 'test' global.VERSION_TSR = 'test' // @ts-ignore global.VERSION_INTEGRATION = 'test' + +import { GraphicLLayer } from '../../tv2-constants' import { parseConfig 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 Blueprints from '../index' import { defaultShowStyleConfig, defaultStudioConfig } from './configs' -const configs = [{ id: 'default', studioConfig: defaultStudioConfig, showStyleConfig: defaultShowStyleConfig }] +const configSpec = { id: 'default', studioConfig: defaultStudioConfig, showStyleConfig: defaultShowStyleConfig } const RUNDOWN_ID = 'test_rundown' const SEGMENT_ID = 'test_segment' const PART_ID = 'test_part' describe('Baseline', () => { - for (const configSpec of configs) { - test('Config: ' + configSpec.id, () => { - expect(configSpec.studioConfig).toBeTruthy() - expect(configSpec.showStyleConfig).toBeTruthy() - - const rundown: ExtendedIngestRundown = { - externalId: 'abc', - name: 'Mock RO', - type: 'mock', - payload: {}, - segments: [], - coreData: undefined - } - - const mockContext = new ShowStyleUserContext( - rundown.name, - mappingsDefaults, - parseStudioConfig, - parseShowStyleConfig, - RUNDOWN_ID, - SEGMENT_ID, - PART_ID - ) - mockContext.studioConfig = configSpec.studioConfig as any - mockContext.showStyleConfig = configSpec.showStyleConfig as any - - const res = Blueprints.getRundown(mockContext, rundown) - - expect(res).not.toBeNull() - expect(res.baseline.timelineObjects).not.toHaveLength(0) - expect(res.globalAdLibPieces).not.toHaveLength(0) - - checkAllLayers(mockContext, res.globalAdLibPieces, res.baseline.timelineObjects) - - // ensure there were no warnings - expect(mockContext.getNotes()).toEqual([]) - }) - } + test('Config: ' + configSpec.id, () => { + expect(configSpec.studioConfig).toBeTruthy() + expect(configSpec.showStyleConfig).toBeTruthy() + + const mockRundown: ExtendedIngestRundown = createMockRundown() + const mockContext: ShowStyleUserContext = createMockContext(mockRundown.name) + + const result = Blueprints.getRundown(mockContext, mockRundown) + + expect(result).not.toBeNull() + expect(result.baseline.timelineObjects).not.toHaveLength(0) + expect(result.globalAdLibPieces).not.toHaveLength(0) + + checkAllLayers(mockContext, result.globalAdLibPieces, result.baseline.timelineObjects) + + // ensure there were no warnings + expect(mockContext.getNotes()).toEqual([]) + }) + + test('SetConcept timeline object is created in base rundown', () => { + const mockRundown: ExtendedIngestRundown = createMockRundown() + const mockContext: ShowStyleUserContext = createMockContext(mockRundown.name) + + const rundown = Blueprints.getRundown(mockContext, mockRundown) + + const result = rundown.baseline.timelineObjects.filter( + timelineObject => + timelineObject.layer === GraphicLLayer.GraphicLLayerConcept && + timelineObject.content.deviceType === TSR.DeviceType.VIZMSE + ) + + expect(result).toHaveLength(1) + }) }) + +function createMockRundown(): ExtendedIngestRundown { + return { + externalId: 'abc', + name: 'Mock RO', + type: 'mock', + payload: {}, + segments: [], + coreData: undefined + } +} + +function createMockContext(rundownName: string): ShowStyleUserContext { + const mockContext = new ShowStyleUserContext( + rundownName, + mappingsDefaults, + parseStudioConfig, + parseShowStyleConfig, + RUNDOWN_ID, + SEGMENT_ID, + PART_ID + ) + mockContext.studioConfig = configSpec.studioConfig as any + mockContext.showStyleConfig = configSpec.showStyleConfig as any + + return mockContext +} diff --git a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts index e512fac98..fdc109790 100644 --- a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts @@ -12,7 +12,9 @@ const blankShowStyleConfig: ShowStyleConfig = { LYDConfig: [], CasparCGLoadingClip: '', Transitions: [{ Transition: '1' }, { Transition: '2' }], - ShowstyleTransition: 'CUT' + ShowstyleTransition: 'CUT', + GraphicINewsCode: '', + GraphicSetups: [] } describe('Config Manifest', () => { diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index 345df7b0d..c9f2f775a 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -255,6 +255,8 @@ export const defaultShowStyleConfig: ShowStyleConfig = { FadeOut: 0 } ], + GraphicINewsCode: '', + GraphicSetups: [], Transitions: [{ Transition: '1' }, { Transition: '2' }], ShowstyleTransition: 'CUT' } diff --git a/src/tv2_afvd_showstyle/config-manifests.ts b/src/tv2_afvd_showstyle/config-manifests.ts index af2c6c582..2d4c921d6 100644 --- a/src/tv2_afvd_showstyle/config-manifests.ts +++ b/src/tv2_afvd_showstyle/config-manifests.ts @@ -142,6 +142,47 @@ export const dveStylesManifest: ConfigManifestEntry = { ] } +const graphicProfileSetup: ConfigManifestEntry[] = [ + { + id: 'GraphicSetups', + name: 'Graphic Setups', + description: 'Possible graphic profile setup', + type: ConfigManifestEntryType.TABLE, + required: false, + defaultVal: [], + columns: [ + { + id: 'INewsCode', + name: 'iNews Command (*)', + description: 'The code as it will appear in iNews', + type: ConfigManifestEntryType.STRING, + required: true, + defaultVal: '', + rank: 0 + }, + { + id: 'Concept', + name: 'Concept', + rank: 1, + required: true, + defaultVal: '', + hint: '', + description: '', + type: ConfigManifestEntryType.STRING + } + ], + hint: '' + }, + { + id: 'GraphicINewsCode', + name: 'Graphic Profile cue', + description: 'GRAPHIC_PROFILE cue from iNews', + type: ConfigManifestEntryType.STRING, + required: false, + defaultVal: '' + } +] + export const showStyleConfigManifest: ConfigManifestEntry[] = [ { id: 'MakeAdlibsForFulls', @@ -263,6 +304,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ } ] }, + ...graphicProfileSetup, { /* Wipes Config diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index f6c33ccba..dbfce39dd 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -36,6 +36,7 @@ import { literal, SourceInfo, t, + TableConfigGraphicSetup, TimelineBlueprintExt } from 'tv2-common' import { @@ -48,6 +49,7 @@ import { TallyTags } from 'tv2-constants' import * as _ from 'underscore' +import { TimelineContentTypeVizMSE } from '../../../tv-automation-state-timeline-resolver/packages/timeline-state-resolver-types' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' import { SisyfosChannel, sisyfosChannels } from '../tv2_afvd_studio/sisyfosChannels' import { AtemSourceIndex } from '../types/atem' @@ -144,13 +146,14 @@ function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: Blueprint deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, overridePriority: 1, - channels: config.stickyLayers - .map(layer => { + channels: config.stickyLayers.map( + layer => { return { mappedLayer: layer, isPgm: 0 } - }) + } + ) }, metaData: { sisyfosPersistLevel: true @@ -1188,7 +1191,25 @@ function getBaseline(config: BlueprintConfig): BlueprintResultBaseline { } }) }) - : []) + : []), + + literal({ + id: '', + enable: { while: '1' }, + layer: GraphicLLayer.GraphicLLayerConcept, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TimelineContentTypeVizMSE.SET_CONCEPT, + concept: findGraphicConcept(config) + } + }) ] } } + +function findGraphicConcept(config: BlueprintConfig): string { + const foundTableConfigGraphicSetup: TableConfigGraphicSetup | undefined = config.showStyle.GraphicSetups.find( + tableConfigGraphicSetup => tableConfigGraphicSetup.INewsCode === config.showStyle.GraphicINewsCode + ) + return !!foundTableConfigGraphicSetup ? foundTableConfigGraphicSetup.Concept : '' +} diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index 7708c933a..779e3bd8c 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -8,7 +8,7 @@ import { SisyfosPlayerClip } from 'tv2-common' import { AbstractLLayer, GraphicLLayer } from 'tv2-constants' -import * as _ from 'underscore' +import { DeviceType } from '../../../../tv-automation-state-timeline-resolver/packages/timeline-state-resolver-types' import { ATEMModel } from '../../types/atem' import { BlueprintConfig } from '../helpers/config' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../layers' @@ -536,6 +536,12 @@ export const MAPPINGS_GRAPHICS: BlueprintMappings = { deviceId: 'viz0', layerName: 'GFX Full Loop', lookahead: LookaheadMode.NONE + }), + [GraphicLLayer.GraphicLLayerConcept]: literal({ + device: DeviceType.VIZMSE, + deviceId: 'viz0', + layerName: 'Override Concept', + lookahead: LookaheadMode.NONE }) } diff --git a/src/tv2_offtube_studio/migrations/mappings-defaults.ts b/src/tv2_offtube_studio/migrations/mappings-defaults.ts index 26c2dd950..1350c8835 100644 --- a/src/tv2_offtube_studio/migrations/mappings-defaults.ts +++ b/src/tv2_offtube_studio/migrations/mappings-defaults.ts @@ -7,7 +7,6 @@ import { literal } from 'tv2-common' import { AbstractLLayer, GraphicLLayer } from 'tv2-constants' -import * as _ from 'underscore' import { ATEMModel } from '../../types/atem' import { OfftubeAbstractLLayer, OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../layers' @@ -442,6 +441,12 @@ const MAPPINGS_GRAPHICS: BlueprintMappings = { deviceId: 'abstract0', layerName: 'GFX Wall', lookahead: LookaheadMode.NONE + }), + [GraphicLLayer.GraphicLLayerConcept]: literal({ + device: TSR.DeviceType.ABSTRACT, + deviceId: 'abstract0', + layerName: 'Override Concept', + lookahead: LookaheadMode.NONE }) } From 4a99509a8791eec33118ba09baea0d804d7194b1 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 9 Feb 2022 08:45:00 +0100 Subject: [PATCH 041/184] Now allows to specify file to convert to and file to upload from --- rundowns/.gitignore | 2 ++ rundowns/convert.js | 11 ++++++++--- rundowns/upload.sh | 14 +++++++++++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/rundowns/.gitignore b/rundowns/.gitignore index 7ceb50f3e..ed69df547 100644 --- a/rundowns/.gitignore +++ b/rundowns/.gitignore @@ -1 +1,3 @@ dump.json + +converted-rundown.json diff --git a/rundowns/convert.js b/rundowns/convert.js index 13624ff57..e274f9ff5 100644 --- a/rundowns/convert.js +++ b/rundowns/convert.js @@ -1,8 +1,8 @@ // this converts a snapshot into importable rundown data -// use with `node convert.js snapshot.json` +// use with `node convert.js snapshot.json [output-rundown.json]` if (process.argv.length < 3) { console.log(process.argv) - console.log(`Usage: node convert.js snapshot.json`) + console.log(`Usage: node convert.js snapshot.json [output-rundown.json]`) process.exit(0) } const fs = require('fs') @@ -26,5 +26,10 @@ segments = segments.sort((a, b) => b.rank - a.rank) const rundown = rundownData[0].data rundown.segments = segments // console.log(JSON.stringify(rundown, undefined, 4)) -fs.writeFileSync('output.json', JSON.stringify(rundown, undefined, 4)) +let outputString = 'converted-rundown.json'; +const outputArgument = process.argv[3]; +if (outputArgument !== undefined && outputArgument !== '') { + outputString = outputArgument; +} +fs.writeFileSync(outputString, JSON.stringify(rundown, undefined, 4)) console.log('done') \ No newline at end of file diff --git a/rundowns/upload.sh b/rundowns/upload.sh index 4f44c3719..f6f394e5e 100755 --- a/rundowns/upload.sh +++ b/rundowns/upload.sh @@ -1,11 +1,19 @@ #!/bin/bash -STUDIO_ID=studio0 +RUNDOWN_FILE=converted-rundown.json if [[ $1 != "" ]] then - STUDIO_ID=$1 + RUNDOWN_FILE=$1 +fi + +STUDIO_ID=studio0 +if [[ $2 != "" ]] +then + STUDIO_ID=$2 fi -curl -ks --data-binary @output.json --header 'Content-Type:application/json' http://localhost:3000/ingest/${STUDIO_ID} +echo $STUDIO_ID + +curl -ks --data-binary @$RUNDOWN_FILE --header 'Content-Type:application/json' http://localhost:3000/ingest/${STUDIO_ID} echo "\n" From 0cf9e3c573d54ccbf9f1a6aefea2adcf825fa91e Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Fri, 11 Feb 2022 14:54:34 +0100 Subject: [PATCH 042/184] SOF-699 Studio baseline now creates a timelineObject with an empty concept --- src/tv2_afvd_showstyle/getRundown.ts | 2 +- src/tv2_afvd_studio/getBaseline.ts | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index dbfce39dd..cd9b7a030 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -49,7 +49,7 @@ import { TallyTags } from 'tv2-constants' import * as _ from 'underscore' -import { TimelineContentTypeVizMSE } from '../../../tv-automation-state-timeline-resolver/packages/timeline-state-resolver-types' +import { TimelineContentTypeVizMSE } from '../../node_modules/timeline-state-resolver-types' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../tv2_afvd_studio/layers' import { SisyfosChannel, sisyfosChannels } from '../tv2_afvd_studio/sisyfosChannels' import { AtemSourceIndex } from '../types/atem' diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index 0d726e279..f8e3e36b0 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -7,6 +7,8 @@ import { } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import * as _ from 'underscore' +import { TimelineContentTypeVizMSE } from '../../node_modules/timeline-state-resolver-types' +import { GraphicLLayer } from '../tv2-constants' import { AtemSourceIndex } from '../types/atem' import { getStudioConfig } from './helpers/config' import { AtemLLayer, SisyfosLLAyer } from './layers' @@ -157,6 +159,16 @@ export function getBaseline(context: IStudioContext): BlueprintResultBaseline { clipFrame: 0 } } + }), + literal({ + id: '', + enable: { while: '1' }, + layer: GraphicLLayer.GraphicLLayerConcept, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TimelineContentTypeVizMSE.SET_CONCEPT, + concept: '' + } }) ] } From 13a942430fa87138b8ce9e41a034c072f738cc30 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Tue, 15 Feb 2022 09:10:43 +0100 Subject: [PATCH 043/184] SOF-699 Now uses correct version of timeline-state-resolver-types library --- package.json | 1 + src/tv2-common/blueprintConfig.ts | 7 ------- src/tv2_afvd_showstyle/getRundown.ts | 7 +++---- src/tv2_afvd_showstyle/helpers/config.ts | 8 +++++++- src/tv2_afvd_studio/getBaseline.ts | 4 ++-- yarn.lock | 7 +++++++ 6 files changed, 20 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 426d5afc5..dca8056c6 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ }, "dependencies": { "@tv2media/blueprints-integration": "v1.37.1-in-testing.1", + "@tv2media/timeline-state-resolver-types": "^1.0.0-release37.5", "underscore": "^1.12.1" } } \ No newline at end of file diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index cd4199faf..b3ccb9e5c 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -34,11 +34,6 @@ export interface TableConfigItemAdLibTransitions { Transition: string } -export interface TableConfigGraphicSetup { - INewsCode: string - Concept: string -} - export interface TV2StudioConfigBase { MaximumPartDuration: number DefaultPartDuration: number @@ -135,8 +130,6 @@ export interface TV2ShowstyleBlueprintConfigBase { ShowstyleTransition: string MakeAdlibsForFulls: boolean LYDConfig: TableConfigItemValue - GraphicINewsCode: string - GraphicSetups: TableConfigGraphicSetup[] } export interface TV2BlueprintConfigBase diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index cd9b7a030..cdcb555bd 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -15,6 +15,7 @@ import { TSR, WithTimeline } from '@tv2media/blueprints-integration' +import { TimelineContentTypeVizMSE, TimelineObjVIZMSESetConcept } from '@tv2media/timeline-state-resolver-types' import { ActionClearGraphics, ActionCutSourceToBox, @@ -36,7 +37,6 @@ import { literal, SourceInfo, t, - TableConfigGraphicSetup, TimelineBlueprintExt } from 'tv2-common' import { @@ -49,11 +49,10 @@ import { TallyTags } from 'tv2-constants' import * as _ from 'underscore' -import { TimelineContentTypeVizMSE } from '../../node_modules/timeline-state-resolver-types' 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 { BlueprintConfig, getConfig as getShowStyleConfig, TableConfigGraphicSetup } from './helpers/config' import { NUMBER_OF_DVE_BOXES } from './helpers/content/dve' import { SourceLayer } from './layers' import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' @@ -1193,7 +1192,7 @@ function getBaseline(config: BlueprintConfig): BlueprintResultBaseline { }) : []), - literal({ + literal({ id: '', enable: { while: '1' }, layer: GraphicLLayer.GraphicLLayerConcept, diff --git a/src/tv2_afvd_showstyle/helpers/config.ts b/src/tv2_afvd_showstyle/helpers/config.ts index 1b26d37bf..f084e990b 100644 --- a/src/tv2_afvd_showstyle/helpers/config.ts +++ b/src/tv2_afvd_showstyle/helpers/config.ts @@ -5,7 +5,6 @@ import { TableConfigItemValue } from '@tv2media/blueprints-integration' import { TV2ShowstyleBlueprintConfigBase } from 'tv2-common' -import * as _ from 'underscore' import { BlueprintConfig as BlueprintConfigBase } from '../../tv2_afvd_studio/helpers/config' export interface BlueprintConfig extends BlueprintConfigBase { @@ -14,6 +13,8 @@ export interface BlueprintConfig extends BlueprintConfigBase { export interface ShowStyleConfig extends TV2ShowstyleBlueprintConfigBase { WipesConfig: TableConfigItemValue + GraphicINewsCode: string + GraphicSetups: TableConfigGraphicSetup[] } export function parseConfig(_context: ICommonContext, config: IBlueprintConfig): any { @@ -23,3 +24,8 @@ export function parseConfig(_context: ICommonContext, config: IBlueprintConfig): export function getConfig(context: IShowStyleContext): BlueprintConfig { return ({ ...(context.getStudioConfig() as any), ...(context.getShowStyleConfig() as any) } as any) as BlueprintConfig } + +export interface TableConfigGraphicSetup { + INewsCode: string + Concept: string +} diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index f8e3e36b0..3177f8ac9 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -5,9 +5,9 @@ import { IStudioContext, TSR } from '@tv2media/blueprints-integration' +import { TimelineContentTypeVizMSE, TimelineObjVIZMSESetConcept } from '@tv2media/timeline-state-resolver-types' import { literal } from 'tv2-common' import * as _ from 'underscore' -import { TimelineContentTypeVizMSE } from '../../node_modules/timeline-state-resolver-types' import { GraphicLLayer } from '../tv2-constants' import { AtemSourceIndex } from '../types/atem' import { getStudioConfig } from './helpers/config' @@ -160,7 +160,7 @@ export function getBaseline(context: IStudioContext): BlueprintResultBaseline { } } }), - literal({ + literal({ id: '', enable: { while: '1' }, layer: GraphicLLayer.GraphicLLayerConcept, diff --git a/yarn.lock b/yarn.lock index c66e62d4d..3b61585e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -297,6 +297,13 @@ tslib "^2.3.1" underscore "1.13.1" +"@tv2media/timeline-state-resolver-types@^1.0.0-release37.5": + version "1.0.0-release37.5" + resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-1.0.0-release37.5.tgz#6d8c9d2b9fc5f48bce88fd8a2da3dec49b29fca6" + integrity sha512-LZHzJm/Ss6Xd/H1xvsPRvZ98ou33szscyD0hzs8gtFcU7B15nzyD5ImgMRrgJl6+tlcIIhfHq6oc83/HqHBLZw== + dependencies: + tslib "^2.3.1" + "@types/babel__core@^7.1.0": version "7.1.6" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.6.tgz#16ff42a5ae203c9af1c6e190ed1f30f83207b610" From d4b22f815b79fea472b812feb2fd1a01a2b49a81 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Tue, 15 Feb 2022 09:15:02 +0100 Subject: [PATCH 044/184] SOF-699 Fix imports --- src/tv2_afvd_studio/migrations/mappings-defaults.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index 779e3bd8c..8478e3fb1 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -1,4 +1,5 @@ import { BlueprintMapping, BlueprintMappings, LookaheadMode, TSR } from '@tv2media/blueprints-integration' +import { DeviceType } from '@tv2media/timeline-state-resolver-types' import { AbstractLLayerServerEnable, CasparPlayerClip, @@ -8,7 +9,6 @@ import { SisyfosPlayerClip } from 'tv2-common' import { AbstractLLayer, GraphicLLayer } from 'tv2-constants' -import { DeviceType } from '../../../../tv-automation-state-timeline-resolver/packages/timeline-state-resolver-types' import { ATEMModel } from '../../types/atem' import { BlueprintConfig } from '../helpers/config' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../layers' From d16597beed31b4b161475b2613cfff5421c2d0c3 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Tue, 15 Feb 2022 10:23:23 +0100 Subject: [PATCH 045/184] Update README --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b52a2b75f..3e28b4d7d 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,10 @@ yarn test # watch for changes ``` ## Ingest mockdata: -Ingest mock data into Sofie: -In ./rundowns/upload.sh rename "studio0" to _id of studio (look in mongoDb under collection studios) +To ingest mock data into Sofie use the 'upload.sh' script found in ./rundowns. + +The script takes two optional parameters: name of the rundown file and id of the studio. The default values are: 'converted-rundown.json' and 'studio0'. + Run: ``` ./upload.sh on-air.json From 8e25e6f8a2b21ab22b357000e133c5e74d5b5433 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Thu, 17 Feb 2022 09:36:10 +0100 Subject: [PATCH 046/184] Update timeline-state-resolver-types version and fix conflicts --- package.json | 2 +- src/tv2_afvd_showstyle/getRundown.ts | 6 +++--- src/tv2_afvd_studio/getBaseline.ts | 6 +++--- yarn.lock | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index dca8056c6..3e4292064 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ }, "dependencies": { "@tv2media/blueprints-integration": "v1.37.1-in-testing.1", - "@tv2media/timeline-state-resolver-types": "^1.0.0-release37.5", + "@tv2media/timeline-state-resolver-types": "^1.0.0-release37.6", "underscore": "^1.12.1" } } \ No newline at end of file diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index cdcb555bd..69424ce99 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -15,7 +15,7 @@ import { TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { TimelineContentTypeVizMSE, TimelineObjVIZMSESetConcept } from '@tv2media/timeline-state-resolver-types' +import { TimelineContentTypeVizMSE, TimelineObjVIZMSEConcept } from '@tv2media/timeline-state-resolver-types' import { ActionClearGraphics, ActionCutSourceToBox, @@ -1192,13 +1192,13 @@ function getBaseline(config: BlueprintConfig): BlueprintResultBaseline { }) : []), - literal({ + literal({ id: '', enable: { while: '1' }, layer: GraphicLLayer.GraphicLLayerConcept, content: { deviceType: TSR.DeviceType.VIZMSE, - type: TimelineContentTypeVizMSE.SET_CONCEPT, + type: TimelineContentTypeVizMSE.CONCEPT, concept: findGraphicConcept(config) } }) diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index 3177f8ac9..867c56a48 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -5,7 +5,7 @@ import { IStudioContext, TSR } from '@tv2media/blueprints-integration' -import { TimelineContentTypeVizMSE, TimelineObjVIZMSESetConcept } from '@tv2media/timeline-state-resolver-types' +import { TimelineContentTypeVizMSE, TimelineObjVIZMSEConcept } from '@tv2media/timeline-state-resolver-types' import { literal } from 'tv2-common' import * as _ from 'underscore' import { GraphicLLayer } from '../tv2-constants' @@ -160,13 +160,13 @@ export function getBaseline(context: IStudioContext): BlueprintResultBaseline { } } }), - literal({ + literal({ id: '', enable: { while: '1' }, layer: GraphicLLayer.GraphicLLayerConcept, content: { deviceType: TSR.DeviceType.VIZMSE, - type: TimelineContentTypeVizMSE.SET_CONCEPT, + type: TimelineContentTypeVizMSE.CONCEPT, concept: '' } }) diff --git a/yarn.lock b/yarn.lock index 3b61585e9..34cc69944 100644 --- a/yarn.lock +++ b/yarn.lock @@ -297,10 +297,10 @@ tslib "^2.3.1" underscore "1.13.1" -"@tv2media/timeline-state-resolver-types@^1.0.0-release37.5": - version "1.0.0-release37.5" - resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-1.0.0-release37.5.tgz#6d8c9d2b9fc5f48bce88fd8a2da3dec49b29fca6" - integrity sha512-LZHzJm/Ss6Xd/H1xvsPRvZ98ou33szscyD0hzs8gtFcU7B15nzyD5ImgMRrgJl6+tlcIIhfHq6oc83/HqHBLZw== +"@tv2media/timeline-state-resolver-types@^1.0.0-release37.6": + version "1.0.0-release37.6" + resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-1.0.0-release37.6.tgz#48eca1760f254e38564b5901fead16ba02022e13" + integrity sha512-+Gd5fTSWyP4Z9l2CUC/gABJhCOKGD4gn5oR5VmnaL33U4KvGEgJE3X0SsW9Gn80O6y+2NBb/YcbDavRmlIG0TA== dependencies: tslib "^2.3.1" From 3ac0b365388d4f09c2fa27f44cf470bb362e79b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Fri, 18 Feb 2022 10:39:51 +0100 Subject: [PATCH 047/184] feat: config change to add mini rundown to the commentator dashboard --- shelf-layouts/Kommentator.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/shelf-layouts/Kommentator.json b/shelf-layouts/Kommentator.json index 3a4601482..7b2e41377 100644 --- a/shelf-layouts/Kommentator.json +++ b/shelf-layouts/Kommentator.json @@ -373,6 +373,25 @@ "showSegmentName": true, "showPartTitle": false, "hideForDynamicallyInsertedParts": true + }, + { + "_id" : "jLzHen2LoGEMxE68N", + "type" : "mini_rundown", + "name" : "Mini rundown", + "currentSegment" : false, + "displayStyle" : "buttons", + "rank" : 0, + "rundownBaseline" : false, + "showThumbnailsInList" : false, + "hideDuplicates" : false, + "default" : false, + "nextInCurrentPart" : false, + "oneNextPerSourceLayer" : false, + "x" : 7, + "y" : 0, + "width" : 14, + "height" : 7, + "scale" : 1 } ], "type": "dashboard_layout", From f0583f6ef6ff35c7e01b92eced502ab6c7dc3b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Tue, 22 Feb 2022 12:09:28 +0100 Subject: [PATCH 048/184] lint: Lint and renamed AFKD to AFVD. --- src/tv2_afvd_showstyle/getRundown.ts | 9 +++++---- src/tv2_offtube_showstyle/getRundown.ts | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 3dac690f9..efec04f82 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -62,8 +62,9 @@ export function getShowStyleVariantId( showStyleVariants: IBlueprintShowStyleVariant[], ingestRundown: IngestRundown ): string | null { - const graphicsprofile = ingestRundown.payload?.graphicProfile?.trim().toLowerCase(); - const variant = showStyleVariants.find(v => v.name.trim().toLowerCase() === graphicsprofile) ?? _.first(showStyleVariants) + const graphicsprofile = ingestRundown.payload?.graphicProfile?.trim().toLowerCase() + const variant = + showStyleVariants.find(v => v.name.trim().toLowerCase() === graphicsprofile) ?? _.first(showStyleVariants) if (variant) { return variant._id @@ -82,13 +83,13 @@ export function getRundown(context: IShowStyleUserContext, ingestRundown: Ingest type: PlaylistTimingType.None } }), - globalAdLibPieces: getGlobalAdLibPiecesAFKD(context, config), + globalAdLibPieces: getGlobalAdLibPiecesAFVD(context, config), globalActions: getGlobalAdlibActionsAFVD(context, config), baseline: getBaseline(config) } } -function getGlobalAdLibPiecesAFKD(context: IStudioUserContext, config: BlueprintConfig): IBlueprintAdLibPiece[] { +function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: BlueprintConfig): IBlueprintAdLibPiece[] { function makeEVSAdLibs(info: SourceInfo, rank: number, vo: boolean): IBlueprintAdLibPiece[] { const res: IBlueprintAdLibPiece[] = [] res.push({ diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index a39bdf2e3..1f164214d 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -66,8 +66,9 @@ export function getShowStyleVariantId( showStyleVariants: IBlueprintShowStyleVariant[], ingestRundown: IngestRundown ): string | null { - const graphicsprofile = ingestRundown.payload?.graphicProfile?.trim().toLowerCase(); - const variant = showStyleVariants.find(v => v.name.trim().toLowerCase() === graphicsprofile) ?? _.first(showStyleVariants) + const graphicsprofile = ingestRundown.payload?.graphicProfile?.trim().toLowerCase() + const variant = + showStyleVariants.find(v => v.name.trim().toLowerCase() === graphicsprofile) ?? _.first(showStyleVariants) if (variant) { return variant._id From 4c5e544b0e2ee08d6e5aa88944feeac9993efc79 Mon Sep 17 00:00:00 2001 From: ianshade Date: Fri, 25 Feb 2022 11:55:12 +0100 Subject: [PATCH 049/184] feat: SOF-752 support showId as a property of internal elements --- src/tv2-common/actions/executeAction.ts | 3 +- src/tv2-common/blueprintConfig.ts | 8 ++++ src/tv2-common/evaluateCues.ts | 20 +++++----- .../helpers/graphics/design/index.ts | 3 +- src/tv2-common/helpers/graphics/index.ts | 14 ++++++- src/tv2-common/helpers/graphics/viz/index.ts | 4 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 13 ++++++- src/tv2_afvd_showstyle/config-manifests.ts | 20 ++++++++++ src/tv2_afvd_showstyle/getRundown.ts | 38 ++++++++---------- src/tv2_afvd_showstyle/helpers/config.ts | 33 ++++++++++++---- .../pieces/__tests__/grafikViz.spec.ts | 39 ++++++++++++------- .../helpers/pieces/__tests__/telefon.spec.ts | 13 +++++-- .../helpers/pieces/clearGrafiks.ts | 5 ++- .../helpers/pieces/design.ts | 5 +-- .../helpers/pieces/ekstern.ts | 5 +-- .../helpers/pieces/graphicBackgroundLoop.ts | 12 +++--- .../helpers/pieces/graphicPilot.ts | 5 ++- .../helpers/pieces/routing.ts | 5 +-- .../postProcessTimelineObjects.ts | 2 +- .../cues/OfftubeGraphicBackgroundLoop.ts | 3 +- src/tv2_offtube_showstyle/helpers/config.ts | 25 ++++++++++-- 21 files changed, 189 insertions(+), 86 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 37fbd300f..24c4982e5 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -2026,7 +2026,8 @@ function executeActionClearGraphics< content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, - channelsToSendCommands: userData.sendCommands ? ['OVL1', 'FULL1', 'WALL1'] : undefined + channelsToSendCommands: userData.sendCommands ? ['OVL1', 'FULL1', 'WALL1'] : undefined, + showId: config.selectedGraphicsSetup.OvlShowId } }) ] diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index b3ccb9e5c..1477fc1bb 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -34,6 +34,13 @@ export interface TableConfigItemAdLibTransitions { Transition: string } +export interface TableConfigGraphicSetup { + INewsCode: string + Concept: string + OvlShowId: string + FullShowId: string +} + export interface TV2StudioConfigBase { MaximumPartDuration: number DefaultPartDuration: number @@ -135,6 +142,7 @@ export interface TV2ShowstyleBlueprintConfigBase { export interface TV2BlueprintConfigBase extends TV2StudioBlueprintConfigBase { showStyle: TV2ShowstyleBlueprintConfigBase + selectedGraphicsSetup: TableConfigGraphicSetup } export type TV2BlueprintConfig = TV2BlueprintConfigBase diff --git a/src/tv2-common/evaluateCues.ts b/src/tv2-common/evaluateCues.ts index 6136660c3..fcddb6b22 100644 --- a/src/tv2-common/evaluateCues.ts +++ b/src/tv2-common/evaluateCues.ts @@ -47,6 +47,7 @@ export interface EvaluateCuesShowstyleOptions { rank?: number ) => void EvaluateCueBackgroundLoop?: ( + config: TV2BlueprintConfig, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -373,6 +374,7 @@ export function EvaluateCuesBase( case CueType.BackgroundLoop: if (showStyleOptions.EvaluateCueBackgroundLoop) { showStyleOptions.EvaluateCueBackgroundLoop( + config, pieces, adLibPieces, actions, @@ -444,9 +446,8 @@ export function EvaluateCuesBase( content: { templateName: (obj as TSR.TimelineObjVIZMSEElementInternal).content.templateName, templateData: (obj as TSR.TimelineObjVIZMSEElementInternal).content.templateData, - channelName: o.content.channelName - // R35: rundownId: context.rundownId, - // R35: playlistId: '' + channel: o.content.channelName, + showId: o.content.showId } }) } @@ -456,10 +457,8 @@ export function EvaluateCuesBase( piece.expectedPlayoutItems.push({ deviceSubType: TSR.DeviceType.VIZMSE, content: { - templateName: (obj as TSR.TimelineObjVIZMSEElementPilot).content.templateVcpId, - channelName: (obj as TSR.TimelineObjVIZMSEElementPilot).content.channelName - // R35: rundownId: context.rundownId, - // R35: playlistId: '' + vcpid: (obj as TSR.TimelineObjVIZMSEElementPilot).content.templateVcpId, + channel: (obj as TSR.TimelineObjVIZMSEElementPilot).content.channelName } }) } @@ -468,10 +467,9 @@ export function EvaluateCuesBase( deviceSubType: TSR.DeviceType.VIZMSE, content: { templateName: 'altud', - channelName: 'OVL1', - templateData: [] - // R35: rundownId: context.rundownId, - // R35: playlistId: '' + channel: 'OVL1', + templateData: [], + showId: config.selectedGraphicsSetup.OvlShowId } }) } diff --git a/src/tv2-common/helpers/graphics/design/index.ts b/src/tv2-common/helpers/graphics/design/index.ts index 8ae3e7a31..59c4aeba2 100644 --- a/src/tv2-common/helpers/graphics/design/index.ts +++ b/src/tv2-common/helpers/graphics/design/index.ts @@ -103,7 +103,8 @@ function designTimeline(config: TV2BlueprintConfig, parsedCue: CueDefinitionGrap deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: parsedCue.design, - templateData: [] + templateData: [], + showId: config.selectedGraphicsSetup.OvlShowId } }) ] diff --git a/src/tv2-common/helpers/graphics/index.ts b/src/tv2-common/helpers/graphics/index.ts index e505d322f..a6410db46 100644 --- a/src/tv2-common/helpers/graphics/index.ts +++ b/src/tv2-common/helpers/graphics/index.ts @@ -1,6 +1,6 @@ import { IBlueprintPart, TSR } from '@tv2media/blueprints-integration' import { layerToHTMLGraphicSlot, literal, TV2BlueprintConfig } from 'tv2-common' -import { GraphicLLayer } from 'tv2-constants' +import { GraphicEngine, GraphicLLayer } from 'tv2-constants' export * from './name' export * from './timing' @@ -149,3 +149,15 @@ export function CreateGraphicBaseline(config: TV2BlueprintConfig): TSR.TSRTimeli ] } } + +export function findShowId(config: TV2BlueprintConfig, engine: GraphicEngine) { + const graphicSetup = config.selectedGraphicsSetup + switch (engine) { + case 'FULL': + case 'WALL': + return graphicSetup.FullShowId + case 'TLF': + case 'OVL': + return graphicSetup.OvlShowId + } +} diff --git a/src/tv2-common/helpers/graphics/viz/index.ts b/src/tv2-common/helpers/graphics/viz/index.ts index 2ff240b38..a73bb00da 100644 --- a/src/tv2-common/helpers/graphics/viz/index.ts +++ b/src/tv2-common/helpers/graphics/viz/index.ts @@ -8,6 +8,7 @@ import { } from '@tv2media/blueprints-integration' import { CueDefinitionGraphic, + findShowId, GetEnableForGraphic, GetFullGraphicTemplateNameFromCue, GetTimelineLayerForGraphic, @@ -56,7 +57,8 @@ export function GetInternalGraphicContentVIZ( type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: mappedTemplate, templateData: parsedCue.graphic.textFields, - channelName: engine === 'WALL' ? 'WALL1' : 'OVL1' // TODO: TranslateEngine + channelName: engine === 'WALL' ? 'WALL1' : 'OVL1', // TODO: TranslateEngine + showId: findShowId(config, engine) } }), // Assume DSK is off by default (config table) diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index c9f2f775a..49de2cc42 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -43,6 +43,15 @@ function prepareConfig( }) } +export const OVL_SHOW_ID = 'ovl-show-id' +export const FULL_SHOW_ID = 'full-show-id' +export const DEFAULT_GRAPHICS_SETUP = { + INewsCode: 'SomeProfile', + Concept: 'SomeConcept', + OvlShowId: OVL_SHOW_ID, + FullShowId: FULL_SHOW_ID +} + // in here will be some mock configs that can be referenced paired with ro's for the tests export const defaultStudioConfig: StudioConfig = { ClipMediaFlowId: '', @@ -255,8 +264,8 @@ export const defaultShowStyleConfig: ShowStyleConfig = { FadeOut: 0 } ], - GraphicINewsCode: '', - GraphicSetups: [], + GraphicINewsCode: 'SomeProfile', + GraphicSetups: [DEFAULT_GRAPHICS_SETUP], Transitions: [{ Transition: '1' }, { Transition: '2' }], ShowstyleTransition: 'CUT' } diff --git a/src/tv2_afvd_showstyle/config-manifests.ts b/src/tv2_afvd_showstyle/config-manifests.ts index 2d4c921d6..5da303853 100644 --- a/src/tv2_afvd_showstyle/config-manifests.ts +++ b/src/tv2_afvd_showstyle/config-manifests.ts @@ -169,6 +169,26 @@ const graphicProfileSetup: ConfigManifestEntry[] = [ hint: '', description: '', type: ConfigManifestEntryType.STRING + }, + { + id: 'OvlShowId', + name: 'OVL Show ID', + rank: 2, + required: true, + defaultVal: '', + hint: '', + description: 'UUID of the show used for OVL channel', + type: ConfigManifestEntryType.STRING + }, + { + id: 'FullShowId', + name: 'FULL Show ID', + rank: 3, + required: true, + defaultVal: '', + hint: '', + description: 'UUID of the show used for FULL and WALL channels', + type: ConfigManifestEntryType.STRING } ], hint: '' diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index efec04f82..5706d3932 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -52,7 +52,7 @@ 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, TableConfigGraphicSetup } from './helpers/config' +import { BlueprintConfig, getConfig as getShowStyleConfig } from './helpers/config' import { NUMBER_OF_DVE_BOXES } from './helpers/content/dve' import { SourceLayer } from './layers' import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' @@ -542,18 +542,21 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint path: 'BG_LOADER_SC', ignoreMediaObjectStatus: true, timelineObjects: _.compact([ - literal({ - id: '', - enable: { start: 0 }, - priority: 110, - layer: GraphicLLayer.GraphicLLayerDesign, - content: { - deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, - templateName: 'BG_LOADER_SC', - templateData: [] - } - }), + config.studio.GraphicsType === 'VIZ' + ? literal({ + id: '', + enable: { start: 0 }, + priority: 110, + layer: GraphicLLayer.GraphicLLayerDesign, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, + templateName: 'BG_LOADER_SC', + templateData: [], + showId: config.selectedGraphicsSetup.OvlShowId + } + }) + : null, literal({ id: '', enable: { start: 0 }, @@ -1201,16 +1204,9 @@ function getBaseline(config: BlueprintConfig): BlueprintResultBaseline { content: { deviceType: TSR.DeviceType.VIZMSE, type: TimelineContentTypeVizMSE.CONCEPT, - concept: findGraphicConcept(config) + concept: config.selectedGraphicsSetup.Concept } }) ] } } - -function findGraphicConcept(config: BlueprintConfig): string { - const foundTableConfigGraphicSetup: TableConfigGraphicSetup | undefined = config.showStyle.GraphicSetups.find( - tableConfigGraphicSetup => tableConfigGraphicSetup.INewsCode === config.showStyle.GraphicINewsCode - ) - return !!foundTableConfigGraphicSetup ? foundTableConfigGraphicSetup.Concept : '' -} diff --git a/src/tv2_afvd_showstyle/helpers/config.ts b/src/tv2_afvd_showstyle/helpers/config.ts index f084e990b..bae5e8101 100644 --- a/src/tv2_afvd_showstyle/helpers/config.ts +++ b/src/tv2_afvd_showstyle/helpers/config.ts @@ -4,11 +4,12 @@ import { IShowStyleContext, TableConfigItemValue } from '@tv2media/blueprints-integration' -import { TV2ShowstyleBlueprintConfigBase } from 'tv2-common' +import { TableConfigGraphicSetup, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' import { BlueprintConfig as BlueprintConfigBase } from '../../tv2_afvd_studio/helpers/config' export interface BlueprintConfig extends BlueprintConfigBase { showStyle: ShowStyleConfig + selectedGraphicsSetup: TableConfigGraphicSetup } export interface ShowStyleConfig extends TV2ShowstyleBlueprintConfigBase { @@ -17,15 +18,31 @@ export interface ShowStyleConfig extends TV2ShowstyleBlueprintConfigBase { GraphicSetups: TableConfigGraphicSetup[] } -export function parseConfig(_context: ICommonContext, config: IBlueprintConfig): any { - return { showStyle: config } +export function findGraphicSetup(context: ICommonContext, config: ShowStyleConfig): TableConfigGraphicSetup { + const foundTableConfigGraphicSetup: TableConfigGraphicSetup | undefined = config.GraphicSetups.find( + tableConfigGraphicSetup => tableConfigGraphicSetup.INewsCode === config.GraphicINewsCode + ) + if (!foundTableConfigGraphicSetup) { + context.logWarning(`No graphics setup found for profile ${config.GraphicINewsCode})`) + return { + INewsCode: '', + Concept: '', + OvlShowId: '', + FullShowId: '' + } + } + return foundTableConfigGraphicSetup } -export function getConfig(context: IShowStyleContext): BlueprintConfig { - return ({ ...(context.getStudioConfig() as any), ...(context.getShowStyleConfig() as any) } as any) as BlueprintConfig +export function parseConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { + const showstyleConfig = (rawConfig as unknown) as ShowStyleConfig + const selectedGraphicsSetup = findGraphicSetup(context, showstyleConfig) + return { + showStyle: showstyleConfig, + selectedGraphicsSetup + } } -export interface TableConfigGraphicSetup { - INewsCode: string - Concept: string +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/pieces/__tests__/grafikViz.spec.ts b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts index 84c602471..8ce74b61f 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -18,11 +18,11 @@ import { } from 'tv2-common' import { AbstractLLayer, AdlibTags, CueType, GraphicLLayer, PartType, SharedOutputLayers } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' -import { BlueprintConfig, parseConfig as parseStudioConfig } from '../../../../tv2_afvd_studio/helpers/config' +import { parseConfig as parseStudioConfig } from '../../../../tv2_afvd_studio/helpers/config' import mappingsDefaults from '../../../../tv2_afvd_studio/migrations/mappings-defaults' -import { defaultShowStyleConfig, defaultStudioConfig } from '../../../__tests__/configs' +import { defaultShowStyleConfig, defaultStudioConfig, OVL_SHOW_ID } from '../../../__tests__/configs' import { SourceLayer } from '../../../layers' -import { getConfig, parseConfig as parseShowStyleConfig } from '../../config' +import { BlueprintConfig, getConfig, parseConfig as parseShowStyleConfig } from '../../config' import { EvaluateCueGraphic } from '../graphic' function makeMockContext() { @@ -144,7 +144,8 @@ describe('grafik piece', () => { type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'bund', templateData: ['Odense', 'Copenhagen'], - channelName: 'OVL1' + channelName: 'OVL1', + showId: OVL_SHOW_ID } }), dskEnableObj @@ -214,7 +215,8 @@ describe('grafik piece', () => { type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'bund', templateData: ['Odense', 'Copenhagen'], - channelName: 'OVL1' + channelName: 'OVL1', + showId: OVL_SHOW_ID } }), dskEnableObj @@ -248,7 +250,8 @@ describe('grafik piece', () => { type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'bund', templateData: ['Odense', 'Copenhagen'], - channelName: 'OVL1' + channelName: 'OVL1', + showId: OVL_SHOW_ID } }), dskEnableObj @@ -320,7 +323,8 @@ describe('grafik piece', () => { type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'bund', templateData: ['Odense', 'Copenhagen'], - channelName: 'OVL1' + channelName: 'OVL1', + showId: OVL_SHOW_ID } }), dskEnableObj @@ -354,7 +358,8 @@ describe('grafik piece', () => { type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'bund', templateData: ['Odense', 'Copenhagen'], - channelName: 'OVL1' + channelName: 'OVL1', + showId: OVL_SHOW_ID } }), dskEnableObj @@ -425,7 +430,8 @@ describe('grafik piece', () => { type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'bund', templateData: ['Odense', 'Copenhagen'], - channelName: 'OVL1' + channelName: 'OVL1', + showId: OVL_SHOW_ID } }), dskEnableObj @@ -498,7 +504,8 @@ describe('grafik piece', () => { type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'bund', templateData: ['Odense', 'Copenhagen'], - channelName: 'OVL1' + channelName: 'OVL1', + showId: OVL_SHOW_ID } }), dskEnableObj @@ -568,7 +575,8 @@ describe('grafik piece', () => { type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'direkte', templateData: ['KØBENHAVN'], - channelName: 'OVL1' + channelName: 'OVL1', + showId: OVL_SHOW_ID } }), dskEnableObj @@ -663,7 +671,8 @@ describe('grafik piece', () => { type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'arkiv', templateData: ['unnamed org'], - channelName: 'OVL1' + channelName: 'OVL1', + showId: OVL_SHOW_ID } }), dskEnableObj @@ -733,7 +742,8 @@ describe('grafik piece', () => { type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'tlftoptlive', templateData: ['Line 1', 'Line 2'], - channelName: 'OVL1' + channelName: 'OVL1', + showId: OVL_SHOW_ID } }), dskEnableObj @@ -767,7 +777,8 @@ describe('grafik piece', () => { type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'tlftoptlive', templateData: ['Line 1', 'Line 2'], - channelName: 'OVL1' + channelName: 'OVL1', + showId: OVL_SHOW_ID } }), 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 7e07edbad..2519a3edc 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -18,7 +18,12 @@ import { } from 'tv2-common' import { CueType, GraphicLLayer, PartType, SharedOutputLayers } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' -import { defaultShowStyleConfig, defaultStudioConfig } from '../../../../tv2_afvd_showstyle/__tests__/configs' +import { + DEFAULT_GRAPHICS_SETUP, + defaultShowStyleConfig, + defaultStudioConfig, + OVL_SHOW_ID +} from '../../../../tv2_afvd_showstyle/__tests__/configs' import { SourceLayer } from '../../../../tv2_afvd_showstyle/layers' import { defaultDSKConfig, @@ -87,7 +92,8 @@ describe('telefon', () => { mediaPlayers: [], stickyLayers: [], liveAudio: [], - dsk: defaultDSKConfig + dsk: defaultDSKConfig, + selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP }, mockContext, dummyBlueprintPart, @@ -125,7 +131,8 @@ describe('telefon', () => { type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: 'bund', templateData: ['Odense', 'Copenhagen'], - channelName: 'OVL1' + channelName: 'OVL1', + showId: OVL_SHOW_ID } }), literal({ diff --git a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts index da7465389..3dae45760 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts @@ -7,8 +7,8 @@ import { } from '@tv2media/blueprints-integration' import { CreateTimingEnable, CueDefinitionClearGrafiks, GetDefaultOut, literal } from 'tv2-common' import { GraphicLLayer, SharedOutputLayers } from 'tv2-constants' +import { BlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { SourceLayer } from '../../../tv2_afvd_showstyle/layers' -import { BlueprintConfig } from '../../../tv2_afvd_studio/helpers/config' export function EvaluateClearGrafiks( config: BlueprintConfig, @@ -71,7 +71,8 @@ export function EvaluateClearGrafiks( layer: GraphicLLayer.GraphicLLayerAdLibs, content: { deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS + type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, + showId: config.selectedGraphicsSetup.OvlShowId } }) ] diff --git a/src/tv2_afvd_showstyle/helpers/pieces/design.ts b/src/tv2_afvd_showstyle/helpers/pieces/design.ts index 862e25e1a..09d8c7764 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/design.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/design.ts @@ -4,12 +4,11 @@ import { IBlueprintPiece, ISegmentUserContext } from '@tv2media/blueprints-integration' -import { CueDefinitionGraphicDesign, EvaluateDesignBase } from 'tv2-common' +import { CueDefinitionGraphicDesign, EvaluateDesignBase, TV2BlueprintConfig } from 'tv2-common' import * as _ from 'underscore' -import { BlueprintConfig } from '../../../tv2_afvd_studio/helpers/config' export function EvaluateCueDesign( - config: BlueprintConfig, + config: TV2BlueprintConfig, context: ISegmentUserContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], diff --git a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts index 1affab492..1ea331dc1 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts @@ -5,14 +5,13 @@ import { IBlueprintPiece, ISegmentUserContext } from '@tv2media/blueprints-integration' -import { CueDefinitionEkstern, EvaluateEksternBase, PartDefinition } from 'tv2-common' -import { BlueprintConfig } from '../../../tv2_afvd_studio/helpers/config' +import { CueDefinitionEkstern, EvaluateEksternBase, PartDefinition, TV2BlueprintConfig } from 'tv2-common' import { AtemLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' export function EvaluateEkstern( context: ISegmentUserContext, - config: BlueprintConfig, + config: TV2BlueprintConfig, part: IBlueprintPart, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts index cbc949e14..50dff440c 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts @@ -7,12 +7,13 @@ import { TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { CalculateTime, CueDefinitionBackgroundLoop, literal } from 'tv2-common' +import { CalculateTime, CueDefinitionBackgroundLoop, literal, TV2BlueprintConfig } from 'tv2-common' import { GraphicLLayer, SharedOutputLayers } from 'tv2-constants' import { CasparLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' export function EvaluateCueBackgroundLoop( + config: TV2BlueprintConfig, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], _actions: IBlueprintActionManifest[], @@ -78,7 +79,7 @@ export function EvaluateCueBackgroundLoop( fileName: parsedCue.backgroundLoop, path: parsedCue.backgroundLoop, ignoreMediaObjectStatus: true, - timelineObjects: fullLoopTimeline(parsedCue) + timelineObjects: fullLoopTimeline(config, parsedCue) }) }) ) @@ -97,7 +98,7 @@ export function EvaluateCueBackgroundLoop( fileName: parsedCue.backgroundLoop, path: parsedCue.backgroundLoop, ignoreMediaObjectStatus: true, - timelineObjects: fullLoopTimeline(parsedCue) + timelineObjects: fullLoopTimeline(config, parsedCue) }) }) ) @@ -122,7 +123,7 @@ function dveLoopTimeline(path: string): TSR.TSRTimelineObj[] { ] } -function fullLoopTimeline(parsedCue: CueDefinitionBackgroundLoop): TSR.TSRTimelineObj[] { +function fullLoopTimeline(config: TV2BlueprintConfig, parsedCue: CueDefinitionBackgroundLoop): TSR.TSRTimelineObj[] { return [ literal({ id: '', @@ -133,7 +134,8 @@ function fullLoopTimeline(parsedCue: CueDefinitionBackgroundLoop): TSR.TSRTimeli deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, templateName: parsedCue.backgroundLoop, - templateData: [] + templateData: [], + showId: config.selectedGraphicsSetup.FullShowId } }) ] diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts index 0fad4ec5b..f62bdfb02 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts @@ -18,7 +18,8 @@ import { literal, PilotGeneratorSettings, SisyfosEVSSource, - SourceInfo + SourceInfo, + TV2BlueprintConfig } from 'tv2-common' import { AtemLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' import { BlueprintConfig } from '../config' @@ -29,7 +30,7 @@ export const pilotGeneratorSettingsAFVD: PilotGeneratorSettings = { } export function EvaluateCueGraphicPilot( - config: BlueprintConfig, + config: TV2BlueprintConfig, context: IShowStyleUserContext, part: Readonly, pieces: IBlueprintPiece[], diff --git a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts index ee035e889..6a17fbf76 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts @@ -9,15 +9,14 @@ import { TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { CalculateTime, CueDefinitionRouting, FindSourceInfoStrict, literal } from 'tv2-common' +import { CalculateTime, CueDefinitionRouting, FindSourceInfoStrict, literal, TV2BlueprintConfig } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import _ = require('underscore') import { AtemLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' -import { BlueprintConfig } from '../config' export function EvaluateCueRouting( - config: BlueprintConfig, + config: TV2BlueprintConfig, context: ISegmentUserContext, pieces: IBlueprintPiece[], _adlibPieces: IBlueprintAdLibPiece[], diff --git a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts index 73f97ab0b..4b0fe21ad 100644 --- a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts @@ -11,8 +11,8 @@ import { } from '@tv2media/blueprints-integration' import { AtemLLayerDSK, FindDSKJingle, literal, TimelineBlueprintExt } from 'tv2-common' import * as _ from 'underscore' -import { BlueprintConfig } from '../tv2_afvd_studio/helpers/config' import { AtemLLayer } from '../tv2_afvd_studio/layers' +import { BlueprintConfig } from './helpers/config' import { SourceLayer } from './layers' export function postProcessPartTimelineObjects( diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts index 8761817ba..ddf7526c9 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts @@ -7,13 +7,14 @@ import { TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { CalculateTime, CueDefinitionBackgroundLoop, literal } from 'tv2-common' +import { CalculateTime, CueDefinitionBackgroundLoop, literal, TV2BlueprintConfig } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import _ = require('underscore') import { OfftubeCasparLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeSourceLayer } from '../layers' export function OfftubeEvaluateCueBackgroundLoop( + _config: TV2BlueprintConfig, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], _actions: IBlueprintActionManifest[], diff --git a/src/tv2_offtube_showstyle/helpers/config.ts b/src/tv2_offtube_showstyle/helpers/config.ts index be441d409..a00d11214 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 '@tv2media/blueprints-integration' -import { TV2ShowstyleBlueprintConfigBase } from 'tv2-common' +import { TableConfigGraphicSetup, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' import * as _ from 'underscore' import { OfftubeStudioBlueprintConfig } from '../../tv2_offtube_studio/helpers/config' @@ -22,6 +22,7 @@ export interface TableConfigItemGFXTemplates { export interface OfftubeShowstyleBlueprintConfig extends OfftubeStudioBlueprintConfig { showStyle: OfftubeShowStyleConfig + selectedGraphicsSetup: TableConfigGraphicSetup } export interface DVEConfigInput { @@ -37,8 +38,26 @@ export interface OfftubeShowStyleConfig extends TV2ShowstyleBlueprintConfigBase WipesConfig: TableConfigItemValue } -export function parseConfig(_context: ICommonContext, config: IBlueprintConfig): any { - return { showStyle: config } +export function findGraphicSetup( + _context: ICommonContext, + _config: TV2ShowstyleBlueprintConfigBase +): TableConfigGraphicSetup { + // just for type compatibility, not really supported in offtube + return { + INewsCode: '', + Concept: '', + OvlShowId: '', + FullShowId: '' + } +} + +export function parseConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { + const showstyleConfig = (rawConfig as unknown) as OfftubeShowStyleConfig + const selectedGraphicsSetup = findGraphicSetup(context, showstyleConfig) + return { + showStyle: showstyleConfig, + selectedGraphicsSetup + } } export function getConfig(context: IShowStyleContext): OfftubeShowstyleBlueprintConfig { From 7fd06fd3045ff0151a1a922cede6f7eca3737cd3 Mon Sep 17 00:00:00 2001 From: ianshade Date: Fri, 25 Feb 2022 11:59:19 +0100 Subject: [PATCH 050/184] chore: SOF-752 rename for consistency --- src/tv2-common/blueprintConfig.ts | 4 ++-- src/tv2-common/helpers/graphics/index.ts | 6 ++--- .../__tests__/config-manifest.spec.ts | 4 ++-- src/tv2_afvd_showstyle/__tests__/configs.ts | 4 ++-- src/tv2_afvd_showstyle/config-manifests.ts | 10 ++++----- src/tv2_afvd_showstyle/helpers/config.ts | 22 +++++++++---------- src/tv2_offtube_showstyle/helpers/config.ts | 10 ++++----- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 1477fc1bb..c2dca77dd 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -34,7 +34,7 @@ export interface TableConfigItemAdLibTransitions { Transition: string } -export interface TableConfigGraphicSetup { +export interface TableConfigGraphicsSetup { INewsCode: string Concept: string OvlShowId: string @@ -142,7 +142,7 @@ export interface TV2ShowstyleBlueprintConfigBase { export interface TV2BlueprintConfigBase extends TV2StudioBlueprintConfigBase { showStyle: TV2ShowstyleBlueprintConfigBase - selectedGraphicsSetup: TableConfigGraphicSetup + selectedGraphicsSetup: TableConfigGraphicsSetup } export type TV2BlueprintConfig = TV2BlueprintConfigBase diff --git a/src/tv2-common/helpers/graphics/index.ts b/src/tv2-common/helpers/graphics/index.ts index a6410db46..aee52ff31 100644 --- a/src/tv2-common/helpers/graphics/index.ts +++ b/src/tv2-common/helpers/graphics/index.ts @@ -151,13 +151,13 @@ export function CreateGraphicBaseline(config: TV2BlueprintConfig): TSR.TSRTimeli } export function findShowId(config: TV2BlueprintConfig, engine: GraphicEngine) { - const graphicSetup = config.selectedGraphicsSetup + const graphicsSetup = config.selectedGraphicsSetup switch (engine) { case 'FULL': case 'WALL': - return graphicSetup.FullShowId + return graphicsSetup.FullShowId case 'TLF': case 'OVL': - return graphicSetup.OvlShowId + return graphicsSetup.OvlShowId } } diff --git a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts index fdc109790..e22721bb4 100644 --- a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts @@ -13,8 +13,8 @@ const blankShowStyleConfig: ShowStyleConfig = { CasparCGLoadingClip: '', Transitions: [{ Transition: '1' }, { Transition: '2' }], ShowstyleTransition: 'CUT', - GraphicINewsCode: '', - GraphicSetups: [] + GraphicsINewsCode: '', + GraphicsSetups: [] } describe('Config Manifest', () => { diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index 49de2cc42..4198497c8 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -264,8 +264,8 @@ export const defaultShowStyleConfig: ShowStyleConfig = { FadeOut: 0 } ], - GraphicINewsCode: 'SomeProfile', - GraphicSetups: [DEFAULT_GRAPHICS_SETUP], + GraphicsINewsCode: 'SomeProfile', + GraphicsSetups: [DEFAULT_GRAPHICS_SETUP], Transitions: [{ Transition: '1' }, { Transition: '2' }], ShowstyleTransition: 'CUT' } diff --git a/src/tv2_afvd_showstyle/config-manifests.ts b/src/tv2_afvd_showstyle/config-manifests.ts index 5da303853..3c411c537 100644 --- a/src/tv2_afvd_showstyle/config-manifests.ts +++ b/src/tv2_afvd_showstyle/config-manifests.ts @@ -144,8 +144,8 @@ export const dveStylesManifest: ConfigManifestEntry = { const graphicProfileSetup: ConfigManifestEntry[] = [ { - id: 'GraphicSetups', - name: 'Graphic Setups', + id: 'GraphicsSetups', + name: 'Graphics Setups', description: 'Possible graphic profile setup', type: ConfigManifestEntryType.TABLE, required: false, @@ -194,9 +194,9 @@ const graphicProfileSetup: ConfigManifestEntry[] = [ hint: '' }, { - id: 'GraphicINewsCode', - name: 'Graphic Profile cue', - description: 'GRAPHIC_PROFILE cue from iNews', + id: 'GraphicsINewsCode', + name: 'Graphics Profile cue', + description: 'GRAPHICS_PROFILE cue from iNews', type: ConfigManifestEntryType.STRING, required: false, defaultVal: '' diff --git a/src/tv2_afvd_showstyle/helpers/config.ts b/src/tv2_afvd_showstyle/helpers/config.ts index bae5e8101..773346cfb 100644 --- a/src/tv2_afvd_showstyle/helpers/config.ts +++ b/src/tv2_afvd_showstyle/helpers/config.ts @@ -4,26 +4,26 @@ import { IShowStyleContext, TableConfigItemValue } from '@tv2media/blueprints-integration' -import { TableConfigGraphicSetup, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' +import { TableConfigGraphicsSetup, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' import { BlueprintConfig as BlueprintConfigBase } from '../../tv2_afvd_studio/helpers/config' export interface BlueprintConfig extends BlueprintConfigBase { showStyle: ShowStyleConfig - selectedGraphicsSetup: TableConfigGraphicSetup + selectedGraphicsSetup: TableConfigGraphicsSetup } export interface ShowStyleConfig extends TV2ShowstyleBlueprintConfigBase { WipesConfig: TableConfigItemValue - GraphicINewsCode: string - GraphicSetups: TableConfigGraphicSetup[] + GraphicsINewsCode: string + GraphicsSetups: TableConfigGraphicsSetup[] } -export function findGraphicSetup(context: ICommonContext, config: ShowStyleConfig): TableConfigGraphicSetup { - const foundTableConfigGraphicSetup: TableConfigGraphicSetup | undefined = config.GraphicSetups.find( - tableConfigGraphicSetup => tableConfigGraphicSetup.INewsCode === config.GraphicINewsCode +export function findGraphicsSetup(context: ICommonContext, config: ShowStyleConfig): TableConfigGraphicsSetup { + const foundTableConfigGraphicsSetup: TableConfigGraphicsSetup | undefined = config.GraphicsSetups.find( + tableConfigGraphicsSetup => tableConfigGraphicsSetup.INewsCode === config.GraphicsINewsCode ) - if (!foundTableConfigGraphicSetup) { - context.logWarning(`No graphics setup found for profile ${config.GraphicINewsCode})`) + if (!foundTableConfigGraphicsSetup) { + context.logWarning(`No graphics setup found for profile ${config.GraphicsINewsCode})`) return { INewsCode: '', Concept: '', @@ -31,12 +31,12 @@ export function findGraphicSetup(context: ICommonContext, config: ShowStyleConfi FullShowId: '' } } - return foundTableConfigGraphicSetup + return foundTableConfigGraphicsSetup } export function parseConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { const showstyleConfig = (rawConfig as unknown) as ShowStyleConfig - const selectedGraphicsSetup = findGraphicSetup(context, showstyleConfig) + const selectedGraphicsSetup = findGraphicsSetup(context, showstyleConfig) return { showStyle: showstyleConfig, selectedGraphicsSetup diff --git a/src/tv2_offtube_showstyle/helpers/config.ts b/src/tv2_offtube_showstyle/helpers/config.ts index a00d11214..ded7c48a9 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 '@tv2media/blueprints-integration' -import { TableConfigGraphicSetup, TV2ShowstyleBlueprintConfigBase } from 'tv2-common' +import { TableConfigGraphicsSetup, 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: TableConfigGraphicSetup + selectedGraphicsSetup: TableConfigGraphicsSetup } export interface DVEConfigInput { @@ -38,10 +38,10 @@ export interface OfftubeShowStyleConfig extends TV2ShowstyleBlueprintConfigBase WipesConfig: TableConfigItemValue } -export function findGraphicSetup( +export function findGraphicsSetup( _context: ICommonContext, _config: TV2ShowstyleBlueprintConfigBase -): TableConfigGraphicSetup { +): TableConfigGraphicsSetup { // just for type compatibility, not really supported in offtube return { INewsCode: '', @@ -53,7 +53,7 @@ export function findGraphicSetup( export function parseConfig(context: ICommonContext, rawConfig: IBlueprintConfig): any { const showstyleConfig = (rawConfig as unknown) as OfftubeShowStyleConfig - const selectedGraphicsSetup = findGraphicSetup(context, showstyleConfig) + const selectedGraphicsSetup = findGraphicsSetup(context, showstyleConfig) return { showStyle: showstyleConfig, selectedGraphicsSetup From ace7caa2dedb390ce38c6f8ed2c7846e4b7b99d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Fri, 25 Feb 2022 13:31:36 +0100 Subject: [PATCH 051/184] wip: Fade down sticky faders adlib begun. The adlib action is registered, but does not do any real work yet. --- src/tv2-common/actions/actionTypes.ts | 5 +++++ src/tv2-common/actions/executeAction.ts | 17 +++++++++++++++++ src/tv2-constants/enums.ts | 6 ++++-- src/tv2_afvd_showstyle/getRundown.ts | 18 ++++++++++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/actions/actionTypes.ts b/src/tv2-common/actions/actionTypes.ts index 307070ec2..80db98b21 100644 --- a/src/tv2-common/actions/actionTypes.ts +++ b/src/tv2-common/actions/actionTypes.ts @@ -124,6 +124,10 @@ export interface ActionRecallLastDVE extends ActionBase { type: AdlibActionType.RECALL_LAST_DVE } +export interface ActionFadeDownPersistedAudioLevels extends ActionBase { + type: AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS +} + export type TV2AdlibAction = | ActionSelectServerClip | ActionSelectDVE @@ -140,3 +144,4 @@ export type TV2AdlibAction = | ActionTakeWithTransition | ActionRecallLastLive | ActionRecallLastDVE + | ActionFadeDownPersistedAudioLevels diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 37fbd300f..f43199340 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -86,6 +86,7 @@ import { import { assertUnreachable } from '../util' import { ActionCommentatorSelectJingle, + ActionFadeDownPersistedAudioLevels, ActionRecallLastDVE, ActionRecallLastLive, ActionSelectJingle, @@ -249,6 +250,9 @@ export function executeAction< case AdlibActionType.RECALL_LAST_DVE: executeActionRecallLastDVE(context, settings, actionId, userData as ActionRecallLastDVE) break + case AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS: + executeActionFadeDownPersistedAudioLevels(context, settings, actionId, userData as ActionFadeDownPersistedAudioLevels) + break default: assertUnreachable(actionId) break @@ -1837,6 +1841,19 @@ function executeActionRecallLastDVE< } } +function executeActionFadeDownPersistedAudioLevels< +StudioConfig extends TV2StudioConfigBase, +ShowStyleConfig extends TV2BlueprintConfigBase +>( + context: ITV2ActionExecutionContext, + _settings: ActionExecutionSettings, + _actionId: string, + _userData: ActionFadeDownPersistedAudioLevels +) { + // TODO: Use enum instead of string literal. + context.stopPiecesOnLayers(['sisyfos_persisted_levels']) +} + function scheduleLastPlayedDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index ea46f41d7..c213221e3 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -90,7 +90,8 @@ export enum AdlibTags { ADLIB_RECALL_LAST_LIVE = 'recall_last_live', ADLIB_RECALL_LAST_DVE = 'recall_last_dve', ADLIB_SELECT_DVE_LAYOUT = 'select_dve_layout', - ADLIB_TAKE_WITH_TRANSITION = 'take_with_transition' + ADLIB_TAKE_WITH_TRANSITION = 'take_with_transition', + ADLIB_FADE_DOWN_PERSISTED_AUDIO_LEVELS = 'fade_down_persisted_audio_levels', } /** @@ -133,7 +134,8 @@ export enum AdlibActionType { CLEAR_GRAPHICS = 'clear_graphics', TAKE_WITH_TRANSITION = 'take_with_transition', RECALL_LAST_LIVE = 'recall_last_live', - RECALL_LAST_DVE = 'recall_last_dve' + RECALL_LAST_DVE = 'recall_last_dve', + FADE_DOWN_PERSISTED_AUDIO_LEVELS = 'fade_down_persisted_audio_levels', } export enum TallyTags { diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index efec04f82..1045c7505 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -20,6 +20,7 @@ import { ActionClearGraphics, ActionCutSourceToBox, ActionCutToCamera, + ActionFadeDownPersistedAudioLevels, ActionRecallLastDVE, ActionRecallLastLive, ActionSelectDVELayout, @@ -850,6 +851,23 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri ) }) + res.push( + literal({ + actionId: AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS, + userData: literal({ + type: AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS, + }), + 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] + } + }) + ) + return res } From 6a5e8d606d20c6110c28de9b5a29a9cfef04b17a Mon Sep 17 00:00:00 2001 From: ianshade Date: Mon, 28 Feb 2022 12:46:29 +0100 Subject: [PATCH 052/184] chore: SOF-752 fix tests --- .../helpers/pieces/__tests__/lyd.spec.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) 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 233a26f05..bfae478e6 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts @@ -7,7 +7,11 @@ import { import { CueDefinitionLYD, EvaluateLYD, literal, ParseCue, PartDefinitionKam } from 'tv2-common' import { NoteType, PartType } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' -import { defaultShowStyleConfig, defaultStudioConfig } from '../../../../tv2_afvd_showstyle/__tests__/configs' +import { + DEFAULT_GRAPHICS_SETUP, + defaultShowStyleConfig, + defaultStudioConfig +} from '../../../../tv2_afvd_showstyle/__tests__/configs' import { defaultDSKConfig, parseConfig as parseStudioConfig, @@ -56,7 +60,8 @@ describe('lyd', () => { mediaPlayers: [], stickyLayers: [], liveAudio: [], - dsk: defaultDSKConfig + dsk: defaultDSKConfig, + selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP }, pieces, adlibPieces, @@ -103,7 +108,8 @@ describe('lyd', () => { mediaPlayers: [], stickyLayers: [], liveAudio: [], - dsk: defaultDSKConfig + dsk: defaultDSKConfig, + selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP }, pieces, adlibPieces, @@ -153,7 +159,8 @@ describe('lyd', () => { mediaPlayers: [], stickyLayers: [], liveAudio: [], - dsk: defaultDSKConfig + dsk: defaultDSKConfig, + selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP }, pieces, adlibPieces, From 5f1b02cec29efa7e9b12019c15f3a1c43e03d1bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Mon, 28 Feb 2022 15:25:16 +0100 Subject: [PATCH 053/184] fix: Renamed graphicProfile to showstyleVariant for IngestRundown payload. --- src/tv2_afvd_showstyle/getRundown.ts | 2 +- src/tv2_offtube_showstyle/getRundown.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index efec04f82..f017fb7ef 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -62,7 +62,7 @@ export function getShowStyleVariantId( showStyleVariants: IBlueprintShowStyleVariant[], ingestRundown: IngestRundown ): string | null { - const graphicsprofile = ingestRundown.payload?.graphicProfile?.trim().toLowerCase() + const graphicsprofile = ingestRundown.payload?.showstyleVariant?.trim().toLowerCase() const variant = showStyleVariants.find(v => v.name.trim().toLowerCase() === graphicsprofile) ?? _.first(showStyleVariants) diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 1f164214d..4cafe819b 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -66,7 +66,7 @@ export function getShowStyleVariantId( showStyleVariants: IBlueprintShowStyleVariant[], ingestRundown: IngestRundown ): string | null { - const graphicsprofile = ingestRundown.payload?.graphicProfile?.trim().toLowerCase() + const graphicsprofile = ingestRundown.payload?.showstyleVariant?.trim().toLowerCase() const variant = showStyleVariants.find(v => v.name.trim().toLowerCase() === graphicsprofile) ?? _.first(showStyleVariants) From 40cb15f6439456ab3700bf4d3a93d723cac00c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Mon, 7 Mar 2022 11:51:34 +0100 Subject: [PATCH 054/184] refactor: Renamed local variable from graphicsProfile to showstyleVariant. --- src/tv2_afvd_showstyle/getRundown.ts | 4 ++-- src/tv2_offtube_showstyle/getRundown.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index f017fb7ef..74a80d37c 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -62,9 +62,9 @@ export function getShowStyleVariantId( showStyleVariants: IBlueprintShowStyleVariant[], ingestRundown: IngestRundown ): string | null { - const graphicsprofile = ingestRundown.payload?.showstyleVariant?.trim().toLowerCase() + const showstyleVariant = ingestRundown.payload?.showstyleVariant?.trim().toLowerCase() const variant = - showStyleVariants.find(v => v.name.trim().toLowerCase() === graphicsprofile) ?? _.first(showStyleVariants) + showStyleVariants.find(v => v.name.trim().toLowerCase() === showstyleVariant) ?? _.first(showStyleVariants) if (variant) { return variant._id diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 4cafe819b..8ea92b2ae 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -66,9 +66,9 @@ export function getShowStyleVariantId( showStyleVariants: IBlueprintShowStyleVariant[], ingestRundown: IngestRundown ): string | null { - const graphicsprofile = ingestRundown.payload?.showstyleVariant?.trim().toLowerCase() + const showstyleVariant = ingestRundown.payload?.showstyleVariant?.trim().toLowerCase() const variant = - showStyleVariants.find(v => v.name.trim().toLowerCase() === graphicsprofile) ?? _.first(showStyleVariants) + showStyleVariants.find(v => v.name.trim().toLowerCase() === showstyleVariant) ?? _.first(showStyleVariants) if (variant) { return variant._id From be851ccb724e1ff1a579c38671652c597beed558 Mon Sep 17 00:00:00 2001 From: Krzysztof Zegzula Date: Tue, 8 Mar 2022 11:00:46 +0100 Subject: [PATCH 055/184] fix: correct layers and keys for recall-last actions --- src/tv2-common/hotkeys/global.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/hotkeys/global.ts b/src/tv2-common/hotkeys/global.ts index 7f2e40c63..9b2af643a 100644 --- a/src/tv2-common/hotkeys/global.ts +++ b/src/tv2-common/hotkeys/global.ts @@ -105,7 +105,7 @@ export function MakeGlobalTriggers( ) const recallLastTriggers = [ makeRecallLastTrigger( - SharedSourceLayers.PgmDVE, + SharedSourceLayers.PgmDVEAdLib, getNextRank, recallLastHotkeyId(showStyleId, SharedSourceLayers.PgmDVE, 'dve', 0), 'Last DVE', @@ -117,7 +117,7 @@ export function MakeGlobalTriggers( getNextRank, recallLastHotkeyId(showStyleId, SharedSourceLayers.PgmLive, 'live', 0), 'Last Live', - assignments.recallLast.DVE, + assignments.recallLast.Live, [AdlibTags.ADLIB_RECALL_LAST_LIVE] ) ] From 8456aa55b34547b03a5badc9470350b0bf5117b3 Mon Sep 17 00:00:00 2001 From: Krzysztof Zegzula Date: Tue, 8 Mar 2022 11:05:14 +0100 Subject: [PATCH 056/184] fix: some typos in triggers --- src/tv2-common/hotkeys/hotkey-defaults.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/hotkeys/hotkey-defaults.ts b/src/tv2-common/hotkeys/hotkey-defaults.ts index ee899ad3d..cd8b1c18e 100644 --- a/src/tv2-common/hotkeys/hotkey-defaults.ts +++ b/src/tv2-common/hotkeys/hotkey-defaults.ts @@ -25,7 +25,7 @@ export const defaultHotkeys: TV2Hotkeys = { queue: ['Ctrl+Shift+F1', 'Ctrl+Shift+F2', 'Ctrl+Shift+F3', 'Ctrl+Shift+F4', 'Ctrl+Shift+F5'], cutToBox: [ ['Shift+F1', 'Shift+F2', 'Shift+F3', 'Shift+F4', 'Shift+F5'], - ['Ctrl+F1', 'Crtl+F2', 'Ctrl+F3', 'Ctrl+Alt+Shift+KeyA', 'Ctrl+F5'], + ['Ctrl+F1', 'Ctrl+F2', 'Ctrl+F3', 'Ctrl+Alt+Shift+KeyA', 'Ctrl+F5'], ['Shift+Alt+F1', 'Shift+Alt+F2', 'Shift+Alt+F3', 'Shift+Alt+F4', 'Shift+Alt+F5'], [] ], @@ -210,7 +210,7 @@ export const defaultHotkeys: TV2Hotkeys = { rundownView: literal({ activate: 'Backquote', activateRehearsal: 'Ctrl+Backquote', - deactivate: 'Crtl+Shift+Backquote', + deactivate: 'Ctrl+Shift+Backquote', take: 'AnyEnter', goToLiveLive: 'Shift+Home', rewindSegments: 'Ctrl+Home', From aa3f292995ac8bc36dd90ae9d44a18db27d91db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Tue, 8 Mar 2022 12:23:59 +0100 Subject: [PATCH 057/184] refactor: Renamed label for deactivate rundown shortcut. --- src/tv2-common/hotkeys/rundownView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv2-common/hotkeys/rundownView.ts b/src/tv2-common/hotkeys/rundownView.ts index cd5547977..008e1e466 100644 --- a/src/tv2-common/hotkeys/rundownView.ts +++ b/src/tv2-common/hotkeys/rundownView.ts @@ -87,7 +87,7 @@ export function MakeRundownViewTriggers( literal({ _id: rundownViewActionTriggerId(showStyleId, 'deactivate_rundown'), _rank: getNextRank(), - name: 'deaktivate rundown', + name: 'Deactivate rundown', triggers: [ literal({ type: TriggerType.hotkey, From 54b840f9d6b7300fddcaaff34c5f727bff47786f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Tue, 8 Mar 2022 12:27:57 +0100 Subject: [PATCH 058/184] fix: Don't force activation of rundown. Force activating a rundown will if already actiavated reset the rundown. To avoid producers accidentaly resetting the rundown, we won't force activation. --- src/tv2-common/hotkeys/rundownView.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/hotkeys/rundownView.ts b/src/tv2-common/hotkeys/rundownView.ts index 008e1e466..406fb943a 100644 --- a/src/tv2-common/hotkeys/rundownView.ts +++ b/src/tv2-common/hotkeys/rundownView.ts @@ -51,7 +51,7 @@ export function MakeRundownViewTriggers( literal({ action: PlayoutActions.activateRundownPlaylist, rehearsal: false, - force: true, + force: false, filterChain: [ literal({ object: 'view' @@ -75,7 +75,7 @@ export function MakeRundownViewTriggers( literal({ action: PlayoutActions.activateRundownPlaylist, rehearsal: true, - force: true, + force: false, filterChain: [ literal({ object: 'view' From 87fe70c0b0fa38187db3b7b93d08379d523b9586 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 9 Mar 2022 14:02:57 +0100 Subject: [PATCH 059/184] SOF-789 Blueprints now only considers the configuration for 'wantsToPersistAudio' and 'acceptPersistAudio' when calculating which Sisyfos levels to persist --- config/tsconfig.base.json | 2 +- package.json | 6 +- .../__tests__/onTimelineGenerate.spec.ts | 348 ++ src/tv2-common/actions/executeAction.ts | 136 +- src/tv2-common/blueprintConfig.ts | 12 +- src/tv2-common/content/dve.ts | 52 +- src/tv2-common/content/server.ts | 21 - src/tv2-common/cues/ekstern.ts | 25 +- src/tv2-common/helpers/sisyfos.ts | 116 +- src/tv2-common/migrations/sourceManifest.ts | 28 +- src/tv2-common/onTimelineGenerate.ts | 220 +- src/tv2-common/parts/server.ts | 9 +- src/tv2-common/sources.ts | 6 +- src/tv2-common/types/config.ts | 6 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 6 +- src/tv2_afvd_showstyle/actions.ts | 8 +- src/tv2_afvd_showstyle/getRundown.ts | 117 +- src/tv2_afvd_showstyle/helpers/content/dve.ts | 15 +- .../helpers/pieces/__tests__/lyd.spec.ts | 6 - .../helpers/pieces/__tests__/telefon.spec.ts | 2 - .../helpers/pieces/adlib.ts | 18 +- src/tv2_afvd_showstyle/helpers/pieces/dve.ts | 12 +- .../helpers/sisyfos/__tests__/sisyfos.spec.ts | 70 - src/tv2_afvd_showstyle/parts/evs.ts | 6 + src/tv2_afvd_showstyle/parts/grafik.ts | 5 +- src/tv2_afvd_showstyle/parts/kam.ts | 15 +- src/tv2_afvd_studio/config-manifests.ts | 42 +- src/tv2_afvd_studio/helpers/config.ts | 8 - src/tv2_afvd_studio/migrations/index.ts | 2 + src/tv2_offtube_showstyle/actions.ts | 8 +- .../content/OfftubeDVEContent.ts | 8 +- .../cues/OfftubeAdlib.ts | 12 - src/tv2_offtube_showstyle/cues/OfftubeDVE.ts | 5 +- .../cues/OfftubeJingle.ts | 3 + .../parts/OfftubeGrafik.ts | 13 +- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 10 +- src/tv2_offtube_studio/config-manifests.ts | 16 +- src/tv2_offtube_studio/helpers/config.ts | 8 - src/tv2_offtube_studio/migrations/index.ts | 2 + yarn.lock | 3360 ++++++++++------- 40 files changed, 2714 insertions(+), 2050 deletions(-) create mode 100644 src/tv2-common/__tests__/onTimelineGenerate.spec.ts delete mode 100644 src/tv2_afvd_showstyle/helpers/sisyfos/__tests__/sisyfos.spec.ts diff --git a/config/tsconfig.base.json b/config/tsconfig.base.json index 34c2e3b1b..51fc7e74b 100644 --- a/config/tsconfig.base.json +++ b/config/tsconfig.base.json @@ -19,7 +19,7 @@ "traceResolution": false, "pretty": true, "lib": [ - "es6" + "ES2019" ], "types": [ "node", diff --git a/package.json b/package.json index 3e4292064..2fdb9085e 100644 --- a/package.json +++ b/package.json @@ -35,19 +35,19 @@ ] }, "devDependencies": { - "@types/jest": "^24.0.0", + "@types/jest": "^27.4.1", "@types/node": "^12.12.2", "@types/underscore": "^1.8.9", "axios": "^0.19.0", "git-revision-webpack-plugin": "^3.0.3", - "jest": "^24.0.0", + "jest": "^27.5.1", "jest-haste-map": "^24.5.0", "jest-resolve": "^24.5.0", "moment": "^2.22.2", "node-license-validator": "^1.3.0", "prettier": "^1.18.2", "standard-version": "9.1.1", - "ts-jest": "^24.0.0", + "ts-jest": "^27.1.3", "ts-loader": "^6.2.1", "ts-node": "^8.0.3", "tsconfig-paths-webpack-plugin": "^3.2.0", diff --git a/src/tv2-common/__tests__/onTimelineGenerate.spec.ts b/src/tv2-common/__tests__/onTimelineGenerate.spec.ts new file mode 100644 index 000000000..db4602305 --- /dev/null +++ b/src/tv2-common/__tests__/onTimelineGenerate.spec.ts @@ -0,0 +1,348 @@ +import { IBlueprintPieceDB, IBlueprintResolvedPieceInstance, TSR } from '@tv2media/blueprints-integration' +import { SisyfosLLAyer } from '../../tv2_afvd_studio/layers' +import { createSisyfosPersistedLevelsTimelineObject, SisyfosPersistMetaData } from '../onTimelineGenerate' + +const LAYER_THAT_WANTS_TO_BE_PERSISTED = 'layerThatWantsToBePersisted' +const LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY: SisyfosPersistMetaData['sisyfosLayers'] = [ + LAYER_THAT_WANTS_TO_BE_PERSISTED +] + +// tslint:disable:no-object-literal-type-assertion +describe('onTimelineGenerate', () => { + describe('createSisyfosPersistedLevelsTimelineObject', () => { + it('has one layer to persist, piece accept persist - timelineObject with layer is added', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('currentPiece', 10, undefined, true, true) + ] + + 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 + ) + expect(indexOfLayerThatWantToBePersisted).toBeGreaterThanOrEqual(0) + }) + + it('has layer to persist, timelineObject with correct Sisyfos information is added', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('currentPiece', 10, undefined, true, true) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) + + expect(result.layer).toEqual(SisyfosLLAyer.SisyfosPersistedLevels) + expect(result.content.deviceType).toEqual(TSR.DeviceType.SISYFOS) + expect(result.content.type).toEqual(TSR.TimelineContentTypeSisyfos.CHANNELS) + expect(result.enable).toEqual({ start: 0 }) + }) + + it('should persist non-VO layers with isPgm 1', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('currentPiece', 10, undefined, true, true) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) + expect(result.content.channels[0].isPgm).toEqual(1) + }) + + it('should persist a VO layer, isPgm is 2', () => { + const sisyfosLayersThatWantsToBePersisted: SisyfosPersistMetaData['sisyfosLayers'] = [ + 'layerThatWantsToBePersisted VO' + ] + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('currentPiece VO', 10, undefined, true, true) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, sisyfosLayersThatWantsToBePersisted) + expect(result.content.channels[0].isPgm).toEqual(2) + }) + + it('should persist only current piece layer when piece wants to persist but dont accept', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('previousPiece', 0, 10, true, true), + createPieceInstance('currentPiece', 10, undefined, true, false) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) + + expect(result.content.channels).toHaveLength(1) + }) + + it('should not persist anything when current piece dont accept and dont want to persist', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('previousPiece', 0, 10, true, true), + createPieceInstance('currentPiece', 10, undefined, false, false) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) + + expect(result.content.channels).toHaveLength(0) + }) + + it('should persist when previous piece does not accept persist, but current does accept', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('previousPiece', 0, 10, true, false), + createPieceInstance('currentPiece', 10, undefined, false, true) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) + + expect(result.content.channels).toHaveLength(1) + }) + + it('should persist when current piece accepts persist and duration is not undefined', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [createPieceInstance('currentPiece', 0, 5, false, true)] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) + + expect(result.content.channels).toHaveLength(1) + }) + + it('should persist all previous layers that wants to be persisted', () => { + const firstLayerThatWantToBePersisted: string = 'firstLayer' + const secondLayerThatWantToBePersisted: string = 'secondLayer' + const thirdLayerThatWantToBePersisted: string = 'thirdLayer' + const layersThatWantToBePersisted: SisyfosPersistMetaData['sisyfosLayers'] = [ + firstLayerThatWantToBePersisted, + secondLayerThatWantToBePersisted, + thirdLayerThatWantToBePersisted + ] + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [createPieceInstance('currentPiece', 0, 5, true, true)] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, layersThatWantToBePersisted) + + expect( + result.content.channels.some(channel => channel.mappedLayer === firstLayerThatWantToBePersisted) + ).toBeTruthy() + expect( + result.content.channels.some(channel => channel.mappedLayer === secondLayerThatWantToBePersisted) + ).toBeTruthy() + expect( + result.content.channels.some(channel => channel.mappedLayer === thirdLayerThatWantToBePersisted) + ).toBeTruthy() + }) + + it('cuts to executeAction that dont accept persist, dont persist layers', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('previousPieceNotExecuteAction', 0, 10, true, true), + createExecuteActionPieceInstance('currentPieceIsExecuteAction', 10, undefined, false, false) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) + + expect(result.content.channels).toHaveLength(0) + }) + + it('cuts to executeAction that accept persist from piece that accept, add persist timelineObject containing all layers that want to be persisted plus previous piece layers', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('previousPieceNotExecuteAction', 0, 10, true, true), + createExecuteActionPieceInstance('currentPieceIsExecuteAction', 10, undefined, false, true) + ] + + 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) + ).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', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('previousPieceNotExecuteAction', 0, 10, true, false), + createExecuteActionPieceInstance('currentPieceIsExecuteAction', 10, undefined, false, true) + ] + + 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() + }) + + it('cuts to executeAction that accept persist from piece that dont want to persist and dont accept persist, dont persist any layers', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('previousPieceNotExecuteAction', 0, 10, false, false), + createExecuteActionPieceInstance('currentPieceIsExecuteAction', 10, undefined, false, true) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) + + expect(result.content.channels).toHaveLength(0) + }) + + it('cuts to executeAction that accept persist from piece that dont want to persist and that accept persist, persist previous layers', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('previousPieceNotExecuteAction', 0, 10, false, true), + createExecuteActionPieceInstance('currentPieceIsExecuteAction', 10, undefined, false, true) + ] + + 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 === LAYER_THAT_WANTS_TO_BE_PERSISTED) + ).toBeTruthy() + }) + + it('cuts from executeAction that dont accept to piece that accepts, dont persist', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createExecuteActionPieceInstance('previousPieceIsExecuteAction', 0, 10, false, false), + createPieceInstance('currentPieceNotExecuteAction', 10, undefined, false, true) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) + + expect(result.content.channels).toHaveLength(0) + }) + + it('cuts from executeAction that dont accept to piece that dont accepts, dont persist layers', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createExecuteActionPieceInstance('previousPieceIsExecuteAction', 0, 10, false, false), + createPieceInstance('currentPieceNotExecuteAction', 10, undefined, false, false) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) + + expect(result.content.channels).toHaveLength(0) + }) + + it('cuts from executeAction that accept to piece that dont accepts, dont persist layers', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createExecuteActionPieceInstance('previousPieceIsExecuteAction', 0, 10, false, true), + createPieceInstance('currentPieceNotExecuteAction', 10, undefined, false, false) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) + + expect(result.content.channels).toHaveLength(0) + }) + + it('cuts from executeAction that accept to piece that accepts, add persist timelineObject with previous layer before executeAction + new layer', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('firstPiece', 0, 5, true, true), + createExecuteActionPieceInstance('previousPieceIsExecuteAction', 5, 5, false, true, { + acceptPersistAudio: true, + sisyfosLayers: [] + }), + createPieceInstance('currentPieceNotExecuteAction', 10, undefined, false, true) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) + + expect(result.content.channels).toHaveLength(2) + }) + + it('cuts from piece that wants to persist to executeAction that do not accept to piece that accepts, do not persist', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('firstPiece', 0, 5, true, true), + createExecuteActionPieceInstance('previousPieceIsExecuteAction', 5, 5, false, true, { + acceptPersistAudio: false, + sisyfosLayers: [] + }), + createPieceInstance('currentPieceNotExecuteAction', 10, undefined, false, true) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) + + expect(result.content.channels).toHaveLength(0) + }) + + it('cuts from piece that wants to persist to executeAction that accepts to another executeAction that accepts, persist layer from first piece', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('firstPiece', 0, 5, true, true), + createExecuteActionPieceInstance('executeAction', 5, undefined, false, true, { + acceptPersistAudio: true, + sisyfosLayers: [], + previousPersistMetaDataForCurrentPiece: { + acceptPersistAudio: true, + sisyfosLayers: [] + } + }) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, []) + + expect(result.content.channels).toHaveLength(1) + 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', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('firstPiece', 0, 5, true, true), + createExecuteActionPieceInstance('executeAction', 5, undefined, false, true, { + acceptPersistAudio: true, + sisyfosLayers: [], + previousPersistMetaDataForCurrentPiece: { + acceptPersistAudio: false, + sisyfosLayers: [] + } + }) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, []) + + expect(result.content.channels).toHaveLength(0) + }) + + it('should not contain any duplicate layers to persist', () => { + const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + createPieceInstance('piece', 0, 5, true, true), + createPieceInstance('piece', 5, undefined, true, true) + ] + + const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, []) + + expect(result.content.channels).toHaveLength(1) + }) + }) +}) + +function createPieceInstance( + name: string, + start: number, + duration: number | undefined, + wantToPersistAudio: boolean, + acceptPersistAudio: boolean, + isExecuteAction?: boolean +): IBlueprintResolvedPieceInstance { + return { + resolvedStart: start, + resolvedDuration: duration, + piece: { + name, + metaData: { + sisyfosPersistMetaData: { + sisyfosLayers: [name], + wantsToPersistAudio: wantToPersistAudio, + acceptPersistAudio, + isExecuteAction + } as SisyfosPersistMetaData + } + } as IBlueprintPieceDB + } as IBlueprintResolvedPieceInstance +} + +function createExecuteActionPieceInstance( + name: string, + start: number, + duration: number | undefined, + wantToPersistAudio: boolean, + acceptPersistAudio: boolean, + previousMetaData?: SisyfosPersistMetaData +): IBlueprintResolvedPieceInstance { + return { + resolvedStart: start, + resolvedDuration: duration, + piece: { + name, + metaData: { + sisyfosPersistMetaData: { + sisyfosLayers: [name], + wantsToPersistAudio: wantToPersistAudio, + acceptPersistAudio, + previousPersistMetaDataForCurrentPiece: previousMetaData + } as SisyfosPersistMetaData + } + } as IBlueprintPieceDB + } as IBlueprintResolvedPieceInstance +} diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 37fbd300f..459ea0bb0 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -42,12 +42,8 @@ import { EvaluateCuesOptions, executeWithContext, FindSourceInfoStrict, - GetCameraMetaData, GetDVETemplate, - GetEksternMetaData, GetFullGrafikTemplateName, - GetLayersForCamera, - GetLayersForEkstern, GetSisyfosTimelineObjForCamera, GetSisyfosTimelineObjForEkstern, GraphicPilot, @@ -56,6 +52,7 @@ import { MakeContentDVE2, PartDefinition, PieceMetaData, + SisyfosPersistMetaData, TimelineBlueprintExt, TV2AdlibAction, TV2BlueprintConfigBase, @@ -151,7 +148,6 @@ export interface ActionExecutionSettings< ClipPending: string Effekt: string StudioMics: string - PersistedLevels: string } Atem: { MEProgram: string @@ -174,7 +170,6 @@ export interface ActionExecutionSettings< } SELECTED_ADLIB_LAYERS: string[] } - ServerAudioLayers: string[] createJingleContent: ( config: ShowStyleConfig, file: string, @@ -543,6 +538,9 @@ function executeActionSelectDVE< mediaPlayerSessions: dveContainsServer(parsedCue.sources) ? [externalId] : [], sources: parsedCue.sources, config: rawTemplate, + sisyfosPersistMetaData: { + sisyfosLayers: [] + }, userData }) @@ -704,9 +702,12 @@ function executeActionSelectDVELayout< return } - const newMetaData = literal({ + const newMetaData = literal({ sources, config: userData.config, + sisyfosPersistMetaData: { + sisyfosLayers: [] + }, userData: literal({ type: AdlibActionType.SELECT_DVE, config: literal({ @@ -754,7 +755,10 @@ function executeActionSelectDVELayout< const newMetaData2 = literal({ ...meta, - config: userData.config + config: userData.config, + sisyfosPersistMetaData: { + sisyfosLayers: [] + } }) const pieceContent = MakeContentDVE2(context, config, userData.config, {}, meta.sources, settings.DVEGeneratorOptions) @@ -1042,7 +1046,12 @@ function executeActionCutToCamera< outputLayerId: SharedOutputLayers.PGM, sourceLayerId: settings.SourceLayers.Cam, lifespan: PieceLifespan.WithinPart, - metaData: GetCameraMetaData(config, GetLayersForCamera(config, sourceInfoCam)), + metaData: { + sisyfosPersistMetaData: literal({ + sisyfosLayers: [], + acceptPersistAudio: sourceInfoCam.acceptPersistAudio + }) + }, tags: [GetTagForKam(userData.name)], content: { timelineObjects: _.compact([ @@ -1061,47 +1070,7 @@ function executeActionCutToCamera< }, classes: ['adlib_deparent'] }), - camSisyfos, - literal({ - id: '', - enable: { - start: 0 - }, - priority: 1, - layer: settings.LLayer.Sisyfos.PersistedLevels, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNELS, - overridePriority: 1, - channels: config.stickyLayers - .filter(layer => camSisyfos.content.channels.map(channel => channel.mappedLayer).indexOf(layer) === -1) - .map(layer => { - return { - mappedLayer: layer, - isPgm: 0 - } - }) - }, - metaData: { - sisyfosPersistLevel: true - } - }), - // Force server to be muted (for adlibbing over DVE) - ...settings.ServerAudioLayers.map(layer => { - return literal({ - id: '', - enable: { - start: 0 - }, - priority: 2, - layer, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: 0 - } - }) - }) + camSisyfos ]) } }) @@ -1121,6 +1090,10 @@ function executeActionCutToCamera< } else if (currentKam) { kamPiece.externalId = currentKam.piece.externalId kamPiece.enable = currentKam.piece.enable + const currentMetaData = currentKam.piece.metaData as PieceMetaData + const metaData = kamPiece.metaData as PieceMetaData + metaData.sisyfosPersistMetaData!.previousPersistMetaDataForCurrentPiece = currentMetaData.sisyfosPersistMetaData + context.updatePieceInstance(currentKam._id, kamPiece) } else { const currentExternalId = context.getPartInstance('current')?.part.externalId @@ -1168,10 +1141,20 @@ function executeActionCutToRemote< }) const eksternSisyfos: TSR.TimelineObjSisyfosAny[] = [ - ...GetSisyfosTimelineObjForEkstern(context, config.sources, `Live ${userData.name}`, GetLayersForEkstern), + ...GetSisyfosTimelineObjForEkstern(context, config.sources, `Live ${userData.name}`), GetSisyfosTimelineObjForCamera(context, config, 'telefon', settings.LLayer.Sisyfos.StudioMics) ] + const sourceInfo = FindSourceInfoStrict(context, config.sources, SourceLayerType.REMOTE, `Live ${userData.name}`) + const sisyfosPersistMetaData: SisyfosPersistMetaData = + sourceInfo !== undefined + ? { + sisyfosLayers: sourceInfo.sisyfosLayers ?? [], + wantsToPersistAudio: sourceInfo.wantsToPersistAudio, + acceptPersistAudio: sourceInfo.acceptPersistAudio + } + : { sisyfosLayers: [] } + const remotePiece = literal({ externalId, name: title, @@ -1182,11 +1165,9 @@ function executeActionCutToRemote< outputLayerId: SharedOutputLayers.PGM, lifespan: PieceLifespan.WithinPart, toBeQueued: true, - metaData: GetEksternMetaData( - config.stickyLayers, - config.studio.StudioMics, - GetLayersForEkstern(context, config.sources, `Live ${userData.name}`) - ), + metaData: { + sisyfosPersistMetaData + }, tags: [GetTagForLive(userData.name)], content: { timelineObjects: _.compact([ @@ -1205,44 +1186,7 @@ function executeActionCutToRemote< }, classes: ['adlib_deparent'] }), - ...eksternSisyfos, - ...config.stickyLayers - .filter(layer => eksternSisyfos.map(obj => obj.layer).indexOf(layer) === -1) - .filter(layer => config.liveAudio.indexOf(layer) === -1) - .map(layer => { - return literal({ - id: '', - enable: { - start: 0 - }, - priority: 1, - layer, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: 0 - }, - metaData: { - sisyfosPersistLevel: true - } - }) - }), - // Force server to be muted (for adlibbing over DVE) - ...settings.ServerAudioLayers.map(layer => { - return literal({ - id: '', - enable: { - start: 0 - }, - priority: 2, - layer, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: 0 - } - }) - }) + ...eksternSisyfos ]) } }) @@ -1303,6 +1247,10 @@ function executeActionCutSourceToBox< const meta: (DVEPieceMetaData & PieceMetaData) | undefined = modifiedPiece?.piece.metaData as PieceMetaData & DVEPieceMetaData + meta.sisyfosPersistMetaData = { + sisyfosLayers: [] + } + if ( !modifiedPiece || !modify || diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index b3ccb9e5c..1c8aa026f 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -1,9 +1,5 @@ import { TableConfigItemValue } from '@tv2media/blueprints-integration' -import { - TableConfigItemDSK, - TableConfigItemSourceMappingWithSisyfos, - TableConfigItemSourceMappingWithSisyfosAndKeepAudio -} from 'tv2-common' +import { TableConfigItemDSK, TableConfigItemSourceMappingWithSisyfos } from 'tv2-common' import { DVEConfigInput } from './helpers' import { SourceInfo } from './sources' @@ -80,8 +76,8 @@ export interface TV2StudioConfigBase { } AtemSettings: {} StudioMics: string[] - SourcesRM: TableConfigItemSourceMappingWithSisyfosAndKeepAudio[] - SourcesFeed: TableConfigItemSourceMappingWithSisyfosAndKeepAudio[] + SourcesRM: TableConfigItemSourceMappingWithSisyfos[] + SourcesFeed: TableConfigItemSourceMappingWithSisyfos[] SourcesSkype: TableConfigItemSourceMappingWithSisyfos[] SourcesCam: TableConfigItemSourceMappingWithSisyfos[] PreventOverlayWithFull?: boolean @@ -115,8 +111,6 @@ export interface TV2StudioBlueprintConfigBase string[], enable?: TSR.Timeline.TimelineEnable ) => TSR.TSRTimelineObj[] GetLayersForEkstern: (context: IStudioUserContext, sources: SourceInfo[], sourceType: string) => string[] @@ -129,8 +127,6 @@ export interface DVEOptions { boxMappings: [string, string, string, string] /** All audio layers */ AUDIO_LAYERS: string[] - /** Layers to exclude from filter */ - EXCLUDED_LAYERS: string[] } export function MakeContentDVEBase< @@ -145,7 +141,7 @@ export function MakeContentDVEBase< dveGeneratorOptions: DVEOptions, addClass?: boolean, adlib?: boolean -): { content: WithTimeline; valid: boolean; stickyLayers: string[] } { +): { content: WithTimeline; valid: boolean } { if (!dveConfig) { context.notifyUserWarning(`DVE ${parsedCue.template} is not configured`) return { @@ -153,8 +149,7 @@ export function MakeContentDVEBase< content: { boxSourceConfiguration: [], timelineObjects: [] - }, - stickyLayers: [] + } } } @@ -195,7 +190,7 @@ export function MakeContentDVE2< adlib?: boolean, videoId?: string, mediaPlayerSessionId?: string -): { content: WithTimeline; valid: boolean; stickyLayers: string[] } { +): { content: WithTimeline; valid: boolean } { let template: DVEConfig try { template = JSON.parse(dveConfig.DVEJSON) as DVEConfig @@ -206,8 +201,7 @@ export function MakeContentDVE2< content: { boxSourceConfiguration: [], timelineObjects: [] - }, - stickyLayers: [] + } } } @@ -374,7 +368,6 @@ export function MakeContentDVE2< context, config.sources, mappingFrom.source, - dveGeneratorOptions.dveTimelineGenerators.GetLayersForEkstern, audioEnable ) ) @@ -457,34 +450,6 @@ export function MakeContentDVE2< frameFile = JoinAssetToFolder(config.studio.DVEFolder, frameFile) } - if (adlib) { - dveTimeline.push( - literal({ - id: '', - enable: getDVEEnable(), - priority: 1, - layer: dveGeneratorOptions.dveLayers.SisyfosLLayer.PersistedLevels, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNELS, - overridePriority: 1, - channels: config.stickyLayers - .filter(layer => dveTimeline.map(obj => obj.layer).indexOf(layer) === -1) - .filter(layer => config.liveAudio.indexOf(layer) === -1) - .map(layer => { - return { - mappedLayer: layer, - isPgm: 0 - } - }) - }, - metaData: { - sisyfosPersistLevel: true - } - }) - ) - } - return { valid, content: literal>({ @@ -606,14 +571,7 @@ export function MakeContentDVE2< ...(server && mediaPlayerSessionId ? [EnableServer(mediaPlayerSessionId)] : []), ...dveTimeline ]) - }), - stickyLayers: [ - ...dveTimeline - .filter(obj => obj.content.deviceType === TSR.DeviceType.SISYFOS) - .filter(obj => dveGeneratorOptions.AUDIO_LAYERS.includes(obj.layer.toString())) - .filter(obj => !dveGeneratorOptions.EXCLUDED_LAYERS.includes(obj.layer.toString())) - .map(obj => obj.layer.toString()) - ] + }) } } diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 9cf1ce449..60db3df6e 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -147,27 +147,6 @@ function GetServerTimeline( }, classes: [] }), - - ...(adLibPix - ? config.stickyLayers.map(layer => { - return literal({ - id: '', - enable: { - while: serverEnableClass - }, - priority: 1, - layer, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: 0 - }, - metaData: { - sisyfosPersistLevel: true - } - }) - }) - : []), ...(voLevels ? [GetSisyfosTimelineObjForCamera(context, config, 'server', sourceLayers.Sisyfos.StudioMicsGroup)] : []), diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index a5b61485b..866233e66 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -16,13 +16,12 @@ import { CueDefinitionEkstern, EksternParentClass, FindSourceInfoStrict, - GetEksternMetaData, - GetLayersForEkstern, GetSisyfosTimelineObjForCamera, GetSisyfosTimelineObjForEkstern, literal, PartDefinition, PartToParentClass, + SisyfosPersistMetaData, TransitionFromString, TransitionSettings, TV2BlueprintConfigBase, @@ -80,8 +79,6 @@ export function EvaluateEksternBase< } const atemInput = sourceInfoEkstern.port - const layers = GetLayersForEkstern(context, config.sources, parsedCue.source) - if (adlib) { adlibPieces.push( literal({ @@ -92,7 +89,13 @@ export function EvaluateEksternBase< sourceLayerId: layersEkstern.SourceLayer.PgmLive, toBeQueued: true, lifespan: PieceLifespan.WithinPart, - metaData: GetEksternMetaData(config.stickyLayers, config.studio.StudioMics, layers), + metaData: { + sisyfosPersistMetaData: literal({ + sisyfosLayers: sourceInfoEkstern.sisyfosLayers ?? [], + wantsToPersistAudio: sourceInfoEkstern.wantsToPersistAudio, + acceptPersistAudio: sourceInfoEkstern.acceptPersistAudio + }) + }, content: literal>({ studioLabel: '', switcherInput: atemInput, @@ -118,7 +121,7 @@ export function EvaluateEksternBase< classes: [ControlClasses.LiveSourceOnAir] }), - ...GetSisyfosTimelineObjForEkstern(context, config.sources, parsedCue.source, GetLayersForEkstern), + ...GetSisyfosTimelineObjForEkstern(context, config.sources, parsedCue.source), GetSisyfosTimelineObjForCamera(context, config, 'telefon', layersEkstern.Sisyfos.StudioMics) ]) }) @@ -136,7 +139,13 @@ export function EvaluateEksternBase< sourceLayerId: layersEkstern.SourceLayer.PgmLive, lifespan: PieceLifespan.WithinPart, toBeQueued: true, - metaData: GetEksternMetaData(config.stickyLayers, config.studio.StudioMics, layers), + metaData: { + sisyfosPersistMetaData: literal({ + sisyfosLayers: sourceInfoEkstern.sisyfosLayers ?? [], + wantsToPersistAudio: sourceInfoEkstern.wantsToPersistAudio, + acceptPersistAudio: sourceInfoEkstern.acceptPersistAudio + }) + }, tags: [GetTagForLive(sourceInfoEkstern.id)], content: literal>({ studioLabel: '', @@ -171,7 +180,7 @@ export function EvaluateEksternBase< : {}) }), - ...GetSisyfosTimelineObjForEkstern(context, config.sources, parsedCue.source, GetLayersForEkstern), + ...GetSisyfosTimelineObjForEkstern(context, config.sources, parsedCue.source), GetSisyfosTimelineObjForCamera(context, config, 'telefon', layersEkstern.Sisyfos.StudioMics) ]) }) diff --git a/src/tv2-common/helpers/sisyfos.ts b/src/tv2-common/helpers/sisyfos.ts index 9ef5ce48b..c0309db32 100644 --- a/src/tv2-common/helpers/sisyfos.ts +++ b/src/tv2-common/helpers/sisyfos.ts @@ -1,74 +1,11 @@ -import * as _ from 'underscore' - -import { IStudioUserContext, SourceLayerType, Timeline, TSR } from '@tv2media/blueprints-integration' -import { - FindSourceInfoStrict, - SisyfosEVSSource, - SourceInfo, - TV2StudioBlueprintConfigBase, - TV2StudioConfigBase -} from 'tv2-common' -import { PieceMetaData } from '../onTimelineGenerate' +import { IBlueprintPiece, IStudioUserContext, SourceLayerType, Timeline, TSR } from '@tv2media/blueprints-integration' +import { FindSourceInfoStrict, PieceMetaData, SisyfosEVSSource, SisyfosPersistMetaData, SourceInfo } from 'tv2-common' import { literal } from '../util' -export function GetStickyForPiece( - layers: Array<{ layer: string; isPgm: 0 | 1 | 2 }>, - STICKY_LAYERS: string[] -): PieceMetaData | undefined { - return literal({ - stickySisyfosLevels: _.object( - layers - .filter(layer => STICKY_LAYERS.indexOf(layer.layer) !== -1) - .map<[string, { value: number; followsPrevious: boolean }]>(layer => { - return [ - layer.layer, - { - value: layer.isPgm, - followsPrevious: false - } - ] - }) - ) - }) -} - -export function GetEksternMetaData( - STICKY_LAYERS: string[], - studioMics: string[], - layers?: string[] -): PieceMetaData | undefined { - return layers && layers.length - ? GetStickyForPiece( - [ - ...layers.map<{ layer: string; isPgm: 0 | 1 | 2 }>(layer => { - return { layer, isPgm: 1 } - }), - ...studioMics.map<{ layer: string; isPgm: 0 | 1 | 2 }>(l => { - return { layer: l, isPgm: 1 } - }) - ], - STICKY_LAYERS - ) - : undefined -} - -export function GetCameraMetaData( - config: TV2StudioBlueprintConfigBase, - layers?: string[] -): PieceMetaData | undefined { - return GetStickyForPiece( - [...(layers || []), ...config.studio.StudioMics].map<{ layer: string; isPgm: 0 | 1 | 2 }>(l => { - return { layer: l, isPgm: 1 } - }), - config.stickyLayers - ) -} - export function GetSisyfosTimelineObjForEkstern( context: IStudioUserContext, sources: SourceInfo[], sourceType: string, - getLayersForEkstern: (context: IStudioUserContext, sources: SourceInfo[], sourceType: string) => string[] | undefined, enable?: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosAny[] { if (!enable) { @@ -76,7 +13,7 @@ export function GetSisyfosTimelineObjForEkstern( } const audioTimeline: TSR.TimelineObjSisyfosAny[] = [] - const layers = getLayersForEkstern(context, sources, sourceType) + const layers = GetLayersForEkstern(context, sources, sourceType) if (!layers || !layers.length) { context.notifyUserWarning(`Could not set audio levels for ${sourceType}`) @@ -165,40 +102,6 @@ export function GetSisyfosTimelineObjForCamera( }) } -export function GetLayersForCamera(config: TV2StudioBlueprintConfigBase, sourceInfo: SourceInfo) { - const cameraLayers: string[] = [] - if (sourceInfo.sisyfosLayers) { - cameraLayers.push(...sourceInfo.sisyfosLayers) - } - if (sourceInfo.useStudioMics) { - cameraLayers.push(...config.studio.StudioMics) - } - return cameraLayers -} - -export function getStickyLayers(studioConfig: TV2StudioConfigBase, liveAudioLayers: string[]) { - return [...studioConfig.StudioMics, ...liveAudioLayers] -} - -export function getLiveAudioLayers(studioConfig: TV2StudioConfigBase): string[] { - const res = new Set() - for (const src of studioConfig.SourcesRM) { - if (src.SisyfosLayers && src.KeepAudioInStudio) { - for (const layer of src.SisyfosLayers) { - res.add(layer) - } - } - } - for (const src of studioConfig.SourcesSkype) { - if (src.SisyfosLayers) { - for (const layer of src.SisyfosLayers) { - res.add(layer) - } - } - } - return Array.from(res) -} - export function GetSisyfosTimelineObjForEVS(sourceInfo: SourceInfo, vo: boolean) { return literal({ id: '', @@ -214,3 +117,16 @@ export function GetSisyfosTimelineObjForEVS(sourceInfo: SourceInfo, vo: boolean) } }) } + +export function MapSisyfosPersistMetaDataToPieces(pieces: IBlueprintPiece[]) { + return pieces.map(piece => { + const metaData = piece.metaData as PieceMetaData + piece.metaData = { + ...metaData, + sisyfosPersistMetaData: literal({ + sisyfosLayers: [] + }) + } + return piece + }) +} diff --git a/src/tv2-common/migrations/sourceManifest.ts b/src/tv2-common/migrations/sourceManifest.ts index 3871bc4ad..009611bb6 100644 --- a/src/tv2-common/migrations/sourceManifest.ts +++ b/src/tv2-common/migrations/sourceManifest.ts @@ -4,7 +4,8 @@ import { literal } from '../util' export function MakeConfigForSources( name: string, displayName: string, - withKeepAudio: boolean, + wantsToPersistAudio: boolean, + acceptPersistAudio: boolean, defaultVal: ConfigManifestEntryTable['defaultVal'] ): ConfigManifestEntryTable { return literal({ @@ -55,18 +56,33 @@ export function MakeConfigForSources( defaultVal: true, rank: 3 }, - ...(withKeepAudio + ...(wantsToPersistAudio ? [ literal({ - id: 'KeepAudioInStudio', - name: 'Keep audio in Studio', - description: 'Keep audio in Studio', + id: 'WantsToPersistAudio', + name: 'Wants to persist audio in Studio', + description: + 'Tells the system that it wants to persist the audio. If the next piece accepts persistence, the audio will be persisted', type: ConfigManifestEntryType.BOOLEAN, required: true, - defaultVal: true, + defaultVal: false, rank: 4 }) ] + : []), + ...(acceptPersistAudio + ? [ + literal({ + id: 'AcceptPersistAudio', + name: 'Accept Persist Audio', + description: + 'Accept the persistence of audio from the previous piece if that piece wants to persist audio', + type: ConfigManifestEntryType.BOOLEAN, + required: false, + defaultVal: false, + rank: 5 + }) + ] : []) ] }) diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index 05bc864c7..2d065753f 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -1,6 +1,7 @@ import { BlueprintResultTimeline, GraphicsContent, + IBlueprintPartInstance, IBlueprintResolvedPieceInstance, IRundownContext, IShowStyleContext, @@ -11,16 +12,15 @@ import { TimelinePersistentState, TSR } from '@tv2media/blueprints-integration' -import { CasparPlayerClip } from 'tv2-common' +import { CasparPlayerClip, literal } from 'tv2-common' import { AbstractLLayer, TallyTags } from 'tv2-constants' import * as _ from 'underscore' import { SisyfosLLAyer } from '../tv2_afvd_studio/layers' -import { OfftubeSisyfosLLayer } from '../tv2_offtube_studio/layers' // TODO: REMOVE import { TV2BlueprintConfigBase, TV2StudioConfigBase } from './blueprintConfig' import { ABSourceLayers, assignMediaPlayers } from './helpers' export interface PartEndStateExt { - stickySisyfosLevels: { [key: string]: 0 | 1 | 2 | undefined } + sisyfosPersistMetaData: SisyfosPersistMetaData mediaPlayerSessions: { [layer: string]: string[] } isJingle?: boolean fullFileName?: string @@ -40,7 +40,6 @@ export interface TimelineBlueprintExt extends TimelineObjectCoreExt { /** Metadata for use by the OnTimelineGenerate or other callbacks */ metaData?: { context?: string - sisyfosPersistLevel?: boolean mediaPlayerSession?: string dveAdlibEnabler?: string // Used to restore the original while rule after lookahead templateData?: any @@ -54,12 +53,19 @@ export interface PieceMetaData { isMix?: boolean isJingle?: boolean } - stickySisyfosLevels?: { [key: string]: { value: number; followsPrevious: boolean } } + sisyfosPersistMetaData?: SisyfosPersistMetaData mediaPlayerSessions?: string[] mediaPlayerOptional?: boolean modifiedByAction?: boolean } +export interface SisyfosPersistMetaData { + sisyfosLayers: string[] + wantsToPersistAudio?: boolean + acceptPersistAudio?: boolean + previousPersistMetaDataForCurrentPiece?: SisyfosPersistMetaData +} + export interface PartMetaData { segmentExternalId: string /** If set, part has been modified by an action */ @@ -81,19 +87,18 @@ export function onTimelineGenerate< _atemLayerNext: string ): Promise { const previousPartEndState2 = previousPartEndState as PartEndStateExt | undefined + const persistentState: TimelinePersistentStateExt = { + activeMediaPlayers: {} + } const config = getConfig(context) - copyPreviousSisyfosLevels( - context, - timeline, - previousPartEndState2 ? previousPartEndState2.stickySisyfosLevels : {}, - resolvedPieces + const sisyfosPersistedLevelsTimelineObject = createSisyfosPersistedLevelsTimelineObject( + resolvedPieces, + previousPartEndState2 ? previousPartEndState2.sisyfosPersistMetaData.sisyfosLayers : [] ) + timeline.push(sisyfosPersistedLevelsTimelineObject) - const persistentState: TimelinePersistentStateExt = { - activeMediaPlayers: {} - } const previousPersistentState2 = previousPersistentState as TimelinePersistentStateExt | undefined timeline = processServerLookaheads(context, timeline, resolvedPieces, sourceLayers) @@ -184,16 +189,19 @@ function processServerLookaheads( export function getEndStateForPart( _context: IRundownContext, _previousPersistentState: TimelinePersistentState | undefined, - previousPartEndState: PartEndState | undefined, + previousPartInstance: IBlueprintPartInstance | undefined, resolvedPieces: IBlueprintResolvedPieceInstance[], time: number ): PartEndState { const endState: PartEndStateExt = { - stickySisyfosLevels: {}, + sisyfosPersistMetaData: { + sisyfosLayers: [] + }, mediaPlayerSessions: {} } - - const previousPartEndState2 = previousPartEndState as Partial | undefined + const previousPartEndState = !!previousPartInstance + ? (previousPartInstance.previousPartEndState as Partial) + : undefined const activePieces = resolvedPieces.filter( p => @@ -203,9 +211,12 @@ export function getEndStateForPart( (!p.piece.enable.duration || p.piece.enable.start + (p.piece.enable.duration as number) >= time) ) - for (const piece of activePieces) { - preservePieceSisfosLevel(endState, previousPartEndState2, piece) - } + endState.sisyfosPersistMetaData.sisyfosLayers = findLayersToPersist( + activePieces, + previousPartEndState && previousPartEndState.sisyfosPersistMetaData + ? previousPartEndState.sisyfosPersistMetaData.sisyfosLayers + : [] + ) for (const piece of activePieces) { if (piece.piece.metaData) { @@ -250,125 +261,78 @@ function dveBoxLookaheadUseOriginalEnable(timeline: OnGenerateTimelineObj[]) { } } -export function preservePieceSisfosLevel( - endState: PartEndStateExt, - previousPartEndState: Partial | undefined, - piece: IBlueprintResolvedPieceInstance -) { - const metaData = piece.piece.metaData as PieceMetaData | undefined - if (metaData) { - // Loop through rm level persistance - if (metaData.stickySisyfosLevels) { - for (const key of Object.keys(metaData.stickySisyfosLevels)) { - const values = metaData.stickySisyfosLevels[key] - - // Follow the previous state, if specified, or start with this exposed value - endState.stickySisyfosLevels[key] = - values.followsPrevious && - previousPartEndState && - previousPartEndState.stickySisyfosLevels && - previousPartEndState.stickySisyfosLevels[key] - ? previousPartEndState.stickySisyfosLevels[key] - : (values.value as 0 | 1 | 2 | undefined) - } +export function createSisyfosPersistedLevelsTimelineObject( + resolvedPieces: IBlueprintResolvedPieceInstance[], + previousSisyfosLayersThatWantsToBePersisted: SisyfosPersistMetaData['sisyfosLayers'] +): TSR.TimelineObjSisyfosChannels { + const layersToPersist = findLayersToPersist(resolvedPieces, previousSisyfosLayersThatWantsToBePersisted) + return literal({ + id: 'sisyfosPersistenceObject', + enable: { + start: 0 + }, + layer: SisyfosLLAyer.SisyfosPersistedLevels, + content: { + deviceType: TSR.DeviceType.SISYFOS, + type: TSR.TimelineContentTypeSisyfos.CHANNELS, + overridePriority: 1, + channels: layersToPersist.map(layer => { + return { + mappedLayer: layer, + isPgm: layer.includes('VO') ? 2 : 1 + } + }) } - } -} - -function isSisyfosPersistObject(obj: TSR.TimelineObjSisyfosChannels & TimelineBlueprintExt) { - return ( - (obj.layer === OfftubeSisyfosLLayer.SisyfosPersistedLevels || obj.layer === SisyfosLLAyer.SisyfosPersistedLevels) && - obj.content.deviceType === TSR.DeviceType.SISYFOS && - obj.content.type === TSR.TimelineContentTypeSisyfos.CHANNELS && - obj.metaData?.sisyfosPersistLevel && - !obj.id.match(/previous/i) && - !obj.id.match(/future/) - ) + }) } -export function copyPreviousSisyfosLevels( - _context: IRundownContext, - timelineObjs: OnGenerateTimelineObj[], - previousLevels: PartEndStateExt['stickySisyfosLevels'], - resolvedPieces: IBlueprintResolvedPieceInstance[] -) { - const objectsLookingToPersistLevels: Array = (timelineObjs as Array< - TSR.TimelineObjSisyfosChannels & TimelineBlueprintExt & OnGenerateTimelineObj - >).filter(isSisyfosPersistObject) - - // This needs to look at previous pieces within the part, to make it work for adlibs - // Pieces should be ordered, we shall assume that - const groupedPieces = _.groupBy(resolvedPieces, p => p.resolvedStart) - const sisyfosObjectsByPiece = _.groupBy(objectsLookingToPersistLevels, o => o.pieceInstanceId) - - for (const k of Object.keys(groupedPieces)) { - const pieces = groupedPieces[k] - const pieceIds = _.pluck(pieces, '_id') // getPieceGroupId(p._id)) - // Find all the objs that start here - const objs = _.flatten(Object.values(_.pick(sisyfosObjectsByPiece, pieceIds))) - // Stop if no objects - if (objs.length === 0) { - continue - } - - // Find the active pieces before this time - const time = pieces[0].resolvedStart - - // Start of part - if (time !== 0) { - // Calculate the previous 'state' - const activePieces = resolvedPieces.filter(p => { - const start = p.resolvedStart // Core should be always setting this to a number - const duration = p.resolvedDuration +function findLayersToPersist(pieces: IBlueprintResolvedPieceInstance[], sisyfosLayersThatWantsToBePersisted: string[]) { + const sortedPieces = pieces + .filter(piece => { + const metaData = piece.piece.metaData as PieceMetaData + return !(!metaData || !metaData.sisyfosPersistMetaData) + }) + .sort((a, b) => b.resolvedStart - a.resolvedStart) - // Piece must start before target, and end at or after target starts - return start < time && (duration === undefined || start + duration >= time) - }) + if (sortedPieces.length === 0) { + return [] + } - const newPreviousLevels: PartEndStateExt['stickySisyfosLevels'] = {} - for (const piece of activePieces) { - const metadata = piece.piece.metaData as PieceMetaData | undefined - if (metadata && metadata.stickySisyfosLevels) { - for (const id of Object.keys(metadata.stickySisyfosLevels)) { - // context.notifyUserWarning( - // `New level from ${piece._id} for ${id} of ${JSON.stringify(val)} (last was ${previousLevels[id]})` - // ) - if (newPreviousLevels[id]) { - // context.notifyUserWarning('duplicate level, going with the first!' + id) - } else { - const val = metadata.stickySisyfosLevels[id] - newPreviousLevels[id] = - val.followsPrevious && previousLevels[id] !== undefined - ? previousLevels[id] - : (val.value as 0 | 1 | 2 | undefined) - } - } - } - } + const firstPieceMetaData = sortedPieces[0].piece.metaData as PieceMetaData + if (!firstPieceMetaData.sisyfosPersistMetaData!.acceptPersistAudio) { + return firstPieceMetaData.sisyfosPersistMetaData!.wantsToPersistAudio + ? firstPieceMetaData.sisyfosPersistMetaData!.sisyfosLayers + : [] + } - // Apply newly calculated levels - previousLevels = newPreviousLevels + const layersToPersist: string[] = [] + for (let i = 0; i < sortedPieces.length; i++) { + const pieceMetaData = sortedPieces[i].piece.metaData as PieceMetaData + const sisyfosPersistMetaData: SisyfosPersistMetaData = pieceMetaData!.sisyfosPersistMetaData! + if (sisyfosPersistMetaData.wantsToPersistAudio) { + layersToPersist.push(...sisyfosPersistMetaData.sisyfosLayers) } - const allChannels = [] - // Apply newly calculated levels - for (const sisyfosObj of objs) { - const contentObj = sisyfosObj.content - for (const channel of contentObj.channels) { - const previousVal = previousLevels[channel.mappedLayer] - if (previousVal !== undefined) { - channel.isPgm = previousVal - allChannels.push(channel) - } - } + if (doesMetaDataNotAcceptPersistAudioDeep(sisyfosPersistMetaData)) { + break } - // Apply all persisted levels to all objects in case there's more than one object - for (const sisyfosObj of objs) { - sisyfosObj.content.channels = allChannels + + if (i === sortedPieces.length - 1) { + layersToPersist.push(...sisyfosLayersThatWantsToBePersisted) } } + + return Array.from(new Set(layersToPersist)) +} + +function doesMetaDataNotAcceptPersistAudioDeep(metaData: SisyfosPersistMetaData): boolean { + if (!metaData.acceptPersistAudio) { + return true + } + if (!!metaData.previousPersistMetaDataForCurrentPiece) { + return doesMetaDataNotAcceptPersistAudioDeep(metaData.previousPersistMetaDataForCurrentPiece) + } + return false } export function disablePilotWipeAfterJingle( diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index fa57be34a..5688e9ca3 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -13,7 +13,8 @@ import { GetTagForServerNext, MakeContentServer, MakeContentServerSourceLayers, - PieceMetaData + PieceMetaData, + SisyfosPersistMetaData } from 'tv2-common' import { AdlibActionType, PartType, SharedOutputLayers, TallyTags } from 'tv2-constants' import { ActionSelectServerClip } from '../actions' @@ -264,7 +265,11 @@ function getServerSelectionBlueprintPiece< lifespan: PieceLifespan.OutOnSegmentEnd, metaData: literal({ mediaPlayerSessions: [mediaPlayerSession], - userData: userDataElement + userData: userDataElement, + sisyfosPersistMetaData: literal({ + sisyfosLayers: [], + acceptPersistAudio: props.adLibPix && props.voLayer + }) }), content: contentServerElement, tags: [GetTagForServerNext(partDefinition.segmentExternalId, file, props.voLayer)] diff --git a/src/tv2-common/sources.ts b/src/tv2-common/sources.ts index d09654572..b6881a20f 100644 --- a/src/tv2-common/sources.ts +++ b/src/tv2-common/sources.ts @@ -56,7 +56,9 @@ export function ParseMappingTable( id: `${idPrefix || ''}${conf.SourceName}`, port: conf.AtemSource, sisyfosLayers: conf.SisyfosLayers, - useStudioMics: conf.StudioMics + useStudioMics: conf.StudioMics, + wantsToPersistAudio: conf.WantsToPersistAudio, + acceptPersistAudio: conf.AcceptPersistAudio })) } @@ -75,6 +77,8 @@ export interface SourceInfo { ptzDevice?: string sisyfosLayers?: string[] useStudioMics?: boolean + wantsToPersistAudio?: boolean + acceptPersistAudio?: boolean } export function FindSourceInfo(sources: SourceInfo[], type: SourceInfoType, id: string): SourceInfo | undefined { diff --git a/src/tv2-common/types/config.ts b/src/tv2-common/types/config.ts index 86fba44a4..65d66b271 100644 --- a/src/tv2-common/types/config.ts +++ b/src/tv2-common/types/config.ts @@ -8,12 +8,10 @@ export interface TableConfigItemSourceMapping { export type TableConfigItemSourceMappingWithSisyfos = { SisyfosLayers: string[] StudioMics: boolean + WantsToPersistAudio?: boolean + AcceptPersistAudio?: boolean } & TableConfigItemSourceMapping -export type TableConfigItemSourceMappingWithSisyfosAndKeepAudio = { - KeepAudioInStudio: boolean -} & TableConfigItemSourceMappingWithSisyfos - export interface TableConfigItemDSK { /** 0-based */ Number: number diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index c9f2f775a..2d3590a40 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -24,13 +24,13 @@ function prepareConfig( conf: string, configName: string, studioMics: boolean, - keepAudioInStudio?: boolean + wantsToPersistAudio?: boolean ): Array<{ SourceName: string AtemSource: number SisyfosLayers: string[] StudioMics: boolean - KeepAudioInStudio: boolean + wantsToPersistAudio: boolean }> { return parseMapStr(undefined, conf, true).map(c => { return { @@ -38,7 +38,7 @@ function prepareConfig( AtemSource: c.val, SisyfosLayers: getSisyfosLayers(configName, c.id), StudioMics: studioMics, - KeepAudioInStudio: keepAudioInStudio ?? false + wantsToPersistAudio: wantsToPersistAudio ?? false } }) } diff --git a/src/tv2_afvd_showstyle/actions.ts b/src/tv2_afvd_showstyle/actions.ts index 6d3b78d25..2c13c4ae5 100644 --- a/src/tv2_afvd_showstyle/actions.ts +++ b/src/tv2_afvd_showstyle/actions.ts @@ -38,8 +38,7 @@ export function executeActionAFVD(context: IActionExecutionContext, actionId: st Sisyfos: { ClipPending: SisyfosLLAyer.SisyfosSourceClipPending, Effekt: SisyfosLLAyer.SisyfosSourceJingle, - StudioMics: SisyfosLLAyer.SisyfosGroupStudioMics, - PersistedLevels: SisyfosLLAyer.SisyfosPersistedLevels + StudioMics: SisyfosLLAyer.SisyfosGroupStudioMics }, Atem: { MEProgram: AtemLLayer.AtemMEProgram, @@ -59,11 +58,6 @@ export function executeActionAFVD(context: IActionExecutionContext, actionId: st }, SELECTED_ADLIB_LAYERS: [SourceLayer.SelectedServer, SourceLayer.SelectedVoiceOver] }, - ServerAudioLayers: [ - SisyfosLLAyer.SisyfosSourceClipPending, - SisyfosLLAyer.SisyfosSourceServerA, - SisyfosLLAyer.SisyfosSourceServerB - ], createJingleContent: createJingleContentAFVD, pilotGraphicSettings: pilotGeneratorSettingsAFVD }, diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index efec04f82..444cff96f 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -29,15 +29,14 @@ import { CreateGraphicBaseline, CreateLYDBaseline, FindDSKJingle, - GetEksternMetaData, - GetLayersForEkstern, GetSisyfosTimelineObjForCamera, GetSisyfosTimelineObjForEkstern, GetTransitionAdLibActions, literal, + PieceMetaData, + SisyfosPersistMetaData, SourceInfo, - t, - TimelineBlueprintExt + t } from 'tv2-common' import { AdlibActionType, @@ -101,7 +100,12 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint expectedDuration: 0, lifespan: PieceLifespan.WithinPart, toBeQueued: true, - metaData: GetEksternMetaData(config.stickyLayers, config.studio.StudioMics, info.sisyfosLayers), + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: info.sisyfosLayers ?? [], + acceptPersistAudio: vo + } + }), tags: [AdlibTags.ADLIB_QUEUE_NEXT, vo ? AdlibTags.ADLIB_VO_AUDIO_LEVEL : AdlibTags.ADLIB_FULL_AUDIO_LEVEL], content: { ignoreMediaObjectStatus: true, @@ -134,35 +138,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint } }) }), - ...(vo - ? [ - literal({ - id: '', - enable: { - start: 1 - }, - priority: 1, - layer: SisyfosLLAyer.SisyfosPersistedLevels, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNELS, - overridePriority: 1, - channels: config.stickyLayers.map( - layer => { - return { - mappedLayer: layer, - isPgm: 0 - } - } - ) - }, - metaData: { - sisyfosPersistLevel: true - } - }), - GetSisyfosTimelineObjForCamera(context, config, 'evs', SisyfosLLAyer.SisyfosGroupStudioMics) - ] - : []) + ...(vo ? [GetSisyfosTimelineObjForCamera(context, config, 'evs', SisyfosLLAyer.SisyfosGroupStudioMics)] : []) ]) } }) @@ -173,7 +149,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint function makeRemoteAdLibs(info: SourceInfo, rank: number): IBlueprintAdLibPiece[] { const res: IBlueprintAdLibPiece[] = [] const eksternSisyfos = [ - ...GetSisyfosTimelineObjForEkstern(context, config.sources, `Live ${info.id}`, GetLayersForEkstern), + ...GetSisyfosTimelineObjForEkstern(context, config.sources, `Live ${info.id}`), GetSisyfosTimelineObjForCamera(context, config, 'telefon', SisyfosLLAyer.SisyfosGroupStudioMics) ] res.push({ @@ -185,11 +161,13 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint expectedDuration: 0, lifespan: PieceLifespan.WithinPart, toBeQueued: true, - metaData: GetEksternMetaData( - config.stickyLayers, - config.studio.StudioMics, - GetLayersForEkstern(context, config.sources, `Live ${info.id}`) - ), + metaData: { + sisyfosPersistMetaData: literal({ + sisyfosLayers: info.sisyfosLayers ?? [], + wantsToPersistAudio: info.wantsToPersistAudio, + acceptPersistAudio: info.acceptPersistAudio + }) + }, tags: [AdlibTags.ADLIB_QUEUE_NEXT], content: { timelineObjects: _.compact([ @@ -208,52 +186,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint }, classes: ['adlib_deparent'] }), - ...eksternSisyfos, - literal({ - id: '', - enable: { - start: 0 - }, - priority: 1, - layer: SisyfosLLAyer.SisyfosPersistedLevels, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNELS, - overridePriority: 1, - channels: config.stickyLayers - .filter(layer => eksternSisyfos.map(obj => obj.layer).indexOf(layer) === -1) - .filter(layer => config.liveAudio.indexOf(layer) === -1) - .map(layer => { - return literal({ - mappedLayer: layer, - isPgm: 0 - }) - }) - }, - metaData: { - sisyfosPersistLevel: true - } - }), - // Force server to be muted (for adlibbing over DVE) - ...[ - SisyfosLLAyer.SisyfosSourceClipPending, - SisyfosLLAyer.SisyfosSourceServerA, - SisyfosLLAyer.SisyfosSourceServerB - ].map(layer => { - return literal({ - id: '', - enable: { - start: 0 - }, - priority: 2, - layer, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: 0 - } - }) - }) + ...eksternSisyfos ]) } }) @@ -272,11 +205,13 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint outputLayerId: SharedOutputLayers.AUX, expectedDuration: 0, lifespan: PieceLifespan.OutOnShowStyleEnd, - metaData: GetEksternMetaData( - config.stickyLayers, - config.studio.StudioMics, - GetLayersForEkstern(context, config.sources, `Live ${info.id}`) - ), + metaData: { + sisyfosPersistMetaData: literal({ + sisyfosLayers: info.sisyfosLayers ?? [], + wantsToPersistAudio: info.wantsToPersistAudio, + acceptPersistAudio: info.acceptPersistAudio + }) + }, tags: [AdlibTags.ADLIB_TO_STUDIO_SCREEN_AUX], content: { timelineObjects: _.compact([ diff --git a/src/tv2_afvd_showstyle/helpers/content/dve.ts b/src/tv2_afvd_showstyle/helpers/content/dve.ts index 4db7f0f0e..9d7e91023 100644 --- a/src/tv2_afvd_showstyle/helpers/content/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/content/dve.ts @@ -8,14 +8,11 @@ import { MakeContentDVEBase, PartDefinition } from 'tv2-common' -import * as _ from 'underscore' import { BlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' export const NUMBER_OF_DVE_BOXES = 4 -export const boxMappings = [AtemLLayer.AtemSSrcBox1, AtemLLayer.AtemSSrcBox2, AtemLLayer.AtemSSrcBox3] - export const AFVD_DVE_GENERATOR_OPTIONS: DVEOptions = { dveLayers: { ATEM: { @@ -29,8 +26,7 @@ export const AFVD_DVE_GENERATOR_OPTIONS: DVEOptions = { }, SisyfosLLayer: { ClipPending: SisyfosLLAyer.SisyfosSourceClipPending, - StudioMics: SisyfosLLAyer.SisyfosGroupStudioMics, - PersistedLevels: SisyfosLLAyer.SisyfosPersistedLevels + StudioMics: SisyfosLLAyer.SisyfosGroupStudioMics }, CasparLLayer: { ClipPending: CasparLLayer.CasparPlayerClipPending @@ -41,12 +37,7 @@ export const AFVD_DVE_GENERATOR_OPTIONS: DVEOptions = { GetLayersForEkstern }, boxMappings: [AtemLLayer.AtemSSrcBox1, AtemLLayer.AtemSSrcBox2, AtemLLayer.AtemSSrcBox3, AtemLLayer.AtemSSrcBox4], - AUDIO_LAYERS: Object.keys(SisyfosLLAyer), - EXCLUDED_LAYERS: [ - SisyfosLLAyer.SisyfosSourceClipPending, - SisyfosLLAyer.SisyfosSourceServerA, - SisyfosLLAyer.SisyfosSourceServerB - ] + AUDIO_LAYERS: Object.keys(SisyfosLLAyer) } export function MakeContentDVE( @@ -57,7 +48,7 @@ export function MakeContentDVE( dveConfig: DVEConfigInput | undefined, addClass?: boolean, adlib?: boolean -): { content: WithTimeline; valid: boolean; stickyLayers: string[] } { +): { content: WithTimeline; valid: boolean } { return MakeContentDVEBase( context, config, 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 233a26f05..778732fcb 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts @@ -54,8 +54,6 @@ describe('lyd', () => { studio: (defaultStudioConfig as unknown) as StudioConfig, sources: [], mediaPlayers: [], - stickyLayers: [], - liveAudio: [], dsk: defaultDSKConfig }, pieces, @@ -101,8 +99,6 @@ describe('lyd', () => { studio: (defaultStudioConfig as unknown) as StudioConfig, sources: [], mediaPlayers: [], - stickyLayers: [], - liveAudio: [], dsk: defaultDSKConfig }, pieces, @@ -151,8 +147,6 @@ describe('lyd', () => { studio: (defaultStudioConfig as unknown) as StudioConfig, sources: [], mediaPlayers: [], - stickyLayers: [], - liveAudio: [], dsk: defaultDSKConfig }, pieces, 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 7e07edbad..02fb57f96 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -85,8 +85,6 @@ describe('telefon', () => { studio: (defaultStudioConfig as unknown) as StudioConfig, sources: [], mediaPlayers: [], - stickyLayers: [], - liveAudio: [], dsk: defaultDSKConfig }, mockContext, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts index df1163578..0d8584b50 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts @@ -106,18 +106,6 @@ export function EvaluateAdLib( const content = MakeContentDVE(context, config, partDefinition, cueDVE, rawTemplate, false, true) - let sticky: { [key: string]: { value: number; followsPrevious: boolean } } = {} - - content.stickyLayers.forEach(layer => { - sticky = { - ...sticky, - [layer]: { - value: 1, - followsPrevious: false - } - } - }) - adLibPieces.push( literal({ _rank: rank, @@ -131,7 +119,6 @@ export function EvaluateAdLib( invalid: !content.valid, lifespan: PieceLifespan.WithinPart, metaData: literal({ - stickySisyfosLevels: sticky, sources: cueDVE.sources, config: rawTemplate, userData: literal({ @@ -139,7 +126,10 @@ export function EvaluateAdLib( config: cueDVE, videoId: partDefinition.fields.videoId, segmentExternalId: partDefinition.segmentExternalId - }) + }), + sisyfosPersistMetaData: { + sisyfosLayers: [] + } }), tags: [AdlibTags.ADLIB_FLOW_PRODUCER] }) diff --git a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts index d165e30b4..b715106cb 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts @@ -74,7 +74,7 @@ export function EvaluateDVE( toBeQueued: true, content: content.content, adlibPreroll: Number(config.studio.CasparPrerollDuration) || 0, - metaData: literal({ + metaData: literal({ sources: parsedCue.sources, config: rawTemplate, userData: literal({ @@ -82,7 +82,10 @@ export function EvaluateDVE( config: parsedCue, videoId: partDefinition.fields.videoId, segmentExternalId: partDefinition.segmentExternalId - }) + }), + sisyfosPersistMetaData: { + sisyfosLayers: [] + } }) }) ) @@ -113,7 +116,10 @@ export function EvaluateDVE( config: parsedCue, videoId: partDefinition.fields.videoId, segmentExternalId: partDefinition.segmentExternalId - }) + }), + sisyfosPersistMetaData: { + sisyfosLayers: [] + } }) }) ) diff --git a/src/tv2_afvd_showstyle/helpers/sisyfos/__tests__/sisyfos.spec.ts b/src/tv2_afvd_showstyle/helpers/sisyfos/__tests__/sisyfos.spec.ts deleted file mode 100644 index 30d90ab45..000000000 --- a/src/tv2_afvd_showstyle/helpers/sisyfos/__tests__/sisyfos.spec.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { GetStickyForPiece, literal, PieceMetaData } from 'tv2-common' -import { SisyfosLLAyer } from '../../../../tv2_afvd_studio/layers' - -export const STUDIO_MICS = [ - SisyfosLLAyer.SisyfosSourceHost_1_ST_A, - SisyfosLLAyer.SisyfosSourceHost_2_ST_A, - SisyfosLLAyer.SisyfosSourceGuest_1_ST_A, - SisyfosLLAyer.SisyfosSourceGuest_2_ST_A, - SisyfosLLAyer.SisyfosSourceGuest_3_ST_A, - SisyfosLLAyer.SisyfosSourceGuest_4_ST_A -] - -export const LIVE_AUDIO = [ - SisyfosLLAyer.SisyfosSourceLive_1, - SisyfosLLAyer.SisyfosSourceLive_2, - SisyfosLLAyer.SisyfosSourceLive_3, - SisyfosLLAyer.SisyfosSourceLive_4, - SisyfosLLAyer.SisyfosSourceLive_5, - SisyfosLLAyer.SisyfosSourceLive_6, - SisyfosLLAyer.SisyfosSourceLive_7, - SisyfosLLAyer.SisyfosSourceLive_8, - SisyfosLLAyer.SisyfosSourceLive_9, - SisyfosLLAyer.SisyfosSourceLive_10 -] - -export const STICKY_LAYERS = [...STUDIO_MICS, ...LIVE_AUDIO] - -describe('sisyfos', () => { - test('GetStickyForPiece', () => { - const result = GetStickyForPiece( - STUDIO_MICS.map<{ layer: SisyfosLLAyer; isPgm: 0 | 1 | 2 }>(layer => { - return { - layer, - isPgm: 1 - } - }), - STICKY_LAYERS - ) - expect(result).toEqual( - literal({ - stickySisyfosLevels: { - sisyfos_source_Host_1_st_a: { - value: 1, - followsPrevious: false - }, - sisyfos_source_Host_2_st_a: { - value: 1, - followsPrevious: false - }, - sisyfos_source_Guest_1_st_a: { - value: 1, - followsPrevious: false - }, - sisyfos_source_Guest_2_st_a: { - value: 1, - followsPrevious: false - }, - sisyfos_source_Guest_3_st_a: { - value: 1, - followsPrevious: false - }, - sisyfos_source_Guest_4_st_a: { - value: 1, - followsPrevious: false - } - } - }) - ) - }) -}) diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index 51b5f9054..743ca7d4b 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -21,6 +21,7 @@ import { literal, PartDefinitionEVS, PartTime, + PieceMetaData, SourceInfo, TransitionFromString, TransitionSettings @@ -73,6 +74,11 @@ export function CreatePartEVS( outputLayerId: SharedOutputLayers.PGM, sourceLayerId: SourceLayer.PgmLocal, lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), content: makeContentEVS(context, config, atemInput, partDefinition, sourceInfoDelayedPlayback) }) ) diff --git a/src/tv2_afvd_showstyle/parts/grafik.ts b/src/tv2_afvd_showstyle/parts/grafik.ts index da9b6040f..2d3769086 100644 --- a/src/tv2_afvd_showstyle/parts/grafik.ts +++ b/src/tv2_afvd_showstyle/parts/grafik.ts @@ -12,6 +12,7 @@ import { ApplyFullGraphicPropertiesToPart, GraphicIsPilot, literal, + MapSisyfosPersistMetaDataToPieces, PartDefinition, PartTime } from 'tv2-common' @@ -34,7 +35,7 @@ export function CreatePartGrafik( }) const adLibPieces: IBlueprintAdLibPiece[] = [] - const pieces: IBlueprintPiece[] = [] + let pieces: IBlueprintPiece[] = [] const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] @@ -64,6 +65,8 @@ export function CreatePartGrafik( part.invalid = true } + pieces = MapSisyfosPersistMetaDataToPieces(pieces) + return { part, adLibPieces, diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index 69244dcc4..889d6aac3 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -20,11 +20,10 @@ import { CreatePartKamBase, FindDSKJingle, FindSourceInfoStrict, - GetCameraMetaData, - GetLayersForCamera, GetSisyfosTimelineObjForCamera, literal, PartDefinitionKam, + PieceMetaData, TimeFromINewsField, TransitionFromString, TransitionSettings @@ -63,6 +62,11 @@ export function CreatePartKam( outputLayerId: SharedOutputLayers.PGM, sourceLayerId: SourceLayer.PgmJingle, lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), content: literal>({ ignoreMediaObjectStatus: true, fileName: '', @@ -110,7 +114,12 @@ export function CreatePartKam( outputLayerId: SharedOutputLayers.PGM, sourceLayerId: SourceLayer.PgmCam, lifespan: PieceLifespan.WithinPart, - metaData: GetCameraMetaData(config, GetLayersForCamera(config, sourceInfoCam)), + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: sourceInfoCam.sisyfosLayers ?? [], + acceptPersistAudio: sourceInfoCam.acceptPersistAudio + } + }), content: { studioLabel: '', switcherInput: atemInput, diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index 5d7beeb40..f9431525c 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -28,7 +28,7 @@ const DEFAULT_STUDIO_MICS_LAYERS = [ SisyfosLLAyer.SisyfosSourceGuest_4_ST_A ] -export const manifestAFVDSourcesCam = MakeConfigForSources('Cam', 'Camera', false, [ +export const manifestAFVDSourcesCam = MakeConfigForSources('Cam', 'Camera', false, true, [ { _id: '', SourceName: '1', @@ -101,14 +101,15 @@ export const manifestAFVDSourcesCam = MakeConfigForSources('Cam', 'Camera', fals } ]) -export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, [ +export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, true, [ { _id: '', SourceName: '1', AtemSource: 1, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_1], - StudioMics: false, - KeepAudioInStudio: true + StudioMics: true, + WantsToPersistAudio: true, + AcceptPersistAudio: false }, { _id: '', @@ -116,7 +117,8 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, [ AtemSource: 2, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_2], StudioMics: false, - KeepAudioInStudio: true + WantsToPersistAudio: true, + AcceptPersistAudion: false }, { _id: '', @@ -124,7 +126,8 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, [ AtemSource: 3, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_3], StudioMics: false, - KeepAudioInStudio: true + WantsToPersistAudio: true, + AcceptPersistAudio: false }, { _id: '', @@ -132,7 +135,8 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, [ AtemSource: 4, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_4], StudioMics: false, - KeepAudioInStudio: true + WantsToPersistAudio: true, + AcceptPersistAudio: false }, { _id: '', @@ -140,7 +144,8 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, [ AtemSource: 5, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_5], StudioMics: false, - KeepAudioInStudio: true + WantsToPersistAudio: true, + AcceptPersistAudio: false }, { _id: '', @@ -148,7 +153,8 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, [ AtemSource: 6, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_6], StudioMics: false, - KeepAudioInStudio: true + WantsToPersistAudio: true, + AcceptPersistAudio: false }, { _id: '', @@ -156,7 +162,8 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, [ AtemSource: 7, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_7], StudioMics: false, - KeepAudioInStudio: true + WantsToPersistAudio: true, + AcceptPersistAudio: false }, { _id: '', @@ -164,7 +171,8 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, [ AtemSource: 8, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_8], StudioMics: false, - KeepAudioInStudio: true + WantsToPersistAudio: true, + AcceptPersistAudio: false }, { _id: '', @@ -172,7 +180,8 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, [ AtemSource: 9, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_9], StudioMics: false, - KeepAudioInStudio: true + WantsToPersistAudio: true, + AcceptPersistAudio: false }, { _id: '', @@ -180,13 +189,14 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, [ AtemSource: 10, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_10], StudioMics: false, - KeepAudioInStudio: true + WantsToPersistAudio: true, + AcceptPersistAudio: false } ]) -export const manifestAFVDSourcesFeed = MakeConfigForSources('Feed', 'Feed', true, []) +export const manifestAFVDSourcesFeed = MakeConfigForSources('Feed', 'Feed', true, false, []) -export const manifestAFVDSourcesDelayedPlayback = MakeConfigForSources('DelayedPlayback', 'EVS', false, [ +export const manifestAFVDSourcesDelayedPlayback = MakeConfigForSources('DelayedPlayback', 'EVS', false, false, [ { _id: '', SourceName: '1', @@ -203,7 +213,7 @@ export const manifestAFVDSourcesDelayedPlayback = MakeConfigForSources('DelayedP } ]) -export const manifestAFVDSourcesSkype = MakeConfigForSources('Skype', 'Skype', false, [ +export const manifestAFVDSourcesSkype = MakeConfigForSources('Skype', 'Skype', false, true, [ { _id: '', SourceName: '1', diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index 51400b1a9..fe0457e01 100644 --- a/src/tv2_afvd_studio/helpers/config.ts +++ b/src/tv2_afvd_studio/helpers/config.ts @@ -1,7 +1,5 @@ import { IBlueprintConfig, ICommonContext, IStudioContext } from '@tv2media/blueprints-integration' import { - getLiveAudioLayers, - getStickyLayers, MediaPlayerConfig, SourceInfo, TableConfigItemDSK, @@ -19,8 +17,6 @@ export interface BlueprintConfig { sources: SourceInfo[] showStyle: ShowStyleConfig mediaPlayers: MediaPlayerConfig // Atem Input Ids - liveAudio: string[] - stickyLayers: string[] dsk: TableConfigItemDSK[] } @@ -58,15 +54,11 @@ export function parseConfig(_context: ICommonContext, rawConfig: IBlueprintConfi showStyle: {} as any, sources: [], mediaPlayers: [], - liveAudio: [], - stickyLayers: [], dsk: studioConfig.AtemSource.DSK } config.sources = parseSources(studioConfig) config.mediaPlayers = parseMediaPlayers(studioConfig) - config.liveAudio = getLiveAudioLayers(studioConfig) - config.stickyLayers = getStickyLayers(studioConfig, config.liveAudio) return config } diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index 4cd202ac6..d3783feb5 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -193,6 +193,8 @@ export const studioMigrations: MigrationStepStudio[] = literal; valid: boolean; stickyLayers: string[] } { +): { content: WithTimeline; valid: boolean } { return MakeContentDVEBase( context, config, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts index 6b957803a..601fa75b0 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts @@ -110,18 +110,6 @@ export function OfftubeEvaluateAdLib( const adlibContent = OfftubeMakeContentDVE(context, config, partDefinition, cueDVE, rawTemplate, false, true) - let sticky: { [key: string]: { value: number; followsPrevious: boolean } } = {} - - adlibContent.stickyLayers.forEach(layer => { - sticky = { - ...sticky, - [layer]: { - value: 1, - followsPrevious: false - } - } - }) - actions.push( literal({ actionId: AdlibActionType.SELECT_DVE, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts index c9d3422c3..cb65ca5a0 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts @@ -102,7 +102,10 @@ export function OfftubeEvaluateDVE( config: parsedCue, videoId: partDefinition.fields.videoId, segmentExternalId: partDefinition.segmentExternalId - }) + }), + sisyfosPersistMetaData: { + sisyfosLayers: [] + } }), tags: [ GetTagForDVE(partDefinition.segmentExternalId, parsedCue.template, parsedCue.sources), diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index bdb0d57f7..8cb4b52e3 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -103,6 +103,9 @@ export function OfftubeEvaluateJingle( transition: { isJingle: !effekt, isEffekt: !!effekt + }, + sisyfosPersistMetaData: { + sisyfosLayers: [] } }), content: createJingleContentOfftube( diff --git a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts index fa4867c0f..920f3600c 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts @@ -6,7 +6,14 @@ import { IBlueprintPiece, ISegmentUserContext } from '@tv2media/blueprints-integration' -import { AddScript, ApplyFullGraphicPropertiesToPart, literal, PartDefinition, PartTime } from 'tv2-common' +import { + AddScript, + ApplyFullGraphicPropertiesToPart, + literal, + MapSisyfosPersistMetaDataToPieces, + PartDefinition, + PartTime +} from 'tv2-common' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' @@ -29,7 +36,7 @@ export function OfftubeCreatePartGrafik( }) const adLibPieces: IBlueprintAdLibPiece[] = [] - const pieces: IBlueprintPiece[] = [] + let pieces: IBlueprintPiece[] = [] const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] @@ -57,6 +64,8 @@ export function OfftubeCreatePartGrafik( part.invalid = true } + pieces = MapSisyfosPersistMetaDataToPieces(pieces) + return { part, adLibPieces, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index 9a864c46f..5e090ad5b 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -20,12 +20,11 @@ import { CreatePartKamBase, FindDSKJingle, FindSourceInfoStrict, - GetCameraMetaData, - GetLayersForCamera, GetSisyfosTimelineObjForCamera, GetTagForKam, literal, PartDefinitionKam, + SisyfosPersistMetaData, TransitionFromString, TransitionSettings } from 'tv2-common' @@ -109,7 +108,12 @@ export function OfftubeCreatePartKam( outputLayerId: SharedOutputLayers.PGM, sourceLayerId: OfftubeSourceLayer.PgmCam, lifespan: PieceLifespan.WithinPart, - metaData: GetCameraMetaData(config, GetLayersForCamera(config, sourceInfoCam)), + metaData: { + sisyfosPersistMetaData: literal({ + sisyfosLayers: sourceInfoCam.sisyfosLayers ?? [], + acceptPersistAudio: sourceInfoCam.acceptPersistAudio + }) + }, tags: [GetTagForKam(sourceInfoCam.id)], content: { studioLabel: '', diff --git a/src/tv2_offtube_studio/config-manifests.ts b/src/tv2_offtube_studio/config-manifests.ts index c7f19839c..b818113ec 100644 --- a/src/tv2_offtube_studio/config-manifests.ts +++ b/src/tv2_offtube_studio/config-manifests.ts @@ -12,7 +12,6 @@ import { MakeConfigWithMediaFlow, TableConfigItemSourceMapping } from 'tv2-common' -import * as _ from 'underscore' import { AtemSourceIndex } from '../types/atem' import { defaultDSKConfig } from './helpers/config' import { OfftubeSisyfosLLayer } from './layers' @@ -25,7 +24,7 @@ const DEFAULT_STUDIO_MICS_LAYERS = [ OfftubeSisyfosLLayer.SisyfosSourceHost_3_ST_A ] -export const manifestOfftubeSourcesCam = MakeConfigForSources('Cam', 'Cameras', false, [ +export const manifestOfftubeSourcesCam = MakeConfigForSources('Cam', 'Cameras', false, true, [ { _id: '', SourceName: '1', @@ -35,25 +34,26 @@ export const manifestOfftubeSourcesCam = MakeConfigForSources('Cam', 'Cameras', } ]) -export const manifestOfftubeSourcesRM = MakeConfigForSources('RM', 'Live', true, [ +export const manifestOfftubeSourcesRM = MakeConfigForSources('RM', 'Live', true, true, [ { _id: '', SourceName: '1', AtemSource: 3, SisyfosLayers: [OfftubeSisyfosLLayer.SisyfosSourceLive_3], StudioMics: true, - KeepAudioInStudio: true + WantsToPersistAudio: true, + AcceptPersistAudio: false } ]) -export const manifestOfftubeSourcesFeed = MakeConfigForSources('Feed', 'Feed', true, [ +export const manifestOfftubeSourcesFeed = MakeConfigForSources('Feed', 'Feed', true, true, [ { _id: '', SourceName: '1', AtemSource: 1, SisyfosLayers: [OfftubeSisyfosLLayer.SisyfosSourceLive_1_Stereo, OfftubeSisyfosLLayer.SisyfosSourceLive_1_Surround], StudioMics: true, - KeepAudioInStudio: true + WantsToPersistAudio: false }, { _id: '', @@ -61,11 +61,11 @@ export const manifestOfftubeSourcesFeed = MakeConfigForSources('Feed', 'Feed', t AtemSource: 2, SisyfosLayers: [OfftubeSisyfosLLayer.SisyfosSourceLive_2_Stereo], StudioMics: true, - KeepAudioInStudio: true + WantsToPersistAudio: false } ]) -export const manifestOfftubeSourcesSkype = MakeConfigForSources('Skype', 'Skype', false, []) +export const manifestOfftubeSourcesSkype = MakeConfigForSources('Skype', 'Skype', false, true, []) export const manifestOfftubeSourcesABMediaPlayers: ConfigManifestEntryTable = { id: 'ABMediaPlayers', diff --git a/src/tv2_offtube_studio/helpers/config.ts b/src/tv2_offtube_studio/helpers/config.ts index d7be2b1c8..d424da01d 100644 --- a/src/tv2_offtube_studio/helpers/config.ts +++ b/src/tv2_offtube_studio/helpers/config.ts @@ -1,7 +1,5 @@ import { IBlueprintConfig, ICommonContext } from '@tv2media/blueprints-integration' import { - getLiveAudioLayers, - getStickyLayers, MediaPlayerConfig, SourceInfo, TableConfigItemDSK, @@ -16,8 +14,6 @@ export interface OfftubeStudioBlueprintConfig { studio: OfftubeStudioConfig sources: SourceInfo[] mediaPlayers: MediaPlayerConfig // Atem Input Ids - liveAudio: string[] - stickyLayers: string[] dsk: TableConfigItemDSK[] } @@ -58,14 +54,10 @@ export function parseConfig(_context: ICommonContext, rawConfig: IBlueprintConfi // showStyle: {} as any, sources: [], mediaPlayers: [], - liveAudio: [], - stickyLayers: [], dsk: studioConfig.AtemSource.DSK } config.sources = parseSources(studioConfig) config.mediaPlayers = parseMediaPlayers(studioConfig) - config.liveAudio = getLiveAudioLayers(studioConfig) - config.stickyLayers = getStickyLayers(studioConfig, config.liveAudio) return config } diff --git a/src/tv2_offtube_studio/migrations/index.ts b/src/tv2_offtube_studio/migrations/index.ts index 9fc9a5122..e7092f6bc 100644 --- a/src/tv2_offtube_studio/migrations/index.ts +++ b/src/tv2_offtube_studio/migrations/index.ts @@ -330,6 +330,8 @@ export const studioMigrations: MigrationStepStudio[] = literal=2.2.7 <3" -abab@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" - integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== +abab@^2.0.3, abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== -acorn-globals@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" - integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== dependencies: - acorn "^6.0.1" - acorn-walk "^6.0.1" + acorn "^7.1.1" + acorn-walk "^7.1.1" -acorn-walk@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" - integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== - -acorn@^5.5.3: - version "5.7.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" - integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== - -acorn@^6.0.1: - version "6.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" - integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== acorn@^6.4.1: version "6.4.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== +acorn@^7.1.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.2.4: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + add-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" integrity sha1-anmQQ3ynNtXhKI25K9MmbV9csqo= +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" @@ -627,32 +952,19 @@ ajv@^6.1.0, ajv@^6.10.2: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^6.5.5: - version "6.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" - integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-escapes@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + type-fest "^0.21.3" ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.0.0, ansi-regex@^4.1.0: +ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== @@ -662,6 +974,11 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -669,13 +986,18 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.0.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -684,6 +1006,14 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" +anymatch@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + anymatch@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" @@ -729,11 +1059,6 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -array-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" - integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= - array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" @@ -769,18 +1094,6 @@ asn1.js@^5.2.0: minimalistic-assert "^1.0.0" safer-buffer "^2.1.0" -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - assert@^1.1.1: version "1.5.0" resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" @@ -794,21 +1107,11 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - async-each@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -819,16 +1122,6 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" - integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== - axios@^0.19.0: version "0.19.2" resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" @@ -836,48 +1129,71 @@ axios@^0.19.0: dependencies: follow-redirects "1.5.10" -babel-jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" - integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== - dependencies: - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/babel__core" "^7.1.0" - babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.9.0" - chalk "^2.4.2" - slash "^2.0.0" - -babel-plugin-istanbul@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" - integrity sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw== +babel-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" + integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== + dependencies: + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - find-up "^3.0.0" - istanbul-lib-instrument "^3.3.0" - test-exclude "^5.2.3" - -babel-plugin-jest-hoist@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" - integrity sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw== - dependencies: + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" + integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" -babel-preset-jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc" - integrity sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg== - dependencies: - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.9.0" +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" + integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== + dependencies: + babel-plugin-jest-hoist "^27.5.1" + babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base64-js@^1.0.2: version "1.5.1" @@ -897,13 +1213,6 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -1050,6 +1359,17 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" +browserslist@^4.17.5: + version "4.19.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.3.tgz#29b7caad327ecf2859485f696f9604214bedd383" + integrity sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg== + dependencies: + caniuse-lite "^1.0.30001312" + electron-to-chromium "^1.4.71" + escalade "^3.1.1" + node-releases "^2.0.2" + picocolors "^1.0.0" + bs-logger@0.x: version "0.2.6" resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" @@ -1064,10 +1384,10 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" -buffer-from@1.x, buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== buffer-xor@^1.0.3: version "1.0.3" @@ -1129,6 +1449,14 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1156,16 +1484,21 @@ camelcase@^2.0.0, camelcase@^2.0.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= -camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= - camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001312: + version "1.0.30001312" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz#e11eba4b87e24d22697dae05455d5aea28550d5f" + integrity sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -1173,11 +1506,6 @@ capture-exit@^2.0.0: dependencies: rsvp "^4.8.4" -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -1187,6 +1515,19 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" @@ -1238,6 +1579,11 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +ci-info@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" + integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -1246,6 +1592,11 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -1293,6 +1644,11 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -1325,7 +1681,7 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -1568,10 +1924,10 @@ conventional-recommended-bump@6.1.0: meow "^8.0.0" q "^1.5.1" -convert-source-map@^1.4.0, convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== +convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== dependencies: safe-buffer "~5.1.1" @@ -1592,7 +1948,7 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-util-is@1.0.2, core-util-is@~1.0.0: +core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= @@ -1639,6 +1995,15 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -1656,17 +2021,22 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssom@~0.3.6: version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== -cssstyle@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" - integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== dependencies: - cssom "0.3.x" + cssom "~0.3.6" currently-unhandled@^0.4.1: version "0.4.1" @@ -1685,27 +2055,27 @@ dargs@^7.0.0: resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -data-urls@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" - integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== dependencies: - abab "^2.0.0" - whatwg-mimetype "^2.2.0" - whatwg-url "^7.0.0" + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" dateformat@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== +debug@4, debug@^4.1.0, debug@^4.1.1: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + debug@=3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -1720,13 +2090,6 @@ debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@^4.1.0, debug@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -1745,17 +2108,32 @@ decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= +decimal.js@^10.2.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -define-properties@^1.1.2, define-properties@^1.1.3: +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== @@ -1807,12 +2185,7 @@ detect-indent@^6.0.0: resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.0.0.tgz#0abd0f549f69fc6659a254fe96786186b6f528fd" integrity sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA== -detect-newline@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= - -detect-newline@^3.1.0: +detect-newline@^3.0.0, detect-newline@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== @@ -1825,10 +2198,10 @@ dezalgo@^1.0.0: asap "^2.0.0" wrappy "1" -diff-sequences@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" - integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== +diff-sequences@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" + integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== diff@^4.0.1: version "4.0.2" @@ -1849,12 +2222,12 @@ domain-browser@^1.1.1: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== dependencies: - webidl-conversions "^4.0.2" + webidl-conversions "^5.0.0" dot-prop@^5.1.0: version "5.3.0" @@ -1881,13 +2254,10 @@ duplexify@^3.4.2, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" +electron-to-chromium@^1.4.71: + version "1.4.75" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.75.tgz#d1ad9bb46f2f1bf432118c2be21d27ffeae82fdd" + integrity sha512-LxgUNeu3BVU7sXaKjUDD9xivocQLxFtq6wgERrutdY/yIOps3ODOZExK1jg8DTEg4U8TUCb5MLGeWFOYuxjF3Q== elliptic@^6.5.3: version "6.5.4" @@ -1902,6 +2272,11 @@ elliptic@^6.5.3: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== + emoji-regex@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -1963,22 +2338,31 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: - version "1.17.4" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184" - integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ== +es-abstract@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== dependencies: + call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.1.5" - is-regex "^1.0.5" - object-inspect "^1.7.0" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.1" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" + object-inspect "^1.11.0" object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimleft "^2.1.1" - string.prototype.trimright "^2.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" es-to-primitive@^1.2.1: version "1.2.1" @@ -1999,13 +2383,18 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -escodegen@^1.9.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.1.tgz#ba01d0c8278b5e95a9a45350142026659027a457" - integrity sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ== +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== dependencies: esprima "^4.0.1" - estraverse "^4.2.0" + estraverse "^5.2.0" esutils "^2.0.2" optionator "^0.8.1" optionalDependencies: @@ -2039,7 +2428,7 @@ esrecurse@^4.1.0: dependencies: estraverse "^5.2.0" -estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -2068,9 +2457,9 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: safe-buffer "^5.1.1" exec-sh@^0.3.2: - version "0.3.4" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" - integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== + version "0.3.6" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" + integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== execa@^1.0.0: version "1.0.0" @@ -2085,6 +2474,21 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -2110,17 +2514,15 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" -expect@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" - integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== +expect@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" + integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== dependencies: - "@jest/types" "^24.9.0" - ansi-styles "^3.2.0" - jest-get-type "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-regex-util "^24.9.0" + "@jest/types" "^27.5.1" + jest-get-type "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" extend-shallow@^2.0.1: version "2.0.1" @@ -2137,11 +2539,6 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -2156,20 +2553,10 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-diff@^1.1.1: version "1.2.0" @@ -2258,7 +2645,7 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -find-up@^4.1.0: +find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -2299,23 +2686,25 @@ follow-redirects@1.5.10: dependencies: debug "=3.1.0" +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "^1.0.8" mime-types "^2.1.12" fragment-cache@^0.2.1: @@ -2356,13 +2745,18 @@ fs.realpath@^1.0.0: integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.2.7: - version "1.2.11" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.11.tgz#67bf57f4758f02ede88fb2a1712fef4d15358be3" - integrity sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw== + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== dependencies: bindings "^1.5.0" nan "^2.12.1" +fsevents@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + fsevents@~2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f" @@ -2373,16 +2767,30 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -gensync@^1.0.0-beta.1: - version "1.0.0-beta.1" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" - integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + get-pkg-repo@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" @@ -2406,18 +2814,24 @@ get-stream@^4.0.0: dependencies: pump "^3.0.0" +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - git-raw-commits@^2.0.8: version "2.0.10" resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.10.tgz#e2255ed9563b1c9c3ea6bd05806410290297bbc1" @@ -2480,7 +2894,7 @@ glob-parent@~5.1.0: dependencies: is-glob "^4.0.1" -glob@^7.0.0, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: +glob@^7.0.0, glob@^7.0.5, glob@^7.1.4: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -2492,6 +2906,18 @@ glob@^7.0.0, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + global-modules@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" @@ -2533,21 +2959,16 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.2.9: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== "graceful-readlink@>= 1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= -growly@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= - handlebars@^4.7.6: version "4.7.7" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" @@ -2560,33 +2981,37 @@ handlebars@^4.7.6: optionalDependencies: uglify-js "^3.1.4" -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - hard-rejection@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" has-value@^0.3.1: version "0.3.1" @@ -2659,7 +3084,12 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" -hosted-git-info@^2.1.4, hosted-git-info@^2.1.5: +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +hosted-git-info@^2.1.5: version "2.8.8" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== @@ -2671,32 +3101,45 @@ hosted-git-info@^4.0.1: dependencies: lru-cache "^6.0.0" -html-encoding-sniffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" - integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== dependencies: - whatwg-encoding "^1.0.1" + whatwg-encoding "^1.0.5" html-escaper@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.0.tgz#71e87f931de3fe09e56661ab9a29aadec707b491" - integrity sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig== + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" + "@tootallnate/once" "1" + agent-base "6" + debug "4" https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -2722,6 +3165,14 @@ import-local@^2.0.0: pkg-dir "^3.0.0" resolve-cwd "^2.0.0" +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -2772,6 +3223,15 @@ ini@^1.3.2, ini@^1.3.4, ini@^1.3.5: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + interpret@^1.0.0, interpret@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" @@ -2808,6 +3268,13 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -2822,15 +3289,23 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-callable@^1.1.4, is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== is-ci@^2.0.0: version "2.0.0" @@ -2846,6 +3321,13 @@ is-core-module@^2.2.0: dependencies: has "^1.0.3" +is-core-module@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -2861,9 +3343,11 @@ is-data-descriptor@^1.0.0: kind-of "^6.0.0" is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" is-descriptor@^0.1.0: version "0.1.6" @@ -2941,6 +3425,18 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-negative-zero@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + dependencies: + has-tostringtag "^1.0.0" + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -2970,24 +3466,47 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-regex@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== dependencies: - has "^1.0.3" + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== dependencies: - has-symbols "^1.0.1" + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" is-text-path@^1.0.1: version "1.0.1" @@ -2996,7 +3515,7 @@ is-text-path@^1.0.1: dependencies: text-extensions "^1.0.0" -is-typedarray@~1.0.0: +is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -3006,6 +3525,13 @@ is-utf8@^0.2.0: resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= +is-weakref@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -3038,169 +3564,194 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" - integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== -istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" - integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== - dependencies: - "@babel/generator" "^7.4.0" - "@babel/parser" "^7.4.3" - "@babel/template" "^7.4.0" - "@babel/traverse" "^7.4.3" - "@babel/types" "^7.4.0" - istanbul-lib-coverage "^2.0.5" - semver "^6.0.0" +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" + integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" -istanbul-lib-report@^2.0.4: - version "2.0.8" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" - integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== dependencies: - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - supports-color "^6.1.0" + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" -istanbul-lib-source-maps@^3.0.1: - version "3.0.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" - integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== dependencies: debug "^4.1.1" - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - rimraf "^2.6.3" + istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^2.2.6: - version "2.2.7" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.7.tgz#5d939f6237d7b48393cc0959eab40cd4fd056931" - integrity sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg== +istanbul-reports@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" + integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== dependencies: html-escaper "^2.0.0" - -jest-changed-files@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" - integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg== - dependencies: - "@jest/types" "^24.9.0" - execa "^1.0.0" - throat "^4.0.0" - -jest-cli@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" - integrity sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg== - dependencies: - "@jest/core" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" + integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== + dependencies: + "@jest/types" "^27.5.1" + execa "^5.0.0" + throat "^6.0.1" + +jest-circus@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" + integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" + +jest-cli@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" + integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== + dependencies: + "@jest/core" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" exit "^0.1.2" - import-local "^2.0.0" - is-ci "^2.0.0" - jest-config "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" prompts "^2.0.1" - realpath-native "^1.1.0" - yargs "^13.3.0" - -jest-config@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" - integrity sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ== - dependencies: - "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^24.9.0" - "@jest/types" "^24.9.0" - babel-jest "^24.9.0" - chalk "^2.0.1" + yargs "^16.2.0" + +jest-config@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" + integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== + dependencies: + "@babel/core" "^7.8.0" + "@jest/test-sequencer" "^27.5.1" + "@jest/types" "^27.5.1" + babel-jest "^27.5.1" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" glob "^7.1.1" - jest-environment-jsdom "^24.9.0" - jest-environment-node "^24.9.0" - jest-get-type "^24.9.0" - jest-jasmine2 "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - micromatch "^3.1.10" - pretty-format "^24.9.0" - realpath-native "^1.1.0" - -jest-diff@^24.3.0, jest-diff@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" - integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== - dependencies: - chalk "^2.0.1" - diff-sequences "^24.9.0" - jest-get-type "^24.9.0" - pretty-format "^24.9.0" + graceful-fs "^4.2.9" + jest-circus "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-get-type "^27.5.1" + jest-jasmine2 "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runner "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^27.5.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" + integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== + dependencies: + chalk "^4.0.0" + diff-sequences "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" jest-docblock@^21.0.0: version "21.2.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== -jest-docblock@^24.3.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" - integrity sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA== - dependencies: - detect-newline "^2.1.0" - -jest-each@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" - integrity sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog== - dependencies: - "@jest/types" "^24.9.0" - chalk "^2.0.1" - jest-get-type "^24.9.0" - jest-util "^24.9.0" - pretty-format "^24.9.0" - -jest-environment-jsdom@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" - integrity sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA== - dependencies: - "@jest/environment" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - jest-util "^24.9.0" - jsdom "^11.5.1" - -jest-environment-node@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" - integrity sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA== - dependencies: - "@jest/environment" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - jest-util "^24.9.0" - -jest-get-type@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" - integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== - -jest-haste-map@^24.5.0, jest-haste-map@^24.9.0: +jest-docblock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" + integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== + dependencies: + detect-newline "^3.0.0" + +jest-each@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" + integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + jest-get-type "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + +jest-environment-jsdom@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" + integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + jsdom "^16.6.0" + +jest-environment-node@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" + integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + +jest-get-type@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" + integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== + +jest-haste-map@^24.5.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ== @@ -3219,45 +3770,66 @@ jest-haste-map@^24.5.0, jest-haste-map@^24.9.0: optionalDependencies: fsevents "^1.2.7" -jest-jasmine2@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" - integrity sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw== +jest-haste-map@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" + integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" + "@jest/types" "^27.5.1" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^27.5.1" + jest-serializer "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + +jest-jasmine2@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" + integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" co "^4.6.0" - expect "^24.9.0" + expect "^27.5.1" is-generator-fn "^2.0.0" - jest-each "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-runtime "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - pretty-format "^24.9.0" - throat "^4.0.0" - -jest-leak-detector@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" - integrity sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA== - dependencies: - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - -jest-matcher-utils@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" - integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== - dependencies: - chalk "^2.0.1" - jest-diff "^24.9.0" - jest-get-type "^24.9.0" - pretty-format "^24.9.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + throat "^6.0.1" + +jest-leak-detector@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" + integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== + dependencies: + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== + dependencies: + chalk "^4.0.0" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" jest-message-util@^24.9.0: version "24.9.0" @@ -3273,6 +3845,21 @@ jest-message-util@^24.9.0: slash "^2.0.0" stack-utils "^1.0.1" +jest-message-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" + integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.5.1" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" @@ -3280,26 +3867,34 @@ jest-mock@^24.9.0: dependencies: "@jest/types" "^24.9.0" -jest-pnp-resolver@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" - integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== +jest-mock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" -jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" - integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== +jest-pnp-resolver@^1.2.1, jest-pnp-resolver@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-resolve-dependencies@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" - integrity sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g== +jest-regex-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" + integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== + +jest-resolve-dependencies@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" + integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== dependencies: - "@jest/types" "^24.9.0" - jest-regex-util "^24.3.0" - jest-snapshot "^24.9.0" + "@jest/types" "^27.5.1" + jest-regex-util "^27.5.1" + jest-snapshot "^27.5.1" -jest-resolve@^24.5.0, jest-resolve@^24.9.0: +jest-resolve@^24.5.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" integrity sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ== @@ -3310,83 +3905,117 @@ jest-resolve@^24.5.0, jest-resolve@^24.9.0: jest-pnp-resolver "^1.2.1" realpath-native "^1.1.0" -jest-runner@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" - integrity sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.4.2" - exit "^0.1.2" - graceful-fs "^4.1.15" - jest-config "^24.9.0" - jest-docblock "^24.3.0" - jest-haste-map "^24.9.0" - jest-jasmine2 "^24.9.0" - jest-leak-detector "^24.9.0" - jest-message-util "^24.9.0" - jest-resolve "^24.9.0" - jest-runtime "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.6.0" +jest-resolve@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" + integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-pnp-resolver "^1.2.2" + jest-util "^27.5.1" + jest-validate "^27.5.1" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + +jest-runner@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" + integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.8.1" + graceful-fs "^4.2.9" + jest-docblock "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-haste-map "^27.5.1" + jest-leak-detector "^27.5.1" + jest-message-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runtime "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" source-map-support "^0.5.6" - throat "^4.0.0" - -jest-runtime@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" - integrity sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.9.0" - "@jest/source-map" "^24.3.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/yargs" "^13.0.0" - chalk "^2.0.1" - exit "^0.1.2" + throat "^6.0.1" + +jest-runtime@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" + integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/globals" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" glob "^7.1.3" - graceful-fs "^4.1.15" - jest-config "^24.9.0" - jest-haste-map "^24.9.0" - jest-message-util "^24.9.0" - jest-mock "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - realpath-native "^1.1.0" - slash "^2.0.0" - strip-bom "^3.0.0" - yargs "^13.3.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + strip-bom "^4.0.0" jest-serializer@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== -jest-snapshot@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" - integrity sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew== +jest-serializer@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" + integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.9" + +jest-snapshot@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" + integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" "@babel/types" "^7.0.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" - expect "^24.9.0" - jest-diff "^24.9.0" - jest-get-type "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-resolve "^24.9.0" - mkdirp "^0.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.5.1" + graceful-fs "^4.2.9" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + jest-haste-map "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-util "^27.5.1" natural-compare "^1.4.0" - pretty-format "^24.9.0" - semver "^6.2.0" + pretty-format "^27.5.1" + semver "^7.3.2" jest-util@^24.9.0: version "24.9.0" @@ -3406,32 +4035,44 @@ jest-util@^24.9.0: slash "^2.0.0" source-map "^0.6.0" -jest-validate@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" - integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== - dependencies: - "@jest/types" "^24.9.0" - camelcase "^5.3.1" - chalk "^2.0.1" - jest-get-type "^24.9.0" +jest-util@^27.0.0, jest-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" + integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" + integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== + dependencies: + "@jest/types" "^27.5.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.5.1" leven "^3.1.0" - pretty-format "^24.9.0" - -jest-watcher@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.9.0.tgz#4b56e5d1ceff005f5b88e528dc9afc8dd4ed2b3b" - integrity sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw== - dependencies: - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/yargs" "^13.0.0" - ansi-escapes "^3.0.0" - chalk "^2.0.1" - jest-util "^24.9.0" - string-length "^2.0.0" - -jest-worker@^24.6.0, jest-worker@^24.9.0: + pretty-format "^27.5.1" + +jest-watcher@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" + integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== + dependencies: + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^27.5.1" + string-length "^4.0.1" + +jest-worker@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== @@ -3439,13 +4080,23 @@ jest-worker@^24.6.0, jest-worker@^24.9.0: merge-stream "^2.0.0" supports-color "^6.1.0" -jest@^24.0.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" - integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== +jest-worker@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== dependencies: - import-local "^2.0.0" - jest-cli "^24.9.0" + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" + integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== + dependencies: + "@jest/core" "^27.5.1" + import-local "^3.0.2" + jest-cli "^27.5.1" "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" @@ -3460,41 +4111,37 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsdom@^11.5.1: - version "11.12.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" - integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== - dependencies: - abab "^2.0.0" - acorn "^5.5.3" - acorn-globals "^4.1.0" - array-equal "^1.0.0" - cssom ">= 0.3.2 < 0.4.0" - cssstyle "^1.0.0" - data-urls "^1.0.0" - domexception "^1.0.1" - escodegen "^1.9.1" - html-encoding-sniffer "^1.0.2" - left-pad "^1.3.0" - nwsapi "^2.0.7" - parse5 "4.0.0" - pn "^1.1.0" - request "^2.87.0" - request-promise-native "^1.0.5" - sax "^1.2.4" - symbol-tree "^3.2.2" - tough-cookie "^2.3.4" - w3c-hr-time "^1.0.1" - webidl-conversions "^4.0.2" - whatwg-encoding "^1.0.3" - whatwg-mimetype "^2.1.0" - whatwg-url "^6.4.1" - ws "^5.2.0" +jsdom@^16.6.0: + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== + dependencies: + abab "^2.0.5" + acorn "^8.2.4" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + form-data "^3.0.0" + html-encoding-sniffer "^2.0.1" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.5.0" + ws "^7.4.6" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -3517,17 +4164,12 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json5@2.x, json5@^2.1.0: +json5@2.x: version "2.1.1" resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" integrity sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ== @@ -3541,20 +4183,17 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + jsonparse@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" + integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" @@ -3592,11 +4231,6 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" -left-pad@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" - integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== - leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -3690,15 +4324,10 @@ lodash.memoize@4.x: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= - -lodash@^4.17.13, lodash@^4.17.15: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +lodash@^4.17.15, lodash@^4.7.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== loose-envify@^1.0.0: version "1.4.0" @@ -3729,7 +4358,7 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -make-dir@^2.0.0, make-dir@^2.1.0: +make-dir@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== @@ -3737,17 +4366,24 @@ make-dir@^2.0.0, make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + make-error@1.x, make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== dependencies: - tmpl "1.0.x" + tmpl "1.0.5" map-cache@^0.2.2: version "0.2.2" @@ -3861,6 +4497,14 @@ micromatch@^4.0.0: braces "^3.0.1" picomatch "^2.0.5" +micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -3869,17 +4513,22 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.43.0: - version "1.43.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" - integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== +mime-db@1.51.0: + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.26" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" - integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== +mime-types@^2.1.12: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== dependencies: - mime-db "1.43.0" + mime-db "1.51.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== min-indent@^1.0.0: version "1.0.1" @@ -3897,9 +4546,9 @@ minimalistic-crypto-utils@^1.0.1: integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" @@ -3912,22 +4561,12 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - minimist@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de" integrity sha1-md9lelJXTCHJBXSX33QnkLK0wN4= -minimist@^1.1.1, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minimist@^1.1.3, minimist@^1.2.5: +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== @@ -3956,14 +4595,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.x, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -mkdirp@^0.5.3: +mkdirp@^0.5.1, mkdirp@^0.5.3: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -4002,15 +4634,15 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@^2.1.1: +ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== nan@^2.12.1: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + version "2.15.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" + integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== nanomatch@^1.2.9: version "1.2.13" @@ -4101,21 +4733,10 @@ node-license-validator@^1.3.0: spdx-satisfies "^0.1.3" yargs "^3.32.0" -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= - -node-notifier@^5.4.2: - version "5.4.3" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" - integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== - dependencies: - growly "^1.3.0" - is-wsl "^1.1.0" - semver "^5.5.0" - shellwords "^0.1.1" - which "^1.3.0" +node-releases@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" + integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: version "2.5.0" @@ -4169,6 +4790,13 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + null-check@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" @@ -4179,16 +4807,11 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -nwsapi@^2.0.7: +nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -4203,12 +4826,12 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" + integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -4220,23 +4843,24 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" -object.getownpropertydescriptors@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== +object.getownpropertydescriptors@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e" + integrity sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" + es-abstract "^1.19.1" object.pick@^1.3.0: version "1.3.0" @@ -4252,6 +4876,13 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -4276,13 +4907,6 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" -p-each-series@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" - integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= - dependencies: - p-reduce "^1.0.0" - p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -4295,14 +4919,7 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== - dependencies: - p-try "^2.0.0" - -p-limit@^2.2.0: +p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== @@ -4344,11 +4961,6 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" -p-reduce@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" - integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= - p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -4404,7 +5016,7 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -4419,10 +5031,10 @@ parse-passwd@^1.0.0: resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= -parse5@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" - integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== pascalcase@^0.1.1: version "0.1.1" @@ -4466,10 +5078,15 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6, path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-type@^1.0.0: version "1.1.0" @@ -4498,10 +5115,10 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" @@ -4513,6 +5130,11 @@ picomatch@^2.0.5: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA== +picomatch@^2.2.3: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -4540,12 +5162,10 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= -pirates@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" - integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== - dependencies: - node-modules-regexp "^1.0.0" +pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== pkg-dir@^3.0.0: version "3.0.0" @@ -4554,10 +5174,12 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -pn@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" - integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" posix-character-classes@^0.1.0: version "0.1.1" @@ -4574,15 +5196,14 @@ prettier@^1.18.2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== -pretty-format@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" - integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== +pretty-format@^27.0.0, pretty-format@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== dependencies: - "@jest/types" "^24.9.0" - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - react-is "^16.8.4" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" process-nextick-args@~2.0.0: version "2.0.1" @@ -4600,22 +5221,22 @@ promise-inflight@^1.0.1: integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= prompts@^2.0.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.1.tgz#b63a9ce2809f106fa9ae1277c275b167af46ea05" - integrity sha512-qIP2lQyCwYbdzcqHIUi2HAxiWixhoM9OdLCWf8txXsapC/X9YdsCoeyRIXE/GP+Q0J37Q7+XN/MFqbUa7IzXNA== + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== dependencies: kleur "^3.0.3" - sisteransi "^1.0.4" + sisteransi "^1.0.5" prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -psl@^1.1.28: - version "1.7.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" - integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ== +psl@^1.1.33: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== public-encrypt@^4.0.0: version "4.0.3" @@ -4674,11 +5295,6 @@ q@^1.5.1: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -4709,10 +5325,10 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" -react-is@^16.8.4: - version "16.13.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527" - integrity sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA== +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== read-installed@4.0.3: version "4.0.3" @@ -4756,14 +5372,6 @@ read-pkg-up@^3.0.0: find-up "^2.0.0" read-pkg "^3.0.0" -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== - dependencies: - find-up "^3.0.0" - read-pkg "^3.0.0" - read-pkg-up@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" @@ -4893,9 +5501,9 @@ remove-trailing-separator@^1.0.1: integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== repeat-string@^1.6.1: version "1.6.1" @@ -4909,48 +5517,6 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request-promise-core@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" - integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== - dependencies: - lodash "^4.17.15" - -request-promise-native@^1.0.5: - version "1.0.8" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" - integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== - dependencies: - request-promise-core "1.1.3" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.87.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -4968,6 +5534,13 @@ resolve-cwd@^2.0.0: dependencies: resolve-from "^3.0.0" +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + resolve-dir@^1.0.0, resolve-dir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" @@ -4981,23 +5554,26 @@ resolve-from@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" integrity sha1-six699nWiBvItuZTM17rywoYh0g= +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@1.x, resolve@^1.10.0, resolve@^1.3.2: - version "1.15.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" - integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== - dependencies: - path-parse "^1.0.6" - resolve@^1.1.6, resolve@^1.20.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" @@ -5006,6 +5582,15 @@ resolve@^1.1.6, resolve@^1.20.0: is-core-module "^2.2.0" path-parse "^1.0.6" +resolve@^1.10.0, resolve@^1.3.2: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + dependencies: + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -5018,6 +5603,13 @@ rimraf@^2.5.4, rimraf@^2.6.3: dependencies: glob "^7.1.3" +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -5038,16 +5630,16 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - -safe-buffer@^5.1.1, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-buffer@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -5060,7 +5652,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -5080,10 +5672,12 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" schema-utils@^1.0.0: version "1.0.0" @@ -5094,17 +5688,24 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +semver@7.x, semver@^7.3.2: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + semver@^4.3.6: version "4.3.6" resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" integrity sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto= -semver@^6.0.0, semver@^6.2.0: +semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -5158,11 +5759,23 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + shelljs@^0.8.3: version "0.8.4" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" @@ -5172,26 +5785,35 @@ shelljs@^0.8.3: interpret "^1.0.0" rechoir "^0.6.2" -shellwords@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -sisteransi@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.4.tgz#386713f1ef688c7c0304dc4c0632898941cad2e3" - integrity sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig== +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== slash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + slide@~1.1.3: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" @@ -5244,9 +5866,9 @@ source-map-resolve@^0.5.0: urix "^0.1.0" source-map-support@^0.5.6: - version "0.5.16" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" - integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -5260,9 +5882,9 @@ source-map-support@~0.5.12: source-map "^0.6.0" source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" @@ -5274,6 +5896,11 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + spdx-compare@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/spdx-compare/-/spdx-compare-0.1.2.tgz#b06af3ea34af7437d91a9f449eaf2d2e93c3c8fb" @@ -5283,17 +5910,17 @@ spdx-compare@^0.1.2: spdx-ranges "^1.0.0" spdx-correct@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" - integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== spdx-expression-parse@^1.0.0: version "1.0.4" @@ -5301,9 +5928,9 @@ spdx-expression-parse@^1.0.0: integrity sha1-m98vIOH0DtRH++JzJmGR/O1RYmw= spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" @@ -5316,9 +5943,9 @@ spdx-expression-validate@^1.0.1: spdx-expression-parse "^1.0.0" spdx-license-ids@^3.0.0: - version "3.0.5" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" - integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + version "3.0.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== spdx-ranges@^1.0.0: version "1.0.1" @@ -5359,21 +5986,6 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - ssri@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" @@ -5382,9 +5994,18 @@ ssri@^6.0.1: figgy-pudding "^3.5.1" stack-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" - integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== + version "1.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.5.tgz#a19b0b01947e0029c8e451d5d61a498f5bb1471b" + integrity sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ== + dependencies: + escape-string-regexp "^2.0.0" + +stack-utils@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== + dependencies: + escape-string-regexp "^2.0.0" standard-version@9.1.1: version "9.1.1" @@ -5415,11 +6036,6 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - stream-browserify@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" @@ -5452,13 +6068,13 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== -string-length@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" - integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== dependencies: - astral-regex "^1.0.0" - strip-ansi "^4.0.0" + char-regex "^1.0.2" + strip-ansi "^6.0.0" string-width@^1.0.1: version "1.0.2" @@ -5487,21 +6103,21 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimleft@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" - integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - function-bind "^1.1.1" -string.prototype.trimright@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" - integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - function-bind "^1.1.1" string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" @@ -5529,13 +6145,6 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" @@ -5562,11 +6171,21 @@ strip-bom@^3.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-indent@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" @@ -5581,6 +6200,11 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -5595,7 +6219,34 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" -symbol-tree@^3.2.2: +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== @@ -5605,6 +6256,14 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + terser-webpack-plugin@^1.4.3: version "1.4.5" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" @@ -5629,25 +6288,24 @@ terser@^4.1.2: source-map "~0.6.1" source-map-support "~0.5.12" -test-exclude@^5.2.3: - version "5.2.3" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" - integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g== +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== dependencies: - glob "^7.1.3" + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^2.0.0" text-extensions@^1.0.0: version "1.9.0" resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== -throat@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" - integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= +throat@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== through2@^2.0.0: version "2.0.5" @@ -5683,10 +6341,10 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" -tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== to-arraybuffer@^1.0.0: version "1.0.1" @@ -5730,20 +6388,21 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== dependencies: - psl "^1.1.28" + psl "^1.1.33" punycode "^2.1.1" + universalify "^0.1.2" -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== dependencies: - punycode "^2.1.0" + punycode "^2.1.1" trim-newlines@^1.0.0: version "1.0.0" @@ -5760,21 +6419,19 @@ trim-off-newlines@^1.0.0: resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM= -ts-jest@^24.0.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869" - integrity sha512-Hb94C/+QRIgjVZlJyiWwouYUF+siNJHJHknyspaOcZ+OQAIdFG/UrdQVXw/0B8Z3No34xkUXZJpOTy9alOWdVQ== +ts-jest@^27.1.3: + version "27.1.3" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.3.tgz#1f723e7e74027c4da92c0ffbd73287e8af2b2957" + integrity sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA== dependencies: bs-logger "0.x" - buffer-from "1.x" fast-json-stable-stringify "2.x" + jest-util "^27.0.0" json5 "2.x" lodash.memoize "4.x" make-error "1.x" - mkdirp "0.x" - resolve "1.x" - semver "^5.5" - yargs-parser "10.x" + semver "7.x" + yargs-parser "20.x" ts-loader@^6.2.1: version "6.2.1" @@ -5872,18 +6529,6 @@ tty-browserify@0.0.0: resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -5891,11 +6536,21 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + type-fest@^0.18.0: version "0.18.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + type-fest@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" @@ -5906,6 +6561,13 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -5921,6 +6583,16 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.2.tgz#fe10319861bccc8682bfe2e8151fbdd8aa921c44" integrity sha512-SbMu4D2Vo95LMC/MetNaso1194M1htEA+JrqE9Hk+G2DhI+itfS9TRu9ZKeCahLDNa/J3n4MqUJ/fOHMzQpRWw== +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + underscore@1.13.1, underscore@^1.12.1: version "1.13.1" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.1.tgz#0c1c6bd2df54b6b69f2314066d65b6cde6fcf9d1" @@ -5950,6 +6622,11 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -5964,9 +6641,9 @@ upath@^1.1.1: integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" @@ -5999,14 +6676,15 @@ util-extend@^1.0.1: integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8= util.promisify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" - integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + version "1.1.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" + integrity sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.17.2" + for-each "^0.3.3" has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.0" + object.getownpropertydescriptors "^2.1.1" util@0.10.3: version "0.10.3" @@ -6022,16 +6700,20 @@ util@^0.11.0: dependencies: inherits "2.0.3" -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - v8-compile-cache@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== +v8-to-istanbul@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" + integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -6040,33 +6722,31 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -w3c-hr-time@^1.0.1: +w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== dependencies: browser-process-hrtime "^1.0.0" +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== + dependencies: + xml-name-validator "^3.0.0" + walker@^1.0.7, walker@~1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== dependencies: - makeerror "1.0.x" + makeerror "1.0.12" watchpack-chokidar2@^2.0.1: version "2.0.1" @@ -6086,10 +6766,15 @@ watchpack@^1.7.4: chokidar "^3.4.1" watchpack-chokidar2 "^2.0.1" -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== webpack-cli@^3.1.2: version "3.3.12" @@ -6145,48 +6830,57 @@ webpack@^4.27.1: watchpack "^1.7.4" webpack-sources "^1.4.1" -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: +whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== dependencies: iconv-lite "0.4.24" -whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: +whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== -whatwg-url@^6.4.1: - version "6.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" - integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== +whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" + lodash "^4.7.0" + tr46 "^2.1.0" + webidl-conversions "^6.1.0" -whatwg-url@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" - integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1: +which@^1.2.14, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + window-size@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" @@ -6240,27 +6934,31 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -write-file-atomic@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" - integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== dependencies: - graceful-fs "^4.1.11" imurmurhash "^0.1.4" + is-typedarray "^1.0.0" signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" -ws@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== - dependencies: - async-limiter "~1.0.0" +ws@^7.4.6: + version "7.5.7" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" + integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -6272,9 +6970,9 @@ y18n@^3.2.0: integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== y18n@^5.0.5: version "5.0.5" @@ -6291,20 +6989,10 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yargs-parser@10.x: - version "10.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" - integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== - dependencies: - camelcase "^4.1.0" - -yargs-parser@^13.1.1: - version "13.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" - integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" +yargs-parser@20.x: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== yargs-parser@^13.1.2: version "13.1.2" @@ -6319,22 +7007,6 @@ yargs-parser@^20.2.2, yargs-parser@^20.2.3: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== -yargs@^13.3.0: - version "13.3.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" - integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.1" - yargs@^13.3.2: version "13.3.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" @@ -6351,7 +7023,7 @@ yargs@^13.3.2: y18n "^4.0.0" yargs-parser "^13.1.2" -yargs@^16.0.0: +yargs@^16.0.0, yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== From 39e1503f167db1e381bd8b152b1b3b146cb8e5fd Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 9 Mar 2022 15:12:00 +0100 Subject: [PATCH 060/184] SOF-789 Creating graphic pices now correctly get their metaData about sisyfos when the object is initialized --- .../helpers/graphics/internal/index.ts | 21 +++++++ .../helpers/graphics/pilot/index.ts | 10 +++ src/tv2-common/helpers/sisyfos.ts | 17 +---- .../pieces/__tests__/grafikViz.spec.ts | 63 ++++++++++++++++++- .../helpers/pieces/__tests__/telefon.spec.ts | 8 ++- src/tv2_afvd_showstyle/parts/grafik.ts | 5 +- .../parts/OfftubeGrafik.ts | 13 +--- 7 files changed, 105 insertions(+), 32 deletions(-) diff --git a/src/tv2-common/helpers/graphics/internal/index.ts b/src/tv2-common/helpers/graphics/internal/index.ts index b49967874..ed137b227 100644 --- a/src/tv2-common/helpers/graphics/internal/index.ts +++ b/src/tv2-common/helpers/graphics/internal/index.ts @@ -14,6 +14,7 @@ import { IsStickyIdent, literal, PartDefinition, + PieceMetaData, TV2BlueprintConfig } from 'tv2-common' import { AbstractLLayer, AdlibTags, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' @@ -99,6 +100,11 @@ export function CreateInternalGraphic( sourceLayerId, outputLayerId: SharedOutputLayers.OVERLAY, lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), expectedDuration: 5000, tags: [AdlibTags.ADLIB_KOMMENTATOR], content: _.clone(content), @@ -120,6 +126,11 @@ export function CreateInternalGraphic( ? {} : { expectedDuration: CreateTimingGraphic(config, parsedCue).duration || GetDefaultOut(config) }), lifespan: GetInfiniteModeForGraphic(engine, config, parsedCue, isStickyIdent), + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), content: _.clone(content) }) ) @@ -137,6 +148,11 @@ export function CreateInternalGraphic( outputLayerId, sourceLayerId, lifespan: GetInfiniteModeForGraphic(engine, config, parsedCue, isStickyIdent), + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), content: _.clone(content) }) pieces.push(piece) @@ -154,6 +170,11 @@ export function CreateInternalGraphic( enable: { ...CreateTimingGraphic(config, parsedCue, true) }, // Allow default out for visual representation sourceLayerId: SharedSourceLayers.PgmGraphicsIdent, lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), content: { timelineObjects: [ literal({ diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index e4c43bf69..70936ffeb 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -25,6 +25,8 @@ import { IsTargetingTLF, IsTargetingWall, literal, + PieceMetaData, + SisyfosPersistMetaData, TV2BlueprintConfig } from 'tv2-common' import { @@ -156,6 +158,11 @@ export function CreateFullPiece( sourceLayerId: GetSourceLayer(engine), adlibPreroll: config.studio.VizPilotGraphics.PrerollDuration, lifespan: GetInfiniteModeForGraphic(engine, config, parsedCue), + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), content: CreateFullContent(config, context, part, settings, parsedCue, engine, adlib), tags: [GetTagForFull(segmentExternalId, parsedCue.graphic.vcpid), TallyTags.FULL_IS_LIVE] }) @@ -195,6 +202,9 @@ export function CreateFullDataStore( name: parsedCue.graphic.name, vcpid: parsedCue.graphic.vcpid, segmentExternalId + }), + sisyfosPersistMetaData: literal({ + sisyfosLayers: [] }) }, content, diff --git a/src/tv2-common/helpers/sisyfos.ts b/src/tv2-common/helpers/sisyfos.ts index c0309db32..91170f09e 100644 --- a/src/tv2-common/helpers/sisyfos.ts +++ b/src/tv2-common/helpers/sisyfos.ts @@ -1,5 +1,5 @@ -import { IBlueprintPiece, IStudioUserContext, SourceLayerType, Timeline, TSR } from '@tv2media/blueprints-integration' -import { FindSourceInfoStrict, PieceMetaData, SisyfosEVSSource, SisyfosPersistMetaData, SourceInfo } from 'tv2-common' +import { IStudioUserContext, SourceLayerType, Timeline, TSR } from '@tv2media/blueprints-integration' +import { FindSourceInfoStrict, SisyfosEVSSource, SourceInfo } from 'tv2-common' import { literal } from '../util' export function GetSisyfosTimelineObjForEkstern( @@ -117,16 +117,3 @@ export function GetSisyfosTimelineObjForEVS(sourceInfo: SourceInfo, vo: boolean) } }) } - -export function MapSisyfosPersistMetaDataToPieces(pieces: IBlueprintPiece[]) { - return pieces.map(piece => { - const metaData = piece.metaData as PieceMetaData - piece.metaData = { - ...metaData, - sisyfosPersistMetaData: literal({ - sisyfosLayers: [] - }) - } - return piece - }) -} 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 84c602471..8baf6a411 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -14,7 +14,8 @@ import { GraphicInternal, GraphicPilot, literal, - PartDefinitionKam + PartDefinitionKam, + PieceMetaData } from 'tv2-common' import { AbstractLLayer, AdlibTags, CueType, GraphicLLayer, PartType, SharedOutputLayers } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' @@ -125,6 +126,11 @@ describe('grafik piece', () => { duration: 4000 }, lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, content: literal>({ @@ -191,6 +197,11 @@ describe('grafik piece', () => { externalId: partId, name: 'bund - Odense\n - Copenhagen', lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, uniquenessId: 'gfx_bund - Odense\n - Copenhagen_studio0_graphicsLower_overlay_commentator', @@ -226,6 +237,11 @@ describe('grafik piece', () => { externalId: partId, name: 'bund - Odense\n - Copenhagen', lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, uniquenessId: 'gfx_bund - Odense\n - Copenhagen_studio0_graphicsLower_overlay_flow', @@ -297,6 +313,11 @@ describe('grafik piece', () => { externalId: partId, name: 'bund - Odense\n - Copenhagen', lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, uniquenessId: 'gfx_bund - Odense\n - Copenhagen_studio0_graphicsLower_overlay_commentator', @@ -332,6 +353,11 @@ describe('grafik piece', () => { externalId: partId, name: 'bund - Odense\n - Copenhagen', lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, uniquenessId: 'gfx_bund - Odense\n - Copenhagen_studio0_graphicsLower_overlay_flow', @@ -406,6 +432,11 @@ describe('grafik piece', () => { duration: 4000 }, lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, content: literal>({ @@ -479,6 +510,11 @@ describe('grafik piece', () => { start: 10000 }, lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, content: literal>({ @@ -549,6 +585,11 @@ describe('grafik piece', () => { start: 0 }, lifespan: PieceLifespan.OutOnSegmentEnd, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsIdentPersistent, content: literal>({ @@ -582,6 +623,11 @@ describe('grafik piece', () => { start: 0 }, lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsIdent, content: { @@ -644,6 +690,11 @@ describe('grafik piece', () => { duration: 4000 }, lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsIdent, content: literal>({ @@ -710,6 +761,11 @@ describe('grafik piece', () => { externalId: partId, name: 'tlftoptlive - Line 1\n - Line 2', lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsTop, expectedDuration: 5000, @@ -745,6 +801,11 @@ describe('grafik piece', () => { externalId: partId, name: 'tlftoptlive - Line 1\n - Line 2', lifespan: PieceLifespan.OutOnSegmentEnd, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsTop, expectedDuration: 4000, 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 02fb57f96..0326e2f21 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -14,7 +14,8 @@ import { CueDefinitionTelefon, GraphicInternal, literal, - PartDefinitionKam + PartDefinitionKam, + PieceMetaData } from 'tv2-common' import { CueType, GraphicLLayer, PartType, SharedOutputLayers } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' @@ -106,6 +107,11 @@ describe('telefon', () => { outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsTLF, lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), content: literal>({ fileName: 'bund', path: 'bund', diff --git a/src/tv2_afvd_showstyle/parts/grafik.ts b/src/tv2_afvd_showstyle/parts/grafik.ts index 2d3769086..da9b6040f 100644 --- a/src/tv2_afvd_showstyle/parts/grafik.ts +++ b/src/tv2_afvd_showstyle/parts/grafik.ts @@ -12,7 +12,6 @@ import { ApplyFullGraphicPropertiesToPart, GraphicIsPilot, literal, - MapSisyfosPersistMetaDataToPieces, PartDefinition, PartTime } from 'tv2-common' @@ -35,7 +34,7 @@ export function CreatePartGrafik( }) const adLibPieces: IBlueprintAdLibPiece[] = [] - let pieces: IBlueprintPiece[] = [] + const pieces: IBlueprintPiece[] = [] const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] @@ -65,8 +64,6 @@ export function CreatePartGrafik( part.invalid = true } - pieces = MapSisyfosPersistMetaDataToPieces(pieces) - return { part, adLibPieces, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts index 920f3600c..fa4867c0f 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts @@ -6,14 +6,7 @@ import { IBlueprintPiece, ISegmentUserContext } from '@tv2media/blueprints-integration' -import { - AddScript, - ApplyFullGraphicPropertiesToPart, - literal, - MapSisyfosPersistMetaDataToPieces, - PartDefinition, - PartTime -} from 'tv2-common' +import { AddScript, ApplyFullGraphicPropertiesToPart, literal, PartDefinition, PartTime } from 'tv2-common' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' @@ -36,7 +29,7 @@ export function OfftubeCreatePartGrafik( }) const adLibPieces: IBlueprintAdLibPiece[] = [] - let pieces: IBlueprintPiece[] = [] + const pieces: IBlueprintPiece[] = [] const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] @@ -64,8 +57,6 @@ export function OfftubeCreatePartGrafik( part.invalid = true } - pieces = MapSisyfosPersistMetaDataToPieces(pieces) - return { part, adLibPieces, From 7ac2ea83a1ff8978c938fc4e2ecae5ffb0a18525 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Thu, 10 Mar 2022 14:03:11 +0100 Subject: [PATCH 061/184] SOF-789 Removing Skype layers since they arent used --- src/tv2-common/blueprintConfig.ts | 1 - src/tv2-common/content/dve.ts | 2 +- src/tv2-common/cues/ekstern.ts | 2 +- src/tv2-common/helpers/sisyfos.ts | 2 +- src/tv2-common/sources.ts | 7 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 2 - .../__tests__/config-manifest.spec.ts | 1 - src/tv2_afvd_studio/config-manifests.ts | 74 ------------------- src/tv2_afvd_studio/helpers/sources.ts | 1 - src/tv2_afvd_studio/migrations/index.ts | 14 +--- src/tv2_afvd_studio/migrations/util.ts | 1 - .../__tests__/config-manifest.spec.ts | 1 - src/tv2_offtube_studio/config-manifests.ts | 3 - src/tv2_offtube_studio/migrations/index.ts | 34 ++++++++- 14 files changed, 36 insertions(+), 109 deletions(-) diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 1c8aa026f..738bd246b 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -78,7 +78,6 @@ export interface TV2StudioConfigBase { StudioMics: string[] SourcesRM: TableConfigItemSourceMappingWithSisyfos[] SourcesFeed: TableConfigItemSourceMappingWithSisyfos[] - SourcesSkype: TableConfigItemSourceMappingWithSisyfos[] SourcesCam: TableConfigItemSourceMappingWithSisyfos[] PreventOverlayWithFull?: boolean ServerPostrollDuration: number diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 694eb6fb4..0482a6fc6 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -353,7 +353,7 @@ export function MakeContentDVE2< audioEnable ) ) - } else if (sourceType.match(/LIVE/i) || sourceType.match(/FEED/i) || sourceType.match(/SKYPE/i)) { + } else if (sourceType.match(/LIVE/i) || sourceType.match(/FEED/i)) { const sourceInfoLive = FindSourceInfoStrict(context, config.sources, SourceLayerType.REMOTE, mappingFrom.source) if (sourceInfoLive === undefined) { context.notifyUserWarning(`Invalid source: ${mappingFrom.source}`) diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index 866233e66..5aff49b9c 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -58,7 +58,7 @@ export function EvaluateEksternBase< adlib?: boolean, rank?: number ) { - const matchesEksternSource = /^(?:LIVE|SKYPE|FEED) ?([^\s]+)(?: (.+))?$/i + const matchesEksternSource = /^(?:LIVE|FEED) ?([^\s]+)(?: (.+))?$/i const eksternProps = parsedCue.source.match(matchesEksternSource) if (!eksternProps) { context.notifyUserWarning(`No source entered for EKSTERN`) diff --git a/src/tv2-common/helpers/sisyfos.ts b/src/tv2-common/helpers/sisyfos.ts index 91170f09e..0dacb7836 100644 --- a/src/tv2-common/helpers/sisyfos.ts +++ b/src/tv2-common/helpers/sisyfos.ts @@ -39,7 +39,7 @@ export function GetSisyfosTimelineObjForEkstern( } export function GetLayersForEkstern(context: IStudioUserContext, sources: SourceInfo[], sourceType: string) { - const eksternProps = sourceType.match(/^(?:LIVE|SKYPE|FEED) ?([^\s]+)(?: (.+))?$/i) + const eksternProps = sourceType.match(/^(?:LIVE|FEED) ?([^\s]+)(?: (.+))?$/i) const eksternLayers: string[] = [] if (eksternProps) { const sourceInfo = FindSourceInfoStrict(context, sources, SourceLayerType.REMOTE, sourceType) diff --git a/src/tv2-common/sources.ts b/src/tv2-common/sources.ts index b6881a20f..b79e0d6e9 100644 --- a/src/tv2-common/sources.ts +++ b/src/tv2-common/sources.ts @@ -95,17 +95,14 @@ export function FindSourceInfo(sources: SourceInfo[], type: SourceInfoType, id: const remoteName = id .replace(/VO/i, '') .replace(/\s/g, '') - .match(/^(?:LIVE|SKYPE|FEED) ?(.+).*$/i) + .match(/^(?:LIVE|FEED) ?(.+).*$/i) if (!remoteName) { return undefined } if (id.match(/^LIVE/i)) { return _.find(sources, s => s.type === type && s.id === remoteName[1]) - } else if (id.match(/^FEED/i)) { - return _.find(sources, s => s.type === type && s.id === `F${remoteName[1]}`) } else { - // Skype - return _.find(sources, s => s.type === type && s.id === `S${remoteName[1]}`) + return _.find(sources, s => s.type === type && s.id === `F${remoteName[1]}`) } case SourceLayerType.LOCAL: const dpName = id diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index 2d3590a40..eb54550a0 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -10,7 +10,6 @@ function getSisyfosLayers(configName: string, id: string): string[] { return [] case 'SourcesRM': case 'SourcesFeed': - case 'SourcesSkype': return ['sisyfos_source_live_' + id] case 'SourcesDelayedPlayback': return ['sisyfos_source_evs_' + id] @@ -80,7 +79,6 @@ export const defaultStudioConfig: StudioConfig = { true ), // TODO: prepareConfig is legacy code, refactor when refactoring FindSourceInfo - SourcesSkype: prepareConfig('1:1,2:2,3:3,4:4,5:5,6:6,7:7', 'SourcesSkype', false), SourcesRM: prepareConfig('1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,10:10', 'SourcesRM', false, true), 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), SourcesDelayedPlayback: prepareConfig('1:5,2:5', 'SourcesDelayedPlayback', false), diff --git a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts index 8f6533b0f..6f0b3286c 100644 --- a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts @@ -33,7 +33,6 @@ const blankStudioConfig: StudioConfig = { SourcesCam: [], SourcesRM: [], SourcesFeed: [], - SourcesSkype: [], SourcesDelayedPlayback: [], ABMediaPlayers: [], StudioMics: [], diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index f9431525c..4b9d42d67 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -213,79 +213,6 @@ export const manifestAFVDSourcesDelayedPlayback = MakeConfigForSources('DelayedP } ]) -export const manifestAFVDSourcesSkype = MakeConfigForSources('Skype', 'Skype', false, true, [ - { - _id: '', - SourceName: '1', - AtemSource: 1, - SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_1], - StudioMics: false - }, - { - _id: '', - SourceName: '2', - AtemSource: 2, - SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_2], - StudioMics: false - }, - { - _id: '', - SourceName: '3', - AtemSource: 3, - SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_3], - StudioMics: false - }, - { - _id: '', - SourceName: '4', - AtemSource: 4, - SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_4], - StudioMics: false - }, - { - _id: '', - SourceName: '5', - AtemSource: 5, - SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_5], - StudioMics: false - }, - { - _id: '', - SourceName: '6', - AtemSource: 6, - SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_6], - StudioMics: false - }, - { - _id: '', - SourceName: '7', - AtemSource: 7, - SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_7], - StudioMics: false - }, - { - _id: '', - SourceName: '8', - AtemSource: 8, - SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_8], - StudioMics: false - }, - { - _id: '', - SourceName: '9', - AtemSource: 9, - SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_9], - StudioMics: false - }, - { - _id: '', - SourceName: '10', - AtemSource: 10, - SisyfosLayers: [SisyfosLLAyer.SisyfosSourceLive_10], - StudioMics: false - } -]) - export const manifestAFVDSourcesABMediaPlayers: ConfigManifestEntryTable = { id: 'ABMediaPlayers', name: 'Media Players inputs', @@ -351,7 +278,6 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ manifestAFVDSourcesRM, manifestAFVDSourcesFeed, manifestAFVDSourcesDelayedPlayback, - manifestAFVDSourcesSkype, manifestAFVDSourcesABMediaPlayers, manifestAFVDStudioMics, manifestAFVDDownstreamKeyers, diff --git a/src/tv2_afvd_studio/helpers/sources.ts b/src/tv2_afvd_studio/helpers/sources.ts index 733e51681..e2845adb9 100644 --- a/src/tv2_afvd_studio/helpers/sources.ts +++ b/src/tv2_afvd_studio/helpers/sources.ts @@ -16,7 +16,6 @@ export function parseSources(studioConfig: StudioConfig): SourceInfo[] { ...ParseMappingTable(studioConfig.SourcesFeed, SourceLayerType.REMOTE, 'F'), ...ParseMappingTable(studioConfig.SourcesRM, SourceLayerType.REMOTE), ...ParseMappingTable(studioConfig.SourcesCam, SourceLayerType.CAMERA), - ...ParseMappingTable(studioConfig.SourcesSkype, SourceLayerType.REMOTE, 'S'), ...ParseMappingTable(studioConfig.SourcesDelayedPlayback, SourceLayerType.LOCAL, 'DP') ] } diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index d3783feb5..bbc74c86a 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -10,14 +10,12 @@ import { SetLayerNamesToDefaults } from 'tv2-common' import { GraphicLLayer } from 'tv2-constants' -import * as _ from 'underscore' import { manifestAFVDDownstreamKeyers, manifestAFVDSourcesABMediaPlayers, manifestAFVDSourcesCam, manifestAFVDSourcesDelayedPlayback, manifestAFVDSourcesRM, - manifestAFVDSourcesSkype, manifestAFVDStudioMics } from '../config-manifests' import { CasparLLayer, SisyfosLLAyer } from '../layers' @@ -71,16 +69,6 @@ export const studioMigrations: MigrationStepStudio[] = literal Date: Thu, 10 Mar 2022 15:51:40 +0100 Subject: [PATCH 062/184] feat: SOF-752 add viz show lifecycle timeline objects --- src/tv2-common/getSegment.ts | 9 ++-- .../helpers/graphics/internal/index.ts | 51 ++++++++++++++++++- src/tv2-common/types/inews.ts | 1 + src/tv2-constants/enums.ts | 5 +- src/tv2_afvd_showstyle/getSegment.ts | 35 ++++++++++++- .../migrations/sourcelayer-defaults.ts | 18 +++++++ .../migrations/mappings-defaults.ts | 12 +++++ 7 files changed, 124 insertions(+), 7 deletions(-) diff --git a/src/tv2-common/getSegment.ts b/src/tv2-common/getSegment.ts index a559041ca..702625d9d 100644 --- a/src/tv2-common/getSegment.ts +++ b/src/tv2-common/getSegment.ts @@ -8,7 +8,7 @@ import { import { assertUnreachable, GetNextPartCue, - INewsStory, + INewsPayload, IsTargetingFull, literal, ParseBody, @@ -109,7 +109,8 @@ export function getSegmentBase< ingestSegment: IngestSegment, showStyleOptions: GetSegmentShowstyleOptions ): BlueprintResultSegment { - const iNewsStory: INewsStory | undefined = ingestSegment.payload?.iNewsStory + const segmentPayload = ingestSegment.payload as INewsPayload | undefined + const iNewsStory = segmentPayload?.iNewsStory const segment = literal({ name: ingestSegment.name || '', metaData: {}, @@ -121,7 +122,7 @@ export function getSegmentBase< }) const config = showStyleOptions.getConfig(context) - if (!iNewsStory || iNewsStory.meta.float === 'float' || !iNewsStory.body) { + if (!segmentPayload || !iNewsStory || iNewsStory.meta.float === 'float' || !iNewsStory.body) { segment.isHidden = true return { segment, @@ -383,7 +384,7 @@ export function getSegmentBase< actualPart.invalid = false } - if (ingestSegment.payload?.untimed) { + if (segmentPayload?.untimed) { actualPart.untimed = true } diff --git a/src/tv2-common/helpers/graphics/internal/index.ts b/src/tv2-common/helpers/graphics/internal/index.ts index b49967874..6b23ef098 100644 --- a/src/tv2-common/helpers/graphics/internal/index.ts +++ b/src/tv2-common/helpers/graphics/internal/index.ts @@ -1,4 +1,5 @@ import { + BlueprintResultPart, IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, @@ -16,7 +17,7 @@ import { PartDefinition, TV2BlueprintConfig } from 'tv2-common' -import { AbstractLLayer, AdlibTags, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' +import { AbstractLLayer, AdlibTags, GraphicLLayer, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' import _ = require('underscore') import { CreateTimingGraphic, @@ -173,3 +174,51 @@ export function CreateInternalGraphic( } } } + +export function CreateShowLifecyclePieces( + config: TV2BlueprintConfig, + part: BlueprintResultPart, + initializeShowIds: string[], + cleanupShowIds: string[] +) { + if (config.studio.GraphicsType === 'VIZ') { + part.pieces.push( + literal({ + externalId: part.part.externalId, + name: 'GFX Show Init', + enable: { start: 0 }, + outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SharedSourceLayers.GraphicsShowLifecycle, + lifespan: PieceLifespan.OutOnSegmentChange, + content: { + timelineObjects: [ + literal({ + id: '', + enable: { + while: '1' + }, + layer: GraphicLLayer.GraphicLLayerInitialize, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.INITIALIZE_SHOWS, + showIds: initializeShowIds + } + }), + literal({ + id: '', + enable: { + while: '1' + }, + layer: GraphicLLayer.GraphicLLayerCleanup, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.CLEANUP_SHOWS, + showIds: cleanupShowIds + } + }) + ] + } + }) + ) + } +} diff --git a/src/tv2-common/types/inews.ts b/src/tv2-common/types/inews.ts index 5773bcc87..936e592e2 100644 --- a/src/tv2-common/types/inews.ts +++ b/src/tv2-common/types/inews.ts @@ -36,6 +36,7 @@ export interface INewsStory { export interface INewsPayload { iNewsStory?: INewsStory untimed?: boolean + initializeShows?: string[] } export type UnparsedCue = string[] | null diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index ea46f41d7..b55a31f43 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -171,7 +171,9 @@ export enum GraphicLLayer { GraphicLLayerAdLibs = 'graphic_adlibs', // <= viz_layer_adlibs GraphicLLayerWall = 'graphic_wall', // <= viz_layer_wall GraphicLLayerLocators = 'graphic_locators', - GraphicLLayerConcept = 'graphic_concept' + GraphicLLayerConcept = 'graphic_concept', + GraphicLLayerInitialize = 'graphic_initialize', + GraphicLLayerCleanup = 'graphic_cleanup' } export enum AbstractLLayer { @@ -247,6 +249,7 @@ export enum SharedSourceLayers { // Other / sec / manus PgmScript = 'studio0_script', PgmAudioBed = 'studio0_audio_bed', + GraphicsShowLifecycle = 'studio0_graphic_show_lifecycle', // AUX AuxMixMinus = 'studio0_aux_mix_minus' diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index 85727b197..edd74ac39 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -9,7 +9,7 @@ import { TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { getSegmentBase, literal } from 'tv2-common' +import { CreateShowLifecyclePieces, getSegmentBase, INewsPayload, literal } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import * as _ from 'underscore' import { StudioConfig } from '../tv2_afvd_studio/helpers/config' @@ -27,6 +27,7 @@ import { CreatePartUnknown } from './parts/unknown' import { postProcessPartTimelineObjects } from './postProcessTimelineObjects' export function getSegment(context: ISegmentUserContext, ingestSegment: IngestSegment): BlueprintResultSegment { const config = getConfig(context) + const segmentPayload = ingestSegment.payload as INewsPayload | undefined const result: BlueprintResultSegment = getSegmentBase(context, ingestSegment, { getConfig, @@ -45,6 +46,10 @@ export function getSegment(context: ISegmentUserContext, ingestSegment: IngestSe const blueprintParts = result.parts + if (segmentPayload) { + insertSpecialPieces(config, blueprintParts, segmentPayload) + } + postProcessPartTimelineObjects(context, config, blueprintParts) return { @@ -97,3 +102,31 @@ export function CreatePartContinuity(config: ShowStyleConfig, ingestSegment: Ing adLibPieces: [] }) } + +function insertSpecialPieces( + config: ShowStyleConfig, + blueprintParts: BlueprintResultPart[], + segmentPayload: INewsPayload +) { + // Insert cue-independent pieces + + if (!blueprintParts.length || config.studio.GraphicsType !== 'VIZ') { + return + } + + const graphicsSetupsToInitialize = segmentPayload?.initializeShows + if (graphicsSetupsToInitialize) { + const showsToInitialize = new Set() + const allShows = new Set() + config.showStyle.GraphicsSetups.forEach(graphicsSetup => { + allShows.add(graphicsSetup.FullShowId) + allShows.add(graphicsSetup.OvlShowId) + if (graphicsSetupsToInitialize.includes(graphicsSetup.INewsCode)) { + showsToInitialize.add(graphicsSetup.FullShowId) + showsToInitialize.add(graphicsSetup.OvlShowId) + } + }) + 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/migrations/sourcelayer-defaults.ts b/src/tv2_afvd_showstyle/migrations/sourcelayer-defaults.ts index 049fec20d..86805f009 100644 --- a/src/tv2_afvd_showstyle/migrations/sourcelayer-defaults.ts +++ b/src/tv2_afvd_showstyle/migrations/sourcelayer-defaults.ts @@ -149,6 +149,24 @@ const OVERLAY: ISourceLayer[] = [ isHidden: false, allowDisable: true, onPresenterScreen: false + }, + { + _id: SourceLayer.GraphicsShowLifecycle, + _rank: 60, + name: 'GFX Show Lifecycle', + abbreviation: '', + type: SourceLayerType.GRAPHICS, + exclusiveGroup: '', + isRemoteInput: false, + isGuestInput: false, + isClearable: false, + + isSticky: false, + + isQueueable: false, + isHidden: true, + allowDisable: true, + onPresenterScreen: false } ] diff --git a/src/tv2_afvd_studio/migrations/mappings-defaults.ts b/src/tv2_afvd_studio/migrations/mappings-defaults.ts index 8478e3fb1..b921ada69 100644 --- a/src/tv2_afvd_studio/migrations/mappings-defaults.ts +++ b/src/tv2_afvd_studio/migrations/mappings-defaults.ts @@ -542,6 +542,18 @@ export const MAPPINGS_GRAPHICS: BlueprintMappings = { deviceId: 'viz0', layerName: 'Override Concept', lookahead: LookaheadMode.NONE + }), + [GraphicLLayer.GraphicLLayerInitialize]: literal({ + device: DeviceType.VIZMSE, + deviceId: 'viz0', + layerName: 'GFX Show Initialization', + lookahead: LookaheadMode.NONE + }), + [GraphicLLayer.GraphicLLayerCleanup]: literal({ + device: DeviceType.VIZMSE, + deviceId: 'viz0', + layerName: 'GFX Show Cleanup', + lookahead: LookaheadMode.NONE }) } From b38e2d810730cfb6e88be8ff3fac8219288c6e86 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Mon, 14 Mar 2022 15:21:42 +0100 Subject: [PATCH 063/184] SOF-790 exexuteActionFadeDownPersistedAudioLevels now fade down all sticky Sisyfos layers --- src/tv2-common/actions/executeAction.ts | 61 ++++++++++++++++++++----- src/tv2-constants/enums.ts | 4 +- src/tv2_afvd_showstyle/getRundown.ts | 2 +- 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 2c07d37a5..653d677fa 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -10,6 +10,7 @@ import { IBlueprintPieceDB, IBlueprintPieceGeneric, IBlueprintPieceInstance, + IBlueprintResolvedPieceInstance, IShowStyleUserContext, PieceLifespan, SourceLayerType, @@ -83,7 +84,6 @@ import { import { assertUnreachable } from '../util' import { ActionCommentatorSelectJingle, - ActionFadeDownPersistedAudioLevels, ActionRecallLastDVE, ActionRecallLastLive, ActionSelectJingle, @@ -102,6 +102,8 @@ const STOPPABLE_GRAPHICS_LAYERS = [ SharedSourceLayers.PgmGraphicsTLF ] +const FADE_SISYFOS_LEVELS_PIECE_NAME = 'fadeDown' + export interface ActionExecutionSettings< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase @@ -246,7 +248,7 @@ export function executeAction< executeActionRecallLastDVE(context, settings, actionId, userData as ActionRecallLastDVE) break case AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS: - executeActionFadeDownPersistedAudioLevels(context, settings, actionId, userData as ActionFadeDownPersistedAudioLevels) + executeActionFadeDownPersistedAudioLevels(context, settings) break default: assertUnreachable(actionId) @@ -1790,16 +1792,51 @@ function executeActionRecallLastDVE< } function executeActionFadeDownPersistedAudioLevels< -StudioConfig extends TV2StudioConfigBase, -ShowStyleConfig extends TV2BlueprintConfigBase ->( - context: ITV2ActionExecutionContext, - _settings: ActionExecutionSettings, - _actionId: string, - _userData: ActionFadeDownPersistedAudioLevels -) { - // TODO: Use enum instead of string literal. - context.stopPiecesOnLayers(['sisyfos_persisted_levels']) + StudioConfig extends TV2StudioConfigBase, + ShowStyleConfig extends TV2BlueprintConfigBase +>(context: ITV2ActionExecutionContext, _settings: ActionExecutionSettings) { + const fadeSisyfosMetaData = createFadeSisyfosLevelsMetaData(context) + const resetSisyfosPersistedLevelsPiece: IBlueprintPiece = { + externalId: 'fadeSisyfosPersistedLevelsDown', + name: FADE_SISYFOS_LEVELS_PIECE_NAME, + outputLayerId: '', + sourceLayerId: '', + enable: { start: 'now' }, + lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sisyfosPersistMetaData: fadeSisyfosMetaData + }), + content: { + timelineObjects: [] + } + } + context.insertPiece('current', resetSisyfosPersistedLevelsPiece) +} + +function createFadeSisyfosLevelsMetaData(context: ITV2ActionExecutionContext) { + const resolvedPieceInstances: IBlueprintResolvedPieceInstance[] = context.getResolvedPieceInstances('current') + const emptySisyfosMetaData: SisyfosPersistMetaData = { + sisyfosLayers: [] + } + if (resolvedPieceInstances.length === 0) { + return emptySisyfosMetaData + } + + const latestPiece: IBlueprintResolvedPieceInstance = resolvedPieceInstances + .filter(piece => piece.piece.name !== FADE_SISYFOS_LEVELS_PIECE_NAME) + .sort((a, b) => b.resolvedStart - a.resolvedStart)[0] + + const latestPieceMetaData = latestPiece.piece.metaData as PieceMetaData + + if (!latestPieceMetaData || !latestPieceMetaData.sisyfosPersistMetaData) { + return emptySisyfosMetaData + } + + return { + sisyfosLayers: latestPieceMetaData.sisyfosPersistMetaData.sisyfosLayers, + wantsToPersistAudio: latestPieceMetaData.sisyfosPersistMetaData.wantsToPersistAudio, + acceptPersistAudio: false + } } function scheduleLastPlayedDVE< diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index c213221e3..7a08e051a 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -91,7 +91,7 @@ export enum AdlibTags { ADLIB_RECALL_LAST_DVE = 'recall_last_dve', ADLIB_SELECT_DVE_LAYOUT = 'select_dve_layout', ADLIB_TAKE_WITH_TRANSITION = 'take_with_transition', - ADLIB_FADE_DOWN_PERSISTED_AUDIO_LEVELS = 'fade_down_persisted_audio_levels', + ADLIB_FADE_DOWN_PERSISTED_AUDIO_LEVELS = 'fade_down_persisted_audio_levels' } /** @@ -135,7 +135,7 @@ export enum AdlibActionType { TAKE_WITH_TRANSITION = 'take_with_transition', RECALL_LAST_LIVE = 'recall_last_live', RECALL_LAST_DVE = 'recall_last_dve', - FADE_DOWN_PERSISTED_AUDIO_LEVELS = 'fade_down_persisted_audio_levels', + FADE_DOWN_PERSISTED_AUDIO_LEVELS = 'fade_down_persisted_audio_levels' } export enum TallyTags { diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 5be517114..7676c2153 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -790,7 +790,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri literal({ actionId: AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS, userData: literal({ - type: AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS, + type: AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS }), userDataManifest: {}, display: { From 032185923b63539416131446c695564b36b48e4e Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 16 Mar 2022 09:23:02 +0100 Subject: [PATCH 064/184] SOF-790 Minor refactor according to PR comments --- .../__tests__/onTimelineGenerate.spec.ts | 31 +++++++------------ src/tv2-common/migrations/sourceManifest.ts | 2 +- src/tv2-common/onTimelineGenerate.ts | 15 ++++----- 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/src/tv2-common/__tests__/onTimelineGenerate.spec.ts b/src/tv2-common/__tests__/onTimelineGenerate.spec.ts index db4602305..9c3b39682 100644 --- a/src/tv2-common/__tests__/onTimelineGenerate.spec.ts +++ b/src/tv2-common/__tests__/onTimelineGenerate.spec.ts @@ -1,6 +1,11 @@ import { IBlueprintPieceDB, IBlueprintResolvedPieceInstance, TSR } from '@tv2media/blueprints-integration' import { SisyfosLLAyer } from '../../tv2_afvd_studio/layers' -import { createSisyfosPersistedLevelsTimelineObject, SisyfosPersistMetaData } from '../onTimelineGenerate' +import { + createSisyfosPersistedLevelsTimelineObject, + PieceMetaData, + SisyfosPersistMetaData +} from '../onTimelineGenerate' +import { literal } from '../util' const LAYER_THAT_WANTS_TO_BE_PERSISTED = 'layerThatWantsToBePersisted' const LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY: SisyfosPersistMetaData['sisyfosLayers'] = [ @@ -45,18 +50,6 @@ describe('onTimelineGenerate', () => { expect(result.content.channels[0].isPgm).toEqual(1) }) - it('should persist a VO layer, isPgm is 2', () => { - const sisyfosLayersThatWantsToBePersisted: SisyfosPersistMetaData['sisyfosLayers'] = [ - 'layerThatWantsToBePersisted VO' - ] - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ - createPieceInstance('currentPiece VO', 10, undefined, true, true) - ] - - const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, sisyfosLayersThatWantsToBePersisted) - expect(result.content.channels[0].isPgm).toEqual(2) - }) - it('should persist only current piece layer when piece wants to persist but dont accept', () => { const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ createPieceInstance('previousPiece', 0, 10, true, true), @@ -302,22 +295,20 @@ function createPieceInstance( start: number, duration: number | undefined, wantToPersistAudio: boolean, - acceptPersistAudio: boolean, - isExecuteAction?: boolean + acceptPersistAudio: boolean ): IBlueprintResolvedPieceInstance { return { resolvedStart: start, resolvedDuration: duration, piece: { name, - metaData: { + metaData: literal({ sisyfosPersistMetaData: { sisyfosLayers: [name], wantsToPersistAudio: wantToPersistAudio, - acceptPersistAudio, - isExecuteAction - } as SisyfosPersistMetaData - } + acceptPersistAudio + } + }) } as IBlueprintPieceDB } as IBlueprintResolvedPieceInstance } diff --git a/src/tv2-common/migrations/sourceManifest.ts b/src/tv2-common/migrations/sourceManifest.ts index 009611bb6..068e29085 100644 --- a/src/tv2-common/migrations/sourceManifest.ts +++ b/src/tv2-common/migrations/sourceManifest.ts @@ -60,7 +60,7 @@ export function MakeConfigForSources( ? [ literal({ id: 'WantsToPersistAudio', - name: 'Wants to persist audio in Studio', + name: 'Wants To Persist Audio', description: 'Tells the system that it wants to persist the audio. If the next piece accepts persistence, the audio will be persisted', type: ConfigManifestEntryType.BOOLEAN, diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index 2d065753f..347d45121 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -199,9 +199,7 @@ export function getEndStateForPart( }, mediaPlayerSessions: {} } - const previousPartEndState = !!previousPartInstance - ? (previousPartInstance.previousPartEndState as Partial) - : undefined + const previousPartEndState = previousPartInstance?.previousPartEndState as Partial const activePieces = resolvedPieces.filter( p => @@ -279,18 +277,21 @@ export function createSisyfosPersistedLevelsTimelineObject( channels: layersToPersist.map(layer => { return { mappedLayer: layer, - isPgm: layer.includes('VO') ? 2 : 1 + isPgm: 1 } }) } }) } -function findLayersToPersist(pieces: IBlueprintResolvedPieceInstance[], sisyfosLayersThatWantsToBePersisted: string[]) { +function findLayersToPersist( + pieces: IBlueprintResolvedPieceInstance[], + sisyfosLayersThatWantsToBePersisted: string[] +): string[] { const sortedPieces = pieces .filter(piece => { const metaData = piece.piece.metaData as PieceMetaData - return !(!metaData || !metaData.sisyfosPersistMetaData) + return metaData?.sisyfosPersistMetaData }) .sort((a, b) => b.resolvedStart - a.resolvedStart) @@ -329,7 +330,7 @@ function doesMetaDataNotAcceptPersistAudioDeep(metaData: SisyfosPersistMetaData) if (!metaData.acceptPersistAudio) { return true } - if (!!metaData.previousPersistMetaDataForCurrentPiece) { + if (metaData.previousPersistMetaDataForCurrentPiece) { return doesMetaDataNotAcceptPersistAudioDeep(metaData.previousPersistMetaDataForCurrentPiece) } return false From 7c3e37f02fc7e5773127795b6311f867ae104dab Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 16 Mar 2022 09:23:02 +0100 Subject: [PATCH 065/184] SOF-790 Minor refactor according to PR comments --- .../__tests__/onTimelineGenerate.spec.ts | 31 +++++++------------ src/tv2-common/migrations/sourceManifest.ts | 2 +- src/tv2-common/onTimelineGenerate.ts | 15 ++++----- 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/src/tv2-common/__tests__/onTimelineGenerate.spec.ts b/src/tv2-common/__tests__/onTimelineGenerate.spec.ts index db4602305..9c3b39682 100644 --- a/src/tv2-common/__tests__/onTimelineGenerate.spec.ts +++ b/src/tv2-common/__tests__/onTimelineGenerate.spec.ts @@ -1,6 +1,11 @@ import { IBlueprintPieceDB, IBlueprintResolvedPieceInstance, TSR } from '@tv2media/blueprints-integration' import { SisyfosLLAyer } from '../../tv2_afvd_studio/layers' -import { createSisyfosPersistedLevelsTimelineObject, SisyfosPersistMetaData } from '../onTimelineGenerate' +import { + createSisyfosPersistedLevelsTimelineObject, + PieceMetaData, + SisyfosPersistMetaData +} from '../onTimelineGenerate' +import { literal } from '../util' const LAYER_THAT_WANTS_TO_BE_PERSISTED = 'layerThatWantsToBePersisted' const LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY: SisyfosPersistMetaData['sisyfosLayers'] = [ @@ -45,18 +50,6 @@ describe('onTimelineGenerate', () => { expect(result.content.channels[0].isPgm).toEqual(1) }) - it('should persist a VO layer, isPgm is 2', () => { - const sisyfosLayersThatWantsToBePersisted: SisyfosPersistMetaData['sisyfosLayers'] = [ - 'layerThatWantsToBePersisted VO' - ] - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ - createPieceInstance('currentPiece VO', 10, undefined, true, true) - ] - - const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, sisyfosLayersThatWantsToBePersisted) - expect(result.content.channels[0].isPgm).toEqual(2) - }) - it('should persist only current piece layer when piece wants to persist but dont accept', () => { const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ createPieceInstance('previousPiece', 0, 10, true, true), @@ -302,22 +295,20 @@ function createPieceInstance( start: number, duration: number | undefined, wantToPersistAudio: boolean, - acceptPersistAudio: boolean, - isExecuteAction?: boolean + acceptPersistAudio: boolean ): IBlueprintResolvedPieceInstance { return { resolvedStart: start, resolvedDuration: duration, piece: { name, - metaData: { + metaData: literal({ sisyfosPersistMetaData: { sisyfosLayers: [name], wantsToPersistAudio: wantToPersistAudio, - acceptPersistAudio, - isExecuteAction - } as SisyfosPersistMetaData - } + acceptPersistAudio + } + }) } as IBlueprintPieceDB } as IBlueprintResolvedPieceInstance } diff --git a/src/tv2-common/migrations/sourceManifest.ts b/src/tv2-common/migrations/sourceManifest.ts index 009611bb6..068e29085 100644 --- a/src/tv2-common/migrations/sourceManifest.ts +++ b/src/tv2-common/migrations/sourceManifest.ts @@ -60,7 +60,7 @@ export function MakeConfigForSources( ? [ literal({ id: 'WantsToPersistAudio', - name: 'Wants to persist audio in Studio', + name: 'Wants To Persist Audio', description: 'Tells the system that it wants to persist the audio. If the next piece accepts persistence, the audio will be persisted', type: ConfigManifestEntryType.BOOLEAN, diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index 2d065753f..347d45121 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -199,9 +199,7 @@ export function getEndStateForPart( }, mediaPlayerSessions: {} } - const previousPartEndState = !!previousPartInstance - ? (previousPartInstance.previousPartEndState as Partial) - : undefined + const previousPartEndState = previousPartInstance?.previousPartEndState as Partial const activePieces = resolvedPieces.filter( p => @@ -279,18 +277,21 @@ export function createSisyfosPersistedLevelsTimelineObject( channels: layersToPersist.map(layer => { return { mappedLayer: layer, - isPgm: layer.includes('VO') ? 2 : 1 + isPgm: 1 } }) } }) } -function findLayersToPersist(pieces: IBlueprintResolvedPieceInstance[], sisyfosLayersThatWantsToBePersisted: string[]) { +function findLayersToPersist( + pieces: IBlueprintResolvedPieceInstance[], + sisyfosLayersThatWantsToBePersisted: string[] +): string[] { const sortedPieces = pieces .filter(piece => { const metaData = piece.piece.metaData as PieceMetaData - return !(!metaData || !metaData.sisyfosPersistMetaData) + return metaData?.sisyfosPersistMetaData }) .sort((a, b) => b.resolvedStart - a.resolvedStart) @@ -329,7 +330,7 @@ function doesMetaDataNotAcceptPersistAudioDeep(metaData: SisyfosPersistMetaData) if (!metaData.acceptPersistAudio) { return true } - if (!!metaData.previousPersistMetaDataForCurrentPiece) { + if (metaData.previousPersistMetaDataForCurrentPiece) { return doesMetaDataNotAcceptPersistAudioDeep(metaData.previousPersistMetaDataForCurrentPiece) } return false From 44b0f96f069a4eca86130929853c1583c9fa1737 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 16 Mar 2022 11:06:28 +0100 Subject: [PATCH 066/184] refactor: SOF-752 code style --- src/tv2-common/helpers/graphics/index.ts | 2 +- src/tv2_afvd_showstyle/getRundown.ts | 72 +++++++++++++----------- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/tv2-common/helpers/graphics/index.ts b/src/tv2-common/helpers/graphics/index.ts index aee52ff31..21b9eb1a9 100644 --- a/src/tv2-common/helpers/graphics/index.ts +++ b/src/tv2-common/helpers/graphics/index.ts @@ -150,7 +150,7 @@ export function CreateGraphicBaseline(config: TV2BlueprintConfig): TSR.TSRTimeli } } -export function findShowId(config: TV2BlueprintConfig, engine: GraphicEngine) { +export function findShowId(config: TV2BlueprintConfig, engine: GraphicEngine): string { const graphicsSetup = config.selectedGraphicsSetup switch (engine) { case 'FULL': diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 5706d3932..44d223c3d 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -12,6 +12,7 @@ import { PieceLifespan, PlaylistTimingType, SourceLayerType, + TimelineObjectCoreExt, TSR, WithTimeline } from '@tv2media/blueprints-integration' @@ -528,8 +529,39 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint }) // viz styles and dve backgrounds - adlibItems.push( - literal({ + 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: GraphicLLayer.GraphicLLayerDesign, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, + templateName: 'BG_LOADER_SC', + templateData: [], + showId: config.selectedGraphicsSetup.OvlShowId + } + }) + ) + } + const adLibPiece: IBlueprintAdLibPiece = { _rank: 301, externalId: 'dve-design-sc', name: 'DVE Design SC', @@ -541,38 +573,12 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint fileName: 'BG_LOADER_SC', path: 'BG_LOADER_SC', ignoreMediaObjectStatus: true, - timelineObjects: _.compact([ - config.studio.GraphicsType === 'VIZ' - ? literal({ - id: '', - enable: { start: 0 }, - priority: 110, - layer: GraphicLLayer.GraphicLLayerDesign, - content: { - deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, - templateName: 'BG_LOADER_SC', - templateData: [], - showId: config.selectedGraphicsSetup.OvlShowId - } - }) - : null, - 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 - } - }) - ]) + timelineObjects }) - }) - ) + } + return adLibPiece + } + adlibItems.push(makeDesignAdLib()) adlibItems.push({ externalId: 'stopAudioBed', From 8f6e01b2510cad48162ac22641f396e37a9feae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Wed, 16 Mar 2022 13:05:13 +0100 Subject: [PATCH 067/184] fix: updated layout of commentator shelf for qboxes --- shelf-layouts/Kommentator.json | 133 ++++++++++++++++++++++----------- 1 file changed, 89 insertions(+), 44 deletions(-) diff --git a/shelf-layouts/Kommentator.json b/shelf-layouts/Kommentator.json index 3a4601482..2f4916e87 100644 --- a/shelf-layouts/Kommentator.json +++ b/shelf-layouts/Kommentator.json @@ -11,7 +11,7 @@ "rank": 0, "rundownBaseline": false, "default": false, - "url": "https://multiview.sofsrv04-od.tv2.local/", + "url": "http://multiview.sofqbXX-od.tv2.local/", "width": -1, "height": -1, "x": 0, @@ -43,7 +43,8 @@ "tags": [ "kommentator" ], - "showThumbnailsInList": true + "showThumbnailsInList": true, + "hideDuplicates": false }, { "_id": "QZ6xdWdFmm5Mu7ZKJ", @@ -67,7 +68,7 @@ "showAsTimeline": false, "overflowHorizontally": false, "sourceLayerIds": [ - "studio0_selected_clip", + "studio0_offtube_clip", "studio0_offtube_jingle", "studio0_clip", "studio0_jingle" @@ -98,11 +99,12 @@ "kommentator" ], "sourceLayerIds": [ - "studio0_selected_voiceover", - "studio0_selected_clip", + "studio0_offtube_voiceover", + "studio0_offtube_clip", "studio0_clip", "studio0_voiceover" - ] + ], + "showThumbnailsInList": true }, { "_id": "YC7RNPTbkXd5wnagp", @@ -125,7 +127,9 @@ ], "tags": [ "kommentator" - ] + ], + "hideDuplicates": true, + "lineBreak": "\n - " }, { "_id": "icuekg6wiJxejsYsZ", @@ -136,34 +140,20 @@ "rank": 0, "rundownBaseline": false, "default": false, - "x": 23, - "width": 11, + "x": 20, + "width": 14, "height": 7, "sourceLayerIds": [ "studio0_offtube_graphicsFull", - "studio0_full" + "studio0_full", + "studio0_selected_graphicsFull", + "studio0_pilot" ], "tags": [ "kommentator" ], "showThumbnailsInList": true }, - { - "_id": "LiFso7gPYn2SPwHwg", - "type": "external_frame", - "name": "Sisyfos", - "currentSegment": false, - "displayStyle": "buttons", - "rank": 0, - "rundownBaseline": false, - "default": false, - "x": 0, - "y": 0, - "width": 22, - "height": 7, - "url": "https://sisyfos.sofsrv04-od.tv2.local?minimonitor=1", - "scale": 0.85 - }, { "_id": "6GDpdq547HjjZL9YK", "type": "adlib_region", @@ -180,8 +170,11 @@ "windowNumber": 1, "role": "take", "scale": 1, + "thumbnailPriorityNextPieces": true, + "hideThumbnailsForActivePieces": true, "thumbnailSourceLayerIds": [ - "studio0_full" + "studio0_full", + "studio0_jingle" ] }, { @@ -198,12 +191,17 @@ "width": 22, "height": -11, "y": -2, - "role": "program" + "role": "program", + "thumbnailSourceLayerIds": [ + "studio0_offtube_jingle" + ], + "showBlackIfNoThumbnailPiece": false, + "hideThumbnailsForActivePieces": true }, { "_id": "ooCyWRXeDE6ufYWWQ", "type": "adlib_region", - "name": "Cam 1", + "name": "KAM 1", "currentSegment": false, "displayStyle": "buttons", "rank": 0, @@ -221,7 +219,7 @@ { "_id": "PDKiKYeYB7zcAq6Lp", "type": "adlib_region", - "name": "LIVE 1 (WF 1) st/5.1", + "name": "FEED 1", "currentSegment": false, "displayStyle": "buttons", "rank": 0, @@ -240,7 +238,7 @@ { "_id": "AMrCRTvefKDS6qogp", "type": "adlib_region", - "name": "LIVE 2 (WF 2) stereo", + "name": "FEED 2", "currentSegment": false, "displayStyle": "buttons", "rank": 0, @@ -259,7 +257,7 @@ { "_id": "HLzpg7NdLk6tdYZfT", "type": "adlib_region", - "name": "LIVE 3 (REP)", + "name": "LIVE 1", "currentSegment": false, "displayStyle": "buttons", "rank": 0, @@ -292,9 +290,8 @@ "offtube_set_full_next" ], "role": "queue", - "thumbnailSourceLayerIds": [ - "studio0_offtube_graphicsFull" - ] + "thumbnailPriorityNextPieces": false, + "showBlackIfNoThumbnailPiece": false }, { "_id": "PDKiKYeYB7zcAq6La", @@ -314,8 +311,10 @@ "offtube_set_jingle_next" ], "thumbnailSourceLayerIds": [ - "studio0_offtube_jingle" - ] + "studio0_offtube_jingle", + "studio0_jingle" + ], + "showBlackIfNoThumbnailPiece": true }, { "_id": "AMrCRTvefKDS6qoga", @@ -356,9 +355,29 @@ "role": "queue" }, { - "_id": "CfmFqiSNavu8w5nW9", + "_id": "zavcByHmMndMvZjCA", + "type": "piece_countdown", + "name": "Piece Countdown", + "currentSegment": false, + "displayStyle": "buttons", + "rank": 0, + "rundownBaseline": false, + "showThumbnailsInList": false, + "default": false, + "x": 26, + "y": 25, + "sourceLayerIds": [ + "studio0_offtube_clip", + "studio0_offtube_voiceover", + "studio0_clip", + "studio0_voiceover", + "studio0_jingle" + ] + }, + { + "_id": "get64yaM3ZzT9aRs3", "type": "next_info", - "name": "NEXT", + "name": " NÆSTE INEWS CUE : ", "currentSegment": false, "displayStyle": "buttons", "rank": 0, @@ -366,13 +385,13 @@ "showThumbnailsInList": false, "hideDuplicates": false, "default": false, - "x": 1, + "showSegmentName": true, + "hideForDynamicallyInsertedParts": true, + "x": 1.3, "y": 24.9, "width": 22, "scale": 0.8, - "showSegmentName": true, - "showPartTitle": false, - "hideForDynamicallyInsertedParts": true + "showPartTitle": true } ], "type": "dashboard_layout", @@ -386,9 +405,31 @@ "width": 14, "height": 1.3, "labelToggled": "Deactivate" + }, + { + "_id": "m4ouEduSAvNXm6WZh", + "label": "▲ Previous Segment", + "type": "move_previous_segment", + "x": 0, + "y": 0, + "width": 6, + "height": 1, + "labelToggled": "" + }, + { + "_id": "FgyddcqkKFhSQeMBS", + "label": "▼ Next Segment", + "type": "move_next_segment", + "x": 0, + "y": 2, + "width": 6, + "height": 1, + "labelToggled": "" } ], "exposeAsStandalone": true, + "regionId": "shelf_layouts", + "exposeAsShelf": true, "iconColor": "#8e44ad", "icon": { "prefix": "fas", @@ -400,5 +441,9 @@ "f3c9", "M336 192h-16c-8.84 0-16 7.16-16 16v48c0 74.8-64.49 134.82-140.79 127.38C96.71 376.89 48 317.11 48 250.3V208c0-8.84-7.16-16-16-16H16c-8.84 0-16 7.16-16 16v40.16c0 89.64 63.97 169.55 152 181.69V464H96c-8.84 0-16 7.16-16 16v16c0 8.84 7.16 16 16 16h160c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16h-56v-33.77C285.71 418.47 352 344.9 352 256v-48c0-8.84-7.16-16-16-16zM176 352c53.02 0 96-42.98 96-96h-85.33c-5.89 0-10.67-3.58-10.67-8v-16c0-4.42 4.78-8 10.67-8H272v-32h-85.33c-5.89 0-10.67-3.58-10.67-8v-16c0-4.42 4.78-8 10.67-8H272v-32h-85.33c-5.89 0-10.67-3.58-10.67-8v-16c0-4.42 4.78-8 10.67-8H272c0-53.02-42.98-96-96-96S80 42.98 80 96v160c0 53.02 42.98 96 96 96z" ] - } + }, + "openByDefault": true, + "startingHeight": 80, + "disableContextMenu": true, + "regionId": "shelf_layouts" } \ No newline at end of file From 05cf9298fb376ce5a65ecbcc047c01b002f610ce Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 16 Mar 2022 16:04:23 +0100 Subject: [PATCH 068/184] SOF-789 Sisyfos levels are no longer persisted across segments --- package.json | 2 +- src/tv2-common/onTimelineGenerate.ts | 23 ++++++++++++++--------- yarn.lock | 8 ++++---- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 6b73888fe..a424b3537 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "webpack-cli": "^3.1.2" }, "dependencies": { - "@tv2media/blueprints-integration": "v1.37.1-in-testing.1", + "@tv2media/blueprints-integration": "1.37.1", "@tv2media/timeline-state-resolver-types": "^1.0.0-release37.6", "underscore": "^1.12.1" } diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index 347d45121..255669620 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -34,6 +34,7 @@ export interface MediaPlayerClaim { export interface TimelinePersistentStateExt { activeMediaPlayers: { [player: string]: MediaPlayerClaim[] | undefined } + isNewSegment?: boolean } export interface TimelineBlueprintExt extends TimelineObjectCoreExt { @@ -88,16 +89,19 @@ export function onTimelineGenerate< ): Promise { const previousPartEndState2 = previousPartEndState as PartEndStateExt | undefined const persistentState: TimelinePersistentStateExt = { - activeMediaPlayers: {} + activeMediaPlayers: {}, + isNewSegment: context.previousPartInstance?.segmentId !== context.currentPartInstance?.segmentId } const config = getConfig(context) - const sisyfosPersistedLevelsTimelineObject = createSisyfosPersistedLevelsTimelineObject( - resolvedPieces, - previousPartEndState2 ? previousPartEndState2.sisyfosPersistMetaData.sisyfosLayers : [] - ) - timeline.push(sisyfosPersistedLevelsTimelineObject) + if (!persistentState.isNewSegment) { + const sisyfosPersistedLevelsTimelineObject = createSisyfosPersistedLevelsTimelineObject( + resolvedPieces, + previousPartEndState2 ? previousPartEndState2.sisyfosPersistMetaData.sisyfosLayers : [] + ) + timeline.push(sisyfosPersistedLevelsTimelineObject) + } const previousPersistentState2 = previousPersistentState as TimelinePersistentStateExt | undefined @@ -189,7 +193,7 @@ function processServerLookaheads( export function getEndStateForPart( _context: IRundownContext, _previousPersistentState: TimelinePersistentState | undefined, - previousPartInstance: IBlueprintPartInstance | undefined, + partInstance: IBlueprintPartInstance | undefined, resolvedPieces: IBlueprintResolvedPieceInstance[], time: number ): PartEndState { @@ -199,7 +203,7 @@ export function getEndStateForPart( }, mediaPlayerSessions: {} } - const previousPartEndState = previousPartInstance?.previousPartEndState as Partial + const previousPartEndState = partInstance?.previousPartEndState as Partial const activePieces = resolvedPieces.filter( p => @@ -209,9 +213,10 @@ export function getEndStateForPart( (!p.piece.enable.duration || p.piece.enable.start + (p.piece.enable.duration as number) >= time) ) + const previousPersistentState: TimelinePersistentStateExt = _previousPersistentState as TimelinePersistentStateExt endState.sisyfosPersistMetaData.sisyfosLayers = findLayersToPersist( activePieces, - previousPartEndState && previousPartEndState.sisyfosPersistMetaData + !previousPersistentState.isNewSegment && previousPartEndState && previousPartEndState.sisyfosPersistMetaData ? previousPartEndState.sisyfosPersistMetaData.sisyfosLayers : [] ) diff --git a/yarn.lock b/yarn.lock index 89703c85c..ed6415bd4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -568,10 +568,10 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== -"@tv2media/blueprints-integration@v1.37.1-in-testing.1": - version "1.37.1-in-testing.1" - resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-1.37.1-in-testing.1.tgz#92b11e3c4402650858db539fa5bf7ce7d04b992d" - integrity sha512-hJ+10Gt8xkbwjyGuPWnIecAxbE6a9oiClWW+Dr/9GXjU8z5FcnbKLGXdX/qnbGAMGTU+pNaPo/QUEbyAuFENrQ== +"@tv2media/blueprints-integration@1.37.1": + version "1.37.1" + resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-1.37.1.tgz#7a14af5f1db1eab8da8277f72836d385cd7d9573" + integrity sha512-ylZuzBjPcXmQMsZYBXGYd1Yd7kGWxHYuGr+HQgEvtphKFKQMhLfbQV0AOZ38BlpC6qKoZcYuANuLFcMTk3Vb9g== dependencies: moment "2.29.1" timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@1.0.0-release37" From 3dec814f2e39c74bbd17eb8c4b1c3431576043ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Fri, 18 Mar 2022 09:44:31 +0100 Subject: [PATCH 069/184] fix: execute adlibs on the hidden source layer ident_persistent as actions --- package.json | 2 +- shelf-layouts/Kommentator.json | 1 + shelf-layouts/Q flow.json | 1 + shelf-layouts/Shortcuts and adlib scroll.json | 1 + src/tv2-common/actions/actionTypes.ts | 8 +- src/tv2-common/actions/executeAction.ts | 63 ++++ .../helpers/graphics/caspar/index.ts | 8 +- .../helpers/graphics/internal/index.ts | 351 +++++++++++++----- src/tv2-common/helpers/graphics/viz/index.ts | 4 +- .../converters/__tests__/cue-parser.spec.ts | 49 +++ src/tv2-constants/enums.ts | 3 +- 11 files changed, 382 insertions(+), 109 deletions(-) diff --git a/package.json b/package.json index bf627add7..31bbcb401 100644 --- a/package.json +++ b/package.json @@ -63,4 +63,4 @@ "@tv2media/timeline-state-resolver-types": "^1.0.0-release37.6", "underscore": "^1.12.1" } -} \ No newline at end of file +} diff --git a/shelf-layouts/Kommentator.json b/shelf-layouts/Kommentator.json index 7b2e41377..f0e7337a7 100644 --- a/shelf-layouts/Kommentator.json +++ b/shelf-layouts/Kommentator.json @@ -120,6 +120,7 @@ "displayTakeButtons": true, "sourceLayerIds": [ "studio0_graphicsIdent", + "studio0_graphicsIdent_persistent", "studio0_graphicsTop", "studio0_graphicsLower" ], diff --git a/shelf-layouts/Q flow.json b/shelf-layouts/Q flow.json index 2cb2b5379..debebf807 100644 --- a/shelf-layouts/Q flow.json +++ b/shelf-layouts/Q flow.json @@ -33,6 +33,7 @@ "studio0_offtube_graphicsFull", "studio0_offtube_aux_studio_screen", "studio0_graphicsIdent", + "studio0_graphicsIdent_persistent", "studio0_graphicsTop", "studio0_graphicsLower", "studio0_graphicsHeadline", diff --git a/shelf-layouts/Shortcuts and adlib scroll.json b/shelf-layouts/Shortcuts and adlib scroll.json index 7fec243f4..b2235cc2b 100755 --- a/shelf-layouts/Shortcuts and adlib scroll.json +++ b/shelf-layouts/Shortcuts and adlib scroll.json @@ -31,6 +31,7 @@ "studio0_audio_bed", "studio0_graphicsTop", "studio0_graphicsIdent", + "studio0_graphicsIdent_persistent", "studio0_graphicsTema", "studio0_graphicsHeadline", "studio0_overlay", diff --git a/src/tv2-common/actions/actionTypes.ts b/src/tv2-common/actions/actionTypes.ts index 307070ec2..d73442025 100644 --- a/src/tv2-common/actions/actionTypes.ts +++ b/src/tv2-common/actions/actionTypes.ts @@ -1,7 +1,7 @@ import { SourceLayerType } from '@tv2media/blueprints-integration' import { AdlibActionType } from 'tv2-constants' import { DVEConfigInput } from '../helpers' -import { CueDefinitionDVE, PartDefinition } from '../inewsConversion' +import { CueDefinitionDVE, CueDefinitionGraphic, GraphicInternal, PartDefinition } from '../inewsConversion' interface ActionBase { type: AdlibActionType @@ -124,6 +124,11 @@ export interface ActionRecallLastDVE extends ActionBase { type: AdlibActionType.RECALL_LAST_DVE } +export interface ActionPlayGraphics extends ActionBase { + type: AdlibActionType.PLAY_GRAPHICS + graphic: CueDefinitionGraphic +} + export type TV2AdlibAction = | ActionSelectServerClip | ActionSelectDVE @@ -140,3 +145,4 @@ export type TV2AdlibAction = | ActionTakeWithTransition | ActionRecallLastLive | ActionRecallLastDVE + | ActionPlayGraphics diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 37fbd300f..75ef27361 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -26,11 +26,13 @@ import { ActionCutSourceToBox, ActionCutToCamera, ActionCutToRemote, + ActionPlayGraphics, ActionSelectDVE, ActionSelectDVELayout, ActionSelectFullGrafik, ActionSelectServerClip, CalculateTime, + CreateContinuationPieceForIdentPersistent, CreateFullPiece, CreatePartServerBase, CueDefinition, @@ -46,11 +48,16 @@ import { GetDVETemplate, GetEksternMetaData, GetFullGrafikTemplateName, + GetInfiniteModeForGraphic, + getInternalGraphic, + getInternalGraphicContent, GetLayersForCamera, GetLayersForEkstern, GetSisyfosTimelineObjForCamera, GetSisyfosTimelineObjForEkstern, GraphicPilot, + InternalGraphic, + IsTargetingOVL, ITV2ActionExecutionContext, literal, MakeContentDVE2, @@ -249,6 +256,9 @@ export function executeAction< case AdlibActionType.RECALL_LAST_DVE: executeActionRecallLastDVE(context, settings, actionId, userData as ActionRecallLastDVE) break + case AdlibActionType.PLAY_GRAPHICS: + executeActionPlayGraphics(context, settings, actionId, userData as ActionPlayGraphics) + break default: assertUnreachable(actionId) break @@ -1837,6 +1847,59 @@ function executeActionRecallLastDVE< } } +function executeActionPlayGraphics< + StudioConfig extends TV2StudioConfigBase, + ShowStyleConfig extends TV2BlueprintConfigBase +>( + context: ITV2ActionExecutionContext, + settings: ActionExecutionSettings, + actionId: string, + _userData: ActionPlayGraphics +) { + const internalGraphic: InternalGraphic = getInternalGraphic( + settings.getConfig(context), + _userData.graphic, + true, + undefined, + undefined, + undefined, + undefined + ) + const pieces: IBlueprintPiece[] = [] + if (IsTargetingOVL(_userData.graphic.target)) { + const externalId = context.getPartInstance('current')?.part.externalId ?? generateExternalId(context, actionId, []) + + const content: IBlueprintPiece['content'] = getInternalGraphicContent(internalGraphic) + + const piece = literal({ + externalId, + name: internalGraphic.name, + enable: { start: 0 }, + outputLayerId: internalGraphic.outputLayerId, + sourceLayerId: internalGraphic.sourceLayerId, + lifespan: GetInfiniteModeForGraphic( + internalGraphic.engine, + internalGraphic.config, + internalGraphic.parsedCue, + internalGraphic.isStickyIdent + ), + content: _.clone(content) + }) + pieces.push(piece) + + if ( + internalGraphic.sourceLayerId === SharedSourceLayers.PgmGraphicsIdentPersistent && + (piece.lifespan === PieceLifespan.OutOnSegmentEnd || piece.lifespan === PieceLifespan.OutOnShowStyleEnd) && + internalGraphic.isStickyIdent + ) { + pieces.push(CreateContinuationPieceForIdentPersistent(piece, internalGraphic)) + } + } + pieces.forEach((piece: IBlueprintPiece) => { + context.insertPiece('current', piece) + }) +} + function scheduleLastPlayedDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase diff --git a/src/tv2-common/helpers/graphics/caspar/index.ts b/src/tv2-common/helpers/graphics/caspar/index.ts index 661cc79a0..db0ce6b6f 100644 --- a/src/tv2-common/helpers/graphics/caspar/index.ts +++ b/src/tv2-common/helpers/graphics/caspar/index.ts @@ -31,11 +31,11 @@ export interface CasparPilotGeneratorSettings { export function GetInternalGraphicContentCaspar( config: TV2BlueprintConfig, - part: Readonly, + part: Readonly | undefined, engine: GraphicEngine, parsedCue: CueDefinitionGraphic, isIdentGraphic: boolean, - partDefinition: PartDefinition, + partDefinition: PartDefinition | undefined, mappedTemplate: string, adlib: boolean ): IBlueprintPiece['content'] { @@ -117,11 +117,11 @@ export function GetPilotGraphicContentCaspar( function CasparOverlayTimeline( config: TV2BlueprintConfig, - part: Readonly, + part: Readonly | undefined, engine: GraphicEngine, parsedCue: CueDefinitionGraphic, isIdentGrafik: boolean, - partDefinition: PartDefinition, + partDefinition: PartDefinition | undefined, mappedTemplate: string, adlib: boolean ): TSR.TSRTimelineObj[] { diff --git a/src/tv2-common/helpers/graphics/internal/index.ts b/src/tv2-common/helpers/graphics/internal/index.ts index b49967874..7f7e429ca 100644 --- a/src/tv2-common/helpers/graphics/internal/index.ts +++ b/src/tv2-common/helpers/graphics/internal/index.ts @@ -8,15 +8,24 @@ import { TSR } from '@tv2media/blueprints-integration' import { + ActionPlayGraphics, CueDefinitionGraphic, GetDefaultOut, GraphicInternal, IsStickyIdent, literal, PartDefinition, + t, TV2BlueprintConfig } from 'tv2-common' -import { AbstractLLayer, AdlibTags, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' +import { + AbstractLLayer, + AdlibActionType, + AdlibTags, + GraphicEngine, + SharedOutputLayers, + SharedSourceLayers +} from 'tv2-constants' import _ = require('underscore') import { CreateTimingGraphic, @@ -31,6 +40,22 @@ import { import { GetInternalGraphicContentCaspar } from '../caspar' import { GetInternalGraphicContentVIZ } from '../viz' +export interface InternalGraphic { + config: TV2BlueprintConfig + part?: Readonly + parsedCue: CueDefinitionGraphic + partDefinition?: PartDefinition + adlib: boolean + mappedTemplate: string + isStickyIdent: boolean + engine: GraphicEngine + name: string + sourceLayerId: SharedSourceLayers + outputLayerId: SharedOutputLayers + partId?: string + rank?: number +} + export function CreateInternalGraphic( config: TV2BlueprintConfig, context: IShowStyleUserContext, @@ -44,20 +69,49 @@ export function CreateInternalGraphic( partDefinition: PartDefinition, rank?: number ) { - // Whether this graphic "sticks" to the source it was first assigned to. - // e.g. if this is attached to Live 1, when Live 1 is recalled later in a segment, - // this graphic should be shown again. - const isStickyIdent = IsStickyIdent(parsedCue) - - const mappedTemplate = GetFullGraphicTemplateNameFromCue(config, parsedCue) + const internalGraphic: InternalGraphic = getInternalGraphic( + config, + parsedCue, + adlib, + part, + partId, + partDefinition, + rank + ) - if (!mappedTemplate || !mappedTemplate.length) { + if (!internalGraphic.mappedTemplate || !internalGraphic.mappedTemplate.length) { context.notifyUserWarning(`No valid template found for ${parsedCue.graphic.template}`) return } + const content: IBlueprintPiece['content'] = getInternalGraphicContent(internalGraphic) + + if (adlib) { + createAdlibTargetingOVL(internalGraphic, _actions, adlibPieces, content) + createAdlib(internalGraphic, _actions, adlibPieces, content) + } else { + createPiece(internalGraphic, pieces, content) + } +} + +export function getInternalGraphic( + config: TV2BlueprintConfig, + parsedCue: CueDefinitionGraphic, + adlib: boolean, + part?: Readonly, + partId?: string, + partDefinition?: PartDefinition, + rank?: number +): InternalGraphic { + // Whether this graphic "sticks" to the source it was first assigned to. + // e.g. if this is attached to Live 1, when Live 1 is recalled later in a segment, + // this graphic should be shown again. + const isStickyIdent = IsStickyIdent(parsedCue) + const engine = parsedCue.target + const mappedTemplate = GetFullGraphicTemplateNameFromCue(config, parsedCue) + const sourceLayerId = IsTargetingTLF(engine) ? SharedSourceLayers.PgmGraphicsTLF : GetSourceLayerForGraphic(config, mappedTemplate, isStickyIdent) @@ -65,111 +119,208 @@ export function CreateInternalGraphic( const outputLayerId = IsTargetingWall(engine) ? SharedOutputLayers.SEC : SharedOutputLayers.OVERLAY const name = GraphicDisplayName(config, parsedCue) + return { + config, + part, + parsedCue, + partDefinition, + adlib, + mappedTemplate, + isStickyIdent, + engine: parsedCue.target, + name, + sourceLayerId, + outputLayerId, + partId, + rank + } +} - const content = - config.studio.GraphicsType === 'HTML' - ? GetInternalGraphicContentCaspar( - config, - part, - engine, - parsedCue, - isStickyIdent, - partDefinition, - mappedTemplate, - adlib - ) - : GetInternalGraphicContentVIZ( - config, - part, - engine, - parsedCue, - isStickyIdent, - partDefinition, - mappedTemplate, - adlib - ) +export function getInternalGraphicContent(internalGraphic: InternalGraphic): IBlueprintPiece['content'] { + return internalGraphic.config.studio.GraphicsType === 'HTML' + ? GetInternalGraphicContentCaspar( + internalGraphic.config, + internalGraphic.part, + internalGraphic.engine, + internalGraphic.parsedCue, + internalGraphic.isStickyIdent, + internalGraphic.partDefinition, + internalGraphic.mappedTemplate, + internalGraphic.adlib + ) + : GetInternalGraphicContentVIZ( + internalGraphic.config, + internalGraphic.part, + internalGraphic.engine, + internalGraphic.parsedCue, + internalGraphic.isStickyIdent, + internalGraphic.partDefinition, + internalGraphic.mappedTemplate, + internalGraphic.adlib + ) +} - if (adlib) { - if (IsTargetingOVL(engine)) { - const adLibPiece = literal({ - _rank: rank || 0, - externalId: partId, - name, - uniquenessId: `gfx_${name}_${sourceLayerId}_${outputLayerId}_commentator`, - sourceLayerId, - outputLayerId: SharedOutputLayers.OVERLAY, - lifespan: PieceLifespan.WithinPart, - expectedDuration: 5000, - tags: [AdlibTags.ADLIB_KOMMENTATOR], - content: _.clone(content), - noHotKey: true +function createAdlibTargetingOVL( + internalGraphic: InternalGraphic, + _actions: IBlueprintActionManifest[], + adlibPieces: IBlueprintAdLibPiece[], + content: IBlueprintPiece['content'] +): void { + if (IsTargetingOVL(internalGraphic.engine) && internalGraphic.isStickyIdent) { + _actions.push( + literal({ + actionId: AdlibActionType.PLAY_GRAPHICS, + userData: literal({ + type: AdlibActionType.PLAY_GRAPHICS, + graphic: internalGraphic.parsedCue + }), + userDataManifest: {}, + display: { + _rank: internalGraphic.rank || 0, + label: t(internalGraphic.name), + uniquenessId: `gfx_${internalGraphic.name}_${internalGraphic.sourceLayerId}_${internalGraphic.outputLayerId}_commentator`, + sourceLayerId: internalGraphic.sourceLayerId, + outputLayerId: SharedOutputLayers.OVERLAY, + tags: [AdlibTags.ADLIB_KOMMENTATOR], + content: _.clone(content), + noHotKey: true + } }) - adlibPieces.push(adLibPiece) - } + ) + } else if (IsTargetingOVL(internalGraphic.engine)) { + const adLibPiece = literal({ + _rank: internalGraphic.rank || 0, + externalId: internalGraphic.partId ?? '', + name: internalGraphic.name, + uniquenessId: `gfx_${internalGraphic.name}_${internalGraphic.sourceLayerId}_${internalGraphic.outputLayerId}_commentator`, + sourceLayerId: internalGraphic.sourceLayerId, + outputLayerId: SharedOutputLayers.OVERLAY, + lifespan: PieceLifespan.WithinPart, + expectedDuration: 5000, + tags: [AdlibTags.ADLIB_KOMMENTATOR], + content: _.clone(content), + noHotKey: true + }) + adlibPieces.push(adLibPiece) + } +} +function createAdlib( + internalGraphic: InternalGraphic, + _actions: IBlueprintActionManifest[], + adlibPieces: IBlueprintAdLibPiece[], + content: IBlueprintPiece['content'] +): void { + if (internalGraphic.isStickyIdent) { + _actions.push( + literal({ + actionId: AdlibActionType.PLAY_GRAPHICS, + userData: literal({ + type: AdlibActionType.PLAY_GRAPHICS, + graphic: internalGraphic.parsedCue + }), + userDataManifest: {}, + display: { + _rank: internalGraphic.rank || 0, + label: t(internalGraphic.name), + uniquenessId: `gfx_${internalGraphic.name}_${internalGraphic.sourceLayerId}_${internalGraphic.outputLayerId}_flow`, + sourceLayerId: internalGraphic.sourceLayerId, + outputLayerId: SharedOutputLayers.OVERLAY, + tags: [AdlibTags.ADLIB_FLOW_PRODUCER], + content: _.clone(content) + } + }) + ) + } else { adlibPieces.push( literal({ - _rank: rank || 0, - externalId: partId, - name, - uniquenessId: `gfx_${name}_${sourceLayerId}_${outputLayerId}_flow`, - sourceLayerId, - outputLayerId, + _rank: internalGraphic.rank || 0, + externalId: internalGraphic.partId ?? '', + name: internalGraphic.name, + uniquenessId: `gfx_${internalGraphic.name}_${internalGraphic.sourceLayerId}_${internalGraphic.outputLayerId}_flow`, + sourceLayerId: internalGraphic.sourceLayerId, + outputLayerId: internalGraphic.outputLayerId, tags: [AdlibTags.ADLIB_FLOW_PRODUCER], - ...(IsTargetingTLF(engine) || (parsedCue.end && parsedCue.end.infiniteMode) + ...(IsTargetingTLF(internalGraphic.engine) || + (internalGraphic.parsedCue.end && internalGraphic.parsedCue.end.infiniteMode) ? {} - : { expectedDuration: CreateTimingGraphic(config, parsedCue).duration || GetDefaultOut(config) }), - lifespan: GetInfiniteModeForGraphic(engine, config, parsedCue, isStickyIdent), + : { + expectedDuration: + CreateTimingGraphic(internalGraphic.config, internalGraphic.parsedCue).duration || + GetDefaultOut(internalGraphic.config) + }), + lifespan: GetInfiniteModeForGraphic( + internalGraphic.engine, + internalGraphic.config, + internalGraphic.parsedCue, + internalGraphic.isStickyIdent + ), content: _.clone(content) }) ) - } else { - const piece = literal({ - externalId: partId, - name, - ...(IsTargetingTLF(engine) || IsTargetingWall(engine) - ? { enable: { start: 0 } } - : { - enable: { - ...CreateTimingGraphic(config, parsedCue, !isStickyIdent) - } - }), - outputLayerId, - sourceLayerId, - lifespan: GetInfiniteModeForGraphic(engine, config, parsedCue, isStickyIdent), - content: _.clone(content) - }) - pieces.push(piece) - - if ( - sourceLayerId === SharedSourceLayers.PgmGraphicsIdentPersistent && - (piece.lifespan === PieceLifespan.OutOnSegmentEnd || piece.lifespan === PieceLifespan.OutOnShowStyleEnd) && - isStickyIdent - ) { - // Special case for the ident. We want it to continue to exist in case the Live gets shown again, but we dont want the continuation showing in the ui. - // So we create the normal object on a hidden layer, and then clone it on another layer without content for the ui - pieces.push( - literal({ - ...piece, - enable: { ...CreateTimingGraphic(config, parsedCue, true) }, // Allow default out for visual representation - sourceLayerId: SharedSourceLayers.PgmGraphicsIdent, - lifespan: PieceLifespan.WithinPart, + } +} + +function createPiece( + internalGraphic: InternalGraphic, + pieces: IBlueprintPiece[], + content: IBlueprintPiece['content'] +): void { + const piece = literal({ + externalId: internalGraphic.partId ?? '', + name: internalGraphic.name, + ...(IsTargetingTLF(internalGraphic.engine) || IsTargetingWall(internalGraphic.engine) + ? { enable: { start: 0 } } + : { + enable: { + ...CreateTimingGraphic(internalGraphic.config, internalGraphic.parsedCue, !internalGraphic.isStickyIdent) + } + }), + outputLayerId: internalGraphic.outputLayerId, + sourceLayerId: internalGraphic.sourceLayerId, + lifespan: GetInfiniteModeForGraphic( + internalGraphic.engine, + internalGraphic.config, + internalGraphic.parsedCue, + internalGraphic.isStickyIdent + ), + content: _.clone(content) + }) + pieces.push(piece) + + if ( + internalGraphic.sourceLayerId === SharedSourceLayers.PgmGraphicsIdentPersistent && + (piece.lifespan === PieceLifespan.OutOnSegmentEnd || piece.lifespan === PieceLifespan.OutOnShowStyleEnd) && + internalGraphic.isStickyIdent + ) { + // Special case for the ident. We want it to continue to exist in case the Live gets shown again, but we dont want the continuation showing in the ui. + // So we create the normal object on a hidden layer, and then clone it on another layer without content for the ui + pieces.push(CreateContinuationPieceForIdentPersistent(piece, internalGraphic)) + } +} + +export function CreateContinuationPieceForIdentPersistent( + piece: IBlueprintPiece, + internalGraphic: InternalGraphic +): IBlueprintPiece { + return literal({ + ...piece, + enable: { ...CreateTimingGraphic(internalGraphic.config, internalGraphic.parsedCue, true) }, // Allow default out for visual representation + sourceLayerId: SharedSourceLayers.PgmGraphicsIdent, + lifespan: PieceLifespan.WithinPart, + content: { + timelineObjects: [ + literal({ + id: '', + enable: { + while: '1' + }, + layer: AbstractLLayer.IdentMarker, content: { - timelineObjects: [ - literal({ - id: '', - enable: { - while: '1' - }, - layer: AbstractLLayer.IdentMarker, - content: { - deviceType: TSR.DeviceType.ABSTRACT - } - }) - ] + deviceType: TSR.DeviceType.ABSTRACT } }) - ) + ] } - } + }) } diff --git a/src/tv2-common/helpers/graphics/viz/index.ts b/src/tv2-common/helpers/graphics/viz/index.ts index 2ff240b38..4329e9dd1 100644 --- a/src/tv2-common/helpers/graphics/viz/index.ts +++ b/src/tv2-common/helpers/graphics/viz/index.ts @@ -33,11 +33,11 @@ export interface VizPilotGeneratorSettings { export function GetInternalGraphicContentVIZ( config: TV2BlueprintConfig, - part: Readonly, + part: Readonly | undefined, engine: GraphicEngine, parsedCue: CueDefinitionGraphic, isIdentGraphic: boolean, - partDefinition: PartDefinition, + partDefinition: PartDefinition | undefined, mappedTemplate: string, adlib: boolean ): IBlueprintPiece['content'] { 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 cbd0c1afe..30b7b5fcb 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts @@ -569,6 +569,26 @@ describe('Cue parser', () => { ) }) + test('Grafik (kg) - direkte - create adlib', () => { + const cueGrafik = ['#kg direkte KØBENHAVN', ';x.xx'] + const result = ParseCue(cueGrafik, config) + expect(result).toEqual( + literal>({ + type: CueType.Graphic, + target: 'OVL', + + graphic: { + type: 'internal', + template: 'direkte', + cue: '#kg', + textFields: ['KØBENHAVN'] + }, + adlib: true, + iNewsCommand: '#kg' + }) + ) + }) + test('Grafik (kg) - BillederFra_logo', () => { const cueGrafik = ['#kg BillederFra_logo KØBENHAVN', ';0.01'] const result = ParseCue(cueGrafik, config) @@ -728,6 +748,35 @@ describe('Cue parser', () => { ) }) + test('MOS object manual', () => { + const cueMOS = [ + '*cg4 pilotdata', + 'LgfxWeb/18-AARIG_02-03-2022_13:15:42/Mosart=L|M|00:10', + 'VCPID=2762780', + 'ContinueCount=1', + 'LgfxWeb/18-AARIG_02-03-2022_13:15:42/Mosart=L|M|00:10' + ] + const result = ParseCue(cueMOS, config) + expect(result).toEqual( + literal>({ + type: CueType.Graphic, + adlib: true, + end: { + seconds: 10 + }, + engineNumber: 4, + graphic: { + type: 'pilot', + name: 'LgfxWeb/18-AARIG_02-03-2022_13:15:42', + vcpid: 2762780, + continueCount: 1 + }, + iNewsCommand: 'VCP', + target: 'OVL' + }) + ) + }) + test('MOS object with timing - adlib + O', () => { const cueMOS = [ ']] S3.0 M 0 [[', diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index ea46f41d7..785cc26bd 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -133,7 +133,8 @@ export enum AdlibActionType { CLEAR_GRAPHICS = 'clear_graphics', TAKE_WITH_TRANSITION = 'take_with_transition', RECALL_LAST_LIVE = 'recall_last_live', - RECALL_LAST_DVE = 'recall_last_dve' + RECALL_LAST_DVE = 'recall_last_dve', + PLAY_GRAPHICS = 'play_graphics' } export enum TallyTags { From 3776e2c3d4544fdbe94f8bc4f0a3f93a2dcd4b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Thu, 31 Mar 2022 13:03:17 +0200 Subject: [PATCH 070/184] fix: EVS queue shortcut defaults configured correct. --- src/tv2-common/hotkeys/helpers/studioSource.ts | 13 +++++++------ src/tv2-common/hotkeys/local.ts | 18 ++++++++++++++---- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/tv2-common/hotkeys/helpers/studioSource.ts b/src/tv2-common/hotkeys/helpers/studioSource.ts index e4ee86d40..192c38d66 100644 --- a/src/tv2-common/hotkeys/helpers/studioSource.ts +++ b/src/tv2-common/hotkeys/helpers/studioSource.ts @@ -22,7 +22,8 @@ export function MakeStudioSourceHotkeys( hotkeys: SourceHotkeyTriggers, getNextRank: () => number, nameFunc: (source: string) => string, - idFunc: (showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) => string + idFunc: (showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) => string, + pickFunc: (sourceIndex: number, hotkeyType: string) => number = (sourceIndex) => sourceIndex, ): IBlueprintTriggeredActions[] { const directCutHotkeys: IBlueprintTriggeredActions[] = [] const queueHotkeys: IBlueprintTriggeredActions[] = [] @@ -43,7 +44,7 @@ export function MakeStudioSourceHotkeys( name, directHotkey, sourceLayerId, - currentSourceIndex + pickFunc(currentSourceIndex, 'cut_direct') ) ) } @@ -57,7 +58,7 @@ export function MakeStudioSourceHotkeys( name, queueHotkey, sourceLayerId, - currentSourceIndex + pickFunc(currentSourceIndex, 'queue') ) ) } @@ -72,7 +73,7 @@ export function MakeStudioSourceHotkeys( name + ` inp ${box + 1}`, boxHotkey, sourceLayerId, - currentSourceIndex, + pickFunc(currentSourceIndex, `cut_to_box_${box + 1}`), box ) ) @@ -88,7 +89,7 @@ export function MakeStudioSourceHotkeys( name + ` til SS`, toStudioScreenHotkey, sourceLayerId, - currentSourceIndex + pickFunc(currentSourceIndex, 'studio_screen') ) ) } @@ -102,7 +103,7 @@ export function MakeStudioSourceHotkeys( name, toGraphicsEngineHotkey, sourceLayerId, - currentSourceIndex + pickFunc(currentSourceIndex, 'graphics_engine') ) ) } diff --git a/src/tv2-common/hotkeys/local.ts b/src/tv2-common/hotkeys/local.ts index 02dac2432..72fd0dcc7 100644 --- a/src/tv2-common/hotkeys/local.ts +++ b/src/tv2-common/hotkeys/local.ts @@ -11,7 +11,11 @@ function localSourceFullAudioHotkeyId(showStyleId: string, sourceLayer: string, } function localSourceFullAudioHotkeyName(source: string) { - return `EVS ${source}` + return `EVS ${source} 100%` +} + +function localSourceFullAudioPickId(sourceIndex: number, hotkeyType: string): number { + return sourceIndex * (hotkeyType === 'queue' ? 2 : 0) } function localSourceVoAudioHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { @@ -19,7 +23,11 @@ function localSourceVoAudioHotkeyId(showStyleId: string, sourceLayer: string, ho } function localSourceVoAudioHotkeyName(source: string) { - return `EVS ${source}` + return `EVS ${source} VO` +} + +function localSourceVoAudioPickId(sourceIndex: number, hotkeyType: string): number { + return 1 + sourceIndex * (hotkeyType === 'queue' ? 2 : 0) } export function MakeLocalSourceHotkeys( @@ -36,7 +44,8 @@ export function MakeLocalSourceHotkeys( assignemnts.fullAudio, getNextRank, localSourceFullAudioHotkeyName, - localSourceFullAudioHotkeyId + localSourceFullAudioHotkeyId, + localSourceFullAudioPickId, ) const voAudioKeys = MakeStudioSourceHotkeys( @@ -46,7 +55,8 @@ export function MakeLocalSourceHotkeys( assignemnts.voAudio, getNextRank, localSourceVoAudioHotkeyName, - localSourceVoAudioHotkeyId + localSourceVoAudioHotkeyId, + localSourceVoAudioPickId, ) return [...fullAudioKeys, ...voAudioKeys] From a56c885b61ef43d25e746f6fc03ce917b47bf109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Thu, 31 Mar 2022 15:51:11 +0200 Subject: [PATCH 071/184] fix: EVS cut_to_box shortcut defaults configured correct. --- src/tv2-common/hotkeys/hotkey-defaults.ts | 2 +- src/tv2-common/hotkeys/local.ts | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/tv2-common/hotkeys/hotkey-defaults.ts b/src/tv2-common/hotkeys/hotkey-defaults.ts index cd8b1c18e..6f8afbef0 100644 --- a/src/tv2-common/hotkeys/hotkey-defaults.ts +++ b/src/tv2-common/hotkeys/hotkey-defaults.ts @@ -104,7 +104,7 @@ export const defaultHotkeys: TV2Hotkeys = { voAudio: { directCut: [], queue: ['KeyE', 'KeyU'], - cutToBox: [['Shift+KeyD', 'Shift+KeyU'], ['Ctrl+KeyD', 'Ctrl+Alt+Shift+KeyI'], ['Alt+Shift+KeyD'], []], + cutToBox: [['Shift+KeyD', 'Shift+KeyU'], ['Ctrl+KeyD', 'Ctrl+KeyU'], ['Alt+Shift+KeyD'], []], routeToGraphicsEngine: [], routeToStudioScreen: [] } diff --git a/src/tv2-common/hotkeys/local.ts b/src/tv2-common/hotkeys/local.ts index 72fd0dcc7..f04fd6129 100644 --- a/src/tv2-common/hotkeys/local.ts +++ b/src/tv2-common/hotkeys/local.ts @@ -14,8 +14,11 @@ function localSourceFullAudioHotkeyName(source: string) { return `EVS ${source} 100%` } -function localSourceFullAudioPickId(sourceIndex: number, hotkeyType: string): number { - return sourceIndex * (hotkeyType === 'queue' ? 2 : 0) +function localSourceFullAudioPick(sourceIndex: number, hotkeyType: string): number { + if (hotkeyType === 'queue' || /^cut_to_box_\d+$/.test(hotkeyType)) { + return 2 * sourceIndex + } + return sourceIndex } function localSourceVoAudioHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { @@ -26,8 +29,11 @@ function localSourceVoAudioHotkeyName(source: string) { return `EVS ${source} VO` } -function localSourceVoAudioPickId(sourceIndex: number, hotkeyType: string): number { - return 1 + sourceIndex * (hotkeyType === 'queue' ? 2 : 0) +function localSourceVoAudioPick(sourceIndex: number, hotkeyType: string): number { + if (hotkeyType === 'queue' || /^cut_to_box_\d+$/.test(hotkeyType)) { + return 1 + 2 * sourceIndex + } + return sourceIndex } export function MakeLocalSourceHotkeys( @@ -45,7 +51,7 @@ export function MakeLocalSourceHotkeys( getNextRank, localSourceFullAudioHotkeyName, localSourceFullAudioHotkeyId, - localSourceFullAudioPickId, + localSourceFullAudioPick, ) const voAudioKeys = MakeStudioSourceHotkeys( @@ -56,7 +62,7 @@ export function MakeLocalSourceHotkeys( getNextRank, localSourceVoAudioHotkeyName, localSourceVoAudioHotkeyId, - localSourceVoAudioPickId, + localSourceVoAudioPick, ) return [...fullAudioKeys, ...voAudioKeys] From 93d2493b0bf4d8874effc66a82a6cc337c758cf4 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Mon, 4 Apr 2022 12:02:53 +0200 Subject: [PATCH 072/184] SOF-830 Make blueprints compatiable with NRK release 41 --- config/webpack.config.js | 2 - package.json | 4 +- src/__mocks__/context.ts | 91 +++- src/inews-mixins/__tests__/playlist.spec.ts | 3 +- src/inews-mixins/playlist.ts | 17 +- src/tv2-common/actions/actionTypes.ts | 2 +- src/tv2-common/actions/context.ts | 114 +++-- src/tv2-common/actions/executeAction.ts | 418 ++++++++-------- src/tv2-common/evaluateCues.ts | 4 - src/tv2-common/getSegment.ts | 8 +- .../helpers/graphics/caspar/index.ts | 6 +- src/tv2-common/helpers/graphics/index.ts | 15 +- .../helpers/graphics/internal/index.ts | 24 +- .../helpers/graphics/pilot/index.ts | 39 +- src/tv2-common/helpers/graphics/timing.ts | 20 +- src/tv2-common/helpers/graphics/viz/index.ts | 7 +- src/tv2-common/helpers/rundownAdLibActions.ts | 1 + src/tv2-common/jinglePartProperties.ts | 22 +- .../__tests__/migrationContext.mock.ts | 1 + src/tv2-common/onTimelineGenerate.ts | 5 - src/tv2-common/parts/effekt.ts | 53 +- src/tv2-common/parts/invalid.ts | 3 +- src/tv2-common/parts/kam.ts | 3 +- src/tv2-common/parts/server.ts | 27 +- src/tv2-common/pieces/adlibServer.ts | 1 + .../updatePolicies/partProperties.ts | 9 +- .../shouldRemoveOrphanedPartInstance.ts | 13 +- src/tv2-common/util.ts | 7 +- .../__tests__/actions.spec.ts | 147 +++--- .../__tests__/baseline.spec.ts | 27 +- .../__tests__/regressions.spec.ts | 6 +- .../__tests__/rundown_story_exception.spec.ts | 11 +- .../syncIngestChangesToPartInstance.spec.ts | 14 +- .../__tests__/transitions.spec.ts | 44 +- src/tv2_afvd_showstyle/actions.ts | 8 +- src/tv2_afvd_showstyle/getRundown.ts | 177 ++++--- src/tv2_afvd_showstyle/getSegment.ts | 3 +- .../pieces/__tests__/grafikViz.spec.ts | 71 +-- .../helpers/pieces/__tests__/telefon.spec.ts | 7 - src/tv2_afvd_showstyle/helpers/pieces/dve.ts | 4 +- .../helpers/pieces/graphic.ts | 17 +- .../helpers/pieces/graphicPilot.ts | 3 - .../helpers/pieces/jingle.ts | 27 +- .../helpers/pieces/telefon.ts | 3 - .../helpers/sisyfos/__tests__/sisyfos.spec.ts | 70 --- src/tv2_afvd_showstyle/helpers/time.ts | 9 - src/tv2_afvd_showstyle/parts/cueonly.ts | 2 - src/tv2_afvd_showstyle/parts/unknown.ts | 2 - .../__tests__/graphics.spec.ts | 8 +- .../__tests__/actions.spec.ts | 454 +++++++++--------- src/tv2_offtube_showstyle/actions.ts | 6 +- .../cues/OfftubeAdlib.ts | 15 +- src/tv2_offtube_showstyle/cues/OfftubeDVE.ts | 17 +- .../cues/OfftubeGraphics.ts | 17 +- .../cues/OfftubeJingle.ts | 27 +- src/tv2_offtube_showstyle/getRundown.ts | 201 ++++---- src/tv2_offtube_showstyle/getSegment.ts | 3 +- src/tv2_offtube_showstyle/parts/OfftubeDVE.ts | 5 - src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 3 +- .../parts/OfftubeUnknown.ts | 2 - yarn.lock | 25 +- 61 files changed, 1183 insertions(+), 1171 deletions(-) delete mode 100644 src/tv2_afvd_showstyle/helpers/sisyfos/__tests__/sisyfos.spec.ts delete mode 100644 src/tv2_afvd_showstyle/helpers/time.ts diff --git a/config/webpack.config.js b/config/webpack.config.js index 55f488e14..fb3d4ac28 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -68,8 +68,6 @@ module.exports = env => { }, target: 'node', externals: { - underscore: '_', - moment: 'moment' }, plugins: [ new webpack.DefinePlugin({ diff --git a/package.json b/package.json index bf627add7..76016ee8e 100644 --- a/package.json +++ b/package.json @@ -59,8 +59,8 @@ "webpack-cli": "^3.1.2" }, "dependencies": { - "@tv2media/blueprints-integration": "v1.37.1-in-testing.1", - "@tv2media/timeline-state-resolver-types": "^1.0.0-release37.6", + "@tv2media/blueprints-integration": "1.41.2", + "@tv2media/timeline-state-resolver-types": "1.41.0", "underscore": "^1.12.1" } } \ No newline at end of file diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index 75ff5ef2f..3c6abb0b5 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -13,7 +13,9 @@ import { IBlueprintPieceInstance, IBlueprintResolvedPieceInstance, IBlueprintRundownDB, + IBlueprintRundownPlaylist, ICommonContext, + IGetRundownContext, IPackageInfoContext, IRundownContext, IRundownUserContext, @@ -24,7 +26,8 @@ import { IUserNotesContext, OmitId, PackageInfo, - PieceLifespan + PieceLifespan, + Time } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' import { NoteType } from 'tv2-constants' @@ -110,6 +113,10 @@ export class UserNotesContext extends CommonContext implements IUserNotesContext public notifyUserWarning(message: string, _params?: { [key: string]: any }): void { this.pushNote(NoteType.NOTIFY_USER_WARNING, message) } + + public notifyUserInfo(_message: string, _params?: { [p: string]: any }): void { + // Do nothing + } } // tslint:disable-next-line: max-classes-per-file @@ -187,6 +194,25 @@ export class ShowStyleUserContext extends ShowStyleContext implements IUserNotes public notifyUserWarning(message: string, _params?: { [key: string]: any }): void { this.pushNote(NoteType.NOTIFY_USER_WARNING, message) } + + public notifyUserInfo(_message: string, _params?: { [p: string]: any }): void { + // Do nothing + } +} + +// tslint:disable-next-line: max-classes-per-file +export class GetRundownContext extends ShowStyleUserContext implements IGetRundownContext { + public async getCurrentPlaylist(): Promise | undefined> { + return undefined + } + + public async getPlaylists(): Promise> { + return [] + } + + public getRandomId(): string { + return '' + } } // tslint:disable-next-line: max-classes-per-file @@ -215,6 +241,10 @@ export class RundownUserContext extends RundownContext implements IRundownUserCo public notifyUserWarning(message: string, _params?: { [key: string]: any }): void { this.pushNote(NoteType.NOTIFY_USER_WARNING, message) } + + public notifyUserInfo(_message: string, _params?: { [p: string]: any }): void { + // Do nothing + } } // tslint:disable-next-line: max-classes-per-file @@ -251,6 +281,10 @@ export class SegmentUserContext extends RundownContext implements ISegmentUserCo public getPackageInfo(_packageId: string): readonly PackageInfo.Any[] { return [] } + + public notifyUserInfo(_message: string, _params?: { [p: string]: any }): void { + // Do nothing + } } // tslint:disable-next-line: max-classes-per-file @@ -348,6 +382,10 @@ export class SyncIngestUpdateToPartInstanceContext extends RundownUserContext }) return this.updatedPartInstance } + + public notifyUserInfo(_message: string, _params?: { [p: string]: any }): void { + // Do nothing + } } // tslint:disable-next-line: max-classes-per-file @@ -384,14 +422,14 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct } /** Get a PartInstance which can be modified */ - public getPartInstance(part: 'current' | 'next'): IBlueprintPartInstance | undefined { + public async getPartInstance(part: 'current' | 'next'): Promise { if (part === 'current') { return this.currentPart } return this.nextPart } /** Get the PieceInstances for a modifiable PartInstance */ - public getPieceInstances(part: 'current' | 'next'): IBlueprintPieceInstance[] { + public async getPieceInstances(part: 'current' | 'next'): Promise { if (part === 'current') { return this.currentPieceInstances } @@ -399,30 +437,30 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct return this.nextPieceInstances || [] } /** Get the resolved PieceInstances for a modifiable PartInstance */ - public getResolvedPieceInstances(_part: 'current' | 'next'): IBlueprintResolvedPieceInstance[] { + public async getResolvedPieceInstances(_part: 'current' | 'next'): Promise { return [] } /** Get the last active piece on given layer */ - public findLastPieceOnLayer( + public async findLastPieceOnLayer( _sourceLayerId: string, _options?: { excludeCurrentPart?: boolean originalOnly?: boolean pieceMetaDataFilter?: any } - ): IBlueprintPieceInstance | undefined { + ): Promise { return undefined } - public findLastScriptedPieceOnLayer( + public async findLastScriptedPieceOnLayer( _sourceLayerId: string, _options?: { excludeCurrentPart?: boolean pieceMetaDataFilter?: any } - ): IBlueprintPiece | undefined { + ): Promise { return undefined } - public getPartInstanceForPreviousPiece(_piece: IBlueprintPieceInstance): IBlueprintPartInstance { + public async getPartInstanceForPreviousPiece(_piece: IBlueprintPieceInstance): Promise { return literal({ _id: '', segmentId: '', @@ -435,12 +473,12 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct rehearsal: false }) } - public getPartForPreviousPiece(_piece: { _id: string }): IBlueprintPart | undefined { - return + public async getPartForPreviousPiece(_piece: { _id: string }): Promise { + return undefined } /** Creative actions */ /** Insert a piece. Returns id of new PieceInstance. Any timelineObjects will have their ids changed, so are not safe to reference from another piece */ - public insertPiece(part: 'current' | 'next', piece: IBlueprintPiece): IBlueprintPieceInstance { + public async insertPiece(part: 'current' | 'next', piece: IBlueprintPiece): Promise { const pieceInstance: IBlueprintPieceInstance = { _id: '', piece: { @@ -459,10 +497,10 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct return pieceInstance } /** Update a pieceInstance */ - public updatePieceInstance( + public async updatePieceInstance( _pieceInstanceId: string, piece: Partial> - ): IBlueprintPieceInstance { + ): Promise { return { _id: '', piece: { @@ -473,7 +511,7 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct } } /** Insert a queued part to follow the current part */ - public queuePart(part: IBlueprintPart, pieces: IBlueprintPiece[]): IBlueprintPartInstance { + public async queuePart(part: IBlueprintPart, pieces: IBlueprintPiece[]): Promise { const instance = literal({ _id: '', segmentId: this.notesSegmentId || '', @@ -498,7 +536,10 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct return instance } /** Update a partInstance */ - public updatePartInstance(part: 'current' | 'next', props: Partial): IBlueprintPartInstance { + public async updatePartInstance( + part: 'current' | 'next', + props: Partial + ): Promise { if (part === 'current') { this.currentPart.part = { ...this.currentPart.part, ...props } return this.currentPart @@ -511,15 +552,15 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct } /** Destructive actions */ /** Stop any piecesInstances on the specified sourceLayers. Returns ids of piecesInstances that were affected */ - public stopPiecesOnLayers(_sourceLayerIds: string[], _timeOffset?: number): string[] { + public async stopPiecesOnLayers(_sourceLayerIds: string[], _timeOffset?: number): Promise { return [] } /** Stop piecesInstances by id. Returns ids of piecesInstances that were removed */ - public stopPieceInstances(_pieceInstanceIds: string[], _timeOffset?: number): string[] { + public async stopPieceInstances(_pieceInstanceIds: string[], _timeOffset?: number): Promise { return [] } /** Remove piecesInstances by id. Returns ids of piecesInstances that were removed */ - public removePieceInstances(part: 'current' | 'next', pieceInstanceIds: string[]): string[] { + public async removePieceInstances(part: 'current' | 'next', pieceInstanceIds: string[]): Promise { if (part === 'current') { this.currentPieceInstances = this.currentPieceInstances.filter(p => !pieceInstanceIds.includes(p._id)) } else if (this.nextPieceInstances) { @@ -528,11 +569,11 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct return pieceInstanceIds } - public moveNextPart(_partDelta: number, _segmentDelta: number): void { + public async moveNextPart(_partDelta: number, _segmentDelta: number): Promise { throw new Error('Method not implemented.') } /** Set flag to perform take after executing the current action. Returns state of the flag after each call. */ - public takeAfterExecuteAction(take: boolean): boolean { + public async takeAfterExecuteAction(take: boolean): Promise { this.takeAfterExecute = take return take @@ -546,6 +587,14 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct public getCurrentTime(): number { throw new Error('Method not implemented.') } + + public async blockTakeUntil(_time: Time | null): Promise { + return undefined + } + + public notifyUserInfo(_message: string, _params?: { [p: string]: any }): void { + // Do nothing + } } export interface PartNote { diff --git a/src/inews-mixins/__tests__/playlist.spec.ts b/src/inews-mixins/__tests__/playlist.spec.ts index 9021c5559..f576a66b8 100644 --- a/src/inews-mixins/__tests__/playlist.spec.ts +++ b/src/inews-mixins/__tests__/playlist.spec.ts @@ -40,7 +40,8 @@ function getMockResult(): BlueprintResultRundown { globalAdLibPieces: [], baseline: { timelineObjects: [] - } + }, + globalActions: [] } } diff --git a/src/inews-mixins/playlist.ts b/src/inews-mixins/playlist.ts index 6c9006b9f..0742f164f 100644 --- a/src/inews-mixins/playlist.ts +++ b/src/inews-mixins/playlist.ts @@ -3,8 +3,9 @@ import { BlueprintResultRundown, BlueprintResultRundownPlaylist, ExtendedIngestRundown, + IBlueprintResultRundownPlaylist, IBlueprintRundownDB, - IBlueprintRundownPlaylistInfo, + IGetRundownContext, IngestRundown, IShowStyleUserContext, IStudioUserContext, @@ -114,8 +115,14 @@ type GetRundownPlaylistInfoMixin = ( ) => BlueprintResultRundownPlaylist export function GetRundownWithMixins(getRundown: ShowStyleBlueprintManifest['getRundown'], mixins: GetRundownMixin[]) { - return (context: IShowStyleUserContext, ingestRundown: ExtendedIngestRundown) => { - let result = getRundown(context, ingestRundown) + return async ( + context: IGetRundownContext, + ingestRundown: ExtendedIngestRundown + ): Promise => { + let result = await getRundown(context, ingestRundown) + if (result === null) { + return result + } for (const mixin of mixins) { result = mixin(context, ingestRundown, result) @@ -146,9 +153,9 @@ export function GetRundownPlaylistInfoWithMixins( } } let result = - (getRundownPlaylistInfo ? getRundownPlaylistInfo(context, rundowns) : undefined) ?? + (getRundownPlaylistInfo ? getRundownPlaylistInfo(context, rundowns, '') : undefined) ?? literal({ - playlist: literal({ + playlist: literal({ name: (rundowns[0] ?? { name: '' }).name, timing }), diff --git a/src/tv2-common/actions/actionTypes.ts b/src/tv2-common/actions/actionTypes.ts index 307070ec2..e5a94124f 100644 --- a/src/tv2-common/actions/actionTypes.ts +++ b/src/tv2-common/actions/actionTypes.ts @@ -3,7 +3,7 @@ import { AdlibActionType } from 'tv2-constants' import { DVEConfigInput } from '../helpers' import { CueDefinitionDVE, PartDefinition } from '../inewsConversion' -interface ActionBase { +export interface ActionBase { type: AdlibActionType } diff --git a/src/tv2-common/actions/context.ts b/src/tv2-common/actions/context.ts index a45f1274c..28a5ad4bc 100644 --- a/src/tv2-common/actions/context.ts +++ b/src/tv2-common/actions/context.ts @@ -8,18 +8,20 @@ import { IBlueprintPieceDB, IBlueprintPieceInstance, IBlueprintResolvedPieceInstance, - PackageInfo + PackageInfo, + Time } from '@tv2media/blueprints-integration' import { literal, PartMetaData } from 'tv2-common' export interface ITV2ActionExecutionContext extends IActionExecutionContext { - /** To prompt type errors for frong context type */ + /** To prompt type errors for wrong context type */ isTV2Context: true } class TV2ActionExecutionContext implements ITV2ActionExecutionContext { public studioId: string public isTV2Context: true + private coreContext: IActionExecutionContext private modifiedParts: Set<'current' | 'next'> = new Set() @@ -28,127 +30,167 @@ class TV2ActionExecutionContext implements ITV2ActionExecutionContext { this.coreContext = coreContext this.studioId = coreContext.studioId } - public getPartInstance(part: 'current' | 'next'): IBlueprintPartInstance | undefined { + + public async getPartInstance(part: 'current' | 'next'): Promise | undefined> { return this.coreContext.getPartInstance(part) } - public getPieceInstances(part: 'current' | 'next'): Array> { + + public async getPieceInstances(part: 'current' | 'next'): Promise>> { return this.coreContext.getPieceInstances(part) } - public getResolvedPieceInstances(part: 'current' | 'next'): Array> { + + public async getResolvedPieceInstances( + part: 'current' | 'next' + ): Promise>> { return this.coreContext.getResolvedPieceInstances(part) } - public findLastPieceOnLayer( + + public async findLastPieceOnLayer( sourceLayerId: string | string[], options?: { excludeCurrentPart?: boolean | undefined originalOnly?: boolean | undefined pieceMetaDataFilter?: any } - ): IBlueprintPieceInstance | undefined { + ): Promise | undefined> { return this.coreContext.findLastPieceOnLayer(sourceLayerId, options) } - public findLastScriptedPieceOnLayer( + + public async findLastScriptedPieceOnLayer( sourceLayerId: string | string[], options?: { excludeCurrentPart?: boolean | undefined; pieceMetaDataFilter?: any } - ): IBlueprintPiece | undefined { + ): Promise | undefined> { return this.coreContext.findLastScriptedPieceOnLayer(sourceLayerId, options) } - public getPartInstanceForPreviousPiece(piece: IBlueprintPieceInstance): IBlueprintPartInstance { + + public async getPartInstanceForPreviousPiece( + piece: IBlueprintPieceInstance + ): Promise> { return this.coreContext.getPartInstanceForPreviousPiece(piece) } - public getPartForPreviousPiece(piece: IBlueprintPieceDB): IBlueprintPart | undefined { + + public async getPartForPreviousPiece( + piece: IBlueprintPieceDB + ): Promise | undefined> { return this.coreContext.getPartForPreviousPiece(piece) } - public stopPiecesOnLayers(sourceLayerIds: string[], timeOffset?: number): string[] { + + public async stopPiecesOnLayers(sourceLayerIds: string[], timeOffset?: number): Promise { return this.coreContext.stopPiecesOnLayers(sourceLayerIds, timeOffset) } - public stopPieceInstances(pieceInstanceIds: string[], timeOffset?: number): string[] { + + public async stopPieceInstances(pieceInstanceIds: string[], timeOffset?: number): Promise { return this.coreContext.stopPieceInstances(pieceInstanceIds, timeOffset) } - public takeAfterExecuteAction(take: boolean): boolean { + + 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 hackGetMediaObjectDuration(mediaId: string): number | undefined { return this.coreContext.hackGetMediaObjectDuration(mediaId) } + public getCurrentTime(): number { return this.coreContext.getCurrentTime() } - public moveNextPart(partDelta: number, segmentDelta: number): void { + public async moveNextPart(partDelta: number, segmentDelta: number): Promise { this.modifiedParts.add('next') return this.coreContext.moveNextPart(partDelta, segmentDelta) } - public queuePart(rawPart: IBlueprintPart, rawPieces: IBlueprintPiece[]): IBlueprintPartInstance { + public async queuePart(rawPart: IBlueprintPart, rawPieces: IBlueprintPiece[]): Promise { this.modifiedParts.add('next') return this.coreContext.queuePart(rawPart, rawPieces) } - public removePieceInstances(part: 'next', pieceInstanceIds: string[]): string[] { + public async removePieceInstances(part: 'next', pieceInstanceIds: string[]): Promise { this.modifiedParts.add('next') return this.coreContext.removePieceInstances(part, pieceInstanceIds) } - public insertPiece(part: 'current' | 'next', piece: IBlueprintPiece): IBlueprintPieceInstance { + public async insertPiece(part: 'current' | 'next', piece: IBlueprintPiece): Promise { this.modifiedParts.add(part) return this.coreContext.insertPiece(part, piece) } - public updatePartInstance(part: 'current' | 'next', props: Partial): IBlueprintPartInstance { + + public async updatePartInstance( + part: 'current' | 'next', + props: Partial + ): Promise { this.modifiedParts.add(part) return this.coreContext.updatePartInstance(part, props) } - public updatePieceInstance(pieceInstanceId: string, piece: Partial): IBlueprintPieceInstance { - const currentPieceInstances = this.coreContext.getPieceInstances('current') + + 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 = this.coreContext.getPieceInstances('next') + const nextPieceInstances = await this.coreContext.getPieceInstances('next') if (nextPieceInstances.map(p => p._id).includes(pieceInstanceId)) { this.modifiedParts.add('next') } @@ -164,12 +206,20 @@ class TV2ActionExecutionContext implements ITV2ActionExecutionContext { */ public afterActions() { for (const part of this.modifiedParts) { - this.markPartAsModifiedByAction(part) + this.markPartAsModifiedByAction(part).then() } } - private markPartAsModifiedByAction(part: 'current' | 'next') { - const partInstance = this.coreContext.getPartInstance(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 } @@ -178,17 +228,19 @@ class TV2ActionExecutionContext implements ITV2ActionExecutionContext { partInstance.part.metaData = {} } - this.coreContext.updatePartInstance(part, { - metaData: literal({ ...(partInstance.part.metaData as PartMetaData), dirty: true }) - }) + this.coreContext + .updatePartInstance(part, { + metaData: literal({ ...(partInstance.part.metaData as PartMetaData), dirty: true }) + }) + .then() } } -export function executeWithContext( +export async function executeWithContext( coreContext: IActionExecutionContext, - func: (context: ITV2ActionExecutionContext) => void + func: (context: ITV2ActionExecutionContext) => Promise ) { const context = new TV2ActionExecutionContext(coreContext) - func(context) + await func(context) context.afterActions() } diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 37fbd300f..b7c140048 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -56,6 +56,7 @@ import { MakeContentDVE2, PartDefinition, PieceMetaData, + TimeFromFrames, TimelineBlueprintExt, TV2AdlibAction, TV2BlueprintConfigBase, @@ -186,7 +187,7 @@ export interface ActionExecutionSettings< pilotGraphicSettings: PilotGeneratorSettings } -export function executeAction< +export async function executeAction< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -194,60 +195,70 @@ export function executeAction< settings: ActionExecutionSettings, actionIdStr: string, userData: ActionUserData -): void { - executeWithContext(coreContext, context => { - const existingTransition = getExistingTransition(context, settings, 'next') +): Promise { + await executeWithContext(coreContext, async context => { + const existingTransition = await getExistingTransition(context, settings, 'next') const actionId = actionIdStr as AdlibActionType switch (actionId) { case AdlibActionType.SELECT_SERVER_CLIP: - executeActionSelectServerClip(context, settings, actionId, userData as ActionSelectServerClip) + await executeActionSelectServerClip(context, settings, actionId, userData as ActionSelectServerClip) break case AdlibActionType.SELECT_DVE: - executeActionSelectDVE(context, settings, actionId, userData as ActionSelectDVE) + await executeActionSelectDVE(context, settings, actionId, userData as ActionSelectDVE) break case AdlibActionType.SELECT_DVE_LAYOUT: - executeActionSelectDVELayout(context, settings, actionId, userData as ActionSelectDVELayout) + await executeActionSelectDVELayout(context, settings, actionId, userData as ActionSelectDVELayout) break case AdlibActionType.SELECT_FULL_GRAFIK: - executeActionSelectFull(context, settings, actionId, userData as ActionSelectFullGrafik) + await executeActionSelectFull(context, settings, actionId, userData as ActionSelectFullGrafik) break case AdlibActionType.SELECT_JINGLE: - executeActionSelectJingle(context, settings, actionId, userData as ActionSelectJingle) + await executeActionSelectJingle(context, settings, actionId, userData as ActionSelectJingle) break case AdlibActionType.CLEAR_GRAPHICS: - executeActionClearGraphics(context, settings, actionId, userData as ActionClearGraphics) + await executeActionClearGraphics(context, settings, actionId, userData as ActionClearGraphics) break case AdlibActionType.CUT_TO_CAMERA: - executeActionCutToCamera(context, settings, actionId, userData as ActionCutToCamera) + await executeActionCutToCamera(context, settings, actionId, userData as ActionCutToCamera) break case AdlibActionType.CUT_TO_REMOTE: - executeActionCutToRemote(context, settings, actionId, userData as ActionCutToRemote) + await executeActionCutToRemote(context, settings, actionId, userData as ActionCutToRemote) break case AdlibActionType.CUT_SOURCE_TO_BOX: - executeActionCutSourceToBox(context, settings, actionId, userData as ActionCutSourceToBox) + await executeActionCutSourceToBox(context, settings, actionId, userData as ActionCutSourceToBox) break case AdlibActionType.COMMENTATOR_SELECT_DVE: - executeActionCommentatorSelectDVE(context, settings, actionId, userData as ActionCommentatorSelectDVE) + await executeActionCommentatorSelectDVE(context, settings, actionId, userData as ActionCommentatorSelectDVE) break case AdlibActionType.COMMENTATOR_SELECT_SERVER: - executeActionCommentatorSelectServer(context, settings, actionId, userData as ActionCommentatorSelectServer) + await executeActionCommentatorSelectServer( + context, + settings, + actionId, + userData as ActionCommentatorSelectServer + ) break case AdlibActionType.COMMENTATOR_SELECT_FULL: - executeActionCommentatorSelectFull(context, settings, actionId, userData as ActionCommentatorSelectFull) + await executeActionCommentatorSelectFull(context, settings, actionId, userData as ActionCommentatorSelectFull) break case AdlibActionType.COMMENTATOR_SELECT_JINGLE: - executeActionCommentatorSelectJingle(context, settings, actionId, userData as ActionCommentatorSelectJingle) + await executeActionCommentatorSelectJingle( + context, + settings, + actionId, + userData as ActionCommentatorSelectJingle + ) break case AdlibActionType.TAKE_WITH_TRANSITION: - executeActionTakeWithTransition(context, settings, actionId, userData as ActionTakeWithTransition) + await executeActionTakeWithTransition(context, settings, actionId, userData as ActionTakeWithTransition) break case AdlibActionType.RECALL_LAST_LIVE: - executeActionRecallLastLive(context, settings, actionId, userData as ActionRecallLastLive) + await executeActionRecallLastLive(context, settings, actionId, userData as ActionRecallLastLive) break case AdlibActionType.RECALL_LAST_DVE: - executeActionRecallLastDVE(context, settings, actionId, userData as ActionRecallLastDVE) + await executeActionRecallLastDVE(context, settings, actionId, userData as ActionRecallLastDVE) break default: assertUnreachable(actionId) @@ -256,7 +267,12 @@ export function executeAction< if (actionId !== AdlibActionType.TAKE_WITH_TRANSITION) { if (existingTransition) { - executeActionTakeWithTransition(context, settings, AdlibActionType.TAKE_WITH_TRANSITION, existingTransition) + await executeActionTakeWithTransition( + context, + settings, + AdlibActionType.TAKE_WITH_TRANSITION, + existingTransition + ) } } }) @@ -270,17 +286,17 @@ function sanitizePieceStart(piece: IBlueprintPiece): IBlueprintPiece { return piece } -function getExistingTransition< +async function getExistingTransition< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( context: ITV2ActionExecutionContext, settings: ActionExecutionSettings, part: 'current' | 'next' -): ActionTakeWithTransition | undefined { - const existingTransition = context +): Promise { + const existingTransition = await context .getPieceInstances(part) - .find(p => p.piece.sourceLayerId === settings.SourceLayers.Effekt) + .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.Effekt)) if (!existingTransition) { return @@ -329,13 +345,13 @@ function sanitizePieceId(piece: IBlueprintPieceDB): IBlueprintPiece { return _.omit(piece, ['_id', 'partId', 'infiniteId', 'playoutDuration']) } -export function getPiecesToPreserve( +export async function getPiecesToPreserve( context: ITV2ActionExecutionContext, adlibLayers: string[], - ingoreLayers: string[] -): IBlueprintPiece[] { - const currentPartSegmentId = context.getPartInstance('current')?.segmentId - const nextPartSegmentId = context.getPartInstance('next')?.segmentId + ignoreLayers: string[] +): Promise { + const currentPartSegmentId = await context.getPartInstance('current').then(partInstance => partInstance?.segmentId) + const nextPartSegmentId = await context.getPartInstance('next').then(partInstance => partInstance?.segmentId) if (!currentPartSegmentId || !nextPartSegmentId) { return [] @@ -345,20 +361,21 @@ export function getPiecesToPreserve( return [] } - return context - .getPieceInstances('next') - .filter(p => adlibLayers.includes(p.piece.sourceLayerId) && !ingoreLayers.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)) + return context.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)) + }) } function generateExternalId(context: ITV2ActionExecutionContext, actionId: string, args: string[]): string { return `adlib_action_${actionId}_${context.getHashId(args.join('_'), true)}` } -function executeActionSelectServerClip< +async function executeActionSelectServerClip< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -375,10 +392,12 @@ function executeActionSelectServerClip< const externalId = generateExternalId(context, actionId, [file]) const currentPiece = settings.SelectedAdlibs - ? context + ? await context .getPieceInstances('current') - .find( - p => p.piece.sourceLayerId === (userData.voLayer ? settings.SourceLayers.VO : settings.SourceLayers.Server) + .then(pieceInstances => + pieceInstances.find( + p => p.piece.sourceLayerId === (userData.voLayer ? settings.SourceLayers.VO : settings.SourceLayers.Server) + ) ) : undefined @@ -468,20 +487,21 @@ function executeActionSelectServerClip< settings.postProcessPieceTimelineObjects(context, config, activeServerPiece, false) } - context.queuePart(part, [ + await context.queuePart(part, [ activeServerPiece, serverDataStore, ...grafikPieces, ...(settings.SelectedAdlibs - ? getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, [ + ? await getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, [ settings.SelectedAdlibs.SourceLayer.VO, settings.SelectedAdlibs.SourceLayer.Server ]) : []), ...effektPieces ]) + if (settings.SelectedAdlibs && !currentPiece) { - context.stopPiecesOnLayers([ + await context.stopPiecesOnLayers([ userData.voLayer ? settings.SelectedAdlibs.SourceLayer.VO : settings.SelectedAdlibs.SourceLayer.Server ]) } @@ -496,7 +516,7 @@ function dveContainsServer(sources: DVESources) { ) } -function executeActionSelectDVE< +async function executeActionSelectDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -560,7 +580,7 @@ function executeActionSelectDVE< content: { ...pieceContent.content }, - adlibPreroll: Number(config.studio.CasparPrerollDuration) || 0, + prerollDuration: Number(config.studio.CasparPrerollDuration) || 0, metaData, tags: [ GetTagForDVE(userData.segmentExternalId, parsedCue.template, parsedCue.sources), @@ -569,9 +589,9 @@ function executeActionSelectDVE< ] }) - dvePiece = cutServerToBox(context, settings, dvePiece) + dvePiece = await cutServerToBox(context, settings, dvePiece) - startNewDVELayout( + await startNewDVELayout( context, config, settings, @@ -587,14 +607,14 @@ function executeActionSelectDVE< ) } -function cutServerToBox< +async function cutServerToBox< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( context: ITV2ActionExecutionContext, settings: ActionExecutionSettings, dvePiece: IBlueprintPiece -): IBlueprintPiece { +): Promise { // Check if DVE should continue server + copy server properties if (!dvePiece.metaData) { @@ -608,12 +628,15 @@ function cutServerToBox< } if (dvePiece.content?.timelineObjects) { - const currentPieces = context.getPieceInstances('current') - const currentServer = currentPieces.find( - p => - p.piece.sourceLayerId === settings.SelectedAdlibs?.SourceLayer.Server || - p.piece.sourceLayerId === settings.SelectedAdlibs?.SourceLayer.VO - ) + const currentServer = await context + .getPieceInstances('current') + .then(currentPieces => + currentPieces.find( + p => + p.piece.sourceLayerId === settings.SelectedAdlibs?.SourceLayer.Server || + p.piece.sourceLayerId === settings.SelectedAdlibs?.SourceLayer.VO + ) + ) if (!currentServer || !currentServer.piece.content?.timelineObjects) { context.notifyUserWarning(`No server is playing, cannot start DVE`) @@ -666,7 +689,7 @@ function cutServerToBox< return dvePiece } -function executeActionSelectDVELayout< +async function executeActionSelectDVELayout< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -690,14 +713,15 @@ function executeActionSelectDVELayout< const externalId = generateExternalId(context, actionId, [userData.config.DVEName]) - const nextPart = context.getPartInstance('next') + const nextPart = await context.getPartInstance('next') - const nextInstances = context.getPieceInstances('next') - const nextDVE = nextInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE) + const nextDVE = await context + .getPieceInstances('next') + .then(nextInstances => nextInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE)) const meta = nextDVE?.piece.metaData as DVEPieceMetaData - if (!nextPart || !nextDVE || !meta || nextPart.segmentId !== context.getPartInstance('current')?.segmentId) { + if (!nextPart || !nextDVE || !meta || nextPart.segmentId !== (await context.getPartInstance('current'))?.segmentId) { const content = MakeContentDVE2(context, config, userData.config, {}, sources, settings.DVEGeneratorOptions) if (!content.valid) { @@ -734,7 +758,7 @@ function executeActionSelectDVELayout< content: content.content }) - newDVEPiece = cutServerToBox(context, settings, newDVEPiece) + newDVEPiece = await cutServerToBox(context, settings, newDVEPiece) return startNewDVELayout( context, @@ -769,9 +793,9 @@ function executeActionSelectDVELayout< ] } - dvePiece = cutServerToBox(context, settings, dvePiece) + dvePiece = await cutServerToBox(context, settings, dvePiece) - startNewDVELayout( + await startNewDVELayout( context, config, settings, @@ -789,7 +813,7 @@ function executeActionSelectDVELayout< ) } -function startNewDVELayout< +async function startNewDVELayout< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -841,26 +865,26 @@ function startNewDVELayout< externalId, title: templateName, metaData: {}, - expectedDuration: 0, - prerollDuration: config.studio.CasparPrerollDuration + expectedDuration: 0 }) + const currentPieceInstances = await context.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 = context - .getPieceInstances('current') - .find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE) + const onAirPiece = currentPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE) + const dataPiece = settings.SelectedAdlibs && - context.getPieceInstances('current').find(p => p.piece.sourceLayerId === settings.SelectedAdlibs!.SourceLayer.DVE) + currentPieceInstances.find(p => p.piece.sourceLayerId === settings.SelectedAdlibs!.SourceLayer.DVE) if (onAirPiece === undefined && dataPiece !== undefined) { - context.stopPieceInstances([dataPiece._id]) + await context.stopPieceInstances([dataPiece._id]) } - context.queuePart(newPart, [ + dvePiece.prerollDuration = config.studio.CasparPrerollDuration + await context.queuePart(newPart, [ dvePiece, ...(dveDataStore ? [dveDataStore] : []), ...(settings.SelectedAdlibs - ? getPiecesToPreserve( + ? await getPiecesToPreserve( context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, settings.SelectedAdlibs.SourceLayer.DVE ? [settings.SelectedAdlibs.SourceLayer.DVE] : [] @@ -868,24 +892,24 @@ function startNewDVELayout< : []) ]) if (settings.SelectedAdlibs.SourceLayer.DVE) { - context.stopPiecesOnLayers([settings.SelectedAdlibs.SourceLayer.DVE]) + await context.stopPiecesOnLayers([settings.SelectedAdlibs.SourceLayer.DVE]) } } else { if (replacePieceInstancesOrQueue.activeDVE) { - context.updatePieceInstance(replacePieceInstancesOrQueue.activeDVE, dvePiece) - context.updatePartInstance(part, { expectedDuration: 0 }) + await context.updatePieceInstance(replacePieceInstancesOrQueue.activeDVE, dvePiece) + await context.updatePartInstance(part, { expectedDuration: 0 }) if (dveDataStore) { if (replacePieceInstancesOrQueue.dataStore) { - context.updatePieceInstance(replacePieceInstancesOrQueue.dataStore, dveDataStore) + await context.updatePieceInstance(replacePieceInstancesOrQueue.dataStore, dveDataStore) } else { - context.insertPiece(part, dveDataStore) + await context.insertPiece(part, dveDataStore) } } } } } -function executeActionSelectJingle< +async function executeActionSelectJingle< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -915,7 +939,7 @@ function executeActionSelectJingle< file = jingle.ClipName.toString() } - const props = GetJinglePartPropertiesFromTableValue(config, jingle) + const props = GetJinglePartPropertiesFromTableValue(jingle) const pieceContent = settings.createJingleContent( config, @@ -935,16 +959,13 @@ function executeActionSelectJingle< lifespan: PieceLifespan.WithinPart, outputLayerId: SharedOutputLayers.JINGLE, sourceLayerId: settings.SourceLayers.Effekt, + prerollDuration: config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), content: pieceContent, - metaData: literal({ - transition: { - isJingle: true - } - }), tags: [ GetTagForJingle(userData.segmentExternalId, userData.clip), GetTagForJingleNext(userData.segmentExternalId, userData.clip), - TallyTags.JINGLE_IS_LIVE + TallyTags.JINGLE_IS_LIVE, + TallyTags.JINGLE ] }) @@ -978,11 +999,11 @@ function executeActionSelectJingle< ...props }) - context.queuePart(part, [ + await context.queuePart(part, [ piece, ...(jingleDataStore ? [] : []), ...(settings.SelectedAdlibs - ? getPiecesToPreserve( + ? await getPiecesToPreserve( context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, settings.SelectedAdlibs.SourceLayer.Effekt ? [settings.SelectedAdlibs.SourceLayer.Effekt] : [] @@ -991,11 +1012,11 @@ function executeActionSelectJingle< ]) if (settings.SelectedAdlibs.SourceLayer.Effekt) { - context.stopPiecesOnLayers([settings.SelectedAdlibs.SourceLayer.Effekt]) + await context.stopPiecesOnLayers([settings.SelectedAdlibs.SourceLayer.Effekt]) } } -function executeActionCutToCamera< +async function executeActionCutToCamera< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -1020,7 +1041,7 @@ function executeActionCutToCamera< return } - const currentPieceInstances = context.getPieceInstances('current') + const currentPieceInstances = await context.getPieceInstances('current') const serverInCurrentPart = currentPieceInstances.some( p => p.piece.sourceLayerId === settings.SourceLayers.Server || p.piece.sourceLayerId === settings.SourceLayers.VO @@ -1109,27 +1130,30 @@ function executeActionCutToCamera< settings.postProcessPieceTimelineObjects(context, config, kamPiece, false) if (userData.queue || serverInCurrentPart) { - context.queuePart(part, [ + await context.queuePart(part, [ kamPiece, ...(settings.SelectedAdlibs - ? getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, []) + ? await getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, []) : []) ]) + if (serverInCurrentPart && !userData.queue) { - context.takeAfterExecuteAction(true) + await context.takeAfterExecuteAction(true) } } else if (currentKam) { kamPiece.externalId = currentKam.piece.externalId kamPiece.enable = currentKam.piece.enable - context.updatePieceInstance(currentKam._id, kamPiece) + await context.updatePieceInstance(currentKam._id, kamPiece) } else { - const currentExternalId = context.getPartInstance('current')?.part.externalId + const currentExternalId = await context + .getPartInstance('current') + .then(currentPartInstance => currentPartInstance?.part.externalId) if (currentExternalId) { kamPiece.externalId = currentExternalId } - context.stopPiecesOnLayers([ + await context.stopPiecesOnLayers([ settings.SourceLayers.DVE, ...(settings.SourceLayers.DVEAdLib ? [settings.SourceLayers.DVEAdLib] : []), settings.SourceLayers.Effekt, @@ -1139,12 +1163,13 @@ function executeActionCutToCamera< ...(settings.SourceLayers.EVS ? [settings.SourceLayers.EVS] : []), settings.SourceLayers.Continuity ]) + kamPiece.enable = { start: 'now' } - context.insertPiece('current', kamPiece) + await context.insertPiece('current', kamPiece) } } -function executeActionCutToRemote< +async function executeActionCutToRemote< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -1249,13 +1274,15 @@ function executeActionCutToRemote< settings.postProcessPieceTimelineObjects(context, config, remotePiece, false) - context.queuePart(part, [ + await context.queuePart(part, [ remotePiece, - ...(settings.SelectedAdlibs ? getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, []) : []) + ...(settings.SelectedAdlibs + ? await getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, []) + : []) ]) } -function executeActionCutSourceToBox< +async function executeActionCutSourceToBox< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -1266,8 +1293,8 @@ function executeActionCutSourceToBox< ) { const config = settings.getConfig(context) - const currentPieces = context.getPieceInstances('current') - const nextPieces = context.getPieceInstances('next') + const currentPieces = await context.getPieceInstances('current') + const nextPieces = await context.getPieceInstances('next') const currentDVE = currentPieces.find( p => @@ -1353,11 +1380,11 @@ function executeActionCutSourceToBox< let newDVEPiece: IBlueprintPiece = { ...modifiedPiece.piece, content: newPieceContent.content, metaData: meta } if (!(containsServerBefore && containsServerAfter)) { - newDVEPiece = cutServerToBox(context, settings, newDVEPiece) + newDVEPiece = await cutServerToBox(context, settings, newDVEPiece) } if (newPieceContent.valid) { - startNewDVELayout( + await startNewDVELayout( context, config, settings, @@ -1412,20 +1439,19 @@ function findPrimaryPieceUsingPriority< return undefined } -function applyPrerollToWallGraphics< +async function applyPrerollToWallGraphics< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( context: ITV2ActionExecutionContext, settings: ActionExecutionSettings, - piecesBySourceLayer: PiecesBySourceLayer, - partProps: Partial + piecesBySourceLayer: PiecesBySourceLayer ) { const wallPieces = piecesBySourceLayer[settings.SourceLayers.Wall] if (!wallPieces) { return } - const enable = GetEnableForWall(partProps) + const enable = GetEnableForWall() for (const pieceInstance of wallPieces) { if (pieceInstance.piece.content?.timelineObjects && !pieceInstance.infinite?.fromPreviousPart) { const newPieceProps = { @@ -1440,12 +1466,12 @@ function applyPrerollToWallGraphics< timelineObjectsToUpdate.forEach(timelineObject => { timelineObject.enable = enable }) - context.updatePieceInstance(pieceInstance._id, newPieceProps) + await context.updatePieceInstance(pieceInstance._id, newPieceProps) } } } -function executeActionTakeWithTransition< +async function executeActionTakeWithTransition< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -1456,12 +1482,12 @@ function executeActionTakeWithTransition< ) { const externalId = generateExternalId(context, actionId, [userData.variant.type]) - const nextPieces = context.getPieceInstances('next') + const nextPieces = await context.getPieceInstances('next') const nextPiecesBySourceLayer = groupPiecesBySourceLayer(nextPieces) const primaryPiece = findPrimaryPieceUsingPriority(settings, nextPiecesBySourceLayer) - context.takeAfterExecuteAction(userData.takeNow) + await context.takeAfterExecuteAction(userData.takeNow) if ( !primaryPiece || @@ -1490,7 +1516,7 @@ function executeActionTakeWithTransition< const existingEffektPiece = nextPieces.find(p => p.piece.sourceLayerId === settings.SourceLayers.Effekt) if (existingEffektPiece) { - context.removePieceInstances('next', [existingEffektPiece._id]) + await context.removePieceInstances('next', [existingEffektPiece._id]) } let partProps: Partial | false = false @@ -1502,7 +1528,7 @@ function executeActionTakeWithTransition< primaryPiece.piece.content.timelineObjects[tlObjIndex] = tlObj - context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) + await context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) const cutTransitionPiece: IBlueprintPiece = { enable: { @@ -1522,13 +1548,11 @@ function executeActionTakeWithTransition< } partProps = { - transitionKeepaliveDuration: undefined, - transitionDuration: undefined, - transitionPrerollDuration: undefined + inTransition: undefined } - context.insertPiece('next', cutTransitionPiece) - context.updatePartInstance('next', partProps) + await context.insertPiece('next', cutTransitionPiece) + await context.updatePartInstance('next', partProps) } break case 'breaker': { @@ -1536,7 +1560,7 @@ function executeActionTakeWithTransition< primaryPiece.piece.content.timelineObjects[tlObjIndex] = tlObj - context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) + await context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) const config = settings.getConfig(context) const pieces: IBlueprintPiece[] = [] @@ -1555,7 +1579,7 @@ function executeActionTakeWithTransition< ) if (partProps) { - context.updatePartInstance('next', partProps) + await context.updatePartInstance('next', partProps) pieces.forEach(p => context.insertPiece('next', { ...p, tags: [GetTagForTransition(userData.variant)] })) } break @@ -1571,16 +1595,18 @@ function executeActionTakeWithTransition< primaryPiece.piece.content.timelineObjects[tlObjIndex] = tlObj - context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) + await context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) const pieces: IBlueprintPiece[] = [] - partProps = CreateMixForPartInner(pieces, externalId, userData.variant.frames, { - sourceLayer: settings.SourceLayers.Effekt, - casparLayer: settings.LLayer.Caspar.Effekt, - sisyfosLayer: settings.LLayer.Sisyfos.Effekt - }) + partProps = { + ...CreateMixForPartInner(pieces, externalId, userData.variant.frames, { + sourceLayer: settings.SourceLayers.Effekt, + casparLayer: settings.LLayer.Caspar.Effekt, + sisyfosLayer: settings.LLayer.Sisyfos.Effekt + }) + } - context.updatePartInstance('next', partProps) + await context.updatePartInstance('next', partProps) pieces.forEach(p => context.insertPiece('next', { ...p, tags: [GetTagForTransition(userData.variant)] })) break @@ -1588,16 +1614,17 @@ function executeActionTakeWithTransition< } if (partProps) { - applyPrerollToWallGraphics(context, settings, nextPiecesBySourceLayer, partProps) + await applyPrerollToWallGraphics(context, settings, nextPiecesBySourceLayer) } } -function findPieceToRecoverDataFrom( +async function findPieceToRecoverDataFrom( context: ITV2ActionExecutionContext, dataStoreLayers: string[] -): { piece: IBlueprintPieceInstance; part: 'current' | 'next' } | undefined { - const currentPieces = context.getPieceInstances('current') - const nextPieces = context.getPieceInstances('next') +): Promise<{ piece: IBlueprintPieceInstance; part: 'current' | 'next' } | undefined> { + const pieces = await Promise.all([context.getPieceInstances('current'), context.getPieceInstances('next')]) + const currentPieces = pieces[0] + const nextPieces = pieces[1] const currentServer = currentPieces.find(p => dataStoreLayers.includes(p.piece.sourceLayerId)) @@ -1625,26 +1652,24 @@ function findPieceToRecoverDataFrom( } } -function findDataStore( +async function findDataStore( context: ITV2ActionExecutionContext, dataStoreLayers: string[] -): T | undefined { - const dataStorePiece = findPieceToRecoverDataFrom(context, dataStoreLayers) +): Promise { + const dataStorePiece = await findPieceToRecoverDataFrom(context, dataStoreLayers) if (!dataStorePiece) { return } - const data = (dataStorePiece.piece.piece.metaData as any)?.userData as T | undefined - - return data + return (dataStorePiece.piece.piece.metaData as any)?.userData as T | undefined } -function findMediaPlayerSessions( +async function findMediaPlayerSessions( context: ITV2ActionExecutionContext, sessionLayers: string[] -): { session: string | undefined; part: 'current' | 'next' | undefined } { - const mediaPlayerSessionPiece = findPieceToRecoverDataFrom(context, sessionLayers) +): Promise<{ session: string | undefined; part: 'current' | 'next' | undefined }> { + const mediaPlayerSessionPiece = await findPieceToRecoverDataFrom(context, sessionLayers) if (!mediaPlayerSessionPiece) { return { @@ -1662,7 +1687,7 @@ function findMediaPlayerSessions( } } -function executeActionCommentatorSelectServer< +async function executeActionCommentatorSelectServer< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -1671,12 +1696,7 @@ function executeActionCommentatorSelectServer< _actionId: string, _userData: ActionCommentatorSelectServer ) { - const data = findDataStore(context, [ - settings.SelectedAdlibs.SourceLayer.Server, - settings.SelectedAdlibs.SourceLayer.VO - ]) - - const sessions = findMediaPlayerSessions(context, [ + const data = await findDataStore(context, [ settings.SelectedAdlibs.SourceLayer.Server, settings.SelectedAdlibs.SourceLayer.VO ]) @@ -1685,15 +1705,20 @@ function executeActionCommentatorSelectServer< return } + const sessions = await findMediaPlayerSessions(context, [ + settings.SelectedAdlibs.SourceLayer.Server, + settings.SelectedAdlibs.SourceLayer.VO + ]) + let session: string | undefined if (sessions.session && sessions.part && sessions.part === 'current') { session = sessions.session } - executeActionSelectServerClip(context, settings, AdlibActionType.SELECT_SERVER_CLIP, data, session) + await executeActionSelectServerClip(context, settings, AdlibActionType.SELECT_SERVER_CLIP, data, session) } -function executeActionCommentatorSelectDVE< +async function executeActionCommentatorSelectDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -1706,16 +1731,16 @@ function executeActionCommentatorSelectDVE< return } - const data = findDataStore(context, [settings.SelectedAdlibs.SourceLayer.DVE]) + const data = await findDataStore(context, [settings.SelectedAdlibs.SourceLayer.DVE]) if (!data) { return } - executeActionSelectDVE(context, settings, AdlibActionType.SELECT_DVE, data) + await executeActionSelectDVE(context, settings, AdlibActionType.SELECT_DVE, data) } -function executeActionCommentatorSelectFull< +async function executeActionCommentatorSelectFull< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -1724,16 +1749,16 @@ function executeActionCommentatorSelectFull< _actionId: string, _userData: ActionCommentatorSelectFull ) { - const data = findDataStore(context, [SharedSourceLayers.SelectedAdlibGraphicsFull]) + const data = await findDataStore(context, [SharedSourceLayers.SelectedAdlibGraphicsFull]) if (!data) { return } - executeActionSelectFull(context, settings, AdlibActionType.SELECT_FULL_GRAFIK, data) + await executeActionSelectFull(context, settings, AdlibActionType.SELECT_FULL_GRAFIK, data) } -function executeActionCommentatorSelectJingle< +async function executeActionCommentatorSelectJingle< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -1746,16 +1771,16 @@ function executeActionCommentatorSelectJingle< return } - const data = findDataStore(context, [settings.SelectedAdlibs.SourceLayer.Effekt]) + const data = await findDataStore(context, [settings.SelectedAdlibs.SourceLayer.Effekt]) if (!data) { return } - executeActionSelectJingle(context, settings, AdlibActionType.SELECT_JINGLE, data) + await executeActionSelectJingle(context, settings, AdlibActionType.SELECT_JINGLE, data) } -function executeActionRecallLastLive< +async function executeActionRecallLastLive< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -1764,11 +1789,7 @@ function executeActionRecallLastLive< actionId: string, _userData: ActionRecallLastLive ) { - const lastLive = context.findLastPieceOnLayer(settings.SourceLayers.Live, { - originalOnly: true, - excludeCurrentPart: false - }) - const lastIdent = context.findLastPieceOnLayer(settings.SourceLayers.Ident, { + const lastLive = await context.findLastPieceOnLayer(settings.SourceLayers.Live, { originalOnly: true, excludeCurrentPart: false }) @@ -1777,6 +1798,11 @@ function executeActionRecallLastLive< return } + const lastIdent = await context.findLastPieceOnLayer(settings.SourceLayers.Ident, { + originalOnly: true, + excludeCurrentPart: false + }) + const externalId = generateExternalId(context, actionId, [lastLive.piece.name]) const part = literal({ @@ -1804,10 +1830,10 @@ function executeActionRecallLastLive< }) } - context.queuePart(part, pieces) + await context.queuePart(part, pieces) } -function executeActionRecallLastDVE< +async function executeActionRecallLastDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -1822,7 +1848,7 @@ function executeActionRecallLastDVE< return } - const lastPlayedScheduledDVE: IBlueprintPieceInstance | undefined = context.findLastPieceOnLayer( + const lastPlayedScheduledDVE: IBlueprintPieceInstance | undefined = await context.findLastPieceOnLayer( settings.SourceLayers.DVE, { originalOnly: true @@ -1831,13 +1857,13 @@ function executeActionRecallLastDVE< const isLastPlayedAScheduledDVE: boolean = !lastPlayedScheduledDVE?.dynamicallyInserted if (lastPlayedScheduledDVE && isLastPlayedAScheduledDVE) { - scheduleLastPlayedDVE(context, settings, actionId, lastPlayedScheduledDVE) + await scheduleLastPlayedDVE(context, settings, actionId, lastPlayedScheduledDVE) } else { - scheduleNextScriptedDVE(context, settings, actionId) + await scheduleNextScriptedDVE(context, settings, actionId) } } -function scheduleLastPlayedDVE< +async function scheduleLastPlayedDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -1845,11 +1871,11 @@ function scheduleLastPlayedDVE< settings: ActionExecutionSettings, actionId: string, lastPlayedDVE: IBlueprintPieceInstance -): void { +): Promise { const lastPlayedDVEMeta: DVEPieceMetaData = lastPlayedDVE.piece.metaData as DVEPieceMetaData const externalId: string = generateExternalId(context, actionId, [lastPlayedDVE.piece.name]) - executeActionSelectDVE( + await executeActionSelectDVE( context, settings, actionId, @@ -1862,15 +1888,17 @@ function scheduleLastPlayedDVE< ) } -function scheduleNextScriptedDVE< +async function scheduleNextScriptedDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( context: ITV2ActionExecutionContext, settings: ActionExecutionSettings, actionId: string -): void { - const nextScriptedDVE: IBlueprintPiece | undefined = context.findLastScriptedPieceOnLayer(settings.SourceLayers.DVE) +): Promise { + const nextScriptedDVE: IBlueprintPiece | undefined = await context.findLastScriptedPieceOnLayer( + settings.SourceLayers.DVE + ) if (!nextScriptedDVE) { return @@ -1879,7 +1907,7 @@ function scheduleNextScriptedDVE< const externalId: string = generateExternalId(context, actionId, [nextScriptedDVE.name]) const dveMeta: DVEPieceMetaData = nextScriptedDVE.metaData as DVEPieceMetaData - executeActionSelectDVE( + await executeActionSelectDVE( context, settings, actionId, @@ -1892,7 +1920,7 @@ function scheduleNextScriptedDVE< ) } -function executeActionSelectFull< +async function executeActionSelectFull< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -1910,7 +1938,7 @@ function executeActionSelectFull< const graphicType = config.studio.GraphicsType const prerollDuration = graphicType === 'HTML' ? config.studio.CasparPrerollDuration : config.studio.VizPilotGraphics.OutTransitionDuration - const transitionKeepaliveDuration = + const previousPartKeepaliveDuration = graphicType === 'HTML' ? config.studio.HTMLGraphics.KeepAliveDuration : config.studio.VizPilotGraphics.KeepAliveDuration @@ -1920,8 +1948,11 @@ function executeActionSelectFull< title: `Full ${template}`, metaData: {}, expectedDuration: 0, - prerollDuration, - transitionKeepaliveDuration + inTransition: { + previousPartKeepaliveDuration, + partContentDelayDuration: 0, + blockTakeDuration: 0 + } }) const cue = literal>({ @@ -1939,13 +1970,13 @@ function executeActionSelectFull< const fullPiece = CreateFullPiece( config, context, - part, externalId, cue, 'FULL', settings.pilotGraphicSettings, true, - userData.segmentExternalId + userData.segmentExternalId, + prerollDuration ) settings.postProcessPieceTimelineObjects(context, config, fullPiece, false) @@ -1953,7 +1984,6 @@ function executeActionSelectFull< const fullDataStore = CreateFullDataStore( config, context, - part, settings.pilotGraphicSettings, cue, 'FULL', @@ -1962,18 +1992,18 @@ function executeActionSelectFull< userData.segmentExternalId ) - context.queuePart(part, [ + await context.queuePart(part, [ fullPiece, ...(fullDataStore ? [fullDataStore] : []), - ...getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, [ + ...(await getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, [ SharedSourceLayers.SelectedAdlibGraphicsFull - ]) + ])) ]) - context.stopPiecesOnLayers([SharedSourceLayers.SelectedAdlibGraphicsFull]) + await context.stopPiecesOnLayers([SharedSourceLayers.SelectedAdlibGraphicsFull]) } -function executeActionClearGraphics< +async function executeActionClearGraphics< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -1984,8 +2014,8 @@ function executeActionClearGraphics< ) { const config = settings.getConfig(context) - context.stopPiecesOnLayers(STOPPABLE_GRAPHICS_LAYERS) - context.insertPiece( + await context.stopPiecesOnLayers(STOPPABLE_GRAPHICS_LAYERS) + await context.insertPiece( 'current', literal({ enable: { diff --git a/src/tv2-common/evaluateCues.ts b/src/tv2-common/evaluateCues.ts index 6136660c3..6dcd0a020 100644 --- a/src/tv2-common/evaluateCues.ts +++ b/src/tv2-common/evaluateCues.ts @@ -36,7 +36,6 @@ export interface EvaluateCuesShowstyleOptions { EvaluateCueGraphic?: ( config: TV2BlueprintConfig, context: ISegmentUserContext, - part: Readonly, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -113,7 +112,6 @@ export interface EvaluateCuesShowstyleOptions { EvaluateCueTelefon?: ( config: TV2BlueprintConfig, context: ISegmentUserContext, - part: Readonly, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -222,7 +220,6 @@ export function EvaluateCuesBase( showStyleOptions.EvaluateCueGraphic( config, context, - part, pieces, adLibPieces, actions, @@ -300,7 +297,6 @@ export function EvaluateCuesBase( showStyleOptions.EvaluateCueTelefon( config, context, - part, pieces, adLibPieces, actions, diff --git a/src/tv2-common/getSegment.ts b/src/tv2-common/getSegment.ts index a559041ca..6367c8b74 100644 --- a/src/tv2-common/getSegment.ts +++ b/src/tv2-common/getSegment.ts @@ -17,8 +17,7 @@ import { PartDefinitionKam, PartMetaData } from 'tv2-common' -import { CueType, PartType, SharedSourceLayers } from 'tv2-constants' -import * as _ from 'underscore' +import { CueType, PartType, SharedSourceLayers, TallyTags } from 'tv2-constants' import { TV2BlueprintConfigBase, TV2StudioConfigBase } from './blueprintConfig' import { CueDefinitionUnpairedTarget, @@ -29,7 +28,6 @@ import { PartDefinitionTelefon, TimeFromINewsField } from './inewsConversion' -import { PieceMetaData } from './onTimelineGenerate' import { CreatePartInvalid, ServerPartProps } from './parts' export interface GetSegmentShowstyleOptions< @@ -359,9 +357,7 @@ export function getSegmentBase< part.part.expectedDuration! < config.studio.DefaultPartDuration && // Jingle-only part, do not modify duration !part.pieces.some( - p => - p.sourceLayerId === SharedSourceLayers.PgmJingle && - (p.metaData as PieceMetaData)?.transition?.isJingle === true + p => p.sourceLayerId === SharedSourceLayers.PgmJingle && p.tags?.some(tag => TallyTags.JINGLE === tag) ) ) { part.part.expectedDuration = config.studio.DefaultPartDuration diff --git a/src/tv2-common/helpers/graphics/caspar/index.ts b/src/tv2-common/helpers/graphics/caspar/index.ts index 661cc79a0..463dbe738 100644 --- a/src/tv2-common/helpers/graphics/caspar/index.ts +++ b/src/tv2-common/helpers/graphics/caspar/index.ts @@ -2,7 +2,6 @@ export * from './slotMappings' import { GraphicsContent, - IBlueprintPart, IBlueprintPiece, IShowStyleUserContext, TSR, @@ -31,7 +30,6 @@ export interface CasparPilotGeneratorSettings { export function GetInternalGraphicContentCaspar( config: TV2BlueprintConfig, - part: Readonly, engine: GraphicEngine, parsedCue: CueDefinitionGraphic, isIdentGraphic: boolean, @@ -42,7 +40,6 @@ export function GetInternalGraphicContentCaspar( return { timelineObjects: CasparOverlayTimeline( config, - part, engine, parsedCue, isIdentGraphic, @@ -117,7 +114,6 @@ export function GetPilotGraphicContentCaspar( function CasparOverlayTimeline( config: TV2BlueprintConfig, - part: Readonly, engine: GraphicEngine, parsedCue: CueDefinitionGraphic, isIdentGrafik: boolean, @@ -128,7 +124,7 @@ function CasparOverlayTimeline( return [ literal({ id: '', - enable: GetEnableForGraphic(config, part, engine, parsedCue, isIdentGrafik, partDefinition, adlib), + enable: GetEnableForGraphic(config, engine, parsedCue, isIdentGrafik, partDefinition, adlib), priority: 1, layer: GetTimelineLayerForGraphic(config, mappedTemplate), content: CreateHTMLRendererContent(config, mappedTemplate, { ...parsedCue.graphic.textFields }) diff --git a/src/tv2-common/helpers/graphics/index.ts b/src/tv2-common/helpers/graphics/index.ts index e505d322f..f16856d41 100644 --- a/src/tv2-common/helpers/graphics/index.ts +++ b/src/tv2-common/helpers/graphics/index.ts @@ -13,14 +13,19 @@ export * from './viz' export * from './design' export function ApplyFullGraphicPropertiesToPart(config: TV2BlueprintConfig, part: IBlueprintPart) { - part.prerollDuration = - config.studio.GraphicsType === 'HTML' - ? config.studio.CasparPrerollDuration - : config.studio.VizPilotGraphics.PrerollDuration - part.transitionKeepaliveDuration = + 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[] { diff --git a/src/tv2-common/helpers/graphics/internal/index.ts b/src/tv2-common/helpers/graphics/internal/index.ts index b49967874..92e28b165 100644 --- a/src/tv2-common/helpers/graphics/internal/index.ts +++ b/src/tv2-common/helpers/graphics/internal/index.ts @@ -1,7 +1,6 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, - IBlueprintPart, IBlueprintPiece, IShowStyleUserContext, PieceLifespan, @@ -34,7 +33,6 @@ import { GetInternalGraphicContentVIZ } from '../viz' export function CreateInternalGraphic( config: TV2BlueprintConfig, context: IShowStyleUserContext, - part: Readonly, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], _actions: IBlueprintActionManifest[], @@ -68,26 +66,8 @@ export function CreateInternalGraphic( const content = config.studio.GraphicsType === 'HTML' - ? GetInternalGraphicContentCaspar( - config, - part, - engine, - parsedCue, - isStickyIdent, - partDefinition, - mappedTemplate, - adlib - ) - : GetInternalGraphicContentVIZ( - config, - part, - engine, - parsedCue, - isStickyIdent, - partDefinition, - mappedTemplate, - adlib - ) + ? GetInternalGraphicContentCaspar(config, engine, parsedCue, isStickyIdent, partDefinition, mappedTemplate, adlib) + : GetInternalGraphicContentVIZ(config, engine, parsedCue, isStickyIdent, partDefinition, mappedTemplate, adlib) if (adlib) { if (IsTargetingOVL(engine)) { diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index e4c43bf69..7631aeb19 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -2,7 +2,6 @@ import { GraphicsContent, IBlueprintActionManifest, IBlueprintAdLibPiece, - IBlueprintPart, IBlueprintPiece, IShowStyleUserContext, PieceLifespan, @@ -13,6 +12,7 @@ import { ActionSelectFullGrafik, CreateTimingGraphic, CueDefinitionGraphic, + generateExternalId, GetFullGraphicTemplateNameFromCue, GetInfiniteModeForGraphic, GetPilotGraphicContentViz, @@ -48,7 +48,6 @@ export interface PilotGeneratorSettings { export function CreatePilotGraphic( config: TV2BlueprintConfig, context: IShowStyleUserContext, - part: Readonly, pieces: IBlueprintPiece[], _adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -78,13 +77,11 @@ export function CreatePilotGraphic( } if (!(IsTargetingOVL(engine) && adlib)) { - pieces.push(CreateFullPiece(config, context, part, partId, parsedCue, engine, settings, adlib, externalSegmentId)) + pieces.push(CreateFullPiece(config, context, partId, parsedCue, engine, settings, adlib, externalSegmentId)) } if (IsTargetingFull(engine)) { - pieces.push( - CreateFullDataStore(config, context, part, settings, parsedCue, engine, partId, adlib, externalSegmentId) - ) + pieces.push(CreateFullDataStore(config, context, settings, parsedCue, engine, partId, adlib, externalSegmentId)) } } @@ -102,14 +99,16 @@ function CreatePilotAdLibAction( const sourceLayerId = GetSourceLayer(engine) const outputLayerId = GetOutputLayer(engine) + const userData = literal({ + type: AdlibActionType.SELECT_FULL_GRAFIK, + name: parsedCue.graphic.name, + vcpid: parsedCue.graphic.vcpid, + segmentExternalId + }) return literal({ + externalId: generateExternalId(context, userData), actionId: AdlibActionType.SELECT_FULL_GRAFIK, - userData: literal({ - type: AdlibActionType.SELECT_FULL_GRAFIK, - name: parsedCue.graphic.name, - vcpid: parsedCue.graphic.vcpid, - segmentExternalId - }), + userData, userDataManifest: {}, display: { _rank: adlibRank, @@ -117,7 +116,7 @@ function CreatePilotAdLibAction( sourceLayerId: SharedSourceLayers.PgmPilot, outputLayerId: SharedOutputLayers.PGM, content: { - ...CreateFullContent(config, context, undefined, settings, parsedCue, engine, adlib) + ...CreateFullContent(config, context, settings, parsedCue, engine, adlib) }, uniquenessId: `gfx_${name}_${sourceLayerId}_${outputLayerId}`, tags: [ @@ -134,13 +133,13 @@ function CreatePilotAdLibAction( export function CreateFullPiece( config: TV2BlueprintConfig, context: IShowStyleUserContext, - part: Readonly, partId: string, parsedCue: CueDefinitionGraphic, engine: GraphicEngine, settings: PilotGeneratorSettings, adlib: boolean, - segmentExternalId: string + segmentExternalId: string, + prerollDuration?: number ): IBlueprintPiece { return literal({ externalId: partId, @@ -154,9 +153,9 @@ export function CreateFullPiece( }), outputLayerId: GetOutputLayer(engine), sourceLayerId: GetSourceLayer(engine), - adlibPreroll: config.studio.VizPilotGraphics.PrerollDuration, + prerollDuration: prerollDuration ? prerollDuration : config.studio.VizPilotGraphics.PrerollDuration, lifespan: GetInfiniteModeForGraphic(engine, config, parsedCue), - content: CreateFullContent(config, context, part, settings, parsedCue, engine, adlib), + content: CreateFullContent(config, context, settings, parsedCue, engine, adlib), tags: [GetTagForFull(segmentExternalId, parsedCue.graphic.vcpid), TallyTags.FULL_IS_LIVE] }) } @@ -164,7 +163,6 @@ export function CreateFullPiece( export function CreateFullDataStore( config: TV2BlueprintConfig, context: IShowStyleUserContext, - part: Readonly, settings: PilotGeneratorSettings, parsedCue: CueDefinitionGraphic, engine: GraphicEngine, @@ -172,7 +170,7 @@ export function CreateFullDataStore( adlib: boolean, segmentExternalId: string ): IBlueprintPiece { - const content = CreateFullContent(config, context, part, settings, parsedCue, engine, adlib) + const content = CreateFullContent(config, context, settings, parsedCue, engine, adlib) content.timelineObjects = content.timelineObjects.filter( o => o.content.deviceType !== TSR.DeviceType.ATEM && @@ -205,7 +203,6 @@ export function CreateFullDataStore( function CreateFullContent( config: TV2BlueprintConfig, context: IShowStyleUserContext, - part: Readonly | undefined, settings: PilotGeneratorSettings, cue: CueDefinitionGraphic, engine: GraphicEngine, @@ -214,7 +211,7 @@ function CreateFullContent( if (config.studio.GraphicsType === 'HTML') { return GetPilotGraphicContentCaspar(config, context, cue, settings.caspar, engine) } else { - return GetPilotGraphicContentViz(config, part, context, settings.viz, cue, engine, adlib) + return GetPilotGraphicContentViz(config, context, settings.viz, cue, engine, adlib) } } diff --git a/src/tv2-common/helpers/graphics/timing.ts b/src/tv2-common/helpers/graphics/timing.ts index f3c677adb..6b4668c17 100644 --- a/src/tv2-common/helpers/graphics/timing.ts +++ b/src/tv2-common/helpers/graphics/timing.ts @@ -1,4 +1,4 @@ -import { IBlueprintPart, PieceLifespan, TSR } from '@tv2media/blueprints-integration' +import { PieceLifespan, TSR } from '@tv2media/blueprints-integration' import { CalculateTime, CreateTimingEnable, @@ -120,22 +120,14 @@ export function CreateTimingGraphic( return ret } -export function GetPartPrerollDuration(part: Readonly> | undefined): number { - return (part && (part.transitionPrerollDuration || part.prerollDuration)) || 0 -} - -export function GetEnableForWall(part: Readonly> | undefined): TSR.TSRTimelineObj['enable'] { - const partPrerollDuration = GetPartPrerollDuration(part) - return partPrerollDuration - ? { start: partPrerollDuration } - : { - while: '1' - } +export function GetEnableForWall(): TSR.TSRTimelineObj['enable'] { + return { + while: '1' + } } export function GetEnableForGraphic( config: TV2BlueprintConfig, - part: Readonly | undefined, engine: GraphicEngine, cue: CueDefinitionGraphic, isStickyIdent: boolean, @@ -143,7 +135,7 @@ export function GetEnableForGraphic( adlib?: boolean ): TSR.TSRTimelineObj['enable'] { if (IsTargetingWall(engine)) { - return GetEnableForWall(part) + return GetEnableForWall() } if ( diff --git a/src/tv2-common/helpers/graphics/viz/index.ts b/src/tv2-common/helpers/graphics/viz/index.ts index 2ff240b38..aa0a8eff4 100644 --- a/src/tv2-common/helpers/graphics/viz/index.ts +++ b/src/tv2-common/helpers/graphics/viz/index.ts @@ -1,6 +1,5 @@ import { GraphicsContent, - IBlueprintPart, IBlueprintPiece, IShowStyleUserContext, TSR, @@ -33,7 +32,6 @@ export interface VizPilotGeneratorSettings { export function GetInternalGraphicContentVIZ( config: TV2BlueprintConfig, - part: Readonly, engine: GraphicEngine, parsedCue: CueDefinitionGraphic, isIdentGraphic: boolean, @@ -48,7 +46,7 @@ export function GetInternalGraphicContentVIZ( timelineObjects: literal([ literal({ id: '', - enable: GetEnableForGraphic(config, part, engine, parsedCue, isIdentGraphic, partDefinition, adlib), + enable: GetEnableForGraphic(config, engine, parsedCue, isIdentGraphic, partDefinition, adlib), priority: 1, layer: GetTimelineLayerForGraphic(config, GetFullGraphicTemplateNameFromCue(config, parsedCue)), content: { @@ -67,7 +65,6 @@ export function GetInternalGraphicContentVIZ( export function GetPilotGraphicContentViz( config: TV2BlueprintConfig, - part: Readonly | undefined, context: IShowStyleUserContext, settings: VizPilotGeneratorSettings, parsedCue: CueDefinitionGraphic, @@ -82,7 +79,7 @@ export function GetPilotGraphicContentViz( id: '', enable: IsTargetingOVL(engine) || IsTargetingWall(engine) - ? GetEnableForGraphic(config, part, engine, parsedCue, false, undefined, adlib) + ? GetEnableForGraphic(config, engine, parsedCue, false, undefined, adlib) : { start: 0 }, diff --git a/src/tv2-common/helpers/rundownAdLibActions.ts b/src/tv2-common/helpers/rundownAdLibActions.ts index ae1189b30..c1ad4aa0b 100644 --- a/src/tv2-common/helpers/rundownAdLibActions.ts +++ b/src/tv2-common/helpers/rundownAdLibActions.ts @@ -131,6 +131,7 @@ function makeTransitionAction( const isEffekt = !!label.match(/^\d+$/) return literal({ + externalId: `${JSON.stringify(userData)}_${AdlibActionType.TAKE_WITH_TRANSITION}_${rank}`, actionId: AdlibActionType.TAKE_WITH_TRANSITION, userData, userDataManifest: {}, diff --git a/src/tv2-common/jinglePartProperties.ts b/src/tv2-common/jinglePartProperties.ts index a39b21631..119042d27 100644 --- a/src/tv2-common/jinglePartProperties.ts +++ b/src/tv2-common/jinglePartProperties.ts @@ -8,12 +8,7 @@ export function GetJinglePartProperties, part: PartDefinition -): - | Pick< - IBlueprintPart, - 'autoNext' | 'expectedDuration' | 'prerollDuration' | 'autoNextOverlap' | 'disableOutTransition' - > - | {} { +): Pick | {} { if (part.cues) { const cue = part.cues.find(c => c.type === CueType.Jingle) as CueDefinitionJingle if (cue) { @@ -26,28 +21,23 @@ export function GetJinglePartProperties( - config: TV2BlueprintConfigBase, +export function GetJinglePartPropertiesFromTableValue( realBreaker: TableConfigItemBreakers -): Pick< - IBlueprintPart, - 'autoNext' | 'expectedDuration' | 'prerollDuration' | 'autoNextOverlap' | 'disableOutTransition' -> { +): Pick { return { expectedDuration: TimeFromFrames(Number(realBreaker.Duration)) - TimeFromFrames(Number(realBreaker.EndAlpha)) - TimeFromFrames(Number(realBreaker.StartAlpha)), - prerollDuration: config.studio.CasparPrerollDuration + TimeFromFrames(Number(realBreaker.StartAlpha)), autoNextOverlap: TimeFromFrames(Number(realBreaker.EndAlpha)), - disableOutTransition: false, - autoNext: realBreaker.Autonext === true + autoNext: realBreaker.Autonext === true, + disableNextInTransition: false } } diff --git a/src/tv2-common/migrations/__tests__/migrationContext.mock.ts b/src/tv2-common/migrations/__tests__/migrationContext.mock.ts index 36191ae65..ddc7746ba 100644 --- a/src/tv2-common/migrations/__tests__/migrationContext.mock.ts +++ b/src/tv2-common/migrations/__tests__/migrationContext.mock.ts @@ -12,6 +12,7 @@ import { export class MockShowstyleMigrationContext implements MigrationContextShowStyle { public variants: IBlueprintShowStyleVariant[] public configs: Map = new Map() + public getTriggeredActionId: (triggeredActionId: string) => string public getAllVariants(): IBlueprintShowStyleVariant[] { return this.variants diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index 05bc864c7..d011ce4d7 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -49,11 +49,6 @@ export interface TimelineBlueprintExt extends TimelineObjectCoreExt { } export interface PieceMetaData { - transition?: { - isEffekt?: boolean - isMix?: boolean - isJingle?: boolean - } stickySisyfosLevels?: { [key: string]: { value: number; followsPrevious: boolean } } mediaPlayerSessions?: string[] mediaPlayerOptional?: boolean diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index 404b2c1cd..d56144141 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -1,6 +1,7 @@ import { IBlueprintPart, IBlueprintPiece, + IBlueprintPieceType, IShowStyleUserContext, PieceLifespan, TimelineObjectCoreExt, @@ -21,7 +22,6 @@ import { } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import { TV2BlueprintConfig } from '../blueprintConfig' -import { PieceMetaData } from '../onTimelineGenerate' import { JoinAssetToFolder, JoinAssetToNetworkPath } from '../util' /** Has to be executed before calling EvaluateCues, as some cues may depend on it */ @@ -35,13 +35,7 @@ export function CreateEffektForPartBase( casparLayer: string sisyfosLayer: string } -): - | Pick< - IBlueprintPart, - 'transitionDuration' | 'transitionKeepaliveDuration' | 'transitionPrerollDuration' | 'autoNext' - > - | Pick - | {} { +): Pick | {} { const effekt = partDefinition.effekt const transition = partDefinition.transition @@ -83,12 +77,7 @@ export function CreateEffektForPartInner< sisyfosLayer: string }, label: string -): - | Pick< - IBlueprintPart, - 'transitionDuration' | 'transitionKeepaliveDuration' | 'transitionPrerollDuration' | 'autoNext' - > - | false { +): Pick | false { if (!config.showStyle.BreakerConfig) { context.notifyUserWarning(`Jingles have not been configured`) return false @@ -122,12 +111,7 @@ export function CreateEffektForPartInner< outputLayerId: SharedOutputLayers.JINGLE, sourceLayerId: layers.sourceLayer, lifespan: PieceLifespan.WithinPart, - isTransition: true, - metaData: literal({ - transition: { - isEffekt: true - } - }), + pieceType: IBlueprintPieceType.InTransition, content: literal>({ fileName, path: JoinAssetToNetworkPath( @@ -175,12 +159,15 @@ export function CreateEffektForPartInner< ) return { - transitionDuration: TimeFromFrames(Number(effektConfig.Duration)) + config.studio.CasparPrerollDuration, - transitionKeepaliveDuration: TimeFromFrames(Number(effektConfig.StartAlpha)) + config.studio.CasparPrerollDuration, - transitionPrerollDuration: - TimeFromFrames(Number(effektConfig.Duration)) - - TimeFromFrames(Number(effektConfig.EndAlpha)) + - config.studio.CasparPrerollDuration, + inTransition: { + blockTakeDuration: TimeFromFrames(Number(effektConfig.Duration)) + config.studio.CasparPrerollDuration, + previousPartKeepaliveDuration: + TimeFromFrames(Number(effektConfig.StartAlpha)) + config.studio.CasparPrerollDuration, + partContentDelayDuration: + TimeFromFrames(Number(effektConfig.Duration)) - + TimeFromFrames(Number(effektConfig.EndAlpha)) + + config.studio.CasparPrerollDuration + }, autoNext: false } } @@ -194,7 +181,7 @@ export function CreateMixForPartInner( casparLayer: string sisyfosLayer: string } -): Pick { +): Pick { pieces.push( literal({ enable: { @@ -206,11 +193,6 @@ export function CreateMixForPartInner( sourceLayerId: layers.sourceLayer, outputLayerId: SharedOutputLayers.JINGLE, lifespan: PieceLifespan.WithinPart, - metaData: literal({ - transition: { - isMix: true - } - }), tags: [ GetTagForTransition( literal({ @@ -229,7 +211,10 @@ export function CreateMixForPartInner( const transitionDuration = TimeFromFrames(durationInFrames) return { - transitionKeepaliveDuration: transitionDuration, - transitionDuration + inTransition: { + previousPartKeepaliveDuration: transitionDuration, + blockTakeDuration: transitionDuration, + partContentDelayDuration: 0 + } } } diff --git a/src/tv2-common/parts/invalid.ts b/src/tv2-common/parts/invalid.ts index 378ff79c1..16b40bb79 100644 --- a/src/tv2-common/parts/invalid.ts +++ b/src/tv2-common/parts/invalid.ts @@ -12,6 +12,7 @@ export function CreatePartInvalid(ingestPart: PartDefinition, externalIdSuffix?: return { part, adLibPieces: [], - pieces: [] + pieces: [], + actions: [] } } diff --git a/src/tv2-common/parts/kam.ts b/src/tv2-common/parts/kam.ts index d98aea37b..64de85c31 100644 --- a/src/tv2-common/parts/kam.ts +++ b/src/tv2-common/parts/kam.ts @@ -23,7 +23,8 @@ export function CreatePartKamBase< part: { part, pieces: [], - adLibPieces: [] + adLibPieces: [], + actions: [] }, duration: partTime } diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index fa57be34a..29fd0a668 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -71,7 +71,7 @@ export function CreatePartServerBase< const actualDuration = getActualDuration(duration, sanitisedScript, props) const displayTitle = getDisplayTitle(partDefinition) - const basePart = getBasePart(partDefinition, displayTitle, actualDuration, file, config.studio.CasparPrerollDuration) + const basePart = getBasePart(partDefinition, displayTitle, actualDuration, file) const mediaPlayerSession = SanitizeString(`segment_${props.session ?? partDefinition.segmentExternalId}_${file}`) const pieces: IBlueprintPiece[] = [] @@ -85,7 +85,8 @@ export function CreatePartServerBase< sourceDuration, mediaPlayerSession, context, - config + config, + config.studio.CasparPrerollDuration ) const pgmBlueprintPiece = getPgmBlueprintPiece( @@ -95,7 +96,8 @@ export function CreatePartServerBase< layers, sourceDuration, mediaPlayerSession, - config + config, + config.studio.CasparPrerollDuration ) pieces.push(serverSelectionBlueprintPiece) @@ -105,7 +107,8 @@ export function CreatePartServerBase< part: { part: basePart, adLibPieces: [], - pieces + pieces, + actions: [] }, file, duration: actualDuration @@ -162,15 +165,13 @@ function getBasePart( partDefinition: PartDefinition, displayTitle: string, actualDuration: number, - fileId: string, - casparPrerollDuration: number + fileId: string ): IBlueprintPart { return { externalId: partDefinition.externalId, title: displayTitle, metaData: {}, expectedDuration: actualDuration || 1000, - prerollDuration: casparPrerollDuration, hackListenToMediaObjectUpdates: [{ mediaId: fileId.toUpperCase() }] } } @@ -241,7 +242,8 @@ function getServerSelectionBlueprintPiece< sourceDuration: number | undefined, mediaPlayerSession: string, context: IShowStyleUserContext, - config: ShowStyleConfig + config: ShowStyleConfig, + prerollDuration: number ): IBlueprintPiece { const userDataElement = getUserData(partDefinition, file, actualDuration, props) const contentServerElement = getContentServerElement( @@ -267,7 +269,8 @@ function getServerSelectionBlueprintPiece< userData: userDataElement }), content: contentServerElement, - tags: [GetTagForServerNext(partDefinition.segmentExternalId, file, props.voLayer)] + tags: [GetTagForServerNext(partDefinition.segmentExternalId, file, props.voLayer)], + prerollDuration }) } @@ -281,7 +284,8 @@ function getPgmBlueprintPiece< layers: ServerPartLayers, sourceDuration: number | undefined, mediaPlayerSession: string, - config: ShowStyleConfig + config: ShowStyleConfig, + prerollDuration: number ): IBlueprintPiece { return literal({ externalId: partDefinition.externalId, @@ -297,6 +301,7 @@ function getPgmBlueprintPiece< ...GetVTContentProperties(config, file, sourceDuration), timelineObjects: CutToServer(mediaPlayerSession, partDefinition, config, layers.AtemLLayer.MEPgm) }, - tags: [GetTagForServer(partDefinition.segmentExternalId, file, props.voLayer), TallyTags.SERVER_IS_LIVE] + tags: [GetTagForServer(partDefinition.segmentExternalId, file, props.voLayer), TallyTags.SERVER_IS_LIVE], + prerollDuration }) } diff --git a/src/tv2-common/pieces/adlibServer.ts b/src/tv2-common/pieces/adlibServer.ts index f97c90749..966746a17 100644 --- a/src/tv2-common/pieces/adlibServer.ts +++ b/src/tv2-common/pieces/adlibServer.ts @@ -33,6 +33,7 @@ export function CreateAdlibServer< tagAsAdlib: boolean ): IBlueprintActionManifest { return literal({ + externalId: partDefinition.externalId + '-addLib-server', actionId: AdlibActionType.SELECT_SERVER_CLIP, userData: literal({ type: AdlibActionType.SELECT_SERVER_CLIP, diff --git a/src/tv2-common/updatePolicies/partProperties.ts b/src/tv2-common/updatePolicies/partProperties.ts index efedc72e6..eb5277864 100644 --- a/src/tv2-common/updatePolicies/partProperties.ts +++ b/src/tv2-common/updatePolicies/partProperties.ts @@ -15,10 +15,7 @@ const partPropertiesToOmit = [ 'externalId', 'autoNext', 'autoNextOverlap', - 'prerollDuration', - 'transitionPrerollDuration', - 'transitionKeepaliveDuration', - 'transitionDuration', + 'inTransition', 'disableOutTransition', 'shouldNotifyCurrentPlayingPart' ] as const @@ -33,7 +30,9 @@ const clearedMutatablePart: Complete(o: T) { return o @@ -86,3 +87,7 @@ export function JoinAssetToNetworkPath( return `${networkPathWithWindowsPaths}\\${folderWithWindowsPaths}\\${assetFileWithWindowsPaths}.${extensionWithoutLeadingDot}` } + +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_afvd_showstyle/__tests__/actions.spec.ts b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts index b911831ce..c1af3a4e0 100644 --- a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts @@ -362,22 +362,37 @@ const evsPieceInstance_Effekt: IBlueprintPieceInstance = { partInstanceId: '' } -function getCameraPiece(context: ActionExecutionContext, part: 'current' | 'next'): IBlueprintPieceInstance { - const piece = context.getPieceInstances(part).find(p => p.piece.sourceLayerId === SourceLayer.PgmCam) +async function getCameraPiece( + context: ActionExecutionContext, + part: 'current' | 'next' +): Promise { + const piece = await context + .getPieceInstances(part) + .then(pieceInstance => pieceInstance.find(p => p.piece.sourceLayerId === SourceLayer.PgmCam)) expect(piece).toBeTruthy() return piece! } -function getEVSPiece(context: ActionExecutionContext, part: 'current' | 'next'): IBlueprintPieceInstance { - const piece = context.getPieceInstances(part).find(p => p.piece.sourceLayerId === SourceLayer.PgmLocal) +async function getEVSPiece( + context: ActionExecutionContext, + part: 'current' | 'next' +): Promise { + const piece = await context + .getPieceInstances(part) + .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === SourceLayer.PgmLocal)) expect(piece).toBeTruthy() return piece! } -function getTransitionPiece(context: ActionExecutionContext, part: 'current' | 'next'): IBlueprintPieceInstance { - const piece = context.getPieceInstances(part).find(p => p.piece.sourceLayerId === SourceLayer.PgmJingle) +async function getTransitionPiece( + context: ActionExecutionContext, + part: 'current' | 'next' +): Promise { + const piece = await context + .getPieceInstances(part) + .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === SourceLayer.PgmJingle)) expect(piece).toBeTruthy() return piece! @@ -485,14 +500,18 @@ function makeMockContext( } } -function checkPartExistsWithProperties( +async function checkPartExistsWithProperties( context: ActionExecutionContext, part: 'current' | 'next', props: Partial ) { - const partInstance = context.getPartInstance(part)! + const partInstance = await context.getPartInstance(part)! expect(partInstance).toBeTruthy() + if (partInstance === undefined) { + fail('PartInstances must not be undefined') + } + for (const k in props) { if (k in partInstance.part) { expect({ [k]: partInstance.part[k as keyof IBlueprintPart] }).toEqual({ [k]: props[k as keyof IBlueprintPart] }) @@ -503,10 +522,10 @@ function checkPartExistsWithProperties( } describe('Take with CUT', () => { - it('Sets the take flag', () => { + it('Sets the take flag', async () => { const context = makeMockContext('cut', 'cam', 'cam') - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.TAKE_WITH_TRANSITION, literal({ @@ -519,18 +538,18 @@ describe('Take with CUT', () => { ) expectNoWarningsOrErrors(context) - const camPiece = getCameraPiece(context, 'next') + const camPiece = await getCameraPiece(context, 'next') expectATEMToCut(camPiece) - const transitionPiece = getTransitionPiece(context, 'next') + const transitionPiece = await getTransitionPiece(context, 'next') expect(transitionPiece.piece.name).toBe(`CUT`) expectTakeAfterExecute(context) }) - it('Changes MIX on part to CUT', () => { + it('Changes MIX on part to CUT', async () => { const context = makeMockContext('mix', 'cam', 'cam') - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.TAKE_WITH_TRANSITION, literal({ @@ -543,18 +562,18 @@ describe('Take with CUT', () => { ) expectNoWarningsOrErrors(context) - const camPiece = getCameraPiece(context, 'next') + const camPiece = await getCameraPiece(context, 'next') expectATEMToCut(camPiece) - const transitionPiece = getTransitionPiece(context, 'next') + const transitionPiece = await getTransitionPiece(context, 'next') expect(transitionPiece.piece.name).toBe(`CUT`) expectTakeAfterExecute(context) }) - it('Removes EFFEKT from Next', () => { + it('Removes EFFEKT from Next', async () => { const context = makeMockContext('mix', 'cam', 'cam') - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.TAKE_WITH_TRANSITION, literal({ @@ -567,20 +586,20 @@ describe('Take with CUT', () => { ) expectNoWarningsOrErrors(context) - const camPiece = getCameraPiece(context, 'next') + const camPiece = await getCameraPiece(context, 'next') expectATEMToCut(camPiece) - const transitionPiece = getTransitionPiece(context, 'next') + const transitionPiece = await getTransitionPiece(context, 'next') expect(transitionPiece.piece.name).toBe(`CUT`) expectTakeAfterExecute(context) }) }) describe('Take with MIX', () => { - it('Adds MIX to part with CUT as default', () => { + it('Adds MIX to part with CUT as default', async () => { const context = makeMockContext('cut', 'cam', 'cam') - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.TAKE_WITH_TRANSITION, literal({ @@ -594,21 +613,25 @@ describe('Take with MIX', () => { ) expectNoWarningsOrErrors(context) - checkPartExistsWithProperties(context, 'next', { - transitionKeepaliveDuration: 800 + await checkPartExistsWithProperties(context, 'next', { + inTransition: { + previousPartKeepaliveDuration: 800, + blockTakeDuration: 800, + partContentDelayDuration: 0 + } }) - const camPiece = getCameraPiece(context, 'next') + const camPiece = await getCameraPiece(context, 'next') expectATEMToMixOver(camPiece, 20) - const transitionPiece = getTransitionPiece(context, 'next') + const transitionPiece = await getTransitionPiece(context, 'next') expect(transitionPiece.piece.name).toBe(`MIX 20`) expectTakeAfterExecute(context) }) - it('Changes MIX on part with MIX as default', () => { + it('Changes MIX on part with MIX as default', async () => { const context = makeMockContext('mix', 'cam', 'cam') - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.TAKE_WITH_TRANSITION, literal({ @@ -622,18 +645,18 @@ describe('Take with MIX', () => { ) expectNoWarningsOrErrors(context) - const camPiece = getCameraPiece(context, 'next') + const camPiece = await getCameraPiece(context, 'next') expectATEMToMixOver(camPiece, 20) - const transitionPiece = getTransitionPiece(context, 'next') + const transitionPiece = await getTransitionPiece(context, 'next') expect(transitionPiece.piece.name).toBe(`MIX 20`) expectTakeAfterExecute(context) }) - it('Removes EFFEKT from Next', () => { + it('Removes EFFEKT from Next', async () => { const context = makeMockContext('mix', 'cam', 'cam') - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.TAKE_WITH_TRANSITION, literal({ @@ -647,20 +670,20 @@ describe('Take with MIX', () => { ) expectNoWarningsOrErrors(context) - const camPiece = getCameraPiece(context, 'next') + const camPiece = await getCameraPiece(context, 'next') expectATEMToMixOver(camPiece, 20) - const transitionPiece = getTransitionPiece(context, 'next') + const transitionPiece = await getTransitionPiece(context, 'next') expect(transitionPiece.piece.name).toBe(`MIX 20`) expectTakeAfterExecute(context) }) }) describe('Take with EFFEKT', () => { - it('Adds EFFEKT to part with CUT as default', () => { + it('Adds EFFEKT to part with CUT as default', async () => { const context = makeMockContext('cut', 'cam', 'cam') - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.TAKE_WITH_TRANSITION, literal({ @@ -674,18 +697,18 @@ describe('Take with EFFEKT', () => { ) expectNoWarningsOrErrors(context) - const camPiece = getCameraPiece(context, 'next') + const camPiece = await getCameraPiece(context, 'next') expectATEMToCut(camPiece) - const transitionPiece = getTransitionPiece(context, 'next') + const transitionPiece = await getTransitionPiece(context, 'next') expect(transitionPiece.piece.name).toBe(`EFFEKT 1`) expectTakeAfterExecute(context) }) - it('Removes MIX from Next', () => { + it('Removes MIX from Next', async () => { const context = makeMockContext('mix', 'cam', 'cam') - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.TAKE_WITH_TRANSITION, literal({ @@ -699,18 +722,18 @@ describe('Take with EFFEKT', () => { ) expectNoWarningsOrErrors(context) - const camPiece = getCameraPiece(context, 'next') + const camPiece = await getCameraPiece(context, 'next') expectATEMToCut(camPiece) - const transitionPiece = getTransitionPiece(context, 'next') + const transitionPiece = await getTransitionPiece(context, 'next') expect(transitionPiece.piece.name).toBe(`EFFEKT 1`) expectTakeAfterExecute(context) }) - it('Adds EFFEKT to KAM when on EVS', () => { + it('Adds EFFEKT to KAM when on EVS', async () => { const context = makeMockContext('cut', 'evs', 'cam') - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.TAKE_WITH_TRANSITION, literal({ @@ -724,18 +747,18 @@ describe('Take with EFFEKT', () => { ) expectNoWarningsOrErrors(context) - const camPiece = getCameraPiece(context, 'next') + const camPiece = await getCameraPiece(context, 'next') expectATEMToCut(camPiece) - const transitionPiece = getTransitionPiece(context, 'next') + const transitionPiece = await getTransitionPiece(context, 'next') expect(transitionPiece.piece.name).toBe(`EFFEKT 1`) expectTakeAfterExecute(context) }) - it('Adds EFFEKT to EVS when on KAM', () => { + it('Adds EFFEKT to EVS when on KAM', async () => { const context = makeMockContext('cut', 'cam', 'evs') - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.TAKE_WITH_TRANSITION, literal({ @@ -749,17 +772,17 @@ describe('Take with EFFEKT', () => { ) expectNoWarningsOrErrors(context) - const camPiece = getEVSPiece(context, 'next') + const camPiece = await getEVSPiece(context, 'next') expectATEMToCut(camPiece) - const transitionPiece = getTransitionPiece(context, 'next') + const transitionPiece = await getTransitionPiece(context, 'next') expect(transitionPiece.piece.name).toBe(`EFFEKT 1`) expectTakeAfterExecute(context) }) }) describe('Camera shortcuts on server', () => { - it('It cuts directly to a camera on a server', () => { + it('It cuts directly to a camera on a server', async () => { const context = makeMockContext('cut', 'cam', 'cam') context.currentPieceInstances = [ @@ -786,7 +809,7 @@ describe('Camera shortcuts on server', () => { context.nextPart = undefined context.nextPieceInstances = [] - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.CUT_TO_CAMERA, literal({ @@ -797,12 +820,12 @@ describe('Camera shortcuts on server', () => { ) expectNoWarningsOrErrors(context) - const camPiece = getCameraPiece(context, 'next') + const camPiece = await getCameraPiece(context, 'next') expect(camPiece.piece.name).toEqual('KAM 1') expect(context.takeAfterExecute).toEqual(true) }) - it('It queues a camera without taking it', () => { + it('It queues a camera without taking it', async () => { const context = makeMockContext('cut', 'cam', 'cam') context.currentPieceInstances = [ @@ -829,7 +852,7 @@ describe('Camera shortcuts on server', () => { context.nextPart = undefined context.nextPieceInstances = [] - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.CUT_TO_CAMERA, literal({ @@ -840,14 +863,14 @@ describe('Camera shortcuts on server', () => { ) expectNoWarningsOrErrors(context) - const camPiece = getCameraPiece(context, 'next') + const camPiece = await getCameraPiece(context, 'next') expect(camPiece.piece.name).toEqual('KAM 1') expect(context.takeAfterExecute).toEqual(false) }) }) describe('Camera shortcuts on VO', () => { - it('It cuts directly to a camera on a VO', () => { + it('It cuts directly to a camera on a VO', async () => { const context = makeMockContext('cut', 'cam', 'cam') context.currentPieceInstances = [ @@ -874,7 +897,7 @@ describe('Camera shortcuts on VO', () => { context.nextPart = undefined context.nextPieceInstances = [] - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.CUT_TO_CAMERA, literal({ @@ -885,12 +908,12 @@ describe('Camera shortcuts on VO', () => { ) expectNoWarningsOrErrors(context) - const camPiece = getCameraPiece(context, 'next') + const camPiece = await getCameraPiece(context, 'next') expect(camPiece.piece.name).toEqual('KAM 1') expect(context.takeAfterExecute).toEqual(true) }) - it('It queues a camera without taking it', () => { + it('It queues a camera without taking it', async () => { const context = makeMockContext('cut', 'cam', 'cam') context.currentPieceInstances = [ @@ -917,7 +940,7 @@ describe('Camera shortcuts on VO', () => { context.nextPart = undefined context.nextPieceInstances = [] - executeActionAFVD( + await executeActionAFVD( context, AdlibActionType.CUT_TO_CAMERA, literal({ @@ -928,7 +951,7 @@ describe('Camera shortcuts on VO', () => { ) expectNoWarningsOrErrors(context) - const camPiece = getCameraPiece(context, 'next') + const camPiece = await getCameraPiece(context, 'next') expect(camPiece.piece.name).toEqual('KAM 1') expect(context.takeAfterExecute).toEqual(false) }) diff --git a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts index cecc3ae5f..ef11c3673 100644 --- a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts @@ -1,5 +1,3 @@ -import { ExtendedIngestRundown, TSR } from '@tv2media/blueprints-integration' -import { ShowStyleUserContext } from '../../__mocks__/context' import { checkAllLayers } from './layers-check' // @ts-ignore @@ -9,6 +7,8 @@ global.VERSION_TSR = 'test' // @ts-ignore global.VERSION_INTEGRATION = 'test' +import { ExtendedIngestRundown, IGetRundownContext, TSR } from '@tv2media/blueprints-integration' +import { GetRundownContext } from '../../__mocks__/context' import { GraphicLLayer } from '../../tv2-constants' import { parseConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' @@ -23,16 +23,18 @@ const SEGMENT_ID = 'test_segment' const PART_ID = 'test_part' describe('Baseline', () => { - test('Config: ' + configSpec.id, () => { + test('Config: ' + configSpec.id, async () => { expect(configSpec.studioConfig).toBeTruthy() expect(configSpec.showStyleConfig).toBeTruthy() const mockRundown: ExtendedIngestRundown = createMockRundown() - const mockContext: ShowStyleUserContext = createMockContext(mockRundown.name) + const mockContext: GetRundownContext = createMockContext(mockRundown.name) - const result = Blueprints.getRundown(mockContext, mockRundown) + const result = await Blueprints.getRundown(mockContext, mockRundown) + if (result === null) { + fail('Result is not allowed to null') + } - expect(result).not.toBeNull() expect(result.baseline.timelineObjects).not.toHaveLength(0) expect(result.globalAdLibPieces).not.toHaveLength(0) @@ -42,11 +44,14 @@ describe('Baseline', () => { expect(mockContext.getNotes()).toEqual([]) }) - test('SetConcept timeline object is created in base rundown', () => { + test('SetConcept timeline object is created in base rundown', async () => { const mockRundown: ExtendedIngestRundown = createMockRundown() - const mockContext: ShowStyleUserContext = createMockContext(mockRundown.name) + const mockContext: IGetRundownContext = createMockContext(mockRundown.name) - const rundown = Blueprints.getRundown(mockContext, mockRundown) + const rundown = await Blueprints.getRundown(mockContext, mockRundown) + if (rundown === null) { + fail('Result is not allowed to null') + } const result = rundown.baseline.timelineObjects.filter( timelineObject => @@ -69,8 +74,8 @@ function createMockRundown(): ExtendedIngestRundown { } } -function createMockContext(rundownName: string): ShowStyleUserContext { - const mockContext = new ShowStyleUserContext( +function createMockContext(rundownName: string): GetRundownContext { + const mockContext = new GetRundownContext( rundownName, mappingsDefaults, parseStudioConfig, diff --git a/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts b/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts index 66b648ed1..5178d61e8 100644 --- a/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/regressions.spec.ts @@ -112,7 +112,8 @@ describe('regressions-migrations', () => { ] } } - ] + ], + actions: [] } ] } @@ -216,7 +217,8 @@ describe('regressions-migrations', () => { ] } } - ] + ], + actions: [] } ] } 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 15b53b315..da1498b7d 100644 --- a/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts @@ -10,8 +10,9 @@ global.VERSION = 'test' global.VERSION_TSR = 'test' // @ts-ignore global.VERSION_INTEGRATION = 'test' + import { INewsStory, literal } from 'tv2-common' -import { SegmentUserContext, ShowStyleUserContext } from '../../__mocks__/context' +import { GetRundownContext, SegmentUserContext } from '../../__mocks__/context' import { parseConfig 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' @@ -26,7 +27,7 @@ const RUNDOWN_ID = 'test_rundown' const SEGMENT_ID = 'test_segment' const PART_ID = 'test_part' -describe('Rundown exceptions', () => { +describe('Rundown exceptions', async () => { for (const roSpec of rundowns) { const roData = require(roSpec.ro) as ExtendedIngestRundown test('Valid file: ' + roSpec.ro, () => { @@ -35,7 +36,7 @@ describe('Rundown exceptions', () => { expect(roData.type).toEqual('inews') }) - const showStyleContext = new ShowStyleUserContext( + const showStyleContext = new GetRundownContext( 'mockRo', mappingsDefaults, parseStudioConfig, @@ -47,9 +48,9 @@ describe('Rundown exceptions', () => { // can I do this?: showStyleContext.studioConfig = roSpec.studioConfig as any showStyleContext.showStyleConfig = roSpec.showStyleConfig as any - const blueprintRundown = Blueprints.getRundown(showStyleContext, roData) + const blueprintRundown = await Blueprints.getRundown(showStyleContext, roData) const rundown = literal({ - ...blueprintRundown.rundown, + ...blueprintRundown!.rundown, _id: 'mockRo', showStyleVariantId: 'mock' }) diff --git a/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts b/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts index 3836e7c9a..c7a688e06 100644 --- a/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/syncIngestChangesToPartInstance.spec.ts @@ -146,11 +146,19 @@ describe('Sync Ingest Changes To Part Instances', () => { it('Syncs part properties', () => { const context = makeMockContext() const existingPartInstance: BlueprintSyncIngestPartInstance = literal({ - partInstance: makePartinstance({ title: 'Kam 1', budgetDuration: 2000, transitionPrerollDuration: 200 }), + partInstance: makePartinstance({ + title: 'Kam 1', + budgetDuration: 2000, + inTransition: { partContentDelayDuration: 200, previousPartKeepaliveDuration: 0, blockTakeDuration: 0 } + }), pieceInstances: [] }) const newPart: BlueprintSyncIngestNewData = literal({ - part: makePart({ title: 'Kam 2', budgetDuration: 1000, transitionPrerollDuration: 500 }), + part: makePart({ + title: 'Kam 2', + budgetDuration: 1000, + inTransition: { partContentDelayDuration: 500, previousPartKeepaliveDuration: 0, blockTakeDuration: 0 } + }), pieceInstances: [], adLibPieces: [], actions: [], @@ -158,7 +166,7 @@ describe('Sync Ingest Changes To Part Instances', () => { }) syncIngestUpdateToPartInstance(context, existingPartInstance, newPart, 'current') - expect(context.updatedPartInstance?.part.transitionPrerollDuration).toBeUndefined() + expect(context.updatedPartInstance?.part.inTransition).toBeUndefined() expect(context.updatedPartInstance?.part.budgetDuration).toBe(1000) expect(context.updatedPartInstance?.part.title).toBe('Kam 2') }) diff --git a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts index 33661afce..7678b370f 100644 --- a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts @@ -97,10 +97,12 @@ function checkPartExistsWithProperties(segment: BlueprintResultSegment, props: P function getTransitionProperties(effekt: ShowStyleConfig['BreakerConfig'][0]): Partial { const preroll = defaultStudioConfig.CasparPrerollDuration as number return { - transitionDuration: TimeFromFrames(Number(effekt.Duration)) + preroll, - transitionKeepaliveDuration: TimeFromFrames(Number(effekt.StartAlpha)) + preroll, - transitionPrerollDuration: - TimeFromFrames(Number(effekt.Duration)) - TimeFromFrames(Number(effekt.EndAlpha)) + preroll + inTransition: { + blockTakeDuration: TimeFromFrames(Number(effekt.Duration)) + preroll, + previousPartKeepaliveDuration: TimeFromFrames(Number(effekt.StartAlpha)) + preroll, + partContentDelayDuration: + TimeFromFrames(Number(effekt.Duration)) - TimeFromFrames(Number(effekt.EndAlpha)) + preroll + } } } @@ -176,7 +178,11 @@ describe('Primary Cue Transitions Without Config', () => { const atemCutObj = getATEMMEObj(piece) checkPartExistsWithProperties(segment, { - transitionKeepaliveDuration: 440 + inTransition: { + previousPartKeepaliveDuration: 440, + partContentDelayDuration: 0, + blockTakeDuration: 440 + } }) expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.MIX) expect(atemCutObj.content.me.transitionSettings?.mix?.rate).toBe(11) @@ -229,7 +235,11 @@ describe('Primary Cue Transitions Without Config', () => { const atemCutObj = getATEMMEObj(piece) checkPartExistsWithProperties(segment, { - transitionKeepaliveDuration: 600 + inTransition: { + previousPartKeepaliveDuration: 600, + partContentDelayDuration: 0, + blockTakeDuration: 600 + } }) expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.MIX) expect(atemCutObj.content.me.transitionSettings?.mix?.rate).toBe(15) @@ -282,7 +292,11 @@ describe('Primary Cue Transitions Without Config', () => { const atemCutObj = getATEMMEObj(piece) checkPartExistsWithProperties(segment, { - transitionKeepaliveDuration: 1000 + inTransition: { + previousPartKeepaliveDuration: 1000, + partContentDelayDuration: 0, + blockTakeDuration: 1000 + } }) expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.MIX) expect(atemCutObj.content.me.transitionSettings?.mix?.rate).toBe(25) @@ -301,7 +315,6 @@ describe('Primary Cue Transitions Without Config', () => { const piece = getPieceOnLayerFromPart(segment, SourceLayer.PgmServer) const atemCutObj = getATEMMEObj(piece) - checkPartExistsWithProperties(segment, { prerollDuration: defaultStudioConfig.CasparPrerollDuration as number }) expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.CUT) }) @@ -336,8 +349,11 @@ describe('Primary Cue Transitions Without Config', () => { const atemCutObj = getATEMMEObj(piece) checkPartExistsWithProperties(segment, { - prerollDuration: defaultStudioConfig.CasparPrerollDuration as number, - transitionKeepaliveDuration: 800 + inTransition: { + previousPartKeepaliveDuration: 800, + partContentDelayDuration: 0, + blockTakeDuration: 800 + } }) expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.MIX) expect(atemCutObj.content.me.transitionSettings?.mix?.rate).toBe(20) @@ -356,7 +372,6 @@ describe('Primary Cue Transitions Without Config', () => { const piece = getPieceOnLayerFromPart(segment, SourceLayer.PgmVoiceOver) const atemCutObj = getATEMMEObj(piece) - checkPartExistsWithProperties(segment, { prerollDuration: defaultStudioConfig.CasparPrerollDuration as number }) expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.CUT) }) @@ -391,8 +406,11 @@ describe('Primary Cue Transitions Without Config', () => { const atemCutObj = getATEMMEObj(piece) checkPartExistsWithProperties(segment, { - prerollDuration: defaultStudioConfig.CasparPrerollDuration as number, - transitionKeepaliveDuration: 800 + inTransition: { + previousPartKeepaliveDuration: 800, + partContentDelayDuration: 0, + blockTakeDuration: 800 + } }) expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.MIX) expect(atemCutObj.content.me.transitionSettings?.mix?.rate).toBe(20) diff --git a/src/tv2_afvd_showstyle/actions.ts b/src/tv2_afvd_showstyle/actions.ts index 6d3b78d25..ca27992fd 100644 --- a/src/tv2_afvd_showstyle/actions.ts +++ b/src/tv2_afvd_showstyle/actions.ts @@ -9,8 +9,12 @@ import { createJingleContentAFVD } from './helpers/pieces/jingle' import { SourceLayer } from './layers' import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' -export function executeActionAFVD(context: IActionExecutionContext, actionId: string, userData: ActionUserData): void { - executeAction( +export async function executeActionAFVD( + context: IActionExecutionContext, + actionId: string, + userData: ActionUserData +): Promise { + await executeAction( context, { getConfig, diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 74a80d37c..d0416e640 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -29,6 +29,7 @@ import { CreateGraphicBaseline, CreateLYDBaseline, FindDSKJingle, + generateExternalId, GetEksternMetaData, GetLayersForEkstern, GetSisyfosTimelineObjForCamera, @@ -605,7 +606,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint } function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: BlueprintConfig): IBlueprintActionManifest[] { - const res: IBlueprintActionManifest[] = [] + const blueprintActions: IBlueprintActionManifest[] = [] let globalRank = 1000 @@ -614,16 +615,19 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri const feed = type === 'Live' && info.id.match(/^F(.+).*$/) // TODO: fix when refactoring FindSourceInfo const name = feed ? `Feed ${feed[1]}` : `${type} ${info.id}` const layer = type === 'Kamera' ? SourceLayer.PgmCam : SourceLayer.PgmLive - res.push( + + const userData = literal({ + type: AdlibActionType.CUT_SOURCE_TO_BOX, + name, + port: info.port, + sourceType: info.type, + box + }) + blueprintActions.push( literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CUT_SOURCE_TO_BOX, - userData: literal({ - type: AdlibActionType.CUT_SOURCE_TO_BOX, - name, - port: info.port, - sourceType: info.type, - box - }), + userData, userDataManifest: {}, display: { _rank: rank + 0.1 * box, @@ -640,17 +644,19 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri function makeAdlibBoxesActionsDirectPlayback(info: SourceInfo, vo: boolean, rank: number) { for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { - res.push( + const userData = literal({ + type: AdlibActionType.CUT_SOURCE_TO_BOX, + name: `EVS ${info.id.replace(/dp/i, '')}${vo ? ' VO' : ''}`, + port: info.port, + sourceType: info.type, + box, + vo + }) + blueprintActions.push( literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CUT_SOURCE_TO_BOX, - userData: literal({ - type: AdlibActionType.CUT_SOURCE_TO_BOX, - name: `EVS ${info.id.replace(/dp/i, '')}${vo ? ' VO' : ''}`, - port: info.port, - sourceType: info.type, - box, - vo - }), + userData, userDataManifest: {}, display: { _rank: rank + 0.1 * box, @@ -667,17 +673,19 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri function makeServerAdlibBoxesActions(rank: number) { for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { - res.push( + const userData = literal({ + type: AdlibActionType.CUT_SOURCE_TO_BOX, + name: `SERVER`, + port: -1, + sourceType: SourceLayerType.VT, + box, + server: true + }) + blueprintActions.push( literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CUT_SOURCE_TO_BOX, - userData: literal({ - type: AdlibActionType.CUT_SOURCE_TO_BOX, - name: `SERVER`, - port: -1, - sourceType: SourceLayerType.VT, - box, - server: true - }), + userData, userDataManifest: {}, display: { _rank: rank + 0.1 * box, @@ -693,14 +701,16 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri } function makeCutCameraActions(info: SourceInfo, queue: boolean, rank: number) { - res.push( + const userData = literal({ + type: AdlibActionType.CUT_TO_CAMERA, + queue, + name: info.id + }) + blueprintActions.push( literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CUT_TO_CAMERA, - userData: literal({ - type: AdlibActionType.CUT_TO_CAMERA, - queue, - name: info.id - }), + userData, userDataManifest: {}, display: { _rank: rank, @@ -735,22 +745,28 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri makeAdlibBoxesActions(o, 'Kamera', globalRank++) }) - res.push( - literal({ - actionId: AdlibActionType.RECALL_LAST_LIVE, - userData: literal({ - type: AdlibActionType.RECALL_LAST_LIVE - }), - userDataManifest: {}, - display: { - _rank: 1, - label: t('Last Live'), - sourceLayerId: SourceLayer.PgmLive, - outputLayerId: SharedOutputLayers.PGM, - tags: [AdlibTags.ADLIB_RECALL_LAST_LIVE] - } + function makeRecallLastLiveAction() { + const userData = literal({ + type: AdlibActionType.RECALL_LAST_LIVE }) - ) + blueprintActions.push( + literal({ + 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 .filter(u => u.type === SourceLayerType.REMOTE) @@ -769,14 +785,16 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri makeServerAdlibBoxesActions(globalRank++) - res.push( - literal({ + function makeClearGraphicsAction() { + const userData = literal({ + type: AdlibActionType.CLEAR_GRAPHICS, + sendCommands: true, + label: 'GFX Clear' + }) + return literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CLEAR_GRAPHICS, - userData: literal({ - type: AdlibActionType.CLEAR_GRAPHICS, - sendCommands: true, - label: 'GFX Clear' - }), + userData, userDataManifest: {}, display: { _rank: 300, @@ -788,14 +806,19 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri currentPieceTags: [TallyTags.GFX_CLEAR], nextPieceTags: [TallyTags.GFX_CLEAR] } - }), - literal({ + }) + } + + function makeClearGraphicsAltudAction() { + const userData = literal({ + type: AdlibActionType.CLEAR_GRAPHICS, + sendCommands: false, + label: 'GFX Altud' + }) + return literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CLEAR_GRAPHICS, - userData: literal({ - type: AdlibActionType.CLEAR_GRAPHICS, - sendCommands: false, - label: 'GFX Altud' - }), + userData, userDataManifest: {}, display: { _rank: 400, @@ -808,16 +831,20 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri nextPieceTags: [TallyTags.GFX_ALTUD] } }) - ) + } + + blueprintActions.push(makeClearGraphicsAction(), makeClearGraphicsAltudAction()) - res.push(...GetTransitionAdLibActions(config, 800)) + blueprintActions.push(...GetTransitionAdLibActions(config, 800)) - res.push( + const recallLastLiveDveUserData = literal({ + type: AdlibActionType.RECALL_LAST_DVE + }) + blueprintActions.push( literal({ + externalId: generateExternalId(_context, recallLastLiveDveUserData), actionId: AdlibActionType.RECALL_LAST_DVE, - userData: literal({ - type: AdlibActionType.RECALL_LAST_DVE - }), + userData: recallLastLiveDveUserData, userDataManifest: {}, display: { _rank: 1, @@ -831,13 +858,15 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri _.each(config.showStyle.DVEStyles, (dveConfig, i) => { // const boxSources = ['', '', '', ''] - res.push( + const userData = literal({ + type: AdlibActionType.SELECT_DVE_LAYOUT, + config: dveConfig + }) + blueprintActions.push( literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.SELECT_DVE_LAYOUT, - userData: literal({ - type: AdlibActionType.SELECT_DVE_LAYOUT, - config: dveConfig - }), + userData, userDataManifest: {}, display: { _rank: 200 + i, @@ -850,7 +879,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri ) }) - return res + return blueprintActions } function getBaseline(config: BlueprintConfig): BlueprintResultBaseline { diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index 85727b197..0d0f7d17b 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -94,6 +94,7 @@ export function CreatePartContinuity(config: ShowStyleConfig, ingestSegment: Ing }) }) ], - adLibPieces: [] + adLibPieces: [], + actions: [] }) } 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 84c602471..5d9cf8807 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -2,7 +2,6 @@ import { GraphicsContent, IBlueprintActionManifest, IBlueprintAdLibPiece, - IBlueprintPart, IBlueprintPiece, PieceLifespan, TSR, @@ -50,11 +49,6 @@ const dummyPart = literal({ segmentExternalId: '' }) -const dummyBlueprintPart: IBlueprintPart = { - title: 'Kam 1', - externalId: '0001' -} - const dskEnableObj = literal({ id: '', enable: { @@ -106,7 +100,6 @@ describe('grafik piece', () => { EvaluateCueGraphic( config, makeMockContext(), - dummyBlueprintPart, pieces, adLibPieces, actions, @@ -175,7 +168,6 @@ describe('grafik piece', () => { EvaluateCueGraphic( config, makeMockContext(), - dummyBlueprintPart, pieces, adLibPieces, actions, @@ -281,7 +273,6 @@ describe('grafik piece', () => { EvaluateCueGraphic( newConfig, makeMockContext(), - dummyBlueprintPart, pieces, adLibPieces, actions, @@ -387,7 +378,6 @@ describe('grafik piece', () => { EvaluateCueGraphic( config, makeMockContext(), - dummyBlueprintPart, pieces, adLibPieces, actions, @@ -461,7 +451,6 @@ describe('grafik piece', () => { EvaluateCueGraphic( config, makeMockContext(), - dummyBlueprintPart, pieces, adLibPieces, actions, @@ -531,7 +520,6 @@ describe('grafik piece', () => { EvaluateCueGraphic( config, makeMockContext(), - dummyBlueprintPart, pieces, adLibPieces, actions, @@ -625,7 +613,6 @@ describe('grafik piece', () => { EvaluateCueGraphic( config, makeMockContext(), - dummyBlueprintPart, pieces, adLibPieces, actions, @@ -694,7 +681,6 @@ describe('grafik piece', () => { EvaluateCueGraphic( config, makeMockContext(), - dummyBlueprintPart, pieces, adLibPieces, actions, @@ -777,59 +763,7 @@ describe('grafik piece', () => { ]) }) - it('Applies delay to WALL graphics when part has prerollDuration', () => { - const partWithPreroll: IBlueprintPart = { - title: 'Server', - externalId: '0001', - prerollDuration: 1000 - } - const cue: CueDefinitionGraphic = { - type: CueType.Graphic, - target: 'WALL', - graphic: { - type: 'pilot', - name: '', - vcpid: 1234567890, - continueCount: -1 - }, - iNewsCommand: 'GRAFIK' - } - - const pieces: IBlueprintPiece[] = [] - const adLibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] - const partId = '0000000001' - - EvaluateCueGraphic( - config, - makeMockContext(), - partWithPreroll, - pieces, - adLibPieces, - actions, - partId, - cue, - cue.adlib ? cue.adlib : false, - dummyPart, - 0 - ) - const piece = pieces[0] - expect(piece).toBeTruthy() - const tlObj = (piece.content?.timelineObjects as TSR.TSRTimelineObj[]).find( - obj => - obj.content.deviceType === TSR.DeviceType.VIZMSE && - obj.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT - ) as TSR.TimelineObjVIZMSEElementInternal | undefined - expect(tlObj).toBeTruthy() - expect(tlObj?.enable).toEqual({ start: 1000 }) - }) - - it('Applies delay to WALL graphics when part has transitionPrerollDuration', () => { - const partWithPreroll: IBlueprintPart = { - title: 'Kam 1', - externalId: '0001', - transitionPrerollDuration: 2000 - } + it('WALL graphics have enable equal while 1', () => { const cue: CueDefinitionGraphic = { type: CueType.Graphic, target: 'WALL', @@ -850,7 +784,6 @@ describe('grafik piece', () => { EvaluateCueGraphic( config, makeMockContext(), - partWithPreroll, pieces, adLibPieces, actions, @@ -868,6 +801,6 @@ describe('grafik piece', () => { obj.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT ) as TSR.TimelineObjVIZMSEElementInternal | undefined expect(tlObj).toBeTruthy() - expect(tlObj?.enable).toEqual({ start: 2000 }) + expect(tlObj?.enable).toEqual({ while: '1' }) }) }) 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 7e07edbad..554fbe31c 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -2,7 +2,6 @@ import { GraphicsContent, IBlueprintActionManifest, IBlueprintAdLibPiece, - IBlueprintPart, IBlueprintPiece, PieceLifespan, TSR, @@ -49,11 +48,6 @@ const dummyPart = literal({ segmentExternalId: '' }) -const dummyBlueprintPart: IBlueprintPart = { - title: 'Kam 1', - externalId: '0001' -} - describe('telefon', () => { test('telefon with vizObj', () => { const cue: CueDefinitionTelefon = { @@ -90,7 +84,6 @@ describe('telefon', () => { dsk: defaultDSKConfig }, mockContext, - dummyBlueprintPart, pieces, adLibPieces, actions, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts index d165e30b4..e4f981d8e 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts @@ -73,7 +73,7 @@ export function EvaluateDVE( lifespan: PieceLifespan.WithinPart, toBeQueued: true, content: content.content, - adlibPreroll: Number(config.studio.CasparPrerollDuration) || 0, + prerollDuration: Number(config.studio.CasparPrerollDuration) || 0, metaData: literal({ sources: parsedCue.sources, config: rawTemplate, @@ -103,7 +103,7 @@ export function EvaluateDVE( lifespan: PieceLifespan.WithinPart, toBeQueued: true, content: content.content, - adlibPreroll: Number(config.studio.CasparPrerollDuration) || 0, + prerollDuration: Number(config.studio.CasparPrerollDuration) || 0, metaData: literal({ mediaPlayerSessions: [partDefinition.segmentExternalId], sources: parsedCue.sources, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts index d55e81e7a..72eb3f665 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts @@ -1,7 +1,6 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, - IBlueprintPart, IBlueprintPiece, ISegmentUserContext } from '@tv2media/blueprints-integration' @@ -20,7 +19,6 @@ import { EvaluateCueRouting } from './routing' export function EvaluateCueGraphic( config: BlueprintConfig, context: ISegmentUserContext, - part: Readonly, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -35,24 +33,11 @@ export function EvaluateCueGraphic( } if (GraphicIsInternal(parsedCue)) { - CreateInternalGraphic( - config, - context, - part, - pieces, - adlibPieces, - actions, - partId, - parsedCue, - adlib, - partDefinition, - rank - ) + CreateInternalGraphic(config, context, pieces, adlibPieces, actions, partId, parsedCue, adlib, partDefinition, rank) } else if (GraphicIsPilot(parsedCue)) { EvaluateCueGraphicPilot( config, context, - part, pieces, adlibPieces, actions, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts index 0fad4ec5b..d2d781a27 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts @@ -1,7 +1,6 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, - IBlueprintPart, IBlueprintPiece, IShowStyleUserContext, IStudioUserContext, @@ -31,7 +30,6 @@ export const pilotGeneratorSettingsAFVD: PilotGeneratorSettings = { export function EvaluateCueGraphicPilot( config: BlueprintConfig, context: IShowStyleUserContext, - part: Readonly, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -44,7 +42,6 @@ export function EvaluateCueGraphicPilot( CreatePilotGraphic( config, context, - part, pieces, adlibPieces, actions, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts index 373f8cd36..209022b80 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts @@ -9,14 +9,15 @@ import { ActionSelectJingle, CreateJingleContentBase, CueDefinitionJingle, + generateExternalId, GetTagForJingle, GetTagForJingleNext, literal, PartDefinition, - PieceMetaData, - t + t, + TimeFromFrames } from 'tv2-common' -import { AdlibActionType, AdlibTags, SharedOutputLayers } from 'tv2-constants' +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' @@ -51,14 +52,16 @@ export function EvaluateJingle( } if (adlib) { + const userData = literal({ + type: AdlibActionType.SELECT_JINGLE, + clip: parsedCue.clip, + segmentExternalId: part.segmentExternalId + }) actions.push( literal({ + externalId: generateExternalId(context, userData), actionId: AdlibActionType.SELECT_JINGLE, - userData: literal({ - type: AdlibActionType.SELECT_JINGLE, - clip: parsedCue.clip, - segmentExternalId: part.segmentExternalId - }), + userData, userDataManifest: {}, display: { _rank: rank ?? 0, @@ -93,12 +96,8 @@ export function EvaluateJingle( lifespan: PieceLifespan.WithinPart, outputLayerId: SharedOutputLayers.JINGLE, sourceLayerId: SourceLayer.PgmJingle, - metaData: literal({ - transition: { - isJingle: !effekt, - isEffekt: !!effekt - } - }), + prerollDuration: config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), + tags: [!effekt ? TallyTags.JINGLE : ''], content: createJingleContentAFVD( config, file, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts index 440c3b1ba..15c3758df 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts @@ -1,7 +1,6 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, - IBlueprintPart, IBlueprintPiece, ISegmentUserContext, TSR @@ -20,7 +19,6 @@ import { EvaluateCueGraphic } from './graphic' export function EvaluateTelefon( config: BlueprintConfig, context: ISegmentUserContext, - part: Readonly, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -34,7 +32,6 @@ export function EvaluateTelefon( EvaluateCueGraphic( config, context, - part, pieces, adlibPieces, actions, diff --git a/src/tv2_afvd_showstyle/helpers/sisyfos/__tests__/sisyfos.spec.ts b/src/tv2_afvd_showstyle/helpers/sisyfos/__tests__/sisyfos.spec.ts deleted file mode 100644 index 30d90ab45..000000000 --- a/src/tv2_afvd_showstyle/helpers/sisyfos/__tests__/sisyfos.spec.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { GetStickyForPiece, literal, PieceMetaData } from 'tv2-common' -import { SisyfosLLAyer } from '../../../../tv2_afvd_studio/layers' - -export const STUDIO_MICS = [ - SisyfosLLAyer.SisyfosSourceHost_1_ST_A, - SisyfosLLAyer.SisyfosSourceHost_2_ST_A, - SisyfosLLAyer.SisyfosSourceGuest_1_ST_A, - SisyfosLLAyer.SisyfosSourceGuest_2_ST_A, - SisyfosLLAyer.SisyfosSourceGuest_3_ST_A, - SisyfosLLAyer.SisyfosSourceGuest_4_ST_A -] - -export const LIVE_AUDIO = [ - SisyfosLLAyer.SisyfosSourceLive_1, - SisyfosLLAyer.SisyfosSourceLive_2, - SisyfosLLAyer.SisyfosSourceLive_3, - SisyfosLLAyer.SisyfosSourceLive_4, - SisyfosLLAyer.SisyfosSourceLive_5, - SisyfosLLAyer.SisyfosSourceLive_6, - SisyfosLLAyer.SisyfosSourceLive_7, - SisyfosLLAyer.SisyfosSourceLive_8, - SisyfosLLAyer.SisyfosSourceLive_9, - SisyfosLLAyer.SisyfosSourceLive_10 -] - -export const STICKY_LAYERS = [...STUDIO_MICS, ...LIVE_AUDIO] - -describe('sisyfos', () => { - test('GetStickyForPiece', () => { - const result = GetStickyForPiece( - STUDIO_MICS.map<{ layer: SisyfosLLAyer; isPgm: 0 | 1 | 2 }>(layer => { - return { - layer, - isPgm: 1 - } - }), - STICKY_LAYERS - ) - expect(result).toEqual( - literal({ - stickySisyfosLevels: { - sisyfos_source_Host_1_st_a: { - value: 1, - followsPrevious: false - }, - sisyfos_source_Host_2_st_a: { - value: 1, - followsPrevious: false - }, - sisyfos_source_Guest_1_st_a: { - value: 1, - followsPrevious: false - }, - sisyfos_source_Guest_2_st_a: { - value: 1, - followsPrevious: false - }, - sisyfos_source_Guest_3_st_a: { - value: 1, - followsPrevious: false - }, - sisyfos_source_Guest_4_st_a: { - value: 1, - followsPrevious: false - } - } - }) - ) - }) -}) diff --git a/src/tv2_afvd_showstyle/helpers/time.ts b/src/tv2_afvd_showstyle/helpers/time.ts deleted file mode 100644 index 14164887c..000000000 --- a/src/tv2_afvd_showstyle/helpers/time.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { IBlueprintPart } from '@tv2media/blueprints-integration' -import { INewsStory, TimeFromINewsField } from 'tv2-common' - -export function GetTimeFromPart(story: INewsStory): Partial { - return { - expectedDuration: TimeFromINewsField(story.fields.audioTime), - prerollDuration: 0 - } -} diff --git a/src/tv2_afvd_showstyle/parts/cueonly.ts b/src/tv2_afvd_showstyle/parts/cueonly.ts index fa5f05f67..8ecdee192 100644 --- a/src/tv2_afvd_showstyle/parts/cueonly.ts +++ b/src/tv2_afvd_showstyle/parts/cueonly.ts @@ -52,8 +52,6 @@ export function CreatePartCueOnly( !partDefinition.cues.filter(c => c.type === CueType.Jingle).length ) { ApplyFullGraphicPropertiesToPart(config, part) - } else if (partDefinition.cues.filter(c => c.type === CueType.DVE).length) { - part.prerollDuration = config.studio.CasparPrerollDuration } EvaluateCues(context, config, part, pieces, adLibPieces, actions, mediaSubscriptions, [cue], partDefinitionWithID, {}) diff --git a/src/tv2_afvd_showstyle/parts/unknown.ts b/src/tv2_afvd_showstyle/parts/unknown.ts index eccf3a3ee..a141069c7 100644 --- a/src/tv2_afvd_showstyle/parts/unknown.ts +++ b/src/tv2_afvd_showstyle/parts/unknown.ts @@ -51,8 +51,6 @@ export function CreatePartUnknown( !partDefinition.cues.filter(c => c.type === CueType.Jingle).length ) { ApplyFullGraphicPropertiesToPart(config, part) - } else if (partDefinition.cues.filter(cue => cue.type === CueType.DVE).length) { - part.prerollDuration = config.studio.CasparPrerollDuration } EvaluateCues( diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index bc5736403..d3db32201 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -152,7 +152,7 @@ describe('Graphics', () => { expect(piece.sourceLayerId).toBe(SourceLayer.PgmPilot) expect(piece.outputLayerId).toBe(SharedOutputLayers.PGM) expect(piece.enable).toEqual({ start: 0 }) - expect(piece.adlibPreroll).toBe(config.studio.VizPilotGraphics.PrerollDuration) + expect(piece.prerollDuration).toBe(config.studio.VizPilotGraphics.PrerollDuration) expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] @@ -217,7 +217,7 @@ describe('Graphics', () => { expect(piece.sourceLayerId).toBe(SourceLayer.PgmPilotOverlay) expect(piece.outputLayerId).toBe(SharedOutputLayers.OVERLAY) expect(piece.enable).toEqual({ start: 2000 }) - expect(piece.adlibPreroll).toBe(config.studio.VizPilotGraphics.PrerollDuration) + expect(piece.prerollDuration).toBe(config.studio.VizPilotGraphics.PrerollDuration) expect(piece.lifespan).toBe(PieceLifespan.OutOnShowStyleEnd) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] @@ -275,7 +275,7 @@ describe('Graphics', () => { expect(piece.sourceLayerId).toBe(SourceLayer.WallGraphics) expect(piece.outputLayerId).toBe(SharedOutputLayers.SEC) expect(piece.enable).toEqual({ start: 0 }) - expect(piece.adlibPreroll).toBe(config.studio.VizPilotGraphics.PrerollDuration) + expect(piece.prerollDuration).toBe(config.studio.VizPilotGraphics.PrerollDuration) expect(piece.lifespan).toBe(PieceLifespan.OutOnShowStyleEnd) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] @@ -330,7 +330,7 @@ describe('Graphics', () => { expect(piece.sourceLayerId).toBe(SourceLayer.PgmGraphicsTLF) expect(piece.outputLayerId).toBe(SharedOutputLayers.PGM) expect(piece.enable).toEqual({ start: 0 }) - expect(piece.adlibPreroll).toBe(config.studio.VizPilotGraphics.PrerollDuration) + expect(piece.prerollDuration).toBe(config.studio.VizPilotGraphics.PrerollDuration) expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] diff --git a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts index 089600d10..82d5db5b7 100644 --- a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts @@ -35,9 +35,6 @@ const CURRENT_PART_ID = 'MOCK_PART_CURRENT' const CURRENT_PART_EXTERNAL_ID = `${CURRENT_PART_ID}_EXTERNAL` const SERVER_DURATION_A = 12000 const VO_DURATION_A = 20000 -const SERVER_PREROLL = 280 -const DVE_PREROLL = 280 -const FULL_PREROLL = 280 const FULL_KEEPALIVE = 1000 const currentPartMock: IBlueprintPartInstance = { @@ -242,48 +239,74 @@ interface ActivePiecesForSource { dataStore: IBlueprintPieceInstance | undefined } -function getServerPieces(context: ActionExecutionContext, part: 'current' | 'next'): ActivePiecesForSource { +async function getActiveServerPieces( + context: ActionExecutionContext, + part: 'current' | 'next' +): Promise { return { - activePiece: context.getPieceInstances(part).find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmServer), - dataStore: context.getPieceInstances(part).find(p => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedServer) + activePiece: await context + .getPieceInstances(part) + .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)) } } -function getVOPieces(context: ActionExecutionContext, part: 'current' | 'next'): ActivePiecesForSource { +async function getVOPieces(context: ActionExecutionContext, part: 'current' | 'next'): Promise { return { - activePiece: context.getPieceInstances(part).find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmVoiceOver), - dataStore: context.getPieceInstances(part).find(p => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedVoiceOver) + activePiece: await context + .getPieceInstances(part) + .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)) } } -function getDVEPieces(context: ActionExecutionContext, part: 'current' | 'next'): ActivePiecesForSource { +async function getDVEPieces(context: ActionExecutionContext, part: 'current' | 'next'): Promise { return { - activePiece: context.getPieceInstances(part).find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmDVE), - dataStore: context.getPieceInstances(part).find(p => p.piece.sourceLayerId === OfftubeSourceLayer.SelectedAdLibDVE) + activePiece: await context + .getPieceInstances(part) + .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)) } } -function getFullGrafikPieces(context: ActionExecutionContext, part: 'current' | 'next'): ActivePiecesForSource { +async function getFullGrafikPieces( + context: ActionExecutionContext, + part: 'current' | 'next' +): Promise { return { - activePiece: context.getPieceInstances(part).find(p => p.piece.sourceLayerId === SharedSourceLayers.PgmPilot), - dataStore: context + activePiece: await context .getPieceInstances(part) - .find(p => p.piece.sourceLayerId === SharedSourceLayers.SelectedAdlibGraphicsFull) + .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) + ) } } -function getCameraPiece( +async function getCameraPiece( context: ActionExecutionContext, part: 'current' | 'next' -): IBlueprintPieceInstance | undefined { - return context.getPieceInstances(part).find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmCam) +): Promise { + return context + .getPieceInstances(part) + .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmCam)) } -function getRemotePiece( +async function getRemotePiece( context: ActionExecutionContext, part: 'current' | 'next' -): IBlueprintPieceInstance | undefined { - return context.getPieceInstances(part).find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmLive) +): Promise { + return context + .getPieceInstances(part) + .then(pieceInstances => pieceInstances.find(p => p.piece.sourceLayerId === OfftubeSourceLayer.PgmLive)) } function validateSourcePiecesExist(pieces: ActivePiecesForSource) { @@ -291,6 +314,12 @@ function validateSourcePiecesExist(pieces: ActivePiecesForSource) { expect(pieces.dataStore).toBeTruthy() } +function validateSourcePiecesExistWithPrerollDuration(pieces: ActivePiecesForSource) { + validateSourcePiecesExist(pieces) + expect(pieces.activePiece!.piece.prerollDuration) + expect(pieces.dataStore!.piece.prerollDuration) +} + function validateOnlySelectionIsPreserved(pieces: ActivePiecesForSource) { expect(pieces.activePiece).toBeFalsy() expect(pieces.dataStore).toBeTruthy() @@ -321,14 +350,9 @@ function validateNextPartExistsWithDuration(context: ActionExecutionContext, dur expect(context.nextPart?.part.expectedDuration).toEqual(duration) } -function validateNextPartExistsWithPreRoll(context: ActionExecutionContext, duration: number) { - expect(context.nextPart).toBeTruthy() - expect(context.nextPart?.part.prerollDuration).toEqual(duration) -} - -function validateNextPartExistsWithTransitionKeepAlive(context: ActionExecutionContext, duration: number) { +function validateNextPartExistsWithPreviousPartKeepaliveDuration(context: ActionExecutionContext, duration: number) { expect(context.nextPart).toBeTruthy() - expect(context.nextPart?.part.transitionKeepaliveDuration).toEqual(duration) + expect(context.nextPart?.part.inTransition?.previousPartKeepaliveDuration).toEqual(duration) } function getATEMMEObj(piece: IBlueprintPieceInstance): TSR.TimelineObjAtemME { @@ -357,7 +381,7 @@ function expectATEMToMixOver(piece: IBlueprintPieceInstance, frames: number) { } describe('Select Server Action', () => { - it('Inserts a new part when no next part is present', () => { + it('Inserts a new part when no next part is present', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -373,19 +397,18 @@ describe('Select Server Action', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) - const pieces = getServerPieces(context, 'next') + const activePieces: ActivePiecesForSource = await getActiveServerPieces(context, 'next') validateNextPartExistsWithDuration(context, SERVER_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) - validateSourcePiecesExist(pieces) - expect(pieces.dataStore?.piece.lifespan).toEqual(PieceLifespan.OutOnSegmentEnd) + validateSourcePiecesExistWithPrerollDuration(activePieces) + expect(activePieces.dataStore?.piece.lifespan).toEqual(PieceLifespan.OutOnSegmentEnd) validateNoWarningsOrErrors(context) }) - it('Leaves current part unaffected when a clip is currently playing', () => { + it('Leaves current part unaffected when a clip is currently playing', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -401,10 +424,10 @@ describe('Select Server Action', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) - const currentPieces = getServerPieces(context, 'current') - const nextPieces = getServerPieces(context, 'next') + const currentPieces = await getActiveServerPieces(context, 'current') + const nextPieces = await getActiveServerPieces(context, 'next') validateSourcePiecesExist(currentPieces) expect(currentPieces.activePiece?.piece.name).toEqual('Playing Server') @@ -417,7 +440,7 @@ describe('Select Server Action', () => { }) describe('Combination Actions', () => { - it('Server -> DVE', () => { + it('Server -> DVE', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -433,26 +456,24 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) - let serverPieces = getServerPieces(context, 'next') + let serverPieces = await getActiveServerPieces(context, 'next') validateNextPartExistsWithDuration(context, SERVER_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) - validateSourcePiecesExist(serverPieces) + validateSourcePiecesExistWithPrerollDuration(serverPieces) - executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) + await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) - serverPieces = getServerPieces(context, 'next') - const dvePieces = getDVEPieces(context, 'next') + serverPieces = await getActiveServerPieces(context, 'next') + const dvePieces = await getDVEPieces(context, 'next') validateNextPartExistsWithDuration(context, 0) - validateNextPartExistsWithPreRoll(context, DVE_PREROLL) validateOnlySelectionIsPreserved(serverPieces) - validateSourcePiecesExist(dvePieces) + validateSourcePiecesExistWithPrerollDuration(dvePieces) }) - it('Server -> Full', () => { + it('Server -> Full', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -468,27 +489,25 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) - let serverPieces = getServerPieces(context, 'next') + let serverPieces = await getActiveServerPieces(context, 'next') validateNextPartExistsWithDuration(context, SERVER_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) - validateSourcePiecesExist(serverPieces) + validateSourcePiecesExistWithPrerollDuration(serverPieces) - executeActionOfftube(context, AdlibActionType.SELECT_FULL_GRAFIK, selectFullGrafikAction) + await executeActionOfftube(context, AdlibActionType.SELECT_FULL_GRAFIK, selectFullGrafikAction) - serverPieces = getServerPieces(context, 'next') - const fullGrafikPieces = getFullGrafikPieces(context, 'next') + serverPieces = await getActiveServerPieces(context, 'next') + const fullGrafikPieces = await getFullGrafikPieces(context, 'next') validateNextPartExistsWithDuration(context, 0) - validateNextPartExistsWithPreRoll(context, FULL_PREROLL) - validateNextPartExistsWithTransitionKeepAlive(context, FULL_KEEPALIVE) + validateNextPartExistsWithPreviousPartKeepaliveDuration(context, FULL_KEEPALIVE) validateOnlySelectionIsPreserved(serverPieces) - validateSourcePiecesExist(fullGrafikPieces) + validateSourcePiecesExistWithPrerollDuration(fullGrafikPieces) }) - it('Server -> VO', () => { + it('Server -> VO', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -504,27 +523,25 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) - let serverPieces = getServerPieces(context, 'next') + let serverPieces = await getActiveServerPieces(context, 'next') validateNextPartExistsWithDuration(context, SERVER_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) - validateSourcePiecesExist(serverPieces) + validateSourcePiecesExistWithPrerollDuration(serverPieces) - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectVOClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectVOClipAction) - serverPieces = getServerPieces(context, 'next') - const voPieces = getVOPieces(context, 'next') + serverPieces = await getActiveServerPieces(context, 'next') + const voPieces = await getVOPieces(context, 'next') validateNextPartExistsWithDuration(context, VO_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) validateSelectionRemoved(serverPieces) - validateSourcePiecesExist(voPieces) + validateSourcePiecesExistWithPrerollDuration(voPieces) expect(voPieces.dataStore?.piece.name).toEqual('VOVOA') }) - it('Server -> DVE', () => { + it('Server -> DVE', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -540,26 +557,24 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) - let serverPieces = getServerPieces(context, 'next') + let serverPieces = await getActiveServerPieces(context, 'next') validateNextPartExistsWithDuration(context, SERVER_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) - validateSourcePiecesExist(serverPieces) + validateSourcePiecesExistWithPrerollDuration(serverPieces) - executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) + await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) - serverPieces = getServerPieces(context, 'next') - const dvePieces = getDVEPieces(context, 'next') + serverPieces = await getActiveServerPieces(context, 'next') + const dvePieces = await getDVEPieces(context, 'next') validateNextPartExistsWithDuration(context, 0) - validateNextPartExistsWithPreRoll(context, DVE_PREROLL) validateOnlySelectionIsPreserved(serverPieces) - validateSourcePiecesExist(dvePieces) + validateSourcePiecesExistWithPrerollDuration(dvePieces) }) - it('Server -> CAM', () => { + it('Server -> CAM', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -575,25 +590,24 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) - let serverPieces = getServerPieces(context, 'next') + let serverPieces = await getActiveServerPieces(context, 'next') validateNextPartExistsWithDuration(context, SERVER_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) - validateSourcePiecesExist(serverPieces) + validateSourcePiecesExistWithPrerollDuration(serverPieces) - executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) + await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) - serverPieces = getServerPieces(context, 'next') - const camPiece = getCameraPiece(context, 'next') + serverPieces = await getActiveServerPieces(context, 'next') + const camPiece = await getCameraPiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateOnlySelectionIsPreserved(serverPieces) validateCameraPiece(camPiece) }) - it('Server -> LIVE', () => { + it('Server -> LIVE', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -609,25 +623,24 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) - let serverPieces = getServerPieces(context, 'next') + let serverPieces = await getActiveServerPieces(context, 'next') validateNextPartExistsWithDuration(context, SERVER_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) - validateSourcePiecesExist(serverPieces) + validateSourcePiecesExistWithPrerollDuration(serverPieces) - executeActionOfftube(context, AdlibActionType.CUT_TO_REMOTE, selectLiveAction) + await executeActionOfftube(context, AdlibActionType.CUT_TO_REMOTE, selectLiveAction) - serverPieces = getServerPieces(context, 'next') - const remotePiece = getRemotePiece(context, 'next') + serverPieces = await getActiveServerPieces(context, 'next') + const remotePiece = await getRemotePiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateOnlySelectionIsPreserved(serverPieces) validateRemotePiece(remotePiece) }) - it('DVE -> Server', () => { + it('DVE -> Server', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -643,25 +656,23 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) + await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) - let dvePieces = getDVEPieces(context, 'next') - validateSourcePiecesExist(dvePieces) + let dvePieces = await getDVEPieces(context, 'next') + validateSourcePiecesExistWithPrerollDuration(dvePieces) validateNextPartExistsWithDuration(context, 0) - validateNextPartExistsWithPreRoll(context, DVE_PREROLL) - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) - dvePieces = getDVEPieces(context, 'next') - const serverPieces = getServerPieces(context, 'next') + dvePieces = await getDVEPieces(context, 'next') + const serverPieces = await getActiveServerPieces(context, 'next') validateNextPartExistsWithDuration(context, SERVER_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) validateOnlySelectionIsPreserved(dvePieces) - validateSourcePiecesExist(serverPieces) + validateSourcePiecesExistWithPrerollDuration(serverPieces) }) - it('DVE -> Full', () => { + it('DVE -> Full', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -677,26 +688,24 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) + await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) - let dvePieces = getDVEPieces(context, 'next') + let dvePieces = await getDVEPieces(context, 'next') validateNextPartExistsWithDuration(context, 0) - validateNextPartExistsWithPreRoll(context, DVE_PREROLL) - validateSourcePiecesExist(dvePieces) + validateSourcePiecesExistWithPrerollDuration(dvePieces) - executeActionOfftube(context, AdlibActionType.SELECT_FULL_GRAFIK, selectFullGrafikAction) + await executeActionOfftube(context, AdlibActionType.SELECT_FULL_GRAFIK, selectFullGrafikAction) - dvePieces = getDVEPieces(context, 'next') - const fullGrafikPieces = getFullGrafikPieces(context, 'next') + dvePieces = await getDVEPieces(context, 'next') + const fullGrafikPieces = await getFullGrafikPieces(context, 'next') validateNextPartExistsWithDuration(context, 0) - validateNextPartExistsWithPreRoll(context, FULL_PREROLL) - validateNextPartExistsWithTransitionKeepAlive(context, FULL_KEEPALIVE) + validateNextPartExistsWithPreviousPartKeepaliveDuration(context, FULL_KEEPALIVE) validateOnlySelectionIsPreserved(dvePieces) - validateSourcePiecesExist(fullGrafikPieces) + validateSourcePiecesExistWithPrerollDuration(fullGrafikPieces) }) - it('DVE -> VO', () => { + it('DVE -> VO', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -712,25 +721,23 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) + await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) - let dvePieces = getDVEPieces(context, 'next') - validateSourcePiecesExist(dvePieces) + let dvePieces = await getDVEPieces(context, 'next') + validateSourcePiecesExistWithPrerollDuration(dvePieces) validateNextPartExistsWithDuration(context, 0) - validateNextPartExistsWithPreRoll(context, DVE_PREROLL) - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectVOClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectVOClipAction) - dvePieces = getDVEPieces(context, 'next') - const voPieces = getVOPieces(context, 'next') + dvePieces = await getDVEPieces(context, 'next') + const voPieces = await getVOPieces(context, 'next') validateNextPartExistsWithDuration(context, VO_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) validateOnlySelectionIsPreserved(dvePieces) - validateSourcePiecesExist(voPieces) + validateSourcePiecesExistWithPrerollDuration(voPieces) }) - it('DVE -> CAM', () => { + it('DVE -> CAM', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -746,24 +753,23 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) + await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) - let dvePieces = getDVEPieces(context, 'next') - validateSourcePiecesExist(dvePieces) + let dvePieces = await getDVEPieces(context, 'next') + validateSourcePiecesExistWithPrerollDuration(dvePieces) validateNextPartExistsWithDuration(context, 0) - validateNextPartExistsWithPreRoll(context, DVE_PREROLL) - executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) + await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) - dvePieces = getDVEPieces(context, 'next') - const camPiece = getCameraPiece(context, 'next') + dvePieces = await getDVEPieces(context, 'next') + const camPiece = await getCameraPiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateOnlySelectionIsPreserved(dvePieces) validateCameraPiece(camPiece) }) - it('DVE -> LIVE', () => { + it('DVE -> LIVE', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -779,24 +785,23 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) + await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) - let dvePieces = getDVEPieces(context, 'next') - validateSourcePiecesExist(dvePieces) + let dvePieces = await getDVEPieces(context, 'next') + validateSourcePiecesExistWithPrerollDuration(dvePieces) validateNextPartExistsWithDuration(context, 0) - validateNextPartExistsWithPreRoll(context, DVE_PREROLL) - executeActionOfftube(context, AdlibActionType.CUT_TO_REMOTE, selectLiveAction) + await executeActionOfftube(context, AdlibActionType.CUT_TO_REMOTE, selectLiveAction) - dvePieces = getDVEPieces(context, 'next') - const remotePiece = getRemotePiece(context, 'next') + dvePieces = await getDVEPieces(context, 'next') + const remotePiece = await getRemotePiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateOnlySelectionIsPreserved(dvePieces) validateRemotePiece(remotePiece) }) - it('Server (01234A) -> DVE (morbarn) -> VO (VOVOA) -> DVE (barnmor) -> CAM (1) -> LIVE (2) -> SERVER (01234A) -> Commentator Select DVE', () => { + it('Server (01234A) -> DVE (morbarn) -> VO (VOVOA) -> DVE (barnmor) -> CAM (1) -> LIVE (2) -> SERVER (01234A) -> Commentator Select DVE', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -813,60 +818,56 @@ describe('Combination Actions', () => { ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' // SERVER (A) - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) - let serverPieces = getServerPieces(context, 'next') + let serverPieces = await getActiveServerPieces(context, 'next') validateNextPartExistsWithDuration(context, SERVER_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) - validateSourcePiecesExist(serverPieces) + validateSourcePiecesExistWithPrerollDuration(serverPieces) // DVE (A) - executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) + await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) - serverPieces = getServerPieces(context, 'next') - let dvePieces = getDVEPieces(context, 'next') + serverPieces = await getActiveServerPieces(context, 'next') + let dvePieces = await getDVEPieces(context, 'next') validateNextPartExistsWithDuration(context, 0) - validateNextPartExistsWithPreRoll(context, DVE_PREROLL) validateOnlySelectionIsPreserved(serverPieces) - validateSourcePiecesExist(dvePieces) + validateSourcePiecesExistWithPrerollDuration(dvePieces) // VO (A) - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectVOClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectVOClipAction) - let voPieces = getVOPieces(context, 'next') - serverPieces = getServerPieces(context, 'next') - dvePieces = getDVEPieces(context, 'next') + let voPieces = await getVOPieces(context, 'next') + serverPieces = await getActiveServerPieces(context, 'next') + dvePieces = await getDVEPieces(context, 'next') validateNextPartExistsWithDuration(context, VO_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) validateSelectionRemoved(serverPieces) validateOnlySelectionIsPreserved(dvePieces) - validateSourcePiecesExist(voPieces) + validateSourcePiecesExistWithPrerollDuration(voPieces) // DVE (B) expect(dvePieces.dataStore?.piece.name).toEqual('morbarn') - executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionBarnmor) + await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionBarnmor) - voPieces = getVOPieces(context, 'next') - serverPieces = getServerPieces(context, 'next') - dvePieces = getDVEPieces(context, 'next') + voPieces = await getVOPieces(context, 'next') + serverPieces = await getActiveServerPieces(context, 'next') + dvePieces = await getDVEPieces(context, 'next') validateNextPartExistsWithDuration(context, 0) - validateNextPartExistsWithPreRoll(context, DVE_PREROLL) - validateSourcePiecesExist(dvePieces) + validateSourcePiecesExistWithPrerollDuration(dvePieces) validateSelectionRemoved(serverPieces) validateOnlySelectionIsPreserved(voPieces) expect(dvePieces.dataStore?.piece.name).toEqual('barnmor') // CAM (1) - executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) + await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) - voPieces = getVOPieces(context, 'next') - serverPieces = getServerPieces(context, 'next') - dvePieces = getDVEPieces(context, 'next') - let camPiece = getCameraPiece(context, 'next') + voPieces = await getVOPieces(context, 'next') + serverPieces = await getActiveServerPieces(context, 'next') + dvePieces = await getDVEPieces(context, 'next') + let camPiece = await getCameraPiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateOnlySelectionIsPreserved(voPieces) @@ -875,13 +876,13 @@ describe('Combination Actions', () => { validateCameraPiece(camPiece) // LIVE (2) - executeActionOfftube(context, AdlibActionType.CUT_TO_REMOTE, selectLiveAction) + await executeActionOfftube(context, AdlibActionType.CUT_TO_REMOTE, selectLiveAction) - voPieces = getVOPieces(context, 'next') - serverPieces = getServerPieces(context, 'next') - dvePieces = getDVEPieces(context, 'next') - camPiece = getCameraPiece(context, 'next') - let remotePiece = getRemotePiece(context, 'next') + voPieces = await getVOPieces(context, 'next') + serverPieces = await getActiveServerPieces(context, 'next') + dvePieces = await getDVEPieces(context, 'next') + camPiece = await getCameraPiece(context, 'next') + let remotePiece = await getRemotePiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateOnlySelectionIsPreserved(voPieces) @@ -891,42 +892,40 @@ describe('Combination Actions', () => { validateRemotePiece(remotePiece) // SERVER (A) - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) - voPieces = getVOPieces(context, 'next') - serverPieces = getServerPieces(context, 'next') - dvePieces = getDVEPieces(context, 'next') - camPiece = getCameraPiece(context, 'next') - remotePiece = getRemotePiece(context, 'next') + voPieces = await getVOPieces(context, 'next') + serverPieces = await getActiveServerPieces(context, 'next') + dvePieces = await getDVEPieces(context, 'next') + camPiece = await getCameraPiece(context, 'next') + remotePiece = await getRemotePiece(context, 'next') validateNextPartExistsWithDuration(context, SERVER_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) validateSelectionRemoved(voPieces) validateOnlySelectionIsPreserved(dvePieces) - validateSourcePiecesExist(serverPieces) + validateSourcePiecesExistWithPrerollDuration(serverPieces) expect(camPiece).toBeFalsy() expect(remotePiece).toBeFalsy() // Commentator Select DVE - executeActionOfftube(context, AdlibActionType.COMMENTATOR_SELECT_DVE, commentatorSelectDVE) + await executeActionOfftube(context, AdlibActionType.COMMENTATOR_SELECT_DVE, commentatorSelectDVE) - voPieces = getVOPieces(context, 'next') - serverPieces = getServerPieces(context, 'next') - dvePieces = getDVEPieces(context, 'next') - camPiece = getCameraPiece(context, 'next') - remotePiece = getRemotePiece(context, 'next') + voPieces = await getVOPieces(context, 'next') + serverPieces = await getActiveServerPieces(context, 'next') + dvePieces = await getDVEPieces(context, 'next') + camPiece = await getCameraPiece(context, 'next') + remotePiece = await getRemotePiece(context, 'next') validateNextPartExistsWithDuration(context, 0) - validateNextPartExistsWithPreRoll(context, DVE_PREROLL) validateSelectionRemoved(voPieces) validateOnlySelectionIsPreserved(serverPieces) - validateSourcePiecesExist(dvePieces) + validateSourcePiecesExistWithPrerollDuration(dvePieces) expect(camPiece).toBeFalsy() expect(remotePiece).toBeFalsy() expect(dvePieces.activePiece?.piece.name).toEqual('barnmor') }) - it('CAM -> MIX 20 (No Take) -> LIVE (2)', () => { + it('CAM -> MIX 20 (No Take) -> LIVE (2)', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -942,26 +941,26 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) + await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) - let camPiece = getCameraPiece(context, 'next') + let camPiece = await getCameraPiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateCameraPiece(camPiece) expectATEMToCut(camPiece!) - executeActionOfftube(context, AdlibActionType.TAKE_WITH_TRANSITION, setMIX20AsTransition) + await executeActionOfftube(context, AdlibActionType.TAKE_WITH_TRANSITION, setMIX20AsTransition) - camPiece = getCameraPiece(context, 'next') + camPiece = await getCameraPiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateCameraPiece(camPiece) expectATEMToMixOver(camPiece!, 20) - executeActionOfftube(context, AdlibActionType.CUT_TO_REMOTE, selectLiveAction) + await executeActionOfftube(context, AdlibActionType.CUT_TO_REMOTE, selectLiveAction) - const livePiece = getRemotePiece(context, 'next') - camPiece = getCameraPiece(context, 'next') + const livePiece = await getRemotePiece(context, 'next') + camPiece = await getCameraPiece(context, 'next') expect(camPiece).toBeFalsy() validateNextPartExistsWithDuration(context, 0) @@ -969,7 +968,7 @@ describe('Combination Actions', () => { expectATEMToMixOver(livePiece!, 20) }) - it('CAM -> MIX 20 (No Take) -> SERVER', () => { + it('CAM -> MIX 20 (No Take) -> SERVER', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -985,35 +984,34 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) + await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) - let camPiece = getCameraPiece(context, 'next') + let camPiece = await getCameraPiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateCameraPiece(camPiece) expectATEMToCut(camPiece!) - executeActionOfftube(context, AdlibActionType.TAKE_WITH_TRANSITION, setMIX20AsTransition) + await executeActionOfftube(context, AdlibActionType.TAKE_WITH_TRANSITION, setMIX20AsTransition) - camPiece = getCameraPiece(context, 'next') + camPiece = await getCameraPiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateCameraPiece(camPiece) expectATEMToMixOver(camPiece!, 20) - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) - const serverPieces = getServerPieces(context, 'next') - camPiece = getCameraPiece(context, 'next') + const serverPieces = await getActiveServerPieces(context, 'next') + camPiece = await getCameraPiece(context, 'next') validateNextPartExistsWithDuration(context, SERVER_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) - validateSourcePiecesExist(serverPieces) + validateSourcePiecesExistWithPrerollDuration(serverPieces) expect(camPiece).toBeFalsy() expectATEMToMixOver(serverPieces.activePiece!, 20) }) - it('CAM -> MIX 20 (No Take) -> VO', () => { + it('CAM -> MIX 20 (No Take) -> VO', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -1029,35 +1027,34 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) + await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) - let camPiece = getCameraPiece(context, 'next') + let camPiece = await getCameraPiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateCameraPiece(camPiece) expectATEMToCut(camPiece!) - executeActionOfftube(context, AdlibActionType.TAKE_WITH_TRANSITION, setMIX20AsTransition) + await executeActionOfftube(context, AdlibActionType.TAKE_WITH_TRANSITION, setMIX20AsTransition) - camPiece = getCameraPiece(context, 'next') + camPiece = await getCameraPiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateCameraPiece(camPiece) expectATEMToMixOver(camPiece!, 20) - executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectVOClipAction) + await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectVOClipAction) - const serverPieces = getVOPieces(context, 'next') - camPiece = getCameraPiece(context, 'next') + const serverPieces = await getVOPieces(context, 'next') + camPiece = await getCameraPiece(context, 'next') validateNextPartExistsWithDuration(context, VO_DURATION_A) - validateNextPartExistsWithPreRoll(context, SERVER_PREROLL) - validateSourcePiecesExist(serverPieces) + validateSourcePiecesExistWithPrerollDuration(serverPieces) expect(camPiece).toBeFalsy() expectATEMToMixOver(serverPieces.activePiece!, 20) }) - it('CAM -> MIX 20 (No Take) -> DVE', () => { + it('CAM -> MIX 20 (No Take) -> DVE', async () => { const context = new ActionExecutionContext( 'test', mappingsDefaults, @@ -1073,28 +1070,27 @@ describe('Combination Actions', () => { context.showStyleConfig = defaultShowStyleConfig as any ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) + await executeActionOfftube(context, AdlibActionType.CUT_TO_CAMERA, selectCameraAction) - let camPiece = getCameraPiece(context, 'next') + let camPiece = await getCameraPiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateCameraPiece(camPiece) expectATEMToCut(camPiece!) - executeActionOfftube(context, AdlibActionType.TAKE_WITH_TRANSITION, setMIX20AsTransition) + await executeActionOfftube(context, AdlibActionType.TAKE_WITH_TRANSITION, setMIX20AsTransition) - camPiece = getCameraPiece(context, 'next') + camPiece = await getCameraPiece(context, 'next') validateNextPartExistsWithDuration(context, 0) validateCameraPiece(camPiece) expectATEMToMixOver(camPiece!, 20) - executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) + await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) - const dvePieces = getDVEPieces(context, 'next') + const dvePieces = await getDVEPieces(context, 'next') validateNextPartExistsWithDuration(context, 0) - validateNextPartExistsWithPreRoll(context, DVE_PREROLL) - validateSourcePiecesExist(dvePieces) + validateSourcePiecesExistWithPrerollDuration(dvePieces) expectATEMToMixOver(dvePieces.activePiece!, 20) }) }) diff --git a/src/tv2_offtube_showstyle/actions.ts b/src/tv2_offtube_showstyle/actions.ts index 9ef470da8..1a5de1f92 100644 --- a/src/tv2_offtube_showstyle/actions.ts +++ b/src/tv2_offtube_showstyle/actions.ts @@ -17,12 +17,12 @@ const SELECTED_ADLIB_LAYERS = [ OfftubeSourceLayer.SelectedAdlibJingle ] -export function executeActionOfftube( +export async function executeActionOfftube( context: IActionExecutionContext, actionId: string, userData: ActionUserData -): void { - executeAction( +): Promise { + await executeAction( context, { getConfig, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts index 6b957803a..6bfaa4e29 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts @@ -12,6 +12,7 @@ import { CreateAdlibServer, CueDefinitionAdLib, CueDefinitionDVE, + generateExternalId, GetDVETemplate, getUniquenessIdDVE, literal, @@ -122,15 +123,17 @@ export function OfftubeEvaluateAdLib( } }) + const userData = literal({ + type: AdlibActionType.SELECT_DVE, + config: cueDVE, + videoId: partDefinition.fields.videoId, + segmentExternalId: partDefinition.segmentExternalId + }) actions.push( literal({ + externalId: generateExternalId(context, userData), actionId: AdlibActionType.SELECT_DVE, - userData: literal({ - type: AdlibActionType.SELECT_DVE, - config: cueDVE, - videoId: partDefinition.fields.videoId, - segmentExternalId: partDefinition.segmentExternalId - }), + userData, userDataManifest: {}, display: { sourceLayerId: OfftubeSourceLayer.PgmDVE, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts index c9d3422c3..1a2c8b5e9 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts @@ -12,6 +12,7 @@ import { CalculateTime, CueDefinitionDVE, DVEPieceMetaData, + generateExternalId, GetDVETemplate, GetTagForDVE, GetTagForDVENext, @@ -92,7 +93,7 @@ export function OfftubeEvaluateDVE( ...pieceContent.content, timelineObjects: [...pieceContent.content.timelineObjects] }, - adlibPreroll: Number(config.studio.CasparPrerollDuration) || 0, + prerollDuration: Number(config.studio.CasparPrerollDuration) || 0, metaData: literal({ mediaPlayerSessions: [partDefinition.segmentExternalId], sources: parsedCue.sources, @@ -112,15 +113,17 @@ export function OfftubeEvaluateDVE( }) ) + const userData = literal({ + type: AdlibActionType.SELECT_DVE, + config: parsedCue, + videoId: partDefinition.fields.videoId, + segmentExternalId: partDefinition.segmentExternalId + }) actions.push( literal({ + externalId: generateExternalId(context, userData), actionId: AdlibActionType.SELECT_DVE, - userData: literal({ - type: AdlibActionType.SELECT_DVE, - config: parsedCue, - videoId: partDefinition.fields.videoId, - segmentExternalId: partDefinition.segmentExternalId - }), + userData, userDataManifest: {}, display: { _rank: rank, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts index 7e5e24733..995f8cba9 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts @@ -1,7 +1,6 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, - IBlueprintPart, IBlueprintPiece, IShowStyleUserContext, TSR @@ -34,7 +33,6 @@ export const pilotGeneratorSettingsOfftube: PilotGeneratorSettings = { export function OfftubeEvaluateGrafikCaspar( config: OfftubeShowstyleBlueprintConfig, context: IShowStyleUserContext, - part: Readonly, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], @@ -48,7 +46,6 @@ export function OfftubeEvaluateGrafikCaspar( CreatePilotGraphic( config, context, - part, pieces, adlibPieces, actions, @@ -60,19 +57,7 @@ export function OfftubeEvaluateGrafikCaspar( partDefinition.segmentExternalId ) } else if (GraphicIsInternal(parsedCue)) { - CreateInternalGraphic( - config, - context, - part, - pieces, - adlibPieces, - actions, - partId, - parsedCue, - adlib, - partDefinition, - rank - ) + CreateInternalGraphic(config, context, pieces, adlibPieces, actions, partId, parsedCue, adlib, partDefinition, rank) } } diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index bdb0d57f7..1764ef573 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -9,13 +9,14 @@ import { ActionSelectJingle, CreateJingleContentBase, CueDefinitionJingle, + generateExternalId, GetJinglePartProperties, GetTagForJingle, GetTagForJingleNext, literal, PartDefinition, - PieceMetaData, - t + t, + TimeFromFrames } from 'tv2-common' import { AdlibActionType, AdlibTags, SharedOutputLayers, TallyTags } from 'tv2-constants' import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' @@ -58,14 +59,16 @@ export function OfftubeEvaluateJingle( return } + const userData = literal({ + type: AdlibActionType.SELECT_JINGLE, + clip: parsedCue.clip, + segmentExternalId: part.segmentExternalId + }) actions.push( literal({ + externalId: generateExternalId(context, userData), actionId: AdlibActionType.SELECT_JINGLE, - userData: literal({ - type: AdlibActionType.SELECT_JINGLE, - clip: parsedCue.clip, - segmentExternalId: part.segmentExternalId - }), + userData, userDataManifest: {}, display: { label: t(effekt ? `EFFEKT ${parsedCue.clip}` : parsedCue.clip), @@ -99,12 +102,7 @@ export function OfftubeEvaluateJingle( lifespan: PieceLifespan.WithinPart, outputLayerId: SharedOutputLayers.JINGLE, sourceLayerId: OfftubeSourceLayer.PgmJingle, - metaData: literal({ - transition: { - isJingle: !effekt, - isEffekt: !!effekt - } - }), + prerollDuration: config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), content: createJingleContentOfftube( config, file, @@ -116,7 +114,8 @@ export function OfftubeEvaluateJingle( tags: [ GetTagForJingle(part.segmentExternalId, parsedCue.clip), GetTagForJingleNext(part.segmentExternalId, parsedCue.clip), - TallyTags.JINGLE_IS_LIVE + TallyTags.JINGLE_IS_LIVE, + !effekt ? TallyTags.JINGLE : '' ] }) ) diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 8ea92b2ae..903f2f1fa 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -31,6 +31,7 @@ import { CreateDSKBaselineAdlibs, CreateGraphicBaseline, CreateLYDBaseline, + generateExternalId, GetTagForKam, GetTagForLive, GetTransitionAdLibActions, @@ -248,19 +249,21 @@ function getGlobalAdlibActionsOfftube( _context: IStudioUserContext, config: OfftubeShowstyleBlueprintConfig ): IBlueprintActionManifest[] { - const res: IBlueprintActionManifest[] = [] + const blueprintActions: IBlueprintActionManifest[] = [] let globalRank = 2000 function makeCutCameraActions(info: SourceInfo, queue: boolean, rank: number) { - res.push( + const userData = literal({ + type: AdlibActionType.CUT_TO_CAMERA, + queue, + name: info.id + }) + blueprintActions.push( literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CUT_TO_CAMERA, - userData: literal({ - type: AdlibActionType.CUT_TO_CAMERA, - queue, - name: info.id - }), + userData, userDataManifest: {}, display: { _rank: rank, @@ -277,14 +280,16 @@ function getGlobalAdlibActionsOfftube( } function makeRemoteAction(name: string, type: 'Live' | 'Feed', port: number, rank: number) { - res.push( + const userData = literal({ + type: AdlibActionType.CUT_TO_REMOTE, + name, + port + }) + blueprintActions.push( literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CUT_TO_REMOTE, - userData: literal({ - type: AdlibActionType.CUT_TO_REMOTE, - name, - port - }), + userData, userDataManifest: {}, display: { _rank: rank, @@ -305,16 +310,18 @@ function getGlobalAdlibActionsOfftube( const feed = type === 'Live' && info.id.match(/^F(.+).*$/) const name = feed ? `Feed ${feed[1]}` : `${type} ${info.id}` const layer = type === 'Kamera' ? OfftubeSourceLayer.PgmCam : OfftubeSourceLayer.PgmLive - res.push( + const userData = literal({ + type: AdlibActionType.CUT_SOURCE_TO_BOX, + name, + port: info.port, + sourceType: info.type, + box + }) + blueprintActions.push( literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CUT_SOURCE_TO_BOX, - userData: literal({ - type: AdlibActionType.CUT_SOURCE_TO_BOX, - name, - port: info.port, - sourceType: info.type, - box - }), + userData, userDataManifest: {}, display: { _rank: rank + 0.1 * box, @@ -331,17 +338,19 @@ function getGlobalAdlibActionsOfftube( function makeServerAdlibBoxesActions(rank: number) { for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { - res.push( + const userData = literal({ + type: AdlibActionType.CUT_SOURCE_TO_BOX, + name: `SERVER`, + port: -1, + sourceType: SourceLayerType.VT, + box, + server: true + }) + blueprintActions.push( literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CUT_SOURCE_TO_BOX, - userData: literal({ - type: AdlibActionType.CUT_SOURCE_TO_BOX, - name: `SERVER`, - port: -1, - sourceType: SourceLayerType.VT, - box, - server: true - }), + userData, userDataManifest: {}, display: { _rank: rank + 0.1 * box, @@ -356,12 +365,14 @@ function getGlobalAdlibActionsOfftube( } } - res.push( - literal({ + function makeCommentatorSelectServerAction() { + const userData = literal({ + type: AdlibActionType.COMMENTATOR_SELECT_SERVER + }) + return literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.COMMENTATOR_SELECT_SERVER, - userData: literal({ - type: AdlibActionType.COMMENTATOR_SELECT_SERVER - }), + userData, userDataManifest: {}, display: { _rank: globalRank++, @@ -374,14 +385,18 @@ function getGlobalAdlibActionsOfftube( nextPieceTags: [TallyTags.SERVER_IS_LIVE] } }) - ) + } - res.push( - literal({ + blueprintActions.push(makeCommentatorSelectServerAction()) + + function makeCommentatorSelectDveAction() { + const userData = literal({ + type: AdlibActionType.COMMENTATOR_SELECT_DVE + }) + return literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.COMMENTATOR_SELECT_DVE, - userData: literal({ - type: AdlibActionType.COMMENTATOR_SELECT_DVE - }), + userData, userDataManifest: {}, display: { _rank: globalRank++, @@ -394,14 +409,18 @@ function getGlobalAdlibActionsOfftube( nextPieceTags: [TallyTags.DVE_IS_LIVE] } }) - ) + } + + blueprintActions.push(makeCommentatorSelectDveAction()) - res.push( - literal({ + function makeCommentatorSelectFullAction() { + const userData = literal({ + type: AdlibActionType.COMMENTATOR_SELECT_FULL + }) + return literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.COMMENTATOR_SELECT_FULL, - userData: literal({ - type: AdlibActionType.COMMENTATOR_SELECT_FULL - }), + userData, userDataManifest: {}, display: { _rank: globalRank++, @@ -414,16 +433,20 @@ function getGlobalAdlibActionsOfftube( nextPieceTags: [TallyTags.FULL_IS_LIVE] } }) - ) + } + + blueprintActions.push(makeCommentatorSelectFullAction()) - res.push( - literal({ + function makeClearGraphicsAltudAction() { + const userData = literal({ + type: AdlibActionType.CLEAR_GRAPHICS, + sendCommands: false, + label: 'GFX Altud' + }) + return literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CLEAR_GRAPHICS, - userData: literal({ - type: AdlibActionType.CLEAR_GRAPHICS, - sendCommands: false, - label: 'GFX Altud' - }), + userData, userDataManifest: {}, display: { _rank: 400, @@ -436,16 +459,20 @@ function getGlobalAdlibActionsOfftube( nextPieceTags: [TallyTags.GFX_ALTUD] } }) - ) + } - res.push(...GetTransitionAdLibActions(config, 800)) + blueprintActions.push(makeClearGraphicsAltudAction()) - res.push( - literal({ + blueprintActions.push(...GetTransitionAdLibActions(config, 800)) + + function makeRecallLastDveAction() { + const userData = literal({ + type: AdlibActionType.RECALL_LAST_DVE + }) + return literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.RECALL_LAST_DVE, - userData: literal({ - type: AdlibActionType.RECALL_LAST_DVE - }), + userData, userDataManifest: {}, display: { _rank: 1, @@ -455,16 +482,20 @@ function getGlobalAdlibActionsOfftube( tags: [AdlibTags.ADLIB_RECALL_LAST_DVE] } }) - ) + } + + blueprintActions.push(makeRecallLastDveAction()) _.each(config.showStyle.DVEStyles, (dveConfig, i) => { - res.push( + const userData = literal({ + type: AdlibActionType.SELECT_DVE_LAYOUT, + config: dveConfig + }) + blueprintActions.push( literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.SELECT_DVE_LAYOUT, - userData: literal({ - type: AdlibActionType.SELECT_DVE_LAYOUT, - config: dveConfig - }), + userData, userDataManifest: {}, display: { _rank: 200 + i, @@ -498,12 +529,14 @@ function getGlobalAdlibActionsOfftube( makeAdlibBoxesActions(o, 'Kamera', globalRank++) }) - res.push( - literal({ + function makeRecallLastLiveAction() { + const userData = literal({ + type: AdlibActionType.RECALL_LAST_LIVE + }) + return literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.RECALL_LAST_LIVE, - userData: literal({ - type: AdlibActionType.RECALL_LAST_LIVE - }), + userData, userDataManifest: {}, display: { _rank: 1, @@ -513,7 +546,9 @@ function getGlobalAdlibActionsOfftube( tags: [AdlibTags.ADLIB_RECALL_LAST_LIVE] } }) - ) + } + + blueprintActions.push(makeRecallLastLiveAction()) config.sources .filter(u => u.type === SourceLayerType.REMOTE) @@ -531,12 +566,14 @@ function getGlobalAdlibActionsOfftube( makeServerAdlibBoxesActions(globalRank++) - res.push( - literal({ + function makeCommentatorSelectJingleAction() { + const userData = literal({ + type: AdlibActionType.COMMENTATOR_SELECT_JINGLE + }) + return literal({ + externalId: generateExternalId(_context, userData), actionId: AdlibActionType.COMMENTATOR_SELECT_JINGLE, - userData: literal({ - type: AdlibActionType.COMMENTATOR_SELECT_JINGLE - }), + userData, userDataManifest: {}, display: { _rank: globalRank++, @@ -549,9 +586,11 @@ function getGlobalAdlibActionsOfftube( nextPieceTags: [TallyTags.JINGLE_IS_LIVE] } }) - ) + } + + blueprintActions.push(makeCommentatorSelectJingleAction()) - return res + return blueprintActions } function getBaseline(config: OfftubeShowstyleBlueprintConfig): BlueprintResultBaseline { diff --git a/src/tv2_offtube_showstyle/getSegment.ts b/src/tv2_offtube_showstyle/getSegment.ts index f5db63cfe..ab0c20319 100644 --- a/src/tv2_offtube_showstyle/getSegment.ts +++ b/src/tv2_offtube_showstyle/getSegment.ts @@ -91,6 +91,7 @@ function CreatePartContinuity(config: OfftubeShowstyleBlueprintConfig, ingestSeg }) }) ], - adLibPieces: [] + adLibPieces: [], + actions: [] }) } diff --git a/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts b/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts index 8f24745f2..73453cb57 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts @@ -8,7 +8,6 @@ import { ISegmentUserContext } from '@tv2media/blueprints-integration' import { AddScript, literal, PartDefinitionDVE, PartTime } from 'tv2-common' -import { CueType } from 'tv2-constants' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' @@ -32,10 +31,6 @@ export function OfftubeCreatePartDVE( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - if (partDefinition.cues.filter(cue => cue.type === CueType.DVE).length) { - part.prerollDuration = config.studio.CasparPrerollDuration - } - OfftubeEvaluateCues( context, config, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index 9a864c46f..d05e5fb16 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -174,6 +174,7 @@ export function OfftubeCreatePartKam( return { part, adLibPieces, - pieces + pieces, + actions } } diff --git a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts index 8982511af..fcf7ff70f 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts @@ -49,8 +49,6 @@ export function CreatePartUnknown( !partDefinition.cues.filter(c => c.type === CueType.Jingle).length ) { ApplyFullGraphicPropertiesToPart(config, part) - } else if (partDefinition.cues.filter(cue => cue.type === CueType.DVE).length) { - part.prerollDuration = config.studio.CasparPrerollDuration } OfftubeEvaluateCues( diff --git a/yarn.lock b/yarn.lock index 4048c98b8..b4c293da2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -287,20 +287,20 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@tv2media/blueprints-integration@v1.37.1-in-testing.1": - version "1.37.1-in-testing.1" - resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-1.37.1-in-testing.1.tgz#92b11e3c4402650858db539fa5bf7ce7d04b992d" - integrity sha512-hJ+10Gt8xkbwjyGuPWnIecAxbE6a9oiClWW+Dr/9GXjU8z5FcnbKLGXdX/qnbGAMGTU+pNaPo/QUEbyAuFENrQ== +"@tv2media/blueprints-integration@1.41.2": + version "1.41.2" + resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-1.41.2.tgz#7c9552b59653180eb1bcbac784e8d3c7bbbaf46b" + integrity sha512-lZseNPtrKDKuAboQyEL5qypU3RkfdCTHPdXSQKQz53+8fcc/59AJPAwQWETnJbpuJ2wfOzBTDBFsMmVYady2cA== dependencies: moment "2.29.1" timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@1.0.0-release37" tslib "^2.3.1" - underscore "1.13.1" + type-fest "^2.11.1" -"@tv2media/timeline-state-resolver-types@^1.0.0-release37.6": - version "1.0.0-release37.6" - resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-1.0.0-release37.6.tgz#48eca1760f254e38564b5901fead16ba02022e13" - integrity sha512-+Gd5fTSWyP4Z9l2CUC/gABJhCOKGD4gn5oR5VmnaL33U4KvGEgJE3X0SsW9Gn80O6y+2NBb/YcbDavRmlIG0TA== +"@tv2media/timeline-state-resolver-types@1.41.0": + version "1.41.0" + resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-1.41.0.tgz#d6db847575795e7eeb9d0f75fbaae27436bb1a03" + integrity sha512-hUYOCCQCl/3xxmWS5dPKLITkcVnm6hokrUgu6zUFqzLj24MTgpxPV6i2GHpRYDyajuyWS3lrjrJLiFsSGO3TRg== dependencies: tslib "^2.3.1" @@ -5906,6 +5906,11 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^2.11.1: + version "2.12.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.12.1.tgz#d2be8f50bf5f8f0a5fd916d29bf3e98c17e960be" + integrity sha512-AiknQSEqKVGDDjtZqeKrUoTlcj7FKhupmnVUgz6KoOKtvMwRGE6hUNJ/nVear+h7fnUPO1q/htSkYKb1pyntkQ== + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -5921,7 +5926,7 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.2.tgz#fe10319861bccc8682bfe2e8151fbdd8aa921c44" integrity sha512-SbMu4D2Vo95LMC/MetNaso1194M1htEA+JrqE9Hk+G2DhI+itfS9TRu9ZKeCahLDNa/J3n4MqUJ/fOHMzQpRWw== -underscore@1.13.1, underscore@^1.12.1: +underscore@^1.12.1: version "1.13.1" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.1.tgz#0c1c6bd2df54b6b69f2314066d65b6cde6fcf9d1" integrity sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g== From 79f12264db02a9a8a4497d03805654e9191a65fe Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Mon, 4 Apr 2022 16:44:07 +0200 Subject: [PATCH 073/184] SOF-789 When cutting to executeActionCutToCamera directly after a new Segment we now correctly persist the layers of the first piece in that Segment --- src/tv2-common/actions/executeAction.ts | 3 ++- src/tv2-common/onTimelineGenerate.ts | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 459ea0bb0..91a0a5374 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1049,7 +1049,8 @@ function executeActionCutToCamera< metaData: { sisyfosPersistMetaData: literal({ sisyfosLayers: [], - acceptPersistAudio: sourceInfoCam.acceptPersistAudio + acceptPersistAudio: sourceInfoCam.acceptPersistAudio, + isPieceInjectedInPart: true }) }, tags: [GetTagForKam(userData.name)], diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index 255669620..51ce10932 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -65,6 +65,7 @@ export interface SisyfosPersistMetaData { wantsToPersistAudio?: boolean acceptPersistAudio?: boolean previousPersistMetaDataForCurrentPiece?: SisyfosPersistMetaData + isPieceInjectedInPart?: boolean } export interface PartMetaData { @@ -95,7 +96,7 @@ export function onTimelineGenerate< const config = getConfig(context) - if (!persistentState.isNewSegment) { + if (!persistentState.isNewSegment || isAnyPieceInjectedIntoPart(resolvedPieces, context)) { const sisyfosPersistedLevelsTimelineObject = createSisyfosPersistedLevelsTimelineObject( resolvedPieces, previousPartEndState2 ? previousPartEndState2.sisyfosPersistMetaData.sisyfosLayers : [] @@ -190,6 +191,15 @@ function processServerLookaheads( }) } +function isAnyPieceInjectedIntoPart(resolvedPieces: IBlueprintResolvedPieceInstance[], context: ITimelineEventContext) { + return resolvedPieces + .filter(piece => piece.partInstanceId === context.currentPartInstance?._id) + .some(piece => { + const metaData = piece.piece.metaData as PieceMetaData + return metaData?.sisyfosPersistMetaData?.isPieceInjectedInPart + }) +} + export function getEndStateForPart( _context: IRundownContext, _previousPersistentState: TimelinePersistentState | undefined, From 2607c10ec5281754ab4ab32486cd2a9abf4c8b68 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 5 Apr 2022 14:54:10 +0200 Subject: [PATCH 074/184] fix: SOF-849 removing too many pieces adlib/dynamic pieces are handled separately; infinite continuations shall not be removed --- src/tv2-common/updatePolicies/pieces.ts | 17 +++++++-- .../syncIngestChangesToPartInstance.spec.ts | 37 ++++++++++++++++++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/tv2-common/updatePolicies/pieces.ts b/src/tv2-common/updatePolicies/pieces.ts index 4fdeaadca..ed96c3bdc 100644 --- a/src/tv2-common/updatePolicies/pieces.ts +++ b/src/tv2-common/updatePolicies/pieces.ts @@ -13,6 +13,17 @@ function groupPieceInstances(pieceInstances: Array { +function makeSoundBed( + id: string, + name: string, + instanceProps?: Partial +): IBlueprintPieceInstance { return literal>({ _id: id, + ...instanceProps, piece: { _id: '', enable: { @@ -162,4 +167,34 @@ describe('Sync Ingest Changes To Part Instances', () => { expect(context.updatedPartInstance?.part.budgetDuration).toBe(1000) expect(context.updatedPartInstance?.part.title).toBe('Kam 2') }) + + it('Does not remove adlib instances or infinite continuations', () => { + const context = makeMockContext() + const existingPartInstance: BlueprintSyncIngestPartInstance = literal({ + partInstance: makePartinstance({ title: 'Soundbed' }), + pieceInstances: [ + makeSoundBed('someId1', 'SN_Intro', { adLibSourceId: 'someAdLib' }), + makeSoundBed('someId2', 'SN_Intro', { infinite: { infinitePieceId: 'someInfinite', fromPreviousPart: true } }), + makeSoundBed('someId3', 'SN_Intro', { + infinite: { infinitePieceId: 'someInfinite', fromPreviousPart: false, fromPreviousPlayhead: true } + }), + makeSoundBed('someId4', 'SN_Intro', { + infinite: { infinitePieceId: 'someInfinite', fromPreviousPart: false, fromHold: true } + }), + makeSoundBed('someId5', 'SN_Intro', { dynamicallyInserted: 1649158767173 }) + ] + }) + const newPart: BlueprintSyncIngestNewData = literal({ + part: makePart({ title: 'Soundbed' }), + pieceInstances: [], + adLibPieces: [], + actions: [], + referencedAdlibs: [] + }) + syncIngestUpdateToPartInstance(context, existingPartInstance, newPart, 'current') + + expect(context.removedPieceInstances).toStrictEqual([]) + expect(context.syncedPieceInstances).toStrictEqual([]) + expect(context.updatedPieceInstances).toStrictEqual([]) + }) }) From bd925525782027969c3812b427aee8d6adddad68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Wed, 6 Apr 2022 14:02:27 +0200 Subject: [PATCH 075/184] fix: Normalized EVS shortcuts and removed custom hotkey labels. --- .../AFVD_Default_showstyle_hotkeys.json | 96 ------------------- src/tv2-common/hotkeys/hotkey-defaults.ts | 8 +- 2 files changed, 4 insertions(+), 100 deletions(-) diff --git a/shelf-layouts/AFVD_Default_showstyle_hotkeys.json b/shelf-layouts/AFVD_Default_showstyle_hotkeys.json index d012fa638..9f6191040 100644 --- a/shelf-layouts/AFVD_Default_showstyle_hotkeys.json +++ b/shelf-layouts/AFVD_Default_showstyle_hotkeys.json @@ -28,34 +28,6 @@ "platformKey": "q", "buttonColor": "#f0d718" }, - { - "_id": "agPkaQMbK2FKZpPcv", - "key": "E", - "label": "EVS 1 VO", - "sourceLayerType": 15, - "platformKey": "E" - }, - { - "_id": "Kz8QpoLd3iEWtspyb", - "key": "R", - "label": "EVS 1 100%", - "sourceLayerType": 15, - "platformKey": "R" - }, - { - "_id": "7oCTKdx4Qn7hoKxFT", - "key": "U", - "label": "EVS 2 VO", - "sourceLayerType": 15, - "platformKey": "U" - }, - { - "_id": "YSXBpa44zMLAGdrSx", - "key": "I", - "label": "EVS 2 100%", - "sourceLayerType": 15, - "platformKey": "I" - }, { "_id": "qSptFwTukCezFNK8D", "key": "C", @@ -112,20 +84,6 @@ "platformKey": "Period", "buttonColor": "#8e44ad" }, - { - "_id": "gzN4rBopAsrN9Hubh", - "key": "SHIFT+e", - "label": "EVS 1 100% inp 1", - "sourceLayerType": 15, - "platformKey": "SHIFT+e" - }, - { - "_id": "cjzA9Wi7ReFeGQHRk", - "key": "SHIFT+D", - "label": "EVS 1 VO inp 1", - "sourceLayerType": 15, - "platformKey": "SHIFT+D" - }, { "_id": "CRmsnZEboXfLtiRQw", "key": "SHIFT+A", @@ -141,20 +99,6 @@ "platformKey": "", "buttonColor": "#000000" }, - { - "_id": "zXCnABCGodoiBjecn", - "key": "SHIFT+U", - "label": "EVS 2 VO inp 1", - "sourceLayerType": 15, - "platformKey": "SHIFT+U" - }, - { - "_id": "5xmjuHQidyXfgJcHb", - "key": "SHIFT+I", - "label": "EVS 2 100% inp 1", - "sourceLayerType": 15, - "platformKey": "SHIFT+I" - }, { "_id": "vDF35PGiHBvWpeTxv", "key": "SHIFT+F1", @@ -489,34 +433,6 @@ "label": "øve rundown", "platformKey": "ctrl+½" }, - { - "_id": "sCzTBw8MCcSxrXNqD", - "key": "ctrl+e", - "label": "EVS 1 100% inp 2", - "sourceLayerType": 15, - "platformKey": "ctrl+e" - }, - { - "_id": "Ew6cNpWbBEbr99h9K", - "key": "ctrl+d", - "label": "EVS 1 VO inp 2", - "sourceLayerType": 15, - "platformKey": "ctrl+d" - }, - { - "_id": "p4jf6mpGY3CfNJhiJ", - "key": "Ctrl+Alt+Shift+i", - "label": "EVS 2 VO inp 2", - "sourceLayerType": 15, - "platformKey": "ctrl+u" - }, - { - "_id": "6BdRrR258vtZr35jv", - "key": "ctrl+i", - "label": "EVS 2 100% inp 2", - "sourceLayerType": 15, - "platformKey": "ctrl+i" - }, { "_id": "rphiEaRPCrQphceAZ", "key": "ctrl+home", @@ -635,12 +551,6 @@ "sourceLayerType": 3, "platformKey": "shift+ctrl+0" }, - { - "_id": "R2i2648kXwPaJpGb4", - "key": "shift+ctrl+e", - "label": "EVS 1 til SS", - "platformKey": "shift+ctrl+e" - }, { "_id": "6Lyc63BnGt5k8LXus", "key": "shift+ctrl+a", @@ -677,12 +587,6 @@ "label": "deaktivate rundown", "platformKey": "ctrl+shift+½" }, - { - "_id": "zfr6hP3ozv4nomNRC", - "key": "CTRL+ALT+SHIFT+F", - "label": "EVS 1 til OVL inp1", - "platformKey": "ALT+E" - }, { "_id": "BDi5mebWYmX5dp8YQ", "key": "SHIFT+CTRL+F1", diff --git a/src/tv2-common/hotkeys/hotkey-defaults.ts b/src/tv2-common/hotkeys/hotkey-defaults.ts index 6f8afbef0..8b09c19c9 100644 --- a/src/tv2-common/hotkeys/hotkey-defaults.ts +++ b/src/tv2-common/hotkeys/hotkey-defaults.ts @@ -97,14 +97,14 @@ export const defaultHotkeys: TV2Hotkeys = { fullAudio: { directCut: [], queue: ['KeyR', 'KeyI'], - cutToBox: [['Shift+KeyE', 'Shift+KeyI'], ['Ctrl+KeyE', 'Ctrl+KeyI'], ['Alt+Shift+KeyE', 'Alt+Shift+KeyG'], []], - routeToStudioScreen: ['Shift+Ctrl+KeyE'], - routeToGraphicsEngine: ['Ctrl+Alt+Shift+KeyF'] + cutToBox: [['Shift+KeyR', 'Shift+KeyI'], ['Ctrl+KeyR', 'Ctrl+KeyI'], ['Alt+Shift+KeyR', 'Alt+Shift+KeyI'], []], + routeToStudioScreen: [], + routeToGraphicsEngine: [] }, voAudio: { directCut: [], queue: ['KeyE', 'KeyU'], - cutToBox: [['Shift+KeyD', 'Shift+KeyU'], ['Ctrl+KeyD', 'Ctrl+KeyU'], ['Alt+Shift+KeyD'], []], + cutToBox: [['Shift+KeyE', 'Shift+KeyU'], ['Ctrl+KeyE', 'Ctrl+KeyU'], ['Alt+Shift+KeyE', 'Alt+Shift+KeyU'], []], routeToGraphicsEngine: [], routeToStudioScreen: [] } From a88c373ca90fb966b29d11cba9b3ca5e6822ddeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Tue, 19 Apr 2022 14:14:03 +0200 Subject: [PATCH 076/184] refactor: Eliminate duplicated code. --- src/tv2-common/hotkeys/local.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/hotkeys/local.ts b/src/tv2-common/hotkeys/local.ts index f04fd6129..94e30a279 100644 --- a/src/tv2-common/hotkeys/local.ts +++ b/src/tv2-common/hotkeys/local.ts @@ -14,8 +14,12 @@ function localSourceFullAudioHotkeyName(source: string) { return `EVS ${source} 100%` } +function shouldUseCustomIndexPickerForLocalSourceAudio(hotkeyType: string): boolean { + return hotkeyType === 'queue' || /^cut_to_box_\d+$/.test(hotkeyType) +} + function localSourceFullAudioPick(sourceIndex: number, hotkeyType: string): number { - if (hotkeyType === 'queue' || /^cut_to_box_\d+$/.test(hotkeyType)) { + if (shouldUseCustomIndexPickerForLocalSourceAudio(hotkeyType)) { return 2 * sourceIndex } return sourceIndex @@ -30,7 +34,7 @@ function localSourceVoAudioHotkeyName(source: string) { } function localSourceVoAudioPick(sourceIndex: number, hotkeyType: string): number { - if (hotkeyType === 'queue' || /^cut_to_box_\d+$/.test(hotkeyType)) { + if (shouldUseCustomIndexPickerForLocalSourceAudio(hotkeyType)) { return 1 + 2 * sourceIndex } return sourceIndex From 354c48085291ace59ad936d7257e434eca88a73e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Tue, 19 Apr 2022 14:16:01 +0200 Subject: [PATCH 077/184] refactor: Organized function order. --- src/tv2-common/hotkeys/local.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tv2-common/hotkeys/local.ts b/src/tv2-common/hotkeys/local.ts index 94e30a279..46c6b78ce 100644 --- a/src/tv2-common/hotkeys/local.ts +++ b/src/tv2-common/hotkeys/local.ts @@ -14,10 +14,6 @@ function localSourceFullAudioHotkeyName(source: string) { return `EVS ${source} 100%` } -function shouldUseCustomIndexPickerForLocalSourceAudio(hotkeyType: string): boolean { - return hotkeyType === 'queue' || /^cut_to_box_\d+$/.test(hotkeyType) -} - function localSourceFullAudioPick(sourceIndex: number, hotkeyType: string): number { if (shouldUseCustomIndexPickerForLocalSourceAudio(hotkeyType)) { return 2 * sourceIndex @@ -40,6 +36,10 @@ function localSourceVoAudioPick(sourceIndex: number, hotkeyType: string): number return sourceIndex } +function shouldUseCustomIndexPickerForLocalSourceAudio(hotkeyType: string): boolean { + return hotkeyType === 'queue' || /^cut_to_box_\d+$/.test(hotkeyType) +} + export function MakeLocalSourceHotkeys( showStyleId: string, sourceLayerId: string, From c3d1990f765ab5a30bb4ba04b8bc96b91fac2bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Wed, 20 Apr 2022 09:57:44 +0200 Subject: [PATCH 078/184] chore: converted internalGraphic to class and moved relevant methods to it --- src/tv2-common/actions/executeAction.ts | 48 +-- .../helpers/graphics/InternalGraphic.ts | 241 ++++++++++++++ .../helpers/graphics/internal/index.ts | 297 +----------------- 3 files changed, 261 insertions(+), 325 deletions(-) create mode 100644 src/tv2-common/helpers/graphics/InternalGraphic.ts diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 75ef27361..0659ede7d 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -32,7 +32,6 @@ import { ActionSelectFullGrafik, ActionSelectServerClip, CalculateTime, - CreateContinuationPieceForIdentPersistent, CreateFullPiece, CreatePartServerBase, CueDefinition, @@ -48,15 +47,11 @@ import { GetDVETemplate, GetEksternMetaData, GetFullGrafikTemplateName, - GetInfiniteModeForGraphic, - getInternalGraphic, - getInternalGraphicContent, GetLayersForCamera, GetLayersForEkstern, GetSisyfosTimelineObjForCamera, GetSisyfosTimelineObjForEkstern, GraphicPilot, - InternalGraphic, IsTargetingOVL, ITV2ActionExecutionContext, literal, @@ -98,6 +93,7 @@ import { ActionSelectJingle, ActionTakeWithTransition } from './actionTypes' +import { InternalGraphic } from '../helpers/graphics/InternalGraphic' const STOPPABLE_GRAPHICS_LAYERS = [ SharedSourceLayers.PgmGraphicsIdent, @@ -1854,47 +1850,27 @@ function executeActionPlayGraphics< context: ITV2ActionExecutionContext, settings: ActionExecutionSettings, actionId: string, - _userData: ActionPlayGraphics + userData: ActionPlayGraphics ) { - const internalGraphic: InternalGraphic = getInternalGraphic( + if (!IsTargetingOVL(userData.graphic.target)) { + return + } + + const externalId = context.getPartInstance('current')?.part.externalId ?? generateExternalId(context, actionId, []) + + const internalGraphic: InternalGraphic = new InternalGraphic( settings.getConfig(context), - _userData.graphic, + userData.graphic, true, undefined, - undefined, + externalId, undefined, undefined ) const pieces: IBlueprintPiece[] = [] - if (IsTargetingOVL(_userData.graphic.target)) { - const externalId = context.getPartInstance('current')?.part.externalId ?? generateExternalId(context, actionId, []) - const content: IBlueprintPiece['content'] = getInternalGraphicContent(internalGraphic) + internalGraphic.createPiece(pieces) - const piece = literal({ - externalId, - name: internalGraphic.name, - enable: { start: 0 }, - outputLayerId: internalGraphic.outputLayerId, - sourceLayerId: internalGraphic.sourceLayerId, - lifespan: GetInfiniteModeForGraphic( - internalGraphic.engine, - internalGraphic.config, - internalGraphic.parsedCue, - internalGraphic.isStickyIdent - ), - content: _.clone(content) - }) - pieces.push(piece) - - if ( - internalGraphic.sourceLayerId === SharedSourceLayers.PgmGraphicsIdentPersistent && - (piece.lifespan === PieceLifespan.OutOnSegmentEnd || piece.lifespan === PieceLifespan.OutOnShowStyleEnd) && - internalGraphic.isStickyIdent - ) { - pieces.push(CreateContinuationPieceForIdentPersistent(piece, internalGraphic)) - } - } pieces.forEach((piece: IBlueprintPiece) => { context.insertPiece('current', piece) }) diff --git a/src/tv2-common/helpers/graphics/InternalGraphic.ts b/src/tv2-common/helpers/graphics/InternalGraphic.ts new file mode 100644 index 000000000..18ffc503e --- /dev/null +++ b/src/tv2-common/helpers/graphics/InternalGraphic.ts @@ -0,0 +1,241 @@ +import { + IBlueprintActionManifest, + IBlueprintAdLibPiece, + IBlueprintPart, + IBlueprintPiece, + PieceLifespan, + TSR +} from '@tv2media/blueprints-integration' +import _ = require('underscore') +import { + AbstractLLayer, + AdlibActionType, + AdlibTags, + GraphicEngine, + SharedOutputLayers, + SharedSourceLayers +} from '../../../tv2-constants' +import { ActionPlayGraphics } from '../../actions' +import { TV2BlueprintConfig } from '../../blueprintConfig' +import { GetDefaultOut } from '../../cueTiming' +import { CueDefinitionGraphic, GraphicInternal, IsStickyIdent, PartDefinition } from '../../inewsConversion' +import { literal } from '../../util' +import { t } from '../translation' +import { GetInternalGraphicContentCaspar } from './caspar' +import { GetSourceLayerForGraphic } from './layers' +import { GetFullGraphicTemplateNameFromCue, GraphicDisplayName } from './name' +import { IsTargetingOVL, IsTargetingTLF, IsTargetingWall } from './target' +import { CreateTimingGraphic, GetInfiniteModeForGraphic } from './timing' +import { GetInternalGraphicContentVIZ } from './viz' + +export class InternalGraphic { + public mappedTemplate: string + private readonly config: TV2BlueprintConfig + private readonly part?: Readonly + private readonly parsedCue: CueDefinitionGraphic + private readonly partDefinition?: PartDefinition + private readonly adlib: boolean + private readonly isStickyIdent: boolean + 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, + parsedCue: CueDefinitionGraphic, + adlib: boolean, + part?: Readonly, + partId?: string, + partDefinition?: PartDefinition, + rank?: number + ) { + const isStickyIdent = IsStickyIdent(parsedCue) + + const engine = parsedCue.target + + const mappedTemplate = GetFullGraphicTemplateNameFromCue(config, parsedCue) + + const sourceLayerId = IsTargetingTLF(engine) + ? SharedSourceLayers.PgmGraphicsTLF + : GetSourceLayerForGraphic(config, mappedTemplate, isStickyIdent) + + this.config = config + this.part = part + this.parsedCue = parsedCue + this.partDefinition = partDefinition + this.adlib = adlib + this.mappedTemplate = mappedTemplate + this.isStickyIdent = isStickyIdent + this.engine = parsedCue.target + this.name = GraphicDisplayName(config, parsedCue) + this.sourceLayerId = sourceLayerId + this.outputLayerId = IsTargetingWall(engine) ? SharedOutputLayers.SEC : SharedOutputLayers.OVERLAY + this.partId = partId + this.rank = rank + this.content = this.getInternalGraphicContent() + } + + public createAdlibTargetingOVL(actions: IBlueprintActionManifest[], adlibPieces: IBlueprintAdLibPiece[]): void { + if (IsTargetingOVL(this.engine) && this.isStickyIdent) { + actions.push( + literal({ + actionId: AdlibActionType.PLAY_GRAPHICS, + userData: literal({ + type: AdlibActionType.PLAY_GRAPHICS, + graphic: this.parsedCue + }), + userDataManifest: {}, + display: { + _rank: this.rank || 0, + label: t(this.name), + uniquenessId: `gfx_${this.name}_${this.sourceLayerId}_${this.outputLayerId}_commentator`, + sourceLayerId: this.sourceLayerId, + outputLayerId: SharedOutputLayers.OVERLAY, + tags: [AdlibTags.ADLIB_KOMMENTATOR], + content: _.clone(this.content), + noHotKey: true + } + }) + ) + } else if (IsTargetingOVL(this.engine)) { + const adLibPiece = literal({ + _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, + expectedDuration: 5000, + tags: [AdlibTags.ADLIB_KOMMENTATOR], + content: _.clone(this.content), + noHotKey: true + }) + adlibPieces.push(adLibPiece) + } + } + + public createAdlib(actions: IBlueprintActionManifest[], adlibPieces: IBlueprintAdLibPiece[]): void { + if (this.isStickyIdent) { + actions.push( + literal({ + actionId: AdlibActionType.PLAY_GRAPHICS, + userData: literal({ + type: AdlibActionType.PLAY_GRAPHICS, + graphic: this.parsedCue + }), + userDataManifest: {}, + display: { + _rank: this.rank || 0, + label: t(this.name), + uniquenessId: `gfx_${this.name}_${this.sourceLayerId}_${this.outputLayerId}_flow`, + sourceLayerId: this.sourceLayerId, + outputLayerId: SharedOutputLayers.OVERLAY, + tags: [AdlibTags.ADLIB_FLOW_PRODUCER], + content: _.clone(this.content) + } + }) + ) + } else { + adlibPieces.push( + literal({ + _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 || GetDefaultOut(this.config) + }), + lifespan: GetInfiniteModeForGraphic(this.engine, this.config, this.parsedCue, this.isStickyIdent), + content: _.clone(this.content) + }) + ) + } + } + + public createPiece(pieces: IBlueprintPiece[]): void { + const piece = literal({ + externalId: this.partId ?? '', + name: this.name, + ...(IsTargetingTLF(this.engine) || IsTargetingWall(this.engine) + ? { enable: { start: 0 } } + : { + enable: { + ...CreateTimingGraphic(this.config, this.parsedCue, !this.isStickyIdent) + } + }), + outputLayerId: this.outputLayerId, + sourceLayerId: this.sourceLayerId, + lifespan: GetInfiniteModeForGraphic(this.engine, this.config, this.parsedCue, this.isStickyIdent), + content: _.clone(this.content) + }) + pieces.push(piece) + + if ( + this.sourceLayerId === SharedSourceLayers.PgmGraphicsIdentPersistent && + (piece.lifespan === PieceLifespan.OutOnSegmentEnd || piece.lifespan === PieceLifespan.OutOnShowStyleEnd) && + this.isStickyIdent + ) { + // Special case for the ident. We want it to continue to exist in case the Live gets shown again, but we dont want the continuation showing in the ui. + // So we create the normal object on a hidden layer, and then clone it on another layer without content for the ui + pieces.push(this.createIndicatorPieceForIdentPersistent(piece)) + } + } + + public createIndicatorPieceForIdentPersistent(piece: IBlueprintPiece): IBlueprintPiece { + return literal({ + ...piece, + enable: { ...CreateTimingGraphic(this.config, this.parsedCue, true) }, // Allow default out for visual representation + sourceLayerId: SharedSourceLayers.PgmGraphicsIdent, + lifespan: PieceLifespan.WithinPart, + content: { + timelineObjects: [ + literal({ + id: '', + enable: { + while: '1' + }, + layer: AbstractLLayer.IdentMarker, + content: { + deviceType: TSR.DeviceType.ABSTRACT + } + }) + ] + } + }) + } + + private getInternalGraphicContent(): IBlueprintPiece['content'] { + return this.config.studio.GraphicsType === 'HTML' + ? GetInternalGraphicContentCaspar( + this.config, + this.part, + this.engine, + this.parsedCue, + this.isStickyIdent, + this.partDefinition, + this.mappedTemplate, + this.adlib + ) + : GetInternalGraphicContentVIZ( + this.config, + this.part, + this.engine, + this.parsedCue, + this.isStickyIdent, + this.partDefinition, + this.mappedTemplate, + this.adlib + ) + } +} diff --git a/src/tv2-common/helpers/graphics/internal/index.ts b/src/tv2-common/helpers/graphics/internal/index.ts index 7f7e429ca..b5df19bb9 100644 --- a/src/tv2-common/helpers/graphics/internal/index.ts +++ b/src/tv2-common/helpers/graphics/internal/index.ts @@ -3,58 +3,10 @@ import { IBlueprintAdLibPiece, IBlueprintPart, IBlueprintPiece, - IShowStyleUserContext, - PieceLifespan, - TSR + IShowStyleUserContext } from '@tv2media/blueprints-integration' -import { - ActionPlayGraphics, - CueDefinitionGraphic, - GetDefaultOut, - GraphicInternal, - IsStickyIdent, - literal, - PartDefinition, - t, - TV2BlueprintConfig -} from 'tv2-common' -import { - AbstractLLayer, - AdlibActionType, - AdlibTags, - GraphicEngine, - SharedOutputLayers, - SharedSourceLayers -} from 'tv2-constants' -import _ = require('underscore') -import { - CreateTimingGraphic, - GetFullGraphicTemplateNameFromCue, - GetInfiniteModeForGraphic, - GetSourceLayerForGraphic, - GraphicDisplayName, - IsTargetingOVL, - IsTargetingTLF, - IsTargetingWall -} from '..' -import { GetInternalGraphicContentCaspar } from '../caspar' -import { GetInternalGraphicContentVIZ } from '../viz' - -export interface InternalGraphic { - config: TV2BlueprintConfig - part?: Readonly - parsedCue: CueDefinitionGraphic - partDefinition?: PartDefinition - adlib: boolean - mappedTemplate: string - isStickyIdent: boolean - engine: GraphicEngine - name: string - sourceLayerId: SharedSourceLayers - outputLayerId: SharedOutputLayers - partId?: string - rank?: number -} +import { CueDefinitionGraphic, GraphicInternal, PartDefinition, TV2BlueprintConfig } from 'tv2-common' +import { InternalGraphic } from '../InternalGraphic' export function CreateInternalGraphic( config: TV2BlueprintConfig, @@ -62,14 +14,14 @@ export function CreateInternalGraphic( part: Readonly, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], - _actions: IBlueprintActionManifest[], + actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionGraphic, adlib: boolean, partDefinition: PartDefinition, rank?: number ) { - const internalGraphic: InternalGraphic = getInternalGraphic( + const internalGraphic: InternalGraphic = new InternalGraphic( config, parsedCue, adlib, @@ -84,243 +36,10 @@ export function CreateInternalGraphic( return } - const content: IBlueprintPiece['content'] = getInternalGraphicContent(internalGraphic) - if (adlib) { - createAdlibTargetingOVL(internalGraphic, _actions, adlibPieces, content) - createAdlib(internalGraphic, _actions, adlibPieces, content) - } else { - createPiece(internalGraphic, pieces, content) - } -} - -export function getInternalGraphic( - config: TV2BlueprintConfig, - parsedCue: CueDefinitionGraphic, - adlib: boolean, - part?: Readonly, - partId?: string, - partDefinition?: PartDefinition, - rank?: number -): InternalGraphic { - // Whether this graphic "sticks" to the source it was first assigned to. - // e.g. if this is attached to Live 1, when Live 1 is recalled later in a segment, - // this graphic should be shown again. - const isStickyIdent = IsStickyIdent(parsedCue) - - const engine = parsedCue.target - - const mappedTemplate = GetFullGraphicTemplateNameFromCue(config, parsedCue) - - const sourceLayerId = IsTargetingTLF(engine) - ? SharedSourceLayers.PgmGraphicsTLF - : GetSourceLayerForGraphic(config, mappedTemplate, isStickyIdent) - - const outputLayerId = IsTargetingWall(engine) ? SharedOutputLayers.SEC : SharedOutputLayers.OVERLAY - - const name = GraphicDisplayName(config, parsedCue) - return { - config, - part, - parsedCue, - partDefinition, - adlib, - mappedTemplate, - isStickyIdent, - engine: parsedCue.target, - name, - sourceLayerId, - outputLayerId, - partId, - rank - } -} - -export function getInternalGraphicContent(internalGraphic: InternalGraphic): IBlueprintPiece['content'] { - return internalGraphic.config.studio.GraphicsType === 'HTML' - ? GetInternalGraphicContentCaspar( - internalGraphic.config, - internalGraphic.part, - internalGraphic.engine, - internalGraphic.parsedCue, - internalGraphic.isStickyIdent, - internalGraphic.partDefinition, - internalGraphic.mappedTemplate, - internalGraphic.adlib - ) - : GetInternalGraphicContentVIZ( - internalGraphic.config, - internalGraphic.part, - internalGraphic.engine, - internalGraphic.parsedCue, - internalGraphic.isStickyIdent, - internalGraphic.partDefinition, - internalGraphic.mappedTemplate, - internalGraphic.adlib - ) -} - -function createAdlibTargetingOVL( - internalGraphic: InternalGraphic, - _actions: IBlueprintActionManifest[], - adlibPieces: IBlueprintAdLibPiece[], - content: IBlueprintPiece['content'] -): void { - if (IsTargetingOVL(internalGraphic.engine) && internalGraphic.isStickyIdent) { - _actions.push( - literal({ - actionId: AdlibActionType.PLAY_GRAPHICS, - userData: literal({ - type: AdlibActionType.PLAY_GRAPHICS, - graphic: internalGraphic.parsedCue - }), - userDataManifest: {}, - display: { - _rank: internalGraphic.rank || 0, - label: t(internalGraphic.name), - uniquenessId: `gfx_${internalGraphic.name}_${internalGraphic.sourceLayerId}_${internalGraphic.outputLayerId}_commentator`, - sourceLayerId: internalGraphic.sourceLayerId, - outputLayerId: SharedOutputLayers.OVERLAY, - tags: [AdlibTags.ADLIB_KOMMENTATOR], - content: _.clone(content), - noHotKey: true - } - }) - ) - } else if (IsTargetingOVL(internalGraphic.engine)) { - const adLibPiece = literal({ - _rank: internalGraphic.rank || 0, - externalId: internalGraphic.partId ?? '', - name: internalGraphic.name, - uniquenessId: `gfx_${internalGraphic.name}_${internalGraphic.sourceLayerId}_${internalGraphic.outputLayerId}_commentator`, - sourceLayerId: internalGraphic.sourceLayerId, - outputLayerId: SharedOutputLayers.OVERLAY, - lifespan: PieceLifespan.WithinPart, - expectedDuration: 5000, - tags: [AdlibTags.ADLIB_KOMMENTATOR], - content: _.clone(content), - noHotKey: true - }) - adlibPieces.push(adLibPiece) - } -} - -function createAdlib( - internalGraphic: InternalGraphic, - _actions: IBlueprintActionManifest[], - adlibPieces: IBlueprintAdLibPiece[], - content: IBlueprintPiece['content'] -): void { - if (internalGraphic.isStickyIdent) { - _actions.push( - literal({ - actionId: AdlibActionType.PLAY_GRAPHICS, - userData: literal({ - type: AdlibActionType.PLAY_GRAPHICS, - graphic: internalGraphic.parsedCue - }), - userDataManifest: {}, - display: { - _rank: internalGraphic.rank || 0, - label: t(internalGraphic.name), - uniquenessId: `gfx_${internalGraphic.name}_${internalGraphic.sourceLayerId}_${internalGraphic.outputLayerId}_flow`, - sourceLayerId: internalGraphic.sourceLayerId, - outputLayerId: SharedOutputLayers.OVERLAY, - tags: [AdlibTags.ADLIB_FLOW_PRODUCER], - content: _.clone(content) - } - }) - ) + internalGraphic.createAdlibTargetingOVL(actions, adlibPieces) + internalGraphic.createAdlib(actions, adlibPieces) } else { - adlibPieces.push( - literal({ - _rank: internalGraphic.rank || 0, - externalId: internalGraphic.partId ?? '', - name: internalGraphic.name, - uniquenessId: `gfx_${internalGraphic.name}_${internalGraphic.sourceLayerId}_${internalGraphic.outputLayerId}_flow`, - sourceLayerId: internalGraphic.sourceLayerId, - outputLayerId: internalGraphic.outputLayerId, - tags: [AdlibTags.ADLIB_FLOW_PRODUCER], - ...(IsTargetingTLF(internalGraphic.engine) || - (internalGraphic.parsedCue.end && internalGraphic.parsedCue.end.infiniteMode) - ? {} - : { - expectedDuration: - CreateTimingGraphic(internalGraphic.config, internalGraphic.parsedCue).duration || - GetDefaultOut(internalGraphic.config) - }), - lifespan: GetInfiniteModeForGraphic( - internalGraphic.engine, - internalGraphic.config, - internalGraphic.parsedCue, - internalGraphic.isStickyIdent - ), - content: _.clone(content) - }) - ) + internalGraphic.createPiece(pieces) } } - -function createPiece( - internalGraphic: InternalGraphic, - pieces: IBlueprintPiece[], - content: IBlueprintPiece['content'] -): void { - const piece = literal({ - externalId: internalGraphic.partId ?? '', - name: internalGraphic.name, - ...(IsTargetingTLF(internalGraphic.engine) || IsTargetingWall(internalGraphic.engine) - ? { enable: { start: 0 } } - : { - enable: { - ...CreateTimingGraphic(internalGraphic.config, internalGraphic.parsedCue, !internalGraphic.isStickyIdent) - } - }), - outputLayerId: internalGraphic.outputLayerId, - sourceLayerId: internalGraphic.sourceLayerId, - lifespan: GetInfiniteModeForGraphic( - internalGraphic.engine, - internalGraphic.config, - internalGraphic.parsedCue, - internalGraphic.isStickyIdent - ), - content: _.clone(content) - }) - pieces.push(piece) - - if ( - internalGraphic.sourceLayerId === SharedSourceLayers.PgmGraphicsIdentPersistent && - (piece.lifespan === PieceLifespan.OutOnSegmentEnd || piece.lifespan === PieceLifespan.OutOnShowStyleEnd) && - internalGraphic.isStickyIdent - ) { - // Special case for the ident. We want it to continue to exist in case the Live gets shown again, but we dont want the continuation showing in the ui. - // So we create the normal object on a hidden layer, and then clone it on another layer without content for the ui - pieces.push(CreateContinuationPieceForIdentPersistent(piece, internalGraphic)) - } -} - -export function CreateContinuationPieceForIdentPersistent( - piece: IBlueprintPiece, - internalGraphic: InternalGraphic -): IBlueprintPiece { - return literal({ - ...piece, - enable: { ...CreateTimingGraphic(internalGraphic.config, internalGraphic.parsedCue, true) }, // Allow default out for visual representation - sourceLayerId: SharedSourceLayers.PgmGraphicsIdent, - lifespan: PieceLifespan.WithinPart, - content: { - timelineObjects: [ - literal({ - id: '', - enable: { - while: '1' - }, - layer: AbstractLLayer.IdentMarker, - content: { - deviceType: TSR.DeviceType.ABSTRACT - } - }) - ] - } - }) -} From fcf72bab7915fe921c7a59a1baa2a69962437425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Wed, 20 Apr 2022 10:11:14 +0200 Subject: [PATCH 079/184] chore: converted internalGraphic to class and moved relevant methods to it --- src/tv2-common/actions/executeAction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 0659ede7d..4a6326957 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -74,6 +74,7 @@ import { import _ = require('underscore') import { EnableServer } from '../content' import { CreateFullDataStore, GetEnableForWall, PilotGeneratorSettings } from '../helpers' +import { InternalGraphic } from '../helpers/graphics/InternalGraphic' import { GetJinglePartPropertiesFromTableValue } from '../jinglePartProperties' import { CreateEffektForPartBase, CreateEffektForPartInner, CreateMixForPartInner } from '../parts' import { @@ -93,7 +94,6 @@ import { ActionSelectJingle, ActionTakeWithTransition } from './actionTypes' -import { InternalGraphic } from '../helpers/graphics/InternalGraphic' const STOPPABLE_GRAPHICS_LAYERS = [ SharedSourceLayers.PgmGraphicsIdent, From 8bf3cb9cad22f1c55bd70d31e5e3b0b591a4fe42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Wed, 20 Apr 2022 10:47:45 +0200 Subject: [PATCH 080/184] chore: bumped version of moment because of https://github.com/advisories/GHSA-8hfj-j24r-96c4 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a9257f32e..94c95cafd 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "jest": "^27.5.1", "jest-haste-map": "^24.5.0", "jest-resolve": "^24.5.0", - "moment": "^2.22.2", + "moment": "^2.29.2", "node-license-validator": "^1.3.0", "prettier": "^1.18.2", "standard-version": "9.1.1", diff --git a/yarn.lock b/yarn.lock index ed6415bd4..914075e0e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4612,10 +4612,10 @@ moment@2.29.1: resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== -moment@^2.22.2: - version "2.24.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" - integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== +moment@^2.29.2: + version "2.29.3" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.3.tgz#edd47411c322413999f7a5940d526de183c031f3" + integrity sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw== move-concurrently@^1.0.1: version "1.0.1" From 7c8449002f14ff6d82475a0220451df573054740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Korgaard=20Nielsen?= Date: Wed, 20 Apr 2022 11:34:53 +0200 Subject: [PATCH 081/184] chore: force blueprint-integrations to use moment 2.29.2 --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 94c95cafd..25276ec45 100644 --- a/package.json +++ b/package.json @@ -62,5 +62,8 @@ "@tv2media/blueprints-integration": "1.37.1", "@tv2media/timeline-state-resolver-types": "^1.0.0-release37.6", "underscore": "^1.12.1" + }, + "resolutions": { + "moment": "^2.29.2" } } From 0ea48f3ba1cb07225a67ba8833790425a4c52f47 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Fri, 22 Apr 2022 09:55:11 +0200 Subject: [PATCH 082/184] SOF-830 Fix compilation errors --- package.json | 2 +- src/tv2-common/actions/executeAction.ts | 4 +- src/tv2-common/content/dve.ts | 2 +- src/tv2-common/helpers/abPlayback.ts | 2 +- .../__tests__/rundown_story_exception.spec.ts | 39 +++++-------------- src/tv2_afvd_showstyle/getRundown.ts | 18 ++++----- src/tv2_afvd_showstyle/getSegment.ts | 2 +- src/tv2_afvd_showstyle/helpers/pieces/dve.ts | 1 - .../helpers/pieces/routing.ts | 2 +- .../postProcessTimelineObjects.ts | 6 ++- .../cues/OfftubeGraphicBackgroundLoop.ts | 4 +- src/tv2_offtube_showstyle/getSegment.ts | 2 +- 12 files changed, 32 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index 5ecacecf1..87e539ad5 100644 --- a/package.json +++ b/package.json @@ -63,4 +63,4 @@ "@tv2media/timeline-state-resolver-types": "1.41.0", "underscore": "^1.12.1" } -} \ No newline at end of file +} diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index b99f1dc94..8d1be1824 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1082,7 +1082,7 @@ async function executeActionCutToCamera< }, tags: [GetTagForKam(userData.name)], content: { - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { while: '1' }, @@ -1202,7 +1202,7 @@ async function executeActionCutToRemote< }, tags: [GetTagForLive(userData.name)], content: { - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { while: '1' }, diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 0482a6fc6..4e5943e05 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -454,7 +454,7 @@ export function MakeContentDVE2< valid, content: literal>({ boxSourceConfiguration: boxSources, - timelineObjects: _.compact([ + timelineObjects: _.compact([ // Setup classes for adlibs to be able to override boxes createEmptyObject({ enable: getDVEEnable(), diff --git a/src/tv2-common/helpers/abPlayback.ts b/src/tv2-common/helpers/abPlayback.ts index c23c65d10..8ab82fcc2 100644 --- a/src/tv2-common/helpers/abPlayback.ts +++ b/src/tv2-common/helpers/abPlayback.ts @@ -414,7 +414,7 @@ export function applyMediaPlayersAssignments< ) const groupedObjs = _.groupBy(labelledObjs, o => { const sessionId = (o.metaData || {}).mediaPlayerSession - if (sessionId === '' || sessionId === MEDIA_PLAYER_AUTO) { + if (sessionId === undefined || sessionId === '' || sessionId === MEDIA_PLAYER_AUTO) { const piece = resolvedPieces.find(p => p._id === o.pieceInstanceId) return piece?.infinite?.infinitePieceId || o.pieceInstanceId || MEDIA_PLAYER_AUTO } else { 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 da1498b7d..22a396d84 100644 --- a/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts @@ -1,6 +1,6 @@ import * as _ from 'underscore' -import { ExtendedIngestRundown, IBlueprintPieceGeneric, IBlueprintRundownDB } from '@tv2media/blueprints-integration' +import { ExtendedIngestRundown, IBlueprintPieceGeneric } from '@tv2media/blueprints-integration' import { defaultShowStyleConfig, defaultStudioConfig } from './configs' import { checkAllLayers } from './layers-check' @@ -11,23 +11,21 @@ global.VERSION_TSR = 'test' // @ts-ignore global.VERSION_INTEGRATION = 'test' -import { INewsStory, literal } from 'tv2-common' -import { GetRundownContext, SegmentUserContext } from '../../__mocks__/context' +import { INewsStory } from 'tv2-common' +import { SegmentUserContext } from '../../__mocks__/context' import { parseConfig 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 Blueprints from '../index' -// More ROs can be listed here to make them part of the basic blueprint doesnt crash test +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 }> = [ - { ro: '../../../rundowns/on-air.json', studioConfig: defaultStudioConfig, showStyleConfig: defaultShowStyleConfig } + { ro: onAirRundownRelativePath, studioConfig: defaultStudioConfig, showStyleConfig: defaultShowStyleConfig } ] -const RUNDOWN_ID = 'test_rundown' -const SEGMENT_ID = 'test_segment' -const PART_ID = 'test_part' - -describe('Rundown exceptions', async () => { +describe('Generate rundowns without error', () => { for (const roSpec of rundowns) { const roData = require(roSpec.ro) as ExtendedIngestRundown test('Valid file: ' + roSpec.ro, () => { @@ -36,27 +34,8 @@ describe('Rundown exceptions', async () => { expect(roData.type).toEqual('inews') }) - const showStyleContext = new GetRundownContext( - 'mockRo', - mappingsDefaults, - parseStudioConfig, - parseShowStyleConfig, - RUNDOWN_ID, - SEGMENT_ID, - PART_ID - ) - // can I do this?: - showStyleContext.studioConfig = roSpec.studioConfig as any - showStyleContext.showStyleConfig = roSpec.showStyleConfig as any - const blueprintRundown = await Blueprints.getRundown(showStyleContext, roData) - const rundown = literal({ - ...blueprintRundown!.rundown, - _id: 'mockRo', - showStyleVariantId: 'mock' - }) - for (const segment of roData.segments) { - test('Rundown segment: ' + roSpec.ro + ' - ' + rundown.externalId, async () => { + test(`Rundown segment: ${segment.name} - ${roSpec.ro} - ${roData.externalId}`, () => { const mockContext = new SegmentUserContext('test', mappingsDefaults, parseStudioConfig, parseShowStyleConfig) mockContext.studioConfig = roSpec.studioConfig as any mockContext.showStyleConfig = roSpec.showStyleConfig as any diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index d679775fe..a86b8b594 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -111,7 +111,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint tags: [AdlibTags.ADLIB_QUEUE_NEXT, vo ? AdlibTags.ADLIB_VO_AUDIO_LEVEL : AdlibTags.ADLIB_FULL_AUDIO_LEVEL], content: { ignoreMediaObjectStatus: true, - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { while: '1' }, @@ -172,7 +172,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint }, tags: [AdlibTags.ADLIB_QUEUE_NEXT], content: { - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { while: '1' }, @@ -216,7 +216,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint }, tags: [AdlibTags.ADLIB_TO_STUDIO_SCREEN_AUX], content: { - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { while: '1' }, @@ -270,7 +270,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint lifespan: PieceLifespan.OutOnShowStyleEnd, tags: [AdlibTags.ADLIB_TO_STUDIO_SCREEN_AUX], content: { - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { while: '1' }, @@ -297,7 +297,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint lifespan: PieceLifespan.OutOnShowStyleEnd, tags: [AdlibTags.ADLIB_TO_GRAPHICS_ENGINE_AUX], content: { - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { while: '1' }, @@ -327,7 +327,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint lifespan: PieceLifespan.WithinPart, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_LOAD], content: { - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: 'loadAllElements', enable: { @@ -355,7 +355,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint lifespan: PieceLifespan.WithinPart, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_CONTINUE_FORWARD], content: { - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { @@ -448,7 +448,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIBS_RESYNC_SISYFOS], expectedDuration: 1000, content: { - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { start: 0 }, @@ -478,7 +478,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint fileName: 'BG_LOADER_SC', path: 'BG_LOADER_SC', ignoreMediaObjectStatus: true, - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { start: 0 }, diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index 0d0f7d17b..32016cee2 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -73,7 +73,7 @@ export function CreatePartContinuity(config: ShowStyleConfig, ingestSegment: Ing content: literal>({ studioLabel: '', switcherInput: config.studio.AtemSource.Continuity, - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { diff --git a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts index ffeccee78..46081decc 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts @@ -19,7 +19,6 @@ import { TemplateIsValid } from 'tv2-common' import { AdlibActionType, SharedOutputLayers } from 'tv2-constants' -import * as _ from 'underscore' import { BlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { SourceLayer } from '../../../tv2_afvd_showstyle/layers' import { MakeContentDVE } from '../content/dve' diff --git a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts index ee035e889..1819e0efb 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts @@ -52,7 +52,7 @@ export function EvaluateCueRouting( content: literal>({ studioLabel: '', switcherInput: sourceInfo.port, - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { start: 0 }, diff --git a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts index 73f97ab0b..7a33f30ad 100644 --- a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts @@ -122,7 +122,9 @@ export function postProcessPieceTimelineObjects( if (mixMinusSource !== null && mixMinusSource !== -1) { const mixMinusObj = literal({ ..._.omit(tlObj, 'content'), - ...literal>({ + ...literal< + Partial & Pick + >({ id: '', layer: AtemLLayer.AtemAuxVideoMixMinus, priority: tlObj.classes?.includes('MIX_MINUS_OVERRIDE_DSK') ? 10 : tlObj.priority, @@ -165,7 +167,7 @@ export function postProcessPieceTimelineObjects( const cleanObj = literal({ ..._.omit(tlObj, 'content'), - ...literal>({ + ...literal & Pick>({ id: '', layer: AtemLLayer.AtemCleanUSKEffect, content: { diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts index 8761817ba..6e60f6bc0 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts @@ -38,7 +38,7 @@ export function OfftubeEvaluateCueBackgroundLoop( fileName, path, ignoreMediaObjectStatus: true, - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { start: 0 }, @@ -70,7 +70,7 @@ export function OfftubeEvaluateCueBackgroundLoop( fileName, path, ignoreMediaObjectStatus: true, - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { start: 0 }, diff --git a/src/tv2_offtube_showstyle/getSegment.ts b/src/tv2_offtube_showstyle/getSegment.ts index ab0c20319..edc27e656 100644 --- a/src/tv2_offtube_showstyle/getSegment.ts +++ b/src/tv2_offtube_showstyle/getSegment.ts @@ -70,7 +70,7 @@ function CreatePartContinuity(config: OfftubeShowstyleBlueprintConfig, ingestSeg content: literal>({ studioLabel: '', switcherInput: config.studio.AtemSource.Continuity, - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { From 4fa6c9cabe3e1abb4c6ed41cd39e8b3bf1214838 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Fri, 22 Apr 2022 10:45:54 +0200 Subject: [PATCH 083/184] SOF-830 Fix compilation error --- src/tv2_offtube_showstyle/getRundown.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 903f2f1fa..4ca495ec4 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -196,7 +196,7 @@ function getGlobalAdLibPiecesOfftube( tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIBS_RESYNC_SISYFOS], expectedDuration: 1000, content: { - timelineObjects: _.compact([ + timelineObjects: _.compact([ literal({ id: '', enable: { start: 0 }, From 16f6ebf654f7f13fe0aa1fd1c54e8a5bc32d3e8f Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 26 Apr 2022 14:09:10 +0200 Subject: [PATCH 084/184] refactor: SOF-752 make tests pass also removeTSR-types dependency - these types should come from blueprints-integration; bump blueprints-integration --- package.json | 3 +- src/tv2-common/actions/executeAction.ts | 8 +-- src/tv2-common/content/dve.ts | 4 +- .../helpers/graphics/caspar/index.ts | 4 +- .../helpers/graphics/caspar/slotMappings.ts | 18 +++---- .../helpers/graphics/design/index.ts | 6 +-- src/tv2-common/helpers/graphics/index.ts | 30 +++++------ .../helpers/graphics/internal/index.ts | 51 +----------------- src/tv2-common/helpers/graphics/layers.ts | 36 ++++++------- src/tv2-common/helpers/graphics/viz/index.ts | 8 +-- src/tv2-constants/enums.ts | 7 +-- .../__tests__/baseline.spec.ts | 4 +- src/tv2_afvd_showstyle/getRundown.ts | 19 ++++--- src/tv2_afvd_showstyle/getSegment.ts | 3 +- .../pieces/__tests__/grafikViz.spec.ts | 24 ++++----- .../helpers/pieces/__tests__/telefon.spec.ts | 4 +- .../helpers/pieces/clearGrafiks.ts | 4 +- .../helpers/pieces/graphicBackgroundLoop.ts | 4 +- .../helpers/pieces/showLifecycle.ts | 53 +++++++++++++++++++ src/tv2_afvd_showstyle/layers.ts | 1 + src/tv2_afvd_showstyle/migrations/index.ts | 4 +- .../__tests__/graphics.spec.ts | 12 ++--- src/tv2_afvd_studio/getBaseline.ts | 9 ++-- src/tv2_afvd_studio/layers.ts | 21 +++++++- src/tv2_afvd_studio/migrations/index.ts | 4 +- .../migrations/mappings-defaults.ts | 11 ++-- src/tv2_offtube_showstyle/migrations/index.ts | 26 ++++----- .../onTimelineGenerate.ts | 4 +- src/tv2_offtube_studio/layers.ts | 16 +++++- src/tv2_offtube_studio/migrations/index.ts | 18 +++---- .../migrations/mappings-defaults.ts | 38 +++++++------ yarn.lock | 29 ++++------ 32 files changed, 256 insertions(+), 227 deletions(-) create mode 100644 src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts diff --git a/package.json b/package.json index 3e4292064..abe2465d5 100644 --- a/package.json +++ b/package.json @@ -59,8 +59,7 @@ "webpack-cli": "^3.1.2" }, "dependencies": { - "@tv2media/blueprints-integration": "v1.37.1-in-testing.1", - "@tv2media/timeline-state-resolver-types": "^1.0.0-release37.6", + "@tv2media/blueprints-integration": "v1.37.1-1", "underscore": "^1.12.1" } } \ No newline at end of file diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 24c4982e5..50b5bbefa 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -64,7 +64,7 @@ import { import { AdlibActionType, CueType, - GraphicLLayer, + SharedGraphicLLayer, SharedOutputLayers, SharedSourceLayers, TallyTags @@ -1433,7 +1433,7 @@ function applyPrerollToWallGraphics< } const timelineObjectsToUpdate = newPieceProps.content.timelineObjects.filter( timelineObject => - timelineObject.layer === GraphicLLayer.GraphicLLayerWall && + timelineObject.layer === SharedGraphicLLayer.GraphicLLayerWall && (timelineObject.content.deviceType === TSR.DeviceType.VIZMSE || timelineObject.content.deviceType === TSR.DeviceType.CASPARCG) ) @@ -2007,7 +2007,7 @@ function executeActionClearGraphics< start: 0 }, priority: 1, - layer: GraphicLLayer.GraphicLLayerAdLibs, + layer: SharedGraphicLLayer.GraphicLLayerAdLibs, content: { deviceType: TSR.DeviceType.ABSTRACT } @@ -2022,7 +2022,7 @@ function executeActionClearGraphics< start: 0 }, priority: 100, - layer: GraphicLLayer.GraphicLLayerAdLibs, + layer: SharedGraphicLLayer.GraphicLLayerAdLibs, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 3f7012594..ba94a1a91 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -30,7 +30,7 @@ import { TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' -import { ControlClasses, GraphicLLayer, MEDIA_PLAYER_AUTO } from 'tv2-constants' +import { ControlClasses, MEDIA_PLAYER_AUTO, SharedGraphicLLayer } from 'tv2-constants' import * as _ from 'underscore' import { AtemSourceIndex } from '../../types/atem' import { ActionSelectDVE } from '../actions' @@ -562,7 +562,7 @@ export function MakeContentDVE2< id: '', enable: getDVEEnable(), priority: 1, - layer: GraphicLLayer.GraphicLLayerLocators, + layer: SharedGraphicLLayer.GraphicLLayerLocators, content: CreateHTMLRendererContent(config, 'locators', { ...graphicsTemplateContent, style: graphicsTemplateStyle ?? {} diff --git a/src/tv2-common/helpers/graphics/caspar/index.ts b/src/tv2-common/helpers/graphics/caspar/index.ts index 661cc79a0..79632fb00 100644 --- a/src/tv2-common/helpers/graphics/caspar/index.ts +++ b/src/tv2-common/helpers/graphics/caspar/index.ts @@ -19,7 +19,7 @@ import { TimelineBlueprintExt, TV2BlueprintConfig } from 'tv2-common' -import { GraphicEngine, GraphicLLayer } from 'tv2-constants' +import { GraphicEngine, SharedGraphicLLayer } from 'tv2-constants' import { GetEnableForGraphic, GetTimelineLayerForGraphic } from '..' import { EnableDSK } from '../../dsk' import { IsTargetingFull, IsTargetingWall } from '../target' @@ -96,7 +96,7 @@ export function GetPilotGraphicContentCaspar( while: '1' }, priority: 100, - layer: IsTargetingWall(engine) ? GraphicLLayer.GraphicLLayerWall : GraphicLLayer.GraphicLLayerPilot, + layer: IsTargetingWall(engine) ? SharedGraphicLLayer.GraphicLLayerWall : SharedGraphicLLayer.GraphicLLayerPilot, metaData: { templateData, fileName }, content: { deviceType: TSR.DeviceType.CASPARCG, diff --git a/src/tv2-common/helpers/graphics/caspar/slotMappings.ts b/src/tv2-common/helpers/graphics/caspar/slotMappings.ts index 71798f046..4eeb8c0c9 100644 --- a/src/tv2-common/helpers/graphics/caspar/slotMappings.ts +++ b/src/tv2-common/helpers/graphics/caspar/slotMappings.ts @@ -3,17 +3,17 @@ * This will go to the graphics package and become a dependency of the blueprints. */ -import { GraphicLLayer } from 'tv2-constants' +import { SharedGraphicLLayer } from 'tv2-constants' export const layerToHTMLGraphicSlot: { [slot: string]: string } = { - [GraphicLLayer.GraphicLLayerOverlay]: '', - [GraphicLLayer.GraphicLLayerOverlayIdent]: '650_ident', - [GraphicLLayer.GraphicLLayerOverlayLower]: '450_lowerThird', - [GraphicLLayer.GraphicLLayerOverlayTema]: '', - [GraphicLLayer.GraphicLLayerOverlayTopt]: '660_topt', - [GraphicLLayer.GraphicLLayerPilot]: '250_full', - [GraphicLLayer.GraphicLLayerPilotOverlay]: '250_full', - [GraphicLLayer.GraphicLLayerLocators]: '850_dve' + [SharedGraphicLLayer.GraphicLLayerOverlay]: '', + [SharedGraphicLLayer.GraphicLLayerOverlayIdent]: '650_ident', + [SharedGraphicLLayer.GraphicLLayerOverlayLower]: '450_lowerThird', + [SharedGraphicLLayer.GraphicLLayerOverlayTema]: '', + [SharedGraphicLLayer.GraphicLLayerOverlayTopt]: '660_topt', + [SharedGraphicLLayer.GraphicLLayerPilot]: '250_full', + [SharedGraphicLLayer.GraphicLLayerPilotOverlay]: '250_full', + [SharedGraphicLLayer.GraphicLLayerLocators]: '850_dve' } export interface Slots { diff --git a/src/tv2-common/helpers/graphics/design/index.ts b/src/tv2-common/helpers/graphics/design/index.ts index 59c4aeba2..fd2adf6a8 100644 --- a/src/tv2-common/helpers/graphics/design/index.ts +++ b/src/tv2-common/helpers/graphics/design/index.ts @@ -9,7 +9,7 @@ import { WithTimeline } from '@tv2media/blueprints-integration' import { CalculateTime, CueDefinitionGraphicDesign, literal, TV2BlueprintConfig } from 'tv2-common' -import { GraphicLLayer, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' +import { SharedGraphicLLayer, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' export function EvaluateDesignBase( config: TV2BlueprintConfig, @@ -77,7 +77,7 @@ function designTimeline(config: TV2BlueprintConfig, parsedCue: CueDefinitionGrap start: 0 }, priority: 1, - layer: GraphicLLayer.GraphicLLayerDesign, + layer: SharedGraphicLLayer.GraphicLLayerDesign, content: { deviceType: TSR.DeviceType.CASPARCG, type: TSR.TimelineContentTypeCasparCg.TEMPLATE, @@ -98,7 +98,7 @@ function designTimeline(config: TV2BlueprintConfig, parsedCue: CueDefinitionGrap id: '', enable: { start: 0 }, priority: 100, - layer: GraphicLLayer.GraphicLLayerDesign, + layer: SharedGraphicLLayer.GraphicLLayerDesign, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, diff --git a/src/tv2-common/helpers/graphics/index.ts b/src/tv2-common/helpers/graphics/index.ts index 21b9eb1a9..581c3cf0e 100644 --- a/src/tv2-common/helpers/graphics/index.ts +++ b/src/tv2-common/helpers/graphics/index.ts @@ -1,6 +1,6 @@ import { IBlueprintPart, TSR } from '@tv2media/blueprints-integration' import { layerToHTMLGraphicSlot, literal, TV2BlueprintConfig } from 'tv2-common' -import { GraphicEngine, GraphicLLayer } from 'tv2-constants' +import { GraphicEngine, SharedGraphicLLayer } from 'tv2-constants' export * from './name' export * from './timing' @@ -29,11 +29,11 @@ export function CreateGraphicBaseline(config: TV2BlueprintConfig): TSR.TSRTimeli } else { const slotBaselineObjects: TSR.TSRTimelineObj[] = [] ;[ - GraphicLLayer.GraphicLLayerOverlayIdent, - GraphicLLayer.GraphicLLayerOverlayLower, - GraphicLLayer.GraphicLLayerOverlayTema, - GraphicLLayer.GraphicLLayerOverlayTopt, - GraphicLLayer.GraphicLLayerLocators + SharedGraphicLLayer.GraphicLLayerOverlayIdent, + SharedGraphicLLayer.GraphicLLayerOverlayLower, + SharedGraphicLLayer.GraphicLLayerOverlayTema, + SharedGraphicLLayer.GraphicLLayerOverlayTopt, + SharedGraphicLLayer.GraphicLLayerLocators ].forEach(layer => { if (layerToHTMLGraphicSlot[layer]) { slotBaselineObjects.push( @@ -74,7 +74,7 @@ export function CreateGraphicBaseline(config: TV2BlueprintConfig): TSR.TSRTimeli while: '1' }, priority: 0, - layer: GraphicLLayer.GraphicLLayerOverlay, + layer: SharedGraphicLLayer.GraphicLLayerOverlay, content: { deviceType: TSR.DeviceType.CASPARCG, type: TSR.TimelineContentTypeCasparCg.TEMPLATE, @@ -83,11 +83,11 @@ export function CreateGraphicBaseline(config: TV2BlueprintConfig): TSR.TSRTimeli data: { display: 'program', slots: [ - GraphicLLayer.GraphicLLayerOverlayIdent, - GraphicLLayer.GraphicLLayerOverlayLower, - GraphicLLayer.GraphicLLayerOverlayTema, - GraphicLLayer.GraphicLLayerOverlayTopt, - GraphicLLayer.GraphicLLayerLocators + SharedGraphicLLayer.GraphicLLayerOverlayIdent, + SharedGraphicLLayer.GraphicLLayerOverlayLower, + SharedGraphicLLayer.GraphicLLayerOverlayTema, + SharedGraphicLLayer.GraphicLLayerOverlayTopt, + SharedGraphicLLayer.GraphicLLayerLocators ].reduce((obj: Record, layer) => { if (layerToHTMLGraphicSlot[layer]) { obj[layerToHTMLGraphicSlot[layer]] = { @@ -108,7 +108,7 @@ export function CreateGraphicBaseline(config: TV2BlueprintConfig): TSR.TSRTimeli while: '1' }, priority: 0, - layer: GraphicLLayer.GraphicLLayerDesign, + layer: SharedGraphicLLayer.GraphicLLayerDesign, content: { deviceType: TSR.DeviceType.CASPARCG, type: TSR.TimelineContentTypeCasparCg.TEMPLATE, @@ -128,7 +128,7 @@ export function CreateGraphicBaseline(config: TV2BlueprintConfig): TSR.TSRTimeli while: '1' }, priority: 0, - layer: GraphicLLayer.GraphicLLayerPilot, + layer: SharedGraphicLLayer.GraphicLLayerPilot, content: { deviceType: TSR.DeviceType.CASPARCG, type: TSR.TimelineContentTypeCasparCg.TEMPLATE, @@ -137,7 +137,7 @@ export function CreateGraphicBaseline(config: TV2BlueprintConfig): TSR.TSRTimeli data: { display: 'program', slots: { - [layerToHTMLGraphicSlot[GraphicLLayer.GraphicLLayerPilot]]: { + [layerToHTMLGraphicSlot[SharedGraphicLLayer.GraphicLLayerPilot]]: { payload: {}, display: 'hidden' } diff --git a/src/tv2-common/helpers/graphics/internal/index.ts b/src/tv2-common/helpers/graphics/internal/index.ts index 6b23ef098..b49967874 100644 --- a/src/tv2-common/helpers/graphics/internal/index.ts +++ b/src/tv2-common/helpers/graphics/internal/index.ts @@ -1,5 +1,4 @@ import { - BlueprintResultPart, IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPart, @@ -17,7 +16,7 @@ import { PartDefinition, TV2BlueprintConfig } from 'tv2-common' -import { AbstractLLayer, AdlibTags, GraphicLLayer, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' +import { AbstractLLayer, AdlibTags, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' import _ = require('underscore') import { CreateTimingGraphic, @@ -174,51 +173,3 @@ export function CreateInternalGraphic( } } } - -export function CreateShowLifecyclePieces( - config: TV2BlueprintConfig, - part: BlueprintResultPart, - initializeShowIds: string[], - cleanupShowIds: string[] -) { - if (config.studio.GraphicsType === 'VIZ') { - part.pieces.push( - literal({ - externalId: part.part.externalId, - name: 'GFX Show Init', - enable: { start: 0 }, - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: SharedSourceLayers.GraphicsShowLifecycle, - lifespan: PieceLifespan.OutOnSegmentChange, - content: { - timelineObjects: [ - literal({ - id: '', - enable: { - while: '1' - }, - layer: GraphicLLayer.GraphicLLayerInitialize, - content: { - deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.INITIALIZE_SHOWS, - showIds: initializeShowIds - } - }), - literal({ - id: '', - enable: { - while: '1' - }, - layer: GraphicLLayer.GraphicLLayerCleanup, - content: { - deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.CLEANUP_SHOWS, - showIds: cleanupShowIds - } - }) - ] - } - }) - ) - } -} diff --git a/src/tv2-common/helpers/graphics/layers.ts b/src/tv2-common/helpers/graphics/layers.ts index 308cfaf59..cb9b4967d 100644 --- a/src/tv2-common/helpers/graphics/layers.ts +++ b/src/tv2-common/helpers/graphics/layers.ts @@ -1,5 +1,5 @@ import { TV2BlueprintConfig } from 'tv2-common' -import { GraphicLLayer, SharedSourceLayers } from 'tv2-constants' +import { SharedGraphicLLayer, SharedSourceLayers } from 'tv2-constants' export function GetSourceLayerForGraphic(config: TV2BlueprintConfig, name: string, isStickyIdent?: boolean) { const conf = config.showStyle.GFXTemplates @@ -47,29 +47,29 @@ export function GetTimelineLayerForGraphic(config: TV2BlueprintConfig, name: str : undefined if (!conf) { - return GraphicLLayer.GraphicLLayerOverlay + return SharedGraphicLLayer.GraphicLLayerOverlay } switch (conf.LayerMapping) { // TODO: When adding more output layers - case GraphicLLayer.GraphicLLayerOverlayIdent: - return GraphicLLayer.GraphicLLayerOverlayIdent - case GraphicLLayer.GraphicLLayerOverlayTopt: - return GraphicLLayer.GraphicLLayerOverlayTopt - case GraphicLLayer.GraphicLLayerOverlayLower: - return GraphicLLayer.GraphicLLayerOverlayLower - case GraphicLLayer.GraphicLLayerOverlayHeadline: + case SharedGraphicLLayer.GraphicLLayerOverlayIdent: + return SharedGraphicLLayer.GraphicLLayerOverlayIdent + case SharedGraphicLLayer.GraphicLLayerOverlayTopt: + return SharedGraphicLLayer.GraphicLLayerOverlayTopt + case SharedGraphicLLayer.GraphicLLayerOverlayLower: + return SharedGraphicLLayer.GraphicLLayerOverlayLower + case SharedGraphicLLayer.GraphicLLayerOverlayHeadline: if (config.studio.GraphicsType === 'HTML') { - return GraphicLLayer.GraphicLLayerOverlayLower + return SharedGraphicLLayer.GraphicLLayerOverlayLower } - return GraphicLLayer.GraphicLLayerOverlayHeadline - case GraphicLLayer.GraphicLLayerOverlayTema: - return GraphicLLayer.GraphicLLayerOverlayTema - case GraphicLLayer.GraphicLLayerWall: - return GraphicLLayer.GraphicLLayerWall - case GraphicLLayer.GraphicLLayerLocators: - return GraphicLLayer.GraphicLLayerLocators + return SharedGraphicLLayer.GraphicLLayerOverlayHeadline + case SharedGraphicLLayer.GraphicLLayerOverlayTema: + return SharedGraphicLLayer.GraphicLLayerOverlayTema + case SharedGraphicLLayer.GraphicLLayerWall: + return SharedGraphicLLayer.GraphicLLayerWall + case SharedGraphicLLayer.GraphicLLayerLocators: + return SharedGraphicLLayer.GraphicLLayerLocators default: - return GraphicLLayer.GraphicLLayerOverlay + return SharedGraphicLLayer.GraphicLLayerOverlay } } diff --git a/src/tv2-common/helpers/graphics/viz/index.ts b/src/tv2-common/helpers/graphics/viz/index.ts index a73bb00da..ce24ec7e7 100644 --- a/src/tv2-common/helpers/graphics/viz/index.ts +++ b/src/tv2-common/helpers/graphics/viz/index.ts @@ -21,7 +21,7 @@ import { PartDefinition, TV2BlueprintConfig } from 'tv2-common' -import { GraphicEngine, GraphicLLayer } from 'tv2-constants' +import { GraphicEngine, SharedGraphicLLayer } from 'tv2-constants' import { EnableDSK } from '../../dsk' export interface VizPilotGeneratorSettings { @@ -90,10 +90,10 @@ export function GetPilotGraphicContentViz( }, priority: 1, layer: IsTargetingWall(engine) - ? GraphicLLayer.GraphicLLayerWall + ? SharedGraphicLLayer.GraphicLLayerWall : IsTargetingOVL(engine) - ? GraphicLLayer.GraphicLLayerPilotOverlay - : GraphicLLayer.GraphicLLayerPilot, + ? SharedGraphicLLayer.GraphicLLayerPilotOverlay + : SharedGraphicLLayer.GraphicLLayerPilot, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT, diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index b55a31f43..4d6b1b69a 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -157,7 +157,7 @@ export enum TallyTags { JINGLE_IS_LIVE = 'JINGLE_IS_LIVE' } -export enum GraphicLLayer { +export enum SharedGraphicLLayer { GraphicLLayerOverlay = 'graphic_overlay', // <= viz_layer_overlay GraphicLLayerOverlayIdent = 'graphic_overlay_ident', // <= viz_layer_overlay_ident GraphicLLayerOverlayTopt = 'graphic_overlay_topt', // <= viz_layer_overlay_topt @@ -171,9 +171,7 @@ export enum GraphicLLayer { GraphicLLayerAdLibs = 'graphic_adlibs', // <= viz_layer_adlibs GraphicLLayerWall = 'graphic_wall', // <= viz_layer_wall GraphicLLayerLocators = 'graphic_locators', - GraphicLLayerConcept = 'graphic_concept', - GraphicLLayerInitialize = 'graphic_initialize', - GraphicLLayerCleanup = 'graphic_cleanup' + GraphicLLayerConcept = 'graphic_concept' } export enum AbstractLLayer { @@ -249,7 +247,6 @@ export enum SharedSourceLayers { // Other / sec / manus PgmScript = 'studio0_script', PgmAudioBed = 'studio0_audio_bed', - GraphicsShowLifecycle = 'studio0_graphic_show_lifecycle', // AUX AuxMixMinus = 'studio0_aux_mix_minus' diff --git a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts index cecc3ae5f..8587ab742 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_TSR = 'test' // @ts-ignore global.VERSION_INTEGRATION = 'test' -import { GraphicLLayer } from '../../tv2-constants' +import { SharedGraphicLLayer } from '../../tv2-constants' import { parseConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' import { parseConfig as parseShowStyleConfig } from '../helpers/config' @@ -50,7 +50,7 @@ describe('Baseline', () => { const result = rundown.baseline.timelineObjects.filter( timelineObject => - timelineObject.layer === GraphicLLayer.GraphicLLayerConcept && + timelineObject.layer === SharedGraphicLLayer.GraphicLLayerConcept && timelineObject.content.deviceType === TSR.DeviceType.VIZMSE ) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 44d223c3d..eb16514d9 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -16,7 +16,6 @@ import { TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { TimelineContentTypeVizMSE, TimelineObjVIZMSEConcept } from '@tv2media/timeline-state-resolver-types' import { ActionClearGraphics, ActionCutSourceToBox, @@ -45,7 +44,7 @@ import { AdlibTagCutToBox, AdlibTags, CONSTANTS, - GraphicLLayer, + SharedGraphicLLayer, SharedOutputLayers, TallyTags } from 'tv2-constants' @@ -399,7 +398,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint duration: 1000 }, priority: 100, - layer: GraphicLLayer.GraphicLLayerAdLibs, + layer: SharedGraphicLLayer.GraphicLLayerAdLibs, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.LOAD_ALL_ELEMENTS @@ -427,12 +426,12 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint duration: 1000 }, priority: 100, - layer: GraphicLLayer.GraphicLLayerAdLibs, + layer: SharedGraphicLLayer.GraphicLLayerAdLibs, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CONTINUE, direction: 1, - reference: GraphicLLayer.GraphicLLayerPilot + reference: SharedGraphicLLayer.GraphicLLayerPilot } }) ]) @@ -550,7 +549,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint id: '', enable: { start: 0 }, priority: 110, - layer: GraphicLLayer.GraphicLLayerDesign, + layer: SharedGraphicLLayer.GraphicLLayerDesign, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, @@ -1142,7 +1141,7 @@ function getBaseline(config: BlueprintConfig): BlueprintResultBaseline { id: '', enable: { start: 0 }, priority: 2, // Take priority over anything trying to set the template on the Viz version of this layer - layer: GraphicLLayer.GraphicLLayerFullLoop, + layer: SharedGraphicLLayer.GraphicLLayerFullLoop, content: { deviceType: TSR.DeviceType.CASPARCG, type: TSR.TimelineContentTypeCasparCg.ROUTE, @@ -1203,13 +1202,13 @@ function getBaseline(config: BlueprintConfig): BlueprintResultBaseline { }) : []), - literal({ + literal({ id: '', enable: { while: '1' }, - layer: GraphicLLayer.GraphicLLayerConcept, + layer: SharedGraphicLLayer.GraphicLLayerConcept, content: { deviceType: TSR.DeviceType.VIZMSE, - type: TimelineContentTypeVizMSE.CONCEPT, + type: TSR.TimelineContentTypeVizMSE.CONCEPT, concept: config.selectedGraphicsSetup.Concept } }) diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index edd74ac39..2f0c366a3 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -9,12 +9,13 @@ import { TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { CreateShowLifecyclePieces, getSegmentBase, INewsPayload, literal } from 'tv2-common' +import { 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 { CreateShowLifecyclePieces } from './helpers/pieces/showLifecycle' import { SourceLayer } from './layers' import { CreatePartEVS } from './parts/evs' import { CreatePartGrafik } from './parts/grafik' 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 8ce74b61f..ba9bafaa4 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -16,7 +16,7 @@ import { literal, PartDefinitionKam } from 'tv2-common' -import { AbstractLLayer, AdlibTags, CueType, GraphicLLayer, PartType, SharedOutputLayers } from 'tv2-constants' +import { AbstractLLayer, AdlibTags, CueType, PartType, SharedGraphicLLayer, SharedOutputLayers } 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' @@ -138,7 +138,7 @@ describe('grafik piece', () => { while: '!.full' }, priority: 1, - layer: GraphicLLayer.GraphicLLayerOverlayLower, + layer: SharedGraphicLLayer.GraphicLLayerOverlayLower, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, @@ -209,7 +209,7 @@ describe('grafik piece', () => { while: '!.full' }, priority: 1, - layer: GraphicLLayer.GraphicLLayerOverlayLower, + layer: SharedGraphicLLayer.GraphicLLayerOverlayLower, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, @@ -244,7 +244,7 @@ describe('grafik piece', () => { while: '!.full' }, priority: 1, - layer: GraphicLLayer.GraphicLLayerOverlayLower, + layer: SharedGraphicLLayer.GraphicLLayerOverlayLower, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, @@ -317,7 +317,7 @@ describe('grafik piece', () => { start: 0 }, priority: 1, - layer: GraphicLLayer.GraphicLLayerOverlayLower, + layer: SharedGraphicLLayer.GraphicLLayerOverlayLower, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, @@ -352,7 +352,7 @@ describe('grafik piece', () => { start: 0 }, priority: 1, - layer: GraphicLLayer.GraphicLLayerOverlayLower, + layer: SharedGraphicLLayer.GraphicLLayerOverlayLower, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, @@ -424,7 +424,7 @@ describe('grafik piece', () => { while: '!.full' }, priority: 1, - layer: GraphicLLayer.GraphicLLayerOverlayLower, + layer: SharedGraphicLLayer.GraphicLLayerOverlayLower, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, @@ -498,7 +498,7 @@ describe('grafik piece', () => { while: `.studio0_parent_camera_1 & !.adlib_deparent & !.full` }, priority: 1, - layer: GraphicLLayer.GraphicLLayerOverlayLower, + layer: SharedGraphicLLayer.GraphicLLayerOverlayLower, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, @@ -569,7 +569,7 @@ describe('grafik piece', () => { while: `.studio0_parent_camera_1 & !.adlib_deparent & !.full` }, priority: 1, - layer: GraphicLLayer.GraphicLLayerOverlayIdent, + layer: SharedGraphicLLayer.GraphicLLayerOverlayIdent, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, @@ -665,7 +665,7 @@ describe('grafik piece', () => { while: `!.full` }, priority: 1, - layer: GraphicLLayer.GraphicLLayerOverlayIdent, + layer: SharedGraphicLLayer.GraphicLLayerOverlayIdent, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, @@ -736,7 +736,7 @@ describe('grafik piece', () => { while: `!.full` }, priority: 1, - layer: GraphicLLayer.GraphicLLayerOverlayTopt, + layer: SharedGraphicLLayer.GraphicLLayerOverlayTopt, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, @@ -771,7 +771,7 @@ describe('grafik piece', () => { while: `!.full` }, priority: 1, - layer: GraphicLLayer.GraphicLLayerOverlayTopt, + layer: SharedGraphicLLayer.GraphicLLayerOverlayTopt, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, 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 2519a3edc..d59b97ca9 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -16,7 +16,7 @@ import { literal, PartDefinitionKam } from 'tv2-common' -import { CueType, GraphicLLayer, PartType, SharedOutputLayers } from 'tv2-constants' +import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayers } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' import { DEFAULT_GRAPHICS_SETUP, @@ -125,7 +125,7 @@ describe('telefon', () => { while: '!.full' }, priority: 1, - layer: GraphicLLayer.GraphicLLayerOverlayLower, + layer: SharedGraphicLLayer.GraphicLLayerOverlayLower, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts index 3dae45760..d7cbb0d48 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts @@ -6,7 +6,7 @@ import { TSR } from '@tv2media/blueprints-integration' import { CreateTimingEnable, CueDefinitionClearGrafiks, GetDefaultOut, literal } from 'tv2-common' -import { GraphicLLayer, SharedOutputLayers } from 'tv2-constants' +import { SharedGraphicLLayer, SharedOutputLayers } from 'tv2-constants' import { BlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { SourceLayer } from '../../../tv2_afvd_showstyle/layers' @@ -68,7 +68,7 @@ export function EvaluateClearGrafiks( duration: 1000 }, priority: 100, - layer: GraphicLLayer.GraphicLLayerAdLibs, + layer: SharedGraphicLLayer.GraphicLLayerAdLibs, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts index 50dff440c..944e0626e 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 '@tv2media/blueprints-integration' import { CalculateTime, CueDefinitionBackgroundLoop, literal, TV2BlueprintConfig } from 'tv2-common' -import { GraphicLLayer, SharedOutputLayers } from 'tv2-constants' +import { SharedGraphicLLayer, SharedOutputLayers } from 'tv2-constants' import { CasparLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' @@ -129,7 +129,7 @@ function fullLoopTimeline(config: TV2BlueprintConfig, parsedCue: CueDefinitionBa id: '', enable: { start: 0 }, priority: 1, - layer: GraphicLLayer.GraphicLLayerFullLoop, + layer: SharedGraphicLLayer.GraphicLLayerFullLoop, content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts b/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts new file mode 100644 index 000000000..c5f647e2e --- /dev/null +++ b/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts @@ -0,0 +1,53 @@ +import { BlueprintResultPart, IBlueprintPiece, PieceLifespan, TSR } from '@tv2media/blueprints-integration' +import { literal, TV2BlueprintConfig } from 'tv2-common' +import { SharedOutputLayers } from 'tv2-constants' +import { GraphicLLayer } from '../../../tv2_afvd_studio/layers' +import { SourceLayer } from '../../layers' + +export function CreateShowLifecyclePieces( + config: TV2BlueprintConfig, + part: BlueprintResultPart, + initializeShowIds: string[], + cleanupShowIds: string[] +) { + if (config.studio.GraphicsType === 'VIZ') { + part.pieces.push( + literal({ + externalId: part.part.externalId, + name: 'GFX Show Init', + enable: { start: 0 }, + outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SourceLayer.GraphicsShowLifecycle, + lifespan: PieceLifespan.OutOnSegmentChange, + content: { + timelineObjects: [ + literal({ + id: '', + enable: { + while: '1' + }, + layer: GraphicLLayer.GraphicLLayerInitialize, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.INITIALIZE_SHOWS, + showIds: initializeShowIds + } + }), + literal({ + id: '', + enable: { + while: '1' + }, + layer: GraphicLLayer.GraphicLLayerCleanup, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.CLEANUP_SHOWS, + showIds: cleanupShowIds + } + }) + ] + } + }) + ) + } +} diff --git a/src/tv2_afvd_showstyle/layers.ts b/src/tv2_afvd_showstyle/layers.ts index 904163b23..2af817cd4 100644 --- a/src/tv2_afvd_showstyle/layers.ts +++ b/src/tv2_afvd_showstyle/layers.ts @@ -8,6 +8,7 @@ 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' diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 78a309df9..3c6b6ca17 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -12,7 +12,7 @@ import { StripFolderFromDVEConfig, UpsertValuesIntoTransitionTable } from 'tv2-common' -import { GraphicLLayer } from 'tv2-constants' +import { SharedGraphicLLayer } from 'tv2-constants' import * as _ from 'underscore' import { remapVizDOvl, remapVizLLayer } from '../../tv2_offtube_showstyle/migrations' import { remapTableColumnValues } from '../../tv2_offtube_showstyle/migrations/util' @@ -82,7 +82,7 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal { t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT )! as TSR.TimelineObjVIZMSEElementPilot expect(vizObj.enable).toEqual({ start: 0 }) - expect(vizObj.layer).toEqual(GraphicLLayer.GraphicLLayerPilot) + expect(vizObj.layer).toEqual(SharedGraphicLLayer.GraphicLLayerPilot) expect(vizObj.content.channelName).toBe('FULL1') // TODO: FULL1: Enum / Type expect(vizObj.content.templateVcpId).toBe(1234567890) expect(vizObj.content.continueStep).toBe(-1) @@ -227,7 +227,7 @@ describe('Graphics', () => { t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT )! as TSR.TimelineObjVIZMSEElementPilot expect(vizObj.enable).toEqual({ while: '!.full' }) - expect(vizObj.layer).toEqual(GraphicLLayer.GraphicLLayerPilotOverlay) + expect(vizObj.layer).toEqual(SharedGraphicLLayer.GraphicLLayerPilotOverlay) expect(vizObj.content.channelName).toBe('OVL1') // TODO: OVL1: Enum / Type expect(vizObj.content.templateVcpId).toBe(1234567890) expect(vizObj.content.continueStep).toBe(-1) @@ -285,7 +285,7 @@ describe('Graphics', () => { t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT )! as TSR.TimelineObjVIZMSEElementPilot expect(vizObj.enable).toEqual({ while: '1' }) - expect(vizObj.layer).toEqual(GraphicLLayer.GraphicLLayerWall) + expect(vizObj.layer).toEqual(SharedGraphicLLayer.GraphicLLayerWall) expect(vizObj.content.channelName).toBe('WALL1') // TODO: OVL1: Enum / Type expect(vizObj.content.templateVcpId).toBe(1234567890) expect(vizObj.content.continueStep).toBe(-1) @@ -340,7 +340,7 @@ describe('Graphics', () => { t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT )! as TSR.TimelineObjVIZMSEElementPilot expect(vizObj.enable).toEqual({ start: 0 }) - expect(vizObj.layer).toEqual(GraphicLLayer.GraphicLLayerPilot) + expect(vizObj.layer).toEqual(SharedGraphicLLayer.GraphicLLayerPilot) expect(vizObj.content.channelName).toBe('FULL1') // TODO: FULL1: Enum / Type expect(vizObj.content.templateVcpId).toBe(1234567890) expect(vizObj.content.continueStep).toBe(-1) @@ -531,7 +531,7 @@ describe('Graphics', () => { obj.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_INTERNAL ) as TSR.TimelineObjVIZMSEElementInternal | undefined expect(tlObj).toBeTruthy() - expect(tlObj?.layer).toBe(GraphicLLayer.GraphicLLayerOverlayLower) + expect(tlObj?.layer).toBe(SharedGraphicLLayer.GraphicLLayerOverlayLower) expect(tlObj?.content.templateName).toBe('bund') expect(tlObj?.content.templateData).toStrictEqual(['Some Person', 'Some Info']) expect(tlObj?.content.channelName).toBe('OVL1') diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index 867c56a48..97604eb98 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -5,10 +5,9 @@ import { IStudioContext, TSR } from '@tv2media/blueprints-integration' -import { TimelineContentTypeVizMSE, TimelineObjVIZMSEConcept } from '@tv2media/timeline-state-resolver-types' import { literal } from 'tv2-common' import * as _ from 'underscore' -import { GraphicLLayer } from '../tv2-constants' +import { SharedGraphicLLayer } from '../tv2-constants' import { AtemSourceIndex } from '../types/atem' import { getStudioConfig } from './helpers/config' import { AtemLLayer, SisyfosLLAyer } from './layers' @@ -160,13 +159,13 @@ export function getBaseline(context: IStudioContext): BlueprintResultBaseline { } } }), - literal({ + literal({ id: '', enable: { while: '1' }, - layer: GraphicLLayer.GraphicLLayerConcept, + layer: SharedGraphicLLayer.GraphicLLayerConcept, content: { deviceType: TSR.DeviceType.VIZMSE, - type: TimelineContentTypeVizMSE.CONCEPT, + type: TSR.TimelineContentTypeVizMSE.CONCEPT, concept: '' } }) diff --git a/src/tv2_afvd_studio/layers.ts b/src/tv2_afvd_studio/layers.ts index 0d1b00a31..e13eb34ff 100644 --- a/src/tv2_afvd_studio/layers.ts +++ b/src/tv2_afvd_studio/layers.ts @@ -1,4 +1,10 @@ -import { AbstractLLayer, GraphicLLayer, SharedATEMLLayer, SharedCasparLLayer, SharedSisyfosLLayer } from 'tv2-constants' +import { + AbstractLLayer, + SharedATEMLLayer, + SharedCasparLLayer, + SharedGraphicLLayer, + SharedSisyfosLLayer +} from 'tv2-constants' import * as _ from 'underscore' export type LLayer = VirtualAbstractLLayer | AtemLLayer | CasparLLayer | SisyfosLLAyer @@ -70,6 +76,19 @@ export const CasparLLayer = { export type CasparLLayer = AFVDCasparLLayer | SharedCasparLLayer +enum AFVDGraphicLLayer { + GraphicLLayerInitialize = 'graphic_initialize', + GraphicLLayerCleanup = 'graphic_cleanup' +} + +// tslint:disable-next-line: variable-name +export const GraphicLLayer = { + ...AFVDGraphicLLayer, + ...SharedGraphicLLayer +} + +export type GraphicLLayer = AFVDGraphicLLayer | SharedGraphicLLayer + enum AFVDSisyfosLLAyer { SisyfosConfig = 'sisyfos_config', SisyfosGroupStudioMics = 'sisyfos_group_studio_mics', diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index 4cd202ac6..0d6546050 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -9,7 +9,7 @@ import { SetConfigTo, SetLayerNamesToDefaults } from 'tv2-common' -import { GraphicLLayer } from 'tv2-constants' +import { SharedGraphicLLayer } from 'tv2-constants' import * as _ from 'underscore' import { manifestAFVDDownstreamKeyers, @@ -174,7 +174,7 @@ export const studioMigrations: MigrationStepStudio[] = literal({ @@ -538,19 +537,19 @@ export const MAPPINGS_GRAPHICS: BlueprintMappings = { lookahead: LookaheadMode.NONE }), [GraphicLLayer.GraphicLLayerConcept]: literal({ - device: DeviceType.VIZMSE, + device: TSR.DeviceType.VIZMSE, deviceId: 'viz0', layerName: 'Override Concept', lookahead: LookaheadMode.NONE }), [GraphicLLayer.GraphicLLayerInitialize]: literal({ - device: DeviceType.VIZMSE, + device: TSR.DeviceType.VIZMSE, deviceId: 'viz0', layerName: 'GFX Show Initialization', lookahead: LookaheadMode.NONE }), [GraphicLLayer.GraphicLLayerCleanup]: literal({ - device: DeviceType.VIZMSE, + device: TSR.DeviceType.VIZMSE, deviceId: 'viz0', layerName: 'GFX Show Cleanup', lookahead: LookaheadMode.NONE diff --git a/src/tv2_offtube_showstyle/migrations/index.ts b/src/tv2_offtube_showstyle/migrations/index.ts index 94c84fd22..ad59c4535 100644 --- a/src/tv2_offtube_showstyle/migrations/index.ts +++ b/src/tv2_offtube_showstyle/migrations/index.ts @@ -12,7 +12,7 @@ import { StripFolderFromDVEConfig, UpsertValuesIntoTransitionTable } from 'tv2-common' -import { GraphicLLayer, SharedSourceLayers } from 'tv2-constants' +import { SharedGraphicLLayer, SharedSourceLayers } from 'tv2-constants' import * as _ from 'underscore' import { SetSourceLayerNameMigrationStep } from '../../tv2-common/migrations/shortcuts' import { ATEMModel } from '../../types/atem' @@ -47,17 +47,17 @@ enum VizLLayer { } export const remapVizLLayer: Map = new Map([ - [VizLLayer.VizLLayerOverlay, GraphicLLayer.GraphicLLayerOverlay], - [VizLLayer.VizLLayerOverlayIdent, GraphicLLayer.GraphicLLayerOverlayIdent], - [VizLLayer.VizLLayerOverlayTopt, GraphicLLayer.GraphicLLayerOverlayIdent], - [VizLLayer.VizLLayerOverlayLower, GraphicLLayer.GraphicLLayerOverlayLower], - [VizLLayer.VizLLayerOverlayHeadline, GraphicLLayer.GraphicLLayerOverlayHeadline], - [VizLLayer.VizLLayerOverlayTema, GraphicLLayer.GraphicLLayerOverlayTema], - [VizLLayer.VizLLayerPilot, GraphicLLayer.GraphicLLayerPilot], - [VizLLayer.VizLLayerPilotOverlay, GraphicLLayer.GraphicLLayerPilotOverlay], - [VizLLayer.VizLLayerDesign, GraphicLLayer.GraphicLLayerDesign], - [VizLLayer.VizLLayerAdLibs, GraphicLLayer.GraphicLLayerAdLibs], - [VizLLayer.VizLLayerWall, GraphicLLayer.GraphicLLayerWall] + [VizLLayer.VizLLayerOverlay, SharedGraphicLLayer.GraphicLLayerOverlay], + [VizLLayer.VizLLayerOverlayIdent, SharedGraphicLLayer.GraphicLLayerOverlayIdent], + [VizLLayer.VizLLayerOverlayTopt, SharedGraphicLLayer.GraphicLLayerOverlayIdent], + [VizLLayer.VizLLayerOverlayLower, SharedGraphicLLayer.GraphicLLayerOverlayLower], + [VizLLayer.VizLLayerOverlayHeadline, SharedGraphicLLayer.GraphicLLayerOverlayHeadline], + [VizLLayer.VizLLayerOverlayTema, SharedGraphicLLayer.GraphicLLayerOverlayTema], + [VizLLayer.VizLLayerPilot, SharedGraphicLLayer.GraphicLLayerPilot], + [VizLLayer.VizLLayerPilotOverlay, SharedGraphicLLayer.GraphicLLayerPilotOverlay], + [VizLLayer.VizLLayerDesign, SharedGraphicLLayer.GraphicLLayerDesign], + [VizLLayer.VizLLayerAdLibs, SharedGraphicLLayer.GraphicLLayerAdLibs], + [VizLLayer.VizLLayerWall, SharedGraphicLLayer.GraphicLLayerWall] ]) export const remapVizDOvl: Map = new Map([['viz-d-ovl', 'OVL1']]) @@ -118,7 +118,7 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal p.piece.tags?.includes(TallyTags.FULL_IS_LIVE)) for (const obj of timeline) { if ( - obj.layer === GraphicLLayer.GraphicLLayerPilot && + obj.layer === SharedGraphicLLayer.GraphicLLayerPilot && obj.content.deviceType === TSR.DeviceType.CASPARCG && (obj.isLookahead || (isFull && !previousPartEndState?.fullFileName) || diff --git a/src/tv2_offtube_studio/layers.ts b/src/tv2_offtube_studio/layers.ts index d9008b611..5f66cf496 100644 --- a/src/tv2_offtube_studio/layers.ts +++ b/src/tv2_offtube_studio/layers.ts @@ -1,4 +1,10 @@ -import { AbstractLLayer, GraphicLLayer, SharedATEMLLayer, SharedCasparLLayer, SharedSisyfosLLayer } from 'tv2-constants' +import { + AbstractLLayer, + SharedATEMLLayer, + 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 */ @@ -14,7 +20,7 @@ export function RealLLayers(): string[] { // @ts-ignore .concat(_.values(AbstractLLayer)) // @ts-ignore - .concat(_.values(GraphicLLayer)) + .concat(_.values(SharedGraphicLLayer)) ) } @@ -93,3 +99,9 @@ export const OfftubeSisyfosLLayer = { } export type OfftubeSisyfosLLayer = SharedSisyfosLLayer | SisyfosLLayer + +// tslint:disable-next-line: variable-name +export const OfftubeGraphicLLayer = { + ...SharedGraphicLLayer +} +export type OfftubeGraphicLLayer = SharedGraphicLLayer diff --git a/src/tv2_offtube_studio/migrations/index.ts b/src/tv2_offtube_studio/migrations/index.ts index 9fc9a5122..aa4e3a539 100644 --- a/src/tv2_offtube_studio/migrations/index.ts +++ b/src/tv2_offtube_studio/migrations/index.ts @@ -14,7 +14,7 @@ import { SetConfigTo, SetLayerNamesToDefaults } from 'tv2-common' -import { GraphicLLayer } from 'tv2-constants' +import { SharedGraphicLLayer } from 'tv2-constants' import * as _ from 'underscore' import { EnsureSisyfosMappingHasType } from '../../tv2_afvd_studio/migrations/util' import { @@ -291,18 +291,18 @@ export const studioMigrations: MigrationStepStudio[] = literal({ @@ -292,7 +298,7 @@ const MAPPINGS_CASPAR: BlueprintMappings = { layer: 100, previewWhenNotOnAir: true }), - [GraphicLLayer.GraphicLLayerLocators]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerLocators]: literal({ device: TSR.DeviceType.CASPARCG, deviceId: 'caspar01', layerName: 'GFX Locators', @@ -343,13 +349,13 @@ const MAPPINGS_CASPAR: BlueprintMappings = { } const MAPPINGS_GRAPHICS: BlueprintMappings = { - [GraphicLLayer.GraphicLLayerAdLibs]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerAdLibs]: literal({ device: TSR.DeviceType.ABSTRACT, deviceId: 'abstract0', layerName: 'GFX AdLibs', lookahead: LookaheadMode.NONE }), - [GraphicLLayer.GraphicLLayerDesign]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerDesign]: literal({ device: TSR.DeviceType.CASPARCG, deviceId: 'caspar01', layerName: 'GFX Design', @@ -358,7 +364,7 @@ const MAPPINGS_GRAPHICS: BlueprintMappings = { channel: 3, layer: 111 }), - [GraphicLLayer.GraphicLLayerOverlay]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerOverlay]: literal({ device: TSR.DeviceType.CASPARCG, deviceId: 'caspar01', layerName: 'GFX Overlay', @@ -367,12 +373,12 @@ const MAPPINGS_GRAPHICS: BlueprintMappings = { channel: 3, layer: 111 }), - [GraphicLLayer.GraphicLLayerOverlayHeadline]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerOverlayHeadline]: literal({ device: TSR.DeviceType.ABSTRACT, deviceId: 'abstract0', lookahead: LookaheadMode.NONE }), - [GraphicLLayer.GraphicLLayerOverlayIdent]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerOverlayIdent]: literal({ device: TSR.DeviceType.CASPARCG, deviceId: 'caspar01', layerName: 'GFX Ident', @@ -381,7 +387,7 @@ const MAPPINGS_GRAPHICS: BlueprintMappings = { channel: 3, layer: 111 }), - [GraphicLLayer.GraphicLLayerOverlayLower]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerOverlayLower]: literal({ device: TSR.DeviceType.CASPARCG, deviceId: 'caspar01', layerName: 'GFX Bund', @@ -390,7 +396,7 @@ const MAPPINGS_GRAPHICS: BlueprintMappings = { channel: 3, layer: 111 }), - [GraphicLLayer.GraphicLLayerOverlayTema]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerOverlayTema]: literal({ device: TSR.DeviceType.CASPARCG, deviceId: 'caspar01', layerName: 'GFX Tema', @@ -399,7 +405,7 @@ const MAPPINGS_GRAPHICS: BlueprintMappings = { channel: 3, layer: 111 }), - [GraphicLLayer.GraphicLLayerOverlayTopt]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerOverlayTopt]: literal({ device: TSR.DeviceType.CASPARCG, deviceId: 'caspar01', layerName: 'GFX Topt', @@ -408,7 +414,7 @@ const MAPPINGS_GRAPHICS: BlueprintMappings = { channel: 3, layer: 111 }), - [GraphicLLayer.GraphicLLayerPilot]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerPilot]: literal({ device: TSR.DeviceType.CASPARCG, deviceId: 'caspar01', layerName: 'GFX Pilot (Full)', @@ -418,7 +424,7 @@ const MAPPINGS_GRAPHICS: BlueprintMappings = { previewWhenNotOnAir: true }), /** TODO: Revisit these */ - [GraphicLLayer.GraphicLLayerPilotOverlay]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerPilotOverlay]: literal({ device: TSR.DeviceType.CASPARCG, deviceId: 'caspar01', layerName: 'GFX Pilot (Overlay)', @@ -429,20 +435,20 @@ const MAPPINGS_GRAPHICS: BlueprintMappings = { }), // Full loop and DVE loop are the same channel in Q2. // No mapping to caspar to avoid conflicts. - [GraphicLLayer.GraphicLLayerFullLoop]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerFullLoop]: literal({ device: TSR.DeviceType.ABSTRACT, deviceId: 'abstract0', layerName: 'GFX Full Loop', lookahead: LookaheadMode.NONE }), // No Screen for now - [GraphicLLayer.GraphicLLayerWall]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerWall]: literal({ device: TSR.DeviceType.ABSTRACT, deviceId: 'abstract0', layerName: 'GFX Wall', lookahead: LookaheadMode.NONE }), - [GraphicLLayer.GraphicLLayerConcept]: literal({ + [OfftubeGraphicLLayer.GraphicLLayerConcept]: literal({ device: TSR.DeviceType.ABSTRACT, deviceId: 'abstract0', layerName: 'Override Concept', diff --git a/yarn.lock b/yarn.lock index 34cc69944..5b1fec21a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -287,23 +287,16 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@tv2media/blueprints-integration@v1.37.1-in-testing.1": - version "1.37.1-in-testing.1" - resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-1.37.1-in-testing.1.tgz#92b11e3c4402650858db539fa5bf7ce7d04b992d" - integrity sha512-hJ+10Gt8xkbwjyGuPWnIecAxbE6a9oiClWW+Dr/9GXjU8z5FcnbKLGXdX/qnbGAMGTU+pNaPo/QUEbyAuFENrQ== +"@tv2media/blueprints-integration@v1.37.1-1": + version "1.37.1-1" + resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-1.37.1-1.tgz#6ea17006d9402f35aad12d1d4b2b8f4a75c04200" + integrity sha512-9zjm4NexyyAOVsDBfBtCdqAtlr1afj/9yva6cQb/VAlXPcLo/RtCMD4FaHPGrcQqqlyGKaCFeljnnUbLfLCQOg== dependencies: moment "2.29.1" - timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@1.0.0-release37" + timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@1.0.0-release37.7" tslib "^2.3.1" underscore "1.13.1" -"@tv2media/timeline-state-resolver-types@^1.0.0-release37.6": - version "1.0.0-release37.6" - resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-1.0.0-release37.6.tgz#48eca1760f254e38564b5901fead16ba02022e13" - integrity sha512-+Gd5fTSWyP4Z9l2CUC/gABJhCOKGD4gn5oR5VmnaL33U4KvGEgJE3X0SsW9Gn80O6y+2NBb/YcbDavRmlIG0TA== - dependencies: - tslib "^2.3.1" - "@types/babel__core@^7.1.0": version "7.1.6" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.6.tgz#16ff42a5ae203c9af1c6e190ed1f30f83207b610" @@ -5669,12 +5662,12 @@ 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@1.0.0-release37": - version "1.0.0-release37" - resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-1.0.0-release37.tgz#3271b202cd0c4e03ae418c76019276238eede7db" - integrity sha512-HdCWUQ0EJ7LwlaH9eRtURwzXknIvo3U8kInzus9Vx0M0HoUixYgfV5Z80w/PVSYdUk0L95kW2oLZB4ECB1M7Pg== +"timeline-state-resolver-types@npm:@tv2media/timeline-state-resolver-types@1.0.0-release37.7": + version "1.0.0-release37.7" + resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-1.0.0-release37.7.tgz#2cb32cd81343c1ed3d160f6f63b909f2a3f47935" + integrity sha512-o5DbFCJRMLHGrzoVjhjAAsZ+F90EjuKrwk7kfVlplMosouv4Kw4cucUQGOU26DzIM8tTlmIkadnZGMnT5sCmUA== dependencies: - tslib "^2.1.0" + tslib "^2.3.1" timers-browserify@^2.0.4: version "2.0.12" @@ -5822,7 +5815,7 @@ tslib@^1.7.1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== -tslib@^2.1.0, tslib@^2.3.1: +tslib@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== From 576acee755992223a33b601e69b209b14d0e1b32 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 27 Apr 2022 08:56:50 +0200 Subject: [PATCH 085/184] SOF-830 Minor refactor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Anders Frederik Jørgensen --- src/tv2-common/helpers/graphics/pilot/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index e0e272537..93b25f93d 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -155,7 +155,7 @@ export function CreateFullPiece( }), outputLayerId: GetOutputLayer(engine), sourceLayerId: GetSourceLayer(engine), - prerollDuration: prerollDuration ? prerollDuration : config.studio.VizPilotGraphics.PrerollDuration, + prerollDuration: prerollDuration ?? config.studio.VizPilotGraphics.PrerollDuration, lifespan: GetInfiniteModeForGraphic(engine, config, parsedCue), metaData: literal({ sisyfosPersistMetaData: { From e23ad8aa2bfcde05e7025e7fcf36dfd23d2258c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Wed, 27 Apr 2022 13:28:26 +0200 Subject: [PATCH 086/184] refactor: Use tags for EVS to DVE inputs. EVS 100% vs EVS VO can be differentiated by either full_audio_level and vo_audio_level. PickFunction for modifying sourceIndex for queue and cut_to_box reverted. --- src/tv2-common/hotkeys/helpers/cutToBox.ts | 5 +++-- src/tv2-common/hotkeys/helpers/queue.ts | 6 ++++- .../hotkeys/helpers/studioSource.ts | 14 +++++++----- src/tv2-common/hotkeys/local.ts | 22 ++----------------- src/tv2-common/hotkeys/server.ts | 1 + src/tv2_afvd_showstyle/getRundown.ts | 9 ++++---- 6 files changed, 24 insertions(+), 33 deletions(-) diff --git a/src/tv2-common/hotkeys/helpers/cutToBox.ts b/src/tv2-common/hotkeys/helpers/cutToBox.ts index 455f98de2..99cf445e2 100644 --- a/src/tv2-common/hotkeys/helpers/cutToBox.ts +++ b/src/tv2-common/hotkeys/helpers/cutToBox.ts @@ -8,7 +8,7 @@ import { TriggerType } from '@tv2media/blueprints-integration' import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' -import { AdlibTagCutToBox } from 'tv2-constants' +import { AdlibTagCutToBox, AdlibTags } from 'tv2-constants' export function MakeCutToBoxTrigger( id: string, @@ -16,6 +16,7 @@ export function MakeCutToBoxTrigger( name: string, hotkey: string | undefined, sourceLayerId: string, + isVO: boolean, pick: number, box: number ) { @@ -52,7 +53,7 @@ export function MakeCutToBoxTrigger( literal({ object: 'adLib', field: 'tag', - value: [AdlibTagCutToBox(box)] + value: [AdlibTagCutToBox(box), isVO ? AdlibTags.ADLIB_VO_AUDIO_LEVEL : AdlibTags.ADLIB_FULL_AUDIO_LEVEL] }), literal({ object: 'adLib', diff --git a/src/tv2-common/hotkeys/helpers/queue.ts b/src/tv2-common/hotkeys/helpers/queue.ts index f728c66c2..65bc5674d 100644 --- a/src/tv2-common/hotkeys/helpers/queue.ts +++ b/src/tv2-common/hotkeys/helpers/queue.ts @@ -16,6 +16,7 @@ export function MakeQueueTrigger( name: string, hotkey: string | undefined, sourceLayerId: string, + isVO: boolean, pick: number ) { return literal({ @@ -51,7 +52,10 @@ export function MakeQueueTrigger( literal({ object: 'adLib', field: 'tag', - value: [AdlibTags.ADLIB_QUEUE_NEXT] + value: [ + AdlibTags.ADLIB_QUEUE_NEXT, + isVO ? AdlibTags.ADLIB_VO_AUDIO_LEVEL : AdlibTags.ADLIB_FULL_AUDIO_LEVEL + ] }), literal({ object: 'adLib', diff --git a/src/tv2-common/hotkeys/helpers/studioSource.ts b/src/tv2-common/hotkeys/helpers/studioSource.ts index 192c38d66..405e02bb7 100644 --- a/src/tv2-common/hotkeys/helpers/studioSource.ts +++ b/src/tv2-common/hotkeys/helpers/studioSource.ts @@ -23,7 +23,7 @@ export function MakeStudioSourceHotkeys( getNextRank: () => number, nameFunc: (source: string) => string, idFunc: (showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) => string, - pickFunc: (sourceIndex: number, hotkeyType: string) => number = (sourceIndex) => sourceIndex, + isVO: boolean = false ): IBlueprintTriggeredActions[] { const directCutHotkeys: IBlueprintTriggeredActions[] = [] const queueHotkeys: IBlueprintTriggeredActions[] = [] @@ -44,7 +44,7 @@ export function MakeStudioSourceHotkeys( name, directHotkey, sourceLayerId, - pickFunc(currentSourceIndex, 'cut_direct') + currentSourceIndex ) ) } @@ -58,7 +58,8 @@ export function MakeStudioSourceHotkeys( name, queueHotkey, sourceLayerId, - pickFunc(currentSourceIndex, 'queue') + isVO, + currentSourceIndex ) ) } @@ -73,7 +74,8 @@ export function MakeStudioSourceHotkeys( name + ` inp ${box + 1}`, boxHotkey, sourceLayerId, - pickFunc(currentSourceIndex, `cut_to_box_${box + 1}`), + isVO, + currentSourceIndex, box ) ) @@ -89,7 +91,7 @@ export function MakeStudioSourceHotkeys( name + ` til SS`, toStudioScreenHotkey, sourceLayerId, - pickFunc(currentSourceIndex, 'studio_screen') + currentSourceIndex ) ) } @@ -103,7 +105,7 @@ export function MakeStudioSourceHotkeys( name, toGraphicsEngineHotkey, sourceLayerId, - pickFunc(currentSourceIndex, 'graphics_engine') + currentSourceIndex ) ) } diff --git a/src/tv2-common/hotkeys/local.ts b/src/tv2-common/hotkeys/local.ts index 46c6b78ce..f7beef2ba 100644 --- a/src/tv2-common/hotkeys/local.ts +++ b/src/tv2-common/hotkeys/local.ts @@ -14,13 +14,6 @@ function localSourceFullAudioHotkeyName(source: string) { return `EVS ${source} 100%` } -function localSourceFullAudioPick(sourceIndex: number, hotkeyType: string): number { - if (shouldUseCustomIndexPickerForLocalSourceAudio(hotkeyType)) { - return 2 * sourceIndex - } - return sourceIndex -} - function localSourceVoAudioHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { return `${showStyleId}_${sourceLayer}_local_vo_audio_${hotkeyType}_${index}` } @@ -29,17 +22,6 @@ function localSourceVoAudioHotkeyName(source: string) { return `EVS ${source} VO` } -function localSourceVoAudioPick(sourceIndex: number, hotkeyType: string): number { - if (shouldUseCustomIndexPickerForLocalSourceAudio(hotkeyType)) { - return 1 + 2 * sourceIndex - } - return sourceIndex -} - -function shouldUseCustomIndexPickerForLocalSourceAudio(hotkeyType: string): boolean { - return hotkeyType === 'queue' || /^cut_to_box_\d+$/.test(hotkeyType) -} - export function MakeLocalSourceHotkeys( showStyleId: string, sourceLayerId: string, @@ -55,7 +37,7 @@ export function MakeLocalSourceHotkeys( getNextRank, localSourceFullAudioHotkeyName, localSourceFullAudioHotkeyId, - localSourceFullAudioPick, + false ) const voAudioKeys = MakeStudioSourceHotkeys( @@ -66,7 +48,7 @@ export function MakeLocalSourceHotkeys( getNextRank, localSourceVoAudioHotkeyName, localSourceVoAudioHotkeyId, - localSourceVoAudioPick, + true ) return [...fullAudioKeys, ...voAudioKeys] diff --git a/src/tv2-common/hotkeys/server.ts b/src/tv2-common/hotkeys/server.ts index c451c58e0..4896098e3 100644 --- a/src/tv2-common/hotkeys/server.ts +++ b/src/tv2-common/hotkeys/server.ts @@ -49,6 +49,7 @@ export function MakeServerHotkeys( name + ` inp ${box + 1}`, boxHotkey, sourceLayerId, + false, currentSourceIndex, box ) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 74a80d37c..42d267b96 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -640,12 +640,13 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri function makeAdlibBoxesActionsDirectPlayback(info: SourceInfo, vo: boolean, rank: number) { for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { + const evsId = info.id.replace(/dp/i, '') res.push( literal({ actionId: AdlibActionType.CUT_SOURCE_TO_BOX, userData: literal({ type: AdlibActionType.CUT_SOURCE_TO_BOX, - name: `EVS ${info.id.replace(/dp/i, '')}${vo ? ' VO' : ''}`, + name: `EVS ${evsId}${vo ? ' VO' : ''}`, port: info.port, sourceType: info.type, box, @@ -654,11 +655,11 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri userDataManifest: {}, display: { _rank: rank + 0.1 * box, - label: t(`EVS ${info.id.replace(/dp/i, '')}${vo ? ' VO' : ''} to box ${box + 1}`), + label: t(`EVS ${evsId}${vo ? ' VO' : ''} to box ${box + 1}`), sourceLayerId: SourceLayer.PgmLocal, outputLayerId: SharedOutputLayers.SEC, content: {}, - tags: [AdlibTagCutToBox(box)] + tags: [AdlibTagCutToBox(box), vo ? AdlibTags.ADLIB_VO_AUDIO_LEVEL : AdlibTags.ADLIB_FULL_AUDIO_LEVEL] } }) ) @@ -685,7 +686,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri sourceLayerId: SourceLayer.PgmServer, outputLayerId: SharedOutputLayers.SEC, content: {}, - tags: [AdlibTagCutToBox(box)] + tags: [AdlibTagCutToBox(box), AdlibTags.ADLIB_FULL_AUDIO_LEVEL] } }) ) From 900f2f32187a350b18e5d5c0558760a88d010fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Wed, 27 Apr 2022 13:33:54 +0200 Subject: [PATCH 087/184] chore: Updated moment due to high security risk (package.json). --- package.json | 8 ++++++-- yarn.lock | 13 ++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index bf627add7..c5a22df82 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "test": "yarn lint --fix && yarn unit", "release": "standard-version", "prepareChangelog": "standard-version --prerelease", + "validate": "yarn validate:dependencies && yarn license-validate", "validate:dependencies": "yarn audit --groups dependencies && yarn license-validate", "license-validate": "node-license-validator -p -d --allow-licenses MIT MIT/X11 BSD BSD-3-Clause 0BSD ISC Apache Unlicense" }, @@ -43,7 +44,7 @@ "jest": "^24.0.0", "jest-haste-map": "^24.5.0", "jest-resolve": "^24.5.0", - "moment": "^2.22.2", + "moment": "^2.29.2", "node-license-validator": "^1.3.0", "prettier": "^1.18.2", "standard-version": "9.1.1", @@ -62,5 +63,8 @@ "@tv2media/blueprints-integration": "v1.37.1-in-testing.1", "@tv2media/timeline-state-resolver-types": "^1.0.0-release37.6", "underscore": "^1.12.1" + }, + "resolutions": { + "moment": "^2.29.2" } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 4048c98b8..ce6e6ac04 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3975,15 +3975,10 @@ modify-values@^1.0.0: resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== -moment@2.29.1: - version "2.29.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" - integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== - -moment@^2.22.2: - version "2.24.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" - integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== +moment@2.29.1, moment@^2.29.2: + version "2.29.3" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.3.tgz#edd47411c322413999f7a5940d526de183c031f3" + integrity sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw== move-concurrently@^1.0.1: version "1.0.1" From 40cad5c68543c64785a4327a0c17dd9c7d1c466f Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Thu, 28 Apr 2022 12:04:34 +0200 Subject: [PATCH 088/184] SOF-830 Refactor from PR comments --- src/tv2-common/actions/context.ts | 14 ++++---- .../helpers/graphics/pilot/index.ts | 4 +-- src/tv2-common/pieces/adlibServer.ts | 2 +- .../__tests__/actions.spec.ts | 1 - .../__tests__/baseline.spec.ts | 3 +- src/tv2_afvd_showstyle/getRundown.ts | 32 ++++++++--------- .../postProcessTimelineObjects.ts | 36 +++++++++---------- 7 files changed, 41 insertions(+), 51 deletions(-) diff --git a/src/tv2-common/actions/context.ts b/src/tv2-common/actions/context.ts index 28a5ad4bc..e477d7d93 100644 --- a/src/tv2-common/actions/context.ts +++ b/src/tv2-common/actions/context.ts @@ -204,9 +204,9 @@ class TV2ActionExecutionContext implements ITV2ActionExecutionContext { * Call this when the context is finished with. * After this, no further calls can be made. */ - public afterActions() { + public async afterActions() { for (const part of this.modifiedParts) { - this.markPartAsModifiedByAction(part).then() + await this.markPartAsModifiedByAction(part) } } @@ -228,11 +228,9 @@ class TV2ActionExecutionContext implements ITV2ActionExecutionContext { partInstance.part.metaData = {} } - this.coreContext - .updatePartInstance(part, { - metaData: literal({ ...(partInstance.part.metaData as PartMetaData), dirty: true }) - }) - .then() + await this.coreContext.updatePartInstance(part, { + metaData: literal({ ...(partInstance.part.metaData as PartMetaData), dirty: true }) + }) } } @@ -242,5 +240,5 @@ export async function executeWithContext( ) { const context = new TV2ActionExecutionContext(coreContext) await func(context) - context.afterActions() + await context.afterActions() } diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index 93b25f93d..9540cad2e 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -117,9 +117,7 @@ function CreatePilotAdLibAction( label: t(GetFullGraphicTemplateNameFromCue(config, parsedCue)), sourceLayerId: SharedSourceLayers.PgmPilot, outputLayerId: SharedOutputLayers.PGM, - content: { - ...CreateFullContent(config, context, settings, parsedCue, engine, adlib) - }, + content: CreateFullContent(config, context, settings, parsedCue, engine, adlib), uniquenessId: `gfx_${name}_${sourceLayerId}_${outputLayerId}`, tags: [ AdlibTags.ADLIB_KOMMENTATOR, diff --git a/src/tv2-common/pieces/adlibServer.ts b/src/tv2-common/pieces/adlibServer.ts index 966746a17..6d376c8ce 100644 --- a/src/tv2-common/pieces/adlibServer.ts +++ b/src/tv2-common/pieces/adlibServer.ts @@ -33,7 +33,7 @@ export function CreateAdlibServer< tagAsAdlib: boolean ): IBlueprintActionManifest { return literal({ - externalId: partDefinition.externalId + '-addLib-server', + externalId: partDefinition.externalId + '-adLib-server', actionId: AdlibActionType.SELECT_SERVER_CLIP, userData: literal({ type: AdlibActionType.SELECT_SERVER_CLIP, diff --git a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts index c1af3a4e0..79e74aea7 100644 --- a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts @@ -506,7 +506,6 @@ async function checkPartExistsWithProperties( props: Partial ) { const partInstance = await context.getPartInstance(part)! - expect(partInstance).toBeTruthy() if (partInstance === undefined) { fail('PartInstances must not be undefined') diff --git a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts index ef11c3673..67e94bb29 100644 --- a/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/baseline.spec.ts @@ -21,7 +21,6 @@ const configSpec = { id: 'default', studioConfig: defaultStudioConfig, showStyle const RUNDOWN_ID = 'test_rundown' const SEGMENT_ID = 'test_segment' const PART_ID = 'test_part' - describe('Baseline', () => { test('Config: ' + configSpec.id, async () => { expect(configSpec.studioConfig).toBeTruthy() @@ -32,7 +31,7 @@ describe('Baseline', () => { const result = await Blueprints.getRundown(mockContext, mockRundown) if (result === null) { - fail('Result is not allowed to null') + throw new Error('result must not be null') } expect(result.baseline.timelineObjects).not.toHaveLength(0) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index a86b8b594..520d836c8 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -111,7 +111,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint tags: [AdlibTags.ADLIB_QUEUE_NEXT, vo ? AdlibTags.ADLIB_VO_AUDIO_LEVEL : AdlibTags.ADLIB_FULL_AUDIO_LEVEL], content: { ignoreMediaObjectStatus: true, - timelineObjects: _.compact([ + timelineObjects: [ literal({ id: '', enable: { while: '1' }, @@ -141,7 +141,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint }) }), ...(vo ? [GetSisyfosTimelineObjForCamera(context, config, 'evs', SisyfosLLAyer.SisyfosGroupStudioMics)] : []) - ]) + ] } }) @@ -172,7 +172,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint }, tags: [AdlibTags.ADLIB_QUEUE_NEXT], content: { - timelineObjects: _.compact([ + timelineObjects: [ literal({ id: '', enable: { while: '1' }, @@ -189,7 +189,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint classes: ['adlib_deparent'] }), ...eksternSisyfos - ]) + ] } }) @@ -216,7 +216,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint }, tags: [AdlibTags.ADLIB_TO_STUDIO_SCREEN_AUX], content: { - timelineObjects: _.compact([ + timelineObjects: [ literal({ id: '', enable: { while: '1' }, @@ -230,7 +230,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint } } }) - ]) + ] } }) @@ -270,7 +270,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint lifespan: PieceLifespan.OutOnShowStyleEnd, tags: [AdlibTags.ADLIB_TO_STUDIO_SCREEN_AUX], content: { - timelineObjects: _.compact([ + timelineObjects: [ literal({ id: '', enable: { while: '1' }, @@ -284,7 +284,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint } } }) - ]) + ] } }) adlibItems.push({ @@ -297,7 +297,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint lifespan: PieceLifespan.OutOnShowStyleEnd, tags: [AdlibTags.ADLIB_TO_GRAPHICS_ENGINE_AUX], content: { - timelineObjects: _.compact([ + timelineObjects: [ literal({ id: '', enable: { while: '1' }, @@ -311,7 +311,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint } } }) - ]) + ] } }) }) @@ -355,7 +355,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint lifespan: PieceLifespan.WithinPart, tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIB_GFX_CONTINUE_FORWARD], content: { - timelineObjects: _.compact([ + timelineObjects: [ literal({ id: '', enable: { @@ -371,7 +371,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint reference: GraphicLLayer.GraphicLLayerPilot } }) - ]) + ] } }) @@ -448,7 +448,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint tags: [AdlibTags.ADLIB_STATIC_BUTTON, AdlibTags.ADLIBS_RESYNC_SISYFOS], expectedDuration: 1000, content: { - timelineObjects: _.compact([ + timelineObjects: [ literal({ id: '', enable: { start: 0 }, @@ -460,7 +460,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint resync: true } }) - ]) + ] } }) @@ -478,7 +478,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint fileName: 'BG_LOADER_SC', path: 'BG_LOADER_SC', ignoreMediaObjectStatus: true, - timelineObjects: _.compact([ + timelineObjects: [ literal({ id: '', enable: { start: 0 }, @@ -503,7 +503,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint loop: true } }) - ]) + ] }) }) ) diff --git a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts index 7a33f30ad..3c390ae75 100644 --- a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts @@ -122,27 +122,23 @@ export function postProcessPieceTimelineObjects( if (mixMinusSource !== null && mixMinusSource !== -1) { const mixMinusObj = literal({ ..._.omit(tlObj, 'content'), - ...literal< - Partial & Pick - >({ - id: '', - layer: AtemLLayer.AtemAuxVideoMixMinus, - priority: tlObj.classes?.includes('MIX_MINUS_OVERRIDE_DSK') ? 10 : tlObj.priority, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: - mixMinusSource !== undefined && mixMinusSource !== -1 - ? mixMinusSource - : config.studio.AtemSource.MixMinusDefault - } - }, - metaData: { - ...tlObj.metaData, - context: `Mix-minus for ${tlObj.id}` + id: '', + layer: AtemLLayer.AtemAuxVideoMixMinus, + priority: tlObj.classes?.includes('MIX_MINUS_OVERRIDE_DSK') ? 10 : tlObj.priority, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.AUX, + aux: { + input: + mixMinusSource !== undefined && mixMinusSource !== -1 + ? mixMinusSource + : config.studio.AtemSource.MixMinusDefault } - }) + }, + metaData: { + ...tlObj.metaData, + context: `Mix-minus for ${tlObj.id}` + } }) mixMinusObj.classes = mixMinusObj.classes?.filter( c => !c.match(`studio0_parent_`) && !c.match('PLACEHOLDER_OBJECT_REMOVEME') From 3fa924e7518b06ac4f785cb38337f6cfa9ce02b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Fri, 29 Apr 2022 12:02:51 +0200 Subject: [PATCH 089/184] fix: Remove Reload Browser (Ctrl+R) custom hotkey label. The key combo is now used for EVS adlibbing. --- shelf-layouts/AFVD_Default_showstyle_hotkeys.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/shelf-layouts/AFVD_Default_showstyle_hotkeys.json b/shelf-layouts/AFVD_Default_showstyle_hotkeys.json index 9f6191040..8abb8e205 100644 --- a/shelf-layouts/AFVD_Default_showstyle_hotkeys.json +++ b/shelf-layouts/AFVD_Default_showstyle_hotkeys.json @@ -642,12 +642,5 @@ "label": "serv til inp 1", "sourceLayerType": 2, "platformKey": "shift+t" - }, - { - "_id": "6gREn5sKmuyE8dN8h", - "key": "ctrl+r", - "label": "Reload Browser", - "platformKey": "ctrl+r", - "buttonColor": "#95a5a6" } ] \ No newline at end of file From 9621de3fd0106cd14b3dce2d9dbcbb58b454574c Mon Sep 17 00:00:00 2001 From: ianshade Date: Fri, 29 Apr 2022 15:52:22 +0200 Subject: [PATCH 090/184] fix: SOF-833 make adlib and piece labels more consistent also remove some redundant hotkey overrides --- .../AFVD_Default_showstyle_hotkeys.json | 175 ------------------ src/tv2-common/helpers/adLibNames.ts | 11 ++ src/tv2-common/helpers/index.ts | 1 + .../helpers/postProcessDefinitions.ts | 2 +- src/tv2-common/hotkeys/local.ts | 13 +- src/tv2-common/hotkeys/remote.ts | 2 +- .../inewsConversion/converters/ParseBody.ts | 12 +- .../converters/__tests__/body-parser.spec.ts | 8 +- src/tv2_afvd_showstyle/getRundown.ts | 21 ++- src/tv2_afvd_showstyle/parts/evs.ts | 6 +- src/tv2_offtube_showstyle/getRundown.ts | 14 +- 11 files changed, 44 insertions(+), 221 deletions(-) create mode 100644 src/tv2-common/helpers/adLibNames.ts diff --git a/shelf-layouts/AFVD_Default_showstyle_hotkeys.json b/shelf-layouts/AFVD_Default_showstyle_hotkeys.json index 9f6191040..da474ccd5 100644 --- a/shelf-layouts/AFVD_Default_showstyle_hotkeys.json +++ b/shelf-layouts/AFVD_Default_showstyle_hotkeys.json @@ -99,41 +99,6 @@ "platformKey": "", "buttonColor": "#000000" }, - { - "_id": "vDF35PGiHBvWpeTxv", - "key": "SHIFT+F1", - "label": "KAM 1 inp 1", - "sourceLayerType": 1, - "platformKey": "SHIFT+F1" - }, - { - "_id": "8MgfgjiW2NJLye2zr", - "key": "SHIFT+F2", - "label": "KAM 2 inp 1", - "sourceLayerType": 1, - "platformKey": "SHIFT+F2" - }, - { - "_id": "5RGpzWrTCfxhSpdvi", - "key": "SHIFT+F3", - "label": "KAM 3 inp 1", - "sourceLayerType": 1, - "platformKey": "SHIFT+F3" - }, - { - "_id": "JTsP9ecyp5JB9A6fv", - "key": "SHIFT+F4", - "label": "KAM 4 inp 1", - "sourceLayerType": 1, - "platformKey": "SHIFT+F4" - }, - { - "_id": "727iMuZT9GW3f4ntq", - "key": "SHIFT+F5", - "label": "KAM 5 inp 1", - "sourceLayerType": 1, - "platformKey": "SHIFT+F5" - }, { "_id": "QtCCqL72TBM7xdLHz", "key": "1", @@ -204,146 +169,6 @@ "sourceLayerType": 3, "platformKey": "0" }, - { - "_id": "Rk585scZjcNdG4oxM", - "key": "SHIFT+1", - "label": "LIVE 1 inp 1", - "sourceLayerType": 3, - "platformKey": "SHIFT+1" - }, - { - "_id": "kpdoQuBaQSG9WgnJ3", - "key": "SHIFT+2", - "label": "LIVE 2 inp 1", - "sourceLayerType": 3, - "platformKey": "SHIFT+2" - }, - { - "_id": "LyZ5oTez6FoYNJ4Ek", - "key": "shift+3", - "label": "LIVE 3 inp 1", - "sourceLayerType": 3, - "platformKey": "shift+3" - }, - { - "_id": "ixxRGQk8y3fk6LnbH", - "key": "shift+4", - "label": "LIVE 4 inp 1", - "sourceLayerType": 3, - "platformKey": "shift+4" - }, - { - "_id": "qZ4AhPGiqB9xhdqyg", - "key": "shift+5", - "label": "LIVE 5 inp 1", - "sourceLayerType": 3, - "platformKey": "shift+5" - }, - { - "_id": "Q4ePKSSKLYMN4fuyi", - "key": "shift+6", - "label": "LIVE 6 inp 1", - "sourceLayerType": 3, - "platformKey": "shift+6" - }, - { - "_id": "ck263XymZdg6q6vL4", - "key": "shift+7", - "label": "LIVE 7 inp 1", - "sourceLayerType": 3, - "platformKey": "shift+7" - }, - { - "_id": "HfjjdjeASpcy7YFsd", - "key": "shift+8", - "label": "LIVE 8 inp 1", - "sourceLayerType": 3, - "platformKey": "shift+8" - }, - { - "_id": "C6oNik83Q6PfWNdGS", - "key": "shift+9", - "label": "LIVE 9 inp 1", - "sourceLayerType": 3, - "platformKey": "shift+9" - }, - { - "_id": "JnMrbNg86KNSaQQYW", - "key": "shift+0", - "label": "LIVE 10 inp 1", - "sourceLayerType": 3, - "platformKey": "shift+0" - }, - { - "_id": "Cq886fvBRfgAgKgbf", - "key": "ctrl+1", - "label": "LIVE 1 inp 2", - "sourceLayerType": 3, - "platformKey": "ctrl+1" - }, - { - "_id": "c5TxgSSoA4tHYZ3xt", - "key": "ctrl+2", - "label": "LIVE 2 inp 2", - "sourceLayerType": 3, - "platformKey": "ctrl+2" - }, - { - "_id": "KgZpj2Q3gjGLS9CYa", - "key": "ctrl+3", - "label": "LIVE 3 inp 2", - "sourceLayerType": 3, - "platformKey": "ctrl+3" - }, - { - "_id": "ymsGD9SH8HR4TmCGS", - "key": "ctrl+4", - "label": "LIVE 4 inp 2", - "sourceLayerType": 3, - "platformKey": "ctrl+4" - }, - { - "_id": "rexi6Jm2nz8NqBw4q", - "key": "ctrl+5", - "label": "LIVE 5 inp 2", - "sourceLayerType": 3, - "platformKey": "ctrl+5" - }, - { - "_id": "ncMKuPussDv8uZ7xP", - "key": "ctrl+6", - "label": "LIVE 6 inp 2", - "sourceLayerType": 3, - "platformKey": "ctrl+6" - }, - { - "_id": "5npcfZbFRiuyeSgzR", - "key": "ctrl+7", - "label": "LIVE 7 inp 2", - "sourceLayerType": 3, - "platformKey": "ctrl+7" - }, - { - "_id": "AbsJ8SG3JTptoF8Gi", - "key": "ctrl+8", - "label": "LIVE 8 inp 2", - "sourceLayerType": 3, - "platformKey": "ctrl+8" - }, - { - "_id": "o4qEp4K8BQMAfixHH", - "key": "ctrl+9", - "label": "LIVE 9 inp 2", - "sourceLayerType": 3, - "platformKey": "ctrl+9" - }, - { - "_id": "KjPdj5SjYXGsPw8rQ", - "key": "ctrl+0", - "label": "LIVE 10 inp 2", - "sourceLayerType": 3, - "platformKey": "ctrl+0" - }, { "_id": "sRMm2pfzf34smfJnP", "key": "ctrl+F1", diff --git a/src/tv2-common/helpers/adLibNames.ts b/src/tv2-common/helpers/adLibNames.ts new file mode 100644 index 000000000..0b190dfda --- /dev/null +++ b/src/tv2-common/helpers/adLibNames.ts @@ -0,0 +1,11 @@ +export function localSourceFullAudioName(source: string) { + return `EVS ${source} 100%` +} + +export function localSourceVoAudioName(source: string) { + return `EVS ${source} VO` +} + +export function localSourceName(source: string, vo: boolean) { + return vo ? localSourceVoAudioName(source) : localSourceFullAudioName(source) +} diff --git a/src/tv2-common/helpers/index.ts b/src/tv2-common/helpers/index.ts index 2bc9a8494..b5ac9914f 100644 --- a/src/tv2-common/helpers/index.ts +++ b/src/tv2-common/helpers/index.ts @@ -6,6 +6,7 @@ export * from './graphics/index' export * from './rundownAdLibActions' export * from './postProcessDefinitions' export * from './translation' +export * from './adLibNames' export function SanitizePath(path: string): string { return path.replace(/[\/\\]*$/, '') diff --git a/src/tv2-common/helpers/postProcessDefinitions.ts b/src/tv2-common/helpers/postProcessDefinitions.ts index ea643adf2..5748a66b0 100644 --- a/src/tv2-common/helpers/postProcessDefinitions.ts +++ b/src/tv2-common/helpers/postProcessDefinitions.ts @@ -52,7 +52,7 @@ function getExternalId(segmentId: string, partDefinition: PartDefinition, foundM switch (partDefinition.type) { case PartType.EVS: // Common pattern to see EV1 and EVS1VO in the same story. Changing from EVS1 to EVS1VO would mean a new part - id += `-${partDefinition.variant.evs}-${partDefinition.variant.isVO}` + id += `-${partDefinition.variant.evs}-${!!partDefinition.variant.vo}` break case PartType.INTRO: // Intro must have a jingle cue, if it doesn't then padId will handle diff --git a/src/tv2-common/hotkeys/local.ts b/src/tv2-common/hotkeys/local.ts index f7beef2ba..c223edb59 100644 --- a/src/tv2-common/hotkeys/local.ts +++ b/src/tv2-common/hotkeys/local.ts @@ -1,4 +1,5 @@ import { IBlueprintTriggeredActions } from '@tv2media/blueprints-integration' +import { localSourceFullAudioName, localSourceVoAudioName } from '../helpers' import { MakeStudioSourceHotkeys, SourceHotkeyTriggers } from './helpers' export interface LocalSourceHotkeyAssignments { @@ -10,18 +11,10 @@ function localSourceFullAudioHotkeyId(showStyleId: string, sourceLayer: string, return `${showStyleId}_${sourceLayer}_local_full_audio_${hotkeyType}_${index}` } -function localSourceFullAudioHotkeyName(source: string) { - return `EVS ${source} 100%` -} - function localSourceVoAudioHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) { return `${showStyleId}_${sourceLayer}_local_vo_audio_${hotkeyType}_${index}` } -function localSourceVoAudioHotkeyName(source: string) { - return `EVS ${source} VO` -} - export function MakeLocalSourceHotkeys( showStyleId: string, sourceLayerId: string, @@ -35,7 +28,7 @@ export function MakeLocalSourceHotkeys( localSources, assignemnts.fullAudio, getNextRank, - localSourceFullAudioHotkeyName, + localSourceFullAudioName, localSourceFullAudioHotkeyId, false ) @@ -46,7 +39,7 @@ export function MakeLocalSourceHotkeys( localSources, assignemnts.voAudio, getNextRank, - localSourceVoAudioHotkeyName, + localSourceVoAudioName, localSourceVoAudioHotkeyId, true ) diff --git a/src/tv2-common/hotkeys/remote.ts b/src/tv2-common/hotkeys/remote.ts index 8092700e7..752cf6a28 100644 --- a/src/tv2-common/hotkeys/remote.ts +++ b/src/tv2-common/hotkeys/remote.ts @@ -13,7 +13,7 @@ function feedHotkeyId(showStyleId: string, sourceLayer: string, hotkeyType: stri function remoteHotkeyName(remote: string) { const feed = remote.match(/^F(.+).*$/) // TODO: fix when refactoring FindSourceInfo - return feed ? `Feed ${feed[1]}` : `LIVE ${remote}` + return feed ? `FEED ${feed[1]}` : `LIVE ${remote}` } export function MakeRemoteHotkeys( diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index 2ee078048..1091615a2 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -66,7 +66,7 @@ export interface PartDefinitionEVS extends PartDefinitionBase { type: PartType.EVS variant: { evs: string - isVO: boolean + vo?: 'VO' | 'VOV' } } @@ -541,17 +541,11 @@ function extractTypeProperties(typeStr: string): PartdefinitionTypes { type: PartType.EVS, variant: { evs: strippedToken && strippedToken[1] ? strippedToken[1] : '1', - isVO: !!strippedToken && !!strippedToken[2] + vo: (strippedToken && (strippedToken[2] as 'VO' | 'VOV')) ?? undefined }, ...definition } - } else if (firstToken.match(/VOV?/i)) { - return { - type: PartType.VO, - variant: {}, - ...definition - } - } else if (firstToken.match(/VOSB/i)) { + } else if (firstToken.match(/VOV?/i) || firstToken.match(/VOSB/i)) { return { type: PartType.VO, variant: {}, 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 42e8f9378..96091783c 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts @@ -1581,8 +1581,7 @@ describe('Body parser', () => { type: PartType.EVS, rawType: 'EVS 1', variant: { - evs: '1', - isVO: false + evs: '1' }, cues: [cueGrafik1, cueGrafik2, cueGrafik3], fields, @@ -1606,7 +1605,7 @@ describe('Body parser', () => { rawType: 'EVS1VOV', variant: { evs: '1', - isVO: true + vo: 'VOV' }, cues: [cueGrafik1, cueGrafik2, cueGrafik3], fields, @@ -2651,8 +2650,7 @@ describe('Body parser', () => { type: PartType.EVS, rawType: 'EVS 1', variant: { - evs: '1', - isVO: false + evs: '1' }, effekt: 1, cues: [cueGrafik1, cueGrafik2, cueGrafik3], diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 42d267b96..6103cb555 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -35,6 +35,7 @@ import { GetSisyfosTimelineObjForEkstern, GetTransitionAdLibActions, literal, + localSourceName, SourceInfo, t, TimelineBlueprintExt @@ -94,7 +95,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint const res: IBlueprintAdLibPiece[] = [] res.push({ externalId: 'delayed', - name: `EVS ${info.id.replace(/dp/i, '')}${vo ? ' VO' : ''}`, + name: localSourceName(info.id.replace(/dp/i, ''), vo), _rank: rank, sourceLayerId: SourceLayer.PgmLocal, outputLayerId: SharedOutputLayers.PGM, @@ -609,11 +610,11 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri let globalRank = 1000 - function makeAdlibBoxesActions(info: SourceInfo, type: 'Kamera' | 'Live' | 'Feed', rank: number) { + function makeAdlibBoxesActions(info: SourceInfo, type: 'KAM' | 'LIVE' | 'FEED', rank: number) { for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { - const feed = type === 'Live' && info.id.match(/^F(.+).*$/) // TODO: fix when refactoring FindSourceInfo - const name = feed ? `Feed ${feed[1]}` : `${type} ${info.id}` - const layer = type === 'Kamera' ? SourceLayer.PgmCam : SourceLayer.PgmLive + const feed = type === 'LIVE' && info.id.match(/^F(.+).*$/) // TODO: fix when refactoring FindSourceInfo + const name = feed ? `FEED ${feed[1]}` : `${type} ${info.id}` + const layer = type === 'KAM' ? SourceLayer.PgmCam : SourceLayer.PgmLive res.push( literal({ actionId: AdlibActionType.CUT_SOURCE_TO_BOX, @@ -627,7 +628,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri userDataManifest: {}, display: { _rank: rank + 0.1 * box, - label: t(`${name} to box ${box + 1}`), + label: t(`${name} inp ${box + 1}`), sourceLayerId: layer, outputLayerId: SharedOutputLayers.SEC, content: {}, @@ -646,7 +647,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri actionId: AdlibActionType.CUT_SOURCE_TO_BOX, userData: literal({ type: AdlibActionType.CUT_SOURCE_TO_BOX, - name: `EVS ${evsId}${vo ? ' VO' : ''}`, + name: localSourceName(evsId, vo), port: info.port, sourceType: info.type, box, @@ -655,7 +656,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri userDataManifest: {}, display: { _rank: rank + 0.1 * box, - label: t(`EVS ${evsId}${vo ? ' VO' : ''} to box ${box + 1}`), + label: t(`${localSourceName(evsId, vo)} inp ${box + 1}`), sourceLayerId: SourceLayer.PgmLocal, outputLayerId: SharedOutputLayers.SEC, content: {}, @@ -733,7 +734,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri .filter(u => u.type === SourceLayerType.CAMERA) .slice(0, 5) // the first x cameras to dve actions from .forEach(o => { - makeAdlibBoxesActions(o, 'Kamera', globalRank++) + makeAdlibBoxesActions(o, 'KAM', globalRank++) }) res.push( @@ -757,7 +758,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri .filter(u => u.type === SourceLayerType.REMOTE) .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from .forEach(o => { - makeAdlibBoxesActions(o, o.id.match(/^F/) ? 'Feed' : 'Live', globalRank++) + makeAdlibBoxesActions(o, o.id.match(/^F/) ? 'FEED' : 'LIVE', globalRank++) }) config.sources diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index 51b5f9054..a76f2102f 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -42,7 +42,7 @@ export function CreatePartEVS( let part = literal({ externalId: partDefinition.externalId, - title: `EVS ${partDefinition.variant.evs} ${partDefinition.variant.isVO ? ' VO' : ''}`, + title: `EVS ${partDefinition.variant.evs} ${partDefinition.variant.vo ?? ''}`, metaData: {}, expectedDuration: partTime > 0 ? partTime : 0 }) @@ -137,8 +137,8 @@ function makeContentEVS( }, classes: [EVSParentClass('studio0', partDefinition.variant.evs)] }), - GetSisyfosTimelineObjForEVS(sourceInfoDelayedPlayback, partDefinition.variant.isVO), - ...(partDefinition.variant.isVO + GetSisyfosTimelineObjForEVS(sourceInfoDelayedPlayback, !!partDefinition.variant.vo), + ...(partDefinition.variant.vo ? [GetSisyfosTimelineObjForCamera(context, config, 'evs', SisyfosLLAyer.SisyfosGroupStudioMics)] : []) ]) diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 8ea92b2ae..0b25ac782 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -300,11 +300,11 @@ function getGlobalAdlibActionsOfftube( ) } - function makeAdlibBoxesActions(info: SourceInfo, type: 'Kamera' | 'Live', rank: number) { + function makeAdlibBoxesActions(info: SourceInfo, type: 'KAM' | 'LIVE', rank: number) { for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { - const feed = type === 'Live' && info.id.match(/^F(.+).*$/) - const name = feed ? `Feed ${feed[1]}` : `${type} ${info.id}` - const layer = type === 'Kamera' ? OfftubeSourceLayer.PgmCam : OfftubeSourceLayer.PgmLive + const feed = type === 'LIVE' && info.id.match(/^F(.+).*$/) + const name = feed ? `FEED ${feed[1]}` : `${type} ${info.id}` + const layer = type === 'KAM' ? OfftubeSourceLayer.PgmCam : OfftubeSourceLayer.PgmLive res.push( literal({ actionId: AdlibActionType.CUT_SOURCE_TO_BOX, @@ -318,7 +318,7 @@ function getGlobalAdlibActionsOfftube( userDataManifest: {}, display: { _rank: rank + 0.1 * box, - label: t(`Cut ${name} to box ${box + 1}`), + label: t(`${name} inp ${box + 1}`), sourceLayerId: layer, outputLayerId: OfftubeOutputLayers.PGM, content: {}, @@ -495,7 +495,7 @@ function getGlobalAdlibActionsOfftube( .filter(u => u.type === SourceLayerType.CAMERA) .slice(0, 5) // the first x cameras to create preview cam-adlibs from .forEach(o => { - makeAdlibBoxesActions(o, 'Kamera', globalRank++) + makeAdlibBoxesActions(o, 'KAM', globalRank++) }) res.push( @@ -526,7 +526,7 @@ function getGlobalAdlibActionsOfftube( .filter(u => u.type === SourceLayerType.REMOTE) .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from .forEach(o => { - makeAdlibBoxesActions(o, 'Live', globalRank++) + makeAdlibBoxesActions(o, 'LIVE', globalRank++) }) makeServerAdlibBoxesActions(globalRank++) From 20ad5d537cbd35228a9ba2731e196c626988477e Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Mon, 2 May 2022 08:19:27 +0200 Subject: [PATCH 091/184] SOF-830 Minor syntax refactor --- .../postProcessTimelineObjects.ts | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts index 75d96dcfb..be5274fb8 100644 --- a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts @@ -162,26 +162,24 @@ export function postProcessPieceTimelineObjects( } const cleanObj = literal({ - ..._.omit(tlObj, 'content'), - ...literal & Pick>({ - id: '', - layer: AtemLLayer.AtemCleanUSKEffect, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.ME, - me: { - upstreamKeyers: [ - { - upstreamKeyerId: 0 - }, - { - upstreamKeyerId: 1, - ...newProps - } - ] - } + ..._.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) } From f42f7e75ccace4021bc93cfa3560056ae55b6ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Mon, 2 May 2022 08:45:13 +0200 Subject: [PATCH 092/184] fix: Renamed 'to box' to 'inp' for Server for consistency. --- src/tv2_afvd_showstyle/getRundown.ts | 2 +- src/tv2_offtube_showstyle/getRundown.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 6103cb555..aa939ceb1 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -683,7 +683,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri userDataManifest: {}, display: { _rank: rank + 0.1 * box, - label: t(`Server to box ${box + 1}`), + label: t(`Server inp ${box + 1}`), sourceLayerId: SourceLayer.PgmServer, outputLayerId: SharedOutputLayers.SEC, content: {}, diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 0b25ac782..bdbec1880 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -345,7 +345,7 @@ function getGlobalAdlibActionsOfftube( userDataManifest: {}, display: { _rank: rank + 0.1 * box, - label: t(`Server to box ${box + 1}`), + label: t(`Server inp ${box + 1}`), sourceLayerId: OfftubeSourceLayer.PgmServer, outputLayerId: SharedOutputLayers.SEC, content: {}, From 096ef66a95b56d48a6f29ec407ceec8576b839cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Mon, 2 May 2022 09:10:05 +0200 Subject: [PATCH 093/184] fix: Rename and remove Server custom hotkey labels. --- shelf-layouts/AFVD_Default_showstyle_hotkeys.json | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/shelf-layouts/AFVD_Default_showstyle_hotkeys.json b/shelf-layouts/AFVD_Default_showstyle_hotkeys.json index da474ccd5..0ff0522c8 100644 --- a/shelf-layouts/AFVD_Default_showstyle_hotkeys.json +++ b/shelf-layouts/AFVD_Default_showstyle_hotkeys.json @@ -450,7 +450,7 @@ { "_id": "kS3YARWkhv3nLfRsJ", "key": "CTRL+ALT+SHIFT+G", - "label": "serv til inp 2", + "label": "serv inp 2", "sourceLayerType": 2, "platformKey": "ctrl+T" }, @@ -461,13 +461,6 @@ "sourceLayerType": 1, "platformKey": "F5" }, - { - "_id": "QS6pXQ2CARySFJKkh", - "key": "shift+t", - "label": "serv til inp 1", - "sourceLayerType": 2, - "platformKey": "shift+t" - }, { "_id": "6gREn5sKmuyE8dN8h", "key": "ctrl+r", From 8f0e617a0f067cd687263e4fa8dd21e4d2f4719d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Tue, 3 May 2022 12:35:27 +0200 Subject: [PATCH 094/184] fix: Use full or VO only for EVS. live and server was also filtered by either full_audio_level or vo_audio_level, without having the tags. --- src/tv2-common/hotkeys/helpers/cutToBox.ts | 6 +++--- src/tv2-common/hotkeys/helpers/queue.ts | 7 ++----- src/tv2-common/hotkeys/helpers/studioSource.ts | 6 +++--- src/tv2-common/hotkeys/local.ts | 5 +++-- src/tv2-common/hotkeys/server.ts | 2 +- src/tv2_afvd_showstyle/getRundown.ts | 2 +- 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/tv2-common/hotkeys/helpers/cutToBox.ts b/src/tv2-common/hotkeys/helpers/cutToBox.ts index 99cf445e2..5530dfef7 100644 --- a/src/tv2-common/hotkeys/helpers/cutToBox.ts +++ b/src/tv2-common/hotkeys/helpers/cutToBox.ts @@ -8,7 +8,7 @@ import { TriggerType } from '@tv2media/blueprints-integration' import { literal, TRIGGER_HOTKEYS_ON_KEYUP } from 'tv2-common' -import { AdlibTagCutToBox, AdlibTags } from 'tv2-constants' +import { AdlibTagCutToBox } from 'tv2-constants' export function MakeCutToBoxTrigger( id: string, @@ -16,7 +16,7 @@ export function MakeCutToBoxTrigger( name: string, hotkey: string | undefined, sourceLayerId: string, - isVO: boolean, + tags: string[], pick: number, box: number ) { @@ -53,7 +53,7 @@ export function MakeCutToBoxTrigger( literal({ object: 'adLib', field: 'tag', - value: [AdlibTagCutToBox(box), isVO ? AdlibTags.ADLIB_VO_AUDIO_LEVEL : AdlibTags.ADLIB_FULL_AUDIO_LEVEL] + value: [AdlibTagCutToBox(box), ...tags] }), literal({ object: 'adLib', diff --git a/src/tv2-common/hotkeys/helpers/queue.ts b/src/tv2-common/hotkeys/helpers/queue.ts index 65bc5674d..c65e28bf1 100644 --- a/src/tv2-common/hotkeys/helpers/queue.ts +++ b/src/tv2-common/hotkeys/helpers/queue.ts @@ -16,7 +16,7 @@ export function MakeQueueTrigger( name: string, hotkey: string | undefined, sourceLayerId: string, - isVO: boolean, + tags: string[], pick: number ) { return literal({ @@ -52,10 +52,7 @@ export function MakeQueueTrigger( literal({ object: 'adLib', field: 'tag', - value: [ - AdlibTags.ADLIB_QUEUE_NEXT, - isVO ? AdlibTags.ADLIB_VO_AUDIO_LEVEL : AdlibTags.ADLIB_FULL_AUDIO_LEVEL - ] + value: [AdlibTags.ADLIB_QUEUE_NEXT, ...tags] }), literal({ object: 'adLib', diff --git a/src/tv2-common/hotkeys/helpers/studioSource.ts b/src/tv2-common/hotkeys/helpers/studioSource.ts index 405e02bb7..1298bf4ff 100644 --- a/src/tv2-common/hotkeys/helpers/studioSource.ts +++ b/src/tv2-common/hotkeys/helpers/studioSource.ts @@ -23,7 +23,7 @@ export function MakeStudioSourceHotkeys( getNextRank: () => number, nameFunc: (source: string) => string, idFunc: (showStyleId: string, sourceLayer: string, hotkeyType: string, index: number) => string, - isVO: boolean = false + tags: string[] = [] ): IBlueprintTriggeredActions[] { const directCutHotkeys: IBlueprintTriggeredActions[] = [] const queueHotkeys: IBlueprintTriggeredActions[] = [] @@ -58,7 +58,7 @@ export function MakeStudioSourceHotkeys( name, queueHotkey, sourceLayerId, - isVO, + tags, currentSourceIndex ) ) @@ -74,7 +74,7 @@ export function MakeStudioSourceHotkeys( name + ` inp ${box + 1}`, boxHotkey, sourceLayerId, - isVO, + tags, currentSourceIndex, box ) diff --git a/src/tv2-common/hotkeys/local.ts b/src/tv2-common/hotkeys/local.ts index c223edb59..9167df3cf 100644 --- a/src/tv2-common/hotkeys/local.ts +++ b/src/tv2-common/hotkeys/local.ts @@ -1,4 +1,5 @@ import { IBlueprintTriggeredActions } from '@tv2media/blueprints-integration' +import { AdlibTags } from 'tv2-constants' import { localSourceFullAudioName, localSourceVoAudioName } from '../helpers' import { MakeStudioSourceHotkeys, SourceHotkeyTriggers } from './helpers' @@ -30,7 +31,7 @@ export function MakeLocalSourceHotkeys( getNextRank, localSourceFullAudioName, localSourceFullAudioHotkeyId, - false + [AdlibTags.ADLIB_FULL_AUDIO_LEVEL] ) const voAudioKeys = MakeStudioSourceHotkeys( @@ -41,7 +42,7 @@ export function MakeLocalSourceHotkeys( getNextRank, localSourceVoAudioName, localSourceVoAudioHotkeyId, - true + [AdlibTags.ADLIB_VO_AUDIO_LEVEL] ) return [...fullAudioKeys, ...voAudioKeys] diff --git a/src/tv2-common/hotkeys/server.ts b/src/tv2-common/hotkeys/server.ts index 4896098e3..8df38e639 100644 --- a/src/tv2-common/hotkeys/server.ts +++ b/src/tv2-common/hotkeys/server.ts @@ -49,7 +49,7 @@ export function MakeServerHotkeys( name + ` inp ${box + 1}`, boxHotkey, sourceLayerId, - false, + [], currentSourceIndex, box ) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index aa939ceb1..99703fd47 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -687,7 +687,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri sourceLayerId: SourceLayer.PgmServer, outputLayerId: SharedOutputLayers.SEC, content: {}, - tags: [AdlibTagCutToBox(box), AdlibTags.ADLIB_FULL_AUDIO_LEVEL] + tags: [AdlibTagCutToBox(box)] } }) ) From 0e4871738055d8c39331a5db14a736acb50b5bbd Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Tue, 3 May 2022 14:15:20 +0200 Subject: [PATCH 095/184] SOF-830 Now dependent on timeline-state-resolver-type 2.0.0 --- package.json | 2 +- src/__mocks__/context.ts | 6 +++--- src/inews-mixins/__tests__/playlist.spec.ts | 3 ++- .../helpers/graphics/InternalGraphic.ts | 6 ++---- src/tv2-common/helpers/graphics/pilot/index.ts | 3 +-- .../helpers/pieces/__tests__/grafikViz.spec.ts | 3 --- .../helpers/pieces/jingle.ts | 3 +-- src/tv2_offtube_showstyle/cues/OfftubeDVE.ts | 1 - .../cues/OfftubeJingle.ts | 3 +-- yarn.lock | 18 +++++++++--------- 10 files changed, 20 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index 2f65828b7..9089ee5fe 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "webpack-cli": "^3.1.2" }, "dependencies": { - "@tv2media/blueprints-integration": "1.41.2", + "@tv2media/blueprints-integration": "1.42.5", "underscore": "^1.12.1" }, "resolutions": { diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index 3c6abb0b5..745e7087b 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -181,7 +181,7 @@ export class ShowStyleContext extends StudioContext implements IShowStyleContext public getShowStyleConfigRef(_configKey: string): string { return 'test' } - public hackGetMediaObjectDuration(_mediaId: string) { + public hackGetMediaObjectDuration(_mediaId: string): number | undefined { return undefined } } @@ -275,7 +275,7 @@ export class SegmentUserContext extends RundownContext implements ISegmentUserCo ) { this.pushNote(NoteType.NOTIFY_USER_WARNING, message) } - public hackGetMediaObjectDuration(_mediaId: string) { + public hackGetMediaObjectDuration(_mediaId: string): number | undefined { return undefined } public getPackageInfo(_packageId: string): readonly PackageInfo.Any[] { @@ -578,7 +578,7 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct return take } - public hackGetMediaObjectDuration(_mediaId: string) { + public hackGetMediaObjectDuration(_mediaId: string): number | undefined { return undefined } public getPackageInfo(_packageId: string): PackageInfo.Any[] { diff --git a/src/inews-mixins/__tests__/playlist.spec.ts b/src/inews-mixins/__tests__/playlist.spec.ts index f576a66b8..8893fbd80 100644 --- a/src/inews-mixins/__tests__/playlist.spec.ts +++ b/src/inews-mixins/__tests__/playlist.spec.ts @@ -2,6 +2,7 @@ import { BlueprintResultRundown, ExtendedIngestRundown, IngestSegment, + IShowStyleUserContext, PlaylistTimingType } from '@tv2media/blueprints-integration' import { getRundownWithBackTime } from 'inews-mixins' @@ -16,7 +17,7 @@ const RUNDOWN_NAME = 'Rundown 1' const SEGMENT_ID = 'test_segment' const PART_ID = 'test_part' -function getMockContext() { +function getMockContext(): IShowStyleUserContext { return new ShowStyleUserContext( RUNDOWN_NAME, mappingsDefaults, diff --git a/src/tv2-common/helpers/graphics/InternalGraphic.ts b/src/tv2-common/helpers/graphics/InternalGraphic.ts index b5a7a2244..003c394d7 100644 --- a/src/tv2-common/helpers/graphics/InternalGraphic.ts +++ b/src/tv2-common/helpers/graphics/InternalGraphic.ts @@ -100,8 +100,7 @@ export class InternalGraphic { sourceLayerId: this.sourceLayerId, outputLayerId: SharedOutputLayers.OVERLAY, tags: [AdlibTags.ADLIB_KOMMENTATOR], - content: _.clone(this.content), - noHotKey: true + content: _.clone(this.content) } }) ) @@ -121,8 +120,7 @@ export class InternalGraphic { }), expectedDuration: 5000, tags: [AdlibTags.ADLIB_KOMMENTATOR], - content: _.clone(this.content), - noHotKey: true + content: _.clone(this.content) }) adlibPieces.push(adLibPiece) } diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index 9540cad2e..68d2f65fa 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -124,8 +124,7 @@ function CreatePilotAdLibAction( ...(config.showStyle.MakeAdlibsForFulls && IsTargetingFull(engine) ? [AdlibTags.ADLIB_FLOW_PRODUCER] : []) ], currentPieceTags: [GetTagForFull(segmentExternalId, parsedCue.graphic.vcpid)], - nextPieceTags: [GetTagForFullNext(segmentExternalId, parsedCue.graphic.vcpid)], - noHotKey: !(config.showStyle.MakeAdlibsForFulls && IsTargetingFull(engine)) + nextPieceTags: [GetTagForFullNext(segmentExternalId, parsedCue.graphic.vcpid)] } }) } 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 94f7fafbf..e95be0f64 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -200,7 +200,6 @@ describe('grafik piece', () => { uniquenessId: 'gfx_bund - Odense\n - Copenhagen_studio0_graphicsLower_overlay_commentator', expectedDuration: 5000, tags: [AdlibTags.ADLIB_KOMMENTATOR], - noHotKey: true, content: literal>({ fileName: 'bund', path: 'bund', @@ -317,7 +316,6 @@ describe('grafik piece', () => { uniquenessId: 'gfx_bund - Odense\n - Copenhagen_studio0_graphicsLower_overlay_commentator', tags: [AdlibTags.ADLIB_KOMMENTATOR], expectedDuration: 5000, - noHotKey: true, content: literal>({ fileName: 'bund', path: 'bund', @@ -766,7 +764,6 @@ describe('grafik piece', () => { expectedDuration: 5000, tags: ['kommentator'], uniquenessId: 'gfx_tlftoptlive - Line 1\n - Line 2_studio0_graphicsTop_overlay_commentator', - noHotKey: true, content: literal>({ fileName: 'tlftoptlive', path: 'tlftoptlive', diff --git a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts index 209022b80..4aaf7057c 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts @@ -80,8 +80,7 @@ export function EvaluateJingle( }, tags: [AdlibTags.ADLIB_FLOW_PRODUCER], currentPieceTags: [GetTagForJingle(part.segmentExternalId, parsedCue.clip)], - nextPieceTags: [GetTagForJingleNext(part.segmentExternalId, parsedCue.clip)], - noHotKey: true + nextPieceTags: [GetTagForJingleNext(part.segmentExternalId, parsedCue.clip)] } }) ) diff --git a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts index e2e61b0c0..86e808193 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts @@ -134,7 +134,6 @@ export function OfftubeEvaluateDVE( outputLayerId: OfftubeOutputLayers.PGM, label: t(`${partDefinition.storyName}`), tags: [AdlibTags.ADLIB_KOMMENTATOR, ...(adlib ? [AdlibTags.ADLIB_FLOW_PRODUCER] : [])], - noHotKey: !adlib, content: literal({ ...pieceContent.content }), diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index 73948b5e0..2d2c4d005 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -87,8 +87,7 @@ export function OfftubeEvaluateJingle( }, tags: [AdlibTags.OFFTUBE_100pc_SERVER, AdlibTags.ADLIB_KOMMENTATOR], currentPieceTags: [GetTagForJingle(part.segmentExternalId, parsedCue.clip)], - nextPieceTags: [GetTagForJingleNext(part.segmentExternalId, parsedCue.clip)], - noHotKey: true + nextPieceTags: [GetTagForJingleNext(part.segmentExternalId, parsedCue.clip)] } }) ) diff --git a/yarn.lock b/yarn.lock index 7d324fdd0..d6ce9233d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -570,13 +570,13 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== -"@tv2media/blueprints-integration@1.41.2": - version "1.41.2" - resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-1.41.2.tgz#7c9552b59653180eb1bcbac784e8d3c7bbbaf46b" - integrity sha512-lZseNPtrKDKuAboQyEL5qypU3RkfdCTHPdXSQKQz53+8fcc/59AJPAwQWETnJbpuJ2wfOzBTDBFsMmVYady2cA== +"@tv2media/blueprints-integration@1.42.5": + version "1.42.5" + resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-1.42.5.tgz#872e603d8107bab34dd26af4187d82b39ed74b98" + integrity sha512-8vIbTTHosvdex4Fqb3Eay7STss4fSvv3JuWLYe28dczzpwcLTyAwuNgElpwBrfaoRFkpLGIvO8hvAae/Uh7I5A== dependencies: moment "2.29.1" - timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@1.0.0-release37" + timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@2.0.0" tslib "^2.3.1" type-fest "^2.11.1" @@ -6049,10 +6049,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@1.0.0-release37.7": - version "1.0.0-release37.7" - resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-1.0.0-release37.7.tgz#2cb32cd81343c1ed3d160f6f63b909f2a3f47935" - integrity sha512-o5DbFCJRMLHGrzoVjhjAAsZ+F90EjuKrwk7kfVlplMosouv4Kw4cucUQGOU26DzIM8tTlmIkadnZGMnT5sCmUA== +"timeline-state-resolver-types@npm:@tv2media/timeline-state-resolver-types@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-2.0.0.tgz#0af6ed0c1d69bd6c27b77c175f4fedf204ef8505" + integrity sha512-hfNrbMp9fPV5ItBM1MqDNLOxlzRJGEMb2HyY9Blr1+5ql7ap+eeb8XkH2asIJAljIyHjJ1MwKjjqLgfEYY6h0w== dependencies: tslib "^2.3.1" From 2373ddae6579777a8bcba28cee78c67cf2e8adbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Wed, 4 May 2022 11:33:32 +0200 Subject: [PATCH 096/184] refactor: Removed dead code. --- src/tv2-common/content/dve.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 3f7012594..4e82197f8 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -229,8 +229,6 @@ export function MakeContentDVE2< classes.push(`${fromCue.replace(/\s/g, '')}_${dveGeneratorOptions.boxMappings[targetBox - 1]}`) - let usedServer = false - if (sources) { const prop = sources[fromCue as keyof DVESources] if (prop?.match(/[K|C]AM(?:era)? ?.*/i)) { @@ -254,16 +252,14 @@ export function MakeContentDVE2< } else if (prop?.match(/DEFAULT/)) { boxMap[targetBox - 1] = { source: `DEFAULT SOURCE` } } else if (prop) { - if (videoId && !usedServer) { + if (videoId) { boxMap[targetBox - 1] = { source: `SERVER ${videoId}` } - usedServer = true } else { boxMap[targetBox - 1] = { source: prop } } } else { - if (videoId && !usedServer) { + if (videoId) { boxMap[targetBox - 1] = { source: `SERVER ${videoId}` } - usedServer = true } else { context.notifyUserWarning(`Missing mapping for ${targetBox}`) boxMap[targetBox - 1] = { source: '' } @@ -450,7 +446,7 @@ export function MakeContentDVE2< let frameFile = dveConfig.DVEGraphicsFrame ? dveConfig.DVEGraphicsFrame.toString() : undefined if (keyFile) { - keyFile = keyFile = JoinAssetToFolder(config.studio.DVEFolder, keyFile) + keyFile = JoinAssetToFolder(config.studio.DVEFolder, keyFile) } if (frameFile) { From 6ca00f965db9c7b4837996b7f2aedef75d4fe794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Wed, 4 May 2022 11:37:31 +0200 Subject: [PATCH 097/184] fix: More simple and flexible dpName matching for EVS. Since label and name for adlib actions and keyboard preview are the same, changing 'EVS 1' to 'EVS 1 100%' was looking for the source '1100' instead of '1'. --- src/tv2-common/sources.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/tv2-common/sources.ts b/src/tv2-common/sources.ts index d09654572..2e1e49e73 100644 --- a/src/tv2-common/sources.ts +++ b/src/tv2-common/sources.ts @@ -104,10 +104,7 @@ export function FindSourceInfo(sources: SourceInfo[], type: SourceInfoType, id: return _.find(sources, s => s.type === type && s.id === `S${remoteName[1]}`) } case SourceLayerType.LOCAL: - const dpName = id - .replace(/VO/i, '') - .replace(/\s/g, '') - .match(/^(?:EVS) ?(.+).*$/i) + const dpName = id.match(/^(?:EVS)\s*(\d+).*$/i) if (!dpName) { return undefined } From 79def58fd9a26eebe942a0c587f35dd26a5c868b Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Thu, 5 May 2022 13:23:05 +0200 Subject: [PATCH 098/184] SOF-693 Able to parse DESIGN_LAYOUT and DESIGN_BG cues from iNews. Implemented inital draft of Schema/Design config --- src/tv2-common/blueprintConfig.ts | 8 +++ src/tv2-common/getSegment.ts | 7 +-- .../inewsConversion/converters/ParseCue.ts | 46 ++++++++++++++++- src/tv2-common/types/inews.ts | 1 + .../__tests__/config-manifest.spec.ts | 3 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 3 +- src/tv2_afvd_showstyle/config-manifests.ts | 50 +++++++++++++++++++ .../__tests__/config-manifest.spec.ts | 3 +- src/tv2_offtube_showstyle/config-manifests.ts | 46 +++++++++++++++++ 9 files changed, 158 insertions(+), 9 deletions(-) diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index f680522a3..7d9daa1b6 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -30,6 +30,13 @@ export interface TableConfigItemAdLibTransitions { Transition: string } +export interface TableConfigSchema { + schemaName: string + designIdentifier: string + vizTemplateName: string + casparCgDveBgScene: string +} + export interface TableConfigGraphicsSetup { INewsCode: string Concept: string @@ -130,6 +137,7 @@ export interface TV2ShowstyleBlueprintConfigBase { ShowstyleTransition: string MakeAdlibsForFulls: boolean LYDConfig: TableConfigItemValue + SchemaConfig: TableConfigSchema[] } export interface TV2BlueprintConfigBase diff --git a/src/tv2-common/getSegment.ts b/src/tv2-common/getSegment.ts index a034849e8..1db8ee4c9 100644 --- a/src/tv2-common/getSegment.ts +++ b/src/tv2-common/getSegment.ts @@ -132,7 +132,7 @@ export function getSegmentBase< const totalTimeMs = TimeFromINewsField(iNewsStory.fields.totalTime) * 1000 let blueprintParts: BlueprintResultPart[] = [] - const parsedParts = ParseBody( + const parsedParts: PartDefinition[] = ParseBody( config, ingestSegment.externalId, ingestSegment.name, @@ -346,10 +346,7 @@ export function getSegmentBase< blueprintParts[0].part.budgetDuration = totalTimeMs } - if ( - blueprintParts.filter(part => part.part.invalid === true).length === blueprintParts.length && - iNewsStory.cues.length === 0 - ) { + if (blueprintParts.every(part => part.part.invalid) && iNewsStory.cues.length === 0) { segment.isHidden = true } diff --git a/src/tv2-common/inewsConversion/converters/ParseCue.ts b/src/tv2-common/inewsConversion/converters/ParseCue.ts index b9476f8b1..0af8de903 100644 --- a/src/tv2-common/inewsConversion/converters/ParseCue.ts +++ b/src/tv2-common/inewsConversion/converters/ParseCue.ts @@ -1,4 +1,4 @@ -import { GetInfiniteModeForGraphic, literal, TV2BlueprintConfig, UnparsedCue } from 'tv2-common' +import { GetInfiniteModeForGraphic, literal, TableConfigSchema, TV2BlueprintConfig, UnparsedCue } from 'tv2-common' import { CueType, GraphicEngine, PartType } from 'tv2-constants' import { getTransitionProperties, PartDefinition, PartdefinitionTypes, stripTransitionProperties } from './ParseBody' @@ -233,6 +233,10 @@ export function ParseCue(cue: UnparsedCue, config: TV2BlueprintConfig): CueDefin return parsePgmClean(cue) } else if (cue[0].match(/^MINUSKAM\s*=/i)) { return parseMixMinus(cue) + } else if (cue[0].match(/^DESIGN_LAYOUT=/i)) { + return parseDesignLayout(cue, config) + } else if (cue[0].match(/^DESIGN_BG=/i)) { + return parseDesignBg(cue, config) } return literal({ @@ -841,6 +845,46 @@ export function parseTime(line: string): Pick({ + type: CueType.GraphicDesign, + design: tableConfigSchema.vizTemplateName, + iNewsCommand: layout, + start: { + frames: 1 + } + }) +} + +function findSchemaConfiguration(config: TV2BlueprintConfig, designIdentifier: string): TableConfigSchema | undefined { + return config.showStyle.SchemaConfig.find( + schema => schema.designIdentifier && schema.designIdentifier.toUpperCase() === designIdentifier.toUpperCase() + ) +} + +function parseDesignBg(cue: string[], config: TV2BlueprintConfig): CueDefinitionBackgroundLoop | undefined { + const array = cue[0].split('DESIGN_BG=') + const layout = array[1] + const tableConfigSchema = findSchemaConfiguration(config, layout) + if (!tableConfigSchema) { + return undefined + } + + return literal({ + type: CueType.BackgroundLoop, + target: 'DVE', + backgroundLoop: tableConfigSchema.casparCgDveBgScene, + iNewsCommand: layout + }) +} + /** * Creates a parent class for a part, for keeping children of the parent alive when the parent is alive. * @param studio Studio name that the part belongs to. diff --git a/src/tv2-common/types/inews.ts b/src/tv2-common/types/inews.ts index 936e592e2..21ca5f707 100644 --- a/src/tv2-common/types/inews.ts +++ b/src/tv2-common/types/inews.ts @@ -7,6 +7,7 @@ export interface INewsFields { totalTime?: string // number cumeTime?: string // number backTime?: string // @number (seconds since midnight) + layout?: string } export interface INewsMetaData { diff --git a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts index e22721bb4..ef03b6536 100644 --- a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts @@ -14,7 +14,8 @@ const blankShowStyleConfig: ShowStyleConfig = { Transitions: [{ Transition: '1' }, { Transition: '2' }], ShowstyleTransition: 'CUT', GraphicsINewsCode: '', - GraphicsSetups: [] + GraphicsSetups: [], + SchemaConfig: [] } describe('Config Manifest', () => { diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index ba44ee61c..2513953ff 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -265,5 +265,6 @@ export const defaultShowStyleConfig: ShowStyleConfig = { GraphicsINewsCode: 'SomeProfile', GraphicsSetups: [DEFAULT_GRAPHICS_SETUP], Transitions: [{ Transition: '1' }, { Transition: '2' }], - ShowstyleTransition: 'CUT' + ShowstyleTransition: 'CUT', + SchemaConfig: [] } diff --git a/src/tv2_afvd_showstyle/config-manifests.ts b/src/tv2_afvd_showstyle/config-manifests.ts index 3c411c537..b2ad4ae6c 100644 --- a/src/tv2_afvd_showstyle/config-manifests.ts +++ b/src/tv2_afvd_showstyle/config-manifests.ts @@ -203,6 +203,55 @@ const graphicProfileSetup: ConfigManifestEntry[] = [ } ] +export const schemaConfigManifest: ConfigManifestEntry[] = [ + { + id: 'SchemaConfig', + name: 'Skema', + description: 'The values for the Skema and Design combinations', + type: ConfigManifestEntryType.TABLE, + required: false, + defaultVal: [], + columns: [ + { + id: 'schemaName', + name: 'Skema', + description: 'The name of the Skema', + rank: 0, + required: true, + defaultVal: '', + type: ConfigManifestEntryType.STRING + }, + { + id: 'designIdentifier', + name: 'Design', + description: 'The identifier of the Design', + rank: 1, + required: true, + defaultVal: '', + type: ConfigManifestEntryType.STRING + }, + { + id: 'vizTemplateName', + name: 'Viz Template Name', + description: 'The name of the Viz template', + rank: 2, + required: true, + defaultVal: '', + type: ConfigManifestEntryType.STRING + }, + { + id: 'casparCgDveBgScene', + name: 'CasparCG DVE Bg Scene', + description: 'The dveBgScene', + defaultVal: '', + rank: 3, + required: true, + type: ConfigManifestEntryType.STRING + } + ] + } +] + export const showStyleConfigManifest: ConfigManifestEntry[] = [ { id: 'MakeAdlibsForFulls', @@ -325,6 +374,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ ] }, ...graphicProfileSetup, + ...schemaConfigManifest, { /* Wipes Config diff --git a/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts index 28726caeb..f162b4cf0 100644 --- a/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/config-manifest.spec.ts @@ -12,7 +12,8 @@ const blankShowStyleConfig: OfftubeShowStyleConfig = { CasparCGLoadingClip: '', Transitions: [{ Transition: '1' }, { Transition: '2' }], ShowstyleTransition: 'CUT', - MakeAdlibsForFulls: true + MakeAdlibsForFulls: true, + SchemaConfig: [] } describe('Config Manifest', () => { diff --git a/src/tv2_offtube_showstyle/config-manifests.ts b/src/tv2_offtube_showstyle/config-manifests.ts index af30f36bf..96716b859 100644 --- a/src/tv2_offtube_showstyle/config-manifests.ts +++ b/src/tv2_offtube_showstyle/config-manifests.ts @@ -515,5 +515,51 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ rank: 0 } ] + }, + { + id: 'SchemaConfig', + name: 'Skema', + description: 'The values for the Skema and Design combinations', + type: ConfigManifestEntryType.TABLE, + required: false, + defaultVal: [], + columns: [ + { + id: 'schemaName', + name: 'Skema', + description: 'The name of the Skema', + rank: 0, + required: true, + defaultVal: '', + type: ConfigManifestEntryType.STRING + }, + { + id: 'designIdentifier', + name: 'Design', + description: 'The identifier of the Design', + rank: 1, + required: true, + defaultVal: '', + type: ConfigManifestEntryType.STRING + }, + { + id: 'vizTemplateName', + name: 'Viz Template Name', + description: 'The name of the Viz template', + rank: 2, + required: true, + defaultVal: '', + type: ConfigManifestEntryType.STRING + }, + { + id: 'casparCgDveBgScene', + name: 'CasparCG DVE Bg Scene', + description: 'The dveBgScene', + defaultVal: '', + rank: 3, + required: true, + type: ConfigManifestEntryType.STRING + } + ] } ] From e7036cee6297dca3471fb3ac283fe906bcff8b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Thu, 5 May 2022 13:23:34 +0200 Subject: [PATCH 099/184] fix: Change default config for bundright. --- src/tv2-common/migrations/graphic-defaults.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tv2-common/migrations/graphic-defaults.ts b/src/tv2-common/migrations/graphic-defaults.ts index 7fa372547..87ec64d88 100644 --- a/src/tv2-common/migrations/graphic-defaults.ts +++ b/src/tv2-common/migrations/graphic-defaults.ts @@ -156,10 +156,10 @@ export const DEFAULT_GRAPHICS: TV2ShowstyleBlueprintConfigBase['GFXTemplates'] = INewsName: 'bundright', VizTemplate: 'bund_right', VizDestination: 'OVL1', - OutType: 'S', + OutType: '', IsDesign: false, - SourceLayer: 'studio0_graphicsTema', - LayerMapping: 'graphic_overlay_tema' + SourceLayer: 'studio0_graphicsLower', + LayerMapping: 'graphic_overlay_lower' }, { INewsCode: 'KG=', From a21200d491a788358f5bfc6ad758b8a002bbf717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Fri, 6 May 2022 09:43:14 +0200 Subject: [PATCH 100/184] fix: Added migration for bundright configuration. --- package.json | 2 +- src/tv2-common/migrations/index.ts | 36 +++++++++++++++++++ src/tv2_afvd_showstyle/migrations/index.ts | 32 ++++++++++++++++- src/tv2_offtube_showstyle/migrations/index.ts | 34 ++++++++++++++++-- 4 files changed, 100 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index c5a22df82..ea9dcdf0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tv2-sofie-blueprints-inews", - "version": "1.7.1", + "version": "1.7.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 5622dfe36..da81986a0 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -121,6 +121,42 @@ export function AddGraphicToGFXTable(versionStr: string, studio: string, config: }) } +export function changeGFXTemplate( + versionStr: string, + studio: string, + oldConfig: TableConfigItemGFXTemplates, + config: TableConfigItemGFXTemplates +) { + return literal({ + id: `${versionStr}.gfxConfig.change${config.INewsName}.${studio}`, + version: versionStr, + canBeRunAutomatically: true, + validate: (context: MigrationContextShowStyle) => { + const gfxTemplates = (context.getBaseConfig('GFXTemplates') as unknown) as TableConfigItemGFXTemplates[] | undefined + + if (!gfxTemplates || !gfxTemplates.length) { + return false + } + + return gfxTemplates.some(g => compareGfxTemplate(g, oldConfig)) + }, + migrate: (context: MigrationContextShowStyle) => { + let existing = (context.getBaseConfig('GFXTemplates') as unknown) as TableConfigItemGFXTemplates[] + + existing = existing.map(g => (compareGfxTemplate(g, oldConfig) ? config : g)) + + context.setBaseConfig('GFXTemplates', (existing as unknown) as ConfigItemValue) + } + }) +} + +function compareGfxTemplate(template1: TableConfigItemGFXTemplates, template2: TableConfigItemGFXTemplates): boolean { + return Object.keys(template2).reduce( + (acc: boolean, key: keyof TableConfigItemGFXTemplates) => acc && template1[key] === template2[key], + true + ) +} + export function SetLayerNamesToDefaults( versionStr: string, studio: string, diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 3ce3e2012..b606d6ffe 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -1,6 +1,7 @@ import { MigrationStepShowStyle, SourceLayerType } from '@tv2media/blueprints-integration' import { AddGraphicToGFXTable, + changeGFXTemplate, GetDefaultAdLibTriggers, GetDSKSourceLayerNames, literal, @@ -178,7 +179,7 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal Date: Fri, 6 May 2022 09:51:17 +0200 Subject: [PATCH 101/184] chore: Updated from deprecated ConfigManifestEntryType.NUMBER to .INT. --- src/tv2-common/helpers/dsk.ts | 6 +-- src/tv2-common/migrations/sourceManifest.ts | 2 +- src/tv2_afvd_showstyle/config-manifests.ts | 20 ++++---- src/tv2_afvd_studio/config-manifests.ts | 46 +++++++++--------- src/tv2_offtube_showstyle/config-manifests.ts | 20 ++++---- src/tv2_offtube_studio/config-manifests.ts | 48 +++++++++---------- 6 files changed, 71 insertions(+), 71 deletions(-) diff --git a/src/tv2-common/helpers/dsk.ts b/src/tv2-common/helpers/dsk.ts index d84d33efc..bbf628afe 100644 --- a/src/tv2-common/helpers/dsk.ts +++ b/src/tv2-common/helpers/dsk.ts @@ -206,7 +206,7 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { id: 'Number', name: 'Number', description: 'DSK number, starting from 1', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 1, rank: 0, @@ -216,7 +216,7 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { id: 'Fill', name: 'ATEM Fill', description: 'ATEM vision mixer input for DSK Fill', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 21, rank: 1 @@ -225,7 +225,7 @@ export function DSKConfigManifest(defaultVal: TableConfigItemDSK[]) { id: 'Key', name: 'ATEM Key', description: 'ATEM vision mixer input for DSK Key', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 34, rank: 2 diff --git a/src/tv2-common/migrations/sourceManifest.ts b/src/tv2-common/migrations/sourceManifest.ts index 3871bc4ad..2faa53796 100644 --- a/src/tv2-common/migrations/sourceManifest.ts +++ b/src/tv2-common/migrations/sourceManifest.ts @@ -28,7 +28,7 @@ export function MakeConfigForSources( id: 'AtemSource', name: 'ATEM input', description: `ATEM vision mixer input for ${displayName} input`, - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 1 diff --git a/src/tv2_afvd_showstyle/config-manifests.ts b/src/tv2_afvd_showstyle/config-manifests.ts index 2d4c921d6..4beb0e0a5 100644 --- a/src/tv2_afvd_showstyle/config-manifests.ts +++ b/src/tv2_afvd_showstyle/config-manifests.ts @@ -333,7 +333,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'EffektNumber', name: 'Effekt Number', description: 'The Effect Number', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 0 @@ -351,7 +351,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'Duration', name: 'Effekt Duration', description: 'Duration of the effekt', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 2 @@ -360,7 +360,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'StartAlpha', name: 'Alpha at Start', description: 'Number of frames of alpha at start', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 3 @@ -369,7 +369,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'EndAlpha', name: 'Alpha at End', description: 'Number of frames of alpha at end', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 4 @@ -424,7 +424,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'Duration', name: 'Effekt Duration', description: 'Duration of the effekt', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 2 @@ -433,7 +433,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'StartAlpha', name: 'Alpha at Start', description: 'Number of frames of alpha at start', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 3 @@ -442,7 +442,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'EndAlpha', name: 'Alpha at End', description: 'Number of frames of alpha at end', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 4 @@ -471,7 +471,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'DefaultTemplateDuration', name: 'Default Template Duration', description: 'Default Template Duration', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 4 }, @@ -516,7 +516,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'FadeIn', name: 'Fade In', description: 'ms duration to fade in file', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 1000, rank: 2 @@ -525,7 +525,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'FadeOut', name: 'Fade Out', description: 'ms duration to fade out file', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 1000, rank: 3 diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index 5d7beeb40..0934dfc6e 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -308,7 +308,7 @@ export const manifestAFVDSourcesABMediaPlayers: ConfigManifestEntryTable = { id: 'AtemSource', name: 'ATEM input', description: 'ATEM vision mixer input for Media player', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 1 @@ -357,7 +357,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AtemSource.SplitArtF', name: 'ATEM Split Screen Art Fill', description: 'ATEM vision mixer input for Split Screen Art Fill', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 30 }, @@ -365,7 +365,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AtemSource.SplitArtK', name: 'ATEM Split Screen Art Key', description: 'ATEM vision mixer input for Split Screen Art Key', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 32 }, @@ -373,7 +373,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AtemSource.Default', name: 'ATEM Default source', description: 'ATEM vision mixer default source', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col1 }, @@ -381,7 +381,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AtemSource.MixMinusDefault', name: 'ATEM Mix-minus default source', description: 'ATEM vision mixer default source for mix-minus', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col1 }, @@ -389,7 +389,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AtemSource.Continuity', name: 'ATEM continuity source', description: 'ATEM input for continuity', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col2 }, @@ -397,7 +397,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AtemSettings.MP1Baseline.Clip', name: 'ATEM MP1 baseline clip number', description: 'Number of the clip to play on MP1 (counting from 1)', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 1 }, @@ -421,7 +421,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AudioBedSettings.fadeIn', name: 'Bed Fade In', description: 'Default fade in duration for audio beds', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 25 }, @@ -429,7 +429,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AudioBedSettings.volume', name: 'Bed Volume', description: 'Volume (0 - 100)', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 80 }, @@ -437,7 +437,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AudioBedSettings.fadeOut', name: 'Bed Fade Out', description: 'Default fade out duration for audio beds', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 25 }, @@ -445,7 +445,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'CasparPrerollDuration', name: 'Caspar preroll duration', description: 'ms of preroll before switching to caspar', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 200 // 5 frames }, @@ -453,7 +453,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'MaximumPartDuration', name: 'Maximum Part Duration', description: 'Maximum duration (ms) to give parts in UI', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 10000 }, @@ -461,7 +461,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'DefaultPartDuration', name: 'Default Part Duration', description: 'Duration to give parts by default', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 4000 }, @@ -469,7 +469,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'ServerPostrollDuration', name: 'Server Postroll Duration', description: 'ms of postroll at the end of Server and VO clips', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0 }, @@ -496,7 +496,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'HTMLGraphics.KeepAliveDuration', name: 'Full Keep Alive Duration (HTML)', description: 'How long to keep the old part alive when going to a full', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 1000 }, @@ -504,7 +504,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'HTMLGraphics.TransitionSettings.borderSoftness', name: 'Full graphic wipe softness (HTML)', description: 'Border softness of full graphic background wipe', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 7500 }, @@ -512,7 +512,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'HTMLGraphics.TransitionSettings.loopOutTransitionDuration', name: 'Full graphic background loop out transition duration', description: 'Duration (ms) that the background loop behind a full takes to transition out', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 120 }, @@ -520,7 +520,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'HTMLGraphics.TransitionSettings.wipeRate', name: 'Full graphic background loop wipe duration (HTML)', description: 'Frames (max 250) over which to wipe background loop behind Full', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 10 }, @@ -528,7 +528,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'VizPilotGraphics.CutToMediaPlayer', name: 'Pilot media Player Cut Point', description: 'ms from start of grafik before switching to background source', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 500 }, @@ -536,7 +536,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'VizPilotGraphics.FullGraphicBackground', name: 'Full frame grafik background source', description: 'ATEM source for mos full-frame grafik background source', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 36 }, @@ -544,7 +544,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'VizPilotGraphics.KeepAliveDuration', name: 'Pilot Keepalive Duration', description: 'ms to keep old part alive before switching to Pilot elements', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 2000 }, @@ -552,7 +552,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'VizPilotGraphics.OutTransitionDuration', name: 'Pilot Out Transition Duration', description: 'ms to keep pilot elements alive before transition to next part', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 1000 }, @@ -560,7 +560,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'VizPilotGraphics.PrerollDuration', name: 'Pilot Preroll Duration', description: 'ms of preroll before switching to Pilot elements', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 2000 }, diff --git a/src/tv2_offtube_showstyle/config-manifests.ts b/src/tv2_offtube_showstyle/config-manifests.ts index af30f36bf..e5717addf 100644 --- a/src/tv2_offtube_showstyle/config-manifests.ts +++ b/src/tv2_offtube_showstyle/config-manifests.ts @@ -289,7 +289,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'EffektNumber', name: 'Effekt Number', description: 'The Effect Number', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 0 @@ -307,7 +307,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'Duration', name: 'Effekt Duration', description: 'Duration of the effekt', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 2 @@ -316,7 +316,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'StartAlpha', name: 'Alpha at Start', description: 'Number of frames of alpha at start', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 3 @@ -325,7 +325,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'EndAlpha', name: 'Alpha at End', description: 'Number of frames of alpha at end', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 4 @@ -380,7 +380,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'Duration', name: 'Effekt Duration', description: 'Duration of the effekt', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 2 @@ -389,7 +389,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'StartAlpha', name: 'Alpha at Start', description: 'Number of frames of alpha at start', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 3 @@ -398,7 +398,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'EndAlpha', name: 'Alpha at End', description: 'Number of frames of alpha at end', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 4 @@ -427,7 +427,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'DefaultTemplateDuration', name: 'Default Template Duration', description: 'Default Template Duration', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 4 }, @@ -472,7 +472,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'FadeIn', name: 'Fade In', description: 'ms duration to fade in file', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 1000, rank: 2 @@ -481,7 +481,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ id: 'FadeOut', name: 'Fade Out', description: 'ms duration to fade out file', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 1000, rank: 3 diff --git a/src/tv2_offtube_studio/config-manifests.ts b/src/tv2_offtube_studio/config-manifests.ts index c7f19839c..9718b8d0d 100644 --- a/src/tv2_offtube_studio/config-manifests.ts +++ b/src/tv2_offtube_studio/config-manifests.ts @@ -99,7 +99,7 @@ export const manifestOfftubeSourcesABMediaPlayers: ConfigManifestEntryTable = { id: 'AtemSource', name: 'ATEM input', description: 'ATEM vision mixer input for Media player', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0, rank: 1 @@ -147,7 +147,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AtemSource.SplitArtF', name: 'ATEM Split Screen Art Fill', description: 'ATEM vision mixer input for Split Screen Art Fill', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 10 }, @@ -155,7 +155,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AtemSource.SplitArtK', name: 'ATEM Split Screen Art Key', description: 'ATEM vision mixer input for Split Screen Art Key', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 9 }, @@ -163,7 +163,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AtemSource.SplitBackground', name: 'ATEM split screen background loop source', description: 'ATEM source for mos full-frame grafik background source', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 11 }, @@ -171,7 +171,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AtemSource.Loop', name: 'Studio screen loop graphics source', description: 'ATEM source for loop for studio screen', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 12 }, @@ -179,7 +179,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AtemSource.Default', name: 'ATEM Default source', description: 'ATEM vision mixer default source', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col1 }, @@ -187,7 +187,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AtemSource.Continuity', name: 'ATEM continuity source', description: 'ATEM input for continuity', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: AtemSourceIndex.Col2 }, @@ -195,7 +195,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AudioBedSettings.fadeIn', name: 'Bed Fade In', description: 'Default fade in duration for audio beds', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 25 }, @@ -203,7 +203,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AudioBedSettings.volume', name: 'Bed Volume', description: 'Volume (0 - 100)', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 80 }, @@ -211,7 +211,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'AudioBedSettings.fadeOut', name: 'Bed Fade Out', description: 'Default fade out duration for audio beds', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 25 }, @@ -219,7 +219,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'CasparPrerollDuration', name: 'Caspar preroll duration', description: 'ms of preroll before switching to caspar', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 200 // 5 frames }, @@ -227,7 +227,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'MaximumPartDuration', name: 'Maximum Part Duration', description: 'Maximum duration (ms) to give parts in UI', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 10000 }, @@ -235,7 +235,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'DefaultPartDuration', name: 'Default Part Duration', description: 'Duration to give parts by default', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 4000 }, @@ -243,7 +243,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'IdleSource', name: 'Idle Source', description: 'Source to display when studio is off-air', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 1 }, @@ -263,7 +263,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'ServerPostrollDuration', name: 'Server Postroll Duration', description: 'ms of postroll at the end of Server and VO clips', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: true, defaultVal: 0 }, @@ -290,7 +290,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'HTMLGraphics.KeepAliveDuration', name: 'Full Keep Alive Duration (HTML)', description: 'How long to keep the old part alive when going to a full', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 1000 }, @@ -298,7 +298,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'HTMLGraphics.TransitionSettings.borderSoftness', name: 'Full graphic wipe softness (HTML)', description: 'Border softness of full graphic background wipe', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 7500 }, @@ -306,7 +306,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'HTMLGraphics.TransitionSettings.loopOutTransitionDuration', name: 'Full graphic background loop out transition duration', description: 'Duration (ms) that the background loop behind a full takes to transition out', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 120 }, @@ -314,7 +314,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'HTMLGraphics.TransitionSettings.wipeRate', name: 'Full graphic background loop wipe duration (HTML)', description: 'Frames (max 250) over which to wipe background loop behind Full', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 10 }, @@ -322,7 +322,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'VizPilotGraphics.CutToMediaPlayer', name: 'Pilot media Player Cut Point', description: 'ms from start of grafik before switching to background source', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 500 }, @@ -330,7 +330,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'VizPilotGraphics.KeepAliveDuration', name: 'Pilot Keepalive Duration', description: 'ms to keep old part alive before switching to Pilot elements', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 2000 }, @@ -338,7 +338,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'VizPilotGraphics.OutTransitionDuration', name: 'Pilot Out Transition Duration', description: 'ms to keep pilot elements alive before transition to next part', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 1000 }, @@ -346,7 +346,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'VizPilotGraphics.PrerollDuration', name: 'Pilot Preroll Duration', description: 'ms of preroll before switching to Pilot elements', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 2000 }, @@ -354,7 +354,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ id: 'VizPilotGraphics.FullGraphicBackground', name: 'Full frame grafik background source', description: 'ATEM source for mos full-frame grafik background source', - type: ConfigManifestEntryType.NUMBER, + type: ConfigManifestEntryType.INT, required: false, defaultVal: 0 }, From 0777666a614b002353e49ac5171b8493794b771d Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Fri, 6 May 2022 12:54:56 +0200 Subject: [PATCH 102/184] SOF-903 Dont cut to boxes on current DVE if the current DVE has stopped playback --- 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 85ac1d3c9..da42e7051 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -536,7 +536,7 @@ async function executeActionSelectDVE< const config = settings.getConfig(context) - const parsedCue = userData.config + const parsedCue: CueDefinitionDVE = userData.config const rawTemplate = GetDVETemplate(config.showStyle.DVEStyles, parsedCue.template) if (!rawTemplate) { @@ -727,7 +727,7 @@ async function executeActionSelectDVELayout< const nextDVE = await context .getPieceInstances('next') - .then(nextInstances => nextInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE)) + .then(nextPieceInstances => nextPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE)) const meta = nextDVE?.piece.metaData as DVEPieceMetaData @@ -1250,8 +1250,8 @@ async function executeActionCutSourceToBox< ) { const config = settings.getConfig(context) - const currentPieces = await context.getPieceInstances('current') - const nextPieces = await context.getPieceInstances('next') + const currentPieces: IBlueprintPieceInstance[] = await context.getPieceInstances('current') + const nextPieces: IBlueprintPieceInstance[] = await context.getPieceInstances('next') const currentDVE = currentPieces.find( p => @@ -1274,7 +1274,7 @@ async function executeActionCutSourceToBox< let modifiedPiece: IBlueprintPieceInstance | undefined let modifiedDataStore: IBlueprintPieceInstance | undefined - if (currentDVE) { + if (currentDVE && currentDVE.stoppedPlayback === undefined) { modify = 'current' modifiedPiece = currentDVE modifiedDataStore = currentDataStore From 2d66d7cf957520cd13f56b73f5dced07b48d22af Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Mon, 9 May 2022 08:37:51 +0200 Subject: [PATCH 103/184] SOF-925 Minor lint fix --- src/tv2_afvd_showstyle/getRundown.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index a6c33aa24..9cf6c06f1 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -35,9 +35,9 @@ import { GetSisyfosTimelineObjForEkstern, GetTransitionAdLibActions, literal, + localSourceName, PieceMetaData, SisyfosPersistMetaData, - localSourceName, SourceInfo, t } from 'tv2-common' From 73920b62069b89c42ec92ee781a773c52b542727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Mon, 9 May 2022 09:48:41 +0200 Subject: [PATCH 104/184] lint: Fixed linting error. --- src/tv2-common/content/dve.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 4e82197f8..d8c816f69 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -252,11 +252,7 @@ export function MakeContentDVE2< } else if (prop?.match(/DEFAULT/)) { boxMap[targetBox - 1] = { source: `DEFAULT SOURCE` } } else if (prop) { - if (videoId) { - boxMap[targetBox - 1] = { source: `SERVER ${videoId}` } - } else { - boxMap[targetBox - 1] = { source: prop } - } + boxMap[targetBox - 1] = { source: videoId ? `SERVER ${videoId}` : prop } } else { if (videoId) { boxMap[targetBox - 1] = { source: `SERVER ${videoId}` } From b67acc8d2440578435ffb697395cc99abb979d2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Tue, 10 May 2022 09:26:46 +0200 Subject: [PATCH 105/184] fix: changeGfxTemplate can now update a subset instead of entire template. --- src/tv2-common/migrations/index.ts | 25 +++++++++------- src/tv2_afvd_showstyle/migrations/index.ts | 30 +++++++++++++------ src/tv2_offtube_showstyle/migrations/index.ts | 30 +++++++++++++------ 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index da81986a0..443611804 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -124,37 +124,40 @@ export function AddGraphicToGFXTable(versionStr: string, studio: string, config: export function changeGFXTemplate( versionStr: string, studio: string, - oldConfig: TableConfigItemGFXTemplates, - config: TableConfigItemGFXTemplates + oldConfig: Partial, + config: Partial ) { + const keysToUpdate = Object.keys(config).join('_') return literal({ - id: `${versionStr}.gfxConfig.change${config.INewsName}.${studio}`, + id: `${versionStr}.gfxConfig.change_${keysToUpdate}.${studio}`, version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextShowStyle) => { - const gfxTemplates = (context.getBaseConfig('GFXTemplates') as unknown) as TableConfigItemGFXTemplates[] | undefined + const gfxTemplates = (context.getBaseConfig('GFXTemplates') as unknown) as + | TableConfigItemGFXTemplates[] + | undefined if (!gfxTemplates || !gfxTemplates.length) { return false } - return gfxTemplates.some(g => compareGfxTemplate(g, oldConfig)) + return gfxTemplates.some(g => isGfxTemplateSubset(g, oldConfig)) }, migrate: (context: MigrationContextShowStyle) => { let existing = (context.getBaseConfig('GFXTemplates') as unknown) as TableConfigItemGFXTemplates[] - existing = existing.map(g => (compareGfxTemplate(g, oldConfig) ? config : g)) + existing = existing.map(g => (isGfxTemplateSubset(g, oldConfig) ? { ...g, ...config } : g)) context.setBaseConfig('GFXTemplates', (existing as unknown) as ConfigItemValue) } }) } -function compareGfxTemplate(template1: TableConfigItemGFXTemplates, template2: TableConfigItemGFXTemplates): boolean { - return Object.keys(template2).reduce( - (acc: boolean, key: keyof TableConfigItemGFXTemplates) => acc && template1[key] === template2[key], - true - ) +function isGfxTemplateSubset( + superset: Partial, + subset: Partial +): boolean { + return Object.keys(subset).every((key: keyof TableConfigItemGFXTemplates) => superset[key] === subset[key]) } export function SetLayerNamesToDefaults( diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index b606d6ffe..94e5847cd 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -212,20 +212,32 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal Date: Wed, 11 May 2022 15:31:02 +0200 Subject: [PATCH 106/184] fix: Removed F5 from custom hotkey labels. The generated AutoHotKey script broke F5 cut to cam 5 functionality, since it mapped to an unused key combo. --- shelf-layouts/AFVD_Default_showstyle_hotkeys.json | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/shelf-layouts/AFVD_Default_showstyle_hotkeys.json b/shelf-layouts/AFVD_Default_showstyle_hotkeys.json index d7c7f417f..4933aed9a 100644 --- a/shelf-layouts/AFVD_Default_showstyle_hotkeys.json +++ b/shelf-layouts/AFVD_Default_showstyle_hotkeys.json @@ -453,12 +453,5 @@ "label": "serv inp 2", "sourceLayerType": 2, "platformKey": "ctrl+T" - }, - { - "_id": "n8nZWWRcHSkrG7GqM", - "key": "SHIFT+ctrl+alt+c", - "label": "KAM 5", - "sourceLayerType": 1, - "platformKey": "F5" } -] \ No newline at end of file +] From dc4ead829a97ae7a339b217398368ab049db5b99 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Tue, 17 May 2022 08:21:26 +0200 Subject: [PATCH 107/184] Now uses license-checker instead of node-license-validator --- package.json | 6 +- yarn.lock | 380 +++++++++++++++++---------------------------------- 2 files changed, 129 insertions(+), 257 deletions(-) diff --git a/package.json b/package.json index 9089ee5fe..546731af4 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,9 @@ "test": "yarn lint --fix && yarn unit", "release": "standard-version", "prepareChangelog": "standard-version --prerelease", - "validate": "yarn validate:dependencies && yarn license-validate", + "validate": "yarn validate:dependencies", "validate:dependencies": "yarn audit --groups dependencies && yarn license-validate", - "license-validate": "node-license-validator -p -d --allow-licenses MIT MIT/X11 BSD BSD-3-Clause 0BSD ISC Apache Unlicense" + "license-validate": "license-checker --onlyAllow MIT;Apache-2.0;ISC;BSD;CC0;CC-BY-3.0;CC-BY-4.0;UNLICENSED --summary" }, "husky": { "hooks": { @@ -44,8 +44,8 @@ "jest": "^27.5.1", "jest-haste-map": "^24.5.0", "jest-resolve": "^24.5.0", + "license-checker": "^25.0.1", "moment": "^2.29.2", - "node-license-validator": "^1.3.0", "prettier": "^1.18.2", "standard-version": "9.1.1", "ts-jest": "^27.1.3", diff --git a/yarn.lock b/yarn.lock index d6ce9233d..85d618c85 100644 --- a/yarn.lock +++ b/yarn.lock @@ -546,11 +546,6 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@octetstream/promisify@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@octetstream/promisify/-/promisify-2.0.2.tgz#29ac3bd7aefba646db670227f895d812c1a19615" - integrity sha512-7XHoRB61hxsz8lBQrjC1tq/3OEIgpvGWg6DKAdwi7WRzruwkmsdwmOoUXbU4Dtd4RSOMDwed0SkP3y8UlMt1Bg== - "@sinonjs/commons@^1.7.0": version "1.8.3" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" @@ -887,6 +882,11 @@ abab@^2.0.3, abab@^2.0.5: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + acorn-globals@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" @@ -983,11 +983,6 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -ansicolors@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" - integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk= - anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -1009,11 +1004,6 @@ aproba@^1.1.1: resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== -archy@1.0.0, archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= - arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" @@ -1061,7 +1051,7 @@ arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= -asap@~2.0.3: +asap@^2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= @@ -1395,11 +1385,6 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= -builtins@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= - cacache@^12.0.2: version "12.0.4" resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" @@ -1480,7 +1465,7 @@ capture-exit@^2.0.0: dependencies: rsvp "^4.8.4" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1646,11 +1631,6 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== - commander@^2.12.1, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -1669,11 +1649,6 @@ compare-func@^2.0.0: array-ify "^1.0.0" dot-prop "^5.1.0" -compare-versions@3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.4.0.tgz#e0747df5c9cb7f054d6d3dc3e1dbc444f9e92b26" - integrity sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg== - component-emitter@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" @@ -2045,13 +2020,18 @@ debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@^3.1.0, debug@^3.2.5: +debug@^3.1.0: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" +debuglog@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" + integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= + decamelize-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" @@ -2148,6 +2128,14 @@ detect-newline@^3.0.0, detect-newline@^3.1.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +dezalgo@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81" + integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig== + dependencies: + asap "^2.0.0" + wrappy "1" + diff-sequences@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" @@ -2794,14 +2782,6 @@ gitconfiglocal@^1.0.0: dependencies: ini "^1.3.2" -glob-all@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.1.0.tgz#8913ddfb5ee1ac7812656241b03d5217c64b02ab" - integrity sha1-iRPd+17hrHgSZWJBsD1SF8ZLAqs= - dependencies: - glob "^7.0.5" - yargs "~1.2.6" - glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -2817,7 +2797,7 @@ glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -2997,7 +2977,7 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" -hosted-git-info@^2.1.4, hosted-git-info@^2.7.1: +hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== @@ -4102,6 +4082,22 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +license-checker@^25.0.1: + version "25.0.1" + resolved "https://registry.yarnpkg.com/license-checker/-/license-checker-25.0.1.tgz#4d14504478a5240a857bb3c21cd0491a00d761fa" + integrity sha512-mET5AIwl7MR2IAKYYoVBBpV0OnkKQ1xGj2IMMeEFIs42QAkEVjRtFZGWmQ28WeU7MP779iAgOaOy93Mn44mn6g== + dependencies: + chalk "^2.4.1" + debug "^3.1.0" + mkdirp "^0.5.1" + nopt "^4.0.1" + read-installed "~4.0.3" + semver "^5.5.0" + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + spdx-satisfies "^4.0.0" + treeify "^1.1.0" + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" @@ -4161,36 +4157,6 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.assign@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" - integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= - -lodash.assignin@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" - integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= - -lodash.clone@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" - integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y= - -lodash.clonedeep@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - -lodash.flatten@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= - -lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= - lodash.ismatch@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" @@ -4201,11 +4167,6 @@ lodash.memoize@4.x: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= -lodash.set@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" - integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= - lodash@^4.17.15, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -4218,14 +4179,6 @@ loose-envify@^1.0.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" -lru-cache@^4.0.0: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -4419,11 +4372,6 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de" - integrity sha1-md9lelJXTCHJBXSX33QnkLK0wN4= - minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" @@ -4534,17 +4482,6 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -nlf@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/nlf/-/nlf-2.1.1.tgz#73189d4c7f8a0d9f46de501a1a7aff880882b959" - integrity sha512-ysGGIax/WydhF78a5k//FPMt9tVDVLsnuSZqxwuzIfc5waKKc0Y/jz082a81aAayrP1QQNQm5ck+5Kv+jlbU6Q== - dependencies: - archy "1.0.0" - commander "2.19.0" - compare-versions "3.4.0" - glob-all "3.1.0" - snyk-resolve-deps "4.0.2" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -4579,24 +4516,20 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" -node-license-validator@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/node-license-validator/-/node-license-validator-1.3.2.tgz#c7884596e3ec107cae6ee0a94a86a4149c98b77b" - integrity sha512-pw6eXdzPkY6+NLeFQA1dUSZ14m9ovjbBq3MaEFfFZgFdJtIjfhoiM7i9BhXV6dQcEN5mD34k8Ry+mYuri48tXg== - dependencies: - nlf "^2.1.1" - npm-package-arg "^8.1.5" - semver "^7.3.5" - spdx-expression-validate "^2.0.0" - spdx-satisfies "^5.0.1" - yargs "^17.0.1" - node-releases@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== -normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: +nopt@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -4628,14 +4561,10 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -npm-package-arg@^8.1.5: - version "8.1.5" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44" - integrity sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q== - dependencies: - hosted-git-info "^4.0.1" - semver "^7.3.4" - validate-npm-package-name "^3.0.0" +npm-normalize-package-bin@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== npm-run-path@^2.0.0: version "2.0.2" @@ -4749,6 +4678,24 @@ os-browserify@^0.3.0: resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-tmpdir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -5007,25 +4954,11 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= -promise-fs@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/promise-fs/-/promise-fs-2.1.1.tgz#0b725a592c165ff16157d1f13640ba390637e557" - integrity sha512-43p7e4QzAQ3w6eyN0+gbBL7jXiZFWLWYITg9wIObqkBySu/a5K1EDcQ/S6UyB/bmiZWDA4NjTbcopKLTaKcGSw== - dependencies: - "@octetstream/promisify" "2.0.2" - promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= -"promise@>=3.2 <8": - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== - dependencies: - asap "~2.0.3" - prompts@^2.0.1: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -5039,11 +4972,6 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" @@ -5141,6 +5069,30 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +read-installed@~4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" + integrity sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc= + dependencies: + debuglog "^1.0.1" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + semver "2 || 3 || 4 || 5" + slide "~1.1.3" + util-extend "^1.0.1" + optionalDependencies: + graceful-fs "^4.1.2" + +read-package-json@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.2.tgz#6992b2b66c7177259feb8eaac73c3acd28b9222a" + integrity sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA== + dependencies: + glob "^7.1.1" + json-parse-even-better-errors "^2.3.0" + normalize-package-data "^2.0.0" + npm-normalize-package-bin "^1.0.0" + read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" @@ -5199,6 +5151,16 @@ readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stre string_decoder "^1.1.1" util-deprecate "^1.0.1" +readdir-scoped-modules@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" + integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + graceful-fs "^4.1.2" + once "^1.3.0" + readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -5411,12 +5373,12 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@7.x, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: +semver@7.x, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4: version "7.3.7" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== @@ -5516,6 +5478,11 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slide@~1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -5546,60 +5513,6 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -snyk-module@^1.6.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/snyk-module/-/snyk-module-1.9.1.tgz#b2a78f736600b0ab680f1703466ed7309c980804" - integrity sha512-A+CCyBSa4IKok5uEhqT+hV/35RO6APFNLqk9DRRHg7xW2/j//nPX8wTSZUPF8QeRNEk/sX+6df7M1y6PBHGSHA== - dependencies: - debug "^3.1.0" - hosted-git-info "^2.7.1" - -snyk-resolve-deps@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/snyk-resolve-deps/-/snyk-resolve-deps-4.0.2.tgz#c3fa08a14fff6667628ec590061360de15f67ae6" - integrity sha512-nlw62wiWhGOTw3BD3jVIwrUkRR4iNxEkkO4Y/PWs8BsUWseGu1H6QgLesFXJb3qx7ANJ5UbUCJMgV+eL0Lf9cA== - dependencies: - ansicolors "^0.3.2" - debug "^3.2.5" - lodash.assign "^4.2.0" - lodash.assignin "^4.2.0" - lodash.clone "^4.5.0" - lodash.flatten "^4.4.0" - lodash.get "^4.4.2" - lodash.set "^4.3.2" - lru-cache "^4.0.0" - semver "^5.5.1" - snyk-module "^1.6.0" - snyk-resolve "^1.0.0" - snyk-tree "^1.0.0" - snyk-try-require "^1.1.1" - then-fs "^2.0.0" - -snyk-resolve@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/snyk-resolve/-/snyk-resolve-1.1.0.tgz#52740cb01ba477851086855f9857b3a44296ee0e" - integrity sha512-OZMF8I8TOu0S58Z/OS9mr8jkEzGAPByCsAkrWlcmZgPaE0RsxVKVIFPhbMNy/JlYswgGDYYIEsNw+e0j1FnTrw== - dependencies: - debug "^4.1.1" - promise-fs "^2.1.1" - -snyk-tree@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/snyk-tree/-/snyk-tree-1.0.0.tgz#0fb73176dbf32e782f19100294160448f9111cc8" - integrity sha1-D7cxdtvzLngvGRAClBYESPkRHMg= - dependencies: - archy "^1.0.0" - -snyk-try-require@^1.1.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/snyk-try-require/-/snyk-try-require-1.3.1.tgz#6e026f92e64af7fcccea1ee53d524841e418a212" - integrity sha1-bgJvkuZK9/zM6h7lPVJIQeQYohI= - dependencies: - debug "^3.1.0" - lodash.clonedeep "^4.3.0" - lru-cache "^4.0.0" - then-fs "^2.0.0" - source-list-map@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" @@ -5674,13 +5587,6 @@ spdx-expression-parse@^3.0.0: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" -spdx-expression-validate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-validate/-/spdx-expression-validate-2.0.0.tgz#25c9408e1c63fad94fff5517bb7101ffcd23350b" - integrity sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids@^3.0.0: version "3.0.11" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" @@ -5691,10 +5597,10 @@ spdx-ranges@^2.0.0: resolved "https://registry.yarnpkg.com/spdx-ranges/-/spdx-ranges-2.1.1.tgz#87573927ba51e92b3f4550ab60bfc83dd07bac20" integrity sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA== -spdx-satisfies@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/spdx-satisfies/-/spdx-satisfies-5.0.1.tgz#9feeb2524686c08e5f7933c16248d4fdf07ed6a6" - integrity sha512-Nwor6W6gzFp8XX4neaKQ7ChV4wmpSh2sSDemMFSzHxpTw460jxFYeOn+jq4ybnSSw/5sc3pjka9MQPouksQNpw== +spdx-satisfies@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/spdx-satisfies/-/spdx-satisfies-4.0.1.tgz#9a09a68d80f5f1a31cfaebb384b0c6009e4969fe" + integrity sha512-WVzZ/cXAzoNmjCWiEluEA3BjHp5tiUmmhn9MK+X0tBbR9sOqtC6UQwmgCNrAIZvNlMuBUYAaHYfb2oqlF9SwKA== dependencies: spdx-compare "^1.0.0" spdx-expression-parse "^3.0.0" @@ -5825,7 +5731,7 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -6017,13 +5923,6 @@ text-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== -then-fs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/then-fs/-/then-fs-2.0.0.tgz#72f792dd9d31705a91ae19ebfcf8b3f968c81da2" - integrity sha1-cveS3Z0xcFqRrhnr/Piz+WjIHaI= - dependencies: - promise ">=3.2 <8" - throat@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" @@ -6126,6 +6025,11 @@ tr46@^2.1.0: dependencies: punycode "^2.1.1" +treeify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.1.0.tgz#4e31c6a463accd0943879f30667c4fdaff411bb8" + integrity sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A== + trim-newlines@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" @@ -6387,6 +6291,11 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +util-extend@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" + integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8= + util.promisify@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" @@ -6434,13 +6343,6 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -validate-npm-package-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= - dependencies: - builtins "^1.0.3" - vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" @@ -6680,11 +6582,6 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" @@ -6708,11 +6605,6 @@ yargs-parser@^13.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^21.0.0: - version "21.0.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" - integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== - yargs@^13.3.2: version "13.3.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" @@ -6742,26 +6634,6 @@ yargs@^16.0.0, yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^17.0.1: - version "17.4.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.4.1.tgz#ebe23284207bb75cee7c408c33e722bfb27b5284" - integrity sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.0.0" - -yargs@~1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.2.6.tgz#9c7b4a82fd5d595b2bf17ab6dcc43135432fe34b" - integrity sha1-nHtKgv1dWVsr8Xq23MQxNUMv40s= - dependencies: - minimist "^0.1.0" - yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" From 5d59818d01649687865fc0ac8037e33e7140f3c8 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Tue, 17 May 2022 09:57:08 +0200 Subject: [PATCH 108/184] Wraps list of allowed licenses in quotes --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 546731af4..ee437764e 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "prepareChangelog": "standard-version --prerelease", "validate": "yarn validate:dependencies", "validate:dependencies": "yarn audit --groups dependencies && yarn license-validate", - "license-validate": "license-checker --onlyAllow MIT;Apache-2.0;ISC;BSD;CC0;CC-BY-3.0;CC-BY-4.0;UNLICENSED --summary" + "license-validate": "license-checker --onlyAllow \"MIT;Apache-2.0;ISC;BSD;CC0;CC-BY-3.0;CC-BY-4.0;UNLICENSED\" --summary" }, "husky": { "hooks": { From 3dd156980c1bdde4ce4eade65fa03eea1793e752 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 18 May 2022 13:55:05 +0200 Subject: [PATCH 109/184] SOF-930 Blueprints now strips GraphicDesign and BackgroundLoop cues that is not from the iNews layout, if there is an iNews layout cue that also has a configuration in blueprints --- .../inewsConversion/converters/ParseBody.ts | 32 +++- .../inewsConversion/converters/ParseCue.ts | 14 +- .../converters/__tests__/body-parser.spec.ts | 171 +++++++++++++++++- 3 files changed, 210 insertions(+), 7 deletions(-) diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index 2ee078048..6a78023e9 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -1,4 +1,4 @@ -import { PostProcessDefinitions, TV2BlueprintConfig, UnparsedCue } from 'tv2-common' +import { CueDefinitionFromLayout, PostProcessDefinitions, TV2BlueprintConfig, UnparsedCue } from 'tv2-common' import { CueType, PartType } from 'tv2-constants' import { CueDefinition, CueDefinitionUnpairedPilot, ParseCue, UnpairedPilotToGraphic } from './ParseCue' @@ -118,7 +118,7 @@ export function ParseBody( fields: any, modified: number ): PartDefinition[] { - const definitions: PartDefinition[] = [] + let definitions: PartDefinition[] = [] let definition: PartDefinition = initDefinition(fields, modified, segmentName) // Handle intro segments, they have special behaviour. @@ -287,6 +287,8 @@ export function ParseBody( partDefinition.cues = partDefinition.cues.filter(c => c.type !== CueType.UNKNOWN) }) + definitions = stripRedundantCuesWhenLayoutCueIsPresent(definitions) + return PostProcessDefinitions(definitions, segmentId) } @@ -565,3 +567,29 @@ function extractTypeProperties(typeStr: string): PartdefinitionTypes { } } } + +export function stripRedundantCuesWhenLayoutCueIsPresent(partDefinitions: PartDefinition[]): PartDefinition[] { + const hasLayoutCue: boolean = partDefinitions.some(definition => + definition.cues.some(cue => { + const cueFromLayout = cue as CueDefinitionFromLayout + return cueFromLayout.isFromLayout + }) + ) + + if (!hasLayoutCue) { + return partDefinitions + } + + return partDefinitions.map(definition => { + const cues = definition.cues.filter(cue => { + if (cue.type !== CueType.GraphicDesign && cue.type !== CueType.BackgroundLoop) { + return true + } + return (cue as CueDefinitionFromLayout).isFromLayout + }) + return { + ...definition, + cues + } + }) +} diff --git a/src/tv2-common/inewsConversion/converters/ParseCue.ts b/src/tv2-common/inewsConversion/converters/ParseCue.ts index 0af8de903..b5b0e36f3 100644 --- a/src/tv2-common/inewsConversion/converters/ParseCue.ts +++ b/src/tv2-common/inewsConversion/converters/ParseCue.ts @@ -100,17 +100,21 @@ export interface CueDefinitionUnpairedPilot extends CueDefinitionBase { engineNumber?: number } -export interface CueDefinitionBackgroundLoop extends CueDefinitionBase { +export interface CueDefinitionBackgroundLoop extends CueDefinitionBase, CueDefinitionFromLayout { type: CueType.BackgroundLoop target: 'FULL' | 'DVE' backgroundLoop: string } -export interface CueDefinitionGraphicDesign extends CueDefinitionBase { +export interface CueDefinitionGraphicDesign extends CueDefinitionBase, CueDefinitionFromLayout { type: CueType.GraphicDesign design: string } +export interface CueDefinitionFromLayout { + isFromLayout?: boolean +} + export interface GraphicInternal { type: 'internal' template: string @@ -859,7 +863,8 @@ function parseDesignLayout(cue: string[], config: TV2BlueprintConfig): CueDefini iNewsCommand: layout, start: { frames: 1 - } + }, + isFromLayout: true }) } @@ -881,7 +886,8 @@ function parseDesignBg(cue: string[], config: TV2BlueprintConfig): CueDefinition type: CueType.BackgroundLoop, target: 'DVE', backgroundLoop: tableConfigSchema.casparCgDveBgScene, - iNewsCommand: layout + iNewsCommand: layout, + isFromLayout: true }) } 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 42e8f9378..927362cc7 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts @@ -1,5 +1,10 @@ import { IBlueprintRundownDB, PlaylistTimingType } from '@tv2media/blueprints-integration' -import { UnparsedCue } from 'tv2-common' +import { + CueDefinitionBackgroundLoop, + CueDefinitionGraphicDesign, + stripRedundantCuesWhenLayoutCueIsPresent, + UnparsedCue +} from 'tv2-common' import { CueType, PartType } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' import { defaultShowStyleConfig, defaultStudioConfig } from '../../../../tv2_afvd_showstyle/__tests__/configs' @@ -3432,8 +3437,172 @@ describe('Body parser', () => { }) /** END Merging Cues From Config */ + + describe('removeDuplicateDesignCues', () => { + it('has no no cues, does nothing', () => { + const definitions: PartDefinition[] = [createPartDefinition(), createPartDefinition()] + + const result: PartDefinition[] = stripRedundantCuesWhenLayoutCueIsPresent(definitions) + + expect(result).toEqual(definitions) + }) + + it('has a designCue from layout and a regular design cue, removes the regular design cue', () => { + const designFromLayout = 'designFromLayout' + const definitions: PartDefinition[] = [ + createPartDefinition([ + createDesignCueDefinition(designFromLayout, true), + createDesignCueDefinition('regularDesign') + ]) + ] + + const result: PartDefinition[] = stripRedundantCuesWhenLayoutCueIsPresent(definitions) + + expect(result[0].cues).toHaveLength(1) + const graphicDesignCue: CueDefinitionGraphicDesign = result[0].cues[0] as CueDefinitionGraphicDesign + expect(graphicDesignCue.design).toEqual(designFromLayout) + }) + + it('only have a regular design cue, does nothing', () => { + const definitions: PartDefinition[] = [createPartDefinition([createDesignCueDefinition('someDesign')])] + + const result: PartDefinition[] = stripRedundantCuesWhenLayoutCueIsPresent(definitions) + + expect(result).toEqual(definitions) + }) + + it('only have a layout design cue, does nothing', () => { + const definitions: PartDefinition[] = [ + createPartDefinition([createDesignCueDefinition('designFromLayout', true)]) + ] + + const result: PartDefinition[] = stripRedundantCuesWhenLayoutCueIsPresent(definitions) + + expect(result).toEqual(definitions) + }) + + it('has a regular design, layout design and two other random cues, only removes the regular design cue', () => { + const regularDesign = 'regularDesignCue' + const definitions: PartDefinition[] = [ + createPartDefinition([ + createDesignCueDefinition('designFromLayout', true), + createDesignCueDefinition(regularDesign), + createUnknownCueDefinition(), + createUnknownCueDefinition() + ]) + ] + + const result: PartDefinition[] = stripRedundantCuesWhenLayoutCueIsPresent(definitions) + + const cues = result[0].cues + expect(cues).toHaveLength(3) + const regularDesignCue = cues.find(cue => { + const designCue = cue as CueDefinitionGraphicDesign + if (!designCue.design) { + return false + } + return designCue.design === regularDesign + }) + expect(regularDesignCue).toBeUndefined() + }) + + it('has a regular design cue in one partDefinition, has a layout cue in another partDefinition, remove the regular designCue', () => { + const layoutDesign = 'designFromLayout' + const definitions: PartDefinition[] = [ + createPartDefinition([createDesignCueDefinition(layoutDesign, true)]), + createPartDefinition([createDesignCueDefinition('regularDesign')]) + ] + + const result: PartDefinition[] = stripRedundantCuesWhenLayoutCueIsPresent(definitions) + + const cues: CueDefinition[] = result.flatMap(definition => definition.cues) + expect(cues).toHaveLength(1) + const graphicCue = cues[0] as CueDefinitionGraphicDesign + expect(graphicCue.design).toBe(layoutDesign) + }) + + it('has layout background cue and regular background cue, remove regular background cue', () => { + const layoutBackground = 'layoutBackground' + const definitions: PartDefinition[] = [ + createPartDefinition([ + createBackgroundLoopCueDefinition(layoutBackground, true), + createBackgroundLoopCueDefinition('regularBackground') + ]) + ] + + const result: PartDefinition[] = stripRedundantCuesWhenLayoutCueIsPresent(definitions) + + expect(result[0].cues).toHaveLength(1) + const backgroundCue: CueDefinitionBackgroundLoop = result[0].cues[0] as CueDefinitionBackgroundLoop + expect(backgroundCue.backgroundLoop).toBe(layoutBackground) + }) + + it('only have a regular background cue, does nothing', () => { + const definitions: PartDefinition[] = [ + createPartDefinition([createBackgroundLoopCueDefinition('regularBackground')]) + ] + + const result: PartDefinition[] = stripRedundantCuesWhenLayoutCueIsPresent(definitions) + + expect(result).toEqual(definitions) + }) + + it('only have a layout background cue, does nothing', () => { + const definitions: PartDefinition[] = [ + createPartDefinition([createBackgroundLoopCueDefinition('layoutBackground', true)]) + ] + + const result: PartDefinition[] = stripRedundantCuesWhenLayoutCueIsPresent(definitions) + + expect(result).toEqual(definitions) + }) + }) }) +function createPartDefinition(cues?: CueDefinition[]): PartDefinition { + if (!cues) { + cues = [] + } + return { + externalId: `externalId_${Math.random() * 1000}`, + cues, + type: PartType.Grafik, + variant: {}, + script: '', + fields: {}, + modified: 123, + storyName: 'someName', + segmentExternalId: `segmentExternalId_${Math.random() * 1000}`, + rawType: '' + } +} + +function createDesignCueDefinition(design: string, isFromLayout?: boolean): CueDefinition { + return { + type: CueType.GraphicDesign, + design, + iNewsCommand: '', + isFromLayout + } +} + +function createBackgroundLoopCueDefinition(backgroundLoop: string, isFromLayout?: boolean): CueDefinition { + return { + type: CueType.BackgroundLoop, + target: 'DVE', + backgroundLoop, + isFromLayout, + iNewsCommand: '' + } +} + +function createUnknownCueDefinition(): CueDefinition { + return { + type: CueType.UNKNOWN, + iNewsCommand: '' + } +} + export function stripExternalId(definitions: PartDefinition[]) { return definitions.map(def => { return { ...def, ...{ externalId: '' } } From e1acb0dc894d0dc1b5a832c09c8668d93d958586 Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 18 May 2022 14:35:44 +0200 Subject: [PATCH 110/184] Update node version for GitHub action --- .github/workflows/deploy-image.yml | 10 ++++++++-- .github/workflows/node.yml | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy-image.yml b/.github/workflows/deploy-image.yml index f1c343978..c96f5bb84 100644 --- a/.github/workflows/deploy-image.yml +++ b/.github/workflows/deploy-image.yml @@ -1,4 +1,7 @@ name: Node CI +env: + node-version: 16.14 + node-packager-manager: yarn on: push: branches: @@ -17,7 +20,10 @@ jobs: with: path: '**/node_modules' key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - + - uses: actions/setup-node@v2 + with: + node-version: "16.14" + registry-url: "https://registry.npmjs.org" - name: yarn install run: yarn install --check-files --frozen-lockfile @@ -74,4 +80,4 @@ jobs: context: . push: true tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/node.yml b/.github/workflows/node.yml index 9d053660d..3aba30e82 100644 --- a/.github/workflows/node.yml +++ b/.github/workflows/node.yml @@ -1,4 +1,7 @@ name: Node CI +env: + node-version: 16.14 + node-packager-manager: yarn on: push: branches: @@ -17,7 +20,10 @@ jobs: with: path: '**/node_modules' key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - + - uses: actions/setup-node@v2 + with: + node-version: "16.14" + registry-url: "https://registry.npmjs.org" - name: yarn install run: yarn install --check-files --frozen-lockfile @@ -116,4 +122,4 @@ jobs: context: . push: true tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file + labels: ${{ steps.meta.outputs.labels }} From 00a2b64ee8556ffc46ee46b0de26fd86911ea99d Mon Sep 17 00:00:00 2001 From: Rasmus Lindved Date: Wed, 18 May 2022 14:47:09 +0200 Subject: [PATCH 111/184] Update Docker file to use Node image: 16-alpine --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0b23334c4..64922d85e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:12-alpine +FROM node:16-alpine RUN apk update RUN apk add git @@ -8,4 +8,4 @@ WORKDIR /opt/blueprints/ RUN yarn install --production -CMD ["./docker-entrypoint.sh"] \ No newline at end of file +CMD ["./docker-entrypoint.sh"] From 4bb64e7db1dc4beec0dffb28282e2e0bb07292b7 Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 19 May 2022 09:54:42 +0200 Subject: [PATCH 112/184] fix: SOF-932 Server adlibs and VO parts should have VO-level audio also server adlibs (ADLIBPIX=SERVER) should accept persistence --- src/tv2-common/actions/executeAction.ts | 3 ++- src/tv2-common/content/server.ts | 24 ++++++++++++------- src/tv2-common/parts/server.ts | 3 ++- .../helpers/pieces/adlib.ts | 5 ++-- src/tv2_afvd_showstyle/parts/server.ts | 3 ++- .../cues/OfftubeAdlib.ts | 3 ++- .../parts/OfftubeServer.ts | 6 +++-- 7 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 37fbd300f..1f9d8dee8 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -411,7 +411,8 @@ function executeActionSelectServerClip< }, Sisyfos: { ClipPending: settings.LLayer.Sisyfos.ClipPending, - StudioMicsGroup: settings.LLayer.Sisyfos.StudioMics + StudioMicsGroup: settings.LLayer.Sisyfos.StudioMics, + SisyfosPersistedLevels: settings.LLayer.Sisyfos.PersistedLevels }, ATEM: { ServerLookaheadAux: settings.LLayer.Atem.ServerLookaheadAUX diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 9cf1ce449..4304126e8 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -28,6 +28,7 @@ export interface MakeContentServerSourceLayers { Sisyfos: { ClipPending: string StudioMicsGroup: string + SisyfosPersistedLevels: string } ATEM: { ServerLookaheadAux?: string @@ -139,8 +140,7 @@ function GetServerTimeline( content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNEL, - // isPgm: voiceOver ? 2 : 1 - isPgm: 1 + isPgm: voLevels ? 2 : 1 }, metaData: { mediaPlayerSession: mediaPlayerSessionId @@ -149,24 +149,30 @@ function GetServerTimeline( }), ...(adLibPix - ? config.stickyLayers.map(layer => { - return literal({ + ? [ + literal({ id: '', enable: { - while: serverEnableClass + start: 1 }, priority: 1, - layer, + layer: sourceLayers.Sisyfos.SisyfosPersistedLevels, content: { deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: 0 + type: TSR.TimelineContentTypeSisyfos.CHANNELS, + overridePriority: 1, + channels: config.stickyLayers.map(layer => { + return { + mappedLayer: layer, + isPgm: 0 + } + }) }, metaData: { sisyfosPersistLevel: true } }) - }) + ] : []), ...(voLevels ? [GetSisyfosTimelineObjForCamera(context, config, 'server', sourceLayers.Sisyfos.StudioMicsGroup)] diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index fa57be34a..fcde1e11a 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -217,7 +217,8 @@ function getContentServerElement< }, Sisyfos: { ClipPending: layers.Sisyfos.ClipPending, - StudioMicsGroup: layers.Sisyfos.StudioMicsGroup + StudioMicsGroup: layers.Sisyfos.StudioMicsGroup, + SisyfosPersistedLevels: layers.Sisyfos.SisyfosPersistedLevels }, ATEM: { ServerLookaheadAux: layers.ATEM.ServerLookaheadAux diff --git a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts index df1163578..543a37c88 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts @@ -55,7 +55,7 @@ export function EvaluateAdLib( partDefinition, file, false, - false, + true, { SourceLayer: { PgmServer: SourceLayer.PgmServer, @@ -66,7 +66,8 @@ export function EvaluateAdLib( }, Sisyfos: { ClipPending: SisyfosLLAyer.SisyfosSourceClipPending, - StudioMicsGroup: SisyfosLLAyer.SisyfosGroupStudioMics + StudioMicsGroup: SisyfosLLAyer.SisyfosGroupStudioMics, + SisyfosPersistedLevels: SisyfosLLAyer.SisyfosPersistedLevels }, AtemLLayer: { MEPgm: AtemLLayer.AtemMEProgram diff --git a/src/tv2_afvd_showstyle/parts/server.ts b/src/tv2_afvd_showstyle/parts/server.ts index 82d951b7c..ad9090241 100644 --- a/src/tv2_afvd_showstyle/parts/server.ts +++ b/src/tv2_afvd_showstyle/parts/server.ts @@ -30,7 +30,8 @@ export function CreatePartServer( }, Sisyfos: { ClipPending: SisyfosLLAyer.SisyfosSourceClipPending, - StudioMicsGroup: SisyfosLLAyer.SisyfosGroupStudioMics + StudioMicsGroup: SisyfosLLAyer.SisyfosGroupStudioMics, + SisyfosPersistedLevels: SisyfosLLAyer.SisyfosPersistedLevels }, ATEM: {} }) diff --git a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts index 6b957803a..d70e430bd 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts @@ -68,7 +68,8 @@ export function OfftubeEvaluateAdLib( }, Sisyfos: { ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending, - StudioMicsGroup: OfftubeSisyfosLLayer.SisyfosGroupStudioMics + StudioMicsGroup: OfftubeSisyfosLLayer.SisyfosGroupStudioMics, + SisyfosPersistedLevels: OfftubeSisyfosLLayer.SisyfosPersistedLevels }, AtemLLayer: { MEPgm: OfftubeAtemLLayer.AtemMEClean diff --git a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts index f3bd50ee3..7991ff33e 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts @@ -31,7 +31,8 @@ export function OfftubeCreatePartServer( }, Sisyfos: { ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending, - StudioMicsGroup: OfftubeSisyfosLLayer.SisyfosGroupStudioMics + StudioMicsGroup: OfftubeSisyfosLLayer.SisyfosGroupStudioMics, + SisyfosPersistedLevels: OfftubeSisyfosLLayer.SisyfosPersistedLevels }, ATEM: { ServerLookaheadAux: OfftubeAtemLLayer.AtemAuxServerLookahead @@ -75,7 +76,8 @@ export function OfftubeCreatePartServer( }, Sisyfos: { ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending, - StudioMicsGroup: OfftubeSisyfosLLayer.SisyfosGroupStudioMics + StudioMicsGroup: OfftubeSisyfosLLayer.SisyfosGroupStudioMics, + SisyfosPersistedLevels: OfftubeSisyfosLLayer.SisyfosPersistedLevels }, AtemLLayer: { MEPgm: OfftubeAtemLLayer.AtemMEClean, From 339eed5204e48e41098eea25de84f134f10a3b72 Mon Sep 17 00:00:00 2001 From: ianshade Date: Fri, 27 May 2022 11:18:03 +0200 Subject: [PATCH 113/184] fix: SOF-938 don't reset video in an on-air DVE the server-selection piece has to be preserved during DVE AdLibs because we need its timeline object --- src/tv2-common/actions/executeAction.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 1f9d8dee8..176e9b946 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -375,11 +375,7 @@ function executeActionSelectServerClip< const externalId = generateExternalId(context, actionId, [file]) const currentPiece = settings.SelectedAdlibs - ? context - .getPieceInstances('current') - .find( - p => p.piece.sourceLayerId === (userData.voLayer ? settings.SourceLayers.VO : settings.SourceLayers.Server) - ) + ? context.getPieceInstances('current').find(p => isServerOnPgm(p, settings, userData.voLayer)) : undefined const basePart = CreatePartServerBase( @@ -497,6 +493,21 @@ function dveContainsServer(sources: DVESources) { ) } +function isServerOnPgm< + StudioConfig extends TV2StudioConfigBase, + ShowStyleConfig extends TV2BlueprintConfigBase +>( + pieceInstance: IBlueprintPieceInstance, + settings: ActionExecutionSettings, + voLayer: boolean +) { + return ( + pieceInstance.piece.sourceLayerId === (voLayer ? settings.SourceLayers.VO : settings.SourceLayers.Server) || + (pieceInstance.piece.sourceLayerId === settings.SourceLayers.DVEAdLib && + dveContainsServer((pieceInstance.piece.metaData as DVEPieceMetaData).sources)) + ) +} + function executeActionSelectDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase From 76234500dff6591dbfbdce7fb3ba3ac0fb4056ae Mon Sep 17 00:00:00 2001 From: ianshade Date: Mon, 30 May 2022 14:57:34 +0200 Subject: [PATCH 114/184] fix: SOF-943 failing to set source to box Seems like a small change in core, `stoppedPlayback` used to be undefined, but now is 0 instead --- 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 da42e7051..a9e5ecbe9 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1274,7 +1274,7 @@ async function executeActionCutSourceToBox< let modifiedPiece: IBlueprintPieceInstance | undefined let modifiedDataStore: IBlueprintPieceInstance | undefined - if (currentDVE && currentDVE.stoppedPlayback === undefined) { + if (currentDVE && !currentDVE.stoppedPlayback) { modify = 'current' modifiedPiece = currentDVE modifiedDataStore = currentDataStore @@ -1287,10 +1287,6 @@ async function executeActionCutSourceToBox< const meta: (DVEPieceMetaData & PieceMetaData) | undefined = modifiedPiece?.piece.metaData as PieceMetaData & DVEPieceMetaData - meta.sisyfosPersistMetaData = { - sisyfosLayers: [] - } - if ( !modifiedPiece || !modify || @@ -1301,6 +1297,10 @@ async function executeActionCutSourceToBox< return } + meta.sisyfosPersistMetaData = { + sisyfosLayers: [] + } + const containsServerBefore = dveContainsServer(meta.sources) // ADD 'VO' to VO sources From 3bbec3f190263ec2f5c64a8fac3c5af1328cc7a3 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 31 May 2022 11:06:22 +0200 Subject: [PATCH 115/184] fix: SOF-954 make hackGetMediaObjectDuration async --- src/tv2-common/actions/context.ts | 2 +- src/tv2-common/getSegment.ts | 48 +++++++++---------- src/tv2-common/parts/server.ts | 9 ++-- src/tv2_afvd_showstyle/getSegment.ts | 7 ++- .../helpers/pieces/adlib.ts | 4 +- .../helpers/pieces/evaluateCues.ts | 4 +- src/tv2_afvd_showstyle/parts/cueonly.ts | 27 +++++++++-- src/tv2_afvd_showstyle/parts/evs.ts | 6 +-- src/tv2_afvd_showstyle/parts/grafik.ts | 6 +-- src/tv2_afvd_showstyle/parts/intro.ts | 6 +-- src/tv2_afvd_showstyle/parts/kam.ts | 6 +-- src/tv2_afvd_showstyle/parts/live.ts | 6 +-- src/tv2_afvd_showstyle/parts/server.ts | 8 ++-- src/tv2_afvd_showstyle/parts/teknik.ts | 6 +-- src/tv2_afvd_showstyle/parts/unknown.ts | 4 +- .../cues/OfftubeAdlib.ts | 4 +- src/tv2_offtube_showstyle/getSegment.ts | 7 ++- .../helpers/EvaluateCues.ts | 4 +- src/tv2_offtube_showstyle/parts/OfftubeDVE.ts | 6 +-- .../parts/OfftubeGrafik.ts | 4 +- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 6 +-- .../parts/OfftubeServer.ts | 10 ++-- .../parts/OfftubeUnknown.ts | 4 +- 23 files changed, 111 insertions(+), 83 deletions(-) diff --git a/src/tv2-common/actions/context.ts b/src/tv2-common/actions/context.ts index e477d7d93..bc647e4a6 100644 --- a/src/tv2-common/actions/context.ts +++ b/src/tv2-common/actions/context.ts @@ -143,7 +143,7 @@ class TV2ActionExecutionContext implements ITV2ActionExecutionContext { return this.coreContext.getPackageInfo(packageId) } - public hackGetMediaObjectDuration(mediaId: string): number | undefined { + public async hackGetMediaObjectDuration(mediaId: string): Promise { return this.coreContext.hackGetMediaObjectDuration(mediaId) } diff --git a/src/tv2-common/getSegment.ts b/src/tv2-common/getSegment.ts index 1db8ee4c9..3d57b9760 100644 --- a/src/tv2-common/getSegment.ts +++ b/src/tv2-common/getSegment.ts @@ -42,71 +42,71 @@ export interface GetSegmentShowstyleOptions< partDefinition: PartDefinition, totalWords: number, asAdlibs?: boolean - ) => BlueprintResultPart + ) => BlueprintResultPart | Promise CreatePartIntro?: ( context: IShowStyleUserContext, config: ShowStyleConfig, partDefinition: PartDefinition, totalWords: number - ) => BlueprintResultPart + ) => BlueprintResultPart | Promise CreatePartKam?: ( context: IShowStyleUserContext, config: ShowStyleConfig, partDefinition: PartDefinitionKam, totalWords: number - ) => BlueprintResultPart + ) => BlueprintResultPart | Promise CreatePartServer?: ( context: IShowStyleUserContext, config: ShowStyleConfig, partDefinition: PartDefinition, props: ServerPartProps - ) => BlueprintResultPart + ) => BlueprintResultPart | Promise CreatePartTeknik?: ( context: IShowStyleUserContext, config: ShowStyleConfig, partDefinition: PartDefinitionTeknik, totalWords: number - ) => BlueprintResultPart + ) => BlueprintResultPart | Promise CreatePartGrafik?: ( context: IShowStyleUserContext, config: ShowStyleConfig, partDefinition: PartDefinitionGrafik, totalWords: number - ) => BlueprintResultPart + ) => BlueprintResultPart | Promise CreatePartEkstern?: ( context: IShowStyleUserContext, config: ShowStyleConfig, partDefinition: PartDefinitionEkstern, totalWords: number - ) => BlueprintResultPart + ) => BlueprintResultPart | Promise CreatePartTelefon?: ( context: IShowStyleUserContext, config: ShowStyleConfig, partDefinition: PartDefinitionTelefon, totalWords: number - ) => BlueprintResultPart + ) => BlueprintResultPart | Promise CreatePartDVE?: ( context: IShowStyleUserContext, config: ShowStyleConfig, partDefinition: PartDefinitionDVE, totalWords: number - ) => BlueprintResultPart + ) => BlueprintResultPart | Promise CreatePartEVS?: ( context: IShowStyleUserContext, config: ShowStyleConfig, partDefinition: PartDefinitionEVS, totalWords: number - ) => BlueprintResultPart + ) => BlueprintResultPart | Promise } -export function getSegmentBase< +export async function getSegmentBase< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( context: IShowStyleUserContext, ingestSegment: IngestSegment, showStyleOptions: GetSegmentShowstyleOptions -): BlueprintResultSegment { +): Promise { const segmentPayload = ingestSegment.payload as INewsPayload | undefined const iNewsStory = segmentPayload?.iNewsStory const segment = literal({ @@ -168,7 +168,7 @@ export function getSegmentBase< part.type === PartType.Unknown && part.cues.filter(cue => cue.type === CueType.Jingle || cue.type === CueType.AdLib).length === 0 ) { - blueprintParts.push(showStyleOptions.CreatePartUnknown(context, config, part, totalWords, true)) + blueprintParts.push(await showStyleOptions.CreatePartUnknown(context, config, part, totalWords, true)) continue } @@ -186,18 +186,18 @@ export function getSegmentBase< switch (part.type) { case PartType.INTRO: if (showStyleOptions.CreatePartIntro) { - blueprintParts.push(showStyleOptions.CreatePartIntro(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartIntro(context, config, part, totalWords)) } break case PartType.Kam: if (showStyleOptions.CreatePartKam) { - blueprintParts.push(showStyleOptions.CreatePartKam(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartKam(context, config, part, totalWords)) } break case PartType.Server: if (showStyleOptions.CreatePartServer) { blueprintParts.push( - showStyleOptions.CreatePartServer(context, config, part, { + await showStyleOptions.CreatePartServer(context, config, part, { voLayer: false, voLevels: false, totalTime, @@ -210,18 +210,18 @@ export function getSegmentBase< break case PartType.Teknik: if (showStyleOptions.CreatePartTeknik) { - blueprintParts.push(showStyleOptions.CreatePartTeknik(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartTeknik(context, config, part, totalWords)) } break case PartType.Grafik: if (showStyleOptions.CreatePartGrafik) { - blueprintParts.push(showStyleOptions.CreatePartGrafik(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartGrafik(context, config, part, totalWords)) } break case PartType.VO: if (showStyleOptions.CreatePartServer) { blueprintParts.push( - showStyleOptions.CreatePartServer(context, config, part, { + await showStyleOptions.CreatePartServer(context, config, part, { voLayer: true, voLevels: true, totalTime, @@ -234,27 +234,27 @@ export function getSegmentBase< break case PartType.DVE: if (showStyleOptions.CreatePartDVE) { - blueprintParts.push(showStyleOptions.CreatePartDVE(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartDVE(context, config, part, totalWords)) } break case PartType.Ekstern: if (showStyleOptions.CreatePartEkstern) { - blueprintParts.push(showStyleOptions.CreatePartEkstern(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartEkstern(context, config, part, totalWords)) } break case PartType.Telefon: if (showStyleOptions.CreatePartTelefon) { - blueprintParts.push(showStyleOptions.CreatePartTelefon(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartTelefon(context, config, part, totalWords)) } break case PartType.Unknown: if (part.cues.length) { - blueprintParts.push(showStyleOptions.CreatePartUnknown(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartUnknown(context, config, part, totalWords)) } break case PartType.EVS: if (showStyleOptions.CreatePartEVS) { - blueprintParts.push(showStyleOptions.CreatePartEVS(context, config, part, totalWords)) + blueprintParts.push(await showStyleOptions.CreatePartEVS(context, config, part, totalWords)) } break default: diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index 1806341de..9b4ee4322 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -49,7 +49,7 @@ export type ServerPartLayers = { } } & MakeContentServerSourceLayers -export function CreatePartServerBase< +export async function CreatePartServerBase< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( @@ -58,14 +58,15 @@ export function CreatePartServerBase< partDefinition: PartDefinition, props: ServerPartProps, layers: ServerPartLayers -): { part: BlueprintResultPart; file: string; duration: number; invalid?: true } { +): Promise<{ part: BlueprintResultPart; file: string; duration: number; invalid?: true }> { if (isVideoIdMissing(partDefinition)) { context.notifyUserWarning('Video ID not set!') return { part: CreatePartInvalid(partDefinition), file: '', duration: 0, invalid: true } } const file = getVideoId(partDefinition) - const mediaObjectDuration = context.hackGetMediaObjectDuration(file) + const mediaObjectDurationSec = await context.hackGetMediaObjectDuration(file) + const mediaObjectDuration = mediaObjectDurationSec && mediaObjectDurationSec * 1000 const sourceDuration = getSourceDuration(mediaObjectDuration, config.studio.ServerPostrollDuration) const duration = getDuration(mediaObjectDuration, sourceDuration, props) const sanitisedScript = getScriptWithoutLineBreaks(partDefinition) @@ -128,7 +129,7 @@ function getSourceDuration( mediaObjectDuration: number | undefined, serverPostrollDuration: number ): number | undefined { - return mediaObjectDuration !== undefined ? mediaObjectDuration * 1000 - serverPostrollDuration : undefined + return mediaObjectDuration !== undefined ? mediaObjectDuration - serverPostrollDuration : undefined } function getDuration( diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index 2de6b15ed..fad4593aa 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -26,11 +26,14 @@ import { CreatePartServer } from './parts/server' import { CreatePartTeknik } from './parts/teknik' import { CreatePartUnknown } from './parts/unknown' import { postProcessPartTimelineObjects } from './postProcessTimelineObjects' -export function getSegment(context: ISegmentUserContext, ingestSegment: IngestSegment): BlueprintResultSegment { +export async function getSegment( + context: ISegmentUserContext, + ingestSegment: IngestSegment +): Promise { const config = getConfig(context) const segmentPayload = ingestSegment.payload as INewsPayload | undefined - const result: BlueprintResultSegment = getSegmentBase(context, ingestSegment, { + const result: BlueprintResultSegment = await getSegmentBase(context, ingestSegment, { getConfig, CreatePartContinuity, CreatePartUnknown, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts index 442e7f241..9718714f9 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts @@ -24,7 +24,7 @@ import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studi import { SourceLayer } from '../../layers' import { MakeContentDVE } from '../content/dve' -export function EvaluateAdLib( +export async function EvaluateAdLib( context: IShowStyleUserContext, config: BlueprintConfig, adLibPieces: IBlueprintAdLibPiece[], @@ -44,7 +44,7 @@ export function EvaluateAdLib( } const sourceDuration = Math.max( - (context.hackGetMediaObjectDuration(file) || 0) * 1000 - config.studio.ServerPostrollDuration, + ((await context.hackGetMediaObjectDuration(file)) || 0) * 1000 - config.studio.ServerPostrollDuration, 0 ) diff --git a/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts b/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts index 74089c556..46dc27b6f 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/evaluateCues.ts @@ -26,7 +26,7 @@ import { EvaluateJingle } from './jingle' import { EvaluateCueRouting } from './routing' import { EvaluateTelefon } from './telefon' -export function EvaluateCues( +export async function EvaluateCues( context: ISegmentUserContext, config: BlueprintConfig, part: IBlueprintPart, @@ -38,7 +38,7 @@ export function EvaluateCues( partDefinition: PartDefinition, options: EvaluateCuesOptions ) { - EvaluateCuesBase( + await EvaluateCuesBase( { EvaluateCueAdLib: EvaluateAdLib, EvaluateCueClearGrafiks: EvaluateClearGrafiks, diff --git a/src/tv2_afvd_showstyle/parts/cueonly.ts b/src/tv2_afvd_showstyle/parts/cueonly.ts index 8ecdee192..350a7f026 100644 --- a/src/tv2_afvd_showstyle/parts/cueonly.ts +++ b/src/tv2_afvd_showstyle/parts/cueonly.ts @@ -21,7 +21,7 @@ import { BlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' -export function CreatePartCueOnly( +export async function CreatePartCueOnly( context: ISegmentUserContext, config: BlueprintConfig, partDefinition: PartDefinition, @@ -54,11 +54,32 @@ export function CreatePartCueOnly( ApplyFullGraphicPropertiesToPart(config, part) } - EvaluateCues(context, config, part, pieces, adLibPieces, actions, mediaSubscriptions, [cue], partDefinitionWithID, {}) + await EvaluateCues( + context, + config, + part, + pieces, + adLibPieces, + actions, + mediaSubscriptions, + [cue], + partDefinitionWithID, + {} + ) AddScript(partDefinitionWithID, pieces, partTime, SourceLayer.PgmScript) if (makeAdlibs) { - EvaluateCues(context, config, part, pieces, adLibPieces, actions, mediaSubscriptions, [cue], partDefinitionWithID, { + await EvaluateCues( + context, + config, + part, + pieces, + adLibPieces, + actions, + mediaSubscriptions, + [cue], + partDefinitionWithID, + { adlib: true }) } diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index 9bd56cf18..041e2e092 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -33,12 +33,12 @@ import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' -export function CreatePartEVS( +export async function CreatePartEVS( context: ISegmentUserContext, config: BlueprintConfig, partDefinition: PartDefinitionEVS, totalWords: number -): BlueprintResultPart { +): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) let part = literal({ @@ -83,7 +83,7 @@ export function CreatePartEVS( }) ) - EvaluateCues( + await EvaluateCues( context, config, part, diff --git a/src/tv2_afvd_showstyle/parts/grafik.ts b/src/tv2_afvd_showstyle/parts/grafik.ts index da9b6040f..36c6989ad 100644 --- a/src/tv2_afvd_showstyle/parts/grafik.ts +++ b/src/tv2_afvd_showstyle/parts/grafik.ts @@ -20,12 +20,12 @@ import { BlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' -export function CreatePartGrafik( +export async function CreatePartGrafik( context: ISegmentUserContext, config: BlueprintConfig, partDefinition: PartDefinition, totalWords: number -): BlueprintResultPart { +): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) const part = literal({ externalId: partDefinition.externalId, @@ -42,7 +42,7 @@ export function CreatePartGrafik( ApplyFullGraphicPropertiesToPart(config, part) } - EvaluateCues( + await EvaluateCues( context, config, part, diff --git a/src/tv2_afvd_showstyle/parts/intro.ts b/src/tv2_afvd_showstyle/parts/intro.ts index ad9b560c2..9e41d554c 100644 --- a/src/tv2_afvd_showstyle/parts/intro.ts +++ b/src/tv2_afvd_showstyle/parts/intro.ts @@ -21,12 +21,12 @@ import { BlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' -export function CreatePartIntro( +export async function CreatePartIntro( context: ISegmentUserContext, config: BlueprintConfig, partDefinition: PartDefinition, totalWords: number -): BlueprintResultPart { +): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) const jingleCue = partDefinition.cues.find(cue => { @@ -77,7 +77,7 @@ export function CreatePartIntro( ...GetJinglePartProperties(context, config, partDefinition) } - EvaluateCues( + await EvaluateCues( context, config, part, diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index 889d6aac3..eeb7d9b03 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -35,12 +35,12 @@ import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' -export function CreatePartKam( +export async function CreatePartKam( context: ISegmentUserContext, config: BlueprintConfig, partDefinition: PartDefinitionKam, totalWords: number -): BlueprintResultPart { +): Promise { const partKamBase = CreatePartKamBase(context, config, partDefinition, totalWords) let part = partKamBase.part.part @@ -159,7 +159,7 @@ export function CreatePartKam( ) } - EvaluateCues( + await EvaluateCues( context, config, part, diff --git a/src/tv2_afvd_showstyle/parts/live.ts b/src/tv2_afvd_showstyle/parts/live.ts index d901d3bf2..958f95a15 100644 --- a/src/tv2_afvd_showstyle/parts/live.ts +++ b/src/tv2_afvd_showstyle/parts/live.ts @@ -14,12 +14,12 @@ import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' -export function CreatePartLive( +export async function CreatePartLive( context: ISegmentUserContext, config: BlueprintConfig, partDefinition: PartDefinition, totalWords: number -): BlueprintResultPart { +): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) let part = literal({ externalId: partDefinition.externalId, @@ -35,7 +35,7 @@ export function CreatePartLive( part = { ...part, ...CreateEffektForpart(context, config, partDefinition, pieces) } - EvaluateCues( + await EvaluateCues( context, config, part, diff --git a/src/tv2_afvd_showstyle/parts/server.ts b/src/tv2_afvd_showstyle/parts/server.ts index 82d951b7c..4e2f313ae 100644 --- a/src/tv2_afvd_showstyle/parts/server.ts +++ b/src/tv2_afvd_showstyle/parts/server.ts @@ -11,13 +11,13 @@ import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' -export function CreatePartServer( +export async function CreatePartServer( context: ISegmentUserContext, config: BlueprintConfig, partDefinition: PartDefinition, props: ServerPartProps -): BlueprintResultPart { - const basePartProps = CreatePartServerBase(context, config, partDefinition, props, { +): Promise { + const basePartProps = await CreatePartServerBase(context, config, partDefinition, props, { SourceLayer: { PgmServer: props.voLayer ? SourceLayer.PgmVoiceOver : SourceLayer.PgmServer, // TODO this actually is shared SelectedServer: props.voLayer ? SourceLayer.SelectedVoiceOver : SourceLayer.SelectedServer @@ -52,7 +52,7 @@ export function CreatePartServer( } AddScript(partDefinition, pieces, duration, SourceLayer.PgmScript) - EvaluateCues( + await EvaluateCues( context, config, part, diff --git a/src/tv2_afvd_showstyle/parts/teknik.ts b/src/tv2_afvd_showstyle/parts/teknik.ts index 777b4b365..42708b0ba 100644 --- a/src/tv2_afvd_showstyle/parts/teknik.ts +++ b/src/tv2_afvd_showstyle/parts/teknik.ts @@ -12,12 +12,12 @@ import { BlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' -export function CreatePartTeknik( +export async function CreatePartTeknik( context: ISegmentUserContext, config: BlueprintConfig, partDefinition: PartDefinition, totalWords: number -): BlueprintResultPart { +): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) const part = literal({ externalId: partDefinition.externalId, @@ -30,7 +30,7 @@ export function CreatePartTeknik( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - EvaluateCues( + await EvaluateCues( context, config, part, diff --git a/src/tv2_afvd_showstyle/parts/unknown.ts b/src/tv2_afvd_showstyle/parts/unknown.ts index a141069c7..eb79c1164 100644 --- a/src/tv2_afvd_showstyle/parts/unknown.ts +++ b/src/tv2_afvd_showstyle/parts/unknown.ts @@ -21,7 +21,7 @@ import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' import { CreateEffektForpart } from './effekt' -export function CreatePartUnknown( +export async function CreatePartUnknown( context: ISegmentUserContext, config: BlueprintConfig, partDefinition: PartDefinition, @@ -53,7 +53,7 @@ export function CreatePartUnknown( ApplyFullGraphicPropertiesToPart(config, part) } - EvaluateCues( + await EvaluateCues( context, config, part, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts index 5f8f3a4ad..49e7cc93e 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts @@ -27,7 +27,7 @@ import { OfftubeMakeContentDVE } from '../content/OfftubeDVEContent' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' import { OfftubeOutputLayers, OfftubeSourceLayer } from '../layers' -export function OfftubeEvaluateAdLib( +export async function OfftubeEvaluateAdLib( context: ISegmentUserContext, config: OfftubeShowstyleBlueprintConfig, _adLibPieces: IBlueprintAdLibPiece[], @@ -47,7 +47,7 @@ export function OfftubeEvaluateAdLib( } const sourceDuration = Math.max( - (context.hackGetMediaObjectDuration(file) || 0) * 1000 - config.studio.ServerPostrollDuration, + ((await context.hackGetMediaObjectDuration(file)) || 0) * 1000 - config.studio.ServerPostrollDuration, 0 ) diff --git a/src/tv2_offtube_showstyle/getSegment.ts b/src/tv2_offtube_showstyle/getSegment.ts index edc27e656..5c0175639 100644 --- a/src/tv2_offtube_showstyle/getSegment.ts +++ b/src/tv2_offtube_showstyle/getSegment.ts @@ -22,10 +22,13 @@ import { OfftubeCreatePartServer } from './parts/OfftubeServer' import { CreatePartUnknown } from './parts/OfftubeUnknown' import { postProcessPartTimelineObjects } from './postProcessTimelineObjects' -export function getSegment(context: ISegmentUserContext, ingestSegment: IngestSegment): BlueprintResultSegment { +export async function getSegment( + context: ISegmentUserContext, + ingestSegment: IngestSegment +): Promise { const config = getConfig(context) - const result: BlueprintResultSegment = getSegmentBase(context, ingestSegment, { + const result: BlueprintResultSegment = await getSegmentBase(context, ingestSegment, { getConfig, CreatePartContinuity, CreatePartUnknown, diff --git a/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts b/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts index d9d234cde..1744b59d3 100644 --- a/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts +++ b/src/tv2_offtube_showstyle/helpers/EvaluateCues.ts @@ -17,7 +17,7 @@ import { OfftubeEvaluateJingle } from '../cues/OfftubeJingle' import { OfftubeEvaluatePgmClean } from '../cues/OfftubePgmClean' import { OfftubeShowstyleBlueprintConfig } from './config' -export function OfftubeEvaluateCues( +export async function OfftubeEvaluateCues( context: ISegmentUserContext, config: OfftubeShowstyleBlueprintConfig, part: IBlueprintPart, @@ -29,7 +29,7 @@ export function OfftubeEvaluateCues( partDefinition: PartDefinition, options: EvaluateCuesOptions ) { - EvaluateCuesBase( + await EvaluateCuesBase( { EvaluateCueDVE: OfftubeEvaluateDVE, EvaluateCueJingle: OfftubeEvaluateJingle, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts b/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts index 73453cb57..f8cfbc835 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts @@ -12,12 +12,12 @@ import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' -export function OfftubeCreatePartDVE( +export async function OfftubeCreatePartDVE( context: ISegmentUserContext, config: OfftubeShowstyleBlueprintConfig, partDefinition: PartDefinitionDVE, totalWords: number -): BlueprintResultPart { +): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) const part = literal({ @@ -31,7 +31,7 @@ export function OfftubeCreatePartDVE( const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] - OfftubeEvaluateCues( + await OfftubeEvaluateCues( context, config, part, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts index fa4867c0f..8282b8deb 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts @@ -11,7 +11,7 @@ import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' -export function OfftubeCreatePartGrafik( +export async function OfftubeCreatePartGrafik( context: ISegmentUserContext, config: OfftubeShowstyleBlueprintConfig, partDefinition: PartDefinition, @@ -35,7 +35,7 @@ export function OfftubeCreatePartGrafik( ApplyFullGraphicPropertiesToPart(config, part) - OfftubeEvaluateCues( + await OfftubeEvaluateCues( context, config, part, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index f8b38399b..35d509068 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -35,12 +35,12 @@ import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' import { CreateEffektForpart } from './OfftubeEffekt' -export function OfftubeCreatePartKam( +export async function OfftubeCreatePartKam( context: ISegmentUserContext, config: OfftubeShowstyleBlueprintConfig, partDefinition: PartDefinitionKam, totalWords: number -): BlueprintResultPart { +): Promise { const partKamBase = CreatePartKamBase(context, config, partDefinition, totalWords) let part = partKamBase.part.part @@ -154,7 +154,7 @@ export function OfftubeCreatePartKam( ) } - OfftubeEvaluateCues( + await OfftubeEvaluateCues( context, config, part, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts index f3bd50ee3..71a077b0f 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts @@ -11,13 +11,13 @@ import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' import { CreateEffektForpart } from './OfftubeEffekt' -export function OfftubeCreatePartServer( +export async function OfftubeCreatePartServer( context: ISegmentUserContext, config: OfftubeShowstyleBlueprintConfig, partDefinition: PartDefinition, props: ServerPartProps -): BlueprintResultPart { - const basePartProps = CreatePartServerBase(context, config, partDefinition, props, { +): Promise { + const basePartProps = await CreatePartServerBase(context, config, partDefinition, props, { SourceLayer: { PgmServer: props.voLayer ? OfftubeSourceLayer.PgmVoiceOver : OfftubeSourceLayer.PgmServer, // TODO this actually is shared SelectedServer: props.voLayer ? OfftubeSourceLayer.SelectedVoiceOver : OfftubeSourceLayer.SelectedServer @@ -53,7 +53,7 @@ export function OfftubeCreatePartServer( part = { ...part, ...CreateEffektForpart(context, config, partDefinition, pieces) } const sourceDuration = Math.max( - (context.hackGetMediaObjectDuration(file) || 0) * 1000 - config.studio.ServerPostrollDuration, + ((await context.hackGetMediaObjectDuration(file)) || 0) * 1000 - config.studio.ServerPostrollDuration, 0 ) @@ -90,7 +90,7 @@ export function OfftubeCreatePartServer( ) ) - OfftubeEvaluateCues( + await OfftubeEvaluateCues( context, config, part, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts index fcf7ff70f..0b90e1fa3 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts @@ -20,7 +20,7 @@ import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' -export function CreatePartUnknown( +export async function CreatePartUnknown( context: ISegmentUserContext, config: OfftubeShowstyleBlueprintConfig, partDefinition: PartDefinition, @@ -51,7 +51,7 @@ export function CreatePartUnknown( ApplyFullGraphicPropertiesToPart(config, part) } - OfftubeEvaluateCues( + await OfftubeEvaluateCues( context, config, part, From a304b66d9a06c8b276b1db337783db383ab1c728 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 31 May 2022 11:10:14 +0200 Subject: [PATCH 116/184] feat: SOF-767 add Server Resume --- src/tv2-common/actions/executeAction.ts | 93 +++++++++---- src/tv2-common/content/dve.ts | 1 + src/tv2-common/content/server.ts | 28 ++-- src/tv2-common/evaluateCues.ts | 6 +- src/tv2-common/helpers/index.ts | 1 + src/tv2-common/helpers/serverResume.ts | 170 ++++++++++++++++++++++++ src/tv2-common/onTimelineGenerate.ts | 19 ++- src/tv2-common/parts/server.ts | 8 +- src/tv2-common/pieces/adlibServer.ts | 7 +- src/tv2_afvd_showstyle/actions.ts | 6 +- src/tv2_afvd_showstyle/parts/cueonly.ts | 5 +- 11 files changed, 288 insertions(+), 56 deletions(-) create mode 100644 src/tv2-common/helpers/serverResume.ts diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index a9e5ecbe9..b330ebb0d 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -72,7 +72,7 @@ import { } from 'tv2-constants' import _ = require('underscore') import { EnableServer } from '../content' -import { CreateFullDataStore, GetEnableForWall, PilotGeneratorSettings } from '../helpers' +import { CreateFullDataStore, GetEnableForWall, getServerPosition, PilotGeneratorSettings } from '../helpers' import { InternalGraphic } from '../helpers/graphics/InternalGraphic' import { GetJinglePartPropertiesFromTableValue } from '../jinglePartProperties' import { CreateEffektForPartBase, CreateEffektForPartInner, CreateMixForPartInner } from '../parts' @@ -195,7 +195,8 @@ export async function executeAction< coreContext: IActionExecutionContext, settings: ActionExecutionSettings, actionIdStr: string, - userData: ActionUserData + userData: ActionUserData, + triggerMode?: string ): Promise { await executeWithContext(coreContext, async context => { const existingTransition = await getExistingTransition(context, settings, 'next') @@ -204,7 +205,13 @@ export async function executeAction< switch (actionId) { case AdlibActionType.SELECT_SERVER_CLIP: - await executeActionSelectServerClip(context, settings, actionId, userData as ActionSelectServerClip) + await executeActionSelectServerClip( + context, + settings, + actionId, + userData as ActionSelectServerClip, + triggerMode + ) break case AdlibActionType.SELECT_DVE: await executeActionSelectDVE(context, settings, actionId, userData as ActionSelectDVE) @@ -390,6 +397,7 @@ async function executeActionSelectServerClip< settings: ActionExecutionSettings, actionId: string, userData: ActionSelectServerClip, + triggerMode?: string, sessionToContinue?: string ) { const file = userData.file @@ -403,12 +411,15 @@ async function executeActionSelectServerClip< .getPieceInstances('current') .then(pieceInstances => pieceInstances.find( - p => p.piece.sourceLayerId === (userData.voLayer ? settings.SourceLayers.VO : settings.SourceLayers.Server) + p => + p.piece.sourceLayerId === (userData.voLayer ? settings.SourceLayers.VO : settings.SourceLayers.Server) || + (p.piece.sourceLayerId === settings.SourceLayers.DVEAdLib && + dveContainsServer((p.piece.metaData as DVEPieceMetaData).sources)) ) ) : undefined - const basePart = CreatePartServerBase( + const basePart = await CreatePartServerBase( context, config, partDefinition, @@ -419,7 +430,9 @@ async function executeActionSelectServerClip< totalTime: 0, tapeTime: userData.duration / 1000, session: sessionToContinue ?? externalId, - adLibPix: userData.adLibPix + adLibPix: userData.adLibPix, + lastServerPosition: await getServerPosition(context), + actionTriggerMode: triggerMode }, { SourceLayer: { @@ -623,21 +636,28 @@ async function cutServerToBox< >( context: ITV2ActionExecutionContext, settings: ActionExecutionSettings, - dvePiece: IBlueprintPiece + newDvePiece: IBlueprintPiece, + containedServerBefore?: boolean, + modifiesCurrent?: boolean ): Promise { // Check if DVE should continue server + copy server properties - if (!dvePiece.metaData) { - return dvePiece + if (!newDvePiece.metaData) { + return newDvePiece } - const meta = dvePiece.metaData as DVEPieceMetaData + const meta = newDvePiece.metaData as DVEPieceMetaData - if (!dveContainsServer(meta.sources)) { - return dvePiece + const containsServer = dveContainsServer(meta.sources) + + if (!containsServer) { + if (containedServerBefore) { + stopServerMetadata(context, meta) + } + return newDvePiece } - if (dvePiece.content?.timelineObjects) { + if (newDvePiece.content?.timelineObjects) { const currentServer = await context .getPieceInstances('current') .then(currentPieces => @@ -650,7 +670,7 @@ async function cutServerToBox< if (!currentServer || !currentServer.piece.content?.timelineObjects) { context.notifyUserWarning(`No server is playing, cannot start DVE`) - return dvePiece + return newDvePiece } // Find existing CasparCG object @@ -662,8 +682,8 @@ async function cutServerToBox< obj => obj.layer === settings.LLayer.Sisyfos.ClipPending ) as TSR.TimelineObjSisyfosChannel & TimelineBlueprintExt // Find SSRC object in DVE piece - const ssrcObjIndex = dvePiece.content?.timelineObjects - ? (dvePiece.content?.timelineObjects as TSR.TSRTimelineObj[]).findIndex( + const ssrcObjIndex = newDvePiece.content?.timelineObjects + ? (newDvePiece.content?.timelineObjects as TSR.TSRTimelineObj[]).findIndex( obj => obj.layer === settings.LLayer.Atem.SSrcDefault ) : -1 @@ -676,27 +696,46 @@ async function cutServerToBox< !existingCasparObj.metaData.mediaPlayerSession ) { context.notifyUserWarning(`Failed to start DVE with server`) - return dvePiece + return newDvePiece } - const ssrcObj = (dvePiece.content.timelineObjects as Array)[ssrcObjIndex] + const ssrcObj = (newDvePiece.content.timelineObjects as Array)[ + ssrcObjIndex + ] ssrcObj.metaData = { ...ssrcObj.metaData, mediaPlayerSession: existingCasparObj.metaData.mediaPlayerSession } - dvePiece.content.timelineObjects[ssrcObjIndex] = ssrcObj - dvePiece.content.timelineObjects.push(EnableServer(existingCasparObj.metaData.mediaPlayerSession)) + newDvePiece.content.timelineObjects[ssrcObjIndex] = ssrcObj + newDvePiece.content.timelineObjects.push(EnableServer(existingCasparObj.metaData.mediaPlayerSession)) + ;(newDvePiece.metaData as any).mediaPlayerSessions = [existingCasparObj.metaData.mediaPlayerSession] - if (!dvePiece.metaData) { - dvePiece.metaData = {} + if (!containedServerBefore) { + startServerMetadata(context, meta, modifiesCurrent) } + } - ;(dvePiece.metaData as any).mediaPlayerSessions = [existingCasparObj.metaData.mediaPlayerSession] + return newDvePiece +} + +function stopServerMetadata(context: ITV2ActionExecutionContext, metaData: DVEPieceMetaData) { + const length = metaData.serverPlaybackTiming?.length + if (metaData.serverPlaybackTiming && length) { + metaData.serverPlaybackTiming[length - 1].end = context.getCurrentTime() } +} - return dvePiece +function startServerMetadata( + context: ITV2ActionExecutionContext, + metaData: DVEPieceMetaData, + modifiesCurrent?: boolean +) { + if (!metaData.serverPlaybackTiming) { + metaData.serverPlaybackTiming = [] + } + metaData.serverPlaybackTiming.push(modifiesCurrent ? { start: context.getCurrentTime() } : {}) } async function executeActionSelectDVELayout< @@ -1340,8 +1379,8 @@ async function executeActionCutSourceToBox< } let newDVEPiece: IBlueprintPiece = { ...modifiedPiece.piece, content: newPieceContent.content, metaData: meta } - if (!(containsServerBefore && containsServerAfter)) { - newDVEPiece = await cutServerToBox(context, settings, newDVEPiece) + if (!containsServerBefore || !containsServerAfter) { + newDVEPiece = await cutServerToBox(context, settings, newDVEPiece, !!containsServerBefore, modify === 'current') } if (newPieceContent.valid) { @@ -1676,7 +1715,7 @@ async function executeActionCommentatorSelectServer< session = sessions.session } - await executeActionSelectServerClip(context, settings, AdlibActionType.SELECT_SERVER_CLIP, data, session) + await executeActionSelectServerClip(context, settings, AdlibActionType.SELECT_SERVER_CLIP, data, undefined, session) } async function executeActionCommentatorSelectDVE< diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index fb71b4700..a6d986078 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -109,6 +109,7 @@ export interface DVEPieceMetaData { sources: DVESources userData: ActionSelectDVE mediaPlayerSessions?: string[] // TODO: Should probably move to a ServerPieceMetaData + serverPlaybackTiming?: Array<{ start?: number; end?: number }> } export interface DVETimelineObjectGenerators { diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 7529fa799..42b7285b8 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -34,17 +34,17 @@ export interface MakeContentServerSourceLayers { } } -export interface VTFields { - file: string - duration: number -} - type VTProps = Pick< VTContent, - 'fileName' | 'path' | 'mediaFlowIds' | 'ignoreMediaObjectStatus' | 'sourceDuration' | 'postrollDuration' + 'fileName' | 'path' | 'mediaFlowIds' | 'ignoreMediaObjectStatus' | 'sourceDuration' | 'postrollDuration' | 'seek' > -export function GetVTContentProperties(config: TV2BlueprintConfig, file: string, sourceDuration?: number): VTProps { +export function GetVTContentProperties( + config: TV2BlueprintConfig, + file: string, + seek?: number, + sourceDuration?: number +): VTProps { return literal({ fileName: file, path: JoinAssetToNetworkPath( @@ -56,7 +56,8 @@ export function GetVTContentProperties(config: TV2BlueprintConfig, file: string, mediaFlowIds: [config.studio.ClipMediaFlowId], sourceDuration: sourceDuration && sourceDuration > 0 ? sourceDuration : undefined, postrollDuration: config.studio.ServerPostrollDuration, - ignoreMediaObjectStatus: config.studio.ClipIgnoreStatus + ignoreMediaObjectStatus: config.studio.ClipIgnoreStatus, + seek }) } @@ -69,10 +70,11 @@ export function MakeContentServer( sourceLayers: MakeContentServerSourceLayers, adLibPix: boolean, voLevels: boolean, + seek?: number, sourceDuration?: number ): WithTimeline { return literal>({ - ...GetVTContentProperties(config, file, sourceDuration), + ...GetVTContentProperties(config, file, seek, sourceDuration), ignoreMediaObjectStatus: true, timelineObjects: GetServerTimeline( context, @@ -82,7 +84,8 @@ export function MakeContentServer( config, sourceLayers, adLibPix, - voLevels + voLevels, + seek ) }) } @@ -95,7 +98,8 @@ function GetServerTimeline( config: TV2BlueprintConfig, sourceLayers: MakeContentServerSourceLayers, adLibPix?: boolean, - voLevels?: boolean + voLevels?: boolean, + seek?: number ) { const serverEnableClass = `.${GetEnableClassForServer(mediaPlayerSessionId)}` @@ -111,7 +115,7 @@ function GetServerTimeline( type: TSR.TimelineContentTypeCasparCg.MEDIA, file, loop: adLibPix, - seek: 0, + seek, // length: duration, playing: true }, diff --git a/src/tv2-common/evaluateCues.ts b/src/tv2-common/evaluateCues.ts index f7ea64330..12686f236 100644 --- a/src/tv2-common/evaluateCues.ts +++ b/src/tv2-common/evaluateCues.ts @@ -109,7 +109,7 @@ export interface EvaluateCuesShowstyleOptions { parsedCue: CueDefinitionAdLib, partDefinition: PartDefinition, rank: number - ) => void + ) => Promise EvaluateCueTelefon?: ( config: TV2BlueprintConfig, context: ISegmentUserContext, @@ -187,7 +187,7 @@ export interface EvaluateCuesOptions { adlibsOnly?: boolean } -export function EvaluateCuesBase( +export async function EvaluateCuesBase( showStyleOptions: EvaluateCuesShowstyleOptions, context: ISegmentUserContext, config: TV2BlueprintConfig, @@ -280,7 +280,7 @@ export function EvaluateCuesBase( break case CueType.AdLib: if (showStyleOptions.EvaluateCueAdLib) { - showStyleOptions.EvaluateCueAdLib( + await showStyleOptions.EvaluateCueAdLib( context, config, adLibPieces, diff --git a/src/tv2-common/helpers/index.ts b/src/tv2-common/helpers/index.ts index b5ac9914f..9e36821ab 100644 --- a/src/tv2-common/helpers/index.ts +++ b/src/tv2-common/helpers/index.ts @@ -7,6 +7,7 @@ export * from './rundownAdLibActions' export * from './postProcessDefinitions' export * from './translation' export * from './adLibNames' +export * from './serverResume' export function SanitizePath(path: string): string { return path.replace(/[\/\\]*$/, '') diff --git a/src/tv2-common/helpers/serverResume.ts b/src/tv2-common/helpers/serverResume.ts new file mode 100644 index 000000000..5c8804372 --- /dev/null +++ b/src/tv2-common/helpers/serverResume.ts @@ -0,0 +1,170 @@ +import { + IActionExecutionContext, + IBlueprintActionTriggerMode, + IBlueprintPartInstance, + IBlueprintResolvedPieceInstance, + ICommonContext, + VTContent +} from '@tv2media/blueprints-integration' +import { PartEndStateExt, t } from 'tv2-common' +import { SharedSourceLayers } from 'tv2-constants' +import _ = require('underscore') +import { DVEPieceMetaData } from '../content' + +/** If the seek position is closer to the end of the file than this value, it will be reset to 0. */ +const REMAINING_DURATION_BEFORE_RESET = 2 * 1000 + +export interface ServerPosition { + fileName: string + lastEnd: number + isPlaying: boolean + fromPartInstanceId: string +} + +export enum ServerSelectMode { + RESUME = 'resume', + RESET = 'reset' +} + +export function getServerSeek( + lastServerPosition: ServerPosition | undefined, + fileName: string, + mediaObjectDuration?: number, + triggerMode?: string +): number { + if (triggerMode === ServerSelectMode.RESET) { + return 0 + } + if (lastServerPosition?.fileName === fileName && !lastServerPosition.isPlaying) { + if (!mediaObjectDuration) { + return lastServerPosition.lastEnd + } + const seek = lastServerPosition.lastEnd % mediaObjectDuration + const remainingDuration = mediaObjectDuration - seek + if (remainingDuration > REMAINING_DURATION_BEFORE_RESET) { + return seek + } + } + return 0 +} + +export async function getServerPosition( + context: IActionExecutionContext, + replacingCurrentPieceWithOffset?: number +): Promise { + const partInstance = await context.getPartInstance('current') + if (!partInstance) { + throw new Error('Missing current PartInstance while calculating serverOffsets') + } + + const pieceEnd = + replacingCurrentPieceWithOffset !== undefined + ? context.getCurrentTime() + replacingCurrentPieceWithOffset + : undefined + + return getServerPositionForPartInstance( + context, + partInstance, + await context.getResolvedPieceInstances('current'), + pieceEnd + ) +} + +/** + * Calculate the offsets for clips based on the pieceinstances that have already been played. + */ +export function getServerPositionForPartInstance( + _context: ICommonContext, + partInstance: IBlueprintPartInstance, + pieceInstances: IBlueprintResolvedPieceInstance[], + setCurrentPieceToNow0?: number +): ServerPosition | undefined { + const setCurrentPieceToNow = + setCurrentPieceToNow0 !== undefined && partInstance.timings?.startedPlayback + ? setCurrentPieceToNow0 - partInstance.timings.startedPlayback + : undefined + + const previousPartEndState = partInstance.previousPartEndState as Partial | undefined + const previousServerPosition = previousPartEndState?.serverPosition + + const currentPiecesWithServer = _.sortBy(pieceInstances.filter(shouldPreservePosition), p => p.resolvedStart) + + let currentServerPosition = + previousPartEndState?.segmentId === partInstance.segmentId ? previousServerPosition : undefined + + for (const pieceInstance of currentPiecesWithServer) { + const pieceDuration = + pieceInstance.resolvedDuration || + (setCurrentPieceToNow !== undefined ? setCurrentPieceToNow - pieceInstance.resolvedStart : undefined) + + const content = pieceInstance.piece.content as VTContent | undefined + if (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmServer && content) { + const pieceSeek = content.seek ?? 0 + const pieceClipEnd = pieceSeek + (pieceDuration ?? 0) + const isPlaying = + (previousServerPosition?.fileName === content.fileName && previousServerPosition?.isPlaying) || !pieceDuration + currentServerPosition = { + fileName: content.fileName, + lastEnd: pieceClipEnd, + isPlaying, + fromPartInstanceId: partInstance._id + } + } else if (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmDVEAdLib) { + const serverPlaybackTiming = (pieceInstance.piece.metaData as DVEPieceMetaData | undefined)?.serverPlaybackTiming + if (serverPlaybackTiming) { + for (const timing of serverPlaybackTiming) { + const start = timing.start ?? pieceInstance.resolvedStart + const end = timing.end ?? (pieceDuration ? pieceInstance.resolvedStart + pieceDuration : undefined) + if (currentServerPosition && end) { + currentServerPosition.lastEnd += end - start + currentServerPosition.fromPartInstanceId = partInstance._id + } + } + } + } + } + + const inTransitionDuration = partInstance.part.inTransition?.previousPartKeepaliveDuration + if ( + currentServerPosition && + !currentPiecesWithServer.length && + inTransitionDuration && + currentServerPosition?.fromPartInstanceId === previousPartEndState?.partInstanceId + ) { + currentServerPosition.lastEnd += inTransitionDuration + } + + return currentServerPosition +} + +export function shouldPreservePosition(pieceInstance: IBlueprintResolvedPieceInstance): boolean { + return ( + !!pieceInstance.dynamicallyInserted && + (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmServer || + (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmDVEAdLib && + !!(pieceInstance.piece.metaData as DVEPieceMetaData | undefined)?.serverPlaybackTiming)) + ) +} + +export function hasTransition(pieceInstance: IBlueprintResolvedPieceInstance): boolean { + return pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmJingle +} + +export function getServerAdLibTriggerModes(): IBlueprintActionTriggerMode[] { + return [ + { + data: ServerSelectMode.RESUME, + display: { + _rank: 0, + label: t('Resume') + } + }, + { + data: ServerSelectMode.RESET, + display: { + _rank: 1, + label: t('From Start') + } + } + ] +} diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index e43dbaa11..c16012854 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -17,13 +17,16 @@ import { AbstractLLayer, TallyTags } from 'tv2-constants' import * as _ from 'underscore' import { SisyfosLLAyer } from '../tv2_afvd_studio/layers' import { TV2BlueprintConfigBase, TV2StudioConfigBase } from './blueprintConfig' -import { ABSourceLayers, assignMediaPlayers } from './helpers' +import { ABSourceLayers, assignMediaPlayers, getServerPositionForPartInstance, ServerPosition } from './helpers' export interface PartEndStateExt { sisyfosPersistMetaData: SisyfosPersistMetaData mediaPlayerSessions: { [layer: string]: string[] } isJingle?: boolean fullFileName?: string + serverPosition?: ServerPosition + segmentId?: string + partInstanceId: string } export interface MediaPlayerClaim { @@ -190,15 +193,15 @@ function isAnyPieceInjectedIntoPart(resolvedPieces: IBlueprintResolvedPieceInsta return resolvedPieces .filter(piece => piece.partInstanceId === context.currentPartInstance?._id) .some(piece => { - const metaData = piece.piece.metaData as PieceMetaData + const metaData = piece.piece.metaData as PieceMetaData | undefined return metaData?.sisyfosPersistMetaData?.isPieceInjectedInPart }) } export function getEndStateForPart( - _context: IRundownContext, + context: IRundownContext, _previousPersistentState: TimelinePersistentState | undefined, - partInstance: IBlueprintPartInstance | undefined, + partInstance: IBlueprintPartInstance, resolvedPieces: IBlueprintResolvedPieceInstance[], time: number ): PartEndState { @@ -206,7 +209,9 @@ export function getEndStateForPart( sisyfosPersistMetaData: { sisyfosLayers: [] }, - mediaPlayerSessions: {} + mediaPlayerSessions: {}, + segmentId: partInstance.segmentId, + partInstanceId: partInstance._id } const previousPartEndState = partInstance?.previousPartEndState as Partial @@ -243,6 +248,8 @@ export function getEndStateForPart( } } + endState.serverPosition = getServerPositionForPartInstance(context, partInstance, resolvedPieces, time) + return endState } @@ -300,7 +307,7 @@ function findLayersToPersist( ): string[] { const sortedPieces = pieces .filter(piece => { - const metaData = piece.piece.metaData as PieceMetaData + const metaData = piece.piece.metaData as PieceMetaData | undefined return metaData?.sisyfosPersistMetaData }) .sort((a, b) => b.resolvedStart - a.resolvedStart) diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index 9b4ee4322..0adb03aaa 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -20,6 +20,7 @@ import { AdlibActionType, PartType, SharedOutputLayers, TallyTags } from 'tv2-co import { ActionSelectServerClip } from '../actions' import { TV2BlueprintConfigBase, TV2StudioConfigBase } from '../blueprintConfig' import { GetVTContentProperties } from '../content' +import { getServerSeek, ServerPosition } from '../helpers' import { PartDefinition } from '../inewsConversion' import { literal, SanitizeString } from '../util' import { CreatePartInvalid } from './invalid' @@ -36,6 +37,9 @@ export interface ServerPartProps { tapeTime: number adLibPix: boolean session?: string + lastServerPosition?: ServerPosition + actionTriggerMode?: string + seek?: number } export type ServerPartLayers = { @@ -71,6 +75,7 @@ export async function CreatePartServerBase< const duration = getDuration(mediaObjectDuration, sourceDuration, props) const sanitisedScript = getScriptWithoutLineBreaks(partDefinition) const actualDuration = getActualDuration(duration, sanitisedScript, props) + props.seek = getServerSeek(props.lastServerPosition, file, mediaObjectDuration, props.actionTriggerMode) const displayTitle = getDisplayTitle(partDefinition) const basePart = getBasePart(partDefinition, displayTitle, actualDuration, file) @@ -228,6 +233,7 @@ function getContentServerElement< }, props.adLibPix, props.voLevels, + props.seek, sourceDuration ) } @@ -304,7 +310,7 @@ function getPgmBlueprintPiece< mediaPlayerSessions: [mediaPlayerSession] }), content: { - ...GetVTContentProperties(config, file, sourceDuration), + ...GetVTContentProperties(config, file, props.seek, sourceDuration), timelineObjects: CutToServer(mediaPlayerSession, partDefinition, config, layers.AtemLLayer.MEPgm) }, tags: [GetTagForServer(partDefinition.segmentExternalId, file, props.voLayer), TallyTags.SERVER_IS_LIVE], diff --git a/src/tv2-common/pieces/adlibServer.ts b/src/tv2-common/pieces/adlibServer.ts index 6d376c8ce..7d4e72d3d 100644 --- a/src/tv2-common/pieces/adlibServer.ts +++ b/src/tv2-common/pieces/adlibServer.ts @@ -11,7 +11,7 @@ import { TV2StudioConfigBase } from 'tv2-common' import { AdlibActionType, AdlibTags, SharedOutputLayers } from 'tv2-constants' -import { t } from '../helpers' +import { getServerAdLibTriggerModes, t } from '../helpers' export interface AdlibServerOfftubeOptions { /** By passing in this object, you're creating a server according to the OFFTUBE showstyle. */ @@ -50,7 +50,7 @@ export function CreateAdlibServer< label: t(`${partDefinition.storyName}`), sourceLayerId: sourceLayers.SourceLayer.PgmServer, outputLayerId: SharedOutputLayers.PGM, - content: GetVTContentProperties(config, file, duration), + content: GetVTContentProperties(config, file, 0, duration), tags: [ tagAsAdlib || voLayer ? AdlibTags.OFFTUBE_ADLIB_SERVER : AdlibTags.OFFTUBE_100pc_SERVER, AdlibTags.ADLIB_KOMMENTATOR, @@ -59,6 +59,7 @@ export function CreateAdlibServer< currentPieceTags: [GetTagForServer(partDefinition.segmentExternalId, file, !!voLayer)], nextPieceTags: [GetTagForServerNext(partDefinition.segmentExternalId, file, !!voLayer)], uniquenessId: `${voLayer ? 'vo' : 'server'}_${partDefinition.storyName}_${file}` - } + }, + triggerModes: getServerAdLibTriggerModes() }) } diff --git a/src/tv2_afvd_showstyle/actions.ts b/src/tv2_afvd_showstyle/actions.ts index 233d89554..beebb70f6 100644 --- a/src/tv2_afvd_showstyle/actions.ts +++ b/src/tv2_afvd_showstyle/actions.ts @@ -12,7 +12,8 @@ import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' export async function executeActionAFVD( context: IActionExecutionContext, actionId: string, - userData: ActionUserData + userData: ActionUserData, + triggerMode?: string ): Promise { await executeAction( context, @@ -66,6 +67,7 @@ export async function executeActionAFVD( pilotGraphicSettings: pilotGeneratorSettingsAFVD }, actionId, - userData + userData, + triggerMode ) } diff --git a/src/tv2_afvd_showstyle/parts/cueonly.ts b/src/tv2_afvd_showstyle/parts/cueonly.ts index 350a7f026..22eced5db 100644 --- a/src/tv2_afvd_showstyle/parts/cueonly.ts +++ b/src/tv2_afvd_showstyle/parts/cueonly.ts @@ -80,8 +80,9 @@ export async function CreatePartCueOnly( [cue], partDefinitionWithID, { - adlib: true - }) + adlib: true + } + ) } part.hackListenToMediaObjectUpdates = mediaSubscriptions From d8ff4e139781b6523866512094ff3eca802a5148 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 31 May 2022 11:41:41 +0200 Subject: [PATCH 117/184] fix: SOF-954 update tests --- src/__mocks__/context.ts | 6 +- .../__tests__/blueprint.spec.ts | 116 +++++++++--------- .../__tests__/rundown_story_exception.spec.ts | 4 +- .../__tests__/transitions.spec.ts | 60 ++++----- .../__tests__/graphics.spec.ts | 36 +++--- 5 files changed, 111 insertions(+), 111 deletions(-) diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index 745e7087b..36f69d7eb 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -181,7 +181,7 @@ export class ShowStyleContext extends StudioContext implements IShowStyleContext public getShowStyleConfigRef(_configKey: string): string { return 'test' } - public hackGetMediaObjectDuration(_mediaId: string): number | undefined { + public async hackGetMediaObjectDuration(_mediaId: string): Promise { return undefined } } @@ -275,7 +275,7 @@ export class SegmentUserContext extends RundownContext implements ISegmentUserCo ) { this.pushNote(NoteType.NOTIFY_USER_WARNING, message) } - public hackGetMediaObjectDuration(_mediaId: string): number | undefined { + public async hackGetMediaObjectDuration(_mediaId: string): Promise { return undefined } public getPackageInfo(_packageId: string): readonly PackageInfo.Any[] { @@ -578,7 +578,7 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct return take } - public hackGetMediaObjectDuration(_mediaId: string): number | undefined { + public async hackGetMediaObjectDuration(_mediaId: string): Promise { return undefined } public getPackageInfo(_packageId: string): PackageInfo.Any[] { diff --git a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts index 137ce3986..536f5ae59 100644 --- a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts @@ -66,10 +66,10 @@ function expectAllPartsToBeValid(result: BlueprintResultSegment) { } describe('AFVD Blueprint', () => { - it('Accepts KAM CS 3', () => { + it('Accepts KAM CS 3', async () => { const ingestSegment = makeIngestSegment([], `\r\nKam CS 3\r\n`) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(1) @@ -82,10 +82,10 @@ describe('AFVD Blueprint', () => { expect(kamPart.pieces[0].name).toEqual('CS 3 (JINGLE)') }) - it('Accepts KAM CS3', () => { + it('Accepts KAM CS3', async () => { const ingestSegment = makeIngestSegment([], `\r\nKam CS3\r\n`) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(1) @@ -98,7 +98,7 @@ describe('AFVD Blueprint', () => { expect(kamPart.pieces[0].name).toEqual('CS 3 (JINGLE)') }) - it('Shows warning for Pilot without destination', () => { + it('Shows warning for Pilot without destination', async () => { const ingestSegment = makeIngestSegment( [ [ @@ -112,7 +112,7 @@ describe('AFVD Blueprint', () => { `\r\nKam 1\r\n

Some script

\r\n

\r\n` ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['Graphic found without target engine']) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(1) @@ -126,13 +126,13 @@ describe('AFVD Blueprint', () => { expect(kamPart.actions).toHaveLength(0) }) - it('Creates invalid part for standalone GRAFIK=FULL', () => { + it('Creates invalid part for standalone GRAFIK=FULL', async () => { const ingestSegment = makeIngestSegment( [['GRAFIK=FULL']], `\r\nKam 1\r\n

Some script

\r\n

\r\n` ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after GRAFIK cue']) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(2) @@ -149,7 +149,7 @@ describe('AFVD Blueprint', () => { expect(fullPart.part.invalid).toBe(true) }) - it('Creates graphic for GRAFIK=FULL with Pilot', () => { + it('Creates graphic for GRAFIK=FULL with Pilot', async () => { const ingestSegment = makeIngestSegment( [ ['GRAFIK=FULL'], @@ -164,7 +164,7 @@ describe('AFVD Blueprint', () => { `\r\nKam 1\r\n

Some script

\r\n

\r\n

\r\n` ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(2) @@ -193,7 +193,7 @@ describe('AFVD Blueprint', () => { ) }) - it("Doesn't merge MOSART=L with GRAFIK=FULL", () => { + it("Doesn't merge MOSART=L with GRAFIK=FULL", async () => { const ingestSegment = makeIngestSegment( [ ['GRAFIK=FULL'], @@ -209,7 +209,7 @@ describe('AFVD Blueprint', () => { `\r\nKam 1\r\n

Some script

\r\n

\r\n

\r\n` ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after GRAFIK cue']) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(2) @@ -226,7 +226,7 @@ describe('AFVD Blueprint', () => { expect(fullPart.part.invalid).toBe(true) }) - it('Creates full when cues are correct and shows warning when OVL with FULL is disabled', () => { + it('Creates full when cues are correct and shows warning when OVL with FULL is disabled', async () => { const ingestSegment = makeIngestSegment( [ ['GRAFIK=FULL'], @@ -249,7 +249,7 @@ describe('AFVD Blueprint', () => { `\r\nKam 1\r\n

Some script

\r\n

\r\n

\r\n

\r\n` ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['Cannot create overlay graphic with FULL']) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(2) @@ -278,7 +278,7 @@ describe('AFVD Blueprint', () => { ]) }) - it('Creates full when cues are correct and creates overlay when allowed', () => { + it('Creates full when cues are correct and creates overlay when allowed', async () => { const ingestSegment = makeIngestSegment( [ ['GRAFIK=FULL'], @@ -301,7 +301,7 @@ describe('AFVD Blueprint', () => { `\r\nKam 1\r\n

Some script

\r\n

\r\n

\r\n

\r\n` ) const context = makeMockContext(false) - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(2) @@ -331,7 +331,7 @@ describe('AFVD Blueprint', () => { ]) }) - it('Creates graphic for GRAFIK=FULL with Pilot with space', () => { + it('Creates graphic for GRAFIK=FULL with Pilot with space', async () => { const ingestSegment = makeIngestSegment( [ ['GRAFIK=FULL'], @@ -347,7 +347,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 = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(2) @@ -377,7 +377,7 @@ describe('AFVD Blueprint', () => { ) }) - it("Creates invalid part for GRAFIK=FULL with Pilot with 'notes'", () => { + it("Creates invalid part for GRAFIK=FULL with Pilot with 'notes'", async () => { const ingestSegment = makeIngestSegment( [ ['GRAFIK=FULL'], @@ -393,7 +393,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 = makeMockContext() - const result = getSegment(context, ingestSegment) + 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) expect(result.parts).toHaveLength(2) @@ -413,7 +413,7 @@ describe('AFVD Blueprint', () => { expect(fullPart.actions).toHaveLength(0) }) - it('Creates invalid part for GRAFIK=FULL with Pilot and bund in between', () => { + it('Creates invalid part for GRAFIK=FULL with Pilot and bund in between', async () => { const ingestSegment = makeIngestSegment( [ ['GRAFIK=FULL'], @@ -429,7 +429,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 = makeMockContext() - const result = getSegment(context, ingestSegment) + 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) expect(result.parts).toHaveLength(2) @@ -449,7 +449,7 @@ describe('AFVD Blueprint', () => { expect(fullPart.actions).toHaveLength(0) }) - it('Creates invalid part and show warning when GRAFIK=FULL and Pilot in different parts', () => { + it('Creates invalid part and show warning when GRAFIK=FULL and Pilot in different parts', async () => { const ingestSegment = makeIngestSegment( [ ['GRAFIK=FULL'], @@ -464,7 +464,7 @@ describe('AFVD Blueprint', () => { `\r\nKam 1\r\n

Some script

\r\n

\r\nKam 2\r\n

\r\n` ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + 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) expect(result.parts).toHaveLength(3) @@ -491,7 +491,7 @@ describe('AFVD Blueprint', () => { expect(kamPart2.actions).toHaveLength(0) }) - it('Creates overlay graphic for MOSART=L', () => { + it('Creates overlay graphic for MOSART=L', async () => { const ingestSegment = makeIngestSegment( [ [ @@ -506,7 +506,7 @@ describe('AFVD Blueprint', () => { `\r\nKam 1\r\n

Some script

\r\n

\r\n` ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(1) @@ -524,7 +524,7 @@ describe('AFVD Blueprint', () => { expect(kamPart.actions).toHaveLength(0) }) - it('Creates wall graphic for MOSART=W', () => { + it('Creates wall graphic for MOSART=W', async () => { const ingestSegment = makeIngestSegment( [ [ @@ -539,7 +539,7 @@ describe('AFVD Blueprint', () => { `\r\nKam 1\r\n

Some script

\r\n

\r\n` ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(1) @@ -557,7 +557,7 @@ describe('AFVD Blueprint', () => { expect(kamPart.actions).toHaveLength(0) }) - it('Creates full graphic for MOSART=F', () => { + it('Creates full graphic for MOSART=F', async () => { const ingestSegment = makeIngestSegment( [ [ @@ -572,7 +572,7 @@ describe('AFVD Blueprint', () => { `\r\nKam 1\r\n

Some script

\r\n

\r\n` ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(2) @@ -601,7 +601,7 @@ describe('AFVD Blueprint', () => { ]) }) - it('Loads graphic on wall, and loop on wall in next part', () => { + it('Loads graphic on wall, and loop on wall in next part', async () => { const ingestSegment = makeIngestSegment( [ ['SS=SC-STILLS', ';0.00.01'], @@ -617,7 +617,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 = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(2) @@ -641,7 +641,7 @@ describe('AFVD Blueprint', () => { ]) }) - it('Shows warning for missing wall graphic', () => { + it('Shows warning for missing wall graphic', async () => { const ingestSegment = makeIngestSegment( [ ['SS=SC-STILLS', ';0.00.01'], @@ -650,7 +650,7 @@ describe('AFVD Blueprint', () => { `\r\n

Kam 1

\r\n

\r\n

Some script

\r\n

Kam 2

\r\n

\r\n` ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after SS cue']) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(2) @@ -667,7 +667,7 @@ describe('AFVD Blueprint', () => { expect(kamPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmCam, SharedSourceLayers.PgmScript]) }) - it('Shows warning for missing wall graphic with MOSART=L', () => { + it('Shows warning for missing wall graphic with MOSART=L', async () => { const ingestSegment = makeIngestSegment( [ ['SS=SC-STILLS', ';0.00.01'], @@ -683,7 +683,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 = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after SS cue']) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(2) @@ -707,7 +707,7 @@ describe('AFVD Blueprint', () => { ]) }) - it('Shows warning for graphic in wrong place', () => { + it('Shows warning for graphic in wrong place', async () => { const ingestSegment = makeIngestSegment( [ ['SS=SC-STILLS', ';0.00.01'], @@ -723,7 +723,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 = makeMockContext() - const result = getSegment(context, ingestSegment) + 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) expect(result.parts).toHaveLength(2) @@ -743,7 +743,7 @@ describe('AFVD Blueprint', () => { ]) }) - it('Changes design and background loops', () => { + it('Changes design and background loops', async () => { const ingestSegment = makeIngestSegment( [ ['KG=DESIGN_FODBOLD_20', ';0.00.01'], @@ -753,7 +753,7 @@ describe('AFVD Blueprint', () => { `\r\n

KAM 1

\r\n

\r\n

\r\n

\r\n

Some script

\r\n` ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(1) @@ -771,10 +771,10 @@ describe('AFVD Blueprint', () => { ]) }) - it('Creates Live1', () => { + it('Creates Live1', async () => { const ingestSegment = makeIngestSegment([['EKSTERN=LIVE1']], `\r\n

\r\n

`) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(1) @@ -786,10 +786,10 @@ describe('AFVD Blueprint', () => { expect(livePart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) }) - it('Creates Live 1', () => { + it('Creates Live 1', async () => { const ingestSegment = makeIngestSegment([['EKSTERN=LIVE 1']], `\r\n

\r\n

`) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(1) @@ -801,10 +801,10 @@ describe('AFVD Blueprint', () => { expect(livePart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) }) - it('Creates Feed1', () => { + it('Creates Feed1', async () => { const ingestSegment = makeIngestSegment([['EKSTERN=FEED1']], `\r\n

\r\n

`) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(1) @@ -816,10 +816,10 @@ describe('AFVD Blueprint', () => { expect(feedPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) }) - it('Creates Feed 1', () => { + it('Creates Feed 1', async () => { const ingestSegment = makeIngestSegment([['EKSTERN=FEED 1']], `\r\n

\r\n

`) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(1) @@ -831,23 +831,23 @@ describe('AFVD Blueprint', () => { expect(feedPart1.pieces.map(p => p.sourceLayerId)).toEqual([SharedSourceLayers.PgmLive]) }) - it('Creates invalid part for EKSTERN=LIVE', () => { + it('Creates invalid part for EKSTERN=LIVE', async () => { const ingestSegment = makeIngestSegment( [['EKSTERN=LIVE'], ['#kg direkte ODDER', ';0.00']], `\r\n

***LIVE***

\r\n

\r\n

\r\n` ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No source entered for EKSTERN']) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(1) expect(result.parts[0].part.invalid).toBe(true) }) - it('Creates effekt for KAM 1 EFFEKT 1', () => { + it('Creates effekt for KAM 1 EFFEKT 1', async () => { const ingestSegment = makeIngestSegment([], '\r\n

KAM 1 EFFEKT 1

\r\n') const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expectAllPartsToBeValid(result) expect(result.segment.isHidden).toBe(false) @@ -860,10 +860,10 @@ describe('AFVD Blueprint', () => { expect(kamPart1.pieces[0].name).toBe('EFFEKT 1') }) - it('Creates mix for KAM 1 MIX 5', () => { + it('Creates mix for KAM 1 MIX 5', async () => { const ingestSegment = makeIngestSegment([], '\r\n

KAM 1 MIX 5

\r\n') const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expectAllPartsToBeValid(result) expect(result.segment.isHidden).toBe(false) @@ -876,13 +876,13 @@ describe('AFVD Blueprint', () => { expect(kamPart1.pieces[0].name).toBe('MIX 5') }) - it('Creates mix for EKSTERN=LIVE 1 EFFEKT 1', () => { + it('Creates mix for EKSTERN=LIVE 1 EFFEKT 1', async () => { const ingestSegment = makeIngestSegment( [['EKSTERN=LIVE 1 EFFEKT 1']], '\r\n

***LIVE***

\r\n

\r\n' ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expectAllPartsToBeValid(result) expect(result.segment.isHidden).toBe(false) @@ -898,13 +898,13 @@ describe('AFVD Blueprint', () => { expect(livePart1.pieces[0].name).toBe('EFFEKT 1') }) - it('Creates mix for EKSTERN=LIVE 1 MIX 10', () => { + it('Creates mix for EKSTERN=LIVE 1 MIX 10', async () => { const ingestSegment = makeIngestSegment( [['EKSTERN=LIVE 1 MIX 10']], '\r\n

***LIVE***

\r\n

\r\n' ) const context = makeMockContext() - const result = getSegment(context, ingestSegment) + const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expectAllPartsToBeValid(result) expect(result.segment.isHidden).toBe(false) 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 22a396d84..92c4abbdb 100644 --- a/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/rundown_story_exception.spec.ts @@ -35,14 +35,14 @@ describe('Generate rundowns without error', () => { }) for (const segment of roData.segments) { - test(`Rundown segment: ${segment.name} - ${roSpec.ro} - ${roData.externalId}`, () => { + test(`Rundown segment: ${segment.name} - ${roSpec.ro} - ${roData.externalId}`, async () => { const mockContext = new SegmentUserContext('test', mappingsDefaults, parseStudioConfig, parseShowStyleConfig) mockContext.studioConfig = roSpec.studioConfig as any mockContext.showStyleConfig = roSpec.showStyleConfig as any const iNewsStory: INewsStory | undefined = segment.payload?.iNewsStory - const res = Blueprints.getSegment(mockContext, segment) + const res = await Blueprints.getSegment(mockContext, segment) if (iNewsStory && iNewsStory.fields.pageNumber && iNewsStory.fields.pageNumber.trim()) { expect(res.segment.identifier).toEqual(iNewsStory.fields.pageNumber.trim()) } diff --git a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts index 7678b370f..a8097cee3 100644 --- a/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/transitions.spec.ts @@ -130,13 +130,13 @@ function testNotes(context: SegmentUserContext) { } describe('Primary Cue Transitions Without Config', () => { - it('Cuts by default for KAM', () => { + it('Cuts by default for KAM', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

KAM 1

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -146,13 +146,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.CUT) }) - it('Adds effekt to KAM', () => { + it('Adds effekt to KAM', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

KAM 1 EFFEKT 2

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -164,13 +164,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.CUT) }) - it('Adds mix to KAM', () => { + it('Adds mix to KAM', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

KAM 1 Mix 11

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -188,13 +188,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transitionSettings?.mix?.rate).toBe(11) }) - it('Cuts by default for EVS1', () => { + it('Cuts by default for EVS1', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

EVS 1

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -204,13 +204,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.CUT) }) - it('Adds effekt to EVS1', () => { + it('Adds effekt to EVS1', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

EVS 1 EFFEKT 1

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -221,13 +221,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.CUT) }) - it('Adds mix to EVS1', () => { + it('Adds mix to EVS1', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

EVS 1 Mix 15

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -245,13 +245,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transitionSettings?.mix?.rate).toBe(15) }) - it('Cuts by default for EVS1VO', () => { + it('Cuts by default for EVS1VO', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

EVS1VO

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -261,13 +261,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.CUT) }) - it('Adds effekt to EVS1VO', () => { + it('Adds effekt to EVS1VO', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

EVS 1VO EFFEKT 1

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -278,13 +278,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.CUT) }) - it('Adds mix to EVS1VO', () => { + it('Adds mix to EVS1VO', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

EVS 1 VO Mix 25

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -302,13 +302,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transitionSettings?.mix?.rate).toBe(25) }) - it('Cuts by default for SERVER', () => { + it('Cuts by default for SERVER', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

SERVER

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -318,13 +318,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.CUT) }) - it('Adds effekt to SERVER', () => { + it('Adds effekt to SERVER', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

SERVER EFFEKT 2

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -335,13 +335,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.CUT) }) - it('Adds mix to SERVER', () => { + it('Adds mix to SERVER', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

SERVER Mix 20

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -359,13 +359,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transitionSettings?.mix?.rate).toBe(20) }) - it('Cuts by default for VO', () => { + it('Cuts by default for VO', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

VO

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -375,13 +375,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.CUT) }) - it('Adds effekt to VO', () => { + it('Adds effekt to VO', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

VO EFFEKT 1

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) @@ -392,13 +392,13 @@ describe('Primary Cue Transitions Without Config', () => { expect(atemCutObj.content.me.transition).toBe(TSR.AtemTransitionStyle.CUT) }) - it('Adds mix to VO', () => { + it('Adds mix to VO', async () => { const ingestSegment = _.clone(templateSegment) ingestSegment.payload.iNewsStory.body = '\r\n

VO Mix 20

' const context = makeMockContextWithoutTransitionsConfig() - const segment = getSegment(context, ingestSegment) + const segment = await getSegment(context, ingestSegment) testNotes(context) diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index a96b15549..56bdb2e56 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -49,7 +49,7 @@ function makeMockContext() { } describe('Graphics', () => { - it('Throws warning for unpaired target and creates invalid part', () => { + it('Throws warning for unpaired target and creates invalid part', async () => { const context = makeMockContext() const config = getConfig(context) @@ -74,7 +74,7 @@ describe('Graphics', () => { storyName: '' }) - const result = CreatePartGrafik(context, config, partDefintion, 0) + const result = await CreatePartGrafik(context, config, partDefintion, 0) expect(context.getNotes().map(msg => msg.message)).toEqual([`No graphic found after GRAFIK cue`]) expect(result.pieces).toHaveLength(0) @@ -115,7 +115,7 @@ describe('Graphics', () => { expect(context.getNotes().map(msg => msg.message)).toEqual([`Graphic found without target engine`]) }) - it('Creates FULL graphic correctly', () => { + it('Creates FULL graphic correctly', async () => { const context = makeMockContext() const config = getConfig(context) @@ -146,7 +146,7 @@ describe('Graphics', () => { storyName: '' }) - const result = CreatePartGrafik(context, config, partDefinition, 0) + const result = await CreatePartGrafik(context, config, partDefinition, 0) expect(result.pieces).toHaveLength(2) const piece = result.pieces[0] expect(piece.sourceLayerId).toBe(SourceLayer.PgmPilot) @@ -174,7 +174,7 @@ describe('Graphics', () => { expect(vizObj.classes).toEqual(['full']) }) - it('Creates OVL pilot graphic correctly', () => { + it('Creates OVL pilot graphic correctly', async () => { const context = makeMockContext() const config = getConfig(context) @@ -211,7 +211,7 @@ describe('Graphics', () => { storyName: '' }) - const result = CreatePartGrafik(context, config, partDefinition, 0) + const result = await CreatePartGrafik(context, config, partDefinition, 0) expect(result.pieces).toHaveLength(1) const piece = result.pieces[0] expect(piece.sourceLayerId).toBe(SourceLayer.PgmPilotOverlay) @@ -238,7 +238,7 @@ describe('Graphics', () => { }) }) - it('Creates WALL graphic correctly', () => { + it('Creates WALL graphic correctly', async () => { const context = makeMockContext() const config = getConfig(context) @@ -269,7 +269,7 @@ describe('Graphics', () => { storyName: '' }) - const result = CreatePartGrafik(context, config, partDefinition, 0) + const result = await CreatePartGrafik(context, config, partDefinition, 0) expect(result.pieces).toHaveLength(1) const piece = result.pieces[0] expect(piece.sourceLayerId).toBe(SourceLayer.WallGraphics) @@ -293,7 +293,7 @@ describe('Graphics', () => { expect(vizObj.content.outTransition).toEqual(undefined) }) - it('Creates TLF graphic correctly', () => { + it('Creates TLF graphic correctly', async () => { const context = makeMockContext() const config = getConfig(context) @@ -324,7 +324,7 @@ describe('Graphics', () => { storyName: '' }) - const result = CreatePartGrafik(context, config, partDefinition, 0) + const result = await CreatePartGrafik(context, config, partDefinition, 0) expect(result.pieces).toHaveLength(2) const piece = result.pieces[0] expect(piece.sourceLayerId).toBe(SourceLayer.PgmGraphicsTLF) @@ -352,7 +352,7 @@ describe('Graphics', () => { expect(vizObj.classes).toEqual(['full']) }) - it('Routes source to engine', () => { + it('Routes source to engine', async () => { const context = makeMockContext() const config = getConfig(context) @@ -389,7 +389,7 @@ describe('Graphics', () => { storyName: '' }) - const result = CreatePartGrafik(context, config, partDefinition, 0) + const result = await CreatePartGrafik(context, config, partDefinition, 0) expect(result.pieces).toHaveLength(3) const auxPiece = result.pieces.find(p => p.outputLayerId === SharedOutputLayers.AUX)! expect(auxPiece.enable).toEqual({ start: 0 }) @@ -404,7 +404,7 @@ describe('Graphics', () => { expect(auxObj?.content.aux.input).toBe(1) }) - it('Creates design element', () => { + it('Creates design element', async () => { const context = makeMockContext() const config = getConfig(context) @@ -429,7 +429,7 @@ describe('Graphics', () => { storyName: '' }) - const result = CreatePartUnknown(context, config, partDefinition, 0) + const result = await CreatePartUnknown(context, config, partDefinition, 0) expect(result.pieces).toHaveLength(1) const piece = result.pieces[0] expect(piece).toBeTruthy() @@ -439,7 +439,7 @@ describe('Graphics', () => { expect(piece.enable).toEqual({ start: 0 }) }) - it('Creates background loop', () => { + it('Creates background loop', async () => { const context = makeMockContext() const config = getConfig(context) @@ -465,7 +465,7 @@ describe('Graphics', () => { storyName: '' }) - const result = CreatePartUnknown(context, config, partDefinition, 0) + const result = await CreatePartUnknown(context, config, partDefinition, 0) expect(result.pieces).toHaveLength(1) const piece = result.pieces[0] expect(piece).toBeTruthy() @@ -483,7 +483,7 @@ describe('Graphics', () => { expect(tlObj?.content.loop).toBe(true) }) - it('Creates overlay internal graphic', () => { + it('Creates overlay internal graphic', async () => { const context = makeMockContext() const config = getConfig(context) @@ -517,7 +517,7 @@ describe('Graphics', () => { storyName: '' }) - const result = CreatePartUnknown(context, config, partDefinition, 0) + const result = await CreatePartUnknown(context, config, partDefinition, 0) expect(result.pieces).toHaveLength(1) const piece = result.pieces[0] expect(piece).toBeTruthy() From b98a2f1f1bd88b1e6cb9764780d840f16008f815 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 31 May 2022 13:35:43 +0200 Subject: [PATCH 118/184] fix: SOF-833 allow extra space in EVS X VO --- .../inewsConversion/converters/ParseBody.ts | 7 +- .../converters/__tests__/body-parser.spec.ts | 68 +++++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index 1091615a2..3861a4bc7 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -107,7 +107,8 @@ export type PartdefinitionTypes = | Pick | Pick -const ACCEPTED_RED_TEXT = /\b(KAM(?:\d+)?|CAM(?:\d+)?|KAMERA(?:\d+)?|CAMERA(?:\d+)?|SERVER|ATTACK|TEKNIK|GRAFIK|EVS ?\d+(?:VOV?)?|VOV?|VOSB)+\b/gi +const ACCEPTED_RED_TEXT = /\b(KAM(?:\d+)?|CAM(?:\d+)?|KAMERA(?:\d+)?|CAMERA(?:\d+)?|SERVER|ATTACK|TEKNIK|GRAFIK|EVS ?\d+ ?(?:VOV?)?|VOV?|VOSB)+\b/gi +const EVS_RED_TEXT = /EVS ?(\d+) ?(VOV?)?/i export function ParseBody( config: TV2BlueprintConfig, @@ -535,8 +536,8 @@ function extractTypeProperties(typeStr: string): PartdefinitionTypes { variant: {}, ...definition } - } else if (typeStr.match(/EVS ?\d+(?:VOV?)?/i)) { - const strippedToken = typeStr.match(/EVS ?(\d+)(VOV?)?/i) + } else if (typeStr.match(EVS_RED_TEXT)) { + const strippedToken = typeStr.match(EVS_RED_TEXT) return { type: PartType.EVS, variant: { 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 96091783c..b0117f171 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts @@ -1617,6 +1617,74 @@ describe('Body parser', () => { ]) }) + test('test 27c: accepts spaces in EVS VO red text', () => { + const body27 = + '\r\n

EVS 1 VO

\r\n

EVS 2VO

\r\n

EVS3VO

\r\n

EVS4 VO

\r\n' + const result = ParseBody(config, '00000000001', 'test-segment', body27, [], fields, 0) + expect(stripExternalId(result)).toEqual([ + literal({ + externalId: '', + type: PartType.EVS, + rawType: 'EVS 1 VO', + variant: { + evs: '1', + vo: 'VO' + }, + cues: [], + fields, + modified: 0, + script: '', + storyName: 'test-segment', + segmentExternalId: '00000000001' + }), + literal({ + externalId: '', + type: PartType.EVS, + rawType: 'EVS 2VO', + variant: { + evs: '2', + vo: 'VO' + }, + cues: [], + fields, + modified: 0, + script: '', + storyName: 'test-segment', + segmentExternalId: '00000000001' + }), + literal({ + externalId: '', + type: PartType.EVS, + rawType: 'EVS3VO', + variant: { + evs: '3', + vo: 'VO' + }, + cues: [], + fields, + modified: 0, + script: '', + storyName: 'test-segment', + segmentExternalId: '00000000001' + }), + literal({ + externalId: '', + type: PartType.EVS, + rawType: 'EVS4 VO', + variant: { + evs: '4', + vo: 'VO' + }, + cues: [], + fields, + modified: 0, + script: '', + storyName: 'test-segment', + segmentExternalId: '00000000001' + }) + ]) + }) + test('test 28', () => { const body28 = '\r\n

****SERVER****

\r\n

---

\r\n

\r\n

SLUTORD:... bare mega fedt

\r\n

\r\n

Big body of comment text. Big body of comment text. Big body of comment text. Big body of comment text. Big body of comment text. Big body of comment text. Big body of comment text. Big body of comment text.

\r\n

\r\n

****LIVE****

\r\n

\r\n

\r\n

Some Script here

\r\n

\r\n' From 3c42fccd895fdb6dafdb6b9600da6ee6a79f6c59 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 1 Jun 2022 10:01:42 +0200 Subject: [PATCH 119/184] fix: SOF-767 minor issues and add tests --- .../helpers/__tests__/serverResume.spec.ts | 201 ++++++++++++++++++ src/tv2-common/helpers/serverResume.ts | 33 +-- src/tv2-common/onTimelineGenerate.ts | 4 +- 3 files changed, 221 insertions(+), 17 deletions(-) create mode 100644 src/tv2-common/helpers/__tests__/serverResume.spec.ts diff --git a/src/tv2-common/helpers/__tests__/serverResume.spec.ts b/src/tv2-common/helpers/__tests__/serverResume.spec.ts new file mode 100644 index 000000000..2a0b27ce2 --- /dev/null +++ b/src/tv2-common/helpers/__tests__/serverResume.spec.ts @@ -0,0 +1,201 @@ +import { + IBlueprintPartInstance, + IBlueprintResolvedPieceInstance, + PieceLifespan, + SplitsContent, + VTContent, + WithTimeline +} from '@tv2media/blueprints-integration' +import { DVEPieceMetaData, literal } from 'tv2-common' +import { SharedSourceLayers } from 'tv2-constants' +import { getServerPositionForPartInstance } from '../serverResume' + +function getMockPartInstance(partInstance: Partial): IBlueprintPartInstance { + return { + _id: '', + segmentId: '', + part: { + _id: '', + segmentId: '', + externalId: '', + title: '' + }, + rehearsal: false, + ...partInstance + } +} + +describe('Server Resume', () => { + it('Returns server position from server part with resolved duration', () => { + const position = getServerPositionForPartInstance(getMockPartInstance({ _id: 'mock_1' }), [ + literal({ + _id: '', + partInstanceId: 'mock_1', + resolvedStart: 1000, + resolvedDuration: 10000, + dynamicallyInserted: 1, + piece: { + _id: '', + enable: { start: 'now' }, + externalId: '', + name: '', + lifespan: PieceLifespan.WithinPart, + sourceLayerId: SharedSourceLayers.PgmServer, + outputLayerId: '', + content: literal>({ + fileName: '123456', + path: 'somewhere/123456', + timelineObjects: [] + }) + } + }) + ]) + expect(position).toEqual({ fileName: '123456', lastEnd: 10000, isPlaying: false }) + }) + it('Returns server position from server part when setting "now"', () => { + const position = getServerPositionForPartInstance( + getMockPartInstance({ _id: 'mock_1', timings: { startedPlayback: 1000 } }), + [ + literal({ + _id: '', + partInstanceId: 'mock_1', + startedPlayback: 1000, + resolvedStart: 2000, + dynamicallyInserted: 1, + piece: { + _id: '', + enable: { start: 'now' }, + externalId: '', + name: '', + lifespan: PieceLifespan.WithinPart, + sourceLayerId: SharedSourceLayers.PgmServer, + outputLayerId: '', + content: literal>({ + fileName: '123456', + path: 'somewhere/123456', + timelineObjects: [] + }) + } + }) + ], + 11000 + ) + expect(position).toEqual({ fileName: '123456', lastEnd: 8000, endedWithPartInstance: 'mock_1', isPlaying: false }) + }) + it('Returns server position from DVE adlib with continuous server', () => { + const position = getServerPositionForPartInstance( + getMockPartInstance({ + _id: 'mock_1', + segmentId: 'segment_0', + previousPartEndState: { + partInstanceId: 'mock_0', + sisyfosPersistMetaData: { sisyfosLayers: [] }, + mediaPlayerSessions: {}, + segmentId: 'segment_0', + serverPosition: { fileName: '123456', lastEnd: 10000, endedWithPartInstance: 'mock_0', isPlaying: false } + }, + timings: { startedPlayback: 11000 } + }), + [ + literal({ + _id: '', + partInstanceId: 'mock_1', + resolvedStart: 1000, + dynamicallyInserted: 1, + piece: { + _id: '', + enable: { start: 'now' }, + externalId: '', + name: '', + lifespan: PieceLifespan.WithinPart, + sourceLayerId: SharedSourceLayers.PgmDVEAdLib, + outputLayerId: '', + content: literal>({ + boxSourceConfiguration: [], + timelineObjects: [] + }), + metaData: literal>({ + sources: { + INP1: 'SERVER', + INP2: 'LIVE 1' + }, + serverPlaybackTiming: [{}] + }) + } + }) + ], + 20000 + ) + expect(position).toEqual({ fileName: '123456', lastEnd: 18000, isPlaying: false, endedWithPartInstance: 'mock_1' }) + }) + it('Returns server position from DVE adlib with interrupted server', () => { + const position = getServerPositionForPartInstance( + getMockPartInstance({ + _id: 'mock_1', + segmentId: 'segment_0', + previousPartEndState: { + partInstanceId: 'mock_0', + sisyfosPersistMetaData: { sisyfosLayers: [] }, + mediaPlayerSessions: {}, + segmentId: 'segment_0', + serverPosition: { fileName: '123456', lastEnd: 10000, endedWithPartInstance: 'mock_0', isPlaying: false } + }, + timings: { startedPlayback: 11000 } + }), + [ + literal({ + _id: '', + partInstanceId: 'mock_1', + resolvedStart: 1000, + dynamicallyInserted: 1, + piece: { + _id: '', + enable: { start: 'now' }, + externalId: '', + name: '', + lifespan: PieceLifespan.WithinPart, + sourceLayerId: SharedSourceLayers.PgmDVEAdLib, + outputLayerId: '', + content: literal>({ + boxSourceConfiguration: [], + timelineObjects: [] + }), + metaData: literal>({ + sources: { + INP1: 'SERVER', + INP2: 'LIVE 1' + }, + serverPlaybackTiming: [{ end: 13000 }, { start: 14000, end: 15000 }, { start: 16000 }] + }) + } + }) + ], + 20000 + ) + expect(position).toEqual({ fileName: '123456', lastEnd: 16000, isPlaying: false, endedWithPartInstance: 'mock_1' }) + }) + it('Includes transition in server position', () => { + const position = getServerPositionForPartInstance( + getMockPartInstance({ + _id: 'mock_1', + segmentId: 'segment_0', + previousPartEndState: { + partInstanceId: 'mock_0', + sisyfosPersistMetaData: { sisyfosLayers: [] }, + mediaPlayerSessions: {}, + segmentId: 'segment_0', + serverPosition: { fileName: '123456', lastEnd: 10000, endedWithPartInstance: 'mock_0', isPlaying: false } + }, + part: { + _id: '', + segmentId: '', + externalId: '', + title: '', + inTransition: { previousPartKeepaliveDuration: 2000, blockTakeDuration: 4000, partContentDelayDuration: 0 } + } + }), + [] + ) + expect(position).toEqual({ fileName: '123456', lastEnd: 12000, isPlaying: false, endedWithPartInstance: 'mock_0' }) + }) +}) diff --git a/src/tv2-common/helpers/serverResume.ts b/src/tv2-common/helpers/serverResume.ts index 5c8804372..150abf1e9 100644 --- a/src/tv2-common/helpers/serverResume.ts +++ b/src/tv2-common/helpers/serverResume.ts @@ -3,7 +3,6 @@ import { IBlueprintActionTriggerMode, IBlueprintPartInstance, IBlueprintResolvedPieceInstance, - ICommonContext, VTContent } from '@tv2media/blueprints-integration' import { PartEndStateExt, t } from 'tv2-common' @@ -18,7 +17,7 @@ export interface ServerPosition { fileName: string lastEnd: number isPlaying: boolean - fromPartInstanceId: string + endedWithPartInstance?: string } export enum ServerSelectMode { @@ -62,19 +61,13 @@ export async function getServerPosition( ? context.getCurrentTime() + replacingCurrentPieceWithOffset : undefined - return getServerPositionForPartInstance( - context, - partInstance, - await context.getResolvedPieceInstances('current'), - pieceEnd - ) + return getServerPositionForPartInstance(partInstance, await context.getResolvedPieceInstances('current'), pieceEnd) } /** * Calculate the offsets for clips based on the pieceinstances that have already been played. */ export function getServerPositionForPartInstance( - _context: ICommonContext, partInstance: IBlueprintPartInstance, pieceInstances: IBlueprintResolvedPieceInstance[], setCurrentPieceToNow0?: number @@ -103,21 +96,31 @@ export function getServerPositionForPartInstance( const pieceClipEnd = pieceSeek + (pieceDuration ?? 0) const isPlaying = (previousServerPosition?.fileName === content.fileName && previousServerPosition?.isPlaying) || !pieceDuration + const serverEndedWithPartInstance = !pieceInstance.resolvedDuration && setCurrentPieceToNow !== undefined currentServerPosition = { fileName: content.fileName, lastEnd: pieceClipEnd, isPlaying, - fromPartInstanceId: partInstance._id + endedWithPartInstance: serverEndedWithPartInstance ? partInstance._id : undefined } } else if (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmDVEAdLib) { const serverPlaybackTiming = (pieceInstance.piece.metaData as DVEPieceMetaData | undefined)?.serverPlaybackTiming if (serverPlaybackTiming) { for (const timing of serverPlaybackTiming) { - const start = timing.start ?? pieceInstance.resolvedStart - const end = timing.end ?? (pieceDuration ? pieceInstance.resolvedStart + pieceDuration : undefined) - if (currentServerPosition && end) { + const start = + timing.start ?? + (partInstance.timings?.startedPlayback && + partInstance.timings?.startedPlayback + pieceInstance.resolvedStart) + const end = + timing.end ?? + (pieceDuration && partInstance.timings?.startedPlayback + ? partInstance.timings?.startedPlayback + pieceInstance.resolvedStart + pieceDuration + : undefined) + const serverEndedWithPartInstance = + !pieceInstance.resolvedDuration && setCurrentPieceToNow !== undefined && !timing.end + if (currentServerPosition && end && start) { currentServerPosition.lastEnd += end - start - currentServerPosition.fromPartInstanceId = partInstance._id + currentServerPosition.endedWithPartInstance = serverEndedWithPartInstance ? partInstance._id : undefined } } } @@ -129,7 +132,7 @@ export function getServerPositionForPartInstance( currentServerPosition && !currentPiecesWithServer.length && inTransitionDuration && - currentServerPosition?.fromPartInstanceId === previousPartEndState?.partInstanceId + currentServerPosition?.endedWithPartInstance === previousPartEndState?.partInstanceId ) { currentServerPosition.lastEnd += inTransitionDuration } diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index c16012854..eecdef434 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -199,7 +199,7 @@ function isAnyPieceInjectedIntoPart(resolvedPieces: IBlueprintResolvedPieceInsta } export function getEndStateForPart( - context: IRundownContext, + _context: IRundownContext, _previousPersistentState: TimelinePersistentState | undefined, partInstance: IBlueprintPartInstance, resolvedPieces: IBlueprintResolvedPieceInstance[], @@ -248,7 +248,7 @@ export function getEndStateForPart( } } - endState.serverPosition = getServerPositionForPartInstance(context, partInstance, resolvedPieces, time) + endState.serverPosition = getServerPositionForPartInstance(partInstance, resolvedPieces, time) return endState } From 525661a2d579e1c0963a05be7997d303e3185c68 Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 2 Jun 2022 12:41:46 +0200 Subject: [PATCH 120/184] fix: SOF-934 show LYD adlibs in the shelf --- src/tv2-common/cues/lyd.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tv2-common/cues/lyd.ts b/src/tv2-common/cues/lyd.ts index dcce95d09..ce24d1790 100644 --- a/src/tv2-common/cues/lyd.ts +++ b/src/tv2-common/cues/lyd.ts @@ -12,6 +12,7 @@ import { import { CreateTimingEnable, CueDefinitionLYD, literal, PartDefinition, TimeFromFrames } from 'tv2-common' import { AbstractLLayer, + AdlibTags, ControlClasses, SharedCasparLLayer, SharedOutputLayers, @@ -64,7 +65,8 @@ 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(config, file, lydType, fadeIn, fadeOut), + tags: [AdlibTags.ADLIB_FLOW_PRODUCER] }) ) } else { From 6c182359c93c3cd8a149d60dc0ae0a43c7b87803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Thu, 2 Jun 2022 13:06:40 +0200 Subject: [PATCH 121/184] SOF-937 Now start fading audioBed level immediately --- src/tv2-common/cues/lyd.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/tv2-common/cues/lyd.ts b/src/tv2-common/cues/lyd.ts index dcce95d09..0647df2c2 100644 --- a/src/tv2-common/cues/lyd.ts +++ b/src/tv2-common/cues/lyd.ts @@ -44,8 +44,9 @@ export function EvaluateLYD( } const file = fade ? 'empty' : conf ? conf.FileName.toString() : parsedCue.variant - const fadeIn = fade ? Number(fade[1]) : conf ? Number(conf.FadeIn) : undefined - const fadeOut = conf ? Number(conf.FadeOut) : undefined + const fadeTimeInFrames = fade ? Number(fade[1]) : undefined + const fadeIn = fadeTimeInFrames ?? (conf ? Number(conf.FadeIn) : undefined) + const fadeOut = fadeTimeInFrames ?? (conf ? Number(conf.FadeOut) : undefined) const lydType = stop ? 'stop' : fade ? 'fade' : 'bed' const lifespan = stop || fade || parsedCue.end ? PieceLifespan.WithinPart : PieceLifespan.OutOnRundownChange @@ -64,7 +65,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(config, file, lydType, fadeIn, fadeOut, fadeTimeInFrames) }) ) } else { @@ -83,24 +84,21 @@ export function EvaluateLYD( } : CreateTimingEnable(parsedCue)), outputLayerId: SharedOutputLayers.MUSIK, - sourceLayerId: GetLYDSourceLayer(file), + sourceLayerId: SharedSourceLayers.PgmAudioBed, lifespan, - content: LydContent(config, file, lydType, fadeIn, fadeOut) + content: LydContent(config, file, lydType, fadeIn, fadeOut, fadeTimeInFrames) }) ) } } -export function GetLYDSourceLayer(_name: string): SharedSourceLayers { - return SharedSourceLayers.PgmAudioBed -} - function LydContent( config: TV2BlueprintConfig, file: string, lydType: 'bed' | 'stop' | 'fade', fadeIn?: number, - fadeOut?: number + fadeOut?: number, + fadeTimeInFrames?: number ): WithTimeline { if (lydType === 'stop') { return literal>({ @@ -170,7 +168,8 @@ function LydContent( content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: 1 + isPgm: fadeIn ? 0 : 1, + fadeTime: fadeTimeInFrames ? TimeFromFrames(fadeTimeInFrames) : undefined } }) ]) From 2b627f927734229b0e278fd8d6b72973d23152b5 Mon Sep 17 00:00:00 2001 From: ianshade Date: Fri, 3 Jun 2022 09:36:47 +0200 Subject: [PATCH 122/184] test: SOF-934 add test case for LYD adlib --- .../helpers/pieces/__tests__/lyd.spec.ts | 122 ++++++++++++------ 1 file changed, 80 insertions(+), 42 deletions(-) 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 a40ab4f8d..5e1a80c58 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts @@ -5,7 +5,7 @@ import { PieceLifespan } from '@tv2media/blueprints-integration' import { CueDefinitionLYD, EvaluateLYD, literal, ParseCue, PartDefinitionKam } from 'tv2-common' -import { NoteType, PartType } from 'tv2-constants' +import { AdlibTags, NoteType, PartType, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' import { DEFAULT_GRAPHICS_SETUP, @@ -29,6 +29,20 @@ function makeMockContext() { } const config = getConfig(makeMockContext()) +const mockPart = literal({ + type: PartType.Kam, + variant: { + name: '1' + }, + externalId: '0001', + rawType: 'Kam 1', + cues: [], + script: '', + storyName: '', + fields: {}, + modified: 0, + segmentExternalId: '' +}) describe('lyd', () => { test('Lyd with no out time', () => { @@ -36,20 +50,6 @@ describe('lyd', () => { const pieces: IBlueprintPiece[] = [] const adlibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] - const mockPart = literal({ - type: PartType.Kam, - variant: { - name: '1' - }, - externalId: '0001', - rawType: 'Kam 1', - cues: [], - script: '', - storyName: '', - fields: {}, - modified: 0, - segmentExternalId: '' - }) EvaluateLYD( makeMockContext(), @@ -82,20 +82,6 @@ describe('lyd', () => { const pieces: IBlueprintPiece[] = [] const adlibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] - const mockPart = literal({ - type: PartType.Kam, - variant: { - name: '1' - }, - externalId: '0001', - rawType: 'Kam 1', - cues: [], - script: '', - storyName: '', - fields: {}, - modified: 0, - segmentExternalId: '' - }) EvaluateLYD( makeMockContext(), @@ -129,20 +115,36 @@ describe('lyd', () => { const pieces: IBlueprintPiece[] = [] const adlibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] - const mockPart = literal({ - type: PartType.Kam, - variant: { - name: '1' + + const context = makeMockContext() + + EvaluateLYD( + context, + { + showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, + studio: (defaultStudioConfig as unknown) as StudioConfig, + sources: [], + mediaPlayers: [], + dsk: defaultDSKConfig, + selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP }, - externalId: '0001', - rawType: 'Kam 1', - cues: [], - script: '', - storyName: '', - fields: {}, - modified: 0, - segmentExternalId: '' - }) + pieces, + adlibPieces, + actions, + parsedCue, + mockPart + ) + + expect(pieces.length).toEqual(0) + expect(context.getNotes().length).toEqual(1) + expect(context.getNotes()[0].type).toEqual(NoteType.NOTIFY_USER_WARNING) + }) + + test('Lyd not configured', () => { + const parsedCue = ParseCue(['LYD=SN_MISSING', ';0.00-0.10'], config) as CueDefinitionLYD + const pieces: IBlueprintPiece[] = [] + const adlibPieces: IBlueprintAdLibPiece[] = [] + const actions: IBlueprintActionManifest[] = [] const context = makeMockContext() @@ -167,4 +169,40 @@ describe('lyd', () => { expect(context.getNotes().length).toEqual(1) expect(context.getNotes()[0].type).toEqual(NoteType.NOTIFY_USER_WARNING) }) + + test('Lyd adlib', () => { + const parsedCue = ParseCue(['LYD=SN_INTRO', ';x.xx'], config) as CueDefinitionLYD + const pieces: IBlueprintPiece[] = [] + const adlibPieces: IBlueprintAdLibPiece[] = [] + const actions: IBlueprintActionManifest[] = [] + + EvaluateLYD( + makeMockContext(), + { + showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, + studio: (defaultStudioConfig as unknown) as StudioConfig, + sources: [], + mediaPlayers: [], + dsk: defaultDSKConfig, + selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP + }, + pieces, + adlibPieces, + actions, + parsedCue, + mockPart, + true + ) + + expect(adlibPieces.length).toEqual(1) + expect(adlibPieces[0]).toMatchObject( + literal>({ + name: 'SN_INTRO', + outputLayerId: SharedOutputLayers.MUSIK, + sourceLayerId: SharedSourceLayers.PgmAudioBed, + lifespan: PieceLifespan.OutOnRundownChange, + tags: [AdlibTags.ADLIB_FLOW_PRODUCER] + }) + ) + }) }) From e636b6fb5312c5a7228452df5dbd7233c9b2a87d Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 8 Jun 2022 09:13:18 +0200 Subject: [PATCH 123/184] refactor: SOF-767 code style --- src/tv2-common/actions/executeAction.ts | 8 +- src/tv2-common/helpers/serverResume.ts | 137 +++++++++++++++++------- 2 files changed, 101 insertions(+), 44 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index b330ebb0d..ea1b70d69 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -652,7 +652,7 @@ async function cutServerToBox< if (!containsServer) { if (containedServerBefore) { - stopServerMetadata(context, meta) + stopServerMetaData(context, meta) } return newDvePiece } @@ -713,21 +713,21 @@ async function cutServerToBox< ;(newDvePiece.metaData as any).mediaPlayerSessions = [existingCasparObj.metaData.mediaPlayerSession] if (!containedServerBefore) { - startServerMetadata(context, meta, modifiesCurrent) + startServerMetaData(context, meta, modifiesCurrent) } } return newDvePiece } -function stopServerMetadata(context: ITV2ActionExecutionContext, metaData: DVEPieceMetaData) { +function stopServerMetaData(context: ITV2ActionExecutionContext, metaData: DVEPieceMetaData) { const length = metaData.serverPlaybackTiming?.length if (metaData.serverPlaybackTiming && length) { metaData.serverPlaybackTiming[length - 1].end = context.getCurrentTime() } } -function startServerMetadata( +function startServerMetaData( context: ITV2ActionExecutionContext, metaData: DVEPieceMetaData, modifiesCurrent?: boolean diff --git a/src/tv2-common/helpers/serverResume.ts b/src/tv2-common/helpers/serverResume.ts index 150abf1e9..412712540 100644 --- a/src/tv2-common/helpers/serverResume.ts +++ b/src/tv2-common/helpers/serverResume.ts @@ -70,11 +70,11 @@ export async function getServerPosition( export function getServerPositionForPartInstance( partInstance: IBlueprintPartInstance, pieceInstances: IBlueprintResolvedPieceInstance[], - setCurrentPieceToNow0?: number + setCurrentPieceToNow?: number ): ServerPosition | undefined { - const setCurrentPieceToNow = - setCurrentPieceToNow0 !== undefined && partInstance.timings?.startedPlayback - ? setCurrentPieceToNow0 - partInstance.timings.startedPlayback + setCurrentPieceToNow = + setCurrentPieceToNow !== undefined && partInstance.timings?.startedPlayback + ? setCurrentPieceToNow - partInstance.timings.startedPlayback : undefined const previousPartEndState = partInstance.previousPartEndState as Partial | undefined @@ -92,41 +92,36 @@ export function getServerPositionForPartInstance( const content = pieceInstance.piece.content as VTContent | undefined if (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmServer && content) { - const pieceSeek = content.seek ?? 0 - const pieceClipEnd = pieceSeek + (pieceDuration ?? 0) - const isPlaying = - (previousServerPosition?.fileName === content.fileName && previousServerPosition?.isPlaying) || !pieceDuration - const serverEndedWithPartInstance = !pieceInstance.resolvedDuration && setCurrentPieceToNow !== undefined - currentServerPosition = { - fileName: content.fileName, - lastEnd: pieceClipEnd, - isPlaying, - endedWithPartInstance: serverEndedWithPartInstance ? partInstance._id : undefined - } + currentServerPosition = getCurrentPositionFromServerPiece( + content, + pieceDuration, + previousServerPosition, + pieceInstance, + setCurrentPieceToNow, + partInstance + ) } else if (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmDVEAdLib) { - const serverPlaybackTiming = (pieceInstance.piece.metaData as DVEPieceMetaData | undefined)?.serverPlaybackTiming - if (serverPlaybackTiming) { - for (const timing of serverPlaybackTiming) { - const start = - timing.start ?? - (partInstance.timings?.startedPlayback && - partInstance.timings?.startedPlayback + pieceInstance.resolvedStart) - const end = - timing.end ?? - (pieceDuration && partInstance.timings?.startedPlayback - ? partInstance.timings?.startedPlayback + pieceInstance.resolvedStart + pieceDuration - : undefined) - const serverEndedWithPartInstance = - !pieceInstance.resolvedDuration && setCurrentPieceToNow !== undefined && !timing.end - if (currentServerPosition && end && start) { - currentServerPosition.lastEnd += end - start - currentServerPosition.endedWithPartInstance = serverEndedWithPartInstance ? partInstance._id : undefined - } - } - } + updateServerPositionFromDVEPiece( + pieceInstance, + partInstance, + pieceDuration, + setCurrentPieceToNow, + currentServerPosition + ) } } + updateServerPositionFromTransition(partInstance, currentServerPosition, currentPiecesWithServer, previousPartEndState) + + return currentServerPosition +} + +function updateServerPositionFromTransition( + partInstance: IBlueprintPartInstance, + currentServerPosition: ServerPosition | undefined, + currentPiecesWithServer: Array>, + previousPartEndState: Partial | undefined +) { const inTransitionDuration = partInstance.part.inTransition?.previousPartKeepaliveDuration if ( currentServerPosition && @@ -136,8 +131,74 @@ export function getServerPositionForPartInstance( ) { currentServerPosition.lastEnd += inTransitionDuration } +} - return currentServerPosition +function updateServerPositionFromDVEPiece( + pieceInstance: IBlueprintResolvedPieceInstance, + partInstance: IBlueprintPartInstance, + pieceDuration: number | undefined, + setCurrentPieceToNow: number | undefined, + currentServerPosition: ServerPosition | undefined +) { + const serverPlaybackTiming = (pieceInstance.piece.metaData as DVEPieceMetaData | undefined)?.serverPlaybackTiming + if (serverPlaybackTiming) { + for (const timing of serverPlaybackTiming) { + const start = getStartTimeForServerInDVE(timing, partInstance, pieceInstance) + const end = getEndTimeForServerInDVE(timing, pieceDuration, partInstance, pieceInstance) + const serverEndedWithPartInstance = + !pieceInstance.resolvedDuration && setCurrentPieceToNow !== undefined && !timing.end + if (currentServerPosition && end && start) { + currentServerPosition.lastEnd += end - start + currentServerPosition.endedWithPartInstance = serverEndedWithPartInstance ? partInstance._id : undefined + } + } + } +} + +function getStartTimeForServerInDVE( + timing: { start?: number | undefined; end?: number | undefined }, + partInstance: IBlueprintPartInstance, + pieceInstance: IBlueprintResolvedPieceInstance +) { + return ( + timing.start ?? + (partInstance.timings?.startedPlayback && partInstance.timings?.startedPlayback + pieceInstance.resolvedStart) + ) +} + +function getEndTimeForServerInDVE( + timing: { start?: number | undefined; end?: number | undefined }, + pieceDuration: number | undefined, + partInstance: IBlueprintPartInstance, + pieceInstance: IBlueprintResolvedPieceInstance +) { + return ( + timing.end ?? + (pieceDuration && partInstance.timings?.startedPlayback + ? partInstance.timings?.startedPlayback + pieceInstance.resolvedStart + pieceDuration + : undefined) + ) +} + +function getCurrentPositionFromServerPiece( + content: VTContent, + pieceDuration: number | undefined, + previousServerPosition: ServerPosition | undefined, + pieceInstance: IBlueprintResolvedPieceInstance, + setCurrentPieceToNow: number | undefined, + partInstance: IBlueprintPartInstance +) { + const pieceSeek = content.seek ?? 0 + const pieceClipEnd = pieceSeek + (pieceDuration ?? 0) + const isPlaying = + (previousServerPosition?.fileName === content.fileName && previousServerPosition?.isPlaying) || !pieceDuration + const serverEndedWithPartInstance = !pieceInstance.resolvedDuration && setCurrentPieceToNow !== undefined + return { + fileName: content.fileName, + lastEnd: pieceClipEnd, + isPlaying, + endedWithPartInstance: serverEndedWithPartInstance ? partInstance._id : undefined + } } export function shouldPreservePosition(pieceInstance: IBlueprintResolvedPieceInstance): boolean { @@ -149,10 +210,6 @@ export function shouldPreservePosition(pieceInstance: IBlueprintResolvedPieceIns ) } -export function hasTransition(pieceInstance: IBlueprintResolvedPieceInstance): boolean { - return pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmJingle -} - export function getServerAdLibTriggerModes(): IBlueprintActionTriggerMode[] { return [ { From e3ea5f76cae6546dc41d06d1785c6efeed36015e Mon Sep 17 00:00:00 2001 From: ianshade Date: Fri, 3 Jun 2022 14:38:02 +0200 Subject: [PATCH 124/184] fix: SOF-936 don't clear PgmGraphicsTLF layer Internal graphics cannot appear on this layer. We might not need this layer at all, but it's TBD. --- src/tv2-common/helpers/graphics/internal/index.ts | 4 +--- src/tv2-common/hotkeys/hotkey-defaults.ts | 3 +-- .../helpers/pieces/__tests__/telefon.spec.ts | 2 +- src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/tv2-common/helpers/graphics/internal/index.ts b/src/tv2-common/helpers/graphics/internal/index.ts index b49967874..c2a626fd7 100644 --- a/src/tv2-common/helpers/graphics/internal/index.ts +++ b/src/tv2-common/helpers/graphics/internal/index.ts @@ -58,9 +58,7 @@ export function CreateInternalGraphic( const engine = parsedCue.target - const sourceLayerId = IsTargetingTLF(engine) - ? SharedSourceLayers.PgmGraphicsTLF - : GetSourceLayerForGraphic(config, mappedTemplate, isStickyIdent) + const sourceLayerId = GetSourceLayerForGraphic(config, mappedTemplate, isStickyIdent) const outputLayerId = IsTargetingWall(engine) ? SharedOutputLayers.SEC : SharedOutputLayers.OVERLAY diff --git a/src/tv2-common/hotkeys/hotkey-defaults.ts b/src/tv2-common/hotkeys/hotkey-defaults.ts index 8b09c19c9..bdef58820 100644 --- a/src/tv2-common/hotkeys/hotkey-defaults.ts +++ b/src/tv2-common/hotkeys/hotkey-defaults.ts @@ -42,8 +42,7 @@ export const defaultHotkeys: TV2Hotkeys = { SharedSourceLayers.PgmGraphicsHeadline, SharedSourceLayers.PgmGraphicsTema, SharedSourceLayers.PgmGraphicsOverlay, - SharedSourceLayers.PgmPilotOverlay, - SharedSourceLayers.PgmGraphicsTLF + SharedSourceLayers.PgmPilotOverlay ], key: 'KeyQ', name: 'overlay ALT UD' 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 7e07edbad..08a116da0 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -106,7 +106,7 @@ describe('telefon', () => { start: 0 }, outputLayerId: SharedOutputLayers.OVERLAY, - sourceLayerId: SourceLayer.PgmGraphicsTLF, + sourceLayerId: SourceLayer.PgmGraphicsLower, lifespan: PieceLifespan.WithinPart, content: literal>({ fileName: 'bund', diff --git a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts index da7465389..541c07954 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts @@ -30,8 +30,7 @@ export function EvaluateClearGrafiks( SourceLayer.PgmGraphicsLower, SourceLayer.PgmGraphicsHeadline, SourceLayer.PgmGraphicsTema, - SourceLayer.PgmGraphicsOverlay, - SourceLayer.PgmGraphicsTLF + SourceLayer.PgmGraphicsOverlay ].forEach(sourceLayerId => { pieces.push({ externalId: partId, From 748ea77dd82e81d246259f50ca3b3e57c8790b30 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 14 Jun 2022 11:11:54 +0200 Subject: [PATCH 125/184] chore: update blueprints-integration --- package.json | 2 +- yarn.lock | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 3f25f2679..15f4e7f32 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "webpack-cli": "^3.1.2" }, "dependencies": { - "@tv2media/blueprints-integration": "1.42.5", + "@tv2media/blueprints-integration": "1.42.6", "underscore": "^1.12.1" }, "resolutions": { diff --git a/yarn.lock b/yarn.lock index 85d618c85..a1e50dfac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -565,13 +565,13 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== -"@tv2media/blueprints-integration@1.42.5": - version "1.42.5" - resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-1.42.5.tgz#872e603d8107bab34dd26af4187d82b39ed74b98" - integrity sha512-8vIbTTHosvdex4Fqb3Eay7STss4fSvv3JuWLYe28dczzpwcLTyAwuNgElpwBrfaoRFkpLGIvO8hvAae/Uh7I5A== +"@tv2media/blueprints-integration@1.42.6": + version "1.42.6" + resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-1.42.6.tgz#723d6410112b0b16c4ba8e2087f8bf6a3aec76e8" + integrity sha512-fWJOaEa3Wtwoc4lZ/WwgLOknuu3F/0Tg9l9EbXw1MxKwajrPOmb4wMsz5FyQB6LpuTxuuJKIPXBcwvCEMz4eCg== dependencies: - moment "2.29.1" - timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@2.0.0" + moment "2.29.3" + timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@2.1.0" tslib "^2.3.1" type-fest "^2.11.1" @@ -4413,7 +4413,7 @@ modify-values@^1.0.0: resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== -moment@2.29.1, moment@^2.29.2: +moment@2.29.3, moment@^2.29.2: version "2.29.3" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.3.tgz#edd47411c322413999f7a5940d526de183c031f3" integrity sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw== @@ -5948,10 +5948,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.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-2.0.0.tgz#0af6ed0c1d69bd6c27b77c175f4fedf204ef8505" - integrity sha512-hfNrbMp9fPV5ItBM1MqDNLOxlzRJGEMb2HyY9Blr1+5ql7ap+eeb8XkH2asIJAljIyHjJ1MwKjjqLgfEYY6h0w== +"timeline-state-resolver-types@npm:@tv2media/timeline-state-resolver-types@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-2.1.0.tgz#0dc866dcd24c79cd89283de97dd6a7c454b6b846" + integrity sha512-Z8Z2UqHov18auFJJsyEWZzBnqMxfLQujd9Ihoos/0FJHouRTcR/TRhaqFfqjNe7T1YN5nee73wuLcyBkJferKQ== dependencies: tslib "^2.3.1" From d5bd4d1f24cd4d35c7a03daf378d9d6fd4f551ed Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 14 Jun 2022 11:19:28 +0200 Subject: [PATCH 126/184] fix: SOF-767 disable Resume for commentator server adlibs --- src/tv2-common/actions/executeAction.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index ea1b70d69..81cf61f13 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1715,7 +1715,14 @@ async function executeActionCommentatorSelectServer< session = sessions.session } - await executeActionSelectServerClip(context, settings, AdlibActionType.SELECT_SERVER_CLIP, data, undefined, session) + await executeActionSelectServerClip( + context, + settings, + AdlibActionType.SELECT_SERVER_CLIP, + data, + ServerSelectMode.RESET, + session + ) } async function executeActionCommentatorSelectDVE< From e8ce98cd7d128cc530d7e7eb37c54fbb256cf80a Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 14 Jun 2022 11:27:14 +0200 Subject: [PATCH 127/184] refactor: SOF-767 better types and parameter names --- src/tv2-common/actions/executeAction.ts | 16 ++++++++++------ src/tv2-common/helpers/serverResume.ts | 24 ++++++++++++------------ src/tv2-common/parts/server.ts | 4 ++-- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 81cf61f13..0a41d1a5f 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -72,7 +72,13 @@ import { } from 'tv2-constants' import _ = require('underscore') import { EnableServer } from '../content' -import { CreateFullDataStore, GetEnableForWall, getServerPosition, PilotGeneratorSettings } from '../helpers' +import { + CreateFullDataStore, + GetEnableForWall, + getServerPosition, + PilotGeneratorSettings, + ServerSelectMode +} from '../helpers' import { InternalGraphic } from '../helpers/graphics/InternalGraphic' import { GetJinglePartPropertiesFromTableValue } from '../jinglePartProperties' import { CreateEffektForPartBase, CreateEffektForPartInner, CreateMixForPartInner } from '../parts' @@ -210,7 +216,7 @@ export async function executeAction< settings, actionId, userData as ActionSelectServerClip, - triggerMode + triggerMode as ServerSelectMode | undefined ) break case AdlibActionType.SELECT_DVE: @@ -397,7 +403,7 @@ async function executeActionSelectServerClip< settings: ActionExecutionSettings, actionId: string, userData: ActionSelectServerClip, - triggerMode?: string, + triggerMode?: ServerSelectMode, sessionToContinue?: string ) { const file = userData.file @@ -699,9 +705,7 @@ async function cutServerToBox< return newDvePiece } - const ssrcObj = (newDvePiece.content.timelineObjects as Array)[ - ssrcObjIndex - ] + const ssrcObj = newDvePiece.content.timelineObjects[ssrcObjIndex] as TSR.TSRTimelineObj & TimelineBlueprintExt ssrcObj.metaData = { ...ssrcObj.metaData, diff --git a/src/tv2-common/helpers/serverResume.ts b/src/tv2-common/helpers/serverResume.ts index 412712540..7fae49cfc 100644 --- a/src/tv2-common/helpers/serverResume.ts +++ b/src/tv2-common/helpers/serverResume.ts @@ -29,7 +29,7 @@ export function getServerSeek( lastServerPosition: ServerPosition | undefined, fileName: string, mediaObjectDuration?: number, - triggerMode?: string + triggerMode?: ServerSelectMode ): number { if (triggerMode === ServerSelectMode.RESET) { return 0 @@ -70,11 +70,11 @@ export async function getServerPosition( export function getServerPositionForPartInstance( partInstance: IBlueprintPartInstance, pieceInstances: IBlueprintResolvedPieceInstance[], - setCurrentPieceToNow?: number + currentPieceEnd?: number ): ServerPosition | undefined { - setCurrentPieceToNow = - setCurrentPieceToNow !== undefined && partInstance.timings?.startedPlayback - ? setCurrentPieceToNow - partInstance.timings.startedPlayback + currentPieceEnd = + currentPieceEnd !== undefined && partInstance.timings?.startedPlayback + ? currentPieceEnd - partInstance.timings.startedPlayback : undefined const previousPartEndState = partInstance.previousPartEndState as Partial | undefined @@ -88,7 +88,7 @@ export function getServerPositionForPartInstance( for (const pieceInstance of currentPiecesWithServer) { const pieceDuration = pieceInstance.resolvedDuration || - (setCurrentPieceToNow !== undefined ? setCurrentPieceToNow - pieceInstance.resolvedStart : undefined) + (currentPieceEnd !== undefined ? currentPieceEnd - pieceInstance.resolvedStart : undefined) const content = pieceInstance.piece.content as VTContent | undefined if (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmServer && content) { @@ -97,7 +97,7 @@ export function getServerPositionForPartInstance( pieceDuration, previousServerPosition, pieceInstance, - setCurrentPieceToNow, + currentPieceEnd, partInstance ) } else if (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmDVEAdLib) { @@ -105,7 +105,7 @@ export function getServerPositionForPartInstance( pieceInstance, partInstance, pieceDuration, - setCurrentPieceToNow, + currentPieceEnd, currentServerPosition ) } @@ -137,7 +137,7 @@ function updateServerPositionFromDVEPiece( pieceInstance: IBlueprintResolvedPieceInstance, partInstance: IBlueprintPartInstance, pieceDuration: number | undefined, - setCurrentPieceToNow: number | undefined, + currentPieceEnd: number | undefined, currentServerPosition: ServerPosition | undefined ) { const serverPlaybackTiming = (pieceInstance.piece.metaData as DVEPieceMetaData | undefined)?.serverPlaybackTiming @@ -146,7 +146,7 @@ function updateServerPositionFromDVEPiece( const start = getStartTimeForServerInDVE(timing, partInstance, pieceInstance) const end = getEndTimeForServerInDVE(timing, pieceDuration, partInstance, pieceInstance) const serverEndedWithPartInstance = - !pieceInstance.resolvedDuration && setCurrentPieceToNow !== undefined && !timing.end + !pieceInstance.resolvedDuration && currentPieceEnd !== undefined && !timing.end if (currentServerPosition && end && start) { currentServerPosition.lastEnd += end - start currentServerPosition.endedWithPartInstance = serverEndedWithPartInstance ? partInstance._id : undefined @@ -185,14 +185,14 @@ function getCurrentPositionFromServerPiece( pieceDuration: number | undefined, previousServerPosition: ServerPosition | undefined, pieceInstance: IBlueprintResolvedPieceInstance, - setCurrentPieceToNow: number | undefined, + currentPieceEnd: number | undefined, partInstance: IBlueprintPartInstance ) { const pieceSeek = content.seek ?? 0 const pieceClipEnd = pieceSeek + (pieceDuration ?? 0) const isPlaying = (previousServerPosition?.fileName === content.fileName && previousServerPosition?.isPlaying) || !pieceDuration - const serverEndedWithPartInstance = !pieceInstance.resolvedDuration && setCurrentPieceToNow !== undefined + const serverEndedWithPartInstance = !pieceInstance.resolvedDuration && currentPieceEnd !== undefined return { fileName: content.fileName, lastEnd: pieceClipEnd, diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index 0adb03aaa..7ce92687f 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -20,7 +20,7 @@ import { AdlibActionType, PartType, SharedOutputLayers, TallyTags } from 'tv2-co import { ActionSelectServerClip } from '../actions' import { TV2BlueprintConfigBase, TV2StudioConfigBase } from '../blueprintConfig' import { GetVTContentProperties } from '../content' -import { getServerSeek, ServerPosition } from '../helpers' +import { getServerSeek, ServerPosition, ServerSelectMode } from '../helpers' import { PartDefinition } from '../inewsConversion' import { literal, SanitizeString } from '../util' import { CreatePartInvalid } from './invalid' @@ -38,7 +38,7 @@ export interface ServerPartProps { adLibPix: boolean session?: string lastServerPosition?: ServerPosition - actionTriggerMode?: string + actionTriggerMode?: ServerSelectMode seek?: number } From 2095cb6c1c49eb6b5953c696ee69a9d8f5903a0c Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 14 Jun 2022 14:52:53 +0200 Subject: [PATCH 128/184] fix: SOF-975 make offtube jingles respect LoadFirstFrame setting --- package.json | 2 +- src/tv2-common/content/jingle.ts | 53 ++++++++----------- .../cues/OfftubeJingle.ts | 2 +- src/tv2_offtube_studio/layers.ts | 3 +- src/tv2_offtube_studio/migrations/index.ts | 11 +++- .../migrations/mappings-defaults.ts | 6 +-- 6 files changed, 40 insertions(+), 37 deletions(-) diff --git a/package.json b/package.json index ea9dcdf0a..0dcbf7603 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tv2-sofie-blueprints-inews", - "version": "1.7.2", + "version": "1.7.3", "repository": "https://github.com/olzzon/tv2-sofie-blueprints-inews", "license": "MIT", "private": true, diff --git a/src/tv2-common/content/jingle.ts b/src/tv2-common/content/jingle.ts index 7944ca962..1215352a1 100644 --- a/src/tv2-common/content/jingle.ts +++ b/src/tv2-common/content/jingle.ts @@ -8,7 +8,7 @@ import { JoinAssetToFolder, JoinAssetToNetworkPath, literal } from '../util' export interface JingleLayers { Caspar: { PlayerJingle: string - PlayerJingleLookahead?: string + PlayerJinglePreload?: string } ATEM: { USKCleanEffekt?: string @@ -63,35 +63,7 @@ export function CreateJingleContentBase< return literal>({ ...CreateJingleExpectedMedia(config, file, alphaAtStart, duration, alphaAtEnd), timelineObjects: literal([ - literal({ - id: '', - enable: { - start: 0 - }, - priority: 1, - layer: layers.Caspar.PlayerJingle, - content: { - deviceType: TSR.DeviceType.CASPARCG, - type: TSR.TimelineContentTypeCasparCg.MEDIA, - file: fileName - } - }), - - ...(loadFirstFrame && layers.Caspar.PlayerJingleLookahead - ? [ - literal({ - id: '', - enable: { start: 0 }, - priority: 1, - layer: layers.Caspar.PlayerJingleLookahead, - content: { - deviceType: TSR.DeviceType.CASPARCG, - type: TSR.TimelineContentTypeCasparCg.MEDIA, - file: fileName - } - }) - ] - : []), + CreateJingleCasparTimelineObject(fileName, loadFirstFrame, layers), ...EnableDSK(config, 'JINGLE', { start: Number(config.studio.CasparPrerollDuration) }), @@ -199,3 +171,24 @@ export function CreateJingleContentBase< ]) }) } + +function CreateJingleCasparTimelineObject( + fileName: string, + loadFirstFrame: boolean, + layers: JingleLayers +): TSR.TimelineObjCCGMedia & TimelineBlueprintExt { + return { + id: '', + enable: { start: 0 }, + priority: 1, + layer: + loadFirstFrame && layers.Caspar.PlayerJinglePreload + ? layers.Caspar.PlayerJinglePreload + : layers.Caspar.PlayerJingle, + content: { + deviceType: TSR.DeviceType.CASPARCG, + type: TSR.TimelineContentTypeCasparCg.MEDIA, + file: fileName + } + } +} diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index bdb0d57f7..2ff4af2a9 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -133,7 +133,7 @@ export function createJingleContentOfftube( return CreateJingleContentBase(config, file, alphaAtStart, loadFirstFrame, duration, alphaAtEnd, { Caspar: { PlayerJingle: OfftubeCasparLLayer.CasparPlayerJingle, - PlayerJingleLookahead: OfftubeCasparLLayer.CasparPlayerJingleLookahead + PlayerJinglePreload: OfftubeCasparLLayer.CasparPlayerJinglePreload }, ATEM: { USKJinglePreview: OfftubeAtemLLayer.AtemMENextJingle diff --git a/src/tv2_offtube_studio/layers.ts b/src/tv2_offtube_studio/layers.ts index d9008b611..f1470b69d 100644 --- a/src/tv2_offtube_studio/layers.ts +++ b/src/tv2_offtube_studio/layers.ts @@ -70,7 +70,8 @@ export const OfftubeAtemLLayer = { export type OfftubeAtemLLayer = AtemLLayer | SharedATEMLLayer enum CasparLLayer { - CasparPlayerJingleLookahead = 'casparcg_player_jingle_looakhead', + /** Maps to the same Caspar layer as CasparPlayerJingle but its lookahead preloads the first frame */ + CasparPlayerJinglePreload = 'casparcg_player_jingle_preload', CasparGraphicsFullLoop = 'casparcg_graphics_full_loop', CasparCGDVELoop = 'casparcg_dve_loop', CasparCGDVEKeyedLoop = 'casparcg_dve_keyed_loop', diff --git a/src/tv2_offtube_studio/migrations/index.ts b/src/tv2_offtube_studio/migrations/index.ts index 9fc9a5122..42f1efed1 100644 --- a/src/tv2_offtube_studio/migrations/index.ts +++ b/src/tv2_offtube_studio/migrations/index.ts @@ -268,7 +268,7 @@ export const studioMigrations: MigrationStepStudio[] = literal({ + [OfftubeCasparLLayer.CasparPlayerJinglePreload]: literal({ device: TSR.DeviceType.CASPARCG, deviceId: 'caspar01', - layerName: 'Jingle Lookahead', + layerName: 'Jingle (Preloading First Frame)', lookahead: LookaheadMode.PRELOAD, lookaheadMaxSearchDistance: 1, channel: 3, From 314496f61bc6396782067d10581fa62abbd14d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Mon, 20 Jun 2022 14:29:09 +0200 Subject: [PATCH 129/184] fix:SOF-937 no longer prepend the audio bed folder configuration if we are evaluating a fade cue --- src/tv2-common/cues/lyd.ts | 12 +++- .../helpers/pieces/__tests__/lyd.spec.ts | 70 +++++++++++++++---- 2 files changed, 66 insertions(+), 16 deletions(-) diff --git a/src/tv2-common/cues/lyd.ts b/src/tv2-common/cues/lyd.ts index 5ca23a02d..4acf28666 100644 --- a/src/tv2-common/cues/lyd.ts +++ b/src/tv2-common/cues/lyd.ts @@ -9,7 +9,14 @@ import { TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { CreateTimingEnable, CueDefinitionLYD, literal, PartDefinition, TimeFromFrames } from 'tv2-common' +import { + CreateTimingEnable, + CueDefinitionLYD, + JoinAssetToFolder, + literal, + PartDefinition, + TimeFromFrames +} from 'tv2-common' import { AbstractLLayer, AdlibTags, @@ -20,7 +27,6 @@ import { SharedSourceLayers } from 'tv2-constants' import { TV2BlueprintConfig } from '../blueprintConfig' -import { JoinAssetToFolder } from '../util' export function EvaluateLYD( context: IShowStyleUserContext, @@ -122,7 +128,7 @@ function LydContent( }) } - const filePath = JoinAssetToFolder(config.studio.AudioBedFolder, file) + const filePath = lydType === 'fade' ? file : JoinAssetToFolder(config.studio.AudioBedFolder, file) return literal>({ timelineObjects: literal([ 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 5e1a80c58..50dc262a8 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts @@ -2,7 +2,8 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece, - PieceLifespan + PieceLifespan, + TSR } from '@tv2media/blueprints-integration' import { CueDefinitionLYD, EvaluateLYD, literal, ParseCue, PartDefinitionKam } from 'tv2-common' import { AdlibTags, NoteType, PartType, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' @@ -28,8 +29,8 @@ function makeMockContext() { return mockContext } -const config = getConfig(makeMockContext()) -const mockPart = literal({ +const CONFIG = getConfig(makeMockContext()) +const MOCK_PART = literal({ type: PartType.Kam, variant: { name: '1' @@ -46,7 +47,7 @@ const mockPart = literal({ describe('lyd', () => { test('Lyd with no out time', () => { - const parsedCue = ParseCue(['LYD=SN_INTRO', ';0.00'], config) as CueDefinitionLYD + const parsedCue = ParseCue(['LYD=SN_INTRO', ';0.00'], CONFIG) as CueDefinitionLYD const pieces: IBlueprintPiece[] = [] const adlibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] @@ -65,7 +66,7 @@ describe('lyd', () => { adlibPieces, actions, parsedCue, - mockPart + MOCK_PART ) expect(pieces[0].enable).toEqual( @@ -78,7 +79,7 @@ describe('lyd', () => { }) test('Lyd with out time', () => { - const parsedCue = ParseCue(['LYD=SN_INTRO', ';0.00-0.10'], config) as CueDefinitionLYD + const parsedCue = ParseCue(['LYD=SN_INTRO', ';0.00-0.10'], CONFIG) as CueDefinitionLYD const pieces: IBlueprintPiece[] = [] const adlibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] @@ -97,7 +98,7 @@ describe('lyd', () => { adlibPieces, actions, parsedCue, - mockPart + MOCK_PART ) expect(pieces[0].enable).toEqual( @@ -111,7 +112,7 @@ describe('lyd', () => { }) test('Lyd not configured', () => { - const parsedCue = ParseCue(['LYD=SN_MISSING', ';0.00-0.10'], config) as CueDefinitionLYD + const parsedCue = ParseCue(['LYD=SN_MISSING', ';0.00-0.10'], CONFIG) as CueDefinitionLYD const pieces: IBlueprintPiece[] = [] const adlibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] @@ -132,7 +133,7 @@ describe('lyd', () => { adlibPieces, actions, parsedCue, - mockPart + MOCK_PART ) expect(pieces.length).toEqual(0) @@ -141,7 +142,7 @@ describe('lyd', () => { }) test('Lyd not configured', () => { - const parsedCue = ParseCue(['LYD=SN_MISSING', ';0.00-0.10'], config) as CueDefinitionLYD + const parsedCue = ParseCue(['LYD=SN_MISSING', ';0.00-0.10'], CONFIG) as CueDefinitionLYD const pieces: IBlueprintPiece[] = [] const adlibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] @@ -162,7 +163,7 @@ describe('lyd', () => { adlibPieces, actions, parsedCue, - mockPart + MOCK_PART ) expect(pieces.length).toEqual(0) @@ -171,7 +172,7 @@ describe('lyd', () => { }) test('Lyd adlib', () => { - const parsedCue = ParseCue(['LYD=SN_INTRO', ';x.xx'], config) as CueDefinitionLYD + const parsedCue = ParseCue(['LYD=SN_INTRO', ';x.xx'], CONFIG) as CueDefinitionLYD const pieces: IBlueprintPiece[] = [] const adlibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] @@ -190,7 +191,7 @@ describe('lyd', () => { adlibPieces, actions, parsedCue, - mockPart, + MOCK_PART, true ) @@ -205,4 +206,47 @@ describe('lyd', () => { }) ) }) + + it("should fade, studio audio bed folder is configured, audio file should evaluate to 'empty'", () => { + const parsedCue = ParseCue(['LYD=FADE 100', ';0.00'], CONFIG) as CueDefinitionLYD + const pieces: IBlueprintPiece[] = [] + const adLibPieces: IBlueprintAdLibPiece[] = [] + const actions: IBlueprintActionManifest[] = [] + + CONFIG.studio.AudioBedFolder = 'audio' + + EvaluateLYD(makeMockContext(), CONFIG, pieces, adLibPieces, actions, parsedCue, MOCK_PART) + + expect(pieces).toHaveLength(1) + const timelineObject: TSR.TimelineObjCCGMedia = pieces[0].content.timelineObjects[0] as TSR.TimelineObjCCGMedia + const file = timelineObject.content.file + expect(file).toBe('empty') + }) + + it('should play audio, studio audio bed is configured, audio file should be prepended with the configured audio bed', () => { + const iNewsName = 'ATP_soundbed' + const parsedCue = ParseCue([`LYD=${iNewsName}`, ';0.00'], CONFIG) as CueDefinitionLYD + const pieces: IBlueprintPiece[] = [] + const adLibPieces: IBlueprintAdLibPiece[] = [] + 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) + + expect(pieces).toHaveLength(1) + const timelineObject: TSR.TimelineObjCCGMedia = pieces[0].content.timelineObjects[0] as TSR.TimelineObjCCGMedia + const file = timelineObject.content.file + expect(file).toBe(`${audioBedFolder}/${fileName}`) + }) }) From c0a276ded12188b1ba1365fba4b711800a4a23e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Mon, 20 Jun 2022 14:38:33 +0200 Subject: [PATCH 130/184] chore: SOF-937 Revert fading through Sisyfos --- src/tv2-common/cues/lyd.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/tv2-common/cues/lyd.ts b/src/tv2-common/cues/lyd.ts index 4acf28666..229c1d4bc 100644 --- a/src/tv2-common/cues/lyd.ts +++ b/src/tv2-common/cues/lyd.ts @@ -72,7 +72,7 @@ export function EvaluateLYD( : fade ? Math.max(1000, fadeIn ? TimeFromFrames(fadeIn) : 0) : CreateTimingEnable(parsedCue).enable.duration ?? undefined, - content: LydContent(config, file, lydType, fadeIn, fadeOut, fadeTimeInFrames), + content: LydContent(config, file, lydType, fadeIn, fadeOut), tags: [AdlibTags.ADLIB_FLOW_PRODUCER] }) ) @@ -94,7 +94,7 @@ export function EvaluateLYD( outputLayerId: SharedOutputLayers.MUSIK, sourceLayerId: SharedSourceLayers.PgmAudioBed, lifespan, - content: LydContent(config, file, lydType, fadeIn, fadeOut, fadeTimeInFrames) + content: LydContent(config, file, lydType, fadeIn, fadeOut) }) ) } @@ -105,8 +105,7 @@ function LydContent( file: string, lydType: 'bed' | 'stop' | 'fade', fadeIn?: number, - fadeOut?: number, - fadeTimeInFrames?: number + fadeOut?: number ): WithTimeline { if (lydType === 'stop') { return literal>({ @@ -176,8 +175,7 @@ function LydContent( content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: fadeIn ? 0 : 1, - fadeTime: fadeTimeInFrames ? TimeFromFrames(fadeTimeInFrames) : undefined + isPgm: 1 } }) ]) From 7dd0b9d181d10bd4326246e1d905ed60d5974c84 Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 23 Jun 2022 12:40:55 +0200 Subject: [PATCH 131/184] fix: SOF-767 set `length` for clips with `seek` (in TSR, seek does not work without length); also refactor some functions by grouping params --- src/tv2-common/content/server.ts | 69 ++++++++++-------------- src/tv2-common/parts/server.ts | 80 +++++++++++++--------------- src/tv2-common/pieces/adlibServer.ts | 5 +- 3 files changed, 69 insertions(+), 85 deletions(-) diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 42b7285b8..8b3541e7d 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -17,6 +17,7 @@ import { import { AbstractLLayer, ControlClasses, GetEnableClassForServer } from 'tv2-constants' import { TV2BlueprintConfig } from '../blueprintConfig' import { TimelineBlueprintExt } from '../onTimelineGenerate' +import { ServerContentProps, ServerPartProps } from '../parts' import { AdlibServerOfftubeOptions } from '../pieces' import { JoinAssetToNetworkPath } from '../util' @@ -41,67 +42,49 @@ type VTProps = Pick< export function GetVTContentProperties( config: TV2BlueprintConfig, - file: string, - seek?: number, - sourceDuration?: number + contentProps: Omit ): VTProps { return literal({ - fileName: file, + fileName: contentProps.file, path: JoinAssetToNetworkPath( config.studio.ClipNetworkBasePath, config.studio.ClipFolder, - file, + contentProps.file, config.studio.ClipFileExtension ), // full path on the source network storage mediaFlowIds: [config.studio.ClipMediaFlowId], - sourceDuration: sourceDuration && sourceDuration > 0 ? sourceDuration : undefined, + sourceDuration: + contentProps.sourceDuration && contentProps.sourceDuration > 0 ? contentProps.sourceDuration : undefined, postrollDuration: config.studio.ServerPostrollDuration, ignoreMediaObjectStatus: config.studio.ClipIgnoreStatus, - seek + seek: contentProps.seek }) } export function MakeContentServer( context: IShowStyleUserContext, - file: string, - mediaPlayerSessionId: string, partDefinition: PartDefinition, config: TV2BlueprintConfig, sourceLayers: MakeContentServerSourceLayers, - adLibPix: boolean, - voLevels: boolean, - seek?: number, - sourceDuration?: number + props: ServerPartProps, + contentProps: ServerContentProps ): WithTimeline { return literal>({ - ...GetVTContentProperties(config, file, seek, sourceDuration), + ...GetVTContentProperties(config, contentProps), ignoreMediaObjectStatus: true, - timelineObjects: GetServerTimeline( - context, - file, - mediaPlayerSessionId, - partDefinition, - config, - sourceLayers, - adLibPix, - voLevels, - seek - ) + timelineObjects: GetServerTimeline(context, partDefinition, config, sourceLayers, props, contentProps) }) } function GetServerTimeline( context: IShowStyleUserContext, - file: string, - mediaPlayerSessionId: string, partDefinition: PartDefinition, config: TV2BlueprintConfig, sourceLayers: MakeContentServerSourceLayers, - adLibPix?: boolean, - voLevels?: boolean, - seek?: number + props: ServerPartProps, + contentProps: ServerContentProps ) { - const serverEnableClass = `.${GetEnableClassForServer(mediaPlayerSessionId)}` + const serverEnableClass = `.${GetEnableClassForServer(contentProps.mediaPlayerSession)}` const mediaObj = literal({ id: '', @@ -113,16 +96,20 @@ function GetServerTimeline( content: { deviceType: TSR.DeviceType.CASPARCG, type: TSR.TimelineContentTypeCasparCg.MEDIA, - file, - loop: adLibPix, - seek, - // length: duration, + file: contentProps.file, + loop: props.adLibPix, + seek: contentProps.seek, + length: contentProps.clipDuration, playing: true }, metaData: { - mediaPlayerSession: mediaPlayerSessionId + mediaPlayerSession: contentProps.mediaPlayerSession }, - classes: [...(AddParentClass(config, partDefinition) && !adLibPix ? [ServerParentClass('studio0', file)] : [])] + classes: [ + ...(AddParentClass(config, partDefinition) && !props.adLibPix + ? [ServerParentClass('studio0', contentProps.file)] + : []) + ] }) const mediaOffObj = JSON.parse(JSON.stringify(mediaObj)) as TSR.TimelineObjCCGMedia & TimelineBlueprintExt @@ -143,14 +130,14 @@ function GetServerTimeline( content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: voLevels ? 2 : 1 + isPgm: props.voLevels ? 2 : 1 }, metaData: { - mediaPlayerSession: mediaPlayerSessionId + mediaPlayerSession: contentProps.mediaPlayerSession }, classes: [] }), - ...(voLevels + ...(props.voLevels ? [GetSisyfosTimelineObjForCamera(context, config, 'server', sourceLayers.Sisyfos.StudioMicsGroup)] : []), ...(sourceLayers.ATEM.ServerLookaheadAux @@ -170,7 +157,7 @@ function GetServerTimeline( } }, metaData: { - mediaPlayerSession: mediaPlayerSessionId + mediaPlayerSession: contentProps.mediaPlayerSession } }) ] diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index 7ce92687f..875126486 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -37,9 +37,18 @@ export interface ServerPartProps { tapeTime: number adLibPix: boolean session?: string - lastServerPosition?: ServerPosition actionTriggerMode?: ServerSelectMode + lastServerPosition?: ServerPosition +} + +export interface ServerContentProps { seek?: number + /** Clip duration from mediaObject or tapeTime */ + clipDuration?: number + /** Clip duration as in `clipDuration` but with postroll subtracted */ + sourceDuration?: number + mediaPlayerSession: string + file: string } export type ServerPartLayers = { @@ -75,22 +84,25 @@ export async function CreatePartServerBase< const duration = getDuration(mediaObjectDuration, sourceDuration, props) const sanitisedScript = getScriptWithoutLineBreaks(partDefinition) const actualDuration = getActualDuration(duration, sanitisedScript, props) - props.seek = getServerSeek(props.lastServerPosition, file, mediaObjectDuration, props.actionTriggerMode) + + const contentProps: ServerContentProps = { + seek: getServerSeek(props.lastServerPosition, file, mediaObjectDuration, props.actionTriggerMode), + clipDuration: mediaObjectDuration ?? props.tapeTime * 1000, + mediaPlayerSession: SanitizeString(`segment_${props.session ?? partDefinition.segmentExternalId}_${file}`), + file + } const displayTitle = getDisplayTitle(partDefinition) const basePart = getBasePart(partDefinition, displayTitle, actualDuration, file) - const mediaPlayerSession = SanitizeString(`segment_${props.session ?? partDefinition.segmentExternalId}_${file}`) const pieces: IBlueprintPiece[] = [] const serverSelectionBlueprintPiece = getServerSelectionBlueprintPiece( partDefinition, - file, actualDuration, props, + contentProps, layers, - sourceDuration, - mediaPlayerSession, context, config, config.studio.CasparPrerollDuration @@ -98,11 +110,9 @@ export async function CreatePartServerBase< const pgmBlueprintPiece = getPgmBlueprintPiece( partDefinition, - file, props, + contentProps, layers, - sourceDuration, - mediaPlayerSession, config, config.studio.CasparPrerollDuration ) @@ -205,18 +215,14 @@ function getContentServerElement< ShowStyleConfig extends TV2BlueprintConfigBase >( partDefinition: PartDefinition, - file: string, props: ServerPartProps, + contentProps: ServerContentProps, layers: ServerPartLayers, - sourceDuration: number | undefined, - mediaPlayerSession: string, context: IShowStyleUserContext, config: ShowStyleConfig ): WithTimeline { return MakeContentServer( context, - file, - mediaPlayerSession, partDefinition, config, { @@ -231,10 +237,8 @@ function getContentServerElement< ServerLookaheadAux: layers.ATEM.ServerLookaheadAux } }, - props.adLibPix, - props.voLevels, - props.seek, - sourceDuration + props, + contentProps ) } @@ -243,37 +247,26 @@ function getServerSelectionBlueprintPiece< ShowStyleConfig extends TV2BlueprintConfigBase >( partDefinition: PartDefinition, - file: string, actualDuration: number, props: ServerPartProps, + contentProps: ServerContentProps, layers: ServerPartLayers, - sourceDuration: number | undefined, - mediaPlayerSession: string, context: IShowStyleUserContext, config: ShowStyleConfig, prerollDuration: number ): IBlueprintPiece { - const userDataElement = getUserData(partDefinition, file, actualDuration, props) - const contentServerElement = getContentServerElement( - partDefinition, - file, - props, - layers, - sourceDuration, - mediaPlayerSession, - context, - config - ) + const userDataElement = getUserData(partDefinition, contentProps.file, actualDuration, props) + const contentServerElement = getContentServerElement(partDefinition, props, contentProps, layers, context, config) return literal({ externalId: partDefinition.externalId, - name: file, + name: contentProps.file, enable: { start: 0 }, outputLayerId: SharedOutputLayers.SEC, sourceLayerId: layers.SourceLayer.SelectedServer, lifespan: PieceLifespan.OutOnSegmentEnd, metaData: literal({ - mediaPlayerSessions: [mediaPlayerSession], + mediaPlayerSessions: [contentProps.mediaPlayerSession], userData: userDataElement, sisyfosPersistMetaData: literal({ sisyfosLayers: [], @@ -281,7 +274,7 @@ function getServerSelectionBlueprintPiece< }) }), content: contentServerElement, - tags: [GetTagForServerNext(partDefinition.segmentExternalId, file, props.voLayer)], + tags: [GetTagForServerNext(partDefinition.segmentExternalId, contentProps.file, props.voLayer)], prerollDuration }) } @@ -291,29 +284,30 @@ function getPgmBlueprintPiece< ShowStyleConfig extends TV2BlueprintConfigBase >( partDefinition: PartDefinition, - file: string, props: ServerPartProps, + contentProps: ServerContentProps, layers: ServerPartLayers, - sourceDuration: number | undefined, - mediaPlayerSession: string, config: ShowStyleConfig, prerollDuration: number ): IBlueprintPiece { return literal({ externalId: partDefinition.externalId, - name: file, + name: contentProps.file, enable: { start: 0 }, outputLayerId: SharedOutputLayers.PGM, sourceLayerId: layers.SourceLayer.PgmServer, lifespan: PieceLifespan.WithinPart, metaData: literal({ - mediaPlayerSessions: [mediaPlayerSession] + mediaPlayerSessions: [contentProps.mediaPlayerSession] }), content: { - ...GetVTContentProperties(config, file, props.seek, sourceDuration), - timelineObjects: CutToServer(mediaPlayerSession, partDefinition, config, layers.AtemLLayer.MEPgm) + ...GetVTContentProperties(config, contentProps), + timelineObjects: CutToServer(contentProps.mediaPlayerSession, partDefinition, config, layers.AtemLLayer.MEPgm) }, - tags: [GetTagForServer(partDefinition.segmentExternalId, file, props.voLayer), TallyTags.SERVER_IS_LIVE], + tags: [ + GetTagForServer(partDefinition.segmentExternalId, contentProps.file, props.voLayer), + TallyTags.SERVER_IS_LIVE + ], prerollDuration }) } diff --git a/src/tv2-common/pieces/adlibServer.ts b/src/tv2-common/pieces/adlibServer.ts index 7d4e72d3d..5c9c64c04 100644 --- a/src/tv2-common/pieces/adlibServer.ts +++ b/src/tv2-common/pieces/adlibServer.ts @@ -50,7 +50,10 @@ export function CreateAdlibServer< label: t(`${partDefinition.storyName}`), sourceLayerId: sourceLayers.SourceLayer.PgmServer, outputLayerId: SharedOutputLayers.PGM, - content: GetVTContentProperties(config, file, 0, duration), + content: GetVTContentProperties(config, { + file, + sourceDuration: duration + }), tags: [ tagAsAdlib || voLayer ? AdlibTags.OFFTUBE_ADLIB_SERVER : AdlibTags.OFFTUBE_100pc_SERVER, AdlibTags.ADLIB_KOMMENTATOR, From 84c6bad0c745f717f7d7ec8a8a09ec98aec5b4dc Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 23 Jun 2022 15:10:45 +0200 Subject: [PATCH 132/184] fix: SOF-942 jingles expected durations after changes in core, `expectedDuration` has to include the `autoNextOverlap` time --- .../__tests__/jinglePartProperties.spec.ts | 21 +++++++++++++++++++ src/tv2-common/jinglePartProperties.ts | 5 +---- 2 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 src/tv2-common/__tests__/jinglePartProperties.spec.ts diff --git a/src/tv2-common/__tests__/jinglePartProperties.spec.ts b/src/tv2-common/__tests__/jinglePartProperties.spec.ts new file mode 100644 index 000000000..9b861749f --- /dev/null +++ b/src/tv2-common/__tests__/jinglePartProperties.spec.ts @@ -0,0 +1,21 @@ +import { GetJinglePartPropertiesFromTableValue } from 'tv2-common' + +describe('GetJinglePartPropertiesFromTableValue', () => { + it('Calculates values correctly', () => { + const properties = GetJinglePartPropertiesFromTableValue({ + BreakerName: 'intro', + ClipName: 'intro', + Duration: 200, + StartAlpha: 50, + EndAlpha: 100, + Autonext: true, + LoadFirstFrame: false + }) + expect(properties).toEqual({ + expectedDuration: 6000, + autoNextOverlap: 4000, + autoNext: true, + disableNextInTransition: false + }) + }) +}) diff --git a/src/tv2-common/jinglePartProperties.ts b/src/tv2-common/jinglePartProperties.ts index 119042d27..d4efe4e77 100644 --- a/src/tv2-common/jinglePartProperties.ts +++ b/src/tv2-common/jinglePartProperties.ts @@ -32,10 +32,7 @@ export function GetJinglePartPropertiesFromTableValue( realBreaker: TableConfigItemBreakers ): Pick { return { - expectedDuration: - TimeFromFrames(Number(realBreaker.Duration)) - - TimeFromFrames(Number(realBreaker.EndAlpha)) - - TimeFromFrames(Number(realBreaker.StartAlpha)), + expectedDuration: TimeFromFrames(Number(realBreaker.Duration)) - TimeFromFrames(Number(realBreaker.StartAlpha)), autoNextOverlap: TimeFromFrames(Number(realBreaker.EndAlpha)), autoNext: realBreaker.Autonext === true, disableNextInTransition: false From 338033c932a9152a627eff52fe298bacfdca765c Mon Sep 17 00:00:00 2001 From: ianshade Date: Fri, 24 Jun 2022 13:15:11 +0200 Subject: [PATCH 133/184] fix: SOF-854 generate adlib for manual pilots --- src/tv2-common/actions/executeAction.ts | 34 +++-- .../helpers/graphics/pilot/index.ts | 124 ++++++++++-------- .../helpers/pieces/graphicPilot.ts | 12 +- .../cues/OfftubeGraphics.ts | 23 +++- 4 files changed, 107 insertions(+), 86 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index e794d4b62..bfaac005f 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -33,8 +33,8 @@ import { ActionSelectFullGrafik, ActionSelectServerClip, CalculateTime, - CreateFullPiece, CreatePartServerBase, + CreatePilotPiece, CueDefinition, CueDefinitionDVE, CueDefinitionGraphic, @@ -77,6 +77,7 @@ import { GetEnableForWall, getServerPosition, PilotGeneratorSettings, + PilotGraphicProps, ServerSelectMode } from '../helpers' import { InternalGraphic } from '../helpers/graphics/InternalGraphic' @@ -2067,30 +2068,25 @@ async function executeActionSelectFull< iNewsCommand: '' }) - const fullPiece = CreateFullPiece( + const graphicProps: PilotGraphicProps = { config, context, - externalId, - cue, - 'FULL', - settings.pilotGraphicSettings, - true, - userData.segmentExternalId, + partId: externalId, + settings: settings.pilotGraphicSettings, + parsedCue: cue, + engine: 'FULL', + segmentExternalId: userData.segmentExternalId, + adlib: true + } + + const fullPiece = CreatePilotPiece({ + ...graphicProps, prerollDuration - ) + }) settings.postProcessPieceTimelineObjects(context, config, fullPiece, false) - const fullDataStore = CreateFullDataStore( - config, - context, - settings.pilotGraphicSettings, - cue, - 'FULL', - externalId, - true, - userData.segmentExternalId - ) + const fullDataStore = CreateFullDataStore(graphicProps) await context.queuePart(part, [ fullPiece, diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index 68d2f65fa..45b783f42 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -47,19 +47,26 @@ export interface PilotGeneratorSettings { viz: VizPilotGeneratorSettings } +export interface PilotGraphicProps { + config: TV2BlueprintConfig + context: IShowStyleUserContext + engine: GraphicEngine + partId: string + parsedCue: CueDefinitionGraphic + settings: PilotGeneratorSettings + adlib: boolean + segmentExternalId: string + adlibRank?: number + prerollDuration?: number +} + export function CreatePilotGraphic( - config: TV2BlueprintConfig, - context: IShowStyleUserContext, pieces: IBlueprintPiece[], - _adlibPieces: IBlueprintAdLibPiece[], + adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], - partId: string, - parsedCue: CueDefinitionGraphic, - settings: PilotGeneratorSettings, - adlib: boolean, - adlibRank: number, - externalSegmentId: string + pilotGraphicProps: PilotGraphicProps ) { + const { context, engine, adlib, parsedCue } = pilotGraphicProps if ( parsedCue.graphic.vcpid === undefined || parsedCue.graphic.vcpid === null || @@ -70,33 +77,33 @@ export function CreatePilotGraphic( return } - const engine = parsedCue.target - if (IsTargetingFull(engine)) { - actions.push( - CreatePilotAdLibAction(config, context, parsedCue, engine, settings, adlib, adlibRank, externalSegmentId) - ) + actions.push(CreatePilotAdLibAction(pilotGraphicProps)) + } + + if (!(IsTargetingOVL(pilotGraphicProps.engine) && adlib)) { + pieces.push(CreatePilotPiece(pilotGraphicProps)) } - if (!(IsTargetingOVL(engine) && adlib)) { - pieces.push(CreateFullPiece(config, context, partId, parsedCue, engine, settings, adlib, externalSegmentId)) + if (IsTargetingOVL(engine) && adlib) { + adlibPieces.push(CreatePilotAdlibPiece(pilotGraphicProps)) } if (IsTargetingFull(engine)) { - pieces.push(CreateFullDataStore(config, context, settings, parsedCue, engine, partId, adlib, externalSegmentId)) + pieces.push(CreateFullDataStore(pilotGraphicProps)) } } -function CreatePilotAdLibAction( - config: TV2BlueprintConfig, - context: IShowStyleUserContext, - parsedCue: CueDefinitionGraphic, - engine: GraphicEngine, - settings: PilotGeneratorSettings, - adlib: boolean, - adlibRank: number, - segmentExternalId: string -) { +function CreatePilotAdLibAction({ + config, + context, + parsedCue, + engine, + settings, + adlib, + adlibRank, + segmentExternalId +}: PilotGraphicProps) { const name = GraphicDisplayName(config, parsedCue) const sourceLayerId = GetSourceLayer(engine) const outputLayerId = GetOutputLayer(engine) @@ -117,7 +124,7 @@ function CreatePilotAdLibAction( label: t(GetFullGraphicTemplateNameFromCue(config, parsedCue)), sourceLayerId: SharedSourceLayers.PgmPilot, outputLayerId: SharedOutputLayers.PGM, - content: CreateFullContent(config, context, settings, parsedCue, engine, adlib), + content: CreatePilotContent(config, context, settings, parsedCue, engine, adlib), uniquenessId: `gfx_${name}_${sourceLayerId}_${outputLayerId}`, tags: [ AdlibTags.ADLIB_KOMMENTATOR, @@ -129,17 +136,17 @@ function CreatePilotAdLibAction( }) } -export function CreateFullPiece( - config: TV2BlueprintConfig, - context: IShowStyleUserContext, - partId: string, - parsedCue: CueDefinitionGraphic, - engine: GraphicEngine, - settings: PilotGeneratorSettings, - adlib: boolean, - segmentExternalId: string, - prerollDuration?: number -): IBlueprintPiece { +export function CreatePilotPiece({ + config, + context, + partId, + parsedCue, + engine, + settings, + adlib, + segmentExternalId, + prerollDuration +}: PilotGraphicProps): IBlueprintPiece { return literal({ externalId: partId, name: GraphicDisplayName(config, parsedCue), @@ -159,22 +166,33 @@ export function CreateFullPiece( sisyfosLayers: [] } }), - content: CreateFullContent(config, context, settings, parsedCue, engine, adlib), - tags: [GetTagForFull(segmentExternalId, parsedCue.graphic.vcpid), TallyTags.FULL_IS_LIVE] + content: CreatePilotContent(config, context, settings, parsedCue, engine, adlib), + tags: IsTargetingFull(engine) + ? [GetTagForFull(segmentExternalId, parsedCue.graphic.vcpid), TallyTags.FULL_IS_LIVE] + : [] }) } -export function CreateFullDataStore( - config: TV2BlueprintConfig, - context: IShowStyleUserContext, - settings: PilotGeneratorSettings, - parsedCue: CueDefinitionGraphic, - engine: GraphicEngine, - partId: string, - adlib: boolean, - segmentExternalId: string -): IBlueprintPiece { - const content = CreateFullContent(config, context, settings, parsedCue, engine, adlib) +export function CreatePilotAdlibPiece(pieceProps: PilotGraphicProps, rank?: number): IBlueprintAdLibPiece { + const pilotPiece = CreatePilotPiece(pieceProps) + pilotPiece.tags = [...(pilotPiece.tags ?? []), AdlibTags.ADLIB_FLOW_PRODUCER] + return { + ...pilotPiece, + _rank: rank ?? 0 + } +} + +export function CreateFullDataStore({ + config, + context, + partId, + parsedCue, + engine, + settings, + adlib, + segmentExternalId +}: PilotGraphicProps): IBlueprintPiece { + const content = CreatePilotContent(config, context, settings, parsedCue, engine, adlib) content.timelineObjects = content.timelineObjects.filter( o => o.content.deviceType !== TSR.DeviceType.ATEM && @@ -207,7 +225,7 @@ export function CreateFullDataStore( }) } -function CreateFullContent( +function CreatePilotContent( config: TV2BlueprintConfig, context: IShowStyleUserContext, settings: PilotGeneratorSettings, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts index 218c415f1..0a553f71e 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts @@ -40,19 +40,17 @@ export function EvaluateCueGraphicPilot( segmentExternalId: string, rank?: number ) { - CreatePilotGraphic( + CreatePilotGraphic(pieces, adlibPieces, actions, { config, context, - pieces, - adlibPieces, - actions, + engine: parsedCue.target, partId, parsedCue, - pilotGeneratorSettingsAFVD, + settings: pilotGeneratorSettingsAFVD, adlib, - rank ?? 0, + adlibRank: rank ?? 0, segmentExternalId - ) + }) } function makeStudioTimelineViz( diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts index 995f8cba9..3d22b63bf 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts @@ -40,10 +40,22 @@ export function OfftubeEvaluateGrafikCaspar( parsedCue: CueDefinitionGraphic, adlib: boolean, partDefinition: PartDefinition, - rank?: number + adlibRank?: number ) { if (GraphicIsPilot(parsedCue)) { - CreatePilotGraphic( + CreatePilotGraphic(pieces, adlibPieces, actions, { + engine: parsedCue.target, + config, + context, + partId, + parsedCue, + settings: pilotGeneratorSettingsOfftube, + adlib, + adlibRank, + segmentExternalId: partDefinition.segmentExternalId + }) + } else if (GraphicIsInternal(parsedCue)) { + CreateInternalGraphic( config, context, pieces, @@ -51,13 +63,10 @@ export function OfftubeEvaluateGrafikCaspar( actions, partId, parsedCue, - pilotGeneratorSettingsOfftube, adlib, - rank ?? 0, - partDefinition.segmentExternalId + partDefinition, + adlibRank ) - } else if (GraphicIsInternal(parsedCue)) { - CreateInternalGraphic(config, context, pieces, adlibPieces, actions, partId, parsedCue, adlib, partDefinition, rank) } } From 9ea0e39a4b83a8bb314bff0700936c64010b26bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Mon, 27 Jun 2022 09:12:52 +0200 Subject: [PATCH 134/184] chore: Remove deprecation warning from jest. The 'tsConfig' directive in jest-config is renamed to 'tsonfig'. --- jest.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jest.config.js b/jest.config.js index 85eaaeedd..313d6a6b1 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,7 +1,7 @@ module.exports = { globals: { 'ts-jest': { - tsConfig: 'tsconfig.json', + tsconfig: 'tsconfig.json', }, }, moduleFileExtensions: [ From c8fe73a1aaff36ec59016fd9adba9e4dae0fbc25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Mon, 27 Jun 2022 09:33:54 +0200 Subject: [PATCH 135/184] refactor: Use test instead of match for regex in ParseBody. Regex matching in places where we are simply testing for a pattern withouth extracting information has been changed to using re.test. test is faster and is semantically more describing of what is happening. --- .../inewsConversion/converters/ParseBody.ts | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index 207a3e695..b4c2a6d19 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -1,6 +1,6 @@ import { CueDefinitionFromLayout, PostProcessDefinitions, TV2BlueprintConfig, UnparsedCue } from 'tv2-common' import { CueType, PartType } from 'tv2-constants' -import { CueDefinition, CueDefinitionUnpairedPilot, ParseCue, UnpairedPilotToGraphic } from './ParseCue' +import { CueDefinition, ParseCue, UnpairedPilotToGraphic } from './ParseCue' export interface PartTransition { style: string @@ -107,7 +107,7 @@ export type PartdefinitionTypes = | Pick | Pick -const ACCEPTED_RED_TEXT = /\b(KAM(?:\d+)?|CAM(?:\d+)?|KAMERA(?:\d+)?|CAMERA(?:\d+)?|SERVER|ATTACK|TEKNIK|GRAFIK|EVS ?\d+ ?(?:VOV?)?|VOV?|VOSB)+\b/gi +const ACCEPTED_RED_TEXT = /\b(KAM(?:\d+)?|CAM(?:\d+)?|KAMERA(?:\d+)?|CAMERA(?:\d+)?|SERVER|ATTACK|TEKNIK|GRAFIK|EVS ?\d+ ?(?:VOV?)?|VOV?|VOSB)+\b/i const EVS_RED_TEXT = /EVS ?(\d+) ?(VOV?)?/i export function ParseBody( @@ -162,11 +162,11 @@ export function ParseBody( .replace(/<\/tab>/i, '') .trim() - if (typeStr && !!typeStr.match(ACCEPTED_RED_TEXT)) { + if (typeStr && ACCEPTED_RED_TEXT.test(typeStr)) { const inlineCues = line .replace(/<\/?p>/g, '') .split(/(.*?)<\/pi>/i) - .filter(cue => cue !== '' && !cue.match(/<\/a>/)) + .filter(cue => cue !== '' && !/<\/a>/.test(cue)) /** Hold any secondary cues in the form: `[] KAM 1` */ const secondaryInlineCues: CueDefinition[] = [] @@ -175,7 +175,7 @@ export function ParseBody( let pos = 0 let redTextFound = false while (pos < inlineCues.length && !redTextFound) { - if (inlineCues[pos].match(ACCEPTED_RED_TEXT)) { + if (ACCEPTED_RED_TEXT.test(inlineCues[pos])) { redTextFound = true } else { const parsedCues = getCuesInLine(inlineCues[pos], cues, config) @@ -183,7 +183,7 @@ export function ParseBody( // Create standalone parts for primary cues. if ( isPrimaryCue(cue) && - !(cue.type === CueType.UNPAIRED_TARGET && cue.target === 'FULL' && !!typeStr.match(/GRAFIK/i)) + !(cue.type === CueType.UNPAIRED_TARGET && cue.target === 'FULL' && /GRAFIK/i.test(typeStr)) ) { if (shouldPushDefinition(definition)) { definitions.push(definition) @@ -213,7 +213,7 @@ export function ParseBody( line = line.replace(/<\/a>/g, '') const lastCue = definition.cues[definition.cues.length - 1] - if (typeStr.match(/GRAFIK/i) && lastCue && lastCue.type === CueType.UNPAIRED_TARGET && !definition.script) { + if (/GRAFIK/i.test(typeStr) && lastCue && lastCue.type === CueType.UNPAIRED_TARGET && !definition.script) { definition = makeDefinition(segmentId, definitions.length, typeStr, fields, modified, segmentName) definition.cues.push(lastCue) } else { @@ -228,7 +228,7 @@ export function ParseBody( definition.cues.push(...secondaryInlineCues) } - if (typeStr && typeStr.match(/SLUTORD/i)) { + if (typeStr && /SLUTORD/i.test(typeStr)) { if (definition.endWords) { definition.endWords += ` ${typeStr.replace(/^SLUTORD:? ?/i, '')}` } else { @@ -320,7 +320,7 @@ export function FindTargetPair(partDefinition: PartDefinition): boolean { } if (nextCue.type === CueType.UNPAIRED_PILOT) { - const mosCue = nextCue as CueDefinitionUnpairedPilot + const mosCue = nextCue if (targetCue.type === CueType.UNPAIRED_TARGET) { partDefinition.cues[index] = UnpairedPilotToGraphic(mosCue, targetCue.target, targetCue) } else if (targetCue.type === CueType.Telefon) { @@ -353,7 +353,7 @@ function initDefinition(fields: any, modified: number, segmentName: string): Par /** Returns true if there is a cue in the given line. */ function cueInLine(line: string) { - return !!line.match(//gi) + return //i.test(line) } /** Returns all the cues in a given line as parsed cues. */ @@ -383,8 +383,8 @@ function getCuesInLine(line: string, cues: UnparsedCue[], config: TV2BlueprintCo } function addScript(line: string, definition: PartDefinition) { - const script = line.match(/

(.*)?<\/p>/i) - if (script && script[1] && !script[1].match(/(.*?)<\/pi>/i)) { + const script = line.match(/

(.*?)<\/p>/i) + if (script && script[1] && !/.*?<\/pi>/i.test(script[1])) { const trimscript = script[1] .replace(/<.*?>/gi, '') .replace('\n\r', '') @@ -511,7 +511,7 @@ function extractTypeProperties(typeStr: string): PartdefinitionTypes { .split(' ') const firstToken = tokens[0] - if (firstToken.match(/KAM|CAM/i)) { + if (/[CK]AM/i.test(firstToken)) { const adjacentKamNumber = tokens[0].match(/KAM(\d+)/i) return { type: PartType.Kam, @@ -520,25 +520,25 @@ function extractTypeProperties(typeStr: string): PartdefinitionTypes { }, ...definition } - } else if (firstToken.match(/SERVER/i) || firstToken.match(/ATTACK/i)) { + } else if (/SERVER|ATTACK/i.test(firstToken)) { return { type: PartType.Server, variant: {}, ...definition } - } else if (firstToken.match(/TEKNIK/i)) { + } else if (/TEKNIK/i.test(firstToken)) { return { type: PartType.Teknik, variant: {}, ...definition } - } else if (firstToken.match(/GRAFIK/i)) { + } else if (/GRAFIK/i.test(firstToken)) { return { type: PartType.Grafik, variant: {}, ...definition } - } else if (typeStr.match(EVS_RED_TEXT)) { + } else if (EVS_RED_TEXT.test(typeStr)) { const strippedToken = typeStr.match(EVS_RED_TEXT) return { type: PartType.EVS, @@ -548,7 +548,7 @@ function extractTypeProperties(typeStr: string): PartdefinitionTypes { }, ...definition } - } else if (firstToken.match(/VOV?/i) || firstToken.match(/VOSB/i)) { + } else if (/VOV?|VOSB/i.test(firstToken)) { return { type: PartType.VO, variant: {}, From b7b19af1da8e24f6c6f8cf2548ae8c0a74ec0397 Mon Sep 17 00:00:00 2001 From: ianshade Date: Mon, 27 Jun 2022 11:12:27 +0200 Subject: [PATCH 136/184] refactor: SOF-767 types, parameter names and duplicated code --- src/tv2-common/content/server.ts | 24 ++++--- src/tv2-common/getSegment.ts | 2 +- src/tv2-common/parts/server.ts | 62 +++++++++---------- src/tv2-common/pieces/adlibServer.ts | 18 ++++-- .../helpers/pieces/adlib.ts | 9 +-- src/tv2_afvd_showstyle/parts/server.ts | 8 +-- .../cues/OfftubeAdlib.ts | 9 +-- .../parts/OfftubeServer.ts | 25 +++----- 8 files changed, 74 insertions(+), 83 deletions(-) diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 8b3541e7d..2518cad34 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -53,8 +53,7 @@ export function GetVTContentProperties( config.studio.ClipFileExtension ), // full path on the source network storage mediaFlowIds: [config.studio.ClipMediaFlowId], - sourceDuration: - contentProps.sourceDuration && contentProps.sourceDuration > 0 ? contentProps.sourceDuration : undefined, + sourceDuration: contentProps.sourceDuration, postrollDuration: config.studio.ServerPostrollDuration, ignoreMediaObjectStatus: config.studio.ClipIgnoreStatus, seek: contentProps.seek @@ -66,13 +65,13 @@ export function MakeContentServer( partDefinition: PartDefinition, config: TV2BlueprintConfig, sourceLayers: MakeContentServerSourceLayers, - props: ServerPartProps, + partProps: ServerPartProps, contentProps: ServerContentProps ): WithTimeline { return literal>({ ...GetVTContentProperties(config, contentProps), ignoreMediaObjectStatus: true, - timelineObjects: GetServerTimeline(context, partDefinition, config, sourceLayers, props, contentProps) + timelineObjects: GetServerTimeline(context, partDefinition, config, sourceLayers, partProps, contentProps) }) } @@ -81,7 +80,7 @@ function GetServerTimeline( partDefinition: PartDefinition, config: TV2BlueprintConfig, sourceLayers: MakeContentServerSourceLayers, - props: ServerPartProps, + partProps: ServerPartProps, contentProps: ServerContentProps ) { const serverEnableClass = `.${GetEnableClassForServer(contentProps.mediaPlayerSession)}` @@ -97,7 +96,7 @@ function GetServerTimeline( deviceType: TSR.DeviceType.CASPARCG, type: TSR.TimelineContentTypeCasparCg.MEDIA, file: contentProps.file, - loop: props.adLibPix, + loop: partProps.adLibPix, seek: contentProps.seek, length: contentProps.clipDuration, playing: true @@ -106,7 +105,7 @@ function GetServerTimeline( mediaPlayerSession: contentProps.mediaPlayerSession }, classes: [ - ...(AddParentClass(config, partDefinition) && !props.adLibPix + ...(AddParentClass(config, partDefinition) && !partProps.adLibPix ? [ServerParentClass('studio0', contentProps.file)] : []) ] @@ -130,14 +129,14 @@ function GetServerTimeline( content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: props.voLevels ? 2 : 1 + isPgm: partProps.voLevels ? 2 : 1 }, metaData: { mediaPlayerSession: contentProps.mediaPlayerSession }, classes: [] }), - ...(props.voLevels + ...(partProps.voLevels ? [GetSisyfosTimelineObjForCamera(context, config, 'server', sourceLayers.Sisyfos.StudioMicsGroup)] : []), ...(sourceLayers.ATEM.ServerLookaheadAux @@ -220,3 +219,10 @@ export function EnableServer(mediaPlayerSessionId: string) { classes: [GetEnableClassForServer(mediaPlayerSessionId)] }) } + +export function getSourceDuration( + mediaObjectDuration: number | undefined, + serverPostrollDuration: number +): number | undefined { + return mediaObjectDuration !== undefined ? Math.max(mediaObjectDuration - serverPostrollDuration, 0) : undefined +} diff --git a/src/tv2-common/getSegment.ts b/src/tv2-common/getSegment.ts index 3d57b9760..25cb9c1dd 100644 --- a/src/tv2-common/getSegment.ts +++ b/src/tv2-common/getSegment.ts @@ -59,7 +59,7 @@ export interface GetSegmentShowstyleOptions< context: IShowStyleUserContext, config: ShowStyleConfig, partDefinition: PartDefinition, - props: ServerPartProps + partProps: ServerPartProps ) => BlueprintResultPart | Promise CreatePartTeknik?: ( context: IShowStyleUserContext, diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index 875126486..22c1f0991 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -19,7 +19,7 @@ import { import { AdlibActionType, PartType, SharedOutputLayers, TallyTags } from 'tv2-constants' import { ActionSelectServerClip } from '../actions' import { TV2BlueprintConfigBase, TV2StudioConfigBase } from '../blueprintConfig' -import { GetVTContentProperties } from '../content' +import { getSourceDuration, GetVTContentProperties } from '../content' import { getServerSeek, ServerPosition, ServerSelectMode } from '../helpers' import { PartDefinition } from '../inewsConversion' import { literal, SanitizeString } from '../util' @@ -44,9 +44,9 @@ export interface ServerPartProps { export interface ServerContentProps { seek?: number /** Clip duration from mediaObject or tapeTime */ - clipDuration?: number + clipDuration: number | undefined /** Clip duration as in `clipDuration` but with postroll subtracted */ - sourceDuration?: number + sourceDuration: number | undefined mediaPlayerSession: string file: string } @@ -69,7 +69,7 @@ export async function CreatePartServerBase< context: IShowStyleUserContext, config: ShowStyleConfig, partDefinition: PartDefinition, - props: ServerPartProps, + partProps: ServerPartProps, layers: ServerPartLayers ): Promise<{ part: BlueprintResultPart; file: string; duration: number; invalid?: true }> { if (isVideoIdMissing(partDefinition)) { @@ -81,14 +81,15 @@ export async function CreatePartServerBase< const mediaObjectDurationSec = await context.hackGetMediaObjectDuration(file) const mediaObjectDuration = mediaObjectDurationSec && mediaObjectDurationSec * 1000 const sourceDuration = getSourceDuration(mediaObjectDuration, config.studio.ServerPostrollDuration) - const duration = getDuration(mediaObjectDuration, sourceDuration, props) + const duration = getDuration(mediaObjectDuration, sourceDuration, partProps) const sanitisedScript = getScriptWithoutLineBreaks(partDefinition) - const actualDuration = getActualDuration(duration, sanitisedScript, props) + const actualDuration = getActualDuration(duration, sanitisedScript, partProps) const contentProps: ServerContentProps = { - seek: getServerSeek(props.lastServerPosition, file, mediaObjectDuration, props.actionTriggerMode), - clipDuration: mediaObjectDuration ?? props.tapeTime * 1000, - mediaPlayerSession: SanitizeString(`segment_${props.session ?? partDefinition.segmentExternalId}_${file}`), + seek: getServerSeek(partProps.lastServerPosition, file, mediaObjectDuration, partProps.actionTriggerMode), + clipDuration: mediaObjectDuration ?? partProps.tapeTime * 1000, + mediaPlayerSession: SanitizeString(`segment_${partProps.session ?? partDefinition.segmentExternalId}_${file}`), + sourceDuration, file } @@ -100,7 +101,7 @@ export async function CreatePartServerBase< const serverSelectionBlueprintPiece = getServerSelectionBlueprintPiece( partDefinition, actualDuration, - props, + partProps, contentProps, layers, context, @@ -110,7 +111,7 @@ export async function CreatePartServerBase< const pgmBlueprintPiece = getPgmBlueprintPiece( partDefinition, - props, + partProps, contentProps, layers, config, @@ -140,23 +141,16 @@ function getVideoId(partDefinition: PartDefinition): string { return partDefinition.fields.videoId ? partDefinition.fields.videoId : '' } -function getSourceDuration( - mediaObjectDuration: number | undefined, - serverPostrollDuration: number -): number | undefined { - return mediaObjectDuration !== undefined ? mediaObjectDuration - serverPostrollDuration : undefined -} - function getDuration( mediaObjectDuration: number | undefined, sourceDuration: number | undefined, - props: ServerPartProps + partProps: ServerPartProps ): number { return ( (mediaObjectDuration !== undefined && - ((props.voLayer && props.totalWords <= 0) || !props.voLayer) && + ((partProps.voLayer && partProps.totalWords <= 0) || !partProps.voLayer) && sourceDuration) || - props.tapeTime * 1000 || + partProps.tapeTime * 1000 || 0 ) } @@ -197,16 +191,16 @@ function getUserData( partDefinition: PartDefinition, file: string, actualDuration: number, - props: ServerPartProps + partProps: ServerPartProps ): ActionSelectServerClip { return { type: AdlibActionType.SELECT_SERVER_CLIP, file, partDefinition, duration: actualDuration, - voLayer: props.voLayer, - voLevels: props.voLevels, - adLibPix: props.adLibPix + voLayer: partProps.voLayer, + voLevels: partProps.voLevels, + adLibPix: partProps.adLibPix } } @@ -215,7 +209,7 @@ function getContentServerElement< ShowStyleConfig extends TV2BlueprintConfigBase >( partDefinition: PartDefinition, - props: ServerPartProps, + partProps: ServerPartProps, contentProps: ServerContentProps, layers: ServerPartLayers, context: IShowStyleUserContext, @@ -237,7 +231,7 @@ function getContentServerElement< ServerLookaheadAux: layers.ATEM.ServerLookaheadAux } }, - props, + partProps, contentProps ) } @@ -248,15 +242,15 @@ function getServerSelectionBlueprintPiece< >( partDefinition: PartDefinition, actualDuration: number, - props: ServerPartProps, + partProps: ServerPartProps, contentProps: ServerContentProps, layers: ServerPartLayers, context: IShowStyleUserContext, config: ShowStyleConfig, prerollDuration: number ): IBlueprintPiece { - const userDataElement = getUserData(partDefinition, contentProps.file, actualDuration, props) - const contentServerElement = getContentServerElement(partDefinition, props, contentProps, layers, context, config) + const userDataElement = getUserData(partDefinition, contentProps.file, actualDuration, partProps) + const contentServerElement = getContentServerElement(partDefinition, partProps, contentProps, layers, context, config) return literal({ externalId: partDefinition.externalId, @@ -270,11 +264,11 @@ function getServerSelectionBlueprintPiece< userData: userDataElement, sisyfosPersistMetaData: literal({ sisyfosLayers: [], - acceptPersistAudio: props.adLibPix && props.voLevels + acceptPersistAudio: partProps.adLibPix && partProps.voLevels }) }), content: contentServerElement, - tags: [GetTagForServerNext(partDefinition.segmentExternalId, contentProps.file, props.voLayer)], + tags: [GetTagForServerNext(partDefinition.segmentExternalId, contentProps.file, partProps.voLayer)], prerollDuration }) } @@ -284,7 +278,7 @@ function getPgmBlueprintPiece< ShowStyleConfig extends TV2BlueprintConfigBase >( partDefinition: PartDefinition, - props: ServerPartProps, + partProps: ServerPartProps, contentProps: ServerContentProps, layers: ServerPartLayers, config: ShowStyleConfig, @@ -305,7 +299,7 @@ function getPgmBlueprintPiece< timelineObjects: CutToServer(contentProps.mediaPlayerSession, partDefinition, config, layers.AtemLLayer.MEPgm) }, tags: [ - GetTagForServer(partDefinition.segmentExternalId, contentProps.file, props.voLayer), + GetTagForServer(partDefinition.segmentExternalId, contentProps.file, partProps.voLayer), TallyTags.SERVER_IS_LIVE ], prerollDuration diff --git a/src/tv2-common/pieces/adlibServer.ts b/src/tv2-common/pieces/adlibServer.ts index 5c9c64c04..cbc0f14fb 100644 --- a/src/tv2-common/pieces/adlibServer.ts +++ b/src/tv2-common/pieces/adlibServer.ts @@ -1,6 +1,7 @@ -import { IBlueprintActionManifest } from '@tv2media/blueprints-integration' +import { IBlueprintActionManifest, IShowStyleUserContext } from '@tv2media/blueprints-integration' import { ActionSelectServerClip, + getSourceDuration, GetTagForServer, GetTagForServerNext, GetVTContentProperties, @@ -18,10 +19,11 @@ export interface AdlibServerOfftubeOptions { isOfftube: boolean } -export function CreateAdlibServer< +export async function CreateAdlibServer< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >( + context: IShowStyleUserContext, config: ShowStyleConfig, rank: number, partDefinition: PartDefinition, @@ -29,9 +31,12 @@ export function CreateAdlibServer< voLayer: boolean, voLevels: boolean, sourceLayers: ServerPartLayers, - duration: number, tagAsAdlib: boolean -): IBlueprintActionManifest { +): Promise { + const mediaObjectDurationSec = await context.hackGetMediaObjectDuration(file) + const mediaObjectDuration = mediaObjectDurationSec && mediaObjectDurationSec * 1000 + const sourceDuration = getSourceDuration(mediaObjectDuration, config.studio.ServerPostrollDuration) + return literal({ externalId: partDefinition.externalId + '-adLib-server', actionId: AdlibActionType.SELECT_SERVER_CLIP, @@ -39,7 +44,7 @@ export function CreateAdlibServer< type: AdlibActionType.SELECT_SERVER_CLIP, file, partDefinition, - duration, + duration: sourceDuration ?? 0, voLayer, voLevels, adLibPix: tagAsAdlib @@ -52,7 +57,8 @@ export function CreateAdlibServer< outputLayerId: SharedOutputLayers.PGM, content: GetVTContentProperties(config, { file, - sourceDuration: duration + clipDuration: mediaObjectDuration, + sourceDuration }), tags: [ tagAsAdlib || voLayer ? AdlibTags.OFFTUBE_ADLIB_SERVER : AdlibTags.OFFTUBE_100pc_SERVER, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts index 9718714f9..f5f991eae 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts @@ -43,13 +43,9 @@ export async function EvaluateAdLib( return } - const sourceDuration = Math.max( - ((await context.hackGetMediaObjectDuration(file)) || 0) * 1000 - config.studio.ServerPostrollDuration, - 0 - ) - actions.push( - CreateAdlibServer( + await CreateAdlibServer( + context, config, rank, partDefinition, @@ -73,7 +69,6 @@ export async function EvaluateAdLib( }, ATEM: {} }, - sourceDuration, true ) ) diff --git a/src/tv2_afvd_showstyle/parts/server.ts b/src/tv2_afvd_showstyle/parts/server.ts index 4e2f313ae..86f224f4f 100644 --- a/src/tv2_afvd_showstyle/parts/server.ts +++ b/src/tv2_afvd_showstyle/parts/server.ts @@ -15,12 +15,12 @@ export async function CreatePartServer( context: ISegmentUserContext, config: BlueprintConfig, partDefinition: PartDefinition, - props: ServerPartProps + partProps: ServerPartProps ): Promise { - const basePartProps = await CreatePartServerBase(context, config, partDefinition, props, { + const basePartProps = await CreatePartServerBase(context, config, partDefinition, partProps, { SourceLayer: { - PgmServer: props.voLayer ? SourceLayer.PgmVoiceOver : SourceLayer.PgmServer, // TODO this actually is shared - SelectedServer: props.voLayer ? SourceLayer.SelectedVoiceOver : SourceLayer.SelectedServer + PgmServer: partProps.voLayer ? SourceLayer.PgmVoiceOver : SourceLayer.PgmServer, // TODO this actually is shared + SelectedServer: partProps.voLayer ? SourceLayer.SelectedVoiceOver : SourceLayer.SelectedServer }, AtemLLayer: { MEPgm: AtemLLayer.AtemMEProgram diff --git a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts index 49e7cc93e..6c8b832d6 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts @@ -46,13 +46,9 @@ export async function OfftubeEvaluateAdLib( return } - const sourceDuration = Math.max( - ((await context.hackGetMediaObjectDuration(file)) || 0) * 1000 - config.studio.ServerPostrollDuration, - 0 - ) - actions.push( - CreateAdlibServer( + await CreateAdlibServer( + context, config, rank, partDefinition, @@ -78,7 +74,6 @@ export async function OfftubeEvaluateAdLib( ServerLookaheadAux: OfftubeAtemLLayer.AtemAuxServerLookahead } }, - sourceDuration, true ) ) diff --git a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts index 71a077b0f..4a2b5930a 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts @@ -15,12 +15,12 @@ export async function OfftubeCreatePartServer( context: ISegmentUserContext, config: OfftubeShowstyleBlueprintConfig, partDefinition: PartDefinition, - props: ServerPartProps + partProps: ServerPartProps ): Promise { - const basePartProps = await CreatePartServerBase(context, config, partDefinition, props, { + const basePartProps = await CreatePartServerBase(context, config, partDefinition, partProps, { SourceLayer: { - PgmServer: props.voLayer ? OfftubeSourceLayer.PgmVoiceOver : OfftubeSourceLayer.PgmServer, // TODO this actually is shared - SelectedServer: props.voLayer ? OfftubeSourceLayer.SelectedVoiceOver : OfftubeSourceLayer.SelectedServer + PgmServer: partProps.voLayer ? OfftubeSourceLayer.PgmVoiceOver : OfftubeSourceLayer.PgmServer, // TODO this actually is shared + SelectedServer: partProps.voLayer ? OfftubeSourceLayer.SelectedVoiceOver : OfftubeSourceLayer.SelectedServer }, AtemLLayer: { MEPgm: OfftubeAtemLLayer.AtemMEClean, @@ -52,23 +52,19 @@ export async function OfftubeCreatePartServer( part = { ...part, ...CreateEffektForpart(context, config, partDefinition, pieces) } - const sourceDuration = Math.max( - ((await context.hackGetMediaObjectDuration(file)) || 0) * 1000 - config.studio.ServerPostrollDuration, - 0 - ) - actions.push( - CreateAdlibServer( + await CreateAdlibServer( + context, config, 0, partDefinition, file, - props.voLayer, - props.voLevels, + partProps.voLayer, + partProps.voLevels, { SourceLayer: { - PgmServer: props.voLayer ? OfftubeSourceLayer.PgmVoiceOver : OfftubeSourceLayer.PgmServer, // TODO this actually is shared - SelectedServer: props.voLayer ? OfftubeSourceLayer.SelectedVoiceOver : OfftubeSourceLayer.SelectedServer + PgmServer: partProps.voLayer ? OfftubeSourceLayer.PgmVoiceOver : OfftubeSourceLayer.PgmServer, // TODO this actually is shared + SelectedServer: partProps.voLayer ? OfftubeSourceLayer.SelectedVoiceOver : OfftubeSourceLayer.SelectedServer }, Caspar: { ClipPending: OfftubeCasparLLayer.CasparPlayerClipPending @@ -85,7 +81,6 @@ export async function OfftubeCreatePartServer( ServerLookaheadAux: OfftubeAtemLLayer.AtemAuxServerLookahead } }, - sourceDuration, false ) ) From 596789b46d5bb2ed0c1681fabcd51f138315f2a7 Mon Sep 17 00:00:00 2001 From: ianshade Date: Mon, 27 Jun 2022 12:36:41 +0200 Subject: [PATCH 137/184] chore: SOF-1006 add Q Flow rundown view layout --- shelf-layouts/Q_Flow_Rundown_View_Layout.json | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 shelf-layouts/Q_Flow_Rundown_View_Layout.json diff --git a/shelf-layouts/Q_Flow_Rundown_View_Layout.json b/shelf-layouts/Q_Flow_Rundown_View_Layout.json new file mode 100644 index 000000000..1e06d78ba --- /dev/null +++ b/shelf-layouts/Q_Flow_Rundown_View_Layout.json @@ -0,0 +1,34 @@ +{ + "_id": "X4GYdLrEcFTXWKkhm", + "name": "Q flow", + "showStyleBaseId": "show0", + "type": "rundown_view_layout", + "icon": { + "prefix": "fas", + "iconName": "columns", + "icon": [ + 512, + 512, + [], + "f0db", + "M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM224 416H64V160h160v256zm224 0H288V160h160v256z" + ] + }, + "iconColor": "#14c942", + "regionId": "rundown_view_layouts", + "shelfLayout": "Ri9ZjAJh3QfeJ7KzG", + "miniShelfLayout": "2LcnzqDKS6PaQKhze", + "exposeAsSelectableLayout": true, + "liveLineProps": { + "requiredLayerIds": [ + "studio0_clip", + "studio0_voiceover" + ] + }, + "hideRundownDivider": true, + "showBreaksAsSegments": true, + "fixedSegmentDuration": true, + "countdownToSegmentRequireLayers": [ + "studio0_live" + ] +} \ No newline at end of file From 90656a7b7a915fd0b5a1924966b7ab9262d8ae1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Tue, 28 Jun 2022 10:36:17 +0200 Subject: [PATCH 138/184] feat(SOF-980): EPSIO can be used as red text or DVE source. This requires setting up an entry in EVS mappings with the name EPSIO. --- src/tv2-common/content/dve.ts | 19 +++++++++------ .../inewsConversion/converters/ParseBody.ts | 11 ++++++++- src/tv2-common/sources.ts | 24 +++++++++++++++---- src/tv2_afvd_showstyle/parts/evs.ts | 3 ++- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index a6d986078..41b220cef 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -244,6 +244,8 @@ export function MakeContentDVE2< const match = prop.match(/EVS ?(\d+)? ?(.*)/i) as RegExpExecArray boxMap[targetBox - 1] = { source: `EVS${match[1]} ${match[2]}` } + } else if (/EPSIO/.test(prop ?? '')) { + boxMap[targetBox - 1] = { source: 'EPSIO' } } else if (prop?.match(/DEFAULT/)) { boxMap[targetBox - 1] = { source: `DEFAULT SOURCE` } } else if (prop) { @@ -309,7 +311,7 @@ export function MakeContentDVE2< const props = mappingFrom.source.split(' ') const sourceType = props[0] const sourceInput = props[1] - if ((!sourceType || !sourceInput) && !mappingFrom.source.match(/EVS/i) && !mappingFrom.source.match(/SERVER/)) { + if ((!sourceType || !sourceInput) && !mappingFrom.source.match(/EVS|EPSIO|SERVER/i)) { context.notifyUserWarning(`Invalid DVE source: ${mappingFrom.source}`) setBoxToBlack(num) return @@ -327,7 +329,7 @@ export function MakeContentDVE2< }, mappingFrom.source ) - } else if (sourceType.match(/KAM/i)) { + } else if (/KAM/i.test(sourceType)) { const sourceInfoCam = FindSourceInfoStrict(context, config.sources, SourceLayerType.CAMERA, mappingFrom.source) if (sourceInfoCam === undefined) { context.notifyUserWarning(`Invalid source: ${mappingFrom.source}`) @@ -346,7 +348,7 @@ export function MakeContentDVE2< audioEnable ) ) - } else if (sourceType.match(/LIVE/i) || sourceType.match(/FEED/i)) { + } else if (/LIVE|FEED/i.test(sourceType)) { const sourceInfoLive = FindSourceInfoStrict(context, config.sources, SourceLayerType.REMOTE, mappingFrom.source) if (sourceInfoLive === undefined) { context.notifyUserWarning(`Invalid source: ${mappingFrom.source}`) @@ -364,7 +366,7 @@ export function MakeContentDVE2< audioEnable ) ) - } else if (sourceType.match(/EVS/i)) { + } else if (/EVS|EPSIO/.test(sourceType)) { const sourceInfoDelayedPlayback = FindSourceInfoStrict( context, config.sources, @@ -380,10 +382,13 @@ export function MakeContentDVE2< setBoxSource(num, sourceInfoDelayedPlayback, mappingFrom.source) dveTimeline.push( - GetSisyfosTimelineObjForEVS(sourceInfoDelayedPlayback, !!mappingFrom.source.match(/VO/i)), + GetSisyfosTimelineObjForEVS( + sourceInfoDelayedPlayback, + /VO/i.test(mappingFrom.source) || /EPSIO/i.test(sourceInfoDelayedPlayback.id) + ), GetSisyfosTimelineObjForCamera(context, config, 'evs', dveGeneratorOptions.dveLayers.SisyfosLLayer.StudioMics) ) - } else if (sourceType.match(/ENGINE/i)) { + } else if (/ENGINE/i.test(sourceType)) { if (sourceInput.match(/full/i)) { const sourceInfoFull: SourceInfo = { type: SourceLayerType.GRAPHICS, @@ -403,7 +408,7 @@ export function MakeContentDVE2< context.notifyUserWarning(`Unsupported engine for DVE: ${sourceInput}`) setBoxToBlack(num) } - } else if (sourceType.match(/SERVER/i)) { + } else if (/SERVER/i.test(sourceType)) { server = true setBoxSource( num, diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index b4c2a6d19..449e27067 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -107,7 +107,7 @@ export type PartdefinitionTypes = | Pick | Pick -const ACCEPTED_RED_TEXT = /\b(KAM(?:\d+)?|CAM(?:\d+)?|KAMERA(?:\d+)?|CAMERA(?:\d+)?|SERVER|ATTACK|TEKNIK|GRAFIK|EVS ?\d+ ?(?:VOV?)?|VOV?|VOSB)+\b/i +const ACCEPTED_RED_TEXT = /\b(KAM(?:\d+)?|CAM(?:\d+)?|KAMERA(?:\d+)?|CAMERA(?:\d+)?|SERVER|ATTACK|TEKNIK|GRAFIK|EPSIO|EVS ?\d+ ?(?:VOV?)?|VOV?|VOSB)+\b/i const EVS_RED_TEXT = /EVS ?(\d+) ?(VOV?)?/i export function ParseBody( @@ -548,6 +548,15 @@ function extractTypeProperties(typeStr: string): PartdefinitionTypes { }, ...definition } + } else if (/EPSIO/i.test(typeStr)) { + return { + type: PartType.EVS, + variant: { + evs: 'EPSIO', + vo: 'VO' + }, + ...definition + } } else if (/VOV?|VOSB/i.test(firstToken)) { return { type: PartType.VO, diff --git a/src/tv2-common/sources.ts b/src/tv2-common/sources.ts index b063d5c9b..27289158f 100644 --- a/src/tv2-common/sources.ts +++ b/src/tv2-common/sources.ts @@ -95,26 +95,40 @@ export function FindSourceInfo(sources: SourceInfo[], type: SourceInfoType, id: const remoteName = id .replace(/VO/i, '') .replace(/\s/g, '') - .match(/^(?:LIVE|FEED) ?(.+).*$/i) + .match(/^(?:LIVE|FEED) *(.+).*$/i) if (!remoteName) { return undefined } - if (id.match(/^LIVE/i)) { + if (/^LIVE/i.test(id)) { return _.find(sources, s => s.type === type && s.id === remoteName[1]) } else { return _.find(sources, s => s.type === type && s.id === `F${remoteName[1]}`) } case SourceLayerType.LOCAL: - const dpName = id.match(/^(?:EVS)\s*(\d+).*$/i) - if (!dpName) { + const sourceId = getReplaySourceId(id) + if (!sourceId) { return undefined } - return _.find(sources, s => s.type === SourceLayerType.LOCAL && s.id === `DP${dpName[1]}`) + return _.find(sources, s => s.type === SourceLayerType.LOCAL && s.id === sourceId) default: return undefined } } +function getReplaySourceId(id: string): string | undefined { + return getEvsSourceId(id) ?? getEpsioSourceId(id) +} + +function getEvsSourceId(id: string): string | undefined { + const sourceId = id.match(/^EVS *(?\d+).*$/i)?.groups?.id + return sourceId ? `DP${sourceId}` : undefined +} + +function getEpsioSourceId(id: string): string | undefined { + const sourceId = id.match(/^(?EPSIO)$/i)?.groups?.id + return sourceId ? `DP${sourceId}` : undefined +} + export function FindSourceInfoStrict( _context: IStudioContext, sources: SourceInfo[], diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index 041e2e092..a0cf3fa02 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -40,10 +40,11 @@ export async function CreatePartEVS( totalWords: number ): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) + const title = /EPSIO/i.test(partDefinition.variant.evs) ? partDefinition.variant.evs : `EVS ${partDefinition.variant.evs} ${partDefinition.variant.vo ?? ''}` let part = literal({ externalId: partDefinition.externalId, - title: `EVS ${partDefinition.variant.evs} ${partDefinition.variant.vo ?? ''}`, + title, metaData: {}, expectedDuration: partTime > 0 ? partTime : 0 }) From 1bb3bc1230a5199d22f9ae53222d5e0c0817ae40 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 28 Jun 2022 13:40:57 +0200 Subject: [PATCH 139/184] refactor: SOF-854 combine adlib and adlibRank --- src/tv2-common/actions/executeAction.ts | 5 ++-- src/tv2-common/evaluateCues.ts | 16 +++++------ .../helpers/graphics/InternalGraphic.ts | 13 +++++---- .../helpers/graphics/internal/index.ts | 7 +++-- .../helpers/graphics/pilot/index.ts | 15 +++++------ src/tv2-common/helpers/graphics/viz/index.ts | 7 ++--- .../pieces/__tests__/grafikViz.spec.ts | 27 +++++++------------ .../helpers/pieces/graphic.ts | 9 +++---- .../helpers/pieces/graphicPilot.ts | 5 ++-- .../helpers/pieces/telefon.ts | 17 +++--------- .../cues/OfftubeGraphics.ts | 18 +++---------- 11 files changed, 51 insertions(+), 88 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index bfaac005f..f10cfad01 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -1950,9 +1950,8 @@ async function executeActionPlayGraphics< const internalGraphic: InternalGraphic = new InternalGraphic( settings.getConfig(context), userData.graphic, - true, + { rank: 0 }, externalId, - undefined, undefined ) const pieces: IBlueprintPiece[] = [] @@ -2076,7 +2075,7 @@ async function executeActionSelectFull< parsedCue: cue, engine: 'FULL', segmentExternalId: userData.segmentExternalId, - adlib: true + adlib: { rank: 0 } } const fullPiece = CreatePilotPiece({ diff --git a/src/tv2-common/evaluateCues.ts b/src/tv2-common/evaluateCues.ts index 12686f236..6eb710f43 100644 --- a/src/tv2-common/evaluateCues.ts +++ b/src/tv2-common/evaluateCues.ts @@ -32,6 +32,9 @@ import { GraphicIsPilot } from './inewsConversion' +export interface Adlib { + rank: number +} export interface EvaluateCuesShowstyleOptions { EvaluateCueGraphic?: ( config: TV2BlueprintConfig, @@ -41,9 +44,8 @@ export interface EvaluateCuesShowstyleOptions { actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionGraphic, - adlib: boolean, partDefinition: PartDefinition, - rank?: number + adlib?: Adlib ) => void EvaluateCueBackgroundLoop?: ( config: TV2BlueprintConfig, @@ -119,8 +121,7 @@ export interface EvaluateCuesShowstyleOptions { partId: string, partDefinition: PartDefinition, parsedCue: CueDefinitionTelefon, - adlib?: boolean, - rank?: number + adlib?: Adlib ) => void EvaluateCueJingle?: ( context: ISegmentUserContext, @@ -205,6 +206,7 @@ export async function EvaluateCuesBase( for (const cue of cues) { if (cue && !SkipCue(cue, options.selectedCueTypes, options.excludeAdlibs, options.adlibsOnly)) { const shouldAdlib = /* config.showStyle.IsOfftube || */ options.adlib ? true : cue.adlib ? true : false + const adlib = shouldAdlib ? { rank: adLibRank } : undefined switch (cue.type) { case CueType.Graphic: @@ -226,9 +228,8 @@ export async function EvaluateCuesBase( actions, partDefinition.externalId, cue, - shouldAdlib, partDefinition, - adLibRank + adlib ) } break @@ -304,8 +305,7 @@ export async function EvaluateCuesBase( partDefinition.externalId, partDefinition, cue, - shouldAdlib, - adLibRank + adlib ) } break diff --git a/src/tv2-common/helpers/graphics/InternalGraphic.ts b/src/tv2-common/helpers/graphics/InternalGraphic.ts index 153d104fc..856599c89 100644 --- a/src/tv2-common/helpers/graphics/InternalGraphic.ts +++ b/src/tv2-common/helpers/graphics/InternalGraphic.ts @@ -6,6 +6,7 @@ import { PieceLifespan, TSR } from '@tv2media/blueprints-integration' +import { Adlib } from 'tv2-common' import _ = require('underscore') import { AbstractLLayer, @@ -34,7 +35,7 @@ export class InternalGraphic { private readonly config: TV2BlueprintConfig private readonly parsedCue: CueDefinitionGraphic private readonly partDefinition?: PartDefinition - private readonly adlib: boolean + private readonly adlib?: Adlib private readonly isStickyIdent: boolean private readonly engine: GraphicEngine private readonly name: string @@ -47,10 +48,9 @@ export class InternalGraphic { public constructor( config: TV2BlueprintConfig, parsedCue: CueDefinitionGraphic, - adlib: boolean, + adlib?: Adlib, partId?: string, - partDefinition?: PartDefinition, - rank?: number + partDefinition?: PartDefinition ) { const isStickyIdent = IsStickyIdent(parsedCue) @@ -71,7 +71,6 @@ export class InternalGraphic { this.sourceLayerId = sourceLayerId this.outputLayerId = IsTargetingWall(engine) ? SharedOutputLayers.SEC : SharedOutputLayers.OVERLAY this.partId = partId - this.rank = rank this.content = this.getInternalGraphicContent() } @@ -250,7 +249,7 @@ export class InternalGraphic { this.isStickyIdent, this.partDefinition, this.mappedTemplate, - this.adlib + !!this.adlib ) : GetInternalGraphicContentVIZ( this.config, @@ -259,7 +258,7 @@ export class InternalGraphic { this.isStickyIdent, this.partDefinition, this.mappedTemplate, - this.adlib + !!this.adlib ) } } diff --git a/src/tv2-common/helpers/graphics/internal/index.ts b/src/tv2-common/helpers/graphics/internal/index.ts index 813a74c51..19e5b96c4 100644 --- a/src/tv2-common/helpers/graphics/internal/index.ts +++ b/src/tv2-common/helpers/graphics/internal/index.ts @@ -4,7 +4,7 @@ import { IBlueprintPiece, IShowStyleUserContext } from '@tv2media/blueprints-integration' -import { CueDefinitionGraphic, GraphicInternal, PartDefinition, TV2BlueprintConfig } from 'tv2-common' +import { Adlib, CueDefinitionGraphic, GraphicInternal, PartDefinition, TV2BlueprintConfig } from 'tv2-common' import { InternalGraphic } from '../InternalGraphic' export function CreateInternalGraphic( @@ -15,11 +15,10 @@ export function CreateInternalGraphic( actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionGraphic, - adlib: boolean, partDefinition: PartDefinition, - rank?: number + adlib?: Adlib ) { - const internalGraphic: InternalGraphic = new InternalGraphic(config, parsedCue, adlib, partId, partDefinition, rank) + const internalGraphic: InternalGraphic = new InternalGraphic(config, parsedCue, adlib, partId, partDefinition) if (!internalGraphic.mappedTemplate || !internalGraphic.mappedTemplate.length) { context.notifyUserWarning(`No valid template found for ${parsedCue.graphic.template}`) diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index 45b783f42..90762d585 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -10,6 +10,7 @@ import { } from '@tv2media/blueprints-integration' import { ActionSelectFullGrafik, + Adlib, CreateTimingGraphic, CueDefinitionGraphic, generateExternalId, @@ -54,9 +55,8 @@ export interface PilotGraphicProps { partId: string parsedCue: CueDefinitionGraphic settings: PilotGeneratorSettings - adlib: boolean + adlib?: Adlib segmentExternalId: string - adlibRank?: number prerollDuration?: number } @@ -81,7 +81,7 @@ export function CreatePilotGraphic( actions.push(CreatePilotAdLibAction(pilotGraphicProps)) } - if (!(IsTargetingOVL(pilotGraphicProps.engine) && adlib)) { + if (!(IsTargetingOVL(engine) && adlib)) { pieces.push(CreatePilotPiece(pilotGraphicProps)) } @@ -101,7 +101,6 @@ function CreatePilotAdLibAction({ engine, settings, adlib, - adlibRank, segmentExternalId }: PilotGraphicProps) { const name = GraphicDisplayName(config, parsedCue) @@ -120,7 +119,7 @@ function CreatePilotAdLibAction({ userData, userDataManifest: {}, display: { - _rank: adlibRank, + _rank: (adlib && adlib.rank) || 0, label: t(GetFullGraphicTemplateNameFromCue(config, parsedCue)), sourceLayerId: SharedSourceLayers.PgmPilot, outputLayerId: SharedOutputLayers.PGM, @@ -173,8 +172,8 @@ export function CreatePilotPiece({ }) } -export function CreatePilotAdlibPiece(pieceProps: PilotGraphicProps, rank?: number): IBlueprintAdLibPiece { - const pilotPiece = CreatePilotPiece(pieceProps) +export function CreatePilotAdlibPiece(pilotGraphicProps: PilotGraphicProps, rank?: number): IBlueprintAdLibPiece { + const pilotPiece = CreatePilotPiece(pilotGraphicProps) pilotPiece.tags = [...(pilotPiece.tags ?? []), AdlibTags.ADLIB_FLOW_PRODUCER] return { ...pilotPiece, @@ -231,7 +230,7 @@ function CreatePilotContent( settings: PilotGeneratorSettings, cue: CueDefinitionGraphic, engine: GraphicEngine, - adlib: boolean + adlib?: Adlib ): WithTimeline { if (config.studio.GraphicsType === 'HTML') { return GetPilotGraphicContentCaspar(config, context, cue, settings.caspar, engine) diff --git a/src/tv2-common/helpers/graphics/viz/index.ts b/src/tv2-common/helpers/graphics/viz/index.ts index 1a3b38ea9..21138540f 100644 --- a/src/tv2-common/helpers/graphics/viz/index.ts +++ b/src/tv2-common/helpers/graphics/viz/index.ts @@ -6,6 +6,7 @@ import { WithTimeline } from '@tv2media/blueprints-integration' import { + Adlib, CueDefinitionGraphic, findShowId, GetEnableForGraphic, @@ -71,7 +72,7 @@ export function GetPilotGraphicContentViz( settings: VizPilotGeneratorSettings, parsedCue: CueDefinitionGraphic, engine: GraphicEngine, - adlib: boolean + adlib?: Adlib ): WithTimeline { return literal>({ fileName: 'PILOT_' + parsedCue.graphic.vcpid.toString(), @@ -81,7 +82,7 @@ export function GetPilotGraphicContentViz( id: '', enable: IsTargetingOVL(engine) || IsTargetingWall(engine) - ? GetEnableForGraphic(config, engine, parsedCue, false, undefined, adlib) + ? GetEnableForGraphic(config, engine, parsedCue, false, undefined, !!adlib) : { start: 0 }, @@ -110,7 +111,7 @@ export function GetPilotGraphicContentViz( }, ...(IsTargetingFull(engine) ? { classes: ['full'] } : {}) }), - ...(IsTargetingFull(engine) ? settings.createPilotTimelineForStudio(config, context, adlib) : []) + ...(IsTargetingFull(engine) ? settings.createPilotTimelineForStudio(config, context, !!adlib) : []) ] }) } 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 e95be0f64..dafb0212d 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -106,9 +106,8 @@ describe('grafik piece', () => { actions, partId, cue, - cue.adlib ? cue.adlib : false, dummyPart, - 0 + cue.adlib ? { rank: 0 } : undefined ) expect(pieces).toEqual([ literal({ @@ -180,9 +179,8 @@ describe('grafik piece', () => { actions, partId, cue, - cue.adlib ? cue.adlib : false, dummyPart, - 0 + cue.adlib ? { rank: 0 } : undefined ) expect(adLibPieces).toEqual([ literal({ @@ -296,9 +294,8 @@ describe('grafik piece', () => { actions, partId, cue, - cue.adlib ? cue.adlib : false, dummyPart, - 0 + cue.adlib ? { rank: 0 } : undefined ) expect(adLibPieces).toEqual([ literal({ @@ -412,9 +409,8 @@ describe('grafik piece', () => { actions, partId, cue, - cue.adlib ? cue.adlib : false, dummyPart, - 0 + cue.adlib ? { rank: 0 } : undefined ) expect(pieces).toEqual([ literal({ @@ -491,9 +487,8 @@ describe('grafik piece', () => { actions, partId, cue, - cue.adlib ? cue.adlib : false, dummyPart, - 0 + cue.adlib ? { rank: 0 } : undefined ) expect(pieces).toEqual([ literal({ @@ -566,9 +561,8 @@ describe('grafik piece', () => { actions, partId, cue, - cue.adlib ? cue.adlib : false, dummyPart, - 0 + cue.adlib ? { rank: 0 } : undefined ) expect(pieces).toEqual([ literal({ @@ -670,9 +664,8 @@ describe('grafik piece', () => { actions, partId, cue, - cue.adlib ? cue.adlib : false, dummyPart, - 0 + cue.adlib ? { rank: 0 } : undefined ) expect(pieces).toEqual([ literal({ @@ -744,9 +737,8 @@ describe('grafik piece', () => { actions, partId, cue, - cue.adlib ? cue.adlib : false, dummyPart, - 0 + cue.adlib ? { rank: 0 } : undefined ) expect(adLibPieces).toEqual([ literal({ @@ -858,9 +850,8 @@ describe('grafik piece', () => { actions, partId, cue, - cue.adlib ? cue.adlib : false, dummyPart, - 0 + cue.adlib ? { rank: 0 } : undefined ) const piece = pieces[0] expect(piece).toBeTruthy() diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts index 72eb3f665..d570349d6 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts @@ -5,6 +5,7 @@ import { ISegmentUserContext } from '@tv2media/blueprints-integration' import { + Adlib, CreateInternalGraphic, CueDefinitionGraphic, GraphicInternalOrPilot, @@ -24,16 +25,15 @@ export function EvaluateCueGraphic( actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionGraphic, - adlib: boolean, partDefinition: PartDefinition, - rank?: number + adlib?: Adlib ) { if (parsedCue.routing) { EvaluateCueRouting(config, context, pieces, adlibPieces, actions, partId, parsedCue.routing) } if (GraphicIsInternal(parsedCue)) { - CreateInternalGraphic(config, context, pieces, adlibPieces, actions, partId, parsedCue, adlib, partDefinition, rank) + CreateInternalGraphic(config, context, pieces, adlibPieces, actions, partId, parsedCue, partDefinition, adlib) } else if (GraphicIsPilot(parsedCue)) { EvaluateCueGraphicPilot( config, @@ -43,9 +43,8 @@ export function EvaluateCueGraphic( actions, partId, parsedCue, - adlib, partDefinition.segmentExternalId, - rank + adlib ) } } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts index 0a553f71e..fa6ed2ba5 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts @@ -8,6 +8,7 @@ import { TSR } from '@tv2media/blueprints-integration' import { + Adlib, CreatePilotGraphic, CueDefinitionGraphic, EnableDSK, @@ -36,9 +37,8 @@ export function EvaluateCueGraphicPilot( actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionGraphic, - adlib: boolean, segmentExternalId: string, - rank?: number + adlib?: Adlib ) { CreatePilotGraphic(pieces, adlibPieces, actions, { config, @@ -48,7 +48,6 @@ export function EvaluateCueGraphicPilot( parsedCue, settings: pilotGeneratorSettingsAFVD, adlib, - adlibRank: rank ?? 0, segmentExternalId }) } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts index 15c3758df..ef99c0196 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts @@ -6,6 +6,7 @@ import { TSR } from '@tv2media/blueprints-integration' import { + Adlib, CueDefinitionTelefon, GetSisyfosTimelineObjForCamera, GraphicDisplayName, @@ -25,22 +26,10 @@ export function EvaluateTelefon( partId: string, partDefinition: PartDefinition, parsedCue: CueDefinitionTelefon, - adlib?: boolean, - rank?: number + adlib?: Adlib ) { if (parsedCue.graphic) { - EvaluateCueGraphic( - config, - context, - pieces, - adlibPieces, - actions, - partId, - parsedCue.graphic, - !!adlib, - partDefinition, - rank - ) + EvaluateCueGraphic(config, context, pieces, adlibPieces, actions, partId, parsedCue.graphic, partDefinition, adlib) if ((!adlib && pieces.length) || (adlib && adlibPieces.length)) { if (!adlib) { diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts index 3d22b63bf..b45aa83c7 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts @@ -6,6 +6,7 @@ import { TSR } from '@tv2media/blueprints-integration' import { + Adlib, CreateInternalGraphic, CreatePilotGraphic, CueDefinitionGraphic, @@ -38,9 +39,8 @@ export function OfftubeEvaluateGrafikCaspar( actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionGraphic, - adlib: boolean, partDefinition: PartDefinition, - adlibRank?: number + adlib?: Adlib ) { if (GraphicIsPilot(parsedCue)) { CreatePilotGraphic(pieces, adlibPieces, actions, { @@ -51,22 +51,10 @@ export function OfftubeEvaluateGrafikCaspar( parsedCue, settings: pilotGeneratorSettingsOfftube, adlib, - adlibRank, segmentExternalId: partDefinition.segmentExternalId }) } else if (GraphicIsInternal(parsedCue)) { - CreateInternalGraphic( - config, - context, - pieces, - adlibPieces, - actions, - partId, - parsedCue, - adlib, - partDefinition, - adlibRank - ) + CreateInternalGraphic(config, context, pieces, adlibPieces, actions, partId, parsedCue, partDefinition, adlib) } } From 7366e0f80ff21843990cb05716c68092b266ad94 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 28 Jun 2022 13:52:56 +0200 Subject: [PATCH 140/184] refactor: SOF-854 combine if statements --- src/tv2-common/helpers/graphics/pilot/index.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index 90762d585..85d925c80 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -77,19 +77,14 @@ export function CreatePilotGraphic( return } - if (IsTargetingFull(engine)) { - actions.push(CreatePilotAdLibAction(pilotGraphicProps)) - } - - if (!(IsTargetingOVL(engine) && adlib)) { - pieces.push(CreatePilotPiece(pilotGraphicProps)) - } - if (IsTargetingOVL(engine) && adlib) { adlibPieces.push(CreatePilotAdlibPiece(pilotGraphicProps)) + } else { + pieces.push(CreatePilotPiece(pilotGraphicProps)) } if (IsTargetingFull(engine)) { + actions.push(CreatePilotAdLibAction(pilotGraphicProps)) pieces.push(CreateFullDataStore(pilotGraphicProps)) } } From 234e47f5365447369b4dd902d573b3b2c8fc26e6 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 29 Jun 2022 10:44:43 +0200 Subject: [PATCH 141/184] refactor: SOF-854 convert Pilot creation into a class --- src/tv2-common/actions/executeAction.ts | 19 +- .../helpers/graphics/pilot/index.ts | 323 +++++++++--------- 2 files changed, 170 insertions(+), 172 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index f10cfad01..5db6a3acb 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -34,7 +34,6 @@ import { ActionSelectServerClip, CalculateTime, CreatePartServerBase, - CreatePilotPiece, CueDefinition, CueDefinitionDVE, CueDefinitionGraphic, @@ -73,11 +72,10 @@ import { import _ = require('underscore') import { EnableServer } from '../content' import { - CreateFullDataStore, GetEnableForWall, getServerPosition, PilotGeneratorSettings, - PilotGraphicProps, + PilotGraphicGenerator, ServerSelectMode } from '../helpers' import { InternalGraphic } from '../helpers/graphics/InternalGraphic' @@ -2036,8 +2034,6 @@ async function executeActionSelectFull< const externalId = `adlib-action_${context.getHashId(`cut_to_full_${template}`)}` const graphicType = config.studio.GraphicsType - const prerollDuration = - graphicType === 'HTML' ? config.studio.CasparPrerollDuration : config.studio.VizPilotGraphics.OutTransitionDuration const previousPartKeepaliveDuration = graphicType === 'HTML' ? config.studio.HTMLGraphics.KeepAliveDuration @@ -2067,7 +2063,7 @@ async function executeActionSelectFull< iNewsCommand: '' }) - const graphicProps: PilotGraphicProps = { + const generator = new PilotGraphicGenerator({ config, context, partId: externalId, @@ -2076,20 +2072,17 @@ async function executeActionSelectFull< engine: 'FULL', segmentExternalId: userData.segmentExternalId, adlib: { rank: 0 } - } - - const fullPiece = CreatePilotPiece({ - ...graphicProps, - prerollDuration }) + const fullPiece = generator.createPiece() + settings.postProcessPieceTimelineObjects(context, config, fullPiece, false) - const fullDataStore = CreateFullDataStore(graphicProps) + const fullDataStore = generator.createFullDataStore() await context.queuePart(part, [ fullPiece, - ...(fullDataStore ? [fullDataStore] : []), + fullDataStore, ...(await getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, [ SharedSourceLayers.SelectedAdlibGraphicsFull ])) diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index 85d925c80..18884c8cb 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -57,7 +57,6 @@ export interface PilotGraphicProps { settings: PilotGeneratorSettings adlib?: Adlib segmentExternalId: string - prerollDuration?: number } export function CreatePilotGraphic( @@ -77,179 +76,185 @@ export function CreatePilotGraphic( return } + const generator = new PilotGraphicGenerator(pilotGraphicProps) + if (IsTargetingOVL(engine) && adlib) { - adlibPieces.push(CreatePilotAdlibPiece(pilotGraphicProps)) + adlibPieces.push(generator.createAdlibPiece()) } else { - pieces.push(CreatePilotPiece(pilotGraphicProps)) + pieces.push(generator.createPiece()) } if (IsTargetingFull(engine)) { - actions.push(CreatePilotAdLibAction(pilotGraphicProps)) - pieces.push(CreateFullDataStore(pilotGraphicProps)) + actions.push(generator.createPilotAdLibAction()) + pieces.push(generator.createFullDataStore()) } } -function CreatePilotAdLibAction({ - config, - context, - parsedCue, - engine, - settings, - adlib, - segmentExternalId -}: PilotGraphicProps) { - const name = GraphicDisplayName(config, parsedCue) - const sourceLayerId = GetSourceLayer(engine) - const outputLayerId = GetOutputLayer(engine) - - const userData = literal({ - type: AdlibActionType.SELECT_FULL_GRAFIK, - name: parsedCue.graphic.name, - vcpid: parsedCue.graphic.vcpid, - segmentExternalId - }) - return literal({ - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.SELECT_FULL_GRAFIK, - userData, - userDataManifest: {}, - display: { - _rank: (adlib && adlib.rank) || 0, - label: t(GetFullGraphicTemplateNameFromCue(config, parsedCue)), - sourceLayerId: SharedSourceLayers.PgmPilot, - outputLayerId: SharedOutputLayers.PGM, - content: CreatePilotContent(config, context, settings, parsedCue, engine, adlib), - uniquenessId: `gfx_${name}_${sourceLayerId}_${outputLayerId}`, - tags: [ - AdlibTags.ADLIB_KOMMENTATOR, - ...(config.showStyle.MakeAdlibsForFulls && IsTargetingFull(engine) ? [AdlibTags.ADLIB_FLOW_PRODUCER] : []) - ], - currentPieceTags: [GetTagForFull(segmentExternalId, parsedCue.graphic.vcpid)], - nextPieceTags: [GetTagForFullNext(segmentExternalId, parsedCue.graphic.vcpid)] - } - }) -} +export class PilotGraphicGenerator { + private readonly config: TV2BlueprintConfig + private readonly context: IShowStyleUserContext + private readonly engine: GraphicEngine + private readonly partId: string + private readonly parsedCue: CueDefinitionGraphic + private readonly settings: PilotGeneratorSettings + private readonly adlib?: Adlib + private readonly segmentExternalId: string -export function CreatePilotPiece({ - config, - context, - partId, - parsedCue, - engine, - settings, - adlib, - segmentExternalId, - prerollDuration -}: PilotGraphicProps): IBlueprintPiece { - return literal({ - externalId: partId, - name: GraphicDisplayName(config, parsedCue), - ...(IsTargetingFull(engine) || IsTargetingWall(engine) - ? { enable: { start: 0 } } - : { - enable: { - ...CreateTimingGraphic(config, parsedCue) - } - }), - outputLayerId: GetOutputLayer(engine), - sourceLayerId: GetSourceLayer(engine), - prerollDuration: prerollDuration ?? config.studio.VizPilotGraphics.PrerollDuration, - lifespan: GetInfiniteModeForGraphic(engine, config, parsedCue), - metaData: literal({ - sisyfosPersistMetaData: { - sisyfosLayers: [] - } - }), - content: CreatePilotContent(config, context, settings, parsedCue, engine, adlib), - tags: IsTargetingFull(engine) - ? [GetTagForFull(segmentExternalId, parsedCue.graphic.vcpid), TallyTags.FULL_IS_LIVE] - : [] - }) -} + constructor(graphicProps: PilotGraphicProps) { + this.config = graphicProps.config + this.context = graphicProps.context + this.engine = graphicProps.engine + this.parsedCue = graphicProps.parsedCue + this.settings = graphicProps.settings + this.adlib = graphicProps.adlib + this.segmentExternalId = graphicProps.segmentExternalId + } + + public createPilotAdLibAction() { + const name = GraphicDisplayName(this.config, this.parsedCue) + const sourceLayerId = this.getSourceLayer() + const outputLayerId = this.getOutputLayer() -export function CreatePilotAdlibPiece(pilotGraphicProps: PilotGraphicProps, rank?: number): IBlueprintAdLibPiece { - const pilotPiece = CreatePilotPiece(pilotGraphicProps) - pilotPiece.tags = [...(pilotPiece.tags ?? []), AdlibTags.ADLIB_FLOW_PRODUCER] - return { - ...pilotPiece, - _rank: rank ?? 0 + const userData = literal({ + type: AdlibActionType.SELECT_FULL_GRAFIK, + name: this.parsedCue.graphic.name, + vcpid: this.parsedCue.graphic.vcpid, + segmentExternalId: this.segmentExternalId + }) + return literal({ + 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.createContent(), + 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)] + } + }) } -} -export function CreateFullDataStore({ - config, - context, - partId, - parsedCue, - engine, - settings, - adlib, - segmentExternalId -}: PilotGraphicProps): IBlueprintPiece { - const content = CreatePilotContent(config, context, settings, parsedCue, engine, adlib) - 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 literal({ - externalId: partId, - name: GraphicDisplayName(config, parsedCue), - enable: { - start: 0 - }, - outputLayerId: SharedOutputLayers.SELECTED_ADLIB, - sourceLayerId: SharedSourceLayers.SelectedAdlibGraphicsFull, - lifespan: PieceLifespan.OutOnSegmentEnd, - metaData: { - userData: literal({ - type: AdlibActionType.SELECT_FULL_GRAFIK, - name: parsedCue.graphic.name, - vcpid: parsedCue.graphic.vcpid, - segmentExternalId + public createPiece(): IBlueprintPiece { + return literal({ + 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: GetInfiniteModeForGraphic(this.engine, this.config, this.parsedCue), + metaData: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } }), - sisyfosPersistMetaData: literal({ - sisyfosLayers: [] - }) - }, - content, - tags: [GetTagForFullNext(segmentExternalId, parsedCue.graphic.vcpid)] - }) -} + content: this.createContent(), + tags: IsTargetingFull(this.engine) + ? [GetTagForFull(this.segmentExternalId, this.parsedCue.graphic.vcpid), TallyTags.FULL_IS_LIVE] + : [] + }) + } -function CreatePilotContent( - config: TV2BlueprintConfig, - context: IShowStyleUserContext, - settings: PilotGeneratorSettings, - cue: CueDefinitionGraphic, - engine: GraphicEngine, - adlib?: Adlib -): WithTimeline { - if (config.studio.GraphicsType === 'HTML') { - return GetPilotGraphicContentCaspar(config, context, cue, settings.caspar, engine) - } else { - return GetPilotGraphicContentViz(config, context, settings.viz, cue, engine, adlib) + public createAdlibPiece(rank?: number): IBlueprintAdLibPiece { + const pilotPiece = this.createPiece() + pilotPiece.tags = [...(pilotPiece.tags ?? []), AdlibTags.ADLIB_FLOW_PRODUCER] + return { + ...pilotPiece, + _rank: rank ?? 0 + } } -} -function GetSourceLayer(engine: GraphicEngine): SharedSourceLayers { - return IsTargetingWall(engine) - ? SharedSourceLayers.WallGraphics - : IsTargetingTLF(engine) - ? SharedSourceLayers.PgmGraphicsTLF - : IsTargetingOVL(engine) - ? SharedSourceLayers.PgmPilotOverlay - : SharedSourceLayers.PgmPilot -} + public createFullDataStore(): IBlueprintPiece { + const content = this.createContent() + 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 literal({ + externalId: this.partId, + name: GraphicDisplayName(this.config, this.parsedCue), + enable: { + start: 0 + }, + outputLayerId: SharedOutputLayers.SELECTED_ADLIB, + sourceLayerId: SharedSourceLayers.SelectedAdlibGraphicsFull, + lifespan: PieceLifespan.OutOnSegmentEnd, + metaData: { + userData: literal({ + 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)] + }) + } + + private createContent(): WithTimeline { + if (this.config.studio.GraphicsType === 'HTML') { + return GetPilotGraphicContentCaspar(this.config, this.context, this.parsedCue, this.settings.caspar, this.engine) + } else { + return GetPilotGraphicContentViz( + this.config, + this.context, + this.settings.viz, + this.parsedCue, + this.engine, + this.adlib + ) + } + } + + private getPrerollDuration(): number { + return this.config.studio.GraphicsType === 'HTML' + ? this.config.studio.CasparPrerollDuration + : this.config.studio.VizPilotGraphics.PrerollDuration + } -function GetOutputLayer(engine: GraphicEngine) { - return IsTargetingWall(engine) - ? SharedOutputLayers.SEC - : IsTargetingOVL(engine) - ? SharedOutputLayers.OVERLAY - : IsTargetingFull(engine) - ? SharedOutputLayers.PGM - : SharedOutputLayers.OVERLAY + private getSourceLayer(): SharedSourceLayers { + const engine = this.engine + return IsTargetingWall(engine) + ? SharedSourceLayers.WallGraphics + : IsTargetingTLF(engine) + ? SharedSourceLayers.PgmGraphicsTLF + : IsTargetingOVL(engine) + ? SharedSourceLayers.PgmPilotOverlay + : SharedSourceLayers.PgmPilot + } + + private getOutputLayer() { + const engine = this.engine + return IsTargetingWall(engine) + ? SharedOutputLayers.SEC + : IsTargetingOVL(engine) + ? SharedOutputLayers.OVERLAY + : IsTargetingFull(engine) + ? SharedOutputLayers.PGM + : SharedOutputLayers.OVERLAY + } } From 24fc5718aeda01c388a14753e49c3669c5fd727a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Wed, 29 Jun 2022 13:47:45 +0200 Subject: [PATCH 142/184] feat(SOF-981): Created sisyfos source layers for EPSIO. Configuration is still missing. --- src/tv2-common/layers/timelineLayers.ts | 3 +++ src/tv2_afvd_studio/layers.ts | 3 ++- src/tv2_afvd_studio/sisyfosChannels.ts | 10 ++++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/tv2-common/layers/timelineLayers.ts b/src/tv2-common/layers/timelineLayers.ts index 80183b873..041fe55f2 100644 --- a/src/tv2-common/layers/timelineLayers.ts +++ b/src/tv2-common/layers/timelineLayers.ts @@ -4,6 +4,9 @@ import { ATEMModel } from '../../types/atem' import { GetDSKCount } from '../helpers' export function SisyfosEVSSource(i: number | string) { + if (i.toString().toLowerCase() === 'epsio') { + return 'sisyfos_source_epsio' + } return `sisyfos_source_evs_${i}` } diff --git a/src/tv2_afvd_studio/layers.ts b/src/tv2_afvd_studio/layers.ts index e13eb34ff..e87b2bf41 100644 --- a/src/tv2_afvd_studio/layers.ts +++ b/src/tv2_afvd_studio/layers.ts @@ -122,7 +122,8 @@ enum AFVDSisyfosLLAyer { SisyfosSourceServerB = 'sisyfos_source_server_b', // SisyfosSourceServerC = 'sisyfos_source_server_c', SisyfosSourceEVS_1 = 'sisyfos_source_evs_1', - SisyfosSourceEVS_2 = 'sisyfos_source_evs_2' + SisyfosSourceEVS_2 = 'sisyfos_source_evs_2', + SisyfosSourceEpsio = 'sisyfos_source_epsio', } // tslint:disable-next-line: variable-name diff --git a/src/tv2_afvd_studio/sisyfosChannels.ts b/src/tv2_afvd_studio/sisyfosChannels.ts index b24b1818c..b2a44ae5d 100644 --- a/src/tv2_afvd_studio/sisyfosChannels.ts +++ b/src/tv2_afvd_studio/sisyfosChannels.ts @@ -1,4 +1,3 @@ -import { SisyfosEVSSource } from 'tv2-common' import { SisyfosLLAyer } from './layers' export interface SisyfosChannel { @@ -86,10 +85,10 @@ export const sisyfosChannels: { [key in SisyfosLLAyer]?: SisyfosChannel } = { [SisyfosLLAyer.SisyfosSourceServerB]: { isPgm: 0 }, - [SisyfosEVSSource('1')]: { + [SisyfosLLAyer.SisyfosSourceEVS_1]: { isPgm: 0 }, - [SisyfosEVSSource('2')]: { + [SisyfosLLAyer.SisyfosSourceEVS_2]: { isPgm: 0 }, [SisyfosLLAyer.SisyfosSourceJingle]: { @@ -100,5 +99,8 @@ export const sisyfosChannels: { [key in SisyfosLLAyer]?: SisyfosChannel } = { }, [SisyfosLLAyer.SisyfosSourceTLF]: { isPgm: 0 - } + }, + [SisyfosLLAyer.SisyfosSourceEpsio]: { + isPgm: 0 + }, } From 9ff4706f99b10026d613471363214f729a7e1f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Wed, 29 Jun 2022 14:52:47 +0200 Subject: [PATCH 143/184] chore: Added default values and migration. Added default values and migration for EVS mapping and sisyfos source layer. --- package.json | 2 +- src/tv2-common/content/dve.ts | 2 +- src/tv2-common/migrations/index.ts | 23 ++++++++++++++++++- src/tv2_afvd_studio/config-manifests.ts | 7 ++++++ src/tv2_afvd_studio/migrations/index.ts | 8 +++++++ .../migrations/mappings-defaults.ts | 9 ++++++++ 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 343752739..85e1f9282 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tv2-sofie-blueprints-inews", - "version": "1.7.3", + "version": "1.7.4", "repository": "https://github.com/olzzon/tv2-sofie-blueprints-inews", "license": "MIT", "private": true, diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 41b220cef..30602309a 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -384,7 +384,7 @@ export function MakeContentDVE2< dveTimeline.push( GetSisyfosTimelineObjForEVS( sourceInfoDelayedPlayback, - /VO/i.test(mappingFrom.source) || /EPSIO/i.test(sourceInfoDelayedPlayback.id) + /VO|EPSIO/i.test(mappingFrom.source) ), GetSisyfosTimelineObjForCamera(context, config, 'evs', dveGeneratorOptions.dveLayers.SisyfosLLayer.StudioMics) ) diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index 443611804..52ddedc57 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -7,7 +7,7 @@ import { MigrationStepStudio, TableConfigItemValue } from '@tv2media/blueprints-integration' -import { TableConfigItemGFXTemplates } from 'tv2-common' +import { TableConfigItemGFXTemplates, TableConfigItemSourceMappingWithSisyfos } from 'tv2-common' import _ = require('underscore') import { literal } from '../util' @@ -121,6 +121,27 @@ export function AddGraphicToGFXTable(versionStr: string, studio: string, config: }) } +export function addSourceToSourcesConfig(versionStr: string, studio: string, configId: string, source: TableConfigItemSourceMappingWithSisyfos) { + return literal({ + id: `${versionStr}.studioConfig.addReplaySource.${source.SourceName}.${studio}`, + version: versionStr, + canBeRunAutomatically: true, + validate: (context: MigrationContextStudio) => { + const config = context.getConfig(configId) as unknown as TableConfigItemSourceMappingWithSisyfos[] + + if (!config) { + return false + } + return !config.find((s) => s.SourceName === source.SourceName) + }, + migrate: (context: MigrationContextStudio) => { + const config = context.getConfig(configId) as unknown as TableConfigItemSourceMappingWithSisyfos[] + config.push(source) + context.setConfig(configId, config as unknown as ConfigItemValue) + } + }) +} + export function changeGFXTemplate( versionStr: string, studio: string, diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index 13bec9dc2..1268b718e 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -210,6 +210,13 @@ export const manifestAFVDSourcesDelayedPlayback = MakeConfigForSources('DelayedP AtemSource: 23, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceEVS_2], StudioMics: true + }, + { + _id: '', + SourceName: 'EPSIO', + AtemSource: 30, + SisyfosLayers: [SisyfosLLAyer.SisyfosSourceEpsio], + StudioMics: true } ]) diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index c7d0bec60..46273bac6 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -1,6 +1,7 @@ import { MigrationStepStudio, TSR } from '@tv2media/blueprints-integration' import { AddKeepAudio, + addSourceToSourcesConfig, literal, MoveClipSourcePath, MoveSourcesToTable, @@ -183,6 +184,13 @@ export const studioMigrations: MigrationStepStudio[] = literal({ + device: TSR.DeviceType.SISYFOS, + deviceId: 'sisyfos0', + layerName: 'EPSIO', + channel: 29, + lookahead: LookaheadMode.NONE, + mappingType: TSR.MappingSisyfosType.CHANNEL, + setLabelToLayerName: true + }), [SisyfosLLAyer.SisyfosResync]: literal({ device: TSR.DeviceType.SISYFOS, deviceId: 'sisyfos0', From a5d85405397c51e5236822085690655a7f53f814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Thu, 30 Jun 2022 10:47:54 +0200 Subject: [PATCH 144/184] lint: Prettier ran on files. --- src/tv2-common/content/dve.ts | 5 +---- src/tv2-common/migrations/index.ts | 15 ++++++++++----- src/tv2_afvd_showstyle/parts/evs.ts | 4 +++- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 30602309a..5f9bd975b 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -382,10 +382,7 @@ export function MakeContentDVE2< setBoxSource(num, sourceInfoDelayedPlayback, mappingFrom.source) dveTimeline.push( - GetSisyfosTimelineObjForEVS( - sourceInfoDelayedPlayback, - /VO|EPSIO/i.test(mappingFrom.source) - ), + GetSisyfosTimelineObjForEVS(sourceInfoDelayedPlayback, /VO|EPSIO/i.test(mappingFrom.source)), GetSisyfosTimelineObjForCamera(context, config, 'evs', dveGeneratorOptions.dveLayers.SisyfosLLayer.StudioMics) ) } else if (/ENGINE/i.test(sourceType)) { diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index 52ddedc57..4651c444b 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -121,23 +121,28 @@ export function AddGraphicToGFXTable(versionStr: string, studio: string, config: }) } -export function addSourceToSourcesConfig(versionStr: string, studio: string, configId: string, source: TableConfigItemSourceMappingWithSisyfos) { +export function addSourceToSourcesConfig( + versionStr: string, + studio: string, + configId: string, + source: TableConfigItemSourceMappingWithSisyfos +) { return literal({ id: `${versionStr}.studioConfig.addReplaySource.${source.SourceName}.${studio}`, 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) } }) } diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index a0cf3fa02..bbc920072 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -40,7 +40,9 @@ export async function CreatePartEVS( totalWords: number ): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) - const title = /EPSIO/i.test(partDefinition.variant.evs) ? partDefinition.variant.evs : `EVS ${partDefinition.variant.evs} ${partDefinition.variant.vo ?? ''}` + const title = /EPSIO/i.test(partDefinition.variant.evs) + ? partDefinition.variant.evs + : `EVS ${partDefinition.variant.evs} ${partDefinition.variant.vo ?? ''}` let part = literal({ externalId: partDefinition.externalId, From 4db40f94588c187c6f22f0db3a43fb1f5dbbba98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Thu, 30 Jun 2022 10:49:04 +0200 Subject: [PATCH 145/184] feat(SOF-982): Created adlibs and shortcuts for EPSIO. --- src/tv2-common/helpers/adLibNames.ts | 9 +++++++++ src/tv2-common/hotkeys/hotkey-defaults.ts | 4 ++-- src/tv2_afvd_showstyle/getRundown.ts | 12 +++++++---- src/tv2_afvd_showstyle/migrations/index.ts | 23 +++++++++++----------- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/tv2-common/helpers/adLibNames.ts b/src/tv2-common/helpers/adLibNames.ts index 0b190dfda..875a361d0 100644 --- a/src/tv2-common/helpers/adLibNames.ts +++ b/src/tv2-common/helpers/adLibNames.ts @@ -1,11 +1,20 @@ export function localSourceFullAudioName(source: string) { + if (/EPSIO/i.test(source)) { + return source + } return `EVS ${source} 100%` } export function localSourceVoAudioName(source: string) { + if (/EPSIO/i.test(source)) { + return source + } return `EVS ${source} VO` } export function localSourceName(source: string, vo: boolean) { + if (/EPSIO/i.test(source)) { + return source + } return vo ? localSourceVoAudioName(source) : localSourceFullAudioName(source) } diff --git a/src/tv2-common/hotkeys/hotkey-defaults.ts b/src/tv2-common/hotkeys/hotkey-defaults.ts index bdef58820..9976c28d6 100644 --- a/src/tv2-common/hotkeys/hotkey-defaults.ts +++ b/src/tv2-common/hotkeys/hotkey-defaults.ts @@ -102,8 +102,8 @@ export const defaultHotkeys: TV2Hotkeys = { }, voAudio: { directCut: [], - queue: ['KeyE', 'KeyU'], - cutToBox: [['Shift+KeyE', 'Shift+KeyU'], ['Ctrl+KeyE', 'Ctrl+KeyU'], ['Alt+Shift+KeyE', 'Alt+Shift+KeyU'], []], + queue: ['KeyE', 'KeyU', 'KeyP'], + cutToBox: [['Shift+KeyE', 'Shift+KeyU', 'Shift+KeyP'], ['Ctrl+KeyE', 'Ctrl+KeyU', 'Ctrl+KeyP'], ['Alt+Shift+KeyE', 'Alt+Shift+KeyU', 'Alt+Shift+KeyP'], []], routeToGraphicsEngine: [], routeToStudioScreen: [] } diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 39c89a481..612b534cf 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -259,7 +259,9 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint config.sources .filter(u => u.type === SourceLayerType.LOCAL) .forEach(o => { - adlibItems.push(...makeEVSAdLibs(o, globalRank++, false)) + if (!/EPSIO/i.test(o.id)) { + adlibItems.push(...makeEVSAdLibs(o, globalRank++, false)) + } adlibItems.push(...makeEVSAdLibs(o, globalRank++, true)) adlibItems.push({ externalId: 'delayedaux', @@ -587,7 +589,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri } } - function makeAdlibBoxesActionsDirectPlayback(info: SourceInfo, vo: boolean, rank: number) { + function makeAdlibBoxesActionsReplay(info: SourceInfo, rank: number, vo: boolean) { for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { const evsId = info.id.replace(/dp/i, '') const userData = literal({ @@ -725,8 +727,10 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri .filter(u => u.type === SourceLayerType.LOCAL) .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from .forEach(o => { - makeAdlibBoxesActionsDirectPlayback(o, false, globalRank++) - makeAdlibBoxesActionsDirectPlayback(o, true, globalRank++) + if (!/EPSIO/i.test(o.id)) { + makeAdlibBoxesActionsReplay(o, globalRank++, false) + } + makeAdlibBoxesActionsReplay(o, globalRank++, true) }) makeServerAdlibBoxesActions(globalRank++) diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 31ebbdafe..4cd3ae33f 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -188,18 +188,6 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal Date: Thu, 30 Jun 2022 10:55:13 +0200 Subject: [PATCH 146/184] lint: Prettier lint-fix. --- src/tv2-common/hotkeys/hotkey-defaults.ts | 7 ++++++- src/tv2_afvd_studio/layers.ts | 2 +- src/tv2_afvd_studio/sisyfosChannels.ts | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/tv2-common/hotkeys/hotkey-defaults.ts b/src/tv2-common/hotkeys/hotkey-defaults.ts index 9976c28d6..04566937e 100644 --- a/src/tv2-common/hotkeys/hotkey-defaults.ts +++ b/src/tv2-common/hotkeys/hotkey-defaults.ts @@ -103,7 +103,12 @@ export const defaultHotkeys: TV2Hotkeys = { voAudio: { directCut: [], queue: ['KeyE', 'KeyU', 'KeyP'], - cutToBox: [['Shift+KeyE', 'Shift+KeyU', 'Shift+KeyP'], ['Ctrl+KeyE', 'Ctrl+KeyU', 'Ctrl+KeyP'], ['Alt+Shift+KeyE', 'Alt+Shift+KeyU', 'Alt+Shift+KeyP'], []], + cutToBox: [ + ['Shift+KeyE', 'Shift+KeyU', 'Shift+KeyP'], + ['Ctrl+KeyE', 'Ctrl+KeyU', 'Ctrl+KeyP'], + ['Alt+Shift+KeyE', 'Alt+Shift+KeyU', 'Alt+Shift+KeyP'], + [] + ], routeToGraphicsEngine: [], routeToStudioScreen: [] } diff --git a/src/tv2_afvd_studio/layers.ts b/src/tv2_afvd_studio/layers.ts index e87b2bf41..55a5b00cf 100644 --- a/src/tv2_afvd_studio/layers.ts +++ b/src/tv2_afvd_studio/layers.ts @@ -123,7 +123,7 @@ enum AFVDSisyfosLLAyer { // SisyfosSourceServerC = 'sisyfos_source_server_c', SisyfosSourceEVS_1 = 'sisyfos_source_evs_1', SisyfosSourceEVS_2 = 'sisyfos_source_evs_2', - SisyfosSourceEpsio = 'sisyfos_source_epsio', + SisyfosSourceEpsio = 'sisyfos_source_epsio' } // tslint:disable-next-line: variable-name diff --git a/src/tv2_afvd_studio/sisyfosChannels.ts b/src/tv2_afvd_studio/sisyfosChannels.ts index b2a44ae5d..7dc2d5291 100644 --- a/src/tv2_afvd_studio/sisyfosChannels.ts +++ b/src/tv2_afvd_studio/sisyfosChannels.ts @@ -102,5 +102,5 @@ export const sisyfosChannels: { [key in SisyfosLLAyer]?: SisyfosChannel } = { }, [SisyfosLLAyer.SisyfosSourceEpsio]: { isPgm: 0 - }, + } } From 2c3361e1d1d14fd1b8236ed050c5da263ff76a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Thu, 30 Jun 2022 14:16:31 +0200 Subject: [PATCH 147/184] feature: SOF-985 Blueprints now support making Dip transitions --- .../__tests__/transitionSettings.spec.ts | 173 ++++++++++++++++++ src/tv2-common/actions/actionTypes.ts | 8 +- src/tv2-common/actions/executeAction.ts | 117 +++++++++--- src/tv2-common/blueprintConfig.ts | 1 + src/tv2-common/content/server.ts | 2 +- src/tv2-common/cues/ekstern.ts | 4 +- .../__tests__/rundownAdLibActions.spec.ts | 149 ++++++--------- src/tv2-common/helpers/rundownAdLibActions.ts | 61 +++--- src/tv2-common/parts/effekt.ts | 98 +++++++--- src/tv2-common/pieces/tags.ts | 1 + src/tv2-common/transitionSettings.ts | 50 +++-- src/tv2_afvd_showstyle/__tests__/configs.ts | 3 +- src/tv2_afvd_showstyle/parts/evs.ts | 2 +- src/tv2_afvd_showstyle/parts/kam.ts | 4 +- .../__tests__/config-manifest.spec.ts | 3 +- src/tv2_afvd_studio/config-manifests.ts | 8 + src/tv2_afvd_studio/helpers/config.ts | 1 + src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 4 +- .../__tests__/config-manifest.spec.ts | 3 +- src/tv2_offtube_studio/config-manifests.ts | 8 + src/tv2_offtube_studio/helpers/config.ts | 1 + 21 files changed, 506 insertions(+), 195 deletions(-) create mode 100644 src/tv2-common/__tests__/transitionSettings.spec.ts diff --git a/src/tv2-common/__tests__/transitionSettings.spec.ts b/src/tv2-common/__tests__/transitionSettings.spec.ts new file mode 100644 index 000000000..715ea794a --- /dev/null +++ b/src/tv2-common/__tests__/transitionSettings.spec.ts @@ -0,0 +1,173 @@ +import { AtemTransitionSettings } from '../../../../tv-automation-state-timeline-resolver/packages/timeline-state-resolver-types/src' +import { PartType } from '../../tv2-constants' +import { AtemSourceIndex } from '../../types/atem' +import { TV2BlueprintConfig, TV2BlueprintConfigBase, TV2StudioConfigBase } from '../blueprintConfig' +import { PartDefinition, PartTransition } from '../inewsConversion' +import { TransitionSettings } from '../transitionSettings' + +const DURATION: number = 50 + +const WIPE_STYLE: string = 'WIPE' +const MIX_STYLE: string = 'MIX' +const DIP_STYLE: string = 'DIP' + +describe('transitionsSettingsSuite', () => { + let mockConfig: TV2BlueprintConfig + + beforeEach(() => { + mockConfig = ({} as any) as TV2BlueprintConfig + }) + + 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: 'randomStyle' + } + 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: WIPE_STYLE.toString(), + duration: DURATION + } + const partDefinition: PartDefinition = createPartDefinition(transition) + + const result = TransitionSettings(mockConfig, partDefinition) + const expectedResult: AtemTransitionSettings = { + wipe: { + rate: DURATION + } + } + expect(result).toEqual(expectedResult) + }) + + it('should return Mix when transition is style Mix', () => { + const transition: PartTransition = { + style: MIX_STYLE, + duration: DURATION + } + const partDefinition: PartDefinition = createPartDefinition(transition) + + const result = TransitionSettings(mockConfig, partDefinition) + const expectedResult: AtemTransitionSettings = { + mix: { + rate: DURATION + } + } + expect(result).toEqual(expectedResult) + }) + + it('should return Dip when style is Dip', () => { + const transition: PartTransition = { + style: DIP_STYLE, + duration: DURATION + } + const partDefinition: PartDefinition = createPartDefinition(transition) + + const result = TransitionSettings(mockConfig, partDefinition) + const expectedResult: 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: DIP_STYLE, + duration: DURATION + } + const partDefinition: PartDefinition = createPartDefinition(transition) + + const result = TransitionSettings(mockConfig, partDefinition) + const expectedResult: 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.Ekstern, + variant: {}, + script: '', + fields: {}, + modified: 123, + storyName: 'someName', + segmentExternalId: `segmentExternalId_${Math.random() * 1000}`, + rawType: '', + transition + } +} + +function assertDipInputValueFromConfig( + mockConfig: TV2BlueprintConfigBase, + dipInputSource: number +) { + mockConfig.studio = ({ + AtemSource: createAtemSourceConfig(dipInputSource) + } as any) as TV2StudioConfigBase + const transition: PartTransition = { + style: DIP_STYLE, + duration: DURATION + } + const partDefinition: PartDefinition = createPartDefinition(transition) + + const result = TransitionSettings(mockConfig, partDefinition) + const expectedResult: 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/actions/actionTypes.ts b/src/tv2-common/actions/actionTypes.ts index 86aa3997f..722cd1265 100644 --- a/src/tv2-common/actions/actionTypes.ts +++ b/src/tv2-common/actions/actionTypes.ts @@ -87,7 +87,7 @@ export interface ActionClearGraphics extends ActionBase { } export interface ActionTakeWithTransitionVariantBase { - type: 'cut' | 'mix' | 'breaker' + type: 'cut' | 'mix' | 'breaker' | 'dip' } export interface ActionTakeWithTransitionVariantCut extends ActionTakeWithTransitionVariantBase { @@ -104,10 +104,16 @@ export interface ActionTakeWithTransitionVariantBreaker extends ActionTakeWithTr breaker: string } +export interface ActionTakeWithTransitionVariantDip extends ActionTakeWithTransitionVariantBase { + type: 'dip' + frames: number +} + export type ActionTakeWithTransitionVariant = | ActionTakeWithTransitionVariantCut | ActionTakeWithTransitionVariantMix | ActionTakeWithTransitionVariantBreaker + | ActionTakeWithTransitionVariantDip export interface ActionTakeWithTransition extends ActionBase { type: AdlibActionType.TAKE_WITH_TRANSITION diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index e794d4b62..2375ac61e 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -33,11 +33,13 @@ import { ActionSelectFullGrafik, ActionSelectServerClip, CalculateTime, + CreateDipEffectBlueprintPieceForPart, CreateFullPiece, CreatePartServerBase, CueDefinition, CueDefinitionDVE, CueDefinitionGraphic, + DipTransitionSettings, DVEOptions, DVEPieceMetaData, DVESources, @@ -53,6 +55,7 @@ import { ITV2ActionExecutionContext, literal, MakeContentDVE2, + MixTransitionSettings, PartDefinition, PieceMetaData, SisyfosPersistMetaData, @@ -81,7 +84,7 @@ import { } from '../helpers' import { InternalGraphic } from '../helpers/graphics/InternalGraphic' import { GetJinglePartPropertiesFromTableValue } from '../jinglePartProperties' -import { CreateEffektForPartBase, CreateEffektForPartInner, CreateMixForPartInner } from '../parts' +import { CreateEffektForPartBase, CreateEffektForPartInner, CreateMixEffectBlueprintPieceForPart } from '../parts' import { GetTagForDVE, GetTagForDVENext, @@ -325,7 +328,7 @@ async function getExistingTransition< const transition = existingTransition.piece.name // Case sensitive! Blueprints will set these names correctly. - const transitionProps = transition.match(/CUT|MIX (\d+)|EFFEKT (\d+)/) + const transitionProps = transition.match(/CUT|MIX (\d+)|DIP (\d+)|EFFEKT (\d+)/) if (!transitionProps || !transitionProps[0]) { return } @@ -338,7 +341,9 @@ async function getExistingTransition< }, takeNow: false }) - } else if (transitionProps[0].match(/MIX/) && transitionProps[1] !== undefined) { + } + + if (transitionProps[0].match(/MIX/) && transitionProps[1] !== undefined) { return literal({ type: AdlibActionType.TAKE_WITH_TRANSITION, variant: { @@ -347,7 +352,20 @@ async function getExistingTransition< }, takeNow: false }) - } else if (transitionProps[0].match(/EFFEKT/) && transitionProps[1] !== undefined) { + } + + if (transitionProps[0].match(/DIP/) && transitionProps[1] !== undefined) { + return literal({ + type: AdlibActionType.TAKE_WITH_TRANSITION, + variant: { + type: 'dip', + frames: Number(transitionProps[1]) + }, + takeNow: false + }) + } + + if (transitionProps[0].match(/EFFEKT/) && transitionProps[1] !== undefined) { return literal({ type: AdlibActionType.TAKE_WITH_TRANSITION, variant: { @@ -356,9 +374,8 @@ async function getExistingTransition< }, takeNow: false }) - } else { - return } + return } function sanitizePieceId(piece: IBlueprintPieceDB): IBlueprintPiece { @@ -1494,7 +1511,7 @@ async function executeActionTakeWithTransition< ) { const externalId = generateExternalId(context, actionId, [userData.variant.type]) - const nextPieces = await context.getPieceInstances('next') + const nextPieces: IBlueprintPieceInstance[] = await context.getPieceInstances('next') const nextPiecesBySourceLayer = groupPiecesBySourceLayer(nextPieces) const primaryPiece = findPrimaryPieceUsingPriority(settings, nextPiecesBySourceLayer) @@ -1509,19 +1526,21 @@ async function executeActionTakeWithTransition< return } - const tlObjIndex = (primaryPiece.piece.content.timelineObjects as TSR.TSRTimelineObj[]).findIndex( + const indexOfTimelineObject = (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 tlObj = - tlObjIndex > -1 - ? ((primaryPiece.piece.content.timelineObjects as TSR.TSRTimelineObj[])[tlObjIndex] as TSR.TimelineObjAtemME) + const timelineObject = + indexOfTimelineObject > -1 + ? ((primaryPiece.piece.content.timelineObjects as TSR.TSRTimelineObj[])[ + indexOfTimelineObject + ] as TSR.TimelineObjAtemME) : undefined - if (!tlObj) { + if (!timelineObject) { return } @@ -1536,9 +1555,9 @@ async function executeActionTakeWithTransition< switch (userData.variant.type) { case 'cut': { - tlObj.content.me.transition = TSR.AtemTransitionStyle.CUT + timelineObject.content.me.transition = TSR.AtemTransitionStyle.CUT - primaryPiece.piece.content.timelineObjects[tlObjIndex] = tlObj + primaryPiece.piece.content.timelineObjects[indexOfTimelineObject] = timelineObject await context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) @@ -1568,9 +1587,9 @@ async function executeActionTakeWithTransition< } break case 'breaker': { - tlObj.content.me.transition = TSR.AtemTransitionStyle.CUT + timelineObject.content.me.transition = TSR.AtemTransitionStyle.CUT - primaryPiece.piece.content.timelineObjects[tlObjIndex] = tlObj + primaryPiece.piece.content.timelineObjects[indexOfTimelineObject] = timelineObject await context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) @@ -1597,30 +1616,53 @@ async function executeActionTakeWithTransition< break } case 'mix': { - tlObj.content.me.transition = TSR.AtemTransitionStyle.MIX - tlObj.content.me.transitionSettings = { - ...tlObj.content.me.transitionSettings, - mix: { - rate: userData.variant.frames - } + await updateTimelineObjectMeTransition( + context, + timelineObject, + TSR.AtemTransitionStyle.MIX, + MixTransitionSettings(userData.variant.frames), + primaryPiece, + indexOfTimelineObject + ) + + const pieces: IBlueprintPiece[] = [] + partProps = { + ...CreateMixEffectBlueprintPieceForPart( + pieces, + externalId, + userData.variant.frames, + settings.SourceLayers.Effekt + ) } - primaryPiece.piece.content.timelineObjects[tlObjIndex] = tlObj + await context.updatePartInstance('next', partProps) + pieces.forEach(p => context.insertPiece('next', { ...p, tags: [GetTagForTransition(userData.variant)] })) - await context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) + break + } + case 'dip': { + const config = settings.getConfig(context) + await updateTimelineObjectMeTransition( + context, + timelineObject, + TSR.AtemTransitionStyle.DIP, + DipTransitionSettings(config, userData.variant.frames), + primaryPiece, + indexOfTimelineObject + ) const pieces: IBlueprintPiece[] = [] partProps = { - ...CreateMixForPartInner(pieces, externalId, userData.variant.frames, { - sourceLayer: settings.SourceLayers.Effekt, - casparLayer: settings.LLayer.Caspar.Effekt, - sisyfosLayer: settings.LLayer.Sisyfos.Effekt - }) + ...CreateDipEffectBlueprintPieceForPart( + pieces, + externalId, + userData.variant.frames, + settings.SourceLayers.Effekt + ) } await context.updatePartInstance('next', partProps) pieces.forEach(p => context.insertPiece('next', { ...p, tags: [GetTagForTransition(userData.variant)] })) - break } } @@ -1630,6 +1672,21 @@ async function executeActionTakeWithTransition< } } +async function updateTimelineObjectMeTransition( + context: ITV2ActionExecutionContext, + timelineObject: TSR.TimelineObjAtemME, + transitionStyle: TSR.AtemTransitionStyle, + transitionSettings: TSR.AtemTransitionSettings, + pieceInstance: IBlueprintPieceInstance, + indexOfTimelineObject: number +): Promise { + timelineObject.content.me.transition = transitionStyle + timelineObject.content.me.transitionSettings = transitionSettings + + pieceInstance.piece.content.timelineObjects[indexOfTimelineObject] = timelineObject + await context.updatePieceInstance(pieceInstance._id, pieceInstance.piece) +} + async function findPieceToRecoverDataFrom( context: ITV2ActionExecutionContext, dataStoreLayers: string[] diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 7d9daa1b6..e80425b7a 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -87,6 +87,7 @@ export interface TV2StudioConfigBase { SplitArtF: number SplitArtK: number DSK: TableConfigItemDSK[] + Dip: number } AtemSettings: {} StudioMics: string[] diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 42b7285b8..0ce733cd4 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -203,7 +203,7 @@ export function CutToServer( transition: partDefinition.transition ? TransitionFromString(partDefinition.transition.style) : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(partDefinition) + transitionSettings: TransitionSettings(config, partDefinition) } }, metaData: { diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index 5aff49b9c..2cbddf574 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -115,7 +115,7 @@ export function EvaluateEksternBase< transition: partDefinition.transition ? TransitionFromString(partDefinition.transition.style) : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(partDefinition) + transitionSettings: TransitionSettings(config, partDefinition) } }, classes: [ControlClasses.LiveSourceOnAir] @@ -172,7 +172,7 @@ export function EvaluateEksternBase< transition: partDefinition.transition ? TransitionFromString(partDefinition.transition.style) : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(partDefinition) + transitionSettings: TransitionSettings(config, partDefinition) } }, ...(AddParentClass(config, partDefinition) diff --git a/src/tv2-common/helpers/__tests__/rundownAdLibActions.spec.ts b/src/tv2-common/helpers/__tests__/rundownAdLibActions.spec.ts index 0e5bac50c..445b9767f 100644 --- a/src/tv2-common/helpers/__tests__/rundownAdLibActions.spec.ts +++ b/src/tv2-common/helpers/__tests__/rundownAdLibActions.spec.ts @@ -1,107 +1,76 @@ -import { - ActionTakeWithTransition, - ActionTakeWithTransitionVariantBreaker, - ActionTakeWithTransitionVariantMix, - literal, - ParseTransitionSetting -} from 'tv2-common' -import { AdlibActionType } from 'tv2-constants' +import { ActionTakeWithTransitionVariantDip, ParseTransitionString } from 'tv2-common' -describe('Parse Transition Setting', () => { - it('Parses Mix', () => { - let result = ParseTransitionSetting('MIX 12', true) - - expect(result).toEqual( - literal({ - type: AdlibActionType.TAKE_WITH_TRANSITION, - variant: literal({ - type: 'mix', - frames: 12 - }), - takeNow: true +describe('rundownAdLibActions', () => { + describe('ParseTransitionString', () => { + it('should parses Mix 12', () => { + const result = ParseTransitionString('MIX 12') + expect(result).toEqual({ + type: 'mix', + frames: 12 }) - ) - - result = ParseTransitionSetting('mix9', false) + }) - expect(result).toEqual( - literal({ - type: AdlibActionType.TAKE_WITH_TRANSITION, - variant: literal({ - type: 'mix', - frames: 9 - }), - takeNow: false + it('should parse Mix 9', () => { + const result = ParseTransitionString('mix9') + expect(result).toEqual({ + type: 'mix', + frames: 9 }) - ) - }) + }) - it('Parses EFFEKT', () => { - let result = ParseTransitionSetting('EFFEKT 1', true) - - expect(result).toEqual( - literal({ - type: AdlibActionType.TAKE_WITH_TRANSITION, - variant: literal({ - type: 'breaker', - breaker: '1' - }), - takeNow: true + it('should parse EFFEKT 1', () => { + const result = ParseTransitionString('EFFEKT 1') + expect(result).toEqual({ + type: 'breaker', + breaker: '1' }) - ) - - result = ParseTransitionSetting('effekt2', false) + }) - expect(result).toEqual( - literal({ - type: AdlibActionType.TAKE_WITH_TRANSITION, - variant: literal({ - type: 'breaker', - breaker: '2' - }), - takeNow: false + it('should parse effekt2', () => { + const result = ParseTransitionString('effekt2') + expect(result).toEqual({ + type: 'breaker', + breaker: '2' }) - ) + }) - result = ParseTransitionSetting('13', false) - - expect(result).toEqual( - literal({ - type: AdlibActionType.TAKE_WITH_TRANSITION, - variant: literal({ - type: 'breaker', - breaker: '13' - }), - takeNow: false + it('should parse 13 as breaker', () => { + const result = ParseTransitionString('13') + expect(result).toEqual({ + type: 'breaker', + breaker: '13' }) - ) - }) + }) - it('Parses Transition', () => { - let result = ParseTransitionSetting('INTRO_19', true) + it('should parse INTRO_19', () => { + const result = ParseTransitionString('INTRO_19') + expect(result).toEqual({ + type: 'breaker', + breaker: 'INTRO_19' + }) + }) - expect(result).toEqual( - literal({ - type: AdlibActionType.TAKE_WITH_TRANSITION, - variant: literal({ - type: 'breaker', - breaker: 'INTRO_19' - }), - takeNow: true + it('should parse / Branded Transition', () => { + const result = ParseTransitionString('/ Branded Transition') + expect(result).toEqual({ + type: 'breaker', + breaker: '/ Branded Transition' }) - ) + }) - result = ParseTransitionSetting('/ Branded Transition', false) + it('should return Dip when transitionSetting is Dip', () => { + const result = ParseTransitionString('dip 1') + expect(result.type).toEqual('dip') + }) - expect(result).toEqual( - literal({ - type: AdlibActionType.TAKE_WITH_TRANSITION, - variant: literal({ - type: 'breaker', - breaker: '/ Branded Transition' - }), - takeNow: false - }) - ) + it('should return a dip with 4 frames when transitionSetting is dip 4', () => { + const result = ParseTransitionString('dip 4') + expect((result as ActionTakeWithTransitionVariantDip).frames).toEqual(4) + }) + + it('should return a dip with 15 frames when transitionSetting is dip 15', () => { + const result = ParseTransitionString('dip 15') + expect((result as ActionTakeWithTransitionVariantDip).frames).toEqual(15) + }) }) }) diff --git a/src/tv2-common/helpers/rundownAdLibActions.ts b/src/tv2-common/helpers/rundownAdLibActions.ts index c1ad4aa0b..7157d0b03 100644 --- a/src/tv2-common/helpers/rundownAdLibActions.ts +++ b/src/tv2-common/helpers/rundownAdLibActions.ts @@ -4,6 +4,7 @@ import { ActionTakeWithTransitionVariant, ActionTakeWithTransitionVariantBreaker, ActionTakeWithTransitionVariantCut, + ActionTakeWithTransitionVariantDip, ActionTakeWithTransitionVariantMix, GetTagForTransition, literal, @@ -19,12 +20,16 @@ export function GetTransitionAdLibActions< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase >(config: ShowStyleConfig, startingRank: number): IBlueprintActionManifest[] { - const res: IBlueprintActionManifest[] = [] + const blueprintActionManifests: IBlueprintActionManifest[] = [] if (config.showStyle.ShowstyleTransition && config.showStyle.ShowstyleTransition.length) { const defaultTransition = config.showStyle.ShowstyleTransition - const userData = ParseTransitionSetting(defaultTransition, true) + const userData = literal({ + type: AdlibActionType.TAKE_WITH_TRANSITION, + variant: ParseTransitionString(defaultTransition), + takeNow: true + }) const jingleConfig = config.showStyle.BreakerConfig.find( j => j.BreakerName === config.showStyle.ShowstyleTransition @@ -39,7 +44,7 @@ export function GetTransitionAdLibActions< alphaAtEnd = jingleConfig.EndAlpha } - res.push( + blueprintActionManifests.push( makeTransitionAction( config, userData, @@ -58,7 +63,11 @@ export function GetTransitionAdLibActions< if (config.showStyle.Transitions) { config.showStyle.Transitions.forEach((transition, i) => { if (transition.Transition && transition.Transition.length) { - const userData = ParseTransitionSetting(transition.Transition, true) + const userData = literal({ + type: AdlibActionType.TAKE_WITH_TRANSITION, + variant: ParseTransitionString(transition.Transition), + takeNow: true + }) const jingleConfig = config.showStyle.BreakerConfig.find(j => j.BreakerName === transition.Transition) let alphaAtStart: number | undefined @@ -71,7 +80,7 @@ export function GetTransitionAdLibActions< alphaAtEnd = jingleConfig.EndAlpha } - res.push( + blueprintActionManifests.push( makeTransitionAction( config, userData, @@ -87,33 +96,35 @@ export function GetTransitionAdLibActions< }) } - return res + return blueprintActionManifests } -export function ParseTransitionSetting(transitionSetting: string, takeNow: boolean): ActionTakeWithTransition { - let variant: ActionTakeWithTransitionVariant = literal({ - type: 'cut' - }) - - if (transitionSetting.match(/mix ?(\d+)/i)) { - const props = transitionSetting.match(/mix ?(\d+)/i) - variant = literal({ +export function ParseTransitionString(transitionString: string): ActionTakeWithTransitionVariant { + if (transitionString.match(/mix ?(\d+)/i)) { + const props = transitionString.match(/mix ?(\d+)/i) + return literal({ type: 'mix', frames: Number(props![1]) }) - } else if (transitionSetting.match(/cut/i)) { - // Variant already setup - } else { - variant = literal({ - type: 'breaker', - breaker: transitionSetting.toString().replace(/effekt ?/i, '') + } + + if (transitionString.match(/dip ?(\d+)/i)) { + const props = transitionString.match(/dip ?(\d+)/i) + return literal({ + type: 'dip', + frames: Number(props![1]) + }) + } + + if (transitionString.match(/cut/i)) { + return literal({ + type: 'cut' }) } - return literal({ - type: AdlibActionType.TAKE_WITH_TRANSITION, - variant, - takeNow + return literal({ + type: 'breaker', + breaker: transitionString.toString().replace(/effekt ?/i, '') }) } @@ -144,7 +155,7 @@ function makeTransitionAction( currentPieceTags: [tag], nextPieceTags: [tag], content: - isEffekt || !!label.match(/^MIX ?\d+$/i) || !!label.match(/^CUT$/i) + isEffekt || !!label.match(/^MIX ?\d+$/i) || !!label.match(/^CUT$/i) || !!label.match(/^DIP ?\d+$/i) ? {} : CreateJingleExpectedMedia(config, jingle, alphaAtStart ?? 0, duration ?? 0, alphaAtEnd ?? 0) } diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index d56144141..5f2191942 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -10,6 +10,7 @@ import { WithTimeline } from '@tv2media/blueprints-integration' import { + ActionTakeWithTransitionVariantDip, ActionTakeWithTransitionVariantMix, EnableDSK, GetTagForTransition, @@ -51,15 +52,34 @@ export function CreateEffektForPartBase( ) return ret ?? {} - } else if (transition !== undefined && transition.duration !== undefined) { - if (transition.style.match(/mix/i)) { - return CreateMixForPartInner(pieces, partDefinition.externalId, transition.duration, layers) ?? {} - } else { - return {} - } - } else { + } + + if (transition === undefined || transition.duration === undefined) { return {} } + + if (transition.style.match(/mix/i)) { + return ( + CreateMixEffectBlueprintPieceForPart( + pieces, + partDefinition.externalId, + transition.duration, + layers.sourceLayer + ) ?? {} + ) + } + if (transition.style.match(/dip/i)) { + return ( + CreateDipEffectBlueprintPieceForPart( + pieces, + partDefinition.externalId, + transition.duration, + layers.sourceLayer + ) ?? {} + ) + } + + return {} } export function CreateEffektForPartInner< @@ -172,16 +192,33 @@ export function CreateEffektForPartInner< } } -export function CreateMixForPartInner( +export function CreateMixEffectBlueprintPieceForPart( pieces: IBlueprintPiece[], externalId: string, durationInFrames: number, - layers: { - sourceLayer: string - casparLayer: string - sisyfosLayer: string - } + sourceLayer: string ): Pick { + const tags = [ + GetTagForTransition( + literal({ + type: 'mix', + frames: durationInFrames + }) + ) + ] + const effectName: string = 'mix' + addEffectBlueprintPiece(pieces, durationInFrames, externalId, effectName, sourceLayer, tags) + return createInTransitionForEffect(durationInFrames) +} + +function addEffectBlueprintPiece( + pieces: IBlueprintPiece[], + durationInFrames: number, + externalId: string, + name: string, + sourceLayer: string, + tags: string[] +): void { pieces.push( literal({ enable: { @@ -189,27 +226,21 @@ export function CreateMixForPartInner( duration: Math.max(TimeFromFrames(durationInFrames), 1000) }, externalId, - name: `MIX ${durationInFrames}`, - sourceLayerId: layers.sourceLayer, + name: `${name.toUpperCase()} ${durationInFrames}`, + sourceLayerId: sourceLayer, outputLayerId: SharedOutputLayers.JINGLE, lifespan: PieceLifespan.WithinPart, - tags: [ - GetTagForTransition( - literal({ - type: 'mix', - frames: durationInFrames - }) - ) - ], + tags, content: { timelineObjects: [], ignoreMediaObjectStatus: true } }) ) +} +function createInTransitionForEffect(durationInFrames: number): Pick { const transitionDuration = TimeFromFrames(durationInFrames) - return { inTransition: { previousPartKeepaliveDuration: transitionDuration, @@ -218,3 +249,22 @@ export function CreateMixForPartInner( } } } + +export function CreateDipEffectBlueprintPieceForPart( + pieces: IBlueprintPiece[], + externalId: string, + durationInFrames: number, + sourceLayer: string +): Pick { + const tags = [ + GetTagForTransition( + literal({ + type: 'dip', + frames: durationInFrames + }) + ) + ] + const effectName: string = 'dip' + addEffectBlueprintPiece(pieces, durationInFrames, externalId, effectName, sourceLayer, tags) + return createInTransitionForEffect(durationInFrames) +} diff --git a/src/tv2-common/pieces/tags.ts b/src/tv2-common/pieces/tags.ts index 63c7a5a8a..5c2fe1208 100644 --- a/src/tv2-common/pieces/tags.ts +++ b/src/tv2-common/pieces/tags.ts @@ -9,6 +9,7 @@ export function GetTagForTransition(variant: ActionTakeWithTransitionVariant) { tag += variant.breaker break case 'mix': + case 'dip': tag += variant.frames break default: diff --git a/src/tv2-common/transitionSettings.ts b/src/tv2-common/transitionSettings.ts index ad740bd8e..a2753de57 100644 --- a/src/tv2-common/transitionSettings.ts +++ b/src/tv2-common/transitionSettings.ts @@ -1,20 +1,42 @@ import { TSR } from '@tv2media/blueprints-integration' -import { PartDefinition } from 'tv2-common' +import { PartDefinition, TV2BlueprintConfig } from 'tv2-common' +import { AtemSourceIndex } from '../types/atem' -export function TransitionSettings(part: PartDefinition): TSR.AtemTransitionSettings { - if (part.transition && part.transition.duration) { - if (part.transition.style === 'WIPE') { - return { - wipe: { - rate: part.transition.duration - } - } +export function TransitionSettings(config: TV2BlueprintConfig, part: PartDefinition): TSR.AtemTransitionSettings { + if (!part.transition || !part.transition.duration) { + return {} + } + + if (part.transition.style.match(/WIPE/i)) { + return WipeTransitionSettings(part.transition.duration) + } + if (part.transition.style.match(/DIP/i)) { + return DipTransitionSettings(config, part.transition.duration) + } + return MixTransitionSettings(part.transition.duration) +} + +function WipeTransitionSettings(rate: number): TSR.AtemTransitionSettings { + return { + wipe: { + rate } - return { - mix: { - rate: part.transition.duration - } + } +} + +export function DipTransitionSettings(config: TV2BlueprintConfig, rate: number): TSR.AtemTransitionSettings { + return { + dip: { + rate, + input: config.studio?.AtemSource?.Dip ?? AtemSourceIndex.Col2 + } + } +} + +export function MixTransitionSettings(rate: number): TSR.AtemTransitionSettings { + return { + mix: { + rate } } - return {} } diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index 2513953ff..3485a5ffc 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -105,7 +105,8 @@ export const defaultStudioConfig: StudioConfig = { SplitArtF: 30, SplitArtK: 32, Default: 2001, - Continuity: 2002 + Continuity: 2002, + Dip: 2002 }, SofieHostURL: '', ABMediaPlayers: [ diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index 041e2e092..d81ac1f4c 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -138,7 +138,7 @@ function makeContentEVS( transition: partDefinition.transition ? TransitionFromString(partDefinition.transition.style) : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(partDefinition) + transitionSettings: TransitionSettings(config, partDefinition) } }, classes: [EVSParentClass('studio0', partDefinition.variant.evs)] diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index eeb7d9b03..53f06436d 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -87,7 +87,7 @@ export async function CreatePartKam( transition: partDefinition.transition ? TransitionFromString(partDefinition.transition.style) : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(partDefinition) + transitionSettings: TransitionSettings(config, partDefinition) } } }) @@ -139,7 +139,7 @@ export async function CreatePartKam( transition: partDefinition.transition ? TransitionFromString(partDefinition.transition.style) : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(partDefinition) + transitionSettings: TransitionSettings(config, partDefinition) } }, ...(AddParentClass(config, partDefinition) diff --git a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts index 6f0b3286c..6e02d78eb 100644 --- a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts @@ -44,7 +44,8 @@ const blankStudioConfig: StudioConfig = { SplitArtK: 0, Default: 0, MixMinusDefault: 0, - Continuity: 0 + Continuity: 0, + Dip: 0 }, AtemSettings: { MP1Baseline: { diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index 13bec9dc2..78d420ac9 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -329,6 +329,14 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ 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', + type: ConfigManifestEntryType.INT, + required: true, + defaultVal: AtemSourceIndex.Col2 + }, { id: 'AtemSettings.MP1Baseline.Clip', name: 'ATEM MP1 baseline clip number', diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index fe0457e01..f5f082ea9 100644 --- a/src/tv2_afvd_studio/helpers/config.ts +++ b/src/tv2_afvd_studio/helpers/config.ts @@ -36,6 +36,7 @@ export interface StudioConfig extends TV2StudioConfigBase { Default: number MixMinusDefault: number Continuity: number + Dip: number } AtemSettings: { diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index 35d509068..cb38c587e 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -83,7 +83,7 @@ export async function OfftubeCreatePartKam( transition: partDefinition.transition ? TransitionFromString(partDefinition.transition.style) : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(partDefinition) + transitionSettings: TransitionSettings(config, partDefinition) } } }) @@ -134,7 +134,7 @@ export async function OfftubeCreatePartKam( transition: partDefinition.transition ? TransitionFromString(partDefinition.transition.style) : TSR.AtemTransitionStyle.CUT, - transitionSettings: TransitionSettings(partDefinition) + transitionSettings: TransitionSettings(config, partDefinition) } }, ...(AddParentClass(config, partDefinition) diff --git a/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts b/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts index 7e59c24bc..d3a4f9825 100644 --- a/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_offtube_studio/__tests__/config-manifest.spec.ts @@ -35,7 +35,8 @@ const blankStudioConfig: OfftubeStudioConfig = { Default: 0, Continuity: 0, SplitBackground: 0, - Loop: 0 + Loop: 0, + Dip: 0 }, AtemSettings: {}, AudioBedSettings: { diff --git a/src/tv2_offtube_studio/config-manifests.ts b/src/tv2_offtube_studio/config-manifests.ts index 2ed2539db..4d70a632c 100644 --- a/src/tv2_offtube_studio/config-manifests.ts +++ b/src/tv2_offtube_studio/config-manifests.ts @@ -188,6 +188,14 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ 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', + type: ConfigManifestEntryType.INT, + required: true, + defaultVal: AtemSourceIndex.Col2 + }, { id: 'AudioBedSettings.fadeIn', name: 'Bed Fade In', diff --git a/src/tv2_offtube_studio/helpers/config.ts b/src/tv2_offtube_studio/helpers/config.ts index d424da01d..6940dc5f2 100644 --- a/src/tv2_offtube_studio/helpers/config.ts +++ b/src/tv2_offtube_studio/helpers/config.ts @@ -32,6 +32,7 @@ export interface OfftubeStudioConfig extends TV2StudioConfigBase { Default: number Continuity: number + Dip: number } AtemSettings: {} From e34b72088f6ebf3973a6d6cbe62f348f3235fc32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Mon, 4 Jul 2022 10:55:56 +0200 Subject: [PATCH 148/184] chore: SOF-985 Bump blueprints-integration dependency to get ATEM dip transition --- package.json | 2 +- .../__tests__/transitionSettings.spec.ts | 2 +- yarn.lock | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 343752739..e37b880aa 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "webpack-cli": "^3.1.2" }, "dependencies": { - "@tv2media/blueprints-integration": "1.42.6", + "@tv2media/blueprints-integration": "1.42.7", "underscore": "^1.12.1" }, "resolutions": { diff --git a/src/tv2-common/__tests__/transitionSettings.spec.ts b/src/tv2-common/__tests__/transitionSettings.spec.ts index 715ea794a..eb402ec66 100644 --- a/src/tv2-common/__tests__/transitionSettings.spec.ts +++ b/src/tv2-common/__tests__/transitionSettings.spec.ts @@ -15,7 +15,7 @@ describe('transitionsSettingsSuite', () => { let mockConfig: TV2BlueprintConfig beforeEach(() => { - mockConfig = ({} as any) as TV2BlueprintConfig + mockConfig = ({} as unknown) as TV2BlueprintConfig }) describe('TransitionSettings', () => { diff --git a/yarn.lock b/yarn.lock index a1e50dfac..c445cb791 100644 --- a/yarn.lock +++ b/yarn.lock @@ -565,13 +565,13 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== -"@tv2media/blueprints-integration@1.42.6": - version "1.42.6" - resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-1.42.6.tgz#723d6410112b0b16c4ba8e2087f8bf6a3aec76e8" - integrity sha512-fWJOaEa3Wtwoc4lZ/WwgLOknuu3F/0Tg9l9EbXw1MxKwajrPOmb4wMsz5FyQB6LpuTxuuJKIPXBcwvCEMz4eCg== +"@tv2media/blueprints-integration@1.42.7": + version "1.42.7" + resolved "https://registry.yarnpkg.com/@tv2media/blueprints-integration/-/blueprints-integration-1.42.7.tgz#b88bc4becb27d0b5e828562286bd01cbbb1ee422" + integrity sha512-GAalonu3u6v4bjkM+v0IFDBdKksfMsch7GpsR7Yef7HMpFhEqQvl2rXqd9j3NyQhJKKmywG9Oh081HsvHCfOKg== dependencies: moment "2.29.3" - timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@2.1.0" + timeline-state-resolver-types "npm:@tv2media/timeline-state-resolver-types@2.1.3" tslib "^2.3.1" type-fest "^2.11.1" @@ -5948,10 +5948,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.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-2.1.0.tgz#0dc866dcd24c79cd89283de97dd6a7c454b6b846" - integrity sha512-Z8Z2UqHov18auFJJsyEWZzBnqMxfLQujd9Ihoos/0FJHouRTcR/TRhaqFfqjNe7T1YN5nee73wuLcyBkJferKQ== +"timeline-state-resolver-types@npm:@tv2media/timeline-state-resolver-types@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@tv2media/timeline-state-resolver-types/-/timeline-state-resolver-types-2.1.3.tgz#b79f4a5449428c517398bc908e93c13477ff04a8" + integrity sha512-wHW2S/Q/i2Dn7QPjY8nCdfjGG/a8BCvMfuI/vMm9WTqfzRnBgh9S8gd4TmOFUEaAiEZNGRy/wR6Y0ZquLYQ0mQ== dependencies: tslib "^2.3.1" From c01b8b0066cb55d4f32c0b883449e5899a065016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Mon, 4 Jul 2022 11:59:16 +0200 Subject: [PATCH 149/184] chore: SOF-985 Fix wrong import --- src/tv2-common/__tests__/transitionSettings.spec.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tv2-common/__tests__/transitionSettings.spec.ts b/src/tv2-common/__tests__/transitionSettings.spec.ts index eb402ec66..4d25144f0 100644 --- a/src/tv2-common/__tests__/transitionSettings.spec.ts +++ b/src/tv2-common/__tests__/transitionSettings.spec.ts @@ -1,4 +1,4 @@ -import { AtemTransitionSettings } from '../../../../tv-automation-state-timeline-resolver/packages/timeline-state-resolver-types/src' +import { TSR } from '@tv2media/blueprints-integration' import { PartType } from '../../tv2-constants' import { AtemSourceIndex } from '../../types/atem' import { TV2BlueprintConfig, TV2BlueprintConfigBase, TV2StudioConfigBase } from '../blueprintConfig' @@ -46,7 +46,7 @@ describe('transitionsSettingsSuite', () => { const partDefinition: PartDefinition = createPartDefinition(transition) const result = TransitionSettings(mockConfig, partDefinition) - const expectedResult: AtemTransitionSettings = { + const expectedResult: TSR.AtemTransitionSettings = { wipe: { rate: DURATION } @@ -62,7 +62,7 @@ describe('transitionsSettingsSuite', () => { const partDefinition: PartDefinition = createPartDefinition(transition) const result = TransitionSettings(mockConfig, partDefinition) - const expectedResult: AtemTransitionSettings = { + const expectedResult: TSR.AtemTransitionSettings = { mix: { rate: DURATION } @@ -78,7 +78,7 @@ describe('transitionsSettingsSuite', () => { const partDefinition: PartDefinition = createPartDefinition(transition) const result = TransitionSettings(mockConfig, partDefinition) - const expectedResult: AtemTransitionSettings = { + const expectedResult: TSR.AtemTransitionSettings = { dip: { rate: DURATION, input: AtemSourceIndex.Col2 @@ -112,7 +112,7 @@ describe('transitionsSettingsSuite', () => { const partDefinition: PartDefinition = createPartDefinition(transition) const result = TransitionSettings(mockConfig, partDefinition) - const expectedResult: AtemTransitionSettings = { + const expectedResult: TSR.AtemTransitionSettings = { dip: { rate: DURATION, input: AtemSourceIndex.Col2 @@ -153,7 +153,7 @@ function assertDipInputValueFromConfig( const partDefinition: PartDefinition = createPartDefinition(transition) const result = TransitionSettings(mockConfig, partDefinition) - const expectedResult: AtemTransitionSettings = { + const expectedResult: TSR.AtemTransitionSettings = { dip: { rate: DURATION, input: dipInputSource From 395a679fba36e251786a65ba09b153949b07e08b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Tue, 5 Jul 2022 08:52:32 +0200 Subject: [PATCH 150/184] SOF-985 Refactor PartDefination.Transition.Style to use Enum instead of String. Refactor sideeffect away when creating blueprint pieces for an effect --- .../__tests__/transition-from-string.spec.ts | 24 ++--- .../__tests__/transitionSettings.spec.ts | 16 ++-- src/tv2-common/actions/executeAction.ts | 54 +++++------ ...ng.ts => atemTransitionStyleFromString.ts} | 2 +- src/tv2-common/content/server.ts | 5 +- src/tv2-common/cues/ekstern.ts | 9 +- src/tv2-common/helpers/rundownAdLibActions.ts | 2 +- src/tv2-common/index.ts | 2 +- .../inewsConversion/converters/ParseBody.ts | 13 ++- .../converters/__tests__/body-parser.spec.ts | 4 +- .../converters/__tests__/cue-parser.spec.ts | 4 +- src/tv2-common/parts/effekt.ts | 89 ++++++++----------- src/tv2-common/transitionSettings.ts | 5 +- src/tv2_afvd_showstyle/parts/evs.ts | 5 +- src/tv2_afvd_showstyle/parts/kam.ts | 9 +- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 9 +- 16 files changed, 109 insertions(+), 143 deletions(-) rename src/tv2-common/{transitionFromString.ts => atemTransitionStyleFromString.ts} (81%) diff --git a/src/tv2-common/__tests__/transition-from-string.spec.ts b/src/tv2-common/__tests__/transition-from-string.spec.ts index 614abde1a..a3002113a 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 '@tv2media/blueprints-integration' -import { TransitionFromString } from '../transitionFromString' +import { AtemTransitionStyleFromString } from '../atemTransitionStyleFromString' describe('Transition From String', () => { it('Converts strings', () => { - expect(TransitionFromString('mix')).toEqual(TSR.AtemTransitionStyle.MIX) - expect(TransitionFromString('MIX')).toEqual(TSR.AtemTransitionStyle.MIX) - expect(TransitionFromString('dip')).toEqual(TSR.AtemTransitionStyle.DIP) - expect(TransitionFromString('DIP')).toEqual(TSR.AtemTransitionStyle.DIP) - expect(TransitionFromString('wipe')).toEqual(TSR.AtemTransitionStyle.WIPE) - expect(TransitionFromString('WIPE')).toEqual(TSR.AtemTransitionStyle.WIPE) - expect(TransitionFromString('sting')).toEqual(TSR.AtemTransitionStyle.STING) - expect(TransitionFromString('STING')).toEqual(TSR.AtemTransitionStyle.STING) - expect(TransitionFromString('cut')).toEqual(TSR.AtemTransitionStyle.CUT) - expect(TransitionFromString('CUT')).toEqual(TSR.AtemTransitionStyle.CUT) - expect(TransitionFromString('unknown')).toEqual(TSR.AtemTransitionStyle.CUT) + 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) }) }) diff --git a/src/tv2-common/__tests__/transitionSettings.spec.ts b/src/tv2-common/__tests__/transitionSettings.spec.ts index 4d25144f0..f51b46a58 100644 --- a/src/tv2-common/__tests__/transitionSettings.spec.ts +++ b/src/tv2-common/__tests__/transitionSettings.spec.ts @@ -7,10 +7,6 @@ import { TransitionSettings } from '../transitionSettings' const DURATION: number = 50 -const WIPE_STYLE: string = 'WIPE' -const MIX_STYLE: string = 'MIX' -const DIP_STYLE: string = 'DIP' - describe('transitionsSettingsSuite', () => { let mockConfig: TV2BlueprintConfig @@ -30,7 +26,7 @@ describe('transitionsSettingsSuite', () => { it('should return empty when no duration on transition', () => { const transition: PartTransition = { duration: undefined, - style: 'randomStyle' + style: TSR.AtemTransitionStyle.DUMMY } const partDefinition: PartDefinition = createPartDefinition(transition) const result = TransitionSettings(mockConfig, partDefinition) @@ -40,7 +36,7 @@ describe('transitionsSettingsSuite', () => { it('should return Wipe when transition is style Wip', () => { const transition: PartTransition = { - style: WIPE_STYLE.toString(), + style: TSR.AtemTransitionStyle.WIPE, duration: DURATION } const partDefinition: PartDefinition = createPartDefinition(transition) @@ -56,7 +52,7 @@ describe('transitionsSettingsSuite', () => { it('should return Mix when transition is style Mix', () => { const transition: PartTransition = { - style: MIX_STYLE, + style: TSR.AtemTransitionStyle.MIX, duration: DURATION } const partDefinition: PartDefinition = createPartDefinition(transition) @@ -72,7 +68,7 @@ describe('transitionsSettingsSuite', () => { it('should return Dip when style is Dip', () => { const transition: PartTransition = { - style: DIP_STYLE, + style: TSR.AtemTransitionStyle.DIP, duration: DURATION } const partDefinition: PartDefinition = createPartDefinition(transition) @@ -106,7 +102,7 @@ describe('transitionsSettingsSuite', () => { describe('DipTransitionSettings', () => { it('should return AtemSourceIndex.Col2 when no AtemSource.Dip is configured', () => { const transition: PartTransition = { - style: DIP_STYLE, + style: TSR.AtemTransitionStyle.DIP, duration: DURATION } const partDefinition: PartDefinition = createPartDefinition(transition) @@ -147,7 +143,7 @@ function assertDipInputValueFromConfig( AtemSource: createAtemSourceConfig(dipInputSource) } as any) as TV2StudioConfigBase const transition: PartTransition = { - style: DIP_STYLE, + style: TSR.AtemTransitionStyle.DIP, duration: DURATION } const partDefinition: PartDefinition = createPartDefinition(transition) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 2375ac61e..c1479640a 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -33,8 +33,9 @@ import { ActionSelectFullGrafik, ActionSelectServerClip, CalculateTime, - CreateDipEffectBlueprintPieceForPart, + CreateDipTransitionBlueprintPieceForPart, CreateFullPiece, + CreateInTransitionForAtemTransitionStyle, CreatePartServerBase, CueDefinition, CueDefinitionDVE, @@ -84,7 +85,7 @@ import { } from '../helpers' import { InternalGraphic } from '../helpers/graphics/InternalGraphic' import { GetJinglePartPropertiesFromTableValue } from '../jinglePartProperties' -import { CreateEffektForPartBase, CreateEffektForPartInner, CreateMixEffectBlueprintPieceForPart } from '../parts' +import { CreateEffektForPartBase, CreateEffektForPartInner, CreateMixTransitionBlueprintPieceForPart } from '../parts' import { GetTagForDVE, GetTagForDVENext, @@ -1526,7 +1527,7 @@ async function executeActionTakeWithTransition< return } - const indexOfTimelineObject = (primaryPiece.piece.content.timelineObjects as TSR.TSRTimelineObj[]).findIndex( + 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 && @@ -1534,9 +1535,9 @@ async function executeActionTakeWithTransition< ) const timelineObject = - indexOfTimelineObject > -1 + timelineObjectIndex > -1 ? ((primaryPiece.piece.content.timelineObjects as TSR.TSRTimelineObj[])[ - indexOfTimelineObject + timelineObjectIndex ] as TSR.TimelineObjAtemME) : undefined @@ -1557,7 +1558,7 @@ async function executeActionTakeWithTransition< { timelineObject.content.me.transition = TSR.AtemTransitionStyle.CUT - primaryPiece.piece.content.timelineObjects[indexOfTimelineObject] = timelineObject + primaryPiece.piece.content.timelineObjects[timelineObjectIndex] = timelineObject await context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) @@ -1589,7 +1590,7 @@ async function executeActionTakeWithTransition< case 'breaker': { timelineObject.content.me.transition = TSR.AtemTransitionStyle.CUT - primaryPiece.piece.content.timelineObjects[indexOfTimelineObject] = timelineObject + primaryPiece.piece.content.timelineObjects[timelineObjectIndex] = timelineObject await context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) @@ -1622,21 +1623,18 @@ async function executeActionTakeWithTransition< TSR.AtemTransitionStyle.MIX, MixTransitionSettings(userData.variant.frames), primaryPiece, - indexOfTimelineObject + timelineObjectIndex ) - const pieces: IBlueprintPiece[] = [] - partProps = { - ...CreateMixEffectBlueprintPieceForPart( - pieces, - externalId, - userData.variant.frames, - settings.SourceLayers.Effekt - ) - } + const blueprintPiece: IBlueprintPiece = CreateMixTransitionBlueprintPieceForPart( + externalId, + userData.variant.frames, + settings.SourceLayers.Effekt + ) + partProps = CreateInTransitionForAtemTransitionStyle(userData.variant.frames) await context.updatePartInstance('next', partProps) - pieces.forEach(p => context.insertPiece('next', { ...p, tags: [GetTagForTransition(userData.variant)] })) + await context.insertPiece('next', { ...blueprintPiece, tags: [GetTagForTransition(userData.variant)] }) break } @@ -1648,21 +1646,17 @@ async function executeActionTakeWithTransition< TSR.AtemTransitionStyle.DIP, DipTransitionSettings(config, userData.variant.frames), primaryPiece, - indexOfTimelineObject + timelineObjectIndex + ) + const blueprintPiece: IBlueprintPiece = CreateDipTransitionBlueprintPieceForPart( + externalId, + userData.variant.frames, + settings.SourceLayers.Effekt ) - const pieces: IBlueprintPiece[] = [] - partProps = { - ...CreateDipEffectBlueprintPieceForPart( - pieces, - externalId, - userData.variant.frames, - settings.SourceLayers.Effekt - ) - } - + partProps = CreateInTransitionForAtemTransitionStyle(userData.variant.frames) await context.updatePartInstance('next', partProps) - pieces.forEach(p => context.insertPiece('next', { ...p, tags: [GetTagForTransition(userData.variant)] })) + await context.insertPiece('next', { ...blueprintPiece, tags: [GetTagForTransition(userData.variant)] }) break } } diff --git a/src/tv2-common/transitionFromString.ts b/src/tv2-common/atemTransitionStyleFromString.ts similarity index 81% rename from src/tv2-common/transitionFromString.ts rename to src/tv2-common/atemTransitionStyleFromString.ts index 6d4028af4..ecc3552ec 100644 --- a/src/tv2-common/transitionFromString.ts +++ b/src/tv2-common/atemTransitionStyleFromString.ts @@ -1,6 +1,6 @@ import { TSR } from '@tv2media/blueprints-integration' -export function TransitionFromString(str: string): TSR.AtemTransitionStyle { +export function AtemTransitionStyleFromString(str: string): TSR.AtemTransitionStyle { if (str.match(/MIX/i)) { return TSR.AtemTransitionStyle.MIX } else if (str.match(/DIP/i)) { diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 0ce733cd4..7de631ff9 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -11,7 +11,6 @@ import { literal, PartDefinition, ServerParentClass, - TransitionFromString, TransitionSettings } from 'tv2-common' import { AbstractLLayer, ControlClasses, GetEnableClassForServer } from 'tv2-constants' @@ -200,9 +199,7 @@ export function CutToServer( type: TSR.TimelineContentTypeAtem.ME, me: { input: -1, - transition: partDefinition.transition - ? TransitionFromString(partDefinition.transition.style) - : TSR.AtemTransitionStyle.CUT, + transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, transitionSettings: TransitionSettings(config, partDefinition) } }, diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index 2cbddf574..99bd0cdf4 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -22,7 +22,6 @@ import { PartDefinition, PartToParentClass, SisyfosPersistMetaData, - TransitionFromString, TransitionSettings, TV2BlueprintConfigBase, TV2StudioConfigBase @@ -112,9 +111,7 @@ export function EvaluateEksternBase< type: TSR.TimelineContentTypeAtem.ME, me: { input: atemInput, - transition: partDefinition.transition - ? TransitionFromString(partDefinition.transition.style) - : TSR.AtemTransitionStyle.CUT, + transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, transitionSettings: TransitionSettings(config, partDefinition) } }, @@ -169,9 +166,7 @@ export function EvaluateEksternBase< type: TSR.TimelineContentTypeAtem.ME, me: { input: atemInput, - transition: partDefinition.transition - ? TransitionFromString(partDefinition.transition.style) - : TSR.AtemTransitionStyle.CUT, + transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, transitionSettings: TransitionSettings(config, partDefinition) } }, diff --git a/src/tv2-common/helpers/rundownAdLibActions.ts b/src/tv2-common/helpers/rundownAdLibActions.ts index 7157d0b03..46243960a 100644 --- a/src/tv2-common/helpers/rundownAdLibActions.ts +++ b/src/tv2-common/helpers/rundownAdLibActions.ts @@ -155,7 +155,7 @@ function makeTransitionAction( currentPieceTags: [tag], nextPieceTags: [tag], content: - isEffekt || !!label.match(/^MIX ?\d+$/i) || !!label.match(/^CUT$/i) || !!label.match(/^DIP ?\d+$/i) + isEffekt || !!/^MIX ?\d+$/i.test(label) || !!/^CUT$/i.test(label) || !!/^DIP ?\d+$/i.test(label) ? {} : CreateJingleExpectedMedia(config, jingle, alphaAtStart ?? 0, duration ?? 0, alphaAtEnd ?? 0) } diff --git a/src/tv2-common/index.ts b/src/tv2-common/index.ts index 96096ddf1..3d5e96e8f 100644 --- a/src/tv2-common/index.ts +++ b/src/tv2-common/index.ts @@ -18,7 +18,7 @@ export * from './parts' export * from './pieces' export * from './sources' export * from './time/partTime' -export * from './transitionFromString' +export * from './atemTransitionStyleFromString' export * from './transitionSettings' export * from './translateEngine' export * from './types' diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index 207a3e695..8d33d2240 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -1,9 +1,16 @@ -import { CueDefinitionFromLayout, PostProcessDefinitions, TV2BlueprintConfig, UnparsedCue } from 'tv2-common' +import { TSR } from '@tv2media/blueprints-integration' +import { + AtemTransitionStyleFromString, + CueDefinitionFromLayout, + PostProcessDefinitions, + TV2BlueprintConfig, + UnparsedCue +} from 'tv2-common' import { CueType, PartType } from 'tv2-constants' import { CueDefinition, CueDefinitionUnpairedPilot, ParseCue, UnpairedPilotToGraphic } from './ParseCue' export interface PartTransition { - style: string + style: TSR.AtemTransitionStyle duration?: number } @@ -495,7 +502,7 @@ export function getTransitionProperties(typeStr: string): Pick { name: '1' }, transition: { - style: 'MIX', + style: TSR.AtemTransitionStyle.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 30b7b5fcb..cd3d8c28e 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts @@ -1,4 +1,4 @@ -import { IBlueprintRundownDB, PlaylistTimingType } from '@tv2media/blueprints-integration' +import { IBlueprintRundownDB, PlaylistTimingType, TSR } from '@tv2media/blueprints-integration' import { CueType } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' import { defaultShowStyleConfig, defaultStudioConfig } from '../../../../tv2_afvd_showstyle/__tests__/configs' @@ -1045,7 +1045,7 @@ describe('Cue parser', () => { iNewsCommand: 'EKSTERN', transition: { transition: { - style: 'MIX', + style: TSR.AtemTransitionStyle.MIX, duration: 10 } } diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index 5f2191942..b6dc9b313 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -58,25 +58,19 @@ export function CreateEffektForPartBase( return {} } - if (transition.style.match(/mix/i)) { - return ( - CreateMixEffectBlueprintPieceForPart( - pieces, - partDefinition.externalId, - transition.duration, - layers.sourceLayer - ) ?? {} - ) + if (transition.style === TSR.AtemTransitionStyle.MIX) { + const blueprintPiece: IBlueprintPiece = + CreateMixTransitionBlueprintPieceForPart(partDefinition.externalId, transition.duration, layers.sourceLayer) ?? {} + + pieces.push(blueprintPiece) + return CreateInTransitionForAtemTransitionStyle(transition.duration) } - if (transition.style.match(/dip/i)) { - return ( - CreateDipEffectBlueprintPieceForPart( - pieces, - partDefinition.externalId, - transition.duration, - layers.sourceLayer - ) ?? {} - ) + + if (transition.style === TSR.AtemTransitionStyle.DIP) { + const blueprintPiece: IBlueprintPiece = + CreateDipTransitionBlueprintPieceForPart(partDefinition.externalId, transition.duration, layers.sourceLayer) ?? {} + pieces.push(blueprintPiece) + return CreateInTransitionForAtemTransitionStyle(transition.duration) } return {} @@ -192,12 +186,11 @@ export function CreateEffektForPartInner< } } -export function CreateMixEffectBlueprintPieceForPart( - pieces: IBlueprintPiece[], +export function CreateMixTransitionBlueprintPieceForPart( externalId: string, durationInFrames: number, sourceLayer: string -): Pick { +): IBlueprintPiece { const tags = [ GetTagForTransition( literal({ @@ -207,39 +200,37 @@ export function CreateMixEffectBlueprintPieceForPart( ) ] const effectName: string = 'mix' - addEffectBlueprintPiece(pieces, durationInFrames, externalId, effectName, sourceLayer, tags) - return createInTransitionForEffect(durationInFrames) + return createEffectBlueprintPiece(durationInFrames, externalId, effectName, sourceLayer, tags) } -function addEffectBlueprintPiece( - pieces: IBlueprintPiece[], +function createEffectBlueprintPiece( durationInFrames: number, externalId: string, name: string, sourceLayer: string, tags: string[] -): void { - pieces.push( - literal({ - enable: { - start: 0, - duration: Math.max(TimeFromFrames(durationInFrames), 1000) - }, - externalId, - name: `${name.toUpperCase()} ${durationInFrames}`, - sourceLayerId: sourceLayer, - outputLayerId: SharedOutputLayers.JINGLE, - lifespan: PieceLifespan.WithinPart, - tags, - content: { - timelineObjects: [], - ignoreMediaObjectStatus: true - } - }) - ) +): IBlueprintPiece { + return literal({ + enable: { + start: 0, + duration: Math.max(TimeFromFrames(durationInFrames), 1000) + }, + externalId, + name: `${name.toUpperCase()} ${durationInFrames}`, + sourceLayerId: sourceLayer, + outputLayerId: SharedOutputLayers.JINGLE, + lifespan: PieceLifespan.WithinPart, + tags, + content: { + timelineObjects: [], + ignoreMediaObjectStatus: true + } + }) } -function createInTransitionForEffect(durationInFrames: number): Pick { +export function CreateInTransitionForAtemTransitionStyle( + durationInFrames: number +): Pick { const transitionDuration = TimeFromFrames(durationInFrames) return { inTransition: { @@ -250,12 +241,11 @@ function createInTransitionForEffect(durationInFrames: number): Pick { +): IBlueprintPiece { const tags = [ GetTagForTransition( literal({ @@ -265,6 +255,5 @@ export function CreateDipEffectBlueprintPieceForPart( ) ] const effectName: string = 'dip' - addEffectBlueprintPiece(pieces, durationInFrames, externalId, effectName, sourceLayer, tags) - return createInTransitionForEffect(durationInFrames) + return createEffectBlueprintPiece(durationInFrames, externalId, effectName, sourceLayer, tags) } diff --git a/src/tv2-common/transitionSettings.ts b/src/tv2-common/transitionSettings.ts index a2753de57..03ea8e525 100644 --- a/src/tv2-common/transitionSettings.ts +++ b/src/tv2-common/transitionSettings.ts @@ -7,10 +7,11 @@ export function TransitionSettings(config: TV2BlueprintConfig, part: PartDefinit return {} } - if (part.transition.style.match(/WIPE/i)) { + if (part.transition.style === TSR.AtemTransitionStyle.WIPE) { return WipeTransitionSettings(part.transition.duration) } - if (part.transition.style.match(/DIP/i)) { + + if (part.transition.style === TSR.AtemTransitionStyle.DIP) { return DipTransitionSettings(config, part.transition.duration) } return MixTransitionSettings(part.transition.duration) diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index d81ac1f4c..5d11c73c5 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -23,7 +23,6 @@ import { PartTime, PieceMetaData, SourceInfo, - TransitionFromString, TransitionSettings } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' @@ -135,9 +134,7 @@ function makeContentEVS( type: TSR.TimelineContentTypeAtem.ME, me: { input: atemInput, - transition: partDefinition.transition - ? TransitionFromString(partDefinition.transition.style) - : TSR.AtemTransitionStyle.CUT, + transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, transitionSettings: TransitionSettings(config, partDefinition) } }, diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index 53f06436d..6865c377d 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -25,7 +25,6 @@ import { PartDefinitionKam, PieceMetaData, TimeFromINewsField, - TransitionFromString, TransitionSettings } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' @@ -84,9 +83,7 @@ export async function CreatePartKam( type: TSR.TimelineContentTypeAtem.ME, me: { input: jingleDSK.Fill, - transition: partDefinition.transition - ? TransitionFromString(partDefinition.transition.style) - : TSR.AtemTransitionStyle.CUT, + transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, transitionSettings: TransitionSettings(config, partDefinition) } } @@ -136,9 +133,7 @@ export async function CreatePartKam( type: TSR.TimelineContentTypeAtem.ME, me: { input: Number(atemInput), - transition: partDefinition.transition - ? TransitionFromString(partDefinition.transition.style) - : TSR.AtemTransitionStyle.CUT, + transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, transitionSettings: TransitionSettings(config, partDefinition) } }, diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index cb38c587e..bd912c1c1 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -25,7 +25,6 @@ import { literal, PartDefinitionKam, SisyfosPersistMetaData, - TransitionFromString, TransitionSettings } from 'tv2-common' import { SharedOutputLayers, TallyTags } from 'tv2-constants' @@ -80,9 +79,7 @@ export async function OfftubeCreatePartKam( type: TSR.TimelineContentTypeAtem.ME, me: { input: jingleDSK.Fill, - transition: partDefinition.transition - ? TransitionFromString(partDefinition.transition.style) - : TSR.AtemTransitionStyle.CUT, + transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, transitionSettings: TransitionSettings(config, partDefinition) } } @@ -131,9 +128,7 @@ export async function OfftubeCreatePartKam( type: TSR.TimelineContentTypeAtem.ME, me: { input: Number(atemInput), - transition: partDefinition.transition - ? TransitionFromString(partDefinition.transition.style) - : TSR.AtemTransitionStyle.CUT, + transition: partDefinition.transition ? partDefinition.transition.style : TSR.AtemTransitionStyle.CUT, transitionSettings: TransitionSettings(config, partDefinition) } }, From 689fb1ddc376fb3969d518be17abbc0f9f23b313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Wed, 6 Jul 2022 13:22:52 +0200 Subject: [PATCH 151/184] fix: SOF-959 Rename attributes of GraphicsSetups configuration table + add new column. Rename GrpahicsINewsCode configuration to SelectedGraphicsSetupName as of the current implementation it has no relation to iNews --- src/tv2-common/blueprintConfig.ts | 5 +-- .../__tests__/config-manifest.spec.ts | 2 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 13 +++---- src/tv2_afvd_showstyle/config-manifests.ts | 34 ++++++++++++------- src/tv2_afvd_showstyle/getRundown.ts | 2 +- src/tv2_afvd_showstyle/getSegment.ts | 2 +- src/tv2_afvd_showstyle/helpers/config.ts | 15 ++++---- src/tv2_offtube_showstyle/helpers/config.ts | 9 ++--- 8 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index e80425b7a..4d96a6acb 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -38,10 +38,11 @@ export interface TableConfigSchema { } export interface TableConfigGraphicsSetup { - INewsCode: string - Concept: string + Name: string + VcpConcept: string OvlShowId: string FullShowId: string + DveLayoutFolder: string } export interface TV2StudioConfigBase { diff --git a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts index ef03b6536..9e7358d75 100644 --- a/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/config-manifest.spec.ts @@ -13,7 +13,7 @@ const blankShowStyleConfig: ShowStyleConfig = { CasparCGLoadingClip: '', Transitions: [{ Transition: '1' }, { Transition: '2' }], ShowstyleTransition: 'CUT', - GraphicsINewsCode: '', + SelectedGraphicsSetupName: '', GraphicsSetups: [], SchemaConfig: [] } diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index 3485a5ffc..12a1be104 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -1,4 +1,4 @@ -import { literal, parseMapStr } from 'tv2-common' +import { literal, parseMapStr, TableConfigGraphicsSetup } from 'tv2-common' import { defaultDSKConfig, StudioConfig } from '../../tv2_afvd_studio/helpers/config' import { ShowStyleConfig } from '../helpers/config' import { DefaultBreakerConfig } from './breakerConfigDefault' @@ -44,11 +44,12 @@ function prepareConfig( export const OVL_SHOW_ID = 'ovl-show-id' export const FULL_SHOW_ID = 'full-show-id' -export const DEFAULT_GRAPHICS_SETUP = { - INewsCode: 'SomeProfile', - Concept: 'SomeConcept', +export const DEFAULT_GRAPHICS_SETUP: TableConfigGraphicsSetup = { + Name: 'SomeProfile', + VcpConcept: 'SomeConcept', OvlShowId: OVL_SHOW_ID, - FullShowId: FULL_SHOW_ID + FullShowId: FULL_SHOW_ID, + DveLayoutFolder: 'folder/path' } // in here will be some mock configs that can be referenced paired with ro's for the tests @@ -263,7 +264,7 @@ export const defaultShowStyleConfig: ShowStyleConfig = { FadeOut: 0 } ], - GraphicsINewsCode: 'SomeProfile', + SelectedGraphicsSetupName: 'SomeProfile', GraphicsSetups: [DEFAULT_GRAPHICS_SETUP], Transitions: [{ Transition: '1' }, { Transition: '2' }], ShowstyleTransition: 'CUT', diff --git a/src/tv2_afvd_showstyle/config-manifests.ts b/src/tv2_afvd_showstyle/config-manifests.ts index daf496e1d..259a7c995 100644 --- a/src/tv2_afvd_showstyle/config-manifests.ts +++ b/src/tv2_afvd_showstyle/config-manifests.ts @@ -142,18 +142,18 @@ export const dveStylesManifest: ConfigManifestEntry = { ] } -const graphicProfileSetup: ConfigManifestEntry[] = [ +const graphicsSetups: ConfigManifestEntry[] = [ { id: 'GraphicsSetups', name: 'Graphics Setups', - description: 'Possible graphic profile setup', + description: 'Possible graphics setups', type: ConfigManifestEntryType.TABLE, required: false, defaultVal: [], columns: [ { - id: 'INewsCode', - name: 'iNews Command (*)', + id: 'Name', + name: 'Name', description: 'The code as it will appear in iNews', type: ConfigManifestEntryType.STRING, required: true, @@ -161,8 +161,8 @@ const graphicProfileSetup: ConfigManifestEntry[] = [ rank: 0 }, { - id: 'Concept', - name: 'Concept', + id: 'VcpConcept', + name: 'VCP Concept', rank: 1, required: true, defaultVal: '', @@ -172,7 +172,7 @@ const graphicProfileSetup: ConfigManifestEntry[] = [ }, { id: 'OvlShowId', - name: 'OVL Show ID', + name: 'Overlay Show-ID', rank: 2, required: true, defaultVal: '', @@ -182,21 +182,31 @@ const graphicProfileSetup: ConfigManifestEntry[] = [ }, { id: 'FullShowId', - name: 'FULL Show ID', + name: 'Fullscreen Show-ID', rank: 3, required: true, defaultVal: '', hint: '', description: 'UUID of the show used for FULL and WALL channels', type: ConfigManifestEntryType.STRING + }, + { + id: 'DveLayoutFolder', + name: 'DVE layout folder', + rank: 4, + required: true, + defaultVal: '', + hint: '', + description: 'Path to the folder containing the layouts for DVEs', + type: ConfigManifestEntryType.STRING } ], hint: '' }, { - id: 'GraphicsINewsCode', - name: 'Graphics Profile cue', - description: 'GRAPHICS_PROFILE cue from iNews', + id: 'SelectedGraphicsSetupName', + name: 'Graphic Setup name', + description: 'Name of the Graphic Setup that should be used', type: ConfigManifestEntryType.STRING, required: false, defaultVal: '' @@ -373,7 +383,7 @@ export const showStyleConfigManifest: ConfigManifestEntry[] = [ } ] }, - ...graphicProfileSetup, + ...graphicsSetups, ...schemaConfigManifest, { /* diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 39c89a481..4879ea805 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -1195,7 +1195,7 @@ function getBaseline(config: BlueprintConfig): BlueprintResultBaseline { content: { deviceType: TSR.DeviceType.VIZMSE, type: TSR.TimelineContentTypeVizMSE.CONCEPT, - concept: config.selectedGraphicsSetup.Concept + concept: config.selectedGraphicsSetup.VcpConcept } }) ] diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index fad4593aa..043572f0e 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -126,7 +126,7 @@ function insertSpecialPieces( config.showStyle.GraphicsSetups.forEach(graphicsSetup => { allShows.add(graphicsSetup.FullShowId) allShows.add(graphicsSetup.OvlShowId) - if (graphicsSetupsToInitialize.includes(graphicsSetup.INewsCode)) { + if (graphicsSetupsToInitialize.includes(graphicsSetup.Name)) { showsToInitialize.add(graphicsSetup.FullShowId) showsToInitialize.add(graphicsSetup.OvlShowId) } diff --git a/src/tv2_afvd_showstyle/helpers/config.ts b/src/tv2_afvd_showstyle/helpers/config.ts index 773346cfb..f5e7d4c36 100644 --- a/src/tv2_afvd_showstyle/helpers/config.ts +++ b/src/tv2_afvd_showstyle/helpers/config.ts @@ -14,21 +14,22 @@ export interface BlueprintConfig extends BlueprintConfigBase { export interface ShowStyleConfig extends TV2ShowstyleBlueprintConfigBase { WipesConfig: TableConfigItemValue - GraphicsINewsCode: string + SelectedGraphicsSetupName: string GraphicsSetups: TableConfigGraphicsSetup[] } -export function findGraphicsSetup(context: ICommonContext, config: ShowStyleConfig): TableConfigGraphicsSetup { +function findGraphicsSetup(context: ICommonContext, config: ShowStyleConfig): TableConfigGraphicsSetup { const foundTableConfigGraphicsSetup: TableConfigGraphicsSetup | undefined = config.GraphicsSetups.find( - tableConfigGraphicsSetup => tableConfigGraphicsSetup.INewsCode === config.GraphicsINewsCode + tableConfigGraphicsSetup => tableConfigGraphicsSetup.Name === config.SelectedGraphicsSetupName ) if (!foundTableConfigGraphicsSetup) { - context.logWarning(`No graphics setup found for profile ${config.GraphicsINewsCode})`) + context.logWarning(`No graphics setup found for profile: ${config.SelectedGraphicsSetupName}`) return { - INewsCode: '', - Concept: '', + Name: '', + VcpConcept: '', OvlShowId: '', - FullShowId: '' + FullShowId: '', + DveLayoutFolder: '' } } return foundTableConfigGraphicsSetup diff --git a/src/tv2_offtube_showstyle/helpers/config.ts b/src/tv2_offtube_showstyle/helpers/config.ts index ded7c48a9..3ad8906ad 100644 --- a/src/tv2_offtube_showstyle/helpers/config.ts +++ b/src/tv2_offtube_showstyle/helpers/config.ts @@ -38,16 +38,17 @@ export interface OfftubeShowStyleConfig extends TV2ShowstyleBlueprintConfigBase WipesConfig: TableConfigItemValue } -export function findGraphicsSetup( +function findGraphicsSetup( _context: ICommonContext, _config: TV2ShowstyleBlueprintConfigBase ): TableConfigGraphicsSetup { // just for type compatibility, not really supported in offtube return { - INewsCode: '', - Concept: '', + Name: '', + VcpConcept: '', OvlShowId: '', - FullShowId: '' + FullShowId: '', + DveLayoutFolder: '' } } From 0bbd730d036c5773dd24eecb45d00c1bb6c4162f Mon Sep 17 00:00:00 2001 From: ianshade Date: Mon, 18 Jul 2022 15:12:16 +0200 Subject: [PATCH 152/184] wip: refactor SourceInfo finding --- src/tv2-common/__tests__/frame-time.spec.ts | 33 +- src/tv2-common/actions/actionTypes.ts | 21 +- src/tv2-common/actions/executeAction.ts | 79 ++- src/tv2-common/blueprintConfig.ts | 9 +- src/tv2-common/content/dve.ts | 281 ++++------ src/tv2-common/content/server.ts | 45 +- src/tv2-common/cues/ekstern.ts | 37 +- src/tv2-common/cues/mixMinus.ts | 4 +- src/tv2-common/get-next-part-cue.spec.ts | 70 ++- src/tv2-common/getSegment.ts | 2 +- .../helpers/__tests__/serverResume.spec.ts | 20 +- .../helpers/postProcessDefinitions.ts | 12 +- src/tv2-common/helpers/sisyfos.ts | 213 +++++--- .../inewsConversion/converters/ParseBody.ts | 246 ++++++--- .../inewsConversion/converters/ParseCue.ts | 49 +- .../converters/__tests__/body-parser.spec.ts | 496 +++++++----------- .../converters/__tests__/cue-parser.spec.ts | 32 +- .../__tests__/find-target-pair.spec.ts | 4 - .../__tests__/part-to-parent-class.spec.ts | 13 +- src/tv2-common/layers/timelineLayers.ts | 7 - src/tv2-common/parts/server.ts | 5 - src/tv2-common/pieces/tags.ts | 5 +- src/tv2-common/sources.ts | 175 +++--- src/tv2-constants/enums.ts | 13 +- .../__tests__/addScript.spec.ts | 10 +- src/tv2_afvd_showstyle/__tests__/configs.ts | 11 +- src/tv2_afvd_showstyle/getRundown.ts | 220 ++++---- src/tv2_afvd_showstyle/helpers/content/dve.ts | 14 +- .../pieces/__tests__/grafikViz.spec.ts | 14 +- .../helpers/pieces/__tests__/lyd.spec.ts | 19 +- .../helpers/pieces/__tests__/telefon.spec.ts | 17 +- .../helpers/pieces/graphicPilot.ts | 52 +- .../helpers/pieces/routing.ts | 8 +- .../helpers/pieces/telefon.ts | 31 +- src/tv2_afvd_showstyle/migrations/hotkeys.ts | 6 +- src/tv2_afvd_showstyle/parts/evs.ts | 39 +- src/tv2_afvd_showstyle/parts/kam.ts | 14 +- .../__tests__/config-manifest.spec.ts | 2 +- .../__tests__/graphics.spec.ts | 12 +- src/tv2_afvd_studio/config-manifests.ts | 4 +- src/tv2_afvd_studio/helpers/config.ts | 13 +- src/tv2_afvd_studio/helpers/sources.ts | 16 +- src/tv2_afvd_studio/migrations/index.ts | 9 +- .../__tests__/actions.spec.ts | 36 +- .../content/OfftubeDVEContent.ts | 14 +- .../cues/OfftubeGraphics.ts | 6 +- .../cues/OfftubePgmClean.ts | 19 +- src/tv2_offtube_showstyle/getRundown.ts | 82 +-- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 14 +- src/tv2_offtube_studio/helpers/config.ts | 11 +- src/tv2_offtube_studio/helpers/sources.ts | 15 +- 51 files changed, 1255 insertions(+), 1324 deletions(-) diff --git a/src/tv2-common/__tests__/frame-time.spec.ts b/src/tv2-common/__tests__/frame-time.spec.ts index f0f630091..a61246592 100644 --- a/src/tv2-common/__tests__/frame-time.spec.ts +++ b/src/tv2-common/__tests__/frame-time.spec.ts @@ -1,9 +1,18 @@ import { IBlueprintPiece, PieceLifespan } from '@tv2media/blueprints-integration' -import { CueType } from 'tv2-constants' +import { CueType, SourceType } from 'tv2-constants' import { CreateTiming } from '../cueTiming' +import { SourceDefinitionEkstern } from '../inewsConversion' import { CueDefinitionEkstern } from '../inewsConversion/converters/ParseCue' import { literal } from '../util' +const EKSTERN_SOURCE: SourceDefinitionEkstern = { + sourceType: SourceType.REMOTE, + variant: 'LIVE', + id: '1', + raw: 'Live 1', + name: 'LIVE 1' +} + describe('CreateTiming', () => { test('Start only (seconds)', () => { const time: CueDefinitionEkstern = { @@ -12,7 +21,7 @@ describe('CreateTiming', () => { seconds: 1 }, iNewsCommand: '', - source: '' + sourceDefinition: EKSTERN_SOURCE } const result = CreateTiming(time, 4000) expect(result).toEqual( @@ -33,7 +42,7 @@ describe('CreateTiming', () => { frames: 1 }, iNewsCommand: '', - source: '' + sourceDefinition: EKSTERN_SOURCE } const result = CreateTiming(time, 4000) expect(result).toEqual( @@ -55,7 +64,7 @@ describe('CreateTiming', () => { frames: 1 }, iNewsCommand: '', - source: '' + sourceDefinition: EKSTERN_SOURCE } const result = CreateTiming(time, 4000) expect(result).toEqual( @@ -76,7 +85,7 @@ describe('CreateTiming', () => { seconds: 1 }, iNewsCommand: '', - source: '' + sourceDefinition: EKSTERN_SOURCE } const result = CreateTiming(time, 4000) expect(result).toEqual( @@ -97,7 +106,7 @@ describe('CreateTiming', () => { frames: 1 }, iNewsCommand: '', - source: '' + sourceDefinition: EKSTERN_SOURCE } const result = CreateTiming(time, 4000) expect(result).toEqual( @@ -119,7 +128,7 @@ describe('CreateTiming', () => { frames: 1 }, iNewsCommand: '', - source: '' + sourceDefinition: EKSTERN_SOURCE } const result = CreateTiming(time, 4000) expect(result).toEqual( @@ -140,7 +149,7 @@ describe('CreateTiming', () => { infiniteMode: 'B' }, iNewsCommand: '', - source: '' + sourceDefinition: EKSTERN_SOURCE } const result = CreateTiming(time, 4000) expect(result).toEqual( @@ -160,7 +169,7 @@ describe('CreateTiming', () => { infiniteMode: 'S' }, iNewsCommand: '', - source: '' + sourceDefinition: EKSTERN_SOURCE } const result = CreateTiming(time, 4000) expect(result).toEqual( @@ -180,7 +189,7 @@ describe('CreateTiming', () => { infiniteMode: 'O' }, iNewsCommand: '', - source: '' + sourceDefinition: EKSTERN_SOURCE } const result = CreateTiming(time, 4000) expect(result).toEqual( @@ -203,7 +212,7 @@ describe('CreateTiming', () => { seconds: 1 }, iNewsCommand: '', - source: '' + sourceDefinition: EKSTERN_SOURCE } const result = CreateTiming(time, 4000) expect(result).toEqual( @@ -227,7 +236,7 @@ describe('CreateTiming', () => { infiniteMode: 'B' }, iNewsCommand: '', - source: '' + sourceDefinition: EKSTERN_SOURCE } const result = CreateTiming(time, 4000) expect(result).toEqual( diff --git a/src/tv2-common/actions/actionTypes.ts b/src/tv2-common/actions/actionTypes.ts index 86aa3997f..1cf3083f6 100644 --- a/src/tv2-common/actions/actionTypes.ts +++ b/src/tv2-common/actions/actionTypes.ts @@ -1,7 +1,14 @@ -import { SourceLayerType } from '@tv2media/blueprints-integration' import { AdlibActionType } from 'tv2-constants' import { DVEConfigInput } from '../helpers' -import { CueDefinitionDVE, CueDefinitionGraphic, GraphicInternal, PartDefinition } from '../inewsConversion' +import { + CueDefinitionDVE, + CueDefinitionGraphic, + GraphicInternal, + PartDefinition, + SourceDefinition, + SourceDefinitionEkstern, + SourceDefinitionKam +} from '../inewsConversion' export interface ActionBase { type: AdlibActionType @@ -45,23 +52,19 @@ export interface ActionSelectJingle extends ActionBase { export interface ActionCutToCamera extends ActionBase { type: AdlibActionType.CUT_TO_CAMERA queue: boolean - name: string + sourceDefinition: SourceDefinitionKam } export interface ActionCutToRemote extends ActionBase { type: AdlibActionType.CUT_TO_REMOTE - name: string - port: number + sourceDefinition: SourceDefinitionEkstern } export interface ActionCutSourceToBox extends ActionBase { type: AdlibActionType.CUT_SOURCE_TO_BOX - sourceType: SourceLayerType name: string - port: number box: number - vo?: boolean - server?: boolean + sourceDefinition: SourceDefinition } export interface ActionCommentatorSelectServer extends ActionBase { diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index e794d4b62..c52d65510 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -13,7 +13,6 @@ import { IBlueprintResolvedPieceInstance, IShowStyleUserContext, PieceLifespan, - SourceLayerType, SplitsContent, TSR, VTContent, @@ -43,11 +42,8 @@ import { DVESources, EvaluateCuesOptions, executeWithContext, - FindSourceInfoStrict, GetDVETemplate, GetFullGrafikTemplateName, - GetSisyfosTimelineObjForCamera, - GetSisyfosTimelineObjForEkstern, GraphicPilot, IsTargetingOVL, ITV2ActionExecutionContext, @@ -68,6 +64,7 @@ import { SharedGraphicLLayer, SharedOutputLayers, SharedSourceLayers, + SourceType, TallyTags } from 'tv2-constants' import _ = require('underscore') @@ -76,6 +73,8 @@ import { CreateFullDataStore, GetEnableForWall, getServerPosition, + GetSisyfosTimelineObjForCamera, + GetSisyfosTimelineObjForRemote, PilotGeneratorSettings, ServerSelectMode } from '../helpers' @@ -91,6 +90,7 @@ import { GetTagForLive, GetTagForTransition } from '../pieces' +import { FindSourceInfoByDefinition } from '../sources' import { assertUnreachable } from '../util' import { ActionCommentatorSelectJingle, @@ -528,10 +528,10 @@ async function executeActionSelectServerClip< function dveContainsServer(sources: DVESources) { return ( - sources.INP1?.match(/SERVER/i) || - sources.INP2?.match(/SERVER/i) || - sources.INP3?.match(/SERVER/i) || - sources.INP4?.match(/SERVER/i) + sources.INP1?.sourceType === SourceType.Server || + sources.INP2?.sourceType === SourceType.Server || + sources.INP3?.sourceType === SourceType.Server || + sources.INP4?.sourceType === SourceType.Server ) } @@ -766,10 +766,10 @@ async function executeActionSelectDVELayout< } const sources: DVESources = { - INP1: 'DEFAULT', - INP2: 'DEFAULT', - INP3: 'DEFAULT', - INP4: 'DEFAULT' + INP1: { sourceType: SourceType.DEFAULT }, + INP2: { sourceType: SourceType.DEFAULT }, + INP3: { sourceType: SourceType.DEFAULT }, + INP4: { sourceType: SourceType.DEFAULT } } const externalId = generateExternalId(context, actionId, [userData.config.DVEName]) @@ -1094,16 +1094,16 @@ async function executeActionCutToCamera< ) { const config = settings.getConfig(context) - const externalId = generateExternalId(context, actionId, [userData.name]) + const externalId = generateExternalId(context, actionId, [userData.sourceDefinition.name]) const part = literal({ externalId, - title: `KAM ${userData.name}`, + title: userData.sourceDefinition.name, metaData: {}, expectedDuration: 0 }) - const sourceInfoCam = FindSourceInfoStrict(context, config.sources, SourceLayerType.CAMERA, `Kam ${userData.name}`) + const sourceInfoCam = FindSourceInfoByDefinition(config.sources, userData.sourceDefinition) if (sourceInfoCam === undefined) { return } @@ -1116,12 +1116,7 @@ async function executeActionCutToCamera< const currentKam = currentPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.Cam) - const camSisyfos = GetSisyfosTimelineObjForCamera( - context, - config, - `KAM ${userData.name}`, - settings.LLayer.Sisyfos.StudioMics - ) + const camSisyfos = GetSisyfosTimelineObjForCamera(config, sourceInfoCam, false, settings.LLayer.Sisyfos.StudioMics) const kamPiece = literal({ externalId, @@ -1137,7 +1132,7 @@ async function executeActionCutToCamera< isPieceInjectedInPart: true }) }, - tags: [GetTagForKam(userData.name)], + tags: [GetTagForKam(userData.sourceDefinition.name)], content: { timelineObjects: _.compact([ literal({ @@ -1155,7 +1150,7 @@ async function executeActionCutToCamera< }, classes: ['adlib_deparent'] }), - camSisyfos + ...camSisyfos ]) } }) @@ -1217,10 +1212,9 @@ async function executeActionCutToRemote< ) { const config = settings.getConfig(context) - const externalId = generateExternalId(context, actionId, [userData.name]) + const externalId = generateExternalId(context, actionId, [userData.sourceDefinition.name]) - const feed = userData.name.match(/^F(.+).*$/) // TODO: fix when refactoring FindSourceInfo - const title = feed ? `FEED ${feed[1]}` : `LIVE ${userData.name}` + const title = userData.sourceDefinition.name const part = literal({ externalId, @@ -1229,12 +1223,18 @@ async function executeActionCutToRemote< expectedDuration: 0 }) - const eksternSisyfos: TSR.TimelineObjSisyfosAny[] = [ - ...GetSisyfosTimelineObjForEkstern(context, config.sources, `Live ${userData.name}`), - GetSisyfosTimelineObjForCamera(context, config, 'telefon', settings.LLayer.Sisyfos.StudioMics) - ] + const sourceInfo = FindSourceInfoByDefinition(config.sources, userData.sourceDefinition) + if (sourceInfo === undefined) { + context.notifyUserWarning(`Invalid source: ${userData.sourceDefinition.name}`) + return + } + + const eksternSisyfos: TSR.TimelineObjSisyfosAny[] = GetSisyfosTimelineObjForRemote( + config, + sourceInfo, + settings.LLayer.Sisyfos.StudioMics + ) - const sourceInfo = FindSourceInfoStrict(context, config.sources, SourceLayerType.REMOTE, `Live ${userData.name}`) const sisyfosPersistMetaData: SisyfosPersistMetaData = sourceInfo !== undefined ? { @@ -1257,7 +1257,7 @@ async function executeActionCutToRemote< metaData: { sisyfosPersistMetaData }, - tags: [GetTagForLive(userData.name)], + tags: [GetTagForLive(userData.sourceDefinition)], content: { timelineObjects: _.compact([ literal({ @@ -1269,7 +1269,7 @@ async function executeActionCutToRemote< deviceType: TSR.DeviceType.ATEM, type: TSR.TimelineContentTypeAtem.ME, me: { - input: userData.port, + input: sourceInfo.port, transition: TSR.AtemTransitionStyle.CUT } }, @@ -1354,10 +1354,7 @@ async function executeActionCutSourceToBox< const containsServerBefore = dveContainsServer(meta.sources) - // ADD 'VO' to VO sources - const name = `${userData.name}${userData.vo && !userData.name.match(/VO/i) ? 'VO' : ''}` - - meta.sources[`INP${userData.box + 1}` as keyof DVEPieceMetaData['sources']] = name + meta.sources[`INP${userData.box + 1}` as keyof DVEPieceMetaData['sources']] = userData.sourceDefinition const containsServerAfter = dveContainsServer(meta.sources) @@ -1381,14 +1378,6 @@ async function executeActionCutSourceToBox< undefined, mediaPlayerSession ) - if (userData.vo) { - const studioMics = GetSisyfosTimelineObjForCamera(context, config, 'evs', settings.LLayer.Sisyfos.StudioMics) - // Replace any existing instances of studio mics with VO values - newPieceContent.content.timelineObjects = newPieceContent.content.timelineObjects.filter( - obj => studioMics.layer !== obj.layer - ) - newPieceContent.content.timelineObjects.push(studioMics) - } let newDVEPiece: IBlueprintPiece = { ...modifiedPiece.piece, content: newPieceContent.content, metaData: meta } if (!containsServerBefore || !containsServerAfter) { diff --git a/src/tv2-common/blueprintConfig.ts b/src/tv2-common/blueprintConfig.ts index 7d9daa1b6..c59bfb2e6 100644 --- a/src/tv2-common/blueprintConfig.ts +++ b/src/tv2-common/blueprintConfig.ts @@ -120,9 +120,16 @@ export interface TV2StudioConfigBase { } } +export interface SourceMapping { + cameras: SourceInfo[] + lives: SourceInfo[] + feeds: SourceInfo[] + replays: SourceInfo[] +} + export interface TV2StudioBlueprintConfigBase { studio: StudioConfig - sources: SourceInfo[] + sources: SourceMapping mediaPlayers: MediaPlayerConfig // Atem Input Ids dsk: TableConfigItemDSK[] } diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 5f9bd975b..53616a6a3 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -2,7 +2,6 @@ import { CameraContent, GraphicsContent, IShowStyleUserContext, - IStudioUserContext, RemoteContent, SourceLayerType, SplitsContent, @@ -18,23 +17,26 @@ import { DVEParentClass, DVESources, FindDSKFullGFX, - FindSourceInfoStrict, - GetSisyfosTimelineObjForCamera, - GetSisyfosTimelineObjForEVS, + FindSourceInfoByDefinition, JoinAssetToFolder, literal, PartDefinition, - SourceInfo, - SourceInfoType, TimelineBlueprintExt, TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' -import { ControlClasses, MEDIA_PLAYER_AUTO, SharedGraphicLLayer } 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' -import { CreateHTMLRendererContent } from '../helpers' +import { + CreateHTMLRendererContent, + GetSisyfosTimelineObjForCamera, + GetSisyfosTimelineObjForFull, + GetSisyfosTimelineObjForRemote, + GetSisyfosTimelineObjForReplay +} from '../helpers' +import { SourceDefinition } from '../inewsConversion' import { EnableServer } from './server' export interface DVEConfigBox { @@ -112,19 +114,8 @@ export interface DVEPieceMetaData { serverPlaybackTiming?: Array<{ start?: number; end?: number }> } -export interface DVETimelineObjectGenerators { - GetSisyfosTimelineObjForEkstern: ( - context: IStudioUserContext, - sources: SourceInfo[], - sourceType: string, - enable?: TSR.Timeline.TimelineEnable - ) => TSR.TSRTimelineObj[] - GetLayersForEkstern: (context: IStudioUserContext, sources: SourceInfo[], sourceType: string) => string[] -} - export interface DVEOptions { dveLayers: DVELayers - dveTimelineGenerators: DVETimelineObjectGenerators boxMappings: [string, string, string, string] /** All audio layers */ AUDIO_LAYERS: string[] @@ -209,7 +200,7 @@ export function MakeContentDVE2< const inputs = dveConfig.DVEInputs ? dveConfig.DVEInputs.toString().split(';') : '1:INP1;2:INP2;3:INP3;4:INP4'.split(';') - const boxMap: Array<{ source: string }> = [] + const boxMap: Array = [] const classes: string[] = [] @@ -226,41 +217,15 @@ export function MakeContentDVE2< if (sources) { const prop = sources[fromCue as keyof DVESources] - if (prop?.match(/[K|C]AM(?:era)? ?.*/i)) { - const match = prop.match(/[K|C]AM(?:era)? ?(.*)/i) as RegExpExecArray - - boxMap[targetBox - 1] = { source: `KAM ${match[1]}` } - } else if (prop?.match(/LIVE ?.*/i)) { - const match = prop.match(/LIVE ?(.*)/i) as RegExpExecArray - - boxMap[targetBox - 1] = { source: `LIVE ${match[1]}` } - } else if (prop?.match(/FEED ?.*/i)) { - const match = prop.match(/FEED ?(.*)/i) as RegExpExecArray - - boxMap[targetBox - 1] = { source: `FEED ${match[1]}` } - } else if (prop?.match(/full/i)) { - boxMap[targetBox - 1] = { source: `ENGINE FULL` } - } else if (prop?.match(/EVS ?(?:\d+)? ?.*/i)) { - const match = prop.match(/EVS ?(\d+)? ?(.*)/i) as RegExpExecArray - - boxMap[targetBox - 1] = { source: `EVS${match[1]} ${match[2]}` } - } else if (/EPSIO/.test(prop ?? '')) { - boxMap[targetBox - 1] = { source: 'EPSIO' } - } else if (prop?.match(/DEFAULT/)) { - boxMap[targetBox - 1] = { source: `DEFAULT SOURCE` } - } else if (prop) { - boxMap[targetBox - 1] = { source: videoId ? `SERVER ${videoId}` : prop } + if (prop) { + boxMap[targetBox - 1] = prop.sourceType !== SourceType.Server || videoId ? prop : undefined } else { - if (videoId) { - boxMap[targetBox - 1] = { source: `SERVER ${videoId}` } - } else { - context.notifyUserWarning(`Missing mapping for ${targetBox}`) - boxMap[targetBox - 1] = { source: '' } - } + context.notifyUserWarning(`Missing mapping for ${targetBox}`) + boxMap[targetBox - 1] = undefined } } else { // Need something to keep the layout etc - boxMap[targetBox - 1] = { source: '' } + boxMap[targetBox - 1] = undefined } }) @@ -269,158 +234,130 @@ export function MakeContentDVE2< const boxSources: Array<(VTContent | CameraContent | RemoteContent | GraphicsContent) & SplitsContentBoxProperties> = [] - const setBoxSource = (num: number, sourceInfo: SourceInfo, label: string) => { + const setBoxSource = (num: number, sourceInfo: { port: number; sourceLayerType: SourceLayerType }) => { if (boxes[num]) { - boxes[num].source = Number(sourceInfo.port) + boxes[num].source = sourceInfo.port boxSources.push({ // TODO - draw box geometry - ...boxSource(sourceInfo, label), + ...boxSource(sourceInfo), ...literal({ studioLabel: '', - switcherInput: Number(sourceInfo.port) + switcherInput: sourceInfo.port }) }) } } const setBoxToBlack = (num: number) => { - setBoxSource( - num, - literal({ - type: SourceLayerType.UNKNOWN, - id: 'black', - port: AtemSourceIndex.Blk - }), - 'Black' - ) + setBoxSource(num, { + port: AtemSourceIndex.Blk, + sourceLayerType: SourceLayerType.UNKNOWN + }) } let valid = true let server = false boxMap.forEach((mappingFrom, num) => { - if (mappingFrom === undefined || mappingFrom.source === '') { + if (mappingFrom === undefined) { 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}`) + setBoxToBlack(num) valid = false } } else { - const props = mappingFrom.source.split(' ') - const sourceType = props[0] - const sourceInput = props[1] - if ((!sourceType || !sourceInput) && !mappingFrom.source.match(/EVS|EPSIO|SERVER/i)) { - context.notifyUserWarning(`Invalid DVE source: ${mappingFrom.source}`) - setBoxToBlack(num) - return - } const audioEnable: TSR.Timeline.TimelineEnable = { while: `1` } - if (sourceType.match(/DEFAULT/)) { - setBoxSource( - num, - { - type: SourceLayerType.UNKNOWN, - id: 'DEFAULT', + switch (mappingFrom.sourceType) { + case SourceType.DEFAULT: + setBoxSource(num, { + sourceLayerType: SourceLayerType.UNKNOWN, port: config.studio.AtemSource.Default - }, - mappingFrom.source - ) - } else if (/KAM/i.test(sourceType)) { - const sourceInfoCam = FindSourceInfoStrict(context, config.sources, SourceLayerType.CAMERA, mappingFrom.source) - if (sourceInfoCam === undefined) { - context.notifyUserWarning(`Invalid source: ${mappingFrom.source}`) - setBoxToBlack(num) - valid = false - return - } - - setBoxSource(num, sourceInfoCam, mappingFrom.source) - dveTimeline.push( - GetSisyfosTimelineObjForCamera( - context, - config, - mappingFrom.source, - dveGeneratorOptions.dveLayers.SisyfosLLayer.StudioMics, - audioEnable + }) + break + case SourceType.Kam: + const sourceInfoCam = FindSourceInfoByDefinition(config.sources, mappingFrom) + if (sourceInfoCam === undefined) { + context.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) + setBoxToBlack(num) + valid = false + return + } + + setBoxSource(num, sourceInfoCam) + dveTimeline.push( + ...GetSisyfosTimelineObjForCamera( + config, + sourceInfoCam, + mappingFrom.minusMic, + dveGeneratorOptions.dveLayers.SisyfosLLayer.StudioMics, + audioEnable + ) ) - ) - } else if (/LIVE|FEED/i.test(sourceType)) { - const sourceInfoLive = FindSourceInfoStrict(context, config.sources, SourceLayerType.REMOTE, mappingFrom.source) - if (sourceInfoLive === undefined) { - context.notifyUserWarning(`Invalid source: ${mappingFrom.source}`) - setBoxToBlack(num) - valid = false - return - } - - setBoxSource(num, sourceInfoLive, mappingFrom.source) - dveTimeline.push( - ...dveGeneratorOptions.dveTimelineGenerators.GetSisyfosTimelineObjForEkstern( - context, - config.sources, - mappingFrom.source, - audioEnable + break + case SourceType.REMOTE: + const sourceInfoLive = FindSourceInfoByDefinition(config.sources, mappingFrom) + if (sourceInfoLive === undefined) { + context.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) + setBoxToBlack(num) + valid = false + return + } + + setBoxSource(num, sourceInfoLive) + dveTimeline.push( + ...GetSisyfosTimelineObjForRemote( + config, + sourceInfoLive, + dveGeneratorOptions.dveLayers.SisyfosLLayer.StudioMics, + audioEnable + ) ) - ) - } else if (/EVS|EPSIO/.test(sourceType)) { - const sourceInfoDelayedPlayback = FindSourceInfoStrict( - context, - config.sources, - SourceLayerType.LOCAL, - mappingFrom.source - ) - if (sourceInfoDelayedPlayback === undefined) { - context.notifyUserWarning(`Invalid source: ${mappingFrom.source}`) - setBoxToBlack(num) - valid = false - return - } - - setBoxSource(num, sourceInfoDelayedPlayback, mappingFrom.source) - dveTimeline.push( - GetSisyfosTimelineObjForEVS(sourceInfoDelayedPlayback, /VO|EPSIO/i.test(mappingFrom.source)), - GetSisyfosTimelineObjForCamera(context, config, 'evs', dveGeneratorOptions.dveLayers.SisyfosLLayer.StudioMics) - ) - } else if (/ENGINE/i.test(sourceType)) { - if (sourceInput.match(/full/i)) { - const sourceInfoFull: SourceInfo = { - type: SourceLayerType.GRAPHICS, - id: 'full', - port: FindDSKFullGFX(config).Fill + break + case SourceType.EVS: + const sourceInfoReplay = FindSourceInfoByDefinition(config.sources, mappingFrom) + if (sourceInfoReplay === undefined) { + context.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) + setBoxToBlack(num) + valid = false + return } - setBoxSource(num, sourceInfoFull, mappingFrom.source) + + setBoxSource(num, sourceInfoReplay) dveTimeline.push( - GetSisyfosTimelineObjForCamera( - context, + ...GetSisyfosTimelineObjForReplay( config, - 'full', + sourceInfoReplay, + !!mappingFrom.vo, dveGeneratorOptions.dveLayers.SisyfosLLayer.StudioMics ) ) - } else { - context.notifyUserWarning(`Unsupported engine for DVE: ${sourceInput}`) - setBoxToBlack(num) - } - } else if (/SERVER/i.test(sourceType)) { - server = true - setBoxSource( - num, - { - type: SourceLayerType.VT, - id: 'SERVER', + break + case SourceType.Grafik: + if (mappingFrom.name === 'FULL') { + setBoxSource(num, { + sourceLayerType: SourceLayerType.GRAPHICS, + port: FindDSKFullGFX(config).Fill + }) + dveTimeline.push( + ...GetSisyfosTimelineObjForFull(config, dveGeneratorOptions.dveLayers.SisyfosLLayer.StudioMics) + ) + } else { + context.notifyUserWarning(`Unsupported engine for DVE: ${mappingFrom.name}`) + setBoxToBlack(num) + } + break + case SourceType.Server: + server = true + setBoxSource(num, { + sourceLayerType: SourceLayerType.VT, port: -1 - }, - mappingFrom.source - ) - return - } else { - context.notifyUserWarning(`Unknown source type for DVE: ${mappingFrom.source}`) - setBoxToBlack(num) - valid = false + }) + break } } }) @@ -570,18 +507,16 @@ export function MakeContentDVE2< } } -function boxSource( - info: SourceInfo, - label: string -): { - studioLabel: string +function boxSource(info: { + port: number + sourceLayerType: SourceLayerType +}): { switcherInput: number - type: SourceInfoType + type: SourceLayerType } { return { - studioLabel: label, switcherInput: info.port, - type: info.type + type: info.sourceLayerType } } diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 42b7285b8..2fbf5962d 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -1,13 +1,7 @@ -import { - IShowStyleUserContext, - TimelineObjectCoreExt, - TSR, - VTContent, - WithTimeline -} from '@tv2media/blueprints-integration' +import { TimelineObjectCoreExt, TSR, VTContent, WithTimeline } from '@tv2media/blueprints-integration' import { AddParentClass, - GetSisyfosTimelineObjForCamera, + GetSisyfosTimelineObjForServer, literal, PartDefinition, ServerParentClass, @@ -62,7 +56,6 @@ export function GetVTContentProperties( } export function MakeContentServer( - context: IShowStyleUserContext, file: string, mediaPlayerSessionId: string, partDefinition: PartDefinition, @@ -77,7 +70,6 @@ export function MakeContentServer( ...GetVTContentProperties(config, file, seek, sourceDuration), ignoreMediaObjectStatus: true, timelineObjects: GetServerTimeline( - context, file, mediaPlayerSessionId, partDefinition, @@ -91,7 +83,6 @@ export function MakeContentServer( } function GetServerTimeline( - context: IShowStyleUserContext, file: string, mediaPlayerSessionId: string, partDefinition: PartDefinition, @@ -129,30 +120,20 @@ function GetServerTimeline( mediaOffObj.enable = { while: `!${serverEnableClass}` } mediaOffObj.content.playing = false + const audioEnable = { + while: serverEnableClass + } return literal([ mediaObj, mediaOffObj, - - literal({ - id: '', - enable: { - while: serverEnableClass - }, - priority: 1, - layer: sourceLayers.Sisyfos.ClipPending, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: voLevels ? 2 : 1 - }, - metaData: { - mediaPlayerSession: mediaPlayerSessionId - }, - classes: [] - }), - ...(voLevels - ? [GetSisyfosTimelineObjForCamera(context, config, 'server', sourceLayers.Sisyfos.StudioMicsGroup)] - : []), + ...GetSisyfosTimelineObjForServer( + config, + !!voLevels, + sourceLayers.Sisyfos.ClipPending, + mediaPlayerSessionId, + sourceLayers.Sisyfos.StudioMicsGroup, + audioEnable + ), ...(sourceLayers.ATEM.ServerLookaheadAux ? [ literal({ diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index 5aff49b9c..3b9f0d947 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -5,7 +5,6 @@ import { IShowStyleUserContext, PieceLifespan, RemoteContent, - SourceLayerType, TimelineObjectCoreExt, TSR, WithTimeline @@ -15,9 +14,6 @@ import { createEmptyObject, CueDefinitionEkstern, EksternParentClass, - FindSourceInfoStrict, - GetSisyfosTimelineObjForCamera, - GetSisyfosTimelineObjForEkstern, literal, PartDefinition, PartToParentClass, @@ -28,7 +24,9 @@ import { TV2StudioConfigBase } from 'tv2-common' import { ControlClasses, SharedOutputLayers } from 'tv2-constants' +import { GetSisyfosTimelineObjForRemote } from '../helpers' import { GetTagForLive } from '../pieces' +import { FindSourceInfoByDefinition } from '../sources' interface EksternLayers { SourceLayer: { @@ -58,22 +56,9 @@ export function EvaluateEksternBase< adlib?: boolean, rank?: number ) { - const matchesEksternSource = /^(?:LIVE|FEED) ?([^\s]+)(?: (.+))?$/i - const eksternProps = parsedCue.source.match(matchesEksternSource) - if (!eksternProps) { - context.notifyUserWarning(`No source entered for EKSTERN`) - part.invalid = true - return - } - const source = eksternProps[1] - if (!source) { - context.notifyUserWarning(`Could not find live source for ${parsedCue.source}`) - part.invalid = true - return - } - const sourceInfoEkstern = FindSourceInfoStrict(context, config.sources, SourceLayerType.REMOTE, parsedCue.source) + const sourceInfoEkstern = FindSourceInfoByDefinition(config.sources, parsedCue.sourceDefinition) if (sourceInfoEkstern === undefined) { - context.notifyUserWarning(`${parsedCue.source} does not exist in this studio`) + context.notifyUserWarning(`${parsedCue.sourceDefinition.raw} does not exist in this studio`) part.invalid = true return } @@ -84,7 +69,7 @@ export function EvaluateEksternBase< literal({ _rank: rank || 0, externalId: partId, - name: eksternProps[0], + name: parsedCue.sourceDefinition.name, outputLayerId: SharedOutputLayers.PGM, sourceLayerId: layersEkstern.SourceLayer.PgmLive, toBeQueued: true, @@ -121,8 +106,7 @@ export function EvaluateEksternBase< classes: [ControlClasses.LiveSourceOnAir] }), - ...GetSisyfosTimelineObjForEkstern(context, config.sources, parsedCue.source), - GetSisyfosTimelineObjForCamera(context, config, 'telefon', layersEkstern.Sisyfos.StudioMics) + ...GetSisyfosTimelineObjForRemote(config, sourceInfoEkstern, layersEkstern.Sisyfos.StudioMics) ]) }) }) @@ -131,7 +115,7 @@ export function EvaluateEksternBase< pieces.push( literal({ externalId: partId, - name: eksternProps[0], + name: parsedCue.sourceDefinition.name, enable: { start: 0 }, @@ -146,7 +130,7 @@ export function EvaluateEksternBase< acceptPersistAudio: sourceInfoEkstern.acceptPersistAudio }) }, - tags: [GetTagForLive(sourceInfoEkstern.id)], + tags: [GetTagForLive(parsedCue.sourceDefinition)], content: literal>({ studioLabel: '', switcherInput: atemInput, @@ -176,12 +160,11 @@ export function EvaluateEksternBase< } }, ...(AddParentClass(config, partDefinition) - ? { classes: [EksternParentClass('studio0', parsedCue.source)] } + ? { classes: [EksternParentClass('studio0', parsedCue.sourceDefinition.name)] } : {}) }), - ...GetSisyfosTimelineObjForEkstern(context, config.sources, parsedCue.source), - GetSisyfosTimelineObjForCamera(context, config, 'telefon', layersEkstern.Sisyfos.StudioMics) + ...GetSisyfosTimelineObjForRemote(config, sourceInfoEkstern, layersEkstern.Sisyfos.StudioMics) ]) }) }) diff --git a/src/tv2-common/cues/mixMinus.ts b/src/tv2-common/cues/mixMinus.ts index 85293c9e8..e245482f3 100644 --- a/src/tv2-common/cues/mixMinus.ts +++ b/src/tv2-common/cues/mixMinus.ts @@ -7,7 +7,7 @@ import { TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { CueDefinitionMixMinus, FindSourceByName, literal, PartDefinition } from 'tv2-common' +import { CueDefinitionMixMinus, FindSourceInfoByName, literal, PartDefinition } from 'tv2-common' import { ControlClasses, SharedATEMLLayer, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' import { TV2BlueprintConfig } from '../blueprintConfig' @@ -18,7 +18,7 @@ export function EvaluateCueMixMinus( part: PartDefinition, parsedCue: CueDefinitionMixMinus ) { - const sourceInfoMixMinus = FindSourceByName(context, config.sources, parsedCue.source) + const sourceInfoMixMinus = FindSourceInfoByName(config.sources, parsedCue.source) if (sourceInfoMixMinus === undefined) { context.notifyUserWarning(`${parsedCue.source} does not exist in this studio (MINUSKAM)`) return diff --git a/src/tv2-common/get-next-part-cue.spec.ts b/src/tv2-common/get-next-part-cue.spec.ts index a6ab0c7de..eb3771848 100644 --- a/src/tv2-common/get-next-part-cue.spec.ts +++ b/src/tv2-common/get-next-part-cue.spec.ts @@ -6,17 +6,29 @@ import { literal, PartDefinitionKam } from 'tv2-common' -import { CueType, PartType } from 'tv2-constants' -import { CueDefinitionGraphic, GraphicInternal } from './inewsConversion' +import { CueType, PartType, SourceType } from 'tv2-constants' +import { CueDefinitionGraphic, GraphicInternal, SourceDefinitionKam } from './inewsConversion' import { GetNextPartCue } from './nextPartCue' +const SOURCE_DEFINITION_KAM_1: SourceDefinitionKam = { + sourceType: SourceType.Kam, + id: '1', + raw: 'Kam 1', + minusMic: false, + name: 'KAM 1' +} +const SOURCE_DEFINITION_KAM_2: SourceDefinitionKam = { + sourceType: SourceType.Kam, + id: '2', + raw: 'Kam 2', + minusMic: false, + name: 'KAM 2' +} const partDefinitionTest1: PartDefinitionKam = { type: PartType.Kam, externalId: 'test-part', rawType: 'KAM 1', - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, fields: {}, script: '', modified: 0, @@ -35,7 +47,13 @@ const partDefinitionTest1: PartDefinitionKam = { // Ekstern 1 - (index 1) literal({ type: CueType.Ekstern, - source: '1', + sourceDefinition: { + sourceType: SourceType.REMOTE, + variant: 'LIVE', + id: '1', + raw: 'Live 1', + name: 'LIVE 1' + }, iNewsCommand: 'EKSTERN' }), literal>({ @@ -63,7 +81,13 @@ const partDefinitionTest1: PartDefinitionKam = { // Ekstern 2 - (index 4) literal({ type: CueType.Ekstern, - source: '2', + sourceDefinition: { + sourceType: SourceType.REMOTE, + variant: 'LIVE', + id: '2', + raw: 'Live 2', + name: 'LIVE 2' + }, iNewsCommand: 'EKSTERN' }), literal>({ @@ -98,8 +122,8 @@ const partDefinitionTest1: PartDefinitionKam = { type: CueType.DVE, template: 'MORBARN', sources: { - INP1: 'Kam 1', - INP2: 'Kam 2' + INP1: SOURCE_DEFINITION_KAM_1, + INP2: SOURCE_DEFINITION_KAM_2 }, labels: [], iNewsCommand: 'DVE' @@ -146,9 +170,7 @@ const partDefinitionTest2: PartDefinitionKam = { type: PartType.Kam, externalId: 'test-part', rawType: 'KAM 1', - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, fields: {}, script: '', modified: 0, @@ -158,8 +180,8 @@ const partDefinitionTest2: PartDefinitionKam = { type: CueType.DVE, template: 'MORBARN', sources: { - INP1: 'Kam 1', - INP2: 'Kam 2' + INP1: SOURCE_DEFINITION_KAM_1, + INP2: SOURCE_DEFINITION_KAM_2 }, labels: [], iNewsCommand: 'DVE' @@ -167,7 +189,13 @@ const partDefinitionTest2: PartDefinitionKam = { // Ekstern 1 - (index 1) literal({ type: CueType.Ekstern, - source: '1', + sourceDefinition: { + sourceType: SourceType.REMOTE, + variant: 'LIVE', + id: '1', + raw: 'Live 1', + name: 'LIVE 1' + }, iNewsCommand: 'EKSTERN' }), literal>({ @@ -208,8 +236,8 @@ const partDefinitionTest2: PartDefinitionKam = { type: CueType.DVE, template: 'MORBARN', sources: { - INP1: 'Kam 1', - INP2: 'Kam 2' + INP1: SOURCE_DEFINITION_KAM_1, + INP2: SOURCE_DEFINITION_KAM_2 }, labels: [], iNewsCommand: 'DVE' @@ -217,7 +245,13 @@ const partDefinitionTest2: PartDefinitionKam = { // Ekstern 2 - (index 6) literal({ type: CueType.Ekstern, - source: '1', + sourceDefinition: { + sourceType: SourceType.REMOTE, + variant: 'LIVE', + id: '1', + raw: 'Live 1', + name: 'LIVE 1' + }, iNewsCommand: 'EKSTERN' }), literal>({ diff --git a/src/tv2-common/getSegment.ts b/src/tv2-common/getSegment.ts index 3d57b9760..039438770 100644 --- a/src/tv2-common/getSegment.ts +++ b/src/tv2-common/getSegment.ts @@ -237,7 +237,7 @@ export async function getSegmentBase< blueprintParts.push(await showStyleOptions.CreatePartDVE(context, config, part, totalWords)) } break - case PartType.Ekstern: + case PartType.REMOTE: if (showStyleOptions.CreatePartEkstern) { blueprintParts.push(await showStyleOptions.CreatePartEkstern(context, config, part, totalWords)) } diff --git a/src/tv2-common/helpers/__tests__/serverResume.spec.ts b/src/tv2-common/helpers/__tests__/serverResume.spec.ts index 2a0b27ce2..746339b02 100644 --- a/src/tv2-common/helpers/__tests__/serverResume.spec.ts +++ b/src/tv2-common/helpers/__tests__/serverResume.spec.ts @@ -6,10 +6,18 @@ import { VTContent, WithTimeline } from '@tv2media/blueprints-integration' -import { DVEPieceMetaData, literal } from 'tv2-common' -import { SharedSourceLayers } from 'tv2-constants' +import { DVEPieceMetaData, literal, SourceDefinitionEkstern } from 'tv2-common' +import { SharedSourceLayers, SourceType } from 'tv2-constants' import { getServerPositionForPartInstance } from '../serverResume' +const EKSTERN_SOURCE: SourceDefinitionEkstern = { + sourceType: SourceType.REMOTE, + variant: 'LIVE', + id: '1', + raw: 'Live 1', + name: 'LIVE 1' +} + function getMockPartInstance(partInstance: Partial): IBlueprintPartInstance { return { _id: '', @@ -116,8 +124,8 @@ describe('Server Resume', () => { }), metaData: literal>({ sources: { - INP1: 'SERVER', - INP2: 'LIVE 1' + INP1: { sourceType: SourceType.Server }, + INP2: EKSTERN_SOURCE }, serverPlaybackTiming: [{}] }) @@ -162,8 +170,8 @@ describe('Server Resume', () => { }), metaData: literal>({ sources: { - INP1: 'SERVER', - INP2: 'LIVE 1' + INP1: { sourceType: SourceType.Server }, + INP2: EKSTERN_SOURCE }, serverPlaybackTiming: [{ end: 13000 }, { start: 14000, end: 15000 }, { start: 16000 }] }) diff --git a/src/tv2-common/helpers/postProcessDefinitions.ts b/src/tv2-common/helpers/postProcessDefinitions.ts index 5748a66b0..e417bc65d 100644 --- a/src/tv2-common/helpers/postProcessDefinitions.ts +++ b/src/tv2-common/helpers/postProcessDefinitions.ts @@ -23,11 +23,11 @@ function setPartTitle(partDefinition: PartDefinition) { const firstCue = partDefinition.cues[0] if ( firstCue && - [PartType.Grafik, PartType.DVE, PartType.Ekstern, PartType.Telefon, PartType.Unknown].includes(partDefinition.type) + [PartType.Grafik, PartType.DVE, PartType.REMOTE, PartType.Telefon, PartType.Unknown].includes(partDefinition.type) ) { switch (firstCue.type) { case CueType.Ekstern: - partDefinition.title = firstCue.source + partDefinition.title = `${firstCue.sourceDefinition.variant} ${firstCue.sourceDefinition.id}` break case CueType.DVE: partDefinition.title = firstCue.template @@ -52,7 +52,7 @@ function getExternalId(segmentId: string, partDefinition: PartDefinition, foundM switch (partDefinition.type) { case PartType.EVS: // Common pattern to see EV1 and EVS1VO in the same story. Changing from EVS1 to EVS1VO would mean a new part - id += `-${partDefinition.variant.evs}-${!!partDefinition.variant.vo}` + id += `-${partDefinition.sourceDefinition.id}-${!!partDefinition.sourceDefinition.vo}` break case PartType.INTRO: // Intro must have a jingle cue, if it doesn't then padId will handle @@ -63,7 +63,7 @@ function getExternalId(segmentId: string, partDefinition: PartDefinition, foundM break case PartType.Kam: // No way of uniquely identifying, add some entropy from cues - id += `-${partDefinition.rawType}-${partDefinition.variant.name}-${partDefinition.cues.length}` + id += `-${partDefinition.rawType}-${partDefinition.sourceDefinition.id}-${partDefinition.cues.length}` break case PartType.VO: case PartType.Server: @@ -77,7 +77,7 @@ function getExternalId(segmentId: string, partDefinition: PartDefinition, foundM break case PartType.Grafik: case PartType.DVE: - case PartType.Ekstern: + case PartType.REMOTE: case PartType.Telefon: case PartType.Unknown: // Special cases based on cues @@ -103,7 +103,7 @@ function getExternalId(segmentId: string, partDefinition: PartDefinition, foundM break case CueType.Ekstern: // Identify based on live source. Changing live source will result in a new part - id += `-${firstCue.source}` + id += `-${firstCue.sourceDefinition.variant}-${firstCue.sourceDefinition.id}` break case CueType.Jingle: // Changing the jingle clip will result in a new part diff --git a/src/tv2-common/helpers/sisyfos.ts b/src/tv2-common/helpers/sisyfos.ts index 0dacb7836..ab4f7a0c6 100644 --- a/src/tv2-common/helpers/sisyfos.ts +++ b/src/tv2-common/helpers/sisyfos.ts @@ -1,119 +1,160 @@ -import { IStudioUserContext, SourceLayerType, Timeline, TSR } from '@tv2media/blueprints-integration' -import { FindSourceInfoStrict, SisyfosEVSSource, SourceInfo } from 'tv2-common' +import { Timeline, TSR } from '@tv2media/blueprints-integration' +import { SourceInfo, TimelineBlueprintExt } from 'tv2-common' +import { TV2BlueprintConfig } from '../blueprintConfig' import { literal } from '../util' -export function GetSisyfosTimelineObjForEkstern( - context: IStudioUserContext, - sources: SourceInfo[], - sourceType: string, +export function GetSisyfosTimelineObjForCamera( + config: TV2BlueprintConfig, + sourceInfo: SourceInfo, + minusMic: boolean, + studioMicsLayer: string, + enable?: Timeline.TimelineEnable +) { + return GetSisyfosTimelineObjForSource(config, sourceInfo, false, minusMic, studioMicsLayer, enable) +} + +export function GetSisyfosTimelineObjForRemote( + config: TV2BlueprintConfig, + sourceInfo: SourceInfo, + studioMicsLayer: string, + enable?: Timeline.TimelineEnable +) { + return GetSisyfosTimelineObjForSource(config, sourceInfo, false, false, studioMicsLayer, enable) +} + +export function GetSisyfosTimelineObjForReplay( + config: TV2BlueprintConfig, + sourceInfo: SourceInfo, + vo: boolean, + studioMicsLayer: string +) { + return GetSisyfosTimelineObjForSource(config, sourceInfo, vo, true, studioMicsLayer) +} + +export function GetSisyfosTimelineObjForServer( + config: TV2BlueprintConfig, + vo: boolean, + clipPendingLayer: string, + mediaPlayerSession: string, + studioMicsLayer: string, enable?: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosAny[] { - if (!enable) { - enable = { start: 0 } + const timelineEnable = getFallbackEnable(enable) + const result: TSR.TimelineObjSisyfosAny[] = [ + literal({ + id: '', + enable: timelineEnable, + priority: 1, + layer: clipPendingLayer, + content: { + deviceType: TSR.DeviceType.SISYFOS, + type: TSR.TimelineContentTypeSisyfos.CHANNEL, + isPgm: vo ? 2 : 1 + }, + metaData: { + mediaPlayerSession + }, + classes: [] + }) + ] + if (vo) { + result.push(getStudioMicsTimelineObj(config, timelineEnable, studioMicsLayer)) } + return result +} - const audioTimeline: TSR.TimelineObjSisyfosAny[] = [] - const layers = GetLayersForEkstern(context, sources, sourceType) +export function GetSisyfosTimelineObjForFull( + config: TV2BlueprintConfig, + studioMicsLayer: string, + enable?: Timeline.TimelineEnable +): TSR.TimelineObjSisyfosAny[] { + const result: TSR.TimelineObjSisyfosAny[] = [] + const timelineEnable = getFallbackEnable(enable) + result.push(getStudioMicsTimelineObj(config, timelineEnable, studioMicsLayer)) + return result +} - if (!layers || !layers.length) { - context.notifyUserWarning(`Could not set audio levels for ${sourceType}`) - return audioTimeline - } +export function GetSisyfosTimelineObjForTelefon( + config: TV2BlueprintConfig, + telefonLayer: string, + studioMicsLayer: string, + enable?: Timeline.TimelineEnable +): TSR.TimelineObjSisyfosAny[] { + const timelineEnable = getFallbackEnable(enable) + const result: TSR.TimelineObjSisyfosAny[] = [ + literal({ + id: '', + enable: timelineEnable, + priority: 1, + layer: telefonLayer, + content: { + deviceType: TSR.DeviceType.SISYFOS, + type: TSR.TimelineContentTypeSisyfos.CHANNEL, + isPgm: 1 + } + }) + ] + result.push(getStudioMicsTimelineObj(config, timelineEnable, studioMicsLayer)) + return result +} - layers.forEach(layer => { - audioTimeline.push( +function GetSisyfosTimelineObjForSource( + config: TV2BlueprintConfig, + sourceInfo: SourceInfo, + vo: boolean, + enableStudioMicsOnlyForVo: boolean, + studioMicsLayer: string, + enable?: Timeline.TimelineEnable +): TSR.TimelineObjSisyfosAny[] { + const result: TSR.TimelineObjSisyfosAny[] = [] + const timelineEnable = getFallbackEnable(enable) + sourceInfo.sisyfosLayers?.forEach(layer => { + result.push( literal({ id: '', - enable: enable!, + enable: timelineEnable, priority: 1, layer, content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: 1 + isPgm: vo ? 2 : 1 } }) ) }) - return audioTimeline -} - -export function GetLayersForEkstern(context: IStudioUserContext, sources: SourceInfo[], sourceType: string) { - const eksternProps = sourceType.match(/^(?:LIVE|FEED) ?([^\s]+)(?: (.+))?$/i) - const eksternLayers: string[] = [] - if (eksternProps) { - const sourceInfo = FindSourceInfoStrict(context, sources, SourceLayerType.REMOTE, sourceType) - if (sourceInfo && sourceInfo.sisyfosLayers) { - eksternLayers.push(...sourceInfo.sisyfosLayers) - } + if (sourceInfo.useStudioMics && (!enableStudioMicsOnlyForVo || vo)) { + result.push(getStudioMicsTimelineObj(config, timelineEnable, studioMicsLayer)) } - return eksternLayers + return result } -export function GetSisyfosTimelineObjForCamera( - context: IStudioUserContext, - config: { sources: SourceInfo[]; studio: { StudioMics: string[] } }, - sourceType: string, - channelLayer: string, - enable?: Timeline.TimelineEnable +function getStudioMicsTimelineObj( + config: TV2BlueprintConfig, + timelineEnable: Timeline.TimelineEnable, + studioMicsLayer: string ): TSR.TimelineObjSisyfosChannels { - if (!enable) { - enable = { start: 0 } - } - - const useMic = !sourceType.match(/^(?:KAM|CAM)(?:ERA)? (.+) minus mic(.*)$/i) - const camName = sourceType.match(/^(?:KAM|CAM)(?:ERA)? (.+)$/i) - const nonCam = !!sourceType.match(/server|telefon|full|evs/i) - const mappedChannels: TSR.TimelineObjSisyfosChannels['content']['channels'] = [] - if ((useMic && camName) || nonCam) { - const camLayers: string[] = [] - if (useMic && camName) { - const sourceInfo = FindSourceInfoStrict(context, config.sources, SourceLayerType.CAMERA, sourceType) - if (sourceInfo) { - if (sourceInfo.sisyfosLayers) { - camLayers.push(...sourceInfo.sisyfosLayers) - } - if (sourceInfo.useStudioMics) { - camLayers.push(...config.studio.StudioMics) - } - } - } else if (nonCam) { - camLayers.push(...config.studio.StudioMics) - } - camLayers.forEach(layer => { - mappedChannels.push({ - mappedLayer: layer, - isPgm: 1 - }) + const studioMicsChannels: TSR.TimelineObjSisyfosChannels['content']['channels'] = [] + config.studio.StudioMics.forEach(layer => { + studioMicsChannels.push({ + mappedLayer: layer, + isPgm: 1 }) - } - - return literal({ + }) + return { id: '', - enable: enable ? enable : { start: 0 }, - priority: mappedChannels.length ? 2 : 0, - layer: channelLayer, + enable: timelineEnable, + priority: studioMicsChannels.length ? 2 : 0, + layer: studioMicsLayer, content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, - channels: mappedChannels, + channels: studioMicsChannels, overridePriority: 2 } - }) + } } -export function GetSisyfosTimelineObjForEVS(sourceInfo: SourceInfo, vo: boolean) { - return literal({ - id: '', - enable: { - start: 0 - }, - priority: 1, - layer: SisyfosEVSSource(sourceInfo.id.replace(/^DP/i, '')), - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: vo ? 2 : 1 - } - }) +function getFallbackEnable(timelineEnable: Timeline.TimelineEnable | undefined): Timeline.TimelineEnable { + return timelineEnable ?? { start: 0 } } diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index 449e27067..c27a06c5f 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -1,5 +1,11 @@ -import { CueDefinitionFromLayout, PostProcessDefinitions, TV2BlueprintConfig, UnparsedCue } from 'tv2-common' -import { CueType, PartType } from 'tv2-constants' +import { + CueDefinitionFromLayout, + isMinusMic, + PostProcessDefinitions, + TV2BlueprintConfig, + UnparsedCue +} from 'tv2-common' +import { CueType, PartType, SourceType } from 'tv2-constants' import { CueDefinition, ParseCue, UnpairedPilotToGraphic } from './ParseCue' export interface PartTransition { @@ -7,11 +13,65 @@ export interface PartTransition { duration?: number } +export interface SourceDefinitionBase { + sourceType: SourceType +} +export interface SourceDefinitionWithRaw { + raw: string +} + +export interface SourceDefinitionKam extends SourceDefinitionWithRaw { + sourceType: SourceType.Kam + /** name that appears in the Camera Mappings table (e.g. "1", "CS 3") */ + id: string + /** full name for display/logging purposes e.g. "KAM 1" */ + name: string + minusMic: boolean +} + +export interface SourceDefinitionEVS extends SourceDefinitionWithRaw { + sourceType: SourceType.EVS + /** id that appears in the Replay Mappings table (e.g. "EVS 1", "EPSIO") */ + id: string + /** full name for display/logging purposes e.g. "EVS 1 VO" */ + name: string + vo: boolean +} + +export interface SourceDefinitionEkstern extends SourceDefinitionWithRaw { + sourceType: SourceType.REMOTE + variant: 'LIVE' | 'FEED' + /** name that appears in the Remote Mappings table (e.g. "1", "2") */ + id: string + /** full name for display/logging purposes e.g. "LIVE 1" */ + name: string +} + +export interface SourceDefinitionServer extends SourceDefinitionBase { + sourceType: SourceType.Server +} + +export interface SourceDefinitionGrafik extends SourceDefinitionWithRaw { + sourceType: SourceType.Grafik + name: string +} + +export interface SourceDefinitionDefault extends SourceDefinitionBase { + sourceType: SourceType.DEFAULT +} + +export type SourceDefinition = + | SourceDefinitionKam + | SourceDefinitionEVS + | SourceDefinitionEkstern + | SourceDefinitionServer + | SourceDefinitionGrafik + | SourceDefinitionDefault + export interface PartDefinitionBase { externalId: string type: PartType rawType: string - variant: {} effekt?: number cues: CueDefinition[] script: string @@ -27,47 +87,33 @@ export interface PartDefinitionBase { export interface PartDefinitionUnknown extends PartDefinitionBase { type: PartType.Unknown - variant: {} } - export interface PartDefinitionKam extends PartDefinitionBase { type: PartType.Kam - variant: { - name: string - } + sourceDefinition: SourceDefinitionKam } - export interface PartDefinitionServer extends PartDefinitionBase { type: PartType.Server - variant: {} } export interface PartDefinitionTeknik extends PartDefinitionBase { type: PartType.Teknik - variant: {} } export interface PartDefinitionGrafik extends PartDefinitionBase { type: PartType.Grafik - variant: {} } export interface PartDefinitionVO extends PartDefinitionBase { type: PartType.VO - variant: {} } export interface PartDefinitionIntro extends PartDefinitionBase { type: PartType.INTRO - variant: {} } - export interface PartDefinitionEVS extends PartDefinitionBase { type: PartType.EVS - variant: { - evs: string - vo?: 'VO' | 'VOV' - } + sourceDefinition: SourceDefinitionEVS } export interface PartDefinitionDVE extends PartDefinitionBase { @@ -75,7 +121,7 @@ export interface PartDefinitionDVE extends PartDefinitionBase { } export interface PartDefinitionEkstern extends PartDefinitionBase { - type: PartType.Ekstern + type: PartType.REMOTE } export interface PartDefinitionTelefon extends PartDefinitionBase { @@ -95,20 +141,23 @@ export type PartDefinition = | PartDefinitionEkstern | PartDefinitionTelefon export type PartdefinitionTypes = - | Pick - | Pick - | Pick - | Pick - | Pick - | Pick - | Pick - | Pick - | Pick - | Pick - | Pick - -const ACCEPTED_RED_TEXT = /\b(KAM(?:\d+)?|CAM(?:\d+)?|KAMERA(?:\d+)?|CAMERA(?:\d+)?|SERVER|ATTACK|TEKNIK|GRAFIK|EPSIO|EVS ?\d+ ?(?:VOV?)?|VOV?|VOSB)+\b/i -const EVS_RED_TEXT = /EVS ?(\d+) ?(VOV?)?/i + | Pick + | Pick + | Pick + | Pick + | Pick + | Pick + | Pick + | Pick + | Pick + | Pick + | Pick + +const CAMERA_RED_TEXT = /\b[KC]AM(?:ERA)? ?(\S+)\b/i +const EVS_RED_TEXT = /\bEVS ?(\d+) ?(VOV?)?\b/i +const ACCEPTED_RED_TEXT = [/\b(SERVER|ATTACK|TEKNIK|GRAFIK|EPSIO|VOV?|VOSB)+\b/i, CAMERA_RED_TEXT, EVS_RED_TEXT] +const REMOTE_CUE = /^(LIVE|FEED) ?([^\s]+)(?: (.+))?$/i +const ENGINE_CUE = /ENGINE ?([^\s]+)/i export function ParseBody( config: TV2BlueprintConfig, @@ -162,7 +211,7 @@ export function ParseBody( .replace(/<\/tab>/i, '') .trim() - if (typeStr && ACCEPTED_RED_TEXT.test(typeStr)) { + if (typeStr && ACCEPTED_RED_TEXT.some(r => r.test(typeStr))) { const inlineCues = line .replace(/<\/?p>/g, '') .split(/(.*?)<\/pi>/i) @@ -175,7 +224,7 @@ export function ParseBody( let pos = 0 let redTextFound = false while (pos < inlineCues.length && !redTextFound) { - if (ACCEPTED_RED_TEXT.test(inlineCues[pos])) { + if (ACCEPTED_RED_TEXT.some(r => r.test(inlineCues[pos]))) { redTextFound = true } else { const parsedCues = getCuesInLine(inlineCues[pos], cues, config) @@ -341,7 +390,6 @@ function initDefinition(fields: any, modified: number, segmentName: string): Par externalId: '', type: PartType.Unknown, rawType: '', - variant: {}, cues: [], script: '', fields, @@ -428,7 +476,7 @@ function makeDefinitionPrimaryCue( switch (cue.type) { case CueType.Ekstern: definition = { ...definition, ...cue.transition } - definition.type = PartType.Ekstern + definition.type = PartType.REMOTE break case CueType.DVE: definition.type = PartType.DVE @@ -504,72 +552,120 @@ export function getTransitionProperties(typeStr: string): Pick = getTransitionProperties(typeStr) + const transitionAndEffekt: Pick = getTransitionProperties(typeStr) + + const sourceDefinition = getSourceDefinition(typeStr) + switch (sourceDefinition?.sourceType) { + case SourceType.Kam: + return { + type: PartType.Kam, + sourceDefinition, + ...transitionAndEffekt + } + case SourceType.EVS: + return { + type: PartType.EVS, + sourceDefinition, + ...transitionAndEffekt + } + default: + break + } + const tokens = stripTransitionProperties(typeStr) .replace(/100%/g, '') .trim() .split(' ') const firstToken = tokens[0] - if (/[CK]AM/i.test(firstToken)) { - const adjacentKamNumber = tokens[0].match(/KAM(\d+)/i) - return { - type: PartType.Kam, - variant: { - name: adjacentKamNumber ? adjacentKamNumber[1] : tokens[1] - }, - ...definition - } - } else if (/SERVER|ATTACK/i.test(firstToken)) { + if (/SERVER|ATTACK/i.test(firstToken)) { return { type: PartType.Server, - variant: {}, - ...definition + ...transitionAndEffekt } } else if (/TEKNIK/i.test(firstToken)) { return { type: PartType.Teknik, - variant: {}, - ...definition + ...transitionAndEffekt } } else if (/GRAFIK/i.test(firstToken)) { return { type: PartType.Grafik, - variant: {}, - ...definition + ...transitionAndEffekt + } + } else if (/VOV?|VOSB/i.test(firstToken)) { + return { + type: PartType.VO, + ...transitionAndEffekt + } + } else { + return { + type: PartType.Unknown, + ...transitionAndEffekt + } + } +} + +export function getSourceDefinition(typeStr: string): SourceDefinition | undefined { + const strippedTypeStr = stripTransitionProperties(typeStr) + .replace(/100%/g, '') + .trim() + if (CAMERA_RED_TEXT.test(strippedTypeStr)) { + const id = strippedTypeStr.match(CAMERA_RED_TEXT)![1] + return { + sourceType: SourceType.Kam, + id, + minusMic: isMinusMic(typeStr), + raw: strippedTypeStr, + name: `KAM ${id}` + } + } else if (REMOTE_CUE.test(typeStr)) { + const remoteNumber = typeStr.match(REMOTE_CUE) + const variant = remoteNumber![1].toUpperCase() as 'LIVE' | 'FEED' + const id = remoteNumber![2] + return { + sourceType: SourceType.REMOTE, + variant, + id, + raw: strippedTypeStr, + name: `${variant} ${id}` } } else if (EVS_RED_TEXT.test(typeStr)) { const strippedToken = typeStr.match(EVS_RED_TEXT) + const id = `EVS ${strippedToken![1].toUpperCase()}` + const vo = strippedToken![2] return { - type: PartType.EVS, - variant: { - evs: strippedToken && strippedToken[1] ? strippedToken[1] : '1', - vo: (strippedToken && (strippedToken[2] as 'VO' | 'VOV')) ?? undefined - }, - ...definition + sourceType: SourceType.EVS, + id, + vo: !!vo, + raw: strippedToken![0].trim(), + name: `${id}${vo ? ' ' + vo : ''}` } } else if (/EPSIO/i.test(typeStr)) { return { - type: PartType.EVS, - variant: { - evs: 'EPSIO', - vo: 'VO' - }, - ...definition + sourceType: SourceType.EVS, + id: 'EPSIO', + vo: true, + raw: typeStr, + name: 'EPSIO' } - } else if (/VOV?|VOSB/i.test(firstToken)) { + } else if (ENGINE_CUE.test(typeStr)) { + const strippedToken = typeStr.match(ENGINE_CUE) return { - type: PartType.VO, - variant: {}, - ...definition + sourceType: SourceType.Grafik, + name: strippedToken![1].toUpperCase(), + raw: typeStr } - } else { + } else if (/DEFAULT/i.test(typeStr)) { return { - type: PartType.Unknown, - variant: {}, - ...definition + sourceType: SourceType.DEFAULT + } + } else if (/SERVER/i.test(typeStr)) { + return { + sourceType: SourceType.Server } } + return undefined } export function stripRedundantCuesWhenLayoutCueIsPresent(partDefinitions: PartDefinition[]): PartDefinition[] { diff --git a/src/tv2-common/inewsConversion/converters/ParseCue.ts b/src/tv2-common/inewsConversion/converters/ParseCue.ts index b5b0e36f3..dc61fb665 100644 --- a/src/tv2-common/inewsConversion/converters/ParseCue.ts +++ b/src/tv2-common/inewsConversion/converters/ParseCue.ts @@ -1,6 +1,14 @@ import { GetInfiniteModeForGraphic, literal, TableConfigSchema, TV2BlueprintConfig, UnparsedCue } from 'tv2-common' -import { CueType, GraphicEngine, PartType } from 'tv2-constants' -import { getTransitionProperties, PartDefinition, PartdefinitionTypes, stripTransitionProperties } from './ParseBody' +import { CueType, GraphicEngine, PartType, SourceType } from 'tv2-constants' +import { + getSourceDefinition, + getTransitionProperties, + PartDefinition, + PartdefinitionTypes, + SourceDefinition, + SourceDefinitionEkstern, + stripTransitionProperties +} from './ParseBody' export interface CueTime { frames?: number @@ -22,15 +30,15 @@ export interface CueDefinitionUnknown extends CueDefinitionBase { export interface CueDefinitionEkstern extends CueDefinitionBase { type: CueType.Ekstern - source: string + sourceDefinition: SourceDefinitionEkstern transition?: Pick } export interface DVESources { - INP1?: string - INP2?: string - INP3?: string - INP4?: string + INP1?: SourceDefinition + INP2?: SourceDefinition + INP3?: SourceDefinition + INP4?: SourceDefinition } export interface CueDefinitionDVE extends CueDefinitionBase { @@ -420,13 +428,16 @@ function parsePilot(cue: string[]): CueDefinitionUnpairedPilot | CueDefinitionGr function parseEkstern(cue: string[]): CueDefinitionEkstern | undefined { const eksternSource = stripTransitionProperties(cue[0]).match(/^EKSTERN=(.+)$/i) if (eksternSource) { - const transitionProperties = getTransitionProperties(cue[0]) - return literal({ - type: CueType.Ekstern, - source: eksternSource[1].replace(/\s+/i, ' ').trim(), - iNewsCommand: 'EKSTERN', - transition: transitionProperties - }) + const sourceDefinition = getSourceDefinition(eksternSource[1]) + if (sourceDefinition?.sourceType === SourceType.REMOTE) { + const transitionProperties = getTransitionProperties(cue[0]) + return literal({ + type: CueType.Ekstern, + iNewsCommand: 'EKSTERN', + transition: transitionProperties, + sourceDefinition + }) + } } return undefined @@ -450,7 +461,7 @@ function parseDVE(cue: string[]): CueDefinitionDVE { } else if (c.match(/^INP\d+=/i)) { const input = c.match(/^(INP\d)+=(.+)$/i) if (input && input[1] && input[2]) { - dvecue.sources[input[1].toUpperCase() as keyof DVESources] = input[2] + dvecue.sources[input[1].toUpperCase() as keyof DVESources] = getSourceDefinition(input[2]) } } else if (c.match(/^BYNAVN=/i)) { const labels = c.match(/^BYNAVN=(.+)$/i) @@ -563,7 +574,7 @@ function parseAdLib(cue: string[]) { for (let i = 0; i < cue.length; i++) { const input = cue[i].match(/^(INP\d)+=(.+)$/i) if (input && input[1] && input[2] && adlib.inputs !== undefined) { - adlib.inputs[input[1].toString().toUpperCase() as keyof DVESources] = input[2] + adlib.inputs[input[1].toUpperCase() as keyof DVESources] = getSourceDefinition(input[2]) } const bynavn = cue[i].match(/^BYNAVN=(.+)$/i) @@ -899,7 +910,7 @@ function parseDesignBg(cue: string[], config: TV2BlueprintConfig): CueDefinition export function PartToParentClass(studio: string, partDefinition: PartDefinition): string | undefined { switch (partDefinition.type) { case PartType.Kam: - return CameraParentClass(studio, partDefinition.variant.name) + return CameraParentClass(studio, partDefinition.sourceDefinition.id) case PartType.Server: case PartType.VO: const clip = partDefinition.fields.videoId @@ -910,7 +921,7 @@ export function PartToParentClass(studio: string, partDefinition: PartDefinition return } case PartType.EVS: - return EVSParentClass(studio, partDefinition.variant.evs) + return EVSParentClass(studio, partDefinition.sourceDefinition.id) default: return UnknownPartParentClass(studio, partDefinition) } @@ -951,7 +962,7 @@ export function UnknownPartParentClass(studio: string, partDefinition: PartDefin case CueType.DVE: return DVEParentClass(studio, firstCue.template) case CueType.Ekstern: - return EksternParentClass(studio, firstCue.source) + return EksternParentClass(studio, `${firstCue.sourceDefinition.variant} ${firstCue.sourceDefinition.id}`) case CueType.Telefon: return TLFParentClass(studio, firstCue.source) default: 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 fc3637f33..fc28e08cf 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts @@ -5,7 +5,7 @@ import { stripRedundantCuesWhenLayoutCueIsPresent, UnparsedCue } from 'tv2-common' -import { CueType, PartType } from 'tv2-constants' +import { CueType, PartType, 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' @@ -25,7 +25,9 @@ import { PartDefinitionTeknik, PartDefinitionTelefon, PartDefinitionUnknown, - PartDefinitionVO + PartDefinitionVO, + SourceDefinitionEkstern, + SourceDefinitionKam } from '../ParseBody' import { CueDefinition, @@ -89,21 +91,35 @@ const cueGrafik3: CueDefinitionGraphic = { const unparsedGrafik3 = ['kg bund 3'] +const SOURCE_DEFINITION_LIVE_1: SourceDefinitionEkstern = { + sourceType: SourceType.REMOTE, + variant: 'LIVE', + id: '1', + name: 'LIVE 1', + raw: 'LIVE 1' +} const cueEkstern1: CueDefinitionEkstern = { type: CueType.Ekstern, - source: 'Live 1', + sourceDefinition: SOURCE_DEFINITION_LIVE_1, iNewsCommand: 'EKSTERN' } -const unparsedEkstern1 = ['EKSTERN=Live 1'] +const unparsedEkstern1 = ['EKSTERN=LIVE 1'] +const SOURCE_DEFINITION_LIVE_2: SourceDefinitionEkstern = { + sourceType: SourceType.REMOTE, + variant: 'LIVE', + id: '2', + name: 'LIVE 2', + raw: 'LIVE 2' +} const cueEkstern2: CueDefinitionEkstern = { type: CueType.Ekstern, - source: 'Live 2', + sourceDefinition: SOURCE_DEFINITION_LIVE_2, iNewsCommand: 'EKSTERN' } -const unparsedEkstern2 = ['EKSTERN=Live 2'] +const unparsedEkstern2 = ['EKSTERN=LIVE 2'] const cueJingle1: CueDefinitionJingle = { type: CueType.Jingle, @@ -145,6 +161,28 @@ const cueTelefon2: CueDefinitionTelefon = { const unparsedTelefon2 = ['TELEFON=TLF 2'] +const SOURCE_DEFINITION_KAM_1: SourceDefinitionKam = { + sourceType: SourceType.Kam, + id: '1', + raw: 'KAM 1', + minusMic: false, + name: 'KAM 1' +} +const SOURCE_DEFINITION_KAM_2: SourceDefinitionKam = { + sourceType: SourceType.Kam, + id: '2', + raw: 'KAM 2', + minusMic: false, + name: 'KAM 2' +} +const SOURCE_DEFINITION_KAM_3: SourceDefinitionKam = { + sourceType: SourceType.Kam, + id: '3', + raw: 'KAM 3', + minusMic: false, + name: 'KAM 3' +} + const RUNDOWN_EXTERNAL_ID = 'TEST.SOFIE.JEST' function makeMockContext() { @@ -195,7 +233,6 @@ describe('Body parser', () => { type: PartType.Teknik, cues: [cueGrafik1, cueGrafik2, cueGrafik3], script: '', - variant: {}, externalId: '', rawType: 'TEKNIK', fields: {}, @@ -204,12 +241,11 @@ describe('Body parser', () => { segmentExternalId: '00000000001' }), literal({ - type: PartType.Ekstern, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern1], - title: 'Live 1', + title: 'LIVE 1', script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -217,12 +253,11 @@ describe('Body parser', () => { segmentExternalId: '00000000001' }), literal({ - type: PartType.Ekstern, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern2, cueJingle1, cueJingle2, cueJingle3], - title: 'Live 2', + title: 'LIVE 2', script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -245,7 +280,6 @@ describe('Body parser', () => { type: PartType.Unknown, cues: [cueGrafik1], script: 'Thid id thr trext for the next DVE\n', - variant: {}, externalId: '', rawType: '', fields: {}, @@ -254,12 +288,11 @@ describe('Body parser', () => { segmentExternalId: '00000000001' }), literal({ - type: PartType.Ekstern, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern1], - title: 'Live 1', + title: 'LIVE 1', script: 'Script here\n', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -285,8 +318,8 @@ describe('Body parser', () => { type: CueType.DVE, template: 'MORBARN', sources: { - INP1: 'Kam 1', - INP2: 'Kam 2' + INP1: { ...SOURCE_DEFINITION_KAM_1, raw: 'Kam 1' }, + INP2: { ...SOURCE_DEFINITION_KAM_2, raw: 'Kam 2' } }, labels: ['Live', 'Odense'], iNewsCommand: 'DVE' @@ -294,7 +327,6 @@ describe('Body parser', () => { ], title: 'MORBARN', script: 'Thid id thr trext for the next DVE\n', - variant: {}, externalId: '', rawType: '', fields: {}, @@ -303,12 +335,11 @@ describe('Body parser', () => { segmentExternalId: '00000000001' }), literal({ - type: PartType.Ekstern, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern1, cueGrafik1], - title: 'Live 1', + title: 'LIVE 1', script: 'Script here\n', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -342,9 +373,7 @@ describe('Body parser', () => { rawType: 'KAM AR', cues: [cueJingle3], script: 'Lots more script\n', - variant: { - name: 'AR' - }, + sourceDefinition: { sourceType: SourceType.Kam, id: 'AR', raw: 'KAM AR', minusMic: false, name: 'KAM AR' }, externalId: '', fields: {}, modified: 0, @@ -356,7 +385,6 @@ describe('Body parser', () => { rawType: 'SERVER', cues: [cueGrafik1, cueGrafik2, cueGrafik3], script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -364,12 +392,11 @@ describe('Body parser', () => { segmentExternalId: '00000000001' }), literal({ - type: PartType.Ekstern, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern1], - title: 'Live 1', + title: 'LIVE 1', script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -377,12 +404,11 @@ describe('Body parser', () => { segmentExternalId: '00000000001' }), literal({ - type: PartType.Ekstern, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern2, cueJingle1, cueJingle2], - title: 'Live 2', + title: 'LIVE 2', script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -406,9 +432,7 @@ describe('Body parser', () => { rawType: 'CAMERA 1', cues: [], script: 'Her står em masse tekst\n', - variant: { - name: '1' - }, + sourceDefinition: { sourceType: SourceType.Kam, id: '1', raw: 'CAMERA 1', minusMic: false, name: 'KAM 1' }, externalId: '', fields, modified: 0, @@ -431,9 +455,7 @@ describe('Body parser', () => { rawType: 'KAM 1', cues: [], script: '', - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', fields: {}, modified: 0, @@ -445,7 +467,6 @@ describe('Body parser', () => { rawType: '100%GRAFIK', cues: [cueGrafik1], script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -453,12 +474,11 @@ describe('Body parser', () => { segmentExternalId: '00000000001' }), literal({ - type: PartType.Ekstern, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern1, cueGrafik3], - title: 'Live 1', + title: 'LIVE 1', script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -481,9 +501,7 @@ describe('Body parser', () => { rawType: 'KAM 1', cues: [], script: '', - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', fields: {}, modified: 0, @@ -506,7 +524,6 @@ describe('Body parser', () => { rawType: 'ATTACK', cues: [cueGrafik1, cueGrafik2, cueGrafik3], script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -520,9 +537,7 @@ describe('Body parser', () => { cues: [], script: 'Long script. Long script. Long script. Long script. Long script. Long script. Long script. Long script. Long script. Long script. Long script. Long script.\n', - variant: { - name: '4' - }, + sourceDefinition: { sourceType: SourceType.Kam, id: '4', raw: 'KAM 4', minusMic: false, name: 'KAM 4' }, externalId: '', fields: {}, modified: 0, @@ -545,9 +560,7 @@ describe('Body parser', () => { rawType: 'KAM 2', cues: [cueGrafik1, cueGrafik2, cueGrafik3], script: 'Some script\n', - variant: { - name: '2' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_2, externalId: '', fields: {}, modified: 0, @@ -555,12 +568,11 @@ describe('Body parser', () => { segmentExternalId: '00000000001' }), literal({ - type: PartType.Ekstern, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern1], - title: 'Live 1', + title: 'LIVE 1', script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -583,9 +595,7 @@ describe('Body parser', () => { rawType: 'KAM 2', cues: [cueGrafik1, cueGrafik2, cueGrafik3], script: 'Some script.\nSome more script with "a quote"\nYet more script, this time it\'s a question?\n', - variant: { - name: '2' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_2, externalId: '', fields: {}, modified: 0, @@ -593,12 +603,11 @@ describe('Body parser', () => { segmentExternalId: '00000000001' }), literal({ - type: PartType.Ekstern, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern1], - title: 'Live 1', + title: 'LIVE 1', script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -621,9 +630,7 @@ describe('Body parser', () => { rawType: 'KAM 2', cues: [cueGrafik1, cueGrafik2, cueGrafik3], script: 'Question?\n', - variant: { - name: '2' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_2, externalId: '', fields: {}, modified: 0, @@ -631,12 +638,11 @@ describe('Body parser', () => { segmentExternalId: '00000000001' }), literal({ - type: PartType.Ekstern, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern1], - title: 'Live 1', + title: 'LIVE 1', script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -659,9 +665,7 @@ describe('Body parser', () => { rawType: 'KAM 1', cues: [], script: 'Some script.\n', - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', fields: {}, modified: 0, @@ -673,7 +677,6 @@ describe('Body parser', () => { rawType: 'VO', cues: [cueGrafik1, cueGrafik2], script: 'More script.\nEven more\nMore script again.\n', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -696,9 +699,7 @@ describe('Body parser', () => { rawType: 'KAM 1', cues: [], script: 'Some script.\n', - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', fields: {}, modified: 0, @@ -710,7 +711,6 @@ describe('Body parser', () => { rawType: 'VOV', cues: [cueGrafik1, cueGrafik2], script: 'More script.\nEven more\nMore script again.\n', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -733,9 +733,7 @@ describe('Body parser', () => { rawType: 'KAM 3', cues: [cueGrafik1, cueGrafik2], script: "Here is our correspondant.\nWhat's going on over there?\n.\n", - variant: { - name: '3' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_3, externalId: '', fields: {}, modified: 0, @@ -773,7 +771,6 @@ describe('Body parser', () => { rawType: '', cues: [cueGrafik1, cueGrafik2, cueGrafik3], script: "What's going on over there?\n", - variant: {}, externalId: '', fields: {}, modified: 0, @@ -781,12 +778,11 @@ describe('Body parser', () => { segmentExternalId: '00000000001' }), literal({ - type: PartType.Ekstern, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern1], - title: 'Live 1', + title: 'LIVE 1', script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -794,12 +790,11 @@ describe('Body parser', () => { segmentExternalId: '00000000001' }), literal({ - type: PartType.Ekstern, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern2], - title: 'Live 2', + title: 'LIVE 2', script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -822,7 +817,6 @@ describe('Body parser', () => { rawType: 'INTRO', cues: [cueGrafik1], script: '', - variant: {}, externalId: '', fields: {}, modified: 0, @@ -853,9 +847,7 @@ describe('Body parser', () => { type: PartType.Kam, rawType: 'KAM 2', script: 'Hallo, I wnat to tell you......\n', - variant: { - name: '2' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_2, cues: [cueGrafik1], fields, modified: 0, @@ -867,7 +859,6 @@ describe('Body parser', () => { type: PartType.Server, rawType: 'SERVER', script: '', - variant: {}, cues: [cueGrafik2, cueGrafik3, cueJingle1, cueJingle2, cueJingle3], fields, modified: 0, @@ -879,9 +870,7 @@ describe('Body parser', () => { type: PartType.Kam, rawType: 'KAM 2', script: '', - variant: { - name: '2' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_2, cues: [], fields, modified: 0, @@ -894,9 +883,7 @@ describe('Body parser', () => { type: PartType.Kam, rawType: 'KAM 2', script: '', - variant: { - name: '2' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_2, cues: [], fields, modified: 0, @@ -928,11 +915,10 @@ describe('Body parser', () => { literal([ literal({ externalId: '', - type: PartType.Ekstern, - variant: {}, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern1], - title: 'Live 1', + title: 'LIVE 1', script: '', fields, modified: 0, @@ -941,11 +927,10 @@ describe('Body parser', () => { }), literal({ externalId: '', - type: PartType.Ekstern, - variant: {}, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern2], - title: 'Live 2', + title: 'LIVE 2', script: '', fields, modified: 0, @@ -955,9 +940,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, rawType: 'KAM 1', cues: [], script: 'Single line of script\n', @@ -969,7 +952,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Server, - variant: {}, rawType: 'SERVER', cues: [cueGrafik2, cueGrafik3, cueJingle1, cueJingle2, cueJingle3], script: '', @@ -981,7 +963,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Telefon, - variant: {}, rawType: '', cues: [cueTelefon1], script: '', @@ -993,7 +974,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Telefon, - variant: {}, rawType: '', cues: [cueTelefon2], script: '', @@ -1006,9 +986,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '2' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_2, rawType: 'KAM 2', cues: [], script: 'And some script.\n', @@ -1031,7 +1009,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.VO, - variant: {}, effekt: 0, rawType: 'VO', cues: [cueGrafik1], @@ -1055,9 +1032,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, effekt: 1, rawType: 'KAM 1', cues: [], @@ -1070,7 +1045,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Server, - variant: {}, rawType: 'SERVER', cues: [cueGrafik1, cueGrafik2], script: 'STORT BILLEDE AF STUDIE\n', @@ -1093,7 +1067,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Unknown, - variant: {}, rawType: '', cues: [cueJingle1], title: '1', @@ -1125,9 +1098,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '2' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_2, rawType: 'KAM 2', cues: [], script: 'Hallo, I wnat to tell you......\nHEREEEELLLLOOOK\nYES\n', @@ -1139,7 +1110,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Server, - variant: {}, rawType: 'SERVER', cues: literal([ literal>({ @@ -1196,9 +1166,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, rawType: 'KAM 1', cues: [], script: '', @@ -1210,9 +1178,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, rawType: 'KAM 1', cues: [], script: '', @@ -1225,9 +1191,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, rawType: 'KAM 1', cues: [], script: '', @@ -1254,9 +1218,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, rawType: 'KAM 1', cues: [], script: 'Skriv spib her\n', @@ -1268,7 +1230,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Telefon, - variant: {}, rawType: '', cues: [ literal({ @@ -1349,9 +1310,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, transition: { style: 'MIX', duration: 200 @@ -1367,7 +1326,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Telefon, - variant: {}, rawType: '', cues: [ literal({ @@ -1444,7 +1402,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.VO, - variant: {}, effekt: 0, rawType: 'VOSB', cues: [cueGrafik1], @@ -1468,7 +1425,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.VO, - variant: {}, effekt: 0, rawType: 'VOSB', cues: [cueGrafik1], @@ -1504,9 +1460,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, rawType: 'KAM 1', cues: [ literal>({ @@ -1533,7 +1487,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Grafik, - variant: {}, rawType: '100%GRAFIK', cues: [ literal>({ @@ -1585,8 +1538,12 @@ describe('Body parser', () => { externalId: '', type: PartType.EVS, rawType: 'EVS 1', - variant: { - evs: '1' + sourceDefinition: { + sourceType: SourceType.EVS, + id: 'EVS 1', + name: 'EVS 1', + raw: 'EVS 1', + vo: false }, cues: [cueGrafik1, cueGrafik2, cueGrafik3], fields, @@ -1608,9 +1565,12 @@ describe('Body parser', () => { externalId: '', type: PartType.EVS, rawType: 'EVS1VOV', - variant: { - evs: '1', - vo: 'VOV' + sourceDefinition: { + sourceType: SourceType.EVS, + id: 'EVS 1', + name: 'EVS 1 VOV', + raw: 'EVS1VOV', + vo: true }, cues: [cueGrafik1, cueGrafik2, cueGrafik3], fields, @@ -1631,9 +1591,12 @@ describe('Body parser', () => { externalId: '', type: PartType.EVS, rawType: 'EVS 1 VO', - variant: { - evs: '1', - vo: 'VO' + sourceDefinition: { + sourceType: SourceType.EVS, + id: 'EVS 1', + name: 'EVS 1 VO', + raw: 'EVS 1 VO', + vo: true }, cues: [], fields, @@ -1646,9 +1609,12 @@ describe('Body parser', () => { externalId: '', type: PartType.EVS, rawType: 'EVS 2VO', - variant: { - evs: '2', - vo: 'VO' + sourceDefinition: { + sourceType: SourceType.EVS, + id: 'EVS 2', + name: 'EVS 2 VO', + raw: 'EVS 2VO', + vo: true }, cues: [], fields, @@ -1661,9 +1627,12 @@ describe('Body parser', () => { externalId: '', type: PartType.EVS, rawType: 'EVS3VO', - variant: { - evs: '3', - vo: 'VO' + sourceDefinition: { + sourceType: SourceType.EVS, + id: 'EVS 3', + name: 'EVS 3 VO', + raw: 'EVS3VO', + vo: true }, cues: [], fields, @@ -1676,9 +1645,12 @@ describe('Body parser', () => { externalId: '', type: PartType.EVS, rawType: 'EVS4 VO', - variant: { - evs: '4', - vo: 'VO' + sourceDefinition: { + sourceType: SourceType.EVS, + id: 'EVS 4', + name: 'EVS 4 VO', + raw: 'EVS4 VO', + vo: true }, cues: [], fields, @@ -1705,7 +1677,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Server, - variant: {}, rawType: 'SERVER', cues: [ literal>({ @@ -1748,15 +1719,14 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.DVE, - variant: {}, rawType: '', cues: [ literal({ type: CueType.DVE, template: 'SOMMERFUGL', sources: { - INP1: 'KAM 1', - INP2: 'LIVE 2' + INP1: SOURCE_DEFINITION_KAM_1, + INP2: SOURCE_DEFINITION_LIVE_2 }, labels: ['Rodovre'], iNewsCommand: 'DVE' @@ -1771,16 +1741,9 @@ describe('Body parser', () => { }), literal({ externalId: '', - type: PartType.Ekstern, - variant: {}, + type: PartType.REMOTE, rawType: '', - cues: [ - literal({ - type: CueType.Ekstern, - source: 'LIVE 2', - iNewsCommand: 'EKSTERN' - }) - ], + cues: [cueEkstern2], title: 'LIVE 2', script: 'Some Script here\n', fields, @@ -1812,11 +1775,10 @@ describe('Body parser', () => { literal([ literal({ externalId: '', - type: PartType.Ekstern, - variant: {}, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern1], - title: 'Live 1', + title: 'LIVE 1', script: '', fields, modified: 0, @@ -1825,11 +1787,10 @@ describe('Body parser', () => { }), literal({ externalId: '', - type: PartType.Ekstern, - variant: {}, + type: PartType.REMOTE, rawType: '', cues: [cueEkstern2], - title: 'Live 2', + title: 'LIVE 2', script: '', fields, modified: 0, @@ -1839,9 +1800,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, rawType: 'KAM 1', cues: [], script: 'Some script.\n', @@ -1853,7 +1812,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Server, - variant: {}, rawType: 'SERVER', cues: [cueGrafik2, cueGrafik3, cueJingle1, cueJingle2, cueJingle3], script: '', @@ -1865,7 +1823,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Telefon, - variant: {}, rawType: '', cues: [cueTelefon1], script: '', @@ -1877,7 +1834,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Telefon, - variant: {}, rawType: '', cues: [cueTelefon2], script: '', @@ -1890,9 +1846,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '2' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_2, rawType: 'KAM 2', cues: [], script: 'Some script.\n', @@ -1920,15 +1874,14 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.DVE, - variant: {}, rawType: '', cues: [ literal({ type: CueType.DVE, template: 'SOMMERFUGL', sources: { - INP1: 'KAM 1', - INP2: 'LIVE 2' + INP1: SOURCE_DEFINITION_KAM_1, + INP2: SOURCE_DEFINITION_LIVE_2 }, labels: ['Rodovre'], iNewsCommand: 'DVE' @@ -1943,16 +1896,9 @@ describe('Body parser', () => { }), literal({ externalId: '', - type: PartType.Ekstern, - variant: {}, + type: PartType.REMOTE, rawType: '', - cues: [ - literal({ - type: CueType.Ekstern, - source: 'LIVE 2', - iNewsCommand: 'EKSTERN' - }) - ], + cues: [cueEkstern2], title: 'LIVE 2', script: 'And some script\n', fields, @@ -1963,7 +1909,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Server, - variant: {}, rawType: 'SERVER', cues: [ literal>({ @@ -2021,7 +1966,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Unknown, - variant: {}, rawType: '', cues: [ literal>({ @@ -2065,15 +2009,14 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.DVE, - variant: {}, rawType: '', cues: [ literal({ type: CueType.DVE, template: 'SOMMERFUGL', sources: { - INP1: 'KAM 1', - INP2: 'LIVE 2' + INP1: SOURCE_DEFINITION_KAM_1, + INP2: SOURCE_DEFINITION_LIVE_2 }, labels: ['Rodovre'], iNewsCommand: 'DVE' @@ -2088,16 +2031,9 @@ describe('Body parser', () => { }), literal({ externalId: '', - type: PartType.Ekstern, - variant: {}, + type: PartType.REMOTE, rawType: '', - cues: [ - literal({ - type: CueType.Ekstern, - source: 'LIVE 2', - iNewsCommand: 'EKSTERN' - }) - ], + cues: [cueEkstern2], script: 'Some script\n', title: 'LIVE 2', fields, @@ -2108,7 +2044,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Server, - variant: {}, rawType: 'SERVER', cues: [], script: '', @@ -2128,9 +2063,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: { ...SOURCE_DEFINITION_KAM_1, raw: 'KAM1' }, rawType: 'KAM1', cues: [], script: '', @@ -2161,7 +2094,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Unknown, - variant: {}, rawType: '', cues: [ literal({ @@ -2230,9 +2162,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: { ...SOURCE_DEFINITION_KAM_1, raw: 'Kam 1' }, rawType: 'Kam 1', cues: [ literal({ @@ -2296,7 +2226,6 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Grafik, - variant: {}, externalId: '', rawType: '100% GRAFIK', cues: [ @@ -2333,9 +2262,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', rawType: 'KAM 1', cues: [], @@ -2347,7 +2274,6 @@ describe('Body parser', () => { }), literal({ type: PartType.Server, - variant: {}, externalId: '', rawType: 'SERVER', cues: [], @@ -2359,9 +2285,7 @@ describe('Body parser', () => { }), literal({ type: PartType.Kam, - variant: { - name: '2' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_2, externalId: '', rawType: 'KAM 2', cues: [], @@ -2382,9 +2306,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', rawType: 'KAM 1', cues: [], @@ -2396,17 +2318,10 @@ describe('Body parser', () => { segmentExternalId: '00000000001' }), literal({ - type: PartType.Ekstern, - variant: {}, + type: PartType.REMOTE, externalId: '', rawType: '', - cues: [ - literal({ - type: CueType.Ekstern, - source: 'LIVE 1', - iNewsCommand: 'EKSTERN' - }) - ], + cues: [cueEkstern1], title: 'LIVE 1', script: '', fields: {}, @@ -2416,9 +2331,7 @@ describe('Body parser', () => { }), literal({ type: PartType.Kam, - variant: { - name: '2' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_2, externalId: '', rawType: 'KAM 2', cues: [], @@ -2457,9 +2370,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, rawType: 'KAM 1', fields, modified: 0, @@ -2487,9 +2398,7 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Kam, - variant: { - name: '2' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_2, rawType: 'KAM 2', cues: [ literal>({ @@ -2529,7 +2438,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Unknown, - variant: {}, rawType: '', cues: [ literal>({ @@ -2595,7 +2503,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Unknown, - variant: {}, rawType: '', cues: [ literal>({ @@ -2629,7 +2536,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Unknown, - variant: {}, rawType: '', cues: [ literal>({ @@ -2676,7 +2582,6 @@ describe('Body parser', () => { literal({ externalId: '', type: PartType.Unknown, - variant: {}, rawType: '', cues: [ literal>({ @@ -2722,8 +2627,12 @@ describe('Body parser', () => { externalId: '', type: PartType.EVS, rawType: 'EVS 1', - variant: { - evs: '1' + sourceDefinition: { + sourceType: SourceType.EVS, + id: 'EVS 1', + name: 'EVS 1', + raw: 'EVS 1', + vo: false }, effekt: 1, cues: [cueGrafik1, cueGrafik2, cueGrafik3], @@ -2743,18 +2652,11 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ externalId: '', - type: PartType.Ekstern, + type: PartType.REMOTE, title: 'LIVE 1', rawType: '', - variant: {}, effekt: 1, - cues: [ - literal({ - type: CueType.Ekstern, - source: 'LIVE 1', - iNewsCommand: 'EKSTERN' - }) - ], + cues: [cueEkstern1], fields, modified: 0, script: '', @@ -2783,9 +2685,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', cues: [ literal>({ @@ -2830,9 +2730,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', cues: [ literal>({ @@ -2884,9 +2782,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', cues: [ literal({ @@ -2932,9 +2828,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', cues: [], rawType: 'KAM 1', @@ -2947,7 +2841,6 @@ describe('Body parser', () => { literal({ type: PartType.Unknown, externalId: '', - variant: {}, cues: [ literal>({ type: CueType.Graphic, @@ -2993,9 +2886,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', cues: [], rawType: 'KAM 1', @@ -3008,7 +2899,6 @@ describe('Body parser', () => { literal({ type: PartType.Grafik, externalId: '', - variant: {}, title: 'LgfxWeb/-ETKAEM_07-05-2019_17:55:42', cues: [ literal>({ @@ -3054,9 +2944,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', cues: [], rawType: 'KAM 1', @@ -3069,7 +2957,6 @@ describe('Body parser', () => { literal({ type: PartType.Unknown, externalId: '', - variant: {}, cues: [ literal({ type: CueType.UNPAIRED_TARGET, @@ -3088,7 +2975,6 @@ describe('Body parser', () => { literal({ type: PartType.Grafik, externalId: '', - variant: {}, cues: [ literal({ type: CueType.UNPAIRED_PILOT, @@ -3128,9 +3014,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', cues: [ literal>({ @@ -3175,9 +3059,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', cues: [ literal>({ @@ -3222,9 +3104,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', cues: [], rawType: 'KAM 1', @@ -3236,7 +3116,6 @@ describe('Body parser', () => { }), literal({ type: PartType.Unknown, - variant: {}, externalId: '', cues: [ literal({ @@ -3290,9 +3169,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', cues: [], rawType: 'KAM 1', @@ -3304,7 +3181,6 @@ describe('Body parser', () => { }), literal({ type: PartType.Unknown, - variant: {}, externalId: '', cues: [ literal({ @@ -3358,9 +3234,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', cues: [], rawType: 'KAM 1', @@ -3372,7 +3246,6 @@ describe('Body parser', () => { }), literal({ type: PartType.Unknown, - variant: {}, externalId: '', cues: [ literal({ @@ -3391,7 +3264,6 @@ describe('Body parser', () => { }), literal({ type: PartType.Unknown, - variant: {}, externalId: '', cues: [ literal>({ @@ -3443,9 +3315,7 @@ describe('Body parser', () => { expect(stripExternalId(result)).toEqual([ literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: SOURCE_DEFINITION_KAM_1, externalId: '', cues: [ literal>({ @@ -3473,7 +3343,6 @@ describe('Body parser', () => { }), literal({ type: PartType.VO, - variant: {}, externalId: '', cues: [ literal>({ @@ -3633,7 +3502,6 @@ function createPartDefinition(cues?: CueDefinition[]): PartDefinition { externalId: `externalId_${Math.random() * 1000}`, cues, type: PartType.Grafik, - variant: {}, script: '', fields: {}, modified: 123, 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 30b7b5fcb..46d0397e3 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,6 @@ import { IBlueprintRundownDB, PlaylistTimingType } from '@tv2media/blueprints-integration' -import { CueType } from 'tv2-constants' +import { SourceDefinitionEkstern, SourceDefinitionKam } 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' @@ -33,6 +34,21 @@ import { const RUNDOWN_EXTERNAL_ID = 'TEST.SOFIE.JEST' +const SOURCE_DEFINITION_KAM_1: SourceDefinitionKam = { + sourceType: SourceType.Kam, + id: '1', + raw: 'KAM 1', + minusMic: false, + name: 'KAM 1' +} +const SOURCE_DEFINITION_LIVE_1: SourceDefinitionEkstern = { + sourceType: SourceType.REMOTE, + variant: 'LIVE', + id: '1', + name: 'LIVE 1', + raw: 'LIVE 1' +} + function makeMockContext() { const rundown = literal({ externalId: RUNDOWN_EXTERNAL_ID, @@ -1013,7 +1029,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.Ekstern, - source: 'LIVE 1', + sourceDefinition: SOURCE_DEFINITION_LIVE_1, iNewsCommand: 'EKSTERN', transition: {} }) @@ -1026,7 +1042,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.Ekstern, - source: 'LIVE 1', + sourceDefinition: SOURCE_DEFINITION_LIVE_1, iNewsCommand: 'EKSTERN', transition: { effekt: 1 @@ -1041,7 +1057,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.Ekstern, - source: 'LIVE 1', + sourceDefinition: SOURCE_DEFINITION_LIVE_1, iNewsCommand: 'EKSTERN', transition: { transition: { @@ -1060,7 +1076,7 @@ describe('Cue parser', () => { literal({ type: CueType.DVE, template: 'sommerfugl', - sources: { INP1: 'KAM 1', INP2: 'LIVE 1' }, + sources: { INP1: SOURCE_DEFINITION_KAM_1, INP2: SOURCE_DEFINITION_LIVE_1 }, labels: ['Odense', 'København'], iNewsCommand: 'DVE' }) @@ -1074,7 +1090,7 @@ describe('Cue parser', () => { literal({ type: CueType.DVE, template: 'sommerfugl', - sources: { INP1: 'KAM 1', INP2: 'LIVE 1' }, + sources: { INP1: SOURCE_DEFINITION_KAM_1, INP2: SOURCE_DEFINITION_LIVE_1 }, labels: ['Odense', 'København'], iNewsCommand: 'DVE' }) @@ -1088,7 +1104,7 @@ describe('Cue parser', () => { literal({ type: CueType.DVE, template: 'sommerfugl', - sources: { INP1: 'KAM 1', INP2: 'LIVE 1' }, + sources: { INP1: SOURCE_DEFINITION_KAM_1, INP2: SOURCE_DEFINITION_LIVE_1 }, labels: ['Odense', 'København'], iNewsCommand: 'DVE' }) @@ -1287,7 +1303,7 @@ describe('Cue parser', () => { literal({ type: CueType.AdLib, variant: 'MORBARN', - inputs: { INP1: 'LIVE 1', INP2: 'KAM 1' }, + inputs: { INP1: SOURCE_DEFINITION_LIVE_1, INP2: SOURCE_DEFINITION_KAM_1 }, iNewsCommand: 'ADLIBPIX' }) ) diff --git a/src/tv2-common/inewsConversion/converters/__tests__/find-target-pair.spec.ts b/src/tv2-common/inewsConversion/converters/__tests__/find-target-pair.spec.ts index 76418a3f0..68475b6ca 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/find-target-pair.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/find-target-pair.spec.ts @@ -13,7 +13,6 @@ describe('Find target pair', () => { test('TargetEngine + Pilot', () => { const part = literal({ type: PartType.Unknown, - variant: {}, externalId: '00001', script: '', rawType: '', @@ -43,7 +42,6 @@ describe('Find target pair', () => { }) const expectedResult = literal({ type: PartType.Unknown, - variant: {}, externalId: '00001', script: '', rawType: '', @@ -78,7 +76,6 @@ describe('Find target pair', () => { test('TLF + Pilot', () => { const part = literal({ type: PartType.Unknown, - variant: {}, externalId: '00001', script: '', rawType: '', @@ -107,7 +104,6 @@ describe('Find target pair', () => { }) const expectedResult = literal({ type: PartType.Unknown, - variant: {}, externalId: '00001', script: '', rawType: '', diff --git a/src/tv2-common/inewsConversion/converters/__tests__/part-to-parent-class.spec.ts b/src/tv2-common/inewsConversion/converters/__tests__/part-to-parent-class.spec.ts index 2b0da76f1..3e13e4dca 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/part-to-parent-class.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/part-to-parent-class.spec.ts @@ -1,19 +1,24 @@ import { literal } from 'tv2-common' -import { CueType, PartType } from 'tv2-constants' +import { CueType, PartType, SourceType } from 'tv2-constants' import { PartDefinitionEkstern } from '../ParseBody' import { CueDefinitionEkstern, PartToParentClass } from '../ParseCue' describe('PartToParentClass', () => { it('Creates class for Ekstern', () => { const partDefinition = literal({ - type: PartType.Ekstern, - variant: '', + type: PartType.REMOTE, externalId: '', rawType: '', cues: [ literal({ type: CueType.Ekstern, - source: 'Live 1', + sourceDefinition: { + sourceType: SourceType.REMOTE, + variant: 'LIVE', + id: '1', + raw: 'Live 1', + name: 'LIVE 1' + }, iNewsCommand: 'EKSTERN' }) ], diff --git a/src/tv2-common/layers/timelineLayers.ts b/src/tv2-common/layers/timelineLayers.ts index 041fe55f2..0e1188edf 100644 --- a/src/tv2-common/layers/timelineLayers.ts +++ b/src/tv2-common/layers/timelineLayers.ts @@ -3,13 +3,6 @@ import { literal } from 'tv2-common' import { ATEMModel } from '../../types/atem' import { GetDSKCount } from '../helpers' -export function SisyfosEVSSource(i: number | string) { - if (i.toString().toLowerCase() === 'epsio') { - return 'sisyfos_source_epsio' - } - return `sisyfos_source_evs_${i}` -} - export function AbstractLLayerServerEnable(i: number) { return `server_enable_${i}` } diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index 7ce92687f..94a5c49cd 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -91,7 +91,6 @@ export async function CreatePartServerBase< layers, sourceDuration, mediaPlayerSession, - context, config, config.studio.CasparPrerollDuration ) @@ -210,11 +209,9 @@ function getContentServerElement< layers: ServerPartLayers, sourceDuration: number | undefined, mediaPlayerSession: string, - context: IShowStyleUserContext, config: ShowStyleConfig ): WithTimeline { return MakeContentServer( - context, file, mediaPlayerSession, partDefinition, @@ -249,7 +246,6 @@ function getServerSelectionBlueprintPiece< layers: ServerPartLayers, sourceDuration: number | undefined, mediaPlayerSession: string, - context: IShowStyleUserContext, config: ShowStyleConfig, prerollDuration: number ): IBlueprintPiece { @@ -261,7 +257,6 @@ function getServerSelectionBlueprintPiece< layers, sourceDuration, mediaPlayerSession, - context, config ) diff --git a/src/tv2-common/pieces/tags.ts b/src/tv2-common/pieces/tags.ts index 63c7a5a8a..9f94865a8 100644 --- a/src/tv2-common/pieces/tags.ts +++ b/src/tv2-common/pieces/tags.ts @@ -1,5 +1,6 @@ import { ActionTakeWithTransitionVariant, CueDefinitionDVE, SanitizeString } from 'tv2-common' import { TallyTags } from 'tv2-constants' +import { SourceDefinitionEkstern } from '../inewsConversion' export function GetTagForTransition(variant: ActionTakeWithTransitionVariant) { let tag = `${TallyTags.TAKE_WITH_TRANSITION}_${variant.type.toUpperCase()}` @@ -22,8 +23,8 @@ export function GetTagForKam(name: string) { return `${TallyTags.KAM}_${SanitizeString(name)}` } -export function GetTagForLive(name: string) { - return `${TallyTags.LIVE}_${SanitizeString(name)}` +export function GetTagForLive(sourceDefinition: SourceDefinitionEkstern) { + return `${TallyTags.LIVE}_${SanitizeString(sourceDefinition.name)}` } export function GetTagForServer(segmentExternalId: string, clip: string, vo: boolean) { diff --git a/src/tv2-common/sources.ts b/src/tv2-common/sources.ts index 27289158f..8f47e6f31 100644 --- a/src/tv2-common/sources.ts +++ b/src/tv2-common/sources.ts @@ -1,8 +1,11 @@ import * as _ from 'underscore' import { IStudioContext, SourceLayerType } from '@tv2media/blueprints-integration' -import { literal } from 'tv2-common' +import { SourceType } from 'tv2-constants' +import { SourceMapping } from './blueprintConfig' +import { SourceDefinition, SourceDefinitionEkstern, SourceDefinitionEVS, SourceDefinitionKam } from './inewsConversion' import { TableConfigItemSourceMappingWithSisyfos } from './types' +import { assertUnreachable } from './util' // TODO: BEGONE! export function parseMapStr( @@ -49,29 +52,33 @@ export function parseMapStr( export function ParseMappingTable( studioConfig: TableConfigItemSourceMappingWithSisyfos[], type: SourceInfoType, - idPrefix?: string + sourceLayerType: SourceLayerType ): SourceInfo[] { return studioConfig.map(conf => ({ type, - id: `${idPrefix || ''}${conf.SourceName}`, + id: conf.SourceName, port: conf.AtemSource, sisyfosLayers: conf.SisyfosLayers, useStudioMics: conf.StudioMics, wantsToPersistAudio: conf.WantsToPersistAudio, - acceptPersistAudio: conf.AcceptPersistAudio + acceptPersistAudio: conf.AcceptPersistAudio, + sourceLayerType })) } +/** + * Types of sources in the mappings + * Note: these values are used for display purposes as well + */ +export enum SourceInfoType { + KAM = 'KAM', + FEED = 'FEED', + LIVE = 'LIVE', + REPLAY = 'REPLAY' +} -export type SourceInfoType = - | SourceLayerType.CAMERA - | SourceLayerType.REMOTE - | SourceLayerType.AUDIO - | SourceLayerType.VT - | SourceLayerType.GRAPHICS - | SourceLayerType.UNKNOWN - | SourceLayerType.LOCAL export interface SourceInfo { type: SourceInfoType + sourceLayerType: SourceLayerType id: string port: number ptzDevice?: string @@ -81,17 +88,13 @@ export interface SourceInfo { acceptPersistAudio?: boolean } -export function FindSourceInfo(sources: SourceInfo[], type: SourceInfoType, id: string): SourceInfo | undefined { +export function FindSourceInfo(sources: SourceMapping, type: SourceInfoType, id: string): SourceInfo | undefined { id = id.replace(/\s+/i, ' ').trim() switch (type) { - case SourceLayerType.CAMERA: - const cameraName = id.match(/^(?:KAM|CAM)(?:ERA)? ?(.+)$/i) - if (cameraName === undefined || cameraName === null) { - return undefined - } - - return _.find(sources, s => s.type === type && s.id === cameraName[1].replace(/minus mic/i, '').trim()) - case SourceLayerType.REMOTE: + case SourceInfoType.KAM: + return _.find(sources.cameras, s => s.id === id.replace(/minus mic/i, '').trim()) + case SourceInfoType.LIVE: + case SourceInfoType.FEED: const remoteName = id .replace(/VO/i, '') .replace(/\s/g, '') @@ -100,67 +103,105 @@ export function FindSourceInfo(sources: SourceInfo[], type: SourceInfoType, id: return undefined } if (/^LIVE/i.test(id)) { - return _.find(sources, s => s.type === type && s.id === remoteName[1]) + return _.find(sources.lives, s => s.id === remoteName[1]) } else { - return _.find(sources, s => s.type === type && s.id === `F${remoteName[1]}`) + return _.find(sources.feeds, s => s.id === remoteName[1]) } - case SourceLayerType.LOCAL: - const sourceId = getReplaySourceId(id) - if (!sourceId) { - return undefined - } - return _.find(sources, s => s.type === SourceLayerType.LOCAL && s.id === sourceId) + case SourceInfoType.REPLAY: + return _.find(sources.replays, s => s.id === id) default: return undefined } } -function getReplaySourceId(id: string): string | undefined { - return getEvsSourceId(id) ?? getEpsioSourceId(id) +export function isMinusMic(inputName: string): boolean { + return /minus mic/i.test(inputName) } -function getEvsSourceId(id: string): string | undefined { - const sourceId = id.match(/^EVS *(?\d+).*$/i)?.groups?.id - return sourceId ? `DP${sourceId}` : undefined -} +export function FindSourceInfoByName(sources: SourceMapping, name: string): SourceInfo | undefined { + name = name.toLowerCase() + + let sourceType: SourceInfoType | undefined + if (name.match(/live/i)) { + sourceType = SourceInfoType.LIVE + } else if (name.match(/feed/i)) { + sourceType = SourceInfoType.FEED + } else if (name.match(/[k|c]am/i)) { + sourceType = SourceInfoType.KAM + } else if (name.match(/evs/i)) { + sourceType = SourceInfoType.REPLAY + } + if (sourceType === undefined) { + return undefined + } -function getEpsioSourceId(id: string): string | undefined { - const sourceId = id.match(/^(?EPSIO)$/i)?.groups?.id - return sourceId ? `DP${sourceId}` : undefined + return FindSourceInfo(sources, sourceType, name) } -export function FindSourceInfoStrict( - _context: IStudioContext, - sources: SourceInfo[], - type: SourceInfoType, - id: string +export function FindSourceInfoByDefinition( + sources: SourceMapping, + sourceDefinition: SourceDefinition ): SourceInfo | undefined { - return FindSourceInfo(sources, type, id) -} - -export function FindSourceByName(context: IStudioContext, sources: SourceInfo[], name: string): SourceInfo | undefined { - name = (name + '').toLowerCase() - - if (name.indexOf('k') === 0 || name.indexOf('c') === 0) { - return FindSourceInfoStrict(context, sources, SourceLayerType.CAMERA, name) - } - - // TODO: This will be different for TV 2 - if (name.indexOf('r') === 0) { - return FindSourceInfoStrict(context, sources, SourceLayerType.REMOTE, name) + let arrayToSearchIn: SourceInfo[] + switch (sourceDefinition.sourceType) { + case SourceType.Kam: + arrayToSearchIn = sources.cameras + break + case SourceType.REMOTE: + arrayToSearchIn = sourceDefinition.variant === 'LIVE' ? sources.lives : sources.feeds + break + case SourceType.EVS: + arrayToSearchIn = sources.replays + break + default: + return undefined } - - // R35: context.notifyUserWarning(`Invalid source name "${name}"`) - return undefined + return _.find(arrayToSearchIn, s => s.id === sourceDefinition.id) } -export function GetInputValue(context: IStudioContext, sources: SourceInfo[], name: string): number { - let input = 1000 - const source = FindSourceByName(context, sources, name) - - if (source !== undefined) { - input = literal(source).port +export function SourceInfoToSourceDefinition( + sourceInfo: SourceInfo +): SourceDefinitionKam | SourceDefinitionEkstern | SourceDefinitionEVS { + switch (sourceInfo.type) { + case SourceInfoType.KAM: { + const name = `KAM ${sourceInfo.id}` + return { + sourceType: SourceType.Kam, + id: sourceInfo.id, + raw: name, + minusMic: false, + name + } + } + case SourceInfoType.LIVE: { + const name = `LIVE ${sourceInfo.id}` + return { + sourceType: SourceType.REMOTE, + variant: 'LIVE', + id: sourceInfo.id, + raw: name, + name + } + } + case SourceInfoType.FEED: { + const name = `FEED ${sourceInfo.id}` + return { + sourceType: SourceType.REMOTE, + variant: 'FEED', + id: sourceInfo.id, + raw: name, + name + } + } + case SourceInfoType.REPLAY: + return { + sourceType: SourceType.EVS, + id: sourceInfo.id, + raw: sourceInfo.id, + name: sourceInfo.id, + vo: false + } + default: + assertUnreachable(sourceInfo.type) } - - return input } diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index ab72c09a6..1bc5d86c1 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -45,10 +45,21 @@ export const enum PartType { INTRO = 'INTRO', EVS = 'EVS', DVE = 'DVE', - Ekstern = 'Ekstern', + REMOTE = 'Ekstern', Telefon = 'Telefon' } +export const enum SourceType { + Kam = 'Kam', + Server = 'Server', + VO = 'VO', + Teknik = 'Teknik', + Grafik = 'Grafik', + EVS = 'EVS', + REMOTE = 'Ekstern', + DEFAULT = 'Default' +} + export enum Enablers { OFFTUBE_ENABLE_FULL = 'offtube_enable_full', OFFTUBE_ENABLE_SERVER_LOOKAHEAD = 'offtube_enable_server_lookahead' diff --git a/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts b/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts index 82bc49310..974739852 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 '@tv2media/blueprints-integration' import { AddScript, literal, PartDefinitionKam } from 'tv2-common' -import { PartType, SharedOutputLayers } from 'tv2-constants' +import { PartType, SharedOutputLayers, SourceType } from 'tv2-constants' import { SourceLayer } from '../layers' describe('addScript', () => { @@ -8,8 +8,12 @@ describe('addScript', () => { const part = literal({ externalId: '00000000001-0', type: PartType.Kam, - variant: { - name: '2' + sourceDefinition: { + sourceType: SourceType.Kam, + id: '2', + raw: 'KAM 2', + name: 'KAM 2', + minusMic: false }, rawType: 'KAM 2', cues: [], diff --git a/src/tv2_afvd_showstyle/__tests__/configs.ts b/src/tv2_afvd_showstyle/__tests__/configs.ts index 2513953ff..5b97aa359 100644 --- a/src/tv2_afvd_showstyle/__tests__/configs.ts +++ b/src/tv2_afvd_showstyle/__tests__/configs.ts @@ -12,7 +12,7 @@ function getSisyfosLayers(configName: string, id: string): string[] { case 'SourcesFeed': return ['sisyfos_source_live_' + id] case 'SourcesDelayedPlayback': - return ['sisyfos_source_evs_' + id] + return ['sisyfos_source_' + id.toLowerCase().replace(' ', '_')] } return [] @@ -90,7 +90,7 @@ export const defaultStudioConfig: StudioConfig = { // TODO: prepareConfig is legacy code, refactor when refactoring FindSourceInfo SourcesRM: prepareConfig('1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,10:10', 'SourcesRM', false, true), 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), - SourcesDelayedPlayback: prepareConfig('1:5,2:5', 'SourcesDelayedPlayback', false), + 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', @@ -268,3 +268,10 @@ export const defaultShowStyleConfig: ShowStyleConfig = { ShowstyleTransition: 'CUT', SchemaConfig: [] } + +export const EMPTY_SOURCE_CONFIG = { + cameras: [], + lives: [], + feeds: [], + replays: [] +} diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 612b534cf..041f9ffaa 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -11,7 +11,6 @@ import { IStudioUserContext, PieceLifespan, PlaylistTimingType, - SourceLayerType, TimelineObjectCoreExt, TSR, WithTimeline @@ -31,14 +30,17 @@ import { CreateLYDBaseline, FindDSKJingle, generateExternalId, - GetSisyfosTimelineObjForCamera, - GetSisyfosTimelineObjForEkstern, + GetSisyfosTimelineObjForRemote, + GetSisyfosTimelineObjForReplay, GetTransitionAdLibActions, literal, localSourceName, PieceMetaData, SisyfosPersistMetaData, + SourceDefinitionKam, SourceInfo, + SourceInfoToSourceDefinition, + SourceInfoType, t } from 'tv2-common' import { @@ -48,6 +50,7 @@ import { CONSTANTS, SharedGraphicLLayer, SharedOutputLayers, + SourceType, TallyTags } from 'tv2-constants' import * as _ from 'underscore' @@ -96,7 +99,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint const res: IBlueprintAdLibPiece[] = [] res.push({ externalId: 'delayed', - name: localSourceName(info.id.replace(/dp/i, ''), vo), + name: localSourceName(info.id.replace(/R/i, ''), vo), _rank: rank, sourceLayerId: SourceLayer.PgmLocal, outputLayerId: SharedOutputLayers.PGM, @@ -128,20 +131,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint }, classes: ['adlib_deparent'] }), - ...(info.sisyfosLayers || []).map(l => { - return literal({ - id: '', - enable: { while: '1' }, - priority: 1, - layer: l, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: vo ? 2 : 1 - } - }) - }), - ...(vo ? [GetSisyfosTimelineObjForCamera(context, config, 'evs', SisyfosLLAyer.SisyfosGroupStudioMics)] : []) + ...GetSisyfosTimelineObjForReplay(config, info, vo, SisyfosLLAyer.SisyfosGroupStudioMics) ] } }) @@ -151,10 +141,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint function makeRemoteAdLibs(info: SourceInfo, rank: number): IBlueprintAdLibPiece[] { const res: IBlueprintAdLibPiece[] = [] - const eksternSisyfos = [ - ...GetSisyfosTimelineObjForEkstern(context, config.sources, `Live ${info.id}`), - GetSisyfosTimelineObjForCamera(context, config, 'telefon', SisyfosLLAyer.SisyfosGroupStudioMics) - ] + const eksternSisyfos = GetSisyfosTimelineObjForRemote(config, info, SisyfosLLAyer.SisyfosGroupStudioMics) res.push({ externalId: 'live', name: `LIVE ${info.id}`, @@ -242,82 +229,78 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint let globalRank = 1000 - config.sources - .filter(u => u.type === SourceLayerType.REMOTE) - .slice(0, 10) // the first x cameras to create live-adlibs from + config.sources.lives + .slice(0, 10) // the first x lives to create live-adlibs from .forEach(o => { adlibItems.push(...makeRemoteAdLibs(o, globalRank++)) }) - config.sources - .filter(u => u.type === SourceLayerType.REMOTE) + config.sources.lives .slice(0, 10) // the first x lives to create AUX1 (studio) adlibs .forEach(o => { adlibItems.push(...makeRemoteAuxStudioAdLibs(o, globalRank++)) }) - config.sources - .filter(u => u.type === SourceLayerType.LOCAL) - .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 - } + 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 } - }) - ] - } - }) - 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], - content: { - timelineObjects: [ - literal({ - id: '', - enable: { while: '1' }, - priority: 1, - layer: AtemLLayer.AtemAuxVizOvlIn1, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: o.port - } + } + }) + ] + } + }) + 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], + content: { + timelineObjects: [ + literal({ + id: '', + enable: { while: '1' }, + priority: 1, + layer: AtemLLayer.AtemAuxVizOvlIn1, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.AUX, + aux: { + input: o.port } - }) - ] - } - }) + } + }) + ] + } }) + }) // the rank (order) of adlibs on SourceLayer.PgmAdlibVizCmd is important, to ensure keyboard shortcuts adlibItems.push({ @@ -557,18 +540,16 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri let globalRank = 1000 - function makeAdlibBoxesActions(info: SourceInfo, type: 'KAM' | 'LIVE' | 'FEED', rank: number) { + function makeAdlibBoxesActions(info: SourceInfo, rank: number) { for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { - const feed = type === 'LIVE' && info.id.match(/^F(.+).*$/) // TODO: fix when refactoring FindSourceInfo - const name = feed ? `FEED ${feed[1]}` : `${type} ${info.id}` - const layer = type === 'KAM' ? SourceLayer.PgmCam : SourceLayer.PgmLive + const name = `${info.type} ${info.id}` + const layer = info.type === SourceInfoType.KAM ? SourceLayer.PgmCam : SourceLayer.PgmLive const userData = literal({ type: AdlibActionType.CUT_SOURCE_TO_BOX, name, - port: info.port, - sourceType: info.type, - box + box, + sourceDefinition: SourceInfoToSourceDefinition(info) }) blueprintActions.push( literal({ @@ -591,14 +572,18 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri function makeAdlibBoxesActionsReplay(info: SourceInfo, rank: number, vo: boolean) { for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { - const evsId = info.id.replace(/dp/i, '') + const name = localSourceName(info.id, vo) const userData = literal({ type: AdlibActionType.CUT_SOURCE_TO_BOX, - name: localSourceName(evsId, vo), - port: info.port, - sourceType: info.type, + name, box, - vo + sourceDefinition: { + sourceType: SourceType.EVS, + id: info.id, + vo, + raw: '', + name + } }) blueprintActions.push( literal({ @@ -608,7 +593,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri userDataManifest: {}, display: { _rank: rank + 0.1 * box, - label: t(`${localSourceName(evsId, vo)} inp ${box + 1}`), + label: t(`${name} inp ${box + 1}`), sourceLayerId: SourceLayer.PgmLocal, outputLayerId: SharedOutputLayers.SEC, content: {}, @@ -624,10 +609,8 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri const userData = literal({ type: AdlibActionType.CUT_SOURCE_TO_BOX, name: `SERVER`, - port: -1, - sourceType: SourceLayerType.VT, box, - server: true + sourceDefinition: { sourceType: SourceType.Server } }) blueprintActions.push( literal({ @@ -649,10 +632,11 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri } function makeCutCameraActions(info: SourceInfo, queue: boolean, rank: number) { + const sourceDefinition = SourceInfoToSourceDefinition(info) as SourceDefinitionKam const userData = literal({ type: AdlibActionType.CUT_TO_CAMERA, queue, - name: info.id + sourceDefinition }) blueprintActions.push( literal({ @@ -662,7 +646,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri userDataManifest: {}, display: { _rank: rank, - label: t(`KAM ${info.id}`), + label: t(sourceDefinition.name), sourceLayerId: SourceLayer.PgmCam, outputLayerId: SharedOutputLayers.PGM, content: {}, @@ -672,25 +656,22 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri ) } - config.sources - .filter(u => u.type === SourceLayerType.CAMERA) + 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 - .filter(u => u.type === SourceLayerType.CAMERA) + config.sources.cameras .slice(0, 5) // the first x cameras to create preview cam-adlibs from .forEach(o => { makeCutCameraActions(o, true, globalRank++) }) - config.sources - .filter(u => u.type === SourceLayerType.CAMERA) + config.sources.cameras .slice(0, 5) // the first x cameras to dve actions from .forEach(o => { - makeAdlibBoxesActions(o, 'KAM', globalRank++) + makeAdlibBoxesActions(o, globalRank++) }) function makeRecallLastLiveAction() { @@ -716,20 +697,21 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri makeRecallLastLiveAction() - config.sources - .filter(u => u.type === SourceLayerType.REMOTE) + config.sources.lives .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from .forEach(o => { - makeAdlibBoxesActions(o, o.id.match(/^F/) ? 'FEED' : 'LIVE', globalRank++) + makeAdlibBoxesActions(o, globalRank++) }) - config.sources - .filter(u => u.type === SourceLayerType.LOCAL) + 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 .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from .forEach(o => { - if (!/EPSIO/i.test(o.id)) { - makeAdlibBoxesActionsReplay(o, globalRank++, false) - } makeAdlibBoxesActionsReplay(o, globalRank++, true) }) diff --git a/src/tv2_afvd_showstyle/helpers/content/dve.ts b/src/tv2_afvd_showstyle/helpers/content/dve.ts index 9d7e91023..8e8cfd6f2 100644 --- a/src/tv2_afvd_showstyle/helpers/content/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/content/dve.ts @@ -1,13 +1,5 @@ import { IShowStyleUserContext, SplitsContent, WithTimeline } from '@tv2media/blueprints-integration' -import { - CueDefinitionDVE, - DVEConfigInput, - DVEOptions, - GetLayersForEkstern, - GetSisyfosTimelineObjForEkstern, - MakeContentDVEBase, - PartDefinition -} from 'tv2-common' +import { CueDefinitionDVE, DVEConfigInput, DVEOptions, MakeContentDVEBase, PartDefinition } from 'tv2-common' import { BlueprintConfig } from '../../../tv2_afvd_showstyle/helpers/config' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' @@ -32,10 +24,6 @@ export const AFVD_DVE_GENERATOR_OPTIONS: DVEOptions = { ClipPending: CasparLLayer.CasparPlayerClipPending } }, - dveTimelineGenerators: { - GetSisyfosTimelineObjForEkstern, - GetLayersForEkstern - }, boxMappings: [AtemLLayer.AtemSSrcBox1, AtemLLayer.AtemSSrcBox2, AtemLLayer.AtemSSrcBox3, AtemLLayer.AtemSSrcBox4], AUDIO_LAYERS: Object.keys(SisyfosLLAyer) } 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 e95be0f64..84f00b25e 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -16,7 +16,15 @@ import { PartDefinitionKam, PieceMetaData } from 'tv2-common' -import { AbstractLLayer, AdlibTags, CueType, PartType, SharedGraphicLLayer, SharedOutputLayers } from 'tv2-constants' +import { + AbstractLLayer, + 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' @@ -37,9 +45,7 @@ const config = getConfig(makeMockContext()) const dummyPart = literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: { sourceType: SourceType.Kam, id: '1', raw: 'Kam 1', minusMic: false, name: 'KAM 1' }, externalId: '0001', rawType: 'Kam 1', cues: [], 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 50dc262a8..706aa1a33 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts @@ -6,12 +6,13 @@ import { TSR } from '@tv2media/blueprints-integration' import { CueDefinitionLYD, EvaluateLYD, literal, ParseCue, PartDefinitionKam } from 'tv2-common' -import { AdlibTags, NoteType, PartType, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' +import { AdlibTags, NoteType, PartType, SharedOutputLayers, SharedSourceLayers, SourceType } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' import { DEFAULT_GRAPHICS_SETUP, defaultShowStyleConfig, - defaultStudioConfig + defaultStudioConfig, + EMPTY_SOURCE_CONFIG } from '../../../../tv2_afvd_showstyle/__tests__/configs' import { defaultDSKConfig, @@ -32,9 +33,7 @@ function makeMockContext() { const CONFIG = getConfig(makeMockContext()) const MOCK_PART = literal({ type: PartType.Kam, - variant: { - name: '1' - }, + sourceDefinition: { sourceType: SourceType.Kam, id: '1', raw: 'Kam 1', minusMic: false, name: 'KAM 1' }, externalId: '0001', rawType: 'Kam 1', cues: [], @@ -57,7 +56,7 @@ describe('lyd', () => { { showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, studio: (defaultStudioConfig as unknown) as StudioConfig, - sources: [], + sources: EMPTY_SOURCE_CONFIG, mediaPlayers: [], dsk: defaultDSKConfig, selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP @@ -89,7 +88,7 @@ describe('lyd', () => { { showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, studio: (defaultStudioConfig as unknown) as StudioConfig, - sources: [], + sources: EMPTY_SOURCE_CONFIG, mediaPlayers: [], dsk: defaultDSKConfig, selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP @@ -124,7 +123,7 @@ describe('lyd', () => { { showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, studio: (defaultStudioConfig as unknown) as StudioConfig, - sources: [], + sources: EMPTY_SOURCE_CONFIG, mediaPlayers: [], dsk: defaultDSKConfig, selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP @@ -154,7 +153,7 @@ describe('lyd', () => { { showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, studio: (defaultStudioConfig as unknown) as StudioConfig, - sources: [], + sources: EMPTY_SOURCE_CONFIG, mediaPlayers: [], dsk: defaultDSKConfig, selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP @@ -182,7 +181,7 @@ describe('lyd', () => { { showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, studio: (defaultStudioConfig as unknown) as StudioConfig, - sources: [], + sources: EMPTY_SOURCE_CONFIG, mediaPlayers: [], dsk: defaultDSKConfig, selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP 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 fe2809a92..9be9d2f18 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -16,7 +16,7 @@ import { PartDefinitionKam, PieceMetaData } from 'tv2-common' -import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayers } from 'tv2-constants' +import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayers, SourceType } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' import { DEFAULT_GRAPHICS_SETUP, @@ -41,8 +41,12 @@ mockContext.showStyleConfig = defaultShowStyleConfig as any const dummyPart = literal({ type: PartType.Kam, - variant: { - name: '1' + sourceDefinition: { + sourceType: SourceType.Kam, + id: '1', + raw: 'Kam 1', + minusMic: false, + name: 'KAM 2' }, externalId: '0001', rawType: 'Kam 1', @@ -83,7 +87,12 @@ describe('telefon', () => { { showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, studio: (defaultStudioConfig as unknown) as StudioConfig, - sources: [], + sources: { + cameras: [], + lives: [], + feeds: [], + replays: [] + }, mediaPlayers: [], dsk: defaultDSKConfig, selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts index 218c415f1..c0670973e 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts @@ -4,7 +4,6 @@ import { IBlueprintPiece, IShowStyleUserContext, IStudioUserContext, - SourceLayerType, TSR } from '@tv2media/blueprints-integration' import { @@ -12,12 +11,10 @@ import { CueDefinitionGraphic, EnableDSK, FindDSKFullGFX, - GetSisyfosTimelineObjForCamera, + GetSisyfosTimelineObjForFull, GraphicPilot, literal, PilotGeneratorSettings, - SisyfosEVSSource, - SourceInfo, TV2BlueprintConfig } from 'tv2-common' import { AtemLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' @@ -57,7 +54,7 @@ export function EvaluateCueGraphicPilot( function makeStudioTimelineViz( config: BlueprintConfig, - context: IStudioUserContext, + _context: IStudioUserContext, adlib: boolean ): TSR.TSRTimelineObj[] { const fullDSK = FindDSKFullGFX(config) @@ -98,12 +95,11 @@ function makeStudioTimelineViz( }), // Assume DSK is off by default (config table) ...EnableDSK(config, 'FULL'), - GetSisyfosTimelineObjForCamera(context, config, 'full', SisyfosLLAyer.SisyfosGroupStudioMics), - ...muteSisyfosChannels(config.sources) + ...GetSisyfosTimelineObjForFull(config, SisyfosLLAyer.SisyfosGroupStudioMics) ] } -function makeStudioTimelineCaspar(config: BlueprintConfig, context: IStudioUserContext) { +function makeStudioTimelineCaspar(config: BlueprintConfig, _context: IStudioUserContext) { const fullDSK = FindDSKFullGFX(config) return [ literal({ @@ -130,44 +126,6 @@ function makeStudioTimelineCaspar(config: BlueprintConfig, context: IStudioUserC } } }), - GetSisyfosTimelineObjForCamera(context, config, 'full', SisyfosLLAyer.SisyfosGroupStudioMics), - ...muteSisyfosChannels(config.sources) + ...GetSisyfosTimelineObjForFull(config, SisyfosLLAyer.SisyfosGroupStudioMics) ] } - -function muteSisyfosChannels(sources: SourceInfo[]): TSR.TimelineObjSisyfosChannel[] { - return [ - SisyfosLLAyer.SisyfosSourceServerA, - SisyfosLLAyer.SisyfosSourceServerB, - SisyfosLLAyer.SisyfosSourceLive_1, - SisyfosLLAyer.SisyfosSourceLive_2, - SisyfosLLAyer.SisyfosSourceLive_3, - SisyfosLLAyer.SisyfosSourceLive_4, - SisyfosLLAyer.SisyfosSourceLive_5, - SisyfosLLAyer.SisyfosSourceLive_6, - SisyfosLLAyer.SisyfosSourceLive_7, - SisyfosLLAyer.SisyfosSourceLive_8, - SisyfosLLAyer.SisyfosSourceLive_9, - SisyfosLLAyer.SisyfosSourceLive_10, - SisyfosLLAyer.SisyfosSourceTLF, - ...[ - ...(sources - .filter(s => s.type === SourceLayerType.LOCAL) - .map(s => SisyfosEVSSource(s.id.replace(/^DP/i, '') as SisyfosLLAyer)) as SisyfosLLAyer[]) - ] - ].map(layer => { - return literal({ - id: '', - enable: { - start: 0 - }, - priority: 2, - layer, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: 0 - } - }) - }) -} diff --git a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts index 84ac7f7c7..1b7b8d8d5 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts @@ -5,11 +5,10 @@ import { IBlueprintPiece, ISegmentUserContext, PieceLifespan, - SourceLayerType, TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { CalculateTime, CueDefinitionRouting, FindSourceInfoStrict, literal, TV2BlueprintConfig } from 'tv2-common' +import { CalculateTime, CueDefinitionRouting, FindSourceInfoByName, literal, TV2BlueprintConfig } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import _ = require('underscore') import { AtemLLayer } from '../../../tv2_afvd_studio/layers' @@ -30,10 +29,7 @@ export function EvaluateCueRouting( if (!source || !source.length) { context.notifyUserWarning(`No input provided for viz engine aux`) } else { - let sourceInfo = FindSourceInfoStrict(context, config.sources, SourceLayerType.REMOTE, source) - if (!sourceInfo) { - sourceInfo = FindSourceInfoStrict(context, config.sources, SourceLayerType.CAMERA, source) - } + const sourceInfo = FindSourceInfoByName(config.sources, source) if (!sourceInfo) { context.notifyUserWarning(`Could not find source ${source}`) diff --git a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts index 15c3758df..4cce5e9be 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts @@ -2,16 +2,9 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintPiece, - ISegmentUserContext, - TSR + ISegmentUserContext } from '@tv2media/blueprints-integration' -import { - CueDefinitionTelefon, - GetSisyfosTimelineObjForCamera, - GraphicDisplayName, - literal, - PartDefinition -} from 'tv2-common' +import { CueDefinitionTelefon, GetSisyfosTimelineObjForTelefon, GraphicDisplayName, PartDefinition } from 'tv2-common' import { SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' import { BlueprintConfig } from '../config' import { EvaluateCueGraphic } from './graphic' @@ -48,21 +41,11 @@ export function EvaluateTelefon( const graphicPiece = pieces[graphicPieceIndex] if (graphicPiece && graphicPiece.content && graphicPiece.content.timelineObjects) { graphicPiece.content.timelineObjects.push( - literal({ - id: '', - enable: { - start: 0 - }, - priority: 1, - layer: SisyfosLLAyer.SisyfosSourceTLF, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: 1 - } - }), - - GetSisyfosTimelineObjForCamera(context, config, 'telefon', SisyfosLLAyer.SisyfosGroupStudioMics) + ...GetSisyfosTimelineObjForTelefon( + config, + SisyfosLLAyer.SisyfosSourceTLF, + SisyfosLLAyer.SisyfosGroupStudioMics + ) ) graphicPiece.name = `${parsedCue.source}` pieces[graphicPieceIndex] = graphicPiece diff --git a/src/tv2_afvd_showstyle/migrations/hotkeys.ts b/src/tv2_afvd_showstyle/migrations/hotkeys.ts index 0b83ffcea..e97083b60 100644 --- a/src/tv2_afvd_showstyle/migrations/hotkeys.ts +++ b/src/tv2_afvd_showstyle/migrations/hotkeys.ts @@ -6,8 +6,8 @@ import { import { GlobalHotkeySources } from 'tv2-common' import { manifestAFVDSourcesCam, - manifestAFVDSourcesDelayedPlayback, manifestAFVDSourcesFeed, + manifestAFVDSourcesReplay, manifestAFVDSourcesRM } from '../../tv2_afvd_studio/config-manifests' import { dveStylesManifest } from '../config-manifests' @@ -25,8 +25,8 @@ export function GetDefaultStudioSourcesForAFVD(context: MigrationContextShowStyl 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 => `F${source.SourceName}`) as string[] - const local = manifestAFVDSourcesDelayedPlayback.defaultVal.map(source => source.SourceName) as string[] + const feed = manifestAFVDSourcesFeed.defaultVal.map(source => source.SourceName) as string[] + const local = manifestAFVDSourcesReplay.defaultVal.map(source => source.SourceName) as string[] return { camera, diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index bbc920072..f9926843d 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -7,7 +7,6 @@ import { IBlueprintPiece, ISegmentUserContext, PieceLifespan, - SourceLayerType, TimelineObjectCoreExt, TSR } from '@tv2media/blueprints-integration' @@ -15,14 +14,14 @@ import { AddScript, CreatePartInvalid, EVSParentClass, - FindSourceInfoStrict, - GetSisyfosTimelineObjForCamera, - GetSisyfosTimelineObjForEVS, + FindSourceInfo, + GetSisyfosTimelineObjForReplay, literal, PartDefinitionEVS, PartTime, PieceMetaData, SourceInfo, + SourceInfoType, TransitionFromString, TransitionSettings } from 'tv2-common' @@ -40,9 +39,7 @@ export async function CreatePartEVS( totalWords: number ): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) - const title = /EPSIO/i.test(partDefinition.variant.evs) - ? partDefinition.variant.evs - : `EVS ${partDefinition.variant.evs} ${partDefinition.variant.vo ?? ''}` + const title = `${partDefinition.sourceDefinition.id} ${partDefinition.sourceDefinition.vo ?? ''}` let part = literal({ externalId: partDefinition.externalId, @@ -58,16 +55,11 @@ export async function CreatePartEVS( part = { ...part, ...CreateEffektForpart(context, config, partDefinition, pieces) } - const sourceInfoDelayedPlayback = FindSourceInfoStrict( - context, - config.sources, - SourceLayerType.LOCAL, - partDefinition.rawType.replace(/ ?VO/i, '') - ) - if (sourceInfoDelayedPlayback === undefined) { + const sourceInfoReplay = FindSourceInfo(config.sources, SourceInfoType.REPLAY, partDefinition.rawType) + if (sourceInfoReplay === undefined) { return CreatePartInvalid(partDefinition) } - const atemInput = sourceInfoDelayedPlayback.port + const atemInput = sourceInfoReplay.port pieces.push( literal({ @@ -82,7 +74,7 @@ export async function CreatePartEVS( sisyfosLayers: [] } }), - content: makeContentEVS(context, config, atemInput, partDefinition, sourceInfoDelayedPlayback) + content: makeContentEVS(config, atemInput, partDefinition, sourceInfoReplay) }) ) @@ -115,11 +107,10 @@ export async function CreatePartEVS( } function makeContentEVS( - context: ISegmentUserContext, config: BlueprintConfig, atemInput: number, partDefinition: PartDefinitionEVS, - sourceInfoDelayedPlayback: SourceInfo + sourceInfoReplay: SourceInfo ): IBlueprintPiece['content'] { return { studioLabel: '', @@ -144,12 +135,14 @@ function makeContentEVS( transitionSettings: TransitionSettings(partDefinition) } }, - classes: [EVSParentClass('studio0', partDefinition.variant.evs)] + classes: [EVSParentClass('studio0', partDefinition.sourceDefinition.id)] }), - GetSisyfosTimelineObjForEVS(sourceInfoDelayedPlayback, !!partDefinition.variant.vo), - ...(partDefinition.variant.vo - ? [GetSisyfosTimelineObjForCamera(context, config, 'evs', SisyfosLLAyer.SisyfosGroupStudioMics)] - : []) + ...GetSisyfosTimelineObjForReplay( + config, + sourceInfoReplay, + !!partDefinition.sourceDefinition.vo, + SisyfosLLAyer.SisyfosGroupStudioMics + ) ]) } } diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index eeb7d9b03..606f73e23 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -6,7 +6,6 @@ import { IBlueprintPiece, ISegmentUserContext, PieceLifespan, - SourceLayerType, TimelineObjectCoreExt, TSR, VTContent, @@ -19,7 +18,7 @@ import { CreatePartInvalid, CreatePartKamBase, FindDSKJingle, - FindSourceInfoStrict, + FindSourceInfoByDefinition, GetSisyfosTimelineObjForCamera, literal, PartDefinitionKam, @@ -97,7 +96,7 @@ export async function CreatePartKam( ) part.expectedDuration = TimeFromINewsField(partDefinition.fields.totalTime) * 1000 } else { - const sourceInfoCam = FindSourceInfoStrict(context, config.sources, SourceLayerType.CAMERA, partDefinition.rawType) + const sourceInfoCam = FindSourceInfoByDefinition(config.sources, partDefinition.sourceDefinition) if (sourceInfoCam === undefined) { context.notifyUserWarning(`${partDefinition.rawType} does not exist in this studio`) return CreatePartInvalid(partDefinition) @@ -143,14 +142,13 @@ export async function CreatePartKam( } }, ...(AddParentClass(config, partDefinition) - ? { classes: [CameraParentClass('studio0', partDefinition.variant.name)] } + ? { classes: [CameraParentClass('studio0', partDefinition.sourceDefinition.id)] } : {}) }), - - GetSisyfosTimelineObjForCamera( - context, + ...GetSisyfosTimelineObjForCamera( config, - partDefinition.rawType, + sourceInfoCam, + partDefinition.sourceDefinition.minusMic, SisyfosLLAyer.SisyfosGroupStudioMics ) ]) diff --git a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts index 6f0b3286c..e27d9456b 100644 --- a/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts +++ b/src/tv2_afvd_studio/__tests__/config-manifest.spec.ts @@ -33,7 +33,7 @@ const blankStudioConfig: StudioConfig = { SourcesCam: [], SourcesRM: [], SourcesFeed: [], - SourcesDelayedPlayback: [], + SourcesReplay: [], ABMediaPlayers: [], StudioMics: [], ABPlaybackDebugLogging: false, diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index 56bdb2e56..c16c52a83 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -63,7 +63,6 @@ describe('Graphics', () => { const partDefintion: PartDefinition = literal({ type: PartType.Grafik, - variant: {}, externalId: '', segmentExternalId: SEGMENT_EXTERNAL_ID, rawType: '', @@ -99,7 +98,6 @@ describe('Graphics', () => { const partDefinition: PartDefinition = literal({ type: PartType.Grafik, - variant: {}, externalId: '', segmentExternalId: SEGMENT_EXTERNAL_ID, rawType: '', @@ -135,7 +133,6 @@ describe('Graphics', () => { const partDefinition: PartDefinition = literal({ type: PartType.Grafik, - variant: {}, externalId: '', segmentExternalId: SEGMENT_EXTERNAL_ID, rawType: '', @@ -152,7 +149,7 @@ describe('Graphics', () => { expect(piece.sourceLayerId).toBe(SourceLayer.PgmPilot) expect(piece.outputLayerId).toBe(SharedOutputLayers.PGM) expect(piece.enable).toEqual({ start: 0 }) - expect(piece.prerollDuration).toBe(config.studio.VizPilotGraphics.PrerollDuration) + // expect(piece.prerollDuration).toBe(config.studio.VizPilotGraphics.PrerollDuration) expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] @@ -200,7 +197,6 @@ describe('Graphics', () => { const partDefinition: PartDefinition = literal({ type: PartType.Grafik, - variant: {}, externalId: '', segmentExternalId: SEGMENT_EXTERNAL_ID, rawType: '', @@ -258,7 +254,6 @@ describe('Graphics', () => { const partDefinition: PartDefinition = literal({ type: PartType.Grafik, - variant: {}, externalId: '', segmentExternalId: SEGMENT_EXTERNAL_ID, rawType: '', @@ -313,7 +308,6 @@ describe('Graphics', () => { const partDefinition: PartDefinition = literal({ type: PartType.Grafik, - variant: {}, externalId: '', segmentExternalId: SEGMENT_EXTERNAL_ID, rawType: '', @@ -378,7 +372,6 @@ describe('Graphics', () => { const partDefinition: PartDefinition = literal({ type: PartType.Grafik, - variant: {}, externalId: '', segmentExternalId: SEGMENT_EXTERNAL_ID, rawType: '', @@ -418,7 +411,6 @@ describe('Graphics', () => { const partDefinition: PartDefinition = literal({ type: PartType.Unknown, - variant: {}, externalId: '', segmentExternalId: SEGMENT_EXTERNAL_ID, rawType: '', @@ -454,7 +446,6 @@ describe('Graphics', () => { const partDefinition: PartDefinition = literal({ type: PartType.Unknown, - variant: {}, externalId: '', segmentExternalId: SEGMENT_EXTERNAL_ID, rawType: '', @@ -506,7 +497,6 @@ describe('Graphics', () => { const partDefinition: PartDefinition = literal({ type: PartType.Unknown, - variant: {}, externalId: '', segmentExternalId: SEGMENT_EXTERNAL_ID, rawType: '', diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index 1268b718e..9180c7122 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -196,7 +196,7 @@ export const manifestAFVDSourcesRM = MakeConfigForSources('RM', 'Live', true, tr export const manifestAFVDSourcesFeed = MakeConfigForSources('Feed', 'Feed', true, false, []) -export const manifestAFVDSourcesDelayedPlayback = MakeConfigForSources('DelayedPlayback', 'EVS', false, false, [ +export const manifestAFVDSourcesReplay = MakeConfigForSources('Replay', 'Replay', false, false, [ { _id: '', SourceName: '1', @@ -284,7 +284,7 @@ export const studioConfigManifest: ConfigManifestEntry[] = [ manifestAFVDSourcesCam, manifestAFVDSourcesRM, manifestAFVDSourcesFeed, - manifestAFVDSourcesDelayedPlayback, + manifestAFVDSourcesReplay, manifestAFVDSourcesABMediaPlayers, manifestAFVDStudioMics, manifestAFVDDownstreamKeyers, diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index fe0457e01..24a9cccab 100644 --- a/src/tv2_afvd_studio/helpers/config.ts +++ b/src/tv2_afvd_studio/helpers/config.ts @@ -1,7 +1,7 @@ import { IBlueprintConfig, ICommonContext, IStudioContext } from '@tv2media/blueprints-integration' import { MediaPlayerConfig, - SourceInfo, + SourceMapping, TableConfigItemDSK, TableConfigItemSourceMapping, TableConfigItemSourceMappingWithSisyfos, @@ -14,7 +14,7 @@ import { parseMediaPlayers, parseSources } from './sources' export interface BlueprintConfig { studio: StudioConfig - sources: SourceInfo[] + sources: SourceMapping showStyle: ShowStyleConfig mediaPlayers: MediaPlayerConfig // Atem Input Ids dsk: TableConfigItemDSK[] @@ -24,7 +24,7 @@ export interface StudioConfig extends TV2StudioConfigBase { // Injected by core SofieHostURL: string - SourcesDelayedPlayback: TableConfigItemSourceMappingWithSisyfos[] + SourcesReplay: TableConfigItemSourceMappingWithSisyfos[] ABMediaPlayers: TableConfigItemSourceMapping[] ABPlaybackDebugLogging: boolean StudioMics: string[] @@ -52,14 +52,11 @@ export function parseConfig(_context: ICommonContext, rawConfig: IBlueprintConfi const config: BlueprintConfig = { studio: studioConfig, showStyle: {} as any, - sources: [], - mediaPlayers: [], + sources: parseSources(studioConfig), + mediaPlayers: parseMediaPlayers(studioConfig), dsk: studioConfig.AtemSource.DSK } - config.sources = parseSources(studioConfig) - config.mediaPlayers = parseMediaPlayers(studioConfig) - return config } diff --git a/src/tv2_afvd_studio/helpers/sources.ts b/src/tv2_afvd_studio/helpers/sources.ts index e2845adb9..dd5edeb23 100644 --- a/src/tv2_afvd_studio/helpers/sources.ts +++ b/src/tv2_afvd_studio/helpers/sources.ts @@ -1,7 +1,7 @@ import * as _ from 'underscore' import { SourceLayerType } from '@tv2media/blueprints-integration' -import { ParseMappingTable, SourceInfo } from 'tv2-common' +import { ParseMappingTable, SourceInfoType, SourceMapping } from 'tv2-common' import { StudioConfig } from './config' export function parseMediaPlayers(studioConfig: StudioConfig): Array<{ id: string; val: string }> { @@ -11,11 +11,11 @@ export function parseMediaPlayers(studioConfig: StudioConfig): Array<{ id: strin })) } -export function parseSources(studioConfig: StudioConfig): SourceInfo[] { - return [ - ...ParseMappingTable(studioConfig.SourcesFeed, SourceLayerType.REMOTE, 'F'), - ...ParseMappingTable(studioConfig.SourcesRM, SourceLayerType.REMOTE), - ...ParseMappingTable(studioConfig.SourcesCam, SourceLayerType.CAMERA), - ...ParseMappingTable(studioConfig.SourcesDelayedPlayback, SourceLayerType.LOCAL, 'DP') - ] +export function parseSources(studioConfig: StudioConfig): SourceMapping { + return { + cameras: ParseMappingTable(studioConfig.SourcesCam, SourceInfoType.KAM, SourceLayerType.CAMERA), + feeds: ParseMappingTable(studioConfig.SourcesFeed, SourceInfoType.FEED, SourceLayerType.REMOTE), + lives: ParseMappingTable(studioConfig.SourcesRM, SourceInfoType.LIVE, SourceLayerType.REMOTE), + replays: ParseMappingTable(studioConfig.SourcesReplay, SourceInfoType.REPLAY, SourceLayerType.LOCAL) + } } diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index 46273bac6..fd70d281f 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -15,7 +15,7 @@ import { manifestAFVDDownstreamKeyers, manifestAFVDSourcesABMediaPlayers, manifestAFVDSourcesCam, - manifestAFVDSourcesDelayedPlayback, + manifestAFVDSourcesReplay, manifestAFVDSourcesRM, manifestAFVDStudioMics } from '../config-manifests' @@ -63,11 +63,11 @@ export const studioMigrations: MigrationStepStudio[] = literal({ partDefinition: literal({ type: PartType.Unknown, externalId: CURRENT_PART_EXTERNAL_ID, - variant: {}, rawType: '', cues: [], script: '', @@ -155,7 +171,6 @@ const selectVOClipAction = literal({ partDefinition: literal({ type: PartType.Unknown, externalId: CURRENT_PART_EXTERNAL_ID, - variant: {}, rawType: '', cues: [], script: '', @@ -176,8 +191,8 @@ const selectDVEActionMorbarn = literal({ type: CueType.DVE, template: 'morbarn', sources: { - INP1: 'Kam 1', - INP2: 'Live 2' + INP1: SOURCE_DEFINITION_KAM_1, + INP2: SOURCE_DEFINITION_LIVE_2 }, labels: ['Live'], iNewsCommand: 'DVE=MORBARN' @@ -192,8 +207,8 @@ const selectDVEActionBarnmor = literal({ type: CueType.DVE, template: 'barnmor', sources: { - INP1: 'Kam 1', - INP2: 'Live 2' + INP1: SOURCE_DEFINITION_KAM_1, + INP2: SOURCE_DEFINITION_LIVE_2 }, labels: ['Live'], iNewsCommand: 'DVE=BARNMOR' @@ -208,14 +223,13 @@ const commentatorSelectDVE = literal({ const selectCameraAction = literal({ type: AdlibActionType.CUT_TO_CAMERA, - name: '1', + sourceDefinition: SOURCE_DEFINITION_KAM_1, queue: true }) const selectLiveAction = literal({ type: AdlibActionType.CUT_TO_REMOTE, - name: '2', - port: 3 + sourceDefinition: SOURCE_DEFINITION_LIVE_2 }) const selectFullGrafikAction = literal({ diff --git a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts index c27b788a7..8996e0054 100644 --- a/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts +++ b/src/tv2_offtube_showstyle/content/OfftubeDVEContent.ts @@ -1,13 +1,5 @@ import { ISegmentUserContext, SplitsContent, WithTimeline } from '@tv2media/blueprints-integration' -import { - CueDefinitionDVE, - DVEConfigInput, - DVEOptions, - GetLayersForEkstern, - GetSisyfosTimelineObjForEkstern, - MakeContentDVEBase, - PartDefinition -} from 'tv2-common' +import { CueDefinitionDVE, DVEConfigInput, DVEOptions, MakeContentDVEBase, PartDefinition } from 'tv2-common' import { OfftubeAtemLLayer, OfftubeCasparLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' @@ -39,10 +31,6 @@ export const OFFTUBE_DVE_GENERATOR_OPTIONS: DVEOptions = { ClipPending: OfftubeCasparLLayer.CasparPlayerClipPending } }, - dveTimelineGenerators: { - GetSisyfosTimelineObjForEkstern, - GetLayersForEkstern - }, boxMappings, AUDIO_LAYERS: [] // TODO } diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts index 995f8cba9..761b05c13 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts @@ -10,7 +10,7 @@ import { CreatePilotGraphic, CueDefinitionGraphic, FindDSKFullGFX, - GetSisyfosTimelineObjForCamera, + GetSisyfosTimelineObjForFull, GraphicInternalOrPilot, GraphicIsInternal, GraphicIsPilot, @@ -63,7 +63,7 @@ export function OfftubeEvaluateGrafikCaspar( function createPilotTimeline( config: OfftubeShowstyleBlueprintConfig, - context: IShowStyleUserContext + _context: IShowStyleUserContext ): TSR.TSRTimelineObj[] { const fullDSK = FindDSKFullGFX(config) return [ @@ -91,6 +91,6 @@ function createPilotTimeline( } } }), - GetSisyfosTimelineObjForCamera(context, config, 'full', OfftubeSisyfosLLayer.SisyfosGroupStudioMics) + ...GetSisyfosTimelineObjForFull(config, OfftubeSisyfosLLayer.SisyfosGroupStudioMics) ] } diff --git a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts index 4b83543b9..191c0e50d 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts @@ -3,12 +3,11 @@ import { IBlueprintPiece, IShowStyleUserContext, PieceLifespan, - SourceLayerType, TimelineObjectCoreExt, TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { CueDefinitionPgmClean, FindSourceInfoStrict, literal, SourceInfo, SourceInfoType } from 'tv2-common' +import { CueDefinitionPgmClean, FindSourceInfoByName, literal, SourceInfo } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' @@ -26,21 +25,7 @@ export function OfftubeEvaluatePgmClean( return } - let sourceType: SourceInfoType | undefined - if (parsedCue.source.match(/live|feed/i)) { - sourceType = SourceLayerType.REMOTE - } else if (parsedCue.source.match(/[k|c]am/i)) { - sourceType = SourceLayerType.CAMERA - } else if (parsedCue.source.match(/evs/i)) { - sourceType = SourceLayerType.LOCAL - } - - if (!sourceType) { - context.notifyUserWarning(`Invalid source for clean output: ${parsedCue.source}`) - return - } - - sourceInfo = FindSourceInfoStrict(context, config.sources, sourceType, parsedCue.source) + sourceInfo = FindSourceInfoByName(config.sources, parsedCue.source) if (!sourceInfo) { context.notifyUserWarning(`Invalid source for clean output: ${parsedCue.source}`) diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index f9ed5d8eb..f6fdcff64 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -11,7 +11,6 @@ import { IStudioUserContext, PieceLifespan, PlaylistTimingType, - SourceLayerType, TSR } from '@tv2media/blueprints-integration' import { @@ -36,7 +35,11 @@ import { GetTagForLive, GetTransitionAdLibActions, literal, + SourceDefinitionEkstern, + SourceDefinitionKam, SourceInfo, + SourceInfoToSourceDefinition, + SourceInfoType, t, TimeFromINewsField } from 'tv2-common' @@ -48,6 +51,7 @@ import { SharedOutputLayers, SharedSisyfosLLayer, SharedSourceLayers, + SourceType, TallyTags } from 'tv2-constants' import * as _ from 'underscore' @@ -254,10 +258,11 @@ function getGlobalAdlibActionsOfftube( let globalRank = 2000 function makeCutCameraActions(info: SourceInfo, queue: boolean, rank: number) { + const sourceDefinition = SourceInfoToSourceDefinition(info) as SourceDefinitionKam const userData = literal({ type: AdlibActionType.CUT_TO_CAMERA, queue, - name: info.id + sourceDefinition }) blueprintActions.push( literal({ @@ -267,7 +272,7 @@ function getGlobalAdlibActionsOfftube( userDataManifest: {}, display: { _rank: rank, - label: t(`KAM ${info.id}`), + label: t(sourceDefinition.name), sourceLayerId: OfftubeSourceLayer.PgmCam, outputLayerId: SharedOutputLayers.PGM, content: {}, @@ -279,11 +284,11 @@ function getGlobalAdlibActionsOfftube( ) } - function makeRemoteAction(name: string, type: 'Live' | 'Feed', port: number, rank: number) { + function makeRemoteAction(sourceInfo: SourceInfo, rank: number) { + const sourceDefinition = SourceInfoToSourceDefinition(sourceInfo) as SourceDefinitionEkstern const userData = literal({ type: AdlibActionType.CUT_TO_REMOTE, - name, - port + sourceDefinition }) blueprintActions.push( literal({ @@ -293,29 +298,31 @@ function getGlobalAdlibActionsOfftube( userDataManifest: {}, display: { _rank: rank, - label: t(`${type} ${name}`), + label: t(`${sourceDefinition.name}`), sourceLayerId: OfftubeSourceLayer.PgmLive, outputLayerId: OfftubeOutputLayers.PGM, content: {}, tags: [AdlibTags.OFFTUBE_SET_REMOTE_NEXT, AdlibTags.ADLIB_QUEUE_NEXT], - currentPieceTags: [GetTagForLive(name)], - nextPieceTags: [GetTagForLive(name)] + currentPieceTags: [GetTagForLive(sourceDefinition)], + nextPieceTags: [GetTagForLive(sourceDefinition)] } }) ) } - function makeAdlibBoxesActions(info: SourceInfo, type: 'KAM' | 'LIVE', rank: number) { + function makeAdlibBoxesActions( + info: SourceInfo, + type: SourceInfoType.KAM | SourceInfoType.LIVE | SourceInfoType.FEED, + rank: number + ) { for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { - const feed = type === 'LIVE' && info.id.match(/^F(.+).*$/) - const name = feed ? `FEED ${feed[1]}` : `${type} ${info.id}` - const layer = type === 'KAM' ? OfftubeSourceLayer.PgmCam : OfftubeSourceLayer.PgmLive + const sourceDefinition = SourceInfoToSourceDefinition(info) + const layer = type === SourceInfoType.KAM ? OfftubeSourceLayer.PgmCam : OfftubeSourceLayer.PgmLive const userData = literal({ type: AdlibActionType.CUT_SOURCE_TO_BOX, - name, - port: info.port, - sourceType: info.type, - box + name: sourceDefinition.name, + box, + sourceDefinition }) blueprintActions.push( literal({ @@ -325,7 +332,7 @@ function getGlobalAdlibActionsOfftube( userDataManifest: {}, display: { _rank: rank + 0.1 * box, - label: t(`${name} inp ${box + 1}`), + label: t(`${sourceDefinition.name} inp ${box + 1}`), sourceLayerId: layer, outputLayerId: OfftubeOutputLayers.PGM, content: {}, @@ -341,10 +348,8 @@ function getGlobalAdlibActionsOfftube( const userData = literal({ type: AdlibActionType.CUT_SOURCE_TO_BOX, name: `SERVER`, - port: -1, - sourceType: SourceLayerType.VT, box, - server: true + sourceDefinition: { sourceType: SourceType.Server } }) blueprintActions.push( literal({ @@ -508,25 +513,22 @@ function getGlobalAdlibActionsOfftube( ) }) - config.sources - .filter(u => u.type === SourceLayerType.CAMERA) + 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 - .filter(u => u.type === SourceLayerType.CAMERA) + config.sources.cameras .slice(0, 5) // the first x cameras to create preview cam-adlibs from .forEach(o => { makeCutCameraActions(o, true, globalRank++) }) - config.sources - .filter(u => u.type === SourceLayerType.CAMERA) + config.sources.cameras .slice(0, 5) // the first x cameras to create preview cam-adlibs from .forEach(o => { - makeAdlibBoxesActions(o, 'KAM', globalRank++) + makeAdlibBoxesActions(o, SourceInfoType.KAM, globalRank++) }) function makeRecallLastLiveAction() { @@ -550,18 +552,28 @@ function getGlobalAdlibActionsOfftube( blueprintActions.push(makeRecallLastLiveAction()) - config.sources - .filter(u => u.type === SourceLayerType.REMOTE) - .slice(0, 10) // the first x cameras to create live-adlibs from + config.sources.feeds + .slice(0, 10) // the first x sources to create feed-adlibs from + .forEach(o => { + makeRemoteAction(o, globalRank++) + }) + + config.sources.lives + .slice(0, 10) // the first x sources to create live-adlibs from + .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 => { - makeRemoteAction(o.id, o.id.match(/^F/) ? 'Feed' : 'Live', o.port, globalRank++) + makeAdlibBoxesActions(o, SourceInfoType.FEED, globalRank++) }) - config.sources - .filter(u => u.type === SourceLayerType.REMOTE) + config.sources.lives .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from .forEach(o => { - makeAdlibBoxesActions(o, 'LIVE', globalRank++) + makeAdlibBoxesActions(o, SourceInfoType.LIVE, globalRank++) }) makeServerAdlibBoxesActions(globalRank++) diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index 35d509068..0fcf92b9e 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -6,7 +6,6 @@ import { IBlueprintPiece, ISegmentUserContext, PieceLifespan, - SourceLayerType, TimelineObjectCoreExt, TSR, VTContent, @@ -19,12 +18,13 @@ import { CreatePartInvalid, CreatePartKamBase, FindDSKJingle, - FindSourceInfoStrict, + FindSourceInfo, GetSisyfosTimelineObjForCamera, GetTagForKam, literal, PartDefinitionKam, SisyfosPersistMetaData, + SourceInfoType, TransitionFromString, TransitionSettings } from 'tv2-common' @@ -92,7 +92,7 @@ export async function OfftubeCreatePartKam( }) ) } else { - const sourceInfoCam = FindSourceInfoStrict(context, config.sources, SourceLayerType.CAMERA, partDefinition.rawType) + const sourceInfoCam = FindSourceInfo(config.sources, SourceInfoType.KAM, partDefinition.rawType) if (sourceInfoCam === undefined) { return CreatePartInvalid(partDefinition) } @@ -138,14 +138,14 @@ export async function OfftubeCreatePartKam( } }, ...(AddParentClass(config, partDefinition) - ? { classes: [CameraParentClass('studio0', partDefinition.variant.name)] } + ? { classes: [CameraParentClass('studio0', partDefinition.sourceDefinition.id)] } : {}) }), - GetSisyfosTimelineObjForCamera( - context, + ...GetSisyfosTimelineObjForCamera( config, - partDefinition.rawType, + sourceInfoCam, + partDefinition.sourceDefinition.minusMic, OfftubeSisyfosLLayer.SisyfosGroupStudioMics ) ]) diff --git a/src/tv2_offtube_studio/helpers/config.ts b/src/tv2_offtube_studio/helpers/config.ts index d424da01d..e0c341147 100644 --- a/src/tv2_offtube_studio/helpers/config.ts +++ b/src/tv2_offtube_studio/helpers/config.ts @@ -1,7 +1,7 @@ import { IBlueprintConfig, ICommonContext } from '@tv2media/blueprints-integration' import { MediaPlayerConfig, - SourceInfo, + SourceMapping, TableConfigItemDSK, TableConfigItemSourceMapping, TV2StudioConfigBase @@ -12,7 +12,7 @@ import { parseMediaPlayers, parseSources } from './sources' export interface OfftubeStudioBlueprintConfig { studio: OfftubeStudioConfig - sources: SourceInfo[] + sources: SourceMapping mediaPlayers: MediaPlayerConfig // Atem Input Ids dsk: TableConfigItemDSK[] } @@ -52,13 +52,10 @@ export function parseConfig(_context: ICommonContext, rawConfig: IBlueprintConfi const config: OfftubeStudioBlueprintConfig = { studio: rawConfig as any, // showStyle: {} as any, - sources: [], - mediaPlayers: [], + sources: parseSources(studioConfig), + mediaPlayers: parseMediaPlayers(studioConfig), dsk: studioConfig.AtemSource.DSK } - config.sources = parseSources(studioConfig) - config.mediaPlayers = parseMediaPlayers(studioConfig) - return config } diff --git a/src/tv2_offtube_studio/helpers/sources.ts b/src/tv2_offtube_studio/helpers/sources.ts index 508aba378..b19c28bd2 100644 --- a/src/tv2_offtube_studio/helpers/sources.ts +++ b/src/tv2_offtube_studio/helpers/sources.ts @@ -1,17 +1,18 @@ import * as _ from 'underscore' import { SourceLayerType } from '@tv2media/blueprints-integration' -import { ParseMappingTable, SourceInfo } from 'tv2-common' +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() })) } -export function parseSources(studioConfig: OfftubeStudioConfig): SourceInfo[] { - return [ - ...ParseMappingTable(studioConfig.SourcesFeed, SourceLayerType.REMOTE, 'F'), - ...ParseMappingTable(studioConfig.SourcesRM, SourceLayerType.REMOTE), - ...ParseMappingTable(studioConfig.SourcesCam, SourceLayerType.CAMERA) - ] +export function parseSources(studioConfig: OfftubeStudioConfig): SourceMapping { + return { + cameras: ParseMappingTable(studioConfig.SourcesCam, SourceInfoType.KAM, SourceLayerType.CAMERA), + lives: ParseMappingTable(studioConfig.SourcesRM, SourceInfoType.LIVE, SourceLayerType.REMOTE), + feeds: ParseMappingTable(studioConfig.SourcesFeed, SourceInfoType.FEED, SourceLayerType.REMOTE), + replays: [] + } } From 6410dd5dd9b8fea804f91b84312b41dc8ed6346d Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 20 Jul 2022 22:46:07 +0200 Subject: [PATCH 153/184] chore: upgrade moment to fix vulnerability --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c445cb791..573b38d9e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4414,9 +4414,9 @@ modify-values@^1.0.0: integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== moment@2.29.3, moment@^2.29.2: - version "2.29.3" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.3.tgz#edd47411c322413999f7a5940d526de183c031f3" - integrity sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw== + version "2.29.4" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" + integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== move-concurrently@^1.0.1: version "1.0.1" From fecd77dffcf4804677c04e50d00c1212423f7b9d Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 20 Jul 2022 22:56:41 +0200 Subject: [PATCH 154/184] fix: merge issue --- src/tv2-common/actions/executeAction.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 061e7abb5..a2afe466b 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -34,7 +34,6 @@ import { ActionSelectServerClip, CalculateTime, CreateDipEffectBlueprintPieceForPart, - CreateFullPiece, CreatePartServerBase, CueDefinition, CueDefinitionDVE, From ecb8b646512ec4361520907f0e87710d8be59370 Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 21 Jul 2022 10:07:39 +0200 Subject: [PATCH 155/184] fix: SOF-942 add value clamping and improve tests --- .../__tests__/jinglePartProperties.spec.ts | 65 +++++++++++++++---- src/tv2-common/jinglePartProperties.ts | 6 +- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/tv2-common/__tests__/jinglePartProperties.spec.ts b/src/tv2-common/__tests__/jinglePartProperties.spec.ts index 9b861749f..ac599ca9c 100644 --- a/src/tv2-common/__tests__/jinglePartProperties.spec.ts +++ b/src/tv2-common/__tests__/jinglePartProperties.spec.ts @@ -1,21 +1,64 @@ import { GetJinglePartPropertiesFromTableValue } from 'tv2-common' +const BREAKER = { + BreakerName: 'intro', + ClipName: 'intro', + LoadFirstFrame: false, + Autonext: true, + Duration: 200, + StartAlpha: 50, + EndAlpha: 100 +} + describe('GetJinglePartPropertiesFromTableValue', () => { - it('Calculates values correctly', () => { + it('Subtracts StartAlpha from Duration', () => { const properties = GetJinglePartPropertiesFromTableValue({ - BreakerName: 'intro', - ClipName: 'intro', + ...BREAKER, Duration: 200, StartAlpha: 50, - EndAlpha: 100, - Autonext: true, - LoadFirstFrame: false + EndAlpha: 100 + }) + expect(properties.expectedDuration).toBe(6000) + }) + it('Clamps Duration when StartAlpha > Duration', () => { + const properties = GetJinglePartPropertiesFromTableValue({ + ...BREAKER, + Duration: 50, + StartAlpha: 100, + EndAlpha: 50 }) - expect(properties).toEqual({ - expectedDuration: 6000, - autoNextOverlap: 4000, - autoNext: true, - disableNextInTransition: false + expect(properties.expectedDuration).toBe(0) + }) + it('Calculates autoNextOverlap from EndAlpha', () => { + const properties = GetJinglePartPropertiesFromTableValue({ + ...BREAKER, + Duration: 100, + StartAlpha: 20, + EndAlpha: 50 + }) + expect(properties.autoNextOverlap).toBe(2000) + }) + it('Clamps autoNextOverlap when EndAlpha > Duration - StartAlpha', () => { + const properties = GetJinglePartPropertiesFromTableValue({ + ...BREAKER, + Duration: 100, + StartAlpha: 75, + EndAlpha: 50 + }) + expect(properties.autoNextOverlap).toBe(1000) + }) + it('Disables autoNext when Autonext is false', () => { + const properties = GetJinglePartPropertiesFromTableValue({ + ...BREAKER, + Autonext: false + }) + expect(properties.autoNext).toBe(false) + }) + it('Enables autoNext when Autonext is true', () => { + const properties = GetJinglePartPropertiesFromTableValue({ + ...BREAKER, + Autonext: true }) + expect(properties.autoNext).toBe(true) }) }) diff --git a/src/tv2-common/jinglePartProperties.ts b/src/tv2-common/jinglePartProperties.ts index d4efe4e77..d16da3f78 100644 --- a/src/tv2-common/jinglePartProperties.ts +++ b/src/tv2-common/jinglePartProperties.ts @@ -31,9 +31,11 @@ export function GetJinglePartProperties { + const expectedDuration = Math.max(0, TimeFromFrames(Number(realBreaker.Duration) - Number(realBreaker.StartAlpha))) + const autoNextOverlap = Math.min(expectedDuration, TimeFromFrames(Number(realBreaker.EndAlpha))) return { - expectedDuration: TimeFromFrames(Number(realBreaker.Duration)) - TimeFromFrames(Number(realBreaker.StartAlpha)), - autoNextOverlap: TimeFromFrames(Number(realBreaker.EndAlpha)), + expectedDuration, + autoNextOverlap, autoNext: realBreaker.Autonext === true, disableNextInTransition: false } From 5844791dd0a2c86fabc50cf88f1616c63a3030b0 Mon Sep 17 00:00:00 2001 From: ianshade Date: Fri, 22 Jul 2022 11:41:14 +0200 Subject: [PATCH 156/184] chore: SOF-769 enable single click to toggle adlibs --- shelf-layouts/Kommentator.json | 15 ++++++++++----- shelf-layouts/Mini_Shelf_Layout.json | 3 ++- shelf-layouts/Q flow.json | 6 ++++-- shelf-layouts/Shortcuts and adlib scroll.json | 15 ++++++++++----- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/shelf-layouts/Kommentator.json b/shelf-layouts/Kommentator.json index dd4d9445c..52c586c8b 100644 --- a/shelf-layouts/Kommentator.json +++ b/shelf-layouts/Kommentator.json @@ -44,7 +44,8 @@ "kommentator" ], "showThumbnailsInList": true, - "hideDuplicates": false + "hideDuplicates": false, + "toggleOnSingleClick": true }, { "_id": "QZ6xdWdFmm5Mu7ZKJ", @@ -77,7 +78,8 @@ "offtube_adlib_100pc_server", "kommentator" ], - "showThumbnailsInList": true + "showThumbnailsInList": true, + "toggleOnSingleClick": true }, { "_id": "zHX89zpASjzyn7GTz", @@ -104,7 +106,8 @@ "studio0_clip", "studio0_voiceover" ], - "showThumbnailsInList": true + "showThumbnailsInList": true, + "toggleOnSingleClick": true }, { "_id": "YC7RNPTbkXd5wnagp", @@ -130,7 +133,8 @@ "kommentator" ], "hideDuplicates": true, - "lineBreak": "\n - " + "lineBreak": "\n - ", + "toggleOnSingleClick": true }, { "_id": "icuekg6wiJxejsYsZ", @@ -153,7 +157,8 @@ "tags": [ "kommentator" ], - "showThumbnailsInList": true + "showThumbnailsInList": true, + "toggleOnSingleClick": true }, { "_id": "LiFso7gPYn2SPwHwg", diff --git a/shelf-layouts/Mini_Shelf_Layout.json b/shelf-layouts/Mini_Shelf_Layout.json index 09a82b1c1..30d492451 100644 --- a/shelf-layouts/Mini_Shelf_Layout.json +++ b/shelf-layouts/Mini_Shelf_Layout.json @@ -27,7 +27,8 @@ ], "tags": [ "flow_producer" - ] + ], + "toggleOnSingleClick": true } ] } \ No newline at end of file diff --git a/shelf-layouts/Q flow.json b/shelf-layouts/Q flow.json index debebf807..15c73cc44 100644 --- a/shelf-layouts/Q flow.json +++ b/shelf-layouts/Q flow.json @@ -49,7 +49,8 @@ "assignHotKeys": true, "tags": [ "flow_producer" - ] + ], + "toggleOnSingleClick": true }, { "_id": "ibMYwgJfn8TB52vhb", @@ -61,7 +62,8 @@ "rundownBaseline": "only", "default": false, "hide": true, - "assignHotKeys": true + "assignHotKeys": true, + "toggleOnSingleClick": true }, { "_id": "tGynaBdafH5dZnttN", diff --git a/shelf-layouts/Shortcuts and adlib scroll.json b/shelf-layouts/Shortcuts and adlib scroll.json index b2235cc2b..c013c683c 100755 --- a/shelf-layouts/Shortcuts and adlib scroll.json +++ b/shelf-layouts/Shortcuts and adlib scroll.json @@ -40,7 +40,8 @@ ], "tags": [ "flow_producer" - ] + ], + "toggleOnSingleClick": true }, { "_id": "s4KkTnsERPNcrkqeD", @@ -81,7 +82,8 @@ "studio0_adlib_graphic_cmd" ], "buttonWidthScale": 1.7, - "buttonHeightScale": 1.7 + "buttonHeightScale": 1.7, + "toggleOnSingleClick": true }, { "_id": "QZ6xdWdFmm5Mu7ZKJ", @@ -98,7 +100,8 @@ "x": -1, "includeClearInRundownBaseline": true, "assignHotKeys": true, - "hide": true + "hide": true, + "toggleOnSingleClick": true }, { "_id": "j54rMBuuTvufKJ8yp", @@ -121,7 +124,8 @@ "buttonWidthScale": 1.5, "buttonHeightScale": 1.5, "showAsTimeline": true, - "includeClearInRundownBaseline": true + "includeClearInRundownBaseline": true, + "toggleOnSingleClick": true }, { "_id": "nmNfZ8azaAAHD7jjT", @@ -144,7 +148,8 @@ "width": 58, "height": 5, "showAsTimeline": true, - "includeClearInRundownBaseline": true + "includeClearInRundownBaseline": true, + "toggleOnSingleClick": true } ], "type": "dashboard_layout", From 18c01050815d3095eb614df28ba729130959d6d5 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 26 Jul 2022 09:21:03 +0200 Subject: [PATCH 157/184] refactor: SourceInfo and audio for sources --- config/tsconfig.base.json | 2 +- src/__mocks__/context.ts | 17 ++ src/tv2-common/__tests__/frame-time.spec.ts | 6 +- src/tv2-common/actions/actionTypes.ts | 6 +- src/tv2-common/actions/executeAction.ts | 27 +-- src/tv2-common/content/dve.ts | 50 ++--- src/tv2-common/content/server.ts | 2 - src/tv2-common/cues/ekstern.ts | 17 +- src/tv2-common/cues/mixMinus.ts | 15 +- src/tv2-common/get-next-part-cue.spec.ts | 14 +- .../helpers/__tests__/serverResume.spec.ts | 10 +- .../helpers/__tests__/sisyfos.spec.ts | 135 +++++++++++++ .../helpers/postProcessDefinitions.ts | 6 +- src/tv2-common/helpers/sisyfos.ts | 33 +-- .../inewsConversion/converters/ParseBody.ts | 74 ++++--- .../inewsConversion/converters/ParseCue.ts | 66 +++--- .../converters/__tests__/body-parser.spec.ts | 51 ++--- .../converters/__tests__/cue-parser.spec.ts | 56 ++++-- .../__tests__/part-to-parent-class.spec.ts | 4 +- src/tv2-common/parts/server.ts | 3 +- src/tv2-common/pieces/tags.ts | 8 +- src/tv2-common/sources.ts | 79 ++------ src/tv2-constants/enums.ts | 19 +- .../__tests__/actions.spec.ts | 19 +- .../__tests__/addScript.spec.ts | 2 +- .../__tests__/blueprint.spec.ts | 189 +++++++++++++----- src/tv2_afvd_showstyle/getRundown.ts | 8 +- .../pieces/__tests__/grafikViz.spec.ts | 2 +- .../helpers/pieces/__tests__/lyd.spec.ts | 2 +- .../helpers/pieces/__tests__/telefon.spec.ts | 2 +- .../helpers/pieces/adlib.ts | 3 +- .../helpers/pieces/ekstern.ts | 5 +- .../helpers/pieces/graphicPilot.ts | 6 +- .../helpers/pieces/routing.ts | 87 ++++---- .../helpers/pieces/telefon.ts | 6 +- src/tv2_afvd_showstyle/parts/evs.ts | 16 +- src/tv2_afvd_showstyle/parts/kam.ts | 13 +- src/tv2_afvd_showstyle/parts/server.ts | 3 +- .../__tests__/graphics.spec.ts | 11 +- src/tv2_afvd_studio/layers.ts | 7 +- .../__tests__/actions.spec.ts | 11 +- .../cues/OfftubeAdlib.ts | 3 +- .../cues/OfftubeEkstern.ts | 5 +- .../cues/OfftubeGraphics.ts | 4 +- .../cues/OfftubePgmClean.ts | 14 +- src/tv2_offtube_showstyle/getRundown.ts | 10 +- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 20 +- .../parts/OfftubeServer.ts | 6 +- src/tv2_offtube_studio/layers.ts | 1 - 49 files changed, 673 insertions(+), 482 deletions(-) create mode 100644 src/tv2-common/helpers/__tests__/sisyfos.spec.ts diff --git a/config/tsconfig.base.json b/config/tsconfig.base.json index 51fc7e74b..2101867f0 100644 --- a/config/tsconfig.base.json +++ b/config/tsconfig.base.json @@ -5,7 +5,7 @@ "target": "es6", "noImplicitAny": true, "moduleResolution": "node", - "sourceMap": false, + "sourceMap": true, "outDir": "../dist", "baseUrl": "../", "paths": { diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index 36f69d7eb..b7bc3c4d2 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -31,6 +31,10 @@ import { } from '@tv2media/blueprints-integration' import { literal } 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 mappingsDefaultsAFVD from '../tv2_afvd_studio/migrations/mappings-defaults' export function getHash(str: string): string { const hash = crypto.createHash('sha1') @@ -608,3 +612,16 @@ export interface PartNote { } message: string } + +export function makeMockAFVDContext(studioConfigOverrides?: Partial) { + const mockContext = new SegmentUserContext( + 'test', + mappingsDefaultsAFVD, + parseStudioConfigAFVD, + parseShowStyleConfigAFVD + ) + mockContext.studioConfig = { ...defaultStudioConfig, ...studioConfigOverrides } as any + mockContext.showStyleConfig = defaultShowStyleConfig as any + + return mockContext +} diff --git a/src/tv2-common/__tests__/frame-time.spec.ts b/src/tv2-common/__tests__/frame-time.spec.ts index a61246592..4b599af08 100644 --- a/src/tv2-common/__tests__/frame-time.spec.ts +++ b/src/tv2-common/__tests__/frame-time.spec.ts @@ -1,13 +1,13 @@ import { IBlueprintPiece, PieceLifespan } from '@tv2media/blueprints-integration' import { CueType, SourceType } from 'tv2-constants' import { CreateTiming } from '../cueTiming' -import { SourceDefinitionEkstern } from '../inewsConversion' +import { RemoteType, SourceDefinitionRemote } from '../inewsConversion' import { CueDefinitionEkstern } from '../inewsConversion/converters/ParseCue' import { literal } from '../util' -const EKSTERN_SOURCE: SourceDefinitionEkstern = { +const EKSTERN_SOURCE: SourceDefinitionRemote = { sourceType: SourceType.REMOTE, - variant: 'LIVE', + remoteType: RemoteType.LIVE, id: '1', raw: 'Live 1', name: 'LIVE 1' diff --git a/src/tv2-common/actions/actionTypes.ts b/src/tv2-common/actions/actionTypes.ts index 1cf3083f6..e15add5ea 100644 --- a/src/tv2-common/actions/actionTypes.ts +++ b/src/tv2-common/actions/actionTypes.ts @@ -6,8 +6,8 @@ import { GraphicInternal, PartDefinition, SourceDefinition, - SourceDefinitionEkstern, - SourceDefinitionKam + SourceDefinitionKam, + SourceDefinitionRemote } from '../inewsConversion' export interface ActionBase { @@ -57,7 +57,7 @@ export interface ActionCutToCamera extends ActionBase { export interface ActionCutToRemote extends ActionBase { type: AdlibActionType.CUT_TO_REMOTE - sourceDefinition: SourceDefinitionEkstern + sourceDefinition: SourceDefinitionRemote } export interface ActionCutSourceToBox extends ActionBase { diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index c52d65510..b6b9828fe 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -90,7 +90,7 @@ import { GetTagForLive, GetTagForTransition } from '../pieces' -import { FindSourceInfoByDefinition } from '../sources' +import { findSourceInfo } from '../sources' import { assertUnreachable } from '../util' import { ActionCommentatorSelectJingle, @@ -448,8 +448,7 @@ async function executeActionSelectServerClip< ClipPending: settings.LLayer.Caspar.ClipPending }, Sisyfos: { - ClipPending: settings.LLayer.Sisyfos.ClipPending, - StudioMicsGroup: settings.LLayer.Sisyfos.StudioMics + ClipPending: settings.LLayer.Sisyfos.ClipPending }, ATEM: { ServerLookaheadAux: settings.LLayer.Atem.ServerLookaheadAUX @@ -528,10 +527,10 @@ async function executeActionSelectServerClip< function dveContainsServer(sources: DVESources) { return ( - sources.INP1?.sourceType === SourceType.Server || - sources.INP2?.sourceType === SourceType.Server || - sources.INP3?.sourceType === SourceType.Server || - sources.INP4?.sourceType === SourceType.Server + sources.INP1?.sourceType === SourceType.SERVER || + sources.INP2?.sourceType === SourceType.SERVER || + sources.INP3?.sourceType === SourceType.SERVER || + sources.INP4?.sourceType === SourceType.SERVER ) } @@ -1103,7 +1102,7 @@ async function executeActionCutToCamera< expectedDuration: 0 }) - const sourceInfoCam = FindSourceInfoByDefinition(config.sources, userData.sourceDefinition) + const sourceInfoCam = findSourceInfo(config.sources, userData.sourceDefinition) if (sourceInfoCam === undefined) { return } @@ -1116,7 +1115,7 @@ async function executeActionCutToCamera< const currentKam = currentPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.Cam) - const camSisyfos = GetSisyfosTimelineObjForCamera(config, sourceInfoCam, false, settings.LLayer.Sisyfos.StudioMics) + const camSisyfos = GetSisyfosTimelineObjForCamera(config, sourceInfoCam, false) const kamPiece = literal({ externalId, @@ -1132,7 +1131,7 @@ async function executeActionCutToCamera< isPieceInjectedInPart: true }) }, - tags: [GetTagForKam(userData.sourceDefinition.name)], + tags: [GetTagForKam(userData.sourceDefinition)], content: { timelineObjects: _.compact([ literal({ @@ -1223,17 +1222,13 @@ async function executeActionCutToRemote< expectedDuration: 0 }) - const sourceInfo = FindSourceInfoByDefinition(config.sources, userData.sourceDefinition) + const sourceInfo = findSourceInfo(config.sources, userData.sourceDefinition) if (sourceInfo === undefined) { context.notifyUserWarning(`Invalid source: ${userData.sourceDefinition.name}`) return } - const eksternSisyfos: TSR.TimelineObjSisyfosAny[] = GetSisyfosTimelineObjForRemote( - config, - sourceInfo, - settings.LLayer.Sisyfos.StudioMics - ) + const eksternSisyfos: TSR.TimelineObjSisyfosAny[] = GetSisyfosTimelineObjForRemote(config, sourceInfo) const sisyfosPersistMetaData: SisyfosPersistMetaData = sourceInfo !== undefined diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 53616a6a3..ee38414d6 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -17,7 +17,7 @@ import { DVEParentClass, DVESources, FindDSKFullGFX, - FindSourceInfoByDefinition, + findSourceInfo, JoinAssetToFolder, literal, PartDefinition, @@ -218,7 +218,7 @@ export function MakeContentDVE2< if (sources) { const prop = sources[fromCue as keyof DVESources] if (prop) { - boxMap[targetBox - 1] = prop.sourceType !== SourceType.Server || videoId ? prop : undefined + boxMap[targetBox - 1] = prop.sourceType !== SourceType.SERVER || videoId ? prop : undefined } else { context.notifyUserWarning(`Missing mapping for ${targetBox}`) boxMap[targetBox - 1] = undefined @@ -279,8 +279,8 @@ export function MakeContentDVE2< port: config.studio.AtemSource.Default }) break - case SourceType.Kam: - const sourceInfoCam = FindSourceInfoByDefinition(config.sources, mappingFrom) + case SourceType.KAM: + const sourceInfoCam = findSourceInfo(config.sources, mappingFrom) if (sourceInfoCam === undefined) { context.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) setBoxToBlack(num) @@ -289,18 +289,10 @@ export function MakeContentDVE2< } setBoxSource(num, sourceInfoCam) - dveTimeline.push( - ...GetSisyfosTimelineObjForCamera( - config, - sourceInfoCam, - mappingFrom.minusMic, - dveGeneratorOptions.dveLayers.SisyfosLLayer.StudioMics, - audioEnable - ) - ) + dveTimeline.push(...GetSisyfosTimelineObjForCamera(config, sourceInfoCam, mappingFrom.minusMic, audioEnable)) break case SourceType.REMOTE: - const sourceInfoLive = FindSourceInfoByDefinition(config.sources, mappingFrom) + const sourceInfoLive = findSourceInfo(config.sources, mappingFrom) if (sourceInfoLive === undefined) { context.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) setBoxToBlack(num) @@ -309,17 +301,10 @@ export function MakeContentDVE2< } setBoxSource(num, sourceInfoLive) - dveTimeline.push( - ...GetSisyfosTimelineObjForRemote( - config, - sourceInfoLive, - dveGeneratorOptions.dveLayers.SisyfosLLayer.StudioMics, - audioEnable - ) - ) + dveTimeline.push(...GetSisyfosTimelineObjForRemote(config, sourceInfoLive, audioEnable)) break - case SourceType.EVS: - const sourceInfoReplay = FindSourceInfoByDefinition(config.sources, mappingFrom) + case SourceType.REPLAY: + const sourceInfoReplay = findSourceInfo(config.sources, mappingFrom) if (sourceInfoReplay === undefined) { context.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) setBoxToBlack(num) @@ -328,30 +313,21 @@ export function MakeContentDVE2< } setBoxSource(num, sourceInfoReplay) - dveTimeline.push( - ...GetSisyfosTimelineObjForReplay( - config, - sourceInfoReplay, - !!mappingFrom.vo, - dveGeneratorOptions.dveLayers.SisyfosLLayer.StudioMics - ) - ) + dveTimeline.push(...GetSisyfosTimelineObjForReplay(config, sourceInfoReplay, mappingFrom.vo)) break - case SourceType.Grafik: + case SourceType.GRAFIK: if (mappingFrom.name === 'FULL') { setBoxSource(num, { sourceLayerType: SourceLayerType.GRAPHICS, port: FindDSKFullGFX(config).Fill }) - dveTimeline.push( - ...GetSisyfosTimelineObjForFull(config, dveGeneratorOptions.dveLayers.SisyfosLLayer.StudioMics) - ) + dveTimeline.push(...GetSisyfosTimelineObjForFull(config)) } else { context.notifyUserWarning(`Unsupported engine for DVE: ${mappingFrom.name}`) setBoxToBlack(num) } break - case SourceType.Server: + case SourceType.SERVER: server = true setBoxSource(num, { sourceLayerType: SourceLayerType.VT, diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 2fbf5962d..0dda2ec9d 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -21,7 +21,6 @@ export interface MakeContentServerSourceLayers { } Sisyfos: { ClipPending: string - StudioMicsGroup: string } ATEM: { ServerLookaheadAux?: string @@ -131,7 +130,6 @@ function GetServerTimeline( !!voLevels, sourceLayers.Sisyfos.ClipPending, mediaPlayerSessionId, - sourceLayers.Sisyfos.StudioMicsGroup, audioEnable ), ...(sourceLayers.ATEM.ServerLookaheadAux diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index 3b9f0d947..dc36d96f2 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -23,10 +23,10 @@ import { TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' -import { ControlClasses, SharedOutputLayers } from 'tv2-constants' +import { ControlClasses, SharedOutputLayers, SourceType } from 'tv2-constants' import { GetSisyfosTimelineObjForRemote } from '../helpers' import { GetTagForLive } from '../pieces' -import { FindSourceInfoByDefinition } from '../sources' +import { findSourceInfo } from '../sources' interface EksternLayers { SourceLayer: { @@ -35,9 +35,6 @@ interface EksternLayers { ATEM: { MEProgram: string } - Sisyfos: { - StudioMics: string - } } export function EvaluateEksternBase< @@ -56,9 +53,9 @@ export function EvaluateEksternBase< adlib?: boolean, rank?: number ) { - const sourceInfoEkstern = FindSourceInfoByDefinition(config.sources, parsedCue.sourceDefinition) - if (sourceInfoEkstern === undefined) { - context.notifyUserWarning(`${parsedCue.sourceDefinition.raw} does not exist in this studio`) + const sourceInfoEkstern = findSourceInfo(config.sources, parsedCue.sourceDefinition) + if (parsedCue.sourceDefinition.sourceType !== SourceType.REMOTE || sourceInfoEkstern === undefined) { + context.notifyUserWarning(`EKSTERN source is not valid: "${parsedCue.sourceDefinition.raw}"`) part.invalid = true return } @@ -106,7 +103,7 @@ export function EvaluateEksternBase< classes: [ControlClasses.LiveSourceOnAir] }), - ...GetSisyfosTimelineObjForRemote(config, sourceInfoEkstern, layersEkstern.Sisyfos.StudioMics) + ...GetSisyfosTimelineObjForRemote(config, sourceInfoEkstern) ]) }) }) @@ -164,7 +161,7 @@ export function EvaluateEksternBase< : {}) }), - ...GetSisyfosTimelineObjForRemote(config, sourceInfoEkstern, layersEkstern.Sisyfos.StudioMics) + ...GetSisyfosTimelineObjForRemote(config, sourceInfoEkstern) ]) }) }) diff --git a/src/tv2-common/cues/mixMinus.ts b/src/tv2-common/cues/mixMinus.ts index e245482f3..eb29881f7 100644 --- a/src/tv2-common/cues/mixMinus.ts +++ b/src/tv2-common/cues/mixMinus.ts @@ -7,7 +7,7 @@ import { TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { CueDefinitionMixMinus, FindSourceInfoByName, literal, PartDefinition } from 'tv2-common' +import { CueDefinitionMixMinus, findSourceInfo, literal, PartDefinition } from 'tv2-common' import { ControlClasses, SharedATEMLLayer, SharedOutputLayers, SharedSourceLayers } from 'tv2-constants' import { TV2BlueprintConfig } from '../blueprintConfig' @@ -18,17 +18,20 @@ export function EvaluateCueMixMinus( part: PartDefinition, parsedCue: CueDefinitionMixMinus ) { - const sourceInfoMixMinus = FindSourceInfoByName(config.sources, parsedCue.source) - if (sourceInfoMixMinus === undefined) { - context.notifyUserWarning(`${parsedCue.source} does not exist in this studio (MINUSKAM)`) + const sourceInfo = findSourceInfo(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)`) return } - const atemInput = sourceInfoMixMinus.port + const atemInput = sourceInfo.port pieces.push( literal({ externalId: part.externalId, - name: `MixMinus: ${parsedCue.source}`, + name: `MixMinus: ${name}`, enable: { start: 0 }, diff --git a/src/tv2-common/get-next-part-cue.spec.ts b/src/tv2-common/get-next-part-cue.spec.ts index eb3771848..c924b1321 100644 --- a/src/tv2-common/get-next-part-cue.spec.ts +++ b/src/tv2-common/get-next-part-cue.spec.ts @@ -7,18 +7,18 @@ import { PartDefinitionKam } from 'tv2-common' import { CueType, PartType, SourceType } from 'tv2-constants' -import { CueDefinitionGraphic, GraphicInternal, SourceDefinitionKam } from './inewsConversion' +import { CueDefinitionGraphic, GraphicInternal, RemoteType, SourceDefinitionKam } from './inewsConversion' import { GetNextPartCue } from './nextPartCue' const SOURCE_DEFINITION_KAM_1: SourceDefinitionKam = { - sourceType: SourceType.Kam, + sourceType: SourceType.KAM, id: '1', raw: 'Kam 1', minusMic: false, name: 'KAM 1' } const SOURCE_DEFINITION_KAM_2: SourceDefinitionKam = { - sourceType: SourceType.Kam, + sourceType: SourceType.KAM, id: '2', raw: 'Kam 2', minusMic: false, @@ -49,7 +49,7 @@ const partDefinitionTest1: PartDefinitionKam = { type: CueType.Ekstern, sourceDefinition: { sourceType: SourceType.REMOTE, - variant: 'LIVE', + remoteType: RemoteType.LIVE, id: '1', raw: 'Live 1', name: 'LIVE 1' @@ -83,7 +83,7 @@ const partDefinitionTest1: PartDefinitionKam = { type: CueType.Ekstern, sourceDefinition: { sourceType: SourceType.REMOTE, - variant: 'LIVE', + remoteType: RemoteType.LIVE, id: '2', raw: 'Live 2', name: 'LIVE 2' @@ -191,7 +191,7 @@ const partDefinitionTest2: PartDefinitionKam = { type: CueType.Ekstern, sourceDefinition: { sourceType: SourceType.REMOTE, - variant: 'LIVE', + remoteType: RemoteType.LIVE, id: '1', raw: 'Live 1', name: 'LIVE 1' @@ -247,7 +247,7 @@ const partDefinitionTest2: PartDefinitionKam = { type: CueType.Ekstern, sourceDefinition: { sourceType: SourceType.REMOTE, - variant: 'LIVE', + remoteType: RemoteType.LIVE, id: '1', raw: 'Live 1', name: 'LIVE 1' diff --git a/src/tv2-common/helpers/__tests__/serverResume.spec.ts b/src/tv2-common/helpers/__tests__/serverResume.spec.ts index 746339b02..67e893531 100644 --- a/src/tv2-common/helpers/__tests__/serverResume.spec.ts +++ b/src/tv2-common/helpers/__tests__/serverResume.spec.ts @@ -6,13 +6,13 @@ import { VTContent, WithTimeline } from '@tv2media/blueprints-integration' -import { DVEPieceMetaData, literal, SourceDefinitionEkstern } from 'tv2-common' +import { DVEPieceMetaData, literal, RemoteType, SourceDefinitionRemote } from 'tv2-common' import { SharedSourceLayers, SourceType } from 'tv2-constants' import { getServerPositionForPartInstance } from '../serverResume' -const EKSTERN_SOURCE: SourceDefinitionEkstern = { +const EKSTERN_SOURCE: SourceDefinitionRemote = { sourceType: SourceType.REMOTE, - variant: 'LIVE', + remoteType: RemoteType.LIVE, id: '1', raw: 'Live 1', name: 'LIVE 1' @@ -124,7 +124,7 @@ describe('Server Resume', () => { }), metaData: literal>({ sources: { - INP1: { sourceType: SourceType.Server }, + INP1: { sourceType: SourceType.SERVER }, INP2: EKSTERN_SOURCE }, serverPlaybackTiming: [{}] @@ -170,7 +170,7 @@ describe('Server Resume', () => { }), metaData: literal>({ sources: { - INP1: { sourceType: SourceType.Server }, + INP1: { sourceType: SourceType.SERVER }, INP2: EKSTERN_SOURCE }, serverPlaybackTiming: [{ end: 13000 }, { start: 14000, end: 15000 }, { start: 16000 }] diff --git a/src/tv2-common/helpers/__tests__/sisyfos.spec.ts b/src/tv2-common/helpers/__tests__/sisyfos.spec.ts new file mode 100644 index 000000000..47d4f3f80 --- /dev/null +++ b/src/tv2-common/helpers/__tests__/sisyfos.spec.ts @@ -0,0 +1,135 @@ +import { SourceLayerType, TSR } from '@tv2media/blueprints-integration' +import { + GetSisyfosTimelineObjForCamera, + GetSisyfosTimelineObjForRemote, + GetSisyfosTimelineObjForReplay, + SourceInfoType +} from 'tv2-common' +import { SharedSisyfosLLayer } from 'tv2-constants' +import { makeMockAFVDContext } from '../../../__mocks__/context' +import { getConfig } from '../../../tv2_afvd_showstyle/helpers/config' + +describe('Sisyfos', () => { + const config = getConfig(makeMockAFVDContext()) + it('Enables audio layers for cameras', () => { + const sourceInfo = { + type: SourceInfoType.KAM, + sourceLayerType: SourceLayerType.CAMERA, + id: '1', + port: 1, + sisyfosLayers: ['some_layer', 'some_layer2'], + useStudioMics: false + } + const timelineObjects = GetSisyfosTimelineObjForCamera(config, sourceInfo, false) + expect(timelineObjects.length).toBe(2) + expect(timelineObjects[0].layer).toBe('some_layer') + expect((timelineObjects[0] as TSR.TimelineObjSisyfosChannel).content.isPgm).toBe(1) + expect(timelineObjects[1].layer).toBe('some_layer2') + expect((timelineObjects[1] as TSR.TimelineObjSisyfosChannel).content.isPgm).toBe(1) + }) + it('Enables studio mics for cameras', () => { + const sourceInfo = { + type: SourceInfoType.KAM, + sourceLayerType: SourceLayerType.CAMERA, + id: '1', + port: 1, + sisyfosLayers: ['some_layer', 'some_layer2'], + useStudioMics: true + } + const timelineObjects = GetSisyfosTimelineObjForCamera(config, sourceInfo, false) + expect(timelineObjects.length).toBe(3) + const studioMicsTimelineObject = timelineObjects.find(t => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) + expect(studioMicsTimelineObject).toBeDefined() + }) + it('Does not enable studio mics for "minus mic" cameras', () => { + const sourceInfo = { + type: SourceInfoType.KAM, + sourceLayerType: SourceLayerType.CAMERA, + id: '1', + port: 1, + sisyfosLayers: ['some_layer', 'some_layer2'], + useStudioMics: true + } + const timelineObjects = GetSisyfosTimelineObjForCamera(config, sourceInfo, true) + expect(timelineObjects.length).toBe(2) + const studioMicsTimelineObject = timelineObjects.find(t => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) + expect(studioMicsTimelineObject).toBeUndefined() + }) + it('Enables audio layers for remotes', () => { + const sourceInfo = { + type: SourceInfoType.LIVE, + sourceLayerType: SourceLayerType.REMOTE, + id: '1', + port: 1, + sisyfosLayers: ['some_layer', 'some_layer2'], + useStudioMics: false + } + const timelineObjects = GetSisyfosTimelineObjForRemote(config, sourceInfo) + expect(timelineObjects.length).toBe(2) + expect(timelineObjects[0].layer).toBe('some_layer') + expect((timelineObjects[0] as TSR.TimelineObjSisyfosChannel).content.isPgm).toBe(1) + expect(timelineObjects[1].layer).toBe('some_layer2') + expect((timelineObjects[1] as TSR.TimelineObjSisyfosChannel).content.isPgm).toBe(1) + }) + it('Enables studio mics for remotes', () => { + const sourceInfo = { + type: SourceInfoType.LIVE, + sourceLayerType: SourceLayerType.REMOTE, + id: '1', + port: 1, + sisyfosLayers: ['some_layer', 'some_layer2'], + useStudioMics: true + } + const timelineObjects = GetSisyfosTimelineObjForRemote(config, sourceInfo) + expect(timelineObjects.length).toBe(3) + const studioMicsTimelineObject = timelineObjects.find(t => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) + expect(studioMicsTimelineObject).toBeDefined() + }) + it('Enables audio layers for replay', () => { + const sourceInfo = { + type: SourceInfoType.REPLAY, + sourceLayerType: SourceLayerType.LOCAL, + id: '1', + port: 1, + sisyfosLayers: ['some_layer', 'some_layer2'], + useStudioMics: false + } + const timelineObjects = GetSisyfosTimelineObjForReplay(config, sourceInfo, false) + expect(timelineObjects.length).toBe(2) + expect(timelineObjects[0].layer).toBe('some_layer') + expect((timelineObjects[0] as TSR.TimelineObjSisyfosChannel).content.isPgm).toBe(1) + expect(timelineObjects[1].layer).toBe('some_layer2') + expect((timelineObjects[1] as TSR.TimelineObjSisyfosChannel).content.isPgm).toBe(1) + }) + it('Enables audio layers for replay (vo)', () => { + const sourceInfo = { + type: SourceInfoType.REPLAY, + sourceLayerType: SourceLayerType.LOCAL, + id: '1', + port: 1, + sisyfosLayers: ['some_layer', 'some_layer2'], + useStudioMics: false + } + const timelineObjects = GetSisyfosTimelineObjForReplay(config, sourceInfo, true) + 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) + expect(layersTimelineObjects[1].layer).toBe('some_layer2') + expect((layersTimelineObjects[1] as TSR.TimelineObjSisyfosChannel).content.isPgm).toBe(2) + }) + it('Enables studio mics for replay (vo)', () => { + const sourceInfo = { + type: SourceInfoType.REPLAY, + sourceLayerType: SourceLayerType.LOCAL, + id: '1', + port: 1, + sisyfosLayers: ['some_layer', 'some_layer2'], + useStudioMics: true + } + const timelineObjects = GetSisyfosTimelineObjForReplay(config, sourceInfo, true) + expect(timelineObjects.length).toBe(3) + const studioMicsTimelineObject = timelineObjects.find(t => t.layer === SharedSisyfosLLayer.SisyfosGroupStudioMics) + expect(studioMicsTimelineObject).toBeDefined() + }) +}) diff --git a/src/tv2-common/helpers/postProcessDefinitions.ts b/src/tv2-common/helpers/postProcessDefinitions.ts index e417bc65d..ff0db9512 100644 --- a/src/tv2-common/helpers/postProcessDefinitions.ts +++ b/src/tv2-common/helpers/postProcessDefinitions.ts @@ -27,7 +27,7 @@ function setPartTitle(partDefinition: PartDefinition) { ) { switch (firstCue.type) { case CueType.Ekstern: - partDefinition.title = `${firstCue.sourceDefinition.variant} ${firstCue.sourceDefinition.id}` + partDefinition.title = firstCue.sourceDefinition.name break case CueType.DVE: partDefinition.title = firstCue.template @@ -52,7 +52,7 @@ function getExternalId(segmentId: string, partDefinition: PartDefinition, foundM switch (partDefinition.type) { case PartType.EVS: // Common pattern to see EV1 and EVS1VO in the same story. Changing from EVS1 to EVS1VO would mean a new part - id += `-${partDefinition.sourceDefinition.id}-${!!partDefinition.sourceDefinition.vo}` + id += `-${partDefinition.sourceDefinition.id}-${partDefinition.sourceDefinition.vo}` break case PartType.INTRO: // Intro must have a jingle cue, if it doesn't then padId will handle @@ -103,7 +103,7 @@ function getExternalId(segmentId: string, partDefinition: PartDefinition, foundM break case CueType.Ekstern: // Identify based on live source. Changing live source will result in a new part - id += `-${firstCue.sourceDefinition.variant}-${firstCue.sourceDefinition.id}` + id += `-${firstCue.sourceDefinition.name}` break case CueType.Jingle: // Changing the jingle clip will result in a new part diff --git a/src/tv2-common/helpers/sisyfos.ts b/src/tv2-common/helpers/sisyfos.ts index ab4f7a0c6..01f382fdd 100644 --- a/src/tv2-common/helpers/sisyfos.ts +++ b/src/tv2-common/helpers/sisyfos.ts @@ -1,5 +1,6 @@ import { Timeline, TSR } from '@tv2media/blueprints-integration' import { SourceInfo, TimelineBlueprintExt } from 'tv2-common' +import { SharedSisyfosLLayer } from 'tv2-constants' import { TV2BlueprintConfig } from '../blueprintConfig' import { literal } from '../util' @@ -7,28 +8,21 @@ export function GetSisyfosTimelineObjForCamera( config: TV2BlueprintConfig, sourceInfo: SourceInfo, minusMic: boolean, - studioMicsLayer: string, enable?: Timeline.TimelineEnable ) { - return GetSisyfosTimelineObjForSource(config, sourceInfo, false, minusMic, studioMicsLayer, enable) + return GetSisyfosTimelineObjForSource(config, sourceInfo, false, minusMic, enable) } export function GetSisyfosTimelineObjForRemote( config: TV2BlueprintConfig, sourceInfo: SourceInfo, - studioMicsLayer: string, enable?: Timeline.TimelineEnable ) { - return GetSisyfosTimelineObjForSource(config, sourceInfo, false, false, studioMicsLayer, enable) + return GetSisyfosTimelineObjForSource(config, sourceInfo, false, false, enable) } -export function GetSisyfosTimelineObjForReplay( - config: TV2BlueprintConfig, - sourceInfo: SourceInfo, - vo: boolean, - studioMicsLayer: string -) { - return GetSisyfosTimelineObjForSource(config, sourceInfo, vo, true, studioMicsLayer) +export function GetSisyfosTimelineObjForReplay(config: TV2BlueprintConfig, sourceInfo: SourceInfo, vo: boolean) { + return GetSisyfosTimelineObjForSource(config, sourceInfo, vo, true) } export function GetSisyfosTimelineObjForServer( @@ -36,7 +30,6 @@ export function GetSisyfosTimelineObjForServer( vo: boolean, clipPendingLayer: string, mediaPlayerSession: string, - studioMicsLayer: string, enable?: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosAny[] { const timelineEnable = getFallbackEnable(enable) @@ -58,26 +51,24 @@ export function GetSisyfosTimelineObjForServer( }) ] if (vo) { - result.push(getStudioMicsTimelineObj(config, timelineEnable, studioMicsLayer)) + result.push(getStudioMicsTimelineObj(config, timelineEnable)) } return result } export function GetSisyfosTimelineObjForFull( config: TV2BlueprintConfig, - studioMicsLayer: string, enable?: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosAny[] { const result: TSR.TimelineObjSisyfosAny[] = [] const timelineEnable = getFallbackEnable(enable) - result.push(getStudioMicsTimelineObj(config, timelineEnable, studioMicsLayer)) + result.push(getStudioMicsTimelineObj(config, timelineEnable)) return result } export function GetSisyfosTimelineObjForTelefon( config: TV2BlueprintConfig, telefonLayer: string, - studioMicsLayer: string, enable?: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosAny[] { const timelineEnable = getFallbackEnable(enable) @@ -94,7 +85,7 @@ export function GetSisyfosTimelineObjForTelefon( } }) ] - result.push(getStudioMicsTimelineObj(config, timelineEnable, studioMicsLayer)) + result.push(getStudioMicsTimelineObj(config, timelineEnable)) return result } @@ -103,7 +94,6 @@ function GetSisyfosTimelineObjForSource( sourceInfo: SourceInfo, vo: boolean, enableStudioMicsOnlyForVo: boolean, - studioMicsLayer: string, enable?: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosAny[] { const result: TSR.TimelineObjSisyfosAny[] = [] @@ -124,15 +114,14 @@ function GetSisyfosTimelineObjForSource( ) }) if (sourceInfo.useStudioMics && (!enableStudioMicsOnlyForVo || vo)) { - result.push(getStudioMicsTimelineObj(config, timelineEnable, studioMicsLayer)) + result.push(getStudioMicsTimelineObj(config, timelineEnable)) } return result } function getStudioMicsTimelineObj( config: TV2BlueprintConfig, - timelineEnable: Timeline.TimelineEnable, - studioMicsLayer: string + timelineEnable: Timeline.TimelineEnable ): TSR.TimelineObjSisyfosChannels { const studioMicsChannels: TSR.TimelineObjSisyfosChannels['content']['channels'] = [] config.studio.StudioMics.forEach(layer => { @@ -145,7 +134,7 @@ function getStudioMicsTimelineObj( id: '', enable: timelineEnable, priority: studioMicsChannels.length ? 2 : 0, - layer: studioMicsLayer, + layer: SharedSisyfosLLayer.SisyfosGroupStudioMics, content: { deviceType: TSR.DeviceType.SISYFOS, type: TSR.TimelineContentTypeSisyfos.CHANNELS, diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index c27a06c5f..20f64fb73 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -1,10 +1,4 @@ -import { - CueDefinitionFromLayout, - isMinusMic, - PostProcessDefinitions, - TV2BlueprintConfig, - UnparsedCue -} from 'tv2-common' +import { CueDefinitionFromLayout, PostProcessDefinitions, TV2BlueprintConfig, UnparsedCue } from 'tv2-common' import { CueType, PartType, SourceType } from 'tv2-constants' import { CueDefinition, ParseCue, UnpairedPilotToGraphic } from './ParseCue' @@ -15,13 +9,14 @@ export interface PartTransition { export interface SourceDefinitionBase { sourceType: SourceType + name?: string } export interface SourceDefinitionWithRaw { raw: string } export interface SourceDefinitionKam extends SourceDefinitionWithRaw { - sourceType: SourceType.Kam + sourceType: SourceType.KAM /** name that appears in the Camera Mappings table (e.g. "1", "CS 3") */ id: string /** full name for display/logging purposes e.g. "KAM 1" */ @@ -29,8 +24,8 @@ export interface SourceDefinitionKam extends SourceDefinitionWithRaw { minusMic: boolean } -export interface SourceDefinitionEVS extends SourceDefinitionWithRaw { - sourceType: SourceType.EVS +export interface SourceDefinitionReplay extends SourceDefinitionWithRaw { + sourceType: SourceType.REPLAY /** id that appears in the Replay Mappings table (e.g. "EVS 1", "EPSIO") */ id: string /** full name for display/logging purposes e.g. "EVS 1 VO" */ @@ -38,21 +33,30 @@ export interface SourceDefinitionEVS extends SourceDefinitionWithRaw { vo: boolean } -export interface SourceDefinitionEkstern extends SourceDefinitionWithRaw { +export enum RemoteType { + LIVE = 'LIVE', + FEED = 'FEED' +} +export interface SourceDefinitionRemote extends SourceDefinitionWithRaw { sourceType: SourceType.REMOTE - variant: 'LIVE' | 'FEED' + remoteType: RemoteType /** name that appears in the Remote Mappings table (e.g. "1", "2") */ id: string /** full name for display/logging purposes e.g. "LIVE 1" */ name: string } +export interface SourceDefinitionInvalid extends SourceDefinitionWithRaw { + sourceType: SourceType.INVALID + /** full name for display/logging purposes */ + name: string +} export interface SourceDefinitionServer extends SourceDefinitionBase { - sourceType: SourceType.Server + sourceType: SourceType.SERVER } export interface SourceDefinitionGrafik extends SourceDefinitionWithRaw { - sourceType: SourceType.Grafik + sourceType: SourceType.GRAFIK name: string } @@ -60,13 +64,19 @@ export interface SourceDefinitionDefault extends SourceDefinitionBase { sourceType: SourceType.DEFAULT } +export interface SourceDefinitionPGM extends SourceDefinitionBase { + sourceType: SourceType.PGM +} + export type SourceDefinition = | SourceDefinitionKam - | SourceDefinitionEVS - | SourceDefinitionEkstern + | SourceDefinitionReplay + | SourceDefinitionRemote | SourceDefinitionServer | SourceDefinitionGrafik | SourceDefinitionDefault + | SourceDefinitionPGM + | SourceDefinitionInvalid export interface PartDefinitionBase { externalId: string @@ -90,6 +100,7 @@ export interface PartDefinitionUnknown extends PartDefinitionBase { } export interface PartDefinitionKam extends PartDefinitionBase { type: PartType.Kam + /** Definition of the primary source */ sourceDefinition: SourceDefinitionKam } export interface PartDefinitionServer extends PartDefinitionBase { @@ -113,7 +124,8 @@ export interface PartDefinitionIntro extends PartDefinitionBase { } export interface PartDefinitionEVS extends PartDefinitionBase { type: PartType.EVS - sourceDefinition: SourceDefinitionEVS + /** Definition of the primary source */ + sourceDefinition: SourceDefinitionReplay } export interface PartDefinitionDVE extends PartDefinitionBase { @@ -556,13 +568,13 @@ function extractTypeProperties(typeStr: string): PartdefinitionTypes { const sourceDefinition = getSourceDefinition(typeStr) switch (sourceDefinition?.sourceType) { - case SourceType.Kam: + case SourceType.KAM: return { type: PartType.Kam, sourceDefinition, ...transitionAndEffekt } - case SourceType.EVS: + case SourceType.REPLAY: return { type: PartType.EVS, sourceDefinition, @@ -611,9 +623,9 @@ export function getSourceDefinition(typeStr: string): SourceDefinition | undefin .replace(/100%/g, '') .trim() if (CAMERA_RED_TEXT.test(strippedTypeStr)) { - const id = strippedTypeStr.match(CAMERA_RED_TEXT)![1] + const id = strippedTypeStr.match(CAMERA_RED_TEXT)![1].toUpperCase() return { - sourceType: SourceType.Kam, + sourceType: SourceType.KAM, id, minusMic: isMinusMic(typeStr), raw: strippedTypeStr, @@ -621,11 +633,11 @@ export function getSourceDefinition(typeStr: string): SourceDefinition | undefin } } else if (REMOTE_CUE.test(typeStr)) { const remoteNumber = typeStr.match(REMOTE_CUE) - const variant = remoteNumber![1].toUpperCase() as 'LIVE' | 'FEED' + const variant = remoteNumber![1].toUpperCase() as RemoteType const id = remoteNumber![2] return { sourceType: SourceType.REMOTE, - variant, + remoteType: variant, id, raw: strippedTypeStr, name: `${variant} ${id}` @@ -635,7 +647,7 @@ export function getSourceDefinition(typeStr: string): SourceDefinition | undefin const id = `EVS ${strippedToken![1].toUpperCase()}` const vo = strippedToken![2] return { - sourceType: SourceType.EVS, + sourceType: SourceType.REPLAY, id, vo: !!vo, raw: strippedToken![0].trim(), @@ -643,7 +655,7 @@ export function getSourceDefinition(typeStr: string): SourceDefinition | undefin } } else if (/EPSIO/i.test(typeStr)) { return { - sourceType: SourceType.EVS, + sourceType: SourceType.REPLAY, id: 'EPSIO', vo: true, raw: typeStr, @@ -652,7 +664,7 @@ export function getSourceDefinition(typeStr: string): SourceDefinition | undefin } else if (ENGINE_CUE.test(typeStr)) { const strippedToken = typeStr.match(ENGINE_CUE) return { - sourceType: SourceType.Grafik, + sourceType: SourceType.GRAFIK, name: strippedToken![1].toUpperCase(), raw: typeStr } @@ -662,12 +674,20 @@ export function getSourceDefinition(typeStr: string): SourceDefinition | undefin } } else if (/SERVER/i.test(typeStr)) { return { - sourceType: SourceType.Server + sourceType: SourceType.SERVER + } + } else if (/PGM/i.test(typeStr)) { + return { + sourceType: SourceType.PGM } } return undefined } +export function isMinusMic(inputName: string): boolean { + return /minus mic/i.test(inputName) +} + export function stripRedundantCuesWhenLayoutCueIsPresent(partDefinitions: PartDefinition[]): PartDefinition[] { const hasLayoutCue: boolean = partDefinitions.some(definition => definition.cues.some(cue => { diff --git a/src/tv2-common/inewsConversion/converters/ParseCue.ts b/src/tv2-common/inewsConversion/converters/ParseCue.ts index dc61fb665..14a6709bf 100644 --- a/src/tv2-common/inewsConversion/converters/ParseCue.ts +++ b/src/tv2-common/inewsConversion/converters/ParseCue.ts @@ -6,7 +6,8 @@ import { PartDefinition, PartdefinitionTypes, SourceDefinition, - SourceDefinitionEkstern, + SourceDefinitionInvalid, + SourceDefinitionRemote, stripTransitionProperties } from './ParseBody' @@ -30,7 +31,8 @@ export interface CueDefinitionUnknown extends CueDefinitionBase { export interface CueDefinitionEkstern extends CueDefinitionBase { type: CueType.Ekstern - sourceDefinition: SourceDefinitionEkstern + /** Definition of the primary source */ + sourceDefinition: SourceDefinitionRemote | SourceDefinitionInvalid transition?: Pick } @@ -89,7 +91,7 @@ export interface CueDefinitionClearGrafiks extends CueDefinitionBase { export interface CueDefinitionMixMinus extends CueDefinitionBase { type: CueType.MixMinus - source: string + sourceDefinition: SourceDefinition } // If unpaired when evaluated, throw warning. If target === 'FULL' create invalid part. @@ -150,13 +152,13 @@ export interface CueDefinitionGraphic extends export interface CueDefinitionRouting extends CueDefinitionBase { type: CueType.Routing target: GraphicEngine - INP?: string - INP1?: string + INP?: SourceDefinition + INP1?: SourceDefinition } export interface CueDefinitionPgmClean extends CueDefinitionBase { type: CueType.PgmClean - source: 'PGM' | string + sourceDefinition: SourceDefinition } export type CueDefinition = @@ -428,16 +430,21 @@ function parsePilot(cue: string[]): CueDefinitionUnpairedPilot | CueDefinitionGr function parseEkstern(cue: string[]): CueDefinitionEkstern | undefined { const eksternSource = stripTransitionProperties(cue[0]).match(/^EKSTERN=(.+)$/i) if (eksternSource) { - const sourceDefinition = getSourceDefinition(eksternSource[1]) - if (sourceDefinition?.sourceType === SourceType.REMOTE) { - const transitionProperties = getTransitionProperties(cue[0]) - return literal({ - type: CueType.Ekstern, - iNewsCommand: 'EKSTERN', - transition: transitionProperties, - sourceDefinition - }) + let sourceDefinition = getSourceDefinition(eksternSource[1]) + if (sourceDefinition?.sourceType !== SourceType.REMOTE) { + sourceDefinition = { + sourceType: SourceType.INVALID, + name: eksternSource[1], + raw: eksternSource[1] + } } + const transitionProperties = getTransitionProperties(cue[0]) + return literal({ + type: CueType.Ekstern, + iNewsCommand: 'EKSTERN', + transition: transitionProperties, + sourceDefinition + }) } return undefined @@ -676,7 +683,7 @@ function parseTargetEngine( target: engineCue.target, iNewsCommand: '' } - + let hasInputs = false for (let i = 1; i < cue.length; i++) { if (isTime(cue[i])) { engineCue = { ...engineCue, ...parseTime(cue[i]) } @@ -684,16 +691,18 @@ function parseTargetEngine( const c = cue[i].split('=') const input = c[0].toString().toUpperCase() if (input === 'INP') { - routing.INP = c[1] + routing.INP = getSourceDefinition(c[1]) + hasInputs = true } if (input === 'INP1') { - routing.INP1 = c[1] + routing.INP1 = getSourceDefinition(c[1]) + hasInputs = true } } } - if (routing.INP1 !== undefined || routing.INP !== undefined) { + if (hasInputs) { engineCue.routing = routing } @@ -764,14 +773,17 @@ function parseAllOut(cue: string[]): CueDefinitionClearGrafiks { } export function parsePgmClean(cue: string[]): CueDefinitionPgmClean { + const pgmSource = cue[0].match(/^PGMCLEAN=(.+)$/i) const pgmCleanCue: CueDefinitionPgmClean = { type: CueType.PgmClean, - source: 'PGM', - iNewsCommand: 'PGMCLEAN' + iNewsCommand: 'PGMCLEAN', + sourceDefinition: { sourceType: SourceType.PGM } } - const pgmSource = cue[0].match(/^PGMCLEAN=(.+)$/i) if (pgmSource && pgmSource[1]) { - pgmCleanCue.source = pgmSource[1].toString().toUpperCase() + const sourceDefinition = getSourceDefinition(pgmSource[1]) + if (sourceDefinition) { + pgmCleanCue.sourceDefinition = sourceDefinition + } } return pgmCleanCue } @@ -781,9 +793,13 @@ export function parseMixMinus(cue: string[]): CueDefinitionMixMinus | undefined if (sourceMatch === null) { return undefined } + const sourceDefinition = getSourceDefinition(sourceMatch.groups!.source) + if (sourceDefinition === undefined) { + return undefined + } return literal({ type: CueType.MixMinus, - source: sourceMatch.groups!.source.toUpperCase(), + sourceDefinition, iNewsCommand: 'MINUSKAM' }) } @@ -962,7 +978,7 @@ export function UnknownPartParentClass(studio: string, partDefinition: PartDefin case CueType.DVE: return DVEParentClass(studio, firstCue.template) case CueType.Ekstern: - return EksternParentClass(studio, `${firstCue.sourceDefinition.variant} ${firstCue.sourceDefinition.id}`) + return EksternParentClass(studio, firstCue.sourceDefinition.name) case CueType.Telefon: return TLFParentClass(studio, firstCue.source) default: 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 fc28e08cf..0f46e9c39 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/body-parser.spec.ts @@ -26,8 +26,9 @@ import { PartDefinitionTelefon, PartDefinitionUnknown, PartDefinitionVO, - SourceDefinitionEkstern, - SourceDefinitionKam + RemoteType, + SourceDefinitionKam, + SourceDefinitionRemote } from '../ParseBody' import { CueDefinition, @@ -91,9 +92,9 @@ const cueGrafik3: CueDefinitionGraphic = { const unparsedGrafik3 = ['kg bund 3'] -const SOURCE_DEFINITION_LIVE_1: SourceDefinitionEkstern = { +const SOURCE_DEFINITION_LIVE_1: SourceDefinitionRemote = { sourceType: SourceType.REMOTE, - variant: 'LIVE', + remoteType: RemoteType.LIVE, id: '1', name: 'LIVE 1', raw: 'LIVE 1' @@ -106,9 +107,9 @@ const cueEkstern1: CueDefinitionEkstern = { const unparsedEkstern1 = ['EKSTERN=LIVE 1'] -const SOURCE_DEFINITION_LIVE_2: SourceDefinitionEkstern = { +const SOURCE_DEFINITION_LIVE_2: SourceDefinitionRemote = { sourceType: SourceType.REMOTE, - variant: 'LIVE', + remoteType: RemoteType.LIVE, id: '2', name: 'LIVE 2', raw: 'LIVE 2' @@ -162,21 +163,21 @@ const cueTelefon2: CueDefinitionTelefon = { const unparsedTelefon2 = ['TELEFON=TLF 2'] const SOURCE_DEFINITION_KAM_1: SourceDefinitionKam = { - sourceType: SourceType.Kam, + sourceType: SourceType.KAM, id: '1', raw: 'KAM 1', minusMic: false, name: 'KAM 1' } const SOURCE_DEFINITION_KAM_2: SourceDefinitionKam = { - sourceType: SourceType.Kam, + sourceType: SourceType.KAM, id: '2', raw: 'KAM 2', minusMic: false, name: 'KAM 2' } const SOURCE_DEFINITION_KAM_3: SourceDefinitionKam = { - sourceType: SourceType.Kam, + sourceType: SourceType.KAM, id: '3', raw: 'KAM 3', minusMic: false, @@ -373,7 +374,7 @@ describe('Body parser', () => { rawType: 'KAM AR', cues: [cueJingle3], script: 'Lots more script\n', - sourceDefinition: { sourceType: SourceType.Kam, id: 'AR', raw: 'KAM AR', minusMic: false, name: 'KAM AR' }, + sourceDefinition: { sourceType: SourceType.KAM, id: 'AR', raw: 'KAM AR', minusMic: false, name: 'KAM AR' }, externalId: '', fields: {}, modified: 0, @@ -432,7 +433,7 @@ describe('Body parser', () => { rawType: 'CAMERA 1', cues: [], script: 'Her står em masse tekst\n', - sourceDefinition: { sourceType: SourceType.Kam, id: '1', raw: 'CAMERA 1', minusMic: false, name: 'KAM 1' }, + sourceDefinition: { sourceType: SourceType.KAM, id: '1', raw: 'CAMERA 1', minusMic: false, name: 'KAM 1' }, externalId: '', fields, modified: 0, @@ -537,7 +538,7 @@ describe('Body parser', () => { cues: [], script: 'Long script. Long script. Long script. Long script. Long script. Long script. Long script. Long script. Long script. Long script. Long script. Long script.\n', - sourceDefinition: { sourceType: SourceType.Kam, id: '4', raw: 'KAM 4', minusMic: false, name: 'KAM 4' }, + sourceDefinition: { sourceType: SourceType.KAM, id: '4', raw: 'KAM 4', minusMic: false, name: 'KAM 4' }, externalId: '', fields: {}, modified: 0, @@ -1539,7 +1540,7 @@ describe('Body parser', () => { type: PartType.EVS, rawType: 'EVS 1', sourceDefinition: { - sourceType: SourceType.EVS, + sourceType: SourceType.REPLAY, id: 'EVS 1', name: 'EVS 1', raw: 'EVS 1', @@ -1566,7 +1567,7 @@ describe('Body parser', () => { type: PartType.EVS, rawType: 'EVS1VOV', sourceDefinition: { - sourceType: SourceType.EVS, + sourceType: SourceType.REPLAY, id: 'EVS 1', name: 'EVS 1 VOV', raw: 'EVS1VOV', @@ -1592,7 +1593,7 @@ describe('Body parser', () => { type: PartType.EVS, rawType: 'EVS 1 VO', sourceDefinition: { - sourceType: SourceType.EVS, + sourceType: SourceType.REPLAY, id: 'EVS 1', name: 'EVS 1 VO', raw: 'EVS 1 VO', @@ -1610,7 +1611,7 @@ describe('Body parser', () => { type: PartType.EVS, rawType: 'EVS 2VO', sourceDefinition: { - sourceType: SourceType.EVS, + sourceType: SourceType.REPLAY, id: 'EVS 2', name: 'EVS 2 VO', raw: 'EVS 2VO', @@ -1628,7 +1629,7 @@ describe('Body parser', () => { type: PartType.EVS, rawType: 'EVS3VO', sourceDefinition: { - sourceType: SourceType.EVS, + sourceType: SourceType.REPLAY, id: 'EVS 3', name: 'EVS 3 VO', raw: 'EVS3VO', @@ -1646,7 +1647,7 @@ describe('Body parser', () => { type: PartType.EVS, rawType: 'EVS4 VO', sourceDefinition: { - sourceType: SourceType.EVS, + sourceType: SourceType.REPLAY, id: 'EVS 4', name: 'EVS 4 VO', raw: 'EVS4 VO', @@ -2172,7 +2173,7 @@ describe('Body parser', () => { routing: { type: CueType.Routing, target: 'OVL', - INP: 'LIVE 2', + INP: SOURCE_DEFINITION_LIVE_2, iNewsCommand: '' }, start: { @@ -2452,8 +2453,8 @@ describe('Body parser', () => { routing: { type: CueType.Routing, target: 'FULL', - INP: '', - INP1: '', + INP: undefined, + INP1: undefined, iNewsCommand: '' }, engineNumber: 4, @@ -2517,7 +2518,7 @@ describe('Body parser', () => { routing: { type: CueType.Routing, target: 'FULL', - INP1: '', + INP1: undefined, iNewsCommand: '' }, iNewsCommand: 'GRAFIK', @@ -2550,7 +2551,7 @@ describe('Body parser', () => { routing: { type: CueType.Routing, target: 'FULL', - INP1: '', + INP1: undefined, iNewsCommand: '' }, iNewsCommand: 'GRAFIK', @@ -2590,7 +2591,7 @@ describe('Body parser', () => { routing: { type: CueType.Routing, target: 'WALL', - INP1: 'EVS 1', + INP1: { sourceType: SourceType.REPLAY, name: 'EVS 1', id: 'EVS 1', raw: 'EVS 1', vo: false }, iNewsCommand: '' }, graphic: { @@ -2628,7 +2629,7 @@ describe('Body parser', () => { type: PartType.EVS, rawType: 'EVS 1', sourceDefinition: { - sourceType: SourceType.EVS, + sourceType: SourceType.REPLAY, id: 'EVS 1', name: 'EVS 1', raw: 'EVS 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 46d0397e3..3f317acc1 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,5 @@ import { IBlueprintRundownDB, PlaylistTimingType } from '@tv2media/blueprints-integration' -import { SourceDefinitionEkstern, SourceDefinitionKam } from 'tv2-common' +import { 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' @@ -35,19 +35,33 @@ import { const RUNDOWN_EXTERNAL_ID = 'TEST.SOFIE.JEST' const SOURCE_DEFINITION_KAM_1: SourceDefinitionKam = { - sourceType: SourceType.Kam, + sourceType: SourceType.KAM, id: '1', raw: 'KAM 1', minusMic: false, name: 'KAM 1' } -const SOURCE_DEFINITION_LIVE_1: SourceDefinitionEkstern = { +const SOURCE_DEFINITION_KAM_2: SourceDefinitionKam = { + sourceType: SourceType.KAM, + id: '2', + raw: 'KAM 2', + minusMic: false, + name: 'KAM 2' +} +const SOURCE_DEFINITION_LIVE_1: SourceDefinitionRemote = { sourceType: SourceType.REMOTE, - variant: 'LIVE', + remoteType: RemoteType.LIVE, id: '1', name: 'LIVE 1', raw: 'LIVE 1' } +const SOURCE_DEFINITION_LIVE_2: SourceDefinitionRemote = { + sourceType: SourceType.REMOTE, + remoteType: RemoteType.LIVE, + id: '2', + name: 'LIVE 2', + raw: 'LIVE 2' +} function makeMockContext() { const rundown = literal({ @@ -921,8 +935,8 @@ describe('Cue parser', () => { routing: { type: CueType.Routing, target: 'FULL', - INP1: '', - INP: '', + INP1: undefined, + INP: undefined, iNewsCommand: '' }, iNewsCommand: 'GRAFIK', @@ -1470,7 +1484,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.PgmClean, - source: 'LIVE 1', + sourceDefinition: { ...SOURCE_DEFINITION_LIVE_1, raw: 'Live 1' }, iNewsCommand: 'PGMCLEAN' }) ) @@ -1506,7 +1520,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.MixMinus, - source: 'KAM 1', + sourceDefinition: SOURCE_DEFINITION_KAM_1, iNewsCommand: 'MINUSKAM' }) ) @@ -1518,7 +1532,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.MixMinus, - source: 'KAM 2', + sourceDefinition: SOURCE_DEFINITION_KAM_2, iNewsCommand: 'MINUSKAM' }) ) @@ -1530,7 +1544,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.MixMinus, - source: 'KAMERA 1', + sourceDefinition: { ...SOURCE_DEFINITION_KAM_1, raw: 'KAMERA 1' }, iNewsCommand: 'MINUSKAM' }) ) @@ -1542,7 +1556,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.MixMinus, - source: 'KAMERA 2', + sourceDefinition: { ...SOURCE_DEFINITION_KAM_2, raw: 'KAMERA 2' }, iNewsCommand: 'MINUSKAM' }) ) @@ -1554,7 +1568,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.MixMinus, - source: 'LIVE 1', + sourceDefinition: SOURCE_DEFINITION_LIVE_1, iNewsCommand: 'MINUSKAM' }) ) @@ -1566,7 +1580,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.MixMinus, - source: 'LIVE 2', + sourceDefinition: SOURCE_DEFINITION_LIVE_2, iNewsCommand: 'MINUSKAM' }) ) @@ -1578,7 +1592,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.MixMinus, - source: 'SERVER', + sourceDefinition: { sourceType: SourceType.SERVER }, iNewsCommand: 'MINUSKAM' }) ) @@ -1590,7 +1604,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.MixMinus, - source: 'SERVER', + sourceDefinition: { sourceType: SourceType.SERVER }, iNewsCommand: 'MINUSKAM' }) ) @@ -1602,7 +1616,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.MixMinus, - source: 'LIVE 1', + sourceDefinition: SOURCE_DEFINITION_LIVE_1, iNewsCommand: 'MINUSKAM' }) ) @@ -1614,7 +1628,7 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.MixMinus, - source: 'LIVE 2', + sourceDefinition: SOURCE_DEFINITION_LIVE_2, iNewsCommand: 'MINUSKAM' }) ) @@ -1632,19 +1646,19 @@ describe('Cue parser', () => { expect(result).toEqual( literal({ type: CueType.MixMinus, - source: 'KAM 2', + sourceDefinition: { ...SOURCE_DEFINITION_KAM_2, raw: 'Kam 2' }, iNewsCommand: 'MINUSKAM' }) ) }) - test('minuskam = Kam 3 ', () => { - const minusKamCue = ['minuskam = Kam 3 '] + test('minuskam = Kam 2 ', () => { + const minusKamCue = ['minuskam = Kam 2 '] const result = ParseCue(minusKamCue, config) expect(result).toEqual( literal({ type: CueType.MixMinus, - source: 'KAM 3', + sourceDefinition: { ...SOURCE_DEFINITION_KAM_2, raw: 'Kam 2' }, iNewsCommand: 'MINUSKAM' }) ) diff --git a/src/tv2-common/inewsConversion/converters/__tests__/part-to-parent-class.spec.ts b/src/tv2-common/inewsConversion/converters/__tests__/part-to-parent-class.spec.ts index 3e13e4dca..6a55df041 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/part-to-parent-class.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/part-to-parent-class.spec.ts @@ -1,6 +1,6 @@ import { literal } from 'tv2-common' import { CueType, PartType, SourceType } from 'tv2-constants' -import { PartDefinitionEkstern } from '../ParseBody' +import { PartDefinitionEkstern, RemoteType } from '../ParseBody' import { CueDefinitionEkstern, PartToParentClass } from '../ParseCue' describe('PartToParentClass', () => { @@ -14,7 +14,7 @@ describe('PartToParentClass', () => { type: CueType.Ekstern, sourceDefinition: { sourceType: SourceType.REMOTE, - variant: 'LIVE', + remoteType: RemoteType.LIVE, id: '1', raw: 'Live 1', name: 'LIVE 1' diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index 94a5c49cd..c0133dd59 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -221,8 +221,7 @@ function getContentServerElement< ClipPending: layers.Caspar.ClipPending }, Sisyfos: { - ClipPending: layers.Sisyfos.ClipPending, - StudioMicsGroup: layers.Sisyfos.StudioMicsGroup + ClipPending: layers.Sisyfos.ClipPending }, ATEM: { ServerLookaheadAux: layers.ATEM.ServerLookaheadAux diff --git a/src/tv2-common/pieces/tags.ts b/src/tv2-common/pieces/tags.ts index 9f94865a8..423d6dc5a 100644 --- a/src/tv2-common/pieces/tags.ts +++ b/src/tv2-common/pieces/tags.ts @@ -1,6 +1,6 @@ import { ActionTakeWithTransitionVariant, CueDefinitionDVE, SanitizeString } from 'tv2-common' import { TallyTags } from 'tv2-constants' -import { SourceDefinitionEkstern } from '../inewsConversion' +import { SourceDefinitionKam, SourceDefinitionRemote } from '../inewsConversion' export function GetTagForTransition(variant: ActionTakeWithTransitionVariant) { let tag = `${TallyTags.TAKE_WITH_TRANSITION}_${variant.type.toUpperCase()}` @@ -19,11 +19,11 @@ export function GetTagForTransition(variant: ActionTakeWithTransitionVariant) { return tag } -export function GetTagForKam(name: string) { - return `${TallyTags.KAM}_${SanitizeString(name)}` +export function GetTagForKam(sourceDefinition: SourceDefinitionKam) { + return `${TallyTags.KAM}_${SanitizeString(sourceDefinition.name)}` } -export function GetTagForLive(sourceDefinition: SourceDefinitionEkstern) { +export function GetTagForLive(sourceDefinition: SourceDefinitionRemote) { return `${TallyTags.LIVE}_${SanitizeString(sourceDefinition.name)}` } diff --git a/src/tv2-common/sources.ts b/src/tv2-common/sources.ts index 8f47e6f31..784eaee76 100644 --- a/src/tv2-common/sources.ts +++ b/src/tv2-common/sources.ts @@ -3,7 +3,13 @@ import * as _ from 'underscore' import { IStudioContext, SourceLayerType } from '@tv2media/blueprints-integration' import { SourceType } from 'tv2-constants' import { SourceMapping } from './blueprintConfig' -import { SourceDefinition, SourceDefinitionEkstern, SourceDefinitionEVS, SourceDefinitionKam } from './inewsConversion' +import { + RemoteType, + SourceDefinition, + SourceDefinitionReplay, + SourceDefinitionKam, + SourceDefinitionRemote +} from './inewsConversion' import { TableConfigItemSourceMappingWithSisyfos } from './types' import { assertUnreachable } from './util' @@ -88,69 +94,16 @@ export interface SourceInfo { acceptPersistAudio?: boolean } -export function FindSourceInfo(sources: SourceMapping, type: SourceInfoType, id: string): SourceInfo | undefined { - id = id.replace(/\s+/i, ' ').trim() - switch (type) { - case SourceInfoType.KAM: - return _.find(sources.cameras, s => s.id === id.replace(/minus mic/i, '').trim()) - case SourceInfoType.LIVE: - case SourceInfoType.FEED: - const remoteName = id - .replace(/VO/i, '') - .replace(/\s/g, '') - .match(/^(?:LIVE|FEED) *(.+).*$/i) - if (!remoteName) { - return undefined - } - if (/^LIVE/i.test(id)) { - return _.find(sources.lives, s => s.id === remoteName[1]) - } else { - return _.find(sources.feeds, s => s.id === remoteName[1]) - } - case SourceInfoType.REPLAY: - return _.find(sources.replays, s => s.id === id) - default: - return undefined - } -} - -export function isMinusMic(inputName: string): boolean { - return /minus mic/i.test(inputName) -} - -export function FindSourceInfoByName(sources: SourceMapping, name: string): SourceInfo | undefined { - name = name.toLowerCase() - - let sourceType: SourceInfoType | undefined - if (name.match(/live/i)) { - sourceType = SourceInfoType.LIVE - } else if (name.match(/feed/i)) { - sourceType = SourceInfoType.FEED - } else if (name.match(/[k|c]am/i)) { - sourceType = SourceInfoType.KAM - } else if (name.match(/evs/i)) { - sourceType = SourceInfoType.REPLAY - } - if (sourceType === undefined) { - return undefined - } - - return FindSourceInfo(sources, sourceType, name) -} - -export function FindSourceInfoByDefinition( - sources: SourceMapping, - sourceDefinition: SourceDefinition -): SourceInfo | undefined { +export function findSourceInfo(sources: SourceMapping, sourceDefinition: SourceDefinition): SourceInfo | undefined { let arrayToSearchIn: SourceInfo[] switch (sourceDefinition.sourceType) { - case SourceType.Kam: + case SourceType.KAM: arrayToSearchIn = sources.cameras break case SourceType.REMOTE: - arrayToSearchIn = sourceDefinition.variant === 'LIVE' ? sources.lives : sources.feeds + arrayToSearchIn = sourceDefinition.remoteType === RemoteType.LIVE ? sources.lives : sources.feeds break - case SourceType.EVS: + case SourceType.REPLAY: arrayToSearchIn = sources.replays break default: @@ -161,12 +114,12 @@ export function FindSourceInfoByDefinition( export function SourceInfoToSourceDefinition( sourceInfo: SourceInfo -): SourceDefinitionKam | SourceDefinitionEkstern | SourceDefinitionEVS { +): SourceDefinitionKam | SourceDefinitionRemote | SourceDefinitionReplay { switch (sourceInfo.type) { case SourceInfoType.KAM: { const name = `KAM ${sourceInfo.id}` return { - sourceType: SourceType.Kam, + sourceType: SourceType.KAM, id: sourceInfo.id, raw: name, minusMic: false, @@ -177,7 +130,7 @@ export function SourceInfoToSourceDefinition( const name = `LIVE ${sourceInfo.id}` return { sourceType: SourceType.REMOTE, - variant: 'LIVE', + remoteType: RemoteType.LIVE, id: sourceInfo.id, raw: name, name @@ -187,7 +140,7 @@ export function SourceInfoToSourceDefinition( const name = `FEED ${sourceInfo.id}` return { sourceType: SourceType.REMOTE, - variant: 'FEED', + remoteType: RemoteType.FEED, id: sourceInfo.id, raw: name, name @@ -195,7 +148,7 @@ export function SourceInfoToSourceDefinition( } case SourceInfoType.REPLAY: return { - sourceType: SourceType.EVS, + sourceType: SourceType.REPLAY, id: sourceInfo.id, raw: sourceInfo.id, name: sourceInfo.id, diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index 1bc5d86c1..8eb2b493d 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -50,14 +50,16 @@ export const enum PartType { } export const enum SourceType { - Kam = 'Kam', - Server = 'Server', + KAM = 'KAM', + SERVER = 'SERVER', VO = 'VO', - Teknik = 'Teknik', - Grafik = 'Grafik', - EVS = 'EVS', - REMOTE = 'Ekstern', - DEFAULT = 'Default' + TEKNIK = 'TEKNIK', + GRAFIK = 'GRAFIK', + REPLAY = 'REPLAY', + REMOTE = 'REMOTE', + DEFAULT = 'DEFAULT', + PGM = 'PGM', + INVALID = 'INVALID' } export enum Enablers { @@ -207,7 +209,8 @@ export enum SharedCasparLLayer { export enum SharedSisyfosLLayer { SisyfosSourceAudiobed = 'sisyfos_source_audiobed', - SisyfosResync = 'sisyfos_resync' + SisyfosResync = 'sisyfos_resync', + SisyfosGroupStudioMics = 'sisyfos_group_studio_mics' } export enum SharedOutputLayers { diff --git a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts index 79e74aea7..87cd90246 100644 --- a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts @@ -7,8 +7,8 @@ import { PieceLifespan, TSR } from '@tv2media/blueprints-integration' -import { ActionCutToCamera, ActionTakeWithTransition, literal } from 'tv2-common' -import { AdlibActionType, NoteType, SharedOutputLayers } from 'tv2-constants' +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 { AtemLLayer } from '../../tv2_afvd_studio/layers' @@ -25,6 +25,13 @@ const CURRENT_PART_ID = 'MOCK_PART_CURRENT' const CURRENT_PART_EXTERNAL_ID = `${CURRENT_PART_ID}_EXTERNAL` const NEXT_PART_ID = 'MOCK_PART_CURRENT' const NEXT_PART_EXTERNAL_ID = `${CURRENT_PART_ID}_EXTERNAL` +const SOURCE_DEFINITION_KAM_1: SourceDefinitionKam = { + sourceType: SourceType.KAM, + id: '1', + raw: 'Kam 1', + minusMic: false, + name: 'KAM 1' +} const currentPartMock: IBlueprintPartInstance = { _id: CURRENT_PART_ID, @@ -814,7 +821,7 @@ describe('Camera shortcuts on server', () => { literal({ type: AdlibActionType.CUT_TO_CAMERA, queue: false, - name: '1' + sourceDefinition: SOURCE_DEFINITION_KAM_1 }) ) @@ -857,7 +864,7 @@ describe('Camera shortcuts on server', () => { literal({ type: AdlibActionType.CUT_TO_CAMERA, queue: true, - name: '1' + sourceDefinition: SOURCE_DEFINITION_KAM_1 }) ) @@ -902,7 +909,7 @@ describe('Camera shortcuts on VO', () => { literal({ type: AdlibActionType.CUT_TO_CAMERA, queue: false, - name: '1' + sourceDefinition: SOURCE_DEFINITION_KAM_1 }) ) @@ -945,7 +952,7 @@ describe('Camera shortcuts on VO', () => { literal({ type: AdlibActionType.CUT_TO_CAMERA, queue: true, - name: '1' + sourceDefinition: SOURCE_DEFINITION_KAM_1 }) ) diff --git a/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts b/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts index 974739852..37d317676 100644 --- a/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/addScript.spec.ts @@ -9,7 +9,7 @@ describe('addScript', () => { externalId: '00000000001-0', type: PartType.Kam, sourceDefinition: { - sourceType: SourceType.Kam, + sourceType: SourceType.KAM, id: '2', raw: 'KAM 2', name: 'KAM 2', diff --git a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts index 536f5ae59..fff09412d 100644 --- a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts @@ -6,27 +6,13 @@ import { } from '@tv2media/blueprints-integration' import { INewsStory, literal, UnparsedCue } from 'tv2-common' import { SharedSourceLayers } from 'tv2-constants' -import { SegmentUserContext } from '../../__mocks__/context' -import { defaultShowStyleConfig, defaultStudioConfig } from '../../tv2_afvd_showstyle/__tests__/configs' -import { parseConfig as parseStudioConfig } from '../../tv2_afvd_studio/helpers/config' -import mappingsDefaults from '../../tv2_afvd_studio/migrations/mappings-defaults' +import { makeMockAFVDContext, SegmentUserContext } from '../../__mocks__/context' +import { SisyfosLLAyer } from '../../tv2_afvd_studio/layers' import { getSegment } from '../getSegment' -import { parseConfig as parseShowStyleConfig } from '../helpers/config' import { SourceLayer } from '../layers' const SEGMENT_EXTERNAL_ID = '00000000' -function makeMockContext(preventOverlay?: boolean) { - const mockContext = new SegmentUserContext('test', mappingsDefaults, parseStudioConfig, parseShowStyleConfig) - mockContext.studioConfig = - preventOverlay === undefined - ? defaultStudioConfig - : ({ ...defaultStudioConfig, PreventOverlayWithFull: preventOverlay } as any) - mockContext.showStyleConfig = defaultShowStyleConfig as any - - return mockContext -} - function makeIngestSegment(cues: UnparsedCue[], body: string) { return literal({ externalId: SEGMENT_EXTERNAL_ID, @@ -68,7 +54,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 = makeMockContext() + const context = makeMockAFVDContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -84,7 +70,7 @@ describe('AFVD Blueprint', () => { it('Accepts KAM CS3', async () => { const ingestSegment = makeIngestSegment([], `\r\nKam CS3\r\n`) - const context = makeMockContext() + const context = makeMockAFVDContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -111,7 +97,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

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

Some script

\r\n

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

Some script

\r\n

\r\n

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

Some script

\r\n

\r\n

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

Some script

\r\n

\r\n

\r\n

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

Some script

\r\n

\r\n

\r\n

\r\n` ) - const context = makeMockContext(false) + const context = makeMockAFVDContext({ PreventOverlayWithFull: false }) const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -346,7 +332,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 = makeMockContext() + const context = makeMockAFVDContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -392,7 +378,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 = makeMockContext() + const context = makeMockAFVDContext() 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) @@ -428,7 +414,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 = makeMockContext() + const context = makeMockAFVDContext() 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) @@ -463,7 +449,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

\r\nKam 2\r\n

\r\n` ) - const context = makeMockContext() + const context = makeMockAFVDContext() 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) @@ -505,7 +491,7 @@ describe('AFVD Blueprint', () => { ], `\r\nKam 1\r\n

Some script

\r\n

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

Some script

\r\n

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

Some script

\r\n

\r\n` ) - const context = makeMockContext() + const context = makeMockAFVDContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -616,7 +602,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 = makeMockContext() + const context = makeMockAFVDContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expect(result.segment.isHidden).toBe(false) @@ -649,7 +635,7 @@ describe('AFVD Blueprint', () => { ], `\r\n

Kam 1

\r\n

\r\n

Some script

\r\n

Kam 2

\r\n

\r\n` ) - const context = makeMockContext() + const context = makeMockAFVDContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after SS cue']) expect(result.segment.isHidden).toBe(false) @@ -682,7 +668,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 = makeMockContext() + const context = makeMockAFVDContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, ['No graphic found after SS cue']) expect(result.segment.isHidden).toBe(false) @@ -722,7 +708,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 = makeMockContext() + const context = makeMockAFVDContext() 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) @@ -752,7 +738,7 @@ describe('AFVD Blueprint', () => { ], `\r\n

KAM 1

\r\n

\r\n

\r\n

\r\n

Some script

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

\r\n

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

\r\n

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

\r\n

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

\r\n

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

***LIVE***

\r\n

\r\n

\r\n` ) - const context = makeMockContext() + const context = makeMockAFVDContext() const result = await getSegment(context, ingestSegment) - expectNotesToBe(context, ['No source entered for EKSTERN']) + + expectNotesToBe(context, ['EKSTERN source is not valid: "LIVE"']) expect(result.segment.isHidden).toBe(false) expect(result.parts).toHaveLength(1) expect(result.parts[0].part.invalid).toBe(true) @@ -846,7 +833,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 = makeMockContext() + const context = makeMockAFVDContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expectAllPartsToBeValid(result) @@ -862,7 +849,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 = makeMockContext() + const context = makeMockAFVDContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expectAllPartsToBeValid(result) @@ -881,7 +868,7 @@ describe('AFVD Blueprint', () => { [['EKSTERN=LIVE 1 EFFEKT 1']], '\r\n

***LIVE***

\r\n

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

***LIVE***

\r\n

\r\n' ) - const context = makeMockContext() + const context = makeMockAFVDContext() const result = await getSegment(context, ingestSegment) expectNotesToBe(context, []) expectAllPartsToBeValid(result) @@ -919,4 +906,114 @@ describe('AFVD Blueprint', () => { ]) expect(livePart1.pieces[0].name).toBe('MIX 10') }) + + 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 result = await getSegment(context, ingestSegment) + const livePart = result.parts[0] + const livePiece = livePart.pieces[0] + const studioMicsObject = livePiece.content.timelineObjects.find( + t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + ) + expect(studioMicsObject).toBeDefined() + }) + + 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 result = await getSegment(context, ingestSegment) + const livePart = result.parts[0] + const livePiece = livePart.pieces[0] + const studioMicsObject = livePiece.content.timelineObjects.find( + t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + ) + expect(studioMicsObject).toBeUndefined() + }) + + 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 result = await getSegment(context, ingestSegment) + const livePart = result.parts[0] + const livePiece = livePart.pieces[0] + const studioMicsObject = livePiece.content.timelineObjects.find( + t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + ) + expect(studioMicsObject).toBeDefined() + }) + + 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 result = await getSegment(context, ingestSegment) + const livePart = result.parts[0] + const livePiece = livePart.pieces[0] + const studioMicsObject = livePiece.content.timelineObjects.find( + t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + ) + expect(studioMicsObject).toBeUndefined() + }) + + 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 result = await getSegment(context, ingestSegment) + const livePart = result.parts[0] + const livePiece = livePart.pieces[0] + const studioMicsObject = livePiece.content.timelineObjects.find( + t => t.layer === SisyfosLLAyer.SisyfosGroupStudioMics + ) + expect(studioMicsObject).toBeUndefined() + }) }) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 041f9ffaa..104e0d721 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -131,7 +131,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint }, classes: ['adlib_deparent'] }), - ...GetSisyfosTimelineObjForReplay(config, info, vo, SisyfosLLAyer.SisyfosGroupStudioMics) + ...GetSisyfosTimelineObjForReplay(config, info, vo) ] } }) @@ -141,7 +141,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint function makeRemoteAdLibs(info: SourceInfo, rank: number): IBlueprintAdLibPiece[] { const res: IBlueprintAdLibPiece[] = [] - const eksternSisyfos = GetSisyfosTimelineObjForRemote(config, info, SisyfosLLAyer.SisyfosGroupStudioMics) + const eksternSisyfos = GetSisyfosTimelineObjForRemote(config, info) res.push({ externalId: 'live', name: `LIVE ${info.id}`, @@ -578,7 +578,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri name, box, sourceDefinition: { - sourceType: SourceType.EVS, + sourceType: SourceType.REPLAY, id: info.id, vo, raw: '', @@ -610,7 +610,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri type: AdlibActionType.CUT_SOURCE_TO_BOX, name: `SERVER`, box, - sourceDefinition: { sourceType: SourceType.Server } + sourceDefinition: { sourceType: SourceType.SERVER } }) blueprintActions.push( literal({ 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 84f00b25e..d6c1a59d6 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -45,7 +45,7 @@ const config = getConfig(makeMockContext()) const dummyPart = literal({ type: PartType.Kam, - sourceDefinition: { sourceType: SourceType.Kam, id: '1', raw: 'Kam 1', minusMic: false, name: 'KAM 1' }, + sourceDefinition: { sourceType: SourceType.KAM, id: '1', raw: 'Kam 1', minusMic: false, name: 'KAM 1' }, externalId: '0001', rawType: 'Kam 1', cues: [], 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 706aa1a33..a6bcd1e8b 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts @@ -33,7 +33,7 @@ function makeMockContext() { const CONFIG = getConfig(makeMockContext()) const MOCK_PART = literal({ type: PartType.Kam, - sourceDefinition: { sourceType: SourceType.Kam, id: '1', raw: 'Kam 1', minusMic: false, name: 'KAM 1' }, + sourceDefinition: { sourceType: SourceType.KAM, id: '1', raw: 'Kam 1', minusMic: false, name: 'KAM 1' }, externalId: '0001', rawType: 'Kam 1', cues: [], 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 9be9d2f18..f4b8745f0 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -42,7 +42,7 @@ mockContext.showStyleConfig = defaultShowStyleConfig as any const dummyPart = literal({ type: PartType.Kam, sourceDefinition: { - sourceType: SourceType.Kam, + sourceType: SourceType.KAM, id: '1', raw: 'Kam 1', minusMic: false, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts index 9718714f9..688847917 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts @@ -65,8 +65,7 @@ export async function EvaluateAdLib( ClipPending: CasparLLayer.CasparPlayerClipPending }, Sisyfos: { - ClipPending: SisyfosLLAyer.SisyfosSourceClipPending, - StudioMicsGroup: SisyfosLLAyer.SisyfosGroupStudioMics + ClipPending: SisyfosLLAyer.SisyfosSourceClipPending }, AtemLLayer: { MEPgm: AtemLLayer.AtemMEProgram diff --git a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts index 1ea331dc1..f986e38e3 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts @@ -6,7 +6,7 @@ import { ISegmentUserContext } from '@tv2media/blueprints-integration' import { CueDefinitionEkstern, EvaluateEksternBase, PartDefinition, TV2BlueprintConfig } from 'tv2-common' -import { AtemLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' +import { AtemLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' export function EvaluateEkstern( @@ -37,9 +37,6 @@ export function EvaluateEkstern( }, ATEM: { MEProgram: AtemLLayer.AtemMEProgram - }, - Sisyfos: { - StudioMics: SisyfosLLAyer.SisyfosGroupStudioMics } }, adlib, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts index c0670973e..5b5b79417 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicPilot.ts @@ -17,7 +17,7 @@ import { PilotGeneratorSettings, TV2BlueprintConfig } from 'tv2-common' -import { AtemLLayer, SisyfosLLAyer } from '../../../tv2_afvd_studio/layers' +import { AtemLLayer } from '../../../tv2_afvd_studio/layers' import { BlueprintConfig } from '../config' export const pilotGeneratorSettingsAFVD: PilotGeneratorSettings = { @@ -95,7 +95,7 @@ function makeStudioTimelineViz( }), // Assume DSK is off by default (config table) ...EnableDSK(config, 'FULL'), - ...GetSisyfosTimelineObjForFull(config, SisyfosLLAyer.SisyfosGroupStudioMics) + ...GetSisyfosTimelineObjForFull(config) ] } @@ -126,6 +126,6 @@ function makeStudioTimelineCaspar(config: BlueprintConfig, _context: IStudioUser } } }), - ...GetSisyfosTimelineObjForFull(config, SisyfosLLAyer.SisyfosGroupStudioMics) + ...GetSisyfosTimelineObjForFull(config) ] } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts index 1b7b8d8d5..d6e450c53 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts @@ -8,7 +8,7 @@ import { TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { CalculateTime, CueDefinitionRouting, FindSourceInfoByName, literal, TV2BlueprintConfig } from 'tv2-common' +import { CalculateTime, CueDefinitionRouting, findSourceInfo, literal, TV2BlueprintConfig } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import _ = require('underscore') import { AtemLLayer } from '../../../tv2_afvd_studio/layers' @@ -24,48 +24,49 @@ export function EvaluateCueRouting( parsedCue: CueDefinitionRouting ) { const time = (parsedCue.start ? CalculateTime(parsedCue.start) : 0) ?? 0 - if (parsedCue.INP1 !== undefined || parsedCue.INP !== undefined) { - const source = parsedCue.INP1 ?? parsedCue.INP - if (!source || !source.length) { - context.notifyUserWarning(`No input provided for viz engine aux`) - } else { - const sourceInfo = FindSourceInfoByName(config.sources, source) + const sourceDefinition = parsedCue.INP1 ?? parsedCue.INP + if (!sourceDefinition) { + context.notifyUserWarning(`No input provided for viz engine aux`) + return + } - if (!sourceInfo) { - context.notifyUserWarning(`Could not find source ${source}`) - } else { - pieces.push( - literal({ - externalId: partId, - enable: { - start: time - }, - name: source, - outputLayerId: SharedOutputLayers.AUX, - sourceLayerId: SourceLayer.VizFullIn1, - lifespan: PieceLifespan.WithinPart, - content: literal>({ - studioLabel: '', - switcherInput: sourceInfo.port, - timelineObjects: _.compact([ - literal({ - id: '', - enable: { start: 0 }, - priority: 100, - layer: AtemLLayer.AtemAuxVizOvlIn1, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: sourceInfo.port - } - } - }) - ]) - }) - }) - ) - } - } + const sourceInfo = findSourceInfo(config.sources, sourceDefinition) + const name = sourceDefinition.name || sourceDefinition.sourceType + if (!sourceInfo) { + context.notifyUserWarning(`Could not find source ${name}`) + return } + + pieces.push( + literal({ + externalId: partId, + enable: { + start: time + }, + name, + outputLayerId: SharedOutputLayers.AUX, + sourceLayerId: SourceLayer.VizFullIn1, + lifespan: PieceLifespan.WithinPart, + content: literal>({ + studioLabel: '', + switcherInput: sourceInfo.port, + timelineObjects: _.compact([ + literal({ + id: '', + enable: { start: 0 }, + priority: 100, + layer: AtemLLayer.AtemAuxVizOvlIn1, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.AUX, + aux: { + input: sourceInfo.port + } + } + }) + ]) + }) + }) + ) + } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts index 4cce5e9be..2b5908b11 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/telefon.ts @@ -41,11 +41,7 @@ export function EvaluateTelefon( const graphicPiece = pieces[graphicPieceIndex] if (graphicPiece && graphicPiece.content && graphicPiece.content.timelineObjects) { graphicPiece.content.timelineObjects.push( - ...GetSisyfosTimelineObjForTelefon( - config, - SisyfosLLAyer.SisyfosSourceTLF, - SisyfosLLAyer.SisyfosGroupStudioMics - ) + ...GetSisyfosTimelineObjForTelefon(config, SisyfosLLAyer.SisyfosSourceTLF) ) graphicPiece.name = `${parsedCue.source}` pieces[graphicPieceIndex] = graphicPiece diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index f9926843d..116564aa4 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -14,19 +14,18 @@ import { AddScript, CreatePartInvalid, EVSParentClass, - FindSourceInfo, + findSourceInfo, GetSisyfosTimelineObjForReplay, literal, PartDefinitionEVS, PartTime, PieceMetaData, SourceInfo, - SourceInfoType, TransitionFromString, TransitionSettings } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' -import { AtemLLayer, SisyfosLLAyer } from '../../tv2_afvd_studio/layers' +import { AtemLLayer } from '../../tv2_afvd_studio/layers' import { BlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' @@ -39,7 +38,7 @@ export async function CreatePartEVS( totalWords: number ): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) - const title = `${partDefinition.sourceDefinition.id} ${partDefinition.sourceDefinition.vo ?? ''}` + const title = partDefinition.sourceDefinition.name let part = literal({ externalId: partDefinition.externalId, @@ -55,7 +54,7 @@ export async function CreatePartEVS( part = { ...part, ...CreateEffektForpart(context, config, partDefinition, pieces) } - const sourceInfoReplay = FindSourceInfo(config.sources, SourceInfoType.REPLAY, partDefinition.rawType) + const sourceInfoReplay = findSourceInfo(config.sources, partDefinition.sourceDefinition) if (sourceInfoReplay === undefined) { return CreatePartInvalid(partDefinition) } @@ -137,12 +136,7 @@ function makeContentEVS( }, classes: [EVSParentClass('studio0', partDefinition.sourceDefinition.id)] }), - ...GetSisyfosTimelineObjForReplay( - config, - sourceInfoReplay, - !!partDefinition.sourceDefinition.vo, - SisyfosLLAyer.SisyfosGroupStudioMics - ) + ...GetSisyfosTimelineObjForReplay(config, sourceInfoReplay, partDefinition.sourceDefinition.vo) ]) } } diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index 606f73e23..5b58afd26 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -18,7 +18,7 @@ import { CreatePartInvalid, CreatePartKamBase, FindDSKJingle, - FindSourceInfoByDefinition, + findSourceInfo, GetSisyfosTimelineObjForCamera, literal, PartDefinitionKam, @@ -28,7 +28,7 @@ import { TransitionSettings } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' -import { AtemLLayer, SisyfosLLAyer } from '../../tv2_afvd_studio/layers' +import { AtemLLayer } from '../../tv2_afvd_studio/layers' import { BlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' @@ -96,7 +96,7 @@ export async function CreatePartKam( ) part.expectedDuration = TimeFromINewsField(partDefinition.fields.totalTime) * 1000 } else { - const sourceInfoCam = FindSourceInfoByDefinition(config.sources, partDefinition.sourceDefinition) + const sourceInfoCam = findSourceInfo(config.sources, partDefinition.sourceDefinition) if (sourceInfoCam === undefined) { context.notifyUserWarning(`${partDefinition.rawType} does not exist in this studio`) return CreatePartInvalid(partDefinition) @@ -145,12 +145,7 @@ export async function CreatePartKam( ? { classes: [CameraParentClass('studio0', partDefinition.sourceDefinition.id)] } : {}) }), - ...GetSisyfosTimelineObjForCamera( - config, - sourceInfoCam, - partDefinition.sourceDefinition.minusMic, - SisyfosLLAyer.SisyfosGroupStudioMics - ) + ...GetSisyfosTimelineObjForCamera(config, sourceInfoCam, partDefinition.sourceDefinition.minusMic) ]) } }) diff --git a/src/tv2_afvd_showstyle/parts/server.ts b/src/tv2_afvd_showstyle/parts/server.ts index 4e2f313ae..729361b38 100644 --- a/src/tv2_afvd_showstyle/parts/server.ts +++ b/src/tv2_afvd_showstyle/parts/server.ts @@ -29,8 +29,7 @@ export async function CreatePartServer( ClipPending: CasparLLayer.CasparPlayerClipPending }, Sisyfos: { - ClipPending: SisyfosLLAyer.SisyfosSourceClipPending, - StudioMicsGroup: SisyfosLLAyer.SisyfosGroupStudioMics + ClipPending: SisyfosLLAyer.SisyfosSourceClipPending }, ATEM: {} }) diff --git a/src/tv2_afvd_studio/__tests__/graphics.spec.ts b/src/tv2_afvd_studio/__tests__/graphics.spec.ts index c16c52a83..fab91a42a 100644 --- a/src/tv2_afvd_studio/__tests__/graphics.spec.ts +++ b/src/tv2_afvd_studio/__tests__/graphics.spec.ts @@ -9,9 +9,10 @@ import { GraphicInternal, GraphicPilot, literal, - PartDefinition + PartDefinition, + RemoteType } from 'tv2-common' -import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayers } from 'tv2-constants' +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' @@ -153,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(20) + expect(timeline).toHaveLength(5) const vizObj = timeline.find( t => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT @@ -328,7 +329,7 @@ describe('Graphics', () => { expect(piece.lifespan).toBe(PieceLifespan.WithinPart) const content = piece.content! const timeline = content.timelineObjects as TSR.TSRTimelineObj[] - expect(timeline).toHaveLength(20) + expect(timeline).toHaveLength(5) const vizObj = timeline.find( t => t.content.deviceType === TSR.DeviceType.VIZMSE && t.content.type === TSR.TimelineContentTypeVizMSE.ELEMENT_PILOT @@ -357,7 +358,7 @@ describe('Graphics', () => { routing: { type: CueType.Routing, target: 'TLF', - INP1: 'LIVE 1', + INP1: { sourceType: SourceType.REMOTE, id: '1', name: 'LIVE 1', raw: 'LIVE 1', remoteType: RemoteType.LIVE }, iNewsCommand: '' }, graphic: { diff --git a/src/tv2_afvd_studio/layers.ts b/src/tv2_afvd_studio/layers.ts index 55a5b00cf..da63cf864 100644 --- a/src/tv2_afvd_studio/layers.ts +++ b/src/tv2_afvd_studio/layers.ts @@ -89,9 +89,8 @@ export const GraphicLLayer = { export type GraphicLLayer = AFVDGraphicLLayer | SharedGraphicLLayer -enum AFVDSisyfosLLAyer { +enum AFVDSisyfosLLayer { SisyfosConfig = 'sisyfos_config', - SisyfosGroupStudioMics = 'sisyfos_group_studio_mics', SisyfosPersistedLevels = 'sisyfos_persisted_levels', SisyfosSourceClipPending = 'sisyfos_source_clip_pending', SisyfosSourceJingle = 'sisyfos_source_jingle', @@ -129,7 +128,7 @@ enum AFVDSisyfosLLAyer { // tslint:disable-next-line: variable-name export const SisyfosLLAyer = { ...SharedSisyfosLLayer, - ...AFVDSisyfosLLAyer + ...AFVDSisyfosLLayer } -export type SisyfosLLAyer = SharedSisyfosLLayer | AFVDSisyfosLLAyer +export type SisyfosLLAyer = SharedSisyfosLLayer | AFVDSisyfosLLayer diff --git a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts index 5069ebbc0..a009709c4 100644 --- a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts @@ -16,8 +16,9 @@ import { ActionTakeWithTransition, literal, PartDefinitionUnknown, - SourceDefinitionEkstern, - SourceDefinitionKam + RemoteType, + SourceDefinitionKam, + SourceDefinitionRemote } from 'tv2-common' import { AdlibActionType, CueType, NoteType, PartType, SharedSourceLayers, SourceType } from 'tv2-constants' import { ActionExecutionContext } from '../../__mocks__/context' @@ -40,15 +41,15 @@ const VO_DURATION_A = 20000 const FULL_KEEPALIVE = 1000 const SOURCE_DEFINITION_KAM_1: SourceDefinitionKam = { - sourceType: SourceType.Kam, + sourceType: SourceType.KAM, id: '1', raw: 'KAM 1', minusMic: false, name: 'KAM 1' } -const SOURCE_DEFINITION_LIVE_2: SourceDefinitionEkstern = { +const SOURCE_DEFINITION_LIVE_2: SourceDefinitionRemote = { sourceType: SourceType.REMOTE, - variant: 'LIVE', + remoteType: RemoteType.LIVE, id: '1', name: 'LIVE 1', raw: 'Live 1' diff --git a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts index 49e7cc93e..b89fd2b86 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts @@ -68,8 +68,7 @@ export async function OfftubeEvaluateAdLib( ClipPending: OfftubeCasparLLayer.CasparPlayerClipPending }, Sisyfos: { - ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending, - StudioMicsGroup: OfftubeSisyfosLLayer.SisyfosGroupStudioMics + ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending }, AtemLLayer: { MEPgm: OfftubeAtemLLayer.AtemMEClean diff --git a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts index 46dae6ef0..abcd29a45 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts @@ -6,7 +6,7 @@ import { ISegmentUserContext } from '@tv2media/blueprints-integration' import { CueDefinitionEkstern, EvaluateEksternBase, PartDefinition } from 'tv2-common' -import { OfftubeAtemLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' +import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' import { OfftubeSourceLayer } from '../layers' @@ -38,9 +38,6 @@ export function OfftubeEvaluateEkstern( }, ATEM: { MEProgram: OfftubeAtemLLayer.AtemMEClean - }, - Sisyfos: { - StudioMics: OfftubeSisyfosLLayer.SisyfosGroupStudioMics } }, adlib, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts index 761b05c13..65e9b0a84 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphics.ts @@ -18,7 +18,7 @@ import { PartDefinition, PilotGeneratorSettings } from 'tv2-common' -import { OfftubeAtemLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' +import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' export const pilotGeneratorSettingsOfftube: PilotGeneratorSettings = { @@ -91,6 +91,6 @@ function createPilotTimeline( } } }), - ...GetSisyfosTimelineObjForFull(config, OfftubeSisyfosLLayer.SisyfosGroupStudioMics) + ...GetSisyfosTimelineObjForFull(config) ] } diff --git a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts index 191c0e50d..124c9bd88 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts @@ -7,8 +7,8 @@ import { TSR, WithTimeline } from '@tv2media/blueprints-integration' -import { CueDefinitionPgmClean, FindSourceInfoByName, literal, SourceInfo } from 'tv2-common' -import { SharedOutputLayers } from 'tv2-constants' +import { CueDefinitionPgmClean, 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 { OfftubeSourceLayer } from '../layers' @@ -21,21 +21,23 @@ export function OfftubeEvaluatePgmClean( parsedCue: CueDefinitionPgmClean ) { let sourceInfo: SourceInfo | undefined - if (parsedCue.source.match(/PGM/i)) { + if (parsedCue.sourceDefinition.sourceType === SourceType.PGM) { return } - sourceInfo = FindSourceInfoByName(config.sources, parsedCue.source) + sourceInfo = findSourceInfo(config.sources, parsedCue.sourceDefinition) + + const name = parsedCue.sourceDefinition.name || parsedCue.sourceDefinition.sourceType if (!sourceInfo) { - context.notifyUserWarning(`Invalid source for clean output: ${parsedCue.source}`) + context.notifyUserWarning(`Invalid source for clean output: ${name}`) return } pieces.push( literal({ externalId: partId, - name: parsedCue.source, + name, enable: { start: 0 }, diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index f6fdcff64..6ef998bdc 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -35,8 +35,8 @@ import { GetTagForLive, GetTransitionAdLibActions, literal, - SourceDefinitionEkstern, SourceDefinitionKam, + SourceDefinitionRemote, SourceInfo, SourceInfoToSourceDefinition, SourceInfoType, @@ -277,15 +277,15 @@ function getGlobalAdlibActionsOfftube( outputLayerId: SharedOutputLayers.PGM, content: {}, tags: queue ? [AdlibTags.OFFTUBE_SET_CAM_NEXT, AdlibTags.ADLIB_QUEUE_NEXT] : [AdlibTags.ADLIB_CUT_DIRECT], - currentPieceTags: [GetTagForKam(info.id)], - nextPieceTags: [GetTagForKam(info.id)] + currentPieceTags: [GetTagForKam(sourceDefinition)], + nextPieceTags: [GetTagForKam(sourceDefinition)] } }) ) } function makeRemoteAction(sourceInfo: SourceInfo, rank: number) { - const sourceDefinition = SourceInfoToSourceDefinition(sourceInfo) as SourceDefinitionEkstern + const sourceDefinition = SourceInfoToSourceDefinition(sourceInfo) as SourceDefinitionRemote const userData = literal({ type: AdlibActionType.CUT_TO_REMOTE, sourceDefinition @@ -349,7 +349,7 @@ function getGlobalAdlibActionsOfftube( type: AdlibActionType.CUT_SOURCE_TO_BOX, name: `SERVER`, box, - sourceDefinition: { sourceType: SourceType.Server } + sourceDefinition: { sourceType: SourceType.SERVER } }) blueprintActions.push( literal({ diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index 0fcf92b9e..e38510e44 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -18,18 +18,17 @@ import { CreatePartInvalid, CreatePartKamBase, FindDSKJingle, - FindSourceInfo, + findSourceInfo, GetSisyfosTimelineObjForCamera, GetTagForKam, literal, PartDefinitionKam, SisyfosPersistMetaData, - SourceInfoType, TransitionFromString, TransitionSettings } from 'tv2-common' import { SharedOutputLayers, TallyTags } from 'tv2-constants' -import { OfftubeAtemLLayer, OfftubeSisyfosLLayer } from '../../tv2_offtube_studio/layers' +import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' @@ -53,7 +52,7 @@ export async function OfftubeCreatePartKam( const jingleDSK = FindDSKJingle(config) - if (partDefinition.rawType.match(/kam cs ?3/i)) { + if (/cs ?3/i.test(partDefinition.sourceDefinition.id)) { pieces.push( literal({ externalId: partDefinition.externalId, @@ -62,7 +61,7 @@ export async function OfftubeCreatePartKam( outputLayerId: SharedOutputLayers.PGM, sourceLayerId: OfftubeSourceLayer.PgmJingle, lifespan: PieceLifespan.WithinPart, - tags: [GetTagForKam('JINGLE'), TallyTags.JINGLE_IS_LIVE], + tags: [GetTagForKam(partDefinition.sourceDefinition), TallyTags.JINGLE_IS_LIVE], content: literal>({ ignoreMediaObjectStatus: true, fileName: '', @@ -92,7 +91,7 @@ export async function OfftubeCreatePartKam( }) ) } else { - const sourceInfoCam = FindSourceInfo(config.sources, SourceInfoType.KAM, partDefinition.rawType) + const sourceInfoCam = findSourceInfo(config.sources, partDefinition.sourceDefinition) if (sourceInfoCam === undefined) { return CreatePartInvalid(partDefinition) } @@ -114,7 +113,7 @@ export async function OfftubeCreatePartKam( acceptPersistAudio: sourceInfoCam.acceptPersistAudio }) }, - tags: [GetTagForKam(sourceInfoCam.id)], + tags: [GetTagForKam(partDefinition.sourceDefinition)], content: { studioLabel: '', switcherInput: atemInput, @@ -142,12 +141,7 @@ export async function OfftubeCreatePartKam( : {}) }), - ...GetSisyfosTimelineObjForCamera( - config, - sourceInfoCam, - partDefinition.sourceDefinition.minusMic, - OfftubeSisyfosLLayer.SisyfosGroupStudioMics - ) + ...GetSisyfosTimelineObjForCamera(config, sourceInfoCam, partDefinition.sourceDefinition.minusMic) ]) } }) diff --git a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts index 71a077b0f..9beff33af 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeServer.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeServer.ts @@ -30,8 +30,7 @@ export async function OfftubeCreatePartServer( ClipPending: OfftubeCasparLLayer.CasparPlayerClipPending }, Sisyfos: { - ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending, - StudioMicsGroup: OfftubeSisyfosLLayer.SisyfosGroupStudioMics + ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending }, ATEM: { ServerLookaheadAux: OfftubeAtemLLayer.AtemAuxServerLookahead @@ -74,8 +73,7 @@ export async function OfftubeCreatePartServer( ClipPending: OfftubeCasparLLayer.CasparPlayerClipPending }, Sisyfos: { - ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending, - StudioMicsGroup: OfftubeSisyfosLLayer.SisyfosGroupStudioMics + ClipPending: OfftubeSisyfosLLayer.SisyfosSourceClipPending }, AtemLLayer: { MEPgm: OfftubeAtemLLayer.AtemMEClean, diff --git a/src/tv2_offtube_studio/layers.ts b/src/tv2_offtube_studio/layers.ts index 6167c0656..96797bb71 100644 --- a/src/tv2_offtube_studio/layers.ts +++ b/src/tv2_offtube_studio/layers.ts @@ -31,7 +31,6 @@ export enum OfftubeAbstractLLayer { enum SisyfosLLayer { SisyfosConfig = 'sisyfos_config', - SisyfosGroupStudioMics = 'sisyfos_group_studio_mics', SisyfosGroupServer = 'sisyfos_group_server', SisyfosPersistedLevels = 'sisyfos_persisted_levels', SisyfosSourceClipPending = 'sisyfos_source_clip_pending', From 9225b2b003a3258efe7efc449fe9aea270848074 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 26 Jul 2022 12:57:23 +0200 Subject: [PATCH 158/184] fix: SOF-1022 missing externalId on pieces enables `strictPropertyInitialization` compiler option to avoid such bugs in the future --- config/tsconfig.strict.json | 3 ++- src/__mocks__/context.ts | 25 ++++++++++++++----- src/tv2-common/actions/context.ts | 2 +- .../helpers/graphics/pilot/index.ts | 1 + .../__tests__/migrationContext.mock.ts | 6 +++-- 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/config/tsconfig.strict.json b/config/tsconfig.strict.json index 7d976bd40..05ff016e9 100755 --- a/config/tsconfig.strict.json +++ b/config/tsconfig.strict.json @@ -7,6 +7,7 @@ "noImplicitReturns": true, "noImplicitThis": true, "noUnusedLocals": true, - "noUnusedParameters": true + "noUnusedParameters": true, + "strictPropertyInitialization": true } } diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index 36f69d7eb..1e79bd27f 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -27,6 +27,7 @@ import { OmitId, PackageInfo, PieceLifespan, + PlaylistTimingType, Time } from '@tv2media/blueprints-integration' import { literal } from 'tv2-common' @@ -121,7 +122,7 @@ 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 + public studioId: string = 'studio0' public studioConfig: { [key: string]: ConfigItemValue } = {} public showStyleConfig: { [key: string]: ConfigItemValue } = {} @@ -217,7 +218,7 @@ 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 + public readonly rundownId: string = 'rundown0' public readonly rundown: Readonly constructor( @@ -230,6 +231,16 @@ export class RundownContext extends ShowStyleContext implements IRundownContext partId?: string ) { super(contextName, mappingsDefaults, parseStudioConfig, parseShowStyleConfig, rundownId, segmentId, partId) + this.rundownId = rundownId ?? this.rundownId + this.rundown = { + _id: this.rundownId, + externalId: this.rundownId, + name: this.rundownId, + timing: { + type: PlaylistTimingType.None + }, + showStyleVariantId: 'variant0' + } } } @@ -300,7 +311,7 @@ export class SyncIngestUpdateToPartInstanceContext extends RundownUserContext mappingsDefaults: BlueprintMappings, parseStudioConfig: (context: ICommonContext, rawConfig: IBlueprintConfig) => any, parseShowStyleConfig: (context: ICommonContext, config: IBlueprintConfig) => any, - rundownId?: string, + rundownId: string, segmentId?: string, partId?: string ) { @@ -397,9 +408,6 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct public takeAfterExecute: boolean = false - /** Get the mappings for the studio */ - public getStudioMappings: () => Readonly - constructor( contextName: string, mappingsDefaults: BlueprintMappings, @@ -421,6 +429,11 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct this.nextPieceInstances = nextPieceInstances } + /** Get the mappings for the studio */ + public getStudioMappings = () => { + throw new Error(`Function not implemented in mock: 'getStudioMappings'`) + } + /** Get a PartInstance which can be modified */ public async getPartInstance(part: 'current' | 'next'): Promise { if (part === 'current') { diff --git a/src/tv2-common/actions/context.ts b/src/tv2-common/actions/context.ts index bc647e4a6..21e2da47f 100644 --- a/src/tv2-common/actions/context.ts +++ b/src/tv2-common/actions/context.ts @@ -20,7 +20,7 @@ export interface ITV2ActionExecutionContext extends IActionExecutionContext { class TV2ActionExecutionContext implements ITV2ActionExecutionContext { public studioId: string - public isTV2Context: true + public isTV2Context: true = true private coreContext: IActionExecutionContext diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index 18884c8cb..99eb9f7ea 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -105,6 +105,7 @@ export class PilotGraphicGenerator { this.context = graphicProps.context this.engine = graphicProps.engine this.parsedCue = graphicProps.parsedCue + this.partId = graphicProps.partId this.settings = graphicProps.settings this.adlib = graphicProps.adlib this.segmentExternalId = graphicProps.segmentExternalId diff --git a/src/tv2-common/migrations/__tests__/migrationContext.mock.ts b/src/tv2-common/migrations/__tests__/migrationContext.mock.ts index ddc7746ba..252686982 100644 --- a/src/tv2-common/migrations/__tests__/migrationContext.mock.ts +++ b/src/tv2-common/migrations/__tests__/migrationContext.mock.ts @@ -10,9 +10,8 @@ import { } from '@tv2media/blueprints-integration' export class MockShowstyleMigrationContext implements MigrationContextShowStyle { - public variants: IBlueprintShowStyleVariant[] + public variants: IBlueprintShowStyleVariant[] = [] public configs: Map = new Map() - public getTriggeredActionId: (triggeredActionId: string) => string public getAllVariants(): IBlueprintShowStyleVariant[] { return this.variants @@ -97,4 +96,7 @@ export class MockShowstyleMigrationContext implements MigrationContextShowStyle public removeTriggeredAction(triggeredActionsId: string): void { throw new Error(`Function not implemented in mock: 'removeTriggeredAction' args: ${triggeredActionsId}`) } + public getTriggeredActionId(triggeredActionId: string): string { + throw new Error(`Function not implemented in mock: 'getTriggeredActionId' args: ${triggeredActionId}`) + } } From 0cec7b9da40745d24c6d4be7d4b8d298c5f1b332 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 27 Jul 2022 08:50:40 +0200 Subject: [PATCH 159/184] fix: SOF-979 EVS adlib name --- src/tv2-common/helpers/adLibNames.ts | 12 ++++++------ src/tv2-common/hotkeys/local.ts | 6 +++--- src/tv2_afvd_showstyle/getRundown.ts | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/tv2-common/helpers/adLibNames.ts b/src/tv2-common/helpers/adLibNames.ts index 875a361d0..dd6e89624 100644 --- a/src/tv2-common/helpers/adLibNames.ts +++ b/src/tv2-common/helpers/adLibNames.ts @@ -1,20 +1,20 @@ -export function localSourceFullAudioName(source: string) { +export function replaySourceFullAudioName(source: string) { if (/EPSIO/i.test(source)) { return source } - return `EVS ${source} 100%` + return `${source} 100%` } -export function localSourceVoAudioName(source: string) { +export function replaySourceVoAudioName(source: string) { if (/EPSIO/i.test(source)) { return source } - return `EVS ${source} VO` + return `${source} VO` } -export function localSourceName(source: string, vo: boolean) { +export function replaySourceName(source: string, vo: boolean) { if (/EPSIO/i.test(source)) { return source } - return vo ? localSourceVoAudioName(source) : localSourceFullAudioName(source) + return vo ? replaySourceVoAudioName(source) : replaySourceFullAudioName(source) } diff --git a/src/tv2-common/hotkeys/local.ts b/src/tv2-common/hotkeys/local.ts index 9167df3cf..48e0e507c 100644 --- a/src/tv2-common/hotkeys/local.ts +++ b/src/tv2-common/hotkeys/local.ts @@ -1,6 +1,6 @@ import { IBlueprintTriggeredActions } from '@tv2media/blueprints-integration' import { AdlibTags } from 'tv2-constants' -import { localSourceFullAudioName, localSourceVoAudioName } from '../helpers' +import { replaySourceFullAudioName, replaySourceVoAudioName } from '../helpers' import { MakeStudioSourceHotkeys, SourceHotkeyTriggers } from './helpers' export interface LocalSourceHotkeyAssignments { @@ -29,7 +29,7 @@ export function MakeLocalSourceHotkeys( localSources, assignemnts.fullAudio, getNextRank, - localSourceFullAudioName, + replaySourceFullAudioName, localSourceFullAudioHotkeyId, [AdlibTags.ADLIB_FULL_AUDIO_LEVEL] ) @@ -40,7 +40,7 @@ export function MakeLocalSourceHotkeys( localSources, assignemnts.voAudio, getNextRank, - localSourceVoAudioName, + replaySourceVoAudioName, localSourceVoAudioHotkeyId, [AdlibTags.ADLIB_VO_AUDIO_LEVEL] ) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index ba4182052..cf8c8a14e 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -34,7 +34,7 @@ import { GetSisyfosTimelineObjForReplay, GetTransitionAdLibActions, literal, - localSourceName, + replaySourceName, PieceMetaData, SisyfosPersistMetaData, SourceDefinitionKam, @@ -99,7 +99,7 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint const res: IBlueprintAdLibPiece[] = [] res.push({ externalId: 'delayed', - name: localSourceName(info.id.replace(/R/i, ''), vo), + name: replaySourceName(info.id, vo), _rank: rank, sourceLayerId: SourceLayer.PgmLocal, outputLayerId: SharedOutputLayers.PGM, @@ -572,7 +572,7 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri function makeAdlibBoxesActionsReplay(info: SourceInfo, rank: number, vo: boolean) { for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { - const name = localSourceName(info.id, vo) + const name = replaySourceName(info.id, vo) const userData = literal({ type: AdlibActionType.CUT_SOURCE_TO_BOX, name, From 1a72e7ae478e739148ea9f45a9808e749cab2c54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Mon, 1 Aug 2022 14:07:40 +0200 Subject: [PATCH 160/184] chore:SOF-985 Minor import optimization --- src/tv2_afvd_showstyle/getRundown.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index cf8c8a14e..687180744 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -34,8 +34,8 @@ import { GetSisyfosTimelineObjForReplay, GetTransitionAdLibActions, literal, - replaySourceName, PieceMetaData, + replaySourceName, SisyfosPersistMetaData, SourceDefinitionKam, SourceInfo, From 2a69391b9caefbf57499e0060e7670beba7346da Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 2 Aug 2022 10:20:05 +0200 Subject: [PATCH 161/184] fix: SOF-767 temporarily disable Server Resume --- src/tv2-common/actions/executeAction.ts | 1 + src/tv2-common/pieces/adlibServer.ts | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index b8a88e8e3..de9e85bfd 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -423,6 +423,7 @@ async function executeActionSelectServerClip< triggerMode?: ServerSelectMode, sessionToContinue?: string ) { + triggerMode = ServerSelectMode.RESET /** @todo: remove for Server Resume */ const file = userData.file const partDefinition = userData.partDefinition const config = settings.getConfig(context) diff --git a/src/tv2-common/pieces/adlibServer.ts b/src/tv2-common/pieces/adlibServer.ts index cbc0f14fb..1e704c1d1 100644 --- a/src/tv2-common/pieces/adlibServer.ts +++ b/src/tv2-common/pieces/adlibServer.ts @@ -12,7 +12,7 @@ import { TV2StudioConfigBase } from 'tv2-common' import { AdlibActionType, AdlibTags, SharedOutputLayers } from 'tv2-constants' -import { getServerAdLibTriggerModes, t } from '../helpers' +import { t } from '../helpers' export interface AdlibServerOfftubeOptions { /** By passing in this object, you're creating a server according to the OFFTUBE showstyle. */ @@ -68,7 +68,7 @@ export async function CreateAdlibServer< currentPieceTags: [GetTagForServer(partDefinition.segmentExternalId, file, !!voLayer)], nextPieceTags: [GetTagForServerNext(partDefinition.segmentExternalId, file, !!voLayer)], uniquenessId: `${voLayer ? 'vo' : 'server'}_${partDefinition.storyName}_${file}` - }, - triggerModes: getServerAdLibTriggerModes() + } + // triggerModes: getServerAdLibTriggerModes() /** @todo: uncomment for Server Resume */ }) } From 416919bc3709975cb2175a77f860543829d852a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Wed, 3 Aug 2022 09:49:56 +0200 Subject: [PATCH 162/184] fix: added regionId to shelf-layouts. --- shelf-layouts/List.json | 3 ++- shelf-layouts/Streamdeck.json | 3 ++- shelf-layouts/dve controls.json | 3 ++- shelf-layouts/inspect all adlibs.json | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/shelf-layouts/List.json b/shelf-layouts/List.json index 2eb6a5fda..cf6fbfdc0 100755 --- a/shelf-layouts/List.json +++ b/shelf-layouts/List.json @@ -3,5 +3,6 @@ "name": "List", "showStyleBaseId": "show0", "filters": [], - "type": "dashboard_layout" + "type": "dashboard_layout", + "regionId": "shelf_layouts" } \ No newline at end of file diff --git a/shelf-layouts/Streamdeck.json b/shelf-layouts/Streamdeck.json index 882a5680d..e72309736 100755 --- a/shelf-layouts/Streamdeck.json +++ b/shelf-layouts/Streamdeck.json @@ -46,5 +46,6 @@ ] } ], - "type": "dashboard_layout" + "type": "dashboard_layout", + "regionId": "shelf_layouts" } \ No newline at end of file diff --git a/shelf-layouts/dve controls.json b/shelf-layouts/dve controls.json index df8cd324c..6f8a2b6f2 100755 --- a/shelf-layouts/dve controls.json +++ b/shelf-layouts/dve controls.json @@ -49,5 +49,6 @@ "y": 23 } ], - "type": "dashboard_layout" + "type": "dashboard_layout", + "regionId": "shelf_layouts" } \ No newline at end of file diff --git a/shelf-layouts/inspect all adlibs.json b/shelf-layouts/inspect all adlibs.json index 176901acd..681d6847f 100755 --- a/shelf-layouts/inspect all adlibs.json +++ b/shelf-layouts/inspect all adlibs.json @@ -21,5 +21,6 @@ "height": -1 } ], - "type": "dashboard_layout" + "type": "dashboard_layout", + "regionId": "shelf_layouts" } \ No newline at end of file From a0d6cef081b3b5569eec1ba7e70ea949f4e87796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Wed, 3 Aug 2022 09:54:00 +0200 Subject: [PATCH 163/184] fix: Changed EPSIO atem channel to correct. --- src/tv2_afvd_studio/config-manifests.ts | 2 +- src/tv2_afvd_studio/migrations/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index a8464133a..710b48bc9 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -214,7 +214,7 @@ export const manifestAFVDSourcesReplay = MakeConfigForSources('Replay', 'Replay' { _id: '', SourceName: 'EPSIO', - AtemSource: 30, + AtemSource: 25, SisyfosLayers: [SisyfosLLAyer.SisyfosSourceEpsio], StudioMics: true } diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index fd70d281f..5396ce917 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[] = literal Date: Wed, 3 Aug 2022 13:39:10 +0200 Subject: [PATCH 164/184] chore: SOF-1001 update versionIntegration to 42.0.0 --- 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 fb3d4ac28..356e5a979 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -28,7 +28,7 @@ module.exports = env => { // versionIntegration = versionIntegration.replace(/[^\d.]/g, '') || '0.0.0' versionTSRTypes = '1.3.0' - versionIntegration = '1.37.0' + versionIntegration = '42.0.0' const entrypoints = env.bundle ? GetEntrypointsForBundle(env.bundle) : BlueprintEntrypoints From dfc6ad7e0e362837724a16a3d94aaafc4aa4ddbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Wed, 3 Aug 2022 14:42:46 +0200 Subject: [PATCH 165/184] fix: SOF-1054 Update placement of black box in header --- shelf-layouts/Rundown_Header_Layout.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shelf-layouts/Rundown_Header_Layout.json b/shelf-layouts/Rundown_Header_Layout.json index 89e4cd5c7..e09265569 100644 --- a/shelf-layouts/Rundown_Header_Layout.json +++ b/shelf-layouts/Rundown_Header_Layout.json @@ -192,8 +192,8 @@ "iconColor": "#000000", "x": 37, "width": 27, - "height": 1, - "y": -1.1, + "height": 1.1, + "y": 0, "xUnit": "%", "widthUnit": "%" }, From b956bf76d24611d22f852b3abf2caa8131ed6843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Thu, 4 Aug 2022 14:16:41 +0200 Subject: [PATCH 166/184] fix: SOF-1056 migrations now prefix EVS sources with EVS --- src/tv2-common/migrations/index.ts | 34 ++++++++++++++++++++ src/tv2_afvd_showstyle/migrations/hotkeys.ts | 4 +-- src/tv2_afvd_studio/migrations/index.ts | 4 +++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index 4651c444b..22af3c89d 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -332,3 +332,37 @@ export function StripFolderFromShowStyleConfig( } }) } + +export function PrefixEvsWithEvs( + versionStr: string, + studio: string, + configId: string, + evsSourceNumber: string +): MigrationStepStudio { + return literal({ + id: `${versionStr}.prefixEvs${evsSourceNumber}WithEvs.${studio}`, + version: '1.7.4', + canBeRunAutomatically: true, + validate: (context: MigrationContextStudio) => { + const config = (context.getConfig(configId) as unknown) as TableConfigItemSourceMappingWithSisyfos[] + + if (!config || config.find(value => value.SourceName === `EVS ${evsSourceNumber}`) !== undefined) { + return false + } + + 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) + if (index === -1) { + return + } + const evsSource = config[index] + + evsSource.SourceName = `EVS ${evsSource.SourceName}` + config[index] = evsSource + context.setConfig(configId, (config as unknown) as ConfigItemValue) + } + }) +} diff --git a/src/tv2_afvd_showstyle/migrations/hotkeys.ts b/src/tv2_afvd_showstyle/migrations/hotkeys.ts index e97083b60..979843c4b 100644 --- a/src/tv2_afvd_showstyle/migrations/hotkeys.ts +++ b/src/tv2_afvd_showstyle/migrations/hotkeys.ts @@ -26,13 +26,13 @@ export function GetDefaultStudioSourcesForAFVD(context: MigrationContextShowStyl 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 local = manifestAFVDSourcesReplay.defaultVal.map(source => source.SourceName) as string[] + const replay = manifestAFVDSourcesReplay.defaultVal.map(source => source.SourceName) as string[] return { camera, remote, feed, - local, + local: replay, dveLayouts } } diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index fd70d281f..eb9e98926 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -5,6 +5,7 @@ import { literal, MoveClipSourcePath, MoveSourcesToTable, + PrefixEvsWithEvs, RemoveConfig, RenameStudioConfig, SetConfigTo, @@ -192,6 +193,9 @@ export const studioMigrations: MigrationStepStudio[] = literal Date: Thu, 4 Aug 2022 14:20:14 +0200 Subject: [PATCH 167/184] chore: SOF-1056 No longer hardcode the version of the migration --- src/tv2-common/migrations/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index 22af3c89d..c74ecaa72 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -341,7 +341,7 @@ export function PrefixEvsWithEvs( ): MigrationStepStudio { return literal({ id: `${versionStr}.prefixEvs${evsSourceNumber}WithEvs.${studio}`, - version: '1.7.4', + version: versionStr, canBeRunAutomatically: true, validate: (context: MigrationContextStudio) => { const config = (context.getConfig(configId) as unknown) as TableConfigItemSourceMappingWithSisyfos[] From a4481aafd62697826071feeaa0f11286a7e4ad7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Fri, 5 Aug 2022 08:27:33 +0200 Subject: [PATCH 168/184] fix: SOF-1057 Creates cut-to-dve-box addlibs for EVS X 100 again --- src/tv2_afvd_showstyle/getRundown.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 687180744..3878b9961 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -709,11 +709,12 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri makeAdlibBoxesActions(o, globalRank++) }) - config.sources.replays - .slice(0, 10) // the first x remote to create INP1/2/3 live-adlibs from - .forEach(o => { - makeAdlibBoxesActionsReplay(o, globalRank++, true) - }) + config.sources.replays.forEach(o => { + if (!/EPSIO/i.test(o.id)) { + makeAdlibBoxesActionsReplay(o, globalRank++, false) + } + makeAdlibBoxesActionsReplay(o, globalRank++, true) + }) makeServerAdlibBoxesActions(globalRank++) From e9fd1fc0569d29b7fc061c565268c9c3d69b7599 Mon Sep 17 00:00:00 2001 From: ianshade Date: Mon, 8 Aug 2022 09:26:19 +0200 Subject: [PATCH 169/184] fix: SOF-938 server not appearing in DVE --- src/tv2-common/content/dve.ts | 140 +++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 61 deletions(-) diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index ee38414d6..550d70c04 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -121,6 +121,9 @@ export interface DVEOptions { AUDIO_LAYERS: string[] } +type BoxConfig = DVEConfigBox & { source: number } +type BoxSources = Array<(VTContent | CameraContent | RemoteContent | GraphicsContent) & SplitsContentBoxProperties> + export function MakeContentDVEBase< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase @@ -180,7 +183,7 @@ export function MakeContentDVE2< dveGeneratorOptions: DVEOptions, className?: string, adlib?: boolean, - videoId?: string, + _videoId?: string, mediaPlayerSessionId?: string ): { content: WithTimeline; valid: boolean } { let template: DVEConfig @@ -204,68 +207,23 @@ export function MakeContentDVE2< const classes: string[] = [] - inputs.forEach(source => { - const sourceProps = source.split(':') - const fromCue = sourceProps[1] - const targetBox = Number(sourceProps[0]) - if (!fromCue || !targetBox || isNaN(targetBox)) { - context.notifyUserWarning(`Invalid DVE mapping: ${sourceProps}`) - return - } + makeBoxMap(inputs, context, classes, dveGeneratorOptions, sources, boxMap) - classes.push(`${fromCue.replace(/\s/g, '')}_${dveGeneratorOptions.boxMappings[targetBox - 1]}`) - - if (sources) { - const prop = sources[fromCue as keyof DVESources] - if (prop) { - boxMap[targetBox - 1] = prop.sourceType !== SourceType.SERVER || videoId ? prop : undefined - } else { - context.notifyUserWarning(`Missing mapping for ${targetBox}`) - boxMap[targetBox - 1] = undefined - } - } else { - // Need something to keep the layout etc - boxMap[targetBox - 1] = undefined - } - }) - - const boxes = _.map(template.boxes, box => ({ ...box, source: config.studio.AtemSource.Default })) + const boxes: BoxConfig[] = _.map(template.boxes, box => ({ ...box, source: config.studio.AtemSource.Default })) const dveTimeline: TSR.TSRTimelineObj[] = [] - const boxSources: Array<(VTContent | CameraContent | RemoteContent | GraphicsContent) & - SplitsContentBoxProperties> = [] - - const setBoxSource = (num: number, sourceInfo: { port: number; sourceLayerType: SourceLayerType }) => { - if (boxes[num]) { - boxes[num].source = sourceInfo.port - - boxSources.push({ - // TODO - draw box geometry - ...boxSource(sourceInfo), - ...literal({ - studioLabel: '', - switcherInput: sourceInfo.port - }) - }) - } - } - - const setBoxToBlack = (num: number) => { - setBoxSource(num, { - port: AtemSourceIndex.Blk, - sourceLayerType: SourceLayerType.UNKNOWN - }) - } + const boxSources: BoxSources = [] let valid = true let server = false boxMap.forEach((mappingFrom, num) => { + const box = boxes[num] if (mappingFrom === undefined) { 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}`) - setBoxToBlack(num) + setBoxToBlack(box, boxSources) valid = false } } else { @@ -274,7 +232,7 @@ export function MakeContentDVE2< } switch (mappingFrom.sourceType) { case SourceType.DEFAULT: - setBoxSource(num, { + setBoxSource(box, boxSources, { sourceLayerType: SourceLayerType.UNKNOWN, port: config.studio.AtemSource.Default }) @@ -283,53 +241,53 @@ export function MakeContentDVE2< const sourceInfoCam = findSourceInfo(config.sources, mappingFrom) if (sourceInfoCam === undefined) { context.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) - setBoxToBlack(num) + setBoxToBlack(box, boxSources) valid = false return } - setBoxSource(num, sourceInfoCam) + setBoxSource(box, boxSources, sourceInfoCam) dveTimeline.push(...GetSisyfosTimelineObjForCamera(config, sourceInfoCam, mappingFrom.minusMic, audioEnable)) break case SourceType.REMOTE: const sourceInfoLive = findSourceInfo(config.sources, mappingFrom) if (sourceInfoLive === undefined) { context.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) - setBoxToBlack(num) + setBoxToBlack(box, boxSources) valid = false return } - setBoxSource(num, sourceInfoLive) + setBoxSource(box, boxSources, sourceInfoLive) dveTimeline.push(...GetSisyfosTimelineObjForRemote(config, sourceInfoLive, audioEnable)) break case SourceType.REPLAY: const sourceInfoReplay = findSourceInfo(config.sources, mappingFrom) if (sourceInfoReplay === undefined) { context.notifyUserWarning(`Invalid source: ${mappingFrom.raw}`) - setBoxToBlack(num) + setBoxToBlack(box, boxSources) valid = false return } - setBoxSource(num, sourceInfoReplay) + setBoxSource(box, boxSources, sourceInfoReplay) dveTimeline.push(...GetSisyfosTimelineObjForReplay(config, sourceInfoReplay, mappingFrom.vo)) break case SourceType.GRAFIK: if (mappingFrom.name === 'FULL') { - setBoxSource(num, { + setBoxSource(box, boxSources, { sourceLayerType: SourceLayerType.GRAPHICS, port: FindDSKFullGFX(config).Fill }) dveTimeline.push(...GetSisyfosTimelineObjForFull(config)) } else { context.notifyUserWarning(`Unsupported engine for DVE: ${mappingFrom.name}`) - setBoxToBlack(num) + setBoxToBlack(box, boxSources) } break case SourceType.SERVER: server = true - setBoxSource(num, { + setBoxSource(box, boxSources, { sourceLayerType: SourceLayerType.VT, port: -1 }) @@ -483,6 +441,66 @@ export function MakeContentDVE2< } } +const setBoxSource = ( + boxConfig: BoxConfig, + boxSources: BoxSources, + sourceInfo: { port: number; sourceLayerType: SourceLayerType } +) => { + if (boxConfig) { + boxConfig.source = sourceInfo.port + + boxSources.push({ + // TODO - draw box geometry + ...boxSource(sourceInfo), + ...literal({ + studioLabel: '', + switcherInput: sourceInfo.port + }) + }) + } +} + +const setBoxToBlack = (boxConfig: BoxConfig, boxSources: BoxSources) => { + setBoxSource(boxConfig, boxSources, { + port: AtemSourceIndex.Blk, + sourceLayerType: SourceLayerType.UNKNOWN + }) +} + +function makeBoxMap( + inputs: string[], + context: IShowStyleUserContext, + classes: string[], + dveGeneratorOptions: DVEOptions, + sources: DVESources | undefined, + boxMap: Array +) { + inputs.forEach(source => { + const sourceProps = source.split(':') + const fromCue = sourceProps[1] + const targetBox = Number(sourceProps[0]) + if (!fromCue || !targetBox || isNaN(targetBox)) { + context.notifyUserWarning(`Invalid DVE mapping: ${sourceProps}`) + return + } + + classes.push(`${fromCue.replace(/\s/g, '')}_${dveGeneratorOptions.boxMappings[targetBox - 1]}`) + + if (sources) { + const prop = sources[fromCue as keyof DVESources] + if (prop) { + boxMap[targetBox - 1] = prop + } else { + context.notifyUserWarning(`Missing mapping for ${targetBox}`) + boxMap[targetBox - 1] = undefined + } + } else { + // Need something to keep the layout etc + boxMap[targetBox - 1] = undefined + } + }) +} + function boxSource(info: { port: number sourceLayerType: SourceLayerType From e172b09edfc93228ad862de5199cdfba73f98cbf Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 10 Aug 2022 09:52:19 +0200 Subject: [PATCH 170/184] refactor: SOF-938 minor improvements --- src/tv2-common/actions/executeAction.ts | 2 -- src/tv2-common/content/dve.ts | 41 +++++++++++++------------ 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index de9e85bfd..3c956756b 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -602,7 +602,6 @@ async function executeActionSelectDVE< settings.DVEGeneratorOptions, undefined, false, - userData.videoId, externalId ) @@ -1388,7 +1387,6 @@ async function executeActionCutSourceToBox< settings.DVEGeneratorOptions, undefined, undefined, - undefined, mediaPlayerSession ) diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index 550d70c04..c4305b327 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -166,7 +166,6 @@ export function MakeContentDVEBase< dveGeneratorOptions, addClass ? DVEParentClass('studio0', dveConfig.DVEName) : undefined, adlib, - partDefinition.fields.videoId, partDefinition.segmentExternalId ) } @@ -183,7 +182,6 @@ export function MakeContentDVE2< dveGeneratorOptions: DVEOptions, className?: string, adlib?: boolean, - _videoId?: string, mediaPlayerSessionId?: string ): { content: WithTimeline; valid: boolean } { let template: DVEConfig @@ -203,20 +201,22 @@ export function MakeContentDVE2< const inputs = dveConfig.DVEInputs ? dveConfig.DVEInputs.toString().split(';') : '1:INP1;2:INP2;3:INP3;4:INP4'.split(';') - const boxMap: Array = [] const classes: string[] = [] - makeBoxMap(inputs, context, classes, dveGeneratorOptions, sources, boxMap) + const boxAssigments = makeBoxAssignments(inputs, context, classes, dveGeneratorOptions, sources) - const boxes: BoxConfig[] = _.map(template.boxes, box => ({ ...box, source: config.studio.AtemSource.Default })) + const boxes: BoxConfig[] = Object.entries(template.boxes).map(([_num, box]) => ({ + ...box, + source: config.studio.AtemSource.Default + })) const dveTimeline: TSR.TSRTimelineObj[] = [] const boxSources: BoxSources = [] let valid = true let server = false - boxMap.forEach((mappingFrom, num) => { + boxAssigments.forEach((mappingFrom, num) => { const box = boxes[num] if (mappingFrom === undefined) { if (sources) { @@ -467,14 +467,14 @@ const setBoxToBlack = (boxConfig: BoxConfig, boxSources: BoxSources) => { }) } -function makeBoxMap( +function makeBoxAssignments( inputs: string[], context: IShowStyleUserContext, classes: string[], dveGeneratorOptions: DVEOptions, - sources: DVESources | undefined, - boxMap: Array + sources: DVESources | undefined ) { + const boxAssignments: Array = [] inputs.forEach(source => { const sourceProps = source.split(':') const fromCue = sourceProps[1] @@ -486,19 +486,22 @@ function makeBoxMap( classes.push(`${fromCue.replace(/\s/g, '')}_${dveGeneratorOptions.boxMappings[targetBox - 1]}`) - if (sources) { - const prop = sources[fromCue as keyof DVESources] - if (prop) { - boxMap[targetBox - 1] = prop - } else { - context.notifyUserWarning(`Missing mapping for ${targetBox}`) - boxMap[targetBox - 1] = undefined - } - } else { + if (!sources) { // Need something to keep the layout etc - boxMap[targetBox - 1] = undefined + boxAssignments[targetBox - 1] = undefined + return } + + const prop = sources[fromCue as keyof DVESources] + if (prop) { + boxAssignments[targetBox - 1] = prop + return + } + + context.notifyUserWarning(`Missing mapping for ${targetBox}`) + boxAssignments[targetBox - 1] = undefined }) + return boxAssignments } function boxSource(info: { From 87c8c4dc95009b4cb6700086b6ada7d4b2951f9f Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 10 Aug 2022 13:33:34 +0200 Subject: [PATCH 171/184] Revert "fix: SOF-767 temporarily disable Server Resume" This reverts commit 2a69391b9caefbf57499e0060e7670beba7346da. --- src/tv2-common/actions/executeAction.ts | 1 - src/tv2-common/pieces/adlibServer.ts | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index de9e85bfd..b8a88e8e3 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -423,7 +423,6 @@ async function executeActionSelectServerClip< triggerMode?: ServerSelectMode, sessionToContinue?: string ) { - triggerMode = ServerSelectMode.RESET /** @todo: remove for Server Resume */ const file = userData.file const partDefinition = userData.partDefinition const config = settings.getConfig(context) diff --git a/src/tv2-common/pieces/adlibServer.ts b/src/tv2-common/pieces/adlibServer.ts index 1e704c1d1..cbc0f14fb 100644 --- a/src/tv2-common/pieces/adlibServer.ts +++ b/src/tv2-common/pieces/adlibServer.ts @@ -12,7 +12,7 @@ import { TV2StudioConfigBase } from 'tv2-common' import { AdlibActionType, AdlibTags, SharedOutputLayers } from 'tv2-constants' -import { t } from '../helpers' +import { getServerAdLibTriggerModes, t } from '../helpers' export interface AdlibServerOfftubeOptions { /** By passing in this object, you're creating a server according to the OFFTUBE showstyle. */ @@ -68,7 +68,7 @@ export async function CreateAdlibServer< currentPieceTags: [GetTagForServer(partDefinition.segmentExternalId, file, !!voLayer)], nextPieceTags: [GetTagForServerNext(partDefinition.segmentExternalId, file, !!voLayer)], uniquenessId: `${voLayer ? 'vo' : 'server'}_${partDefinition.storyName}_${file}` - } - // triggerModes: getServerAdLibTriggerModes() /** @todo: uncomment for Server Resume */ + }, + triggerModes: getServerAdLibTriggerModes() }) } From 72dec620adae30baeca3b66a5479331bc8f79b13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Tue, 16 Aug 2022 07:53:55 +0200 Subject: [PATCH 172/184] chore: SOF-1068 klar_on_air is now named ready_on_air --- shelf-layouts/Kommentator.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shelf-layouts/Kommentator.json b/shelf-layouts/Kommentator.json index 52c586c8b..760c4f3e2 100644 --- a/shelf-layouts/Kommentator.json +++ b/shelf-layouts/Kommentator.json @@ -440,7 +440,7 @@ { "_id": "PTJBfPjrxPMwY4cqW", "label": "Activate", - "type": "klar_on_air", + "type": "ready_on_air", "x": -1, "y": 0, "width": 14, @@ -486,4 +486,4 @@ "startingHeight": 80, "disableContextMenu": true, "regionId": "shelf_layouts" -} \ No newline at end of file +} From c3f660aa4b3c8720a9cffd4227a8e3f14e2c7225 Mon Sep 17 00:00:00 2001 From: ianshade Date: Thu, 18 Aug 2022 09:54:58 +0200 Subject: [PATCH 173/184] fix: SOF-1079 set postrollDuration on jingles to offset the freeze indicator --- src/tv2-common/content/jingle.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tv2-common/content/jingle.ts b/src/tv2-common/content/jingle.ts index 1215352a1..52eeff218 100644 --- a/src/tv2-common/content/jingle.ts +++ b/src/tv2-common/content/jingle.ts @@ -42,6 +42,7 @@ export function CreateJingleExpectedMedia( ignoreBlackFrames: true, ignoreFreezeFrame: true, sourceDuration: TimeFromFrames(Number(duration) - Number(alphaAtEnd)), + postrollDuration: TimeFromFrames(Number(alphaAtEnd)), timelineObjects: [] }) } From 8379666433f8795e1aa88231a24389db6cef0678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Frederik=20J=C3=B8rgensen?= Date: Mon, 22 Aug 2022 10:53:51 +0200 Subject: [PATCH 174/184] fix: Updated black box in header to correct position and size. --- shelf-layouts/Rundown_Header_Layout.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shelf-layouts/Rundown_Header_Layout.json b/shelf-layouts/Rundown_Header_Layout.json index e09265569..2b253079f 100644 --- a/shelf-layouts/Rundown_Header_Layout.json +++ b/shelf-layouts/Rundown_Header_Layout.json @@ -192,7 +192,7 @@ "iconColor": "#000000", "x": 37, "width": 27, - "height": 1.1, + "height": 2, "y": 0, "xUnit": "%", "widthUnit": "%" @@ -215,7 +215,7 @@ "" ], "timingType": "count_down", - "y": -1.25, + "y": -1.35, "x": 37.5, "hideLabel": true, "requiredLayerIds": [ From 3d1718fc9678a6d3c85ebe352ce1a5036b55187e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Tue, 30 Aug 2022 08:07:55 +0200 Subject: [PATCH 175/184] chroe:SOF-1043 uppdate scaling. Rename Sisoifys to mic tally --- shelf-layouts/Kommentator.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/shelf-layouts/Kommentator.json b/shelf-layouts/Kommentator.json index 52c586c8b..670c252f9 100644 --- a/shelf-layouts/Kommentator.json +++ b/shelf-layouts/Kommentator.json @@ -163,7 +163,7 @@ { "_id": "LiFso7gPYn2SPwHwg", "type": "external_frame", - "name": "Sisyfos", + "name": "Mic tally", "currentSegment": false, "displayStyle": "buttons", "rank": 0, @@ -173,7 +173,7 @@ "y": 0, "width": 22, "height": 7, - "url": "https://sisyfos.sofsrv04-od.tv2.local?minimonitor=1", + "url": "https://sisyfos.sofsrv04-od.tv2.local?view=mic-tally", "scale": 0.85 }, { @@ -191,7 +191,7 @@ "height": -11, "windowNumber": 1, "role": "take", - "scale": 1, + "scale": 0, "thumbnailPriorityNextPieces": true, "hideThumbnailsForActivePieces": true, "thumbnailSourceLayerIds": [ @@ -412,7 +412,7 @@ "x": 1.3, "y": 24.9, "width": 22, - "scale": 0.8, + "scale": 0, "showPartTitle": true }, { @@ -432,7 +432,7 @@ "y" : 0, "width" : 14, "height" : 7, - "scale" : 1 + "scale" : 0 } ], "type": "dashboard_layout", @@ -486,4 +486,4 @@ "startingHeight": 80, "disableContextMenu": true, "regionId": "shelf_layouts" -} \ No newline at end of file +} From 769764654dfd301767fad585a936f5bfbc96c005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Tue, 30 Aug 2022 08:12:06 +0200 Subject: [PATCH 176/184] chore: SOF-1043 fix scaling of mic tally view --- shelf-layouts/Kommentator.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shelf-layouts/Kommentator.json b/shelf-layouts/Kommentator.json index 670c252f9..49298e877 100644 --- a/shelf-layouts/Kommentator.json +++ b/shelf-layouts/Kommentator.json @@ -174,7 +174,7 @@ "width": 22, "height": 7, "url": "https://sisyfos.sofsrv04-od.tv2.local?view=mic-tally", - "scale": 0.85 + "scale": 0 }, { "_id": "6GDpdq547HjjZL9YK", From 2eb9f0614a401684f6273a84415e686df9f6e55f Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 30 Aug 2022 13:21:13 +0200 Subject: [PATCH 177/184] fix: SOF-769 make `direkte` idents behave like other idents --- package.json | 2 +- src/tv2-common/actions/actionTypes.ts | 8 - src/tv2-common/actions/executeAction.ts | 70 +++--- src/tv2-common/cues/ekstern.ts | 2 +- .../helpers/graphics/InternalGraphic.ts | 212 ++++-------------- .../helpers/graphics/caspar/index.ts | 14 +- .../helpers/graphics/internal/index.ts | 12 +- src/tv2-common/helpers/graphics/layers.ts | 6 +- .../helpers/graphics/pilot/index.ts | 4 +- src/tv2-common/helpers/graphics/timing.ts | 92 ++++---- src/tv2-common/helpers/graphics/viz/index.ts | 5 +- src/tv2-common/hotkeys/hotkey-defaults.ts | 3 +- .../inewsConversion/converters/ParseCue.ts | 11 +- src/tv2-common/onTimelineGenerate.ts | 1 + .../shouldRemoveOrphanedPartInstance.ts | 2 +- .../syncIngestUpdateToPartInstance.ts | 1 - src/tv2-constants/enums.ts | 5 +- .../pieces/__tests__/grafikViz.spec.ts | 59 ++--- .../helpers/pieces/__tests__/telefon.spec.ts | 1 + .../helpers/pieces/clearGrafiks.ts | 1 - .../helpers/pieces/graphic.ts | 2 +- src/tv2_afvd_showstyle/migrations/index.ts | 11 +- .../migrations/sourcelayer-defaults.ts | 18 -- .../cues/OfftubeGraphics.ts | 2 +- src/tv2_offtube_showstyle/migrations/index.ts | 20 +- .../migrations/sourcelayer-defaults.ts | 15 -- 26 files changed, 175 insertions(+), 404 deletions(-) diff --git a/package.json b/package.json index 556bc79c2..fa692afbe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tv2-sofie-blueprints-inews", - "version": "1.7.4", + "version": "1.7.5", "repository": "https://github.com/olzzon/tv2-sofie-blueprints-inews", "license": "MIT", "private": true, diff --git a/src/tv2-common/actions/actionTypes.ts b/src/tv2-common/actions/actionTypes.ts index 9e1479dd7..0d0e3c282 100644 --- a/src/tv2-common/actions/actionTypes.ts +++ b/src/tv2-common/actions/actionTypes.ts @@ -2,8 +2,6 @@ import { AdlibActionType } from 'tv2-constants' import { DVEConfigInput } from '../helpers' import { CueDefinitionDVE, - CueDefinitionGraphic, - GraphicInternal, PartDefinition, SourceDefinition, SourceDefinitionKam, @@ -137,11 +135,6 @@ export interface ActionFadeDownPersistedAudioLevels extends ActionBase { type: AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS } -export interface ActionPlayGraphics extends ActionBase { - type: AdlibActionType.PLAY_GRAPHICS - graphic: CueDefinitionGraphic -} - export type TV2AdlibAction = | ActionSelectServerClip | ActionSelectDVE @@ -159,4 +152,3 @@ export type TV2AdlibAction = | ActionRecallLastLive | ActionRecallLastDVE | ActionFadeDownPersistedAudioLevels - | ActionPlayGraphics diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index 3c956756b..a9f8e0a34 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -26,7 +26,6 @@ import { ActionCutSourceToBox, ActionCutToCamera, ActionCutToRemote, - ActionPlayGraphics, ActionSelectDVE, ActionSelectDVELayout, ActionSelectFullGrafik, @@ -47,7 +46,6 @@ import { GetDVETemplate, GetFullGrafikTemplateName, GraphicPilot, - IsTargetingOVL, ITV2ActionExecutionContext, literal, MakeContentDVE2, @@ -81,7 +79,6 @@ import { PilotGraphicGenerator, ServerSelectMode } from '../helpers' -import { InternalGraphic } from '../helpers/graphics/InternalGraphic' import { GetJinglePartPropertiesFromTableValue } from '../jinglePartProperties' import { CreateEffektForPartBase, CreateEffektForPartInner, CreateMixTransitionBlueprintPieceForPart } from '../parts' import { @@ -105,7 +102,6 @@ import { const STOPPABLE_GRAPHICS_LAYERS = [ SharedSourceLayers.PgmGraphicsIdent, - SharedSourceLayers.PgmGraphicsIdentPersistent, SharedSourceLayers.PgmGraphicsTop, SharedSourceLayers.PgmGraphicsLower, SharedSourceLayers.PgmGraphicsHeadline, @@ -280,9 +276,6 @@ export async function executeAction< case AdlibActionType.FADE_DOWN_PERSISTED_AUDIO_LEVELS: await executeActionFadeDownPersistedAudioLevels(context, settings) break - case AdlibActionType.PLAY_GRAPHICS: - await executeActionPlayGraphics(context, settings, actionId, userData as ActionPlayGraphics) - break default: assertUnreachable(actionId) break @@ -1191,6 +1184,8 @@ async function executeActionCutToCamera< const metaData = kamPiece.metaData as PieceMetaData metaData.sisyfosPersistMetaData!.previousPersistMetaDataForCurrentPiece = currentMetaData.sisyfosPersistMetaData + await stopGraphicPiecesThatShouldEndWithPart(context, currentPieceInstances) + await context.updatePieceInstance(currentKam._id, kamPiece) } else { const currentExternalId = await context @@ -1211,12 +1206,32 @@ async function executeActionCutToCamera< ...(settings.SourceLayers.EVS ? [settings.SourceLayers.EVS] : []), settings.SourceLayers.Continuity ]) + await stopGraphicPiecesThatShouldEndWithPart(context, currentPieceInstances) kamPiece.enable = { start: 'now' } await context.insertPiece('current', kamPiece) } } +async function stopGraphicPiecesThatShouldEndWithPart( + context: ITV2ActionExecutionContext, + currentPieceInstances: Array> +) { + await context.stopPieceInstances( + currentPieceInstances + .filter(pieceInstance => isGraphicThatShouldEndWithPart(pieceInstance)) + .map(pieceInstance => pieceInstance._id) + ) +} + +function isGraphicThatShouldEndWithPart(pieceInstance: IBlueprintPieceInstance): unknown { + return ( + pieceInstance.piece.lifespan === PieceLifespan.WithinPart && + !pieceInstance.stoppedPlayback && + (STOPPABLE_GRAPHICS_LAYERS as string[]).includes(pieceInstance.piece.sourceLayerId) + ) +} + async function executeActionCutToRemote< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase @@ -1852,7 +1867,10 @@ async function executeActionRecallLastLive< const lastIdent = await context.findLastPieceOnLayer(settings.SourceLayers.Ident, { originalOnly: true, - excludeCurrentPart: false + excludeCurrentPart: false, + pieceMetaDataFilter: { + belongsToRemotePart: true + } }) const externalId = generateExternalId(context, actionId, [lastLive.piece.name]) @@ -1872,12 +1890,10 @@ async function executeActionRecallLastLive< lifespan: PieceLifespan.WithinPart }) - // externalId should be replaced with something more concrete like partInstanceId - if (lastIdent && lastIdent.piece.externalId === lastLive.piece.externalId) { + if (lastIdent) { pieces.push({ ...lastIdent.piece, externalId, - enable: { ...lastIdent.piece.enable, start: 0 }, lifespan: PieceLifespan.WithinPart }) } @@ -1963,38 +1979,6 @@ async function createFadeSisyfosLevelsMetaData(context: ITV2ActionExecutionConte } } -async function executeActionPlayGraphics< - StudioConfig extends TV2StudioConfigBase, - ShowStyleConfig extends TV2BlueprintConfigBase ->( - context: ITV2ActionExecutionContext, - settings: ActionExecutionSettings, - actionId: string, - userData: ActionPlayGraphics -): Promise { - if (!IsTargetingOVL(userData.graphic.target)) { - return - } - - const currentPartInstance = await context.getPartInstance('current') - const externalId = currentPartInstance?.part.externalId ?? generateExternalId(context, actionId, []) - - const internalGraphic: InternalGraphic = new InternalGraphic( - settings.getConfig(context), - userData.graphic, - { rank: 0 }, - externalId, - undefined - ) - const pieces: IBlueprintPiece[] = [] - - internalGraphic.createPiece(pieces) - - pieces.forEach((piece: IBlueprintPiece) => { - context.insertPiece('current', piece) - }) -} - async function scheduleLastPlayedDVE< StudioConfig extends TV2StudioConfigBase, ShowStyleConfig extends TV2BlueprintConfigBase diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index afdb863b6..c7a2c5273 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -133,7 +133,7 @@ export function EvaluateEksternBase< // Only want the ident for original versions (or clones) enable: { start: 0 }, layer: 'ekstern_enable_ident', - classes: [ControlClasses.ShowIdentGraphic, PartToParentClass('studio0', partDefinition) ?? ''] + classes: [PartToParentClass('studio0', partDefinition) ?? ''] }), literal({ id: '', diff --git a/src/tv2-common/helpers/graphics/InternalGraphic.ts b/src/tv2-common/helpers/graphics/InternalGraphic.ts index 856599c89..00a23c7f7 100644 --- a/src/tv2-common/helpers/graphics/InternalGraphic.ts +++ b/src/tv2-common/helpers/graphics/InternalGraphic.ts @@ -1,33 +1,16 @@ -import { - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPiece, - ICommonContext, - PieceLifespan, - TSR -} from '@tv2media/blueprints-integration' +import { IBlueprintAdLibPiece, IBlueprintPiece, PieceLifespan } from '@tv2media/blueprints-integration' import { Adlib } from 'tv2-common' import _ = require('underscore') -import { - AbstractLLayer, - AdlibActionType, - AdlibTags, - GraphicEngine, - SharedOutputLayers, - SharedSourceLayers -} from '../../../tv2-constants' -import { ActionPlayGraphics } from '../../actions' +import { AdlibTags, GraphicEngine, PartType, SharedOutputLayers, SharedSourceLayers } from '../../../tv2-constants' import { TV2BlueprintConfig } from '../../blueprintConfig' -import { GetDefaultOut } from '../../cueTiming' -import { CueDefinitionGraphic, GraphicInternal, IsStickyIdent, PartDefinition } from '../../inewsConversion' +import { CueDefinitionGraphic, GraphicInternal, PartDefinition } from '../../inewsConversion' import { PieceMetaData } from '../../onTimelineGenerate' -import { generateExternalId, literal } from '../../util' -import { t } from '../translation' +import { literal } from '../../util' import { GetInternalGraphicContentCaspar } from './caspar' import { GetSourceLayerForGraphic } from './layers' import { GetFullGraphicTemplateNameFromCue, GraphicDisplayName } from './name' import { IsTargetingOVL, IsTargetingTLF, IsTargetingWall } from './target' -import { CreateTimingGraphic, GetInfiniteModeForGraphic } from './timing' +import { CreateTimingGraphic, GetPieceLifespanForGraphic } from './timing' import { GetInternalGraphicContentVIZ } from './viz' export class InternalGraphic { @@ -36,7 +19,6 @@ export class InternalGraphic { private readonly parsedCue: CueDefinitionGraphic private readonly partDefinition?: PartDefinition private readonly adlib?: Adlib - private readonly isStickyIdent: boolean private readonly engine: GraphicEngine private readonly name: string private readonly sourceLayerId: SharedSourceLayers @@ -52,130 +34,71 @@ export class InternalGraphic { partId?: string, partDefinition?: PartDefinition ) { - const isStickyIdent = IsStickyIdent(parsedCue) - - const engine = parsedCue.target - const mappedTemplate = GetFullGraphicTemplateNameFromCue(config, parsedCue) - const sourceLayerId = GetSourceLayerForGraphic(config, mappedTemplate, isStickyIdent) + const sourceLayerId = GetSourceLayerForGraphic(config, mappedTemplate) this.config = config this.parsedCue = parsedCue this.partDefinition = partDefinition this.adlib = adlib this.mappedTemplate = mappedTemplate - this.isStickyIdent = isStickyIdent this.engine = parsedCue.target this.name = GraphicDisplayName(config, parsedCue) this.sourceLayerId = sourceLayerId - this.outputLayerId = IsTargetingWall(engine) ? SharedOutputLayers.SEC : SharedOutputLayers.OVERLAY + this.outputLayerId = IsTargetingWall(this.engine) ? SharedOutputLayers.SEC : SharedOutputLayers.OVERLAY this.partId = partId this.content = this.getInternalGraphicContent() } - public createAdlibTargetingOVL( - context: ICommonContext, - actions: IBlueprintActionManifest[], - adlibPieces: IBlueprintAdLibPiece[] - ): void { - if (IsTargetingOVL(this.engine) && this.isStickyIdent) { - const userData = literal({ - type: AdlibActionType.PLAY_GRAPHICS, - graphic: this.parsedCue - }) - actions.push( - literal({ - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.PLAY_GRAPHICS, - userData, - userDataManifest: {}, - display: { - _rank: this.rank || 0, - label: t(this.name), - uniquenessId: `gfx_${this.name}_${this.sourceLayerId}_${this.outputLayerId}_commentator`, - sourceLayerId: this.sourceLayerId, - outputLayerId: SharedOutputLayers.OVERLAY, - tags: [AdlibTags.ADLIB_KOMMENTATOR], - content: _.clone(this.content) - } - }) - ) - } else if (IsTargetingOVL(this.engine)) { - const adLibPiece = literal({ + public createCommentatorAdlib(adlibPieces: IBlueprintAdLibPiece[]): void { + if (!IsTargetingOVL(this.engine)) { + return + } + const adLibPiece = literal({ + _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: literal({ + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), + expectedDuration: 5000, + tags: [AdlibTags.ADLIB_KOMMENTATOR], + content: _.clone(this.content) + }) + adlibPieces.push(adLibPiece) + } + + public createAdlib(adlibPieces: IBlueprintAdLibPiece[]): void { + adlibPieces.push( + literal({ _rank: this.rank || 0, externalId: this.partId ?? '', name: this.name, - uniquenessId: `gfx_${this.name}_${this.sourceLayerId}_${this.outputLayerId}_commentator`, + uniquenessId: `gfx_${this.name}_${this.sourceLayerId}_${this.outputLayerId}_flow`, sourceLayerId: this.sourceLayerId, - outputLayerId: SharedOutputLayers.OVERLAY, - lifespan: PieceLifespan.WithinPart, + 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: literal({ sisyfosPersistMetaData: { sisyfosLayers: [] } }), - expectedDuration: 5000, - tags: [AdlibTags.ADLIB_KOMMENTATOR], content: _.clone(this.content) }) - adlibPieces.push(adLibPiece) - } - } - - public createAdlib( - context: ICommonContext, - actions: IBlueprintActionManifest[], - adlibPieces: IBlueprintAdLibPiece[] - ): void { - if (this.isStickyIdent) { - const userData = literal({ - type: AdlibActionType.PLAY_GRAPHICS, - graphic: this.parsedCue - }) - actions.push( - literal({ - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.PLAY_GRAPHICS, - userData, - userDataManifest: {}, - display: { - _rank: this.rank || 0, - label: t(this.name), - uniquenessId: `gfx_${this.name}_${this.sourceLayerId}_${this.outputLayerId}_flow`, - sourceLayerId: this.sourceLayerId, - outputLayerId: SharedOutputLayers.OVERLAY, - tags: [AdlibTags.ADLIB_FLOW_PRODUCER], - content: _.clone(this.content) - } - }) - ) - } else { - adlibPieces.push( - literal({ - _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 || GetDefaultOut(this.config) - }), - lifespan: GetInfiniteModeForGraphic(this.engine, this.config, this.parsedCue, this.isStickyIdent), - metaData: literal({ - sisyfosPersistMetaData: { - sisyfosLayers: [] - } - }), - content: _.clone(this.content) - }) - ) - } + ) } public createPiece(pieces: IBlueprintPiece[]): void { @@ -186,58 +109,21 @@ export class InternalGraphic { ? { enable: { start: 0 } } : { enable: { - ...CreateTimingGraphic(this.config, this.parsedCue, !this.isStickyIdent) + ...CreateTimingGraphic(this.config, this.parsedCue) } }), outputLayerId: this.outputLayerId, sourceLayerId: this.sourceLayerId, - lifespan: GetInfiniteModeForGraphic(this.engine, this.config, this.parsedCue, this.isStickyIdent), + lifespan: GetPieceLifespanForGraphic(this.engine, this.config, this.parsedCue), metaData: literal({ sisyfosPersistMetaData: { sisyfosLayers: [] - } + }, + belongsToRemotePart: this.partDefinition?.type === PartType.REMOTE }), content: _.clone(this.content) }) pieces.push(piece) - - if ( - this.sourceLayerId === SharedSourceLayers.PgmGraphicsIdentPersistent && - (piece.lifespan === PieceLifespan.OutOnSegmentEnd || piece.lifespan === PieceLifespan.OutOnShowStyleEnd) && - this.isStickyIdent - ) { - // Special case for the ident. We want it to continue to exist in case the Live gets shown again, but we dont want the continuation showing in the ui. - // So we create the normal object on a hidden layer, and then clone it on another layer without content for the ui - pieces.push(this.createIndicatorPieceForIdentPersistent(piece)) - } - } - - public createIndicatorPieceForIdentPersistent(piece: IBlueprintPiece): IBlueprintPiece { - return literal({ - ...piece, - enable: { ...CreateTimingGraphic(this.config, this.parsedCue, true) }, // Allow default out for visual representation - sourceLayerId: SharedSourceLayers.PgmGraphicsIdent, - lifespan: PieceLifespan.WithinPart, - metaData: literal({ - sisyfosPersistMetaData: { - sisyfosLayers: [] - } - }), - content: { - timelineObjects: [ - literal({ - id: '', - enable: { - while: '1' - }, - layer: AbstractLLayer.IdentMarker, - content: { - deviceType: TSR.DeviceType.ABSTRACT - } - }) - ] - } - }) } private getInternalGraphicContent(): IBlueprintPiece['content'] { @@ -246,7 +132,6 @@ export class InternalGraphic { this.config, this.engine, this.parsedCue, - this.isStickyIdent, this.partDefinition, this.mappedTemplate, !!this.adlib @@ -255,7 +140,6 @@ export class InternalGraphic { this.config, this.engine, this.parsedCue, - this.isStickyIdent, this.partDefinition, this.mappedTemplate, !!this.adlib diff --git a/src/tv2-common/helpers/graphics/caspar/index.ts b/src/tv2-common/helpers/graphics/caspar/index.ts index 43ff6239f..3d4615650 100644 --- a/src/tv2-common/helpers/graphics/caspar/index.ts +++ b/src/tv2-common/helpers/graphics/caspar/index.ts @@ -32,21 +32,12 @@ export function GetInternalGraphicContentCaspar( config: TV2BlueprintConfig, engine: GraphicEngine, parsedCue: CueDefinitionGraphic, - isIdentGraphic: boolean, partDefinition: PartDefinition | undefined, mappedTemplate: string, adlib: boolean ): IBlueprintPiece['content'] { return { - timelineObjects: CasparOverlayTimeline( - config, - engine, - parsedCue, - isIdentGraphic, - partDefinition, - mappedTemplate, - adlib - ) + timelineObjects: CasparOverlayTimeline(config, engine, parsedCue, partDefinition, mappedTemplate, adlib) } } @@ -116,7 +107,6 @@ function CasparOverlayTimeline( config: TV2BlueprintConfig, engine: GraphicEngine, parsedCue: CueDefinitionGraphic, - isIdentGrafik: boolean, partDefinition: PartDefinition | undefined, mappedTemplate: string, adlib: boolean @@ -124,7 +114,7 @@ function CasparOverlayTimeline( return [ literal({ id: '', - enable: GetEnableForGraphic(config, engine, parsedCue, isIdentGrafik, partDefinition, adlib), + enable: GetEnableForGraphic(config, engine, parsedCue, partDefinition, adlib), priority: 1, layer: GetTimelineLayerForGraphic(config, mappedTemplate), content: CreateHTMLRendererContent(config, mappedTemplate, { ...parsedCue.graphic.textFields }) diff --git a/src/tv2-common/helpers/graphics/internal/index.ts b/src/tv2-common/helpers/graphics/internal/index.ts index 19e5b96c4..40b1e65fa 100644 --- a/src/tv2-common/helpers/graphics/internal/index.ts +++ b/src/tv2-common/helpers/graphics/internal/index.ts @@ -1,9 +1,4 @@ -import { - IBlueprintActionManifest, - IBlueprintAdLibPiece, - IBlueprintPiece, - IShowStyleUserContext -} from '@tv2media/blueprints-integration' +import { IBlueprintAdLibPiece, IBlueprintPiece, IShowStyleUserContext } from '@tv2media/blueprints-integration' import { Adlib, CueDefinitionGraphic, GraphicInternal, PartDefinition, TV2BlueprintConfig } from 'tv2-common' import { InternalGraphic } from '../InternalGraphic' @@ -12,7 +7,6 @@ export function CreateInternalGraphic( context: IShowStyleUserContext, pieces: IBlueprintPiece[], adlibPieces: IBlueprintAdLibPiece[], - actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionGraphic, partDefinition: PartDefinition, @@ -26,8 +20,8 @@ export function CreateInternalGraphic( } if (adlib) { - internalGraphic.createAdlibTargetingOVL(context, actions, adlibPieces) - internalGraphic.createAdlib(context, actions, adlibPieces) + internalGraphic.createCommentatorAdlib(adlibPieces) + internalGraphic.createAdlib(adlibPieces) } else { internalGraphic.createPiece(pieces) } diff --git a/src/tv2-common/helpers/graphics/layers.ts b/src/tv2-common/helpers/graphics/layers.ts index cb9b4967d..54e914b0a 100644 --- a/src/tv2-common/helpers/graphics/layers.ts +++ b/src/tv2-common/helpers/graphics/layers.ts @@ -1,7 +1,7 @@ import { TV2BlueprintConfig } from 'tv2-common' import { SharedGraphicLLayer, SharedSourceLayers } from 'tv2-constants' -export function GetSourceLayerForGraphic(config: TV2BlueprintConfig, name: string, isStickyIdent?: boolean) { +export function GetSourceLayerForGraphic(config: TV2BlueprintConfig, name: string) { const conf = config.showStyle.GFXTemplates ? config.showStyle.GFXTemplates.find(gfk => gfk.VizTemplate.toString() === name) : undefined @@ -19,10 +19,6 @@ export function GetSourceLayerForGraphic(config: TV2BlueprintConfig, name: strin } return SharedSourceLayers.PgmGraphicsHeadline case SharedSourceLayers.PgmGraphicsIdent: - if (isStickyIdent) { - return SharedSourceLayers.PgmGraphicsIdentPersistent - } - return SharedSourceLayers.PgmGraphicsIdent case SharedSourceLayers.PgmGraphicsLower: return SharedSourceLayers.PgmGraphicsLower diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index 99eb9f7ea..e799565ee 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -15,7 +15,7 @@ import { CueDefinitionGraphic, generateExternalId, GetFullGraphicTemplateNameFromCue, - GetInfiniteModeForGraphic, + GetPieceLifespanForGraphic, GetPilotGraphicContentViz, GetTagForFull, GetTagForFullNext, @@ -160,7 +160,7 @@ export class PilotGraphicGenerator { outputLayerId: this.getOutputLayer(), sourceLayerId: this.getSourceLayer(), prerollDuration: this.getPrerollDuration(), - lifespan: GetInfiniteModeForGraphic(this.engine, this.config, this.parsedCue), + lifespan: GetPieceLifespanForGraphic(this.engine, this.config, this.parsedCue), metaData: literal({ sisyfosPersistMetaData: { sisyfosLayers: [] diff --git a/src/tv2-common/helpers/graphics/timing.ts b/src/tv2-common/helpers/graphics/timing.ts index 6b4668c17..3304294b9 100644 --- a/src/tv2-common/helpers/graphics/timing.ts +++ b/src/tv2-common/helpers/graphics/timing.ts @@ -10,26 +10,27 @@ import { LifeSpan, PartDefinition, PartToParentClass, + TableConfigItemGFXTemplates, TV2BlueprintConfig } from 'tv2-common' -import { ControlClasses, GraphicEngine } from 'tv2-constants' +import { GraphicEngine } from 'tv2-constants' import { GetFullGraphicTemplateNameFromCue, IsTargetingTLF, IsTargetingWall } from '.' -export function GetInfiniteModeForGraphic( +export function GetPieceLifespanForGraphic( engine: GraphicEngine, config: TV2BlueprintConfig, - parsedCue: CueDefinitionGraphic, - isStickyIdent?: boolean + parsedCue: CueDefinitionGraphic ): PieceLifespan { - return IsTargetingWall(engine) - ? PieceLifespan.OutOnShowStyleEnd - : IsTargetingTLF(engine) - ? PieceLifespan.WithinPart - : isStickyIdent - ? PieceLifespan.OutOnSegmentEnd - : parsedCue.end && parsedCue.end.infiniteMode - ? LifeSpan(parsedCue.end.infiniteMode, PieceLifespan.WithinPart) - : FindInfiniteModeFromConfig(config, parsedCue) + if (IsTargetingWall(engine)) { + return PieceLifespan.OutOnShowStyleEnd + } + if (IsTargetingTLF(engine)) { + return PieceLifespan.WithinPart + } + if (parsedCue.end && parsedCue.end.infiniteMode) { + return LifeSpan(parsedCue.end.infiniteMode, PieceLifespan.WithinPart) + } + return FindInfiniteModeFromConfig(config, parsedCue) } export function FindInfiniteModeFromConfig( @@ -68,46 +69,27 @@ export function FindInfiniteModeFromConfig( export function GetGraphicDuration( config: TV2BlueprintConfig, - cue: CueDefinitionGraphic, - defaultTime: boolean + cue: CueDefinitionGraphic ): number | undefined { if (config.showStyle.GFXTemplates) { - if (GraphicIsInternal(cue)) { - const template = config.showStyle.GFXTemplates.find(templ => - templ.INewsName ? templ.INewsName.toString().toUpperCase() === cue.graphic.template.toUpperCase() : false - ) - if (template) { - if (template.OutType && !template.OutType.toString().match(/default/i)) { - return undefined - } - } - } else if (GraphicIsPilot(cue)) { - const template = config.showStyle.GFXTemplates.find(templ => - templ.INewsName - ? templ.INewsName.toString().toUpperCase() === cue.graphic.vcpid.toString().toUpperCase() - : false - ) - if (template) { - if (template.OutType && !template.OutType.toString().match(/default/i)) { - return undefined - } - } + const template = findGFXTemplate(config, cue) + if (template && template.OutType && !template.OutType.toString().match(/default/i)) { + return undefined } } - return defaultTime ? GetDefaultOut(config) : undefined + return GetDefaultOut(config) } export function CreateTimingGraphic( config: TV2BlueprintConfig, - cue: CueDefinitionGraphic, - defaultTime: boolean = true + 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, defaultTime) + const duration = GetGraphicDuration(config, cue) const end = cue.end ? cue.end.infiniteMode ? undefined @@ -126,11 +108,27 @@ export function GetEnableForWall(): TSR.TSRTimelineObj['enable'] { } } +export function findGFXTemplate( + config: TV2BlueprintConfig, + cue: CueDefinitionGraphic +): TableConfigItemGFXTemplates | 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, - isStickyIdent: boolean, partDefinition?: PartDefinition, adlib?: boolean ): TSR.TSRTimelineObj['enable'] { @@ -139,20 +137,13 @@ export function GetEnableForGraphic( } if ( - ((cue.end && cue.end.infiniteMode && cue.end.infiniteMode === 'B') || - GetInfiniteModeForGraphic(engine, config, cue, isStickyIdent) === PieceLifespan.OutOnSegmentEnd) && partDefinition && + (endsOnPartEnd(config, cue) || GetPieceLifespanForGraphic(engine, config, cue) === PieceLifespan.OutOnSegmentEnd) && !adlib ) { return { while: `.${PartToParentClass('studio0', partDefinition)} & !.adlib_deparent & !.full` } } - if (isStickyIdent) { - return { - while: `.${ControlClasses.ShowIdentGraphic} & !.full` - } - } - const timing = CreateTimingEnable(cue, GetDefaultOut(config)) if (!timing.lifespan) { @@ -169,3 +160,8 @@ export function GetEnableForGraphic( } } } +function endsOnPartEnd(config: TV2BlueprintConfig, cue: CueDefinitionGraphic) { + return ( + (cue.end && cue.end.infiniteMode && cue.end.infiniteMode === 'B') || findGFXTemplate(config, cue)?.OutType === 'B' + ) +} diff --git a/src/tv2-common/helpers/graphics/viz/index.ts b/src/tv2-common/helpers/graphics/viz/index.ts index 21138540f..a41f0a874 100644 --- a/src/tv2-common/helpers/graphics/viz/index.ts +++ b/src/tv2-common/helpers/graphics/viz/index.ts @@ -36,7 +36,6 @@ export function GetInternalGraphicContentVIZ( config: TV2BlueprintConfig, engine: GraphicEngine, parsedCue: CueDefinitionGraphic, - isIdentGraphic: boolean, partDefinition: PartDefinition | undefined, mappedTemplate: string, adlib: boolean @@ -48,7 +47,7 @@ export function GetInternalGraphicContentVIZ( timelineObjects: literal([ literal({ id: '', - enable: GetEnableForGraphic(config, engine, parsedCue, isIdentGraphic, partDefinition, adlib), + enable: GetEnableForGraphic(config, engine, parsedCue, partDefinition, adlib), priority: 1, layer: GetTimelineLayerForGraphic(config, GetFullGraphicTemplateNameFromCue(config, parsedCue)), content: { @@ -82,7 +81,7 @@ export function GetPilotGraphicContentViz( id: '', enable: IsTargetingOVL(engine) || IsTargetingWall(engine) - ? GetEnableForGraphic(config, engine, parsedCue, false, undefined, !!adlib) + ? GetEnableForGraphic(config, engine, parsedCue, undefined, !!adlib) : { start: 0 }, diff --git a/src/tv2-common/hotkeys/hotkey-defaults.ts b/src/tv2-common/hotkeys/hotkey-defaults.ts index 04566937e..e6da72e03 100644 --- a/src/tv2-common/hotkeys/hotkey-defaults.ts +++ b/src/tv2-common/hotkeys/hotkey-defaults.ts @@ -36,7 +36,6 @@ export const defaultHotkeys: TV2Hotkeys = { { sourceLayers: [ SharedSourceLayers.PgmGraphicsIdent, - SharedSourceLayers.PgmGraphicsIdentPersistent, SharedSourceLayers.PgmGraphicsTop, SharedSourceLayers.PgmGraphicsLower, SharedSourceLayers.PgmGraphicsHeadline, @@ -48,7 +47,7 @@ export const defaultHotkeys: TV2Hotkeys = { name: 'overlay ALT UD' }, { - sourceLayers: [SharedSourceLayers.PgmGraphicsIdent, SharedSourceLayers.PgmGraphicsIdentPersistent], + sourceLayers: [SharedSourceLayers.PgmGraphicsIdent], key: 'Ctrl+Shift+KeyA', name: 'ovl: ident OUT' }, diff --git a/src/tv2-common/inewsConversion/converters/ParseCue.ts b/src/tv2-common/inewsConversion/converters/ParseCue.ts index 14a6709bf..ba40ff172 100644 --- a/src/tv2-common/inewsConversion/converters/ParseCue.ts +++ b/src/tv2-common/inewsConversion/converters/ParseCue.ts @@ -1,4 +1,4 @@ -import { GetInfiniteModeForGraphic, literal, TableConfigSchema, TV2BlueprintConfig, UnparsedCue } from 'tv2-common' +import { GetPieceLifespanForGraphic, literal, TableConfigSchema, TV2BlueprintConfig, UnparsedCue } from 'tv2-common' import { CueType, GraphicEngine, PartType, SourceType } from 'tv2-constants' import { getSourceDefinition, @@ -996,17 +996,10 @@ export function AddParentClass(config: TV2BlueprintConfig, partDefinition: PartD } return partDefinition.cues.some( - c => - c.type === CueType.Graphic && - GraphicIsInternal(c) && - GetInfiniteModeForGraphic(c.target, config, c, IsStickyIdent(c)) + c => c.type === CueType.Graphic && GraphicIsInternal(c) && GetPieceLifespanForGraphic(c.target, config, c) ) } -export function IsStickyIdent(cue: CueDefinitionGraphic) { - return !!cue.graphic.template.match(/direkte/i) -} - export function UnpairedPilotToGraphic( pilotCue: CueDefinitionUnpairedPilot, target: GraphicEngine, diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index eecdef434..e668d7595 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -56,6 +56,7 @@ export interface PieceMetaData { mediaPlayerSessions?: string[] mediaPlayerOptional?: boolean modifiedByAction?: boolean + belongsToRemotePart?: boolean // used to find last idents in Lives } export interface SisyfosPersistMetaData { diff --git a/src/tv2-common/updatePolicies/shouldRemoveOrphanedPartInstance.ts b/src/tv2-common/updatePolicies/shouldRemoveOrphanedPartInstance.ts index 90e8d449a..626c4a5a1 100644 --- a/src/tv2-common/updatePolicies/shouldRemoveOrphanedPartInstance.ts +++ b/src/tv2-common/updatePolicies/shouldRemoveOrphanedPartInstance.ts @@ -5,5 +5,5 @@ export function shouldRemoveOrphanedPartInstance( _context: IRundownUserContext, partInstance: BlueprintRemoveOrphanedPartInstance ): boolean { - return !(partInstance.partInstance.part.metaData as PartMetaData).dirty + return !(partInstance.partInstance.part.metaData as PartMetaData | undefined)?.dirty } diff --git a/src/tv2-common/updatePolicies/syncIngestUpdateToPartInstance.ts b/src/tv2-common/updatePolicies/syncIngestUpdateToPartInstance.ts index b14d28d4b..c385a68fc 100644 --- a/src/tv2-common/updatePolicies/syncIngestUpdateToPartInstance.ts +++ b/src/tv2-common/updatePolicies/syncIngestUpdateToPartInstance.ts @@ -22,7 +22,6 @@ export function syncIngestUpdateToPartInstanceBase( ...freelyEditableLayers, SharedSourceLayers.PgmGraphicsHeadline, SharedSourceLayers.PgmGraphicsIdent, - SharedSourceLayers.PgmGraphicsIdentPersistent, SharedSourceLayers.PgmGraphicsLower, SharedSourceLayers.PgmGraphicsOverlay, SharedSourceLayers.PgmGraphicsTLF, diff --git a/src/tv2-constants/enums.ts b/src/tv2-constants/enums.ts index 8eb2b493d..d7f0f6605 100644 --- a/src/tv2-constants/enums.ts +++ b/src/tv2-constants/enums.ts @@ -116,7 +116,6 @@ export function AdlibTagCutToBox(box: number): AdlibTags { } export enum ControlClasses { - ShowIdentGraphic = 'show_ident_graphic', /** Indicates that a DVE is currently on air */ DVEOnAir = 'dve_on_air', ServerOnAir = 'server_on_air', @@ -148,8 +147,7 @@ export enum AdlibActionType { TAKE_WITH_TRANSITION = 'take_with_transition', RECALL_LAST_LIVE = 'recall_last_live', RECALL_LAST_DVE = 'recall_last_dve', - FADE_DOWN_PERSISTED_AUDIO_LEVELS = 'fade_down_persisted_audio_levels', - PLAY_GRAPHICS = 'play_graphics' + FADE_DOWN_PERSISTED_AUDIO_LEVELS = 'fade_down_persisted_audio_levels' } export enum TallyTags { @@ -237,7 +235,6 @@ export enum SharedSourceLayers { // Graphics PgmGraphicsIdent = 'studio0_graphicsIdent', - PgmGraphicsIdentPersistent = 'studio0_graphicsIdent_persistent', PgmGraphicsTop = 'studio0_graphicsTop', PgmGraphicsLower = 'studio0_graphicsLower', PgmGraphicsHeadline = 'studio0_graphicsHeadline', 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 09d149f28..773c2e71c 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -16,15 +16,7 @@ import { PartDefinitionKam, PieceMetaData } from 'tv2-common' -import { - AbstractLLayer, - AdlibTags, - CueType, - PartType, - SharedGraphicLLayer, - SharedOutputLayers, - SourceType -} from 'tv2-constants' +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' @@ -127,7 +119,8 @@ describe('grafik piece', () => { metaData: literal({ sisyfosPersistMetaData: { sisyfosLayers: [] - } + }, + belongsToRemotePart: false }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, @@ -430,7 +423,8 @@ describe('grafik piece', () => { metaData: literal({ sisyfosPersistMetaData: { sisyfosLayers: [] - } + }, + belongsToRemotePart: false }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, @@ -507,7 +501,8 @@ describe('grafik piece', () => { metaData: literal({ sisyfosPersistMetaData: { sisyfosLayers: [] - } + }, + belongsToRemotePart: false }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, @@ -577,14 +572,15 @@ describe('grafik piece', () => { enable: { start: 0 }, - lifespan: PieceLifespan.OutOnSegmentEnd, + lifespan: PieceLifespan.WithinPart, metaData: literal({ sisyfosPersistMetaData: { sisyfosLayers: [] - } + }, + belongsToRemotePart: false }), outputLayerId: SharedOutputLayers.OVERLAY, - sourceLayerId: SourceLayer.PgmGraphicsIdentPersistent, + sourceLayerId: SourceLayer.PgmGraphicsIdent, content: literal>({ fileName: 'direkte', path: 'direkte', @@ -609,35 +605,6 @@ describe('grafik piece', () => { dskEnableObj ]) }) - }), - literal({ - externalId: partId, - name: 'direkte - KØBENHAVN', - enable: { - start: 0 - }, - lifespan: PieceLifespan.WithinPart, - metaData: literal({ - sisyfosPersistMetaData: { - sisyfosLayers: [] - } - }), - outputLayerId: SharedOutputLayers.OVERLAY, - sourceLayerId: SourceLayer.PgmGraphicsIdent, - content: { - timelineObjects: [ - literal({ - id: '', - enable: { - while: '1' - }, - layer: AbstractLLayer.IdentMarker, - content: { - deviceType: TSR.DeviceType.ABSTRACT - } - }) - ] - } }) ]) }) @@ -685,7 +652,8 @@ describe('grafik piece', () => { metaData: literal({ sisyfosPersistMetaData: { sisyfosLayers: [] - } + }, + belongsToRemotePart: false }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsIdent, @@ -799,7 +767,6 @@ describe('grafik piece', () => { }), outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsTop, - expectedDuration: 4000, tags: ['flow_producer'], uniquenessId: 'gfx_tlftoptlive - Line 1\n - Line 2_studio0_graphicsTop_overlay_flow', content: literal>({ 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 f4b8745f0..54cf0d7e3 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -116,6 +116,7 @@ describe('telefon', () => { sourceLayerId: SourceLayer.PgmGraphicsLower, lifespan: PieceLifespan.WithinPart, metaData: literal({ + belongsToRemotePart: false, sisyfosPersistMetaData: { sisyfosLayers: [] } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts index 11919187c..c040aae4d 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts @@ -25,7 +25,6 @@ export function EvaluateClearGrafiks( ;[ SourceLayer.PgmGraphicsIdent, - SourceLayer.PgmGraphicsIdentPersistent, SourceLayer.PgmGraphicsTop, SourceLayer.PgmGraphicsLower, SourceLayer.PgmGraphicsHeadline, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts index d570349d6..dbd656b19 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphic.ts @@ -33,7 +33,7 @@ export function EvaluateCueGraphic( } if (GraphicIsInternal(parsedCue)) { - CreateInternalGraphic(config, context, pieces, adlibPieces, actions, partId, parsedCue, partDefinition, adlib) + CreateInternalGraphic(config, context, pieces, adlibPieces, partId, parsedCue, partDefinition, adlib) } else if (GraphicIsPilot(parsedCue)) { EvaluateCueGraphicPilot( config, diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 4cd3ae33f..06952aa59 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -119,7 +119,7 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal Date: Wed, 31 Aug 2022 12:31:46 +0200 Subject: [PATCH 178/184] fix: SOF-767 set `length` only when `seek` is truthy because Caspar needs it just for the purpose of seek working --- src/tv2-common/content/server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index f470c042b..5c364ae66 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -95,7 +95,7 @@ function GetServerTimeline( file: contentProps.file, loop: partProps.adLibPix, seek: contentProps.seek, - length: contentProps.clipDuration, + length: contentProps.seek ? contentProps.clipDuration : undefined, playing: true }, metaData: { From 21fd0aa11aab48e93017ed68fd054c498ae6e2e5 Mon Sep 17 00:00:00 2001 From: ianshade Date: Tue, 6 Sep 2022 08:59:08 +0200 Subject: [PATCH 179/184] refactor: SOF-769 remove some assertions and literals; improve return types and other small refactors --- src/__mocks__/context.ts | 67 ++-- src/inews-mixins/playlist.ts | 22 +- .../__tests__/onTimelineGenerate.spec.ts | 65 ++-- src/tv2-common/actions/context.ts | 85 ++++- src/tv2-common/actions/executeAction.ts | 348 ++++++++---------- src/tv2-common/content/dve.ts | 7 +- src/tv2-common/content/server.ts | 10 +- src/tv2-common/cueTiming.ts | 12 +- src/tv2-common/cues/ekstern.ts | 192 +++++----- src/tv2-common/cues/lyd.ts | 70 ++-- src/tv2-common/cues/mixMinus.ts | 28 +- src/tv2-common/evaluateCues.ts | 2 +- src/tv2-common/getSegment.ts | 8 +- .../helpers/__tests__/serverResume.spec.ts | 10 +- src/tv2-common/helpers/abPlayback.ts | 13 +- .../helpers/graphics/InternalGraphic.ts | 76 ++-- .../helpers/graphics/caspar/index.ts | 6 +- .../helpers/graphics/design/index.ts | 60 ++- .../helpers/graphics/internal/index.ts | 17 +- src/tv2-common/helpers/graphics/name.ts | 12 +- .../helpers/graphics/pilot/index.ts | 31 +- src/tv2-common/helpers/graphics/timing.ts | 40 +- src/tv2-common/helpers/graphics/viz/index.ts | 18 +- src/tv2-common/helpers/rundownAdLibActions.ts | 12 +- src/tv2-common/helpers/serverResume.ts | 22 +- .../inewsConversion/converters/ParseBody.ts | 11 +- .../inewsConversion/converters/ParseCue.ts | 6 +- .../converters/__tests__/cue-parser.spec.ts | 20 - src/tv2-common/layers/sourceLayers.ts | 5 +- src/tv2-common/migrations/addKeepAudio.ts | 5 +- .../forceSourceLayerToDefaultsBase.ts | 5 +- src/tv2-common/migrations/hotkeys.ts | 11 +- src/tv2-common/migrations/index.ts | 98 ++--- .../migrations/moveSourcesToTable.ts | 12 +- src/tv2-common/migrations/sourceManifest.ts | 4 +- src/tv2-common/migrations/transitions.ts | 74 ++-- src/tv2-common/onTimelineGenerate.ts | 60 +-- src/tv2-common/parts/effekt.ts | 115 +++--- src/tv2-common/parts/invalid.ts | 6 +- src/tv2-common/parts/kam.ts | 6 +- src/tv2-common/parts/server.ts | 34 +- src/tv2-common/pieces/adlibServer.ts | 4 +- src/tv2-common/pieces/script.ts | 45 ++- src/tv2-common/util.ts | 4 +- .../__tests__/actions.spec.ts | 34 +- .../__tests__/blueprint.spec.ts | 11 +- .../__tests__/layers-check.ts | 6 +- src/tv2_afvd_showstyle/getRundown.ts | 300 +++++++-------- src/tv2_afvd_showstyle/getSegment.ts | 6 +- .../pieces/__tests__/grafikViz.spec.ts | 31 +- .../helpers/pieces/__tests__/lyd.spec.ts | 30 -- .../helpers/pieces/__tests__/telefon.spec.ts | 10 +- .../helpers/pieces/adlib.ts | 54 ++- .../helpers/pieces/clearGrafiks.ts | 58 ++- src/tv2_afvd_showstyle/helpers/pieces/dve.ts | 17 +- .../helpers/pieces/ekstern.ts | 12 +- .../helpers/pieces/graphicBackgroundLoop.ts | 120 +++--- .../helpers/pieces/jingle.ts | 101 +++-- .../helpers/pieces/routing.ts | 56 ++- .../helpers/pieces/showLifecycle.ts | 76 ++-- src/tv2_afvd_showstyle/migrations/index.ts | 6 +- src/tv2_afvd_showstyle/migrations/util.ts | 8 +- src/tv2_afvd_showstyle/parts/cueonly.ts | 5 +- src/tv2_afvd_showstyle/parts/evs.ts | 36 +- src/tv2_afvd_showstyle/parts/grafik.ts | 13 +- src/tv2_afvd_showstyle/parts/intro.ts | 5 +- src/tv2_afvd_showstyle/parts/kam.ts | 156 ++++---- src/tv2_afvd_showstyle/parts/live.ts | 6 +- src/tv2_afvd_showstyle/parts/teknik.ts | 6 +- src/tv2_afvd_showstyle/parts/unknown.ts | 5 +- .../postProcessTimelineObjects.ts | 14 +- src/tv2_afvd_studio/config-manifests.ts | 1 - src/tv2_afvd_studio/getBaseline.ts | 4 +- src/tv2_afvd_studio/helpers/config.ts | 1 - src/tv2_afvd_studio/migrations/devices.ts | 5 +- src/tv2_afvd_studio/migrations/index.ts | 5 +- src/tv2_afvd_studio/migrations/util.ts | 17 +- src/tv2_afvd_studio/onTimelineGenerate.ts | 5 +- .../__tests__/actions.spec.ts | 55 +-- .../cues/OfftubeAdlib.ts | 38 +- src/tv2_offtube_showstyle/cues/OfftubeDVE.ts | 113 +++--- .../cues/OfftubeEkstern.ts | 6 +- .../cues/OfftubeGraphicBackgroundLoop.ts | 112 +++--- .../cues/OfftubeJingle.ts | 117 +++--- .../cues/OfftubePgmClean.ts | 52 ++- src/tv2_offtube_showstyle/getRundown.ts | 236 ++++++------ src/tv2_offtube_showstyle/getSegment.ts | 14 +- .../migrations/hotkeys.ts | 2 +- src/tv2_offtube_showstyle/migrations/index.ts | 6 +- src/tv2_offtube_showstyle/migrations/util.ts | 16 +- .../onTimelineGenerate.ts | 10 +- src/tv2_offtube_showstyle/parts/OfftubeDVE.ts | 6 +- .../parts/OfftubeGrafik.ts | 6 +- src/tv2_offtube_showstyle/parts/OfftubeKam.ts | 154 ++++---- .../parts/OfftubeUnknown.ts | 5 +- .../postProcessTimelineObjects.ts | 10 +- src/tv2_offtube_studio/getBaseline.ts | 6 +- src/tv2_offtube_studio/migrations/devices.ts | 5 +- src/tv2_offtube_studio/migrations/index.ts | 23 +- src/tv2_offtube_studio/migrations/util.ts | 13 +- src/tv2_system/migrations/hotkeys.ts | 7 +- src/tv2_system/migrations/index.ts | 5 +- 102 files changed, 1896 insertions(+), 2099 deletions(-) diff --git a/src/__mocks__/context.ts b/src/__mocks__/context.ts index 0e31148fd..1473f5ca3 100644 --- a/src/__mocks__/context.ts +++ b/src/__mocks__/context.ts @@ -4,7 +4,6 @@ import * as _ from 'underscore' import { BlueprintMappings, ConfigItemValue, - IActionExecutionContext, IBlueprintConfig, IBlueprintMutatablePart, IBlueprintPart, @@ -30,7 +29,7 @@ import { PlaylistTimingType, Time } from '@tv2media/blueprints-integration' -import { literal } from 'tv2-common' +import { ITV2ActionExecutionContext, PieceMetaData } 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' @@ -82,7 +81,6 @@ export class CommonContext implements ICommonContext { id = getHash(this.contextName + '_' + str.toString()) this.hashed[id] = str return id - // return Random.id() } public unhashId(hash: string): string { return this.hashed[hash] || hash @@ -327,7 +325,7 @@ export class SyncIngestUpdateToPartInstanceContext extends RundownUserContext mutatedPiece?: Omit, 'lifespan'> ): IBlueprintPieceInstance { this.syncedPieceInstances.push(pieceInstanceId) - return literal({ + return { _id: pieceInstanceId, piece: { _id: '', @@ -343,24 +341,24 @@ export class SyncIngestUpdateToPartInstanceContext extends RundownUserContext content: mutatedPiece?.content ?? { timelineObjects: [] } }, partInstanceId: '' - }) + } } public insertPieceInstance(piece: IBlueprintPiece): IBlueprintPieceInstance { - return literal({ + return { _id: '', piece: { _id: '', ...piece }, partInstanceId: '' - }) + } } public updatePieceInstance( pieceInstanceId: string, piece: Partial> ): IBlueprintPieceInstance { this.updatedPieceInstances.push(pieceInstanceId) - return literal({ + return { _id: pieceInstanceId, piece: { _id: '', @@ -376,14 +374,14 @@ export class SyncIngestUpdateToPartInstanceContext extends RundownUserContext content: piece.content ?? { timelineObjects: [] } }, partInstanceId: '' - }) + } } public removePieceInstances(...pieceInstanceIds: string[]): string[] { this.removedPieceInstances.push(...pieceInstanceIds) return pieceInstanceIds } public updatePartInstance(props: Partial>): IBlueprintPartInstance { - this.updatedPartInstance = literal({ + this.updatedPartInstance = { _id: '', segmentId: '', part: { @@ -394,7 +392,7 @@ export class SyncIngestUpdateToPartInstanceContext extends RundownUserContext ...props }, rehearsal: false - }) + } return this.updatedPartInstance } @@ -404,13 +402,14 @@ export class SyncIngestUpdateToPartInstanceContext extends RundownUserContext } // tslint:disable-next-line: max-classes-per-file -export class ActionExecutionContext extends ShowStyleUserContext implements IActionExecutionContext { +export class ActionExecutionContext extends ShowStyleUserContext implements ITV2ActionExecutionContext { public currentPart: IBlueprintPartInstance - public currentPieceInstances: IBlueprintPieceInstance[] + public currentPieceInstances: Array> public nextPart: IBlueprintPartInstance | undefined - public nextPieceInstances: IBlueprintPieceInstance[] | undefined + public nextPieceInstances: Array> | undefined public takeAfterExecute: boolean = false + public isTV2Context: true = true constructor( contextName: string, @@ -421,9 +420,9 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct segmentId: string, partId: string, currentPart: IBlueprintPartInstance, - currentPieceInstances: IBlueprintPieceInstance[], + currentPieceInstances: Array>, nextPart?: IBlueprintPartInstance, - nextPieceInstances?: IBlueprintPieceInstance[] + nextPieceInstances?: Array> ) { super(contextName, mappingsDefaults, parseStudioConfig, parseShowStyleConfig, rundownId, segmentId, partId) @@ -446,7 +445,7 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct return this.nextPart } /** Get the PieceInstances for a modifiable PartInstance */ - public async getPieceInstances(part: 'current' | 'next'): Promise { + public async getPieceInstances(part: 'current' | 'next'): Promise>> { if (part === 'current') { return this.currentPieceInstances } @@ -454,7 +453,9 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct return this.nextPieceInstances || [] } /** Get the resolved PieceInstances for a modifiable PartInstance */ - public async getResolvedPieceInstances(_part: 'current' | 'next'): Promise { + public async getResolvedPieceInstances( + _part: 'current' | 'next' + ): Promise>> { return [] } /** Get the last active piece on given layer */ @@ -465,7 +466,7 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct originalOnly?: boolean pieceMetaDataFilter?: any } - ): Promise { + ): Promise | undefined> { return undefined } public async findLastScriptedPieceOnLayer( @@ -474,11 +475,11 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct excludeCurrentPart?: boolean pieceMetaDataFilter?: any } - ): Promise { + ): Promise | undefined> { return undefined } public async getPartInstanceForPreviousPiece(_piece: IBlueprintPieceInstance): Promise { - return literal({ + return { _id: '', segmentId: '', part: { @@ -488,15 +489,18 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct title: '' }, rehearsal: false - }) + } } public async getPartForPreviousPiece(_piece: { _id: string }): Promise { return undefined } /** Creative actions */ /** Insert a piece. Returns id of new PieceInstance. Any timelineObjects will have their ids changed, so are not safe to reference from another piece */ - public async insertPiece(part: 'current' | 'next', piece: IBlueprintPiece): Promise { - const pieceInstance: IBlueprintPieceInstance = { + public async insertPiece( + part: 'current' | 'next', + piece: IBlueprintPiece + ): Promise> { + const pieceInstance: IBlueprintPieceInstance = { _id: '', piece: { _id: '', @@ -517,19 +521,22 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct public async updatePieceInstance( _pieceInstanceId: string, piece: Partial> - ): Promise { + ): Promise> { return { _id: '', piece: { _id: '', - ...(piece as IBlueprintPiece) + ...(piece as IBlueprintPiece) }, partInstanceId: '' } } /** Insert a queued part to follow the current part */ - public async queuePart(part: IBlueprintPart, pieces: IBlueprintPiece[]): Promise { - const instance = literal({ + public async queuePart( + part: IBlueprintPart, + pieces: Array> + ): Promise { + const instance: IBlueprintPartInstance = { _id: '', segmentId: this.notesSegmentId || '', part: { @@ -538,10 +545,10 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct segmentId: this.notesSegmentId || '' }, rehearsal: false - }) + } this.nextPart = instance - this.nextPieceInstances = pieces.map(p => ({ + this.nextPieceInstances = pieces.map>(p => ({ _id: (Date.now() * Math.random()).toString(), piece: { _id: '', diff --git a/src/inews-mixins/playlist.ts b/src/inews-mixins/playlist.ts index 0742f164f..9da91bec0 100644 --- a/src/inews-mixins/playlist.ts +++ b/src/inews-mixins/playlist.ts @@ -93,13 +93,13 @@ function getRundownPlaylistInfoINewsPlaylist( resultPlaylist: BlueprintResultRundownPlaylist ): BlueprintResultRundownPlaylist { const result: BlueprintResultOrderedRundowns = {} - return literal({ + return { ...resultPlaylist, order: rundowns.reduce((prev, curr) => { prev[curr.externalId] = (curr.metaData as RundownMetaData).rank return prev }, result) - }) + } } type GetRundownMixin = ( @@ -152,15 +152,15 @@ export function GetRundownPlaylistInfoWithMixins( expectedStart: lastRundownTiming.expectedStart } } - let result = - (getRundownPlaylistInfo ? getRundownPlaylistInfo(context, rundowns, '') : undefined) ?? - literal({ - playlist: literal({ - name: (rundowns[0] ?? { name: '' }).name, - timing - }), - order: null - }) + let result: BlueprintResultRundownPlaylist = (getRundownPlaylistInfo + ? getRundownPlaylistInfo(context, rundowns, '') + : undefined) ?? { + playlist: literal({ + name: (rundowns[0] ?? { name: '' }).name, + timing + }), + order: null + } for (const mixin of mixins) { result = mixin(context, rundowns, result) diff --git a/src/tv2-common/__tests__/onTimelineGenerate.spec.ts b/src/tv2-common/__tests__/onTimelineGenerate.spec.ts index 9c3b39682..015636d75 100644 --- a/src/tv2-common/__tests__/onTimelineGenerate.spec.ts +++ b/src/tv2-common/__tests__/onTimelineGenerate.spec.ts @@ -5,7 +5,6 @@ import { PieceMetaData, SisyfosPersistMetaData } from '../onTimelineGenerate' -import { literal } from '../util' const LAYER_THAT_WANTS_TO_BE_PERSISTED = 'layerThatWantsToBePersisted' const LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY: SisyfosPersistMetaData['sisyfosLayers'] = [ @@ -16,7 +15,7 @@ const LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY: SisyfosPersistMetaData['sisyfosLa describe('onTimelineGenerate', () => { describe('createSisyfosPersistedLevelsTimelineObject', () => { it('has one layer to persist, piece accept persist - timelineObject with layer is added', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('currentPiece', 10, undefined, true, true) ] @@ -29,7 +28,7 @@ describe('onTimelineGenerate', () => { }) it('has layer to persist, timelineObject with correct Sisyfos information is added', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('currentPiece', 10, undefined, true, true) ] @@ -42,7 +41,7 @@ describe('onTimelineGenerate', () => { }) it('should persist non-VO layers with isPgm 1', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('currentPiece', 10, undefined, true, true) ] @@ -51,7 +50,7 @@ describe('onTimelineGenerate', () => { }) it('should persist only current piece layer when piece wants to persist but dont accept', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('previousPiece', 0, 10, true, true), createPieceInstance('currentPiece', 10, undefined, true, false) ] @@ -62,7 +61,7 @@ describe('onTimelineGenerate', () => { }) it('should not persist anything when current piece dont accept and dont want to persist', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('previousPiece', 0, 10, true, true), createPieceInstance('currentPiece', 10, undefined, false, false) ] @@ -73,7 +72,7 @@ describe('onTimelineGenerate', () => { }) it('should persist when previous piece does not accept persist, but current does accept', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('previousPiece', 0, 10, true, false), createPieceInstance('currentPiece', 10, undefined, false, true) ] @@ -84,7 +83,9 @@ describe('onTimelineGenerate', () => { }) it('should persist when current piece accepts persist and duration is not undefined', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [createPieceInstance('currentPiece', 0, 5, false, true)] + const resolvedPieces: Array> = [ + createPieceInstance('currentPiece', 0, 5, false, true) + ] const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, LAYERS_THAT_WANTS_TO_BE_PERSISTED_ARRAY) @@ -100,7 +101,9 @@ describe('onTimelineGenerate', () => { secondLayerThatWantToBePersisted, thirdLayerThatWantToBePersisted ] - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [createPieceInstance('currentPiece', 0, 5, true, true)] + const resolvedPieces: Array> = [ + createPieceInstance('currentPiece', 0, 5, true, true) + ] const result = createSisyfosPersistedLevelsTimelineObject(resolvedPieces, layersThatWantToBePersisted) @@ -116,7 +119,7 @@ describe('onTimelineGenerate', () => { }) it('cuts to executeAction that dont accept persist, dont persist layers', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('previousPieceNotExecuteAction', 0, 10, true, true), createExecuteActionPieceInstance('currentPieceIsExecuteAction', 10, undefined, false, false) ] @@ -127,7 +130,7 @@ describe('onTimelineGenerate', () => { }) it('cuts to executeAction that accept persist from piece that accept, add persist timelineObject containing all layers that want to be persisted plus previous piece layers', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('previousPieceNotExecuteAction', 0, 10, true, true), createExecuteActionPieceInstance('currentPieceIsExecuteAction', 10, undefined, false, true) ] @@ -141,7 +144,7 @@ describe('onTimelineGenerate', () => { }) it('cuts to executionAction that accept from piece that dont accept, add persist timelineObject that only contain previous piece layers', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('previousPieceNotExecuteAction', 0, 10, true, false), createExecuteActionPieceInstance('currentPieceIsExecuteAction', 10, undefined, false, true) ] @@ -153,7 +156,7 @@ describe('onTimelineGenerate', () => { }) it('cuts to executeAction that accept persist from piece that dont want to persist and dont accept persist, dont persist any layers', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('previousPieceNotExecuteAction', 0, 10, false, false), createExecuteActionPieceInstance('currentPieceIsExecuteAction', 10, undefined, false, true) ] @@ -164,7 +167,7 @@ describe('onTimelineGenerate', () => { }) it('cuts to executeAction that accept persist from piece that dont want to persist and that accept persist, persist previous layers', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('previousPieceNotExecuteAction', 0, 10, false, true), createExecuteActionPieceInstance('currentPieceIsExecuteAction', 10, undefined, false, true) ] @@ -178,7 +181,7 @@ describe('onTimelineGenerate', () => { }) it('cuts from executeAction that dont accept to piece that accepts, dont persist', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createExecuteActionPieceInstance('previousPieceIsExecuteAction', 0, 10, false, false), createPieceInstance('currentPieceNotExecuteAction', 10, undefined, false, true) ] @@ -189,7 +192,7 @@ describe('onTimelineGenerate', () => { }) it('cuts from executeAction that dont accept to piece that dont accepts, dont persist layers', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createExecuteActionPieceInstance('previousPieceIsExecuteAction', 0, 10, false, false), createPieceInstance('currentPieceNotExecuteAction', 10, undefined, false, false) ] @@ -200,7 +203,7 @@ describe('onTimelineGenerate', () => { }) it('cuts from executeAction that accept to piece that dont accepts, dont persist layers', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createExecuteActionPieceInstance('previousPieceIsExecuteAction', 0, 10, false, true), createPieceInstance('currentPieceNotExecuteAction', 10, undefined, false, false) ] @@ -211,7 +214,7 @@ describe('onTimelineGenerate', () => { }) it('cuts from executeAction that accept to piece that accepts, add persist timelineObject with previous layer before executeAction + new layer', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('firstPiece', 0, 5, true, true), createExecuteActionPieceInstance('previousPieceIsExecuteAction', 5, 5, false, true, { acceptPersistAudio: true, @@ -226,7 +229,7 @@ describe('onTimelineGenerate', () => { }) it('cuts from piece that wants to persist to executeAction that do not accept to piece that accepts, do not persist', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('firstPiece', 0, 5, true, true), createExecuteActionPieceInstance('previousPieceIsExecuteAction', 5, 5, false, true, { acceptPersistAudio: false, @@ -241,7 +244,7 @@ describe('onTimelineGenerate', () => { }) it('cuts from piece that wants to persist to executeAction that accepts to another executeAction that accepts, persist layer from first piece', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('firstPiece', 0, 5, true, true), createExecuteActionPieceInstance('executeAction', 5, undefined, false, true, { acceptPersistAudio: true, @@ -260,7 +263,7 @@ describe('onTimelineGenerate', () => { }) it('cuts from piece that wants to persist to executeAction that do not accept to another executeAction that accepts, dont persist any layers', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('firstPiece', 0, 5, true, true), createExecuteActionPieceInstance('executeAction', 5, undefined, false, true, { acceptPersistAudio: true, @@ -278,7 +281,7 @@ describe('onTimelineGenerate', () => { }) it('should not contain any duplicate layers to persist', () => { - const resolvedPieces: IBlueprintResolvedPieceInstance[] = [ + const resolvedPieces: Array> = [ createPieceInstance('piece', 0, 5, true, true), createPieceInstance('piece', 5, undefined, true, true) ] @@ -296,21 +299,21 @@ function createPieceInstance( duration: number | undefined, wantToPersistAudio: boolean, acceptPersistAudio: boolean -): IBlueprintResolvedPieceInstance { +): IBlueprintResolvedPieceInstance { return { resolvedStart: start, resolvedDuration: duration, piece: { name, - metaData: literal({ + metaData: { sisyfosPersistMetaData: { sisyfosLayers: [name], wantsToPersistAudio: wantToPersistAudio, acceptPersistAudio } - }) - } as IBlueprintPieceDB - } as IBlueprintResolvedPieceInstance + } + } as IBlueprintPieceDB + } as IBlueprintResolvedPieceInstance } function createExecuteActionPieceInstance( @@ -320,7 +323,7 @@ function createExecuteActionPieceInstance( wantToPersistAudio: boolean, acceptPersistAudio: boolean, previousMetaData?: SisyfosPersistMetaData -): IBlueprintResolvedPieceInstance { +): IBlueprintResolvedPieceInstance { return { resolvedStart: start, resolvedDuration: duration, @@ -332,8 +335,8 @@ function createExecuteActionPieceInstance( wantsToPersistAudio: wantToPersistAudio, acceptPersistAudio, previousPersistMetaDataForCurrentPiece: previousMetaData - } as SisyfosPersistMetaData + } } - } as IBlueprintPieceDB - } as IBlueprintResolvedPieceInstance + } as IBlueprintPieceDB + } as IBlueprintResolvedPieceInstance } diff --git a/src/tv2-common/actions/context.ts b/src/tv2-common/actions/context.ts index 21e2da47f..e0a8ad5b7 100644 --- a/src/tv2-common/actions/context.ts +++ b/src/tv2-common/actions/context.ts @@ -11,11 +11,42 @@ import { PackageInfo, Time } from '@tv2media/blueprints-integration' -import { literal, PartMetaData } from 'tv2-common' +import { literal, PartMetaData, PieceMetaData } from 'tv2-common' 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>> + + findLastPieceOnLayer( + sourceLayerId: string | string[], + options?: { + excludeCurrentPart?: boolean + originalOnly?: boolean + pieceMetaDataFilter?: any + } + ): Promise | undefined> + findLastScriptedPieceOnLayer( + sourceLayerId: string | string[], + options?: { + excludeCurrentPart?: boolean + pieceMetaDataFilter?: any + } + ): Promise | undefined> + getPartInstanceForPreviousPiece(piece: IBlueprintPieceInstance): Promise + getPartForPreviousPiece(piece: IBlueprintPieceDB): Promise + insertPiece( + part: 'current' | 'next', + piece: IBlueprintPiece + ): Promise> + updatePieceInstance( + pieceInstanceId: string, + piece: Partial> + ): Promise> + queuePart(part: IBlueprintPart, pieces: Array>): Promise + updatePartInstance(part: 'current' | 'next', props: Partial): Promise } class TV2ActionExecutionContext implements ITV2ActionExecutionContext { @@ -35,42 +66,48 @@ class TV2ActionExecutionContext implements ITV2ActionExecutionContext { return this.coreContext.getPartInstance(part) } - public async getPieceInstances(part: 'current' | 'next'): Promise>> { - return this.coreContext.getPieceInstances(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) + ): Promise>> { + return this.coreContext.getResolvedPieceInstances(part) as Promise< + Array> + > } public async findLastPieceOnLayer( sourceLayerId: string | string[], options?: { - excludeCurrentPart?: boolean | undefined - originalOnly?: boolean | undefined + excludeCurrentPart?: boolean + originalOnly?: boolean pieceMetaDataFilter?: any } - ): Promise | undefined> { - return this.coreContext.findLastPieceOnLayer(sourceLayerId, options) + ): Promise | undefined> { + return this.coreContext.findLastPieceOnLayer(sourceLayerId, options) as Promise< + IBlueprintPieceInstance | undefined + > } public async findLastScriptedPieceOnLayer( sourceLayerId: string | string[], - options?: { excludeCurrentPart?: boolean | undefined; pieceMetaDataFilter?: any } - ): Promise | undefined> { - return this.coreContext.findLastScriptedPieceOnLayer(sourceLayerId, options) + options?: { excludeCurrentPart?: boolean; pieceMetaDataFilter?: any } + ): Promise | undefined> { + return this.coreContext.findLastScriptedPieceOnLayer(sourceLayerId, options) as Promise< + IBlueprintPiece | undefined + > } public async getPartInstanceForPreviousPiece( - piece: IBlueprintPieceInstance + piece: IBlueprintPieceInstance ): Promise> { return this.coreContext.getPartInstanceForPreviousPiece(piece) } public async getPartForPreviousPiece( - piece: IBlueprintPieceDB + piece: IBlueprintPieceDB ): Promise | undefined> { return this.coreContext.getPartForPreviousPiece(piece) } @@ -157,7 +194,10 @@ class TV2ActionExecutionContext implements ITV2ActionExecutionContext { return this.coreContext.moveNextPart(partDelta, segmentDelta) } - public async queuePart(rawPart: IBlueprintPart, rawPieces: IBlueprintPiece[]): Promise { + public async queuePart( + rawPart: IBlueprintPart, + rawPieces: Array> + ): Promise { this.modifiedParts.add('next') return this.coreContext.queuePart(rawPart, rawPieces) @@ -169,9 +209,12 @@ class TV2ActionExecutionContext implements ITV2ActionExecutionContext { return this.coreContext.removePieceInstances(part, pieceInstanceIds) } - public async insertPiece(part: 'current' | 'next', piece: IBlueprintPiece): Promise { + public async insertPiece( + part: 'current' | 'next', + piece: IBlueprintPiece + ): Promise> { this.modifiedParts.add(part) - return this.coreContext.insertPiece(part, piece) + return this.coreContext.insertPiece(part, piece) as Promise> } public async updatePartInstance( @@ -184,8 +227,8 @@ class TV2ActionExecutionContext implements ITV2ActionExecutionContext { public async updatePieceInstance( pieceInstanceId: string, - piece: Partial - ): Promise { + piece: Partial> + ): Promise> { const currentPieceInstances = await this.coreContext.getPieceInstances('current') if (currentPieceInstances.map(p => p._id).includes(pieceInstanceId)) { this.modifiedParts.add('current') @@ -197,7 +240,9 @@ class TV2ActionExecutionContext implements ITV2ActionExecutionContext { } // Regardless of above, let core handle errors - return this.coreContext.updatePieceInstance(pieceInstanceId, piece) + return this.coreContext.updatePieceInstance(pieceInstanceId, piece) as Promise< + IBlueprintPieceInstance + > } /** diff --git a/src/tv2-common/actions/executeAction.ts b/src/tv2-common/actions/executeAction.ts index a9f8e0a34..1b2420ca5 100644 --- a/src/tv2-common/actions/executeAction.ts +++ b/src/tv2-common/actions/executeAction.ts @@ -10,7 +10,6 @@ import { IBlueprintPieceDB, IBlueprintPieceGeneric, IBlueprintPieceInstance, - IBlueprintResolvedPieceInstance, IShowStyleUserContext, PieceLifespan, SplitsContent, @@ -371,7 +370,7 @@ async function getExistingTransition< return } -function sanitizePieceId(piece: IBlueprintPieceDB): IBlueprintPiece { +function sanitizePieceId(piece: IBlueprintPieceDB): IBlueprintPiece { return _.omit(piece, ['_id', 'partId', 'infiniteId', 'playoutDuration']) } @@ -379,7 +378,7 @@ export async function getPiecesToPreserve( context: ITV2ActionExecutionContext, adlibLayers: string[], ignoreLayers: string[] -): Promise { +): Promise>> { const currentPartSegmentId = await context.getPartInstance('current').then(partInstance => partInstance?.segmentId) const nextPartSegmentId = await context.getPartInstance('next').then(partInstance => partInstance?.segmentId) @@ -395,9 +394,9 @@ export async function getPiecesToPreserve( 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 => p.piece) .map(p => sanitizePieceStart(p)) - .map(p => sanitizePieceId(p as IBlueprintPieceDB)) + .map(p => sanitizePieceId(p as IBlueprintPieceDB)) }) } @@ -479,8 +478,8 @@ async function executeActionSelectServerClip< let part = basePart.part.part - const grafikPieces: IBlueprintPiece[] = [] - const effektPieces: IBlueprintPiece[] = [] + const grafikPieces: Array> = [] + const effektPieces: Array> = [] part = { ...part, @@ -517,8 +516,8 @@ async function executeActionSelectServerClip< } await context.queuePart(part, [ - activeServerPiece, - serverDataStore, + activeServerPiece as IBlueprintPiece, // @todo: get rid of these casts + serverDataStore as IBlueprintPiece, ...grafikPieces, ...(settings.SelectedAdlibs ? await getPiecesToPreserve(context, settings.SelectedAdlibs.SELECTED_ADLIB_LAYERS, [ @@ -602,7 +601,7 @@ async function executeActionSelectDVE< start = start ? start : 0 const end = parsedCue.end ? CalculateTime(parsedCue.end) : undefined - const metaData = literal({ + const metaData: DVEPieceMetaData = { mediaPlayerSessions: dveContainsServer(parsedCue.sources) ? [externalId] : [], sources: parsedCue.sources, config: rawTemplate, @@ -610,9 +609,9 @@ async function executeActionSelectDVE< sisyfosLayers: [] }, userData - }) + } - let dvePiece = literal({ + let dvePiece: IBlueprintPiece = { externalId, name: `${parsedCue.template}`, enable: { @@ -633,7 +632,7 @@ async function executeActionSelectDVE< GetTagForDVENext(userData.segmentExternalId, parsedCue.template, parsedCue.sources), TallyTags.DVE_IS_LIVE ] - }) + } dvePiece = await cutServerToBox(context, settings, dvePiece) @@ -659,17 +658,17 @@ async function cutServerToBox< >( context: ITV2ActionExecutionContext, settings: ActionExecutionSettings, - newDvePiece: IBlueprintPiece, + newDvePiece: IBlueprintPiece, containedServerBefore?: boolean, modifiesCurrent?: boolean -): Promise { +): Promise> { // Check if DVE should continue server + copy server properties if (!newDvePiece.metaData) { return newDvePiece } - const meta = newDvePiece.metaData as DVEPieceMetaData + const meta = newDvePiece.metaData const containsServer = dveContainsServer(meta.sources) @@ -731,7 +730,7 @@ async function cutServerToBox< newDvePiece.content.timelineObjects[ssrcObjIndex] = ssrcObj newDvePiece.content.timelineObjects.push(EnableServer(existingCasparObj.metaData.mediaPlayerSession)) - ;(newDvePiece.metaData as any).mediaPlayerSessions = [existingCasparObj.metaData.mediaPlayerSession] + newDvePiece.metaData.mediaPlayerSessions = [existingCasparObj.metaData.mediaPlayerSession] if (!containedServerBefore) { startServerMetaData(context, meta, modifiesCurrent) @@ -785,11 +784,13 @@ async function executeActionSelectDVELayout< const nextPart = await context.getPartInstance('next') - const nextDVE = await context + const nextDVE = (await context .getPieceInstances('next') - .then(nextPieceInstances => nextPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE)) + .then(nextPieceInstances => nextPieceInstances.find(p => p.piece.sourceLayerId === settings.SourceLayers.DVE))) as + | IBlueprintPieceInstance + | undefined - const meta = nextDVE?.piece.metaData as DVEPieceMetaData + 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) @@ -798,27 +799,27 @@ async function executeActionSelectDVELayout< return } - const newMetaData = literal({ + const newMetaData: DVEPieceMetaData = { sources, config: userData.config, sisyfosPersistMetaData: { sisyfosLayers: [] }, - userData: literal({ + userData: { type: AdlibActionType.SELECT_DVE, - config: literal({ + config: { type: CueType.DVE, template: userData.config.DVEName, sources, labels: [], iNewsCommand: `DVE=${userData.config.DVEName}` - }), + }, videoId: undefined, segmentExternalId: '' - }) - }) + } + } - let newDVEPiece = literal({ + let newDVEPiece: IBlueprintPiece = { externalId, enable: { start: 0 @@ -829,7 +830,7 @@ async function executeActionSelectDVELayout< outputLayerId: SharedOutputLayers.PGM, metaData: newMetaData, content: content.content - }) + } newDVEPiece = await cutServerToBox(context, settings, newDVEPiece) @@ -849,16 +850,16 @@ async function executeActionSelectDVELayout< ) } - const newMetaData2 = literal({ + const newMetaData2: DVEPieceMetaData = { ...meta, config: userData.config, sisyfosPersistMetaData: { sisyfosLayers: [] } - }) + } const pieceContent = MakeContentDVE2(context, config, userData.config, {}, meta.sources, settings.DVEGeneratorOptions) - let dvePiece: IBlueprintPiece = { + let dvePiece: IBlueprintPiece = { ...nextDVE.piece, content: pieceContent.content, metaData: newMetaData2, @@ -896,9 +897,9 @@ async function startNewDVELayout< context: ITV2ActionExecutionContext, config: ShowStyleConfig, settings: ActionExecutionSettings, - dvePiece: IBlueprintPiece, + dvePiece: IBlueprintPiece, pieceContent: WithTimeline, - meta: PieceMetaData & DVEPieceMetaData, + metaData: DVEPieceMetaData, templateName: string, _sources: CueDefinitionDVE['sources'], externalId: string, @@ -908,8 +909,8 @@ async function startNewDVELayout< ) { settings.postProcessPieceTimelineObjects(context, config, dvePiece, false) - const dveDataStore = settings.SelectedAdlibs.SourceLayer.DVE - ? literal({ + const dveDataStore: IBlueprintPiece | undefined = settings.SelectedAdlibs.SourceLayer.DVE + ? { externalId, name: templateName, enable: { @@ -918,7 +919,7 @@ async function startNewDVELayout< outputLayerId: settings.SelectedAdlibs.OutputLayer.SelectedAdLib, sourceLayerId: settings.SelectedAdlibs.SourceLayer.DVE, lifespan: PieceLifespan.OutOnSegmentEnd, - metaData: meta, + metaData, tags: [nextTag], content: { ...pieceContent, @@ -933,16 +934,16 @@ async function startNewDVELayout< ) .map(obj => ({ ...obj, priority: obj.priority ?? 1 / 2 })) } - }) + } : undefined if (replacePieceInstancesOrQueue === 'queue') { - const newPart = literal({ + const newPart: IBlueprintPart = { externalId, title: templateName, metaData: {}, expectedDuration: 0 - }) + } const currentPieceInstances = await context.getPieceInstances('current') // If a DVE is not on air, but a layout is selected, stop the selected layout and replace with the new one. @@ -950,7 +951,7 @@ async function startNewDVELayout< 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.stopPieceInstances([dataPiece._id]) @@ -1026,7 +1027,7 @@ async function executeActionSelectJingle< jingle.EndAlpha ) - const piece = literal({ + const piece: IBlueprintPiece = { externalId: `${externalId}-JINGLE`, name: userData.clip, enable: { @@ -1043,41 +1044,19 @@ async function executeActionSelectJingle< TallyTags.JINGLE_IS_LIVE, TallyTags.JINGLE ] - }) - - const jingleDataStore = settings.SelectedAdlibs.SourceLayer.Effekt - ? literal({ - externalId, - name: userData.clip, - enable: { - start: 0 - }, - outputLayerId: settings.SelectedAdlibs.OutputLayer.SelectedAdLib, - sourceLayerId: settings.SelectedAdlibs.SourceLayer.Effekt, - lifespan: PieceLifespan.WithinPart, - metaData: { - userData - }, - content: { - ...pieceContent, - timelineObjects: [] - }, - tags: [GetTagForJingleNext(userData.segmentExternalId, userData.clip)] - }) - : undefined + } settings.postProcessPieceTimelineObjects(context, config, piece, false) - const part = literal({ + const part: IBlueprintPart = { externalId, title: `JINGLE ${userData.clip}`, metaData: {}, ...props - }) + } await context.queuePart(part, [ piece, - ...(jingleDataStore ? [] : []), ...(settings.SelectedAdlibs ? await getPiecesToPreserve( context, @@ -1105,12 +1084,12 @@ async function executeActionCutToCamera< const externalId = generateExternalId(context, actionId, [userData.sourceDefinition.name]) - const part = literal({ + const part: IBlueprintPart = { externalId, title: userData.sourceDefinition.name, metaData: {}, expectedDuration: 0 - }) + } const sourceInfoCam = findSourceInfo(config.sources, userData.sourceDefinition) if (sourceInfoCam === undefined) { @@ -1127,7 +1106,7 @@ async function executeActionCutToCamera< const camSisyfos = GetSisyfosTimelineObjForCamera(config, sourceInfoCam, false) - const kamPiece = literal({ + const kamPiece: IBlueprintPiece = { externalId, name: part.title, enable: { start: 0 }, @@ -1135,11 +1114,11 @@ async function executeActionCutToCamera< sourceLayerId: settings.SourceLayers.Cam, lifespan: PieceLifespan.WithinPart, metaData: { - sisyfosPersistMetaData: literal({ + sisyfosPersistMetaData: { sisyfosLayers: [], acceptPersistAudio: sourceInfoCam.acceptPersistAudio, isPieceInjectedInPart: true - }) + } }, tags: [GetTagForKam(userData.sourceDefinition)], content: { @@ -1162,7 +1141,7 @@ async function executeActionCutToCamera< ...camSisyfos ]) } - }) + } settings.postProcessPieceTimelineObjects(context, config, kamPiece, false) @@ -1180,8 +1159,8 @@ async function executeActionCutToCamera< } else if (currentKam) { kamPiece.externalId = currentKam.piece.externalId kamPiece.enable = currentKam.piece.enable - const currentMetaData = currentKam.piece.metaData as PieceMetaData - const metaData = kamPiece.metaData as PieceMetaData + const currentMetaData = currentKam.piece.metaData! + const metaData = kamPiece.metaData! metaData.sisyfosPersistMetaData!.previousPersistMetaDataForCurrentPiece = currentMetaData.sisyfosPersistMetaData await stopGraphicPiecesThatShouldEndWithPart(context, currentPieceInstances) @@ -1224,7 +1203,7 @@ async function stopGraphicPiecesThatShouldEndWithPart( ) } -function isGraphicThatShouldEndWithPart(pieceInstance: IBlueprintPieceInstance): unknown { +function isGraphicThatShouldEndWithPart(pieceInstance: IBlueprintPieceInstance): boolean { return ( pieceInstance.piece.lifespan === PieceLifespan.WithinPart && !pieceInstance.stoppedPlayback && @@ -1247,12 +1226,12 @@ async function executeActionCutToRemote< const title = userData.sourceDefinition.name - const part = literal({ + const part: IBlueprintPart = { externalId, title, metaData: {}, expectedDuration: 0 - }) + } const sourceInfo = findSourceInfo(config.sources, userData.sourceDefinition) if (sourceInfo === undefined) { @@ -1271,7 +1250,7 @@ async function executeActionCutToRemote< } : { sisyfosLayers: [] } - const remotePiece = literal({ + const remotePiece: IBlueprintPiece = { externalId, name: title, enable: { @@ -1305,7 +1284,7 @@ async function executeActionCutToRemote< ...eksternSisyfos ]) } - }) + } settings.postProcessPieceTimelineObjects(context, config, remotePiece, false) @@ -1349,21 +1328,20 @@ async function executeActionCutSourceToBox< ) let modify: undefined | 'current' | 'next' - let modifiedPiece: IBlueprintPieceInstance | undefined + let modifiedPiece: IBlueprintPieceInstance | undefined let modifiedDataStore: IBlueprintPieceInstance | undefined if (currentDVE && !currentDVE.stoppedPlayback) { modify = 'current' - modifiedPiece = currentDVE + modifiedPiece = currentDVE as IBlueprintPieceInstance modifiedDataStore = currentDataStore } else if (nextDVE) { modify = 'next' - modifiedPiece = nextDVE + modifiedPiece = nextDVE as IBlueprintPieceInstance modifiedDataStore = nextDataStore } - const meta: (DVEPieceMetaData & PieceMetaData) | undefined = modifiedPiece?.piece.metaData as PieceMetaData & - DVEPieceMetaData + const meta = modifiedPiece?.piece.metaData if ( !modifiedPiece || @@ -1405,7 +1383,11 @@ async function executeActionCutSourceToBox< mediaPlayerSession ) - let newDVEPiece: IBlueprintPiece = { ...modifiedPiece.piece, content: newPieceContent.content, metaData: meta } + let newDVEPiece: IBlueprintPiece = { + ...modifiedPiece.piece, + content: newPieceContent.content, + metaData: meta + } if (!containsServerBefore || !containsServerAfter) { newDVEPiece = await cutServerToBox(context, settings, newDVEPiece, !!containsServerBefore, modify === 'current') } @@ -1429,10 +1411,10 @@ async function executeActionCutSourceToBox< } interface PiecesBySourceLayer { - [key: string]: IBlueprintPieceInstance[] + [key: string]: Array> } -function groupPiecesBySourceLayer(pieceInstances: IBlueprintPieceInstance[]): PiecesBySourceLayer { +function groupPiecesBySourceLayer(pieceInstances: Array>): PiecesBySourceLayer { const piecesBySourceLayer: PiecesBySourceLayer = {} pieceInstances.forEach(piece => { if (!piecesBySourceLayer[piece.piece.sourceLayerId]) { @@ -1509,7 +1491,7 @@ async function executeActionTakeWithTransition< ) { const externalId = generateExternalId(context, actionId, [userData.variant.type]) - const nextPieces: IBlueprintPieceInstance[] = await context.getPieceInstances('next') + const nextPieces = await context.getPieceInstances('next') const nextPiecesBySourceLayer = groupPiecesBySourceLayer(nextPieces) const primaryPiece = findPrimaryPieceUsingPriority(settings, nextPiecesBySourceLayer) @@ -1559,7 +1541,7 @@ async function executeActionTakeWithTransition< await context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) - const cutTransitionPiece: IBlueprintPiece = { + const cutTransitionPiece: IBlueprintPiece = { enable: { start: 0, duration: 1000 @@ -1592,7 +1574,7 @@ async function executeActionTakeWithTransition< await context.updatePieceInstance(primaryPiece._id, primaryPiece.piece) const config = settings.getConfig(context) - const pieces: IBlueprintPiece[] = [] + const pieces: Array> = [] partProps = CreateEffektForPartInner( context, config, @@ -1623,7 +1605,7 @@ async function executeActionTakeWithTransition< timelineObjectIndex ) - const blueprintPiece: IBlueprintPiece = CreateMixTransitionBlueprintPieceForPart( + const blueprintPiece = CreateMixTransitionBlueprintPieceForPart( externalId, userData.variant.frames, settings.SourceLayers.Effekt @@ -1645,7 +1627,7 @@ async function executeActionTakeWithTransition< primaryPiece, timelineObjectIndex ) - const blueprintPiece: IBlueprintPiece = CreateDipTransitionBlueprintPieceForPart( + const blueprintPiece = CreateDipTransitionBlueprintPieceForPart( externalId, userData.variant.frames, settings.SourceLayers.Effekt @@ -1668,7 +1650,7 @@ async function updateTimelineObjectMeTransition( timelineObject: TSR.TimelineObjAtemME, transitionStyle: TSR.AtemTransitionStyle, transitionSettings: TSR.AtemTransitionSettings, - pieceInstance: IBlueprintPieceInstance, + pieceInstance: IBlueprintPieceInstance, indexOfTimelineObject: number ): Promise { timelineObject.content.me.transition = transitionStyle @@ -1681,7 +1663,7 @@ async function updateTimelineObjectMeTransition( async function findPieceToRecoverDataFrom( context: ITV2ActionExecutionContext, dataStoreLayers: string[] -): Promise<{ piece: IBlueprintPieceInstance; part: 'current' | 'next' } | undefined> { +): Promise<{ piece: IBlueprintPieceInstance; part: 'current' | 'next' } | undefined> { const pieces = await Promise.all([context.getPieceInstances('current'), context.getPieceInstances('next')]) const currentPieces = pieces[0] const nextPieces = pieces[1] @@ -1690,7 +1672,7 @@ async function findPieceToRecoverDataFrom( const nextServer = nextPieces.find(p => dataStoreLayers.includes(p.piece.sourceLayerId)) - let pieceToRecoverDataFrom: IBlueprintPieceInstance | undefined + let pieceToRecoverDataFrom: IBlueprintPieceInstance | undefined let part: 'current' | 'next' = 'current' @@ -1698,7 +1680,6 @@ async function findPieceToRecoverDataFrom( part = 'next' pieceToRecoverDataFrom = nextServer } else if (currentServer) { - part = 'current' pieceToRecoverDataFrom = currentServer } @@ -1738,7 +1719,7 @@ async function findMediaPlayerSessions( } } - const sessions = (mediaPlayerSessionPiece.piece.piece.metaData as any)?.mediaPlayerSessions + const sessions = mediaPlayerSessionPiece.piece.piece.metaData?.mediaPlayerSessions return { // Assume there will be only one session @@ -1875,12 +1856,12 @@ async function executeActionRecallLastLive< const externalId = generateExternalId(context, actionId, [lastLive.piece.name]) - const part = literal({ + const part: IBlueprintPart = { externalId, title: lastLive.piece.name - }) + } - const pieces: IBlueprintPiece[] = [] + const pieces: Array> = [] pieces.push({ ...lastLive.piece, externalId, @@ -1916,12 +1897,9 @@ async function executeActionRecallLastDVE< return } - const lastPlayedScheduledDVE: IBlueprintPieceInstance | undefined = await context.findLastPieceOnLayer( - settings.SourceLayers.DVE, - { - originalOnly: true - } - ) + const lastPlayedScheduledDVE = (await context.findLastPieceOnLayer(settings.SourceLayers.DVE, { + originalOnly: true + })) as IBlueprintPieceInstance | undefined const isLastPlayedAScheduledDVE: boolean = !lastPlayedScheduledDVE?.dynamicallyInserted if (lastPlayedScheduledDVE && isLastPlayedAScheduledDVE) { @@ -1936,16 +1914,16 @@ async function executeActionFadeDownPersistedAudioLevels< ShowStyleConfig extends TV2BlueprintConfigBase >(context: ITV2ActionExecutionContext, _settings: ActionExecutionSettings) { const fadeSisyfosMetaData = await createFadeSisyfosLevelsMetaData(context) - const resetSisyfosPersistedLevelsPiece: IBlueprintPiece = { + const resetSisyfosPersistedLevelsPiece: IBlueprintPiece = { externalId: 'fadeSisyfosPersistedLevelsDown', name: FADE_SISYFOS_LEVELS_PIECE_NAME, outputLayerId: '', sourceLayerId: '', enable: { start: 'now' }, lifespan: PieceLifespan.WithinPart, - metaData: literal({ + metaData: { sisyfosPersistMetaData: fadeSisyfosMetaData - }), + }, content: { timelineObjects: [] } @@ -1954,7 +1932,7 @@ async function executeActionFadeDownPersistedAudioLevels< } async function createFadeSisyfosLevelsMetaData(context: ITV2ActionExecutionContext) { - const resolvedPieceInstances: IBlueprintResolvedPieceInstance[] = await context.getResolvedPieceInstances('current') + const resolvedPieceInstances = await context.getResolvedPieceInstances('current') const emptySisyfosMetaData: SisyfosPersistMetaData = { sisyfosLayers: [] } @@ -1962,11 +1940,11 @@ async function createFadeSisyfosLevelsMetaData(context: ITV2ActionExecutionConte return emptySisyfosMetaData } - const latestPiece: IBlueprintResolvedPieceInstance = resolvedPieceInstances + const latestPiece = resolvedPieceInstances .filter(piece => piece.piece.name !== FADE_SISYFOS_LEVELS_PIECE_NAME) .sort((a, b) => b.resolvedStart - a.resolvedStart)[0] - const latestPieceMetaData = latestPiece.piece.metaData as PieceMetaData + const latestPieceMetaData = latestPiece.piece.metaData if (!latestPieceMetaData || !latestPieceMetaData.sisyfosPersistMetaData) { return emptySisyfosMetaData @@ -1986,22 +1964,17 @@ async function scheduleLastPlayedDVE< context: ITV2ActionExecutionContext, settings: ActionExecutionSettings, actionId: string, - lastPlayedDVE: IBlueprintPieceInstance + lastPlayedDVE: IBlueprintPieceInstance ): Promise { - const lastPlayedDVEMeta: DVEPieceMetaData = lastPlayedDVE.piece.metaData as DVEPieceMetaData + const lastPlayedDVEMeta: DVEPieceMetaData = lastPlayedDVE.piece.metaData! const externalId: string = generateExternalId(context, actionId, [lastPlayedDVE.piece.name]) - await executeActionSelectDVE( - context, - settings, - actionId, - literal({ - type: AdlibActionType.SELECT_DVE, - config: lastPlayedDVEMeta.userData.config, - segmentExternalId: externalId, - videoId: lastPlayedDVEMeta.userData.videoId - }) - ) + await executeActionSelectDVE(context, settings, actionId, { + type: AdlibActionType.SELECT_DVE, + config: lastPlayedDVEMeta.userData.config, + segmentExternalId: externalId, + videoId: lastPlayedDVEMeta.userData.videoId + }) } async function scheduleNextScriptedDVE< @@ -2023,17 +1996,12 @@ async function scheduleNextScriptedDVE< const externalId: string = generateExternalId(context, actionId, [nextScriptedDVE.name]) const dveMeta: DVEPieceMetaData = nextScriptedDVE.metaData as DVEPieceMetaData - await executeActionSelectDVE( - context, - settings, - actionId, - literal({ - type: AdlibActionType.SELECT_DVE, - config: dveMeta.userData.config, - segmentExternalId: externalId, - videoId: dveMeta.userData.videoId - }) - ) + await executeActionSelectDVE(context, settings, actionId, { + type: AdlibActionType.SELECT_DVE, + config: dveMeta.userData.config, + segmentExternalId: externalId, + videoId: dveMeta.userData.videoId + }) } async function executeActionSelectFull< @@ -2049,7 +2017,8 @@ async function executeActionSelectFull< const template = GetFullGrafikTemplateName(config, userData.name) - const externalId = `adlib-action_${context.getHashId(`cut_to_full_${template}`)}` + const hash = context.getHashId(`cut_to_full_${template}`) + const externalId = `adlib-action_${hash}` const graphicType = config.studio.GraphicsType const previousPartKeepaliveDuration = @@ -2057,7 +2026,7 @@ async function executeActionSelectFull< ? config.studio.HTMLGraphics.KeepAliveDuration : config.studio.VizPilotGraphics.KeepAliveDuration - const part = literal({ + const part: IBlueprintPart = { externalId, title: `Full ${template}`, metaData: {}, @@ -2067,9 +2036,9 @@ async function executeActionSelectFull< partContentDelayDuration: 0, blockTakeDuration: 0 } - }) + } - const cue = literal>({ + const cue: CueDefinitionGraphic = { type: CueType.Graphic, target: 'FULL', graphic: { @@ -2079,7 +2048,7 @@ async function executeActionSelectFull< continueCount: -1 }, iNewsCommand: '' - }) + } const generator = new PilotGraphicGenerator({ config, @@ -2121,54 +2090,51 @@ async function executeActionClearGraphics< const config = settings.getConfig(context) await context.stopPiecesOnLayers(STOPPABLE_GRAPHICS_LAYERS) - await context.insertPiece( - 'current', - literal({ - enable: { - start: 'now', - duration: 3000 - }, - externalId: 'clearAllGFX', - name: userData.label, - sourceLayerId: SharedSourceLayers.PgmAdlibGraphicCmd, - outputLayerId: SharedOutputLayers.SEC, - lifespan: PieceLifespan.WithinPart, - content: - config.studio.GraphicsType === 'HTML' - ? { - timelineObjects: [ - literal({ - id: '', - enable: { - start: 0 - }, - priority: 1, - layer: SharedGraphicLLayer.GraphicLLayerAdLibs, - content: { - deviceType: TSR.DeviceType.ABSTRACT - } - }) - ] - } - : { - timelineObjects: [ - literal({ - id: '', - enable: { - start: 0 - }, - priority: 100, - layer: SharedGraphicLLayer.GraphicLLayerAdLibs, - content: { - deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, - channelsToSendCommands: userData.sendCommands ? ['OVL1', 'FULL1', 'WALL1'] : undefined, - showId: config.selectedGraphicsSetup.OvlShowId - } - }) - ] - }, - tags: userData.sendCommands ? [TallyTags.GFX_CLEAR] : [TallyTags.GFX_ALTUD] - }) - ) + await context.insertPiece('current', { + enable: { + start: 'now', + duration: 3000 + }, + externalId: 'clearAllGFX', + name: userData.label, + sourceLayerId: SharedSourceLayers.PgmAdlibGraphicCmd, + outputLayerId: SharedOutputLayers.SEC, + lifespan: PieceLifespan.WithinPart, + content: + config.studio.GraphicsType === 'HTML' + ? { + timelineObjects: [ + literal({ + id: '', + enable: { + start: 0 + }, + priority: 1, + layer: SharedGraphicLLayer.GraphicLLayerAdLibs, + content: { + deviceType: TSR.DeviceType.ABSTRACT + } + }) + ] + } + : { + timelineObjects: [ + literal({ + id: '', + enable: { + start: 0 + }, + priority: 100, + layer: SharedGraphicLLayer.GraphicLLayerAdLibs, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, + channelsToSendCommands: userData.sendCommands ? ['OVL1', 'FULL1', 'WALL1'] : undefined, + showId: config.selectedGraphicsSetup.OvlShowId + } + }) + ] + }, + tags: userData.sendCommands ? [TallyTags.GFX_CLEAR] : [TallyTags.GFX_ALTUD] + }) } diff --git a/src/tv2-common/content/dve.ts b/src/tv2-common/content/dve.ts index c4305b327..23795d3a8 100644 --- a/src/tv2-common/content/dve.ts +++ b/src/tv2-common/content/dve.ts @@ -21,6 +21,7 @@ import { JoinAssetToFolder, literal, PartDefinition, + PieceMetaData, TimelineBlueprintExt, TV2BlueprintConfigBase, TV2StudioConfigBase @@ -106,7 +107,7 @@ export interface DVEMetaData { mediaPlayerSession?: string } -export interface DVEPieceMetaData { +export interface DVEPieceMetaData extends PieceMetaData { config: DVEConfigInput sources: DVESources userData: ActionSelectDVE @@ -148,10 +149,6 @@ export function MakeContentDVEBase< } } - // console.log('boxmap1', boxMap) - // boxMap = boxMap.filter(map => map !== '') - // console.log('boxmap2', boxMap) - const graphicsTemplateContent: { [key: string]: string } = {} parsedCue.labels.forEach((label, i) => { graphicsTemplateContent[`${i}`] = label diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index f470c042b..58a7b88b4 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -79,10 +79,10 @@ function GetServerTimeline( sourceLayers: MakeContentServerSourceLayers, partProps: ServerPartProps, contentProps: ServerContentProps -) { +): TimelineObjectCoreExt[] { const serverEnableClass = `.${GetEnableClassForServer(contentProps.mediaPlayerSession)}` - const mediaObj = literal({ + const mediaObj: TSR.TimelineObjCCGMedia & TimelineBlueprintExt = { id: '', enable: { while: serverEnableClass @@ -106,7 +106,7 @@ function GetServerTimeline( ? [ServerParentClass('studio0', contentProps.file)] : []) ] - }) + } const mediaOffObj = JSON.parse(JSON.stringify(mediaObj)) as TSR.TimelineObjCCGMedia & TimelineBlueprintExt mediaOffObj.enable = { while: `!${serverEnableClass}` } @@ -115,7 +115,7 @@ function GetServerTimeline( const audioEnable = { while: serverEnableClass } - return literal([ + return [ mediaObj, mediaOffObj, ...GetSisyfosTimelineObjForServer( @@ -147,7 +147,7 @@ function GetServerTimeline( }) ] : []) - ]) + ] } export function CutToServer( diff --git a/src/tv2-common/cueTiming.ts b/src/tv2-common/cueTiming.ts index ee935c288..168ec0a1c 100644 --- a/src/tv2-common/cueTiming.ts +++ b/src/tv2-common/cueTiming.ts @@ -38,22 +38,14 @@ export function CreateTimingEnable( lifespan: PieceLifespan.WithinPart } - if (cue.start) { - ;(result.enable as any).start = CalculateTime(cue.start) - } else { - ;(result.enable as any).start = 0 - } + result.enable.start = (cue.start && CalculateTime(cue.start)) ?? 0 if (cue.end) { if (cue.end.infiniteMode) { result.lifespan = LifeSpan(cue.end.infiniteMode, PieceLifespan.WithinPart) } else { const end = CalculateTime(cue.end) - ;(result.enable as any).duration = end - ? result.enable.start - ? end - Number(result.enable.start) - : end - : undefined + result.enable.duration = end ? end - result.enable.start : undefined } } else if (defaultOut !== undefined) { result.enable.duration = defaultOut diff --git a/src/tv2-common/cues/ekstern.ts b/src/tv2-common/cues/ekstern.ts index c7a2c5273..a10891f19 100644 --- a/src/tv2-common/cues/ekstern.ts +++ b/src/tv2-common/cues/ekstern.ts @@ -17,7 +17,7 @@ import { literal, PartDefinition, PartToParentClass, - SisyfosPersistMetaData, + PieceMetaData, TransitionSettings, TV2BlueprintConfigBase, TV2StudioConfigBase @@ -43,8 +43,8 @@ export function EvaluateEksternBase< context: IShowStyleUserContext, config: ShowStyleConfig, part: IBlueprintPart, - pieces: IBlueprintPiece[], - adlibPieces: IBlueprintAdLibPiece[], + pieces: Array>, + adlibPieces: Array>, partId: string, parsedCue: CueDefinitionEkstern, partDefinition: PartDefinition, @@ -61,105 +61,101 @@ export function EvaluateEksternBase< const atemInput = sourceInfoEkstern.port if (adlib) { - adlibPieces.push( - literal({ - _rank: rank || 0, - externalId: partId, - name: parsedCue.sourceDefinition.name, - outputLayerId: SharedOutputLayers.PGM, - sourceLayerId: layersEkstern.SourceLayer.PgmLive, - toBeQueued: true, - lifespan: PieceLifespan.WithinPart, - metaData: { - sisyfosPersistMetaData: literal({ - sisyfosLayers: sourceInfoEkstern.sisyfosLayers ?? [], - wantsToPersistAudio: sourceInfoEkstern.wantsToPersistAudio, - acceptPersistAudio: sourceInfoEkstern.acceptPersistAudio - }) - }, - content: literal>({ - studioLabel: '', - switcherInput: atemInput, - timelineObjects: literal([ - literal({ - id: '', - enable: { - start: 0 - }, - 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(config, partDefinition) - } - }, - classes: [ControlClasses.LiveSourceOnAir] - }), + adlibPieces.push({ + _rank: rank || 0, + externalId: partId, + name: parsedCue.sourceDefinition.name, + outputLayerId: SharedOutputLayers.PGM, + sourceLayerId: layersEkstern.SourceLayer.PgmLive, + toBeQueued: true, + lifespan: PieceLifespan.WithinPart, + metaData: { + sisyfosPersistMetaData: { + sisyfosLayers: sourceInfoEkstern.sisyfosLayers ?? [], + wantsToPersistAudio: sourceInfoEkstern.wantsToPersistAudio, + acceptPersistAudio: sourceInfoEkstern.acceptPersistAudio + } + }, + content: literal>({ + studioLabel: '', + switcherInput: atemInput, + timelineObjects: literal([ + literal({ + id: '', + enable: { + start: 0 + }, + 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(config, partDefinition) + } + }, + classes: [ControlClasses.LiveSourceOnAir] + }), - ...GetSisyfosTimelineObjForRemote(config, sourceInfoEkstern) - ]) - }) + ...GetSisyfosTimelineObjForRemote(config, sourceInfoEkstern) + ]) }) - ) + }) } else { - pieces.push( - literal({ - externalId: partId, - name: parsedCue.sourceDefinition.name, - enable: { - start: 0 - }, - outputLayerId: SharedOutputLayers.PGM, - sourceLayerId: layersEkstern.SourceLayer.PgmLive, - lifespan: PieceLifespan.WithinPart, - toBeQueued: true, - metaData: { - sisyfosPersistMetaData: literal({ - sisyfosLayers: sourceInfoEkstern.sisyfosLayers ?? [], - wantsToPersistAudio: sourceInfoEkstern.wantsToPersistAudio, - acceptPersistAudio: sourceInfoEkstern.acceptPersistAudio - }) - }, - tags: [GetTagForLive(parsedCue.sourceDefinition)], - content: literal>({ - studioLabel: '', - switcherInput: atemInput, - timelineObjects: literal([ - createEmptyObject({ - // Only want the ident for original versions (or clones) - enable: { start: 0 }, - layer: 'ekstern_enable_ident', - classes: [PartToParentClass('studio0', partDefinition) ?? ''] - }), - literal({ - id: '', - enable: { - start: 0 - }, - 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(config, partDefinition) - } - }, - ...(AddParentClass(config, partDefinition) - ? { classes: [EksternParentClass('studio0', parsedCue.sourceDefinition.name)] } - : {}) - }), + 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: atemInput, + timelineObjects: literal([ + createEmptyObject({ + // Only want the ident for original versions (or clones) + enable: { start: 0 }, + layer: 'ekstern_enable_ident', + classes: [PartToParentClass('studio0', partDefinition) ?? ''] + }), + literal({ + id: '', + enable: { + start: 0 + }, + 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(config, partDefinition) + } + }, + ...(AddParentClass(config, partDefinition) + ? { classes: [EksternParentClass('studio0', parsedCue.sourceDefinition.name)] } + : {}) + }), - ...GetSisyfosTimelineObjForRemote(config, sourceInfoEkstern) - ]) - }) + ...GetSisyfosTimelineObjForRemote(config, sourceInfoEkstern) + ]) }) - ) + }) } } diff --git a/src/tv2-common/cues/lyd.ts b/src/tv2-common/cues/lyd.ts index 229c1d4bc..b19456688 100644 --- a/src/tv2-common/cues/lyd.ts +++ b/src/tv2-common/cues/lyd.ts @@ -59,44 +59,40 @@ export function EvaluateLYD( const lifespan = stop || fade || parsedCue.end ? PieceLifespan.WithinPart : PieceLifespan.OutOnRundownChange if (adlib) { - adlibPieces.push( - literal({ - _rank: rank || 0, - externalId: part.externalId, - name: parsedCue.variant, - outputLayerId: SharedOutputLayers.MUSIK, - sourceLayerId: SharedSourceLayers.PgmAudioBed, - lifespan, - expectedDuration: stop - ? 2000 - : fade - ? Math.max(1000, fadeIn ? TimeFromFrames(fadeIn) : 0) - : CreateTimingEnable(parsedCue).enable.duration ?? undefined, - content: LydContent(config, file, lydType, fadeIn, fadeOut), - tags: [AdlibTags.ADLIB_FLOW_PRODUCER] - }) - ) + adlibPieces.push({ + _rank: rank || 0, + externalId: part.externalId, + name: parsedCue.variant, + outputLayerId: SharedOutputLayers.MUSIK, + sourceLayerId: SharedSourceLayers.PgmAudioBed, + lifespan, + expectedDuration: stop + ? 2000 + : fade + ? Math.max(1000, fadeIn ? TimeFromFrames(fadeIn) : 0) + : CreateTimingEnable(parsedCue).enable.duration ?? undefined, + content: LydContent(config, file, lydType, fadeIn, fadeOut), + tags: [AdlibTags.ADLIB_FLOW_PRODUCER] + }) } else { - pieces.push( - literal({ - externalId: part.externalId, - name: parsedCue.variant, - ...(stop - ? { enable: { start: CreateTimingEnable(parsedCue).enable.start, duration: 2000 } } - : fade - ? { - enable: { - start: CreateTimingEnable(parsedCue).enable.start, - duration: Math.max(1000, fadeIn ? TimeFromFrames(fadeIn) : 0) - } - } - : CreateTimingEnable(parsedCue)), - outputLayerId: SharedOutputLayers.MUSIK, - sourceLayerId: SharedSourceLayers.PgmAudioBed, - lifespan, - content: LydContent(config, file, lydType, fadeIn, fadeOut) - }) - ) + pieces.push({ + externalId: part.externalId, + name: parsedCue.variant, + ...(stop + ? { enable: { start: CreateTimingEnable(parsedCue).enable.start, duration: 2000 } } + : fade + ? { + enable: { + start: CreateTimingEnable(parsedCue).enable.start, + duration: Math.max(1000, fadeIn ? TimeFromFrames(fadeIn) : 0) + } + } + : CreateTimingEnable(parsedCue)), + outputLayerId: SharedOutputLayers.MUSIK, + sourceLayerId: SharedSourceLayers.PgmAudioBed, + lifespan, + content: LydContent(config, file, lydType, fadeIn, fadeOut) + }) } } diff --git a/src/tv2-common/cues/mixMinus.ts b/src/tv2-common/cues/mixMinus.ts index eb29881f7..abf057a1c 100644 --- a/src/tv2-common/cues/mixMinus.ts +++ b/src/tv2-common/cues/mixMinus.ts @@ -28,23 +28,21 @@ export function EvaluateCueMixMinus( } const atemInput = sourceInfo.port - pieces.push( - literal({ - externalId: part.externalId, - name: `MixMinus: ${name}`, - enable: { - start: 0 - }, - lifespan: PieceLifespan.OutOnShowStyleEnd, - sourceLayerId: SharedSourceLayers.AuxMixMinus, - outputLayerId: SharedOutputLayers.AUX, - content: MixMinusContent(atemInput) - }) - ) + pieces.push({ + externalId: part.externalId, + name: `MixMinus: ${name}`, + enable: { + start: 0 + }, + lifespan: PieceLifespan.OutOnShowStyleEnd, + sourceLayerId: SharedSourceLayers.AuxMixMinus, + outputLayerId: SharedOutputLayers.AUX, + content: MixMinusContent(atemInput) + }) } function MixMinusContent(atemInput: number): WithTimeline { - return literal>({ + return { timelineObjects: literal([ literal({ content: { @@ -62,5 +60,5 @@ function MixMinusContent(atemInput: number): WithTimeline { priority: 1 }) ]) - }) + } } diff --git a/src/tv2-common/evaluateCues.ts b/src/tv2-common/evaluateCues.ts index 6eb710f43..b5191ef41 100644 --- a/src/tv2-common/evaluateCues.ts +++ b/src/tv2-common/evaluateCues.ts @@ -181,7 +181,7 @@ export interface EvaluateCuesOptions { /** Whether the parent part is a graphic part. */ isGrafikPart?: boolean /** Passing this arguments sets the types of cues to evaluate. */ - selectedCueTypes?: CueType[] | undefined + selectedCueTypes?: CueType[] /** Don't evaluate adlibs. */ excludeAdlibs?: boolean /** Only evaluate adlibs. */ diff --git a/src/tv2-common/getSegment.ts b/src/tv2-common/getSegment.ts index 5b70b9ce6..4593e333b 100644 --- a/src/tv2-common/getSegment.ts +++ b/src/tv2-common/getSegment.ts @@ -109,7 +109,7 @@ export async function getSegmentBase< ): Promise { const segmentPayload = ingestSegment.payload as INewsPayload | undefined const iNewsStory = segmentPayload?.iNewsStory - const segment = literal({ + const segment: IBlueprintSegment = { name: ingestSegment.name || '', metaData: {}, showShelf: false, @@ -117,7 +117,7 @@ export async function getSegmentBase< iNewsStory && iNewsStory.fields.pageNumber && iNewsStory.fields.pageNumber.trim() ? iNewsStory.fields.pageNumber.trim() : undefined - }) + } const config = showStyleOptions.getConfig(context) if (!segmentPayload || !iNewsStory || iNewsStory.meta.float === 'float' || !iNewsStory.body) { @@ -292,11 +292,11 @@ export async function getSegmentBase< if (!part.part.expectedDuration && totalTimeMs > 0) { part.part.expectedDuration = (totalTimeMs - allocatedTime || 0) / partsWithoutExpectedDuration - if (part.part.expectedDuration! < 0) { + if (part.part.expectedDuration < 0) { part.part.expectedDuration = 0 } - if (part.part.expectedDuration! > config.studio.MaximumPartDuration) { + if (part.part.expectedDuration > config.studio.MaximumPartDuration) { part.part.expectedDuration = config.studio.MaximumPartDuration } } diff --git a/src/tv2-common/helpers/__tests__/serverResume.spec.ts b/src/tv2-common/helpers/__tests__/serverResume.spec.ts index 67e893531..feb317794 100644 --- a/src/tv2-common/helpers/__tests__/serverResume.spec.ts +++ b/src/tv2-common/helpers/__tests__/serverResume.spec.ts @@ -6,7 +6,7 @@ import { VTContent, WithTimeline } from '@tv2media/blueprints-integration' -import { DVEPieceMetaData, literal, RemoteType, SourceDefinitionRemote } from 'tv2-common' +import { DVEPieceMetaData, literal, PieceMetaData, RemoteType, SourceDefinitionRemote } from 'tv2-common' import { SharedSourceLayers, SourceType } from 'tv2-constants' import { getServerPositionForPartInstance } from '../serverResume' @@ -36,7 +36,7 @@ function getMockPartInstance(partInstance: Partial): IBl describe('Server Resume', () => { it('Returns server position from server part with resolved duration', () => { const position = getServerPositionForPartInstance(getMockPartInstance({ _id: 'mock_1' }), [ - literal({ + literal>({ _id: '', partInstanceId: 'mock_1', resolvedStart: 1000, @@ -64,7 +64,7 @@ describe('Server Resume', () => { const position = getServerPositionForPartInstance( getMockPartInstance({ _id: 'mock_1', timings: { startedPlayback: 1000 } }), [ - literal({ + literal>({ _id: '', partInstanceId: 'mock_1', startedPlayback: 1000, @@ -105,7 +105,7 @@ describe('Server Resume', () => { timings: { startedPlayback: 11000 } }), [ - literal({ + literal>({ _id: '', partInstanceId: 'mock_1', resolvedStart: 1000, @@ -151,7 +151,7 @@ describe('Server Resume', () => { timings: { startedPlayback: 11000 } }), [ - literal({ + literal>({ _id: '', partInstanceId: 'mock_1', resolvedStart: 1000, diff --git a/src/tv2-common/helpers/abPlayback.ts b/src/tv2-common/helpers/abPlayback.ts index 8ab82fcc2..db086d373 100644 --- a/src/tv2-common/helpers/abPlayback.ts +++ b/src/tv2-common/helpers/abPlayback.ts @@ -72,20 +72,19 @@ interface SessionTime { } function calculateSessionTimeRanges( _context: ITimelineEventContext, - resolvedPieces: IBlueprintResolvedPieceInstance[] + resolvedPieces: Array> ) { const piecesWantingMediaPlayers = _.filter(resolvedPieces, p => { if (!p.piece.metaData) { return false } - const metadata = p.piece.metaData as PieceMetaData - return (metadata.mediaPlayerSessions || []).length > 0 + return (p.piece.metaData.mediaPlayerSessions || []).length > 0 }) const sessionRequests: { [sessionId: string]: SessionTime | undefined } = {} _.each(piecesWantingMediaPlayers, p => { - const metadata = p.piece.metaData as PieceMetaData - const start = p.resolvedStart as number + const metadata = p.piece.metaData! + const start = p.resolvedStart const duration = p.resolvedDuration const end = duration !== undefined ? start + duration : undefined @@ -205,7 +204,7 @@ export function resolveMediaPlayerAssignments< context: ITimelineEventContext, config: ShowStyleConfig, previousAssignmentRev: SessionToPlayerMap, - resolvedPieces: IBlueprintResolvedPieceInstance[] + resolvedPieces: Array> ) { const debugLog = config.studio.ABPlaybackDebugLogging const sessionRequests = calculateSessionTimeRanges(context, resolvedPieces) @@ -370,7 +369,7 @@ export function assignMediaPlayers< config: ShowStyleConfig, timelineObjs: OnGenerateTimelineObj[], previousAssignment: TimelinePersistentStateExt['activeMediaPlayers'], - resolvedPieces: IBlueprintResolvedPieceInstance[], + resolvedPieces: Array>, sourceLayers: ABSourceLayers ): TimelinePersistentStateExt['activeMediaPlayers'] { const previousAssignmentRev = reversePreviousAssignment(previousAssignment, timelineObjs) diff --git a/src/tv2-common/helpers/graphics/InternalGraphic.ts b/src/tv2-common/helpers/graphics/InternalGraphic.ts index 00a23c7f7..28218ea4b 100644 --- a/src/tv2-common/helpers/graphics/InternalGraphic.ts +++ b/src/tv2-common/helpers/graphics/InternalGraphic.ts @@ -4,12 +4,11 @@ import _ = require('underscore') import { AdlibTags, GraphicEngine, PartType, SharedOutputLayers, SharedSourceLayers } from '../../../tv2-constants' import { TV2BlueprintConfig } from '../../blueprintConfig' import { CueDefinitionGraphic, GraphicInternal, PartDefinition } from '../../inewsConversion' -import { PieceMetaData } from '../../onTimelineGenerate' -import { literal } from '../../util' +import { GraphicPieceMetaData, PieceMetaData } from '../../onTimelineGenerate' import { GetInternalGraphicContentCaspar } from './caspar' import { GetSourceLayerForGraphic } from './layers' import { GetFullGraphicTemplateNameFromCue, GraphicDisplayName } from './name' -import { IsTargetingOVL, IsTargetingTLF, IsTargetingWall } from './target' +import { IsTargetingTLF, IsTargetingWall } from './target' import { CreateTimingGraphic, GetPieceLifespanForGraphic } from './timing' import { GetInternalGraphicContentVIZ } from './viz' @@ -51,11 +50,8 @@ export class InternalGraphic { this.content = this.getInternalGraphicContent() } - public createCommentatorAdlib(adlibPieces: IBlueprintAdLibPiece[]): void { - if (!IsTargetingOVL(this.engine)) { - return - } - const adLibPiece = literal({ + public createCommentatorAdlib(): IBlueprintAdLibPiece { + return { _rank: this.rank || 0, externalId: this.partId ?? '', name: this.name, @@ -63,46 +59,43 @@ export class InternalGraphic { sourceLayerId: this.sourceLayerId, outputLayerId: SharedOutputLayers.OVERLAY, lifespan: PieceLifespan.WithinPart, - metaData: literal({ + metaData: { sisyfosPersistMetaData: { sisyfosLayers: [] } - }), + }, expectedDuration: 5000, tags: [AdlibTags.ADLIB_KOMMENTATOR], content: _.clone(this.content) - }) - adlibPieces.push(adLibPiece) + } } - public createAdlib(adlibPieces: IBlueprintAdLibPiece[]): void { - adlibPieces.push( - literal({ - _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: literal({ - sisyfosPersistMetaData: { - sisyfosLayers: [] - } - }), - 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(pieces: IBlueprintPiece[]): void { - const piece = literal({ + public createPiece(): IBlueprintPiece { + return { externalId: this.partId ?? '', name: this.name, ...(IsTargetingTLF(this.engine) || IsTargetingWall(this.engine) @@ -115,15 +108,14 @@ export class InternalGraphic { outputLayerId: this.outputLayerId, sourceLayerId: this.sourceLayerId, lifespan: GetPieceLifespanForGraphic(this.engine, this.config, this.parsedCue), - metaData: literal({ + metaData: { sisyfosPersistMetaData: { sisyfosLayers: [] }, belongsToRemotePart: this.partDefinition?.type === PartType.REMOTE - }), + }, content: _.clone(this.content) - }) - pieces.push(piece) + } } private getInternalGraphicContent(): IBlueprintPiece['content'] { diff --git a/src/tv2-common/helpers/graphics/caspar/index.ts b/src/tv2-common/helpers/graphics/caspar/index.ts index 3d4615650..96b34ce8b 100644 --- a/src/tv2-common/helpers/graphics/caspar/index.ts +++ b/src/tv2-common/helpers/graphics/caspar/index.ts @@ -47,7 +47,7 @@ export function GetPilotGraphicContentCaspar( parsedCue: CueDefinitionGraphic, settings: CasparPilotGeneratorSettings, engine: GraphicEngine -) { +): WithTimeline { const graphicFolder = config.studio.GraphicFolder ? `${config.studio.GraphicFolder}\\` : '' const fileName = JoinAssetToFolder(config.studio.GraphicFolder, parsedCue.graphic.name) const templateData = { @@ -65,7 +65,7 @@ export function GetPilotGraphicContentCaspar( } } } - return literal>({ + return { fileName, path: JoinAssetToNetworkPath( config.studio.GraphicNetworkBasePath, @@ -100,7 +100,7 @@ export function GetPilotGraphicContentCaspar( }), ...(IsTargetingFull(engine) ? settings.createPilotTimelineForStudio(config, context) : []) ] - }) + } } function CasparOverlayTimeline( diff --git a/src/tv2-common/helpers/graphics/design/index.ts b/src/tv2-common/helpers/graphics/design/index.ts index fd2adf6a8..2ca0b22cc 100644 --- a/src/tv2-common/helpers/graphics/design/index.ts +++ b/src/tv2-common/helpers/graphics/design/index.ts @@ -29,41 +29,37 @@ export function EvaluateDesignBase( } if (adlib) { - adlibPieces.push( - literal({ - _rank: rank || 0, - externalId: partId, - name: parsedCue.design, - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: SharedSourceLayers.PgmDesign, - lifespan: PieceLifespan.OutOnShowStyleEnd, - content: literal>({ - fileName: parsedCue.design, - path: parsedCue.design, - ignoreMediaObjectStatus: true, - timelineObjects: designTimeline(config, parsedCue) - }) + adlibPieces.push({ + _rank: rank || 0, + externalId: partId, + name: parsedCue.design, + outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SharedSourceLayers.PgmDesign, + lifespan: PieceLifespan.OutOnShowStyleEnd, + content: literal>({ + fileName: parsedCue.design, + path: parsedCue.design, + ignoreMediaObjectStatus: true, + timelineObjects: designTimeline(config, parsedCue) }) - ) + }) } else { - pieces.push( - literal({ - externalId: partId, - name: parsedCue.design, - enable: { - start - }, - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: SharedSourceLayers.PgmDesign, - lifespan: PieceLifespan.OutOnShowStyleEnd, - content: literal>({ - fileName: parsedCue.design, - path: parsedCue.design, - ignoreMediaObjectStatus: true, - timelineObjects: designTimeline(config, parsedCue) - }) + pieces.push({ + externalId: partId, + name: parsedCue.design, + enable: { + start + }, + outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SharedSourceLayers.PgmDesign, + lifespan: PieceLifespan.OutOnShowStyleEnd, + content: literal>({ + fileName: parsedCue.design, + path: parsedCue.design, + ignoreMediaObjectStatus: true, + timelineObjects: designTimeline(config, parsedCue) }) - ) + }) } } diff --git a/src/tv2-common/helpers/graphics/internal/index.ts b/src/tv2-common/helpers/graphics/internal/index.ts index 40b1e65fa..a38bd8cf8 100644 --- a/src/tv2-common/helpers/graphics/internal/index.ts +++ b/src/tv2-common/helpers/graphics/internal/index.ts @@ -1,5 +1,12 @@ import { IBlueprintAdLibPiece, IBlueprintPiece, IShowStyleUserContext } from '@tv2media/blueprints-integration' -import { Adlib, CueDefinitionGraphic, GraphicInternal, PartDefinition, TV2BlueprintConfig } from 'tv2-common' +import { + Adlib, + CueDefinitionGraphic, + GraphicInternal, + IsTargetingOVL, + PartDefinition, + TV2BlueprintConfig +} from 'tv2-common' import { InternalGraphic } from '../InternalGraphic' export function CreateInternalGraphic( @@ -20,9 +27,11 @@ export function CreateInternalGraphic( } if (adlib) { - internalGraphic.createCommentatorAdlib(adlibPieces) - internalGraphic.createAdlib(adlibPieces) + if (IsTargetingOVL(parsedCue.target)) { + adlibPieces.push(internalGraphic.createCommentatorAdlib()) + } + adlibPieces.push(internalGraphic.createAdlib()) } else { - internalGraphic.createPiece(pieces) + pieces.push(internalGraphic.createPiece()) } } diff --git a/src/tv2-common/helpers/graphics/name.ts b/src/tv2-common/helpers/graphics/name.ts index 63329eb42..e4a8bed78 100644 --- a/src/tv2-common/helpers/graphics/name.ts +++ b/src/tv2-common/helpers/graphics/name.ts @@ -34,13 +34,11 @@ export function GetFullGraphicTemplateNameFromCue( } export function GetFullGrafikTemplateName(config: TV2BlueprintConfig, iNewsTempalateName: string): string { - if (config.showStyle.GFXTemplates) { - const template = config.showStyle.GFXTemplates.find(templ => - templ.INewsName ? templ.INewsName.toString().toUpperCase() === iNewsTempalateName.toUpperCase() : false - ) - if (template && template.VizTemplate.toString().length) { - return template.VizTemplate.toString() - } + const template = config.showStyle.GFXTemplates.find(templ => + templ.INewsName ? templ.INewsName.toString().toUpperCase() === iNewsTempalateName.toUpperCase() : false + ) + if (template && template.VizTemplate.toString().length) { + return template.VizTemplate.toString() } // This means unconfigured templates will still be supported, with default out. diff --git a/src/tv2-common/helpers/graphics/pilot/index.ts b/src/tv2-common/helpers/graphics/pilot/index.ts index e799565ee..5308631c5 100644 --- a/src/tv2-common/helpers/graphics/pilot/index.ts +++ b/src/tv2-common/helpers/graphics/pilot/index.ts @@ -13,6 +13,7 @@ import { Adlib, CreateTimingGraphic, CueDefinitionGraphic, + FullPieceMetaData, generateExternalId, GetFullGraphicTemplateNameFromCue, GetPieceLifespanForGraphic, @@ -111,18 +112,18 @@ export class PilotGraphicGenerator { this.segmentExternalId = graphicProps.segmentExternalId } - public createPilotAdLibAction() { + public createPilotAdLibAction(): IBlueprintActionManifest { const name = GraphicDisplayName(this.config, this.parsedCue) const sourceLayerId = this.getSourceLayer() const outputLayerId = this.getOutputLayer() - const userData = literal({ + const userData: ActionSelectFullGrafik = { type: AdlibActionType.SELECT_FULL_GRAFIK, name: this.parsedCue.graphic.name, vcpid: this.parsedCue.graphic.vcpid, segmentExternalId: this.segmentExternalId - }) - return literal({ + } + return { externalId: generateExternalId(this.context, userData), actionId: AdlibActionType.SELECT_FULL_GRAFIK, userData, @@ -143,11 +144,11 @@ export class PilotGraphicGenerator { currentPieceTags: [GetTagForFull(this.segmentExternalId, this.parsedCue.graphic.vcpid)], nextPieceTags: [GetTagForFullNext(this.segmentExternalId, this.parsedCue.graphic.vcpid)] } - }) + } } - public createPiece(): IBlueprintPiece { - return literal({ + public createPiece(): IBlueprintPiece { + return { externalId: this.partId, name: GraphicDisplayName(this.config, this.parsedCue), ...(IsTargetingFull(this.engine) || IsTargetingWall(this.engine) @@ -161,16 +162,16 @@ export class PilotGraphicGenerator { sourceLayerId: this.getSourceLayer(), prerollDuration: this.getPrerollDuration(), lifespan: GetPieceLifespanForGraphic(this.engine, this.config, this.parsedCue), - metaData: literal({ + metaData: { sisyfosPersistMetaData: { sisyfosLayers: [] } - }), + }, content: this.createContent(), tags: IsTargetingFull(this.engine) ? [GetTagForFull(this.segmentExternalId, this.parsedCue.graphic.vcpid), TallyTags.FULL_IS_LIVE] : [] - }) + } } public createAdlibPiece(rank?: number): IBlueprintAdLibPiece { @@ -182,7 +183,7 @@ export class PilotGraphicGenerator { } } - public createFullDataStore(): IBlueprintPiece { + public createFullDataStore(): IBlueprintPiece { const content = this.createContent() content.timelineObjects = content.timelineObjects.filter( o => @@ -191,7 +192,7 @@ export class PilotGraphicGenerator { o.content.deviceType !== TSR.DeviceType.VIZMSE && o.content.deviceType !== TSR.DeviceType.CASPARCG ) - return literal({ + return { externalId: this.partId, name: GraphicDisplayName(this.config, this.parsedCue), enable: { @@ -201,19 +202,19 @@ export class PilotGraphicGenerator { sourceLayerId: SharedSourceLayers.SelectedAdlibGraphicsFull, lifespan: PieceLifespan.OutOnSegmentEnd, metaData: { - userData: literal({ + 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)] - }) + } } private createContent(): WithTimeline { diff --git a/src/tv2-common/helpers/graphics/timing.ts b/src/tv2-common/helpers/graphics/timing.ts index 3304294b9..3bfd74a9a 100644 --- a/src/tv2-common/helpers/graphics/timing.ts +++ b/src/tv2-common/helpers/graphics/timing.ts @@ -37,34 +37,30 @@ export function FindInfiniteModeFromConfig( config: TV2BlueprintConfig, parsedCue: CueDefinitionGraphic ): PieceLifespan { - if (config.showStyle.GFXTemplates) { - 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 - } + 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.OutType || !conf.OutType.toString().length) { - return PieceLifespan.WithinPart - } + if (!conf) { + return PieceLifespan.WithinPart + } - const type = conf.OutType.toString().toUpperCase() + if (!conf.OutType || !conf.OutType.toString().length) { + return PieceLifespan.WithinPart + } - if (type !== 'B' && type !== 'S' && type !== 'O') { - return PieceLifespan.WithinPart - } + const type = conf.OutType.toString().toUpperCase() - return LifeSpan(type, PieceLifespan.WithinPart) + if (type !== 'B' && type !== 'S' && type !== 'O') { + return PieceLifespan.WithinPart } - return PieceLifespan.WithinPart + return LifeSpan(type, PieceLifespan.WithinPart) } export function GetGraphicDuration( diff --git a/src/tv2-common/helpers/graphics/viz/index.ts b/src/tv2-common/helpers/graphics/viz/index.ts index a41f0a874..973f952ac 100644 --- a/src/tv2-common/helpers/graphics/viz/index.ts +++ b/src/tv2-common/helpers/graphics/viz/index.ts @@ -1,10 +1,4 @@ -import { - GraphicsContent, - IBlueprintPiece, - IShowStyleUserContext, - TSR, - WithTimeline -} from '@tv2media/blueprints-integration' +import { GraphicsContent, IShowStyleUserContext, TSR, WithTimeline } from '@tv2media/blueprints-integration' import { Adlib, CueDefinitionGraphic, @@ -39,8 +33,8 @@ export function GetInternalGraphicContentVIZ( partDefinition: PartDefinition | undefined, mappedTemplate: string, adlib: boolean -): IBlueprintPiece['content'] { - return literal>({ +): WithTimeline { + return { fileName: parsedCue.graphic.template, path: parsedCue.graphic.template, ignoreMediaObjectStatus: true, @@ -62,7 +56,7 @@ export function GetInternalGraphicContentVIZ( // Assume DSK is off by default (config table) ...EnableDSK(config, 'OVL') ]) - }) + } } export function GetPilotGraphicContentViz( @@ -73,7 +67,7 @@ export function GetPilotGraphicContentViz( engine: GraphicEngine, adlib?: Adlib ): WithTimeline { - return literal>({ + return { fileName: 'PILOT_' + parsedCue.graphic.vcpid.toString(), path: parsedCue.graphic.vcpid.toString(), timelineObjects: [ @@ -112,5 +106,5 @@ export function GetPilotGraphicContentViz( }), ...(IsTargetingFull(engine) ? settings.createPilotTimelineForStudio(config, context, !!adlib) : []) ] - }) + } } diff --git a/src/tv2-common/helpers/rundownAdLibActions.ts b/src/tv2-common/helpers/rundownAdLibActions.ts index 46243960a..05402989d 100644 --- a/src/tv2-common/helpers/rundownAdLibActions.ts +++ b/src/tv2-common/helpers/rundownAdLibActions.ts @@ -25,11 +25,11 @@ export function GetTransitionAdLibActions< if (config.showStyle.ShowstyleTransition && config.showStyle.ShowstyleTransition.length) { const defaultTransition = config.showStyle.ShowstyleTransition - const userData = literal({ + const userData: ActionTakeWithTransition = { type: AdlibActionType.TAKE_WITH_TRANSITION, variant: ParseTransitionString(defaultTransition), takeNow: true - }) + } const jingleConfig = config.showStyle.BreakerConfig.find( j => j.BreakerName === config.showStyle.ShowstyleTransition @@ -63,11 +63,11 @@ export function GetTransitionAdLibActions< if (config.showStyle.Transitions) { config.showStyle.Transitions.forEach((transition, i) => { if (transition.Transition && transition.Transition.length) { - const userData = literal({ + const userData: ActionTakeWithTransition = { type: AdlibActionType.TAKE_WITH_TRANSITION, variant: ParseTransitionString(transition.Transition), takeNow: true - }) + } const jingleConfig = config.showStyle.BreakerConfig.find(j => j.BreakerName === transition.Transition) let alphaAtStart: number | undefined @@ -141,7 +141,7 @@ function makeTransitionAction( const tag = GetTagForTransition(userData.variant) const isEffekt = !!label.match(/^\d+$/) - return literal({ + return { externalId: `${JSON.stringify(userData)}_${AdlibActionType.TAKE_WITH_TRANSITION}_${rank}`, actionId: AdlibActionType.TAKE_WITH_TRANSITION, userData, @@ -159,5 +159,5 @@ function makeTransitionAction( ? {} : CreateJingleExpectedMedia(config, jingle, alphaAtStart ?? 0, duration ?? 0, alphaAtEnd ?? 0) } - }) + } } diff --git a/src/tv2-common/helpers/serverResume.ts b/src/tv2-common/helpers/serverResume.ts index 7fae49cfc..28d6bb96b 100644 --- a/src/tv2-common/helpers/serverResume.ts +++ b/src/tv2-common/helpers/serverResume.ts @@ -5,7 +5,7 @@ import { IBlueprintResolvedPieceInstance, VTContent } from '@tv2media/blueprints-integration' -import { PartEndStateExt, t } from 'tv2-common' +import { PartEndStateExt, PieceMetaData, t } from 'tv2-common' import { SharedSourceLayers } from 'tv2-constants' import _ = require('underscore') import { DVEPieceMetaData } from '../content' @@ -61,7 +61,11 @@ export async function getServerPosition( ? context.getCurrentTime() + replacingCurrentPieceWithOffset : undefined - return getServerPositionForPartInstance(partInstance, await context.getResolvedPieceInstances('current'), pieceEnd) + const pieceInstances = (await context.getResolvedPieceInstances('current')) as Array< + IBlueprintResolvedPieceInstance + > + + return getServerPositionForPartInstance(partInstance, pieceInstances, pieceEnd) } /** @@ -69,7 +73,7 @@ export async function getServerPosition( */ export function getServerPositionForPartInstance( partInstance: IBlueprintPartInstance, - pieceInstances: IBlueprintResolvedPieceInstance[], + pieceInstances: Array>, currentPieceEnd?: number ): ServerPosition | undefined { currentPieceEnd = @@ -102,7 +106,7 @@ export function getServerPositionForPartInstance( ) } else if (pieceInstance.piece.sourceLayerId === SharedSourceLayers.PgmDVEAdLib) { updateServerPositionFromDVEPiece( - pieceInstance, + pieceInstance as IBlueprintResolvedPieceInstance, partInstance, pieceDuration, currentPieceEnd, @@ -119,7 +123,7 @@ export function getServerPositionForPartInstance( function updateServerPositionFromTransition( partInstance: IBlueprintPartInstance, currentServerPosition: ServerPosition | undefined, - currentPiecesWithServer: Array>, + currentPiecesWithServer: Array>, previousPartEndState: Partial | undefined ) { const inTransitionDuration = partInstance.part.inTransition?.previousPartKeepaliveDuration @@ -134,13 +138,13 @@ function updateServerPositionFromTransition( } function updateServerPositionFromDVEPiece( - pieceInstance: IBlueprintResolvedPieceInstance, + pieceInstance: IBlueprintResolvedPieceInstance, partInstance: IBlueprintPartInstance, pieceDuration: number | undefined, currentPieceEnd: number | undefined, currentServerPosition: ServerPosition | undefined ) { - const serverPlaybackTiming = (pieceInstance.piece.metaData as DVEPieceMetaData | undefined)?.serverPlaybackTiming + const serverPlaybackTiming = pieceInstance.piece.metaData?.serverPlaybackTiming if (serverPlaybackTiming) { for (const timing of serverPlaybackTiming) { const start = getStartTimeForServerInDVE(timing, partInstance, pieceInstance) @@ -156,7 +160,7 @@ function updateServerPositionFromDVEPiece( } function getStartTimeForServerInDVE( - timing: { start?: number | undefined; end?: number | undefined }, + timing: { start?: number; end?: number }, partInstance: IBlueprintPartInstance, pieceInstance: IBlueprintResolvedPieceInstance ) { @@ -167,7 +171,7 @@ function getStartTimeForServerInDVE( } function getEndTimeForServerInDVE( - timing: { start?: number | undefined; end?: number | undefined }, + timing: { start?: number; end?: number }, pieceDuration: number | undefined, partInstance: IBlueprintPartInstance, pieceInstance: IBlueprintResolvedPieceInstance diff --git a/src/tv2-common/inewsConversion/converters/ParseBody.ts b/src/tv2-common/inewsConversion/converters/ParseBody.ts index 2a2e3bf08..8e14270a8 100644 --- a/src/tv2-common/inewsConversion/converters/ParseBody.ts +++ b/src/tv2-common/inewsConversion/converters/ParseBody.ts @@ -192,7 +192,13 @@ export function ParseBody( // Handle intro segments, they have special behaviour. if (segmentName === 'INTRO') { - ;((definition as unknown) as PartDefinitionIntro).type = PartType.INTRO + definition = { + ...definition, + type: PartType.INTRO, + rawType: 'INTRO', + externalId: `${segmentId}-${definitions.length}`, + segmentExternalId: segmentId + } cues.forEach(cue => { if (cue !== null) { const parsedCue = ParseCue(cue, config) @@ -202,9 +208,6 @@ export function ParseBody( } } }) - definition.rawType = 'INTRO' - definition.externalId = `${segmentId}-${definitions.length}` - definition.segmentExternalId = segmentId definitions.push(definition) definition = initDefinition(fields, modified, segmentName) return definitions diff --git a/src/tv2-common/inewsConversion/converters/ParseCue.ts b/src/tv2-common/inewsConversion/converters/ParseCue.ts index ba40ff172..fa52631e8 100644 --- a/src/tv2-common/inewsConversion/converters/ParseCue.ts +++ b/src/tv2-common/inewsConversion/converters/ParseCue.ts @@ -578,13 +578,13 @@ function parseAdLib(cue: string[]) { } // tslint:disable-next-line: prefer-for-of - for (let i = 0; i < cue.length; i++) { - const input = cue[i].match(/^(INP\d)+=(.+)$/i) + for (const element of cue) { + const input = element.match(/^(INP\d)+=(.+)$/i) if (input && input[1] && input[2] && adlib.inputs !== undefined) { adlib.inputs[input[1].toUpperCase() as keyof DVESources] = getSourceDefinition(input[2]) } - const bynavn = cue[i].match(/^BYNAVN=(.+)$/i) + const bynavn = element.match(/^BYNAVN=(.+)$/i) if (bynavn) { adlib.bynavn = bynavn[1].split(/\/|\\/i) } 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 d591ec062..385fa803d 100644 --- a/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts +++ b/src/tv2-common/inewsConversion/converters/__tests__/cue-parser.spec.ts @@ -360,26 +360,6 @@ describe('Cue parser', () => { ) }) - test('Grafik (kg) - Inline first text field, blank time', () => { - const cueGrafik = ['kg bund TEXT MORETEXT', 'some@email.fakeTLD', ';x.xx'] - const result = ParseCue(cueGrafik, config) - expect(result).toEqual( - literal>({ - type: CueType.Graphic, - target: 'OVL', - - graphic: { - type: 'internal', - template: 'bund', - cue: 'kg', - textFields: ['TEXT MORETEXT', 'some@email.fakeTLD'] - }, - adlib: true, - iNewsCommand: 'kg' - }) - ) - }) - test('Grafik (kg) - Multiline text fields', () => { const cueGrafik = ['kg bund', 'TEXT MORETEXT', 'some@email.fakeTLD', ';0.02'] const result = ParseCue(cueGrafik, config) diff --git a/src/tv2-common/layers/sourceLayers.ts b/src/tv2-common/layers/sourceLayers.ts index f4746d8f0..e52a0b919 100644 --- a/src/tv2-common/layers/sourceLayers.ts +++ b/src/tv2-common/layers/sourceLayers.ts @@ -1,7 +1,6 @@ import { ISourceLayer, SourceLayerType } from '@tv2media/blueprints-integration' import { ATEMModel } from '../../types/atem' import { GetDSKCount } from '../helpers' -import { literal } from '../util' /** * Get the sourcelayer name for a given DSK. @@ -12,7 +11,7 @@ export function SourceLayerAtemDSK(i: number): string { } function GetSourceLayerDefaultsForDSK(i: number): ISourceLayer { - return literal({ + return { _id: SourceLayerAtemDSK(i), _rank: 22, name: `DSK${i + 1} off`, @@ -27,7 +26,7 @@ function GetSourceLayerDefaultsForDSK(i: number): ISourceLayer { isHidden: true, allowDisable: false, onPresenterScreen: false - }) + } } export function GetDSKSourceLayerNames(atemModel: ATEMModel): string[] { diff --git a/src/tv2-common/migrations/addKeepAudio.ts b/src/tv2-common/migrations/addKeepAudio.ts index 18dcdc472..c6629842c 100644 --- a/src/tv2-common/migrations/addKeepAudio.ts +++ b/src/tv2-common/migrations/addKeepAudio.ts @@ -1,9 +1,8 @@ import { MigrationContextStudio, MigrationStepStudio, TableConfigItemValue } from '@tv2media/blueprints-integration' import * as _ from 'underscore' -import { literal } from '../util' export function AddKeepAudio(versionStr: string, configName: string): MigrationStepStudio { - const res = literal({ + const res: MigrationStepStudio = { id: `${versionStr}.studioConfig.addKeepAudio.${configName}`, version: versionStr, canBeRunAutomatically: true, @@ -29,7 +28,7 @@ export function AddKeepAudio(versionStr: string, configName: string): MigrationS context.setConfig(configName, configVal) } } - }) + } return res } diff --git a/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts b/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts index d94d7012f..137fad578 100644 --- a/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts +++ b/src/tv2-common/migrations/forceSourceLayerToDefaultsBase.ts @@ -1,5 +1,4 @@ import { ISourceLayer, MigrationContextShowStyle, MigrationStepShowStyle } from '@tv2media/blueprints-integration' -import { literal } from 'tv2-common' import _ = require('underscore') export function forceSourceLayerToDefaultsBase( @@ -9,7 +8,7 @@ export function forceSourceLayerToDefaultsBase( layer: string, overrideSteps?: string[] ): MigrationStepShowStyle { - return literal({ + return { id: `${versionStr}.${showStyleId}.sourcelayer.defaults.${layer}.forced`, version: versionStr, canBeRunAutomatically: true, @@ -43,5 +42,5 @@ export function forceSourceLayerToDefaultsBase( context.insertSourceLayer(layer, defaultVal) } } - }) + } } diff --git a/src/tv2-common/migrations/hotkeys.ts b/src/tv2-common/migrations/hotkeys.ts index 1d1ff0fa7..de3283127 100644 --- a/src/tv2-common/migrations/hotkeys.ts +++ b/src/tv2-common/migrations/hotkeys.ts @@ -43,7 +43,7 @@ export function GetDefaultAdLibTriggers( sourceLayers ) - const needsMigration = shortcutsDefaults.some(defaultShortcut => { + return shortcutsDefaults.some(defaultShortcut => { const existingShortcut = context.getTriggeredAction(defaultShortcut._id) if (!existingShortcut) { @@ -52,7 +52,6 @@ export function GetDefaultAdLibTriggers( return forceToDefaults && shortcutsAreDifferent(defaultShortcut, existingShortcut) }) - return needsMigration }, migrate: (context: MigrationContextShowStyle) => { const shortcutsDefaults = MakeAllAdLibsTriggers( @@ -79,7 +78,7 @@ export function RemoveOldShortcuts( showStyleId: string, sourceLayerDefaults: ISourceLayer[] ): MigrationStepShowStyle { - return literal({ + return { id: `${versionStr}.migrateShortcutsToAdLibTriggers.${showStyleId}`, version: versionStr, canBeRunAutomatically: true, @@ -88,15 +87,13 @@ export function RemoveOldShortcuts( ISourceLayerWithHotKeys | undefined > - const oldHotKeysExist = sourceLayers.some( + return sourceLayers.some( sourceLayer => !!sourceLayer?.clearKeyboardHotkey || !!sourceLayer?.activateKeyboardHotkeys || !!sourceLayer?.activateStickyKeyboardHotkey || sourceLayer?.assignHotkeysToGlobalAdlibs !== undefined ) - - return oldHotKeysExist }, migrate: (context: MigrationContextShowStyle) => { for (const sourceLayer of sourceLayerDefaults) { @@ -113,5 +110,5 @@ export function RemoveOldShortcuts( context.updateSourceLayer(sourceLayer._id, coreSourceLayer) } } - }) + } } diff --git a/src/tv2-common/migrations/index.ts b/src/tv2-common/migrations/index.ts index c74ecaa72..33e1da474 100644 --- a/src/tv2-common/migrations/index.ts +++ b/src/tv2-common/migrations/index.ts @@ -22,7 +22,7 @@ export * from './forceSourceLayerToDefaultsBase' export * from './hotkeys' export function RenameStudioConfig(versionStr: string, studio: string, from: string, to: string): MigrationStepStudio { - return literal({ + return { id: `${versionStr}.studioConfig.rename.${from}.${studio}`, version: versionStr, canBeRunAutomatically: true, @@ -41,7 +41,7 @@ export function RenameStudioConfig(versionStr: string, studio: string, from: str context.removeConfig(from) } - }) + } } export function renameSourceLayer( @@ -50,7 +50,7 @@ export function renameSourceLayer( from: string, to: string ): MigrationStepShowStyle { - return literal({ + return { id: `${versionStr}.renameSourceLayer.${studioId}.${from}.${to}`, version: versionStr, canBeRunAutomatically: true, @@ -69,10 +69,10 @@ export function renameSourceLayer( context.insertSourceLayer(to, existing) context.removeSourceLayer(from) } - }) + } } -export function removeSourceLayer(versionStr: string, studioId: string, layer: string) { +export function removeSourceLayer(versionStr: string, studioId: string, layer: string): MigrationStepShowStyle { return literal({ id: `${versionStr}.removeSourceLayer.${studioId}.${layer}`, version: versionStr, @@ -94,8 +94,12 @@ export function removeSourceLayer(versionStr: string, studioId: string, layer: s }) } -export function AddGraphicToGFXTable(versionStr: string, studio: string, config: TableConfigItemGFXTemplates) { - return literal({ +export function AddGraphicToGFXTable( + versionStr: string, + studio: string, + config: TableConfigItemGFXTemplates +): MigrationStepShowStyle { + return { id: `${versionStr}.gfxConfig.add${config.INewsName}.${studio}`, version: versionStr, canBeRunAutomatically: true, @@ -118,7 +122,7 @@ export function AddGraphicToGFXTable(versionStr: string, studio: string, config: context.setBaseConfig('GFXTemplates', (existing as unknown) as ConfigItemValue) } - }) + } } export function addSourceToSourcesConfig( @@ -126,8 +130,8 @@ export function addSourceToSourcesConfig( studio: string, configId: string, source: TableConfigItemSourceMappingWithSisyfos -) { - return literal({ +): MigrationStepStudio { + return { id: `${versionStr}.studioConfig.addReplaySource.${source.SourceName}.${studio}`, version: versionStr, canBeRunAutomatically: true, @@ -144,7 +148,7 @@ export function addSourceToSourcesConfig( config.push(source) context.setConfig(configId, (config as unknown) as ConfigItemValue) } - }) + } } export function changeGFXTemplate( @@ -152,9 +156,9 @@ export function changeGFXTemplate( studio: string, oldConfig: Partial, config: Partial -) { +): MigrationStepShowStyle { const keysToUpdate = Object.keys(config).join('_') - return literal({ + return { id: `${versionStr}.gfxConfig.change_${keysToUpdate}.${studio}`, version: versionStr, canBeRunAutomatically: true, @@ -176,7 +180,7 @@ export function changeGFXTemplate( context.setBaseConfig('GFXTemplates', (existing as unknown) as ConfigItemValue) } - }) + } } function isGfxTemplateSubset( @@ -194,40 +198,38 @@ export function SetLayerNamesToDefaults( const migrations: MigrationStepStudio[] = [] for (const [layerId, mapping] of Object.entries(mappings)) { - migrations.push( - literal({ - id: `${versionStr}.studioConfig.setLayerName.${layerId}.${studio}`, - version: versionStr, - canBeRunAutomatically: true, - validate: (context: MigrationContextStudio) => { - const configVal = context.getMapping(layerId) - - if (!configVal) { - return false - } - - return configVal.layerName !== mapping.layerName - }, - migrate: (context: MigrationContextStudio) => { - const configVal = context.getMapping(layerId) + migrations.push({ + id: `${versionStr}.studioConfig.setLayerName.${layerId}.${studio}`, + version: versionStr, + canBeRunAutomatically: true, + validate: (context: MigrationContextStudio) => { + const configVal = context.getMapping(layerId) + + if (!configVal) { + return false + } - if (!configVal) { - return - } + return configVal.layerName !== mapping.layerName + }, + migrate: (context: MigrationContextStudio) => { + const configVal = context.getMapping(layerId) - configVal.layerName = mapping.layerName - context.removeMapping(layerId) - context.insertMapping(layerId, configVal) + if (!configVal) { + return } - }) - ) + + configVal.layerName = mapping.layerName + context.removeMapping(layerId) + context.insertMapping(layerId, configVal) + } + }) } return migrations } -export function SetConfigTo(versionStr: string, studio: string, id: string, value: any) { - return literal({ +export function SetConfigTo(versionStr: string, studio: string, id: string, value: any): MigrationStepStudio { + return { id: `${versionStr}.config.valueSet.${studio}.${id}`, version: versionStr, canBeRunAutomatically: true, @@ -244,11 +246,11 @@ export function SetConfigTo(versionStr: string, studio: string, id: string, valu migrate: (context: MigrationContextStudio) => { context.setConfig(id, value) } - }) + } } -export function RemoveConfig(versionStr: string, studio: string, id: string) { - return literal({ +export function RemoveConfig(versionStr: string, studio: string, id: string): MigrationStepStudio { + return { id: `${versionStr}.config.valueSet.${studio}.${id}`, version: versionStr, canBeRunAutomatically: true, @@ -258,7 +260,7 @@ export function RemoveConfig(versionStr: string, studio: string, id: string) { migrate: (context: MigrationContextStudio) => { context.removeConfig(id) } - }) + } } const SOUNDBED_REGEX = /^audio\/(.*)/i @@ -288,7 +290,7 @@ export function StripFolderFromShowStyleConfig( configFields: string[], regex: RegExp ): MigrationStepShowStyle { - return literal({ + return { id: `${versionStr}.normalizeFolders.${studio}.${configId}`, version: versionStr, canBeRunAutomatically: true, @@ -330,7 +332,7 @@ export function StripFolderFromShowStyleConfig( context.setBaseConfig(configId, configTableValue) } - }) + } } export function PrefixEvsWithEvs( @@ -339,7 +341,7 @@ export function PrefixEvsWithEvs( configId: string, evsSourceNumber: string ): MigrationStepStudio { - return literal({ + return { id: `${versionStr}.prefixEvs${evsSourceNumber}WithEvs.${studio}`, version: versionStr, canBeRunAutomatically: true, @@ -364,5 +366,5 @@ export function PrefixEvsWithEvs( config[index] = evsSource context.setConfig(configId, (config as unknown) as ConfigItemValue) } - }) + } } diff --git a/src/tv2-common/migrations/moveSourcesToTable.ts b/src/tv2-common/migrations/moveSourcesToTable.ts index 9533835cb..bc8c5cd49 100644 --- a/src/tv2-common/migrations/moveSourcesToTable.ts +++ b/src/tv2-common/migrations/moveSourcesToTable.ts @@ -10,7 +10,7 @@ export function MoveSourcesToTable( getSisyfosLayersForMigration: (configName: string, val: string) => string[], studioMics?: boolean ): MigrationStepStudio { - const res = literal({ + return { id: `${versionStr}.studioConfig.moveToTable.${configName}`, version: versionStr, canBeRunAutomatically: true, @@ -52,13 +52,11 @@ export function MoveSourcesToTable( context.setConfig(configName, table) } } - }) - - return res + } } export function MoveClipSourcePath(versionStr: string, studio: string): MigrationStepStudio { - const res = literal({ + return { id: `${versionStr}.studioConfig.moveClipSourcePath.${studio}`, version: versionStr, canBeRunAutomatically: true, @@ -76,7 +74,5 @@ export function MoveClipSourcePath(versionStr: string, studio: string): Migratio context.removeConfig('ClipSourcePath') } } - }) - - return res + } } diff --git a/src/tv2-common/migrations/sourceManifest.ts b/src/tv2-common/migrations/sourceManifest.ts index 548259eac..3d180ebaa 100644 --- a/src/tv2-common/migrations/sourceManifest.ts +++ b/src/tv2-common/migrations/sourceManifest.ts @@ -8,7 +8,7 @@ export function MakeConfigForSources( acceptPersistAudio: boolean, defaultVal: ConfigManifestEntryTable['defaultVal'] ): ConfigManifestEntryTable { - return literal({ + return { id: `Sources${name}`, name: `${displayName} Mapping`, description: `${displayName} number to ATEM input and Sisyfos layer`, @@ -85,5 +85,5 @@ export function MakeConfigForSources( ] : []) ] - }) + } } diff --git a/src/tv2-common/migrations/transitions.ts b/src/tv2-common/migrations/transitions.ts index e7abce264..c6e7e353b 100644 --- a/src/tv2-common/migrations/transitions.ts +++ b/src/tv2-common/migrations/transitions.ts @@ -3,7 +3,7 @@ import { literal } from 'tv2-common' import { TableConfigItemAdLibTransitions } from '../blueprintConfig' export function SetShowstyleTransitionMigrationStep(versionStr: string, newValue: string): MigrationStepShowStyle { - return literal({ + return { id: `${versionStr}.setShowstyleTransition`, version: versionStr, canBeRunAutomatically: true, @@ -19,7 +19,7 @@ export function SetShowstyleTransitionMigrationStep(versionStr: string, newValue migrate: (context: MigrationContextShowStyle) => { context.setBaseConfig('ShowstyleTransition', newValue) } - }) + } } type TransitionsTableValue = TableConfigItemAdLibTransitions & { _id: string; [key: string]: string } @@ -31,49 +31,47 @@ export function UpsertValuesIntoTransitionTable( const steps: MigrationStepShowStyle[] = [] values.forEach(val => { - steps.push( - literal({ - 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 + 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 - if (!table) { - return `Transitions table does not exists` - } + 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` - } + if (!existingVal) { + return `Transition "${val.Transition}" does not exist` + } - return existingVal.Transition !== val.Transition - }, - migrate: (context: MigrationContextShowStyle) => { - const table = (context.getBaseConfig('Transitions') as unknown) as TransitionsTableValue[] | undefined + return existingVal.Transition !== val.Transition + }, + migrate: (context: MigrationContextShowStyle) => { + const table = (context.getBaseConfig('Transitions') as unknown) as TransitionsTableValue[] | undefined - if (!table) { - context.setBaseConfig('Transitions', [ - literal({ - _id: val.Transition.replace(/\W\s/g, '_'), - Transition: val.Transition - }) - ]) - } else { - table.push( - literal({ - _id: val.Transition.replace(/\W\s/g, '_'), - Transition: val.Transition - }) - ) + if (!table) { + context.setBaseConfig('Transitions', [ + literal({ + _id: val.Transition.replace(/\W\s/g, '_'), + Transition: val.Transition + }) + ]) + } else { + table.push( + literal({ + _id: val.Transition.replace(/\W\s/g, '_'), + Transition: val.Transition + }) + ) - context.setBaseConfig('Transitions', table) - } + context.setBaseConfig('Transitions', table) } - }) - ) + } + }) }) return steps diff --git a/src/tv2-common/onTimelineGenerate.ts b/src/tv2-common/onTimelineGenerate.ts index e668d7595..9d6fe0a8b 100644 --- a/src/tv2-common/onTimelineGenerate.ts +++ b/src/tv2-common/onTimelineGenerate.ts @@ -12,7 +12,7 @@ import { TimelinePersistentState, TSR } from '@tv2media/blueprints-integration' -import { CasparPlayerClip, literal } from 'tv2-common' +import { ActionSelectFullGrafik, ActionSelectJingle, ActionSelectServerClip, CasparPlayerClip } from 'tv2-common' import { AbstractLLayer, TallyTags } from 'tv2-constants' import * as _ from 'underscore' import { SisyfosLLAyer } from '../tv2_afvd_studio/layers' @@ -56,7 +56,22 @@ export interface PieceMetaData { mediaPlayerSessions?: string[] mediaPlayerOptional?: boolean modifiedByAction?: boolean - belongsToRemotePart?: boolean // used to find last idents in Lives +} + +export interface GraphicPieceMetaData extends PieceMetaData { + belongsToRemotePart?: boolean +} + +export interface JinglePieceMetaData extends PieceMetaData { + userData: ActionSelectJingle +} + +export interface FullPieceMetaData extends PieceMetaData { + userData: ActionSelectFullGrafik +} + +export interface ServerPieceMetaData extends PieceMetaData { + userData: ActionSelectServerClip } export interface SisyfosPersistMetaData { @@ -81,7 +96,7 @@ export function onTimelineGenerate< timeline: OnGenerateTimelineObj[], previousPersistentState: TimelinePersistentState | undefined, previousPartEndState: PartEndState | undefined, - resolvedPieces: IBlueprintResolvedPieceInstance[], + resolvedPieces: Array>, getConfig: (context: IShowStyleContext) => ShowStyleConfig, sourceLayers: ABSourceLayers, _casparLayerClipPending: string, @@ -145,9 +160,7 @@ function processServerLookaheads( return ( [sourceLayers.Caspar.ClipPending, CasparPlayerClip(1), CasparPlayerClip(2)].includes(layer) && !obj.isLookahead && - resolvedPieces.some( - p => p._id === obj.pieceInstanceId && (p as any).partInstanceId === context.currentPartInstance?._id - ) + resolvedPieces.some(p => p._id === obj.pieceInstanceId && p.partInstanceId === context.currentPartInstance?._id) ) }) @@ -190,12 +203,14 @@ function processServerLookaheads( }) } -function isAnyPieceInjectedIntoPart(resolvedPieces: IBlueprintResolvedPieceInstance[], context: ITimelineEventContext) { +function isAnyPieceInjectedIntoPart( + resolvedPieces: Array>, + context: ITimelineEventContext +) { return resolvedPieces .filter(piece => piece.partInstanceId === context.currentPartInstance?._id) .some(piece => { - const metaData = piece.piece.metaData as PieceMetaData | undefined - return metaData?.sisyfosPersistMetaData?.isPieceInjectedInPart + return piece.piece.metaData?.sisyfosPersistMetaData?.isPieceInjectedInPart }) } @@ -203,7 +218,7 @@ export function getEndStateForPart( _context: IRundownContext, _previousPersistentState: TimelinePersistentState | undefined, partInstance: IBlueprintPartInstance, - resolvedPieces: IBlueprintResolvedPieceInstance[], + resolvedPieces: Array>, time: number ): PartEndState { const endState: PartEndStateExt = { @@ -220,8 +235,8 @@ export function getEndStateForPart( p => _.isNumber(p.piece.enable.start) && p.piece.enable && - (p.piece.enable.start as number) <= time && - (!p.piece.enable.duration || p.piece.enable.start + (p.piece.enable.duration as number) >= time) + p.piece.enable.start <= time && + (!p.piece.enable.duration || p.piece.enable.start + p.piece.enable.duration >= time) ) const previousPersistentState: TimelinePersistentStateExt = _previousPersistentState as TimelinePersistentStateExt @@ -234,7 +249,7 @@ export function getEndStateForPart( for (const piece of activePieces) { if (piece.piece.metaData) { - const meta = (piece.piece.metaData as PieceMetaData).mediaPlayerSessions + const meta = piece.piece.metaData.mediaPlayerSessions if (meta && meta.length) { endState.mediaPlayerSessions[piece.piece.sourceLayerId] = meta } @@ -278,11 +293,11 @@ function dveBoxLookaheadUseOriginalEnable(timeline: OnGenerateTimelineObj[]) { } export function createSisyfosPersistedLevelsTimelineObject( - resolvedPieces: IBlueprintResolvedPieceInstance[], + resolvedPieces: Array>, previousSisyfosLayersThatWantsToBePersisted: SisyfosPersistMetaData['sisyfosLayers'] ): TSR.TimelineObjSisyfosChannels { const layersToPersist = findLayersToPersist(resolvedPieces, previousSisyfosLayersThatWantsToBePersisted) - return literal({ + return { id: 'sisyfosPersistenceObject', enable: { start: 0 @@ -299,25 +314,22 @@ export function createSisyfosPersistedLevelsTimelineObject( } }) } - }) + } } function findLayersToPersist( - pieces: IBlueprintResolvedPieceInstance[], + pieces: Array>, sisyfosLayersThatWantsToBePersisted: string[] ): string[] { const sortedPieces = pieces - .filter(piece => { - const metaData = piece.piece.metaData as PieceMetaData | undefined - return metaData?.sisyfosPersistMetaData - }) + .filter(piece => piece.piece.metaData?.sisyfosPersistMetaData) .sort((a, b) => b.resolvedStart - a.resolvedStart) if (sortedPieces.length === 0) { return [] } - const firstPieceMetaData = sortedPieces[0].piece.metaData as PieceMetaData + const firstPieceMetaData = sortedPieces[0].piece.metaData! if (!firstPieceMetaData.sisyfosPersistMetaData!.acceptPersistAudio) { return firstPieceMetaData.sisyfosPersistMetaData!.wantsToPersistAudio ? firstPieceMetaData.sisyfosPersistMetaData!.sisyfosLayers @@ -326,8 +338,8 @@ function findLayersToPersist( const layersToPersist: string[] = [] for (let i = 0; i < sortedPieces.length; i++) { - const pieceMetaData = sortedPieces[i].piece.metaData as PieceMetaData - const sisyfosPersistMetaData: SisyfosPersistMetaData = pieceMetaData!.sisyfosPersistMetaData! + const pieceMetaData = sortedPieces[i].piece.metaData! + const sisyfosPersistMetaData: SisyfosPersistMetaData = pieceMetaData.sisyfosPersistMetaData! if (sisyfosPersistMetaData.wantsToPersistAudio) { layersToPersist.push(...sisyfosPersistMetaData.sisyfosLayers) } diff --git a/src/tv2-common/parts/effekt.ts b/src/tv2-common/parts/effekt.ts index b6dc9b313..68a4cef3f 100644 --- a/src/tv2-common/parts/effekt.ts +++ b/src/tv2-common/parts/effekt.ts @@ -16,6 +16,7 @@ import { GetTagForTransition, literal, PartDefinition, + PieceMetaData, TimeFromFrames, TimelineBlueprintExt, TV2BlueprintConfigBase, @@ -117,60 +118,58 @@ export function CreateEffektForPartInner< const fileName = JoinAssetToFolder(config.studio.JingleFolder, file) - pieces.push( - literal({ - externalId, - name: label, - enable: { start: 0, duration: TimeFromFrames(Number(effektConfig.Duration)) }, - outputLayerId: SharedOutputLayers.JINGLE, - sourceLayerId: layers.sourceLayer, - lifespan: PieceLifespan.WithinPart, - pieceType: IBlueprintPieceType.InTransition, - content: literal>({ - fileName, - path: JoinAssetToNetworkPath( - config.studio.JingleNetworkBasePath, - config.studio.JingleFolder, - file, - config.studio.JingleFileExtension - ), // full path on the source network storage - mediaFlowIds: [config.studio.JingleMediaFlowId], - previewFrame: Number(effektConfig.StartAlpha), - ignoreMediaObjectStatus: config.studio.JingleIgnoreStatus, - ignoreBlackFrames: true, - ignoreFreezeFrame: true, - timelineObjects: literal([ - literal({ - id: '', - enable: { - start: 0 - }, - priority: 1, - layer: layers.casparLayer, - content: { - deviceType: TSR.DeviceType.CASPARCG, - type: TSR.TimelineContentTypeCasparCg.MEDIA, - file: fileName - } - }), - ...EnableDSK(config, 'JINGLE', { start: Number(config.studio.CasparPrerollDuration) }), - literal({ - id: '', - enable: { - start: 0 - }, - priority: 1, - layer: layers.sisyfosLayer, - content: { - deviceType: TSR.DeviceType.SISYFOS, - type: TSR.TimelineContentTypeSisyfos.CHANNEL, - isPgm: 1 - } - }) - ]) - }) + pieces.push({ + externalId, + name: label, + enable: { start: 0, duration: TimeFromFrames(Number(effektConfig.Duration)) }, + outputLayerId: SharedOutputLayers.JINGLE, + sourceLayerId: layers.sourceLayer, + lifespan: PieceLifespan.WithinPart, + pieceType: IBlueprintPieceType.InTransition, + content: literal>({ + fileName, + path: JoinAssetToNetworkPath( + config.studio.JingleNetworkBasePath, + config.studio.JingleFolder, + file, + config.studio.JingleFileExtension + ), // full path on the source network storage + mediaFlowIds: [config.studio.JingleMediaFlowId], + previewFrame: Number(effektConfig.StartAlpha), + ignoreMediaObjectStatus: config.studio.JingleIgnoreStatus, + ignoreBlackFrames: true, + ignoreFreezeFrame: true, + timelineObjects: literal([ + literal({ + id: '', + enable: { + start: 0 + }, + priority: 1, + layer: layers.casparLayer, + content: { + deviceType: TSR.DeviceType.CASPARCG, + type: TSR.TimelineContentTypeCasparCg.MEDIA, + file: fileName + } + }), + ...EnableDSK(config, 'JINGLE', { start: Number(config.studio.CasparPrerollDuration) }), + literal({ + id: '', + enable: { + start: 0 + }, + priority: 1, + layer: layers.sisyfosLayer, + content: { + deviceType: TSR.DeviceType.SISYFOS, + type: TSR.TimelineContentTypeSisyfos.CHANNEL, + isPgm: 1 + } + }) + ]) }) - ) + }) return { inTransition: { @@ -190,7 +189,7 @@ export function CreateMixTransitionBlueprintPieceForPart( externalId: string, durationInFrames: number, sourceLayer: string -): IBlueprintPiece { +): IBlueprintPiece { const tags = [ GetTagForTransition( literal({ @@ -209,8 +208,8 @@ function createEffectBlueprintPiece( name: string, sourceLayer: string, tags: string[] -): IBlueprintPiece { - return literal({ +): IBlueprintPiece { + return { enable: { start: 0, duration: Math.max(TimeFromFrames(durationInFrames), 1000) @@ -225,7 +224,7 @@ function createEffectBlueprintPiece( timelineObjects: [], ignoreMediaObjectStatus: true } - }) + } } export function CreateInTransitionForAtemTransitionStyle( @@ -245,7 +244,7 @@ export function CreateDipTransitionBlueprintPieceForPart( externalId: string, durationInFrames: number, sourceLayer: string -): IBlueprintPiece { +): IBlueprintPiece { const tags = [ GetTagForTransition( literal({ diff --git a/src/tv2-common/parts/invalid.ts b/src/tv2-common/parts/invalid.ts index 16b40bb79..b7b1a2cf8 100644 --- a/src/tv2-common/parts/invalid.ts +++ b/src/tv2-common/parts/invalid.ts @@ -1,13 +1,13 @@ import { BlueprintResultPart, IBlueprintPart } from '@tv2media/blueprints-integration' -import { literal, PartDefinition } from 'tv2-common' +import { PartDefinition } from 'tv2-common' export function CreatePartInvalid(ingestPart: PartDefinition, externalIdSuffix?: string): BlueprintResultPart { - const part = literal({ + const part: IBlueprintPart = { externalId: ingestPart.externalId + (externalIdSuffix ? `_${externalIdSuffix}` : ''), title: ingestPart.rawType || 'Unknown', metaData: {}, invalid: true - }) + } return { part, diff --git a/src/tv2-common/parts/kam.ts b/src/tv2-common/parts/kam.ts index 64de85c31..ebd6bdbc1 100644 --- a/src/tv2-common/parts/kam.ts +++ b/src/tv2-common/parts/kam.ts @@ -1,5 +1,5 @@ import { BlueprintResultPart, IBlueprintPart, IShowStyleUserContext } from '@tv2media/blueprints-integration' -import { literal, PartDefinition, PartTime, TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' +import { PartDefinition, PartTime, TV2BlueprintConfigBase, TV2StudioConfigBase } from 'tv2-common' export function CreatePartKamBase< StudioConfig extends TV2StudioConfigBase, @@ -12,12 +12,12 @@ export function CreatePartKamBase< ): { part: BlueprintResultPart; duration: number; invalid?: true } { const partTime = PartTime(config, partDefinition, totalWords, false) - const part = literal({ + const part: IBlueprintPart = { externalId: partDefinition.externalId, title: partDefinition.rawType, metaData: {}, expectedDuration: partTime > 0 ? partTime : 0 - }) + } return { part: { diff --git a/src/tv2-common/parts/server.ts b/src/tv2-common/parts/server.ts index 27789dc90..56dd40854 100644 --- a/src/tv2-common/parts/server.ts +++ b/src/tv2-common/parts/server.ts @@ -14,7 +14,7 @@ import { MakeContentServer, MakeContentServerSourceLayers, PieceMetaData, - SisyfosPersistMetaData + ServerPieceMetaData } from 'tv2-common' import { AdlibActionType, PartType, SharedOutputLayers, TallyTags } from 'tv2-constants' import { ActionSelectServerClip } from '../actions' @@ -22,13 +22,9 @@ import { TV2BlueprintConfigBase, TV2StudioConfigBase } from '../blueprintConfig' import { getSourceDuration, GetVTContentProperties } from '../content' import { getServerSeek, ServerPosition, ServerSelectMode } from '../helpers' import { PartDefinition } from '../inewsConversion' -import { literal, SanitizeString } from '../util' +import { SanitizeString } from '../util' import { CreatePartInvalid } from './invalid' -interface PieceMetaDataServer { - userData: ActionSelectServerClip -} - export interface ServerPartProps { voLayer: boolean voLevels: boolean @@ -96,7 +92,7 @@ export async function CreatePartServerBase< const displayTitle = getDisplayTitle(partDefinition) const basePart = getBasePart(partDefinition, displayTitle, actualDuration, file) - const pieces: IBlueprintPiece[] = [] + const pieces: Array> = [] const serverSelectionBlueprintPiece = getServerSelectionBlueprintPiece( partDefinition, @@ -247,29 +243,29 @@ function getServerSelectionBlueprintPiece< context: IShowStyleUserContext, config: ShowStyleConfig, prerollDuration: number -): IBlueprintPiece { +): IBlueprintPiece { const userDataElement = getUserData(partDefinition, contentProps.file, actualDuration, partProps) const contentServerElement = getContentServerElement(partDefinition, partProps, contentProps, layers, context, config) - return literal({ + return { externalId: partDefinition.externalId, name: contentProps.file, enable: { start: 0 }, outputLayerId: SharedOutputLayers.SEC, sourceLayerId: layers.SourceLayer.SelectedServer, lifespan: PieceLifespan.OutOnSegmentEnd, - metaData: literal({ + metaData: { mediaPlayerSessions: [contentProps.mediaPlayerSession], userData: userDataElement, - sisyfosPersistMetaData: literal({ + sisyfosPersistMetaData: { sisyfosLayers: [], acceptPersistAudio: partProps.adLibPix && partProps.voLevels - }) - }), + } + }, content: contentServerElement, tags: [GetTagForServerNext(partDefinition.segmentExternalId, contentProps.file, partProps.voLayer)], prerollDuration - }) + } } function getPgmBlueprintPiece< @@ -282,17 +278,17 @@ function getPgmBlueprintPiece< layers: ServerPartLayers, config: ShowStyleConfig, prerollDuration: number -): IBlueprintPiece { - return literal({ +): IBlueprintPiece { + return { externalId: partDefinition.externalId, name: contentProps.file, enable: { start: 0 }, outputLayerId: SharedOutputLayers.PGM, sourceLayerId: layers.SourceLayer.PgmServer, lifespan: PieceLifespan.WithinPart, - metaData: literal({ + metaData: { mediaPlayerSessions: [contentProps.mediaPlayerSession] - }), + }, content: { ...GetVTContentProperties(config, contentProps), timelineObjects: CutToServer(contentProps.mediaPlayerSession, partDefinition, config, layers.AtemLLayer.MEPgm) @@ -302,5 +298,5 @@ function getPgmBlueprintPiece< TallyTags.SERVER_IS_LIVE ], prerollDuration - }) + } } diff --git a/src/tv2-common/pieces/adlibServer.ts b/src/tv2-common/pieces/adlibServer.ts index 1e704c1d1..0b36bd9f1 100644 --- a/src/tv2-common/pieces/adlibServer.ts +++ b/src/tv2-common/pieces/adlibServer.ts @@ -37,7 +37,7 @@ export async function CreateAdlibServer< const mediaObjectDuration = mediaObjectDurationSec && mediaObjectDurationSec * 1000 const sourceDuration = getSourceDuration(mediaObjectDuration, config.studio.ServerPostrollDuration) - return literal({ + return { externalId: partDefinition.externalId + '-adLib-server', actionId: AdlibActionType.SELECT_SERVER_CLIP, userData: literal({ @@ -70,5 +70,5 @@ export async function CreateAdlibServer< uniquenessId: `${voLayer ? 'vo' : 'server'}_${partDefinition.storyName}_${file}` } // triggerModes: getServerAdLibTriggerModes() /** @todo: uncomment for Server Resume */ - }) + } } diff --git a/src/tv2-common/pieces/script.ts b/src/tv2-common/pieces/script.ts index 63f93a124..66830e66a 100644 --- a/src/tv2-common/pieces/script.ts +++ b/src/tv2-common/pieces/script.ts @@ -4,7 +4,6 @@ import { SharedOutputLayers } from 'tv2-constants' const PREVIEW_CHARACTERS = 30 -// export function AddScript(part: PartDefinition, pieces: IBlueprintPiece[], duration: number, slutord: boolean) { export function AddScript(part: PartDefinition, pieces: IBlueprintPiece[], duration: number, sourceLayerId: string) { if (!pieces.length) { return @@ -16,29 +15,27 @@ export function AddScript(part: PartDefinition, pieces: IBlueprintPiece[], durat } if (script.length) { const stripLength = Math.min(PREVIEW_CHARACTERS, script.length) - pieces.push( - literal({ - externalId: part.externalId, - name: script.slice(0, stripLength), - enable: { - start: 0 - }, - outputLayerId: SharedOutputLayers.MANUS, - sourceLayerId, - lifespan: PieceLifespan.WithinPart, - content: literal>({ - firstWords: script.slice(0, stripLength), - lastWords: script - .replace(/\n/gi, ' ') - .trim() - .slice(script.length - stripLength) - ?.trim(), - fullScript: script, - sourceDuration: duration, - lastModified: part.modified * 1000, - timelineObjects: [] - }) + pieces.push({ + externalId: part.externalId, + name: script.slice(0, stripLength), + enable: { + start: 0 + }, + outputLayerId: SharedOutputLayers.MANUS, + sourceLayerId, + lifespan: PieceLifespan.WithinPart, + content: literal>({ + firstWords: script.slice(0, stripLength), + lastWords: script + .replace(/\n/gi, ' ') + .trim() + .slice(script.length - stripLength) + ?.trim(), + fullScript: script, + sourceDuration: duration, + lastModified: part.modified * 1000, + timelineObjects: [] }) - ) + }) } } diff --git a/src/tv2-common/util.ts b/src/tv2-common/util.ts index 0e4f2d0f0..39f213903 100644 --- a/src/tv2-common/util.ts +++ b/src/tv2-common/util.ts @@ -13,7 +13,7 @@ export type WithValuesOfTypes = { [P in keyof T as T[P] extends Q | undefi export type OptionalExceptFor = Partial & Pick export type EmptyBaseObj = OptionalExceptFor, 'layer' | 'enable' | 'classes'> export function createEmptyObject(obj: EmptyBaseObj): TSR.TimelineObjEmpty { - return literal({ + return { id: '', priority: 0, ...obj, @@ -21,7 +21,7 @@ export function createEmptyObject(obj: EmptyBaseObj): TSR.TimelineObjEmpty { deviceType: TSR.DeviceType.ABSTRACT, type: 'empty' } - }) + } } /** diff --git a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts index 87cd90246..b84748084 100644 --- a/src/tv2_afvd_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/actions.spec.ts @@ -406,7 +406,7 @@ async function getTransitionPiece( } function getATEMMEObj(piece: IBlueprintPieceInstance): TSR.TimelineObjAtemME { - const atemObj = (piece.piece.content!.timelineObjects as TSR.TSRTimelineObj[]).find( + const atemObj = (piece.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( obj => obj.layer === AtemLLayer.AtemMEProgram && obj.content.deviceType === TSR.DeviceType.ATEM && @@ -792,9 +792,9 @@ describe('Camera shortcuts on server', () => { const context = makeMockContext('cut', 'cam', 'cam') context.currentPieceInstances = [ - literal({ + { _id: 'serverPieceInstance', - piece: literal({ + piece: { _id: 'Server Current', enable: { start: 0 @@ -807,9 +807,9 @@ describe('Camera shortcuts on server', () => { content: { timelineObjects: [] } - }), + }, partInstanceId: '' - }) + } ] context.nextPart = undefined @@ -835,9 +835,9 @@ describe('Camera shortcuts on server', () => { const context = makeMockContext('cut', 'cam', 'cam') context.currentPieceInstances = [ - literal({ + { _id: 'serverPieceInstance', - piece: literal({ + piece: { _id: 'Server Current', enable: { start: 0 @@ -850,9 +850,9 @@ describe('Camera shortcuts on server', () => { content: { timelineObjects: [] } - }), + }, partInstanceId: '' - }) + } ] context.nextPart = undefined @@ -880,9 +880,9 @@ describe('Camera shortcuts on VO', () => { const context = makeMockContext('cut', 'cam', 'cam') context.currentPieceInstances = [ - literal({ + { _id: 'voPieceInstance', - piece: literal({ + piece: { _id: 'VO Current', enable: { start: 0 @@ -895,9 +895,9 @@ describe('Camera shortcuts on VO', () => { content: { timelineObjects: [] } - }), + }, partInstanceId: '' - }) + } ] context.nextPart = undefined @@ -923,9 +923,9 @@ describe('Camera shortcuts on VO', () => { const context = makeMockContext('cut', 'cam', 'cam') context.currentPieceInstances = [ - literal({ + { _id: 'voPieceInstance', - piece: literal({ + piece: { _id: 'VO Current', enable: { start: 0 @@ -938,9 +938,9 @@ describe('Camera shortcuts on VO', () => { content: { timelineObjects: [] } - }), + }, partInstanceId: '' - }) + } ] context.nextPart = undefined diff --git a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts index fff09412d..acce40bf4 100644 --- a/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts +++ b/src/tv2_afvd_showstyle/__tests__/blueprint.spec.ts @@ -1,6 +1,5 @@ import { BlueprintResultSegment, - IBlueprintActionManifest, IBlueprintActionManifestDisplayContent, IngestSegment } from '@tv2media/blueprints-integration' @@ -172,7 +171,7 @@ describe('AFVD Blueprint', () => { ]) expect(fullPart.adLibPieces).toHaveLength(0) expect(fullPart.actions).toHaveLength(1) - const fullAdlibAction = fullPart.actions![0] as IBlueprintActionManifest + const fullAdlibAction = fullPart.actions[0] expect(fullAdlibAction).toBeTruthy() expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( SharedSourceLayers.PgmPilot @@ -253,7 +252,7 @@ describe('AFVD Blueprint', () => { expect(fullPart.pieces).toHaveLength(2) expect(fullPart.adLibPieces).toHaveLength(0) expect(fullPart.actions).toHaveLength(1) - const fullAdlibAction = fullPart.actions![0] as IBlueprintActionManifest + const fullAdlibAction = fullPart.actions[0] expect(fullAdlibAction).toBeTruthy() expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( SharedSourceLayers.PgmPilot @@ -305,7 +304,7 @@ describe('AFVD Blueprint', () => { expect(fullPart.pieces).toHaveLength(3) expect(fullPart.adLibPieces).toHaveLength(0) expect(fullPart.actions).toHaveLength(1) - const fullAdlibAction = fullPart.actions![0] as IBlueprintActionManifest + const fullAdlibAction = fullPart.actions[0] expect(fullAdlibAction).toBeTruthy() expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( SharedSourceLayers.PgmPilot @@ -356,7 +355,7 @@ describe('AFVD Blueprint', () => { expect(fullPart.adLibPieces).toHaveLength(0) expect(fullPart.actions).toHaveLength(1) expect(fullPart.actions).toHaveLength(1) - const fullAdlibAction = fullPart.actions![0] as IBlueprintActionManifest + const fullAdlibAction = fullPart.actions[0] expect(fullAdlibAction).toBeTruthy() expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( SharedSourceLayers.PgmPilot @@ -576,7 +575,7 @@ describe('AFVD Blueprint', () => { expect(fullPart.pieces).toHaveLength(2) expect(fullPart.adLibPieces).toHaveLength(0) expect(fullPart.actions).toHaveLength(1) - const fullAdlibAction = fullPart.actions![0] as IBlueprintActionManifest + const fullAdlibAction = fullPart.actions[0] expect(fullAdlibAction).toBeTruthy() expect((fullAdlibAction.display as IBlueprintActionManifestDisplayContent).sourceLayerId).toBe( SharedSourceLayers.PgmPilot diff --git a/src/tv2_afvd_showstyle/__tests__/layers-check.ts b/src/tv2_afvd_showstyle/__tests__/layers-check.ts index fa0966dae..7b99f7217 100644 --- a/src/tv2_afvd_showstyle/__tests__/layers-check.ts +++ b/src/tv2_afvd_showstyle/__tests__/layers-check.ts @@ -8,7 +8,7 @@ import { TSR } from '@tv2media/blueprints-integration' -import { GetDSKSourceLayerNames, literal } from 'tv2-common' +import { GetDSKSourceLayerNames } from 'tv2-common' import mappingsDefaults, { getMediaPlayerMappings } from '../../tv2_afvd_studio/migrations/mappings-defaults' import { ATEMModel } from '../../types/atem' import { getConfig } from '../helpers/config' @@ -33,10 +33,10 @@ export function checkAllLayers( .sort() const allOutputLayers = _.map(OutputlayerDefaults, m => m._id) - const allMappings = literal({ + const allMappings: BlueprintMappings = { ...mappingsDefaults, ...getMediaPlayerMappings(config.mediaPlayers) - }) + } const validateObject = (obj: TimelineObjectCoreExt) => { const isAbstract = obj.content.deviceType === TSR.DeviceType.ABSTRACT diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 3878b9961..f3c884548 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -4,7 +4,6 @@ import { GraphicsContent, IBlueprintActionManifest, IBlueprintAdLibPiece, - IBlueprintRundown, IBlueprintShowStyleVariant, IngestRundown, IShowStyleUserContext, @@ -36,7 +35,6 @@ import { literal, PieceMetaData, replaySourceName, - SisyfosPersistMetaData, SourceDefinitionKam, SourceInfo, SourceInfoToSourceDefinition, @@ -81,13 +79,13 @@ export function getRundown(context: IShowStyleUserContext, ingestRundown: Ingest const config = getShowStyleConfig(context) return { - rundown: literal({ + rundown: { externalId: ingestRundown.externalId, name: ingestRundown.name, timing: { type: PlaylistTimingType.None } - }), + }, globalAdLibPieces: getGlobalAdLibPiecesAFVD(context, config), globalActions: getGlobalAdlibActionsAFVD(context, config), baseline: getBaseline(config) @@ -95,8 +93,8 @@ export function getRundown(context: IShowStyleUserContext, ingestRundown: Ingest } function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: BlueprintConfig): IBlueprintAdLibPiece[] { - function makeEVSAdLibs(info: SourceInfo, rank: number, vo: boolean): IBlueprintAdLibPiece[] { - const res: IBlueprintAdLibPiece[] = [] + function makeEVSAdLibs(info: SourceInfo, rank: number, vo: boolean): Array> { + const res: Array> = [] res.push({ externalId: 'delayed', name: replaySourceName(info.id, vo), @@ -106,12 +104,12 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint expectedDuration: 0, lifespan: PieceLifespan.WithinPart, toBeQueued: true, - metaData: literal({ + metaData: { sisyfosPersistMetaData: { sisyfosLayers: info.sisyfosLayers ?? [], acceptPersistAudio: vo } - }), + }, tags: [AdlibTags.ADLIB_QUEUE_NEXT, vo ? AdlibTags.ADLIB_VO_AUDIO_LEVEL : AdlibTags.ADLIB_FULL_AUDIO_LEVEL], content: { ignoreMediaObjectStatus: true, @@ -135,12 +133,11 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint ] } }) - return res } - function makeRemoteAdLibs(info: SourceInfo, rank: number): IBlueprintAdLibPiece[] { - const res: IBlueprintAdLibPiece[] = [] + function makeRemoteAdLibs(info: SourceInfo, rank: number): Array> { + const res: Array> = [] const eksternSisyfos = GetSisyfosTimelineObjForRemote(config, info) res.push({ externalId: 'live', @@ -152,11 +149,11 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint lifespan: PieceLifespan.WithinPart, toBeQueued: true, metaData: { - sisyfosPersistMetaData: literal({ + sisyfosPersistMetaData: { sisyfosLayers: info.sisyfosLayers ?? [], wantsToPersistAudio: info.wantsToPersistAudio, acceptPersistAudio: info.acceptPersistAudio - }) + } }, tags: [AdlibTags.ADLIB_QUEUE_NEXT], content: { @@ -185,8 +182,8 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint } // aux adlibs - function makeRemoteAuxStudioAdLibs(info: SourceInfo, rank: number): IBlueprintAdLibPiece[] { - const res: IBlueprintAdLibPiece[] = [] + function makeRemoteAuxStudioAdLibs(info: SourceInfo, rank: number): Array> { + const res: Array> = [] res.push({ externalId: 'auxstudio', name: info.id + '', @@ -196,11 +193,11 @@ function getGlobalAdLibPiecesAFVD(context: IStudioUserContext, config: Blueprint expectedDuration: 0, lifespan: PieceLifespan.OutOnShowStyleEnd, metaData: { - sisyfosPersistMetaData: literal({ + sisyfosPersistMetaData: { sisyfosLayers: info.sisyfosLayers ?? [], wantsToPersistAudio: info.wantsToPersistAudio, acceptPersistAudio: info.acceptPersistAudio - }) + } }, tags: [AdlibTags.ADLIB_TO_STUDIO_SCREEN_AUX], content: { @@ -545,35 +542,33 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri const name = `${info.type} ${info.id}` const layer = info.type === SourceInfoType.KAM ? SourceLayer.PgmCam : SourceLayer.PgmLive - const userData = literal({ + 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)] + } }) - blueprintActions.push( - literal({ - 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 = literal({ + const userData: ActionCutSourceToBox = { type: AdlibActionType.CUT_SOURCE_TO_BOX, name, box, @@ -584,76 +579,70 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri 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] + } }) - blueprintActions.push( - literal({ - 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 = literal({ + 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)] + } }) - blueprintActions.push( - literal({ - 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 = literal({ + 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] + } }) - blueprintActions.push( - literal({ - 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 @@ -675,24 +664,22 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri }) function makeRecallLastLiveAction() { - const userData = literal({ + 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] + } }) - blueprintActions.push( - literal({ - 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() @@ -718,13 +705,13 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri makeServerAdlibBoxesActions(globalRank++) - function makeClearGraphicsAction() { - const userData = literal({ + function makeClearGraphicsAction(): IBlueprintActionManifest { + const userData: ActionClearGraphics = { type: AdlibActionType.CLEAR_GRAPHICS, sendCommands: true, label: 'GFX Clear' - }) - return literal({ + } + return { externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CLEAR_GRAPHICS, userData, @@ -739,16 +726,16 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri currentPieceTags: [TallyTags.GFX_CLEAR], nextPieceTags: [TallyTags.GFX_CLEAR] } - }) + } } - function makeClearGraphicsAltudAction() { - const userData = literal({ + function makeClearGraphicsAltudAction(): IBlueprintActionManifest { + const userData: ActionClearGraphics = { type: AdlibActionType.CLEAR_GRAPHICS, sendCommands: false, label: 'GFX Altud' - }) - return literal({ + } + return { externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CLEAR_GRAPHICS, userData, @@ -763,73 +750,66 @@ function getGlobalAdlibActionsAFVD(_context: IStudioUserContext, config: Bluepri currentPieceTags: [TallyTags.GFX_ALTUD], nextPieceTags: [TallyTags.GFX_ALTUD] } - }) + } } blueprintActions.push(makeClearGraphicsAction(), makeClearGraphicsAltudAction()) blueprintActions.push(...GetTransitionAdLibActions(config, 800)) - const recallLastLiveDveUserData = literal({ + 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] + } }) - blueprintActions.push( - literal({ - 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 boxSources = ['', '', '', ''] - const userData = literal({ + 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] + } }) - blueprintActions.push( - literal({ - 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 = literal({ + 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( - literal({ - 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] - } - }) - ) return blueprintActions } diff --git a/src/tv2_afvd_showstyle/getSegment.ts b/src/tv2_afvd_showstyle/getSegment.ts index 043572f0e..bb910eedc 100644 --- a/src/tv2_afvd_showstyle/getSegment.ts +++ b/src/tv2_afvd_showstyle/getSegment.ts @@ -62,8 +62,8 @@ export async function getSegment( } } -export function CreatePartContinuity(config: ShowStyleConfig, ingestSegment: IngestSegment) { - return literal({ +export function CreatePartContinuity(config: ShowStyleConfig, ingestSegment: IngestSegment): BlueprintResultPart { + return { part: { externalId: `${ingestSegment.externalId}-CONTINUITY`, title: 'CONTINUITY', @@ -105,7 +105,7 @@ export function CreatePartContinuity(config: ShowStyleConfig, ingestSegment: Ing ], adLibPieces: [], actions: [] - }) + } } function insertSpecialPieces( 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 773c2e71c..81fa9afbd 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/grafikViz.spec.ts @@ -11,6 +11,7 @@ import { AtemLLayerDSK, CueDefinitionGraphic, GraphicInternal, + GraphicPieceMetaData, GraphicPilot, literal, PartDefinitionKam, @@ -108,7 +109,7 @@ describe('grafik piece', () => { cue.adlib ? { rank: 0 } : undefined ) expect(pieces).toEqual([ - literal({ + literal>({ externalId: partId, name: 'bund - Odense\n - Copenhagen', enable: { @@ -116,12 +117,12 @@ describe('grafik piece', () => { duration: 4000 }, lifespan: PieceLifespan.WithinPart, - metaData: literal({ + metaData: { sisyfosPersistMetaData: { sisyfosLayers: [] }, belongsToRemotePart: false - }), + }, outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, content: literal>({ @@ -412,7 +413,7 @@ describe('grafik piece', () => { cue.adlib ? { rank: 0 } : undefined ) expect(pieces).toEqual([ - literal({ + literal>({ externalId: partId, name: 'bund - Odense\n - Copenhagen', enable: { @@ -420,12 +421,12 @@ describe('grafik piece', () => { duration: 4000 }, lifespan: PieceLifespan.WithinPart, - metaData: literal({ + metaData: { sisyfosPersistMetaData: { sisyfosLayers: [] }, belongsToRemotePart: false - }), + }, outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, content: literal>({ @@ -491,19 +492,19 @@ describe('grafik piece', () => { cue.adlib ? { rank: 0 } : undefined ) expect(pieces).toEqual([ - literal({ + literal>({ externalId: partId, name: 'bund - Odense\n - Copenhagen', enable: { start: 10000 }, lifespan: PieceLifespan.WithinPart, - metaData: literal({ + metaData: { sisyfosPersistMetaData: { sisyfosLayers: [] }, belongsToRemotePart: false - }), + }, outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, content: literal>({ @@ -566,19 +567,19 @@ describe('grafik piece', () => { cue.adlib ? { rank: 0 } : undefined ) expect(pieces).toEqual([ - literal({ + literal>({ externalId: partId, name: 'direkte - KØBENHAVN', enable: { start: 0 }, lifespan: PieceLifespan.WithinPart, - metaData: literal({ + metaData: { sisyfosPersistMetaData: { sisyfosLayers: [] }, belongsToRemotePart: false - }), + }, outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsIdent, content: literal>({ @@ -641,7 +642,7 @@ describe('grafik piece', () => { cue.adlib ? { rank: 0 } : undefined ) expect(pieces).toEqual([ - literal({ + literal>({ externalId: partId, name: 'arkiv - unnamed org', enable: { @@ -649,12 +650,12 @@ describe('grafik piece', () => { duration: 4000 }, lifespan: PieceLifespan.WithinPart, - metaData: literal({ + metaData: { sisyfosPersistMetaData: { sisyfosLayers: [] }, belongsToRemotePart: false - }), + }, outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsIdent, content: literal>({ 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 a6bcd1e8b..53fdaea3a 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/lyd.spec.ts @@ -140,36 +140,6 @@ describe('lyd', () => { expect(context.getNotes()[0].type).toEqual(NoteType.NOTIFY_USER_WARNING) }) - test('Lyd not configured', () => { - const parsedCue = ParseCue(['LYD=SN_MISSING', ';0.00-0.10'], CONFIG) as CueDefinitionLYD - const pieces: IBlueprintPiece[] = [] - const adlibPieces: IBlueprintAdLibPiece[] = [] - const actions: IBlueprintActionManifest[] = [] - - const context = makeMockContext() - - EvaluateLYD( - context, - { - showStyle: (defaultShowStyleConfig as unknown) as ShowStyleConfig, - studio: (defaultStudioConfig as unknown) as StudioConfig, - sources: EMPTY_SOURCE_CONFIG, - mediaPlayers: [], - dsk: defaultDSKConfig, - selectedGraphicsSetup: DEFAULT_GRAPHICS_SETUP - }, - 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) - }) - test('Lyd adlib', () => { const parsedCue = ParseCue(['LYD=SN_INTRO', ';x.xx'], CONFIG) as CueDefinitionLYD const pieces: IBlueprintPiece[] = [] 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 54cf0d7e3..fb075a18d 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/__tests__/telefon.spec.ts @@ -12,9 +12,9 @@ import { CueDefinitionGraphic, CueDefinitionTelefon, GraphicInternal, + GraphicPieceMetaData, literal, - PartDefinitionKam, - PieceMetaData + PartDefinitionKam } from 'tv2-common' import { CueType, PartType, SharedGraphicLLayer, SharedOutputLayers, SourceType } from 'tv2-constants' import { SegmentUserContext } from '../../../../__mocks__/context' @@ -106,7 +106,7 @@ describe('telefon', () => { cue ) expect(pieces).toEqual([ - literal({ + literal>({ externalId: partId, name: 'TLF 1', enable: { @@ -115,12 +115,12 @@ describe('telefon', () => { outputLayerId: SharedOutputLayers.OVERLAY, sourceLayerId: SourceLayer.PgmGraphicsLower, lifespan: PieceLifespan.WithinPart, - metaData: literal({ + metaData: { belongsToRemotePart: false, sisyfosPersistMetaData: { sisyfosLayers: [] } - }), + }, content: literal>({ fileName: 'bund', path: 'bund', diff --git a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts index 49655d543..3c2864882 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/adlib.ts @@ -27,7 +27,7 @@ import { MakeContentDVE } from '../content/dve' export async function EvaluateAdLib( context: IShowStyleUserContext, config: BlueprintConfig, - adLibPieces: IBlueprintAdLibPiece[], + adLibPieces: Array>, actions: IBlueprintActionManifest[], mediaSubscriptions: HackPartMediaObjectSubscription[], partId: string, @@ -100,33 +100,31 @@ export async function EvaluateAdLib( const content = MakeContentDVE(context, config, partDefinition, cueDVE, rawTemplate, false, true) - adLibPieces.push( - literal({ - _rank: rank, - externalId: partId, - name: `DVE: ${parsedCue.variant}`, - sourceLayerId: SourceLayer.PgmDVE, - outputLayerId: SharedOutputLayers.PGM, - uniquenessId: getUniquenessIdDVE(cueDVE), - toBeQueued: true, - content: content.content, - invalid: !content.valid, - lifespan: PieceLifespan.WithinPart, - metaData: literal({ - sources: cueDVE.sources, - config: rawTemplate, - userData: literal({ - type: AdlibActionType.SELECT_DVE, - config: cueDVE, - videoId: partDefinition.fields.videoId, - segmentExternalId: partDefinition.segmentExternalId - }), - sisyfosPersistMetaData: { - sisyfosLayers: [] - } + adLibPieces.push({ + _rank: rank, + externalId: partId, + name: `DVE: ${parsedCue.variant}`, + sourceLayerId: SourceLayer.PgmDVE, + outputLayerId: SharedOutputLayers.PGM, + uniquenessId: getUniquenessIdDVE(cueDVE), + toBeQueued: true, + content: content.content, + invalid: !content.valid, + lifespan: PieceLifespan.WithinPart, + metaData: literal({ + sources: cueDVE.sources, + config: rawTemplate, + userData: literal({ + type: AdlibActionType.SELECT_DVE, + config: cueDVE, + videoId: partDefinition.fields.videoId, + segmentExternalId: partDefinition.segmentExternalId }), - tags: [AdlibTags.ADLIB_FLOW_PRODUCER] - }) - ) + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), + 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 c040aae4d..202258d60 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/clearGrafiks.ts @@ -48,34 +48,32 @@ export function EvaluateClearGrafiks( }) }) - pieces.push( - literal({ - externalId: partId, - name: 'CLEAR', - ...CreateTimingEnable(parsedCue, GetDefaultOut(config)), - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, - lifespan: PieceLifespan.WithinPart, - content: { - timelineObjects: config.studio.HTMLGraphics - ? [ - literal({ - id: '', - enable: { - start: 0, - duration: 1000 - }, - priority: 100, - layer: SharedGraphicLLayer.GraphicLLayerAdLibs, - content: { - deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, - showId: config.selectedGraphicsSetup.OvlShowId - } - }) - ] - : [] - } - }) - ) + pieces.push({ + externalId: partId, + name: 'CLEAR', + ...CreateTimingEnable(parsedCue, GetDefaultOut(config)), + outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SourceLayer.PgmAdlibGraphicCmd, + lifespan: PieceLifespan.WithinPart, + content: { + timelineObjects: config.studio.HTMLGraphics + ? [ + literal({ + id: '', + enable: { + start: 0, + duration: 1000 + }, + priority: 100, + layer: SharedGraphicLLayer.GraphicLLayerAdLibs, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.CLEAR_ALL_ELEMENTS, + showId: config.selectedGraphicsSetup.OvlShowId + } + }) + ] + : [] + } + }) } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts index 46081decc..0a5e4ee7b 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/dve.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/dve.ts @@ -15,7 +15,6 @@ import { getUniquenessIdDVE, literal, PartDefinition, - PieceMetaData, TemplateIsValid } from 'tv2-common' import { AdlibActionType, SharedOutputLayers } from 'tv2-constants' @@ -62,7 +61,7 @@ export function EvaluateDVE( if (content.valid) { if (adlib) { adlibPieces.push( - literal({ + literal>({ _rank: rank || 0, externalId: partDefinition.externalId, name: `${partDefinition.storyName} DVE: ${parsedCue.template}`, @@ -73,7 +72,7 @@ export function EvaluateDVE( toBeQueued: true, content: content.content, prerollDuration: Number(config.studio.CasparPrerollDuration) || 0, - metaData: literal({ + metaData: { sources: parsedCue.sources, config: rawTemplate, userData: literal({ @@ -85,7 +84,7 @@ export function EvaluateDVE( sisyfosPersistMetaData: { sisyfosLayers: [] } - }) + } }) ) } else { @@ -93,7 +92,7 @@ export function EvaluateDVE( start = start ? start : 0 const end = parsedCue.end ? CalculateTime(parsedCue.end) : undefined pieces.push( - literal({ + literal>({ externalId: partDefinition.externalId, name: `DVE: ${parsedCue.template}`, enable: { @@ -106,20 +105,20 @@ export function EvaluateDVE( toBeQueued: true, content: content.content, prerollDuration: Number(config.studio.CasparPrerollDuration) || 0, - metaData: literal({ + metaData: { mediaPlayerSessions: [partDefinition.segmentExternalId], sources: parsedCue.sources, config: rawTemplate, - userData: literal({ + userData: { type: AdlibActionType.SELECT_DVE, config: parsedCue, videoId: partDefinition.fields.videoId, segmentExternalId: partDefinition.segmentExternalId - }), + }, sisyfosPersistMetaData: { sisyfosLayers: [] } - }) + } }) ) } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts index f986e38e3..ac382dc39 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/ekstern.ts @@ -5,7 +5,13 @@ import { IBlueprintPiece, ISegmentUserContext } from '@tv2media/blueprints-integration' -import { CueDefinitionEkstern, EvaluateEksternBase, PartDefinition, TV2BlueprintConfig } from 'tv2-common' +import { + CueDefinitionEkstern, + EvaluateEksternBase, + PartDefinition, + PieceMetaData, + TV2BlueprintConfig +} from 'tv2-common' import { AtemLLayer } from '../../../tv2_afvd_studio/layers' import { SourceLayer } from '../../layers' @@ -13,8 +19,8 @@ export function EvaluateEkstern( context: ISegmentUserContext, config: TV2BlueprintConfig, part: IBlueprintPart, - pieces: IBlueprintPiece[], - adlibPieces: IBlueprintAdLibPiece[], + pieces: Array>, + adlibPieces: Array>, _actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionEkstern, diff --git a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts index 944e0626e..3e39ff3de 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/graphicBackgroundLoop.ts @@ -28,80 +28,72 @@ export function EvaluateCueBackgroundLoop( const fileName = parsedCue.backgroundLoop const path = `dve/${fileName}` if (adlib) { - adlibPieces.push( - literal({ - _rank: rank || 0, - externalId: partId, - name: fileName, - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: SourceLayer.PgmDVEBackground, - lifespan: PieceLifespan.OutOnShowStyleEnd, - content: literal>({ - fileName, - path, - ignoreMediaObjectStatus: true, - timelineObjects: dveLoopTimeline(path) - }) + adlibPieces.push({ + _rank: rank || 0, + externalId: partId, + name: fileName, + outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SourceLayer.PgmDVEBackground, + lifespan: PieceLifespan.OutOnShowStyleEnd, + content: literal>({ + fileName, + path, + ignoreMediaObjectStatus: true, + timelineObjects: dveLoopTimeline(path) }) - ) + }) } else { - pieces.push( - literal({ - externalId: partId, - name: fileName, - enable: { - start - }, - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: SourceLayer.PgmDVEBackground, - lifespan: PieceLifespan.OutOnShowStyleEnd, - content: literal>({ - fileName, - path, - ignoreMediaObjectStatus: true, - timelineObjects: dveLoopTimeline(path) - }) + pieces.push({ + externalId: partId, + name: fileName, + enable: { + start + }, + outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SourceLayer.PgmDVEBackground, + lifespan: PieceLifespan.OutOnShowStyleEnd, + content: literal>({ + fileName, + path, + ignoreMediaObjectStatus: true, + timelineObjects: dveLoopTimeline(path) }) - ) + }) } } else { // Full if (adlib) { - adlibPieces.push( - literal({ - _rank: rank || 0, - externalId: partId, - name: parsedCue.backgroundLoop, - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: SourceLayer.PgmFullBackground, - lifespan: PieceLifespan.OutOnShowStyleEnd, - content: literal>({ - fileName: parsedCue.backgroundLoop, - path: parsedCue.backgroundLoop, - ignoreMediaObjectStatus: true, - timelineObjects: fullLoopTimeline(config, parsedCue) - }) + adlibPieces.push({ + _rank: rank || 0, + externalId: partId, + name: parsedCue.backgroundLoop, + outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SourceLayer.PgmFullBackground, + lifespan: PieceLifespan.OutOnShowStyleEnd, + content: literal>({ + fileName: parsedCue.backgroundLoop, + path: parsedCue.backgroundLoop, + ignoreMediaObjectStatus: true, + timelineObjects: fullLoopTimeline(config, parsedCue) }) - ) + }) } else { - pieces.push( - literal({ - externalId: partId, - name: parsedCue.backgroundLoop, - enable: { - start - }, - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: SourceLayer.PgmFullBackground, - lifespan: PieceLifespan.OutOnShowStyleEnd, - content: literal>({ - fileName: parsedCue.backgroundLoop, - path: parsedCue.backgroundLoop, - ignoreMediaObjectStatus: true, - timelineObjects: fullLoopTimeline(config, parsedCue) - }) + pieces.push({ + externalId: partId, + name: parsedCue.backgroundLoop, + enable: { + start + }, + outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SourceLayer.PgmFullBackground, + lifespan: PieceLifespan.OutOnShowStyleEnd, + content: literal>({ + fileName: parsedCue.backgroundLoop, + path: parsedCue.backgroundLoop, + ignoreMediaObjectStatus: true, + timelineObjects: fullLoopTimeline(config, parsedCue) }) - ) + }) } } } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts index 4aaf7057c..706c6b3f9 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/jingle.ts @@ -12,7 +12,6 @@ import { generateExternalId, GetTagForJingle, GetTagForJingleNext, - literal, PartDefinition, t, TimeFromFrames @@ -52,61 +51,57 @@ export function EvaluateJingle( } if (adlib) { - const userData = literal({ + const userData: ActionSelectJingle = { type: AdlibActionType.SELECT_JINGLE, clip: parsedCue.clip, segmentExternalId: part.segmentExternalId + } + actions.push({ + externalId: generateExternalId(context, userData), + actionId: AdlibActionType.SELECT_JINGLE, + userData, + userDataManifest: {}, + display: { + _rank: rank ?? 0, + label: t(effekt ? `EFFEKT ${parsedCue.clip}` : parsedCue.clip), + sourceLayerId: SourceLayer.PgmJingle, + outputLayerId: SharedOutputLayers.JINGLE, + content: { + ...createJingleContentAFVD( + config, + file, + jingle.StartAlpha, + jingle.LoadFirstFrame, + jingle.Duration, + jingle.EndAlpha + ) + }, + tags: [AdlibTags.ADLIB_FLOW_PRODUCER], + currentPieceTags: [GetTagForJingle(part.segmentExternalId, parsedCue.clip)], + nextPieceTags: [GetTagForJingleNext(part.segmentExternalId, parsedCue.clip)] + } }) - actions.push( - literal({ - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.SELECT_JINGLE, - userData, - userDataManifest: {}, - display: { - _rank: rank ?? 0, - label: t(effekt ? `EFFEKT ${parsedCue.clip}` : parsedCue.clip), - sourceLayerId: SourceLayer.PgmJingle, - outputLayerId: SharedOutputLayers.JINGLE, - content: { - ...createJingleContentAFVD( - config, - file, - jingle.StartAlpha, - jingle.LoadFirstFrame, - jingle.Duration, - jingle.EndAlpha - ) - }, - tags: [AdlibTags.ADLIB_FLOW_PRODUCER], - currentPieceTags: [GetTagForJingle(part.segmentExternalId, parsedCue.clip)], - nextPieceTags: [GetTagForJingleNext(part.segmentExternalId, parsedCue.clip)] - } - }) - ) } else { - pieces.push( - literal({ - externalId: `${part.externalId}-JINGLE`, - name: effekt ? `EFFEKT ${parsedCue.clip}` : parsedCue.clip, - enable: { - start: 0 - }, - lifespan: PieceLifespan.WithinPart, - outputLayerId: SharedOutputLayers.JINGLE, - sourceLayerId: SourceLayer.PgmJingle, - prerollDuration: config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), - tags: [!effekt ? TallyTags.JINGLE : ''], - content: createJingleContentAFVD( - config, - file, - jingle.StartAlpha, - jingle.LoadFirstFrame, - jingle.Duration, - jingle.EndAlpha - ) - }) - ) + pieces.push({ + externalId: `${part.externalId}-JINGLE`, + name: effekt ? `EFFEKT ${parsedCue.clip}` : parsedCue.clip, + enable: { + start: 0 + }, + lifespan: PieceLifespan.WithinPart, + outputLayerId: SharedOutputLayers.JINGLE, + sourceLayerId: SourceLayer.PgmJingle, + prerollDuration: config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), + tags: [!effekt ? TallyTags.JINGLE : ''], + content: createJingleContentAFVD( + config, + file, + jingle.StartAlpha, + jingle.LoadFirstFrame, + jingle.Duration, + jingle.EndAlpha + ) + }) } } @@ -118,7 +113,7 @@ export function createJingleContentAFVD( duration: number, alphaAtEnd: number ) { - const content = CreateJingleContentBase(config, file, alphaAtStart, loadFirstFrame, duration, alphaAtEnd, { + return CreateJingleContentBase(config, file, alphaAtStart, loadFirstFrame, duration, alphaAtEnd, { Caspar: { PlayerJingle: CasparLLayer.CasparPlayerJingle }, @@ -129,6 +124,4 @@ export function createJingleContentAFVD( PlayerJingle: SisyfosLLAyer.SisyfosSourceJingle } }) - - return content } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts index 64dda92f1..cf116a812 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/routing.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/routing.ts @@ -37,35 +37,33 @@ export function EvaluateCueRouting( return } - pieces.push( - literal({ - externalId: partId, - enable: { - start: time - }, - name, - outputLayerId: SharedOutputLayers.AUX, - sourceLayerId: SourceLayer.VizFullIn1, - lifespan: PieceLifespan.WithinPart, - content: literal>({ - studioLabel: '', - switcherInput: sourceInfo.port, - timelineObjects: _.compact([ - literal({ - id: '', - enable: { start: 0 }, - priority: 100, - layer: AtemLLayer.AtemAuxVizOvlIn1, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: sourceInfo.port - } + pieces.push({ + externalId: partId, + enable: { + start: time + }, + name, + outputLayerId: SharedOutputLayers.AUX, + sourceLayerId: SourceLayer.VizFullIn1, + lifespan: PieceLifespan.WithinPart, + content: literal>({ + studioLabel: '', + switcherInput: sourceInfo.port, + timelineObjects: _.compact([ + literal({ + id: '', + enable: { start: 0 }, + priority: 100, + layer: AtemLLayer.AtemAuxVizOvlIn1, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.AUX, + aux: { + input: sourceInfo.port } - }) - ]) - }) + } + }) + ]) }) - ) + }) } diff --git a/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts b/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts index c5f647e2e..691b2c59b 100644 --- a/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts +++ b/src/tv2_afvd_showstyle/helpers/pieces/showLifecycle.ts @@ -1,4 +1,4 @@ -import { BlueprintResultPart, IBlueprintPiece, PieceLifespan, TSR } from '@tv2media/blueprints-integration' +import { BlueprintResultPart, PieceLifespan, TSR } from '@tv2media/blueprints-integration' import { literal, TV2BlueprintConfig } from 'tv2-common' import { SharedOutputLayers } from 'tv2-constants' import { GraphicLLayer } from '../../../tv2_afvd_studio/layers' @@ -11,43 +11,41 @@ export function CreateShowLifecyclePieces( cleanupShowIds: string[] ) { if (config.studio.GraphicsType === 'VIZ') { - part.pieces.push( - literal({ - externalId: part.part.externalId, - name: 'GFX Show Init', - enable: { start: 0 }, - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: SourceLayer.GraphicsShowLifecycle, - lifespan: PieceLifespan.OutOnSegmentChange, - content: { - timelineObjects: [ - literal({ - id: '', - enable: { - while: '1' - }, - layer: GraphicLLayer.GraphicLLayerInitialize, - content: { - deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.INITIALIZE_SHOWS, - showIds: initializeShowIds - } - }), - literal({ - id: '', - enable: { - while: '1' - }, - layer: GraphicLLayer.GraphicLLayerCleanup, - content: { - deviceType: TSR.DeviceType.VIZMSE, - type: TSR.TimelineContentTypeVizMSE.CLEANUP_SHOWS, - showIds: cleanupShowIds - } - }) - ] - } - }) - ) + part.pieces.push({ + externalId: part.part.externalId, + name: 'GFX Show Init', + enable: { start: 0 }, + outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: SourceLayer.GraphicsShowLifecycle, + lifespan: PieceLifespan.OutOnSegmentChange, + content: { + timelineObjects: [ + literal({ + id: '', + enable: { + while: '1' + }, + layer: GraphicLLayer.GraphicLLayerInitialize, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.INITIALIZE_SHOWS, + showIds: initializeShowIds + } + }), + literal({ + id: '', + enable: { + while: '1' + }, + layer: GraphicLLayer.GraphicLLayerCleanup, + content: { + deviceType: TSR.DeviceType.VIZMSE, + type: TSR.TimelineContentTypeVizMSE.CLEANUP_SHOWS, + showIds: cleanupShowIds + } + }) + ] + } + }) } } diff --git a/src/tv2_afvd_showstyle/migrations/index.ts b/src/tv2_afvd_showstyle/migrations/index.ts index 06952aa59..302146dc7 100644 --- a/src/tv2_afvd_showstyle/migrations/index.ts +++ b/src/tv2_afvd_showstyle/migrations/index.ts @@ -4,7 +4,6 @@ import { changeGFXTemplate, GetDefaultAdLibTriggers, GetDSKSourceLayerNames, - literal, RemoveOldShortcuts, removeSourceLayer, SetShowstyleTransitionMigrationStep, @@ -15,7 +14,6 @@ import { UpsertValuesIntoTransitionTable } from 'tv2-common' import { SharedGraphicLLayer } from 'tv2-constants' -import * as _ from 'underscore' import { remapVizDOvl, remapVizLLayer } from '../../tv2_offtube_showstyle/migrations' import { remapTableColumnValues } from '../../tv2_offtube_showstyle/migrations/util' import { ATEMModel } from '../../types/atem' @@ -38,7 +36,7 @@ const SHOW_STYLE_ID = 'tv2_afvd_showstyle' * 0.1.0: Core 0.24.0 */ -export const showStyleMigrations: MigrationStepShowStyle[] = literal([ +export const showStyleMigrations: MigrationStepShowStyle[] = [ ...getCreateVariantMigrationSteps(), ...remapTableColumnValues('0.1.0', 'GFXTemplates', 'LayerMapping', remapVizLLayer), // Rename "viz-d-ovl" to "OVL1" @@ -246,4 +244,4 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal { - return literal({ + return { id: `${versionStr}.sourcelayer.defaults${force ? '.forced' : ''}.${defaultVal._id}`, version: versionStr, canBeRunAutomatically: true, @@ -38,7 +38,7 @@ export function getSourceLayerDefaultsMigrationSteps(versionStr: string, force?: context.insertSourceLayer(defaultVal._id, defaultVal) } } - }) + } }) ) } @@ -52,7 +52,7 @@ export function forceSourceLayerToDefaults( } export function forceSettingToDefaults(versionStr: string, setting: string): MigrationStepShowStyle { - return literal({ + return { id: `${versionStr}.sourcelayer.defaults.${setting}.forced`, version: versionStr, canBeRunAutomatically: true, @@ -85,7 +85,7 @@ export function forceSettingToDefaults(versionStr: string, setting: string): Mig context.setBaseConfig(setting, defaultVal.defaultVal) } } - }) + } } export function getOutputLayerDefaultsMigrationSteps(versionStr: string): MigrationStepShowStyle[] { diff --git a/src/tv2_afvd_showstyle/parts/cueonly.ts b/src/tv2_afvd_showstyle/parts/cueonly.ts index 22eced5db..c378d7fb9 100644 --- a/src/tv2_afvd_showstyle/parts/cueonly.ts +++ b/src/tv2_afvd_showstyle/parts/cueonly.ts @@ -12,7 +12,6 @@ import { CueDefinition, GetJinglePartProperties, GraphicIsPilot, - literal, PartDefinition, PartTime } from 'tv2-common' @@ -34,11 +33,11 @@ export async function CreatePartCueOnly( const partDefinitionWithID = { ...partDefinition, ...{ externalId: id } } const partTime = PartTime(config, partDefinitionWithID, totalWords, false) - let part = literal({ + let part: IBlueprintPart = { externalId: id, title, metaData: {} - }) + } const adLibPieces: IBlueprintAdLibPiece[] = [] const pieces: IBlueprintPiece[] = [] diff --git a/src/tv2_afvd_showstyle/parts/evs.ts b/src/tv2_afvd_showstyle/parts/evs.ts index d5f8d3a8f..b2ab05004 100644 --- a/src/tv2_afvd_showstyle/parts/evs.ts +++ b/src/tv2_afvd_showstyle/parts/evs.ts @@ -39,15 +39,15 @@ export async function CreatePartEVS( const partTime = PartTime(config, partDefinition, totalWords, false) const title = partDefinition.sourceDefinition.name - let part = literal({ + let part: IBlueprintPart = { externalId: partDefinition.externalId, title, metaData: {}, expectedDuration: partTime > 0 ? partTime : 0 - }) + } const adLibPieces: IBlueprintAdLibPiece[] = [] - const pieces: IBlueprintPiece[] = [] + const pieces: Array> = [] const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] @@ -59,22 +59,20 @@ export async function CreatePartEVS( } const atemInput = sourceInfoReplay.port - pieces.push( - literal({ - externalId: partDefinition.externalId, - name: part.title, - enable: { start: 0 }, - outputLayerId: SharedOutputLayers.PGM, - sourceLayerId: SourceLayer.PgmLocal, - lifespan: PieceLifespan.WithinPart, - metaData: literal({ - sisyfosPersistMetaData: { - sisyfosLayers: [] - } - }), - content: makeContentEVS(config, atemInput, partDefinition, sourceInfoReplay) - }) - ) + pieces.push({ + externalId: partDefinition.externalId, + name: part.title, + enable: { start: 0 }, + outputLayerId: SharedOutputLayers.PGM, + sourceLayerId: SourceLayer.PgmLocal, + lifespan: PieceLifespan.WithinPart, + metaData: { + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }, + content: makeContentEVS(config, atemInput, partDefinition, sourceInfoReplay) + }) await EvaluateCues( context, diff --git a/src/tv2_afvd_showstyle/parts/grafik.ts b/src/tv2_afvd_showstyle/parts/grafik.ts index 36c6989ad..23b2121d1 100644 --- a/src/tv2_afvd_showstyle/parts/grafik.ts +++ b/src/tv2_afvd_showstyle/parts/grafik.ts @@ -7,14 +7,7 @@ import { IBlueprintPiece, ISegmentUserContext } from '@tv2media/blueprints-integration' -import { - AddScript, - ApplyFullGraphicPropertiesToPart, - GraphicIsPilot, - literal, - PartDefinition, - PartTime -} from 'tv2-common' +import { AddScript, ApplyFullGraphicPropertiesToPart, GraphicIsPilot, PartDefinition, PartTime } from 'tv2-common' import { CueType } from 'tv2-constants' import { BlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' @@ -27,11 +20,11 @@ export async function CreatePartGrafik( totalWords: number ): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) - const part = literal({ + const part: IBlueprintPart = { externalId: partDefinition.externalId, title: partDefinition.type + ' - ' + partDefinition.rawType, metaData: {} - }) + } const adLibPieces: IBlueprintAdLibPiece[] = [] const pieces: IBlueprintPiece[] = [] diff --git a/src/tv2_afvd_showstyle/parts/intro.ts b/src/tv2_afvd_showstyle/parts/intro.ts index 9e41d554c..d62a2c4a6 100644 --- a/src/tv2_afvd_showstyle/parts/intro.ts +++ b/src/tv2_afvd_showstyle/parts/intro.ts @@ -12,7 +12,6 @@ import { CreatePartInvalid, CueDefinitionJingle, GetJinglePartProperties, - literal, PartDefinition, PartTime } from 'tv2-common' @@ -61,11 +60,11 @@ export async function CreatePartIntro( return CreatePartInvalid(partDefinition) } - let part = literal({ + let part: IBlueprintPart = { externalId: partDefinition.externalId, title: partDefinition.type + ' - ' + partDefinition.rawType, metaData: {} - }) + } const adLibPieces: IBlueprintAdLibPiece[] = [] const pieces: IBlueprintPiece[] = [] diff --git a/src/tv2_afvd_showstyle/parts/kam.ts b/src/tv2_afvd_showstyle/parts/kam.ts index 5ba468003..c280c73bf 100644 --- a/src/tv2_afvd_showstyle/parts/kam.ts +++ b/src/tv2_afvd_showstyle/parts/kam.ts @@ -45,52 +45,50 @@ export async function CreatePartKam( const partTime = partKamBase.duration const adLibPieces: IBlueprintAdLibPiece[] = [] - const pieces: IBlueprintPiece[] = [] + const pieces: Array> = [] const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] const jingleDSK = FindDSKJingle(config) if (partDefinition.rawType.match(/kam cs ?3/i)) { - pieces.push( - literal({ - externalId: partDefinition.externalId, - name: 'CS 3 (JINGLE)', - enable: { start: 0 }, - outputLayerId: SharedOutputLayers.PGM, - sourceLayerId: SourceLayer.PgmJingle, - lifespan: PieceLifespan.WithinPart, - metaData: literal({ - sisyfosPersistMetaData: { - sisyfosLayers: [] - } - }), - content: literal>({ - ignoreMediaObjectStatus: true, - fileName: '', - path: '', - timelineObjects: literal([ - literal({ - id: ``, - enable: { - start: 0 - }, - 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(config, partDefinition) - } + pieces.push({ + externalId: partDefinition.externalId, + name: 'CS 3 (JINGLE)', + enable: { start: 0 }, + outputLayerId: SharedOutputLayers.PGM, + sourceLayerId: SourceLayer.PgmJingle, + lifespan: PieceLifespan.WithinPart, + metaData: { + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }, + content: literal>({ + ignoreMediaObjectStatus: true, + fileName: '', + path: '', + timelineObjects: literal([ + literal({ + id: ``, + enable: { + start: 0 + }, + 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(config, partDefinition) } - }) - ]) - }) + } + }) + ]) }) - ) + }) part.expectedDuration = TimeFromINewsField(partDefinition.fields.totalTime) * 1000 } else { const sourceInfoCam = findSourceInfo(config.sources, partDefinition.sourceDefinition) @@ -102,49 +100,47 @@ export async function CreatePartKam( part = { ...part, ...CreateEffektForpart(context, config, partDefinition, pieces) } - pieces.push( - literal({ - externalId: partDefinition.externalId, - name: part.title, - enable: { start: 0 }, - outputLayerId: SharedOutputLayers.PGM, - sourceLayerId: SourceLayer.PgmCam, - lifespan: PieceLifespan.WithinPart, - metaData: literal({ - sisyfosPersistMetaData: { - sisyfosLayers: sourceInfoCam.sisyfosLayers ?? [], - acceptPersistAudio: sourceInfoCam.acceptPersistAudio - } - }), - content: { - studioLabel: '', - switcherInput: atemInput, - timelineObjects: literal([ - literal({ - id: ``, - enable: { - start: 0 - }, - 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(config, partDefinition) - } - }, - ...(AddParentClass(config, partDefinition) - ? { classes: [CameraParentClass('studio0', partDefinition.sourceDefinition.id)] } - : {}) - }), - ...GetSisyfosTimelineObjForCamera(config, sourceInfoCam, partDefinition.sourceDefinition.minusMic) - ]) + pieces.push({ + externalId: partDefinition.externalId, + name: part.title, + enable: { start: 0 }, + outputLayerId: SharedOutputLayers.PGM, + sourceLayerId: SourceLayer.PgmCam, + lifespan: PieceLifespan.WithinPart, + metaData: { + sisyfosPersistMetaData: { + sisyfosLayers: sourceInfoCam.sisyfosLayers ?? [], + acceptPersistAudio: sourceInfoCam.acceptPersistAudio } - }) - ) + }, + content: { + studioLabel: '', + switcherInput: atemInput, + timelineObjects: literal([ + literal({ + id: ``, + enable: { + start: 0 + }, + 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(config, partDefinition) + } + }, + ...(AddParentClass(config, partDefinition) + ? { classes: [CameraParentClass('studio0', partDefinition.sourceDefinition.id)] } + : {}) + }), + ...GetSisyfosTimelineObjForCamera(config, sourceInfoCam, partDefinition.sourceDefinition.minusMic) + ]) + } + }) } await EvaluateCues( diff --git a/src/tv2_afvd_showstyle/parts/live.ts b/src/tv2_afvd_showstyle/parts/live.ts index 958f95a15..6da5eb433 100644 --- a/src/tv2_afvd_showstyle/parts/live.ts +++ b/src/tv2_afvd_showstyle/parts/live.ts @@ -7,7 +7,7 @@ import { IBlueprintPiece, ISegmentUserContext } from '@tv2media/blueprints-integration' -import { AddScript, CueDefinitionEkstern, literal, PartDefinition, PartTime } from 'tv2-common' +import { AddScript, CueDefinitionEkstern, PartDefinition, PartTime } from 'tv2-common' import { CueType } from 'tv2-constants' import { BlueprintConfig } from '../../tv2_afvd_showstyle/helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' @@ -21,12 +21,12 @@ export async function CreatePartLive( totalWords: number ): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) - let part = literal({ + let part: IBlueprintPart = { externalId: partDefinition.externalId, title: partDefinition.title || 'Ekstern', metaData: {}, expectedDuration: partTime > 0 ? partTime : 0 - }) + } const adLibPieces: IBlueprintAdLibPiece[] = [] const pieces: IBlueprintPiece[] = [] diff --git a/src/tv2_afvd_showstyle/parts/teknik.ts b/src/tv2_afvd_showstyle/parts/teknik.ts index 42708b0ba..f93bd2386 100644 --- a/src/tv2_afvd_showstyle/parts/teknik.ts +++ b/src/tv2_afvd_showstyle/parts/teknik.ts @@ -7,7 +7,7 @@ import { IBlueprintPiece, ISegmentUserContext } from '@tv2media/blueprints-integration' -import { AddScript, literal, PartDefinition, PartTime } from 'tv2-common' +import { AddScript, PartDefinition, PartTime } from 'tv2-common' import { BlueprintConfig } from '../helpers/config' import { EvaluateCues } from '../helpers/pieces/evaluateCues' import { SourceLayer } from '../layers' @@ -19,11 +19,11 @@ export async function CreatePartTeknik( totalWords: number ): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) - const part = literal({ + const part: IBlueprintPart = { externalId: partDefinition.externalId, title: partDefinition.type + ' - ' + partDefinition.rawType, metaData: {} - }) + } const adLibPieces: IBlueprintAdLibPiece[] = [] const pieces: IBlueprintPiece[] = [] diff --git a/src/tv2_afvd_showstyle/parts/unknown.ts b/src/tv2_afvd_showstyle/parts/unknown.ts index eb79c1164..6f991fbe2 100644 --- a/src/tv2_afvd_showstyle/parts/unknown.ts +++ b/src/tv2_afvd_showstyle/parts/unknown.ts @@ -11,7 +11,6 @@ import { ApplyFullGraphicPropertiesToPart, GetJinglePartProperties, GraphicIsPilot, - literal, PartDefinition, PartTime } from 'tv2-common' @@ -30,13 +29,13 @@ export async function CreatePartUnknown( ) { const partTime = PartTime(config, partDefinition, totalWords, false) - let part = literal({ + let part: IBlueprintPart = { externalId: partDefinition.externalId, title: partDefinition.type + ' - ' + partDefinition.rawType, metaData: {}, autoNext: false, expectedDuration: partTime - }) + } const adLibPieces: IBlueprintAdLibPiece[] = [] const pieces: IBlueprintPiece[] = [] diff --git a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts index be5274fb8..14ace1ff0 100644 --- a/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_afvd_showstyle/postProcessTimelineObjects.ts @@ -9,7 +9,7 @@ import { TimelineObjHoldMode, TSR } from '@tv2media/blueprints-integration' -import { AtemLLayerDSK, FindDSKJingle, literal, TimelineBlueprintExt } from 'tv2-common' +import { AtemLLayerDSK, FindDSKJingle, TimelineBlueprintExt } from 'tv2-common' import * as _ from 'underscore' import { AtemLLayer } from '../tv2_afvd_studio/layers' import { BlueprintConfig } from './helpers/config' @@ -72,7 +72,7 @@ export function postProcessPieceTimelineObjects( (tlObj.content.me.input !== -1 || tlObj.metaData?.mediaPlayerSession !== undefined) ) { // Create a lookahead-lookahead object for this me-program - const lookaheadObj = literal({ + 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 @@ -92,7 +92,7 @@ export function postProcessPieceTimelineObjects( context: `Lookahead-lookahead for ${tlObj.id}`, mediaPlayerSession: tlObj.metaData?.mediaPlayerSession // TODO - does this work the same? } - }) + } extraObjs.push(lookaheadObj) } @@ -120,7 +120,7 @@ export function postProcessPieceTimelineObjects( mixMinusSource = kamSources.length === 1 ? Number(kamSources[0].switcherInput) : null } if (mixMinusSource !== null && mixMinusSource !== -1) { - const mixMinusObj = literal({ + const mixMinusObj: TSR.TimelineObjAtemAUX & TimelineBlueprintExt = { ..._.omit(tlObj, 'content'), id: '', layer: AtemLLayer.AtemAuxVideoMixMinus, @@ -139,7 +139,7 @@ export function postProcessPieceTimelineObjects( ...tlObj.metaData, context: `Mix-minus for ${tlObj.id}` } - }) + } mixMinusObj.classes = mixMinusObj.classes?.filter( c => !c.match(`studio0_parent_`) && !c.match('PLACEHOLDER_OBJECT_REMOVEME') ) @@ -161,7 +161,7 @@ export function postProcessPieceTimelineObjects( context.notifyUserWarning(`Unhandled Keyer properties for Clean keyer, it may look wrong`) } - const cleanObj = literal({ + const cleanObj: TSR.TimelineObjAtemME & TimelineBlueprintExt = { ..._.omit(tlObj, 'content', 'keyframes'), id: '', layer: AtemLLayer.AtemCleanUSKEffect, @@ -180,7 +180,7 @@ export function postProcessPieceTimelineObjects( ] } } - }) + } extraObjs.push(cleanObj) } }) diff --git a/src/tv2_afvd_studio/config-manifests.ts b/src/tv2_afvd_studio/config-manifests.ts index 710b48bc9..9998bbe39 100644 --- a/src/tv2_afvd_studio/config-manifests.ts +++ b/src/tv2_afvd_studio/config-manifests.ts @@ -12,7 +12,6 @@ import { MakeConfigWithMediaFlow, TableConfigItemSourceMapping } from 'tv2-common' -import * as _ from 'underscore' import { AtemSourceIndex } from '../types/atem' import { defaultDSKConfig } from './helpers/config' import { SisyfosLLAyer } from './layers' diff --git a/src/tv2_afvd_studio/getBaseline.ts b/src/tv2_afvd_studio/getBaseline.ts index 97604eb98..96220025b 100644 --- a/src/tv2_afvd_studio/getBaseline.ts +++ b/src/tv2_afvd_studio/getBaseline.ts @@ -11,7 +11,7 @@ import { SharedGraphicLLayer } from '../tv2-constants' import { AtemSourceIndex } from '../types/atem' import { getStudioConfig } from './helpers/config' import { AtemLLayer, SisyfosLLAyer } from './layers' -import { SisyfosChannel, sisyfosChannels } from './sisyfosChannels' +import { sisyfosChannels } from './sisyfosChannels' function filterMappings( input: BlueprintMappings, @@ -48,7 +48,7 @@ export function getBaseline(context: IStudioContext): BlueprintResultBaseline { const mappedChannels: TSR.TimelineObjSisyfosChannels['content']['channels'] = [] for (const id in sisyfosMappings) { if (sisyfosMappings[id]) { - const sisyfosChannel = sisyfosChannels[id as SisyfosLLAyer] as SisyfosChannel | undefined + const sisyfosChannel = sisyfosChannels[id as SisyfosLLAyer] if (sisyfosChannel) { mappedChannels.push({ mappedLayer: id, diff --git a/src/tv2_afvd_studio/helpers/config.ts b/src/tv2_afvd_studio/helpers/config.ts index 4403e269f..2eb9c2028 100644 --- a/src/tv2_afvd_studio/helpers/config.ts +++ b/src/tv2_afvd_studio/helpers/config.ts @@ -8,7 +8,6 @@ import { TV2StudioConfigBase } from 'tv2-common' import { DSKRoles } from 'tv2-constants' -import * as _ from 'underscore' import { ShowStyleConfig } from '../../tv2_afvd_showstyle/helpers/config' import { parseMediaPlayers, parseSources } from './sources' diff --git a/src/tv2_afvd_studio/migrations/devices.ts b/src/tv2_afvd_studio/migrations/devices.ts index d088ad397..ae375657d 100644 --- a/src/tv2_afvd_studio/migrations/devices.ts +++ b/src/tv2_afvd_studio/migrations/devices.ts @@ -5,7 +5,6 @@ import { MigrationStepStudio, TSR } from '@tv2media/blueprints-integration' -import { literal } from 'tv2-common' import * as _ from 'underscore' declare const VERSION: string // Injected by webpack @@ -218,10 +217,10 @@ const devices: DeviceEntry[] = [ } ] -export const deviceMigrations = literal([ +export const deviceMigrations: MigrationStepStudio[] = [ // create all devices ..._.map(devices, createDevice), // ensure all devices still look valid ..._.map(devices, validateDevice) -]) +] diff --git a/src/tv2_afvd_studio/migrations/index.ts b/src/tv2_afvd_studio/migrations/index.ts index e6b740d0f..421ec2d1a 100644 --- a/src/tv2_afvd_studio/migrations/index.ts +++ b/src/tv2_afvd_studio/migrations/index.ts @@ -2,7 +2,6 @@ import { MigrationStepStudio, TSR } from '@tv2media/blueprints-integration' import { AddKeepAudio, addSourceToSourcesConfig, - literal, MoveClipSourcePath, MoveSourcesToTable, PrefixEvsWithEvs, @@ -40,7 +39,7 @@ declare const VERSION: string // Injected by webpack * 0.1.0: Core 0.24.0 */ -export const studioMigrations: MigrationStepStudio[] = literal([ +export const studioMigrations: MigrationStepStudio[] = [ ensureStudioConfig( '0.1.0', 'SourcesCam', @@ -199,4 +198,4 @@ export const studioMigrations: MigrationStepStudio[] = literal { - return literal({ + return { id: `${versionStr}.mappings.defaults.${id}`, version: versionStr, canBeRunAutomatically: true, @@ -151,11 +150,9 @@ export function getMappingsDefaultsMigrationSteps(versionStr: string): Migration context.insertMapping(id, defaultVal) } } - }) + } }) ) - - return res } export function GetMappingDefaultMigrationStepForLayer( @@ -163,7 +160,7 @@ export function GetMappingDefaultMigrationStepForLayer( layer: string, force?: boolean ): MigrationStepStudio { - return literal({ + return { id: `${versionStr}.mappings.defaults.manualEnsure${layer}`, version: versionStr, canBeRunAutomatically: true, @@ -190,7 +187,7 @@ export function GetMappingDefaultMigrationStepForLayer( context.insertMapping(layer, MappingsDefaults[layer]) } } - }) + } } /** @@ -207,7 +204,7 @@ export function EnsureSisyfosMappingHasType( layer: string, mappingType: TSR.MappingSisyfosType.CHANNEL ): MigrationStepStudio { - return literal({ + return { id: `${versionStr}.mutatesisyfosmappings.${layer}`, version: versionStr, canBeRunAutomatically: true, @@ -237,7 +234,7 @@ export function EnsureSisyfosMappingHasType( context.updateMapping(layer, mapping) } - }) + } } export function GetSisyfosLayersForTableMigrationAFVD(configName: string, val: string): string[] { diff --git a/src/tv2_afvd_studio/onTimelineGenerate.ts b/src/tv2_afvd_studio/onTimelineGenerate.ts index 3b877ce3e..0cbd50c4a 100644 --- a/src/tv2_afvd_studio/onTimelineGenerate.ts +++ b/src/tv2_afvd_studio/onTimelineGenerate.ts @@ -6,8 +6,7 @@ import { PartEndState, TimelinePersistentState } from '@tv2media/blueprints-integration' -import { onTimelineGenerate } from 'tv2-common' -import * as _ from 'underscore' +import { onTimelineGenerate, PieceMetaData } from 'tv2-common' import { getConfig } from '../tv2_afvd_showstyle/helpers/config' import { AtemLLayer, CasparLLayer, SisyfosLLAyer } from './layers' @@ -16,7 +15,7 @@ export function onTimelineGenerateAFVD( timeline: OnGenerateTimelineObj[], previousPersistentState: TimelinePersistentState | undefined, previousPartEndState: PartEndState | undefined, - resolvedPieces: IBlueprintResolvedPieceInstance[] + resolvedPieces: Array> ): Promise { return onTimelineGenerate( context, diff --git a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts index a009709c4..4714696ff 100644 --- a/src/tv2_offtube_showstyle/__tests__/actions.spec.ts +++ b/src/tv2_offtube_showstyle/__tests__/actions.spec.ts @@ -1,7 +1,6 @@ import { IBlueprintPartDB, IBlueprintPartInstance, - IBlueprintPieceDB, IBlueprintPieceInstance, PieceLifespan, TSR @@ -16,6 +15,7 @@ import { ActionTakeWithTransition, literal, PartDefinitionUnknown, + PieceMetaData, RemoteType, SourceDefinitionKam, SourceDefinitionRemote @@ -67,9 +67,9 @@ const currentPartMock: IBlueprintPartInstance = { rehearsal: false } -const kamPieceInstance: IBlueprintPieceInstance = { +const kamPieceInstance: IBlueprintPieceInstance = { _id: '', - piece: literal({ + piece: { _id: 'KAM 1', enable: { start: 0 @@ -98,13 +98,13 @@ const kamPieceInstance: IBlueprintPieceInstance = { }) ] } - }), + }, partInstanceId: '' } -const playingServerPieceInstance: IBlueprintPieceInstance = { +const playingServerPieceInstance: IBlueprintPieceInstance = { _id: '', - piece: literal({ + piece: { _id: 'Playing Server', enable: { start: 0 @@ -117,13 +117,13 @@ const playingServerPieceInstance: IBlueprintPieceInstance = { content: { timelineObjects: [] } - }), + }, partInstanceId: '' } -const selectedServerPieceInstance: IBlueprintPieceInstance = { +const selectedServerPieceInstance: IBlueprintPieceInstance = { _id: '', - piece: literal({ + piece: { _id: 'Selected Server', enable: { start: 0 @@ -136,7 +136,7 @@ const selectedServerPieceInstance: IBlueprintPieceInstance = { content: { timelineObjects: [] } - }), + }, partInstanceId: '' } @@ -371,7 +371,7 @@ function validateNextPartExistsWithPreviousPartKeepaliveDuration(context: Action } function getATEMMEObj(piece: IBlueprintPieceInstance): TSR.TimelineObjAtemME { - const atemObj = (piece.piece.content!.timelineObjects as TSR.TSRTimelineObj[]).find( + const atemObj = (piece.piece.content.timelineObjects as TSR.TSRTimelineObj[]).find( obj => obj.layer === OfftubeAtemLLayer.AtemMEClean && obj.content.deviceType === TSR.DeviceType.ATEM && @@ -556,39 +556,6 @@ describe('Combination Actions', () => { expect(voPieces.dataStore?.piece.name).toEqual('VOVOA') }) - it('Server -> DVE', async () => { - const context = new ActionExecutionContext( - 'test', - mappingsDefaults, - parseStudioConfig, - parseShowStyleConfig, - RUNDOWN_ID, - SEGMENT_ID, - currentPartMock._id, - currentPartMock, - [kamPieceInstance] - ) - context.studioConfig = defaultStudioConfig as any - context.showStyleConfig = defaultShowStyleConfig as any - ;((context.studioConfig as unknown) as OfftubeStudioConfig).GraphicsType = 'HTML' - - await executeActionOfftube(context, AdlibActionType.SELECT_SERVER_CLIP, selectServerClipAction) - - let serverPieces = await getActiveServerPieces(context, 'next') - - validateNextPartExistsWithDuration(context, SERVER_DURATION_A) - validateSourcePiecesExistWithPrerollDuration(serverPieces) - - await executeActionOfftube(context, AdlibActionType.SELECT_DVE, selectDVEActionMorbarn) - - serverPieces = await getActiveServerPieces(context, 'next') - const dvePieces = await getDVEPieces(context, 'next') - - validateNextPartExistsWithDuration(context, 0) - validateOnlySelectionIsPreserved(serverPieces) - validateSourcePiecesExistWithPrerollDuration(dvePieces) - }) - it('Server -> CAM', async () => { const context = new ActionExecutionContext( 'test', diff --git a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts index ecd266d16..c3e76dd71 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeAdlib.ts @@ -90,7 +90,7 @@ export async function OfftubeEvaluateAdLib( return } - if (!TemplateIsValid(rawTemplate.DVEJSON as string)) { + if (!TemplateIsValid(rawTemplate.DVEJSON)) { context.notifyUserWarning(`Invalid DVE template ${parsedCue.variant}`) return } @@ -105,30 +105,28 @@ export async function OfftubeEvaluateAdLib( const adlibContent = OfftubeMakeContentDVE(context, config, partDefinition, cueDVE, rawTemplate, false, true) - const userData = literal({ + const userData: ActionSelectDVE = { type: AdlibActionType.SELECT_DVE, config: cueDVE, videoId: partDefinition.fields.videoId, segmentExternalId: partDefinition.segmentExternalId + } + actions.push({ + externalId: generateExternalId(context, userData), + actionId: AdlibActionType.SELECT_DVE, + userData, + userDataManifest: {}, + display: { + sourceLayerId: OfftubeSourceLayer.PgmDVE, + outputLayerId: OfftubeOutputLayers.PGM, + uniquenessId: getUniquenessIdDVE(cueDVE), + label: t(`${partDefinition.storyName}`), + tags: [AdlibTags.ADLIB_KOMMENTATOR, AdlibTags.ADLIB_FLOW_PRODUCER], + content: literal({ + ...adlibContent.content + }) + } }) - actions.push( - literal({ - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.SELECT_DVE, - userData, - userDataManifest: {}, - display: { - sourceLayerId: OfftubeSourceLayer.PgmDVE, - outputLayerId: OfftubeOutputLayers.PGM, - uniquenessId: getUniquenessIdDVE(cueDVE), - label: t(`${partDefinition.storyName}`), - tags: [AdlibTags.ADLIB_KOMMENTATOR, AdlibTags.ADLIB_FLOW_PRODUCER], - content: literal({ - ...adlibContent.content - }) - } - }) - ) } } diff --git a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts index 86e808193..0f0501234 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeDVE.ts @@ -18,7 +18,6 @@ import { GetTagForDVENext, literal, PartDefinition, - PieceMetaData, t, TemplateIsValid } from 'tv2-common' @@ -77,70 +76,66 @@ export function OfftubeEvaluateDVE( let start = parsedCue.start ? CalculateTime(parsedCue.start) : 0 start = start ? start : 0 const end = parsedCue.end ? CalculateTime(parsedCue.end) : undefined - pieces.push( - literal({ - externalId: partDefinition.externalId, - name: `${parsedCue.template}`, - enable: { - start, - ...(end ? { duration: end - start } : {}) + pieces.push({ + externalId: partDefinition.externalId, + name: `${parsedCue.template}`, + enable: { + start, + ...(end ? { duration: end - start } : {}) + }, + outputLayerId: SharedOutputLayers.PGM, + sourceLayerId: OfftubeSourceLayer.PgmDVE, + lifespan: PieceLifespan.WithinPart, + toBeQueued: true, + content: { + ...pieceContent.content, + timelineObjects: [...pieceContent.content.timelineObjects] + }, + prerollDuration: Number(config.studio.CasparPrerollDuration) || 0, + metaData: literal({ + mediaPlayerSessions: [partDefinition.segmentExternalId], + sources: parsedCue.sources, + config: rawTemplate, + userData: { + type: AdlibActionType.SELECT_DVE, + config: parsedCue, + videoId: partDefinition.fields.videoId, + segmentExternalId: partDefinition.segmentExternalId }, - outputLayerId: SharedOutputLayers.PGM, - sourceLayerId: OfftubeSourceLayer.PgmDVE, - lifespan: PieceLifespan.WithinPart, - toBeQueued: true, - content: { - ...pieceContent.content, - timelineObjects: [...pieceContent.content.timelineObjects] - }, - prerollDuration: Number(config.studio.CasparPrerollDuration) || 0, - metaData: literal({ - mediaPlayerSessions: [partDefinition.segmentExternalId], - sources: parsedCue.sources, - config: rawTemplate, - userData: literal({ - type: AdlibActionType.SELECT_DVE, - config: parsedCue, - videoId: partDefinition.fields.videoId, - segmentExternalId: partDefinition.segmentExternalId - }), - sisyfosPersistMetaData: { - sisyfosLayers: [] - } - }), - tags: [ - GetTagForDVE(partDefinition.segmentExternalId, parsedCue.template, parsedCue.sources), - GetTagForDVENext(partDefinition.segmentExternalId, parsedCue.template, parsedCue.sources), - TallyTags.DVE_IS_LIVE - ] - }) - ) + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }), + tags: [ + GetTagForDVE(partDefinition.segmentExternalId, parsedCue.template, parsedCue.sources), + GetTagForDVENext(partDefinition.segmentExternalId, parsedCue.template, parsedCue.sources), + TallyTags.DVE_IS_LIVE + ] + }) - const userData = literal({ + const userData: ActionSelectDVE = { type: AdlibActionType.SELECT_DVE, config: parsedCue, videoId: partDefinition.fields.videoId, segmentExternalId: partDefinition.segmentExternalId + } + actions.push({ + externalId: generateExternalId(context, userData), + actionId: AdlibActionType.SELECT_DVE, + userData, + userDataManifest: {}, + display: { + _rank: rank, + sourceLayerId: OfftubeSourceLayer.PgmDVE, + outputLayerId: OfftubeOutputLayers.PGM, + label: t(`${partDefinition.storyName}`), + tags: [AdlibTags.ADLIB_KOMMENTATOR, ...(adlib ? [AdlibTags.ADLIB_FLOW_PRODUCER] : [])], + content: literal({ + ...pieceContent.content + }), + currentPieceTags: [GetTagForDVE(partDefinition.segmentExternalId, parsedCue.template, parsedCue.sources)], + nextPieceTags: [GetTagForDVENext(partDefinition.segmentExternalId, parsedCue.template, parsedCue.sources)] + } }) - actions.push( - literal({ - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.SELECT_DVE, - userData, - userDataManifest: {}, - display: { - _rank: rank, - sourceLayerId: OfftubeSourceLayer.PgmDVE, - outputLayerId: OfftubeOutputLayers.PGM, - label: t(`${partDefinition.storyName}`), - tags: [AdlibTags.ADLIB_KOMMENTATOR, ...(adlib ? [AdlibTags.ADLIB_FLOW_PRODUCER] : [])], - content: literal({ - ...pieceContent.content - }), - currentPieceTags: [GetTagForDVE(partDefinition.segmentExternalId, parsedCue.template, parsedCue.sources)], - nextPieceTags: [GetTagForDVENext(partDefinition.segmentExternalId, parsedCue.template, parsedCue.sources)] - } - }) - ) } } diff --git a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts index abcd29a45..1164e20a3 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeEkstern.ts @@ -5,7 +5,7 @@ import { IBlueprintPiece, ISegmentUserContext } from '@tv2media/blueprints-integration' -import { CueDefinitionEkstern, EvaluateEksternBase, PartDefinition } from 'tv2-common' +import { CueDefinitionEkstern, EvaluateEksternBase, PartDefinition, PieceMetaData } from 'tv2-common' import { OfftubeAtemLLayer } from '../../tv2_offtube_studio/layers' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' import { OfftubeSourceLayer } from '../layers' @@ -14,8 +14,8 @@ export function OfftubeEvaluateEkstern( context: ISegmentUserContext, config: OfftubeShowstyleBlueprintConfig, part: IBlueprintPart, - pieces: IBlueprintPiece[], - _adlibPieces: IBlueprintAdLibPiece[], + pieces: Array>, + _adlibPieces: Array>, _actions: IBlueprintActionManifest[], partId: string, parsedCue: CueDefinitionEkstern, diff --git a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts index 6acaf42de..2277c7248 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeGraphicBackgroundLoop.ts @@ -27,66 +27,62 @@ export function OfftubeEvaluateCueBackgroundLoop( const path = `dve/${fileName}` const start = (parsedCue.start ? CalculateTime(parsedCue.start) : 0) ?? 0 if (adlib) { - adlibPieces.push( - literal({ - _rank: rank || 0, - externalId: partId, - name: fileName, - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: OfftubeSourceLayer.PgmDVEBackground, - lifespan: PieceLifespan.OutOnShowStyleEnd, - content: literal>({ - fileName, - path, - ignoreMediaObjectStatus: true, - timelineObjects: _.compact([ - literal({ - id: '', - enable: { start: 0 }, - priority: 100, - layer: OfftubeCasparLLayer.CasparCGDVELoop, - content: { - deviceType: TSR.DeviceType.CASPARCG, - type: TSR.TimelineContentTypeCasparCg.MEDIA, - file: path, - loop: true - } - }) - ]) - }) + adlibPieces.push({ + _rank: rank || 0, + externalId: partId, + name: fileName, + outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: OfftubeSourceLayer.PgmDVEBackground, + lifespan: PieceLifespan.OutOnShowStyleEnd, + content: literal>({ + fileName, + path, + ignoreMediaObjectStatus: true, + timelineObjects: _.compact([ + literal({ + id: '', + enable: { start: 0 }, + priority: 100, + layer: OfftubeCasparLLayer.CasparCGDVELoop, + content: { + deviceType: TSR.DeviceType.CASPARCG, + type: TSR.TimelineContentTypeCasparCg.MEDIA, + file: path, + loop: true + } + }) + ]) }) - ) + }) } else { - pieces.push( - literal({ - externalId: partId, - name: fileName, - enable: { - start - }, - outputLayerId: SharedOutputLayers.SEC, - sourceLayerId: OfftubeSourceLayer.PgmDVEBackground, - lifespan: PieceLifespan.OutOnShowStyleEnd, - content: literal>({ - fileName, - path, - ignoreMediaObjectStatus: true, - timelineObjects: _.compact([ - literal({ - id: '', - enable: { start: 0 }, - priority: 100, - layer: OfftubeCasparLLayer.CasparCGDVELoop, - content: { - deviceType: TSR.DeviceType.CASPARCG, - type: TSR.TimelineContentTypeCasparCg.MEDIA, - file: path, - loop: true - } - }) - ]) - }) + pieces.push({ + externalId: partId, + name: fileName, + enable: { + start + }, + outputLayerId: SharedOutputLayers.SEC, + sourceLayerId: OfftubeSourceLayer.PgmDVEBackground, + lifespan: PieceLifespan.OutOnShowStyleEnd, + content: literal>({ + fileName, + path, + ignoreMediaObjectStatus: true, + timelineObjects: _.compact([ + literal({ + id: '', + enable: { start: 0 }, + priority: 100, + layer: OfftubeCasparLLayer.CasparCGDVELoop, + content: { + deviceType: TSR.DeviceType.CASPARCG, + type: TSR.TimelineContentTypeCasparCg.MEDIA, + file: path, + loop: true + } + }) + ]) }) - ) + }) } } diff --git a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts index 8408b932a..f82cd7ba6 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubeJingle.ts @@ -13,7 +13,6 @@ import { GetJinglePartProperties, GetTagForJingle, GetTagForJingleNext, - literal, PartDefinition, PieceMetaData, t, @@ -27,7 +26,7 @@ import { OfftubeOutputLayers, OfftubeSourceLayer } from '../layers' export function OfftubeEvaluateJingle( context: ISegmentUserContext, config: OfftubeShowstyleBlueprintConfig, - pieces: IBlueprintPiece[], + pieces: Array>, _adlibPieces: IBlueprintAdLibPiece[], actions: IBlueprintActionManifest[], parsedCue: CueDefinitionJingle, @@ -60,70 +59,66 @@ export function OfftubeEvaluateJingle( return } - const userData = literal({ + const userData: ActionSelectJingle = { type: AdlibActionType.SELECT_JINGLE, clip: parsedCue.clip, segmentExternalId: part.segmentExternalId + } + actions.push({ + externalId: generateExternalId(context, userData), + actionId: AdlibActionType.SELECT_JINGLE, + userData, + userDataManifest: {}, + display: { + label: t(effekt ? `EFFEKT ${parsedCue.clip}` : parsedCue.clip), + sourceLayerId: OfftubeSourceLayer.PgmJingle, + outputLayerId: OfftubeOutputLayers.JINGLE, + content: { + ...createJingleContentOfftube( + config, + file, + jingle.StartAlpha, + jingle.LoadFirstFrame, + jingle.Duration, + jingle.EndAlpha + ) + }, + tags: [AdlibTags.OFFTUBE_100pc_SERVER, AdlibTags.ADLIB_KOMMENTATOR], + currentPieceTags: [GetTagForJingle(part.segmentExternalId, parsedCue.clip)], + nextPieceTags: [GetTagForJingleNext(part.segmentExternalId, parsedCue.clip)] + } }) - actions.push( - literal({ - externalId: generateExternalId(context, userData), - actionId: AdlibActionType.SELECT_JINGLE, - userData, - userDataManifest: {}, - display: { - label: t(effekt ? `EFFEKT ${parsedCue.clip}` : parsedCue.clip), - sourceLayerId: OfftubeSourceLayer.PgmJingle, - outputLayerId: OfftubeOutputLayers.JINGLE, - content: { - ...createJingleContentOfftube( - config, - file, - jingle.StartAlpha, - jingle.LoadFirstFrame, - jingle.Duration, - jingle.EndAlpha - ) - }, - tags: [AdlibTags.OFFTUBE_100pc_SERVER, AdlibTags.ADLIB_KOMMENTATOR], - currentPieceTags: [GetTagForJingle(part.segmentExternalId, parsedCue.clip)], - nextPieceTags: [GetTagForJingleNext(part.segmentExternalId, parsedCue.clip)] - } - }) - ) - pieces.push( - literal({ - externalId: `${part.externalId}-JINGLE`, - name: effekt ? `EFFEKT ${parsedCue.clip}` : parsedCue.clip, - enable: { - start: 0 - }, - lifespan: PieceLifespan.WithinPart, - outputLayerId: SharedOutputLayers.JINGLE, - sourceLayerId: OfftubeSourceLayer.PgmJingle, - metaData: literal({ - sisyfosPersistMetaData: { - sisyfosLayers: [] - } - }), - prerollDuration: config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), - content: createJingleContentOfftube( - config, - file, - jingle.StartAlpha, - jingle.LoadFirstFrame, - jingle.Duration, - jingle.EndAlpha - ), - tags: [ - GetTagForJingle(part.segmentExternalId, parsedCue.clip), - GetTagForJingleNext(part.segmentExternalId, parsedCue.clip), - TallyTags.JINGLE_IS_LIVE, - !effekt ? TallyTags.JINGLE : '' - ] - }) - ) + pieces.push({ + externalId: `${part.externalId}-JINGLE`, + name: effekt ? `EFFEKT ${parsedCue.clip}` : parsedCue.clip, + enable: { + start: 0 + }, + lifespan: PieceLifespan.WithinPart, + outputLayerId: SharedOutputLayers.JINGLE, + sourceLayerId: OfftubeSourceLayer.PgmJingle, + metaData: { + sisyfosPersistMetaData: { + sisyfosLayers: [] + } + }, + prerollDuration: config.studio.CasparPrerollDuration + TimeFromFrames(Number(jingle.StartAlpha)), + content: createJingleContentOfftube( + config, + file, + jingle.StartAlpha, + jingle.LoadFirstFrame, + jingle.Duration, + jingle.EndAlpha + ), + tags: [ + GetTagForJingle(part.segmentExternalId, parsedCue.clip), + GetTagForJingleNext(part.segmentExternalId, parsedCue.clip), + TallyTags.JINGLE_IS_LIVE, + !effekt ? TallyTags.JINGLE : '' + ] + }) } export function createJingleContentOfftube( diff --git a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts index 124c9bd88..b54b086d4 100644 --- a/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts +++ b/src/tv2_offtube_showstyle/cues/OfftubePgmClean.ts @@ -34,33 +34,31 @@ export function OfftubeEvaluatePgmClean( return } - pieces.push( - literal({ - externalId: partId, - name, - enable: { - start: 0 - }, - outputLayerId: SharedOutputLayers.AUX, - sourceLayerId: OfftubeSourceLayer.AuxPgmClean, - lifespan: PieceLifespan.OutOnShowStyleEnd, - content: literal>({ - timelineObjects: literal([ - literal({ - id: '', - enable: { while: '1' }, - priority: 0, - layer: OfftubeAtemLLayer.AtemAuxClean, - content: { - deviceType: TSR.DeviceType.ATEM, - type: TSR.TimelineContentTypeAtem.AUX, - aux: { - input: sourceInfo.port - } + pieces.push({ + externalId: partId, + name, + enable: { + start: 0 + }, + outputLayerId: SharedOutputLayers.AUX, + sourceLayerId: OfftubeSourceLayer.AuxPgmClean, + lifespan: PieceLifespan.OutOnShowStyleEnd, + content: literal>({ + timelineObjects: literal([ + literal({ + id: '', + enable: { while: '1' }, + priority: 0, + layer: OfftubeAtemLLayer.AtemAuxClean, + content: { + deviceType: TSR.DeviceType.ATEM, + type: TSR.TimelineContentTypeAtem.AUX, + aux: { + input: sourceInfo.port } - }) - ]) - }) + } + }) + ]) }) - ) + }) } diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 6ef998bdc..90ce6d901 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -259,55 +259,51 @@ function getGlobalAdlibActionsOfftube( function makeCutCameraActions(info: SourceInfo, queue: boolean, rank: number) { const sourceDefinition = SourceInfoToSourceDefinition(info) as SourceDefinitionKam - const userData = literal({ + 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: OfftubeSourceLayer.PgmCam, + outputLayerId: SharedOutputLayers.PGM, + content: {}, + tags: queue ? [AdlibTags.OFFTUBE_SET_CAM_NEXT, AdlibTags.ADLIB_QUEUE_NEXT] : [AdlibTags.ADLIB_CUT_DIRECT], + currentPieceTags: [GetTagForKam(sourceDefinition)], + nextPieceTags: [GetTagForKam(sourceDefinition)] + } }) - blueprintActions.push( - literal({ - externalId: generateExternalId(_context, userData), - actionId: AdlibActionType.CUT_TO_CAMERA, - userData, - userDataManifest: {}, - display: { - _rank: rank, - label: t(sourceDefinition.name), - sourceLayerId: OfftubeSourceLayer.PgmCam, - outputLayerId: SharedOutputLayers.PGM, - content: {}, - tags: queue ? [AdlibTags.OFFTUBE_SET_CAM_NEXT, AdlibTags.ADLIB_QUEUE_NEXT] : [AdlibTags.ADLIB_CUT_DIRECT], - currentPieceTags: [GetTagForKam(sourceDefinition)], - nextPieceTags: [GetTagForKam(sourceDefinition)] - } - }) - ) } function makeRemoteAction(sourceInfo: SourceInfo, rank: number) { const sourceDefinition = SourceInfoToSourceDefinition(sourceInfo) as SourceDefinitionRemote - const userData = literal({ + const userData: ActionCutToRemote = { type: AdlibActionType.CUT_TO_REMOTE, sourceDefinition + } + blueprintActions.push({ + externalId: generateExternalId(_context, userData), + actionId: AdlibActionType.CUT_TO_REMOTE, + userData, + userDataManifest: {}, + display: { + _rank: rank, + label: t(`${sourceDefinition.name}`), + sourceLayerId: OfftubeSourceLayer.PgmLive, + outputLayerId: OfftubeOutputLayers.PGM, + content: {}, + tags: [AdlibTags.OFFTUBE_SET_REMOTE_NEXT, AdlibTags.ADLIB_QUEUE_NEXT], + currentPieceTags: [GetTagForLive(sourceDefinition)], + nextPieceTags: [GetTagForLive(sourceDefinition)] + } }) - blueprintActions.push( - literal({ - externalId: generateExternalId(_context, userData), - actionId: AdlibActionType.CUT_TO_REMOTE, - userData, - userDataManifest: {}, - display: { - _rank: rank, - label: t(`${sourceDefinition.name}`), - sourceLayerId: OfftubeSourceLayer.PgmLive, - outputLayerId: OfftubeOutputLayers.PGM, - content: {}, - tags: [AdlibTags.OFFTUBE_SET_REMOTE_NEXT, AdlibTags.ADLIB_QUEUE_NEXT], - currentPieceTags: [GetTagForLive(sourceDefinition)], - nextPieceTags: [GetTagForLive(sourceDefinition)] - } - }) - ) } function makeAdlibBoxesActions( @@ -318,63 +314,59 @@ function getGlobalAdlibActionsOfftube( for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { const sourceDefinition = SourceInfoToSourceDefinition(info) const layer = type === SourceInfoType.KAM ? OfftubeSourceLayer.PgmCam : OfftubeSourceLayer.PgmLive - const userData = literal({ + const userData: ActionCutSourceToBox = { type: AdlibActionType.CUT_SOURCE_TO_BOX, name: sourceDefinition.name, box, sourceDefinition + } + blueprintActions.push({ + externalId: generateExternalId(_context, userData), + actionId: AdlibActionType.CUT_SOURCE_TO_BOX, + userData, + userDataManifest: {}, + display: { + _rank: rank + 0.1 * box, + label: t(`${sourceDefinition.name} inp ${box + 1}`), + sourceLayerId: layer, + outputLayerId: OfftubeOutputLayers.PGM, + content: {}, + tags: [AdlibTagCutToBox(box)] + } }) - blueprintActions.push( - literal({ - externalId: generateExternalId(_context, userData), - actionId: AdlibActionType.CUT_SOURCE_TO_BOX, - userData, - userDataManifest: {}, - display: { - _rank: rank + 0.1 * box, - label: t(`${sourceDefinition.name} inp ${box + 1}`), - sourceLayerId: layer, - outputLayerId: OfftubeOutputLayers.PGM, - content: {}, - tags: [AdlibTagCutToBox(box)] - } - }) - ) } } function makeServerAdlibBoxesActions(rank: number) { for (let box = 0; box < NUMBER_OF_DVE_BOXES; box++) { - const userData = literal({ + 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: OfftubeSourceLayer.PgmServer, + outputLayerId: SharedOutputLayers.SEC, + content: {}, + tags: [AdlibTagCutToBox(box)] + } }) - blueprintActions.push( - literal({ - 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: OfftubeSourceLayer.PgmServer, - outputLayerId: SharedOutputLayers.SEC, - content: {}, - tags: [AdlibTagCutToBox(box)] - } - }) - ) } } - function makeCommentatorSelectServerAction() { - const userData = literal({ + function makeCommentatorSelectServerAction(): IBlueprintActionManifest { + const userData: ActionCommentatorSelectServer = { type: AdlibActionType.COMMENTATOR_SELECT_SERVER - }) - return literal({ + } + return { externalId: generateExternalId(_context, userData), actionId: AdlibActionType.COMMENTATOR_SELECT_SERVER, userData, @@ -389,16 +381,16 @@ function getGlobalAdlibActionsOfftube( currentPieceTags: [TallyTags.SERVER_IS_LIVE], nextPieceTags: [TallyTags.SERVER_IS_LIVE] } - }) + } } blueprintActions.push(makeCommentatorSelectServerAction()) - function makeCommentatorSelectDveAction() { - const userData = literal({ + function makeCommentatorSelectDveAction(): IBlueprintActionManifest { + const userData: ActionCommentatorSelectDVE = { type: AdlibActionType.COMMENTATOR_SELECT_DVE - }) - return literal({ + } + return { externalId: generateExternalId(_context, userData), actionId: AdlibActionType.COMMENTATOR_SELECT_DVE, userData, @@ -413,16 +405,16 @@ function getGlobalAdlibActionsOfftube( currentPieceTags: [TallyTags.DVE_IS_LIVE], nextPieceTags: [TallyTags.DVE_IS_LIVE] } - }) + } } blueprintActions.push(makeCommentatorSelectDveAction()) - function makeCommentatorSelectFullAction() { - const userData = literal({ + function makeCommentatorSelectFullAction(): IBlueprintActionManifest { + const userData: ActionCommentatorSelectFull = { type: AdlibActionType.COMMENTATOR_SELECT_FULL - }) - return literal({ + } + return { externalId: generateExternalId(_context, userData), actionId: AdlibActionType.COMMENTATOR_SELECT_FULL, userData, @@ -437,18 +429,18 @@ function getGlobalAdlibActionsOfftube( currentPieceTags: [TallyTags.FULL_IS_LIVE], nextPieceTags: [TallyTags.FULL_IS_LIVE] } - }) + } } blueprintActions.push(makeCommentatorSelectFullAction()) - function makeClearGraphicsAltudAction() { - const userData = literal({ + function makeClearGraphicsAltudAction(): IBlueprintActionManifest { + const userData: ActionClearGraphics = { type: AdlibActionType.CLEAR_GRAPHICS, sendCommands: false, label: 'GFX Altud' - }) - return literal({ + } + return { externalId: generateExternalId(_context, userData), actionId: AdlibActionType.CLEAR_GRAPHICS, userData, @@ -463,18 +455,18 @@ function getGlobalAdlibActionsOfftube( currentPieceTags: [TallyTags.GFX_ALTUD], nextPieceTags: [TallyTags.GFX_ALTUD] } - }) + } } blueprintActions.push(makeClearGraphicsAltudAction()) blueprintActions.push(...GetTransitionAdLibActions(config, 800)) - function makeRecallLastDveAction() { - const userData = literal({ + function makeRecallLastDveAction(): IBlueprintActionManifest { + const userData: ActionRecallLastDVE = { type: AdlibActionType.RECALL_LAST_DVE - }) - return literal({ + } + return { externalId: generateExternalId(_context, userData), actionId: AdlibActionType.RECALL_LAST_DVE, userData, @@ -486,31 +478,29 @@ function getGlobalAdlibActionsOfftube( outputLayerId: 'pgm', tags: [AdlibTags.ADLIB_RECALL_LAST_DVE] } - }) + } } blueprintActions.push(makeRecallLastDveAction()) _.each(config.showStyle.DVEStyles, (dveConfig, i) => { - const userData = literal({ + 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: OfftubeSourceLayer.PgmDVEAdLib, + outputLayerId: SharedOutputLayers.PGM, + tags: [AdlibTags.ADLIB_SELECT_DVE_LAYOUT, dveConfig.DVEName] + } }) - blueprintActions.push( - literal({ - externalId: generateExternalId(_context, userData), - actionId: AdlibActionType.SELECT_DVE_LAYOUT, - userData, - userDataManifest: {}, - display: { - _rank: 200 + i, - label: t(dveConfig.DVEName), - sourceLayerId: OfftubeSourceLayer.PgmDVEAdLib, - outputLayerId: SharedOutputLayers.PGM, - tags: [AdlibTags.ADLIB_SELECT_DVE_LAYOUT, dveConfig.DVEName] - } - }) - ) }) config.sources.cameras @@ -531,11 +521,11 @@ function getGlobalAdlibActionsOfftube( makeAdlibBoxesActions(o, SourceInfoType.KAM, globalRank++) }) - function makeRecallLastLiveAction() { - const userData = literal({ + function makeRecallLastLiveAction(): IBlueprintActionManifest { + const userData: ActionRecallLastLive = { type: AdlibActionType.RECALL_LAST_LIVE - }) - return literal({ + } + return { externalId: generateExternalId(_context, userData), actionId: AdlibActionType.RECALL_LAST_LIVE, userData, @@ -547,7 +537,7 @@ function getGlobalAdlibActionsOfftube( outputLayerId: SharedOutputLayers.PGM, tags: [AdlibTags.ADLIB_RECALL_LAST_LIVE] } - }) + } } blueprintActions.push(makeRecallLastLiveAction()) @@ -578,11 +568,11 @@ function getGlobalAdlibActionsOfftube( makeServerAdlibBoxesActions(globalRank++) - function makeCommentatorSelectJingleAction() { - const userData = literal({ + function makeCommentatorSelectJingleAction(): IBlueprintActionManifest { + const userData: ActionCommentatorSelectJingle = { type: AdlibActionType.COMMENTATOR_SELECT_JINGLE - }) - return literal({ + } + return { externalId: generateExternalId(_context, userData), actionId: AdlibActionType.COMMENTATOR_SELECT_JINGLE, userData, @@ -597,7 +587,7 @@ function getGlobalAdlibActionsOfftube( currentPieceTags: [TallyTags.JINGLE_IS_LIVE], nextPieceTags: [TallyTags.JINGLE_IS_LIVE] } - }) + } } blueprintActions.push(makeCommentatorSelectJingleAction()) diff --git a/src/tv2_offtube_showstyle/getSegment.ts b/src/tv2_offtube_showstyle/getSegment.ts index 5c0175639..eedba6e0c 100644 --- a/src/tv2_offtube_showstyle/getSegment.ts +++ b/src/tv2_offtube_showstyle/getSegment.ts @@ -2,7 +2,6 @@ import { BlueprintResultPart, BlueprintResultSegment, CameraContent, - IBlueprintPiece, IngestSegment, ISegmentUserContext, PieceLifespan, @@ -53,15 +52,18 @@ export async function getSegment( } } -function CreatePartContinuity(config: OfftubeShowstyleBlueprintConfig, ingestSegment: IngestSegment) { - return literal({ +function CreatePartContinuity( + config: OfftubeShowstyleBlueprintConfig, + ingestSegment: IngestSegment +): BlueprintResultPart { + return { part: { externalId: `${ingestSegment.externalId}-CONTINUITY`, title: 'CONTINUITY', untimed: true }, pieces: [ - literal({ + { externalId: `${ingestSegment.externalId}-CONTINUITY`, enable: { start: 0 @@ -92,9 +94,9 @@ function CreatePartContinuity(config: OfftubeShowstyleBlueprintConfig, ingestSeg }) ]) }) - }) + } ], adLibPieces: [], actions: [] - }) + } } diff --git a/src/tv2_offtube_showstyle/migrations/hotkeys.ts b/src/tv2_offtube_showstyle/migrations/hotkeys.ts index 472ec9650..52a07d7fe 100644 --- a/src/tv2_offtube_showstyle/migrations/hotkeys.ts +++ b/src/tv2_offtube_showstyle/migrations/hotkeys.ts @@ -24,7 +24,7 @@ export function GetDefaultStudioSourcesForOfftube(context: MigrationContextShowS 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}`) 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 0e9306a60..9ca3d320d 100644 --- a/src/tv2_offtube_showstyle/migrations/index.ts +++ b/src/tv2_offtube_showstyle/migrations/index.ts @@ -4,7 +4,6 @@ import { changeGFXTemplate, GetDefaultAdLibTriggers, GetDSKSourceLayerNames, - literal, RemoveOldShortcuts, removeSourceLayer, renameSourceLayer, @@ -16,7 +15,6 @@ import { UpsertValuesIntoTransitionTable } from 'tv2-common' import { SharedGraphicLLayer, SharedSourceLayers } from 'tv2-constants' -import * as _ from 'underscore' import { ATEMModel } from '../../types/atem' import { OfftubeSourceLayer } from '../layers' import { GetDefaultStudioSourcesForOfftube } from './hotkeys' @@ -71,7 +69,7 @@ const SHOW_STYLE_ID = 'tv2_offtube_showstyle' * 0.1.0: Core 0.24.0 */ -export const showStyleMigrations: MigrationStepShowStyle[] = literal([ +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(), @@ -271,4 +269,4 @@ export const showStyleMigrations: MigrationStepShowStyle[] = literal { - return literal({ + return { id: `${versionStr}.sourcelayer.defaults${force ? '.forced' : ''}.${defaultVal._id}`, version: versionStr, canBeRunAutomatically: true, @@ -39,13 +39,13 @@ export function getSourceLayerDefaultsMigrationSteps(versionStr: string, force?: context.insertSourceLayer(defaultVal._id, defaultVal) } } - }) + } }) ) } export function forceSettingToDefaults(versionStr: string, setting: string): MigrationStepShowStyle { - return literal({ + return { id: `${versionStr}.sourcelayer.defaults.${setting}.forced`, version: versionStr, canBeRunAutomatically: true, @@ -78,13 +78,13 @@ export function forceSettingToDefaults(versionStr: string, setting: string): Mig context.setBaseConfig(setting, defaultVal.defaultVal) } } - }) + } } export function getOutputLayerDefaultsMigrationSteps(versionStr: string): MigrationStepShowStyle[] { return _.compact( _.map(OutputlayerDefaults, (defaultVal: IOutputLayer): MigrationStepShowStyle | null => { - return literal({ + return { id: `${versionStr}.outputlayer.defaults.${defaultVal._id}`, version: versionStr, canBeRunAutomatically: true, @@ -99,7 +99,7 @@ export function getOutputLayerDefaultsMigrationSteps(versionStr: string): Migrat context.insertOutputLayer(defaultVal._id, defaultVal) } } - }) + } }) ) } @@ -112,7 +112,7 @@ function remapTableColumnValuesInner( ): { changed: number; table: TableConfigItemValue } { let changed = 0 - table.map(row => { + table.forEach(row => { const val = row[columnId] if (val) { @@ -123,8 +123,6 @@ function remapTableColumnValuesInner( changed++ } } - - return row }) return { changed, table } diff --git a/src/tv2_offtube_showstyle/onTimelineGenerate.ts b/src/tv2_offtube_showstyle/onTimelineGenerate.ts index a173c4355..805cbe46f 100644 --- a/src/tv2_offtube_showstyle/onTimelineGenerate.ts +++ b/src/tv2_offtube_showstyle/onTimelineGenerate.ts @@ -7,7 +7,13 @@ import { TimelinePersistentState, TSR } from '@tv2media/blueprints-integration' -import { disablePilotWipeAfterJingle, onTimelineGenerate, PartEndStateExt, TimelineBlueprintExt } from 'tv2-common' +import { + disablePilotWipeAfterJingle, + 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' @@ -17,7 +23,7 @@ export function onTimelineGenerateOfftube( timeline: OnGenerateTimelineObj[], previousPersistentState: TimelinePersistentState | undefined, previousPartEndState: PartEndState | undefined, - resolvedPieces: IBlueprintResolvedPieceInstance[] + resolvedPieces: Array> ): Promise { const previousPartEndState2 = previousPartEndState as PartEndStateExt | undefined disablePilotWipeAfterJingle(timeline, previousPartEndState2, resolvedPieces) diff --git a/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts b/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts index f8cfbc835..e4c365924 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeDVE.ts @@ -7,7 +7,7 @@ import { IBlueprintPiece, ISegmentUserContext } from '@tv2media/blueprints-integration' -import { AddScript, literal, PartDefinitionDVE, PartTime } from 'tv2-common' +import { AddScript, PartDefinitionDVE, PartTime } from 'tv2-common' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' @@ -20,12 +20,12 @@ export async function OfftubeCreatePartDVE( ): Promise { const partTime = PartTime(config, partDefinition, totalWords, false) - const part = literal({ + const part: IBlueprintPart = { externalId: partDefinition.externalId, title: partDefinition.title || `DVE`, autoNext: false, expectedDuration: partTime - }) + } const pieces: IBlueprintPiece[] = [] const adLibPieces: IBlueprintAdLibPiece[] = [] const actions: IBlueprintActionManifest[] = [] diff --git a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts index 8282b8deb..e04113b16 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeGrafik.ts @@ -6,7 +6,7 @@ import { IBlueprintPiece, ISegmentUserContext } from '@tv2media/blueprints-integration' -import { AddScript, ApplyFullGraphicPropertiesToPart, literal, PartDefinition, PartTime } from 'tv2-common' +import { AddScript, ApplyFullGraphicPropertiesToPart, PartDefinition, PartTime } from 'tv2-common' import { OfftubeShowstyleBlueprintConfig } from '../helpers/config' import { OfftubeEvaluateCues } from '../helpers/EvaluateCues' import { OfftubeSourceLayer } from '../layers' @@ -20,13 +20,13 @@ export async function OfftubeCreatePartGrafik( ) { const partTime = PartTime(config, partDefinition, totalWords) - const part = literal({ + const part: IBlueprintPart = { externalId: partDefinition.externalId, title: partDefinition.title || partDefinition.type + ' - ' + partDefinition.rawType, metaData: {}, autoNext: false, expectedDuration: partTime - }) + } const adLibPieces: IBlueprintAdLibPiece[] = [] const pieces: IBlueprintPiece[] = [] diff --git a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts index e1cc27c68..055679741 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeKam.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeKam.ts @@ -23,7 +23,7 @@ import { GetTagForKam, literal, PartDefinitionKam, - SisyfosPersistMetaData, + PieceMetaData, TransitionSettings } from 'tv2-common' import { SharedOutputLayers, TallyTags } from 'tv2-constants' @@ -45,48 +45,46 @@ export async function OfftubeCreatePartKam( const partTime = partKamBase.duration const adLibPieces: IBlueprintAdLibPiece[] = [] - const pieces: IBlueprintPiece[] = [] + const pieces: Array> = [] const actions: IBlueprintActionManifest[] = [] const mediaSubscriptions: HackPartMediaObjectSubscription[] = [] const jingleDSK = FindDSKJingle(config) if (/cs ?3/i.test(partDefinition.sourceDefinition.id)) { - pieces.push( - literal({ - externalId: partDefinition.externalId, - name: 'CS 3 (JINGLE)', - enable: { start: 0 }, - outputLayerId: SharedOutputLayers.PGM, - sourceLayerId: OfftubeSourceLayer.PgmJingle, - lifespan: PieceLifespan.WithinPart, - tags: [GetTagForKam(partDefinition.sourceDefinition), TallyTags.JINGLE_IS_LIVE], - content: literal>({ - ignoreMediaObjectStatus: true, - fileName: '', - path: '', - timelineObjects: literal([ - literal({ - id: ``, - enable: { - start: 0 - }, - 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(config, partDefinition) - } + pieces.push({ + externalId: partDefinition.externalId, + name: 'CS 3 (JINGLE)', + enable: { start: 0 }, + outputLayerId: SharedOutputLayers.PGM, + sourceLayerId: OfftubeSourceLayer.PgmJingle, + lifespan: PieceLifespan.WithinPart, + tags: [GetTagForKam(partDefinition.sourceDefinition), TallyTags.JINGLE_IS_LIVE], + content: literal>({ + ignoreMediaObjectStatus: true, + fileName: '', + path: '', + timelineObjects: literal([ + literal({ + id: ``, + enable: { + start: 0 + }, + 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(config, partDefinition) } - }) - ]) - }) + } + }) + ]) }) - ) + }) } else { const sourceInfoCam = findSourceInfo(config.sources, partDefinition.sourceDefinition) if (sourceInfoCam === undefined) { @@ -96,51 +94,49 @@ export async function OfftubeCreatePartKam( part = { ...part, ...CreateEffektForpart(context, config, partDefinition, pieces) } - pieces.push( - literal({ - externalId: partDefinition.externalId, - name: part.title, - enable: { start: 0 }, - outputLayerId: SharedOutputLayers.PGM, - sourceLayerId: OfftubeSourceLayer.PgmCam, - lifespan: PieceLifespan.WithinPart, - metaData: { - sisyfosPersistMetaData: literal({ - sisyfosLayers: sourceInfoCam.sisyfosLayers ?? [], - acceptPersistAudio: sourceInfoCam.acceptPersistAudio - }) - }, - tags: [GetTagForKam(partDefinition.sourceDefinition)], - content: { - studioLabel: '', - switcherInput: atemInput, - timelineObjects: literal([ - literal({ - id: ``, - enable: { - start: 0 - }, - 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(config, partDefinition) - } - }, - ...(AddParentClass(config, partDefinition) - ? { classes: [CameraParentClass('studio0', partDefinition.sourceDefinition.id)] } - : {}) - }), - - ...GetSisyfosTimelineObjForCamera(config, sourceInfoCam, partDefinition.sourceDefinition.minusMic) - ]) + pieces.push({ + externalId: partDefinition.externalId, + name: part.title, + enable: { start: 0 }, + outputLayerId: SharedOutputLayers.PGM, + sourceLayerId: OfftubeSourceLayer.PgmCam, + lifespan: PieceLifespan.WithinPart, + metaData: { + sisyfosPersistMetaData: { + sisyfosLayers: sourceInfoCam.sisyfosLayers ?? [], + acceptPersistAudio: sourceInfoCam.acceptPersistAudio } - }) - ) + }, + tags: [GetTagForKam(partDefinition.sourceDefinition)], + content: { + studioLabel: '', + switcherInput: atemInput, + timelineObjects: literal([ + literal({ + id: ``, + enable: { + start: 0 + }, + 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(config, partDefinition) + } + }, + ...(AddParentClass(config, partDefinition) + ? { classes: [CameraParentClass('studio0', partDefinition.sourceDefinition.id)] } + : {}) + }), + + ...GetSisyfosTimelineObjForCamera(config, sourceInfoCam, partDefinition.sourceDefinition.minusMic) + ]) + } + }) } await OfftubeEvaluateCues( diff --git a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts index 0b90e1fa3..ececf2cbf 100644 --- a/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts +++ b/src/tv2_offtube_showstyle/parts/OfftubeUnknown.ts @@ -11,7 +11,6 @@ import { ApplyFullGraphicPropertiesToPart, GetJinglePartProperties, GraphicIsPilot, - literal, PartDefinition, PartTime } from 'tv2-common' @@ -29,13 +28,13 @@ export async function CreatePartUnknown( ) { const partTime = PartTime(config, partDefinition, totalWords) - let part = literal({ + let part: IBlueprintPart = { externalId: partDefinition.externalId, title: partDefinition.title || partDefinition.type + ' - ' + partDefinition.rawType, metaData: {}, autoNext: false, expectedDuration: partTime - }) + } const adLibPieces: IBlueprintAdLibPiece[] = [] const pieces: IBlueprintPiece[] = [] diff --git a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts b/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts index fe1b658cb..44e44292f 100644 --- a/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts +++ b/src/tv2_offtube_showstyle/postProcessTimelineObjects.ts @@ -7,7 +7,7 @@ import { TimelineObjHoldMode, TSR } from '@tv2media/blueprints-integration' -import { literal, TimelineBlueprintExt, TV2BlueprintConfig } from 'tv2-common' +import { TimelineBlueprintExt, TV2BlueprintConfig } from 'tv2-common' import { ControlClasses } from 'tv2-constants' import _ = require('underscore') import { OfftubeAbstractLLayer, OfftubeAtemLLayer } from '../tv2_offtube_studio/layers' @@ -60,7 +60,7 @@ export function postProcessPieceTimelineObjects( ) { if (tlObj.classes?.includes(ControlClasses.AbstractLookahead)) { // Create a lookahead-lookahead object for this me-program - const lookaheadObj = literal({ + 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 @@ -74,11 +74,11 @@ export function postProcessPieceTimelineObjects( mediaPlayerSession: tlObj.metaData?.mediaPlayerSession }, classes: ['ab_on_preview'] - }) + } extraObjs.push(lookaheadObj) } else { // Create a lookahead-lookahead object for this me-program - const lookaheadObj = literal({ + 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 @@ -97,7 +97,7 @@ export function postProcessPieceTimelineObjects( mediaPlayerSession: tlObj.metaData?.mediaPlayerSession }, classes: ['ab_on_preview'] - }) + } extraObjs.push(lookaheadObj) } } diff --git a/src/tv2_offtube_studio/getBaseline.ts b/src/tv2_offtube_studio/getBaseline.ts index d20332296..7e3ce879d 100644 --- a/src/tv2_offtube_studio/getBaseline.ts +++ b/src/tv2_offtube_studio/getBaseline.ts @@ -10,7 +10,7 @@ import * as _ from 'underscore' import { AtemSourceIndex } from '../types/atem' import { OfftubeStudioBlueprintConfig } from './helpers/config' import { OfftubeAtemLLayer, OfftubeSisyfosLLayer } from './layers' -import { SisyfosChannel, sisyfosChannels } from './sisyfosChannels' +import { sisyfosChannels } from './sisyfosChannels' function filterMappings( input: BlueprintMappings, @@ -30,14 +30,14 @@ function filterMappings( export function getBaseline(context: IStudioContext): BlueprintResultBaseline { const mappings = context.getStudioMappings() - const config = (context.getStudioConfig() as unknown) as OfftubeStudioBlueprintConfig + const config = context.getStudioConfig() as OfftubeStudioBlueprintConfig const sisyfosMappings = filterMappings(mappings, (_id, v) => v.device === TSR.DeviceType.SISYFOS) const mappedChannels: TSR.TimelineObjSisyfosChannels['content']['channels'] = [] for (const id in sisyfosMappings) { if (sisyfosMappings[id]) { - const sisyfosChannel = sisyfosChannels[id as OfftubeSisyfosLLayer] as SisyfosChannel | undefined + const sisyfosChannel = sisyfosChannels[id as OfftubeSisyfosLLayer] if (sisyfosChannel) { mappedChannels.push({ mappedLayer: id, diff --git a/src/tv2_offtube_studio/migrations/devices.ts b/src/tv2_offtube_studio/migrations/devices.ts index d088ad397..ae375657d 100644 --- a/src/tv2_offtube_studio/migrations/devices.ts +++ b/src/tv2_offtube_studio/migrations/devices.ts @@ -5,7 +5,6 @@ import { MigrationStepStudio, TSR } from '@tv2media/blueprints-integration' -import { literal } from 'tv2-common' import * as _ from 'underscore' declare const VERSION: string // Injected by webpack @@ -218,10 +217,10 @@ const devices: DeviceEntry[] = [ } ] -export const deviceMigrations = literal([ +export const deviceMigrations: MigrationStepStudio[] = [ // create all devices ..._.map(devices, createDevice), // ensure all devices still look valid ..._.map(devices, validateDevice) -]) +] diff --git a/src/tv2_offtube_studio/migrations/index.ts b/src/tv2_offtube_studio/migrations/index.ts index 9c58d89e4..9c55ff58f 100644 --- a/src/tv2_offtube_studio/migrations/index.ts +++ b/src/tv2_offtube_studio/migrations/index.ts @@ -6,7 +6,6 @@ import { } from '@tv2media/blueprints-integration' import { AddKeepAudio, - literal, MoveClipSourcePath, MoveSourcesToTable, RemoveConfig, @@ -41,7 +40,7 @@ function renameAudioSources(versionStr: string, renaming: Map): const steps: MigrationStepStudio[] = [] for (const layer in renaming) { if (layer in renaming) { - const res = literal({ + const res: MigrationStepStudio = { id: `${versionStr}.studioConfig.renameAudioSources.${layer}`, version: versionStr, canBeRunAutomatically: true, @@ -64,7 +63,7 @@ function renameAudioSources(versionStr: string, renaming: Map): } } } - }) + } steps.push(res) } @@ -74,7 +73,7 @@ function renameAudioSources(versionStr: string, renaming: Map): } function ensureMappingDeleted(versionStr: string, mapping: string): MigrationStepStudio { - const res = literal({ + return { id: `${versionStr}.studioConfig.ensureMappingDeleted.${mapping}`, version: versionStr, canBeRunAutomatically: true, @@ -92,9 +91,7 @@ function ensureMappingDeleted(versionStr: string, mapping: string): MigrationSte context.removeMapping(mapping) } } - }) - - return res + } } function remapTableColumnValuesInner( @@ -105,7 +102,7 @@ function remapTableColumnValuesInner( ): { changed: number; table: TableConfigItemValue } { let changed = 0 - table.map(row => { + table.forEach(row => { const val = row[columnId] if (val) { @@ -127,8 +124,6 @@ function remapTableColumnValuesInner( } } } - - return row }) return { changed, table } @@ -142,7 +137,7 @@ function remapTableColumnValues( remapping: Map ): MigrationStepStudio[] { return [ - literal({ + { id: `${versionStr}.remapTableColumnValue.${tableId}.${columnId}`, version: versionStr, canBeRunAutomatically: true, @@ -179,7 +174,7 @@ function remapTableColumnValues( context.setConfig(tableId, ret.table) } - }) + } ] } @@ -190,7 +185,7 @@ const audioSourceRenaming: Map = new Map([ ['sisyfos_source_world_feed_surround', OfftubeSisyfosLLayer.SisyfosSourceLive_3] ]) -export const studioMigrations: MigrationStepStudio[] = literal([ +export const studioMigrations: MigrationStepStudio[] = [ ensureStudioConfig( '0.1.0', 'SourcesCam', @@ -370,4 +365,4 @@ export const studioMigrations: MigrationStepStudio[] = literal { - return literal({ + return { id: `${versionStr}.mappings.defaults.${id}`, version: versionStr, canBeRunAutomatically: true, @@ -150,11 +149,9 @@ export function getMappingsDefaultsMigrationSteps(versionStr: string): Migration context.insertMapping(id, defaultVal) } } - }) + } }) ) - - return res } export function GetMappingDefaultMigrationStepForLayer( @@ -162,7 +159,7 @@ export function GetMappingDefaultMigrationStepForLayer( layer: string, force?: boolean ): MigrationStepStudio { - return literal({ + return { id: `${versionStr}.mappings.defaults.manualEnsure${layer}`, version: versionStr, canBeRunAutomatically: true, @@ -189,7 +186,7 @@ export function GetMappingDefaultMigrationStepForLayer( context.insertMapping(layer, MappingsDefaults[layer]) } } - }) + } } export function GetSisyfosLayersForTableMigrationOfftube(configName: string, val: string): string[] { diff --git a/src/tv2_system/migrations/hotkeys.ts b/src/tv2_system/migrations/hotkeys.ts index ae6f98a45..7f0ce7b08 100644 --- a/src/tv2_system/migrations/hotkeys.ts +++ b/src/tv2_system/migrations/hotkeys.ts @@ -6,12 +6,11 @@ import { PlayoutActions, TriggerType } from '@tv2media/blueprints-integration' -import { literal } from 'tv2-common' -export function RemoveDefaultCoreShortcuts(versionStr: string) { +export function RemoveDefaultCoreShortcuts(versionStr: string): MigrationStepSystem { const defaultTriggerIds = DEFAULT_CORE_TRIGGERS.map(trigger => trigger._id) - return literal({ + return { id: `${versionStr}.disableCoreDefaultTriggers`, version: versionStr, canBeRunAutomatically: true, @@ -34,7 +33,7 @@ export function RemoveDefaultCoreShortcuts(versionStr: string) { } } } - }) + } } // copy-pasted from core migrations diff --git a/src/tv2_system/migrations/index.ts b/src/tv2_system/migrations/index.ts index a79e12524..5d86532c1 100644 --- a/src/tv2_system/migrations/index.ts +++ b/src/tv2_system/migrations/index.ts @@ -1,9 +1,6 @@ import { MigrationStepSystem } from '@tv2media/blueprints-integration' -import { literal } from 'tv2-common' import { RemoveDefaultCoreShortcuts } from './hotkeys' declare const VERSION: string // Injected by webpack -export const systemMigrations: MigrationStepSystem[] = literal([ - RemoveDefaultCoreShortcuts(VERSION) -]) +export const systemMigrations: MigrationStepSystem[] = [RemoveDefaultCoreShortcuts(VERSION)] From c74e49f668e9ec7069f729cac5dfa04cc153e6a2 Mon Sep 17 00:00:00 2001 From: ianshade Date: Wed, 7 Sep 2022 13:02:23 +0200 Subject: [PATCH 180/184] fix: SOF-767 make looping adlibs restart from 0 --- src/tv2-common/content/server.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tv2-common/content/server.ts b/src/tv2-common/content/server.ts index 5c364ae66..8e0f2b09c 100644 --- a/src/tv2-common/content/server.ts +++ b/src/tv2-common/content/server.ts @@ -96,6 +96,7 @@ function GetServerTimeline( loop: partProps.adLibPix, seek: contentProps.seek, length: contentProps.seek ? contentProps.clipDuration : undefined, + inPoint: contentProps.seek ? 0 : undefined, playing: true }, metaData: { @@ -111,6 +112,7 @@ function GetServerTimeline( const mediaOffObj = JSON.parse(JSON.stringify(mediaObj)) as TSR.TimelineObjCCGMedia & TimelineBlueprintExt mediaOffObj.enable = { while: `!${serverEnableClass}` } mediaOffObj.content.playing = false + mediaOffObj.content.noStarttime = true const audioEnable = { while: serverEnableClass From 8ff13c8c2661f63728e9c7db42b04b95cb488f2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Tue, 13 Sep 2022 12:41:43 +0200 Subject: [PATCH 181/184] SOF-1120 Now fall backs to a default ShowStyleVariant if it cant find a ShowStyleVariant --- .../__tests__/getshowStyleVariantId.spec.ts | 74 +++++++++++++++++++ src/tv2-common/getShowStyleVariantId.ts | 20 +++++ src/tv2_afvd_showstyle/getRundown.ts | 16 ---- src/tv2_afvd_showstyle/index.ts | 3 +- src/tv2_offtube_showstyle/getRundown.ts | 17 ----- src/tv2_offtube_showstyle/index.ts | 3 +- 6 files changed, 98 insertions(+), 35 deletions(-) create mode 100644 src/tv2-common/__tests__/getshowStyleVariantId.spec.ts create mode 100644 src/tv2-common/getShowStyleVariantId.ts diff --git a/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts b/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts new file mode 100644 index 000000000..6d31e68b9 --- /dev/null +++ b/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts @@ -0,0 +1,74 @@ +import { + IBlueprintShowStyleVariant, + IngestRundown, + IStudioUserContext +} from '../../../../tv-automation-server-core/packages/blueprints-integration' +import { makeMockAFVDContext } from '../../__mocks__/context' +import { getShowStyleVariantId } from '../getShowStyleVariantId' + +describe('getShowStyleVariantId', () => { + it('returns the id of the ingestedShowStyleVariant', () => { + const variantName = 'randomVariantName' + const ingestRundown: IngestRundown = getIngestRundown(variantName) + + const result = getShowStyleVariantId(getMockContext(), getShowStyleVariants([variantName]), ingestRundown) + + expect(result).toBe(variantName) + }) + + function getIngestRundown(showStyleVariant?: string): IngestRundown { + return { + externalId: '', + name: '', + type: '', + segments: [], + payload: { + showstyleVariant: showStyleVariant ?? '' + } + } + } + + function getMockContext(): IStudioUserContext { + return makeMockAFVDContext() + } + + function getShowStyleVariants(variantNames?: string[]): IBlueprintShowStyleVariant[] { + const variants: IBlueprintShowStyleVariant[] = [ + { + _id: 'default', + name: 'default', + blueprintConfig: {} + } + ] + if (variantNames) { + variants.push( + ...variantNames.map(variantName => { + return { + _id: variantName, + name: variantName, + blueprintConfig: {} + } + }) + ) + } + + return variants + } + + it('does not have variant, returns default', () => { + const variantName = 'randomVariantName' + const ingestRundown: IngestRundown = getIngestRundown('nonExistentVariantName') + + const result = getShowStyleVariantId(getMockContext(), getShowStyleVariants([variantName]), ingestRundown) + + expect(result).toBe('default') + }) + + it('does not have variant, no default configured, returns null', () => { + const ingestRundown: IngestRundown = getIngestRundown('nonExistentVariantName') + + const result = getShowStyleVariantId(getMockContext(), [], ingestRundown) + + expect(result).toBeNull() + }) +}) diff --git a/src/tv2-common/getShowStyleVariantId.ts b/src/tv2-common/getShowStyleVariantId.ts new file mode 100644 index 000000000..eab5280b0 --- /dev/null +++ b/src/tv2-common/getShowStyleVariantId.ts @@ -0,0 +1,20 @@ +import { + IBlueprintShowStyleVariant, + IngestRundown, + IStudioUserContext +} from '../../../tv-automation-server-core/packages/blueprints-integration' + +const DEFAULT_VARIANT_NAME = 'default' + +export function getShowStyleVariantId( + _context: IStudioUserContext, + showStyleVariants: IBlueprintShowStyleVariant[], + ingestRundown: IngestRundown +): 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) + + return showStyleVariant?._id ?? null +} diff --git a/src/tv2_afvd_showstyle/getRundown.ts b/src/tv2_afvd_showstyle/getRundown.ts index 3878b9961..5ba1c9e68 100644 --- a/src/tv2_afvd_showstyle/getRundown.ts +++ b/src/tv2_afvd_showstyle/getRundown.ts @@ -5,7 +5,6 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintRundown, - IBlueprintShowStyleVariant, IngestRundown, IShowStyleUserContext, IStudioUserContext, @@ -62,21 +61,6 @@ import { NUMBER_OF_DVE_BOXES } from './helpers/content/dve' import { SourceLayer } from './layers' import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' -export function getShowStyleVariantId( - _context: IStudioUserContext, - showStyleVariants: IBlueprintShowStyleVariant[], - ingestRundown: IngestRundown -): string | null { - const showstyleVariant = ingestRundown.payload?.showstyleVariant?.trim().toLowerCase() - const variant = - showStyleVariants.find(v => v.name.trim().toLowerCase() === showstyleVariant) ?? _.first(showStyleVariants) - - if (variant) { - return variant._id - } - return null -} - export function getRundown(context: IShowStyleUserContext, ingestRundown: IngestRundown): BlueprintResultRundown { const config = getShowStyleConfig(context) diff --git a/src/tv2_afvd_showstyle/index.ts b/src/tv2_afvd_showstyle/index.ts index 29d7dab6a..e39af102f 100644 --- a/src/tv2_afvd_showstyle/index.ts +++ b/src/tv2_afvd_showstyle/index.ts @@ -1,4 +1,5 @@ import { BlueprintManifestType, ShowStyleBlueprintManifest } from '@tv2media/blueprints-integration' +import { getShowStyleVariantId } from '../tv2-common/getShowStyleVariantId' import { showStyleConfigManifest } from './config-manifests' import { showStyleMigrations } from './migrations' @@ -6,7 +7,7 @@ import { GetShowStyleManifestWithMixins, ShowStyleManifestMixinINews } from 'ine import { getEndStateForPart, shouldRemoveOrphanedPartInstance } from 'tv2-common' import { onTimelineGenerateAFVD } from '../tv2_afvd_studio/onTimelineGenerate' import { executeActionAFVD } from './actions' -import { getRundown, getShowStyleVariantId } from './getRundown' +import { getRundown } from './getRundown' import { getSegment } from './getSegment' import { parseConfig } from './helpers/config' import { syncIngestUpdateToPartInstance } from './syncIngestUpdateToPartInstance' diff --git a/src/tv2_offtube_showstyle/getRundown.ts b/src/tv2_offtube_showstyle/getRundown.ts index 6ef998bdc..3a8e3030d 100644 --- a/src/tv2_offtube_showstyle/getRundown.ts +++ b/src/tv2_offtube_showstyle/getRundown.ts @@ -4,10 +4,8 @@ import { IBlueprintActionManifest, IBlueprintAdLibPiece, IBlueprintRundown, - IBlueprintShowStyleVariant, IngestRundown, IShowStyleUserContext, - IStudioContext, IStudioUserContext, PieceLifespan, PlaylistTimingType, @@ -66,21 +64,6 @@ import { NUMBER_OF_DVE_BOXES } from './content/OfftubeDVEContent' import { OfftubeOutputLayers, OfftubeSourceLayer } from './layers' import { postProcessPieceTimelineObjects } from './postProcessTimelineObjects' -export function getShowStyleVariantId( - _context: IStudioContext, - showStyleVariants: IBlueprintShowStyleVariant[], - ingestRundown: IngestRundown -): string | null { - const showstyleVariant = ingestRundown.payload?.showstyleVariant?.trim().toLowerCase() - const variant = - showStyleVariants.find(v => v.name.trim().toLowerCase() === showstyleVariant) ?? _.first(showStyleVariants) - - if (variant) { - return variant._id - } - return null -} - export function getRundown(context: IShowStyleUserContext, ingestRundown: IngestRundown): BlueprintResultRundown { const config = getShowStyleConfig(context) diff --git a/src/tv2_offtube_showstyle/index.ts b/src/tv2_offtube_showstyle/index.ts index 4f1e1ad78..e6aba71e8 100644 --- a/src/tv2_offtube_showstyle/index.ts +++ b/src/tv2_offtube_showstyle/index.ts @@ -1,4 +1,5 @@ import { BlueprintManifestType, ShowStyleBlueprintManifest } from '@tv2media/blueprints-integration' +import { getShowStyleVariantId } from '../tv2-common/getShowStyleVariantId' import { showStyleConfigManifest } from './config-manifests' import { showStyleMigrations } from './migrations' @@ -6,7 +7,7 @@ import { GetShowStyleManifestWithMixins, ShowStyleManifestMixinINews } from 'ine import { getEndStateForPart } from 'tv2-common' import { onTimelineGenerateOfftube } from '../tv2_offtube_showstyle/onTimelineGenerate' import { executeActionOfftube } from './actions' -import { getRundown, getShowStyleVariantId } from './getRundown' +import { getRundown } from './getRundown' import { getSegment } from './getSegment' import { parseConfig } from './helpers/config' import { syncIngestUpdateToPartInstance } from './syncIngestUpdateToPartInstances' From 48d8b59ae0bae880fb99cc65dba446adcf65d76d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Tue, 13 Sep 2022 12:46:24 +0200 Subject: [PATCH 182/184] SOF-1120 Fix wrong imports --- src/tv2-common/__tests__/getshowStyleVariantId.spec.ts | 6 +----- src/tv2-common/getShowStyleVariantId.ts | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts b/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts index 6d31e68b9..593a57f8b 100644 --- a/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts +++ b/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts @@ -1,8 +1,4 @@ -import { - IBlueprintShowStyleVariant, - IngestRundown, - IStudioUserContext -} from '../../../../tv-automation-server-core/packages/blueprints-integration' +import { IBlueprintShowStyleVariant, IngestRundown, IStudioUserContext } from '@tv2media/blueprints-integration' import { makeMockAFVDContext } from '../../__mocks__/context' import { getShowStyleVariantId } from '../getShowStyleVariantId' diff --git a/src/tv2-common/getShowStyleVariantId.ts b/src/tv2-common/getShowStyleVariantId.ts index eab5280b0..88009484e 100644 --- a/src/tv2-common/getShowStyleVariantId.ts +++ b/src/tv2-common/getShowStyleVariantId.ts @@ -1,8 +1,4 @@ -import { - IBlueprintShowStyleVariant, - IngestRundown, - IStudioUserContext -} from '../../../tv-automation-server-core/packages/blueprints-integration' +import { IBlueprintShowStyleVariant, IngestRundown, IStudioUserContext } from '@tv2media/blueprints-integration' const DEFAULT_VARIANT_NAME = 'default' From 25d5690b46a634cc9e70955e0d9ae0e837f1a8e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Wed, 14 Sep 2022 10:49:39 +0200 Subject: [PATCH 183/184] chore: SOF-1120 Unit test now test if the default variant is not the first in the array --- .../__tests__/getshowStyleVariantId.spec.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts b/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts index 593a57f8b..4b2e4ed5c 100644 --- a/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts +++ b/src/tv2-common/__tests__/getshowStyleVariantId.spec.ts @@ -67,4 +67,23 @@ describe('getShowStyleVariantId', () => { expect(result).toBeNull() }) + + it('does not have variant, default is not first in variant array, selects default', () => { + const variantName = 'randomVariantName' + const ingestRundown: IngestRundown = getIngestRundown('nonExistentVariantName') + + const showStyleVariants: IBlueprintShowStyleVariant[] = [ + { + _id: 'someVariant', + name: 'someVariant', + blueprintConfig: {} + }, + ...getShowStyleVariants([variantName]) + ] + + expect(showStyleVariants[0]._id).not.toBe('default') + const result = getShowStyleVariantId(getMockContext(), showStyleVariants, ingestRundown) + + expect(result).toBe('default') + }) }) From b7ab3a0175c480a70da95ca22bedbd49bbf4cdf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20K=C3=A6rvang=20Lindved?= Date: Thu, 15 Sep 2022 07:38:13 +0200 Subject: [PATCH 184/184] chore: SOF-1133 Now contains new values for Gallery D shelf --- shelf-layouts/Shortcuts and adlib scroll.json | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/shelf-layouts/Shortcuts and adlib scroll.json b/shelf-layouts/Shortcuts and adlib scroll.json index c013c683c..c70961fb9 100755 --- a/shelf-layouts/Shortcuts and adlib scroll.json +++ b/shelf-layouts/Shortcuts and adlib scroll.json @@ -14,7 +14,7 @@ "default": false, "x": 1, "y": 7, - "width": 58, + "width": 64.5, "height": 5, "overflowHorizontally": true, "showAsTimeline": true, @@ -53,10 +53,10 @@ "rundownBaseline": false, "default": false, "url": "http://10.201.76.12:8005/keyboardmap", - "x": 1, - "y": 21, - "width": 76, - "height": -1, + "x": 1.2, + "y": 18, + "width": 54.3, + "height": 18.5, "scale": 0.79 }, { @@ -70,8 +70,8 @@ "default": false, "x": -1, "y": 0, - "width": 21, - "height": -1, + "width": 15.7, + "height": 15.5, "includeClearInRundownBaseline": false, "assignHotKeys": false, "hide": false, @@ -83,7 +83,8 @@ ], "buttonWidthScale": 1.7, "buttonHeightScale": 1.7, - "toggleOnSingleClick": true + "toggleOnSingleClick": true, + "scale": 0.6 }, { "_id": "QZ6xdWdFmm5Mu7ZKJ", @@ -119,7 +120,7 @@ "sourceLayerIds": [ "studio0_dve" ], - "width": 58, + "width": 64.5, "height": 5, "buttonWidthScale": 1.5, "buttonHeightScale": 1.5, @@ -145,7 +146,7 @@ "buttonWidthScale": 1.5, "buttonHeightScale": 1.5, "y": 0, - "width": 58, + "width": 64.5, "height": 5, "showAsTimeline": true, "includeClearInRundownBaseline": true, @@ -159,4 +160,4 @@ "startingHeight": 50, "openByDefault": true, "regionId": "shelf_layouts" -} \ No newline at end of file +}