Browse Source

添加数据流相关 API

Riant 6 years ago
parent
commit
d8adf86b43
4 changed files with 109 additions and 25 deletions
  1. 12
    2
      README.md
  2. 32
    1
      android/src/main/java/com/syan/agora/AgoraModule.java
  3. 64
    21
      ios/RCTAgora/RCTAgora.m
  4. 1
    1
      package.json

+ 12
- 2
README.md View File

@@ -82,7 +82,7 @@ Add following to `AndroidManifest.xml`
82 82
 
83 83
 | Property                         | Type                                     | Description                           |
84 84
 | -------------------------------- | ---------------------------------------- | ------------------------------------- |
85
-| init                             | object {appid: 'agora注册的应用id', channelProfile: '频道模式', videoProfile: '视频模式', clientRole: '角色', swapWidthAndHeight: 'bool值'} | 初始化Agora引擎                            |
85
+| init                             | object {appid: 'agora注册的应用id', channelProfile: '频道模式', videoProfile: '视频模式', clientRole: '角色', swapWidthAndHeight: 'bool值', reliable: 'bool值 - 默认数据流通道创建参数,参考 createDataStream', ordered: 'bool值 - 默认数据流通道创建参数,参考 createDataStream'} | 初始化Agora引擎                            |
86 86
 | joinChannel                      | string channelName (房间名称)   number uid (用户设置的uid 传0系统会自动分配) | 加入房间                                  |
87 87
 | leaveChannel                     |                                          | 离开频道                                  |
88 88
 | destroy                          |                                          | 销毁引擎实例                                |
@@ -109,6 +109,8 @@ Add following to `AndroidManifest.xml`
109 109
 | startRecordingService (iOS only) | string  recordingKey                     | 启动服务端录制服务                             |
110 110
 | stopRecordingService (iOS only)  | string  recordingKey                     | 停止服务端录制服务                             |
111 111
 | getSdkVersion                    | callback                                 | 获取版本号                                 |
112
+| createDataStream | (boolean reliable, boolean ordered, (streamId) => {}), 其中 reliable, ordered 请参考官方文档同名方法说明 | 创建数据流通道 |
113
+| sendStreamMessage | (number streamId, string message, (errorCode) => {})| 发送数据 |
112 114
 
113 115
 ##### 原生通知事件
114 116
 
@@ -121,7 +123,8 @@ RtcEngine.eventEmitter({
121 123
   onError: data => {},
122 124
   onWarning: data => {},
123 125
   onLeaveChannel: data => {},
124
-  onAudioVolumeIndication: data => {}
126
+  onAudioVolumeIndication: data => {},
127
+  onStreamMessage: ({uid, streamId, data}) => {}
125 128
 })
126 129
 ```
127 130
 
@@ -135,6 +138,7 @@ RtcEngine.eventEmitter({
135 138
 | onWarning                 | 警告           |
136 139
 | onLeaveChannel            | 退出频道         |
137 140
 | onAudioVolumeIndication            | 音量提示回调         |
141
+| onStreamMessage | 接收到对方数据流消息的回调 |
138 142
 
139 143
 
140 144
 ##### AgoraView 组件
@@ -158,6 +162,12 @@ RtcEngine.eventEmitter({
158 162
 
159 163
 ## 更新信息
160 164
 
165
+#### 1.1.1
166
+
167
+- 新增方法 创建数据流通道 createDataStream
168
+- 新增方法 发送数据流 sendStreamMessage
169
+- 新增监听数据流事件 onStreamMessage
170
+
161 171
 #### 1.0.9
162 172
 
163 173
 - 更新Agora SDK 为 2.0.2

+ 32
- 1
android/src/main/java/com/syan/agora/AgoraModule.java View File

@@ -21,6 +21,7 @@ import io.agora.rtc.RtcEngine;
21 21
 import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread;
22 22
 
23 23
 public class AgoraModule extends ReactContextBaseJavaModule {
24
+    private int defaultStreamId = -1;
24 25
 
25 26
     public AgoraModule(ReactApplicationContext context) {
26 27
 
@@ -91,6 +92,23 @@ public class AgoraModule extends ReactContextBaseJavaModule {
91 92
 
92 93
         }
93 94
 
95
+        // 接收到对方数据流消息的回调
96
+        @Override
97
+        public void onStreamMessage(final int uid, final int streamId, final byte[] data) {
98
+            runOnUiThread(new Runnable() {
99
+                @Override
100
+                public void run() {
101
+                    String msg = new String(data);
102
+                    WritableMap map = Arguments.createMap();
103
+                    map.putString("type", "onStreamMessage");
104
+                    map.putInt("uid", uid);
105
+                    map.putInt("streamId", streamId);
106
+                    map.putString("data", msg);
107
+                    commonEvent(map);
108
+                }
109
+            });
110
+        }
111
+
94 112
         /**
95 113
          * 说话声音音量提示回调
96 114
          */
@@ -188,6 +206,7 @@ public class AgoraModule extends ReactContextBaseJavaModule {
188 206
     @ReactMethod
189 207
     public void init(ReadableMap options) {
190 208
         AgoraManager.getInstance().init(getReactApplicationContext(), mRtcEventHandler, options);
209
+        this.defaultStreamId = AgoraManager.getInstance().mRtcEngine.createDataStream(options.getBoolean("reliable"), options.getBoolean("ordered"));
191 210
     }
192 211
 
193 212
     //进入房间
@@ -347,6 +366,18 @@ public class AgoraModule extends ReactContextBaseJavaModule {
347 366
         AgoraManager.getInstance().mRtcEngine.setDefaultAudioRoutetoSpeakerphone(defaultToSpeaker);
348 367
     }
349 368
 
369
+    // 建立数据通道
370
+    @ReactMethod
371
+    public void createDataStream(boolean reliable, boolean ordered, Callback callback) {
372
+        callback.invoke(AgoraManager.getInstance().mRtcEngine.createDataStream(reliable, ordered));
373
+    }
374
+
375
+    // 发送数据
376
+    @ReactMethod
377
+    public void sendStreamMessage(int streamId, String message, Callback onError) {
378
+        onError.invoke(AgoraManager.getInstance().mRtcEngine.sendStreamMessage(streamId > 0 ? streamId : this.defaultStreamId, message.getBytes()));
379
+    }
380
+
350 381
     //销毁引擎实例
351 382
     @ReactMethod
352 383
     public void destroy() {
@@ -371,4 +402,4 @@ public class AgoraModule extends ReactContextBaseJavaModule {
371 402
                 .emit(eventName, params);
372 403
     }
373 404
 
374
-}
405
+}

+ 64
- 21
ios/RCTAgora/RCTAgora.m View File

@@ -47,13 +47,13 @@ RCT_EXPORT_MODULE();
47 47
  *  @return 0 when executed successfully. return negative value if failed.
48 48
  */
49 49
 RCT_EXPORT_METHOD(init:(NSDictionary *)options) {
50
-    
50
+
51 51
     [AgoraConst share].appid = options[@"appid"];
52
-    
52
+
53 53
     self.rtcEngine = [AgoraRtcEngineKit sharedEngineWithAppId:options[@"appid"] delegate:self];
54
-    
54
+
55 55
     [AgoraConst share].rtcEngine = self.rtcEngine;
56
-    
56
+
57 57
     //频道模式
58 58
     [self.rtcEngine setChannelProfile:[options[@"channelProfile"] integerValue]];
59 59
     //启用双流模式
@@ -61,10 +61,10 @@ RCT_EXPORT_METHOD(init:(NSDictionary *)options) {
61 61
     [self.rtcEngine enableVideo];
62 62
     [self.rtcEngine setVideoProfile:[options[@"videoProfile"] integerValue]swapWidthAndHeight:[options[@"swapWidthAndHeight"]boolValue]];
63 63
     [self.rtcEngine setClientRole:[options[@"clientRole"] integerValue] withKey:nil];
64
-    
64
+
65 65
     //Agora Native SDK 与 Agora Web SDK 间的互通
66 66
     [self.rtcEngine enableWebSdkInteroperability:YES];
67
-    
67
+
68 68
 }
69 69
 
70 70
 //加入房间
@@ -79,7 +79,7 @@ RCT_EXPORT_METHOD(leaveChannel){
79 79
     [self.rtcEngine leaveChannel:^(AgoraRtcStats *stat) {
80 80
         NSMutableDictionary *params = @{}.mutableCopy;
81 81
         params[@"type"] = @"onLeaveChannel";
82
-        
82
+
83 83
         [self sendEvent:params];
84 84
     }];
85 85
 }
@@ -117,7 +117,7 @@ RCT_EXPORT_METHOD(startPreview){
117 117
 //主播必须在加入频道前调用本章 API
118 118
 RCT_EXPORT_METHOD(configPublisher:(NSDictionary *)config){
119 119
     AgoraPublisherConfiguration *apc = [AgoraPublisherConfiguration new];
120
-    
120
+
121 121
     apc.width = [config[@"width"] integerValue];  //旁路直播的输出码流的宽度
122 122
     apc.height = [config[@"height"] integerValue]; //旁路直播的输出码流的高度
123 123
     apc.framerate = [config[@"framerate"] integerValue]; //旁路直播的输出码率帧率
@@ -128,7 +128,7 @@ RCT_EXPORT_METHOD(configPublisher:(NSDictionary *)config){
128 128
     apc.rawStreamUrl = config[@"rawStreamUrl"]; //单流地址
129 129
     apc.extraInfo = config[@"extraInfo"]; //其他信息
130 130
     apc.owner = [config[@"owner"] boolValue]; //是否将当前主播设为该 RTMP 流的主人
131
-  
131
+
132 132
     [self.rtcEngine configPublisher:apc];
133 133
 }
134 134
 
@@ -237,6 +237,23 @@ RCT_EXPORT_METHOD(stopRecordingService:(NSString*)recordingKey){
237 237
     [self.rtcEngine stopRecordingService:recordingKey];
238 238
 }
239 239
 
240
+/*
241
+创建数据流
242
+*/
243
+RCT_EXPORT_METHOD(createDataStream:(BOOL)reliable ordered:(BOOL)ordered callback:(RCTResponseSenderBlock)callback){
244
+  NSInteger streamId = 0;
245
+  [self.rtcEngine createDataStream:&streamId reliable:reliable ordered:ordered];
246
+  callback(@[[NSNumber numberWithInteger:streamId]]);
247
+}
248
+
249
+/*
250
+发送数据流
251
+*/
252
+RCT_EXPORT_METHOD(sendStreamMessage:(NSInteger)streamId data:(NSData*)data callback:(RCTResponseSenderBlock)callback){
253
+  int err = [self.rtcEngine sendStreamMessage:(streamId > 0 ? streamId : defaultDataStreamId) data:data];
254
+  callback(@[[NSNumber numberWithInteger:err]]);
255
+}
256
+
240 257
 //获取版本号
241 258
 RCT_EXPORT_METHOD(getSdkVersion:(RCTResponseSenderBlock)callback){
242 259
     callback(@[[AgoraRtcEngineKit getSdkVersion]]);
@@ -252,7 +269,7 @@ RCT_EXPORT_METHOD(getSdkVersion:(RCTResponseSenderBlock)callback){
252 269
     NSMutableDictionary *params = @{}.mutableCopy;
253 270
     params[@"type"] = @"onError";
254 271
     params[@"err"] = [NSNumber numberWithInteger:errorCode];;
255
-    
272
+
256 273
     [self sendEvent:params];
257 274
 }
258 275
 
@@ -263,7 +280,7 @@ RCT_EXPORT_METHOD(getSdkVersion:(RCTResponseSenderBlock)callback){
263 280
     NSMutableDictionary *params = @{}.mutableCopy;
264 281
     params[@"type"] = @"onWarning";
265 282
     params[@"err"] = [NSNumber numberWithInteger:warningCode];;
266
-    
283
+
267 284
     [self sendEvent:params];
268 285
 }
269 286
 
@@ -277,7 +294,7 @@ RCT_EXPORT_METHOD(getSdkVersion:(RCTResponseSenderBlock)callback){
277 294
     params[@"type"] = @"onJoinChannelSuccess";
278 295
     params[@"uid"] = [NSNumber numberWithInteger:uid];
279 296
     params[@"channel"] = channel;
280
-    
297
+
281 298
     [self sendEvent:params];
282 299
 }
283 300
 
@@ -285,11 +302,11 @@ RCT_EXPORT_METHOD(getSdkVersion:(RCTResponseSenderBlock)callback){
285 302
  远端首帧视频接收解码回调
286 303
  */
287 304
 - (void)rtcEngine:(AgoraRtcEngineKit *)engine firstRemoteVideoDecodedOfUid:(NSUInteger)uid size:(CGSize)size elapsed:(NSInteger)elapsed {
288
-    
305
+
289 306
     NSMutableDictionary *params = @{}.mutableCopy;
290 307
     params[@"type"] = @"onFirstRemoteVideoDecoded";
291 308
     params[@"uid"] = [NSNumber numberWithInteger:uid];
292
-    
309
+
293 310
     [self sendEvent:params];
294 311
 
295 312
 }
@@ -301,7 +318,7 @@ RCT_EXPORT_METHOD(getSdkVersion:(RCTResponseSenderBlock)callback){
301 318
     NSMutableDictionary *params = @{}.mutableCopy;
302 319
     params[@"type"] = @"onUserJoined";
303 320
     params[@"uid"] = [NSNumber numberWithInteger:uid];
304
-    
321
+
305 322
     [self sendEvent:params];
306 323
 }
307 324
 
@@ -312,7 +329,7 @@ RCT_EXPORT_METHOD(getSdkVersion:(RCTResponseSenderBlock)callback){
312 329
     NSMutableDictionary *params = @{}.mutableCopy;
313 330
     params[@"type"] = @"onUserOffline";
314 331
     params[@"uid"] = [NSNumber numberWithInteger:uid];
315
-    
332
+
316 333
     [self sendEvent:params];
317 334
 }
318 335
 
@@ -323,18 +340,44 @@ RCT_EXPORT_METHOD(getSdkVersion:(RCTResponseSenderBlock)callback){
323 340
 - (void)rtcEngine:(AgoraRtcEngineKit *)engine reportAudioVolumeIndicationOfSpeakers:(NSArray*)speakers totalVolume:(NSInteger)totalVolume {
324 341
     NSMutableDictionary *params = @{}.mutableCopy;
325 342
     params[@"type"] = @"onAudioVolumeIndication";
326
-    
343
+
327 344
     NSMutableArray *arr = [NSMutableArray array];
328 345
     for (AgoraRtcAudioVolumeInfo *obj in speakers) {
329 346
         [arr addObject:@{@"uid":[NSNumber numberWithInteger:obj.uid], @"volume":[NSNumber numberWithInteger:obj.volume]}];
330 347
     }
331
-    
348
+
332 349
     params[@"speakers"] = arr;
333 350
     params[@"totalVolume"] = [NSNumber numberWithInteger:totalVolume];
334
-    
351
+
335 352
     [self sendEvent:params];
336 353
 }
337 354
 
355
+/*
356
+接受数据流
357
+*/
358
+
359
+- (void)rtcEngine:(AgoraRtcEngineKit * _Nonnull)engine receiveStreamMessageFromUid:(NSUInteger)uid streamId:(NSInteger)streamId data:(NSData * _Nonnull)data{
360
+  NSMutableDictionary *params = @{}.mutableCopy;
361
+  params[@"type"] = @"onStreamMessage";
362
+  params[@"uid"] = [NSNumber numberWithInteger:uid];
363
+  params[@"streamId"] = [NSNumber numberWithInteger:streamId];
364
+  params[@"data"] = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
365
+
366
+  [self sendEvent:params];
367
+}
368
+
369
+- (void)rtcEngine:(AgoraRtcEngineKit *)engine didOccurStreamMessageErrorFromUid:(NSUInteger)uid streamId:(NSInteger)streamId error:(NSInteger)error missed:(NSInteger)missed cached:(NSInteger)cached{
370
+  NSMutableDictionary *params = @{}.mutableCopy;
371
+  params[@"type"] = @"onStreamMessageError";
372
+  params[@"uid"] = [NSNumber numberWithInteger:uid];
373
+  params[@"streamId"] = [NSNumber numberWithInteger:streamId];
374
+  params[@"error"] = [NSNumber numberWithInteger:error];
375
+  params[@"missed"] = [NSNumber numberWithInteger:missed];
376
+  params[@"cached"] = [NSNumber numberWithInteger:cached];
377
+
378
+  [self sendEvent:params];
379
+}
380
+
338 381
 - (void)sendEvent:(NSDictionary *)params {
339 382
     [_bridge.eventDispatcher sendDeviceEventWithName:@"agoraEvent" body:params];
340 383
 }
@@ -344,10 +387,10 @@ RCT_EXPORT_METHOD(getSdkVersion:(RCTResponseSenderBlock)callback){
344 387
 }
345 388
 
346 389
 //RCT_EXPORT_METHOD(getViewWithTag:(nonnull NSNumber *)reactTag) {
347
-//    
390
+//
348 391
 //    UIView *view = [self.bridge.uiManager viewForReactTag:reactTag];
349 392
 //    NSLog(@"%@",view);
350
-//    
393
+//
351 394
 //}
352 395
 
353 396
 @end

+ 1
- 1
package.json View File

@@ -1,6 +1,6 @@
1 1
 {
2 2
   "name": "react-native-agora",
3
-  "version": "1.1.0",
3
+  "version": "1.1.1",
4 4
   "description": "声网Agora",
5 5
   "main": "index.js",
6 6
   "scripts": {