@mebius-io/web 0.5.1 → 0.5.3

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.
@@ -43047,6 +43047,7 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
43047
43047
  var MAX_DRIFT_S = 2;
43048
43048
  var EDGE_MARGIN_S = 0.4;
43049
43049
  var AUDIO_RETRY_MS = 2500;
43050
+ var ESTIMATED_LATENCY_MS = 3e3;
43050
43051
  function stalledWithData(video, ms) {
43051
43052
  if (video.currentTime > 0) return Promise.resolve(false);
43052
43053
  return new Promise((resolve) => {
@@ -43175,6 +43176,15 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
43175
43176
  }
43176
43177
  return { bitrateKbps, framesPerSecond, latencyMs: void 0 };
43177
43178
  }
43179
+ /**
43180
+ * Estimate only — see {@link ESTIMATED_LATENCY_MS}. Without this, captions
43181
+ * never render on the FLV route at all: {@link MebiusCaptions} withholds
43182
+ * every segment until the playhead reaches its `epochMs`, and a transport
43183
+ * returning `null` here means the playhead comparison never runs.
43184
+ */
43185
+ playheadEpochMs() {
43186
+ return Date.now() - ESTIMATED_LATENCY_MS;
43187
+ }
43178
43188
  };
43179
43189
 
43180
43190
  // src/internal/transport.ts
@@ -43406,6 +43416,7 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
43406
43416
  // src/captions.ts
43407
43417
  var TICK_MS = 100;
43408
43418
  var STALE_MS = 5e3;
43419
+ var MAX_QUEUE_MS = 4e3;
43409
43420
  var MebiusCaptions = class extends TypedEmitter {
43410
43421
  /** @internal */
43411
43422
  constructor(signaling, player, opts) {
@@ -43447,22 +43458,27 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
43447
43458
  if (frame.type !== "caption" || !frame.segmentId) return;
43448
43459
  const prev = this.pending.get(frame.segmentId);
43449
43460
  if (prev && (frame.rev ?? 0) < (prev.rev ?? 0)) return;
43461
+ frame.receivedAtMs = Date.now();
43450
43462
  this.pending.set(frame.segmentId, frame);
43451
43463
  }
43452
43464
  tick() {
43453
43465
  const now2 = this.player.currentEpochMs();
43454
- if (now2 == null) return;
43455
43466
  for (const [id, frame] of this.pending) {
43456
43467
  const due = frame.epochMs ?? 0;
43457
- if (due > now2) continue;
43458
- if (due < now2 - STALE_MS) {
43468
+ const waitedMs = Date.now() - (frame.receivedAtMs ?? 0);
43469
+ const dueNow = now2 == null ? true : due <= now2;
43470
+ if (!dueNow) {
43471
+ if (waitedMs < MAX_QUEUE_MS) continue;
43472
+ }
43473
+ if (waitedMs > STALE_MS && this.shown.has(id)) {
43459
43474
  this.pending.delete(id);
43460
- if (this.shown.delete(id)) this.emit("cleared", { segmentId: id });
43475
+ this.shown.delete(id);
43476
+ this.emit("cleared", { segmentId: id });
43461
43477
  continue;
43462
43478
  }
43479
+ if (this.shown.has(id) && frame.state === "final") continue;
43463
43480
  this.shown.add(id);
43464
43481
  this.emit("segment", toSegment(id, frame, this.opts.lang));
43465
- if (frame.state === "final") this.pending.delete(id);
43466
43482
  }
43467
43483
  }
43468
43484
  };