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
 
82
 
83
 | Property                         | Type                                     | Description                           |
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
 | joinChannel                      | string channelName (房间名称)   number uid (用户设置的uid 传0系统会自动分配) | 加入房间                                  |
86
 | joinChannel                      | string channelName (房间名称)   number uid (用户设置的uid 传0系统会自动分配) | 加入房间                                  |
87
 | leaveChannel                     |                                          | 离开频道                                  |
87
 | leaveChannel                     |                                          | 离开频道                                  |
88
 | destroy                          |                                          | 销毁引擎实例                                |
88
 | destroy                          |                                          | 销毁引擎实例                                |
109
 | startRecordingService (iOS only) | string  recordingKey                     | 启动服务端录制服务                             |
109
 | startRecordingService (iOS only) | string  recordingKey                     | 启动服务端录制服务                             |
110
 | stopRecordingService (iOS only)  | string  recordingKey                     | 停止服务端录制服务                             |
110
 | stopRecordingService (iOS only)  | string  recordingKey                     | 停止服务端录制服务                             |
111
 | getSdkVersion                    | callback                                 | 获取版本号                                 |
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
   onError: data => {},
123
   onError: data => {},
122
   onWarning: data => {},
124
   onWarning: data => {},
123
   onLeaveChannel: data => {},
125
   onLeaveChannel: data => {},
124
-  onAudioVolumeIndication: data => {}
126
+  onAudioVolumeIndication: data => {},
127
+  onStreamMessage: ({uid, streamId, data}) => {}
125
 })
128
 })
126
 ```
129
 ```
127
 
130
 
135
 | onWarning                 | 警告           |
138
 | onWarning                 | 警告           |
136
 | onLeaveChannel            | 退出频道         |
139
 | onLeaveChannel            | 退出频道         |
137
 | onAudioVolumeIndication            | 音量提示回调         |
140
 | onAudioVolumeIndication            | 音量提示回调         |
141
+| onStreamMessage | 接收到对方数据流消息的回调 |
138
 
142
 
139
 
143
 
140
 ##### AgoraView 组件
144
 ##### AgoraView 组件
158
 
162
 
159
 ## 更新信息
163
 ## 更新信息
160
 
164
 
165
+#### 1.1.1
166
+
167
+- 新增方法 创建数据流通道 createDataStream
168
+- 新增方法 发送数据流 sendStreamMessage
169
+- 新增监听数据流事件 onStreamMessage
170
+
161
 #### 1.0.9
171
 #### 1.0.9
162
 
172
 
163
 - 更新Agora SDK 为 2.0.2
173
 - 更新Agora SDK 为 2.0.2

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

21
 import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread;
21
 import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread;
22
 
22
 
23
 public class AgoraModule extends ReactContextBaseJavaModule {
23
 public class AgoraModule extends ReactContextBaseJavaModule {
24
+    private int defaultStreamId = -1;
24
 
25
 
25
     public AgoraModule(ReactApplicationContext context) {
26
     public AgoraModule(ReactApplicationContext context) {
26
 
27
 
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
     @ReactMethod
206
     @ReactMethod
189
     public void init(ReadableMap options) {
207
     public void init(ReadableMap options) {
190
         AgoraManager.getInstance().init(getReactApplicationContext(), mRtcEventHandler, options);
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
         AgoraManager.getInstance().mRtcEngine.setDefaultAudioRoutetoSpeakerphone(defaultToSpeaker);
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
     @ReactMethod
382
     @ReactMethod
352
     public void destroy() {
383
     public void destroy() {
371
                 .emit(eventName, params);
402
                 .emit(eventName, params);
372
     }
403
     }
373
 
404
 
374
-}
405
+}

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

47
  *  @return 0 when executed successfully. return negative value if failed.
47
  *  @return 0 when executed successfully. return negative value if failed.
48
  */
48
  */
49
 RCT_EXPORT_METHOD(init:(NSDictionary *)options) {
49
 RCT_EXPORT_METHOD(init:(NSDictionary *)options) {
50
-    
50
+
51
     [AgoraConst share].appid = options[@"appid"];
51
     [AgoraConst share].appid = options[@"appid"];
52
-    
52
+
53
     self.rtcEngine = [AgoraRtcEngineKit sharedEngineWithAppId:options[@"appid"] delegate:self];
53
     self.rtcEngine = [AgoraRtcEngineKit sharedEngineWithAppId:options[@"appid"] delegate:self];
54
-    
54
+
55
     [AgoraConst share].rtcEngine = self.rtcEngine;
55
     [AgoraConst share].rtcEngine = self.rtcEngine;
56
-    
56
+
57
     //频道模式
57
     //频道模式
58
     [self.rtcEngine setChannelProfile:[options[@"channelProfile"] integerValue]];
58
     [self.rtcEngine setChannelProfile:[options[@"channelProfile"] integerValue]];
59
     //启用双流模式
59
     //启用双流模式
61
     [self.rtcEngine enableVideo];
61
     [self.rtcEngine enableVideo];
62
     [self.rtcEngine setVideoProfile:[options[@"videoProfile"] integerValue]swapWidthAndHeight:[options[@"swapWidthAndHeight"]boolValue]];
62
     [self.rtcEngine setVideoProfile:[options[@"videoProfile"] integerValue]swapWidthAndHeight:[options[@"swapWidthAndHeight"]boolValue]];
63
     [self.rtcEngine setClientRole:[options[@"clientRole"] integerValue] withKey:nil];
63
     [self.rtcEngine setClientRole:[options[@"clientRole"] integerValue] withKey:nil];
64
-    
64
+
65
     //Agora Native SDK 与 Agora Web SDK 间的互通
65
     //Agora Native SDK 与 Agora Web SDK 间的互通
66
     [self.rtcEngine enableWebSdkInteroperability:YES];
66
     [self.rtcEngine enableWebSdkInteroperability:YES];
67
-    
67
+
68
 }
68
 }
69
 
69
 
70
 //加入房间
70
 //加入房间
79
     [self.rtcEngine leaveChannel:^(AgoraRtcStats *stat) {
79
     [self.rtcEngine leaveChannel:^(AgoraRtcStats *stat) {
80
         NSMutableDictionary *params = @{}.mutableCopy;
80
         NSMutableDictionary *params = @{}.mutableCopy;
81
         params[@"type"] = @"onLeaveChannel";
81
         params[@"type"] = @"onLeaveChannel";
82
-        
82
+
83
         [self sendEvent:params];
83
         [self sendEvent:params];
84
     }];
84
     }];
85
 }
85
 }
117
 //主播必须在加入频道前调用本章 API
117
 //主播必须在加入频道前调用本章 API
118
 RCT_EXPORT_METHOD(configPublisher:(NSDictionary *)config){
118
 RCT_EXPORT_METHOD(configPublisher:(NSDictionary *)config){
119
     AgoraPublisherConfiguration *apc = [AgoraPublisherConfiguration new];
119
     AgoraPublisherConfiguration *apc = [AgoraPublisherConfiguration new];
120
-    
120
+
121
     apc.width = [config[@"width"] integerValue];  //旁路直播的输出码流的宽度
121
     apc.width = [config[@"width"] integerValue];  //旁路直播的输出码流的宽度
122
     apc.height = [config[@"height"] integerValue]; //旁路直播的输出码流的高度
122
     apc.height = [config[@"height"] integerValue]; //旁路直播的输出码流的高度
123
     apc.framerate = [config[@"framerate"] integerValue]; //旁路直播的输出码率帧率
123
     apc.framerate = [config[@"framerate"] integerValue]; //旁路直播的输出码率帧率
128
     apc.rawStreamUrl = config[@"rawStreamUrl"]; //单流地址
128
     apc.rawStreamUrl = config[@"rawStreamUrl"]; //单流地址
129
     apc.extraInfo = config[@"extraInfo"]; //其他信息
129
     apc.extraInfo = config[@"extraInfo"]; //其他信息
130
     apc.owner = [config[@"owner"] boolValue]; //是否将当前主播设为该 RTMP 流的主人
130
     apc.owner = [config[@"owner"] boolValue]; //是否将当前主播设为该 RTMP 流的主人
131
-  
131
+
132
     [self.rtcEngine configPublisher:apc];
132
     [self.rtcEngine configPublisher:apc];
133
 }
133
 }
134
 
134
 
237
     [self.rtcEngine stopRecordingService:recordingKey];
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
 RCT_EXPORT_METHOD(getSdkVersion:(RCTResponseSenderBlock)callback){
258
 RCT_EXPORT_METHOD(getSdkVersion:(RCTResponseSenderBlock)callback){
242
     callback(@[[AgoraRtcEngineKit getSdkVersion]]);
259
     callback(@[[AgoraRtcEngineKit getSdkVersion]]);
252
     NSMutableDictionary *params = @{}.mutableCopy;
269
     NSMutableDictionary *params = @{}.mutableCopy;
253
     params[@"type"] = @"onError";
270
     params[@"type"] = @"onError";
254
     params[@"err"] = [NSNumber numberWithInteger:errorCode];;
271
     params[@"err"] = [NSNumber numberWithInteger:errorCode];;
255
-    
272
+
256
     [self sendEvent:params];
273
     [self sendEvent:params];
257
 }
274
 }
258
 
275
 
263
     NSMutableDictionary *params = @{}.mutableCopy;
280
     NSMutableDictionary *params = @{}.mutableCopy;
264
     params[@"type"] = @"onWarning";
281
     params[@"type"] = @"onWarning";
265
     params[@"err"] = [NSNumber numberWithInteger:warningCode];;
282
     params[@"err"] = [NSNumber numberWithInteger:warningCode];;
266
-    
283
+
267
     [self sendEvent:params];
284
     [self sendEvent:params];
268
 }
285
 }
269
 
286
 
277
     params[@"type"] = @"onJoinChannelSuccess";
294
     params[@"type"] = @"onJoinChannelSuccess";
278
     params[@"uid"] = [NSNumber numberWithInteger:uid];
295
     params[@"uid"] = [NSNumber numberWithInteger:uid];
279
     params[@"channel"] = channel;
296
     params[@"channel"] = channel;
280
-    
297
+
281
     [self sendEvent:params];
298
     [self sendEvent:params];
282
 }
299
 }
283
 
300
 
285
  远端首帧视频接收解码回调
302
  远端首帧视频接收解码回调
286
  */
303
  */
287
 - (void)rtcEngine:(AgoraRtcEngineKit *)engine firstRemoteVideoDecodedOfUid:(NSUInteger)uid size:(CGSize)size elapsed:(NSInteger)elapsed {
304
 - (void)rtcEngine:(AgoraRtcEngineKit *)engine firstRemoteVideoDecodedOfUid:(NSUInteger)uid size:(CGSize)size elapsed:(NSInteger)elapsed {
288
-    
305
+
289
     NSMutableDictionary *params = @{}.mutableCopy;
306
     NSMutableDictionary *params = @{}.mutableCopy;
290
     params[@"type"] = @"onFirstRemoteVideoDecoded";
307
     params[@"type"] = @"onFirstRemoteVideoDecoded";
291
     params[@"uid"] = [NSNumber numberWithInteger:uid];
308
     params[@"uid"] = [NSNumber numberWithInteger:uid];
292
-    
309
+
293
     [self sendEvent:params];
310
     [self sendEvent:params];
294
 
311
 
295
 }
312
 }
301
     NSMutableDictionary *params = @{}.mutableCopy;
318
     NSMutableDictionary *params = @{}.mutableCopy;
302
     params[@"type"] = @"onUserJoined";
319
     params[@"type"] = @"onUserJoined";
303
     params[@"uid"] = [NSNumber numberWithInteger:uid];
320
     params[@"uid"] = [NSNumber numberWithInteger:uid];
304
-    
321
+
305
     [self sendEvent:params];
322
     [self sendEvent:params];
306
 }
323
 }
307
 
324
 
312
     NSMutableDictionary *params = @{}.mutableCopy;
329
     NSMutableDictionary *params = @{}.mutableCopy;
313
     params[@"type"] = @"onUserOffline";
330
     params[@"type"] = @"onUserOffline";
314
     params[@"uid"] = [NSNumber numberWithInteger:uid];
331
     params[@"uid"] = [NSNumber numberWithInteger:uid];
315
-    
332
+
316
     [self sendEvent:params];
333
     [self sendEvent:params];
317
 }
334
 }
318
 
335
 
323
 - (void)rtcEngine:(AgoraRtcEngineKit *)engine reportAudioVolumeIndicationOfSpeakers:(NSArray*)speakers totalVolume:(NSInteger)totalVolume {
340
 - (void)rtcEngine:(AgoraRtcEngineKit *)engine reportAudioVolumeIndicationOfSpeakers:(NSArray*)speakers totalVolume:(NSInteger)totalVolume {
324
     NSMutableDictionary *params = @{}.mutableCopy;
341
     NSMutableDictionary *params = @{}.mutableCopy;
325
     params[@"type"] = @"onAudioVolumeIndication";
342
     params[@"type"] = @"onAudioVolumeIndication";
326
-    
343
+
327
     NSMutableArray *arr = [NSMutableArray array];
344
     NSMutableArray *arr = [NSMutableArray array];
328
     for (AgoraRtcAudioVolumeInfo *obj in speakers) {
345
     for (AgoraRtcAudioVolumeInfo *obj in speakers) {
329
         [arr addObject:@{@"uid":[NSNumber numberWithInteger:obj.uid], @"volume":[NSNumber numberWithInteger:obj.volume]}];
346
         [arr addObject:@{@"uid":[NSNumber numberWithInteger:obj.uid], @"volume":[NSNumber numberWithInteger:obj.volume]}];
330
     }
347
     }
331
-    
348
+
332
     params[@"speakers"] = arr;
349
     params[@"speakers"] = arr;
333
     params[@"totalVolume"] = [NSNumber numberWithInteger:totalVolume];
350
     params[@"totalVolume"] = [NSNumber numberWithInteger:totalVolume];
334
-    
351
+
335
     [self sendEvent:params];
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
 - (void)sendEvent:(NSDictionary *)params {
381
 - (void)sendEvent:(NSDictionary *)params {
339
     [_bridge.eventDispatcher sendDeviceEventWithName:@"agoraEvent" body:params];
382
     [_bridge.eventDispatcher sendDeviceEventWithName:@"agoraEvent" body:params];
340
 }
383
 }
344
 }
387
 }
345
 
388
 
346
 //RCT_EXPORT_METHOD(getViewWithTag:(nonnull NSNumber *)reactTag) {
389
 //RCT_EXPORT_METHOD(getViewWithTag:(nonnull NSNumber *)reactTag) {
347
-//    
390
+//
348
 //    UIView *view = [self.bridge.uiManager viewForReactTag:reactTag];
391
 //    UIView *view = [self.bridge.uiManager viewForReactTag:reactTag];
349
 //    NSLog(@"%@",view);
392
 //    NSLog(@"%@",view);
350
-//    
393
+//
351
 //}
394
 //}
352
 
395
 
353
 @end
396
 @end

+ 1
- 1
package.json View File

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