@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.
- package/android/build.gradle +8 -1
- package/android/src/main/java/com/volcengine/reactnative/vertc/VertcHelper.java +15 -2
- package/android/src/main/java/com/volcengine/reactnative/vertc/VertcModule.java +2 -0
- package/android/src/main/java/com/volcengine/reactnative/vertc/VertcView.java +1 -1
- package/android/src/main/java/com/volcengine/reactnative/vertc/VertcViewManager.java +1 -1
- package/android/src/main/java/com/volcengine/reactnative/vertc/live/VertcLive.java +143 -0
- package/android/src/main/java/com/volcengine/reactnative/vertc/vod/VertcVod.java +0 -5
- package/ios/VertcHelper.h +21 -0
- package/ios/VertcHelper.m +39 -0
- package/ios/live/VertcLive.h +24 -0
- package/ios/live/VertcLive.m +124 -0
- package/lib/commonjs/index.js +423 -16
- package/lib/module/index.js +423 -17
- package/lib/typescript/codegen/pack/api.d.ts +13 -0
- package/lib/typescript/core/callback.d.ts +1 -1
- package/lib/typescript/core/rtc-video.d.ts +33 -1
- package/lib/typescript/core.d.ts +0 -4
- package/lib/typescript/interface.d.ts +205 -3
- package/lib/typescript/platforms/android/live.d.ts +8 -0
- package/lib/typescript/platforms/android/vertc.d.ts +4 -1
- package/lib/typescript/platforms/ios/live.d.ts +9 -0
- package/lib/typescript/platforms/ios/vertc.d.ts +10 -0
- package/package.json +1 -1
- package/react-native-rtc.podspec +5 -2
package/android/build.gradle
CHANGED
|
@@ -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
|
-
|
|
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
|
}
|
|
@@ -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
|
-
"
|
|
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
|