@readium/navigator 2.4.0-beta.3 → 2.4.0-beta.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@readium/navigator",
3
- "version": "2.4.0-beta.3",
3
+ "version": "2.4.0-beta.5",
4
4
  "type": "module",
5
5
  "description": "Next generation SDK for publications in Web Apps",
6
6
  "author": "readium",
@@ -66,6 +66,7 @@ export class AudioNavigator extends MediaNavigator implements Configurable<Audio
66
66
  private _defaults: AudioDefaults;
67
67
  private _settings: AudioSettings;
68
68
  private _preferencesEditor: AudioPreferencesEditor | null = null;
69
+ private _mediaSessionEnabled: boolean = false;
69
70
  private pool: AudioPoolManager;
70
71
  private readonly _navigatorProtector: AudioNavigatorProtector | null = null;
71
72
  private readonly _keyboardPeripheralsManager: KeyboardPeripherals | null = null;
@@ -110,7 +111,6 @@ export class AudioNavigator extends MediaNavigator implements Configurable<Audio
110
111
  state: {
111
112
  currentTime: initialTime,
112
113
  duration: 0,
113
- volume: this._settings.volume
114
114
  } as PlaybackState,
115
115
  playWhenReady: false,
116
116
  index: trackIndex
@@ -154,10 +154,7 @@ export class AudioNavigator extends MediaNavigator implements Configurable<Audio
154
154
  }
155
155
 
156
156
  this.setupEventListeners();
157
-
158
- if (this._settings.enableMediaSession) {
159
- this.setupMediaSession();
160
- }
157
+ this.applyPreferences();
161
158
 
162
159
  this.pool.setCurrentAudio(trackIndex, "forward");
163
160
 
@@ -190,7 +187,6 @@ export class AudioNavigator extends MediaNavigator implements Configurable<Audio
190
187
  }
191
188
 
192
189
  private applyPreferences(): void {
193
- const oldSettings = this._settings;
194
190
  this._settings = new AudioSettings(this._preferences, this._defaults);
195
191
 
196
192
  if (this._preferencesEditor !== null) {
@@ -200,9 +196,11 @@ export class AudioNavigator extends MediaNavigator implements Configurable<Audio
200
196
  this.pool.audioEngine.setVolume(this._settings.volume);
201
197
  this.pool.audioEngine.setPlaybackRate(this._settings.playbackRate, this._settings.preservePitch);
202
198
 
203
- if (this._settings.enableMediaSession && !oldSettings.enableMediaSession) {
199
+ if (this._settings.enableMediaSession && !this._mediaSessionEnabled) {
200
+ this._mediaSessionEnabled = true;
204
201
  this.setupMediaSession();
205
- } else if (!this._settings.enableMediaSession && oldSettings.enableMediaSession) {
202
+ } else if (!this._settings.enableMediaSession && this._mediaSessionEnabled) {
203
+ this._mediaSessionEnabled = false;
206
204
  this.destroyMediaSession();
207
205
  }
208
206
  }
@@ -386,12 +384,14 @@ export class AudioNavigator extends MediaNavigator implements Configurable<Audio
386
384
  if (!("mediaSession" in navigator)) return;
387
385
  const trackIndex = this.currentTrackIndex();
388
386
  const track = this.pub.readingOrder.items[trackIndex];
387
+ const cover = this.pub.getCover();
389
388
  navigator.mediaSession.metadata = new MediaMetadata({
390
389
  title: track?.title || `Track ${trackIndex + 1}`,
391
390
  artist: this.pub.metadata.authors
392
391
  ? this.pub.metadata.authors.items.map((a) => a.name.getTranslation()).join(", ")
393
392
  : undefined,
394
393
  album: this.pub.metadata.title.getTranslation(),
394
+ artwork: cover ? [{ src: cover.href, type: cover.type }] : undefined,
395
395
  });
396
396
  }
397
397
 
@@ -11,11 +11,6 @@ export interface PlaybackState {
11
11
  * The duration of the audio resource.
12
12
  */
13
13
  duration: number;
14
-
15
- /**
16
- * The volume of the audio resource.
17
- */
18
- volume: number;
19
14
  }
20
15
 
21
16
  /**
@@ -16,6 +16,7 @@ export class WebAudioEngine implements AudioEngine {
16
16
  private sourceNode: MediaElementAudioSourceNode | null = null;
17
17
  private gainNode: GainNode | null = null;
18
18
  private listeners: { [event: string]: EventCallback[] } = {};
19
+ private currentVolume: number = 1;
19
20
  private currentPlaybackRate: number = 1;
20
21
  private isMutedValue: boolean = false;
21
22
  private isPlayingValue: boolean = false;
@@ -48,7 +49,6 @@ export class WebAudioEngine implements AudioEngine {
48
49
 
49
50
  // crossOrigin is set lazily in activateWebAudio() only when the worklet is needed
50
51
  this.mediaElement = document.createElement("audio");
51
- this.setVolume(this.playback.state.volume);
52
52
 
53
53
  // Event listeners (to report the client app about some async events)
54
54
  this.mediaElement.addEventListener("canplaythrough", this.boundOnCanPlayThrough);
@@ -109,6 +109,7 @@ export class WebAudioEngine implements AudioEngine {
109
109
  this.mediaElement.crossOrigin = "anonymous";
110
110
  this.mediaElement.src = url;
111
111
  this.mediaElement.load();
112
+ this.mediaElement.playbackRate = this.currentPlaybackRate;
112
113
 
113
114
  // If the server doesn't honour the CORS preflight, fall back to a
114
115
  // non-CORS load and tear down the Web Audio graph so the element
@@ -123,6 +124,7 @@ export class WebAudioEngine implements AudioEngine {
123
124
  this.mediaElement.removeAttribute("crossOrigin");
124
125
  this.mediaElement.src = url;
125
126
  this.mediaElement.load();
127
+ this.mediaElement.playbackRate = this.currentPlaybackRate;
126
128
  };
127
129
  const onCORSSuccess = () => cleanup();
128
130
  this.mediaElement.addEventListener("error", onCORSError);
@@ -130,6 +132,7 @@ export class WebAudioEngine implements AudioEngine {
130
132
  } else {
131
133
  this.mediaElement.src = url;
132
134
  this.mediaElement.load();
135
+ this.mediaElement.playbackRate = this.currentPlaybackRate;
133
136
  }
134
137
  }
135
138
 
@@ -203,7 +206,7 @@ export class WebAudioEngine implements AudioEngine {
203
206
  this.mediaElement.addEventListener("progress", this.boundOnProgress);
204
207
 
205
208
  // Re-apply current volume and playback rate to the new element
206
- this.mediaElement.volume = this.isMutedValue ? 0 : this.playback.state.volume;
209
+ this.mediaElement.volume = this.isMutedValue ? 0 : this.currentVolume;
207
210
  this.mediaElement.playbackRate = this.currentPlaybackRate;
208
211
 
209
212
  // Check if metadata is already loaded (common with preloaded elements)
@@ -370,23 +373,23 @@ export class WebAudioEngine implements AudioEngine {
370
373
  */
371
374
  public setVolume(volume: number): void {
372
375
  if (volume < 0) {
376
+ this.currentVolume = 0;
373
377
  this.mediaElement.volume = 0;
374
378
  if (this.gainNode) {
375
379
  this.gainNode.gain.value = 0;
376
380
  }
377
381
  this.isMutedValue = true;
378
- this.playback.state.volume = 0;
379
382
  return;
380
383
  }
381
384
  if (volume > 1) {
382
385
  this.setVolume(volume / 100);
383
386
  return;
384
387
  }
388
+ this.currentVolume = volume;
385
389
  this.mediaElement.volume = volume;
386
390
  if (this.gainNode) {
387
391
  this.gainNode.gain.value = volume;
388
392
  }
389
- this.playback.state.volume = volume;
390
393
  }
391
394
 
392
395
  /**
@@ -82,7 +82,7 @@ export const volumeRangeConfig: RangeConfig = {
82
82
 
83
83
  export const playbackRateRangeConfig: RangeConfig = {
84
84
  range: [0.5, 2],
85
- step: 0.25
85
+ step: 0.1
86
86
  }
87
87
 
88
88
  export const skipIntervalRangeConfig: RangeConfig = {
@@ -34,6 +34,7 @@ export declare class AudioNavigator extends MediaNavigator implements Configurab
34
34
  private _defaults;
35
35
  private _settings;
36
36
  private _preferencesEditor;
37
+ private _mediaSessionEnabled;
37
38
  private pool;
38
39
  private readonly _navigatorProtector;
39
40
  private readonly _keyboardPeripheralsManager;
@@ -10,10 +10,6 @@ export interface PlaybackState {
10
10
  * The duration of the audio resource.
11
11
  */
12
12
  duration: number;
13
- /**
14
- * The volume of the audio resource.
15
- */
16
- volume: number;
17
13
  }
18
14
  /**
19
15
  * Playback interface for an audio engine state
@@ -7,6 +7,7 @@ export declare class WebAudioEngine implements AudioEngine {
7
7
  private sourceNode;
8
8
  private gainNode;
9
9
  private listeners;
10
+ private currentVolume;
10
11
  private currentPlaybackRate;
11
12
  private isMutedValue;
12
13
  private isPlayingValue;