cordova-plugin-media3 1.1.25 → 1.1.27

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cordova-plugin-media3",
3
- "version": "1.1.025",
3
+ "version": "1.1.027",
4
4
  "description": "Media player for Cordova using Google's media3 ExoPlayer framework",
5
5
  "cordova": {
6
6
  "id": "cordova-plugin-media3",
package/plugin.xml CHANGED
@@ -39,6 +39,15 @@
39
39
  </feature>
40
40
  </config-file>
41
41
 
42
+ <edit-config file="AndroidManifest.xml" mode="merge" target="/manifest/application/activity[@android:name='MainActivity']">
43
+ <activity android:resizeableActivity="true"
44
+ android:supportsPictureInPicture="true"
45
+ android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
46
+ > <!-- android:launchMode="singleTask" -->
47
+ </activity>
48
+
49
+ </edit-config>
50
+
42
51
  <!-- <source-file src="src/res/values/ids.xml" target-dir="res/values/"/>
43
52
  <source-file src="src/res/values/constants.xml" target-dir="res/values/"/>
44
53
  <source-file src="src/res/values/styles.xml" target-dir="res/values/"/>
@@ -25,6 +25,7 @@ package com.naja7host.cordova.plugin.exoplayer;
25
25
 
26
26
  import android.graphics.Color;
27
27
  import android.util.Log;
28
+ import android.util.Rational;
28
29
  import android.app.*;
29
30
  import android.content.*;
30
31
  import android.content.pm.PackageManager;
@@ -34,7 +35,6 @@ import android.view.*;
34
35
  import android.widget.*;
35
36
  import android.os.Handler;
36
37
  import android.os.Looper;
37
-
38
38
  import androidx.annotation.NonNull;
39
39
  import androidx.appcompat.widget.ContentFrameLayout;
40
40
 
@@ -108,14 +108,14 @@ public class Player {
108
108
  @Override
109
109
  public void onPlaybackStateChanged(int playbackState) {
110
110
  if (config.getShowBuffering()) {
111
- LayoutProvider.setBufferingVisibility(exoView, activity, playbackState == androidx.media3.common.Player.STATE_BUFFERING);
111
+ LayoutProvider.setBufferingVisibility(exoView, activity, playbackState == ExoPlayer.STATE_BUFFERING);
112
112
  }
113
113
  JSONObject payload = Payload.stateEvent(Player.this.exoPlayer, playbackState, Player.this.controllerVisibility == View.VISIBLE);
114
114
  new CallbackResponse(Player.this.callbackContext).send(PluginResult.Status.OK, payload, true);
115
115
  }
116
116
 
117
117
  @Override
118
- public void onPositionDiscontinuity(@NonNull androidx.media3.common.Player.PositionInfo oldPosition, @NonNull androidx.media3.common.Player.PositionInfo newPosition, int reason) {
118
+ public void onPositionDiscontinuity(@NonNull ExoPlayer.PositionInfo oldPosition, @NonNull ExoPlayer.PositionInfo newPosition, int reason) {
119
119
  JSONObject payload = Payload.positionDiscontinuityEvent(Player.this.exoPlayer, reason);
120
120
  new CallbackResponse(Player.this.callbackContext).send(PluginResult.Status.OK, payload, true);
121
121
  }
@@ -231,8 +231,8 @@ public class Player {
231
231
  public void createPlayer() {
232
232
  Log.i(TAG, "Playing " + config.getUri());
233
233
 
234
- String mediaUrl = config.getUri(); // Your method to get the URL
235
- if (mediaUrl != null && URLUtil.isValidUrl(mediaUrl)) {
234
+ // String mediaUrl = config.getUri(); // Your method to get the URL
235
+ // if (mediaUrl != null && URLUtil.isValidUrl(mediaUrl)) {
236
236
  // Proceed with ExoPlayer setup using mediaUrl
237
237
  if (config.useInlineView()) {
238
238
  // Using a dialog doesn't work for us, as controls are drawn in HTML view (cordova ui)
@@ -247,11 +247,11 @@ public class Player {
247
247
  if (config.useInlineView()) {
248
248
  setController(config.getController());
249
249
  }
250
- } else {
251
- // Handle invalid or null URL: e.g., show an error message, log the issue, or use a placeholder.
252
- Log.e("ExoPlayerDebug", "Invalid media URL: " + mediaUrl);
253
- sendError("Invalid media URL: " + uri);
254
- }
250
+ // } else {
251
+ // // Handle invalid or null URL: e.g., show an error message, log the issue, or use a placeholder.
252
+ // Log.e("ExoPlayerDebug", "Invalid media URL: " + mediaUrl);
253
+ // sendError("Invalid media URL: " + mediaUrl);
254
+ // }
255
255
  }
256
256
 
257
257
  public void createDialog() {
@@ -920,6 +920,93 @@ public class Player {
920
920
  return response;
921
921
  }
922
922
 
923
+ public JSONObject isPipModeSupported() {
924
+ JSONObject response = new JSONObject();
925
+
926
+ try {
927
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // PiP requires API level 26+
928
+ response.put("success", true);
929
+ response.put("message", "PIP mode is supported");
930
+ } else {
931
+ response.put("success", false);
932
+ response.put("message", "PIP mode is not supported");
933
+ }
934
+ } catch (JSONException e) {
935
+ try {
936
+ response.put("success", false);
937
+ response.put("error", "Failed to check PIP mode supported: " + e.getMessage());
938
+ } catch (JSONException je) {
939
+ Log.e(TAG, "Error creating response JSON", je);
940
+ }
941
+ }
942
+
943
+ return response;
944
+ }
945
+
946
+ public JSONObject createPIPMode() {
947
+ JSONObject response = new JSONObject();
948
+
949
+ try {
950
+ if (exoView == null) {
951
+ response.put("success", false);
952
+ response.put("message", "Player view not initialized");
953
+ return response;
954
+ }
955
+
956
+ // activity.enterPictureInPictureMode(PictureInPictureParams.Builder()
957
+ // .setAspectRatio(Rational(16, 9))
958
+ // .build());
959
+
960
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // PiP requires API level 26+
961
+ PictureInPictureParams.Builder pipParamsBuilder = new PictureInPictureParams.Builder();
962
+ // Set desired aspect ratio (e.g., 16:9)
963
+ pipParamsBuilder.setAspectRatio(new Rational(16, 9));
964
+ this.activity.enterPictureInPictureMode(pipParamsBuilder.build());
965
+
966
+ response.put("success", true);
967
+ response.put("message", "PIP mode created successfully");
968
+ }
969
+
970
+ else {
971
+ response.put("success", false);
972
+ response.put("message", "PIP mode not supported");
973
+ }
974
+
975
+ } catch (JSONException e) {
976
+ try {
977
+ response.put("success", false);
978
+ response.put("error", "Failed to createPIPMode: " + e.getMessage());
979
+ } catch (JSONException je) {
980
+ Log.e(TAG, "Error creating response JSON", je);
981
+ }
982
+ }
983
+
984
+ return response;
985
+ }
986
+
987
+ public JSONObject isPipMode() {
988
+ JSONObject response = new JSONObject();
989
+
990
+ try{
991
+ if (this.activity.isInPictureInPictureMode()) {
992
+ response.put("success", true);
993
+ response.put("message", "PIP mode is active");
994
+ } else {
995
+ response.put("success", false);
996
+ response.put("message", "PIP mode is not active");
997
+ }
998
+ } catch(Exception e) {
999
+ try {
1000
+ response.put("success", false);
1001
+ response.put("error", "Failed to check PIP mode: " + e.getMessage());
1002
+ } catch (JSONException je) {
1003
+ Log.e(TAG, "Error creating response JSON", je);
1004
+ }
1005
+ }
1006
+
1007
+ return response;
1008
+ }
1009
+
923
1010
  private int getResizeModeFromString(String aspectRatio) {
924
1011
  switch (aspectRatio.toUpperCase()) {
925
1012
  case "FIT":
@@ -285,6 +285,28 @@ public class Plugin extends CordovaPlugin {
285
285
  }
286
286
  });
287
287
  return true;
288
+ } else if (action.equals("createPIPMode")) {
289
+ if (self.player == null) {
290
+ return false;
291
+ }
292
+ cordova.getActivity().runOnUiThread(new Runnable() {
293
+ public void run() {
294
+ JSONObject response = self.player.createPIPMode();
295
+ new CallbackResponse(callbackContext).send(PluginResult.Status.OK, response, true);
296
+ }
297
+ });
298
+ return true;
299
+ } else if (action.equals("isPipMode")) {
300
+ if (self.player == null) {
301
+ return false;
302
+ }
303
+ cordova.getActivity().runOnUiThread(new Runnable() {
304
+ public void run() {
305
+ JSONObject response = self.player.isPipMode();
306
+ new CallbackResponse(callbackContext).send(PluginResult.Status.OK, response, true);
307
+ }
308
+ });
309
+ return true;
288
310
  } else {
289
311
  new CallbackResponse(callbackContext).send(PluginResult.Status.INVALID_ACTION, false);
290
312
  return false;
package/www/exoplayer.js CHANGED
@@ -85,6 +85,15 @@ module.exports = {
85
85
  setAspectRatio: function (aspectRatio, successCallback, errorCallback) {
86
86
  cordova.exec(successCallback, errorCallback, "ExoPlayer", "setAspectRatio", [aspectRatio]);
87
87
  },
88
+ isPipModeSupported: function (successCallback, errorCallback) {
89
+ cordova.exec(successCallback, errorCallback, "ExoPlayer", "isPipModeSupported", []);
90
+ },
91
+ createPIPMode: function (successCallback, errorCallback) {
92
+ cordova.exec(successCallback, errorCallback, "ExoPlayer", "createPIPMode", []);
93
+ },
94
+ isPipMode: function (successCallback, errorCallback) {
95
+ cordova.exec(successCallback, errorCallback, "ExoPlayer", "isPipMode", []);
96
+ },
88
97
  getDuration: function (successCallback, errorCallback) {
89
98
  cordova.exec(successCallback, errorCallback, "ExoPlayer", "getDuration", []);
90
99
  },