expo-gliph-player 1.3.13 → 1.3.15
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/android/src/main/java/com/gliphplayer/GliphPlayerModule.kt +22 -15
- package/android/src/main/java/com/gliphplayer/GliphPlayerService.kt +147 -79
- package/ios/GliphAudioPlayer.swift +71 -44
- package/ios/GliphPlayerModule.mm +18 -4
- package/lib/typescript/src/GliphPlayer.d.ts +35 -5
- package/package.json +1 -1
- package/src/GliphPlayer.ts +312 -305
- package/src/specs/NativeGliphPlayer.ts +86 -82
|
@@ -6,29 +6,12 @@ import UIKit
|
|
|
6
6
|
|
|
7
7
|
public typealias EventEmitter = (String, [String: Any]?) -> Void
|
|
8
8
|
|
|
9
|
-
// React Native's promise block types
|
|
10
|
-
// no dependency on a bridging header (`import <React/RCTBridgeModule.h>`).
|
|
11
|
-
// Bridging headers are unsupported on framework targets in Xcode, and this
|
|
12
|
-
// pod builds as a static_framework — so this file must never `import React`
|
|
13
|
-
// or rely on one being injected. These signatures are structurally
|
|
14
|
-
// identical to the real `RCTPromiseResolveBlock` / `RCTPromiseRejectBlock`
|
|
15
|
-
// (id -> Any?, NSString* -> String?, NSError* -> Error?), so the resulting
|
|
16
|
-
// @objc blocks are ABI-compatible with what GliphPlayerModule.mm expects.
|
|
9
|
+
// React Native's promise block types
|
|
17
10
|
public typealias RCTPromiseResolveBlock = (Any?) -> Void
|
|
18
11
|
public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
19
12
|
|
|
20
13
|
// MARK: - GliphAudioPlayer
|
|
21
14
|
|
|
22
|
-
/**
|
|
23
|
-
* GliphAudioPlayer
|
|
24
|
-
*
|
|
25
|
-
* Core Swift class that manages:
|
|
26
|
-
* - AVQueuePlayer for audio playback
|
|
27
|
-
* - MPRemoteCommandCenter for lock screen / headphone controls
|
|
28
|
-
* - MPNowPlayingInfoCenter for Now Playing metadata
|
|
29
|
-
* - Audio session configuration
|
|
30
|
-
* - Queue management
|
|
31
|
-
*/
|
|
32
15
|
@objc public class GliphAudioPlayer: NSObject {
|
|
33
16
|
|
|
34
17
|
// ── Properties ──────────────────────────────────────────────────────────────
|
|
@@ -37,7 +20,7 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
37
20
|
private var playerItems: [AVPlayerItem] = []
|
|
38
21
|
private var queue: [[String: Any]] = []
|
|
39
22
|
private var currentIndex: Int = -1
|
|
40
|
-
private var repeatMode: Int = 0
|
|
23
|
+
private var repeatMode: Int = 0
|
|
41
24
|
private var isSetup = false
|
|
42
25
|
private var progressTimer: Timer?
|
|
43
26
|
private var progressInterval: TimeInterval = 1.0
|
|
@@ -56,12 +39,6 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
56
39
|
|
|
57
40
|
// ── Thread helper ───────────────────────────────────────────────────────────
|
|
58
41
|
|
|
59
|
-
/// Executes `block` synchronously on the main thread.
|
|
60
|
-
/// Safe to call from any thread — avoids deadlock if already on main.
|
|
61
|
-
/// Several AVAudioSession / UIApplication / MPRemoteCommandCenter APIs are
|
|
62
|
-
/// documented as main-thread-only; the RN bridge does not guarantee that
|
|
63
|
-
/// native module methods run on main, so every touch of those APIs goes
|
|
64
|
-
/// through this helper.
|
|
65
42
|
private func runOnMain(_ block: () -> Void) {
|
|
66
43
|
if Thread.isMainThread {
|
|
67
44
|
block()
|
|
@@ -145,11 +122,19 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
145
122
|
? queue.count
|
|
146
123
|
: insertBeforeIndex
|
|
147
124
|
|
|
125
|
+
let wasEmpty = queue.isEmpty
|
|
126
|
+
|
|
148
127
|
for (i, track) in tracks.enumerated() {
|
|
149
128
|
queue.insert(track, at: insertAt + i)
|
|
150
129
|
}
|
|
151
130
|
|
|
152
131
|
rebuildPlayerQueue()
|
|
132
|
+
|
|
133
|
+
if wasEmpty && !queue.isEmpty {
|
|
134
|
+
currentIndex = 0
|
|
135
|
+
emitActiveTrackChanged()
|
|
136
|
+
}
|
|
137
|
+
|
|
153
138
|
resolve(insertAt)
|
|
154
139
|
}
|
|
155
140
|
|
|
@@ -177,23 +162,34 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
177
162
|
@objc public func skipToIndex(
|
|
178
163
|
_ index: Int,
|
|
179
164
|
initialPosition: Double,
|
|
165
|
+
autoPlay: Bool = true,
|
|
180
166
|
resolve: @escaping RCTPromiseResolveBlock,
|
|
181
167
|
reject: @escaping RCTPromiseRejectBlock
|
|
182
168
|
) {
|
|
183
169
|
guard index >= 0 && index < queue.count else {
|
|
184
170
|
reject("skip_error", "Index out of bounds", nil); return
|
|
185
171
|
}
|
|
172
|
+
|
|
173
|
+
let lastIndex = currentIndex
|
|
186
174
|
currentIndex = index
|
|
175
|
+
|
|
187
176
|
rebuildPlayerQueue()
|
|
188
177
|
if initialPosition >= 0 {
|
|
189
178
|
player?.seek(to: CMTime(seconds: initialPosition, preferredTimescale: 1000))
|
|
190
179
|
}
|
|
191
|
-
|
|
180
|
+
|
|
181
|
+
if autoPlay {
|
|
182
|
+
player?.play()
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
emitActiveTrackChanged(lastIndex: lastIndex)
|
|
186
|
+
|
|
192
187
|
resolve(nil)
|
|
193
188
|
}
|
|
194
189
|
|
|
195
190
|
@objc public func skipToNext(
|
|
196
191
|
initialPosition: Double,
|
|
192
|
+
autoPlay: Bool = true,
|
|
197
193
|
resolve: @escaping RCTPromiseResolveBlock,
|
|
198
194
|
reject: @escaping RCTPromiseRejectBlock
|
|
199
195
|
) {
|
|
@@ -201,11 +197,12 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
201
197
|
guard next < queue.count else {
|
|
202
198
|
reject("skip_error", "No next track", nil); return
|
|
203
199
|
}
|
|
204
|
-
skipToIndex(next, initialPosition: initialPosition, resolve: resolve, reject: reject)
|
|
200
|
+
skipToIndex(next, initialPosition: initialPosition, autoPlay: autoPlay, resolve: resolve, reject: reject)
|
|
205
201
|
}
|
|
206
202
|
|
|
207
203
|
@objc public func skipToPrevious(
|
|
208
204
|
initialPosition: Double,
|
|
205
|
+
autoPlay: Bool = true,
|
|
209
206
|
resolve: @escaping RCTPromiseResolveBlock,
|
|
210
207
|
reject: @escaping RCTPromiseRejectBlock
|
|
211
208
|
) {
|
|
@@ -213,7 +210,7 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
213
210
|
guard prev >= 0 else {
|
|
214
211
|
reject("skip_error", "No previous track", nil); return
|
|
215
212
|
}
|
|
216
|
-
skipToIndex(prev, initialPosition: initialPosition, resolve: resolve, reject: reject)
|
|
213
|
+
skipToIndex(prev, initialPosition: initialPosition, autoPlay: autoPlay, resolve: resolve, reject: reject)
|
|
217
214
|
}
|
|
218
215
|
|
|
219
216
|
@objc public func moveFrom(
|
|
@@ -237,11 +234,19 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
237
234
|
@objc public func play(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
238
235
|
player?.play()
|
|
239
236
|
startProgressTimer()
|
|
237
|
+
|
|
238
|
+
eventEmitter("playback-state", ["state": "playing"])
|
|
239
|
+
|
|
240
|
+
if currentIndex >= 0 && currentIndex < queue.count {
|
|
241
|
+
emitActiveTrackChanged()
|
|
242
|
+
}
|
|
243
|
+
|
|
240
244
|
resolve(nil)
|
|
241
245
|
}
|
|
242
246
|
|
|
243
247
|
@objc public func pause(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
244
248
|
player?.pause()
|
|
249
|
+
eventEmitter("playback-state", ["state": "paused"])
|
|
245
250
|
resolve(nil)
|
|
246
251
|
}
|
|
247
252
|
|
|
@@ -249,6 +254,7 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
249
254
|
player?.pause()
|
|
250
255
|
player?.seek(to: .zero)
|
|
251
256
|
stopProgressTimer()
|
|
257
|
+
eventEmitter("playback-state", ["state": "stopped"])
|
|
252
258
|
resolve(nil)
|
|
253
259
|
}
|
|
254
260
|
|
|
@@ -257,9 +263,19 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
257
263
|
player?.removeAllItems()
|
|
258
264
|
queue.removeAll()
|
|
259
265
|
playerItems.removeAll()
|
|
266
|
+
let lastIndex = currentIndex
|
|
260
267
|
currentIndex = -1
|
|
261
268
|
stopProgressTimer()
|
|
262
269
|
MPNowPlayingInfoCenter.default().nowPlayingInfo = nil
|
|
270
|
+
|
|
271
|
+
eventEmitter("playback-active-track-changed", [
|
|
272
|
+
"index": -1,
|
|
273
|
+
"track": NSNull(),
|
|
274
|
+
"lastIndex": lastIndex,
|
|
275
|
+
"lastPosition": 0.0,
|
|
276
|
+
] as [String : Any])
|
|
277
|
+
eventEmitter("playback-state", ["state": "none"])
|
|
278
|
+
|
|
263
279
|
resolve(nil)
|
|
264
280
|
}
|
|
265
281
|
|
|
@@ -392,6 +408,18 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
392
408
|
|
|
393
409
|
// ── Private helpers ─────────────────────────────────────────────────────────
|
|
394
410
|
|
|
411
|
+
private func emitActiveTrackChanged(lastIndex: Int = -1) {
|
|
412
|
+
let lastPos = CMTimeGetSeconds(player?.currentTime() ?? .zero)
|
|
413
|
+
let track = (currentIndex >= 0 && currentIndex < queue.count) ? queue[currentIndex] : nil
|
|
414
|
+
|
|
415
|
+
eventEmitter("playback-active-track-changed", [
|
|
416
|
+
"index": currentIndex,
|
|
417
|
+
"track": track as Any,
|
|
418
|
+
"lastIndex": lastIndex >= 0 ? lastIndex : currentIndex,
|
|
419
|
+
"lastPosition": lastPos,
|
|
420
|
+
])
|
|
421
|
+
}
|
|
422
|
+
|
|
395
423
|
private func rebuildPlayerQueue() {
|
|
396
424
|
guard let player = player else { return }
|
|
397
425
|
player.removeAllItems()
|
|
@@ -407,7 +435,9 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
407
435
|
player.insert(item, after: player.items().last)
|
|
408
436
|
}
|
|
409
437
|
|
|
410
|
-
if currentIndex < 0 && !queue.isEmpty {
|
|
438
|
+
if currentIndex < 0 && !queue.isEmpty {
|
|
439
|
+
currentIndex = 0
|
|
440
|
+
}
|
|
411
441
|
updateNowPlayingInfo()
|
|
412
442
|
}
|
|
413
443
|
|
|
@@ -430,7 +460,6 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
430
460
|
info[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(player?.currentTime() ?? .zero)
|
|
431
461
|
info[MPNowPlayingInfoPropertyPlaybackRate] = player?.rate ?? 0.0
|
|
432
462
|
|
|
433
|
-
// Artwork
|
|
434
463
|
if let artworkURL = track["artwork"] as? String, !artworkURL.isEmpty {
|
|
435
464
|
loadArtwork(from: artworkURL) { image in
|
|
436
465
|
if let image = image {
|
|
@@ -467,10 +496,6 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
467
496
|
|
|
468
497
|
// ── Remote commands ─────────────────────────────────────────────────────────
|
|
469
498
|
|
|
470
|
-
/// Must always be called on the main thread (see `runOnMain` call sites:
|
|
471
|
-
/// `setupPlayer` and `updateOptions`). `MPRemoteCommandCenter` and
|
|
472
|
-
/// `UIApplication.beginReceivingRemoteControlEvents()` are main-thread-only
|
|
473
|
-
/// APIs.
|
|
474
499
|
private func setupRemoteCommands() {
|
|
475
500
|
let center = MPRemoteCommandCenter.shared()
|
|
476
501
|
UIApplication.shared.beginReceivingRemoteControlEvents()
|
|
@@ -509,7 +534,7 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
509
534
|
guard let self = self else { return .commandFailed }
|
|
510
535
|
let next = self.currentIndex + 1
|
|
511
536
|
if next < self.queue.count {
|
|
512
|
-
self.skipToIndex(next, initialPosition: -1, resolve: { _ in }, reject: { _, _, _ in })
|
|
537
|
+
self.skipToIndex(next, initialPosition: -1, autoPlay: true, resolve: { _ in }, reject: { _, _, _ in })
|
|
513
538
|
}
|
|
514
539
|
self.eventEmitter("remote-next", nil)
|
|
515
540
|
return .success
|
|
@@ -521,7 +546,7 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
521
546
|
guard let self = self else { return .commandFailed }
|
|
522
547
|
let prev = self.currentIndex - 1
|
|
523
548
|
if prev >= 0 {
|
|
524
|
-
self.skipToIndex(prev, initialPosition: -1, resolve: { _ in }, reject: { _, _, _ in })
|
|
549
|
+
self.skipToIndex(prev, initialPosition: -1, autoPlay: true, resolve: { _ in }, reject: { _, _, _ in })
|
|
525
550
|
}
|
|
526
551
|
self.eventEmitter("remote-previous", nil)
|
|
527
552
|
return .success
|
|
@@ -588,7 +613,6 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
588
613
|
object: nil
|
|
589
614
|
)
|
|
590
615
|
|
|
591
|
-
// Observe player status
|
|
592
616
|
if let player = player {
|
|
593
617
|
let obs = player.observe(\.timeControlStatus, options: [.new]) { [weak self] p, _ in
|
|
594
618
|
self?.eventEmitter("playback-state", ["state": self?.currentStateString() ?? "none"])
|
|
@@ -609,16 +633,18 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
609
633
|
}
|
|
610
634
|
|
|
611
635
|
@objc private func playerItemDidFinish(_ notification: Notification) {
|
|
612
|
-
// Only react to notifications for our own player's current item —
|
|
613
|
-
// `object: nil` on the observer means this fires for *any* AVPlayerItem
|
|
614
|
-
// in the whole app (e.g. a video player elsewhere), so we must filter here.
|
|
615
636
|
guard let finishedItem = notification.object as? AVPlayerItem,
|
|
616
637
|
finishedItem === player?.currentItem else { return }
|
|
617
638
|
|
|
618
639
|
let nextIndex = currentIndex + 1
|
|
640
|
+
let currentPosition = CMTimeGetSeconds(player?.currentTime() ?? .zero)
|
|
641
|
+
|
|
642
|
+
eventEmitter("playback-track-ended", [
|
|
643
|
+
"index": currentIndex,
|
|
644
|
+
"position": currentPosition
|
|
645
|
+
])
|
|
619
646
|
|
|
620
647
|
if repeatMode == 1 {
|
|
621
|
-
// Repeat current track
|
|
622
648
|
player?.seek(to: .zero)
|
|
623
649
|
player?.play()
|
|
624
650
|
return
|
|
@@ -634,14 +660,16 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
634
660
|
"lastPosition": 0.0,
|
|
635
661
|
])
|
|
636
662
|
} else if repeatMode == 2 {
|
|
637
|
-
// Repeat queue
|
|
638
663
|
currentIndex = 0
|
|
639
664
|
rebuildPlayerQueue()
|
|
640
665
|
player?.play()
|
|
666
|
+
if !queue.isEmpty {
|
|
667
|
+
emitActiveTrackChanged()
|
|
668
|
+
}
|
|
641
669
|
} else {
|
|
642
670
|
eventEmitter("playback-queue-ended", [
|
|
643
671
|
"index": currentIndex,
|
|
644
|
-
"position":
|
|
672
|
+
"position": currentPosition,
|
|
645
673
|
])
|
|
646
674
|
}
|
|
647
675
|
}
|
|
@@ -677,7 +705,6 @@ public typealias RCTPromiseRejectBlock = (String?, String?, Error?) -> Void
|
|
|
677
705
|
@objc private func audioRouteChanged(_ notification: Notification) {
|
|
678
706
|
guard let reasonValue = notification.userInfo?[AVAudioSessionRouteChangeReasonKey] as? UInt,
|
|
679
707
|
let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue) else { return }
|
|
680
|
-
// Pause on headphone unplug (standard iOS behavior)
|
|
681
708
|
if reason == .oldDeviceUnavailable { player?.pause() }
|
|
682
709
|
}
|
|
683
710
|
|
package/ios/GliphPlayerModule.mm
CHANGED
|
@@ -37,6 +37,7 @@ RCT_EXPORT_MODULE(RNGliphPlayer)
|
|
|
37
37
|
@"playback-state",
|
|
38
38
|
@"playback-error",
|
|
39
39
|
@"playback-active-track-changed",
|
|
40
|
+
@"playback-track-ended",
|
|
40
41
|
@"playback-queue-ended",
|
|
41
42
|
@"playback-progress-updated",
|
|
42
43
|
@"playback-metadata-received",
|
|
@@ -95,21 +96,34 @@ RCT_EXPORT_METHOD(removeUpcomingTracks:(RCTPromiseResolveBlock)resolve
|
|
|
95
96
|
|
|
96
97
|
RCT_EXPORT_METHOD(skip:(double)index
|
|
97
98
|
initialPosition:(double)initialPosition
|
|
99
|
+
autoPlay:(BOOL)autoPlay
|
|
98
100
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
99
101
|
reject:(RCTPromiseRejectBlock)reject) {
|
|
100
|
-
[_player skipToIndex:(NSInteger)index
|
|
102
|
+
[_player skipToIndex:(NSInteger)index
|
|
103
|
+
initialPosition:initialPosition
|
|
104
|
+
autoPlay:autoPlay
|
|
105
|
+
resolve:resolve
|
|
106
|
+
reject:reject];
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
RCT_EXPORT_METHOD(skipToNext:(double)initialPosition
|
|
110
|
+
autoPlay:(BOOL)autoPlay
|
|
104
111
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
105
112
|
reject:(RCTPromiseRejectBlock)reject) {
|
|
106
|
-
[_player skipToNextWithInitialPosition:initialPosition
|
|
113
|
+
[_player skipToNextWithInitialPosition:initialPosition
|
|
114
|
+
autoPlay:autoPlay
|
|
115
|
+
resolve:resolve
|
|
116
|
+
reject:reject];
|
|
107
117
|
}
|
|
108
118
|
|
|
109
119
|
RCT_EXPORT_METHOD(skipToPrevious:(double)initialPosition
|
|
120
|
+
autoPlay:(BOOL)autoPlay
|
|
110
121
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
111
122
|
reject:(RCTPromiseRejectBlock)reject) {
|
|
112
|
-
[_player skipToPreviousWithInitialPosition:initialPosition
|
|
123
|
+
[_player skipToPreviousWithInitialPosition:initialPosition
|
|
124
|
+
autoPlay:autoPlay
|
|
125
|
+
resolve:resolve
|
|
126
|
+
reject:reject];
|
|
113
127
|
}
|
|
114
128
|
|
|
115
129
|
RCT_EXPORT_METHOD(move:(double)fromIndex
|
|
@@ -240,4 +254,4 @@ RCT_EXPORT_METHOD(updateOptions:(NSDictionary *)options
|
|
|
240
254
|
}
|
|
241
255
|
#endif
|
|
242
256
|
|
|
243
|
-
@end
|
|
257
|
+
@end
|
|
@@ -6,20 +6,24 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { Track, PlayerOptions, UpdateOptions, Progress, PlaybackState } from './types';
|
|
8
8
|
import { RepeatMode, State } from './types';
|
|
9
|
+
|
|
9
10
|
declare const GliphPlayer: {
|
|
10
11
|
/**
|
|
11
12
|
* Initialize the player. Must be called once before any other method.
|
|
12
13
|
* Safe to call multiple times — subsequent calls are no-ops.
|
|
13
14
|
*/
|
|
14
15
|
setupPlayer(options?: PlayerOptions): Promise<void>;
|
|
16
|
+
|
|
15
17
|
/**
|
|
16
18
|
* Destroy the player and release all resources.
|
|
17
19
|
*/
|
|
18
20
|
destroy(): void;
|
|
21
|
+
|
|
19
22
|
/**
|
|
20
23
|
* Returns true if the background service is running (Android).
|
|
21
24
|
*/
|
|
22
25
|
isServiceRunning(): Promise<boolean>;
|
|
26
|
+
|
|
23
27
|
/**
|
|
24
28
|
* Add one or more tracks to the queue.
|
|
25
29
|
* @param tracks Single track or array of tracks.
|
|
@@ -27,71 +31,96 @@ declare const GliphPlayer: {
|
|
|
27
31
|
* @returns The index of the first inserted track.
|
|
28
32
|
*/
|
|
29
33
|
add(tracks: Track | Track[], insertBeforeIndex?: number): Promise<number | void>;
|
|
34
|
+
|
|
30
35
|
/**
|
|
31
36
|
* Remove tracks by their IDs.
|
|
32
37
|
*/
|
|
33
38
|
remove(trackIds: string | string[]): Promise<void>;
|
|
39
|
+
|
|
34
40
|
/**
|
|
35
41
|
* Remove all tracks after the current one.
|
|
36
42
|
*/
|
|
37
43
|
removeUpcomingTracks(): Promise<void>;
|
|
44
|
+
|
|
38
45
|
/**
|
|
39
46
|
* Skip to a specific queue index.
|
|
47
|
+
* @param index - Index of the track to skip to
|
|
48
|
+
* @param initialPosition - Position in seconds to start from (default: -1 = start)
|
|
49
|
+
* @param autoPlay - Whether to automatically start playback (default: true)
|
|
40
50
|
*/
|
|
41
|
-
skip(index: number, initialPosition?: number): Promise<void>;
|
|
51
|
+
skip(index: number, initialPosition?: number, autoPlay?: boolean): Promise<void>;
|
|
52
|
+
|
|
42
53
|
/**
|
|
43
54
|
* Skip to the next track.
|
|
55
|
+
* @param initialPosition - Position in seconds to start from (default: -1 = start)
|
|
56
|
+
* @param autoPlay - Whether to automatically start playback (default: true)
|
|
44
57
|
*/
|
|
45
|
-
skipToNext(initialPosition?: number): Promise<void>;
|
|
58
|
+
skipToNext(initialPosition?: number, autoPlay?: boolean): Promise<void>;
|
|
59
|
+
|
|
46
60
|
/**
|
|
47
61
|
* Skip to the previous track.
|
|
62
|
+
* @param initialPosition - Position in seconds to start from (default: -1 = start)
|
|
63
|
+
* @param autoPlay - Whether to automatically start playback (default: true)
|
|
48
64
|
*/
|
|
49
|
-
skipToPrevious(initialPosition?: number): Promise<void>;
|
|
65
|
+
skipToPrevious(initialPosition?: number, autoPlay?: boolean): Promise<void>;
|
|
66
|
+
|
|
50
67
|
/**
|
|
51
68
|
* Move a track from one index to another.
|
|
52
69
|
*/
|
|
53
70
|
move(fromIndex: number, toIndex: number): Promise<void>;
|
|
71
|
+
|
|
54
72
|
play(): Promise<void>;
|
|
55
73
|
pause(): Promise<void>;
|
|
56
74
|
stop(): Promise<void>;
|
|
75
|
+
|
|
57
76
|
/**
|
|
58
77
|
* Stop playback and clear the queue.
|
|
59
78
|
*/
|
|
60
79
|
reset(): Promise<void>;
|
|
80
|
+
|
|
61
81
|
/**
|
|
62
82
|
* Seek to an absolute position in seconds.
|
|
63
83
|
*/
|
|
64
84
|
seekTo(position: number): Promise<void>;
|
|
85
|
+
|
|
65
86
|
/**
|
|
66
87
|
* Seek by a relative offset in seconds (positive = forward, negative = back).
|
|
67
88
|
*/
|
|
68
89
|
seekBy(offset: number): Promise<void>;
|
|
90
|
+
|
|
69
91
|
/**
|
|
70
92
|
* Set volume (0.0 – 1.0).
|
|
71
93
|
*/
|
|
72
94
|
setVolume(volume: number): Promise<void>;
|
|
73
95
|
getVolume(): Promise<number>;
|
|
96
|
+
|
|
74
97
|
/**
|
|
75
98
|
* Set playback rate (1.0 = normal speed).
|
|
76
99
|
*/
|
|
77
100
|
setRate(rate: number): Promise<void>;
|
|
78
101
|
getRate(): Promise<number>;
|
|
102
|
+
|
|
79
103
|
setRepeatMode(mode: RepeatMode): Promise<void>;
|
|
80
104
|
getRepeatMode(): Promise<RepeatMode>;
|
|
105
|
+
|
|
81
106
|
getQueue(): Promise<Track[]>;
|
|
82
107
|
getActiveTrackIndex(): Promise<number | null>;
|
|
83
108
|
getActiveTrack(): Promise<Track | null>;
|
|
84
109
|
getTrack(index: number): Promise<Track | null>;
|
|
85
110
|
getQueueSize(): Promise<number>;
|
|
111
|
+
|
|
86
112
|
getPlaybackState(): Promise<PlaybackState>;
|
|
87
113
|
getProgress(): Promise<Progress>;
|
|
114
|
+
|
|
88
115
|
updateMetadataForTrack(index: number, metadata: Partial<Track>): Promise<void>;
|
|
89
116
|
clearNowPlayingMetadata(): Promise<void>;
|
|
90
117
|
updateNowPlayingMetadata(metadata: Partial<Track>): Promise<void>;
|
|
118
|
+
|
|
91
119
|
/**
|
|
92
120
|
* Configure notification capabilities, jump intervals, etc.
|
|
93
121
|
*/
|
|
94
122
|
updateOptions(options: UpdateOptions): Promise<void>;
|
|
123
|
+
|
|
95
124
|
/**
|
|
96
125
|
* Subscribe to a player event.
|
|
97
126
|
* Returns an unsubscribe function — call it to remove the listener.
|
|
@@ -105,9 +134,10 @@ declare const GliphPlayer: {
|
|
|
105
134
|
*/
|
|
106
135
|
addEventListener<E extends string>(event: E, listener: (data: any) => void): () => void;
|
|
107
136
|
};
|
|
137
|
+
|
|
108
138
|
export default GliphPlayer;
|
|
139
|
+
|
|
109
140
|
export declare function isPlaying(state: State): boolean;
|
|
110
141
|
export declare function isPaused(state: State): boolean;
|
|
111
142
|
export declare function isBuffering(state: State): boolean;
|
|
112
|
-
export declare function isStopped(state: State): boolean;
|
|
113
|
-
//# sourceMappingURL=GliphPlayer.d.ts.map
|
|
143
|
+
export declare function isStopped(state: State): boolean;
|
package/package.json
CHANGED