str-native-video-player 2.0.0 → 2.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.
@@ -1,236 +1,236 @@
1
- package com.strtv.app;
2
-
3
- import static android.content.ContentValues.TAG;
4
-
5
- import android.app.Activity;
6
- import android.os.Handler;
7
- import android.os.HandlerThread;
8
-
9
- import android.util.Log;
10
- import android.view.SurfaceView;
11
- import android.view.ViewGroup;
12
- import android.widget.FrameLayout;
13
-
14
- import com.getcapacitor.JSArray;
15
- import com.getcapacitor.JSObject;
16
- import com.getcapacitor.Plugin;
17
- import com.getcapacitor.PluginCall;
18
- import com.getcapacitor.PluginMethod;
19
- import com.getcapacitor.annotation.CapacitorPlugin;
20
-
21
- import org.json.JSONArray;
22
-
23
- import java.io.File;
24
-
25
- @CapacitorPlugin(name = "STRTV")
26
- public class STRTVPlugin extends Plugin {
27
-
28
- private STRTV implementation;
29
- private VideoPlayer videoPlayer;
30
- private SurfaceView surfaceView;
31
- private HandlerThread playerThread;
32
- private Handler playerHandler;
33
-
34
- private String currentlyPlayingUuid = null;
35
-
36
-
37
- @Override
38
- public void load() {
39
- Log.i(TAG, "NEW LOADING: ");
40
-
41
- implementation = new STRTV(getContext());
42
- // Initialize ExoPlayer thread
43
- playerThread = new HandlerThread("VideoPlayerThread");
44
- playerThread.start();
45
- playerHandler = new Handler(playerThread.getLooper());
46
- }
47
-
48
- @PluginMethod
49
- public void echo(PluginCall call) {
50
- String value = call.getString("value");
51
- JSObject ret = new JSObject();
52
- ret.put("value", implementation.echo(value));
53
- call.resolve(ret);
54
- }
55
-
56
- @PluginMethod
57
- public void play_video(PluginCall call) {
58
- String uuid = call.getString("uuid");
59
- String url = call.getString("url"); // optional for streaming
60
- boolean loop = call.getBoolean("loop", false);
61
-
62
- if (uuid == null) {
63
- call.reject("Missing uuid");
64
- return;
65
- }
66
-
67
- currentlyPlayingUuid = uuid; // mark this as the currently intended video
68
-
69
-
70
-
71
- if (videoPlayer == null) {
72
- createAndAttachSurfaceView(() -> {
73
- getBridge().execute(() -> {
74
- videoPlayer = new VideoPlayer(getContext(), surfaceView);
75
-
76
- // Now safe to play video
77
- playVideoInternal(uuid, url, loop, call);
78
- });
79
- });
80
- } else {
81
- // Player already exists
82
- playVideoInternal(uuid, url, loop, call);
83
- }
84
- }
85
-
86
- private void playVideoInternal(String uuid, String url, boolean loop, PluginCall call) {
87
- File cachedFile = implementation.getVideoFile(uuid, url);
88
- if (cachedFile != null && cachedFile.exists()) {
89
- videoPlayer.playFile(cachedFile, loop);
90
- call.resolve();
91
- return;
92
- }
93
-
94
- if (url == null) {
95
- call.reject("No cached file and no URL provided");
96
- return;
97
- }
98
-
99
- videoPlayer.playUrl(url, loop);
100
-
101
- implementation.downloadInBackground(uuid, url, _cachedFile -> {
102
- if (!uuid.equals(currentlyPlayingUuid)) return;
103
-
104
- getBridge().execute(() -> {
105
- if (videoPlayer != null) {
106
- long currentPos = videoPlayer.getCurrentPositionMs();
107
- videoPlayer.playFile(_cachedFile, loop);
108
- videoPlayer.seekTo(currentPos);
109
- }
110
- });
111
- });
112
-
113
- call.resolve();
114
- }
115
-
116
-
117
- @PluginMethod
118
- public void resume_video(PluginCall call) {
119
- if (videoPlayer != null) videoPlayer.resume();
120
- call.resolve();
121
- }
122
-
123
- @PluginMethod
124
- public void pause_video(PluginCall call) {
125
- if (videoPlayer != null) videoPlayer.pause();
126
- call.resolve();
127
- }
128
-
129
- @PluginMethod
130
- public void stop_video(PluginCall call) {
131
- if (videoPlayer != null) videoPlayer.stop();
132
- call.resolve();
133
-
134
- currentlyPlayingUuid = null;
135
- }
136
-
137
- @PluginMethod
138
- public void seek_video(PluginCall call) {
139
- long pos = call.getLong("position_ms", 0L);
140
- if (videoPlayer != null) videoPlayer.seekTo(pos);
141
- call.resolve();
142
- }
143
-
144
- @PluginMethod
145
- public void is_video_playing(PluginCall call) {
146
- boolean playing = videoPlayer != null && videoPlayer.isPlaying();
147
- JSObject ret = new JSObject();
148
- ret.put("playing", playing);
149
- call.resolve(ret);
150
- }
151
-
152
- @PluginMethod
153
- public void preload_video(PluginCall call) {
154
- String uuid = call.getString("uuid");
155
- String url = call.getString("url");
156
-
157
- if (uuid == null || url == null) {
158
- call.reject("uuid and url required");
159
- return;
160
- }
161
-
162
- boolean success = implementation.preloadVideo(uuid, url);
163
- JSObject ret = new JSObject();
164
- ret.put("success", success);
165
- call.resolve(ret);
166
- }
167
-
168
- @PluginMethod
169
- public void list_cached_videos(PluginCall call) {
170
- JSArray list = implementation.listCachedVideos();
171
- JSObject ret = new JSObject();
172
- ret.put("value", list);
173
- call.resolve(ret);
174
- }
175
-
176
- @PluginMethod
177
- public void evict_videos(PluginCall call) {
178
- JSArray arr = call.getArray("uuids");
179
- if (arr == null) {
180
- call.reject("uuids array required");
181
- return;
182
- }
183
-
184
- try {
185
- JSONArray list = new JSONArray(arr.toString());
186
- boolean result = implementation.evictVideos(list);
187
-
188
- JSObject ret = new JSObject();
189
- ret.put("success", result);
190
- call.resolve(ret);
191
- } catch (Exception e) {
192
- call.reject("Failed to evict videos: " + e.getMessage());
193
- }
194
- }
195
-
196
- @PluginMethod
197
- public void get_storage_stats(PluginCall call) {
198
- JSObject stats = implementation.getStorageStats();
199
- call.resolve(stats);
200
- }
201
-
202
- @PluginMethod
203
- public void set_max_cache_size(PluginCall call) {
204
- long maxBytes = call.getLong("max_bytes", -1L);
205
- if (maxBytes < 0) {
206
- call.reject("max_bytes required");
207
- return;
208
- }
209
-
210
- implementation.setMaxCacheSize(maxBytes);
211
- JSObject ret = new JSObject();
212
- ret.put("success", true);
213
- call.resolve(ret);
214
- }
215
-
216
- // --- Helper to create and attach SurfaceView ---
217
- private void createAndAttachSurfaceView(Runnable onReady) {
218
- Activity activity = getActivity();
219
- if (activity == null) return;
220
-
221
- activity.runOnUiThread(() -> {
222
- SurfaceView sv = new SurfaceView(activity);
223
- FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
224
- FrameLayout.LayoutParams.MATCH_PARENT,
225
- FrameLayout.LayoutParams.MATCH_PARENT
226
- );
227
- sv.setLayoutParams(params);
228
-
229
- ViewGroup container = activity.findViewById(android.R.id.content);
230
- container.addView(sv, 0);
231
-
232
- surfaceView = sv;
233
- if (onReady != null) onReady.run();
234
- });
235
- }
236
- }
1
+ package com.strtv.app;
2
+
3
+ import static android.content.ContentValues.TAG;
4
+
5
+ import android.app.Activity;
6
+ import android.os.Handler;
7
+ import android.os.HandlerThread;
8
+
9
+ import android.util.Log;
10
+ import android.view.SurfaceView;
11
+ import android.view.ViewGroup;
12
+ import android.widget.FrameLayout;
13
+
14
+ import com.getcapacitor.JSArray;
15
+ import com.getcapacitor.JSObject;
16
+ import com.getcapacitor.Plugin;
17
+ import com.getcapacitor.PluginCall;
18
+ import com.getcapacitor.PluginMethod;
19
+ import com.getcapacitor.annotation.CapacitorPlugin;
20
+
21
+ import org.json.JSONArray;
22
+
23
+ import java.io.File;
24
+
25
+ @CapacitorPlugin(name = "STRTV")
26
+ public class STRTVPlugin extends Plugin {
27
+
28
+ private STRTV implementation;
29
+ private VideoPlayer videoPlayer;
30
+ private SurfaceView surfaceView;
31
+ private HandlerThread playerThread;
32
+ private Handler playerHandler;
33
+
34
+ private String currentlyPlayingUuid = null;
35
+
36
+
37
+ @Override
38
+ public void load() {
39
+ Log.i(TAG, "NEW LOADING: ");
40
+
41
+ implementation = new STRTV(getContext());
42
+ // Initialize ExoPlayer thread
43
+ playerThread = new HandlerThread("VideoPlayerThread");
44
+ playerThread.start();
45
+ playerHandler = new Handler(playerThread.getLooper());
46
+ }
47
+
48
+ @PluginMethod
49
+ public void echo(PluginCall call) {
50
+ String value = call.getString("value");
51
+ JSObject ret = new JSObject();
52
+ ret.put("value", implementation.echo(value));
53
+ call.resolve(ret);
54
+ }
55
+
56
+ @PluginMethod
57
+ public void play_video(PluginCall call) {
58
+ String uuid = call.getString("uuid");
59
+ String url = call.getString("url"); // optional for streaming
60
+ boolean loop = call.getBoolean("loop", false);
61
+
62
+ if (uuid == null) {
63
+ call.reject("Missing uuid");
64
+ return;
65
+ }
66
+
67
+ currentlyPlayingUuid = uuid; // mark this as the currently intended video
68
+
69
+
70
+
71
+ if (videoPlayer == null) {
72
+ createAndAttachSurfaceView(() -> {
73
+ getBridge().execute(() -> {
74
+ videoPlayer = new VideoPlayer(getContext(), surfaceView);
75
+
76
+ // Now safe to play video
77
+ playVideoInternal(uuid, url, loop, call);
78
+ });
79
+ });
80
+ } else {
81
+ // Player already exists
82
+ playVideoInternal(uuid, url, loop, call);
83
+ }
84
+ }
85
+
86
+ private void playVideoInternal(String uuid, String url, boolean loop, PluginCall call) {
87
+ File cachedFile = implementation.getVideoFile(uuid, url);
88
+ if (cachedFile != null && cachedFile.exists()) {
89
+ videoPlayer.playFile(cachedFile, loop);
90
+ call.resolve();
91
+ return;
92
+ }
93
+
94
+ if (url == null) {
95
+ call.reject("No cached file and no URL provided");
96
+ return;
97
+ }
98
+
99
+ videoPlayer.playUrl(url, loop);
100
+
101
+ implementation.downloadInBackground(uuid, url, _cachedFile -> {
102
+ if (!uuid.equals(currentlyPlayingUuid)) return;
103
+
104
+ getBridge().execute(() -> {
105
+ if (videoPlayer != null) {
106
+ long currentPos = videoPlayer.getCurrentPositionMs();
107
+ videoPlayer.playFile(_cachedFile, loop);
108
+ videoPlayer.seekTo(currentPos);
109
+ }
110
+ });
111
+ });
112
+
113
+ call.resolve();
114
+ }
115
+
116
+
117
+ @PluginMethod
118
+ public void resume_video(PluginCall call) {
119
+ if (videoPlayer != null) videoPlayer.resume();
120
+ call.resolve();
121
+ }
122
+
123
+ @PluginMethod
124
+ public void pause_video(PluginCall call) {
125
+ if (videoPlayer != null) videoPlayer.pause();
126
+ call.resolve();
127
+ }
128
+
129
+ @PluginMethod
130
+ public void stop_video(PluginCall call) {
131
+ if (videoPlayer != null) videoPlayer.stop();
132
+ call.resolve();
133
+
134
+ currentlyPlayingUuid = null;
135
+ }
136
+
137
+ @PluginMethod
138
+ public void seek_video(PluginCall call) {
139
+ long pos = call.getLong("position_ms", 0L);
140
+ if (videoPlayer != null) videoPlayer.seekTo(pos);
141
+ call.resolve();
142
+ }
143
+
144
+ @PluginMethod
145
+ public void is_video_playing(PluginCall call) {
146
+ boolean playing = videoPlayer != null && videoPlayer.isPlaying();
147
+ JSObject ret = new JSObject();
148
+ ret.put("playing", playing);
149
+ call.resolve(ret);
150
+ }
151
+
152
+ @PluginMethod
153
+ public void preload_video(PluginCall call) {
154
+ String uuid = call.getString("uuid");
155
+ String url = call.getString("url");
156
+
157
+ if (uuid == null || url == null) {
158
+ call.reject("uuid and url required");
159
+ return;
160
+ }
161
+
162
+ boolean success = implementation.preloadVideo(uuid, url);
163
+ JSObject ret = new JSObject();
164
+ ret.put("success", success);
165
+ call.resolve(ret);
166
+ }
167
+
168
+ @PluginMethod
169
+ public void list_cached_videos(PluginCall call) {
170
+ JSArray list = implementation.listCachedVideos();
171
+ JSObject ret = new JSObject();
172
+ ret.put("value", list);
173
+ call.resolve(ret);
174
+ }
175
+
176
+ @PluginMethod
177
+ public void evict_videos(PluginCall call) {
178
+ JSArray arr = call.getArray("uuids");
179
+ if (arr == null) {
180
+ call.reject("uuids array required");
181
+ return;
182
+ }
183
+
184
+ try {
185
+ JSONArray list = new JSONArray(arr.toString());
186
+ boolean result = implementation.evictVideos(list);
187
+
188
+ JSObject ret = new JSObject();
189
+ ret.put("success", result);
190
+ call.resolve(ret);
191
+ } catch (Exception e) {
192
+ call.reject("Failed to evict videos: " + e.getMessage());
193
+ }
194
+ }
195
+
196
+ @PluginMethod
197
+ public void get_storage_stats(PluginCall call) {
198
+ JSObject stats = implementation.getStorageStats();
199
+ call.resolve(stats);
200
+ }
201
+
202
+ @PluginMethod
203
+ public void set_max_cache_size(PluginCall call) {
204
+ long maxBytes = call.getLong("max_bytes", -1L);
205
+ if (maxBytes < 0) {
206
+ call.reject("max_bytes required");
207
+ return;
208
+ }
209
+
210
+ implementation.setMaxCacheSize(maxBytes);
211
+ JSObject ret = new JSObject();
212
+ ret.put("success", true);
213
+ call.resolve(ret);
214
+ }
215
+
216
+ // --- Helper to create and attach SurfaceView ---
217
+ private void createAndAttachSurfaceView(Runnable onReady) {
218
+ Activity activity = getActivity();
219
+ if (activity == null) return;
220
+
221
+ activity.runOnUiThread(() -> {
222
+ SurfaceView sv = new SurfaceView(activity);
223
+ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
224
+ FrameLayout.LayoutParams.MATCH_PARENT,
225
+ FrameLayout.LayoutParams.MATCH_PARENT
226
+ );
227
+ sv.setLayoutParams(params);
228
+
229
+ ViewGroup container = activity.findViewById(android.R.id.content);
230
+ container.addView(sv, 0);
231
+
232
+ surfaceView = sv;
233
+ if (onReady != null) onReady.run();
234
+ });
235
+ }
236
+ }
@@ -2,6 +2,7 @@ package com.strtv.app;
2
2
 
3
3
  import android.content.Context;
4
4
  import android.net.Uri;
5
+ import android.os.Handler;
5
6
  import android.util.Log;
6
7
  import android.view.Surface;
7
8
  import android.view.SurfaceHolder;
@@ -26,12 +27,14 @@ public class VideoPlayer {
26
27
  private SurfaceView surfaceView;
27
28
  private Surface surface;
28
29
  private boolean isPrepared = false;
30
+ Handler playerHandler;
29
31
 
30
32
  public VideoPlayer(Context context, SurfaceView surfaceView) {
31
33
  this.context = context;
32
34
  this.surfaceView = surfaceView;
33
35
  initPlayer();
34
36
  attachSurfaceView(surfaceView);
37
+ playerHandler = new Handler(player.getApplicationLooper());
35
38
  }
36
39
 
37
40
  @OptIn(markerClass = UnstableApi.class)
@@ -53,7 +56,9 @@ public class VideoPlayer {
53
56
  @Override
54
57
  public void surfaceCreated(SurfaceHolder holder) {
55
58
  surface = holder.getSurface();
56
- player.setVideoSurface(surface);
59
+ playerHandler.post(() -> {
60
+ player.setVideoSurface(surface);
61
+ });
57
62
  }
58
63
 
59
64
  @Override
@@ -63,11 +68,14 @@ public class VideoPlayer {
63
68
 
64
69
  @Override
65
70
  public void surfaceDestroyed(SurfaceHolder holder) {
66
- player.setVideoSurface(null);
67
- if (surface != null) {
68
- surface.release();
69
- surface = null;
70
- }
71
+ playerHandler.post(() ->{
72
+ player.setVideoSurface(null);
73
+ if (surface != null) {
74
+ surface.release();
75
+ surface = null;
76
+ }
77
+ });
78
+
71
79
  }
72
80
  });
73
81
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "str-native-video-player",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Allows for native video player functionality, fetching and storing videos from a CDN, switching between the playback of these videos with cross fade and preloading functionality",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",