@capgo/capacitor-media-session 7.1.4 → 7.2.4
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
|
|
33
|
+
private final String pluginVersion = "7.2.4";
|
|
34
34
|
|
|
35
35
|
private static final String TAG = "CapgoMediaSession";
|
|
36
36
|
|
|
@@ -281,7 +281,7 @@ public class MediaSessionPlugin extends Plugin {
|
|
|
281
281
|
public void getPluginVersion(final PluginCall call) {
|
|
282
282
|
try {
|
|
283
283
|
final JSObject ret = new JSObject();
|
|
284
|
-
ret.put("version", this.
|
|
284
|
+
ret.put("version", this.pluginVersion);
|
|
285
285
|
call.resolve(ret);
|
|
286
286
|
} catch (final Exception e) {
|
|
287
287
|
call.reject("Could not get plugin version", e);
|
|
@@ -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
|
|
7
|
+
private let pluginVersion: String = "7.2.4"
|
|
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
|
-
call.resolve(["version": self.
|
|
162
|
+
call.resolve(["version": self.pluginVersion])
|
|
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
|
}
|