@audiowalk/sdk 2.0.0-rc.3 → 2.0.1
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.
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { BehaviorSubject, Subject } from "rxjs";
|
|
2
|
-
import { PartialBy } from "../helpers/objects";
|
|
3
2
|
export interface PlayerControllerOptions {
|
|
4
3
|
autoSave?: boolean;
|
|
5
|
-
audioElement?: HTMLAudioElement;
|
|
4
|
+
audioElement?: HTMLAudioElement | null;
|
|
6
5
|
loop?: boolean;
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
fadeIn?: boolean;
|
|
7
|
+
fadeOut?: boolean;
|
|
8
|
+
fadeTime?: number;
|
|
9
9
|
keepPlayer?: boolean;
|
|
10
10
|
volume?: number;
|
|
11
11
|
}
|
|
12
|
-
export type PlayerControllerParams = PartialBy<PlayerControllerOptions, "crossfadeTime">;
|
|
13
12
|
export declare enum PlayerStatus {
|
|
14
13
|
"playing" = "playing",
|
|
15
14
|
"paused" = "paused",
|
|
@@ -33,21 +32,22 @@ export declare class PlayerController {
|
|
|
33
32
|
private destroyEvent;
|
|
34
33
|
private volume;
|
|
35
34
|
private fadeCancelEvent;
|
|
36
|
-
constructor(trackId: string, trackUrl: string, options?:
|
|
35
|
+
constructor(trackId: string, trackUrl: string, options?: PlayerControllerOptions);
|
|
37
36
|
open(file: string): Promise<void>;
|
|
38
37
|
destroy(params?: {
|
|
39
38
|
now?: boolean;
|
|
39
|
+
fade?: boolean;
|
|
40
40
|
}): Promise<void>;
|
|
41
41
|
private destroyNow;
|
|
42
42
|
preload(): Promise<void>;
|
|
43
43
|
play(params?: {
|
|
44
|
-
|
|
44
|
+
fadeIn?: boolean;
|
|
45
45
|
}): Promise<this | undefined>;
|
|
46
46
|
pause(params?: {
|
|
47
|
-
|
|
47
|
+
fadeOut?: boolean;
|
|
48
48
|
}): Promise<void>;
|
|
49
49
|
stop(params?: {
|
|
50
|
-
|
|
50
|
+
fadeOut?: boolean;
|
|
51
51
|
}): Promise<void>;
|
|
52
52
|
seekTo(seconds: number): void;
|
|
53
53
|
setVolume(volume: number, params?: {
|
|
@@ -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,EAAmB,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"player.controller.d.ts","sourceRoot":"","sources":["../../src/player/player.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAwC,OAAO,EAAmB,MAAM,MAAM,CAAC;AAGvG,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACvC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oBAAY,YAAY;IACtB,SAAS,YAAY;IACrB,QAAQ,WAAW;IACnB,OAAO,UAAU;CAClB;AAED,qBAAa,gBAAgB;IAsCf,OAAO,CAAC,OAAO;IArC3B,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,CAAoD;IAExE,OAAO,CAAC,OAAO,CAAoC;IAEnD,OAAO,CAAC,cAAc,CASpB;IAEF,OAAO,CAAC,SAAS,CAAS;IAC1B,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,uBAA4B;IAuEtF,IAAI,CAAC,IAAI,EAAE,MAAM;IAYjB,OAAO,CAAC,MAAM,GAAE;QAAE,GAAG,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAA+C;IAmBpG,OAAO,CAAC,UAAU;IAQZ,OAAO;IAUP,IAAI,CAAC,MAAM,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAoC;IAmBnE,KAAK,CAAC,MAAM,GAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAsC;IAkBvE,IAAI,CAAC,MAAM,GAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAsC;IAmB5E,MAAM,CAAC,OAAO,EAAE,MAAM;IAQhB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAO;YAYjD,YAAY;IA2BpB,OAAO;IAMP,MAAM;IAMZ,IAAI,CAAC,OAAO,GAAE,MAAW;IAKzB,OAAO,CAAC,OAAO,GAAE,MAAW;YAMd,YAAY;IAK1B,OAAO,CAAC,GAAG;CAOZ"}
|
|
@@ -20,7 +20,14 @@ export class PlayerController {
|
|
|
20
20
|
localStorage = new LocalStorageController({ prefix: "player" });
|
|
21
21
|
options;
|
|
22
22
|
defaultOptions = {
|
|
23
|
-
|
|
23
|
+
fadeTime: 2000,
|
|
24
|
+
audioElement: null,
|
|
25
|
+
autoSave: false,
|
|
26
|
+
loop: false,
|
|
27
|
+
fadeIn: false,
|
|
28
|
+
fadeOut: false,
|
|
29
|
+
keepPlayer: false,
|
|
30
|
+
volume: 1,
|
|
24
31
|
};
|
|
25
32
|
destroyed = false;
|
|
26
33
|
destroyEvent = new Subject();
|
|
@@ -42,7 +49,7 @@ export class PlayerController {
|
|
|
42
49
|
});
|
|
43
50
|
this.playerElement.addEventListener("ended", () => {
|
|
44
51
|
this.savePosition(0);
|
|
45
|
-
if (!this.options.
|
|
52
|
+
if (!this.options.fadeOut && !this.options.loop) {
|
|
46
53
|
this.onStop.next();
|
|
47
54
|
this.status.next(PlayerStatus.ended);
|
|
48
55
|
}
|
|
@@ -70,11 +77,11 @@ export class PlayerController {
|
|
|
70
77
|
if (this.options.autoSave) {
|
|
71
78
|
this.currentTime.pipe(takeUntil(this.destroyEvent)).subscribe((currentTime) => this.savePosition(currentTime));
|
|
72
79
|
}
|
|
73
|
-
if (this.options.
|
|
80
|
+
if (this.options.fadeOut && !this.options.loop) {
|
|
74
81
|
combineLatest([this.currentTime, this.totalTime])
|
|
75
82
|
.pipe(takeUntil(this.destroyEvent))
|
|
76
83
|
.pipe(filter(([currentTime, totalTime]) => !!totalTime)) // track is loaded
|
|
77
|
-
.pipe(filter(([currentTime, totalTime]) => currentTime >= totalTime - this.options.
|
|
84
|
+
.pipe(filter(([currentTime, totalTime]) => currentTime >= totalTime - this.options.fadeTime / 1000)) // crossfading should start
|
|
78
85
|
.subscribe(([currentTime, totalTime]) => {
|
|
79
86
|
if (this.status.value !== PlayerStatus.ended)
|
|
80
87
|
this.stop();
|
|
@@ -94,16 +101,17 @@ export class PlayerController {
|
|
|
94
101
|
this.playerElement.currentTime = 0;
|
|
95
102
|
this.playerElement.volume = this.volume;
|
|
96
103
|
}
|
|
97
|
-
async destroy(params = { now: false }) {
|
|
104
|
+
async destroy(params = { now: false, fade: this.options.fadeOut }) {
|
|
98
105
|
this.log("Called destroy", params);
|
|
99
106
|
this.destroyed = true;
|
|
100
107
|
if (this.status.value !== PlayerStatus.ended) {
|
|
101
|
-
await this.stop();
|
|
108
|
+
await this.stop({ fadeOut: params.fade });
|
|
102
109
|
return this.destroyNow();
|
|
103
110
|
}
|
|
104
|
-
// if crossfade is enabled, we might be ending crossfade
|
|
105
|
-
if (this.
|
|
106
|
-
|
|
111
|
+
// if crossfade is enabled, we might be in stopped status but ending crossfade, so wait for the crossfade to finish
|
|
112
|
+
if (this.playerElement.paused !== true) {
|
|
113
|
+
this.log("Waiting for crossfade to finish destroying player");
|
|
114
|
+
setTimeout(() => this.destroyNow(), this.options.fadeTime);
|
|
107
115
|
}
|
|
108
116
|
else {
|
|
109
117
|
this.destroyNow();
|
|
@@ -124,14 +132,15 @@ export class PlayerController {
|
|
|
124
132
|
this.playerElement.volume = this.volume;
|
|
125
133
|
this.log("Preloaded");
|
|
126
134
|
}
|
|
127
|
-
async play(params = {
|
|
135
|
+
async play(params = { fadeIn: this.options.fadeIn }) {
|
|
128
136
|
if (!this.playerElement.src)
|
|
129
137
|
throw new Error("No file opened");
|
|
130
138
|
if (this.status.value === PlayerStatus.playing)
|
|
131
139
|
return;
|
|
132
140
|
this.log("Called play", params);
|
|
141
|
+
this.fadeCancelEvent.next();
|
|
133
142
|
await this.playerElement?.play();
|
|
134
|
-
if (params.
|
|
143
|
+
if (params.fadeIn) {
|
|
135
144
|
await this.fadeIn();
|
|
136
145
|
}
|
|
137
146
|
else {
|
|
@@ -139,7 +148,7 @@ export class PlayerController {
|
|
|
139
148
|
}
|
|
140
149
|
return this;
|
|
141
150
|
}
|
|
142
|
-
async pause(params = {
|
|
151
|
+
async pause(params = { fadeOut: this.options.fadeOut }) {
|
|
143
152
|
if (!this.playerElement.src)
|
|
144
153
|
throw new Error("No file opened");
|
|
145
154
|
if (this.status.value === PlayerStatus.ended)
|
|
@@ -147,18 +156,20 @@ export class PlayerController {
|
|
|
147
156
|
this.log("Called pause", params);
|
|
148
157
|
this.status.next(PlayerStatus.paused);
|
|
149
158
|
this.onPause.next();
|
|
150
|
-
|
|
159
|
+
this.fadeCancelEvent.next();
|
|
160
|
+
if (params.fadeOut) {
|
|
151
161
|
await this.fadeOut();
|
|
152
162
|
}
|
|
153
163
|
this.playerElement?.pause();
|
|
154
164
|
}
|
|
155
|
-
async stop(params = {
|
|
165
|
+
async stop(params = { fadeOut: this.options.fadeOut }) {
|
|
156
166
|
this.log("Called stop", params);
|
|
157
167
|
if (!this.destroyed && this.status.value !== PlayerStatus.ended) {
|
|
158
168
|
this.status.next(PlayerStatus.ended);
|
|
159
169
|
this.onStop.next();
|
|
160
170
|
}
|
|
161
|
-
|
|
171
|
+
this.fadeCancelEvent.next();
|
|
172
|
+
if (params.fadeOut) {
|
|
162
173
|
await this.fadeOut();
|
|
163
174
|
}
|
|
164
175
|
else {
|
|
@@ -188,7 +199,7 @@ export class PlayerController {
|
|
|
188
199
|
return new Promise((resolve, reject) => {
|
|
189
200
|
this.fadeCancelEvent.next();
|
|
190
201
|
const fadeOutInterval = 100;
|
|
191
|
-
const fadeOutSteps = this.options.
|
|
202
|
+
const fadeOutSteps = this.options.fadeTime / fadeOutInterval;
|
|
192
203
|
const fadeOutStep = (targetVolume - this.playerElement.volume) / fadeOutSteps;
|
|
193
204
|
if (fadeOutStep === 0)
|
|
194
205
|
return resolve();
|