tunzo-player 1.0.7 → 1.0.9

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,5 +1,5 @@
1
1
  export declare class Player {
2
- private static audioInstance;
2
+ private static audio;
3
3
  private static currentSong;
4
4
  private static currentIndex;
5
5
  private static isPlaying;
@@ -9,24 +9,23 @@ export declare class Player {
9
9
  private static queue;
10
10
  private static playlist;
11
11
  private static selectedQuality;
12
- private static readonly audioId;
13
- private static isInitialized;
14
12
  /** Initialize with playlist and quality */
15
- static initialize(playlist?: any[], quality?: number): void;
16
- static play(song: any, index?: number): Promise<void>;
17
- private static cleanupCurrentPlayback;
18
- static pause(): Promise<void>;
19
- static resume(): Promise<void>;
20
- static togglePlayPause(): Promise<void>;
21
- static next(): Promise<void>;
22
- static prev(): Promise<void>;
23
- static autoNext(): Promise<void>;
24
- static playRandom(): Promise<void>;
13
+ static initialize(playlist: any[], quality?: number): void;
14
+ /** Call this once on user gesture to unlock audio in WebView */
15
+ static unlockAudio(): void;
16
+ static play(song: any, index?: number): void;
17
+ static pause(): void;
18
+ static resume(): void;
19
+ static togglePlayPause(): void;
20
+ static next(): void;
21
+ static prev(): void;
22
+ static seek(seconds: number): void;
23
+ static autoNext(): void;
24
+ static playRandom(): void;
25
25
  static toggleShuffle(): void;
26
26
  static addToQueue(song: any): void;
27
27
  static removeFromQueue(index: number): void;
28
28
  static reorderQueue(from: number, to: number): void;
29
- static seekTo(time: number): Promise<void>;
30
29
  static getCurrentTime(): number;
31
30
  static getDuration(): number;
32
31
  static formatTime(time: number): string;
@@ -35,6 +34,4 @@ export declare class Player {
35
34
  static setQuality(index: number): void;
36
35
  static getQueue(): any[];
37
36
  static getPlaylist(): any[];
38
- static getShuffleStatus(): boolean;
39
- static destroy(): Promise<void>;
40
37
  }
@@ -1,218 +1,94 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.Player = void 0;
13
- const core_1 = require("@capacitor/core");
14
- const native_audio_1 = require("@capacitor-community/native-audio");
15
4
  class Player {
16
5
  /** Initialize with playlist and quality */
17
- static initialize(playlist = [], quality = 3) {
18
- if (!core_1.Capacitor.isNativePlatform() && !this.audioInstance) {
19
- this.audioInstance = new Audio();
20
- }
21
- this.playlist = [...playlist];
6
+ static initialize(playlist, quality = 3) {
7
+ this.playlist = playlist;
22
8
  this.selectedQuality = quality;
23
- this.isInitialized = true;
24
- }
25
- static play(song_1) {
26
- return __awaiter(this, arguments, void 0, function* (song, index = 0) {
27
- var _a, _b;
28
- if (!this.isInitialized) {
29
- console.error('Player not initialized. Call Player.initialize() first.');
30
- return;
31
- }
32
- if (!song || !song.downloadUrl) {
33
- console.error('Invalid song or missing downloadUrl');
34
- return;
35
- }
36
- // Stop current playback
37
- yield this.cleanupCurrentPlayback();
38
- this.currentSong = song;
39
- this.currentIndex = index;
40
- const url = ((_a = song.downloadUrl[this.selectedQuality]) === null || _a === void 0 ? void 0 : _a.url) || ((_b = song.downloadUrl[0]) === null || _b === void 0 ? void 0 : _b.url);
41
- if (!url) {
42
- console.error('No valid URL found for playback');
43
- return;
44
- }
45
- try {
46
- if (core_1.Capacitor.isNativePlatform()) {
47
- // For native platform, use the correct NativeAudio methods
48
- yield native_audio_1.NativeAudio.configure({
49
- fade: false,
50
- focus: true
51
- });
52
- yield native_audio_1.NativeAudio.preload({
53
- assetId: this.audioId,
54
- assetPath: url,
55
- audioChannelNum: 1,
56
- isUrl: true
57
- });
58
- yield native_audio_1.NativeAudio.play({
59
- assetId: this.audioId
60
- });
61
- // For native, we need to manually track duration
62
- this.duration = song.duration || 0;
63
- }
64
- else {
65
- if (!this.audioInstance) {
66
- this.audioInstance = new Audio();
67
- }
68
- this.audioInstance.src = url;
69
- yield this.audioInstance.play();
70
- this.audioInstance.onloadedmetadata = () => {
71
- var _a;
72
- this.duration = ((_a = this.audioInstance) === null || _a === void 0 ? void 0 : _a.duration) || 0;
73
- };
74
- this.audioInstance.ontimeupdate = () => {
75
- var _a;
76
- this.currentTime = ((_a = this.audioInstance) === null || _a === void 0 ? void 0 : _a.currentTime) || 0;
77
- };
78
- this.audioInstance.onended = () => {
79
- this.autoNext();
80
- };
81
- this.audioInstance.onerror = () => {
82
- console.error('Error during playback');
83
- this.isPlaying = false;
84
- };
85
- }
86
- this.isPlaying = true;
87
- }
88
- catch (err) {
89
- console.error('Playback error:', err);
90
- this.isPlaying = false;
91
- }
92
- });
93
9
  }
94
- static cleanupCurrentPlayback() {
95
- return __awaiter(this, void 0, void 0, function* () {
96
- if (core_1.Capacitor.isNativePlatform()) {
97
- try {
98
- yield native_audio_1.NativeAudio.stop({ assetId: this.audioId });
99
- yield native_audio_1.NativeAudio.unload({ assetId: this.audioId });
100
- }
101
- catch (err) {
102
- console.debug('No audio to unload');
103
- }
104
- }
105
- else if (this.audioInstance) {
106
- this.audioInstance.pause();
107
- this.audioInstance.src = '';
108
- this.audioInstance.onloadedmetadata = null;
109
- this.audioInstance.ontimeupdate = null;
110
- this.audioInstance.onended = null;
111
- this.audioInstance.onerror = null;
112
- }
10
+ /** Call this once on user gesture to unlock audio in WebView */
11
+ static unlockAudio() {
12
+ this.audio.src = '';
13
+ this.audio.load();
14
+ this.audio.play().catch(() => { });
15
+ }
16
+ static play(song, index = 0) {
17
+ var _a;
18
+ if (!song || !song.downloadUrl)
19
+ return;
20
+ this.currentSong = song;
21
+ this.currentIndex = index;
22
+ this.audio.src = ((_a = song.downloadUrl[this.selectedQuality]) === null || _a === void 0 ? void 0 : _a.url) || '';
23
+ this.audio.load(); // Ensure audio is loaded before play
24
+ this.audio.play().then(() => {
25
+ this.isPlaying = true;
26
+ }).catch((err) => {
27
+ // Handle play errors (autoplay, WebView restrictions)
28
+ this.isPlaying = false;
29
+ console.warn('Audio play failed:', err);
113
30
  });
31
+ // Set duration
32
+ this.audio.onloadedmetadata = () => {
33
+ this.duration = this.audio.duration;
34
+ };
35
+ // Set current time
36
+ this.audio.ontimeupdate = () => {
37
+ this.currentTime = this.audio.currentTime;
38
+ };
39
+ // Auto-play next song
40
+ this.audio.onended = () => {
41
+ this.autoNext();
42
+ };
114
43
  }
115
44
  static pause() {
116
- return __awaiter(this, void 0, void 0, function* () {
117
- if (!this.isInitialized)
118
- return;
119
- try {
120
- if (core_1.Capacitor.isNativePlatform()) {
121
- yield native_audio_1.NativeAudio.pause({ assetId: this.audioId });
122
- }
123
- else if (this.audioInstance) {
124
- this.audioInstance.pause();
125
- }
126
- this.isPlaying = false;
127
- }
128
- catch (err) {
129
- console.error('Pause error:', err);
130
- }
131
- });
45
+ this.audio.pause();
46
+ this.isPlaying = false;
132
47
  }
133
48
  static resume() {
134
- return __awaiter(this, void 0, void 0, function* () {
135
- if (!this.isInitialized)
136
- return;
137
- try {
138
- if (core_1.Capacitor.isNativePlatform()) {
139
- yield native_audio_1.NativeAudio.play({ assetId: this.audioId });
140
- }
141
- else if (this.audioInstance) {
142
- yield this.audioInstance.play();
143
- }
144
- this.isPlaying = true;
145
- }
146
- catch (err) {
147
- console.error('Resume error:', err);
148
- }
149
- });
49
+ this.audio.play();
50
+ this.isPlaying = true;
150
51
  }
151
52
  static togglePlayPause() {
152
- return __awaiter(this, void 0, void 0, function* () {
153
- if (!this.isInitialized)
154
- return;
155
- if (this.isPlaying) {
156
- yield this.pause();
157
- }
158
- else if (this.currentSong) {
159
- yield this.resume();
160
- }
161
- else if (this.playlist.length > 0) {
162
- yield this.play(this.playlist[0], 0);
163
- }
164
- });
53
+ if (this.isPlaying) {
54
+ this.pause();
55
+ }
56
+ else {
57
+ this.resume();
58
+ }
165
59
  }
166
60
  static next() {
167
- return __awaiter(this, void 0, void 0, function* () {
168
- if (!this.isInitialized)
169
- return;
170
- if (this.queue.length > 0) {
171
- const nextQueued = this.queue.shift();
172
- const index = this.playlist.findIndex(s => s.id === nextQueued.id);
173
- yield this.play(nextQueued, index);
174
- }
175
- else if (this.isShuffle) {
176
- yield this.playRandom();
177
- }
178
- else if (this.currentIndex < this.playlist.length - 1) {
179
- yield this.play(this.playlist[this.currentIndex + 1], this.currentIndex + 1);
180
- }
181
- else {
182
- // End of playlist
183
- this.isPlaying = false;
184
- this.currentSong = null;
185
- }
186
- });
61
+ if (this.queue.length > 0) {
62
+ const nextQueued = this.queue.shift();
63
+ const index = this.playlist.findIndex(s => s.id === nextQueued.id);
64
+ this.play(nextQueued, index);
65
+ }
66
+ else if (this.isShuffle) {
67
+ this.playRandom();
68
+ }
69
+ else if (this.currentIndex < this.playlist.length - 1) {
70
+ this.play(this.playlist[this.currentIndex + 1], this.currentIndex + 1);
71
+ }
187
72
  }
188
73
  static prev() {
189
- return __awaiter(this, void 0, void 0, function* () {
190
- if (!this.isInitialized)
191
- return;
192
- if (this.currentTime > 3) {
193
- // If more than 3 seconds into song, restart current song
194
- yield this.seekTo(0);
195
- }
196
- else if (this.currentIndex > 0) {
197
- yield this.play(this.playlist[this.currentIndex - 1], this.currentIndex - 1);
198
- }
199
- });
74
+ if (this.currentIndex > 0) {
75
+ this.play(this.playlist[this.currentIndex - 1], this.currentIndex - 1);
76
+ }
77
+ }
78
+ static seek(seconds) {
79
+ this.audio.currentTime = seconds;
200
80
  }
201
81
  static autoNext() {
202
- return __awaiter(this, void 0, void 0, function* () {
203
- yield this.next();
204
- });
82
+ this.next();
205
83
  }
206
84
  static playRandom() {
207
- return __awaiter(this, void 0, void 0, function* () {
208
- if (!this.isInitialized || this.playlist.length <= 1)
209
- return;
210
- let randomIndex;
211
- do {
212
- randomIndex = Math.floor(Math.random() * this.playlist.length);
213
- } while (randomIndex === this.currentIndex && this.playlist.length > 1);
214
- yield this.play(this.playlist[randomIndex], randomIndex);
215
- });
85
+ if (this.playlist.length <= 1)
86
+ return;
87
+ let randomIndex;
88
+ do {
89
+ randomIndex = Math.floor(Math.random() * this.playlist.length);
90
+ } while (randomIndex === this.currentIndex);
91
+ this.play(this.playlist[randomIndex], randomIndex);
216
92
  }
217
93
  static toggleShuffle() {
218
94
  this.isShuffle = !this.isShuffle;
@@ -223,34 +99,11 @@ class Player {
223
99
  }
224
100
  }
225
101
  static removeFromQueue(index) {
226
- if (index >= 0 && index < this.queue.length) {
227
- this.queue.splice(index, 1);
228
- }
102
+ this.queue.splice(index, 1);
229
103
  }
230
104
  static reorderQueue(from, to) {
231
- if (from >= 0 && from < this.queue.length && to >= 0 && to < this.queue.length) {
232
- const item = this.queue.splice(from, 1)[0];
233
- this.queue.splice(to, 0, item);
234
- }
235
- }
236
- static seekTo(time) {
237
- return __awaiter(this, void 0, void 0, function* () {
238
- if (!this.isInitialized)
239
- return;
240
- try {
241
- if (core_1.Capacitor.isNativePlatform()) {
242
- // NativeAudio doesn't support seeking directly, might need a plugin extension
243
- console.warn('Seeking not fully supported on native platform');
244
- }
245
- else if (this.audioInstance) {
246
- this.audioInstance.currentTime = time;
247
- }
248
- this.currentTime = time;
249
- }
250
- catch (err) {
251
- console.error('Seek error:', err);
252
- }
253
- });
105
+ const item = this.queue.splice(from, 1)[0];
106
+ this.queue.splice(to, 0, item);
254
107
  }
255
108
  static getCurrentTime() {
256
109
  return this.currentTime;
@@ -270,36 +123,23 @@ class Player {
270
123
  return this.currentSong;
271
124
  }
272
125
  static setQuality(index) {
273
- if (index >= 0) {
274
- this.selectedQuality = index;
275
- }
126
+ this.selectedQuality = index;
276
127
  }
277
128
  static getQueue() {
278
- return [...this.queue];
129
+ return this.queue;
279
130
  }
280
131
  static getPlaylist() {
281
- return [...this.playlist];
282
- }
283
- static getShuffleStatus() {
284
- return this.isShuffle;
285
- }
286
- static destroy() {
287
- return __awaiter(this, void 0, void 0, function* () {
288
- yield this.cleanupCurrentPlayback();
289
- this.isInitialized = false;
290
- });
132
+ return this.playlist;
291
133
  }
292
134
  }
293
135
  exports.Player = Player;
294
- Player.audioInstance = null;
136
+ Player.audio = new Audio();
295
137
  Player.currentSong = null;
296
138
  Player.currentIndex = 0;
297
139
  Player.isPlaying = false;
298
140
  Player.currentTime = 0;
299
141
  Player.duration = 0;
300
- Player.isShuffle = false;
142
+ Player.isShuffle = true;
301
143
  Player.queue = [];
302
144
  Player.playlist = [];
303
145
  Player.selectedQuality = 3;
304
- Player.audioId = 'current-song';
305
- Player.isInitialized = false;
package/package.json CHANGED
@@ -1,28 +1,31 @@
1
1
  {
2
- "name": "tunzo-player",
3
- "version": "1.0.7",
4
- "description": "A music playback service for Angular and Ionic apps with native audio control support.",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "scripts": {
8
- "build": "tsc"
9
- },
10
- "keywords": [
11
- "music",
12
- "player",
13
- "angular",
14
- "ionic",
15
- "audio"
16
- ],
17
- "author": "Kulasekaran",
18
- "license": "MIT",
19
- "publishConfig": {
20
- "access": "public"
21
- },
22
- "devDependencies": {
23
- "typescript": "^5.8.3"
24
- },
25
- "dependencies": {
26
- "@capacitor-community/native-audio": "^7.0.0"
27
- }
2
+ "name": "tunzo-player",
3
+ "version": "1.0.9",
4
+ "description": "A music playback service for Angular and Ionic apps with native audio control support.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "publish:patch": "npm version patch && npm run build && npm publish",
10
+ "publish:minor": "npm version minor && npm run build && npm publish",
11
+ "publish:major": "npm version major && npm run build && npm publish",
12
+ "publish": "npm run build && npm publish"
13
+ },
14
+ "keywords": [
15
+ "music",
16
+ "player",
17
+ "angular",
18
+ "ionic",
19
+ "audio",
20
+ "native",
21
+ "playback",
22
+ "service",
23
+ "tunzo",
24
+ "tunzo-player"
25
+ ],
26
+ "author": "Kulasekaran",
27
+ "license": "MIT",
28
+ "publishConfig": {
29
+ "access": "public"
30
+ }
28
31
  }
@@ -1,294 +1,164 @@
1
-
2
- import { Capacitor } from '@capacitor/core';
3
- import { NativeAudio } from '@capacitor-community/native-audio';
4
-
5
1
  export class Player {
6
- private static audioInstance: HTMLAudioElement | null = null;
7
- private static currentSong: any = null;
8
- private static currentIndex = 0;
9
- private static isPlaying = false;
10
- private static currentTime = 0;
11
- private static duration = 0;
12
- private static isShuffle = false;
13
- private static queue: any[] = [];
14
- private static playlist: any[] = [];
15
- private static selectedQuality = 3;
16
- private static readonly audioId: string = 'current-song';
17
- private static isInitialized = false;
18
-
19
- /** Initialize with playlist and quality */
20
- static initialize(playlist: any[] = [], quality = 3) {
21
- if (!Capacitor.isNativePlatform() && !this.audioInstance) {
22
- this.audioInstance = new Audio();
23
- }
24
-
25
- this.playlist = [...playlist];
26
- this.selectedQuality = quality;
27
- this.isInitialized = true;
28
- }
29
-
30
- static async play(song: any, index: number = 0) {
31
- if (!this.isInitialized) {
32
- console.error('Player not initialized. Call Player.initialize() first.');
33
- return;
34
- }
35
-
36
- if (!song || !song.downloadUrl) {
37
- console.error('Invalid song or missing downloadUrl');
38
- return;
2
+ private static audio = new Audio();
3
+ private static currentSong: any = null;
4
+ private static currentIndex = 0;
5
+ private static isPlaying = false;
6
+ private static currentTime = 0;
7
+ private static duration = 0;
8
+ private static isShuffle = true;
9
+ private static queue: any[] = [];
10
+ private static playlist: any[] = [];
11
+ private static selectedQuality = 3;
12
+
13
+ /** Initialize with playlist and quality */
14
+ static initialize(playlist: any[], quality = 3) {
15
+ this.playlist = playlist;
16
+ this.selectedQuality = quality;
17
+ }
18
+
19
+ /** Call this once on user gesture to unlock audio in WebView */
20
+ static unlockAudio() {
21
+ this.audio.src = '';
22
+ this.audio.load();
23
+ this.audio.play().catch(() => {});
24
+ }
25
+
26
+ static play(song: any, index: number = 0) {
27
+ if (!song || !song.downloadUrl) return;
28
+
29
+ this.currentSong = song;
30
+ this.currentIndex = index;
31
+ this.audio.src = song.downloadUrl[this.selectedQuality]?.url || '';
32
+ this.audio.load(); // Ensure audio is loaded before play
33
+ this.audio.play().then(() => {
34
+ this.isPlaying = true;
35
+ }).catch((err) => {
36
+ // Handle play errors (autoplay, WebView restrictions)
37
+ this.isPlaying = false;
38
+ console.warn('Audio play failed:', err);
39
+ });
40
+
41
+ // Set duration
42
+ this.audio.onloadedmetadata = () => {
43
+ this.duration = this.audio.duration;
44
+ };
45
+
46
+ // Set current time
47
+ this.audio.ontimeupdate = () => {
48
+ this.currentTime = this.audio.currentTime;
49
+ };
50
+
51
+ // Auto-play next song
52
+ this.audio.onended = () => {
53
+ this.autoNext();
54
+ };
55
+ }
56
+
57
+ static pause() {
58
+ this.audio.pause();
59
+ this.isPlaying = false;
39
60
  }
40
-
41
- // Stop current playback
42
- await this.cleanupCurrentPlayback();
43
-
44
- this.currentSong = song;
45
- this.currentIndex = index;
46
- const url = song.downloadUrl[this.selectedQuality]?.url || song.downloadUrl[0]?.url;
47
-
48
- if (!url) {
49
- console.error('No valid URL found for playback');
50
- return;
61
+
62
+ static resume() {
63
+ this.audio.play();
64
+ this.isPlaying = true;
51
65
  }
52
-
53
- try {
54
- if (Capacitor.isNativePlatform()) {
55
- // For native platform, use the correct NativeAudio methods
56
- await NativeAudio.configure({
57
- fade: false,
58
- focus: true
59
- });
60
-
61
- await NativeAudio.preload({
62
- assetId: this.audioId,
63
- assetPath: url,
64
- audioChannelNum: 1,
65
- isUrl: true
66
- });
67
-
68
- await NativeAudio.play({
69
- assetId: this.audioId
70
- });
71
-
72
- // For native, we need to manually track duration
73
- this.duration = song.duration || 0;
66
+
67
+ static togglePlayPause() {
68
+ if (this.isPlaying) {
69
+ this.pause();
74
70
  } else {
75
- if (!this.audioInstance) {
76
- this.audioInstance = new Audio();
77
- }
78
-
79
- this.audioInstance.src = url;
80
- await this.audioInstance.play();
81
-
82
- this.audioInstance.onloadedmetadata = () => {
83
- this.duration = this.audioInstance?.duration || 0;
84
- };
85
-
86
- this.audioInstance.ontimeupdate = () => {
87
- this.currentTime = this.audioInstance?.currentTime || 0;
88
- };
89
-
90
- this.audioInstance.onended = () => {
91
- this.autoNext();
92
- };
93
-
94
- this.audioInstance.onerror = () => {
95
- console.error('Error during playback');
96
- this.isPlaying = false;
97
- };
71
+ this.resume();
98
72
  }
99
-
100
- this.isPlaying = true;
101
- } catch (err) {
102
- console.error('Playback error:', err);
103
- this.isPlaying = false;
104
73
  }
105
- }
106
-
107
- private static async cleanupCurrentPlayback() {
108
- if (Capacitor.isNativePlatform()) {
109
- try {
110
- await NativeAudio.stop({ assetId: this.audioId });
111
- await NativeAudio.unload({ assetId: this.audioId });
112
- } catch (err) {
113
- console.debug('No audio to unload');
74
+
75
+ static next() {
76
+ if (this.queue.length > 0) {
77
+ const nextQueued = this.queue.shift();
78
+ const index = this.playlist.findIndex(s => s.id === nextQueued.id);
79
+ this.play(nextQueued, index);
80
+ } else if (this.isShuffle) {
81
+ this.playRandom();
82
+ } else if (this.currentIndex < this.playlist.length - 1) {
83
+ this.play(this.playlist[this.currentIndex + 1], this.currentIndex + 1);
114
84
  }
115
- } else if (this.audioInstance) {
116
- this.audioInstance.pause();
117
- this.audioInstance.src = '';
118
- this.audioInstance.onloadedmetadata = null;
119
- this.audioInstance.ontimeupdate = null;
120
- this.audioInstance.onended = null;
121
- this.audioInstance.onerror = null;
122
85
  }
123
- }
124
-
125
- static async pause() {
126
- if (!this.isInitialized) return;
127
-
128
- try {
129
- if (Capacitor.isNativePlatform()) {
130
- await NativeAudio.pause({ assetId: this.audioId });
131
- } else if (this.audioInstance) {
132
- this.audioInstance.pause();
86
+
87
+ static prev() {
88
+ if (this.currentIndex > 0) {
89
+ this.play(this.playlist[this.currentIndex - 1], this.currentIndex - 1);
133
90
  }
134
- this.isPlaying = false;
135
- } catch (err) {
136
- console.error('Pause error:', err);
137
91
  }
138
- }
139
-
140
- static async resume() {
141
- if (!this.isInitialized) return;
142
-
143
- try {
144
- if (Capacitor.isNativePlatform()) {
145
- await NativeAudio.play({ assetId: this.audioId });
146
- } else if (this.audioInstance) {
147
- await this.audioInstance.play();
92
+
93
+ static seek(seconds: number) {
94
+ this.audio.currentTime = seconds;
95
+ }
96
+
97
+ static autoNext() {
98
+ this.next();
99
+ }
100
+
101
+ static playRandom() {
102
+ if (this.playlist.length <= 1) return;
103
+
104
+ let randomIndex;
105
+ do {
106
+ randomIndex = Math.floor(Math.random() * this.playlist.length);
107
+ } while (randomIndex === this.currentIndex);
108
+
109
+ this.play(this.playlist[randomIndex], randomIndex);
110
+ }
111
+
112
+ static toggleShuffle() {
113
+ this.isShuffle = !this.isShuffle;
114
+ }
115
+
116
+ static addToQueue(song: any) {
117
+ if (!this.queue.some(q => q.id === song.id)) {
118
+ this.queue.push(song);
148
119
  }
149
- this.isPlaying = true;
150
- } catch (err) {
151
- console.error('Resume error:', err);
152
120
  }
153
- }
154
-
155
- static async togglePlayPause() {
156
- if (!this.isInitialized) return;
157
-
158
- if (this.isPlaying) {
159
- await this.pause();
160
- } else if (this.currentSong) {
161
- await this.resume();
162
- } else if (this.playlist.length > 0) {
163
- await this.play(this.playlist[0], 0);
121
+
122
+ static removeFromQueue(index: number) {
123
+ this.queue.splice(index, 1);
164
124
  }
165
- }
166
-
167
- static async next() {
168
- if (!this.isInitialized) return;
169
-
170
- if (this.queue.length > 0) {
171
- const nextQueued = this.queue.shift();
172
- const index = this.playlist.findIndex(s => s.id === nextQueued.id);
173
- await this.play(nextQueued, index);
174
- } else if (this.isShuffle) {
175
- await this.playRandom();
176
- } else if (this.currentIndex < this.playlist.length - 1) {
177
- await this.play(this.playlist[this.currentIndex + 1], this.currentIndex + 1);
178
- } else {
179
- // End of playlist
180
- this.isPlaying = false;
181
- this.currentSong = null;
125
+
126
+ static reorderQueue(from: number, to: number) {
127
+ const item = this.queue.splice(from, 1)[0];
128
+ this.queue.splice(to, 0, item);
182
129
  }
183
- }
184
-
185
- static async prev() {
186
- if (!this.isInitialized) return;
187
-
188
- if (this.currentTime > 3) {
189
- // If more than 3 seconds into song, restart current song
190
- await this.seekTo(0);
191
- } else if (this.currentIndex > 0) {
192
- await this.play(this.playlist[this.currentIndex - 1], this.currentIndex - 1);
130
+
131
+ static getCurrentTime(): number {
132
+ return this.currentTime;
193
133
  }
194
- }
195
-
196
- static async autoNext() {
197
- await this.next();
198
- }
199
-
200
- static async playRandom() {
201
- if (!this.isInitialized || this.playlist.length <= 1) return;
202
-
203
- let randomIndex;
204
- do {
205
- randomIndex = Math.floor(Math.random() * this.playlist.length);
206
- } while (randomIndex === this.currentIndex && this.playlist.length > 1);
207
-
208
- await this.play(this.playlist[randomIndex], randomIndex);
209
- }
210
-
211
- static toggleShuffle() {
212
- this.isShuffle = !this.isShuffle;
213
- }
214
-
215
- static addToQueue(song: any) {
216
- if (!this.queue.some(q => q.id === song.id)) {
217
- this.queue.push(song);
134
+
135
+ static getDuration(): number {
136
+ return this.duration;
218
137
  }
219
- }
220
-
221
- static removeFromQueue(index: number) {
222
- if (index >= 0 && index < this.queue.length) {
223
- this.queue.splice(index, 1);
138
+
139
+ static formatTime(time: number): string {
140
+ const minutes = Math.floor(time / 60);
141
+ const seconds = Math.floor(time % 60);
142
+ return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
224
143
  }
225
- }
226
-
227
- static reorderQueue(from: number, to: number) {
228
- if (from >= 0 && from < this.queue.length && to >= 0 && to < this.queue.length) {
229
- const item = this.queue.splice(from, 1)[0];
230
- this.queue.splice(to, 0, item);
144
+
145
+ static isPlayingSong(): boolean {
146
+ return this.isPlaying;
231
147
  }
232
- }
233
-
234
- static async seekTo(time: number) {
235
- if (!this.isInitialized) return;
236
-
237
- try {
238
- if (Capacitor.isNativePlatform()) {
239
- // NativeAudio doesn't support seeking directly, might need a plugin extension
240
- console.warn('Seeking not fully supported on native platform');
241
- } else if (this.audioInstance) {
242
- this.audioInstance.currentTime = time;
243
- }
244
- this.currentTime = time;
245
- } catch (err) {
246
- console.error('Seek error:', err);
148
+
149
+ static getCurrentSong(): any {
150
+ return this.currentSong;
247
151
  }
248
- }
249
-
250
- static getCurrentTime(): number {
251
- return this.currentTime;
252
- }
253
-
254
- static getDuration(): number {
255
- return this.duration;
256
- }
257
-
258
- static formatTime(time: number): string {
259
- const minutes = Math.floor(time / 60);
260
- const seconds = Math.floor(time % 60);
261
- return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
262
- }
263
-
264
- static isPlayingSong(): boolean {
265
- return this.isPlaying;
266
- }
267
-
268
- static getCurrentSong(): any {
269
- return this.currentSong;
270
- }
271
-
272
- static setQuality(index: number) {
273
- if (index >= 0) {
152
+
153
+ static setQuality(index: number) {
274
154
  this.selectedQuality = index;
275
155
  }
156
+
157
+ static getQueue(): any[] {
158
+ return this.queue;
159
+ }
160
+
161
+ static getPlaylist(): any[] {
162
+ return this.playlist;
163
+ }
276
164
  }
277
-
278
- static getQueue(): any[] {
279
- return [...this.queue];
280
- }
281
-
282
- static getPlaylist(): any[] {
283
- return [...this.playlist];
284
- }
285
-
286
- static getShuffleStatus(): boolean {
287
- return this.isShuffle;
288
- }
289
-
290
- static async destroy() {
291
- await this.cleanupCurrentPlayback();
292
- this.isInitialized = false;
293
- }
294
- }
package/tsconfig.json CHANGED
@@ -14,8 +14,7 @@
14
14
  "esModuleInterop": true, // allow default imports from CommonJS
15
15
  "forceConsistentCasingInFileNames": true,
16
16
  "strict": true,
17
- "skipLibCheck": true,
18
- "types": ["@capacitor-community/native-audio"] // speed up builds, safe for libs
17
+ "skipLibCheck": true // speed up builds, safe for libs
19
18
  },
20
19
  "include": ["src"] // only compile the src folder
21
20
  }