@mebius-io/web 0.5.2 → 0.5.4

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,7 +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
+ var UPSTREAM_LATENCY_MS = 800;
43051
43051
  function stalledWithData(video, ms) {
43052
43052
  if (video.currentTime > 0) return Promise.resolve(false);
43053
43053
  return new Promise((resolve) => {
@@ -43177,13 +43177,24 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
43177
43177
  return { bitrateKbps, framesPerSecond, latencyMs: void 0 };
43178
43178
  }
43179
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.
43180
+ * Estimate — FLV carries no wall clock, so this is measured where possible
43181
+ * and assumed where not (see {@link UPSTREAM_LATENCY_MS}).
43182
+ *
43183
+ * The measurable half is the decoded media queued ahead of the playhead:
43184
+ * whatever is buffered but not yet shown is, by definition, how far behind
43185
+ * the newest received frame this viewer is watching. A flat guess for the
43186
+ * whole delay was previously used, and being too generous costs real time —
43187
+ * every millisecond of over-estimate is a caption withheld for no reason,
43188
+ * on top of the STT latency the viewer already pays.
43184
43189
  */
43185
43190
  playheadEpochMs() {
43186
- return Date.now() - ESTIMATED_LATENCY_MS;
43191
+ let bufferedAheadMs = 0;
43192
+ const ranges = this.video?.buffered;
43193
+ if (ranges && ranges.length > 0 && this.video) {
43194
+ const ahead = ranges.end(ranges.length - 1) - this.video.currentTime;
43195
+ if (Number.isFinite(ahead) && ahead > 0) bufferedAheadMs = ahead * 1e3;
43196
+ }
43197
+ return Date.now() - UPSTREAM_LATENCY_MS - bufferedAheadMs;
43187
43198
  }
43188
43199
  };
43189
43200
 
@@ -43416,6 +43427,7 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
43416
43427
  // src/captions.ts
43417
43428
  var TICK_MS = 100;
43418
43429
  var STALE_MS = 5e3;
43430
+ var MAX_QUEUE_MS = 1500;
43419
43431
  var MebiusCaptions = class extends TypedEmitter {
43420
43432
  /** @internal */
43421
43433
  constructor(signaling, player, opts) {
@@ -43457,22 +43469,27 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
43457
43469
  if (frame.type !== "caption" || !frame.segmentId) return;
43458
43470
  const prev = this.pending.get(frame.segmentId);
43459
43471
  if (prev && (frame.rev ?? 0) < (prev.rev ?? 0)) return;
43472
+ frame.receivedAtMs = Date.now();
43460
43473
  this.pending.set(frame.segmentId, frame);
43461
43474
  }
43462
43475
  tick() {
43463
43476
  const now2 = this.player.currentEpochMs();
43464
- if (now2 == null) return;
43465
43477
  for (const [id, frame] of this.pending) {
43466
43478
  const due = frame.epochMs ?? 0;
43467
- if (due > now2) continue;
43468
- if (due < now2 - STALE_MS) {
43479
+ const waitedMs = Date.now() - (frame.receivedAtMs ?? 0);
43480
+ const dueNow = now2 == null ? true : due <= now2;
43481
+ if (!dueNow) {
43482
+ if (waitedMs < MAX_QUEUE_MS) continue;
43483
+ }
43484
+ if (waitedMs > STALE_MS && this.shown.has(id)) {
43469
43485
  this.pending.delete(id);
43470
- if (this.shown.delete(id)) this.emit("cleared", { segmentId: id });
43486
+ this.shown.delete(id);
43487
+ this.emit("cleared", { segmentId: id });
43471
43488
  continue;
43472
43489
  }
43490
+ if (this.shown.has(id) && frame.state === "final") continue;
43473
43491
  this.shown.add(id);
43474
43492
  this.emit("segment", toSegment(id, frame, this.opts.lang));
43475
- if (frame.state === "final") this.pending.delete(id);
43476
43493
  }
43477
43494
  }
43478
43495
  };