@readium/navigator 2.4.0-beta.10 → 2.4.0-beta.11
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/dist/index.js +73 -41
- package/dist/index.umd.cjs +11 -11
- package/package.json +1 -1
- package/src/audio/AudioNavigator.ts +67 -13
- package/src/audio/AudioPoolManager.ts +21 -10
- package/src/audio/engine/AudioEngine.ts +4 -3
- package/src/audio/engine/WebAudioEngine.ts +21 -119
- package/types/src/audio/AudioNavigator.d.ts +25 -2
- package/types/src/audio/AudioPoolManager.d.ts +6 -3
- package/types/src/audio/engine/AudioEngine.d.ts +4 -3
- package/types/src/audio/engine/WebAudioEngine.d.ts +5 -8
package/dist/index.js
CHANGED
|
@@ -3622,7 +3622,7 @@ const Ct = class Ct extends bt {
|
|
|
3622
3622
|
), Reflect.defineProperty(t.navigator, "epubReadingSystem", {
|
|
3623
3623
|
value: {
|
|
3624
3624
|
name: "readium-ts-toolkit",
|
|
3625
|
-
version: "2.4.0-beta.
|
|
3625
|
+
version: "2.4.0-beta.11",
|
|
3626
3626
|
hasFeature: (n, r = "") => {
|
|
3627
3627
|
switch (n) {
|
|
3628
3628
|
case "dom-manipulation":
|
|
@@ -10083,7 +10083,7 @@ class Be {
|
|
|
10083
10083
|
}
|
|
10084
10084
|
class Es {
|
|
10085
10085
|
constructor(t) {
|
|
10086
|
-
this.audioContext = null, this.sourceNode = null, this.gainNode = null, this.listeners = {}, this.
|
|
10086
|
+
this.audioContext = null, this.sourceNode = null, this.gainNode = null, this.listeners = {}, this.isMutedValue = !1, this.isPlayingValue = !1, this.isPausedValue = !1, this.isLoadingValue = !1, this.isLoadedValue = !1, this.isEndedValue = !1, this.isStoppedValue = !1, this.worklet = null, this.webAudioActive = !1, this.boundOnCanPlayThrough = this.onCanPlayThrough.bind(this), this.boundOnTimeUpdate = this.onTimeUpdate.bind(this), this.boundOnError = this.onError.bind(this), this.boundOnEnded = this.onEnded.bind(this), this.boundOnStalled = this.onStalled.bind(this), this.boundOnEmptied = this.onEmptied.bind(this), this.boundOnSuspend = this.onSuspend.bind(this), this.boundOnWaiting = this.onWaiting.bind(this), this.boundOnLoadedMetadata = this.onLoadedMetadata.bind(this), this.boundOnSeeking = this.onSeeking.bind(this), this.boundOnSeeked = this.onSeeked.bind(this), this.boundOnPlay = this.onPlay.bind(this), this.boundOnPlaying = this.onPlaying.bind(this), this.boundOnPause = this.onPause.bind(this), this.boundOnProgress = this.onProgress.bind(this), this.playback = t.playback, this.mediaElement = document.createElement("audio"), this.mediaElement.addEventListener("canplaythrough", this.boundOnCanPlayThrough), this.mediaElement.addEventListener("timeupdate", this.boundOnTimeUpdate), this.mediaElement.addEventListener("error", this.boundOnError), this.mediaElement.addEventListener("ended", this.boundOnEnded), this.mediaElement.addEventListener("stalled", this.boundOnStalled), this.mediaElement.addEventListener("emptied", this.boundOnEmptied), this.mediaElement.addEventListener("suspend", this.boundOnSuspend), this.mediaElement.addEventListener("waiting", this.boundOnWaiting), this.mediaElement.addEventListener("loadedmetadata", this.boundOnLoadedMetadata), this.mediaElement.addEventListener("seeking", this.boundOnSeeking), this.mediaElement.addEventListener("seeked", this.boundOnSeeked), this.mediaElement.addEventListener("play", this.boundOnPlay), this.mediaElement.addEventListener("playing", this.boundOnPlaying), this.mediaElement.addEventListener("pause", this.boundOnPause), this.mediaElement.addEventListener("progress", this.boundOnProgress), this.mediaElement.currentTime = this.playback.state.currentTime;
|
|
10087
10087
|
}
|
|
10088
10088
|
/**
|
|
10089
10089
|
* Adds an event listener to the audio engine.
|
|
@@ -10103,23 +10103,6 @@ class Es {
|
|
|
10103
10103
|
(i) => i !== e
|
|
10104
10104
|
));
|
|
10105
10105
|
}
|
|
10106
|
-
deactivateWebAudio() {
|
|
10107
|
-
this.worklet && (this.worklet.destroy(), this.worklet = null), this.sourceNode && (this.sourceNode.disconnect(), this.sourceNode = null), this.gainNode && (this.gainNode.disconnect(), this.gainNode = null), this.webAudioActive = !1;
|
|
10108
|
-
}
|
|
10109
|
-
/**
|
|
10110
|
-
* Sets the media element for playback.
|
|
10111
|
-
* @param element The HTML audio element to use.
|
|
10112
|
-
*/
|
|
10113
|
-
setMediaElement(t) {
|
|
10114
|
-
if (this.mediaElement.removeEventListener("canplaythrough", this.boundOnCanPlayThrough), this.mediaElement.removeEventListener("timeupdate", this.boundOnTimeUpdate), this.mediaElement.removeEventListener("error", this.boundOnError), this.mediaElement.removeEventListener("ended", this.boundOnEnded), this.mediaElement.removeEventListener("stalled", this.boundOnStalled), this.mediaElement.removeEventListener("emptied", this.boundOnEmptied), this.mediaElement.removeEventListener("suspend", this.boundOnSuspend), this.mediaElement.removeEventListener("waiting", this.boundOnWaiting), this.mediaElement.removeEventListener("loadedmetadata", this.boundOnLoadedMetadata), this.mediaElement.removeEventListener("seeking", this.boundOnSeeking), this.mediaElement.removeEventListener("seeked", this.boundOnSeeked), this.mediaElement.removeEventListener("play", this.boundOnPlay), this.mediaElement.removeEventListener("playing", this.boundOnPlaying), this.mediaElement.removeEventListener("pause", this.boundOnPause), this.mediaElement.removeEventListener("progress", this.boundOnProgress), this.mediaElement.pause(), this.isPlayingValue = !1, this.isPausedValue = !1, this.sourceNode && (this.sourceNode.disconnect(), this.sourceNode = null), this.mediaElement = t, this.mediaElement.addEventListener("canplaythrough", this.boundOnCanPlayThrough), this.mediaElement.addEventListener("timeupdate", this.boundOnTimeUpdate), this.mediaElement.addEventListener("error", this.boundOnError), this.mediaElement.addEventListener("ended", this.boundOnEnded), this.mediaElement.addEventListener("stalled", this.boundOnStalled), this.mediaElement.addEventListener("emptied", this.boundOnEmptied), this.mediaElement.addEventListener("suspend", this.boundOnSuspend), this.mediaElement.addEventListener("waiting", this.boundOnWaiting), this.mediaElement.addEventListener("loadedmetadata", this.boundOnLoadedMetadata), this.mediaElement.addEventListener("seeking", this.boundOnSeeking), this.mediaElement.addEventListener("seeked", this.boundOnSeeked), this.mediaElement.addEventListener("play", this.boundOnPlay), this.mediaElement.addEventListener("playing", this.boundOnPlaying), this.mediaElement.addEventListener("pause", this.boundOnPause), this.mediaElement.addEventListener("progress", this.boundOnProgress), this.mediaElement.volume = this.isMutedValue ? 0 : this.currentVolume, this.mediaElement.playbackRate = this.currentPlaybackRate, this.webAudioActive)
|
|
10115
|
-
try {
|
|
10116
|
-
const e = this.getOrCreateAudioContext();
|
|
10117
|
-
this.sourceNode = new MediaElementAudioSourceNode(e, { mediaElement: this.mediaElement }), this.gainNode || (this.gainNode = e.createGain(), this.gainNode.connect(e.destination)), this.worklet?.workletNode ? this.sourceNode.connect(this.worklet.workletNode) : this.sourceNode.connect(this.gainNode);
|
|
10118
|
-
} catch {
|
|
10119
|
-
this.deactivateWebAudio();
|
|
10120
|
-
}
|
|
10121
|
-
this.mediaElement.readyState >= 1 && this.onLoadedMetadata(new Event("loadedmetadata")), this.mediaElement.seekable.length > 0 && this.onProgress(), this.mediaElement.readyState >= 4 ? this.onCanPlayThrough() : (this.isLoadingValue = !0, this.isLoadedValue = !1);
|
|
10122
|
-
}
|
|
10123
10106
|
// Ensure AudioContext is running
|
|
10124
10107
|
async ensureAudioContextRunning() {
|
|
10125
10108
|
this.audioContext || (this.audioContext = new AudioContext()), this.audioContext.state === "suspended" && await this.audioContext.resume();
|
|
@@ -10210,14 +10193,14 @@ class Es {
|
|
|
10210
10193
|
*/
|
|
10211
10194
|
setVolume(t) {
|
|
10212
10195
|
if (t < 0) {
|
|
10213
|
-
this.
|
|
10196
|
+
this.mediaElement.volume = 0, this.gainNode && (this.gainNode.gain.value = 0), this.isMutedValue = !0;
|
|
10214
10197
|
return;
|
|
10215
10198
|
}
|
|
10216
10199
|
if (t > 1) {
|
|
10217
10200
|
this.setVolume(t / 100);
|
|
10218
10201
|
return;
|
|
10219
10202
|
}
|
|
10220
|
-
this.
|
|
10203
|
+
this.mediaElement.volume = t, this.gainNode && (this.gainNode.gain.value = t);
|
|
10221
10204
|
}
|
|
10222
10205
|
/**
|
|
10223
10206
|
* Skips [seconds] either forward or backward if [seconds] is negative.
|
|
@@ -10286,7 +10269,7 @@ class Es {
|
|
|
10286
10269
|
* Sets the playback rate of the audio resource with pitch preservation.
|
|
10287
10270
|
*/
|
|
10288
10271
|
setPlaybackRate(t, e) {
|
|
10289
|
-
this.
|
|
10272
|
+
this.mediaElement.playbackRate = t, e ? "preservesPitch" in this.mediaElement ? this.mediaElement.preservesPitch = !0 : this.activateWebAudio().then(() => {
|
|
10290
10273
|
this.worklet ? this.worklet.updatePitchFactor(1 / t) : (this.sourceNode && (this.sourceNode.disconnect(), this.sourceNode = null), Be.createWorklet({
|
|
10291
10274
|
ctx: this.getOrCreateAudioContext(),
|
|
10292
10275
|
mediaElement: this.mediaElement,
|
|
@@ -10324,6 +10307,13 @@ class Es {
|
|
|
10324
10307
|
get isWebAudioActive() {
|
|
10325
10308
|
return this.webAudioActive;
|
|
10326
10309
|
}
|
|
10310
|
+
/**
|
|
10311
|
+
* Changes the src of the primary media element without swapping the element.
|
|
10312
|
+
* Preserves the RemotePlayback session and all attached event listeners.
|
|
10313
|
+
*/
|
|
10314
|
+
changeSrc(t) {
|
|
10315
|
+
this.mediaElement.src !== t && (this.mediaElement.pause(), this.isPlayingValue = !1, this.isPausedValue = !1, this.isLoadedValue = !1, this.isLoadingValue = !0, this.isEndedValue = !1, this.webAudioActive && (this.mediaElement.crossOrigin = "anonymous"), this.mediaElement.src = t, this.mediaElement.load());
|
|
10316
|
+
}
|
|
10327
10317
|
/**
|
|
10328
10318
|
* Returns the HTML media element used for playback.
|
|
10329
10319
|
*/
|
|
@@ -10453,8 +10443,8 @@ class Fi {
|
|
|
10453
10443
|
}
|
|
10454
10444
|
const Ui = 1, Ii = 1;
|
|
10455
10445
|
class xs {
|
|
10456
|
-
constructor(t, e) {
|
|
10457
|
-
this.pool = /* @__PURE__ */ new Map(), this._audioEngine = t, this._publication = e, this._supportedAudioTypes = this.detectSupportedAudioTypes();
|
|
10446
|
+
constructor(t, e, i = {}) {
|
|
10447
|
+
this.pool = /* @__PURE__ */ new Map(), this._audioEngine = t, this._publication = e, this._supportedAudioTypes = this.detectSupportedAudioTypes(), i.disableRemotePlayback && (this._audioEngine.getMediaElement().disableRemotePlayback = !0);
|
|
10458
10448
|
}
|
|
10459
10449
|
detectSupportedAudioTypes() {
|
|
10460
10450
|
const t = document.createElement("audio"), e = /* @__PURE__ */ new Set();
|
|
@@ -10497,10 +10487,12 @@ class xs {
|
|
|
10497
10487
|
/**
|
|
10498
10488
|
* Updates the pool around the given index: ensures elements exist within
|
|
10499
10489
|
* the LOWER_BOUNDARY and disposes those beyond the UPPER_BOUNDARY.
|
|
10490
|
+
* The current track is excluded — the primary engine element represents it.
|
|
10500
10491
|
*/
|
|
10501
10492
|
update(t) {
|
|
10502
10493
|
const e = this._publication.readingOrder.items, i = /* @__PURE__ */ new Set();
|
|
10503
10494
|
for (let n = 0; n < e.length; n++) {
|
|
10495
|
+
if (n === t) continue;
|
|
10504
10496
|
const r = this.pickPlayableHref(e[n]);
|
|
10505
10497
|
n >= t - Ii && n <= t + Ii ? (this.ensure(r), i.add(r)) : n >= t - Ui && n <= t + Ui && this.pool.has(r) && i.add(r);
|
|
10506
10498
|
}
|
|
@@ -10508,12 +10500,17 @@ class xs {
|
|
|
10508
10500
|
i.has(n) || (r.removeAttribute("src"), r.load(), this.pool.delete(n));
|
|
10509
10501
|
}
|
|
10510
10502
|
/**
|
|
10511
|
-
* Sets the current audio for playback at the given track index
|
|
10512
|
-
*
|
|
10503
|
+
* Sets the current audio for playback at the given track index by changing
|
|
10504
|
+
* the src on the persistent primary element. This preserves the RemotePlayback
|
|
10505
|
+
* session and any Web Audio graph connections across track changes.
|
|
10513
10506
|
*/
|
|
10514
10507
|
setCurrentAudio(t, e) {
|
|
10515
|
-
const i = this.pickPlayableHref(this._publication.readingOrder.items[t])
|
|
10516
|
-
this.audioEngine.
|
|
10508
|
+
const i = this.pickPlayableHref(this._publication.readingOrder.items[t]);
|
|
10509
|
+
if (this.audioEngine.changeSrc(i), this.pool.has(i)) {
|
|
10510
|
+
const n = this.pool.get(i);
|
|
10511
|
+
n.removeAttribute("src"), n.load(), this.pool.delete(i);
|
|
10512
|
+
}
|
|
10513
|
+
this.update(t);
|
|
10517
10514
|
}
|
|
10518
10515
|
destroy() {
|
|
10519
10516
|
this.audioEngine.stop();
|
|
@@ -10600,7 +10597,7 @@ class As extends dr {
|
|
|
10600
10597
|
preferences: {},
|
|
10601
10598
|
defaults: {}
|
|
10602
10599
|
}) {
|
|
10603
|
-
if (super(), this.positionPollInterval = null, this.navigationId = 0, this._playIntent = !1, this._preferencesEditor = null, this._mediaSessionEnabled = !1, this._navigatorProtector = null, this._keyboardPeripheralsManager = null, this._suspiciousActivityListener = null, this._keyboardPeripheralListener = null, this.pub = t, this.listeners = Os(e), this._preferences = new oe(n.preferences), this._defaults = new Cs(n.defaults), this._settings = new Ni(this._preferences, this._defaults), i)
|
|
10600
|
+
if (super(), this.positionPollInterval = null, this.navigationId = 0, this._playIntent = !1, this._preferencesEditor = null, this._mediaSessionEnabled = !1, this._navigatorProtector = null, this._keyboardPeripheralsManager = null, this._suspiciousActivityListener = null, this._keyboardPeripheralListener = null, this._isNavigating = !1, this.pub = t, this.listeners = Os(e), this._preferences = new oe(n.preferences), this._defaults = new Cs(n.defaults), this._settings = new Ni(this._preferences, this._defaults), i)
|
|
10604
10601
|
this.currentLocation = this.ensureLocatorLocations(i);
|
|
10605
10602
|
else {
|
|
10606
10603
|
const u = this.pub.readingOrder.items[0];
|
|
@@ -10626,8 +10623,10 @@ class As extends dr {
|
|
|
10626
10623
|
index: o
|
|
10627
10624
|
}
|
|
10628
10625
|
});
|
|
10629
|
-
this.pool = new xs(l, t);
|
|
10630
|
-
const h = n.contentProtection || {}
|
|
10626
|
+
this.pool = new xs(l, t, n.contentProtection);
|
|
10627
|
+
const h = n.contentProtection || {};
|
|
10628
|
+
this._contentProtection = h;
|
|
10629
|
+
const c = this.mergeKeyboardPeripherals(
|
|
10631
10630
|
h,
|
|
10632
10631
|
n.keyboardPeripherals || []
|
|
10633
10632
|
);
|
|
@@ -10636,9 +10635,10 @@ class As extends dr {
|
|
|
10636
10635
|
m === "context_menu" ? this.listeners.contextMenu(y) : this.listeners.contentProtection(m, y);
|
|
10637
10636
|
}, window.addEventListener(st, this._suspiciousActivityListener)), c.length > 0 && (this._keyboardPeripheralsManager = new He({ keyboardPeripherals: c }), this._keyboardPeripheralListener = (u) => {
|
|
10638
10637
|
this.listeners.peripheral(u.detail);
|
|
10639
|
-
}, window.addEventListener(ot, this._keyboardPeripheralListener)), this.setupEventListeners(), this.applyPreferences(), this.pool.setCurrentAudio(o, "forward"), this.waitForLoadedAndSeeked(a).then(() => {
|
|
10640
|
-
this.listeners.trackLoaded(this.pool.audioEngine.getMediaElement()), this._notifyTimelineChange(this.currentLocator), this.listeners.positionChanged(this.currentLocator);
|
|
10638
|
+
}, window.addEventListener(ot, this._keyboardPeripheralListener)), this.setupEventListeners(), this.applyPreferences(), this._isNavigating = !0, this.pool.setCurrentAudio(o, "forward"), this.waitForLoadedAndSeeked(a).then(() => {
|
|
10639
|
+
this._isNavigating = !1, this.listeners.trackLoaded(this.pool.audioEngine.getMediaElement()), this._notifyTimelineChange(this.currentLocator), this.listeners.positionChanged(this.currentLocator), this._setupRemotePlayback();
|
|
10641
10640
|
}).catch(() => {
|
|
10641
|
+
this._isNavigating = !1;
|
|
10642
10642
|
});
|
|
10643
10643
|
}
|
|
10644
10644
|
get settings() {
|
|
@@ -10751,13 +10751,13 @@ class As extends dr {
|
|
|
10751
10751
|
fragments: [`t=${this.duration}`]
|
|
10752
10752
|
})), this.listeners.trackEnded(this.currentLocator), this.canGoForward && (await this.nextTrack(), this._settings.autoPlay && this.play());
|
|
10753
10753
|
}), this.pool.audioEngine.on("play", () => {
|
|
10754
|
-
this.startPositionPolling(), this.listeners.play(this.currentLocator);
|
|
10754
|
+
this._isNavigating || (this.startPositionPolling(), this.listeners.play(this.currentLocator));
|
|
10755
10755
|
}), this.pool.audioEngine.on("playing", () => {
|
|
10756
|
-
this.listeners.stalled(!1);
|
|
10756
|
+
this._isNavigating || this.listeners.stalled(!1);
|
|
10757
10757
|
}), this.pool.audioEngine.on("pause", () => {
|
|
10758
|
-
this.stopPositionPolling(), this.listeners.pause(this.currentLocator);
|
|
10758
|
+
this._isNavigating || (this.stopPositionPolling(), this.listeners.pause(this.currentLocator));
|
|
10759
10759
|
}), this.pool.audioEngine.on("seeked", () => {
|
|
10760
|
-
if (this.listeners.seeking(!1), !this.isPlaying) {
|
|
10760
|
+
if (!this._isNavigating && (this.listeners.seeking(!1), !this.isPlaying)) {
|
|
10761
10761
|
const t = this.currentTime, e = this.duration, i = e > 0 ? t / e : 0;
|
|
10762
10762
|
this.currentLocation = this.currentLocation.copyWithLocations(new E({
|
|
10763
10763
|
position: this.currentTrackIndex(),
|
|
@@ -10765,8 +10765,24 @@ class As extends dr {
|
|
|
10765
10765
|
fragments: [`t=${t}`]
|
|
10766
10766
|
})), this._notifyTimelineChange(this.currentLocation), this.listeners.positionChanged(this.currentLocation);
|
|
10767
10767
|
}
|
|
10768
|
-
}), this.pool.audioEngine.on("seeking", () =>
|
|
10769
|
-
this.
|
|
10768
|
+
}), this.pool.audioEngine.on("seeking", () => {
|
|
10769
|
+
this._isNavigating || this.listeners.seeking(!0);
|
|
10770
|
+
}), this.pool.audioEngine.on("waiting", () => {
|
|
10771
|
+
this._isNavigating || this.listeners.seeking(!0);
|
|
10772
|
+
}), this.pool.audioEngine.on("stalled", () => {
|
|
10773
|
+
this._isNavigating || this.listeners.stalled(!0);
|
|
10774
|
+
}), this.pool.audioEngine.on("canplaythrough", () => {
|
|
10775
|
+
this._isNavigating || this.listeners.stalled(!1);
|
|
10776
|
+
}), this.pool.audioEngine.on("progress", (t) => {
|
|
10777
|
+
this._isNavigating || this.listeners.seekable(t);
|
|
10778
|
+
}), this.pool.audioEngine.on("loadedmetadata", () => {
|
|
10779
|
+
const t = this.pool.audioEngine.getMediaElement(), e = {
|
|
10780
|
+
duration: this.pool.audioEngine.duration(),
|
|
10781
|
+
textTracks: t.textTracks,
|
|
10782
|
+
readyState: t.readyState,
|
|
10783
|
+
networkState: t.networkState
|
|
10784
|
+
};
|
|
10785
|
+
this.listeners.metadataLoaded(e);
|
|
10770
10786
|
});
|
|
10771
10787
|
}
|
|
10772
10788
|
setupMediaSession() {
|
|
@@ -10806,13 +10822,13 @@ class As extends dr {
|
|
|
10806
10822
|
return;
|
|
10807
10823
|
}
|
|
10808
10824
|
const a = ++this.navigationId, l = r >= this.currentTrackIndex() ? "forward" : "backward", h = this.isPlaying || this._playIntent;
|
|
10809
|
-
if (this._playIntent = h, this.stopPositionPolling(), this.pool.setCurrentAudio(r, l), this.currentLocation = t.copyWithLocations(t.locations), await this.waitForLoadedAndSeeked(o, a), a !== this.navigationId) {
|
|
10825
|
+
if (this._playIntent = h, this._isNavigating = !0, this.stopPositionPolling(), this.pool.setCurrentAudio(r, l), this.currentLocation = t.copyWithLocations(t.locations), await this.waitForLoadedAndSeeked(o, a), this._isNavigating = !1, a !== this.navigationId) {
|
|
10810
10826
|
i(!1);
|
|
10811
10827
|
return;
|
|
10812
10828
|
}
|
|
10813
10829
|
this.listeners.trackLoaded(this.pool.audioEngine.getMediaElement()), this._notifyTimelineChange(this.currentLocator), this.listeners.positionChanged(this.currentLocator), this._settings.enableMediaSession && this.updateMediaSessionMetadata(), h && this.play(), i(!0);
|
|
10814
10830
|
} catch (n) {
|
|
10815
|
-
console.error("Failed to go to locator:", n), i(!1);
|
|
10831
|
+
this._isNavigating = !1, console.error("Failed to go to locator:", n), i(!1);
|
|
10816
10832
|
} finally {
|
|
10817
10833
|
this._playIntent = !1;
|
|
10818
10834
|
}
|
|
@@ -10890,6 +10906,22 @@ class As extends dr {
|
|
|
10890
10906
|
get canGoForward() {
|
|
10891
10907
|
return this.currentTrackIndex() < this.pub.readingOrder.items.length - 1;
|
|
10892
10908
|
}
|
|
10909
|
+
/**
|
|
10910
|
+
* The RemotePlayback object for the primary media element.
|
|
10911
|
+
* Because the element is never swapped, this reference is stable for the
|
|
10912
|
+
* lifetime of the navigator — host apps can store it and call `.prompt()`,
|
|
10913
|
+
* `.watchAvailability()`, etc. directly.
|
|
10914
|
+
*/
|
|
10915
|
+
get remotePlayback() {
|
|
10916
|
+
return this.pool.audioEngine.getMediaElement().remote;
|
|
10917
|
+
}
|
|
10918
|
+
/** Wires up the optional remotePlaybackStateChanged listener. Called once after initial load. */
|
|
10919
|
+
_setupRemotePlayback() {
|
|
10920
|
+
if (this._contentProtection.disableRemotePlayback)
|
|
10921
|
+
return;
|
|
10922
|
+
const t = this.remotePlayback;
|
|
10923
|
+
t && (t.onconnecting = () => this.listeners.remotePlaybackStateChanged?.("connecting"), t.onconnect = () => this.listeners.remotePlaybackStateChanged?.("connected"), t.ondisconnect = () => this.listeners.remotePlaybackStateChanged?.("disconnected"));
|
|
10924
|
+
}
|
|
10893
10925
|
destroyMediaSession() {
|
|
10894
10926
|
"mediaSession" in navigator && (navigator.mediaSession.metadata = null, navigator.mediaSession.setActionHandler("play", null), navigator.mediaSession.setActionHandler("pause", null), navigator.mediaSession.setActionHandler("previoustrack", null), navigator.mediaSession.setActionHandler("nexttrack", null), navigator.mediaSession.setActionHandler("seekbackward", null), navigator.mediaSession.setActionHandler("seekforward", null));
|
|
10895
10927
|
}
|