@xiboplayer/renderer 0.7.3 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/src/renderer-lite.js +8 -10
- package/src/renderer-lite.test.js +51 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xiboplayer/renderer",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"description": "RendererLite - Fast, efficient XLF layout rendering engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"pdfjs-dist": "^4.10.38",
|
|
15
|
-
"@xiboplayer/
|
|
16
|
-
"@xiboplayer/
|
|
17
|
-
"@xiboplayer/
|
|
15
|
+
"@xiboplayer/cache": "0.7.5",
|
|
16
|
+
"@xiboplayer/schedule": "0.7.5",
|
|
17
|
+
"@xiboplayer/utils": "0.7.5"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"jsdom": "^25.0.1",
|
package/src/renderer-lite.js
CHANGED
|
@@ -1517,11 +1517,10 @@ export class RendererLite {
|
|
|
1517
1517
|
el.play().catch(() => {});
|
|
1518
1518
|
};
|
|
1519
1519
|
el.addEventListener('seeked', playAfterSeek);
|
|
1520
|
-
//
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
}
|
|
1520
|
+
// Always call play() — for preloaded-then-paused videos, seeked may not
|
|
1521
|
+
// fire (currentTime already 0) and readyState may be < 2 (not buffered yet).
|
|
1522
|
+
// play() handles both cases: if not ready, it queues; if ready, it plays.
|
|
1523
|
+
el.play().catch(() => {});
|
|
1525
1524
|
}
|
|
1526
1525
|
|
|
1527
1526
|
/**
|
|
@@ -2300,10 +2299,9 @@ export class RendererLite {
|
|
|
2300
2299
|
}
|
|
2301
2300
|
|
|
2302
2301
|
// Detect video duration for dynamic layout timing (when useDuration=0)
|
|
2303
|
-
// Capture the layout ID at creation time —
|
|
2304
|
-
//
|
|
2305
|
-
|
|
2306
|
-
const createdForLayoutId = this.currentLayoutId;
|
|
2302
|
+
// Capture the layout ID at creation time — during preload, _preloadingLayoutId
|
|
2303
|
+
// is the target layout (currentLayoutId is still the playing layout).
|
|
2304
|
+
const createdForLayoutId = this._preloadingLayoutId || this.currentLayoutId;
|
|
2307
2305
|
const onLoadedMetadata = () => {
|
|
2308
2306
|
const videoDuration = video.duration;
|
|
2309
2307
|
this.log.info(`Video ${storedAs} duration detected: ${videoDuration}s`);
|
|
@@ -2464,7 +2462,7 @@ export class RendererLite {
|
|
|
2464
2462
|
audio.addEventListener('ended', onAudioEnded);
|
|
2465
2463
|
|
|
2466
2464
|
// Detect audio duration for dynamic layout timing (when useDuration=0)
|
|
2467
|
-
const audioCreatedForLayoutId = this.currentLayoutId;
|
|
2465
|
+
const audioCreatedForLayoutId = this._preloadingLayoutId || this.currentLayoutId;
|
|
2468
2466
|
const onAudioLoadedMetadata = () => {
|
|
2469
2467
|
const audioDuration = Math.floor(audio.duration);
|
|
2470
2468
|
this.log.info(`Audio ${storedAs} duration detected: ${audioDuration}s`);
|
|
@@ -2917,4 +2917,55 @@ describe('RendererLite', () => {
|
|
|
2917
2917
|
vi.useRealTimers();
|
|
2918
2918
|
});
|
|
2919
2919
|
});
|
|
2920
|
+
|
|
2921
|
+
// ── Video layout ID tracking during preload ──────────────────────
|
|
2922
|
+
// Regression test: createdForLayoutId must use _preloadingLayoutId
|
|
2923
|
+
// during preload, not currentLayoutId (which is the *playing* layout).
|
|
2924
|
+
// Without this, video duration updates for preloaded layouts are
|
|
2925
|
+
// rejected, causing layouts to play with wrong (10s) duration.
|
|
2926
|
+
|
|
2927
|
+
describe('Video createdForLayoutId during preload', () => {
|
|
2928
|
+
it('should capture _preloadingLayoutId for video elements created during preload', () => {
|
|
2929
|
+
renderer.currentLayoutId = 100; // currently playing
|
|
2930
|
+
renderer._preloadingLayoutId = 200; // preloading next
|
|
2931
|
+
|
|
2932
|
+
// The fix: _preloadingLayoutId || currentLayoutId should give 200
|
|
2933
|
+
const capturedId = renderer._preloadingLayoutId || renderer.currentLayoutId;
|
|
2934
|
+
expect(capturedId).toBe(200);
|
|
2935
|
+
});
|
|
2936
|
+
|
|
2937
|
+
it('should fall back to currentLayoutId when not preloading', () => {
|
|
2938
|
+
renderer.currentLayoutId = 100;
|
|
2939
|
+
renderer._preloadingLayoutId = null;
|
|
2940
|
+
|
|
2941
|
+
const capturedId = renderer._preloadingLayoutId || renderer.currentLayoutId;
|
|
2942
|
+
expect(capturedId).toBe(100);
|
|
2943
|
+
});
|
|
2944
|
+
|
|
2945
|
+
it('should allow duration update when preloaded layout becomes current', () => {
|
|
2946
|
+
// Simulate: video created during preload of layout 200
|
|
2947
|
+
renderer._preloadingLayoutId = 200;
|
|
2948
|
+
const createdForLayoutId = renderer._preloadingLayoutId || renderer.currentLayoutId;
|
|
2949
|
+
|
|
2950
|
+
// Now layout 200 swaps in
|
|
2951
|
+
renderer.currentLayoutId = 200;
|
|
2952
|
+
renderer._preloadingLayoutId = null;
|
|
2953
|
+
|
|
2954
|
+
// Duration update check should pass
|
|
2955
|
+
expect(renderer.currentLayoutId === createdForLayoutId).toBe(true);
|
|
2956
|
+
});
|
|
2957
|
+
|
|
2958
|
+
it('should reject duration update when a different layout is current', () => {
|
|
2959
|
+
// Video created during preload of layout 200
|
|
2960
|
+
renderer._preloadingLayoutId = 200;
|
|
2961
|
+
const createdForLayoutId = renderer._preloadingLayoutId || renderer.currentLayoutId;
|
|
2962
|
+
|
|
2963
|
+
// But layout 300 swaps in instead (e.g., schedule changed)
|
|
2964
|
+
renderer.currentLayoutId = 300;
|
|
2965
|
+
renderer._preloadingLayoutId = null;
|
|
2966
|
+
|
|
2967
|
+
// Duration update should be rejected — wrong layout
|
|
2968
|
+
expect(renderer.currentLayoutId === createdForLayoutId).toBe(false);
|
|
2969
|
+
});
|
|
2970
|
+
});
|
|
2920
2971
|
});
|