@audiowalk/sdk 1.5.4 → 1.5.6

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.
@@ -35,7 +35,7 @@ export class MediaControlsController {
35
35
  .subscribe(([currentTime, totalTime]) => {
36
36
  navigator.mediaSession.setPositionState({
37
37
  duration: totalTime || 0,
38
- position: currentTime,
38
+ position: currentTime || 0,
39
39
  });
40
40
  });
41
41
  }
@@ -6,6 +6,8 @@ export interface PlayerControllerOptions {
6
6
  loop?: boolean;
7
7
  crossfade?: boolean;
8
8
  crossfadeTime: number;
9
+ keepPlayer?: boolean;
10
+ volume?: number;
9
11
  }
10
12
  export type PlayerControllerParams = PartialBy<PlayerControllerOptions, "crossfadeTime">;
11
13
  export declare enum PlayerStatus {
@@ -14,13 +16,13 @@ export declare enum PlayerStatus {
14
16
  "ended" = "ended"
15
17
  }
16
18
  export declare class PlayerController {
19
+ private trackId;
17
20
  readonly onPlay: Subject<void>;
18
21
  readonly onPause: Subject<void>;
19
22
  readonly onStop: Subject<void>;
20
23
  readonly currentTime: BehaviorSubject<number>;
21
24
  readonly totalTime: BehaviorSubject<number | null>;
22
25
  readonly progress: import("rxjs").Observable<number | null>;
23
- private trackId;
24
26
  readonly status: BehaviorSubject<PlayerStatus | null>;
25
27
  readonly playing: import("rxjs").Observable<boolean>;
26
28
  private playerElement;
@@ -31,8 +33,10 @@ export declare class PlayerController {
31
33
  private volume;
32
34
  private fadeCancelEvent;
33
35
  constructor(trackId: string, trackUrl: string, options?: PlayerControllerParams);
34
- open(id: string, file: string): Promise<void>;
36
+ open(file: string): Promise<void>;
35
37
  destroy(now?: boolean): Promise<void>;
38
+ private destroyNow;
39
+ preload(): Promise<void>;
36
40
  play(params?: {
37
41
  fade?: boolean;
38
42
  }): Promise<void>;
@@ -43,7 +47,7 @@ export declare class PlayerController {
43
47
  seekTo(seconds: number): void;
44
48
  setVolume(volume: number, params?: {
45
49
  fade?: boolean;
46
- }): void;
50
+ }): Promise<void>;
47
51
  fadeToVolume(volume: number): Promise<void>;
48
52
  back(seconds?: number): void;
49
53
  forward(seconds?: number): void;
@@ -1 +1 @@
1
- {"version":3,"file":"player-controller.d.ts","sourceRoot":"","sources":["../../src/player/player-controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAwC,OAAO,EAAwB,MAAM,MAAM,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,sBAAsB,GAAG,SAAS,CAAC,uBAAuB,EAAE,eAAe,CAAC,CAAC;AAEzF,oBAAY,YAAY;IACtB,SAAS,YAAY;IACrB,QAAQ,WAAW;IACnB,OAAO,UAAU;CAClB;AAED,qBAAa,gBAAgB;IAC3B,SAAgB,MAAM,gBAAuB;IAC7C,SAAgB,OAAO,gBAAuB;IAC9C,SAAgB,MAAM,gBAAuB;IAE7C,SAAgB,WAAW,0BAAkC;IAC7D,SAAgB,SAAS,iCAA4C;IACrE,SAAgB,QAAQ,2CAEtB;IAEF,OAAO,CAAC,OAAO,CAAuB;IAEtC,SAAgB,MAAM,uCAAkD;IACxE,SAAgB,OAAO,qCAA2D;IAElF,OAAO,CAAC,aAAa,CAAmB;IAExC,OAAO,CAAC,YAAY,CAA0C;IAE9D,OAAO,CAAC,OAAO,CAA0B;IAEzC,OAAO,CAAC,cAAc,CAEpB;IAEF,OAAO,CAAC,YAAY,CAAuB;IAE3C,OAAO,CAAC,MAAM,CAAa;IAE3B,OAAO,CAAC,eAAe,CAAuB;gBAElC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B;IAiE7E,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAQ7B,OAAO,CAAC,GAAG,GAAE,OAAe;IAa5B,IAAI,CAAC,MAAM,GAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAqC;IAiBlE,KAAK;IAQL,IAAI,CAAC,MAAM,GAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAqC;IAexE,MAAM,CAAC,OAAO,EAAE,MAAM;IAQtB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAO;IAYnD,YAAY,CAAC,MAAM,EAAE,MAAM;IA4BjC,IAAI,CAAC,OAAO,GAAE,MAAW;IAKzB,OAAO,CAAC,OAAO,GAAE,MAAW;YAMd,YAAY;IAK1B,OAAO,CAAC,GAAG;CAOZ"}
1
+ {"version":3,"file":"player-controller.d.ts","sourceRoot":"","sources":["../../src/player/player-controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAwC,OAAO,EAAwB,MAAM,MAAM,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,sBAAsB,GAAG,SAAS,CAAC,uBAAuB,EAAE,eAAe,CAAC,CAAC;AAEzF,oBAAY,YAAY;IACtB,SAAS,YAAY;IACrB,QAAQ,WAAW;IACnB,OAAO,UAAU;CAClB;AAED,qBAAa,gBAAgB;IA8Bf,OAAO,CAAC,OAAO;IA7B3B,SAAgB,MAAM,gBAAuB;IAC7C,SAAgB,OAAO,gBAAuB;IAC9C,SAAgB,MAAM,gBAAuB;IAE7C,SAAgB,WAAW,0BAAkC;IAC7D,SAAgB,SAAS,iCAA4C;IACrE,SAAgB,QAAQ,2CAEtB;IAEF,SAAgB,MAAM,uCAAkD;IACxE,SAAgB,OAAO,qCAA2D;IAElF,OAAO,CAAC,aAAa,CAAmB;IAExC,OAAO,CAAC,YAAY,CAA0C;IAE9D,OAAO,CAAC,OAAO,CAA0B;IAEzC,OAAO,CAAC,cAAc,CAEpB;IAEF,OAAO,CAAC,YAAY,CAAuB;IAE3C,OAAO,CAAC,MAAM,CAAa;IAE3B,OAAO,CAAC,eAAe,CAAuB;gBAE1B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B;IAuErF,IAAI,CAAC,IAAI,EAAE,MAAM;IAYjB,OAAO,CAAC,GAAG,GAAE,OAAe;IAgBlC,OAAO,CAAC,UAAU;IAQZ,OAAO;IAUP,IAAI,CAAC,MAAM,GAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAqC;IAgBlE,KAAK;IAQL,IAAI,CAAC,MAAM,GAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAqC;IAgBxE,MAAM,CAAC,OAAO,EAAE,MAAM;IAQhB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAO;IAYzD,YAAY,CAAC,MAAM,EAAE,MAAM;IA4BjC,IAAI,CAAC,OAAO,GAAE,MAAW;IAKzB,OAAO,CAAC,OAAO,GAAE,MAAW;YAMd,YAAY;IAK1B,OAAO,CAAC,GAAG;CAOZ"}
@@ -7,13 +7,13 @@ export var PlayerStatus;
7
7
  PlayerStatus["ended"] = "ended";
8
8
  })(PlayerStatus || (PlayerStatus = {}));
9
9
  export class PlayerController {
10
+ trackId;
10
11
  onPlay = new Subject();
11
12
  onPause = new Subject();
12
13
  onStop = new Subject();
13
14
  currentTime = new BehaviorSubject(0);
14
15
  totalTime = new BehaviorSubject(null);
15
16
  progress = combineLatest([this.currentTime, this.totalTime]).pipe(map(([currentTime, totalTime]) => (totalTime ? currentTime / totalTime : null)));
16
- trackId = null;
17
17
  status = new BehaviorSubject(null);
18
18
  playing = this.status.pipe(map((status) => status === "playing"));
19
19
  playerElement;
@@ -26,8 +26,10 @@ export class PlayerController {
26
26
  volume = 1;
27
27
  fadeCancelEvent = new Subject();
28
28
  constructor(trackId, trackUrl, options = {}) {
29
+ this.trackId = trackId;
29
30
  this.options = { ...this.defaultOptions, ...options };
30
31
  this.playerElement = this.options.audioElement ?? new Audio();
32
+ this.volume = options.volume ?? this.volume;
31
33
  this.playerElement.volume = this.volume;
32
34
  this.playerElement.addEventListener("play", () => {
33
35
  this.onPlay.next();
@@ -38,10 +40,20 @@ export class PlayerController {
38
40
  this.status.next(PlayerStatus.paused);
39
41
  });
40
42
  this.playerElement.addEventListener("ended", () => {
43
+ this.savePosition(0);
41
44
  if (!this.options.crossfade && !this.options.loop) {
42
45
  this.onStop.next();
43
46
  this.status.next(PlayerStatus.ended);
44
47
  }
48
+ if (this.options.keepPlayer && !this.options.loop) {
49
+ this.playerElement.currentTime = 0;
50
+ this.playerElement.play();
51
+ this.playerElement.pause();
52
+ }
53
+ if (this.options.loop) {
54
+ this.playerElement.currentTime = 0;
55
+ this.playerElement.play();
56
+ }
45
57
  });
46
58
  this.playerElement.addEventListener("loadedmetadata", (event) => {
47
59
  if (this.playerElement.duration) {
@@ -67,45 +79,63 @@ export class PlayerController {
67
79
  this.stop();
68
80
  });
69
81
  }
70
- if (this.options.loop) {
71
- this.onStop.pipe(takeUntil(this.destroyEvent)).subscribe(() => {
72
- this.playerElement.currentTime = 0;
73
- this.playerElement.play();
74
- });
75
- }
76
- this.open(trackId, trackUrl);
77
- this.log("Initialized player", trackId);
82
+ this.open(trackUrl).then(() => {
83
+ this.log("Initialized player", trackId);
84
+ });
78
85
  }
79
- async open(id, file) {
80
- this.trackId = id;
86
+ async open(file) {
87
+ this.log("Called open", file);
81
88
  this.playerElement.src = file;
82
89
  const position = await this.localStorage.get(`progress-${this.trackId}`, (value) => typeof value === "number");
83
90
  if (position && this.options.autoSave)
84
91
  this.playerElement.currentTime = position;
92
+ else
93
+ this.playerElement.currentTime = 0;
94
+ this.playerElement.volume = this.volume;
85
95
  }
86
96
  async destroy(now = false) {
87
- this.log("Called destroy", now ? "now" : "");
97
+ this.log("Called destroy" + (now ? "now" : ""));
98
+ if (this.status.value !== PlayerStatus.ended) {
99
+ await this.stop();
100
+ return this.destroyNow();
101
+ }
102
+ // if crossfade is enabled, we might be ending crossfade just now, so wait for the crossfade to finish
88
103
  if (this.options.crossfade && now !== true) {
89
- setTimeout(() => this.destroy(true), this.options.crossfadeTime);
90
- return;
104
+ setTimeout(() => this.destroyNow(), this.options.crossfadeTime);
105
+ }
106
+ else {
107
+ this.destroyNow();
91
108
  }
109
+ }
110
+ destroyNow() {
92
111
  this.log("Destroying player");
93
112
  this.destroyEvent.next();
113
+ this.playerElement.src = "";
114
+ this.playerElement.pause();
94
115
  this.playerElement.remove();
95
116
  }
117
+ async preload() {
118
+ this.log("Called preload");
119
+ this.playerElement.volume = 0.01;
120
+ this.playerElement.play().catch(() => { });
121
+ this.playerElement.pause();
122
+ this.playerElement.volume = this.volume;
123
+ this.log("Preloaded");
124
+ }
96
125
  async play(params = { fade: this.options.crossfade }) {
97
126
  if (!this.playerElement.src)
98
127
  throw new Error("No file opened");
99
128
  if (this.status.value === PlayerStatus.playing)
100
129
  return;
101
- this.log("Called play", params.fade ? "with fade" : "");
102
- if (params.fade) {
103
- this.playerElement.volume = 0;
104
- }
130
+ this.log("Called play" + (params.fade ? "with fade" : ""));
105
131
  await this.playerElement?.play();
106
132
  if (params.fade) {
133
+ this.playerElement.volume = 0.01;
107
134
  await this.fadeToVolume(this.volume);
108
135
  }
136
+ else {
137
+ this.playerElement.volume = this.volume;
138
+ }
109
139
  }
110
140
  async pause() {
111
141
  if (!this.playerElement.src)
@@ -118,13 +148,14 @@ export class PlayerController {
118
148
  async stop(params = { fade: this.options.crossfade }) {
119
149
  this.log("Called stop", params.fade ? "with fade" : "");
120
150
  if (this.status.value !== PlayerStatus.ended) {
121
- this.onStop.next();
122
151
  this.status.next(PlayerStatus.ended);
152
+ this.onStop.next();
123
153
  }
124
154
  if (params.fade) {
125
155
  await this.fadeToVolume(0);
126
156
  }
127
157
  this.playerElement.pause();
158
+ this.playerElement.currentTime = 0;
128
159
  }
129
160
  seekTo(seconds) {
130
161
  if (!this.playerElement.src)
@@ -134,11 +165,11 @@ export class PlayerController {
134
165
  this.log("Called seekTo");
135
166
  this.playerElement.currentTime = seconds;
136
167
  }
137
- setVolume(volume, params = {}) {
168
+ async setVolume(volume, params = {}) {
138
169
  this.log("Called set volume", volume, params.fade ? "with fade" : "");
139
170
  this.volume = volume;
140
171
  if (params.fade) {
141
- this.fadeToVolume(volume);
172
+ await this.fadeToVolume(volume);
142
173
  }
143
174
  else {
144
175
  this.playerElement.volume = Math.max(Math.min(volume, 1), 0);
@@ -158,7 +189,7 @@ export class PlayerController {
158
189
  .pipe(takeWhile(() => Math.abs(this.playerElement.volume - this.volume) > Math.abs(fadeOutStep)))
159
190
  .subscribe({
160
191
  next: () => {
161
- this.playerElement.volume += fadeOutStep;
192
+ this.playerElement.volume = Math.max(0, Math.min(1, fadeOutStep));
162
193
  },
163
194
  error: (error) => reject(error),
164
195
  complete: () => {
@@ -186,6 +217,6 @@ export class PlayerController {
186
217
  const time = this.playerElement?.currentTime ? Math.round(this.playerElement?.currentTime) : null;
187
218
  if (time)
188
219
  args.push(`@${time}s`);
189
- console.log(`[PlayerController] ${message}`, ...args);
220
+ console.log(`[PlayerController: ${this.trackId}] ${message}`, ...args);
190
221
  }
191
222
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@audiowalk/sdk",
3
- "version": "1.5.4",
3
+ "version": "1.5.6",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/audiowalk-cz/components.git"