@capgo/capacitor-jw-player 0.0.1
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/CapgoCapacitorJwPlayer.podspec +18 -0
- package/Package.swift +30 -0
- package/README.md +493 -0
- package/android/build.gradle +83 -0
- package/android/src/main/AndroidManifest.xml +37 -0
- package/android/src/main/java/ee/forgr/capacitor_jw_player/JwPlayerPlugin.java +529 -0
- package/android/src/main/java/ee/forgr/capacitor_jw_player/PlayerActivity.java +469 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/android/src/main/res/drawable/close_button_background.xml +5 -0
- package/android/src/main/res/layout/activity_player.xml +28 -0
- package/android/src/main/res/values/colors.xml +16 -0
- package/android/src/main/res/values/strings.xml +3 -0
- package/android/src/main/res/values/styles.xml +32 -0
- package/dist/docs.json +459 -0
- package/dist/esm/definitions.d.ts +156 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +57 -0
- package/dist/esm/web.js +65 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +79 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +82 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/JwPlayerPlugin/JwPlayer.swift +24 -0
- package/ios/Sources/JwPlayerPlugin/JwPlayerPlugin.swift +749 -0
- package/ios/Sources/JwPlayerPlugin/LinkedList.swift +219 -0
- package/ios/Sources/JwPlayerPlugin/VideosToPlay.swift +56 -0
- package/ios/Tests/JwPlayerPluginTests/JwPlayerPluginTests.swift +15 -0
- package/package.json +80 -0
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
package ee.forgr.capacitor_jw_player;
|
|
2
|
+
|
|
3
|
+
import android.content.Intent;
|
|
4
|
+
import android.util.Log;
|
|
5
|
+
|
|
6
|
+
import com.getcapacitor.JSArray;
|
|
7
|
+
import com.getcapacitor.JSObject;
|
|
8
|
+
import com.getcapacitor.Plugin;
|
|
9
|
+
import com.getcapacitor.PluginCall;
|
|
10
|
+
import com.getcapacitor.PluginMethod;
|
|
11
|
+
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
12
|
+
import com.jwplayer.pub.api.JWPlayer;
|
|
13
|
+
import com.jwplayer.pub.api.configuration.PlayerConfig;
|
|
14
|
+
import com.jwplayer.pub.api.license.LicenseUtil;
|
|
15
|
+
import com.jwplayer.pub.api.media.playlists.PlaylistItem;
|
|
16
|
+
import com.jwplayer.pub.api.media.audio.AudioTrack;
|
|
17
|
+
import com.jwplayer.pub.api.media.captions.Caption;
|
|
18
|
+
|
|
19
|
+
import java.lang.ref.WeakReference;
|
|
20
|
+
import java.util.List;
|
|
21
|
+
import java.util.ArrayList;
|
|
22
|
+
|
|
23
|
+
@CapacitorPlugin(name = "JwPlayer")
|
|
24
|
+
public class JwPlayerPlugin extends Plugin {
|
|
25
|
+
|
|
26
|
+
private static final String TAG = "JwPlayerPlugin";
|
|
27
|
+
// Static reference to the plugin instance for activity communication
|
|
28
|
+
private static WeakReference<JwPlayerPlugin> staticPluginRef;
|
|
29
|
+
private static JWPlayer staticPlayerInstance; // To control playback from plugin methods
|
|
30
|
+
|
|
31
|
+
@Override
|
|
32
|
+
public void load() {
|
|
33
|
+
super.load();
|
|
34
|
+
staticPluginRef = new WeakReference<>(this);
|
|
35
|
+
Log.i(TAG, "Plugin loaded and static reference set.");
|
|
36
|
+
// License key initialization might be better placed here or in initialize()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@PluginMethod
|
|
40
|
+
public void initialize(PluginCall call) {
|
|
41
|
+
String licenseKey = call.getString("licenseKey");
|
|
42
|
+
if (licenseKey == null || licenseKey.isEmpty()) {
|
|
43
|
+
call.reject("licenseKey is required for initialize");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
Log.i(TAG, "Initializing JW Player SDK with license key.");
|
|
47
|
+
// Initialize license
|
|
48
|
+
new LicenseUtil().setLicenseKey(getContext(), licenseKey);
|
|
49
|
+
// You might want to add success/failure listeners to the license call if available
|
|
50
|
+
call.resolve();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@PluginMethod
|
|
54
|
+
public void play(PluginCall call) {
|
|
55
|
+
String mediaUrl = call.getString("mediaUrl");
|
|
56
|
+
String mediaType = call.getString("mediaType");
|
|
57
|
+
|
|
58
|
+
if (mediaUrl == null || mediaUrl.isEmpty()) {
|
|
59
|
+
call.reject("mediaUrl is required for play");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (mediaType == null || mediaType.isEmpty()) {
|
|
63
|
+
call.reject("mediaType is required for play");
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
Log.d(TAG, "Launching PlayerActivity with URL: " + mediaUrl + ", Type: " + mediaType);
|
|
68
|
+
|
|
69
|
+
Intent intent = new Intent(getContext(), PlayerActivity.class);
|
|
70
|
+
intent.putExtra(PlayerActivity.EXTRA_MEDIA_URL, mediaUrl);
|
|
71
|
+
intent.putExtra(PlayerActivity.EXTRA_MEDIA_TYPE, mediaType);
|
|
72
|
+
getActivity().startActivity(intent);
|
|
73
|
+
|
|
74
|
+
// We resolve immediately, actual playback state comes via events
|
|
75
|
+
call.resolve();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@PluginMethod
|
|
79
|
+
public void pause(PluginCall call) {
|
|
80
|
+
Log.d(TAG, "Pause called");
|
|
81
|
+
if (staticPlayerInstance != null) {
|
|
82
|
+
staticPlayerInstance.pause();
|
|
83
|
+
call.resolve();
|
|
84
|
+
} else {
|
|
85
|
+
call.reject("Player not active");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@PluginMethod
|
|
90
|
+
public void resume(PluginCall call) {
|
|
91
|
+
Log.d(TAG, "Resume called");
|
|
92
|
+
if (staticPlayerInstance != null) {
|
|
93
|
+
staticPlayerInstance.play();
|
|
94
|
+
call.resolve();
|
|
95
|
+
} else {
|
|
96
|
+
call.reject("Player not active");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@PluginMethod
|
|
101
|
+
public void stop(PluginCall call) {
|
|
102
|
+
Log.d(TAG, "Stop called");
|
|
103
|
+
if (staticPlayerInstance != null) {
|
|
104
|
+
staticPlayerInstance.stop();
|
|
105
|
+
// Consider finishing PlayerActivity here? Maybe PlayerActivity should finish itself on stop.
|
|
106
|
+
call.resolve();
|
|
107
|
+
} else {
|
|
108
|
+
call.reject("Player not active");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@PluginMethod
|
|
113
|
+
public void seekTo(PluginCall call) {
|
|
114
|
+
Double time = call.getDouble("time");
|
|
115
|
+
if (time == null) {
|
|
116
|
+
call.reject("time parameter is required");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (staticPlayerInstance != null) {
|
|
120
|
+
staticPlayerInstance.seek(time);
|
|
121
|
+
call.resolve();
|
|
122
|
+
} else {
|
|
123
|
+
call.reject("Player not active");
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@PluginMethod
|
|
128
|
+
public void setVolume(PluginCall call) {
|
|
129
|
+
Double volume = call.getDouble("volume"); // JW Player Android uses 0-100
|
|
130
|
+
if (volume == null) {
|
|
131
|
+
call.reject("volume parameter is required");
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (staticPlayerInstance != null) {
|
|
135
|
+
// Cast the result to int
|
|
136
|
+
staticPlayerInstance.setVolume((int) (volume.floatValue() * 100));
|
|
137
|
+
call.resolve();
|
|
138
|
+
} else {
|
|
139
|
+
call.reject("Player not active");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@PluginMethod
|
|
144
|
+
public void setSpeed(PluginCall call) {
|
|
145
|
+
Double speed = call.getDouble("speed");
|
|
146
|
+
if (speed == null) {
|
|
147
|
+
call.reject("speed parameter is required");
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (staticPlayerInstance != null) {
|
|
151
|
+
staticPlayerInstance.setPlaybackRate(speed.floatValue());
|
|
152
|
+
call.resolve();
|
|
153
|
+
} else {
|
|
154
|
+
call.reject("Player not active");
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@PluginMethod
|
|
159
|
+
public void getPosition(PluginCall call) {
|
|
160
|
+
if (staticPlayerInstance != null) {
|
|
161
|
+
JSObject ret = new JSObject();
|
|
162
|
+
ret.put("position", staticPlayerInstance.getPosition());
|
|
163
|
+
call.resolve(ret);
|
|
164
|
+
} else {
|
|
165
|
+
call.reject("Player not active");
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
@PluginMethod
|
|
170
|
+
public void getState(PluginCall call) {
|
|
171
|
+
if (staticPlayerInstance != null) {
|
|
172
|
+
JSObject ret = new JSObject();
|
|
173
|
+
// Convert JWPlayerState enum to int like iOS
|
|
174
|
+
int stateInt = mapPlayerStateToInt(staticPlayerInstance.getState());
|
|
175
|
+
ret.put("state", stateInt);
|
|
176
|
+
call.resolve(ret);
|
|
177
|
+
} else {
|
|
178
|
+
call.reject("Player not active", "-1"); // Return -1 or similar on error
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@PluginMethod
|
|
183
|
+
public void loadPlaylist(PluginCall call) {
|
|
184
|
+
String playlistUrl = call.getString("playlistUrl");
|
|
185
|
+
if (playlistUrl == null || playlistUrl.isEmpty()) {
|
|
186
|
+
call.reject("playlistUrl parameter is required");
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if (staticPlayerInstance != null) {
|
|
190
|
+
Log.d(TAG, "Loading playlist from URL: " + playlistUrl);
|
|
191
|
+
// Use PlayerConfig with a single playlist item URL
|
|
192
|
+
PlaylistItem playlistItem = new PlaylistItem.Builder()
|
|
193
|
+
.file(playlistUrl)
|
|
194
|
+
.build();
|
|
195
|
+
List<PlaylistItem> playlist = new ArrayList<>();
|
|
196
|
+
playlist.add(playlistItem);
|
|
197
|
+
PlayerConfig config = new PlayerConfig.Builder()
|
|
198
|
+
.playlist(playlist)
|
|
199
|
+
// Autostart false when just loading?
|
|
200
|
+
.autostart(false)
|
|
201
|
+
.build();
|
|
202
|
+
staticPlayerInstance.setup(config); // Use setup for subsequent loads
|
|
203
|
+
call.resolve();
|
|
204
|
+
} else {
|
|
205
|
+
call.reject("Player not active");
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
@PluginMethod
|
|
210
|
+
public void loadPlaylistWithItems(PluginCall call) {
|
|
211
|
+
JSArray itemsJS = call.getArray("playlist");
|
|
212
|
+
if (itemsJS == null) {
|
|
213
|
+
call.reject("playlist parameter is required and must be an array");
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (staticPlayerInstance != null) {
|
|
217
|
+
try {
|
|
218
|
+
List<PlaylistItem> playlist = new ArrayList<>();
|
|
219
|
+
for (int i = 0; i < itemsJS.length(); i++) {
|
|
220
|
+
JSObject itemJS = JSObject.fromJSONObject(itemsJS.getJSONObject(i));
|
|
221
|
+
String file = itemJS.getString("file");
|
|
222
|
+
if (file != null) {
|
|
223
|
+
PlaylistItem.Builder itemBuilder = new PlaylistItem.Builder().file(file);
|
|
224
|
+
if (itemJS.has("title")) {
|
|
225
|
+
itemBuilder.title(itemJS.getString("title"));
|
|
226
|
+
}
|
|
227
|
+
playlist.add(itemBuilder.build());
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (!playlist.isEmpty()) {
|
|
231
|
+
Log.d(TAG, "Loading playlist with " + playlist.size() + " items");
|
|
232
|
+
// Use PlayerConfig for loading multiple items too
|
|
233
|
+
PlayerConfig config = new PlayerConfig.Builder()
|
|
234
|
+
.playlist(playlist)
|
|
235
|
+
.autostart(false) // Or true depending on desired behavior
|
|
236
|
+
.build();
|
|
237
|
+
staticPlayerInstance.setup(config); // Use setup
|
|
238
|
+
call.resolve();
|
|
239
|
+
} else {
|
|
240
|
+
call.reject("No valid playlist items found");
|
|
241
|
+
}
|
|
242
|
+
} catch (Exception e) {
|
|
243
|
+
Log.e(TAG, "Error parsing playlist items", e);
|
|
244
|
+
call.reject("Error parsing playlist items: " + e.getMessage());
|
|
245
|
+
}
|
|
246
|
+
} else {
|
|
247
|
+
call.reject("Player not active");
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
@PluginMethod
|
|
252
|
+
public void setPlaylistIndex(PluginCall call) {
|
|
253
|
+
Integer index = call.getInt("index");
|
|
254
|
+
if (index == null) {
|
|
255
|
+
call.reject("index parameter is required");
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
if (staticPlayerInstance != null) {
|
|
259
|
+
Log.d(TAG, "Setting playlist index to: " + index);
|
|
260
|
+
staticPlayerInstance.playlistItem(index);
|
|
261
|
+
call.resolve();
|
|
262
|
+
} else {
|
|
263
|
+
call.reject("Player not active");
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
@PluginMethod
|
|
268
|
+
public void getAudioTracks(PluginCall call) {
|
|
269
|
+
if (staticPlayerInstance != null) {
|
|
270
|
+
List<AudioTrack> audioTracks = staticPlayerInstance.getAudioTracks();
|
|
271
|
+
JSArray tracksArray = new JSArray();
|
|
272
|
+
if (audioTracks != null) {
|
|
273
|
+
for (AudioTrack track : audioTracks) {
|
|
274
|
+
JSObject trackObj = new JSObject();
|
|
275
|
+
trackObj.put("name", track.getName());
|
|
276
|
+
trackObj.put("language", track.getLanguage());
|
|
277
|
+
// trackObj.put("defaultTrack", track.isDefaultTrack()); // Check API for default
|
|
278
|
+
tracksArray.put(trackObj);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
JSObject result = new JSObject();
|
|
282
|
+
result.put("tracks", tracksArray);
|
|
283
|
+
call.resolve(result);
|
|
284
|
+
} else {
|
|
285
|
+
call.reject("Player not active");
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
@PluginMethod
|
|
290
|
+
public void getCurrentAudioTrack(PluginCall call) {
|
|
291
|
+
if (staticPlayerInstance != null) {
|
|
292
|
+
int index = staticPlayerInstance.getCurrentAudioTrack();
|
|
293
|
+
JSObject result = new JSObject();
|
|
294
|
+
result.put("index", index);
|
|
295
|
+
call.resolve(result);
|
|
296
|
+
} else {
|
|
297
|
+
call.reject("Player not active");
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
@PluginMethod
|
|
302
|
+
public void setCurrentAudioTrack(PluginCall call) {
|
|
303
|
+
Integer index = call.getInt("index");
|
|
304
|
+
if (index == null) {
|
|
305
|
+
call.reject("index parameter is required");
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (staticPlayerInstance != null) {
|
|
309
|
+
Log.d(TAG, "Setting audio track index to: " + index);
|
|
310
|
+
staticPlayerInstance.setCurrentAudioTrack(index);
|
|
311
|
+
call.resolve();
|
|
312
|
+
} else {
|
|
313
|
+
call.reject("Player not active");
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
@PluginMethod
|
|
318
|
+
public void getCaptions(PluginCall call) {
|
|
319
|
+
if (staticPlayerInstance != null) {
|
|
320
|
+
List<Caption> captions = staticPlayerInstance.getCaptionsList();
|
|
321
|
+
JSArray captionsArray = new JSArray();
|
|
322
|
+
if (captions != null) {
|
|
323
|
+
for (int i = 0; i < captions.size(); i++) {
|
|
324
|
+
Caption caption = captions.get(i);
|
|
325
|
+
JSObject captionObj = new JSObject();
|
|
326
|
+
captionObj.put("index", i); // Use list index
|
|
327
|
+
captionObj.put("label", caption.getLabel());
|
|
328
|
+
// captionObj.put("language", caption.getLanguage()); // Check API
|
|
329
|
+
captionsArray.put(captionObj);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
JSObject result = new JSObject();
|
|
333
|
+
result.put("captions", captionsArray);
|
|
334
|
+
call.resolve(result);
|
|
335
|
+
} else {
|
|
336
|
+
call.reject("Player not active");
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
@PluginMethod
|
|
341
|
+
public void getCurrentCaptions(PluginCall call) {
|
|
342
|
+
if (staticPlayerInstance != null) {
|
|
343
|
+
int index = staticPlayerInstance.getCurrentCaptions();
|
|
344
|
+
JSObject result = new JSObject();
|
|
345
|
+
result.put("index", index); // 0 typically means off
|
|
346
|
+
call.resolve(result);
|
|
347
|
+
} else {
|
|
348
|
+
call.reject("Player not active");
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
@PluginMethod
|
|
353
|
+
public void setCurrentCaptions(PluginCall call) {
|
|
354
|
+
Integer index = call.getInt("index");
|
|
355
|
+
if (index == null) {
|
|
356
|
+
call.reject("index parameter is required");
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (staticPlayerInstance != null) {
|
|
360
|
+
Log.d(TAG, "Setting captions index to: " + index);
|
|
361
|
+
staticPlayerInstance.setCurrentCaptions(index);
|
|
362
|
+
call.resolve();
|
|
363
|
+
} else {
|
|
364
|
+
call.reject("Player not active");
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
@PluginMethod
|
|
369
|
+
public void currentPlaylist(PluginCall call) {
|
|
370
|
+
if (staticPlayerInstance != null) {
|
|
371
|
+
List<PlaylistItem> playlist = staticPlayerInstance.getPlaylist();
|
|
372
|
+
JSArray playlistJS = new JSArray();
|
|
373
|
+
if (playlist != null) {
|
|
374
|
+
for (PlaylistItem item : playlist) {
|
|
375
|
+
JSObject itemJS = new JSObject();
|
|
376
|
+
itemJS.put("file", item.getFile());
|
|
377
|
+
itemJS.put("title", item.getTitle());
|
|
378
|
+
itemJS.put("description", item.getDescription());
|
|
379
|
+
// Add other relevant properties
|
|
380
|
+
playlistJS.put(itemJS);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
JSObject result = new JSObject();
|
|
384
|
+
result.put("playlist", playlistJS);
|
|
385
|
+
call.resolve(result);
|
|
386
|
+
} else {
|
|
387
|
+
call.reject("Player not active");
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// --- Static methods for PlayerActivity Communication ---
|
|
392
|
+
|
|
393
|
+
public static void setStaticPlayerInstance(JWPlayer player) {
|
|
394
|
+
Log.d(TAG, "Setting static player instance: " + (player != null));
|
|
395
|
+
staticPlayerInstance = player;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
public static void onPlayerDismissed() {
|
|
399
|
+
Log.d(TAG, "PlayerActivity dismissed, clearing static player instance.");
|
|
400
|
+
staticPlayerInstance = null;
|
|
401
|
+
JwPlayerPlugin plugin = staticPluginRef != null ? staticPluginRef.get() : null;
|
|
402
|
+
if (plugin != null) {
|
|
403
|
+
plugin.notifyListeners("playerDismissed", null);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
public static void notifyPipChanged(boolean isInPip) {
|
|
408
|
+
JwPlayerPlugin plugin = staticPluginRef != null ? staticPluginRef.get() : null;
|
|
409
|
+
if (plugin != null) {
|
|
410
|
+
JSObject data = new JSObject();
|
|
411
|
+
data.put("isInPictureInPictureMode", isInPip);
|
|
412
|
+
plugin.notifyListeners(isInPip ? "pipStarted" : "pipStopped", data);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Static notification helpers called by PlayerActivity listeners
|
|
417
|
+
public static void notifyReady() {
|
|
418
|
+
JwPlayerPlugin plugin = staticPluginRef != null ? staticPluginRef.get() : null;
|
|
419
|
+
if (plugin != null) {
|
|
420
|
+
plugin.notifyListeners("ready", null);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
public static void notifyError(String type, String message) {
|
|
425
|
+
JwPlayerPlugin plugin = staticPluginRef != null ? staticPluginRef.get() : null;
|
|
426
|
+
if (plugin != null) {
|
|
427
|
+
JSObject data = new JSObject();
|
|
428
|
+
data.put("message", message);
|
|
429
|
+
// data.put("code", code); // Android SDK might not provide code easily
|
|
430
|
+
plugin.notifyListeners(type, data);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
public static void notifyWarning(String type, String message) {
|
|
435
|
+
JwPlayerPlugin plugin = staticPluginRef != null ? staticPluginRef.get() : null;
|
|
436
|
+
if (plugin != null) {
|
|
437
|
+
JSObject data = new JSObject();
|
|
438
|
+
data.put("message", message);
|
|
439
|
+
plugin.notifyListeners(type, data);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
public static void notifyPlaylistItem(int index, PlaylistItem item) {
|
|
444
|
+
JwPlayerPlugin plugin = staticPluginRef != null ? staticPluginRef.get() : null;
|
|
445
|
+
if (plugin != null) {
|
|
446
|
+
JSObject data = new JSObject();
|
|
447
|
+
data.put("index", index);
|
|
448
|
+
if (item != null) {
|
|
449
|
+
data.put("title", item.getTitle());
|
|
450
|
+
// data.put("file", item.getFile()); // Be careful with accessing file directly
|
|
451
|
+
}
|
|
452
|
+
plugin.notifyListeners("playlistItem", data);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
public static void notifyPlaylistComplete() {
|
|
457
|
+
JwPlayerPlugin plugin = staticPluginRef != null ? staticPluginRef.get() : null;
|
|
458
|
+
if (plugin != null) {
|
|
459
|
+
plugin.notifyListeners("complete", null); // Maybe playlistComplete event?
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
public static void notifyPause(String reason) {
|
|
464
|
+
JwPlayerPlugin plugin = staticPluginRef != null ? staticPluginRef.get() : null;
|
|
465
|
+
if (plugin != null) {
|
|
466
|
+
JSObject data = new JSObject();
|
|
467
|
+
data.put("reason", reason); // Android uses enum names
|
|
468
|
+
plugin.notifyListeners("pause", data);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
public static void notifyPlay(String reason) {
|
|
473
|
+
JwPlayerPlugin plugin = staticPluginRef != null ? staticPluginRef.get() : null;
|
|
474
|
+
if (plugin != null) {
|
|
475
|
+
JSObject data = new JSObject();
|
|
476
|
+
data.put("reason", reason); // Android uses enum names
|
|
477
|
+
plugin.notifyListeners("play", data);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
public static void notifyComplete() {
|
|
482
|
+
JwPlayerPlugin plugin = staticPluginRef != null ? staticPluginRef.get() : null;
|
|
483
|
+
if (plugin != null) {
|
|
484
|
+
plugin.notifyListeners("complete", null);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
public static void notifySeek(double position, double offset) {
|
|
489
|
+
JwPlayerPlugin plugin = staticPluginRef != null ? staticPluginRef.get() : null;
|
|
490
|
+
if (plugin != null) {
|
|
491
|
+
JSObject data = new JSObject();
|
|
492
|
+
data.put("position", position);
|
|
493
|
+
data.put("offset", offset);
|
|
494
|
+
plugin.notifyListeners("seek", data);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
public static void notifySeeked() {
|
|
499
|
+
JwPlayerPlugin plugin = staticPluginRef != null ? staticPluginRef.get() : null;
|
|
500
|
+
if (plugin != null) {
|
|
501
|
+
plugin.notifyListeners("seeked", null);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
public static void notifyTime(double position, double duration) {
|
|
506
|
+
JwPlayerPlugin plugin = staticPluginRef != null ? staticPluginRef.get() : null;
|
|
507
|
+
if (plugin != null) {
|
|
508
|
+
JSObject data = new JSObject();
|
|
509
|
+
data.put("position", position);
|
|
510
|
+
data.put("duration", duration);
|
|
511
|
+
plugin.notifyListeners("time", data);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Helper to map Android state enum to iOS-like integers
|
|
516
|
+
private int mapPlayerStateToInt(com.jwplayer.pub.api.PlayerState state) {
|
|
517
|
+
switch (state) {
|
|
518
|
+
case IDLE: return 0;
|
|
519
|
+
case BUFFERING: return 1;
|
|
520
|
+
case PLAYING: return 2;
|
|
521
|
+
case PAUSED: return 3;
|
|
522
|
+
case COMPLETE: return 4;
|
|
523
|
+
default: return -1; // Unknown
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// TODO: Implement other methods like loadPlaylist, getAudioTracks, setAudioTrack, getCaptions, setCaptions etc.
|
|
528
|
+
// These will require more complex communication with the PlayerActivity or direct player interaction.
|
|
529
|
+
}
|