@mebius-io/web 0.6.0 → 0.6.2
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.
- package/LICENSE +21 -0
- package/dist/index.cjs +56 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.global.js +56 -6
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +56 -6
- package/dist/index.js.map +1 -1
- package/package.json +11 -12
package/dist/index.d.cts
CHANGED
|
@@ -431,12 +431,30 @@ declare class MebiusCaptions extends TypedEmitter<CaptionsEventMap> {
|
|
|
431
431
|
* every 100ms tick. Comparing revs emits exactly once per actual revision.
|
|
432
432
|
*/
|
|
433
433
|
private readonly shown;
|
|
434
|
+
/** Kept so the feed can be reopened after a hidden-tab suspend. */
|
|
435
|
+
private streamId;
|
|
436
|
+
private hiddenTimer;
|
|
437
|
+
private onVisibility;
|
|
434
438
|
/** @internal */
|
|
435
439
|
constructor(signaling: SignalingClient, player: MebiusPlayer, opts: CaptionsOptions);
|
|
436
440
|
/** Open the SSE connection and begin emitting segments for `streamId`. */
|
|
437
441
|
start(streamId: string): void;
|
|
438
442
|
/** Close the connection and drop all buffered segments. */
|
|
439
443
|
stop(): void;
|
|
444
|
+
private openFeed;
|
|
445
|
+
private closeFeed;
|
|
446
|
+
/**
|
|
447
|
+
* Drop the feed while the page is hidden, restore it when it comes back.
|
|
448
|
+
*
|
|
449
|
+
* Nothing here is about rendering — a hidden tab shows no captions either
|
|
450
|
+
* way. It is about not holding a subscriber open, since that subscriber is
|
|
451
|
+
* what keeps a billed session alive on the engine.
|
|
452
|
+
*
|
|
453
|
+
* Buffered segments are deliberately kept across a suspend: they age out on
|
|
454
|
+
* their own (STALE_MS) and clearing them would blank the screen on return
|
|
455
|
+
* for no benefit.
|
|
456
|
+
*/
|
|
457
|
+
private watchVisibility;
|
|
440
458
|
private onFrame;
|
|
441
459
|
private tick;
|
|
442
460
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -431,12 +431,30 @@ declare class MebiusCaptions extends TypedEmitter<CaptionsEventMap> {
|
|
|
431
431
|
* every 100ms tick. Comparing revs emits exactly once per actual revision.
|
|
432
432
|
*/
|
|
433
433
|
private readonly shown;
|
|
434
|
+
/** Kept so the feed can be reopened after a hidden-tab suspend. */
|
|
435
|
+
private streamId;
|
|
436
|
+
private hiddenTimer;
|
|
437
|
+
private onVisibility;
|
|
434
438
|
/** @internal */
|
|
435
439
|
constructor(signaling: SignalingClient, player: MebiusPlayer, opts: CaptionsOptions);
|
|
436
440
|
/** Open the SSE connection and begin emitting segments for `streamId`. */
|
|
437
441
|
start(streamId: string): void;
|
|
438
442
|
/** Close the connection and drop all buffered segments. */
|
|
439
443
|
stop(): void;
|
|
444
|
+
private openFeed;
|
|
445
|
+
private closeFeed;
|
|
446
|
+
/**
|
|
447
|
+
* Drop the feed while the page is hidden, restore it when it comes back.
|
|
448
|
+
*
|
|
449
|
+
* Nothing here is about rendering — a hidden tab shows no captions either
|
|
450
|
+
* way. It is about not holding a subscriber open, since that subscriber is
|
|
451
|
+
* what keeps a billed session alive on the engine.
|
|
452
|
+
*
|
|
453
|
+
* Buffered segments are deliberately kept across a suspend: they age out on
|
|
454
|
+
* their own (STALE_MS) and clearing them would blank the screen on return
|
|
455
|
+
* for no benefit.
|
|
456
|
+
*/
|
|
457
|
+
private watchVisibility;
|
|
440
458
|
private onFrame;
|
|
441
459
|
private tick;
|
|
442
460
|
}
|
package/dist/index.global.js
CHANGED
|
@@ -43428,6 +43428,7 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
|
|
|
43428
43428
|
var TICK_MS = 100;
|
|
43429
43429
|
var STALE_MS = 5e3;
|
|
43430
43430
|
var MAX_QUEUE_MS = 1500;
|
|
43431
|
+
var HIDDEN_GRACE_MS = 6e4;
|
|
43431
43432
|
var MebiusCaptions = class extends TypedEmitter {
|
|
43432
43433
|
/** @internal */
|
|
43433
43434
|
constructor(signaling, player, opts) {
|
|
@@ -43445,25 +43446,74 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
|
|
|
43445
43446
|
* every 100ms tick. Comparing revs emits exactly once per actual revision.
|
|
43446
43447
|
*/
|
|
43447
43448
|
this.shown = /* @__PURE__ */ new Map();
|
|
43449
|
+
/** Kept so the feed can be reopened after a hidden-tab suspend. */
|
|
43450
|
+
this.streamId = null;
|
|
43451
|
+
this.hiddenTimer = null;
|
|
43452
|
+
this.onVisibility = null;
|
|
43448
43453
|
}
|
|
43449
43454
|
/** Open the SSE connection and begin emitting segments for `streamId`. */
|
|
43450
43455
|
start(streamId) {
|
|
43451
43456
|
if (this.es) return;
|
|
43452
|
-
|
|
43453
|
-
|
|
43457
|
+
this.streamId = streamId;
|
|
43458
|
+
this.openFeed();
|
|
43459
|
+
this.watchVisibility();
|
|
43460
|
+
}
|
|
43461
|
+
/** Close the connection and drop all buffered segments. */
|
|
43462
|
+
stop() {
|
|
43463
|
+
this.streamId = null;
|
|
43464
|
+
if (this.onVisibility && typeof document !== "undefined") {
|
|
43465
|
+
document.removeEventListener("visibilitychange", this.onVisibility);
|
|
43466
|
+
}
|
|
43467
|
+
this.onVisibility = null;
|
|
43468
|
+
if (this.hiddenTimer) clearTimeout(this.hiddenTimer);
|
|
43469
|
+
this.hiddenTimer = null;
|
|
43470
|
+
this.closeFeed();
|
|
43471
|
+
this.pending.clear();
|
|
43472
|
+
this.shown.clear();
|
|
43473
|
+
}
|
|
43474
|
+
openFeed() {
|
|
43475
|
+
if (this.es || !this.streamId) return;
|
|
43476
|
+
const es = new EventSource(this.signaling.captionsUrl(this.streamId, this.opts.lang));
|
|
43454
43477
|
es.onmessage = (ev) => this.onFrame(ev);
|
|
43455
43478
|
es.onerror = () => this.emit("error", void 0);
|
|
43456
43479
|
this.es = es;
|
|
43457
43480
|
this.timer = setInterval(() => this.tick(), TICK_MS);
|
|
43458
43481
|
}
|
|
43459
|
-
|
|
43460
|
-
stop() {
|
|
43482
|
+
closeFeed() {
|
|
43461
43483
|
this.es?.close();
|
|
43462
43484
|
this.es = null;
|
|
43463
43485
|
if (this.timer) clearInterval(this.timer);
|
|
43464
43486
|
this.timer = null;
|
|
43465
|
-
|
|
43466
|
-
|
|
43487
|
+
}
|
|
43488
|
+
/**
|
|
43489
|
+
* Drop the feed while the page is hidden, restore it when it comes back.
|
|
43490
|
+
*
|
|
43491
|
+
* Nothing here is about rendering — a hidden tab shows no captions either
|
|
43492
|
+
* way. It is about not holding a subscriber open, since that subscriber is
|
|
43493
|
+
* what keeps a billed session alive on the engine.
|
|
43494
|
+
*
|
|
43495
|
+
* Buffered segments are deliberately kept across a suspend: they age out on
|
|
43496
|
+
* their own (STALE_MS) and clearing them would blank the screen on return
|
|
43497
|
+
* for no benefit.
|
|
43498
|
+
*/
|
|
43499
|
+
watchVisibility() {
|
|
43500
|
+
if (typeof document === "undefined") return;
|
|
43501
|
+
this.onVisibility = () => {
|
|
43502
|
+
if (document.visibilityState === "hidden") {
|
|
43503
|
+
if (this.hiddenTimer) return;
|
|
43504
|
+
this.hiddenTimer = setTimeout(() => {
|
|
43505
|
+
this.hiddenTimer = null;
|
|
43506
|
+
this.closeFeed();
|
|
43507
|
+
}, HIDDEN_GRACE_MS);
|
|
43508
|
+
return;
|
|
43509
|
+
}
|
|
43510
|
+
if (this.hiddenTimer) {
|
|
43511
|
+
clearTimeout(this.hiddenTimer);
|
|
43512
|
+
this.hiddenTimer = null;
|
|
43513
|
+
}
|
|
43514
|
+
this.openFeed();
|
|
43515
|
+
};
|
|
43516
|
+
document.addEventListener("visibilitychange", this.onVisibility);
|
|
43467
43517
|
}
|
|
43468
43518
|
onFrame(ev) {
|
|
43469
43519
|
let frame;
|