@editframe/elements 0.20.4-beta.0 → 0.23.6-beta.0
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/dist/DelayedLoadingState.js +0 -27
- package/dist/EF_FRAMEGEN.d.ts +5 -3
- package/dist/EF_FRAMEGEN.js +49 -11
- package/dist/_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js +7 -0
- package/dist/attachContextRoot.d.ts +1 -0
- package/dist/attachContextRoot.js +9 -0
- package/dist/elements/ContextProxiesController.d.ts +1 -2
- package/dist/elements/EFAudio.js +5 -9
- package/dist/elements/EFCaptions.d.ts +1 -3
- package/dist/elements/EFCaptions.js +112 -129
- package/dist/elements/EFImage.js +6 -7
- package/dist/elements/EFMedia/AssetIdMediaEngine.js +2 -5
- package/dist/elements/EFMedia/AssetMediaEngine.js +36 -33
- package/dist/elements/EFMedia/BaseMediaEngine.js +57 -73
- package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +1 -1
- package/dist/elements/EFMedia/BufferedSeekingInput.js +134 -78
- package/dist/elements/EFMedia/JitMediaEngine.js +9 -19
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +7 -13
- package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +2 -3
- package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js +1 -1
- package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js +6 -5
- package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +1 -3
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js +1 -1
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js +1 -1
- package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +1 -1
- package/dist/elements/EFMedia/shared/AudioSpanUtils.js +9 -25
- package/dist/elements/EFMedia/shared/BufferUtils.js +2 -17
- package/dist/elements/EFMedia/shared/GlobalInputCache.js +0 -24
- package/dist/elements/EFMedia/shared/PrecisionUtils.js +0 -21
- package/dist/elements/EFMedia/shared/ThumbnailExtractor.js +0 -17
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +1 -10
- package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.d.ts +29 -0
- package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js +32 -0
- package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js +1 -15
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js +1 -7
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.js +8 -5
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.js +12 -13
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.js +1 -1
- package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js +134 -70
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +11 -18
- package/dist/elements/EFMedia.d.ts +19 -0
- package/dist/elements/EFMedia.js +44 -25
- package/dist/elements/EFSourceMixin.js +5 -7
- package/dist/elements/EFSurface.js +6 -9
- package/dist/elements/EFTemporal.browsertest.d.ts +11 -0
- package/dist/elements/EFTemporal.d.ts +10 -0
- package/dist/elements/EFTemporal.js +100 -41
- package/dist/elements/EFThumbnailStrip.js +23 -73
- package/dist/elements/EFTimegroup.browsertest.d.ts +3 -3
- package/dist/elements/EFTimegroup.d.ts +35 -14
- package/dist/elements/EFTimegroup.js +138 -181
- package/dist/elements/EFVideo.d.ts +16 -2
- package/dist/elements/EFVideo.js +156 -108
- package/dist/elements/EFWaveform.js +23 -40
- package/dist/elements/SampleBuffer.js +3 -7
- package/dist/elements/TargetController.js +5 -5
- package/dist/elements/durationConverter.js +4 -4
- package/dist/elements/renderTemporalAudio.d.ts +10 -0
- package/dist/elements/renderTemporalAudio.js +35 -0
- package/dist/elements/updateAnimations.js +19 -43
- package/dist/gui/ContextMixin.d.ts +5 -5
- package/dist/gui/ContextMixin.js +167 -162
- package/dist/gui/Controllable.browsertest.d.ts +0 -0
- package/dist/gui/Controllable.d.ts +15 -0
- package/dist/gui/Controllable.js +9 -0
- package/dist/gui/EFConfiguration.js +7 -7
- package/dist/gui/EFControls.browsertest.d.ts +11 -0
- package/dist/gui/EFControls.d.ts +18 -4
- package/dist/gui/EFControls.js +70 -28
- package/dist/gui/EFDial.browsertest.d.ts +0 -0
- package/dist/gui/EFDial.d.ts +18 -0
- package/dist/gui/EFDial.js +141 -0
- package/dist/gui/EFFilmstrip.browsertest.d.ts +11 -0
- package/dist/gui/EFFilmstrip.d.ts +12 -2
- package/dist/gui/EFFilmstrip.js +214 -129
- package/dist/gui/EFFitScale.js +5 -8
- package/dist/gui/EFFocusOverlay.js +4 -4
- package/dist/gui/EFPause.browsertest.d.ts +0 -0
- package/dist/gui/EFPause.d.ts +23 -0
- package/dist/gui/EFPause.js +59 -0
- package/dist/gui/EFPlay.browsertest.d.ts +0 -0
- package/dist/gui/EFPlay.d.ts +23 -0
- package/dist/gui/EFPlay.js +59 -0
- package/dist/gui/EFPreview.d.ts +4 -0
- package/dist/gui/EFPreview.js +18 -9
- package/dist/gui/EFResizableBox.browsertest.d.ts +0 -0
- package/dist/gui/EFResizableBox.d.ts +34 -0
- package/dist/gui/EFResizableBox.js +547 -0
- package/dist/gui/EFScrubber.d.ts +9 -3
- package/dist/gui/EFScrubber.js +13 -13
- package/dist/gui/EFTimeDisplay.d.ts +7 -1
- package/dist/gui/EFTimeDisplay.js +8 -8
- package/dist/gui/EFToggleLoop.d.ts +9 -3
- package/dist/gui/EFToggleLoop.js +7 -5
- package/dist/gui/EFTogglePlay.d.ts +12 -4
- package/dist/gui/EFTogglePlay.js +26 -21
- package/dist/gui/EFWorkbench.js +5 -5
- package/dist/gui/PlaybackController.d.ts +67 -0
- package/dist/gui/PlaybackController.js +310 -0
- package/dist/gui/TWMixin.js +1 -1
- package/dist/gui/TWMixin2.js +1 -1
- package/dist/gui/TargetOrContextMixin.d.ts +10 -0
- package/dist/gui/TargetOrContextMixin.js +98 -0
- package/dist/gui/efContext.d.ts +2 -2
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -1
- package/dist/otel/BridgeSpanExporter.d.ts +13 -0
- package/dist/otel/BridgeSpanExporter.js +87 -0
- package/dist/otel/setupBrowserTracing.d.ts +12 -0
- package/dist/otel/setupBrowserTracing.js +32 -0
- package/dist/otel/tracingHelpers.d.ts +34 -0
- package/dist/otel/tracingHelpers.js +112 -0
- package/dist/style.css +1 -1
- package/dist/transcoding/cache/RequestDeduplicator.js +0 -21
- package/dist/transcoding/cache/URLTokenDeduplicator.js +1 -21
- package/dist/transcoding/utils/UrlGenerator.js +2 -19
- package/dist/utils/LRUCache.js +6 -53
- package/package.json +13 -5
- package/src/elements/ContextProxiesController.ts +10 -10
- package/src/elements/EFAudio.ts +1 -0
- package/src/elements/EFCaptions.browsertest.ts +128 -56
- package/src/elements/EFCaptions.ts +60 -34
- package/src/elements/EFImage.browsertest.ts +1 -2
- package/src/elements/EFMedia/AssetMediaEngine.ts +65 -37
- package/src/elements/EFMedia/BaseMediaEngine.ts +110 -52
- package/src/elements/EFMedia/BufferedSeekingInput.ts +218 -101
- package/src/elements/EFMedia/JitMediaEngine.browsertest.ts +3 -0
- package/src/elements/EFMedia/audioTasks/makeAudioInputTask.ts +7 -3
- package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.chunkboundary.regression.browsertest.ts +1 -1
- package/src/elements/EFMedia/videoTasks/MainVideoInputCache.ts +76 -0
- package/src/elements/EFMedia/videoTasks/makeScrubVideoInputTask.ts +16 -10
- package/src/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.ts +7 -1
- package/src/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.ts +222 -116
- package/src/elements/EFMedia.browsertest.ts +8 -15
- package/src/elements/EFMedia.ts +54 -8
- package/src/elements/EFSurface.browsertest.ts +2 -6
- package/src/elements/EFSurface.ts +1 -0
- package/src/elements/EFTemporal.browsertest.ts +58 -1
- package/src/elements/EFTemporal.ts +140 -4
- package/src/elements/EFThumbnailStrip.browsertest.ts +2 -8
- package/src/elements/EFThumbnailStrip.ts +1 -0
- package/src/elements/EFTimegroup.browsertest.ts +16 -15
- package/src/elements/EFTimegroup.ts +281 -275
- package/src/elements/EFVideo.browsertest.ts +162 -74
- package/src/elements/EFVideo.ts +229 -101
- package/src/elements/FetchContext.browsertest.ts +7 -2
- package/src/elements/TargetController.browsertest.ts +1 -0
- package/src/elements/TargetController.ts +1 -0
- package/src/elements/renderTemporalAudio.ts +108 -0
- package/src/elements/updateAnimations.browsertest.ts +181 -6
- package/src/elements/updateAnimations.ts +6 -6
- package/src/gui/ContextMixin.browsertest.ts +274 -27
- package/src/gui/ContextMixin.ts +230 -175
- package/src/gui/Controllable.browsertest.ts +258 -0
- package/src/gui/Controllable.ts +41 -0
- package/src/gui/EFControls.browsertest.ts +294 -80
- package/src/gui/EFControls.ts +139 -28
- package/src/gui/EFDial.browsertest.ts +84 -0
- package/src/gui/EFDial.ts +172 -0
- package/src/gui/EFFilmstrip.browsertest.ts +712 -0
- package/src/gui/EFFilmstrip.ts +213 -23
- package/src/gui/EFPause.browsertest.ts +202 -0
- package/src/gui/EFPause.ts +73 -0
- package/src/gui/EFPlay.browsertest.ts +202 -0
- package/src/gui/EFPlay.ts +73 -0
- package/src/gui/EFPreview.ts +20 -5
- package/src/gui/EFResizableBox.browsertest.ts +79 -0
- package/src/gui/EFResizableBox.ts +898 -0
- package/src/gui/EFScrubber.ts +7 -5
- package/src/gui/EFTimeDisplay.browsertest.ts +19 -19
- package/src/gui/EFTimeDisplay.ts +3 -1
- package/src/gui/EFToggleLoop.ts +6 -5
- package/src/gui/EFTogglePlay.ts +30 -23
- package/src/gui/PlaybackController.ts +522 -0
- package/src/gui/TWMixin.css +3 -0
- package/src/gui/TargetOrContextMixin.ts +185 -0
- package/src/gui/efContext.ts +2 -2
- package/src/otel/BridgeSpanExporter.ts +150 -0
- package/src/otel/setupBrowserTracing.ts +73 -0
- package/src/otel/tracingHelpers.ts +251 -0
- package/test/cache-integration-verification.browsertest.ts +1 -1
- package/types.json +1 -1
- package/dist/elements/ContextProxiesController.js +0 -69
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { html, render } from "lit";
|
|
2
|
-
import { beforeAll, beforeEach, describe, vi } from "vitest";
|
|
2
|
+
import { beforeAll, beforeEach, describe, expect, vi } from "vitest";
|
|
3
3
|
|
|
4
4
|
import { test as baseTest } from "../../test/useMSW.js";
|
|
5
5
|
import type { EFVideo } from "./EFVideo.js";
|
|
@@ -8,7 +8,6 @@ import "../gui/EFWorkbench.js";
|
|
|
8
8
|
import "../gui/EFPreview.js";
|
|
9
9
|
import "./EFTimegroup.js";
|
|
10
10
|
|
|
11
|
-
import { TaskStatus } from "@lit/task";
|
|
12
11
|
import type { EFTimegroup } from "./EFTimegroup.js";
|
|
13
12
|
|
|
14
13
|
// Helper to wait for task completion but ignore abort errors
|
|
@@ -80,7 +79,7 @@ const test = baseTest.extend<{
|
|
|
80
79
|
const container = document.createElement("div");
|
|
81
80
|
render(
|
|
82
81
|
html`
|
|
83
|
-
<ef-configuration api-host="http://localhost:63315">
|
|
82
|
+
<ef-configuration api-host="http://localhost:63315" signing-url="">
|
|
84
83
|
<ef-preview>
|
|
85
84
|
<ef-timegroup mode="sequence" id="barsNtoneTimegroup"
|
|
86
85
|
class="relative h-[500px] w-[1000px] overflow-hidden bg-slate-500">
|
|
@@ -92,10 +91,9 @@ const test = baseTest.extend<{
|
|
|
92
91
|
container,
|
|
93
92
|
);
|
|
94
93
|
document.body.appendChild(container);
|
|
95
|
-
const configuration = container.querySelector("ef-configuration") as any;
|
|
96
|
-
configuration.signingURL = ""; // Disable URL signing for tests
|
|
97
94
|
const timegroup = container.querySelector("ef-timegroup") as EFTimegroup;
|
|
98
95
|
await timegroup.updateComplete;
|
|
96
|
+
await timegroup.waitForMediaDurations();
|
|
99
97
|
await use(timegroup);
|
|
100
98
|
// Cleanup: remove from DOM
|
|
101
99
|
container.remove();
|
|
@@ -104,7 +102,7 @@ const test = baseTest.extend<{
|
|
|
104
102
|
const container = document.createElement("div");
|
|
105
103
|
render(
|
|
106
104
|
html`
|
|
107
|
-
<ef-configuration api-host="http://localhost:63315">
|
|
105
|
+
<ef-configuration api-host="http://localhost:63315" signing-url="">
|
|
108
106
|
<ef-preview>
|
|
109
107
|
<ef-timegroup mode="sequence"
|
|
110
108
|
class="relative h-[500px] w-[1000px] overflow-hidden bg-slate-500">
|
|
@@ -124,10 +122,9 @@ const test = baseTest.extend<{
|
|
|
124
122
|
container,
|
|
125
123
|
);
|
|
126
124
|
document.body.appendChild(container);
|
|
127
|
-
const configuration = container.querySelector("ef-configuration") as any;
|
|
128
|
-
configuration.signingURL = ""; // Disable URL signing for tests
|
|
129
125
|
const timegroup = container.querySelector("ef-timegroup") as EFTimegroup;
|
|
130
126
|
await timegroup.updateComplete;
|
|
127
|
+
await timegroup.waitForMediaDurations();
|
|
131
128
|
await use(timegroup);
|
|
132
129
|
// Cleanup: remove from DOM
|
|
133
130
|
container.remove();
|
|
@@ -238,7 +235,7 @@ describe("EFVideo", () => {
|
|
|
238
235
|
|
|
239
236
|
// Should not throw when video asset is missing
|
|
240
237
|
expect(() => {
|
|
241
|
-
video.
|
|
238
|
+
video.paint(0);
|
|
242
239
|
}).not.toThrow();
|
|
243
240
|
});
|
|
244
241
|
});
|
|
@@ -267,7 +264,7 @@ describe("EFVideo", () => {
|
|
|
267
264
|
close: vi.fn(),
|
|
268
265
|
} as unknown as VideoFrame;
|
|
269
266
|
|
|
270
|
-
// Simulate frame painting (this would normally happen through
|
|
267
|
+
// Simulate frame painting (this would normally happen through paint method)
|
|
271
268
|
const ctx = canvas.getContext("2d");
|
|
272
269
|
if (ctx && mockFrame.codedWidth && mockFrame.codedHeight) {
|
|
273
270
|
canvas.width = mockFrame.codedWidth;
|
|
@@ -355,20 +352,16 @@ describe("EFVideo", () => {
|
|
|
355
352
|
|
|
356
353
|
// Simulate the decoder being in use
|
|
357
354
|
if (decoderLockDescriptor) {
|
|
358
|
-
// We can
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
// All should complete without throwing
|
|
365
|
-
await expect(
|
|
366
|
-
Promise.allSettled([paintPromise1, paintPromise2, paintPromise3]),
|
|
367
|
-
).resolves.toBeDefined();
|
|
355
|
+
// We can test that multiple paint calls don't cause issues
|
|
356
|
+
expect(() => {
|
|
357
|
+
video.paint(0);
|
|
358
|
+
video.paint(0);
|
|
359
|
+
video.paint(0);
|
|
360
|
+
}).not.toThrow();
|
|
368
361
|
}
|
|
369
362
|
});
|
|
370
363
|
|
|
371
|
-
test("
|
|
364
|
+
test("paint handles missing canvas gracefully", ({ expect }) => {
|
|
372
365
|
const container = document.createElement("div");
|
|
373
366
|
render(html`<ef-video></ef-video>`, container);
|
|
374
367
|
document.body.appendChild(container);
|
|
@@ -379,23 +372,19 @@ describe("EFVideo", () => {
|
|
|
379
372
|
const canvas = video.canvasElement;
|
|
380
373
|
canvas?.remove();
|
|
381
374
|
|
|
382
|
-
// Paint
|
|
383
|
-
expect(() =>
|
|
384
|
-
video.paintTask.run();
|
|
385
|
-
}).not.toThrow();
|
|
375
|
+
// Paint should handle missing canvas
|
|
376
|
+
expect(() => video.paint(0)).not.toThrow();
|
|
386
377
|
});
|
|
387
378
|
|
|
388
|
-
test("handles paint
|
|
379
|
+
test("handles paint with no video asset", ({ expect }) => {
|
|
389
380
|
const container = document.createElement("div");
|
|
390
381
|
render(html`<ef-video></ef-video>`, container);
|
|
391
382
|
document.body.appendChild(container);
|
|
392
383
|
|
|
393
384
|
const video = container.querySelector("ef-video") as EFVideo;
|
|
394
385
|
|
|
395
|
-
// Paint
|
|
396
|
-
expect(() =>
|
|
397
|
-
video.paintTask.run();
|
|
398
|
-
}).not.toThrow();
|
|
386
|
+
// Paint should handle missing video asset gracefully
|
|
387
|
+
expect(() => video.paint(0)).not.toThrow();
|
|
399
388
|
});
|
|
400
389
|
});
|
|
401
390
|
|
|
@@ -445,12 +434,12 @@ describe("EFVideo", () => {
|
|
|
445
434
|
// Should handle invalid seek times gracefully
|
|
446
435
|
expect(() => {
|
|
447
436
|
video.desiredSeekTimeMs = -1000; // Invalid negative time
|
|
448
|
-
video.
|
|
437
|
+
video.paint(-1000);
|
|
449
438
|
}).not.toThrow();
|
|
450
439
|
|
|
451
440
|
expect(() => {
|
|
452
441
|
video.desiredSeekTimeMs = Number.POSITIVE_INFINITY;
|
|
453
|
-
video.
|
|
442
|
+
video.paint(Number.POSITIVE_INFINITY);
|
|
454
443
|
}).not.toThrow();
|
|
455
444
|
});
|
|
456
445
|
|
|
@@ -462,14 +451,14 @@ describe("EFVideo", () => {
|
|
|
462
451
|
const video = container.querySelector("ef-video") as EFVideo;
|
|
463
452
|
|
|
464
453
|
// Start some operations
|
|
465
|
-
video.
|
|
454
|
+
video.paint(0);
|
|
466
455
|
|
|
467
456
|
// Remove element
|
|
468
457
|
video.remove();
|
|
469
458
|
|
|
470
459
|
// Should not cause errors
|
|
471
460
|
expect(() => {
|
|
472
|
-
video.
|
|
461
|
+
video.paint(0);
|
|
473
462
|
}).not.toThrow();
|
|
474
463
|
});
|
|
475
464
|
|
|
@@ -491,7 +480,7 @@ describe("EFVideo", () => {
|
|
|
491
480
|
|
|
492
481
|
// Should handle context loss gracefully
|
|
493
482
|
expect(() => {
|
|
494
|
-
video.
|
|
483
|
+
video.paint(0);
|
|
495
484
|
}).not.toThrow();
|
|
496
485
|
|
|
497
486
|
// Restore original method
|
|
@@ -572,6 +561,54 @@ describe("EFVideo", () => {
|
|
|
572
561
|
// The video should have loaded successfully within the timegroup
|
|
573
562
|
expect(video.intrinsicDurationMs).toBeGreaterThan(0);
|
|
574
563
|
});
|
|
564
|
+
|
|
565
|
+
test("works as standalone root temporal in ef-preview", async ({
|
|
566
|
+
expect,
|
|
567
|
+
}) => {
|
|
568
|
+
const container = document.createElement("div");
|
|
569
|
+
render(
|
|
570
|
+
html`
|
|
571
|
+
<ef-configuration api-host="http://localhost:63315" signing-url="">
|
|
572
|
+
<ef-preview id="test-preview">
|
|
573
|
+
<ef-video src="bars-n-tone.mp4" mode="asset" id="standalone-video"></ef-video>
|
|
574
|
+
</ef-preview>
|
|
575
|
+
</ef-configuration>
|
|
576
|
+
`,
|
|
577
|
+
container,
|
|
578
|
+
);
|
|
579
|
+
document.body.appendChild(container);
|
|
580
|
+
|
|
581
|
+
const preview = container.querySelector("ef-preview") as any;
|
|
582
|
+
const video = container.querySelector("ef-video") as EFVideo;
|
|
583
|
+
|
|
584
|
+
await preview.updateComplete;
|
|
585
|
+
await video.updateComplete;
|
|
586
|
+
|
|
587
|
+
// Wait for media to be ready
|
|
588
|
+
await video.mediaEngineTask.taskComplete;
|
|
589
|
+
|
|
590
|
+
// Video should have loaded successfully
|
|
591
|
+
expect(video.intrinsicDurationMs).toBeGreaterThan(0);
|
|
592
|
+
|
|
593
|
+
// Preview should recognize the video as its root temporal
|
|
594
|
+
expect(preview.targetTemporal).toBe(video);
|
|
595
|
+
|
|
596
|
+
// Video should have a playback controller as a root element
|
|
597
|
+
expect(video.playbackController).toBeDefined();
|
|
598
|
+
|
|
599
|
+
// Preview should be able to control playback
|
|
600
|
+
expect(preview.playing).toBe(false);
|
|
601
|
+
|
|
602
|
+
// Seek the video through the preview
|
|
603
|
+
preview.currentTimeMs = 1000;
|
|
604
|
+
await video.frameTask.taskComplete;
|
|
605
|
+
|
|
606
|
+
// Video should have seeked
|
|
607
|
+
expect(video.ownCurrentTimeMs).toBeCloseTo(1000, 0);
|
|
608
|
+
|
|
609
|
+
// Cleanup
|
|
610
|
+
container.remove();
|
|
611
|
+
});
|
|
575
612
|
});
|
|
576
613
|
|
|
577
614
|
describe.skip("loading indicator", () => {
|
|
@@ -837,17 +874,13 @@ describe("EFVideo", () => {
|
|
|
837
874
|
barsNtoneTimegroup,
|
|
838
875
|
expect,
|
|
839
876
|
}) => {
|
|
840
|
-
barsNtoneTimegroup.
|
|
841
|
-
await barsNtoneTimegroup.seekTask.taskComplete;
|
|
877
|
+
await barsNtoneTimegroup.seek(8000);
|
|
842
878
|
expect(barsNtone.unifiedVideoSeekTask.value?.timestamp).toBeCloseTo(
|
|
843
879
|
8.066,
|
|
844
880
|
);
|
|
845
881
|
|
|
846
|
-
expect(barsNtoneTimegroup.seekTask.status).toBe(TaskStatus.COMPLETE);
|
|
847
882
|
// Then seek backward
|
|
848
|
-
barsNtoneTimegroup.
|
|
849
|
-
expect(barsNtoneTimegroup.seekTask.status).toBe(TaskStatus.PENDING);
|
|
850
|
-
await barsNtoneTimegroup.seekTask.taskComplete;
|
|
883
|
+
await barsNtoneTimegroup.seek(2000);
|
|
851
884
|
expect(barsNtone.unifiedVideoSeekTask.value?.timestamp).toBeCloseTo(
|
|
852
885
|
2.066,
|
|
853
886
|
);
|
|
@@ -1025,9 +1058,7 @@ describe("EFVideo", () => {
|
|
|
1025
1058
|
barsNtoneTimegroup,
|
|
1026
1059
|
expect,
|
|
1027
1060
|
}) => {
|
|
1028
|
-
|
|
1029
|
-
barsNtoneTimegroup.currentTimeMs = 7975;
|
|
1030
|
-
await barsNtoneTimegroup.seekTask.taskComplete;
|
|
1061
|
+
await barsNtoneTimegroup.seek(7975);
|
|
1031
1062
|
|
|
1032
1063
|
expect(barsNtone.unifiedVideoSeekTask.value?.timestamp).toBeCloseTo(
|
|
1033
1064
|
8.033,
|
|
@@ -1039,9 +1070,8 @@ describe("EFVideo", () => {
|
|
|
1039
1070
|
barsNtoneTimegroup,
|
|
1040
1071
|
expect,
|
|
1041
1072
|
}) => {
|
|
1042
|
-
await barsNtoneTimegroup.frameTask.taskComplete;
|
|
1043
|
-
barsNtoneTimegroup.currentTimeMs = 8041.667;
|
|
1044
1073
|
await barsNtoneTimegroup.seekTask.taskComplete;
|
|
1074
|
+
await barsNtoneTimegroup.seek(8041.667);
|
|
1045
1075
|
expect(barsNtone.unifiedVideoSeekTask.value?.timestamp).toBe(8.1);
|
|
1046
1076
|
});
|
|
1047
1077
|
|
|
@@ -1085,26 +1115,22 @@ describe("EFVideo", () => {
|
|
|
1085
1115
|
});
|
|
1086
1116
|
|
|
1087
1117
|
test("seeks to 1000ms", async ({ timegroup, headMoov480p, expect }) => {
|
|
1088
|
-
timegroup.
|
|
1089
|
-
await timegroup.seekTask.taskComplete;
|
|
1118
|
+
await timegroup.seek(1000);
|
|
1090
1119
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBe(1);
|
|
1091
1120
|
});
|
|
1092
1121
|
|
|
1093
1122
|
test("seeks to 3000ms", async ({ timegroup, headMoov480p, expect }) => {
|
|
1094
|
-
timegroup.
|
|
1095
|
-
await timegroup.seekTask.taskComplete;
|
|
1123
|
+
await timegroup.seek(3000);
|
|
1096
1124
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBe(3);
|
|
1097
1125
|
});
|
|
1098
1126
|
|
|
1099
1127
|
test("seeks to 5000ms", async ({ timegroup, headMoov480p, expect }) => {
|
|
1100
|
-
timegroup.
|
|
1101
|
-
await timegroup.seekTask.taskComplete;
|
|
1128
|
+
await timegroup.seek(5000);
|
|
1102
1129
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBe(5);
|
|
1103
1130
|
});
|
|
1104
1131
|
|
|
1105
1132
|
test("seeks to 7500ms", async ({ timegroup, headMoov480p, expect }) => {
|
|
1106
|
-
timegroup.
|
|
1107
|
-
await timegroup.seekTask.taskComplete;
|
|
1133
|
+
await timegroup.seek(7500);
|
|
1108
1134
|
|
|
1109
1135
|
// JIT transcoding returns actual video frame timestamps, not idealized segment boundaries
|
|
1110
1136
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBeCloseTo(
|
|
@@ -1114,8 +1140,7 @@ describe("EFVideo", () => {
|
|
|
1114
1140
|
});
|
|
1115
1141
|
|
|
1116
1142
|
test("seeks to 8500ms", async ({ timegroup, headMoov480p, expect }) => {
|
|
1117
|
-
timegroup.
|
|
1118
|
-
await timegroup.seekTask.taskComplete;
|
|
1143
|
+
await timegroup.seek(8500);
|
|
1119
1144
|
|
|
1120
1145
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBeCloseTo(
|
|
1121
1146
|
8.5,
|
|
@@ -1128,8 +1153,7 @@ describe("EFVideo", () => {
|
|
|
1128
1153
|
headMoov480p,
|
|
1129
1154
|
expect,
|
|
1130
1155
|
}) => {
|
|
1131
|
-
timegroup.
|
|
1132
|
-
await timegroup.seekTask.taskComplete;
|
|
1156
|
+
await timegroup.seek(9000);
|
|
1133
1157
|
|
|
1134
1158
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBe(9);
|
|
1135
1159
|
});
|
|
@@ -1139,12 +1163,10 @@ describe("EFVideo", () => {
|
|
|
1139
1163
|
headMoov480p,
|
|
1140
1164
|
expect,
|
|
1141
1165
|
}) => {
|
|
1142
|
-
timegroup.
|
|
1143
|
-
await expect(timegroup.seekTask.taskComplete).resolves.toBe(7);
|
|
1166
|
+
await timegroup.seek(7000);
|
|
1144
1167
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBe(7);
|
|
1145
1168
|
|
|
1146
|
-
timegroup.
|
|
1147
|
-
await expect(timegroup.seekTask.taskComplete).resolves.toBe(2);
|
|
1169
|
+
await timegroup.seek(2000);
|
|
1148
1170
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBe(2);
|
|
1149
1171
|
});
|
|
1150
1172
|
|
|
@@ -1157,8 +1179,7 @@ describe("EFVideo", () => {
|
|
|
1157
1179
|
const expectedTimestamps = [1, 3, 5, 2, 6, 0];
|
|
1158
1180
|
|
|
1159
1181
|
for (let i = 0; i < seekPoints.length; i++) {
|
|
1160
|
-
timegroup.
|
|
1161
|
-
await timegroup.seekTask.taskComplete;
|
|
1182
|
+
await timegroup.seek(seekPoints[i]!);
|
|
1162
1183
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBeCloseTo(
|
|
1163
1184
|
expectedTimestamps[i]!,
|
|
1164
1185
|
1,
|
|
@@ -1175,8 +1196,7 @@ describe("EFVideo", () => {
|
|
|
1175
1196
|
const expectedTimestamps = [1.234567, 3.456789, 5.678901];
|
|
1176
1197
|
|
|
1177
1198
|
for (let i = 0; i < fractionalTimes.length; i++) {
|
|
1178
|
-
timegroup.
|
|
1179
|
-
await timegroup.seekTask.taskComplete;
|
|
1199
|
+
await timegroup.seek(fractionalTimes[i]!);
|
|
1180
1200
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBeCloseTo(
|
|
1181
1201
|
expectedTimestamps[i]!,
|
|
1182
1202
|
1,
|
|
@@ -1189,22 +1209,19 @@ describe("EFVideo", () => {
|
|
|
1189
1209
|
headMoov480p,
|
|
1190
1210
|
expect,
|
|
1191
1211
|
}) => {
|
|
1192
|
-
timegroup.
|
|
1193
|
-
await timegroup.seekTask.taskComplete;
|
|
1212
|
+
await timegroup.seek(0);
|
|
1194
1213
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBeCloseTo(
|
|
1195
1214
|
0,
|
|
1196
1215
|
1,
|
|
1197
1216
|
);
|
|
1198
1217
|
|
|
1199
|
-
timegroup.
|
|
1200
|
-
await timegroup.seekTask.taskComplete;
|
|
1218
|
+
await timegroup.seek(1000);
|
|
1201
1219
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBeCloseTo(
|
|
1202
1220
|
1,
|
|
1203
1221
|
1,
|
|
1204
1222
|
);
|
|
1205
1223
|
|
|
1206
|
-
timegroup.
|
|
1207
|
-
await timegroup.seekTask.taskComplete;
|
|
1224
|
+
await timegroup.seek(4000);
|
|
1208
1225
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBeCloseTo(
|
|
1209
1226
|
4,
|
|
1210
1227
|
1,
|
|
@@ -1216,8 +1233,7 @@ describe("EFVideo", () => {
|
|
|
1216
1233
|
headMoov480p,
|
|
1217
1234
|
expect,
|
|
1218
1235
|
}) => {
|
|
1219
|
-
timegroup.
|
|
1220
|
-
await timegroup.seekTask.taskComplete;
|
|
1236
|
+
await timegroup.seek(1000);
|
|
1221
1237
|
expect(headMoov480p.unifiedVideoSeekTask.value?.timestamp).toBe(1);
|
|
1222
1238
|
|
|
1223
1239
|
// // Track frameTask executions using a spy on the run method
|
|
@@ -1391,4 +1407,76 @@ describe("EFVideo", () => {
|
|
|
1391
1407
|
expect(true).toBe(true);
|
|
1392
1408
|
});
|
|
1393
1409
|
});
|
|
1410
|
+
|
|
1411
|
+
describe("loop attribute", () => {
|
|
1412
|
+
test(
|
|
1413
|
+
"standalone ef-video respects loop attribute",
|
|
1414
|
+
{ timeout: 1000 },
|
|
1415
|
+
async () => {
|
|
1416
|
+
const container = document.createElement("div");
|
|
1417
|
+
render(
|
|
1418
|
+
html`
|
|
1419
|
+
<ef-video
|
|
1420
|
+
loop
|
|
1421
|
+
id="loop-video"
|
|
1422
|
+
src="bars-n-tone.mp4"
|
|
1423
|
+
sourceout="2s"
|
|
1424
|
+
></ef-video>
|
|
1425
|
+
`,
|
|
1426
|
+
container,
|
|
1427
|
+
);
|
|
1428
|
+
document.body.appendChild(container);
|
|
1429
|
+
|
|
1430
|
+
const video = container.querySelector("#loop-video") as EFVideo;
|
|
1431
|
+
await video.updateComplete;
|
|
1432
|
+
|
|
1433
|
+
expect(video.loop).toBe(true);
|
|
1434
|
+
expect(video.playbackController).toBeDefined();
|
|
1435
|
+
expect(video.playbackController?.loop).toBe(true);
|
|
1436
|
+
|
|
1437
|
+
container.remove();
|
|
1438
|
+
},
|
|
1439
|
+
);
|
|
1440
|
+
|
|
1441
|
+
test(
|
|
1442
|
+
"loop property is reactive after initialization",
|
|
1443
|
+
{ timeout: 1000 },
|
|
1444
|
+
async () => {
|
|
1445
|
+
const container = document.createElement("div");
|
|
1446
|
+
render(
|
|
1447
|
+
html`
|
|
1448
|
+
<ef-video
|
|
1449
|
+
id="reactive-loop-video"
|
|
1450
|
+
src="bars-n-tone.mp4"
|
|
1451
|
+
sourceout="2s"
|
|
1452
|
+
></ef-video>
|
|
1453
|
+
`,
|
|
1454
|
+
container,
|
|
1455
|
+
);
|
|
1456
|
+
document.body.appendChild(container);
|
|
1457
|
+
|
|
1458
|
+
const video = container.querySelector(
|
|
1459
|
+
"#reactive-loop-video",
|
|
1460
|
+
) as EFVideo;
|
|
1461
|
+
await video.updateComplete;
|
|
1462
|
+
|
|
1463
|
+
expect(video.loop).toBe(false);
|
|
1464
|
+
expect(video.playbackController?.loop).toBe(false);
|
|
1465
|
+
|
|
1466
|
+
video.loop = true;
|
|
1467
|
+
await video.updateComplete;
|
|
1468
|
+
|
|
1469
|
+
expect(video.loop).toBe(true);
|
|
1470
|
+
expect(video.playbackController?.loop).toBe(true);
|
|
1471
|
+
|
|
1472
|
+
video.loop = false;
|
|
1473
|
+
await video.updateComplete;
|
|
1474
|
+
|
|
1475
|
+
expect(video.loop).toBe(false);
|
|
1476
|
+
expect(video.playbackController?.loop).toBe(false);
|
|
1477
|
+
|
|
1478
|
+
container.remove();
|
|
1479
|
+
},
|
|
1480
|
+
);
|
|
1481
|
+
});
|
|
1394
1482
|
});
|