@byteplus/react-native-rtc 1.0.5 → 1.0.7-rc.0

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.
@@ -9,6 +9,8 @@ buildscript {
9
9
  }
10
10
  }
11
11
 
12
+ def enableUnionForRTCWithLive = rootProject.ext.has('enableUnionForRTCWithLive') ? rootProject.ext.get('enableUnionForRTCWithLive') : false
13
+
12
14
  def isNewArchitectureEnabled() {
13
15
  return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
14
16
  }
@@ -51,7 +53,7 @@ def getNativeDep() {
51
53
  def parsedJson = new groovy.json.JsonSlurper().parseText(packageJson.text)
52
54
  def isBp = parsedJson.name.startsWith("@byteplus")
53
55
 
54
- def enableUnionForRTCWithLive = rootProject.ext.has('enableUnionForRTCWithLive') ? rootProject.ext.get('enableUnionForRTCWithLive') : false
56
+
55
57
  def rtcVersionToUse
56
58
  if (isBp) {
57
59
  rtcVersionToUse = enableUnionForRTCWithLive ? "3.58.1.20600" : "3.58.1.15100"
@@ -106,6 +108,7 @@ dependencies {
106
108
  implementation "com.facebook.react:react-native:+"
107
109
 
108
110
  implementation "com.volcengine:VolcApiEngine:1.6.2"
111
+ implementation project(':byteplus_react-native-live-push')
109
112
  // implementation project(":hybrid-runtime");
110
113
 
111
114
  // Use the RTC SDK dependency determined by getNativeDep() which can be overridden by customer's app build.gradle.
@@ -118,4 +121,8 @@ dependencies {
118
121
  // byteplus com.bytedanceapi:ttsdk-player_premium:1.42.300.101 com.bytedanceapi:ttsdk-player_standard:1.42.300.101
119
122
  def license_type = getLicenseType()
120
123
  implementation "com.bytedanceapi:ttsdk-player_$license_type:1.+"
124
+
125
+ if (enableUnionForRTCWithLive) {
126
+ api 'com.bytedanceapi:ttsdk-ttlivepush_rtc:1.46.300.2'
127
+ }
121
128
  }
@@ -7,18 +7,31 @@ import android.util.Log;
7
7
 
8
8
  import com.ss.bytertc.engine.RTCVideo;
9
9
  import com.ss.bytertc.engine.VideoEncoderConfig;
10
+ import com.ss.bytertc.engine.data.MirrorType;
11
+ import com.ss.bytertc.engine.live.IPushSingleStreamToCDNObserver;
12
+ import com.ss.bytertc.engine.live.PushSingleStreamParam;
10
13
 
11
14
  public class VertcHelper {
12
15
 
16
+ final public String TAG = "VertcHelper";
13
17
  static public VertcHelper sInstance = new VertcHelper();
14
18
 
15
19
  public static VertcHelper getInstance() {
16
- Log.d("VertcHelper", "channelSolutions" + sInstance);
17
20
  return sInstance;
18
21
  }
19
22
 
20
23
  public int invokeSetVideoEncoderConfig(RTCVideo engine, VideoEncoderConfig[] channelSolutions) {
21
- Log.d("VertcHelper", "channelSolutions");
22
24
  return engine.setVideoEncoderConfig(channelSolutions);
23
25
  }
26
+
27
+ public int invokeSetLocalVideoMirrorType(RTCVideo engine, int mirrorType) {
28
+ return engine.setLocalVideoMirrorType(MirrorType.fromId(mirrorType));
29
+ }
30
+
31
+ public int invokeStartPushSingleStreamToCDN(RTCVideo engine, String taskId, PushSingleStreamParam param) {
32
+ IPushSingleStreamToCDNObserver observer = (eventType, taskId1, error) -> {
33
+ Log.d(TAG, "StartPushSingleStreamToCDN: " + eventType + " " + taskId1 + " " + error);
34
+ };
35
+ return engine.startPushSingleStreamToCDN(taskId, param, observer);
36
+ }
24
37
  }
@@ -3,6 +3,8 @@
3
3
 
4
4
  package com.volcengine.reactnative.vertc;
5
5
 
6
+ import android.util.Log;
7
+
6
8
  import androidx.annotation.Nullable;
7
9
 
8
10
  import com.facebook.react.bridge.Arguments;
@@ -31,6 +31,6 @@ public class VertcView extends FrameLayout {
31
31
  ReactContext reactContext = (ReactContext)getContext();
32
32
  reactContext
33
33
  .getJSModule(RCTEventEmitter.class)
34
- .receiveEvent(getId(), "load", event);
34
+ .receiveEvent(getId(), "vertcLoad", event);
35
35
  }
36
36
  }
@@ -72,7 +72,7 @@ public class VertcViewManager extends SimpleViewManager<VertcView> implements Vo
72
72
 
73
73
  public Map getExportedCustomBubblingEventTypeConstants() {
74
74
  return MapBuilder.builder().put(
75
- "load",
75
+ "vertcLoad",
76
76
  MapBuilder.of(
77
77
  "phasedRegistrationNames",
78
78
  MapBuilder.of("bubbled", "onViewLoad")
@@ -0,0 +1,143 @@
1
+ // Copyright © 2022 BytePlusRTC All rights reserved.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ package com.volcengine.reactnative.vertc.live;
5
+
6
+ import android.util.Log;
7
+
8
+ import com.ss.avframework.live.VeLivePusherDef;
9
+ import com.ss.avframework.live.VeLiveVideoFrame;
10
+ import com.ss.avframework.opengl.RendererCommon;
11
+ import com.ss.bytertc.engine.RTCVideo;
12
+ import com.ss.avframework.live.VeLivePusher;
13
+ import com.ss.bytertc.engine.data.ReturnStatus;
14
+ import com.ss.bytertc.engine.data.StreamIndex;
15
+ import com.ss.bytertc.engine.data.VideoPixelFormat;
16
+ import com.ss.bytertc.engine.data.VideoRotation;
17
+ import com.ss.bytertc.engine.data.VideoSourceType;
18
+ import java.util.concurrent.TimeUnit;
19
+ import com.ss.bytertc.engine.video.builder.GLTextureVideoFrameBuilder;
20
+ import com.volcengine.velive.rn.push.VeLivePushHelper;
21
+
22
+ import javax.annotation.Nonnull;
23
+
24
+ public class VertcLive {
25
+ private String TAG = "VertcLive";
26
+
27
+ private VeLivePusher mLivePusher;
28
+ private VeLivePusherDef.VeLiveVideoFrameListener mListener;
29
+ private org.json.JSONObject mOptions;
30
+ private RTCVideo mEngine;
31
+
32
+ /**
33
+ * @brief Start to capture live stream.
34
+ */
35
+ public int startLiveVideoCapture(RTCVideo engine, String pusherViewId, org.json.JSONObject options) {
36
+ try {
37
+ stopLiveVideoCapture();
38
+
39
+ mEngine = engine;
40
+ mOptions = options;
41
+
42
+ mLivePusher = getVeLivePusher(pusherViewId);
43
+ if (mLivePusher == null) {
44
+ throw new RuntimeException("[Unknown LivePusher] can't find pusher instance by view id.");
45
+ }
46
+
47
+ // set video source as external
48
+ engine.setVideoSourceType(getStreamIndex(), VideoSourceType.VIDEO_SOURCE_TYPE_EXTERNAL);
49
+ // set video frame listener
50
+ mListener = new VeLivePusherDef.VeLiveVideoFrameListener() {
51
+ @Nonnull
52
+ @Override
53
+ public VeLivePusherDef.VeLiveVideoFrameSource getObservedVideoFrameSource() {
54
+ return new VeLivePusherDef.VeLiveVideoFrameSource(VeLivePusherDef.VeLiveVideoFrameSource.VeLiveVideoFrameSourcePreEncode);
55
+ }
56
+
57
+ @Override
58
+ public void onPreEncodeVideoFrame(VeLiveVideoFrame frame) {
59
+ int ret_status = -1;
60
+ StreamIndex streamIndex = getStreamIndex();
61
+
62
+ float[] mMVPMatrix = RendererCommon.convertMatrixFromAndroidGraphicsMatrix(frame.getTextureMatrix());
63
+ GLTextureVideoFrameBuilder builder = new GLTextureVideoFrameBuilder(
64
+ frame.isOesTextureFrame() ? VideoPixelFormat.TEXTURE_OES : VideoPixelFormat.TEXTURE_2D
65
+ )
66
+ .setTextureID(frame.getTextureId())
67
+ .setWidth(frame.getWidth())
68
+ .setHeight(frame.getHeight())
69
+ .setRotation(VideoRotation.VIDEO_ROTATION_0)
70
+ .setTextureMatrix(mMVPMatrix)
71
+ .setEGLContext(VeLivePusher.getEGLContext())
72
+ .setTimeStampUs(System.currentTimeMillis() * TimeUnit.MILLISECONDS.toNanos(1));
73
+
74
+ if (streamIndex == StreamIndex.STREAM_INDEX_MAIN) {
75
+ ret_status = engine.pushExternalVideoFrame(builder.build());
76
+ }
77
+ if (streamIndex == StreamIndex.STREAM_INDEX_SCREEN) {
78
+ ret_status = engine.pushScreenVideoFrame(builder.build());
79
+ }
80
+ boolean result = ret_status == ReturnStatus.RETURN_STATUS_SUCCESS.value()
81
+ || ret_status == ReturnStatus.RETURN_STATUS_VIDEO_TIMESTAMP_WARNING.value();
82
+ if (!result) {
83
+ Log.d(TAG, "Push external frame fail: " + ret_status);
84
+ }
85
+ }
86
+ };
87
+ mLivePusher.addVideoFrameListener(mListener);
88
+
89
+ return 0;
90
+ } catch (Exception err) {
91
+ Log.d(TAG, "startLiveVideoCapture failed:" + err.getMessage());
92
+ throw new RuntimeException(err);
93
+ }
94
+ }
95
+
96
+ /**
97
+ * @brief Stop to capture live stream.
98
+ */
99
+ public int stopLiveVideoCapture() {
100
+ try {
101
+ if (
102
+ mOptions == null ||
103
+ mEngine == null
104
+ ) {
105
+ return 0;
106
+ }
107
+
108
+ // reset sourceType to Internal
109
+ mEngine.setVideoSourceType(getStreamIndex(), VideoSourceType.VIDEO_SOURCE_TYPE_INTERNAL);
110
+
111
+ // release listener
112
+ mLivePusher.removeVideoFrameListener(mListener);
113
+ mListener = null;
114
+ mOptions = null;
115
+ mLivePusher = null;
116
+ mEngine = null;
117
+
118
+ return 0;
119
+ } catch (Exception err) {
120
+ Log.d(TAG, "stopLiveVideoCapture failed:" + err.getMessage());
121
+ throw new RuntimeException(err);
122
+ }
123
+ }
124
+
125
+
126
+ // Get VeLivePusher from Object
127
+ private VeLivePusher getVeLivePusher(String pusherViewId) {
128
+
129
+ if (VeLivePushHelper.getPusher(pusherViewId) != null) {
130
+ return VeLivePushHelper.getPusher(pusherViewId);
131
+ }
132
+
133
+ return null;
134
+ }
135
+
136
+ // Get StreamIndex from options
137
+ private StreamIndex getStreamIndex() {
138
+ Number index = mOptions.optInt("streamIndex", StreamIndex.STREAM_INDEX_MAIN.value());
139
+ StreamIndex streamIndex = StreamIndex.fromId(index.intValue());
140
+ Log.d(TAG, "getStreamIndex:" + streamIndex);
141
+ return streamIndex;
142
+ }
143
+ }
@@ -136,11 +136,6 @@ public class VertcVod {
136
136
  if (arg instanceof TTVideoEngine) {
137
137
  return (TTVideoEngine)arg;
138
138
  }
139
-
140
- Object decoded = VolcApiEnginePool.getInstance().decodeArg(arg, null);
141
- if (decoded instanceof TTVideoEngine) {
142
- return (TTVideoEngine)arg;
143
- }
144
139
 
145
140
  return null;
146
141
  }
@@ -0,0 +1,21 @@
1
+ // Copyright © 2022 BytePlusRTC All rights reserved.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ //
5
+ // Pods
6
+ //
7
+
8
+ #import "RTCHeader.h"
9
+
10
+
11
+ @interface VertcHelper : NSObject
12
+
13
+ + (instancetype) getInstance;
14
+
15
+ - (void)onStreamPushEvent:(ByteRTCSingleStreamPushEvent)event
16
+ taskId:(NSString *_Nonnull)taskID
17
+ error:(NSInteger)errorCode;
18
+
19
+ - (int) invokeStartPushSingleStreamToCDN:(ByteRTCVideo *)rtc taskId:(NSString *_Nonnull)taskID singleStream:(ByteRTCPushSingleStreamParam *_Nonnull)singleStream;
20
+
21
+ @end
@@ -0,0 +1,39 @@
1
+ // Copyright © 2022 BytePlusRTC All rights reserved.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ //
5
+ // react-native-rtc
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+ #import "RTCHeader.h"
10
+ #import <TTSDKFramework/TTSDKFramework.h>
11
+ #import <VertcHelper.h>
12
+
13
+
14
+ #pragma mark - Helper
15
+ @implementation VertcHelper
16
+
17
+ + (instancetype) getInstance {
18
+ static VertcHelper *instance = nil;
19
+ static dispatch_once_t onceToken;
20
+ dispatch_once(&onceToken, ^{
21
+ instance = [[VertcHelper alloc] init];
22
+ });
23
+ return instance;
24
+ }
25
+
26
+ - (void)onStreamPushEvent:(ByteRTCSingleStreamPushEvent)event
27
+ taskId:(NSString *_Nonnull)taskID
28
+ error:(NSInteger)errorCode {
29
+ NSLog(@"startPushSingleStreamToCDN: event=%ld, taskID=%@, error=%ld", (long)event, taskID, (long)errorCode);
30
+ }
31
+
32
+ - (int)invokeStartPushSingleStreamToCDN:(ByteRTCVideo *)rtc taskId:(NSString *_Nonnull)taskID singleStream:(ByteRTCPushSingleStreamParam *_Nonnull)singleStream {
33
+ singleStream.pushType = ByteRTCSingleStreamPushToCDN;
34
+ singleStream.isScreen = singleStream.isScreen || false;
35
+ int res = [rtc startPushSingleStreamToCDN:taskID singleStream:singleStream observer:self];
36
+ return res;
37
+ }
38
+
39
+ @end
@@ -0,0 +1,24 @@
1
+ // Copyright © 2022 BytePlusRTC All rights reserved.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ //
5
+ // VertcLive.h
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+ #import "RTCHeader.h"
10
+ #import <TTSDKFramework/TTSDKFramework.h>
11
+
12
+ @interface VertcLive : NSObject
13
+
14
+ - (int) startLiveVideoCapture:(ByteRTCVideo *)rtc viewId:(NSString *)viewId options:(NSDictionary *)options;
15
+
16
+ - (int) stopLiveVideoCapture;
17
+
18
+ - (VeLiveVideoFrameSource)getObservedVideoFrameSource;
19
+
20
+ - (ByteRTCVideoPixelFormat)convertToRtcPixelFormat:(VeLivePixelFormat)format;
21
+
22
+ - (void)onPreEncodeVideoFrame:(VeLiveVideoFrame *)frame;
23
+
24
+ @end
@@ -0,0 +1,124 @@
1
+ // Copyright © 2022 BytePlusRTC All rights reserved.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ #import "VertcLive.h"
5
+ #import "RTCHeader.h"
6
+ #import <TTSDKFramework/TTSDKFramework.h>
7
+ #import <TTSDKFramework/VeLivePusherDef.h>
8
+ #import "VeLivePushHelper.h"
9
+
10
+
11
+
12
+ @interface VertcLive ()
13
+
14
+ @property (nonatomic, strong) NSDictionary *options;
15
+ @property (nonatomic, strong) ByteRTCVideo *rtcEngine;
16
+ @property (nonatomic, strong) VeLivePusher *livePusher;
17
+ @property (nonatomic, strong) id<VeLiveVideoFrameListener> videoFrameListener;
18
+
19
+ @end
20
+
21
+ @implementation VertcLive
22
+
23
+ - (void)dealloc {
24
+ if (self.livePusher && self.videoFrameListener) {
25
+ [self.livePusher removeVideoFrameListener:self.videoFrameListener];
26
+ }
27
+ self.livePusher = nil;
28
+ self.rtcEngine = nil;
29
+ self.options = nil;
30
+ }
31
+
32
+ - (int)startLiveVideoCapture:(ByteRTCVideo *)rtc viewId:(NSString *)viewId options:(NSDictionary *)options {
33
+
34
+ VeLivePusher *pusher = [VeLivePushHelper getPusher:viewId];
35
+ if (pusher == nil) {
36
+ @throw [NSException exceptionWithName:@"unknown videoEngine" reason:@"can't get pusher" userInfo:@{}];
37
+ }
38
+ self.rtcEngine = rtc;
39
+ self.options = options;
40
+ self.livePusher = pusher;
41
+
42
+ NSInteger streamIndexValue = [options[@"streamIndex"] integerValue] ?: 0;
43
+ ByteRTCStreamIndex streamIndex = (streamIndexValue == 1) ? ByteRTCStreamIndexScreen : ByteRTCStreamIndexMain;
44
+ [rtc setVideoSourceType:ByteRTCVideoSourceTypeExternal WithStreamIndex:streamIndex];
45
+
46
+ int addRes = [self.livePusher addVideoFrameListener:self];
47
+ NSLog(@"addVideoFrameListener result: %d", addRes);
48
+
49
+ return 0;
50
+ }
51
+
52
+ - (int)stopLiveVideoCapture {
53
+ if (self.rtcEngine == nil || self.livePusher == nil) {
54
+ return 0;
55
+ }
56
+ if (self.livePusher && self.videoFrameListener) {
57
+ [self.livePusher removeVideoFrameListener:self.videoFrameListener];
58
+ self.videoFrameListener = nil;
59
+ }
60
+ NSInteger streamIndexValue = [self.options[@"streamIndex"] integerValue] ?: 0;
61
+ ByteRTCStreamIndex streamIndex = (streamIndexValue == 1) ? ByteRTCStreamIndexScreen : ByteRTCStreamIndexMain;
62
+ [self.rtcEngine setVideoSourceType:ByteRTCVideoSourceTypeInternal WithStreamIndex:streamIndex];
63
+
64
+ [self.livePusher removeVideoFrameListener:self];
65
+
66
+ self.options = nil;
67
+ self.rtcEngine = nil;
68
+ self.livePusher = nil;
69
+ return 0;
70
+ }
71
+
72
+ - (VeLiveVideoFrameSource)getObservedVideoFrameSource {
73
+ return VeLiveVideoFrameSourcePreEncode;
74
+ }
75
+
76
+ - (ByteRTCVideoPixelFormat)convertToRtcPixelFormat:(VeLivePixelFormat)format {
77
+ switch (format) {
78
+ case VeLivePixelFormatBGRA32: return ByteRTCVideoPixelFormatBGRA;
79
+ case VeLivePixelFormatNV12: return ByteRTCVideoPixelFormatNV12;
80
+ case VeLivePixelFormatNV21: return ByteRTCVideoPixelFormatNV21;
81
+ case VeLivePixelFormatI420: return ByteRTCVideoPixelFormatI420;
82
+ case VeLivePixelFormat2DTexture: return ByteRTCVideoPixelFormatGLTexture2D;
83
+ case VeLiveVideoBufferTypeUnKnown: return ByteRTCVideoPixelFormatUnknown;
84
+ }
85
+ return ByteRTCVideoPixelFormatUnknown;
86
+ }
87
+
88
+ - (void)onPreEncodeVideoFrame:(VeLiveVideoFrame *)frame {
89
+
90
+ NSInteger streamIndexValue = [self.options[@"streamIndex"] integerValue] ?: 0;
91
+ ByteRTCStreamIndex streamIndex = (streamIndexValue == 1) ? ByteRTCStreamIndexScreen : ByteRTCStreamIndexMain;
92
+
93
+ int res = 0;
94
+ if (streamIndex == ByteRTCStreamIndexMain) {
95
+ ByteRTCVideoPixelFormat pixelFormat = [self convertToRtcPixelFormat:frame.pixelFormat];
96
+ ByteRTCVideoFrame *videoFrame = [[ByteRTCVideoFrame alloc] init];
97
+ videoFrame.width = frame.width;
98
+ videoFrame.height = frame.height;
99
+ videoFrame.format = (int)pixelFormat;
100
+ videoFrame.time = frame.pts;
101
+ // videoFrame.contentType = ByteRTCVideoContentTypeNormalFrame;
102
+ // same enum
103
+ videoFrame.rotation = (ByteRTCVideoRotation)frame.rotation;
104
+
105
+ if (frame.sampleBuffer) {
106
+ videoFrame.textureBuf = CMSampleBufferGetImageBuffer(frame.sampleBuffer);
107
+ videoFrame.time = CMSampleBufferGetPresentationTimeStamp(frame.sampleBuffer);
108
+ }
109
+
110
+ if (frame.pixelBuffer) {
111
+ videoFrame.textureBuf = frame.pixelBuffer;
112
+ }
113
+
114
+ res = [self.rtcEngine pushExternalVideoFrame: videoFrame];
115
+ }
116
+ if (streamIndex == ByteRTCStreamIndexScreen) {
117
+ res = [self.rtcEngine pushScreenVideoFrame:frame.pixelBuffer time:frame.pts rotation:frame.rotation];
118
+ }
119
+ if (res != 0 && res != -202) {
120
+ NSLog(@"bytertc push video frame fail return '%d'", res);
121
+ }
122
+ }
123
+
124
+ @end