@editframe/elements 0.18.21-beta.0 → 0.18.22-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.
Files changed (34) hide show
  1. package/dist/elements/EFAudio.d.ts +1 -12
  2. package/dist/elements/EFAudio.js +3 -18
  3. package/dist/elements/EFMedia/AssetMediaEngine.d.ts +1 -1
  4. package/dist/elements/EFMedia/AssetMediaEngine.js +3 -3
  5. package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +15 -9
  6. package/dist/elements/EFMedia/BufferedSeekingInput.js +76 -78
  7. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +12 -10
  8. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +2 -18
  9. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +12 -10
  10. package/dist/elements/EFTimegroup.d.ts +4 -4
  11. package/dist/elements/EFTimegroup.js +52 -39
  12. package/dist/elements/EFVideo.d.ts +1 -32
  13. package/dist/elements/EFVideo.js +13 -51
  14. package/dist/elements/SampleBuffer.js +1 -1
  15. package/package.json +2 -2
  16. package/src/elements/EFAudio.browsertest.ts +0 -3
  17. package/src/elements/EFAudio.ts +3 -22
  18. package/src/elements/EFMedia/AssetMediaEngine.browsertest.ts +39 -1
  19. package/src/elements/EFMedia/AssetMediaEngine.ts +5 -4
  20. package/src/elements/EFMedia/BufferedSeekingInput.browsertest.ts +90 -185
  21. package/src/elements/EFMedia/BufferedSeekingInput.ts +119 -130
  22. package/src/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.ts +21 -21
  23. package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.chunkboundary.regression.browsertest.ts +10 -5
  24. package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.ts +33 -34
  25. package/src/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.ts +22 -20
  26. package/src/elements/EFMedia/videoTasks/makeVideoSeekTask.ts +0 -3
  27. package/src/elements/EFMedia.browsertest.ts +72 -60
  28. package/src/elements/EFTimegroup.browsertest.ts +9 -4
  29. package/src/elements/EFTimegroup.ts +79 -55
  30. package/src/elements/EFVideo.browsertest.ts +172 -160
  31. package/src/elements/EFVideo.ts +17 -73
  32. package/src/elements/SampleBuffer.ts +1 -2
  33. package/test/EFVideo.framegen.browsertest.ts +0 -54
  34. package/types.json +1 -1
@@ -2,11 +2,18 @@ import { test as baseTest, describe } from "vitest";
2
2
  import { BufferedSeekingInput, NoSample } from "./BufferedSeekingInput";
3
3
 
4
4
  const test = baseTest.extend<{
5
+ barsNtone: BufferedSeekingInput;
5
6
  fiveSampleBuffer: BufferedSeekingInput;
6
7
  inputAtStart: BufferedSeekingInput;
7
8
  inputAtMiddle: BufferedSeekingInput;
8
9
  segment2: BufferedSeekingInput;
9
10
  }>({
11
+ barsNtone: async ({}, use) => {
12
+ const response = await fetch("/bars-n-tone.mp4");
13
+ const arrayBuffer = await response.arrayBuffer();
14
+ const input = new BufferedSeekingInput(arrayBuffer);
15
+ await use(input);
16
+ },
10
17
  fiveSampleBuffer: async ({}, use) => {
11
18
  const response = await fetch("/jit-segments/segment-0ms-2s-low.mp4");
12
19
  const arrayBuffer = await response.arrayBuffer();
@@ -64,7 +71,7 @@ describe("BufferedSeekingInput", () => {
64
71
  test("seeks to frame at 0.04 seconds", async ({ expect, inputAtStart }) => {
65
72
  const sample = await inputAtStart.seek(1, 40);
66
73
  expect(sample).toBeDefined();
67
- expect(sample!.timestamp).toBe(0); // Updated: improved mediabunny processing changed frame timings
74
+ expect(sample!.timestamp).toBe(0.04);
68
75
  });
69
76
  });
70
77
 
@@ -75,10 +82,10 @@ describe("BufferedSeekingInput", () => {
75
82
  }) => {
76
83
  // Updated expectations based on improved mediabunny processing
77
84
  expect((await inputAtStart.seek(1, 0))!.timestamp).toBe(0);
78
- expect((await inputAtStart.seek(1, 40))!.timestamp).toBe(0); // Frame timing shifted due to improvements
79
- expect((await inputAtStart.seek(1, 80))!.timestamp).toBe(0.04);
80
- expect((await inputAtStart.seek(1, 120))!.timestamp).toBe(0.08);
81
- expect((await inputAtStart.seek(1, 160))!.timestamp).toBe(0.12);
85
+ expect((await inputAtStart.seek(1, 40))!.timestamp).toBe(0.04); // Frame timing shifted due to improvements
86
+ expect((await inputAtStart.seek(1, 80))!.timestamp).toBe(0.08);
87
+ expect((await inputAtStart.seek(1, 120))!.timestamp).toBe(0.12);
88
+ expect((await inputAtStart.seek(1, 160))!.timestamp).toBe(0.16);
82
89
  });
83
90
 
84
91
  test("seeks between samples returns previous sample", async ({
@@ -112,24 +119,27 @@ describe("BufferedSeekingInput", () => {
112
119
  });
113
120
 
114
121
  test("never returns future sample", async ({ expect, inputAtStart }) => {
115
- const testCases = [
116
- { seekTimeMs: 0, expectedTimestamp: 0 },
117
- { seekTimeMs: 10, expectedTimestamp: 0 },
118
- { seekTimeMs: 30, expectedTimestamp: 0 },
119
- { seekTimeMs: 40, expectedTimestamp: 0 }, // Updated: frame timing shifted due to mediabunny improvements
120
- { seekTimeMs: 50, expectedTimestamp: 0.04 }, // Updated: this seek now returns 0.04
121
- { seekTimeMs: 70, expectedTimestamp: 0.04 }, // Updated: this seek now returns 0.04
122
- { seekTimeMs: 80, expectedTimestamp: 0.04 }, // Updated: frame timing shifted
123
- { seekTimeMs: 90, expectedTimestamp: 0.08 }, // Updated: this seek now returns 0.08
124
- ];
125
-
126
- for (const { seekTimeMs, expectedTimestamp } of testCases) {
127
- const result = await inputAtStart.seek(1, seekTimeMs);
128
- expect(result!.timestamp).toBe(expectedTimestamp);
129
-
130
- const resultTimeMs = result!.timestamp! * 1000;
131
- expect(resultTimeMs).toBeLessThanOrEqual(seekTimeMs);
132
- }
122
+ const _0 = await inputAtStart.seek(1, 0);
123
+ const _10 = await inputAtStart.seek(1, 10);
124
+ const _20 = await inputAtStart.seek(1, 20);
125
+ const _30 = await inputAtStart.seek(1, 30);
126
+ const _40 = await inputAtStart.seek(1, 40);
127
+ const _50 = await inputAtStart.seek(1, 50);
128
+ const _60 = await inputAtStart.seek(1, 60);
129
+ const _70 = await inputAtStart.seek(1, 70);
130
+ const _80 = await inputAtStart.seek(1, 80);
131
+ const _90 = await inputAtStart.seek(1, 90);
132
+
133
+ expect(_0?.timestamp).toBe(0);
134
+ expect(_10?.timestamp).toBe(0);
135
+ expect(_20?.timestamp).toBe(0);
136
+ expect(_30?.timestamp).toBe(0);
137
+ expect(_40?.timestamp).toBe(0.04);
138
+ expect(_50?.timestamp).toBe(0.04);
139
+ expect(_60?.timestamp).toBe(0.04);
140
+ expect(_70?.timestamp).toBe(0.04);
141
+ expect(_80?.timestamp).toBe(0.08);
142
+ expect(_90?.timestamp).toBe(0.08);
133
143
  });
134
144
  });
135
145
 
@@ -178,11 +188,7 @@ describe("BufferedSeekingInput", () => {
178
188
  }) => {
179
189
  await fiveSampleBuffer.seek(1, 960);
180
190
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
181
- 0.76,
182
- 0.8,
183
- 0.84,
184
- 0.88,
185
- 0.92, // Updated: improved mediabunny shifted timestamps
191
+ 0.8, 0.84, 0.88, 0.92, 0.96,
186
192
  ]);
187
193
  });
188
194
 
@@ -199,29 +205,20 @@ describe("BufferedSeekingInput", () => {
199
205
  expect,
200
206
  fiveSampleBuffer,
201
207
  }) => {
202
- await fiveSampleBuffer.seek(1, 960);
208
+ const sample1 = await fiveSampleBuffer.seek(1, 960);
209
+ expect(sample1?.timestamp).toBe(0.96);
203
210
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
204
- 0.76,
205
- 0.8,
206
- 0.84,
207
- 0.88,
208
- 0.92, // Updated: improved mediabunny shifted timestamps
211
+ 0.8, 0.84, 0.88, 0.92, 0.96,
209
212
  ]);
210
- await fiveSampleBuffer.seek(1, 900);
213
+ const sample2 = await fiveSampleBuffer.seek(1, 900);
214
+ expect(sample2?.timestamp).toBe(0.88);
211
215
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
212
- 0.76,
213
- 0.8,
214
- 0.84,
215
- 0.88,
216
- 0.92, // Updated: improved mediabunny shifted timestamps
216
+ 0.8, 0.84, 0.88, 0.92, 0.96,
217
217
  ]);
218
- await fiveSampleBuffer.seek(1, 960);
218
+ const sample3 = await fiveSampleBuffer.seek(1, 920);
219
+ expect(sample3?.timestamp).toBe(0.92);
219
220
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
220
- 0.76,
221
- 0.8,
222
- 0.84,
223
- 0.88,
224
- 0.92, // Updated: improved mediabunny shifted timestamps
221
+ 0.8, 0.84, 0.88, 0.92, 0.96,
225
222
  ]);
226
223
  });
227
224
 
@@ -229,21 +226,15 @@ describe("BufferedSeekingInput", () => {
229
226
  expect,
230
227
  fiveSampleBuffer,
231
228
  }) => {
232
- await fiveSampleBuffer.seek(1, 960);
229
+ const sample1 = await fiveSampleBuffer.seek(1, 960);
230
+ expect(sample1?.timestamp).toBe(0.96);
233
231
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
234
- 0.76,
235
- 0.8,
236
- 0.84,
237
- 0.88,
238
- 0.92, // Updated: improved mediabunny shifted timestamps
232
+ 0.8, 0.84, 0.88, 0.92, 0.96,
239
233
  ]);
240
- await fiveSampleBuffer.seek(1, 900);
234
+ const sample2 = await fiveSampleBuffer.seek(1, 900);
235
+ expect(sample2?.timestamp).toBe(0.88);
241
236
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
242
- 0.76,
243
- 0.8,
244
- 0.84,
245
- 0.88,
246
- 0.92, // Updated: improved mediabunny shifted timestamps
237
+ 0.8, 0.84, 0.88, 0.92, 0.96,
247
238
  ]);
248
239
  });
249
240
 
@@ -251,21 +242,15 @@ describe("BufferedSeekingInput", () => {
251
242
  expect,
252
243
  fiveSampleBuffer,
253
244
  }) => {
254
- await fiveSampleBuffer.seek(1, 960);
245
+ const sample1 = await fiveSampleBuffer.seek(1, 960);
246
+ expect(sample1?.timestamp).toBe(0.96);
255
247
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
256
- 0.76,
257
- 0.8,
258
- 0.84,
259
- 0.88,
260
- 0.92, // Updated: improved mediabunny shifted timestamps
248
+ 0.8, 0.84, 0.88, 0.92, 0.96,
261
249
  ]);
262
- await fiveSampleBuffer.seek(1, 800);
250
+ const sample2 = await fiveSampleBuffer.seek(1, 800);
251
+ expect(sample2?.timestamp).toBe(0.8);
263
252
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
264
- 0.76,
265
- 0.8,
266
- 0.84,
267
- 0.88,
268
- 0.92, // Updated: improved mediabunny shifted timestamps
253
+ 0.8, 0.84, 0.88, 0.92, 0.96,
269
254
  ]);
270
255
  });
271
256
 
@@ -273,21 +258,16 @@ describe("BufferedSeekingInput", () => {
273
258
  expect,
274
259
  fiveSampleBuffer,
275
260
  }) => {
276
- await fiveSampleBuffer.seek(1, 960);
261
+ const sample1 = await fiveSampleBuffer.seek(1, 960);
262
+ expect(sample1?.timestamp).toBe(0.96);
277
263
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
278
- 0.76,
279
- 0.8,
280
- 0.84,
281
- 0.88,
282
- 0.92, // Updated: improved mediabunny shifted timestamps
264
+ 0.8, 0.84, 0.88, 0.92, 0.96,
283
265
  ]);
284
- await fiveSampleBuffer.seek(1, 720);
266
+
267
+ const sample2 = await fiveSampleBuffer.seek(1, 720);
268
+ expect(sample2?.timestamp).toBe(0.72);
285
269
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
286
- 0.52,
287
- 0.56,
288
- 0.6,
289
- 0.64,
290
- 0.68, // Updated: improved mediabunny shifted timestamps
270
+ 0.56, 0.6, 0.64, 0.68, 0.72,
291
271
  ]);
292
272
  });
293
273
 
@@ -295,29 +275,19 @@ describe("BufferedSeekingInput", () => {
295
275
  expect,
296
276
  fiveSampleBuffer,
297
277
  }) => {
298
- await fiveSampleBuffer.seek(1, 960);
278
+ const sample1 = await fiveSampleBuffer.seek(1, 960);
279
+ expect(sample1?.timestamp).toBe(0.96);
299
280
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
300
- 0.76,
301
- 0.8,
302
- 0.84,
303
- 0.88,
304
- 0.92, // Updated: improved mediabunny shifted timestamps
281
+ 0.8, 0.84, 0.88, 0.92, 0.96,
305
282
  ]);
306
- await fiveSampleBuffer.seek(1, 900);
283
+ const sample2 = await fiveSampleBuffer.seek(1, 900);
284
+ expect(sample2?.timestamp).toBe(0.88);
307
285
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
308
- 0.76,
309
- 0.8,
310
- 0.84,
311
- 0.88,
312
- 0.92, // Updated: improved mediabunny shifted timestamps
286
+ 0.8, 0.84, 0.88, 0.92, 0.96,
313
287
  ]);
314
288
  await fiveSampleBuffer.seek(1, 960);
315
289
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
316
- 0.76,
317
- 0.8,
318
- 0.84,
319
- 0.88,
320
- 0.92, // Updated: improved mediabunny shifted timestamps
290
+ 0.8, 0.84, 0.88, 0.92, 0.96,
321
291
  ]);
322
292
  });
323
293
 
@@ -325,28 +295,22 @@ describe("BufferedSeekingInput", () => {
325
295
  expect,
326
296
  fiveSampleBuffer,
327
297
  }) => {
328
- await fiveSampleBuffer.seek(1, 960);
298
+ const sample1 = await fiveSampleBuffer.seek(1, 960);
299
+ expect(sample1?.timestamp).toBe(0.96);
329
300
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
330
- 0.76,
331
- 0.8,
332
- 0.84,
333
- 0.88,
334
- 0.92, // Updated: improved mediabunny shifted timestamps
301
+ 0.8, 0.84, 0.88, 0.92, 0.96,
335
302
  ]);
336
- await fiveSampleBuffer.seek(1, 1000);
303
+ const sample2 = await fiveSampleBuffer.seek(1, 1000);
304
+ expect(sample2?.timestamp).toBe(1);
337
305
  expect(fiveSampleBuffer.getBufferTimestamps(1)).toEqual([
338
- 0.8,
339
- 0.84,
340
- 0.88,
341
- 0.92,
342
- 0.96, // Updated: improved mediabunny shifted timestamps
306
+ 0.84, 0.88, 0.92, 0.96, 1,
343
307
  ]);
344
308
  });
345
309
  });
346
310
 
347
311
  describe("seeing to time not in buffer (time is before buffer)", () => {
348
312
  test("throws error", async ({ expect, segment2 }) => {
349
- await expect(segment2.seek(1, 0)).rejects.toThrow(NoSample);
313
+ await expect(segment2.seek(1, -100)).rejects.toThrow(NoSample);
350
314
  });
351
315
  });
352
316
 
@@ -369,7 +333,7 @@ describe("BufferedSeekingInput", () => {
369
333
  });
370
334
  });
371
335
 
372
- describe("edge case: seeking to exact end of last sample", () => {
336
+ describe("seeking to exact end of last sample", () => {
373
337
  test("returns last sample when seeking to 10000ms in bars-n-tone.mp4", async ({
374
338
  expect,
375
339
  }) => {
@@ -397,85 +361,26 @@ describe("BufferedSeekingInput", () => {
397
361
  });
398
362
 
399
363
  describe("concurrency handling", () => {
400
- test("handles concurrent seeking operations safely", async ({
401
- expect,
402
- inputAtStart,
403
- }) => {
404
- const seek1 = inputAtStart.seek(1, 0);
405
- const seek2 = inputAtStart.seek(1, 40);
406
- const seek3 = inputAtStart.seek(1, 80);
407
- // Updated: removed seek4 due to inconsistent sample availability in test media
408
-
409
- const [sample1, sample2, sample3] = await Promise.all([
410
- seek1,
411
- seek2,
412
- seek3,
364
+ test("seeks are serialized", async ({ expect, inputAtStart }) => {
365
+ const samples = await Promise.all([
366
+ inputAtStart.seek(1, 0),
367
+ inputAtStart.seek(1, 40),
368
+ inputAtStart.seek(1, 80),
413
369
  ]);
414
370
 
415
- expect(sample1!.timestamp).toBe(0);
416
- expect(sample2!.timestamp).toBe(0); // Updated: frame timing shifted
417
- expect(sample3!.timestamp).toBe(0.04); // Updated: frame timing shifted
418
-
419
- const bufferTimestamps = inputAtStart.getBufferTimestamps(1);
420
- expect(bufferTimestamps.length).toBeGreaterThan(0);
421
- for (let i = 1; i < bufferTimestamps.length; i++) {
422
- expect(bufferTimestamps[i]).toBeGreaterThanOrEqual(
423
- bufferTimestamps[i - 1]!,
424
- );
425
- }
426
- });
427
-
428
- test("handles concurrent seeks with backward jumps", async ({
429
- expect,
430
- inputAtStart,
431
- }) => {
432
- await inputAtStart.seek(1, 200);
433
-
434
- const seek1 = inputAtStart.seek(1, 40);
435
- const seek2 = inputAtStart.seek(1, 160);
436
- const seek3 = inputAtStart.seek(1, 0);
437
-
438
- const [sample1, sample2, sample3] = await Promise.all([
439
- seek1,
440
- seek2,
441
- seek3,
371
+ expect(samples.map((sample) => sample?.timestamp)).toEqual([
372
+ 0, 0.04, 0.08,
442
373
  ]);
443
-
444
- expect(sample1!.timestamp).toBe(0); // Updated: frame timing shifted
445
- expect(sample2!.timestamp).toBe(0.12); // Updated: frame timing shifted
446
- expect(sample3!.timestamp).toBe(0);
447
- expect(inputAtStart.getBufferSize(1)).toBeGreaterThan(0);
448
- });
449
-
450
- test("handles concurrent seeks to same time", async ({
451
- expect,
452
- inputAtStart,
453
- }) => {
454
- const seeks = Array(5)
455
- .fill(null)
456
- .map(() => inputAtStart.seek(1, 80));
457
- const results = await Promise.all(seeks);
458
-
459
- for (const result of results) {
460
- expect(result!.timestamp).toBe(0.04); // Updated: frame timing shifted
461
- }
462
- expect(inputAtStart.getBufferSize(1)).toBeGreaterThan(0);
463
374
  });
375
+ });
464
376
 
465
- test("handles mixed concurrent operations across different tracks", async ({
377
+ describe("regression tests", () => {
378
+ test("seeks to 7975ms in bars-n-tone.mp4", async ({
466
379
  expect,
467
- inputAtStart,
380
+ barsNtone,
468
381
  }) => {
469
- const track1Seek1 = inputAtStart.seek(1, 40);
470
- const track1Seek2 = inputAtStart.seek(1, 80);
471
-
472
- const [result1, result2] = await Promise.all([track1Seek1, track1Seek2]);
473
-
474
- expect(result1!.timestamp).toBe(0); // Updated: frame timing shifted
475
- expect(result2!.timestamp).toBe(0.04); // Updated: frame timing shifted
476
-
477
- const track1Buffer = inputAtStart.getBufferTimestamps(1);
478
- expect(track1Buffer.length).toBeGreaterThan(0);
382
+ const sample = await barsNtone.seek(1, 7975);
383
+ expect(sample?.timestamp).toBeCloseTo(7.966);
479
384
  });
480
385
  });
481
386
  });