@capgo/capacitor-media-session 7.1.4 → 7.2.3
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/README.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
<a href="https://capgo.app/"><img src='https://raw.githubusercontent.com/Cap-go/capgo/main/assets/capgo_banner.png' alt='Capgo - Instant updates for capacitor'/></a>
|
|
3
3
|
|
|
4
4
|
<div align="center">
|
|
5
|
-
<h2><a href="https://capgo.app/?ref=
|
|
6
|
-
<h2><a href="https://capgo.app/consulting/?ref=
|
|
5
|
+
<h2><a href="https://capgo.app/?ref=plugin_media_session"> ➡️ Get Instant updates for your App with Capgo</a></h2>
|
|
6
|
+
<h2><a href="https://capgo.app/consulting/?ref=plugin_media_session"> Missing a feature? We’ll build the plugin for you 💪</a></h2>
|
|
7
7
|
</div>
|
|
8
8
|
Expose media session controls for Capacitor apps
|
|
9
9
|
|
|
@@ -30,7 +30,7 @@ import org.json.JSONObject;
|
|
|
30
30
|
@CapacitorPlugin(name = "MediaSession")
|
|
31
31
|
public class MediaSessionPlugin extends Plugin {
|
|
32
32
|
|
|
33
|
-
private final String PLUGIN_VERSION = "7.
|
|
33
|
+
private final String PLUGIN_VERSION = "7.2.3";
|
|
34
34
|
|
|
35
35
|
private static final String TAG = "CapgoMediaSession";
|
|
36
36
|
|
|
@@ -1,17 +1,192 @@
|
|
|
1
1
|
import Capacitor
|
|
2
2
|
import Foundation
|
|
3
|
+
import MediaPlayer
|
|
3
4
|
|
|
4
5
|
@objc(MediaSessionPlugin)
|
|
5
6
|
public class MediaSessionPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
6
|
-
private let PLUGIN_VERSION: String = "7.
|
|
7
|
+
private let PLUGIN_VERSION: String = "7.2.3"
|
|
7
8
|
public let identifier = "MediaSessionPlugin"
|
|
8
9
|
public let jsName = "MediaSession"
|
|
9
10
|
public let pluginMethods: [CAPPluginMethod] = [
|
|
11
|
+
CAPPluginMethod(name: "setMetadata", returnType: CAPPluginReturnPromise),
|
|
12
|
+
CAPPluginMethod(name: "setPlaybackState", returnType: CAPPluginReturnPromise),
|
|
13
|
+
CAPPluginMethod(name: "setActionHandler", returnType: CAPPluginReturnPromise),
|
|
14
|
+
CAPPluginMethod(name: "setPositionState", returnType: CAPPluginReturnPromise),
|
|
10
15
|
CAPPluginMethod(name: "getPluginVersion", returnType: CAPPluginReturnPromise)
|
|
11
16
|
]
|
|
12
17
|
|
|
18
|
+
private var nowPlayingInfo: [String: Any] = [:]
|
|
19
|
+
private var registeredCommands: Set<String> = []
|
|
20
|
+
|
|
21
|
+
@objc func setMetadata(_ call: CAPPluginCall) {
|
|
22
|
+
DispatchQueue.main.async {
|
|
23
|
+
let nowPlayingInfo = MPNowPlayingInfoCenter.default()
|
|
24
|
+
var info: [String: Any] = [:]
|
|
25
|
+
|
|
26
|
+
if let title = call.getString("title") {
|
|
27
|
+
info[MPMediaItemPropertyTitle] = title
|
|
28
|
+
}
|
|
29
|
+
if let artist = call.getString("artist") {
|
|
30
|
+
info[MPMediaItemPropertyArtist] = artist
|
|
31
|
+
}
|
|
32
|
+
if let album = call.getString("album") {
|
|
33
|
+
info[MPMediaItemPropertyAlbumTitle] = album
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Handle artwork
|
|
37
|
+
if let artworkArray = call.getArray("artwork"),
|
|
38
|
+
artworkArray.count > 0,
|
|
39
|
+
let firstArtwork = artworkArray[0] as? [String: Any],
|
|
40
|
+
let src = firstArtwork["src"] as? String {
|
|
41
|
+
self.loadArtwork(from: src) { image in
|
|
42
|
+
if let image = image {
|
|
43
|
+
info[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size) { _ in image }
|
|
44
|
+
}
|
|
45
|
+
nowPlayingInfo.nowPlayingInfo = info
|
|
46
|
+
call.resolve()
|
|
47
|
+
}
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
nowPlayingInfo.nowPlayingInfo = info
|
|
52
|
+
call.resolve()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@objc func setPlaybackState(_ call: CAPPluginCall) {
|
|
57
|
+
guard let stateString = call.getString("playbackState") else {
|
|
58
|
+
call.reject("playbackState is required")
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
DispatchQueue.main.async {
|
|
63
|
+
let nowPlayingInfo = MPNowPlayingInfoCenter.default()
|
|
64
|
+
var info = nowPlayingInfo.nowPlayingInfo ?? [:]
|
|
65
|
+
|
|
66
|
+
switch stateString {
|
|
67
|
+
case "playing":
|
|
68
|
+
info[MPNowPlayingInfoPropertyPlaybackRate] = 1.0
|
|
69
|
+
case "paused":
|
|
70
|
+
info[MPNowPlayingInfoPropertyPlaybackRate] = 0.0
|
|
71
|
+
default:
|
|
72
|
+
info[MPNowPlayingInfoPropertyPlaybackRate] = 0.0
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
nowPlayingInfo.nowPlayingInfo = info
|
|
76
|
+
call.resolve()
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@objc func setActionHandler(_ call: CAPPluginCall) {
|
|
81
|
+
guard let action = call.getString("action") else {
|
|
82
|
+
call.reject("action is required")
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
DispatchQueue.main.async {
|
|
87
|
+
let commandCenter = MPRemoteCommandCenter.shared()
|
|
88
|
+
|
|
89
|
+
switch action {
|
|
90
|
+
case "play":
|
|
91
|
+
commandCenter.playCommand.isEnabled = true
|
|
92
|
+
commandCenter.playCommand.addTarget { [weak self] _ in
|
|
93
|
+
self?.notifyListeners("actionHandler", data: ["action": "play"])
|
|
94
|
+
return .success
|
|
95
|
+
}
|
|
96
|
+
case "pause":
|
|
97
|
+
commandCenter.pauseCommand.isEnabled = true
|
|
98
|
+
commandCenter.pauseCommand.addTarget { [weak self] _ in
|
|
99
|
+
self?.notifyListeners("actionHandler", data: ["action": "pause"])
|
|
100
|
+
return .success
|
|
101
|
+
}
|
|
102
|
+
case "nexttrack":
|
|
103
|
+
commandCenter.nextTrackCommand.isEnabled = true
|
|
104
|
+
commandCenter.nextTrackCommand.addTarget { [weak self] _ in
|
|
105
|
+
self?.notifyListeners("actionHandler", data: ["action": "nexttrack"])
|
|
106
|
+
return .success
|
|
107
|
+
}
|
|
108
|
+
case "previoustrack":
|
|
109
|
+
commandCenter.previousTrackCommand.isEnabled = true
|
|
110
|
+
commandCenter.previousTrackCommand.addTarget { [weak self] _ in
|
|
111
|
+
self?.notifyListeners("actionHandler", data: ["action": "previoustrack"])
|
|
112
|
+
return .success
|
|
113
|
+
}
|
|
114
|
+
case "seekforward":
|
|
115
|
+
commandCenter.skipForwardCommand.isEnabled = true
|
|
116
|
+
commandCenter.skipForwardCommand.addTarget { [weak self] _ in
|
|
117
|
+
self?.notifyListeners("actionHandler", data: ["action": "seekforward"])
|
|
118
|
+
return .success
|
|
119
|
+
}
|
|
120
|
+
case "seekbackward":
|
|
121
|
+
commandCenter.skipBackwardCommand.isEnabled = true
|
|
122
|
+
commandCenter.skipBackwardCommand.addTarget { [weak self] _ in
|
|
123
|
+
self?.notifyListeners("actionHandler", data: ["action": "seekbackward"])
|
|
124
|
+
return .success
|
|
125
|
+
}
|
|
126
|
+
case "stop":
|
|
127
|
+
commandCenter.stopCommand.isEnabled = true
|
|
128
|
+
commandCenter.stopCommand.addTarget { [weak self] _ in
|
|
129
|
+
self?.notifyListeners("actionHandler", data: ["action": "stop"])
|
|
130
|
+
return .success
|
|
131
|
+
}
|
|
132
|
+
default:
|
|
133
|
+
call.reject("Unsupported action: \(action)")
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
call.resolve()
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@objc func setPositionState(_ call: CAPPluginCall) {
|
|
142
|
+
DispatchQueue.main.async {
|
|
143
|
+
let nowPlayingInfo = MPNowPlayingInfoCenter.default()
|
|
144
|
+
var info = nowPlayingInfo.nowPlayingInfo ?? [:]
|
|
145
|
+
|
|
146
|
+
if let duration = call.getDouble("duration") {
|
|
147
|
+
info[MPMediaItemPropertyPlaybackDuration] = duration
|
|
148
|
+
}
|
|
149
|
+
if let position = call.getDouble("position") {
|
|
150
|
+
info[MPNowPlayingInfoPropertyElapsedPlaybackTime] = position
|
|
151
|
+
}
|
|
152
|
+
if let playbackRate = call.getDouble("playbackRate") {
|
|
153
|
+
info[MPNowPlayingInfoPropertyPlaybackRate] = playbackRate
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
nowPlayingInfo.nowPlayingInfo = info
|
|
157
|
+
call.resolve()
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
13
161
|
@objc func getPluginVersion(_ call: CAPPluginCall) {
|
|
14
162
|
call.resolve(["version": self.PLUGIN_VERSION])
|
|
15
163
|
}
|
|
16
164
|
|
|
165
|
+
private func loadArtwork(from urlString: String, completion: @escaping (UIImage?) -> Void) {
|
|
166
|
+
guard let url = URL(string: urlString) else {
|
|
167
|
+
completion(nil)
|
|
168
|
+
return
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if url.isFileURL {
|
|
172
|
+
if let image = UIImage(contentsOfFile: url.path) {
|
|
173
|
+
completion(image)
|
|
174
|
+
} else {
|
|
175
|
+
completion(nil)
|
|
176
|
+
}
|
|
177
|
+
return
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
URLSession.shared.dataTask(with: url) { data, _, _ in
|
|
181
|
+
guard let data = data, let image = UIImage(data: data) else {
|
|
182
|
+
DispatchQueue.main.async {
|
|
183
|
+
completion(nil)
|
|
184
|
+
}
|
|
185
|
+
return
|
|
186
|
+
}
|
|
187
|
+
DispatchQueue.main.async {
|
|
188
|
+
completion(image)
|
|
189
|
+
}
|
|
190
|
+
}.resume()
|
|
191
|
+
}
|
|
17
192
|
}
|