@mebius-io/web 0.4.2 → 0.4.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.
@@ -43113,7 +43113,7 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
43113
43113
  }
43114
43114
 
43115
43115
  // src/internal/telemetry.ts
43116
- var SDK_VERSION = "web/0.4.2";
43116
+ var SDK_VERSION = "web/0.4.3";
43117
43117
  var FLUSH_INTERVAL_MS = 15e3;
43118
43118
  var MAX_BATCH = 64;
43119
43119
  function describeDevice() {
@@ -43307,6 +43307,7 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
43307
43307
  // src/player.ts
43308
43308
  var STATS_INTERVAL_MS2 = 2e3;
43309
43309
  var FIRST_FRAME_TIMEOUT_MS = 8e3;
43310
+ var ELEMENT_OWNER = /* @__PURE__ */ new WeakMap();
43310
43311
  var MebiusPlayer = class extends TypedEmitter {
43311
43312
  /** @internal */
43312
43313
  constructor(signaling, options = {}, deliveries = [], telemetry = null, userId) {
@@ -43318,13 +43319,30 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
43318
43319
  this.statsTimer = null;
43319
43320
  this.playing = false;
43320
43321
  this.reporter = null;
43322
+ /** True between a `buffering` event and the element actually resuming. */
43323
+ this.stalled = false;
43324
+ /** Cancels element listeners bound for the lifetime of one play(). */
43325
+ this.elementListeners = null;
43321
43326
  this.candidates = createViewCandidates(options.mode ?? "auto", signaling, deliveries);
43322
43327
  }
43323
43328
  /** Start playing `streamId` into the given video element or selector. */
43324
43329
  async play(streamId, viewTarget) {
43325
43330
  if (this.playing) return;
43326
43331
  const video = resolveVideoElement(viewTarget);
43332
+ const previous = ELEMENT_OWNER.get(video);
43333
+ if (previous && previous !== this) await previous.stop();
43334
+ ELEMENT_OWNER.set(video, this);
43327
43335
  this.video = video;
43336
+ this.elementListeners = new AbortController();
43337
+ video.addEventListener(
43338
+ "playing",
43339
+ () => {
43340
+ if (!this.stalled || !this.playing) return;
43341
+ this.stalled = false;
43342
+ this.emit("playing", { streamId });
43343
+ },
43344
+ { signal: this.elementListeners.signal }
43345
+ );
43328
43346
  const startedAtMs = Date.now();
43329
43347
  let lastError = null;
43330
43348
  for (const candidate of this.candidates) {
@@ -43355,6 +43373,12 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
43355
43373
  }
43356
43374
  /** Stop playback and detach from the video element. */
43357
43375
  async stop() {
43376
+ this.elementListeners?.abort();
43377
+ this.elementListeners = null;
43378
+ if (this.video && ELEMENT_OWNER.get(this.video) === this) {
43379
+ ELEMENT_OWNER.delete(this.video);
43380
+ }
43381
+ this.stalled = false;
43358
43382
  this.stopStats();
43359
43383
  await this.reporter?.stop();
43360
43384
  this.reporter = null;
@@ -43379,6 +43403,7 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
43379
43403
  });
43380
43404
  transport.onBuffering(() => {
43381
43405
  if (this.transport !== transport) return;
43406
+ this.stalled = true;
43382
43407
  this.emit("buffering", void 0);
43383
43408
  });
43384
43409
  }