Skip to content

Commit 58ca72d

Browse files
authored
Merge pull request Sofie-Automation#1738 from bbc/justandras/fix/missing-package-names
fix: always expose packageName when known
2 parents 451d2cc + 064098d commit 58ca72d

2 files changed

Lines changed: 304 additions & 3 deletions

File tree

meteor/server/publications/pieceContentStatusUI/__tests__/checkPieceContentStatus.test.ts

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ import { RundownId } from '@sofie-automation/corelib/dist/dataModel/Ids'
4242
const mockMediaObjectsCollection = MongoMock.getInnerMockCollection<MediaObject>(MediaObjects)
4343

4444
describe('lib/mediaObjects', () => {
45+
beforeEach(async () => {
46+
await mockMediaObjectsCollection.removeAsync({})
47+
})
48+
4549
describe('buildFormatString', () => {
4650
it('deepscan tff, stream unknown', () => {
4751
const format1 = buildFormatString(
@@ -244,6 +248,303 @@ describe('lib/mediaObjects', () => {
244248
expect(mediaId3).toEqual(undefined)
245249
})
246250

251+
test('packageName: media object status uses mediaId or falls back to fileName', async () => {
252+
const mockStudioSettings: IStudioSettings = {
253+
supportedMediaFormats: '1920x1080i5000, 1280x720, i5000, i5000tff',
254+
mediaPreviewsUrl: '',
255+
supportedAudioStreams: '4',
256+
frameRate: 25,
257+
minimumTakeSpan: DEFAULT_MINIMUM_TAKE_SPAN,
258+
allowHold: false,
259+
allowPieceDirectPlay: false,
260+
enableBuckets: false,
261+
enableEvaluationForm: false,
262+
}
263+
264+
const mockDefaultStudio = defaultStudio(protectString('studio0'))
265+
const mockStudio: Complete<PieceContentStatusStudio> = {
266+
_id: mockDefaultStudio._id,
267+
settings: mockStudioSettings,
268+
packageContainerSettings: {
269+
previewContainerIds: ['previews0'],
270+
thumbnailContainerIds: ['thumbnails0'],
271+
},
272+
routeSets: applyAndValidateOverrides(mockDefaultStudio.routeSetsWithOverrides).obj,
273+
mappings: applyAndValidateOverrides(mockDefaultStudio.mappingsWithOverrides).obj,
274+
packageContainers: applyAndValidateOverrides(mockDefaultStudio.packageContainersWithOverrides).obj,
275+
}
276+
277+
await mockMediaObjectsCollection.insertAsync(
278+
literal<MediaObject>({
279+
_id: protectString(''),
280+
_attachments: {},
281+
_rev: '',
282+
cinf: '',
283+
collectionId: 'studio0',
284+
mediaId: 'TEST_FILE',
285+
mediaPath: '',
286+
mediaSize: 0,
287+
mediaTime: 0,
288+
mediainfo: literal<MediaInfo>({
289+
name: 'test_file',
290+
field_order: PackageInfo.FieldOrder.TFF,
291+
streams: [
292+
literal<MediaStream>({
293+
width: 1920,
294+
height: 1080,
295+
codec: {
296+
type: MediaStreamType.Video,
297+
time_base: '1/50',
298+
},
299+
}),
300+
literal<MediaStream>({
301+
channels: 1,
302+
codec: {
303+
type: MediaStreamType.Audio,
304+
time_base: '1/25',
305+
},
306+
}),
307+
literal<MediaStream>({
308+
channels: 1,
309+
codec: {
310+
type: MediaStreamType.Audio,
311+
time_base: '1/25',
312+
},
313+
}),
314+
literal<MediaStream>({
315+
channels: 1,
316+
codec: {
317+
type: MediaStreamType.Audio,
318+
time_base: '1/25',
319+
},
320+
}),
321+
literal<MediaStream>({
322+
channels: 1,
323+
codec: {
324+
type: MediaStreamType.Audio,
325+
time_base: '1/25',
326+
},
327+
}),
328+
],
329+
}),
330+
objId: '',
331+
previewPath: '',
332+
previewSize: 0,
333+
previewTime: 0,
334+
studioId: protectString('studio0'),
335+
thumbSize: 0,
336+
thumbTime: 0,
337+
tinf: '',
338+
})
339+
)
340+
341+
await mockMediaObjectsCollection.insertAsync(
342+
literal<MediaObject>({
343+
_id: protectString(''),
344+
_attachments: {},
345+
_rev: '',
346+
cinf: '',
347+
collectionId: 'studio0',
348+
mediaId: 'TEST_FILE_2',
349+
mediaPath: '',
350+
mediaSize: 0,
351+
mediaTime: 0,
352+
mediainfo: literal<MediaInfo>({
353+
name: 'test_file_2',
354+
field_order: PackageInfo.FieldOrder.Progressive,
355+
streams: [
356+
literal<MediaStream>({
357+
width: 1920,
358+
height: 1080,
359+
codec: {
360+
type: MediaStreamType.Video,
361+
time_base: '1/50',
362+
},
363+
}),
364+
literal<MediaStream>({
365+
channels: 1,
366+
codec: {
367+
type: MediaStreamType.Audio,
368+
time_base: '1/25',
369+
},
370+
}),
371+
literal<MediaStream>({
372+
channels: 1,
373+
codec: {
374+
type: MediaStreamType.Audio,
375+
time_base: '1/25',
376+
},
377+
}),
378+
literal<MediaStream>({
379+
channels: 1,
380+
codec: {
381+
type: MediaStreamType.Audio,
382+
time_base: '1/25',
383+
},
384+
}),
385+
literal<MediaStream>({
386+
channels: 1,
387+
codec: {
388+
type: MediaStreamType.Audio,
389+
time_base: '1/25',
390+
},
391+
}),
392+
],
393+
}),
394+
objId: '',
395+
previewPath: '',
396+
previewSize: 0,
397+
previewTime: 0,
398+
studioId: protectString('studio0'),
399+
thumbSize: 0,
400+
thumbTime: 0,
401+
tinf: '',
402+
})
403+
)
404+
405+
const sourcelayer = literal<ISourceLayer>({
406+
_id: '',
407+
_rank: 0,
408+
name: '',
409+
type: SourceLayerType.LIVE_SPEAK,
410+
})
411+
412+
const messageFactory = new PieceContentStatusMessageFactory(undefined)
413+
const mockOwnerId = protectString<RundownId>('rundown0')
414+
415+
const [status1] = await checkPieceContentStatusAndDependencies(
416+
mockStudio,
417+
mockOwnerId,
418+
messageFactory,
419+
literal<PieceGeneric>({
420+
_id: protectString('piece1'),
421+
name: 'Test_file',
422+
prerollDuration: 0,
423+
externalId: '',
424+
lifespan: PieceLifespan.WithinPart,
425+
privateData: {},
426+
outputLayerId: '',
427+
sourceLayerId: '',
428+
content: literal<VTContent>({
429+
fileName: 'test_file',
430+
path: '',
431+
}),
432+
timelineObjectsString: EmptyPieceTimelineObjectsBlob,
433+
}),
434+
sourcelayer
435+
)
436+
expect(status1.packageName).toEqual('TEST_FILE')
437+
438+
const [status2] = await checkPieceContentStatusAndDependencies(
439+
mockStudio,
440+
mockOwnerId,
441+
messageFactory,
442+
literal<PieceGeneric>({
443+
_id: protectString('piece2'),
444+
name: 'Test_file_2',
445+
prerollDuration: 0,
446+
externalId: '',
447+
lifespan: PieceLifespan.WithinPart,
448+
privateData: {},
449+
outputLayerId: '',
450+
sourceLayerId: '',
451+
content: literal<VTContent>({
452+
fileName: 'test_file_2',
453+
path: '',
454+
}),
455+
timelineObjectsString: EmptyPieceTimelineObjectsBlob,
456+
}),
457+
sourcelayer
458+
)
459+
expect(status2.packageName).toEqual('TEST_FILE_2')
460+
461+
const [status3] = await checkPieceContentStatusAndDependencies(
462+
mockStudio,
463+
mockOwnerId,
464+
messageFactory,
465+
literal<PieceGeneric>({
466+
_id: protectString('piece3'),
467+
name: 'Test_file_3',
468+
prerollDuration: 0,
469+
externalId: '',
470+
lifespan: PieceLifespan.WithinPart,
471+
privateData: {},
472+
outputLayerId: '',
473+
sourceLayerId: '',
474+
content: literal<VTContent>({
475+
fileName: 'test_file_3',
476+
path: '',
477+
}),
478+
timelineObjectsString: EmptyPieceTimelineObjectsBlob,
479+
}),
480+
sourcelayer
481+
)
482+
expect(status3.packageName).toEqual('TEST_FILE_3')
483+
})
484+
485+
test('packageName: exposed even when ignoreMediaObjectStatus is set', async () => {
486+
const mockStudioSettings: IStudioSettings = {
487+
supportedMediaFormats: '1920x1080i5000, 1280x720, i5000, i5000tff',
488+
mediaPreviewsUrl: '',
489+
supportedAudioStreams: '4',
490+
frameRate: 25,
491+
minimumTakeSpan: DEFAULT_MINIMUM_TAKE_SPAN,
492+
allowHold: false,
493+
allowPieceDirectPlay: false,
494+
enableBuckets: false,
495+
enableEvaluationForm: false,
496+
}
497+
498+
const mockDefaultStudio = defaultStudio(protectString('studio0'))
499+
const mockStudio: Complete<PieceContentStatusStudio> = {
500+
_id: mockDefaultStudio._id,
501+
settings: mockStudioSettings,
502+
packageContainerSettings: {
503+
previewContainerIds: ['previews0'],
504+
thumbnailContainerIds: ['thumbnails0'],
505+
},
506+
routeSets: applyAndValidateOverrides(mockDefaultStudio.routeSetsWithOverrides).obj,
507+
mappings: applyAndValidateOverrides(mockDefaultStudio.mappingsWithOverrides).obj,
508+
packageContainers: applyAndValidateOverrides(mockDefaultStudio.packageContainersWithOverrides).obj,
509+
}
510+
511+
const ignorePiece = literal<PieceGeneric>({
512+
_id: protectString('pieceIgnore'),
513+
name: 'Ignore media status',
514+
prerollDuration: 0,
515+
externalId: '',
516+
lifespan: PieceLifespan.WithinPart,
517+
privateData: {},
518+
outputLayerId: '',
519+
sourceLayerId: '',
520+
content: {
521+
fileName: 'ignored_file',
522+
path: '',
523+
ignoreMediaObjectStatus: true,
524+
} as any,
525+
timelineObjectsString: EmptyPieceTimelineObjectsBlob,
526+
})
527+
528+
const messageFactory = new PieceContentStatusMessageFactory(undefined)
529+
const mockOwnerId = protectString<RundownId>('rundown0')
530+
531+
const [ignoredStatus] = await checkPieceContentStatusAndDependencies(
532+
mockStudio,
533+
mockOwnerId,
534+
messageFactory,
535+
ignorePiece,
536+
literal<ISourceLayer>({
537+
_id: '',
538+
_rank: 0,
539+
name: '',
540+
type: SourceLayerType.VT,
541+
})
542+
)
543+
544+
expect(ignoredStatus.status).toEqual(PieceStatusCode.UNKNOWN)
545+
expect(ignoredStatus.packageName).toEqual('IGNORED_FILE')
546+
})
547+
247548
test('checkPieceContentStatus', async () => {
248549
const mockStudioSettings: IStudioSettings = {
249550
supportedMediaFormats: '1920x1080i5000, 1280x720, i5000, i5000tff',

meteor/server/publications/pieceContentStatusUI/checkPieceContentStatus.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ export async function checkPieceContentStatusAndDependencies(
254254
thumbnailUrl: '/dev/fakeThumbnail.png',
255255
previewUrl: '/dev/fakePreview.mp4',
256256

257-
packageName: null,
257+
packageName: '/dev/fakePreview.mp4',
258258
contentDuration: 30 * 1000,
259259
},
260260
pieceDependencies,
@@ -343,7 +343,7 @@ export async function checkPieceContentStatusAndDependencies(
343343
thumbnailUrl: undefined,
344344
previewUrl: undefined,
345345

346-
packageName: null,
346+
packageName: getMediaObjectMediaId(piece, sourceLayer) || null,
347347
contentDuration: undefined,
348348
},
349349
pieceDependencies,
@@ -566,7 +566,7 @@ async function checkPieceContentMediaObjectStatus(
566566
? getAssetUrlFromContentMetaData(metadata, 'preview', studio.settings.mediaPreviewsUrl)
567567
: undefined,
568568

569-
packageName: metadata?.mediaId || null,
569+
packageName: metadata?.mediaId || fileName || null,
570570

571571
contentDuration,
572572
}

0 commit comments

Comments
 (0)