@editframe/elements 0.6.0-beta.18 → 0.6.0-beta.19

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 (82) hide show
  1. package/package.json +2 -2
  2. package/src/gui/EFFilmstrip.ts +19 -17
  3. package/dist/lib/av/EncodedAsset.cjs +0 -570
  4. package/dist/lib/av/EncodedAsset.js +0 -553
  5. package/dist/lib/av/MP4File.cjs +0 -182
  6. package/dist/lib/av/MP4File.js +0 -165
  7. package/dist/lib/av/msToTimeCode.cjs +0 -15
  8. package/dist/lib/av/msToTimeCode.js +0 -15
  9. package/dist/lib/util/awaitMicrotask.cjs +0 -4
  10. package/dist/lib/util/awaitMicrotask.js +0 -4
  11. package/dist/lib/util/memoize.cjs +0 -14
  12. package/dist/lib/util/memoize.js +0 -14
  13. package/dist/packages/elements/src/EF_FRAMEGEN.cjs +0 -200
  14. package/dist/packages/elements/src/EF_FRAMEGEN.d.ts +0 -45
  15. package/dist/packages/elements/src/EF_FRAMEGEN.js +0 -200
  16. package/dist/packages/elements/src/EF_INTERACTIVE.cjs +0 -4
  17. package/dist/packages/elements/src/EF_INTERACTIVE.d.ts +0 -1
  18. package/dist/packages/elements/src/EF_INTERACTIVE.js +0 -4
  19. package/dist/packages/elements/src/elements/CrossUpdateController.cjs +0 -16
  20. package/dist/packages/elements/src/elements/CrossUpdateController.d.ts +0 -9
  21. package/dist/packages/elements/src/elements/CrossUpdateController.js +0 -16
  22. package/dist/packages/elements/src/elements/EFAudio.cjs +0 -53
  23. package/dist/packages/elements/src/elements/EFAudio.d.ts +0 -10
  24. package/dist/packages/elements/src/elements/EFAudio.js +0 -54
  25. package/dist/packages/elements/src/elements/EFCaptions.cjs +0 -164
  26. package/dist/packages/elements/src/elements/EFCaptions.d.ts +0 -38
  27. package/dist/packages/elements/src/elements/EFCaptions.js +0 -166
  28. package/dist/packages/elements/src/elements/EFImage.cjs +0 -79
  29. package/dist/packages/elements/src/elements/EFImage.d.ts +0 -14
  30. package/dist/packages/elements/src/elements/EFImage.js +0 -80
  31. package/dist/packages/elements/src/elements/EFMedia.cjs +0 -334
  32. package/dist/packages/elements/src/elements/EFMedia.d.ts +0 -61
  33. package/dist/packages/elements/src/elements/EFMedia.js +0 -334
  34. package/dist/packages/elements/src/elements/EFSourceMixin.cjs +0 -55
  35. package/dist/packages/elements/src/elements/EFSourceMixin.d.ts +0 -12
  36. package/dist/packages/elements/src/elements/EFSourceMixin.js +0 -55
  37. package/dist/packages/elements/src/elements/EFTemporal.cjs +0 -198
  38. package/dist/packages/elements/src/elements/EFTemporal.d.ts +0 -36
  39. package/dist/packages/elements/src/elements/EFTemporal.js +0 -198
  40. package/dist/packages/elements/src/elements/EFTimegroup.browsertest.d.ts +0 -12
  41. package/dist/packages/elements/src/elements/EFTimegroup.cjs +0 -350
  42. package/dist/packages/elements/src/elements/EFTimegroup.d.ts +0 -39
  43. package/dist/packages/elements/src/elements/EFTimegroup.js +0 -351
  44. package/dist/packages/elements/src/elements/EFTimeline.cjs +0 -15
  45. package/dist/packages/elements/src/elements/EFTimeline.d.ts +0 -3
  46. package/dist/packages/elements/src/elements/EFTimeline.js +0 -15
  47. package/dist/packages/elements/src/elements/EFVideo.cjs +0 -109
  48. package/dist/packages/elements/src/elements/EFVideo.d.ts +0 -14
  49. package/dist/packages/elements/src/elements/EFVideo.js +0 -110
  50. package/dist/packages/elements/src/elements/EFWaveform.cjs +0 -235
  51. package/dist/packages/elements/src/elements/EFWaveform.d.ts +0 -28
  52. package/dist/packages/elements/src/elements/EFWaveform.js +0 -219
  53. package/dist/packages/elements/src/elements/FetchMixin.cjs +0 -28
  54. package/dist/packages/elements/src/elements/FetchMixin.d.ts +0 -8
  55. package/dist/packages/elements/src/elements/FetchMixin.js +0 -28
  56. package/dist/packages/elements/src/elements/TimegroupController.cjs +0 -20
  57. package/dist/packages/elements/src/elements/TimegroupController.d.ts +0 -14
  58. package/dist/packages/elements/src/elements/TimegroupController.js +0 -20
  59. package/dist/packages/elements/src/elements/durationConverter.cjs +0 -8
  60. package/dist/packages/elements/src/elements/durationConverter.d.ts +0 -4
  61. package/dist/packages/elements/src/elements/durationConverter.js +0 -8
  62. package/dist/packages/elements/src/elements/parseTimeToMs.cjs +0 -12
  63. package/dist/packages/elements/src/elements/parseTimeToMs.d.ts +0 -1
  64. package/dist/packages/elements/src/elements/parseTimeToMs.js +0 -12
  65. package/dist/packages/elements/src/elements/util.cjs +0 -11
  66. package/dist/packages/elements/src/elements/util.d.ts +0 -4
  67. package/dist/packages/elements/src/elements/util.js +0 -11
  68. package/dist/packages/elements/src/gui/EFFilmstrip.cjs +0 -820
  69. package/dist/packages/elements/src/gui/EFFilmstrip.d.ts +0 -144
  70. package/dist/packages/elements/src/gui/EFFilmstrip.js +0 -828
  71. package/dist/packages/elements/src/gui/EFWorkbench.cjs +0 -213
  72. package/dist/packages/elements/src/gui/EFWorkbench.d.ts +0 -45
  73. package/dist/packages/elements/src/gui/EFWorkbench.js +0 -214
  74. package/dist/packages/elements/src/gui/TWMixin.cjs +0 -28
  75. package/dist/packages/elements/src/gui/TWMixin.css.cjs +0 -3
  76. package/dist/packages/elements/src/gui/TWMixin.css.js +0 -4
  77. package/dist/packages/elements/src/gui/TWMixin.d.ts +0 -3
  78. package/dist/packages/elements/src/gui/TWMixin.js +0 -28
  79. package/dist/packages/elements/src/index.cjs +0 -51
  80. package/dist/packages/elements/src/index.d.ts +0 -10
  81. package/dist/packages/elements/src/index.js +0 -24
  82. package/dist/style.css +0 -787
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@editframe/elements",
3
- "version": "0.6.0-beta.18",
3
+ "version": "0.6.0-beta.19",
4
4
  "description": "",
5
5
  "exports": {
6
6
  ".": {
@@ -19,7 +19,7 @@
19
19
  "author": "",
20
20
  "license": "UNLICENSED",
21
21
  "dependencies": {
22
- "@editframe/assets": "0.6.0-beta.18",
22
+ "@editframe/assets": "0.6.0-beta.19",
23
23
  "@lit/context": "^1.1.1",
24
24
  "@lit/task": "^1.0.0",
25
25
  "d3": "^7.9.0",
@@ -488,7 +488,7 @@ export class EFFilmstrip extends TWMixin(LitElement) {
488
488
  @property({ type: Number })
489
489
  currentTimeMs = 0;
490
490
 
491
- @property({ type: String, attribute: "target" })
491
+ @property({ type: String, attribute: "target", reflect: true })
492
492
  targetSelector = "";
493
493
 
494
494
  @state()
@@ -504,7 +504,7 @@ export class EFFilmstrip extends TWMixin(LitElement) {
504
504
 
505
505
  connectedCallback(): void {
506
506
  super.connectedCallback();
507
- const target = this.target;
507
+ const target = this.targetTimegroup;
508
508
  if (target) {
509
509
  this.timegroupController = new TimegroupController(target, this);
510
510
  // Set the current time to the last saved time to avoid a cycle
@@ -583,7 +583,7 @@ export class EFFilmstrip extends TWMixin(LitElement) {
583
583
 
584
584
  async #startPlayback() {
585
585
  await this.#stopPlayback();
586
- const timegroup = this.target;
586
+ const timegroup = this.targetTimegroup;
587
587
  if (!timegroup) {
588
588
  return;
589
589
  }
@@ -642,9 +642,11 @@ export class EFFilmstrip extends TWMixin(LitElement) {
642
642
  }
643
643
 
644
644
  advancePlayhead = (tick?: DOMHighResTimeStamp) => {
645
- if (this.#lastTick && tick && this.target) {
646
- this.target.currentTimeMs += tick - this.#lastTick;
647
- if (this.target.currentTimeMs >= this.target.durationMs) {
645
+ if (this.#lastTick && tick && this.targetTimegroup) {
646
+ this.targetTimegroup.currentTimeMs += tick - this.#lastTick;
647
+ if (
648
+ this.targetTimegroup.currentTimeMs >= this.targetTimegroup.durationMs
649
+ ) {
648
650
  this.playing = false;
649
651
  }
650
652
  }
@@ -668,9 +670,9 @@ export class EFFilmstrip extends TWMixin(LitElement) {
668
670
  return;
669
671
  }
670
672
  const rect = gutter.getBoundingClientRect();
671
- if (this.target) {
673
+ if (this.targetTimegroup) {
672
674
  const layerX = e.pageX - rect.left + gutter.scrollLeft;
673
- this.target.currentTimeMs = layerX / this.pixelsPerMs;
675
+ this.targetTimegroup.currentTimeMs = layerX / this.pixelsPerMs;
674
676
  }
675
677
  }
676
678
 
@@ -686,9 +688,9 @@ export class EFFilmstrip extends TWMixin(LitElement) {
686
688
  return;
687
689
  }
688
690
  const rect = gutter.getBoundingClientRect();
689
- if (this.target) {
691
+ if (this.targetTimegroup) {
690
692
  const layerX = e.pageX - rect.left + gutter.scrollLeft;
691
- this.target.currentTimeMs = layerX / this.pixelsPerMs;
693
+ this.targetTimegroup.currentTimeMs = layerX / this.pixelsPerMs;
692
694
  }
693
695
  });
694
696
  addEventListener(
@@ -702,7 +704,7 @@ export class EFFilmstrip extends TWMixin(LitElement) {
702
704
 
703
705
  @eventOptions({ passive: false })
704
706
  scrollScrub(e: WheelEvent) {
705
- if (this.target && this.gutter && !this.playing) {
707
+ if (this.targetTimegroup && this.gutter && !this.playing) {
706
708
  e.preventDefault();
707
709
  // Avoid over-scrolling to the left
708
710
  if (
@@ -726,7 +728,7 @@ export class EFFilmstrip extends TWMixin(LitElement) {
726
728
 
727
729
  if (this) {
728
730
  this.gutter.scrollBy(e.deltaX, e.deltaY);
729
- this.target.currentTimeMs += e.deltaX / this.pixelsPerMs;
731
+ this.targetTimegroup.currentTimeMs += e.deltaX / this.pixelsPerMs;
730
732
  }
731
733
  }
732
734
  }
@@ -740,7 +742,7 @@ export class EFFilmstrip extends TWMixin(LitElement) {
740
742
  }
741
743
 
742
744
  render() {
743
- const target = this.target;
745
+ const target = this.targetTimegroup;
744
746
 
745
747
  return html` <div
746
748
  class="grid h-full bg-slate-100"
@@ -833,17 +835,17 @@ export class EFFilmstrip extends TWMixin(LitElement) {
833
835
  }
834
836
 
835
837
  updated(changes: PropertyValueMap<any> | Map<PropertyKey, unknown>) {
836
- if (!this.target) {
838
+ if (!this.targetTimegroup) {
837
839
  return;
838
840
  }
839
841
  if (changes.has("currentTimeMs")) {
840
- if (this.target.currentTimeMs !== this.currentTimeMs) {
841
- this.target.currentTimeMs = this.currentTimeMs;
842
+ if (this.targetTimegroup.currentTimeMs !== this.currentTimeMs) {
843
+ this.targetTimegroup.currentTimeMs = this.currentTimeMs;
842
844
  }
843
845
  }
844
846
  }
845
847
 
846
- get target() {
848
+ get targetTimegroup() {
847
849
  if (this.getAttribute("target")) {
848
850
  const target = document.querySelector(this.getAttribute("target") ?? "");
849
851
  if (target instanceof EFTimegroup) {
@@ -1,570 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const MP4Box = require("mp4box");
4
- const memoize = require("../util/memoize.cjs");
5
- const MP4File = require("./MP4File.cjs");
6
- function _interopNamespaceDefault(e) {
7
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
8
- if (e) {
9
- for (const k in e) {
10
- if (k !== "default") {
11
- const d = Object.getOwnPropertyDescriptor(e, k);
12
- Object.defineProperty(n, k, d.get ? d : {
13
- enumerable: true,
14
- get: () => e[k]
15
- });
16
- }
17
- }
18
- }
19
- n.default = e;
20
- return Object.freeze(n);
21
- }
22
- const MP4Box__namespace = /* @__PURE__ */ _interopNamespaceDefault(MP4Box);
23
- var __defProp = Object.defineProperty;
24
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
25
- var __decorateClass = (decorators, target, key, kind) => {
26
- var result = __getOwnPropDesc(target, key);
27
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
28
- if (decorator = decorators[i])
29
- result = decorator(target, key, result) || result;
30
- if (result) __defProp(target, key, result);
31
- return result;
32
- };
33
- const BUFFER_SIZE = 10;
34
- class AssetNotAvailableLocally extends Error {
35
- }
36
- class FileAsset {
37
- constructor(localName, file) {
38
- this.localName = localName;
39
- this.file = file;
40
- }
41
- async arrayBuffer() {
42
- return this.file.arrayBuffer();
43
- }
44
- get byteSize() {
45
- return this.file.size;
46
- }
47
- get fileExtension() {
48
- return this.file.name.split(".").pop();
49
- }
50
- slice(start, end) {
51
- return this.file.slice(start, end);
52
- }
53
- }
54
- class ISOFileAsset extends FileAsset {
55
- constructor(localName, file, mp4boxFile) {
56
- super(localName, file);
57
- this.localName = localName;
58
- this.file = file;
59
- this.mp4boxFile = mp4boxFile;
60
- }
61
- get fileInfo() {
62
- return this.mp4boxFile.getInfo();
63
- }
64
- get containerFormat() {
65
- return "mp4";
66
- }
67
- }
68
- __decorateClass([
69
- memoize.memoize
70
- ], ISOFileAsset.prototype, "fileInfo");
71
- const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
72
- constructor(localName, mp4boxFile, file) {
73
- super(localName, file, mp4boxFile);
74
- this.decodedFrames = [];
75
- this.requestedSampleNumber = 0;
76
- this.outCursor = 0;
77
- this.sampleCursor = 0;
78
- this.eventListeners = {};
79
- this.latestSeekCts = 0;
80
- this.videoDecoder = new VideoDecoder({
81
- error: (e) => {
82
- console.error("Video Decoder Error", e);
83
- },
84
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
85
- output: async (decodedFrame) => {
86
- const clone = decodedFrame.clone();
87
- this.decodedFrames.push(clone);
88
- this.pruneBuffer();
89
- decodedFrame.close();
90
- this.outCursor = this.samples.findIndex(
91
- (sample) => sample.cts === decodedFrame.timestamp
92
- );
93
- this.emit("frame", clone);
94
- }
95
- });
96
- this.configureDecoder();
97
- }
98
- static async createFromReadableStream(id, stream, file) {
99
- let fileStart = 0;
100
- const inputFile = new MP4File.MP4File();
101
- const reader = stream.getReader();
102
- const processChunk = ({
103
- done,
104
- value
105
- }) => {
106
- if (done) {
107
- return;
108
- }
109
- if (!value) {
110
- return;
111
- }
112
- const mp4buffer = value.buffer;
113
- mp4buffer.fileStart = fileStart;
114
- const isLast = file.size === fileStart + value.byteLength;
115
- inputFile.appendBuffer(mp4buffer, isLast);
116
- fileStart += value.byteLength;
117
- return reader.read().then(processChunk);
118
- };
119
- await reader.read().then(processChunk);
120
- return new _VideoAsset2(id, inputFile, file);
121
- }
122
- /**
123
- * **Only use this function in tests to reset a VideoAsset to its initial state.**
124
- *
125
- * @deprecated
126
- */
127
- async TEST_ONLY_RESET() {
128
- await this.videoDecoder.flush();
129
- this.configureDecoder();
130
- this.requestedSampleNumber = 0;
131
- this.outCursor = 0;
132
- this.sampleCursor = 0;
133
- for (const frame of this.decodedFrames) {
134
- frame.close();
135
- }
136
- this.decodedFrames = [];
137
- this.lastDecodedSample = void 0;
138
- this.lastSoughtFrame?.close();
139
- this.lastSoughtFrame = void 0;
140
- }
141
- addEventListener(type, callback) {
142
- this.eventListeners[type] ||= /* @__PURE__ */ new Set();
143
- this.eventListeners[type]?.add(callback);
144
- }
145
- removeEventListener(type, callback) {
146
- this.eventListeners[type]?.delete(callback);
147
- }
148
- emit(type, ...args) {
149
- for (const listener of this.eventListeners[type] ?? []) {
150
- listener(...args);
151
- }
152
- }
153
- get videoCodec() {
154
- if (!this.defaultVideoTrack) {
155
- throw new Error("No default video track found");
156
- }
157
- return this.defaultVideoTrack?.codec;
158
- }
159
- get fragmentInfo() {
160
- const fragments = [];
161
- const [first, ...samples] = this.samples;
162
- if (!first) {
163
- return fragments;
164
- }
165
- let currentFragment = {
166
- offset: first.offset,
167
- size: first.size,
168
- start_ms: first.cts,
169
- duration_ms: 0
170
- };
171
- for (const sample of samples) {
172
- if (sample.is_sync) {
173
- if (currentFragment) {
174
- currentFragment.duration_ms = sample.cts - currentFragment.start_ms;
175
- fragments.push(currentFragment);
176
- }
177
- currentFragment = {
178
- offset: sample.offset,
179
- size: sample.size,
180
- start_ms: sample.cts,
181
- duration_ms: 0
182
- };
183
- } else {
184
- currentFragment.size += sample.size;
185
- }
186
- }
187
- return fragments;
188
- }
189
- pruneBuffer() {
190
- if (this.decodedFrames.length > BUFFER_SIZE) {
191
- this.decodedFrames.shift()?.close();
192
- }
193
- }
194
- prettyPrint() {
195
- const samplesInEncoder = this.sampleCursor - this.outCursor;
196
- const cachedSamples = this.decodedFrames.length;
197
- console.log(
198
- Array.from({
199
- length: this.sampleCursor - samplesInEncoder - cachedSamples
200
- }).fill("⬜️").join(" "),
201
- Array.from({ length: cachedSamples }).fill("🟩").join(" "),
202
- Array.from({
203
- length: samplesInEncoder
204
- }).fill("🟨").join(" ")
205
- );
206
- }
207
- get editsOffset() {
208
- if (!this.defaultVideoTrack?.edits) {
209
- return 0;
210
- }
211
- return this.defaultVideoTrack.edits.reduce((acc, edit) => {
212
- return acc + edit.media_time;
213
- }, 0);
214
- }
215
- async waitUntilVideoQueueDrained() {
216
- if (this.videoDecoder.decodeQueueSize === 0) {
217
- return;
218
- }
219
- await new Promise((resolve) => {
220
- this.videoDecoder.addEventListener(
221
- "dequeue",
222
- () => {
223
- resolve();
224
- },
225
- { once: true }
226
- );
227
- });
228
- await this.waitUntilVideoQueueDrained();
229
- }
230
- get canDecodeNextSample() {
231
- return this.sampleCursor < this.samples.length;
232
- }
233
- async decodeNextSample() {
234
- if (!this.canDecodeNextSample) {
235
- throw new Error("No more samples to decode");
236
- }
237
- await this.decodeSlice(this.sampleCursor, this.sampleCursor);
238
- this.sampleCursor++;
239
- }
240
- async decodeSlice(start, end) {
241
- const samples = this.samples.slice(start, end + 1);
242
- const firstSample = samples[0];
243
- const lastSample = samples[samples.length - 1];
244
- if (!firstSample || !lastSample) {
245
- throw new Error("Samples not found");
246
- }
247
- const sliceStart = firstSample.offset;
248
- const sliceEnd = lastSample.offset + lastSample.size;
249
- const buffer = await this.file.slice(sliceStart, sliceEnd).arrayBuffer();
250
- const firstSampleOffset = firstSample.offset;
251
- for (let i = start; i <= end; i++) {
252
- await this.waitUntilVideoQueueDrained();
253
- const sample = this.getSample(i);
254
- const sampleStart = sample.offset - firstSampleOffset;
255
- const sampleEnd = sample.offset + sample.size - firstSampleOffset;
256
- const chunk = new EncodedVideoChunk({
257
- data: buffer.slice(sampleStart, sampleEnd),
258
- timestamp: sample.cts,
259
- duration: sample.duration,
260
- type: sample.is_sync ? "key" : "delta"
261
- });
262
- this.videoDecoder.decode(chunk);
263
- const nextSample = this.defaultVideoTrak?.samples?.[i + 1];
264
- if (nextSample === void 0) {
265
- await this.videoDecoder.flush();
266
- }
267
- }
268
- }
269
- get decoderConfiguration() {
270
- if (!this.defaultVideoTrack) {
271
- throw new Error("No default video track found");
272
- }
273
- let description = new Uint8Array();
274
- const trak = this.mp4boxFile.getTrackById(this.defaultVideoTrack.id);
275
- for (const entry of trak.mdia.minf.stbl.stsd.entries) {
276
- if (entry.avcC ?? entry.hvcC) {
277
- const stream = new MP4Box__namespace.DataStream(
278
- void 0,
279
- 0,
280
- MP4Box__namespace.DataStream.BIG_ENDIAN
281
- );
282
- if (entry.avcC) {
283
- entry.avcC.write(stream);
284
- } else {
285
- entry.hvcC.write(stream);
286
- }
287
- description = new Uint8Array(stream.buffer, 8);
288
- break;
289
- }
290
- }
291
- return {
292
- codec: this.defaultVideoTrack.codec,
293
- codedWidth: this.defaultVideoTrack.track_width,
294
- codedHeight: this.defaultVideoTrack.track_height,
295
- optimizeForLatency: true,
296
- description
297
- };
298
- }
299
- /**
300
- * Configures the video decoder with the appropriate codec, dimensions, and hardware acceleration settings.
301
- * If the decoder is already configured, it will be reset before being reconfigured.
302
- */
303
- configureDecoder() {
304
- if (this.videoDecoder.state === "configured") {
305
- this.videoDecoder.reset();
306
- }
307
- this.videoDecoder.configure(this.decoderConfiguration);
308
- }
309
- // Default to -1 to throw error if called without an index
310
- getSample(index = -1) {
311
- const sample = this.samples?.[index];
312
- if (!sample) {
313
- throw new Error(`Sample not found at index ${index}`);
314
- }
315
- return sample;
316
- }
317
- get timescale() {
318
- if (!this.defaultVideoTrack) {
319
- throw new Error("No default video track found");
320
- }
321
- return this.defaultVideoTrack.timescale;
322
- }
323
- get samples() {
324
- if (!this.defaultVideoTrak.samples) {
325
- throw new Error("No video samples found");
326
- }
327
- return this.defaultVideoTrak.samples;
328
- }
329
- get displayOrderedSamples() {
330
- return Array.from(this.samples).sort((a, b) => {
331
- return a.cts - b.cts;
332
- });
333
- }
334
- getSampleClosetToTime(seconds) {
335
- const targetTime = Math.round(seconds * this.timescale + this.editsOffset);
336
- const sampleIndex = this.displayOrderedSamples.findIndex(
337
- (sample) => sample.cts >= targetTime
338
- );
339
- if (sampleIndex === -1) {
340
- return this.displayOrderedSamples[this.displayOrderedSamples.length - 1];
341
- }
342
- return this.displayOrderedSamples[sampleIndex];
343
- }
344
- seekingWillEmitNewFrame(seconds) {
345
- if (!this.lastSoughtFrame) {
346
- return true;
347
- }
348
- if (this.seekingWillGoBackwards(seconds)) {
349
- return true;
350
- }
351
- const nextCts = this.getSampleClosetToTime(seconds).cts;
352
- return nextCts > this.lastSoughtFrame.timestamp;
353
- }
354
- seekingWillSkipPictureGroup(seconds) {
355
- let start = this.sampleCursor;
356
- const end = this.getSampleClosetToTime(seconds).number;
357
- let syncFrameCrossings = 0;
358
- while (start <= end) {
359
- const sample = this.getSample(start);
360
- if (sample.is_sync) {
361
- if (syncFrameCrossings > 1) {
362
- return true;
363
- }
364
- syncFrameCrossings++;
365
- }
366
- start++;
367
- }
368
- return false;
369
- }
370
- seekingWillGoBackwards(seconds) {
371
- const targetSample = this.getSampleClosetToTime(seconds);
372
- const targetIndex = this.displayOrderedSamples.indexOf(targetSample);
373
- const targetInCache = this.decodedFrames.find(
374
- (frame) => frame.timestamp === targetSample.cts
375
- );
376
- const atEnd = this.sampleCursor === this.samples.length - 1;
377
- if (atEnd) {
378
- return false;
379
- }
380
- if (targetInCache) {
381
- return false;
382
- }
383
- return this.outCursor > targetIndex;
384
- }
385
- async seekToTime(seconds) {
386
- const sample = this.getSampleClosetToTime(seconds);
387
- const cts = sample.cts;
388
- this.latestSeekCts = cts;
389
- const alreadyDecodedFrame = this.decodedFrames.find(
390
- (f) => f.timestamp === cts
391
- );
392
- if (alreadyDecodedFrame) {
393
- return alreadyDecodedFrame;
394
- }
395
- if (this.seekingWillSkipPictureGroup(seconds)) {
396
- await this.videoDecoder.flush();
397
- let syncSampleNumber = sample.number;
398
- while (!this.getSample(syncSampleNumber).is_sync) {
399
- syncSampleNumber--;
400
- if (syncSampleNumber < 0) {
401
- throw new Error("No sync sample found when traversing backwards");
402
- }
403
- }
404
- this.sampleCursor = syncSampleNumber;
405
- }
406
- if (this.seekingWillGoBackwards(seconds)) {
407
- console.log("BACKWARDS FLUSH");
408
- await this.videoDecoder.flush();
409
- for (const frame2 of this.decodedFrames) {
410
- frame2.close();
411
- }
412
- this.decodedFrames = [];
413
- let syncSampleNumber = sample.number;
414
- while (!this.getSample(syncSampleNumber).is_sync) {
415
- syncSampleNumber--;
416
- if (syncSampleNumber < 0) {
417
- throw new Error("No sync sample found when traversing backwards");
418
- }
419
- }
420
- this.sampleCursor = syncSampleNumber;
421
- }
422
- let frame;
423
- const maybeFrame = (_frame) => {
424
- if (frame) {
425
- return;
426
- }
427
- if (_frame.timestamp === cts) {
428
- this.removeEventListener("frame", maybeFrame);
429
- frame = _frame;
430
- }
431
- };
432
- this.addEventListener("frame", maybeFrame);
433
- while (frame === void 0 && this.canDecodeNextSample) {
434
- await this.decodeNextSample();
435
- }
436
- this.removeEventListener("frame", maybeFrame);
437
- if (frame) {
438
- if (this.lastSoughtFrame && !this.decodedFrames.includes(this.lastSoughtFrame)) {
439
- try {
440
- this.lastSoughtFrame.close();
441
- } catch (error) {
442
- }
443
- }
444
- this.lastSoughtFrame = frame;
445
- }
446
- return frame;
447
- }
448
- get defaultVideoTrack() {
449
- return this.fileInfo.videoTracks[0];
450
- }
451
- get defaultVideoTrak() {
452
- return this.mp4boxFile.getTrackById(this.defaultVideoTrack?.id ?? -1);
453
- }
454
- get duration() {
455
- return this.fileInfo.duration / this.fileInfo.timescale;
456
- }
457
- };
458
- __decorateClass([
459
- memoize.memoize
460
- ], _VideoAsset.prototype, "editsOffset");
461
- __decorateClass([
462
- memoize.memoize
463
- ], _VideoAsset.prototype, "timescale");
464
- __decorateClass([
465
- memoize.memoize
466
- ], _VideoAsset.prototype, "samples");
467
- __decorateClass([
468
- memoize.memoize
469
- ], _VideoAsset.prototype, "displayOrderedSamples");
470
- __decorateClass([
471
- memoize.memoize
472
- ], _VideoAsset.prototype, "defaultVideoTrack");
473
- __decorateClass([
474
- memoize.memoize
475
- ], _VideoAsset.prototype, "defaultVideoTrak");
476
- __decorateClass([
477
- memoize.memoize
478
- ], _VideoAsset.prototype, "duration");
479
- let VideoAsset = _VideoAsset;
480
- const _AudioAsset = class _AudioAsset2 extends ISOFileAsset {
481
- static async createFromReadableStream(id, stream, file) {
482
- let fileStart = 0;
483
- const inputFile = new MP4File.MP4File();
484
- const reader = stream.getReader();
485
- const processChunk = ({
486
- done,
487
- value
488
- }) => {
489
- if (done) {
490
- return;
491
- }
492
- if (!value) {
493
- return;
494
- }
495
- const mp4buffer = value.buffer;
496
- mp4buffer.fileStart = fileStart;
497
- fileStart += value.byteLength;
498
- inputFile.appendBuffer(mp4buffer);
499
- return reader.read().then(processChunk);
500
- };
501
- await reader.read().then(processChunk);
502
- return new _AudioAsset2(id, file, inputFile);
503
- }
504
- get defaultAudioTrack() {
505
- return this.fileInfo.audioTracks[0];
506
- }
507
- get defaultAudioTrak() {
508
- return this.mp4boxFile.getTrackById(this.defaultAudioTrack?.id ?? -1);
509
- }
510
- get audioCodec() {
511
- if (!this.defaultAudioTrack) {
512
- throw new Error("No default audio track found");
513
- }
514
- return this.defaultAudioTrack.codec;
515
- }
516
- get samplerate() {
517
- if (!this.defaultAudioTrack) {
518
- throw new Error("No default audio track found");
519
- }
520
- return this.defaultAudioTrack.audio.sample_rate;
521
- }
522
- get channelCount() {
523
- if (!this.defaultAudioTrack) {
524
- throw new Error("No default audio track found");
525
- }
526
- return this.defaultAudioTrack.audio.channel_count;
527
- }
528
- };
529
- __decorateClass([
530
- memoize.memoize
531
- ], _AudioAsset.prototype, "defaultAudioTrack");
532
- __decorateClass([
533
- memoize.memoize
534
- ], _AudioAsset.prototype, "defaultAudioTrak");
535
- __decorateClass([
536
- memoize.memoize
537
- ], _AudioAsset.prototype, "audioCodec");
538
- __decorateClass([
539
- memoize.memoize
540
- ], _AudioAsset.prototype, "samplerate");
541
- __decorateClass([
542
- memoize.memoize
543
- ], _AudioAsset.prototype, "channelCount");
544
- const _ImageAsset = class _ImageAsset2 extends FileAsset {
545
- static async createFromReadableStream(id, file) {
546
- if (file.size === 0) {
547
- throw new AssetNotAvailableLocally();
548
- }
549
- return new _ImageAsset2(id, file);
550
- }
551
- get objectUrl() {
552
- return URL.createObjectURL(this.file);
553
- }
554
- get format() {
555
- return this.fileExtension;
556
- }
557
- get type() {
558
- return `image/${this.format}`;
559
- }
560
- };
561
- __decorateClass([
562
- memoize.memoize
563
- ], _ImageAsset.prototype, "objectUrl");
564
- __decorateClass([
565
- memoize.memoize
566
- ], _ImageAsset.prototype, "format");
567
- exports.AssetNotAvailableLocally = AssetNotAvailableLocally;
568
- exports.FileAsset = FileAsset;
569
- exports.ISOFileAsset = ISOFileAsset;
570
- exports.VideoAsset = VideoAsset;