@@ -245,6 +245,11 @@ function firstDefined(...vals) {
245
245
246
246
const addPart = async ( lang , filename , left , top , opacity , scale , toBoxHole , dashoffset ) => {
247
247
let f ;
248
+ if ( parts [ filename ] ) {
249
+ // treat second place as attmpt to bump an index
250
+ parts [ filename ] . index = Object . values ( parts ) . reduce ( ( a , p ) => Math . max ( a , p . index ) , 0 ) + 1 ;
251
+ return ;
252
+ }
248
253
249
254
const readFname = ( fn ) => {
250
255
const filePath = `${ proc_args . basedir } /src/${ fn } .svg` ;
@@ -301,7 +306,7 @@ const addPart = async (lang, filename, left, top, opacity, scale, toBoxHole, das
301
306
top : + firstDefined ( eval ( top ) , 0 ) ,
302
307
left : + firstDefined ( eval ( left ) , 0 ) ,
303
308
opacity : + firstDefined ( eval ( opacity ) , 1 ) ,
304
- index : Object . values ( parts ) . length ,
309
+ index : Object . values ( parts ) . reduce ( ( a , p ) => Math . max ( a , p . index ) , 0 ) + 1 ,
305
310
scale : + firstDefined ( eval ( scale ) , 1.0 ) ,
306
311
rotate : + firstDefined ( 0 , 0 ) ,
307
312
dashoffset : + firstDefined ( eval ( dashoffset ) , 0 ) ,
@@ -376,8 +381,8 @@ const schedule_eval = (name, ms, ...rest) => {
376
381
return parts [ part ] . content ;
377
382
}
378
383
const set = ( part , value ) => {
379
- parts [ part ] . content = eval ( value ) ;
380
- global [ part + '_value' ] = eval ( value )
384
+ parts [ part ] . content = value ;
385
+ global [ part + '_value' ] = value ;
381
386
}
382
387
eval ( code )
383
388
} ,
@@ -421,8 +426,8 @@ if (! script) {
421
426
throw "Please specify .smte file e.g. -i demo.smte"
422
427
}
423
428
424
- const htmlHashed = { } ;
425
- const reuseFrames = { } ;
429
+ const frameAbsIndexByHTMLHash = { } ;
430
+ const reuseAbsFrameIndexForAbsFrameIndex = { } ;
426
431
427
432
const runGeneration = async ( lang ) => {
428
433
initVariables ( ) ;
@@ -437,22 +442,25 @@ const runGeneration = async (lang) => {
437
442
}
438
443
439
444
const doFrame = async ( ) => {
440
- const html = genHtml ( parts ) ;
441
- const hash = crypto . createHash ( 'sha1' ) . update ( html ) . digest ( 'base64' ) ;
445
+
442
446
if ( cntr < skipFrames || ( globalLastFrame && cntr > globalLastFrame ) ) {
443
447
cntr += 1 ;
444
448
return ;
445
449
}
446
450
totalFramesCount += 1 ;
447
- if ( ! htmlHashed [ hash ] ) {
448
- htmlHashed [ hash ] = cntr ;
451
+
452
+ const html = genHtml ( parts ) ;
453
+ const hash = crypto . createHash ( 'sha1' ) . update ( html ) . digest ( 'base64' ) ;
454
+
455
+ if ( ! frameAbsIndexByHTMLHash [ hash ] ) {
456
+ frameAbsIndexByHTMLHash [ hash ] = cntr ;
449
457
await fs . writeFile ( `${ FRAMES_DIR } /_index${ ( '' + cntr ) . padStart ( MAX_FILENAME_DIGS , '0' ) } .html` , html , function ( err ) {
450
- if ( err ) {
451
- return console . log ( err ) ;
458
+ if ( err ) {
459
+ return console . log ( err ) ;
452
460
}
453
461
} ) ;
454
462
} else {
455
- reuseFrames [ cntr ] = htmlHashed [ hash ] ;
463
+ reuseAbsFrameIndexForAbsFrameIndex [ cntr ] = frameAbsIndexByHTMLHash [ hash ] ;
456
464
}
457
465
458
466
cntr += 1 ;
@@ -667,16 +675,25 @@ const runGeneration = async (lang) => {
667
675
668
676
669
677
log ( '✅ [2/4] HTML generation done' )
670
- log ( `🕗 Total duration: ${ ( globalFramesCounter / FPS ) . toFixed ( 1 ) } s FPS: ${ FPS } ` )
678
+ log ( `🕗 Total duration: ${ ( globalFramesCounter / FPS ) . toFixed ( 1 ) } s 🎞️ FPS: ${ FPS } ` )
671
679
672
680
const THREADS = + proc_args . threads ;
673
681
let totalGenCntr = 0 ;
674
682
675
683
async function genScreenshots ( index ) {
684
+ const absoluteIndex = index + skipFrames ;
676
685
await new Promise ( ( resolve ) => {
677
- if ( ! reuseFrames [ index ] ) {
686
+ if ( ! reuseAbsFrameIndexForAbsFrameIndex [ absoluteIndex ] ) {
678
687
679
- const proc = spawn ( 'node' , [ path . resolve ( __dirname , 'puWorker.js' ) , pageW , pageH , index , totalFramesCount , FRAMES_DIR , FORMAT , QUALITY , skipFrames || 0 ] , { shell : true } ) ;
688
+ const proc = spawn ( 'node' , [
689
+ path . resolve ( __dirname , 'puWorker.js' ) ,
690
+ pageW , pageH ,
691
+ absoluteIndex ,
692
+ totalFramesCount ,
693
+ FRAMES_DIR ,
694
+ FORMAT ,
695
+ QUALITY , skipFrames || 0
696
+ ] , { shell : true } ) ;
680
697
proc . stdout . on ( 'data' , ( data ) => {
681
698
// console.log(`NodeOUT: ${data}`);
682
699
} ) ;
@@ -688,21 +705,23 @@ const runGeneration = async (lang) => {
688
705
log ( `Frames gen: ${ ( totalGenCntr * 100.0 / totalFramesCount ) . toFixed ( 2 ) } %` , '\033[F' ) ;
689
706
if ( code !== 0 ) {
690
707
log ( '🔴 node failed' )
708
+ process . exit ( - 1 )
691
709
}
692
710
resolve ( ) ;
693
711
} ) ;
694
712
} else {
695
713
totalGenCntr += 1 ;
696
714
resolve ( ) ;
697
715
}
698
- } )
716
+ } ) ;
699
717
}
700
718
701
719
async function copyReusedScreenshots ( index ) {
702
- if ( reuseFrames [ index ] ) {
703
- const reuseIndex = reuseFrames [ index ] ;
704
- const srcFile = `${ FRAMES_DIR } /${ ( '' + ( reuseIndex - skipFrames ) ) . padStart ( MAX_FILENAME_DIGS , '0' ) } .${ FORMAT } ` ;
705
- const dstFile = `${ FRAMES_DIR } /${ ( '' + ( index - skipFrames ) ) . padStart ( MAX_FILENAME_DIGS , '0' ) } .${ FORMAT } ` ;
720
+ const absoluteIndex = index + skipFrames ;
721
+ if ( reuseAbsFrameIndexForAbsFrameIndex [ absoluteIndex ] ) {
722
+ const reuseAbsIndex = reuseAbsFrameIndexForAbsFrameIndex [ absoluteIndex ] ;
723
+ const srcFile = `${ FRAMES_DIR } /${ ( '' + ( reuseAbsIndex - skipFrames ) ) . padStart ( MAX_FILENAME_DIGS , '0' ) } .${ FORMAT } ` ;
724
+ const dstFile = `${ FRAMES_DIR } /${ ( '' + ( index ) ) . padStart ( MAX_FILENAME_DIGS , '0' ) } .${ FORMAT } ` ;
706
725
fsExtra . copyFile ( srcFile , dstFile , ( err ) => {
707
726
if ( err ) {
708
727
log ( `🔴 failed to copy frame ${ srcFile } to ${ dstFile } ` , )
@@ -720,7 +739,9 @@ const runGeneration = async (lang) => {
720
739
721
740
const indexes = Array . from ( Array ( totalFramesCount ) . keys ( ) ) ;
722
741
723
- await Promise . all ( arrayChunks ( indexes , Math . round ( ( indexes . length ) / THREADS ) ) . map ( async ( indexesChunk ) => await genScreenshotsForChunk ( indexesChunk ) ) )
742
+ await Promise . all (
743
+ arrayChunks ( indexes , Math . round ( ( indexes . length ) / THREADS ) ) . map ( async ( indexesChunk ) => await genScreenshotsForChunk ( indexesChunk ) )
744
+ )
724
745
725
746
// another run to copy all duplicate files
726
747
indexes . forEach ( copyReusedScreenshots ) ;
0 commit comments