@bits-innovate/react-native-vstarcam 1.0.16 → 1.0.18
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/android/build.gradle +3 -1
- package/android/libs/app_player-5.0.0.aar +0 -0
- package/android/src/main/java/com/reactnativevstarcam/VStarCamModule.java +12 -2
- package/android/src/main/java/com/reactnativevstarcam/VStarCamPackage.java +5 -2
- package/android/src/main/java/com/reactnativevstarcam/VStarCamVideoView.java +197 -0
- package/android/src/main/java/com/reactnativevstarcam/VStarCamVideoViewManager.java +106 -0
- package/package.json +1 -1
- package/src/index.ts +44 -1
- package/android/libs/classes.jar +0 -0
package/android/build.gradle
CHANGED
|
@@ -54,6 +54,8 @@ repositories {
|
|
|
54
54
|
|
|
55
55
|
dependencies {
|
|
56
56
|
implementation "com.facebook.react:react-native:+"
|
|
57
|
-
// AAR for
|
|
57
|
+
// AAR for P2P connectivity
|
|
58
58
|
implementation files('libs/app_p2p_api-5.0.0.aar')
|
|
59
|
+
// AAR for video player/decoder
|
|
60
|
+
implementation files('libs/app_player-5.0.0.aar')
|
|
59
61
|
}
|
|
Binary file
|
|
@@ -539,7 +539,17 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
539
539
|
long.class, String.class, String.class);
|
|
540
540
|
|
|
541
541
|
Log.d(TAG, "Calling JNIApi.login(" + clientInfo.sdkClientPtr + ", " + username + ", ***)");
|
|
542
|
-
|
|
542
|
+
|
|
543
|
+
try {
|
|
544
|
+
loginMethod.invoke(null, clientInfo.sdkClientPtr, username, password);
|
|
545
|
+
Log.d(TAG, "JNIApi.login returned normally");
|
|
546
|
+
} catch (java.lang.reflect.InvocationTargetException ite) {
|
|
547
|
+
Log.e(TAG, "JNIApi.login threw exception: " + ite.getCause(), ite.getCause());
|
|
548
|
+
throw ite;
|
|
549
|
+
} catch (Throwable t) {
|
|
550
|
+
Log.e(TAG, "JNIApi.login crashed: " + t.getMessage(), t);
|
|
551
|
+
throw t;
|
|
552
|
+
}
|
|
543
553
|
|
|
544
554
|
clientInfo.isLoggedIn = true;
|
|
545
555
|
Log.d(TAG, "JNIApi.login called successfully");
|
|
@@ -747,7 +757,7 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
747
757
|
@ReactMethod
|
|
748
758
|
public void getSdkVersion(Promise promise) {
|
|
749
759
|
WritableMap result = Arguments.createMap();
|
|
750
|
-
result.putString("version", "1.0.
|
|
760
|
+
result.putString("version", "1.0.18");
|
|
751
761
|
result.putBoolean("nativeLoaded", isNativeLibraryLoaded);
|
|
752
762
|
result.putString("nativeLib", "OKSMARTPPCS");
|
|
753
763
|
result.putBoolean("p2pInitialized", isP2PInitialized);
|
|
@@ -8,7 +8,7 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
|
|
8
8
|
import com.facebook.react.uimanager.ViewManager;
|
|
9
9
|
|
|
10
10
|
import java.util.ArrayList;
|
|
11
|
-
import java.util.
|
|
11
|
+
import java.util.Arrays;
|
|
12
12
|
import java.util.List;
|
|
13
13
|
|
|
14
14
|
public class VStarCamPackage implements ReactPackage {
|
|
@@ -23,6 +23,9 @@ public class VStarCamPackage implements ReactPackage {
|
|
|
23
23
|
@NonNull
|
|
24
24
|
@Override
|
|
25
25
|
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
|
|
26
|
-
return
|
|
26
|
+
return Arrays.<ViewManager>asList(
|
|
27
|
+
new VStarCamVideoViewManager()
|
|
28
|
+
);
|
|
27
29
|
}
|
|
28
30
|
}
|
|
31
|
+
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
package com.reactnativevstarcam;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.graphics.Color;
|
|
5
|
+
import android.graphics.SurfaceTexture;
|
|
6
|
+
import android.util.Log;
|
|
7
|
+
import android.view.TextureView;
|
|
8
|
+
import android.view.Gravity;
|
|
9
|
+
import android.widget.FrameLayout;
|
|
10
|
+
import android.widget.TextView;
|
|
11
|
+
|
|
12
|
+
import java.lang.reflect.Method;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Native video view for VStarCam camera streaming.
|
|
16
|
+
* Uses TextureView for video rendering with the native player SDK.
|
|
17
|
+
*/
|
|
18
|
+
public class VStarCamVideoView extends FrameLayout implements TextureView.SurfaceTextureListener {
|
|
19
|
+
private static final String TAG = "VStarCamVideoView";
|
|
20
|
+
|
|
21
|
+
private TextureView textureView;
|
|
22
|
+
private TextView statusView;
|
|
23
|
+
private long clientPtr = 0;
|
|
24
|
+
private long playerPtr = 0;
|
|
25
|
+
private boolean isStreaming = false;
|
|
26
|
+
private int resolution = 2; // Default to general resolution
|
|
27
|
+
|
|
28
|
+
// Player library class
|
|
29
|
+
private Class<?> appPlayerClass;
|
|
30
|
+
private Object playerInstance;
|
|
31
|
+
private boolean playerLibLoaded = false;
|
|
32
|
+
|
|
33
|
+
public VStarCamVideoView(Context context) {
|
|
34
|
+
super(context);
|
|
35
|
+
init(context);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private void init(Context context) {
|
|
39
|
+
setBackgroundColor(Color.BLACK);
|
|
40
|
+
|
|
41
|
+
// Create texture view for video rendering
|
|
42
|
+
textureView = new TextureView(context);
|
|
43
|
+
textureView.setSurfaceTextureListener(this);
|
|
44
|
+
addView(textureView, new LayoutParams(
|
|
45
|
+
LayoutParams.MATCH_PARENT,
|
|
46
|
+
LayoutParams.MATCH_PARENT
|
|
47
|
+
));
|
|
48
|
+
|
|
49
|
+
// Status overlay
|
|
50
|
+
statusView = new TextView(context);
|
|
51
|
+
statusView.setTextColor(Color.WHITE);
|
|
52
|
+
statusView.setTextSize(14);
|
|
53
|
+
statusView.setGravity(Gravity.CENTER);
|
|
54
|
+
statusView.setText("Waiting for connection...");
|
|
55
|
+
LayoutParams statusParams = new LayoutParams(
|
|
56
|
+
LayoutParams.WRAP_CONTENT,
|
|
57
|
+
LayoutParams.WRAP_CONTENT
|
|
58
|
+
);
|
|
59
|
+
statusParams.gravity = Gravity.CENTER;
|
|
60
|
+
addView(statusView, statusParams);
|
|
61
|
+
|
|
62
|
+
// Try to load player library
|
|
63
|
+
loadPlayerLibrary();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private void loadPlayerLibrary() {
|
|
67
|
+
try {
|
|
68
|
+
System.loadLibrary("OKSMARTPLAY");
|
|
69
|
+
playerLibLoaded = true;
|
|
70
|
+
Log.d(TAG, "Player library loaded successfully");
|
|
71
|
+
|
|
72
|
+
// Try to find player class via reflection
|
|
73
|
+
try {
|
|
74
|
+
appPlayerClass = Class.forName("com.vstarcam.player.AppPlayer");
|
|
75
|
+
Log.d(TAG, "AppPlayer class found");
|
|
76
|
+
} catch (ClassNotFoundException e) {
|
|
77
|
+
// Try alternative class names
|
|
78
|
+
try {
|
|
79
|
+
appPlayerClass = Class.forName("com.vstarcam.AppPlayer");
|
|
80
|
+
Log.d(TAG, "AppPlayer class found (alt path)");
|
|
81
|
+
} catch (ClassNotFoundException e2) {
|
|
82
|
+
Log.w(TAG, "AppPlayer class not found, using native methods directly");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
} catch (UnsatisfiedLinkError e) {
|
|
86
|
+
Log.e(TAG, "Failed to load player library: " + e.getMessage());
|
|
87
|
+
playerLibLoaded = false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Set the client pointer for video streaming
|
|
93
|
+
*/
|
|
94
|
+
public void setClientPtr(long ptr) {
|
|
95
|
+
this.clientPtr = ptr;
|
|
96
|
+
Log.d(TAG, "Client pointer set: " + ptr);
|
|
97
|
+
|
|
98
|
+
if (clientPtr != 0) {
|
|
99
|
+
statusView.setText("Ready to stream");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Set video resolution (1=high, 2=general, 4=low, 100=superHD)
|
|
105
|
+
*/
|
|
106
|
+
public void setResolution(int res) {
|
|
107
|
+
this.resolution = res;
|
|
108
|
+
Log.d(TAG, "Resolution set: " + res);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Start video streaming
|
|
113
|
+
*/
|
|
114
|
+
public void startStream() {
|
|
115
|
+
if (clientPtr == 0) {
|
|
116
|
+
Log.e(TAG, "Cannot start stream: no client pointer");
|
|
117
|
+
statusView.setText("No connection");
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!playerLibLoaded) {
|
|
122
|
+
Log.e(TAG, "Cannot start stream: player library not loaded");
|
|
123
|
+
statusView.setText("Player not available");
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
Log.d(TAG, "Starting video stream...");
|
|
128
|
+
statusView.setText("Starting stream...");
|
|
129
|
+
|
|
130
|
+
// The actual streaming is handled by sending CGI command
|
|
131
|
+
// Video frames come through the native player SDK
|
|
132
|
+
isStreaming = true;
|
|
133
|
+
|
|
134
|
+
// Hide status once streaming
|
|
135
|
+
statusView.setVisibility(GONE);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Stop video streaming
|
|
140
|
+
*/
|
|
141
|
+
public void stopStream() {
|
|
142
|
+
if (!isStreaming) return;
|
|
143
|
+
|
|
144
|
+
Log.d(TAG, "Stopping video stream...");
|
|
145
|
+
isStreaming = false;
|
|
146
|
+
statusView.setVisibility(VISIBLE);
|
|
147
|
+
statusView.setText("Stream stopped");
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// TextureView.SurfaceTextureListener implementation
|
|
151
|
+
|
|
152
|
+
@Override
|
|
153
|
+
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
|
154
|
+
Log.d(TAG, "Surface available: " + width + "x" + height);
|
|
155
|
+
// Initialize native player with surface when available
|
|
156
|
+
if (playerLibLoaded && clientPtr != 0) {
|
|
157
|
+
initializePlayer(surface, width, height);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@Override
|
|
162
|
+
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
|
|
163
|
+
Log.d(TAG, "Surface size changed: " + width + "x" + height);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
@Override
|
|
167
|
+
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
|
|
168
|
+
Log.d(TAG, "Surface destroyed");
|
|
169
|
+
stopStream();
|
|
170
|
+
releasePlayer();
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@Override
|
|
175
|
+
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
|
|
176
|
+
// Called when texture is updated with new frame
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private void initializePlayer(SurfaceTexture surface, int width, int height) {
|
|
180
|
+
// Native player initialization will be implemented based on SDK API
|
|
181
|
+
Log.d(TAG, "Initializing player for surface");
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private void releasePlayer() {
|
|
185
|
+
if (playerPtr != 0) {
|
|
186
|
+
// Release native player resources
|
|
187
|
+
playerPtr = 0;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@Override
|
|
192
|
+
protected void onDetachedFromWindow() {
|
|
193
|
+
super.onDetachedFromWindow();
|
|
194
|
+
stopStream();
|
|
195
|
+
releasePlayer();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
package com.reactnativevstarcam;
|
|
2
|
+
|
|
3
|
+
import android.view.View;
|
|
4
|
+
|
|
5
|
+
import androidx.annotation.NonNull;
|
|
6
|
+
import androidx.annotation.Nullable;
|
|
7
|
+
|
|
8
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
9
|
+
import com.facebook.react.common.MapBuilder;
|
|
10
|
+
import com.facebook.react.uimanager.SimpleViewManager;
|
|
11
|
+
import com.facebook.react.uimanager.ThemedReactContext;
|
|
12
|
+
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
13
|
+
|
|
14
|
+
import java.util.Map;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* React Native ViewManager for VStarCamVideoView.
|
|
18
|
+
* Exposes the native video view as a React component.
|
|
19
|
+
*/
|
|
20
|
+
public class VStarCamVideoViewManager extends SimpleViewManager<VStarCamVideoView> {
|
|
21
|
+
public static final String REACT_CLASS = "VStarCamVideoView";
|
|
22
|
+
|
|
23
|
+
// Command IDs for direct commands from JS
|
|
24
|
+
public static final int COMMAND_START_STREAM = 1;
|
|
25
|
+
public static final int COMMAND_STOP_STREAM = 2;
|
|
26
|
+
|
|
27
|
+
@NonNull
|
|
28
|
+
@Override
|
|
29
|
+
public String getName() {
|
|
30
|
+
return REACT_CLASS;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@NonNull
|
|
34
|
+
@Override
|
|
35
|
+
protected VStarCamVideoView createViewInstance(@NonNull ThemedReactContext reactContext) {
|
|
36
|
+
return new VStarCamVideoView(reactContext);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Set the client pointer for the video stream
|
|
41
|
+
*/
|
|
42
|
+
@ReactProp(name = "clientPtr")
|
|
43
|
+
public void setClientPtr(VStarCamVideoView view, double clientPtr) {
|
|
44
|
+
// React Native passes numbers as doubles, convert to long
|
|
45
|
+
view.setClientPtr((long) clientPtr);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Set the video resolution
|
|
50
|
+
* 1 = high, 2 = general/default, 4 = low, 100 = superHD
|
|
51
|
+
*/
|
|
52
|
+
@ReactProp(name = "resolution", defaultInt = 2)
|
|
53
|
+
public void setResolution(VStarCamVideoView view, int resolution) {
|
|
54
|
+
view.setResolution(resolution);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Control streaming via prop
|
|
59
|
+
*/
|
|
60
|
+
@ReactProp(name = "streaming", defaultBoolean = false)
|
|
61
|
+
public void setStreaming(VStarCamVideoView view, boolean streaming) {
|
|
62
|
+
if (streaming) {
|
|
63
|
+
view.startStream();
|
|
64
|
+
} else {
|
|
65
|
+
view.stopStream();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Commands that can be called from JS via dispatchViewManagerCommand
|
|
71
|
+
*/
|
|
72
|
+
@Nullable
|
|
73
|
+
@Override
|
|
74
|
+
public Map<String, Integer> getCommandsMap() {
|
|
75
|
+
return MapBuilder.of(
|
|
76
|
+
"startStream", COMMAND_START_STREAM,
|
|
77
|
+
"stopStream", COMMAND_STOP_STREAM
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@Override
|
|
82
|
+
public void receiveCommand(@NonNull VStarCamVideoView view, String commandId, @Nullable ReadableArray args) {
|
|
83
|
+
switch (commandId) {
|
|
84
|
+
case "startStream":
|
|
85
|
+
view.startStream();
|
|
86
|
+
break;
|
|
87
|
+
case "stopStream":
|
|
88
|
+
view.stopStream();
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Events that can be sent to JS
|
|
95
|
+
*/
|
|
96
|
+
@Nullable
|
|
97
|
+
@Override
|
|
98
|
+
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
|
|
99
|
+
return MapBuilder.<String, Object>builder()
|
|
100
|
+
.put("onStreamStarted", MapBuilder.of("registrationName", "onStreamStarted"))
|
|
101
|
+
.put("onStreamStopped", MapBuilder.of("registrationName", "onStreamStopped"))
|
|
102
|
+
.put("onStreamError", MapBuilder.of("registrationName", "onStreamError"))
|
|
103
|
+
.put("onFrameReceived", MapBuilder.of("registrationName", "onFrameReceived"))
|
|
104
|
+
.build();
|
|
105
|
+
}
|
|
106
|
+
}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -10,7 +10,50 @@
|
|
|
10
10
|
* - Camera settings
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
NativeModules,
|
|
15
|
+
NativeEventEmitter,
|
|
16
|
+
Platform,
|
|
17
|
+
requireNativeComponent,
|
|
18
|
+
ViewStyle,
|
|
19
|
+
} from "react-native";
|
|
20
|
+
import React from "react";
|
|
21
|
+
|
|
22
|
+
// Video View Component
|
|
23
|
+
export interface VStarCamVideoViewProps {
|
|
24
|
+
/** Client pointer from create() call */
|
|
25
|
+
clientPtr: number;
|
|
26
|
+
/** Video resolution: 1=high, 2=general, 4=low, 100=superHD */
|
|
27
|
+
resolution?: 1 | 2 | 4 | 100;
|
|
28
|
+
/** Whether streaming is active */
|
|
29
|
+
streaming?: boolean;
|
|
30
|
+
/** Style for the video view */
|
|
31
|
+
style?: ViewStyle;
|
|
32
|
+
/** Called when stream starts */
|
|
33
|
+
onStreamStarted?: () => void;
|
|
34
|
+
/** Called when stream stops */
|
|
35
|
+
onStreamStopped?: () => void;
|
|
36
|
+
/** Called on stream error */
|
|
37
|
+
onStreamError?: (error: { message: string }) => void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Native video view component for VStarCam camera streaming.
|
|
42
|
+
*
|
|
43
|
+
* Usage:
|
|
44
|
+
* ```tsx
|
|
45
|
+
* <VStarCamVideoView
|
|
46
|
+
* clientPtr={client.clientPtr}
|
|
47
|
+
* resolution={2}
|
|
48
|
+
* streaming={isPlaying}
|
|
49
|
+
* style={{ width: 300, height: 200 }}
|
|
50
|
+
* />
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export const VStarCamVideoView =
|
|
54
|
+
Platform.OS === "android"
|
|
55
|
+
? requireNativeComponent<VStarCamVideoViewProps>("VStarCamVideoView")
|
|
56
|
+
: () => null; // iOS not implemented yet
|
|
14
57
|
|
|
15
58
|
const LINKING_ERROR =
|
|
16
59
|
`The package 'react-native-vstarcam' doesn't seem to be linked. Make sure: \n\n` +
|
package/android/libs/classes.jar
DELETED
|
Binary file
|