@meframe/server 0.0.9 → 0.1.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/README.md +1 -1
  2. package/dist/cjs/ServerExporterBase.js +40 -4
  3. package/dist/cjs/ServerExporterBase.js.map +1 -1
  4. package/dist/cjs/utils/http-cors.js +24 -0
  5. package/dist/cjs/utils/http-cors.js.map +1 -0
  6. package/dist/cjs/utils/local-spool-server.js +19 -28
  7. package/dist/cjs/utils/local-spool-server.js.map +1 -1
  8. package/dist/cjs/utils/local-worker-server.js +93 -0
  9. package/dist/cjs/utils/local-worker-server.js.map +1 -0
  10. package/dist/cjs/utils/resolve-core-workers.js +51 -0
  11. package/dist/cjs/utils/resolve-core-workers.js.map +1 -0
  12. package/dist/esm/ServerExporterBase.d.ts.map +1 -1
  13. package/dist/esm/ServerExporterBase.js +40 -4
  14. package/dist/esm/ServerExporterBase.js.map +1 -1
  15. package/dist/esm/types.d.ts +25 -0
  16. package/dist/esm/types.d.ts.map +1 -1
  17. package/dist/esm/utils/http-cors.d.ts +8 -0
  18. package/dist/esm/utils/http-cors.d.ts.map +1 -0
  19. package/dist/esm/utils/http-cors.js +21 -0
  20. package/dist/esm/utils/http-cors.js.map +1 -0
  21. package/dist/esm/utils/local-spool-server.d.ts.map +1 -1
  22. package/dist/esm/utils/local-spool-server.js +19 -28
  23. package/dist/esm/utils/local-spool-server.js.map +1 -1
  24. package/dist/esm/utils/local-worker-server.d.ts +15 -0
  25. package/dist/esm/utils/local-worker-server.d.ts.map +1 -0
  26. package/dist/esm/utils/local-worker-server.js +87 -0
  27. package/dist/esm/utils/local-worker-server.js.map +1 -0
  28. package/dist/esm/utils/resolve-core-workers.d.ts +2 -0
  29. package/dist/esm/utils/resolve-core-workers.d.ts.map +1 -0
  30. package/dist/esm/utils/resolve-core-workers.js +12 -0
  31. package/dist/esm/utils/resolve-core-workers.js.map +1 -0
  32. package/dist/runner-browser/runner.mjs +88 -85
  33. package/docs/INTEGRATION.md +7 -0
  34. package/package.json +2 -2
@@ -1296,7 +1296,7 @@ class Qs {
1296
1296
  this.port.onmessage = h;
1297
1297
  }
1298
1298
  }
1299
- var z = /* @__PURE__ */ ((a) => (a.ModelSet = "model:set", a.ResourceAdd = "resource:add", a.ResourceUpdate = "resource:update", a.ResourceRemove = "resource:remove", a.ResourceStageChange = "resource:state", a.ResourceFirstFrameReady = "resource:firstFrameReady", a.LoadStart = "load:start", a.LoadProgress = "load:progress", a.LoadComplete = "load:complete", a.LoadError = "load:error", a.DemuxStart = "demux:start", a.DemuxProgress = "demux:progress", a.DemuxComplete = "demux:complete", a.DemuxError = "demux:error", a.DecodeStart = "decode:start", a.DecodeProgress = "decode:progress", a.DecodeComplete = "decode:complete", a.DecodeError = "decode:error", a.ComposeStart = "compose:start", a.ComposeProgress = "compose:progress", a.ComposeComplete = "compose:complete", a.ComposeFrameReady = "compose:frameReady", a.ComposeFrameDropped = "compose:frameDropped", a.EncodeChunkReady = "encode:chunkReady", a.EncodeChunkError = "encode:chunkError", a.CacheHit = "cache:hit", a.CacheMiss = "cache:miss", a.CacheEvict = "cache:evict", a.CacheWrite = "cache:write", a.CacheCover = "cache:cover", a.ExportPreparing = "export:preparing", a.ExportStart = "export:start", a.ExportProgress = "export:progress", a.ExportComplete = "export:complete", a.ExportError = "export:error", a.CompositionUpdated = "composition:updated", a.PatchApplied = "patch:applied", a.Ready = "ready", a.WorkerStarted = "worker:started", a.WorkerReady = "worker:ready", a.WorkerError = "worker:error", a.WorkerRestarted = "worker:restarted", a.PlaybackBuffering = "playback:buffering", a.PlaybackPlay = "playback:play", a.PlaybackPause = "playback:pause", a.PlaybackStop = "playback:stop", a.PlaybackSeek = "playback:seek", a.PlaybackEnded = "playback:ended", a.PlaybackTimeUpdate = "playback:timeupdate", a.PlaybackRateChange = "playback:ratechange", a.PlaybackVolumeChange = "playback:volumechange", a.PlaybackError = "playback:error", a.PlaybackStarted = "playback:started", a.PlaybackPaused = "playback:paused", a.PlaybackSeeked = "playback:seeked", a.Error = "error", a.PluginLoaded = "plugin:loaded", a.PluginError = "plugin:error", a.PluginUnloaded = "plugin:unloaded", a.ClipActivated = "clip:activated", a.ClipDeactivated = "clip:deactivated", a))(z || {});
1299
+ var O = /* @__PURE__ */ ((a) => (a.ModelSet = "model:set", a.ResourceAdd = "resource:add", a.ResourceUpdate = "resource:update", a.ResourceRemove = "resource:remove", a.ResourceStageChange = "resource:state", a.ResourceFirstFrameReady = "resource:firstFrameReady", a.LoadStart = "load:start", a.LoadProgress = "load:progress", a.LoadComplete = "load:complete", a.LoadError = "load:error", a.DemuxStart = "demux:start", a.DemuxProgress = "demux:progress", a.DemuxComplete = "demux:complete", a.DemuxError = "demux:error", a.DecodeStart = "decode:start", a.DecodeProgress = "decode:progress", a.DecodeComplete = "decode:complete", a.DecodeError = "decode:error", a.ComposeStart = "compose:start", a.ComposeProgress = "compose:progress", a.ComposeComplete = "compose:complete", a.ComposeFrameReady = "compose:frameReady", a.ComposeFrameDropped = "compose:frameDropped", a.EncodeChunkReady = "encode:chunkReady", a.EncodeChunkError = "encode:chunkError", a.CacheHit = "cache:hit", a.CacheMiss = "cache:miss", a.CacheEvict = "cache:evict", a.CacheWrite = "cache:write", a.CacheCover = "cache:cover", a.ExportPreparing = "export:preparing", a.ExportStart = "export:start", a.ExportProgress = "export:progress", a.ExportComplete = "export:complete", a.ExportError = "export:error", a.CompositionUpdated = "composition:updated", a.PatchApplied = "patch:applied", a.Ready = "ready", a.WorkerStarted = "worker:started", a.WorkerReady = "worker:ready", a.WorkerError = "worker:error", a.WorkerRestarted = "worker:restarted", a.PlaybackBuffering = "playback:buffering", a.PlaybackPlay = "playback:play", a.PlaybackPause = "playback:pause", a.PlaybackStop = "playback:stop", a.PlaybackSeek = "playback:seek", a.PlaybackEnded = "playback:ended", a.PlaybackTimeUpdate = "playback:timeupdate", a.PlaybackRateChange = "playback:ratechange", a.PlaybackVolumeChange = "playback:volumechange", a.PlaybackError = "playback:error", a.PlaybackStarted = "playback:started", a.PlaybackPaused = "playback:paused", a.PlaybackSeeked = "playback:seeked", a.Error = "error", a.PluginLoaded = "plugin:loaded", a.PluginError = "plugin:error", a.PluginUnloaded = "plugin:unloaded", a.ClipActivated = "clip:activated", a.ClipDeactivated = "clip:deactivated", a))(O || {});
1300
1300
  class Xs {
1301
1301
  worker;
1302
1302
  channel;
@@ -1314,7 +1314,7 @@ class Xs {
1314
1314
  }
1315
1315
  setupErrorHandling() {
1316
1316
  this.worker.onerror = (e) => {
1317
- this.state = "error", this.lastError = new Error(e.message || "Worker error"), this.onError?.(this.lastError), this.eventBus.emit(z.WorkerError, {
1317
+ this.state = "error", this.lastError = new Error(e.message || "Worker error"), this.onError?.(this.lastError), this.eventBus.emit(O.WorkerError, {
1318
1318
  type: this.type,
1319
1319
  workerId: this.getWorkerId(),
1320
1320
  error: this.lastError
@@ -1322,13 +1322,13 @@ class Xs {
1322
1322
  };
1323
1323
  }
1324
1324
  async initialize(e) {
1325
- this.eventBus.emit(z.WorkerStarted, {
1325
+ this.eventBus.emit(O.WorkerStarted, {
1326
1326
  type: this.type,
1327
1327
  workerId: this.getWorkerId()
1328
1328
  }), await this.channel.send(mt.Configure, {
1329
1329
  config: e,
1330
1330
  initial: !0
1331
- }), this.eventBus.emit(z.WorkerReady, {
1331
+ }), this.eventBus.emit(O.WorkerReady, {
1332
1332
  type: this.type,
1333
1333
  workerId: this.getWorkerId()
1334
1334
  });
@@ -6166,7 +6166,7 @@ class Ir {
6166
6166
  const l = new kr(), u = h ? this.shouldExtractCover(h) : !1, o = await l.parseFromStream(s, {
6167
6167
  resourceId: r,
6168
6168
  onFirstFrameReady: u ? async (p, m) => {
6169
- p.resourceId = r, this.cacheManager.mp4IndexCache.set(r, p), this.eventBus?.emit(z.ResourceFirstFrameReady, {
6169
+ p.resourceId = r, this.cacheManager.mp4IndexCache.set(r, p), this.eventBus?.emit(O.ResourceFirstFrameReady, {
6170
6170
  resourceId: r,
6171
6171
  clipId: h,
6172
6172
  index: p,
@@ -6224,8 +6224,8 @@ class Ir {
6224
6224
  const h = this.model?.resources.get(e);
6225
6225
  if (h) {
6226
6226
  const l = h.state;
6227
- h.state = s, s === "error" ? h.error = r : h.error = void 0, this.eventBus?.emit(z.ResourceStageChange, {
6228
- type: z.ResourceStageChange,
6227
+ h.state = s, s === "error" ? h.error = r : h.error = void 0, this.eventBus?.emit(O.ResourceStageChange, {
6228
+ type: O.ResourceStageChange,
6229
6229
  resourceId: e,
6230
6230
  oldState: l,
6231
6231
  newState: s
@@ -7365,12 +7365,12 @@ class Nr {
7365
7365
  */
7366
7366
  addFrame(e, s, r, h, l) {
7367
7367
  const u = this.videoL1Cache.addFrame(e, s, r, h, l), o = e.timestamp ?? 0;
7368
- return this.checkAndNotifyClipReady(s, o), l === 0 && this.eventBus?.emit(z.CacheCover, {
7368
+ return this.checkAndNotifyClipReady(s, o), l === 0 && this.eventBus?.emit(O.CacheCover, {
7369
7369
  timeUs: l,
7370
7370
  clipId: s,
7371
7371
  level: "L1",
7372
7372
  size: u.sizeEstimate ?? 0
7373
- }), this.eventBus?.emit(z.ComposeFrameReady, {
7373
+ }), this.eventBus?.emit(O.ComposeFrameReady, {
7374
7374
  timeUs: l,
7375
7375
  frameNumber: Math.floor(l / r),
7376
7376
  renderTimeMs: 0,
@@ -8448,7 +8448,7 @@ class vn {
8448
8448
  if (!ei(u))
8449
8449
  throw new Error(`Clip ${u.id} in audio track is not an audio clip`);
8450
8450
  if (this.deps.cacheManager.audioSampleCache.has(u.resourceId)) {
8451
- this.activeClips.add(u.id), this.deps.eventBus.emit(z.ClipActivated, { clipId: u.id });
8451
+ this.activeClips.add(u.id), this.deps.eventBus.emit(O.ClipActivated, { clipId: u.id });
8452
8452
  continue;
8453
8453
  }
8454
8454
  try {
@@ -8462,7 +8462,7 @@ class vn {
8462
8462
  continue;
8463
8463
  throw o;
8464
8464
  }
8465
- this.activeClips.add(u.id), this.deps.eventBus.emit(z.ClipActivated, { clipId: u.id });
8465
+ this.activeClips.add(u.id), this.deps.eventBus.emit(O.ClipActivated, { clipId: u.id });
8466
8466
  }
8467
8467
  }
8468
8468
  }
@@ -11442,7 +11442,7 @@ class zo {
11442
11442
  await new Promise((T) => setTimeout(T, 100));
11443
11443
  }
11444
11444
  }, x = s.width || e.renderConfig?.width || 720, C = s.height || e.renderConfig?.height || 1280, v = s.fps || e.fps || 30;
11445
- l.emit(z.ExportStart, {
11445
+ l.emit(O.ExportStart, {
11446
11446
  format: s.format || "mp4",
11447
11447
  width: x,
11448
11448
  height: C,
@@ -11456,7 +11456,7 @@ class zo {
11456
11456
  requestedFormat: s.format ?? "mp4",
11457
11457
  requestedAudioCodec: s.audioCodec ?? "aac"
11458
11458
  });
11459
- n && l.emit(z.ExportProgress, {
11459
+ n && l.emit(O.ExportProgress, {
11460
11460
  progress: 0.4,
11461
11461
  stage: "encoding",
11462
11462
  message: n
@@ -11481,7 +11481,7 @@ class zo {
11481
11481
  try {
11482
11482
  await f;
11483
11483
  } catch (y) {
11484
- l.emit(z.ExportProgress, {
11484
+ l.emit(O.ExportProgress, {
11485
11485
  progress: 0.95,
11486
11486
  stage: "encoding",
11487
11487
  message: `Audio skipped (runtime failure): ${y instanceof Error ? y.message : String(y)}`
@@ -11492,16 +11492,16 @@ class zo {
11492
11492
  if (await h.finalizeExportAudio(), o?.aborted)
11493
11493
  throw new DOMException("Export aborted", "AbortError");
11494
11494
  const d = await r.finalize();
11495
- return l.emit(z.ExportComplete, {
11495
+ return l.emit(O.ExportComplete, {
11496
11496
  size: d?.size ?? g,
11497
11497
  durationMs: e.durationUs / 1e3,
11498
11498
  format: s.format || "mp4"
11499
- }), l.emit(z.ExportProgress, {
11499
+ }), l.emit(O.ExportProgress, {
11500
11500
  progress: 1,
11501
11501
  stage: "muxing"
11502
11502
  }), d;
11503
11503
  } catch (T) {
11504
- throw l.emit(z.ExportError, {
11504
+ throw l.emit(O.ExportError, {
11505
11505
  error: T instanceof Error ? T : new Error(String(T)),
11506
11506
  stage: "export"
11507
11507
  }), T;
@@ -11513,7 +11513,7 @@ class zo {
11513
11513
  * Preload all resources (0-40% progress)
11514
11514
  */
11515
11515
  async preloadResources(e, s, r, h) {
11516
- r.emit(z.ExportProgress, {
11516
+ r.emit(O.ExportProgress, {
11517
11517
  progress: 0,
11518
11518
  stage: "preparing",
11519
11519
  message: "Loading and parsing resources..."
@@ -11538,7 +11538,7 @@ class zo {
11538
11538
  }
11539
11539
  g++;
11540
11540
  const C = m > 0 ? g / m * 0.4 : 0.4;
11541
- r.emit(z.ExportProgress, {
11541
+ r.emit(O.ExportProgress, {
11542
11542
  progress: C,
11543
11543
  stage: "preparing",
11544
11544
  message: `Loading resources... (${g}/${m})`
@@ -11601,7 +11601,7 @@ class zo {
11601
11601
  });
11602
11602
  s.writeVideoChunk(U, y), u = k + _;
11603
11603
  const I = 0.4 + k / r.durationUs * 0.6;
11604
- this.deps.eventBus.emit(z.ExportProgress, {
11604
+ this.deps.eventBus.emit(O.ExportProgress, {
11605
11605
  progress: Math.min(1, I),
11606
11606
  stage: "encoding",
11607
11607
  timeUs: k
@@ -11709,7 +11709,7 @@ class Oo {
11709
11709
  }), this.setupResourceFirstFrameHandler();
11710
11710
  }
11711
11711
  setupResourceFirstFrameHandler() {
11712
- this.eventBus.on(z.ResourceFirstFrameReady, async (e) => {
11712
+ this.eventBus.on(O.ResourceFirstFrameReady, async (e) => {
11713
11713
  const { resourceId: s, clipId: r, index: h, chunks: l } = e;
11714
11714
  if (!this.compositionModel) return;
11715
11715
  const u = this.compositionModel.findClip(r);
@@ -11745,7 +11745,7 @@ class Oo {
11745
11745
  async setCompositionModel(e) {
11746
11746
  this.cacheManager.clear(), this.cancelActiveDecoding(), this.audio.preview.stopPlayback(), this.audio.preview.invalidatePreviewMixCache(), this.modelToken++, this.compositionModel = e, this.planner.setModel(e);
11747
11747
  const s = this.resourceLoader.setModel(e);
11748
- this.audio.prepare.setModel(e), await s, this.eventBus.emit(z.ModelSet, e), this.eventBus.emit(z.CompositionUpdated, {
11748
+ this.audio.prepare.setModel(e), await s, this.eventBus.emit(O.ModelSet, e), this.eventBus.emit(O.CompositionUpdated, {
11749
11749
  trackCount: e.tracks.length,
11750
11750
  clipCount: e.tracks.reduce((r, h) => r + h.clips.length, 0),
11751
11751
  durationUs: e.durationUs
@@ -11755,7 +11755,7 @@ class Oo {
11755
11755
  if (!this.compositionModel)
11756
11756
  throw new Error("No composition model set");
11757
11757
  const s = tr(this.compositionModel, e);
11758
- this.planner.applyPatch(e, s), this.eventBus.emit(z.PatchApplied, {
11758
+ this.planner.applyPatch(e, s), this.eventBus.emit(O.PatchApplied, {
11759
11759
  operations: e.operations.length,
11760
11760
  affectedClips: Array.from(s)
11761
11761
  });
@@ -12083,7 +12083,7 @@ class Oo {
12083
12083
  return l;
12084
12084
  }
12085
12085
  }
12086
- var O = /* @__PURE__ */ ((a) => (a.Idle = "idle", a.Buffering = "buffering", a.Playing = "playing", a.Paused = "paused", a.Seeking = "seeking", a.Ended = "ended", a))(O || {});
12086
+ var z = /* @__PURE__ */ ((a) => (a.Idle = "idle", a.Buffering = "buffering", a.Playing = "playing", a.Paused = "paused", a.Seeking = "seeking", a.Ended = "ended", a))(z || {});
12087
12087
  const j = {
12088
12088
  Play: "play",
12089
12089
  Pause: "pause",
@@ -13282,7 +13282,7 @@ class Jo {
13282
13282
  }
13283
13283
  }
13284
13284
  class ea {
13285
- state = O.Idle;
13285
+ state = z.Idle;
13286
13286
  wantsPlay = !1;
13287
13287
  frozenTimeUs = null;
13288
13288
  token = 0;
@@ -13309,13 +13309,13 @@ class ea {
13309
13309
  };
13310
13310
  switch (e.type) {
13311
13311
  case j.ModelSet:
13312
- return h(), r.push({ type: P.CancelRaf }), r.push({ type: P.StopAudio }), r.push({ type: P.SetLastAudioScheduleTime, timeUs: 0 }), o(null), (this.state === O.Playing || this.state === O.Buffering || this.state === O.Seeking) && l(O.Paused), { token: this.token, commands: r };
13312
+ return h(), r.push({ type: P.CancelRaf }), r.push({ type: P.StopAudio }), r.push({ type: P.SetLastAudioScheduleTime, timeUs: 0 }), o(null), (this.state === z.Playing || this.state === z.Buffering || this.state === z.Seeking) && l(z.Paused), { token: this.token, commands: r };
13313
13313
  case j.Play: {
13314
13314
  const g = h(), w = this.state;
13315
- if (u(!0), this.state === O.Ended && p(0), this.state === O.Playing)
13315
+ if (u(!0), this.state === z.Ended && p(0), this.state === z.Playing)
13316
13316
  return { token: g, commands: r };
13317
- l(O.Playing), o(null), r.push({ type: P.SetLastAudioScheduleTime, timeUs: 0 }), r.push({ type: P.CancelRaf });
13318
- const x = w === O.Idle || w === O.Ended ? O.Idle : O.Paused;
13317
+ l(z.Playing), o(null), r.push({ type: P.SetLastAudioScheduleTime, timeUs: 0 }), r.push({ type: P.CancelRaf });
13318
+ const x = w === z.Idle || w === z.Ended ? z.Idle : z.Paused;
13319
13319
  return r.push({
13320
13320
  type: P.Try,
13321
13321
  logPrefix: "[PlaybackController] Failed to start playback:",
@@ -13335,7 +13335,7 @@ class ea {
13335
13335
  { type: P.StartAudioPlayback, timeUs: s.currentTimeUs },
13336
13336
  { type: P.SyncTimeBaseToAudioClock, timeUs: s.currentTimeUs },
13337
13337
  { type: P.StartRafLoop },
13338
- { type: P.Emit, event: z.PlaybackPlay }
13338
+ { type: P.Emit, event: O.PlaybackPlay }
13339
13339
  ]
13340
13340
  }
13341
13341
  }), { token: g, commands: r };
@@ -13343,13 +13343,13 @@ class ea {
13343
13343
  case j.Pause: {
13344
13344
  h();
13345
13345
  const g = this.state;
13346
- return u(!1), o(null), r.push({ type: P.CancelRaf }), r.push({ type: P.StopAudio }), g !== O.Idle && g !== O.Ended && l(O.Paused), (g === O.Playing || g === O.Buffering || g === O.Seeking) && r.push({ type: P.Emit, event: z.PlaybackPause }), { token: this.token, commands: r };
13346
+ return u(!1), o(null), r.push({ type: P.CancelRaf }), r.push({ type: P.StopAudio }), g !== z.Idle && g !== z.Ended && l(z.Paused), (g === z.Playing || g === z.Buffering || g === z.Seeking) && r.push({ type: P.Emit, event: O.PlaybackPause }), { token: this.token, commands: r };
13347
13347
  }
13348
13348
  case j.Stop:
13349
- return h(), u(!1), o(null), l(O.Idle), p(0), r.push({ type: P.CancelRaf }), r.push({ type: P.StopAudio }), r.push({ type: P.ClearCanvas }), r.push({ type: P.ResetAudioSession }), r.push({ type: P.ResetAudioPlaybackStates }), r.push({ type: P.SetLastAudioScheduleTime, timeUs: 0 }), r.push({ type: P.Emit, event: z.PlaybackStop }), { token: this.token, commands: r };
13349
+ return h(), u(!1), o(null), l(z.Idle), p(0), r.push({ type: P.CancelRaf }), r.push({ type: P.StopAudio }), r.push({ type: P.ClearCanvas }), r.push({ type: P.ResetAudioSession }), r.push({ type: P.ResetAudioPlaybackStates }), r.push({ type: P.SetLastAudioScheduleTime, timeUs: 0 }), r.push({ type: P.Emit, event: O.PlaybackStop }), { token: this.token, commands: r };
13350
13350
  case j.Seek: {
13351
13351
  const g = h(), w = this.state, x = m(e.timeUs, e.durationUs);
13352
- return p(x), o(x), l(O.Seeking), r.push({ type: P.CancelRaf }), r.push({ type: P.StopAudio }), r.push({ type: P.SetLastAudioScheduleTime, timeUs: 0 }), r.push({
13352
+ return p(x), o(x), l(z.Seeking), r.push({ type: P.CancelRaf }), r.push({ type: P.StopAudio }), r.push({ type: P.SetLastAudioScheduleTime, timeUs: 0 }), r.push({
13353
13353
  type: P.Try,
13354
13354
  logPrefix: "[PlaybackController] Seek error:",
13355
13355
  emitPlaybackError: !0,
@@ -13380,7 +13380,7 @@ class ea {
13380
13380
  }), { token: g, commands: r };
13381
13381
  }
13382
13382
  case j.EnterBuffering:
13383
- return (e.bumpToken ?? !1) && h(), this.state !== O.Playing ? { token: this.token, commands: r } : (o(e.timeUs), l(O.Buffering), r.push({ type: P.Emit, event: z.PlaybackBuffering }), r.push({ type: P.CancelRaf }), r.push({ type: P.StopAudio }), r.push({
13383
+ return (e.bumpToken ?? !1) && h(), this.state !== z.Playing ? { token: this.token, commands: r } : (o(e.timeUs), l(z.Buffering), r.push({ type: P.Emit, event: O.PlaybackBuffering }), r.push({ type: P.CancelRaf }), r.push({ type: P.StopAudio }), r.push({
13384
13384
  type: P.Try,
13385
13385
  logPrefix: "[PlaybackController] Buffering error:",
13386
13386
  emitPlaybackError: !0,
@@ -13409,11 +13409,11 @@ class ea {
13409
13409
  }
13410
13410
  }), { token: this.token, commands: r });
13411
13411
  case j.BufferingResolved:
13412
- return this.state !== O.Buffering ? { token: this.token, commands: r } : (o(null), this.wantsPlay ? (l(O.Playing), r.push({
13412
+ return this.state !== z.Buffering ? { token: this.token, commands: r } : (o(null), this.wantsPlay ? (l(z.Playing), r.push({
13413
13413
  type: P.Try,
13414
13414
  logPrefix: "[PlaybackController] Failed to start playback:",
13415
13415
  emitPlaybackError: !0,
13416
- onError: { type: j.StartFailed, fallbackState: O.Paused },
13416
+ onError: { type: j.StartFailed, fallbackState: z.Paused },
13417
13417
  command: {
13418
13418
  type: P.Seq,
13419
13419
  commands: [
@@ -13422,20 +13422,20 @@ class ea {
13422
13422
  { type: P.StartAudioPlayback, timeUs: e.timeUs },
13423
13423
  { type: P.SyncTimeBaseToAudioClock, timeUs: e.timeUs },
13424
13424
  { type: P.StartRafLoop },
13425
- { type: P.Emit, event: z.PlaybackPlay }
13425
+ { type: P.Emit, event: O.PlaybackPlay }
13426
13426
  ]
13427
13427
  }
13428
- })) : l(O.Paused), { token: this.token, commands: r });
13428
+ })) : l(z.Paused), { token: this.token, commands: r });
13429
13429
  case j.SeekResolved:
13430
- return this.state !== O.Seeking ? { token: this.token, commands: r } : (o(null), r.push({
13430
+ return this.state !== z.Seeking ? { token: this.token, commands: r } : (o(null), r.push({
13431
13431
  type: P.Emit,
13432
- event: z.PlaybackSeek,
13432
+ event: O.PlaybackSeek,
13433
13433
  payload: { timeUs: s.currentTimeUs }
13434
- }), this.wantsPlay ? (l(O.Playing), r.push({
13434
+ }), this.wantsPlay ? (l(z.Playing), r.push({
13435
13435
  type: P.Try,
13436
13436
  logPrefix: "[PlaybackController] Failed to start playback:",
13437
13437
  emitPlaybackError: !0,
13438
- onError: { type: j.StartFailed, fallbackState: O.Paused },
13438
+ onError: { type: j.StartFailed, fallbackState: z.Paused },
13439
13439
  command: {
13440
13440
  type: P.Seq,
13441
13441
  commands: [
@@ -13448,16 +13448,16 @@ class ea {
13448
13448
  { type: P.StartAudioPlayback, timeUs: s.currentTimeUs },
13449
13449
  { type: P.SyncTimeBaseToAudioClock, timeUs: s.currentTimeUs },
13450
13450
  { type: P.StartRafLoop },
13451
- { type: P.Emit, event: z.PlaybackPlay }
13451
+ { type: P.Emit, event: O.PlaybackPlay }
13452
13452
  ]
13453
13453
  }
13454
13454
  })) : l(
13455
- e.previousState === O.Idle ? O.Idle : O.Paused
13455
+ e.previousState === z.Idle ? z.Idle : z.Paused
13456
13456
  ), { token: this.token, commands: r });
13457
13457
  case j.StartFailed:
13458
13458
  return u(!1), o(null), l(e.fallbackState), r.push({ type: P.CancelRaf }), r.push({ type: P.StopAudio }), r.push({ type: P.SetLastAudioScheduleTime, timeUs: 0 }), { token: this.token, commands: r };
13459
13459
  case j.ClockTick: {
13460
- if (this.state !== O.Playing)
13460
+ if (this.state !== z.Playing)
13461
13461
  return { token: this.token, commands: r };
13462
13462
  if (this.frozenTimeUs !== null)
13463
13463
  return { token: this.token, commands: r };
@@ -13465,13 +13465,13 @@ class ea {
13465
13465
  return g >= e.durationUs ? (e.loop ? (p(0), r.push({
13466
13466
  type: P.SetStartTimeBase,
13467
13467
  startTimeUs: e.audioNowUs
13468
- }), r.push({ type: P.ResetAudioPlaybackStates }), r.push({ type: P.SetLastAudioScheduleTime, timeUs: 0 }), r.push({ type: P.InitWindow, timeUs: 0 })) : (u(!1), l(O.Ended), r.push({ type: P.CancelRaf }), r.push({ type: P.StopAudio }), p(0), r.push({
13468
+ }), r.push({ type: P.ResetAudioPlaybackStates }), r.push({ type: P.SetLastAudioScheduleTime, timeUs: 0 }), r.push({ type: P.InitWindow, timeUs: 0 })) : (u(!1), l(z.Ended), r.push({ type: P.CancelRaf }), r.push({ type: P.StopAudio }), p(0), r.push({
13469
13469
  type: P.Emit,
13470
- event: z.PlaybackEnded,
13470
+ event: O.PlaybackEnded,
13471
13471
  payload: { timeUs: e.durationUs }
13472
13472
  })), { token: this.token, commands: r }) : (p(g), r.push({
13473
13473
  type: P.Emit,
13474
- event: z.PlaybackTimeUpdate,
13474
+ event: O.PlaybackTimeUpdate,
13475
13475
  payload: { timeUs: g }
13476
13476
  }), { token: this.token, commands: r });
13477
13477
  }
@@ -13511,8 +13511,11 @@ class ta {
13511
13511
  seekFlushRafId = null;
13512
13512
  seekInFlight = null;
13513
13513
  // If user drags far away while a seek is decoding, cancel it to avoid visible lag.
13514
- SEEK_CANCEL_DISTANCE_US = 5e5;
13515
- // 500ms
13514
+ SEEK_CANCEL_DISTANCE_US = 5e6;
13515
+ // 5s
13516
+ isSeekActive() {
13517
+ return this.pendingSeekTimeUs !== null || this.seekInFlight !== null || this.fsm.snapshot.state === z.Seeking;
13518
+ }
13516
13519
  // Unified window management for both video and audio
13517
13520
  windowEnd = 0;
13518
13521
  WINDOW_DURATION = 3e6;
@@ -13575,25 +13578,25 @@ class ta {
13575
13578
  this.seekInFlight = { targetUs: e, done: s }, s.finally(() => {
13576
13579
  const r = this.pendingSeekWaiters;
13577
13580
  this.pendingSeekWaiters = [];
13578
- for (const h of r) h();
13579
- this.seekInFlight?.targetUs === e && (this.seekInFlight = null), this.pendingSeekTimeUs === null && !this.orchestrator.cacheManager.isExporting && this.preheatNextWindow(), this.pendingSeekTimeUs !== null && this.seekFlushRafId === null && (this.seekFlushRafId = requestAnimationFrame(() => {
13581
+ for (const l of r) l();
13582
+ this.seekInFlight?.targetUs === e && (this.seekInFlight = null), this.pendingSeekTimeUs === null && !this.orchestrator.cacheManager.isExporting && this.fsm.snapshot.state === z.Playing && this.preheatNextWindow(), this.pendingSeekTimeUs !== null && this.seekFlushRafId === null && (this.seekFlushRafId = requestAnimationFrame(() => {
13580
13583
  this.seekFlushRafId = null, this.flushCoalescedSeek();
13581
13584
  }));
13582
13585
  });
13583
13586
  }
13584
13587
  setRate(e) {
13585
13588
  const s = this.currentTimeUs;
13586
- this.playbackRate = e, this.startTimeUs = this.audioContext.currentTime * 1e6 - s / e, this.audioSession.setPlaybackRate(this.playbackRate), this.eventBus.emit(z.PlaybackRateChange, { rate: e });
13589
+ this.playbackRate = e, this.startTimeUs = this.audioContext.currentTime * 1e6 - s / e, this.audioSession.setPlaybackRate(this.playbackRate), this.eventBus.emit(O.PlaybackRateChange, { rate: e });
13587
13590
  }
13588
13591
  setVolume(e) {
13589
- this.volume = Math.max(0, Math.min(1, e)), this.audioSession.setVolume(this.volume), this.eventBus.emit(z.PlaybackVolumeChange, { volume: this.volume });
13592
+ this.volume = Math.max(0, Math.min(1, e)), this.audioSession.setVolume(this.volume), this.eventBus.emit(O.PlaybackVolumeChange, { volume: this.volume });
13590
13593
  }
13591
13594
  setMute(e) {
13592
13595
  if (e) {
13593
13596
  this.audioSession.stopPlayback();
13594
13597
  return;
13595
13598
  }
13596
- this.fsm.snapshot.state === O.Playing && this.audioSession.startPlayback(this.currentTimeUs, this.audioContext);
13599
+ this.fsm.snapshot.state === z.Playing && this.audioSession.startPlayback(this.currentTimeUs, this.audioContext);
13597
13600
  }
13598
13601
  setLoop(e) {
13599
13602
  this.loop = e;
@@ -13602,7 +13605,7 @@ class ta {
13602
13605
  return this.orchestrator.compositionModel?.durationUs ?? 0;
13603
13606
  }
13604
13607
  get isPlaying() {
13605
- return this.fsm.snapshot.state === O.Playing;
13608
+ return this.fsm.snapshot.state === z.Playing;
13606
13609
  }
13607
13610
  resume() {
13608
13611
  this.play();
@@ -13657,7 +13660,7 @@ class ta {
13657
13660
  p instanceof Nt || // Missing moov may be caused by incomplete/corrupted cache and can be retried via recovery.
13658
13661
  p instanceof Le
13659
13662
  );
13660
- this.eventBus.emit(z.PlaybackError, p), this.eventBus.emit(z.Error, {
13663
+ this.eventBus.emit(O.PlaybackError, p), this.eventBus.emit(O.Error, {
13661
13664
  source: "playback",
13662
13665
  error: p,
13663
13666
  context: {
@@ -13764,7 +13767,7 @@ class ta {
13764
13767
  return;
13765
13768
  }
13766
13769
  case P.StartRafLoop: {
13767
- this.startPlaybackLoop(s);
13770
+ this.startPlaybackLoop(s), !this.orchestrator.cacheManager.isExporting && this.fsm.snapshot.state === z.Playing && this.preheatNextWindow();
13768
13771
  return;
13769
13772
  }
13770
13773
  }
@@ -13781,7 +13784,7 @@ class ta {
13781
13784
  });
13782
13785
  }
13783
13786
  async onRafTick(e) {
13784
- if (!this.isCurrentToken(e) || this.fsm.snapshot.state !== O.Playing)
13787
+ if (!this.isCurrentToken(e) || this.fsm.snapshot.state !== z.Playing)
13785
13788
  return;
13786
13789
  const s = (this.audioContext.currentTime * 1e6 - this.startTimeUs) * this.playbackRate;
13787
13790
  if (this.dispatch({
@@ -13790,7 +13793,7 @@ class ta {
13790
13793
  durationUs: this.duration,
13791
13794
  loop: this.loop,
13792
13795
  audioNowUs: this.audioContext.currentTime * 1e6
13793
- }), !this.isCurrentToken(e) || this.fsm.snapshot.state !== O.Playing)
13796
+ }), !this.isCurrentToken(e) || this.fsm.snapshot.state !== z.Playing)
13794
13797
  return;
13795
13798
  if (this.currentTimeUs - this.lastAudioScheduleTime >= this.AUDIO_SCHEDULE_INTERVAL && (this.audioSession.scheduleAudio(this.currentTimeUs, this.audioContext), this.lastAudioScheduleTime = this.currentTimeUs), this.audioSession.shouldEnterBufferingForUpcomingPreviewAudio(this.currentTimeUs)) {
13796
13799
  this.audioSession.ensureAudioForTime(this.currentTimeUs, { mode: "probe" }), this.dispatch({
@@ -13803,7 +13806,7 @@ class ta {
13803
13806
  const r = await this.orchestrator.getRenderState(this.currentTimeUs, {
13804
13807
  mode: "probe"
13805
13808
  });
13806
- if (!(!this.isCurrentToken(e) || this.fsm.snapshot.state !== O.Playing)) {
13809
+ if (!(!this.isCurrentToken(e) || this.fsm.snapshot.state !== z.Playing)) {
13807
13810
  if (!r) {
13808
13811
  if (this.isTerminalVideoErrorAtTime(this.currentTimeUs)) {
13809
13812
  this.clearCanvas(), this.finalizeFrameAndContinue(e);
@@ -13812,11 +13815,11 @@ class ta {
13812
13815
  this.dispatch({ type: j.EnterBuffering, timeUs: this.currentTimeUs });
13813
13816
  return;
13814
13817
  }
13815
- await this.compose(this.currentTimeUs, r), !(!this.isCurrentToken(e) || this.fsm.snapshot.state !== O.Playing) && this.finalizeFrameAndContinue(e);
13818
+ await this.compose(this.currentTimeUs, r), !(!this.isCurrentToken(e) || this.fsm.snapshot.state !== z.Playing) && this.finalizeFrameAndContinue(e);
13816
13819
  }
13817
13820
  }
13818
13821
  finalizeFrameAndContinue(e) {
13819
- this.updateFps(), this.frameCount++, this.orchestrator.cacheManager.setWindow(this.currentTimeUs), this.checkAndPreheatWindow(), !(!this.isCurrentToken(e) || this.fsm.snapshot.state !== O.Playing) && this.startPlaybackLoop(e);
13822
+ this.updateFps(), this.frameCount++, this.orchestrator.cacheManager.setWindow(this.currentTimeUs), this.checkAndPreheatWindow(), !(!this.isCurrentToken(e) || this.fsm.snapshot.state !== z.Playing) && this.startPlaybackLoop(e);
13820
13823
  }
13821
13824
  updateFps() {
13822
13825
  const e = performance.now();
@@ -13830,30 +13833,30 @@ class ta {
13830
13833
  this.windowEnd = e + this.WINDOW_DURATION, this.preheatInProgress = !1, this.orchestrator.cacheManager.setWindow(e);
13831
13834
  }
13832
13835
  checkAndPreheatWindow() {
13833
- if (this.orchestrator.cacheManager.isExporting || this.preheatInProgress || this.fsm.snapshot.state !== O.Playing)
13834
- return;
13835
- const e = this.windowEnd - this.currentTimeUs;
13836
- if (e < 0) {
13836
+ const e = this.orchestrator.cacheManager.isExporting, s = this.preheatInProgress, r = this.fsm.snapshot.state === z.Playing, h = this.windowEnd - this.currentTimeUs;
13837
+ if (h < 0) {
13837
13838
  this.initWindow(this.currentTimeUs);
13838
13839
  return;
13839
13840
  }
13840
- e > 0 && e <= this.PREHEAT_DISTANCE && this.preheatNextWindow();
13841
+ const l = h > 0 && h <= this.PREHEAT_DISTANCE;
13842
+ e || s || !r || !l || this.isSeekActive() || this.preheatNextWindow();
13841
13843
  }
13842
13844
  async preheatNextWindow() {
13843
- if (!this.orchestrator.cacheManager.isExporting && !this.preheatInProgress) {
13845
+ const e = this.orchestrator.cacheManager.isExporting, s = this.preheatInProgress;
13846
+ if (!(e || s || this.isSeekActive())) {
13844
13847
  this.preheatInProgress = !0;
13845
13848
  try {
13846
- const e = this.currentTimeUs, s = e + this.WINDOW_DURATION, r = this.orchestrator.compositionModel?.getClipsInRange(e, s) ?? [], h = [];
13847
- for (const l of r) {
13848
- if (!Ut(l)) continue;
13849
- const u = Math.max(0, e - l.startUs), o = Math.min(l.durationUs, s - l.startUs);
13850
- u >= o || h.push(
13851
- this.orchestrator.preheatClipWindow(l.id, u, o, e)
13849
+ const h = this.currentTimeUs, l = h + this.WINDOW_DURATION, u = this.orchestrator.compositionModel?.getClipsInRange(h, l) ?? [], o = [];
13850
+ for (const p of u) {
13851
+ if (!Ut(p)) continue;
13852
+ const m = Math.max(0, h - p.startUs), g = Math.min(p.durationUs, l - p.startUs);
13853
+ m >= g || o.push(
13854
+ this.orchestrator.preheatClipWindow(p.id, m, g, h)
13852
13855
  );
13853
13856
  }
13854
- await Promise.all(h), this.windowEnd = s;
13855
- } catch (e) {
13856
- console.warn("[PlaybackController] Preheat failed:", e);
13857
+ await Promise.all(o), this.windowEnd = l;
13858
+ } catch (h) {
13859
+ console.warn("[PlaybackController] Preheat failed:", h);
13857
13860
  } finally {
13858
13861
  this.preheatInProgress = !1;
13859
13862
  }
@@ -13891,10 +13894,10 @@ class ta {
13891
13894
  const e = this.pendingSeekWaiters;
13892
13895
  this.pendingSeekWaiters = [];
13893
13896
  for (const s of e) s();
13894
- this.eventBus.off(z.CacheCover, this.onCacheCover), this.eventBus.off(z.ModelSet, this.onModelSet), this.videoComposer && (this.videoComposer.dispose(), this.videoComposer = null);
13897
+ this.eventBus.off(O.CacheCover, this.onCacheCover), this.eventBus.off(O.ModelSet, this.onModelSet), this.videoComposer && (this.videoComposer.dispose(), this.videoComposer = null);
13895
13898
  }
13896
13899
  onCacheCover = () => {
13897
- this.fsm.snapshot.state === O.Idle && this.currentTimeUs === 0 && this.renderCurrentFrame(0, { mode: "blocking" });
13900
+ this.fsm.snapshot.state === z.Idle && this.currentTimeUs === 0 && this.renderCurrentFrame(0, { mode: "blocking" });
13898
13901
  };
13899
13902
  onModelSet = () => {
13900
13903
  if (!this.videoComposer || !this.orchestrator.compositionModel) return;
@@ -13908,7 +13911,7 @@ class ta {
13908
13911
  }), this.orchestrator.cacheManager.isExporting || this.audioSession.ensureAudioForTime(this.currentTimeUs, { mode: "probe" }), this.renderCurrentFrame(this.currentTimeUs, { mode: "blocking" });
13909
13912
  };
13910
13913
  setupEventListeners() {
13911
- this.eventBus.on(z.CacheCover, this.onCacheCover), this.eventBus.on(z.ModelSet, this.onModelSet);
13914
+ this.eventBus.on(O.CacheCover, this.onCacheCover), this.eventBus.on(O.ModelSet, this.onModelSet);
13912
13915
  }
13913
13916
  isVideoResourceReadyAtTime(e) {
13914
13917
  const s = this.orchestrator.compositionModel;
@@ -14081,7 +14084,7 @@ class ki {
14081
14084
  async setCompositionModel(e) {
14082
14085
  this.ensureNotDestroyed(), this.playbackController?.pause();
14083
14086
  const s = e instanceof Ui ? e : new Ui(e);
14084
- await this.orchestrator.setCompositionModel(s), this.model = s, this.setState("ready"), this.eventBus.emit(z.Ready, {
14087
+ await this.orchestrator.setCompositionModel(s), this.model = s, this.setState("ready"), this.eventBus.emit(O.Ready, {
14085
14088
  trackCount: e.tracks.length,
14086
14089
  clipCount: e.tracks.reduce(
14087
14090
  (r, h) => r + h.clips?.length || 0,
@@ -14322,13 +14325,13 @@ async function ra() {
14322
14325
  }
14323
14326
  };
14324
14327
  let _ = 0;
14325
- if (o.events.on(z.ExportProgress, (b) => {
14328
+ if (o.events.on(O.ExportProgress, (b) => {
14326
14329
  window.runnerReportProgress(b);
14327
14330
  const U = Date.now();
14328
14331
  U - _ >= 1e3 && (_ = U, console.log("[meframe-runner] progress", b));
14329
- }), o.events.on(z.ExportStart, (b) => {
14332
+ }), o.events.on(O.ExportStart, (b) => {
14330
14333
  console.log("[meframe-runner] export:start", b);
14331
- }), o.events.on(z.ExportComplete, (b) => {
14334
+ }), o.events.on(O.ExportComplete, (b) => {
14332
14335
  console.log("[meframe-runner] export:complete", b);
14333
14336
  }), console.log("[meframe-runner] export()..."), await o.export({
14334
14337
  ...s,
@@ -71,6 +71,13 @@ WebCodecs 等 API 需要 secure/trustworthy origin。`exportToStore({ pageUrl })
71
71
 
72
72
  > 核心原则:`CompositionModelData.resources[*].uri`、`workerPath` 指向的文件,都必须能在 Chromium 里直接 `fetch()`/加载到。
73
73
 
74
+ 新增(默认行为):
75
+
76
+ - 若 `exportToStore({ workerPath })` **未提供**,`@meframe/server` 会临时启动一个本地 HTTP 服务,
77
+ 自动托管 `@meframe/core/dist/workers` 并把它的 base URL 作为 `workerPath` 注入到 runner。
78
+ - 你可以通过 `ServerExporterOptions.workerServer.enabled = false` 关闭该行为,或用
79
+ `ServerExporterOptions.workerServer.workerDir` 指向自定义目录。
80
+
74
81
  #### 2.4 音频(AAC)能力说明(强烈建议阅读)
75
82
 
76
83
  当前 `mp4` 输出的音频轨 **只能是 AAC**(对应 WebCodecs `AudioEncoder` 的 `codec: 'mp4a.40.2'`)。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meframe/server",
3
- "version": "0.0.9",
3
+ "version": "0.1.0",
4
4
  "description": "Server-side exporter for @meframe/core (browser-driven, multipart upload via injected store)",
5
5
  "type": "module",
6
6
  "main": "./dist/esm/index.js",
@@ -20,7 +20,7 @@
20
20
  ],
21
21
  "dependencies": {
22
22
  "puppeteer-core": "^23.5.0",
23
- "@meframe/core": "0.3.1"
23
+ "@meframe/core": "0.3.2"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@aws-sdk/client-s3": "^3.758.0",