@editframe/elements 0.18.22-beta.0 → 0.18.26-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/elements/EFMedia/AssetMediaEngine.d.ts +2 -1
- package/dist/elements/EFMedia/AssetMediaEngine.js +3 -0
- package/dist/elements/EFMedia/BaseMediaEngine.d.ts +9 -0
- package/dist/elements/EFMedia/BaseMediaEngine.js +31 -0
- package/dist/elements/EFMedia/JitMediaEngine.d.ts +1 -0
- package/dist/elements/EFMedia/JitMediaEngine.js +12 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +11 -5
- package/dist/elements/EFMedia/shared/BufferUtils.d.ts +19 -18
- package/dist/elements/EFMedia/shared/BufferUtils.js +24 -44
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.browsertest.d.ts +8 -0
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +5 -5
- package/dist/elements/EFMedia/videoTasks/ScrubInputCache.d.ts +25 -0
- package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js +42 -0
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.d.ts +8 -0
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js +70 -0
- package/dist/elements/EFMedia/videoTasks/{makeVideoInitSegmentFetchTask.d.ts → makeScrubVideoInitSegmentFetchTask.d.ts} +1 -1
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.js +21 -0
- package/dist/elements/EFMedia/videoTasks/{makeVideoInputTask.d.ts → makeScrubVideoInputTask.d.ts} +1 -1
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.js +27 -0
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.d.ts +6 -0
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.js +52 -0
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.d.ts +4 -0
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.js +23 -0
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.d.ts +4 -0
- package/dist/elements/EFMedia/videoTasks/{makeVideoSegmentIdTask.js → makeScrubVideoSegmentIdTask.js} +9 -4
- package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.d.ts +6 -0
- package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js +112 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +11 -5
- package/dist/elements/EFMedia.d.ts +0 -10
- package/dist/elements/EFMedia.js +1 -17
- package/dist/elements/EFVideo.d.ts +11 -9
- package/dist/elements/EFVideo.js +31 -23
- package/dist/gui/EFConfiguration.d.ts +1 -0
- package/dist/gui/EFConfiguration.js +5 -0
- package/dist/gui/EFFilmstrip.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/transcoding/types/index.d.ts +11 -0
- package/package.json +2 -2
- package/src/elements/EFCaptions.ts +1 -1
- package/src/elements/EFImage.ts +1 -1
- package/src/elements/EFMedia/AssetMediaEngine.ts +6 -0
- package/src/elements/EFMedia/BaseMediaEngine.ts +60 -0
- package/src/elements/EFMedia/JitMediaEngine.ts +18 -0
- package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.browsertest.ts +185 -59
- package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.ts +19 -6
- package/src/elements/EFMedia/shared/BufferUtils.ts +71 -85
- package/src/elements/EFMedia/tasks/makeMediaEngineTask.browsertest.ts +151 -112
- package/src/elements/EFMedia/tasks/makeMediaEngineTask.ts +12 -5
- package/src/elements/EFMedia/videoTasks/ScrubInputCache.ts +61 -0
- package/src/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.ts +113 -0
- package/src/elements/EFMedia/videoTasks/{makeVideoInitSegmentFetchTask.ts → makeScrubVideoInitSegmentFetchTask.ts} +15 -3
- package/src/elements/EFMedia/videoTasks/{makeVideoInputTask.ts → makeScrubVideoInputTask.ts} +11 -10
- package/src/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.ts +118 -0
- package/src/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.ts +44 -0
- package/src/elements/EFMedia/videoTasks/{makeVideoSegmentIdTask.ts → makeScrubVideoSegmentIdTask.ts} +14 -6
- package/src/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.ts +258 -0
- package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.ts +19 -5
- package/src/elements/EFMedia.browsertest.ts +74 -11
- package/src/elements/EFMedia.ts +1 -23
- package/src/elements/EFVideo.browsertest.ts +204 -80
- package/src/elements/EFVideo.ts +38 -26
- package/src/elements/TargetController.browsertest.ts +1 -1
- package/src/gui/EFConfiguration.ts +4 -1
- package/src/gui/EFFilmstrip.ts +4 -4
- package/src/gui/EFFocusOverlay.ts +1 -1
- package/src/gui/EFPreview.ts +3 -4
- package/src/gui/EFScrubber.ts +1 -1
- package/src/gui/EFTimeDisplay.ts +1 -1
- package/src/gui/EFToggleLoop.ts +1 -1
- package/src/gui/EFTogglePlay.ts +1 -1
- package/src/gui/EFWorkbench.ts +1 -1
- package/src/transcoding/types/index.ts +16 -0
- package/test/__cache__/GET__api_v1_transcode_scrub_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__6ff5127ebeda578a679474347fbd6137/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_scrub_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__6ff5127ebeda578a679474347fbd6137/metadata.json +16 -0
- package/test/__cache__/GET__api_v1_transcode_scrub_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__f6d4793fc9ff854ee9a738917fb64a53/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_scrub_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__f6d4793fc9ff854ee9a738917fb64a53/metadata.json +16 -0
- package/test/cache-integration-verification.browsertest.ts +84 -0
- package/types.json +1 -1
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.test.d.ts +0 -1
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.browsertest.d.ts +0 -9
- package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.browsertest.d.ts +0 -9
- package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.js +0 -16
- package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.browsertest.d.ts +0 -9
- package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.js +0 -27
- package/dist/elements/EFMedia/videoTasks/makeVideoSeekTask.d.ts +0 -7
- package/dist/elements/EFMedia/videoTasks/makeVideoSeekTask.js +0 -34
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.browsertest.d.ts +0 -9
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.d.ts +0 -4
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.js +0 -28
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.browsertest.d.ts +0 -9
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.d.ts +0 -4
- package/src/elements/EFMedia/tasks/makeMediaEngineTask.test.ts +0 -233
- package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.browsertest.ts +0 -555
- package/src/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.browsertest.ts +0 -59
- package/src/elements/EFMedia/videoTasks/makeVideoInputTask.browsertest.ts +0 -55
- package/src/elements/EFMedia/videoTasks/makeVideoSeekTask.ts +0 -65
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.browsertest.ts +0 -57
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.ts +0 -43
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.browsertest.ts +0 -56
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { Task } from "@lit/task";
|
|
2
|
-
|
|
3
|
-
import type { VideoSample } from "mediabunny";
|
|
4
|
-
import { IgnorableError } from "../../EFMedia";
|
|
5
|
-
import type { EFVideo } from "../../EFVideo";
|
|
6
|
-
import type { BufferedSeekingInput } from "../BufferedSeekingInput";
|
|
7
|
-
|
|
8
|
-
type VideoSeekTask = Task<
|
|
9
|
-
readonly [number, BufferedSeekingInput | undefined],
|
|
10
|
-
VideoSample | undefined
|
|
11
|
-
>;
|
|
12
|
-
export const makeVideoSeekTask = (host: EFVideo): VideoSeekTask => {
|
|
13
|
-
return new Task(host, {
|
|
14
|
-
args: () => [host.desiredSeekTimeMs, host.videoInputTask.value] as const,
|
|
15
|
-
onError: (error) => {
|
|
16
|
-
if (error instanceof IgnorableError) {
|
|
17
|
-
console.info("videoSeekTask aborted");
|
|
18
|
-
}
|
|
19
|
-
console.error("videoSeekTask error", error);
|
|
20
|
-
},
|
|
21
|
-
onComplete: (_value) => {},
|
|
22
|
-
task: async (
|
|
23
|
-
[targetSeekTimeMs],
|
|
24
|
-
{ signal },
|
|
25
|
-
): Promise<VideoSample | undefined> => {
|
|
26
|
-
await host.mediaEngineTask.taskComplete;
|
|
27
|
-
signal.throwIfAborted(); // Abort if a new seek started
|
|
28
|
-
await host.videoSegmentIdTask.taskComplete;
|
|
29
|
-
signal.throwIfAborted(); // Abort if a new seek started
|
|
30
|
-
await host.videoSegmentFetchTask.taskComplete;
|
|
31
|
-
signal.throwIfAborted(); // Abort if a new seek started
|
|
32
|
-
await host.videoInitSegmentFetchTask.taskComplete;
|
|
33
|
-
signal.throwIfAborted(); // Abort if a new seek started
|
|
34
|
-
|
|
35
|
-
const videoInput = await host.videoInputTask.taskComplete;
|
|
36
|
-
signal.throwIfAborted(); // Abort if a new seek started
|
|
37
|
-
if (!videoInput) {
|
|
38
|
-
throw new Error("Video input is not available");
|
|
39
|
-
}
|
|
40
|
-
const videoTrack = await videoInput.getFirstVideoTrack();
|
|
41
|
-
if (!videoTrack) {
|
|
42
|
-
throw new Error("Video track is not available");
|
|
43
|
-
}
|
|
44
|
-
signal.throwIfAborted(); // Abort if a new seek started
|
|
45
|
-
|
|
46
|
-
const sample = (await videoInput.seek(
|
|
47
|
-
videoTrack.id,
|
|
48
|
-
targetSeekTimeMs, // Use the captured value, not host.desiredSeekTimeMs
|
|
49
|
-
)) as unknown as VideoSample | undefined;
|
|
50
|
-
|
|
51
|
-
signal.throwIfAborted(); // Abort if a new seek started
|
|
52
|
-
// If seek returned undefined, it was aborted - don't throw
|
|
53
|
-
if (sample === undefined && signal.aborted) {
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// If we got undefined but weren't aborted, that's an actual error
|
|
58
|
-
if (sample === undefined) {
|
|
59
|
-
throw new Error("Video seek failed to find sample");
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return sample;
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
};
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { TaskStatus } from "@lit/task";
|
|
2
|
-
import { customElement } from "lit/decorators.js";
|
|
3
|
-
import { afterEach, beforeEach, describe, vi } from "vitest";
|
|
4
|
-
import { test as baseTest } from "../../../../test/useMSW.js";
|
|
5
|
-
import { EFVideo } from "../../EFVideo";
|
|
6
|
-
import { makeVideoSegmentFetchTask } from "./makeVideoSegmentFetchTask";
|
|
7
|
-
|
|
8
|
-
@customElement("test-media-video-segment-fetch")
|
|
9
|
-
class TestMediaVideoSegmentFetch extends EFVideo {}
|
|
10
|
-
|
|
11
|
-
declare global {
|
|
12
|
-
interface HTMLElementTagNameMap {
|
|
13
|
-
"test-media-video-segment-fetch": TestMediaVideoSegmentFetch;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const test = baseTest.extend<{
|
|
18
|
-
element: TestMediaVideoSegmentFetch;
|
|
19
|
-
}>({
|
|
20
|
-
element: async ({}, use) => {
|
|
21
|
-
const element = document.createElement("test-media-video-segment-fetch");
|
|
22
|
-
await use(element);
|
|
23
|
-
element.remove();
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
describe("makeVideoSegmentFetchTask", () => {
|
|
28
|
-
beforeEach(() => {
|
|
29
|
-
// MSW setup is now handled by test fixtures
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
afterEach(() => {
|
|
33
|
-
const elements = document.querySelectorAll(
|
|
34
|
-
"test-media-video-segment-fetch",
|
|
35
|
-
);
|
|
36
|
-
for (const element of elements) {
|
|
37
|
-
element.remove();
|
|
38
|
-
}
|
|
39
|
-
vi.restoreAllMocks();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test("creates task with correct initial state", ({ element, expect }) => {
|
|
43
|
-
const task = makeVideoSegmentFetchTask(element);
|
|
44
|
-
|
|
45
|
-
expect(task).toBeDefined();
|
|
46
|
-
expect(task.status).toBe(TaskStatus.INITIAL);
|
|
47
|
-
expect(task.value).toBeUndefined();
|
|
48
|
-
expect(task.error).toBeUndefined();
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test("task integrates with element properties", ({ element, expect }) => {
|
|
52
|
-
const task = makeVideoSegmentFetchTask(element);
|
|
53
|
-
|
|
54
|
-
expect(task).toBeDefined();
|
|
55
|
-
expect(task.status).toBe(TaskStatus.INITIAL);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { Task } from "@lit/task";
|
|
2
|
-
import type { MediaEngine } from "../../../transcoding/types";
|
|
3
|
-
import type { EFVideo } from "../../EFVideo";
|
|
4
|
-
import { getLatestMediaEngine } from "../tasks/makeMediaEngineTask";
|
|
5
|
-
|
|
6
|
-
export const makeVideoSegmentFetchTask = (
|
|
7
|
-
host: EFVideo,
|
|
8
|
-
): Task<
|
|
9
|
-
readonly [MediaEngine | undefined, number | undefined],
|
|
10
|
-
ArrayBuffer
|
|
11
|
-
> => {
|
|
12
|
-
return new Task(host, {
|
|
13
|
-
args: () =>
|
|
14
|
-
[host.mediaEngineTask.value, host.videoSegmentIdTask.value] as const,
|
|
15
|
-
onError: (error) => {
|
|
16
|
-
console.error("videoSegmentFetchTask error", error);
|
|
17
|
-
},
|
|
18
|
-
onComplete: (_value) => {},
|
|
19
|
-
task: async (_, { signal }) => {
|
|
20
|
-
const mediaEngine = await getLatestMediaEngine(host, signal);
|
|
21
|
-
const segmentId = await host.videoSegmentIdTask.taskComplete;
|
|
22
|
-
if (segmentId === undefined) {
|
|
23
|
-
// Provide more context in the error to help with debugging
|
|
24
|
-
const rendition = mediaEngine.videoRendition;
|
|
25
|
-
const debugInfo = {
|
|
26
|
-
hasRendition: !!rendition,
|
|
27
|
-
segmentDurationMs: rendition?.segmentDurationMs,
|
|
28
|
-
segmentDurationsMs: rendition?.segmentDurationsMs?.length || 0,
|
|
29
|
-
desiredSeekTimeMs: host.desiredSeekTimeMs,
|
|
30
|
-
intrinsicDurationMs: host.intrinsicDurationMs,
|
|
31
|
-
};
|
|
32
|
-
throw new Error(
|
|
33
|
-
`Segment ID is not available for video. Debug info: ${JSON.stringify(debugInfo)}`,
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
return mediaEngine.fetchMediaSegment(
|
|
37
|
-
segmentId,
|
|
38
|
-
mediaEngine.getVideoRendition(),
|
|
39
|
-
signal,
|
|
40
|
-
);
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
};
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { TaskStatus } from "@lit/task";
|
|
2
|
-
import { customElement } from "lit/decorators.js";
|
|
3
|
-
import { afterEach, beforeEach, describe, vi } from "vitest";
|
|
4
|
-
import { test as baseTest } from "../../../../test/useMSW.js";
|
|
5
|
-
import { EFVideo } from "../../EFVideo";
|
|
6
|
-
import { makeVideoSegmentIdTask } from "./makeVideoSegmentIdTask";
|
|
7
|
-
|
|
8
|
-
@customElement("test-media-video-segment")
|
|
9
|
-
class TestMediaVideoSegment extends EFVideo {}
|
|
10
|
-
|
|
11
|
-
declare global {
|
|
12
|
-
interface HTMLElementTagNameMap {
|
|
13
|
-
"test-media-video-segment": TestMediaVideoSegment;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const test = baseTest.extend<{
|
|
18
|
-
element: TestMediaVideoSegment;
|
|
19
|
-
}>({
|
|
20
|
-
element: async ({}, use) => {
|
|
21
|
-
const element = document.createElement("test-media-video-segment");
|
|
22
|
-
await use(element);
|
|
23
|
-
element.remove();
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
describe("makeVideoSegmentIdTask", () => {
|
|
28
|
-
beforeEach(() => {
|
|
29
|
-
// MSW setup is now handled by test fixtures
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
afterEach(() => {
|
|
33
|
-
const elements = document.querySelectorAll("test-media-video-segment");
|
|
34
|
-
for (const element of elements) {
|
|
35
|
-
element.remove();
|
|
36
|
-
}
|
|
37
|
-
vi.restoreAllMocks();
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test("creates task with correct initial state", ({ element, expect }) => {
|
|
41
|
-
const task = makeVideoSegmentIdTask(element);
|
|
42
|
-
|
|
43
|
-
expect(task).toBeDefined();
|
|
44
|
-
expect(task.status).toBe(TaskStatus.INITIAL);
|
|
45
|
-
expect(task.value).toBeUndefined();
|
|
46
|
-
expect(task.error).toBeUndefined();
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test("task integrates with element properties", ({ element, expect }) => {
|
|
50
|
-
element.desiredSeekTimeMs = 7500;
|
|
51
|
-
|
|
52
|
-
const task = makeVideoSegmentIdTask(element);
|
|
53
|
-
expect(task).toBeDefined();
|
|
54
|
-
expect(task.status).toBe(TaskStatus.INITIAL);
|
|
55
|
-
});
|
|
56
|
-
});
|