@byteplus/react-native-rtc 1.0.6 → 1.1.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.
Files changed (38) hide show
  1. package/README.md +0 -316
  2. package/android/build.gradle +58 -43
  3. package/android/src/live/java/com/volcengine/reactnative/vertc/live/VertcLive.java +143 -0
  4. package/android/src/main/java/com/volcengine/reactnative/vertc/VertcHelper.java +10 -0
  5. package/android/src/main/java/com/volcengine/reactnative/vertc/VertcModule.java +2 -0
  6. package/android/src/main/java/com/volcengine/reactnative/vertc/VertcView.java +1 -1
  7. package/android/src/main/java/com/volcengine/reactnative/vertc/VertcViewManager.java +1 -1
  8. package/ios/core/VertcHelper.h +21 -0
  9. package/ios/core/VertcHelper.m +42 -0
  10. package/ios/live/VertcLive.h +24 -0
  11. package/ios/live/VertcLive.m +124 -0
  12. package/lib/commonjs/index.js +206 -11
  13. package/lib/module/index.js +206 -11
  14. package/lib/typescript/core/callback.d.ts +1 -1
  15. package/lib/typescript/core/rtc-video.d.ts +33 -1
  16. package/lib/typescript/core.d.ts +0 -4
  17. package/lib/typescript/interface.d.ts +53 -1
  18. package/lib/typescript/platforms/android/live.d.ts +8 -0
  19. package/lib/typescript/platforms/android/vertc.d.ts +2 -0
  20. package/lib/typescript/platforms/ios/live.d.ts +9 -0
  21. package/lib/typescript/platforms/ios/vertc.d.ts +10 -0
  22. package/package.json +1 -1
  23. package/react-native-rtc.podspec +44 -27
  24. /package/android/src/{main → vod}/java/com/volcengine/reactnative/vertc/vod/OESTextureProcessor.java +0 -0
  25. /package/android/src/{main → vod}/java/com/volcengine/reactnative/vertc/vod/VertcVod.java +0 -0
  26. /package/android/src/{main → vod}/java/com/volcengine/reactnative/vertc/vod/VideoAudioProcessor.java +0 -0
  27. /package/android/src/{main → vod}/java/com/volcengine/reactnative/vertc/vod/VodAudioProcessor.java +0 -0
  28. /package/android/src/{main → vod}/java/com/volcengine/reactnative/vertc/vod/VodMock.java +0 -0
  29. /package/android/src/{main → vod}/java/com/volcengine/reactnative/vertc/vod/VodVideoEngineCallbackProxy.java +0 -0
  30. /package/ios/{RTCHeader.h → core/RTCHeader.h} +0 -0
  31. /package/ios/{RTCHeader.m → core/RTCHeader.m} +0 -0
  32. /package/ios/{VertcApiEngine.h → core/VertcApiEngine.h} +0 -0
  33. /package/ios/{VertcApiEngine.m → core/VertcApiEngine.m} +0 -0
  34. /package/ios/{VertcModule.h → core/VertcModule.h} +0 -0
  35. /package/ios/{VertcModule.m → core/VertcModule.m} +0 -0
  36. /package/ios/{VertcView.h → core/VertcView.h} +0 -0
  37. /package/ios/{VertcView.m → core/VertcView.m} +0 -0
  38. /package/ios/{VertcViewManager.m → core/VertcViewManager.m} +0 -0
package/README.md CHANGED
@@ -138,12 +138,6 @@ const Login = () => {
138
138
  extras: {
139
139
  source_language: room.language,
140
140
  },
141
- roomConfigs: {
142
- profile: room.roomMode,
143
- isAutoPublish: room.autoPublish,
144
- isAutoSubscribeAudio: room.autoSubscribeAudio,
145
- isAutoSubscribeVideo: room.autoSubscribeVideo,
146
- },
147
141
  });
148
142
 
149
143
  /** Capture local streams */
@@ -171,316 +165,6 @@ const Login = () => {
171
165
 
172
166
  export default Login;
173
167
  ```
174
-
175
- ## On-Demand Video with Real-Time Guest Interaction Example
176
-
177
- **We recommend using the latest RTC React Native SDK version in combination with react-native-vod-player SDK v1.2.4.**
178
-
179
-
180
- ### RTC Core Definition
181
- `@/core/index.ts`
182
-
183
- Based on the rtc core definition in `Basic Example`, add some apis:
184
- ```typescript
185
- ...
186
- import type { TTVideoEngine } from '@byteplus/react-native-vod-player';
187
-
188
- class RTCClient {
189
-
190
- ...
191
-
192
- /**
193
- * @brief Start to observe vod player, capture frames from vod player and set stream for external screen stream.
194
- */
195
- startVodPlayerCapture(player: TTVideoEngine) {
196
- return this.engine?.startVodPlayerCapture(player);
197
- }
198
-
199
- /**
200
- * @brief Stop all vod player observer in rtc.
201
- * @note Once you invoke this api, you should invoke `startVodPlayerCapture` to observe vod player.
202
- */
203
- stopVodPlayerCapture(player: TTVideoEngine) {
204
- return this.engine?.stopVodPlayerCapture(player);
205
- }
206
- }
207
- ```
208
- ### Main logic page in react-native
209
- `@/page/vodRtc.ts`
210
-
211
- ```typescript
212
- import React, {useEffect, useRef, useState} from 'react';
213
- import fs from 'react-native-fs';
214
- import {Platform, SafeAreaView, ScrollView} from 'react-native';
215
- import {Button, Input, Text, Toast, View} from '@ant-design/react-native';
216
- import {
217
- NativeViewComponent,
218
- StreamIndex,
219
- RenderMode,
220
- MediaStreamType,
221
- LocalLogLevel,
222
- } from '@byteplus/react-native-rtc';
223
- import {
224
- createDirectUrlSource,
225
- type TTVideoEngine,
226
- } from '@byteplus/react-native-vod-player';
227
- import {
228
- launchImageLibrary,
229
- type ImagePickerResponse,
230
- } from 'react-native-image-picker';
231
- import RTCClient from '@/core';
232
- import { createVeplayer } from '@/core/veplayer';
233
- import RowItem from '@/components/RowItem';
234
- import {GlobalStyles} from '@/style';
235
-
236
- const viewId = 'my-view';
237
-
238
- const auth = {
239
- appId: 'Your RTC AppID',
240
- roomId: 'Your Room ID',
241
- userId: 'Your User ID',
242
- token: 'Your RTC Token',
243
- };
244
-
245
- const Page = () => {
246
- const [isViewLoaded, setViewLoaded] = useState<boolean>(false);
247
- const [filepath, setFilepath] = useState('');
248
- const hasCaptureRef = useRef(false);
249
- const playerRef = useRef<TTVideoEngine>();
250
-
251
- const handleViewLoad = () => {
252
- setViewLoaded(true);
253
- };
254
-
255
- const handleSelectVideoFile = async () => {
256
- try {
257
- const callback = (response: ImagePickerResponse) => {
258
- if (!response.didCancel && !response.errorCode) {
259
- const filePath = response.assets?.[0]?.uri;
260
- if (filePath) {
261
- setFilepath(filePath);
262
- }
263
- }
264
- };
265
- launchImageLibrary(
266
- {
267
- mediaType: 'video',
268
- },
269
- callback,
270
- );
271
- } catch {
272
- Toast.fail('Select media file failed.');
273
- }
274
- };
275
-
276
- const handlePublish = () => {
277
- RTCClient.publishScreen(MediaStreamType.RTC_MEDIA_STREAM_TYPE_BOTH);
278
- };
279
-
280
- const setVideoSource = () => {
281
- const source = filepath
282
- ? createDirectUrlSource({
283
- url: filepath,
284
- cacheKey: filepath,
285
- })
286
- : createDirectUrlSource({
287
- url: 'Your media url, like https://xxxx.mp4',
288
- cacheKey: 'remote',
289
- vid: 'remote',
290
- });
291
- playerRef.current!.setVideoSource(source);
292
- };
293
-
294
- const handlePlay = async () => {
295
- if (hasCaptureRef.current) {
296
- playerRef.current!.play();
297
- return;
298
- }
299
- if (!playerRef.current) {
300
- return;
301
- }
302
- setVideoSource();
303
- await RTCClient.startVodPlayerCapture(playerRef.current);
304
- await playerRef.current!.play();
305
-
306
- RTCClient.publishScreen(MediaStreamType.RTC_MEDIA_STREAM_TYPE_BOTH);
307
-
308
- hasCaptureRef.current = true;
309
- };
310
-
311
- const handleStop = async () => {
312
- if (hasCaptureRef.current) {
313
- playerRef.current!.pause();
314
- }
315
- }
316
-
317
- const handleDestroy = async () => {
318
- if (!playerRef.current) {
319
- return;
320
- }
321
- await RTCClient.stopVodPlayerCapture(playerRef.current);
322
- hasCaptureRef.current = false;
323
- }
324
-
325
- const initializePlayer = async () => {
326
- /**
327
- * @brief It's not necessary to set viewId for vod player.
328
- * @note You should realize veplayer for youself, refer to @byteplus/react-native-vod-player SDK.
329
- */
330
- playerRef.current = await createVeplayer({ viewId: '' });
331
- playerRef.current.setListener({
332
- onLoadStateChanged(engine, loadState) {
333
- console.log('onLoadStateChanged: ', loadState);
334
- },
335
- onError(message, code) {
336
- console.error('onError: ', message, code);
337
- },
338
- onPlaybackStateChanged(engine, playbackState) {
339
- console.log('onPlaybackStateChanged: ', playbackState);
340
- },
341
- });
342
- };
343
-
344
- const initializeRTC = async () => {
345
- /** Init your engine */
346
- let DefaultPath = fs.ExternalDirectoryPath;
347
- if (Platform.OS === 'ios') {
348
- DefaultPath = fs.DocumentDirectoryPath;
349
- }
350
-
351
- /** Set log */
352
- RTCClient.setLogConfig({
353
- logLevel: LocalLogLevel.INFO,
354
- logPath: DefaultPath,
355
- logFileSize: 10,
356
- logFilenamePrefix: '',
357
- });
358
-
359
- /** Create RTC Engine */
360
- await RTCClient.createEngine({
361
- appID: auth.appId,
362
- parameters: {},
363
- });
364
-
365
- /** Set Local video canvas for player */
366
- RTCClient.setLocalVideoCanvas(StreamIndex.STREAM_INDEX_SCREEN, {
367
- viewId,
368
- renderMode: RenderMode.ByteRTCRenderModeFit,
369
- });
370
-
371
- /** Join room */
372
- RTCClient.createRoom(auth.roomId);
373
- RTCClient.setRTCRoomEventHandler({
374
- onUserJoined(userInfo, elapsed) {
375
- console.log('onUserJoined: ', userInfo, elapsed);
376
- },
377
- });
378
- RTCClient.joinRoom({
379
- token: auth.token,
380
- userId: auth.userId,
381
- roomConfigs: {
382
- profile: 0,
383
- isAutoPublish: true,
384
- isAutoSubscribeAudio: false,
385
- isAutoSubscribeVideo: false,
386
- },
387
- });
388
- };
389
-
390
- useEffect(() => {
391
- if (isViewLoaded) {
392
- initializeRTC();
393
- initializePlayer();
394
- console.log('init success');
395
- }
396
- }, [isViewLoaded]);
397
-
398
- useEffect(() => {
399
- return () => {
400
- RTCClient.engine?.stopVodPlayerCapture(playerRef.current);
401
- }
402
- }, []);
403
-
404
- return (
405
- <SafeAreaView>
406
- <ScrollView
407
- style={{
408
- display: 'flex',
409
- flexDirection: 'column',
410
- width: '100%',
411
- height: '100%',
412
- backgroundColor: 'gray',
413
- }}>
414
- <RowItem
415
- theme="dark"
416
- leftItem="File path"
417
- leftItemStyle={{width: '25%'}}
418
- rightItem={
419
- <Input disabled placeholder="Select media file" value={filepath} />
420
- }
421
- />
422
- <Button
423
- style={{...GlobalStyles.rowBtn, marginBottom: 6}}
424
- onPress={handleSelectVideoFile}>
425
- <Text style={{color: 'gray'}}>Select media file</Text>
426
- </Button>
427
- <Button
428
- style={{...GlobalStyles.rowBtn, marginBottom: 6}}
429
- onPress={() => setFilepath('')}>
430
- <Text style={{color: 'gray'}}>Clear media file</Text>
431
- </Button>
432
- <Button
433
- style={{...GlobalStyles.rowBtn, marginBottom: 6}}
434
- onPress={handlePublish}>
435
- <Text style={{color: 'gray'}}>Push Stream</Text>
436
- </Button>
437
- <Button
438
- style={{...GlobalStyles.rowBtn, marginBottom: 6}}
439
- onPress={handlePlay}>
440
- <Text style={{color: 'gray'}}>Play</Text>
441
- </Button>
442
- <Button
443
- style={{...GlobalStyles.rowBtn, marginBottom: 6}}
444
- onPress={handleStop}>
445
- <Text style={{color: 'gray'}}>Pause</Text>
446
- </Button>
447
- <Button
448
- style={{...GlobalStyles.rowBtn, marginBottom: 6}}
449
- onPress={handleDestroy}>
450
- <Text style={{color: 'gray'}}>Destroy</Text>
451
- </Button>
452
- <View
453
- style={{
454
- flex: 1,
455
- width: '100%',
456
- minHeight: 300,
457
- backgroundColor: '#000',
458
- }}>
459
- <Text>{`${viewId}`}</Text>
460
- <NativeViewComponent
461
- viewId={viewId}
462
- style={{
463
- width: '100%',
464
- height: '100%',
465
- }}
466
- onLoad={handleViewLoad}
467
- kind={
468
- Platform.select({
469
- android: 'SurfaceView',
470
- ios: 'UIView',
471
- })!
472
- }
473
- />
474
- </View>
475
- </ScrollView>
476
- </SafeAreaView>
477
- );
478
- };
479
-
480
- export default Page;
481
- ```
482
-
483
-
484
168
  ## Attention
485
169
  - In Android/iOS scenarios, the screen sharing method is slightly different. For details, please refer to [Android screen sharing](https://docs.byteplus.com/en/docs/byteplus-rtc/docs-124176) and [iOS screen sharing](https://docs.byteplus.com/en/docs/byteplus-rtc/docs-124177).
486
170
  - Not support debug in iOS simulator, using real device instead.
@@ -9,6 +9,35 @@ buildscript {
9
9
  }
10
10
  }
11
11
 
12
+ def getLicenseType() {
13
+ try {
14
+ def packageJson = file("../../../../package.json")
15
+ def parsedJson = new groovy.json.JsonSlurper().parseText(packageJson.text)
16
+ return parsedJson.TTVideoEngine.licenseType
17
+ } catch (e) {
18
+ return "premium"
19
+ }
20
+ }
21
+
22
+ def enableUnionForRTCWithLive = project.findProperty('enableUnionForRTCWithLive') == null ? false : project.findProperty('enableUnionForRTCWithLive').toString().toBoolean()
23
+ def enableUnionForRTCWithVod = project.findProperty('enableUnionForRTCWithVod') == null ? false : project.findProperty('enableUnionForRTCWithVod').toString().toBoolean()
24
+
25
+ def packageJson = file("../package.json")
26
+ def parsedJson = new groovy.json.JsonSlurper().parseText(packageJson.text)
27
+ def isBp = parsedJson.name.startsWith("@byteplus")
28
+
29
+ def license_type = getLicenseType()
30
+
31
+ def rtcVersionToUse
32
+ if (isBp) {
33
+ rtcVersionToUse = enableUnionForRTCWithLive ? "3.58.1.20600" : "3.58.1.15100"
34
+ println "Using BytePlusRTC SDK version : $rtcVersionToUse (union live enabled: $enableUnionForRTCWithLive / union vod enabled: $enableUnionForRTCWithVod)"
35
+ } else {
36
+ rtcVersionToUse = enableUnionForRTCWithLive ? "3.58.1.20700" : "3.58.1.2700"
37
+ println "Using VolcEngineRTC SDK version : $rtcVersionToUse (union build enabled: $enableUnionForRTCWithLive / union vod enabled: $enableUnionForRTCWithVod)"
38
+ }
39
+
40
+
12
41
  def isNewArchitectureEnabled() {
13
42
  return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
14
43
  }
@@ -36,42 +65,16 @@ def supportsNamespace() {
36
65
  return (major == 7 && minor >= 3) || major >= 8
37
66
  }
38
67
 
39
- def getLicenseType() {
40
- try {
41
- def packageJson = file("../../../../package.json")
42
- def parsedJson = new groovy.json.JsonSlurper().parseText(packageJson.text)
43
- return parsedJson.TTVideoEngine.licenseType
44
- } catch (e) {
45
- return "premium"
46
- }
47
- }
48
-
49
- def getNativeDep() {
50
- def packageJson = file("../package.json")
51
- def parsedJson = new groovy.json.JsonSlurper().parseText(packageJson.text)
52
- def isBp = parsedJson.name.startsWith("@byteplus")
53
-
54
- def enableUnionForRTCWithLive = rootProject.ext.has('enableUnionForRTCWithLive') ? rootProject.ext.get('enableUnionForRTCWithLive') : false
55
- def rtcVersionToUse
56
- if (isBp) {
57
- rtcVersionToUse = enableUnionForRTCWithLive ? "3.58.1.20600" : "3.58.1.15100"
58
- println "Using BytePlusRTC SDK version : $rtcVersionToUse (union build enabled: $enableUnionForRTCWithLive)"
59
- return "com.byteplus:BytePlusRTC:$rtcVersionToUse"
68
+ android {
69
+ sourceSets {
70
+ main {
71
+ java.srcDirs = ['src/main/java']
72
+ manifest.srcFile "src/main/AndroidManifestNew.xml"
73
+ }
60
74
  }
61
- rtcVersionToUse = enableUnionForRTCWithLive ? "3.58.1.20700" : "3.58.1.2700"
62
- println "Using VolcEngineRTC SDK version : $rtcVersionToUse (union build enabled: $enableUnionForRTCWithLive)"
63
- return "com.volcengine:VolcEngineRTC:$rtcVersionToUse"
64
- }
65
75
 
66
- android {
67
76
  if (supportsNamespace()) {
68
77
  namespace "com.volcengine.reactnative.vertc"
69
-
70
- sourceSets {
71
- main {
72
- manifest.srcFile "src/main/AndroidManifestNew.xml"
73
- }
74
- }
75
78
  }
76
79
 
77
80
  compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
@@ -99,23 +102,35 @@ android {
99
102
  }
100
103
  }
101
104
 
105
+ def apiVolcEngineVersion = "1.6.2";
106
+
107
+ if (enableUnionForRTCWithLive) {
108
+ android.sourceSets.main.java.srcDirs += 'src/live/java'
109
+ dependencies {
110
+ implementation project(':byteplus_react-native-live-push')
111
+ implementation "com.bytedanceapi:ttsdk-player_$license_type:1.46.300.2"
112
+ }
113
+ }
114
+
115
+ if (enableUnionForRTCWithVod) {
116
+ android.sourceSets.main.java.srcDirs += 'src/vod/java'
117
+ //
118
+ // Might cause rtc api some error, just alpha version.
119
+ //
120
+ apiVolcEngineVersion = '1.5.0'
121
+ dependencies {
122
+ implementation "com.bytedanceapi:ttsdk-player_$license_type:1.46.300.2"
123
+ }
124
+ }
125
+
102
126
  dependencies {
103
127
  // For < 0.71, this will be from the local maven repo
104
128
  // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
105
129
  // noinspection GradleDynamicVersion
106
130
  implementation "com.facebook.react:react-native:+"
107
131
 
108
- implementation "com.volcengine:VolcApiEngine:1.6.2"
109
- // implementation project(":hybrid-runtime");
132
+ implementation "com.volcengine:VolcApiEngine:$apiVolcEngineVersion"
110
133
 
111
134
  // Use the RTC SDK dependency determined by getNativeDep() which can be overridden by customer's app build.gradle.
112
- def rtcDep = getNativeDep()
113
- implementation rtcDep
114
-
115
- // TTVideoEngine
116
- // byteplus and volcengine use different name, different version
117
- // volcengine com.bytedanceapi:ttsdk-player_premium:1.43.1.5 com.bytedanceapi:ttsdk-player_standard:1.43.1.5
118
- // byteplus com.bytedanceapi:ttsdk-player_premium:1.42.300.101 com.bytedanceapi:ttsdk-player_standard:1.42.300.101
119
- def license_type = getLicenseType()
120
- implementation "com.bytedanceapi:ttsdk-player_$license_type:1.+"
135
+ implementation isBp ? "com.byteplus:BytePlusRTC:$rtcVersionToUse" : "com.volcengine:VolcEngineRTC:$rtcVersionToUse"
121
136
  }
@@ -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
+ }
@@ -8,9 +8,12 @@ import android.util.Log;
8
8
  import com.ss.bytertc.engine.RTCVideo;
9
9
  import com.ss.bytertc.engine.VideoEncoderConfig;
10
10
  import com.ss.bytertc.engine.data.MirrorType;
11
+ import com.ss.bytertc.engine.live.IPushSingleStreamToCDNObserver;
12
+ import com.ss.bytertc.engine.live.PushSingleStreamParam;
11
13
 
12
14
  public class VertcHelper {
13
15
 
16
+ final public String TAG = "VertcHelper";
14
17
  static public VertcHelper sInstance = new VertcHelper();
15
18
 
16
19
  public static VertcHelper getInstance() {
@@ -24,4 +27,11 @@ public class VertcHelper {
24
27
  public int invokeSetLocalVideoMirrorType(RTCVideo engine, int mirrorType) {
25
28
  return engine.setLocalVideoMirrorType(MirrorType.fromId(mirrorType));
26
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
+ }
27
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,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