tunzo-player 1.0.32 → 1.0.33

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,4 +1,5 @@
1
1
  import { BehaviorSubject } from 'rxjs';
2
+ import { ToastController } from '@ionic/angular/standalone';
2
3
  export declare class Player {
3
4
  private static audio;
4
5
  private static currentSong;
@@ -11,10 +12,14 @@ export declare class Player {
11
12
  static queue$: BehaviorSubject<any[]>;
12
13
  private static playlist;
13
14
  private static selectedQuality;
15
+ private static intendedPlaying;
16
+ private static toastCtrl;
14
17
  /** Initialize with playlist and quality */
15
18
  static initialize(playlist: any[], quality?: number): void;
19
+ static setToastController(controller: ToastController): void;
16
20
  /** Setup audio element for better compatibility */
17
21
  private static setupAudioElement;
22
+ private static startWatchdog;
18
23
  /** Call this once on user gesture to unlock audio in WebView */
19
24
  static unlockAudio(): void;
20
25
  static play(song: any, index?: number): void;
@@ -28,7 +33,7 @@ export declare class Player {
28
33
  static playRandom(): void;
29
34
  static toggleShuffle(): void;
30
35
  static getShuffleStatus(): boolean;
31
- static addToQueue(song: any): void;
36
+ static addToQueue(song: any): Promise<void>;
32
37
  static removeFromQueue(index: number): void;
33
38
  static reorderQueue(from: number, to: number): void;
34
39
  static getCurrentTime(): number;
@@ -1,4 +1,13 @@
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
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.Player = void 0;
4
13
  const rxjs_1 = require("rxjs");
@@ -10,6 +19,10 @@ class Player {
10
19
  this.selectedQuality = quality;
11
20
  this.setupMediaSession();
12
21
  this.setupAudioElement();
22
+ this.startWatchdog();
23
+ }
24
+ static setToastController(controller) {
25
+ this.toastCtrl = controller;
13
26
  }
14
27
  /** Setup audio element for better compatibility */
15
28
  static setupAudioElement() {
@@ -52,6 +65,14 @@ class Player {
52
65
  console.error('Audio error:', this.audio.error, e);
53
66
  };
54
67
  }
68
+ static startWatchdog() {
69
+ setInterval(() => {
70
+ if (this.intendedPlaying && this.audio.paused && this.currentSong) {
71
+ console.log('Watchdog: Audio paused unexpectedly. Attempting to resume...');
72
+ this.audio.play().catch(e => console.warn('Watchdog resume failed:', e));
73
+ }
74
+ }, 10000);
75
+ }
55
76
  /** Call this once on user gesture to unlock audio in WebView */
56
77
  static unlockAudio() {
57
78
  this.audio.src = '';
@@ -62,6 +83,7 @@ class Player {
62
83
  var _a;
63
84
  if (!song || !song.downloadUrl)
64
85
  return;
86
+ this.intendedPlaying = true;
65
87
  this.currentSong = song;
66
88
  this.currentIndex = index;
67
89
  let url = ((_a = song.downloadUrl[this.selectedQuality]) === null || _a === void 0 ? void 0 : _a.url) || '';
@@ -84,6 +106,7 @@ class Player {
84
106
  });
85
107
  }
86
108
  static pause() {
109
+ this.intendedPlaying = false;
87
110
  this.audio.pause();
88
111
  this.isPlaying = false;
89
112
  keep_awake_1.KeepAwake.allowSleep();
@@ -92,6 +115,7 @@ class Player {
92
115
  }
93
116
  }
94
117
  static resume() {
118
+ this.intendedPlaying = true;
95
119
  this.audio.play();
96
120
  this.isPlaying = true;
97
121
  keep_awake_1.KeepAwake.keepAwake();
@@ -120,6 +144,9 @@ class Player {
120
144
  else if (this.currentIndex < this.playlist.length - 1) {
121
145
  this.play(this.playlist[this.currentIndex + 1], this.currentIndex + 1);
122
146
  }
147
+ else {
148
+ this.intendedPlaying = false;
149
+ }
123
150
  }
124
151
  static prev() {
125
152
  if (this.currentIndex > 0) {
@@ -149,10 +176,23 @@ class Player {
149
176
  return this.isShuffle;
150
177
  }
151
178
  static addToQueue(song) {
152
- if (!this.queue.some(q => q.id === song.id)) {
153
- this.queue.push(song);
154
- this.queue$.next([...this.queue]);
155
- }
179
+ return __awaiter(this, void 0, void 0, function* () {
180
+ if (!this.queue.some(q => q.id === song.id)) {
181
+ this.queue.push(song);
182
+ this.queue$.next([...this.queue]);
183
+ if (this.toastCtrl) {
184
+ const toast = yield this.toastCtrl.create({
185
+ message: 'Song added to queue',
186
+ duration: 2000,
187
+ position: 'bottom',
188
+ mode: 'ios',
189
+ color: 'dark',
190
+ cssClass: 'custom-toast'
191
+ });
192
+ yield toast.present();
193
+ }
194
+ }
195
+ });
156
196
  }
157
197
  static removeFromQueue(index) {
158
198
  this.queue.splice(index, 1);
@@ -269,3 +309,4 @@ Player.queue = [];
269
309
  Player.queue$ = new rxjs_1.BehaviorSubject([]);
270
310
  Player.playlist = [];
271
311
  Player.selectedQuality = 3;
312
+ Player.intendedPlaying = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tunzo-player",
3
- "version": "1.0.32",
3
+ "version": "1.0.33",
4
4
  "description": "A music playback service for Angular and Ionic apps with native audio control support.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -30,6 +30,7 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@capacitor-community/keep-awake": "^7.1.0",
33
+ "@ionic/angular": "^8.7.11",
33
34
  "rxjs": "^7.8.2"
34
35
  }
35
36
  }
@@ -1,5 +1,6 @@
1
1
  import { BehaviorSubject } from 'rxjs';
2
2
  import { KeepAwake } from '@capacitor-community/keep-awake';
3
+ import { ToastController } from '@ionic/angular/standalone';
3
4
 
4
5
  export class Player {
5
6
  private static audio = new Audio();
@@ -13,6 +14,8 @@ export class Player {
13
14
  static queue$ = new BehaviorSubject<any[]>([]);
14
15
  private static playlist: any[] = [];
15
16
  private static selectedQuality = 3;
17
+ private static intendedPlaying = false;
18
+ private static toastCtrl: ToastController;
16
19
 
17
20
  /** Initialize with playlist and quality */
18
21
  static initialize(playlist: any[], quality = 3) {
@@ -20,6 +23,11 @@ export class Player {
20
23
  this.selectedQuality = quality;
21
24
  this.setupMediaSession();
22
25
  this.setupAudioElement();
26
+ this.startWatchdog();
27
+ }
28
+
29
+ static setToastController(controller: ToastController) {
30
+ this.toastCtrl = controller;
23
31
  }
24
32
 
25
33
  /** Setup audio element for better compatibility */
@@ -71,6 +79,15 @@ export class Player {
71
79
  };
72
80
  }
73
81
 
82
+ private static startWatchdog() {
83
+ setInterval(() => {
84
+ if (this.intendedPlaying && this.audio.paused && this.currentSong) {
85
+ console.log('Watchdog: Audio paused unexpectedly. Attempting to resume...');
86
+ this.audio.play().catch(e => console.warn('Watchdog resume failed:', e));
87
+ }
88
+ }, 10000);
89
+ }
90
+
74
91
  /** Call this once on user gesture to unlock audio in WebView */
75
92
  static unlockAudio() {
76
93
  this.audio.src = '';
@@ -81,6 +98,8 @@ export class Player {
81
98
  static play(song: any, index: number = 0) {
82
99
  if (!song || !song.downloadUrl) return;
83
100
 
101
+ this.intendedPlaying = true;
102
+
84
103
  this.currentSong = song;
85
104
  this.currentIndex = index;
86
105
 
@@ -108,6 +127,7 @@ export class Player {
108
127
  }
109
128
 
110
129
  static pause() {
130
+ this.intendedPlaying = false;
111
131
  this.audio.pause();
112
132
  this.isPlaying = false;
113
133
  KeepAwake.allowSleep();
@@ -117,6 +137,7 @@ export class Player {
117
137
  }
118
138
 
119
139
  static resume() {
140
+ this.intendedPlaying = true;
120
141
  this.audio.play();
121
142
  this.isPlaying = true;
122
143
  KeepAwake.keepAwake();
@@ -143,6 +164,8 @@ export class Player {
143
164
  this.playRandom();
144
165
  } else if (this.currentIndex < this.playlist.length - 1) {
145
166
  this.play(this.playlist[this.currentIndex + 1], this.currentIndex + 1);
167
+ } else {
168
+ this.intendedPlaying = false;
146
169
  }
147
170
  }
148
171
 
@@ -178,10 +201,22 @@ export class Player {
178
201
  return this.isShuffle;
179
202
  }
180
203
 
181
- static addToQueue(song: any) {
204
+ static async addToQueue(song: any) {
182
205
  if (!this.queue.some(q => q.id === song.id)) {
183
206
  this.queue.push(song);
184
207
  this.queue$.next([...this.queue]);
208
+
209
+ if (this.toastCtrl) {
210
+ const toast = await this.toastCtrl.create({
211
+ message: 'Song added to queue',
212
+ duration: 2000,
213
+ position: 'bottom',
214
+ mode: 'ios',
215
+ color: 'dark',
216
+ cssClass: 'custom-toast'
217
+ });
218
+ await toast.present();
219
+ }
185
220
  }
186
221
  }
187
222