capacitor-plugin-playlist 0.1.32 → 0.2.0
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/local.properties +8 -0
- package/android/src/main/java/org/dwbn/plugins/playlist/App.kt +6 -1
- package/android/src/main/java/org/dwbn/plugins/playlist/PlaylistPlugin.kt +3 -7
- package/android/src/main/java/org/dwbn/plugins/playlist/RmxAudioPlayer.java +9 -1
- package/android/src/main/java/org/dwbn/plugins/playlist/manager/PlaylistManager.kt +8 -10
- package/android/src/main/java/org/dwbn/plugins/playlist/playlist/AudioPlaylistHandler.java +5 -2
- package/dist/esm/RmxAudioPlayer.js +5 -5
- package/dist/esm/RmxAudioPlayer.js.map +1 -1
- package/dist/esm/interfaces.d.ts +6 -0
- package/dist/esm/web.d.ts +1 -0
- package/dist/esm/web.js +10 -2
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +15 -7
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +15 -7
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/AVBidirectionalQueuePlayer.swift +19 -21
- package/ios/Plugin/RmxAudioPlayer.swift +49 -60
- package/package.json +5 -4
- package/android/.gitignore +0 -1
- package/android/.npmignore +0 -1
|
@@ -74,11 +74,11 @@ final class RmxAudioPlayer: NSObject {
|
|
|
74
74
|
|
|
75
75
|
let startPaused = options["startPaused"] != nil ? (options["startPaused"] as? Bool) ?? false : true
|
|
76
76
|
|
|
77
|
-
if
|
|
77
|
+
if playFromPosition > 0.0 {
|
|
78
|
+
seekToPosition = playFromPosition
|
|
79
|
+
}
|
|
80
|
+
else if retainPosition {
|
|
78
81
|
seekToPosition = getTrackCurrentTime(nil)
|
|
79
|
-
if playFromPosition > 0.0 {
|
|
80
|
-
seekToPosition = playFromPosition
|
|
81
|
-
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
let result = findTrack(byId: playFromId)
|
|
@@ -149,8 +149,10 @@ final class RmxAudioPlayer: NSObject {
|
|
|
149
149
|
guard (0..<avQueuePlayer.queuedAudioTracks.count).contains(index) else {
|
|
150
150
|
throw "Provided index is out of bounds"
|
|
151
151
|
}
|
|
152
|
-
|
|
153
|
-
avQueuePlayer.
|
|
152
|
+
|
|
153
|
+
if avQueuePlayer.currentIndex() != index {
|
|
154
|
+
avQueuePlayer.setCurrentIndex(index)
|
|
155
|
+
}
|
|
154
156
|
playCommand(false)
|
|
155
157
|
|
|
156
158
|
if positionTime != nil {
|
|
@@ -162,13 +164,15 @@ final class RmxAudioPlayer: NSObject {
|
|
|
162
164
|
guard !avQueuePlayer.queuedAudioTracks.isEmpty else {
|
|
163
165
|
throw "The playlist is empty!"
|
|
164
166
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
|
|
168
|
+
if avQueuePlayer.currentAudioTrack?.trackId != trackId {
|
|
169
|
+
let result = findTrack(byId: trackId)
|
|
170
|
+
let idx = result?["index"] as? Int ?? -1
|
|
171
|
+
guard idx >= 0 else {
|
|
172
|
+
throw "Track ID not found"
|
|
173
|
+
}
|
|
174
|
+
avQueuePlayer.setCurrentIndex(idx)
|
|
169
175
|
}
|
|
170
|
-
|
|
171
|
-
avQueuePlayer.setCurrentIndex(idx)
|
|
172
176
|
playCommand(false)
|
|
173
177
|
|
|
174
178
|
if positionTime != nil {
|
|
@@ -257,14 +261,13 @@ final class RmxAudioPlayer: NSObject {
|
|
|
257
261
|
if resetStreamOnPause,
|
|
258
262
|
let currentTrack = avQueuePlayer.currentAudioTrack,
|
|
259
263
|
currentTrack.isStream {
|
|
264
|
+
print( "music-stream-play")
|
|
260
265
|
avQueuePlayer.seek(to: .positiveInfinity, toleranceBefore: .zero, toleranceAfter: .zero)
|
|
261
266
|
currentTrack.seek(to: .positiveInfinity, toleranceBefore: .zero, toleranceAfter: .zero, completionHandler: nil)
|
|
262
267
|
}
|
|
263
268
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
print("\(action)")
|
|
267
|
-
}
|
|
269
|
+
print( "music-controls-play ")
|
|
270
|
+
|
|
268
271
|
avQueuePlayer.play()
|
|
269
272
|
}
|
|
270
273
|
|
|
@@ -461,6 +464,9 @@ final class RmxAudioPlayer: NSObject {
|
|
|
461
464
|
|
|
462
465
|
let trackStatus = getStatusItem(playerItem)
|
|
463
466
|
onStatus(.rmxstatus_COMPLETED, trackId: playerItem?.trackId, param: trackStatus)
|
|
467
|
+
if (avQueuePlayer.isAtEnd) {
|
|
468
|
+
onStatus(.rmxstatus_PLAYLIST_COMPLETED, trackId: "INVALID", param: nil)
|
|
469
|
+
}
|
|
464
470
|
}
|
|
465
471
|
|
|
466
472
|
@objc func handleAudioSessionInterruption(_ interruptionNotification: Notification?) {
|
|
@@ -529,11 +535,15 @@ final class RmxAudioPlayer: NSObject {
|
|
|
529
535
|
// only fire on real change!
|
|
530
536
|
let player = object as? AVBidirectionalQueuePlayer
|
|
531
537
|
let playerItem = player?.currentAudioTrack
|
|
532
|
-
|
|
538
|
+
if playerItem != nil {
|
|
539
|
+
guard self.lastTrackId != playerItem?.trackId else {
|
|
533
540
|
return // todo should call super instead or?
|
|
534
541
|
}
|
|
535
|
-
lastTrackId
|
|
542
|
+
print("observe change currentItem: lastTrackId \(self.lastTrackId) playerItem: \(playerItem?.trackId)")
|
|
543
|
+
self.lastTrackId = playerItem?.trackId
|
|
536
544
|
handleCurrentItemChanged(playerItem)
|
|
545
|
+
}
|
|
546
|
+
|
|
537
547
|
case "rate":
|
|
538
548
|
guard lastRate != change[.newKey] as? Float else {
|
|
539
549
|
return // todo should call super instead or?
|
|
@@ -557,44 +567,39 @@ final class RmxAudioPlayer: NSObject {
|
|
|
557
567
|
handleTrackStatusEvent(playerItem)
|
|
558
568
|
})
|
|
559
569
|
case "timeControlStatus":
|
|
560
|
-
|
|
561
|
-
let player = object as? AVBidirectionalQueuePlayer
|
|
570
|
+
let player = object as? AVBidirectionalQueuePlayer
|
|
562
571
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
572
|
+
guard let playerItem = player?.currentAudioTrack else {
|
|
573
|
+
return
|
|
574
|
+
}
|
|
575
|
+
guard lastTrackId != playerItem.trackId || player?.isAtBeginning ?? false else {
|
|
576
|
+
return // todo should call super instead or?
|
|
577
|
+
}
|
|
569
578
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
})
|
|
579
|
+
let trackStatus = getStatusItem(playerItem)
|
|
580
|
+
print("TCSPlayback rate changed: \(String(describing: change[.newKey])), is playing: \(player?.isPlaying ?? false)")
|
|
581
|
+
|
|
582
|
+
if player?.timeControlStatus == .playing {
|
|
583
|
+
onStatus(.rmxstatus_PLAYING, trackId: playerItem.trackId, param: trackStatus)
|
|
584
|
+
} else if player?.timeControlStatus == .waitingToPlayAtSpecifiedRate {
|
|
585
|
+
onStatus(.rmxstatus_BUFFERING, trackId: playerItem.trackId, param: trackStatus)
|
|
586
|
+
} else {
|
|
587
|
+
onStatus(.rmxstatus_PAUSE, trackId: playerItem.trackId, param: trackStatus)
|
|
588
|
+
}
|
|
581
589
|
case "duration":
|
|
582
590
|
DispatchQueue.main.debounce(interval: 0.5, context: self, action: { [self] in
|
|
583
591
|
let playerItem = object as? AudioTrack
|
|
584
592
|
handleTrackDuration(playerItem)
|
|
585
593
|
})
|
|
586
594
|
case "loadedTimeRanges":
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
handleTrackBuffering(playerItem)
|
|
590
|
-
})
|
|
595
|
+
let playerItem = object as? AudioTrack
|
|
596
|
+
handleTrackBuffering(playerItem)
|
|
591
597
|
default:
|
|
592
598
|
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
|
|
593
599
|
}
|
|
594
600
|
}
|
|
595
601
|
|
|
596
602
|
func updateNowPlayingTrackInfo(_ playerItem: AudioTrack?, updateTrackData: Bool) {
|
|
597
|
-
|
|
598
603
|
let currentItem = playerItem ?? avQueuePlayer.currentAudioTrack
|
|
599
604
|
let nowPlayingInfoCenter = MPNowPlayingInfoCenter.default()
|
|
600
605
|
if updatedNowPlayingInfo == nil {
|
|
@@ -638,7 +643,6 @@ final class RmxAudioPlayer: NSObject {
|
|
|
638
643
|
guard let coverUri = coverUriOrNil else {
|
|
639
644
|
return nil
|
|
640
645
|
}
|
|
641
|
-
|
|
642
646
|
var coverImage: UIImage? = nil
|
|
643
647
|
if coverUri.hasPrefix("http://") || coverUri.hasPrefix("https://") {
|
|
644
648
|
let coverImageUrl = URL(string: coverUri)!
|
|
@@ -754,9 +758,10 @@ final class RmxAudioPlayer: NSObject {
|
|
|
754
758
|
isWaitingToStartPlayback = false
|
|
755
759
|
var errorMsg = ""
|
|
756
760
|
if playerItem.error != nil {
|
|
761
|
+
print("\(playerItem.error)")
|
|
757
762
|
errorMsg = "Error playing audio track: \((playerItem.error as NSError?)?.localizedFailureReason ?? "")"
|
|
758
763
|
}
|
|
759
|
-
print("AVPlayerItemStatusFailed:
|
|
764
|
+
print("AVPlayerItemStatusFailed: \(errorMsg)")
|
|
760
765
|
let errorParam = createError(withCode: .rmxerr_DECODE, message: errorMsg)
|
|
761
766
|
onStatus(.rmxstatus_ERROR, trackId: playerItem.trackId, param: errorParam)
|
|
762
767
|
case .unknown:
|
|
@@ -989,9 +994,6 @@ final class RmxAudioPlayer: NSObject {
|
|
|
989
994
|
}
|
|
990
995
|
|
|
991
996
|
func removeTrackObservers(_ playerItem: AudioTrack?) {
|
|
992
|
-
playerItem?.removeObserver(self, forKeyPath: "status")
|
|
993
|
-
playerItem?.removeObserver(self, forKeyPath: "duration")
|
|
994
|
-
playerItem?.removeObserver(self, forKeyPath: "loadedTimeRanges")
|
|
995
997
|
NotificationCenter.default.removeObserver(self, name: .AVPlayerItemDidPlayToEndTime, object: playerItem)
|
|
996
998
|
NotificationCenter.default.removeObserver(self, name: .AVPlayerItemPlaybackStalled, object: playerItem)
|
|
997
999
|
|
|
@@ -1024,10 +1026,6 @@ final class RmxAudioPlayer: NSObject {
|
|
|
1024
1026
|
func observeLifeCycle() {
|
|
1025
1027
|
let listener = NotificationCenter.default
|
|
1026
1028
|
|
|
1027
|
-
// These aren't really needed. the AVQueuePlayer handles this for us.
|
|
1028
|
-
// [listener addObserver:self selector:@selector(handleEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
|
|
1029
|
-
// [listener addObserver:self selector:@selector(handleEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
|
|
1030
|
-
|
|
1031
1029
|
// We do need these.
|
|
1032
1030
|
listener.addObserver(self, selector: #selector(handleAudioSessionInterruption(_:)), name: AVAudioSession.interruptionNotification, object: AVAudioSession.sharedInstance())
|
|
1033
1031
|
|
|
@@ -1060,11 +1058,6 @@ final class RmxAudioPlayer: NSObject {
|
|
|
1060
1058
|
|
|
1061
1059
|
/// Cleanup
|
|
1062
1060
|
func deregisterMusicControlsEventListener() {
|
|
1063
|
-
// We don't use the remote control, and no need to remove observer on
|
|
1064
|
-
// NSNotificationCenter, that is done automatically
|
|
1065
|
-
// [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
|
|
1066
|
-
// [[NSNotificationCenter defaultCenter] removeObserver:self name:@"receivedEvent" object:nil];
|
|
1067
|
-
|
|
1068
1061
|
let commandCenter = MPRemoteCommandCenter.shared()
|
|
1069
1062
|
commandCenter.playCommand.removeTarget(self)
|
|
1070
1063
|
commandCenter.pauseCommand.removeTarget(self)
|
|
@@ -1079,7 +1072,6 @@ final class RmxAudioPlayer: NSObject {
|
|
|
1079
1072
|
|
|
1080
1073
|
func onReset() {
|
|
1081
1074
|
// Override to cancel any long-running requests when the WebView navigates or refreshes.
|
|
1082
|
-
//super.onReset()
|
|
1083
1075
|
releaseResources()
|
|
1084
1076
|
}
|
|
1085
1077
|
|
|
@@ -1087,9 +1079,6 @@ final class RmxAudioPlayer: NSObject {
|
|
|
1087
1079
|
if let playbackTimeObserver = playbackTimeObserver {
|
|
1088
1080
|
avQueuePlayer.removeTimeObserver(playbackTimeObserver)
|
|
1089
1081
|
}
|
|
1090
|
-
avQueuePlayer.removeObserver(self as NSObject, forKeyPath: "currentItem")
|
|
1091
|
-
avQueuePlayer.removeObserver(self as NSObject, forKeyPath: "rate")
|
|
1092
|
-
avQueuePlayer.removeObserver(self as NSObject, forKeyPath: "timeControlStatus")
|
|
1093
1082
|
deregisterMusicControlsEventListener()
|
|
1094
1083
|
|
|
1095
1084
|
removeAllTracks()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "capacitor-plugin-playlist",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Playlist ",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.js",
|
|
27
27
|
"clean": "rimraf ./dist",
|
|
28
28
|
"watch": "tsc --watch",
|
|
29
|
-
"prepublishOnly": "npm run build"
|
|
29
|
+
"prepublishOnly": "npm run build",
|
|
30
|
+
"prepare": "npm run build"
|
|
30
31
|
},
|
|
31
32
|
"author": "phiamo",
|
|
32
33
|
"license": "MIT",
|
|
@@ -69,9 +70,9 @@
|
|
|
69
70
|
},
|
|
70
71
|
"repository": {
|
|
71
72
|
"type": "git",
|
|
72
|
-
"url": "https://github.com/phiamo"
|
|
73
|
+
"url": "https://github.com/phiamo/capacitor-plugin-playlist"
|
|
73
74
|
},
|
|
74
75
|
"bugs": {
|
|
75
|
-
"url": "https://github.com/phiamo/issues"
|
|
76
|
+
"url": "https://github.com/phiamo/capacitor-plugin-playlist/issues"
|
|
76
77
|
}
|
|
77
78
|
}
|
package/android/.gitignore
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/build
|
package/android/.npmignore
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/build
|