@@ -18,13 +18,14 @@ import {
1818} from 'dive-common/constants' ;
1919import {
2020 JsonMeta , Settings , JsonMetaCurrentVersion , DesktopMetadata , DesktopJobUpdater ,
21- ConvertMedia , RunTraining , ExportDatasetArgs , MediaImportPayload ,
21+ ConvertMedia , RunTraining , ExportDatasetArgs , MediaImportPayload , CheckMediaResults ,
2222} from 'platform/desktop/constants' ;
2323import {
2424 cleanString , filterByGlob , makeid , strNumericCompare ,
2525} from 'platform/desktop/sharedUtils' ;
2626import { Attribute , Attributes } from 'vue-media-annotator/use/useAttributes' ;
2727import processTrackAttributes from './attributeProcessor' ;
28+ import { upgrade } from './migrations' ;
2829import { getMultiCamUrls , transcodeMultiCam } from './multiCamUtils' ;
2930
3031const ProjectsFolderName = 'DIVE_Projects' ;
@@ -148,13 +149,7 @@ async function loadJsonMetadata(metaAbsPath: string): Promise<JsonMeta> {
148149 throw new Error ( `Unable to parse ${ metaAbsPath } : ${ err } ` ) ;
149150 }
150151 /* check if this file meets the current schema version */
151- if ( 'version' in metaJson ) {
152- const { version } = metaJson ;
153- if ( version !== JsonMetaCurrentVersion ) {
154- // TODO: schema migration for older schema versions
155- throw new Error ( 'outdated meta schema version found, migration not implemented' ) ;
156- }
157- }
152+ upgrade ( metaJson ) ;
158153 return metaJson as JsonMeta ;
159154}
160155
@@ -406,7 +401,7 @@ async function _saveAsJson(absPath: string, data: unknown) {
406401}
407402
408403async function saveMetadata ( settings : Settings , datasetId : string ,
409- args : DatasetMetaMutable & { attributes ?: Record < string , Attribute > } ) {
404+ args : DatasetMetaMutable & { attributes ?: Record < string , Attribute > } ) {
410405 const projectDirInfo = await getValidatedProjectDir ( settings , datasetId ) ;
411406 const release = await _acquireLock ( projectDirInfo . basePath , projectDirInfo . metaFileAbsPath , 'meta' ) ;
412407 const existing = await loadJsonMetadata ( projectDirInfo . metaFileAbsPath ) ;
@@ -460,7 +455,7 @@ async function processOtherAnnotationFiles(
460455 datasetId : string ,
461456 absPaths : string [ ] ,
462457) : Promise < { fps ?: number ; processedFiles : string [ ] ; attributes ?: Attributes } > {
463- const fps = undefined ;
458+ let fps : number | undefined ;
464459 const processedFiles = [ ] ; // which files were processed to generate the detections
465460 let attributes : Attributes = { } ;
466461
@@ -474,8 +469,9 @@ async function processOtherAnnotationFiles(
474469 // Attempt to process the file
475470 try {
476471 // eslint-disable-next-line no-await-in-loop
477- const tracks = await viameSerializers . parseFile ( path ) ;
478- const processed = processTrackAttributes ( tracks ) ;
472+ const data = await viameSerializers . parseFile ( path ) ;
473+ const processed = processTrackAttributes ( data . tracks ) ;
474+ fps = fps || data . fps ;
479475 attributes = processed . attributes ;
480476 // eslint-disable-next-line no-await-in-loop
481477 await _saveSerialized ( settings , datasetId , processed . data , true ) ;
@@ -547,7 +543,7 @@ async function _initializeProjectDir(settings: Settings, jsonMeta: JsonMeta): Pr
547543async function beginMediaImport (
548544 settings : Settings ,
549545 path : string ,
550- checkMedia : ( settings : Settings , path : string ) => Promise < boolean > ,
546+ checkMedia : ( settings : Settings , path : string ) => Promise < CheckMediaResults > ,
551547) : Promise < MediaImportPayload > {
552548 let datasetType : DatasetType ;
553549
@@ -568,11 +564,13 @@ async function beginMediaImport(
568564 const dsName = npath . parse ( path ) . name ;
569565 const dsId = `${ cleanString ( dsName ) . substr ( 0 , 20 ) } _${ makeid ( 10 ) } ` ;
570566
567+ const _defaultFps = datasetType === 'video' ? 5 : 1 ;
571568 const jsonMeta : JsonMeta = {
572569 version : JsonMetaCurrentVersion ,
573570 type : datasetType ,
574571 id : dsId ,
575- fps : 5 , // TODO
572+ fps : _defaultFps , // adjusted below
573+ originalFps : _defaultFps , // adjusted below
576574 originalBasePath : path ,
577575 originalVideoFile : '' ,
578576 createdAt : ( new Date ( ) ) . toString ( ) ,
@@ -599,10 +597,16 @@ async function beginMediaImport(
599597 if ( websafeImageTypes . includes ( mimetype ) || otherImageTypes . includes ( mimetype ) ) {
600598 throw new Error ( 'User chose image file for video import option' ) ;
601599 } else if ( websafeVideoTypes . includes ( mimetype ) || otherVideoTypes . includes ( mimetype ) ) {
602- const webSafeVideo = await checkMedia ( settings , path ) ;
603- if ( ! webSafeVideo || otherVideoTypes . includes ( mimetype ) ) {
600+ const checkMediaResult = await checkMedia ( settings , path ) ;
601+ if ( ! checkMediaResult . websafe || otherVideoTypes . includes ( mimetype ) ) {
604602 mediaConvertList . push ( path ) ;
605603 }
604+ const newAnnotationFps = Math . floor (
605+ // Prevent FPS smaller than 1
606+ Math . max ( 1 , Math . min ( jsonMeta . fps , checkMediaResult . originalFps ) ) ,
607+ ) ;
608+ jsonMeta . originalFps = checkMediaResult . originalFps ;
609+ jsonMeta . fps = newAnnotationFps ;
606610 } else {
607611 throw new Error ( `unsupported MIME type for video ${ mimetype } ` ) ;
608612 }
@@ -652,6 +656,12 @@ async function finalizeMediaImport(
652656 mediaConvertList = found . mediaConvertList ;
653657 }
654658
659+ // Verify that the user didn't choose an FPS value higher than originalFPS
660+ // This shouldn't be possible in the UI, but we should still prevent it here.
661+ jsonMeta . fps = Math . floor (
662+ Math . max ( 1 , Math . min ( jsonMeta . fps , jsonMeta . originalFps ) ) ,
663+ ) ;
664+
655665 //Now we will kick off any conversions that are necessary
656666 let jobBase = null ;
657667 if ( mediaConvertList . length ) {
0 commit comments