diff --git a/README.md b/README.md index 27bd41bd7..2449ef0bc 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,8 @@ Add following to `AndroidManifest.xml` | startRecordingService (iOS only) | string recordingKey | 启动服务端录制服务 | | stopRecordingService (iOS only) | string recordingKey | 停止服务端录制服务 | | getSdkVersion | callback | 获取版本号 | +| createDataStream | (boolean reliable, boolean ordered, (streamId) => {}), 其中 reliable, ordered 请参考官方文档同名方法说明 | 创建数据流通道 | +| sendStreamMessage | (number streamId, string message, (errorCode) => {})| 发送数据 | ##### 原生通知事件 @@ -121,7 +123,9 @@ RtcEngine.eventEmitter({ onError: data => {}, onWarning: data => {}, onLeaveChannel: data => {}, - onAudioVolumeIndication: data => {} + onAudioVolumeIndication: data => {}, + onStreamMessage: ({uid, streamId, data}) => {}, + onStreamMessageError: ({uid, streamId, error, missed, cached}) => {}, }) ``` @@ -135,6 +139,8 @@ RtcEngine.eventEmitter({ | onWarning | 警告 | | onLeaveChannel | 退出频道 | | onAudioVolumeIndication | 音量提示回调 | +| onStreamMessage | 接收到对方数据流消息的回调 | +| onStreamMessageError | 接收到对方数据流消息错误的回调 | ##### AgoraView 组件 @@ -158,6 +164,12 @@ RtcEngine.eventEmitter({ ## 更新信息 +#### 1.1.1 + +- 新增方法 创建数据流通道 createDataStream +- 新增方法 发送数据流 sendStreamMessage +- 新增监听数据流事件 onStreamMessage + #### 1.0.9 - 更新Agora SDK 为 2.0.2 diff --git a/android/src/main/java/com/syan/agora/AgoraModule.java b/android/src/main/java/com/syan/agora/AgoraModule.java index 281dbc1b6..1a079042c 100644 --- a/android/src/main/java/com/syan/agora/AgoraModule.java +++ b/android/src/main/java/com/syan/agora/AgoraModule.java @@ -91,6 +91,41 @@ public void run() { } + // 接收到对方数据流消息的回调 + @Override + public void onStreamMessage(final int uid, final int streamId, final byte[] data) { + runOnUiThread(new Runnable() { + @Override + public void run() { + String msg = new String(data); + WritableMap map = Arguments.createMap(); + map.putString("type", "onStreamMessage"); + map.putInt("uid", uid); + map.putInt("streamId", streamId); + map.putString("data", msg); + commonEvent(map); + } + }); + } + + // 接收对方数据流消息错误的回调 + @Override + public void onStreamMessageError(final int uid, final int streamId, final int code, final int missed, final int cached) { + runOnUiThread(new Runnable() { + @Override + public void run() { + WritableMap map = Arguments.createMap(); + map.putString("type", "onStreamMessageError"); + map.putInt("uid", uid); + map.putInt("streamId", streamId); + map.putInt("error", code); + map.putInt("missed", missed); + map.putInt("cached", cached); + commonEvent(map); + } + }); + } + /** * 说话声音音量提示回调 */ @@ -347,6 +382,18 @@ public void setDefaultAudioRouteToSpeakerphone(boolean defaultToSpeaker) { AgoraManager.getInstance().mRtcEngine.setDefaultAudioRoutetoSpeakerphone(defaultToSpeaker); } + // 建立数据通道 + @ReactMethod + public void createDataStream(boolean reliable, boolean ordered, Callback callback) { + callback.invoke(AgoraManager.getInstance().mRtcEngine.createDataStream(reliable, ordered)); + } + + // 发送数据 + @ReactMethod + public void sendStreamMessage(int streamId, String message, Callback onError) { + onError.invoke(AgoraManager.getInstance().mRtcEngine.sendStreamMessage(streamId, message.getBytes())); + } + //销毁引擎实例 @ReactMethod public void destroy() { @@ -371,4 +418,4 @@ private void sendEvent(ReactContext reactContext, .emit(eventName, params); } -} \ No newline at end of file +} diff --git a/ios/RCTAgora/RCTAgora.m b/ios/RCTAgora/RCTAgora.m index f66d2d796..e5214b1c2 100644 --- a/ios/RCTAgora/RCTAgora.m +++ b/ios/RCTAgora/RCTAgora.m @@ -47,13 +47,13 @@ - (NSDictionary *)constantsToExport { * @return 0 when executed successfully. return negative value if failed. */ RCT_EXPORT_METHOD(init:(NSDictionary *)options) { - + [AgoraConst share].appid = options[@"appid"]; - + self.rtcEngine = [AgoraRtcEngineKit sharedEngineWithAppId:options[@"appid"] delegate:self]; - + [AgoraConst share].rtcEngine = self.rtcEngine; - + //频道模式 [self.rtcEngine setChannelProfile:[options[@"channelProfile"] integerValue]]; //启用双流模式 @@ -61,10 +61,10 @@ - (NSDictionary *)constantsToExport { [self.rtcEngine enableVideo]; [self.rtcEngine setVideoProfile:[options[@"videoProfile"] integerValue]swapWidthAndHeight:[options[@"swapWidthAndHeight"]boolValue]]; [self.rtcEngine setClientRole:[options[@"clientRole"] integerValue] withKey:nil]; - + //Agora Native SDK 与 Agora Web SDK 间的互通 [self.rtcEngine enableWebSdkInteroperability:YES]; - + } //加入房间 @@ -79,7 +79,7 @@ - (NSDictionary *)constantsToExport { [self.rtcEngine leaveChannel:^(AgoraRtcStats *stat) { NSMutableDictionary *params = @{}.mutableCopy; params[@"type"] = @"onLeaveChannel"; - + [self sendEvent:params]; }]; } @@ -117,7 +117,7 @@ - (NSDictionary *)constantsToExport { //主播必须在加入频道前调用本章 API RCT_EXPORT_METHOD(configPublisher:(NSDictionary *)config){ AgoraPublisherConfiguration *apc = [AgoraPublisherConfiguration new]; - + apc.width = [config[@"width"] integerValue]; //旁路直播的输出码流的宽度 apc.height = [config[@"height"] integerValue]; //旁路直播的输出码流的高度 apc.framerate = [config[@"framerate"] integerValue]; //旁路直播的输出码率帧率 @@ -128,7 +128,7 @@ - (NSDictionary *)constantsToExport { apc.rawStreamUrl = config[@"rawStreamUrl"]; //单流地址 apc.extraInfo = config[@"extraInfo"]; //其他信息 apc.owner = [config[@"owner"] boolValue]; //是否将当前主播设为该 RTMP 流的主人 - + [self.rtcEngine configPublisher:apc]; } @@ -237,6 +237,23 @@ - (NSDictionary *)constantsToExport { [self.rtcEngine stopRecordingService:recordingKey]; } +/* +创建数据流 +*/ +RCT_EXPORT_METHOD(createDataStream:(BOOL)reliable ordered:(BOOL)ordered callback:(RCTResponseSenderBlock)callback){ +  NSInteger streamId = 0; +  [self.rtcEngine createDataStream:&streamId reliable:reliable ordered:ordered]; +  callback(@[[NSNumber numberWithInteger:streamId]]); +} + +/* +发送数据流 +*/ +RCT_EXPORT_METHOD(sendStreamMessage:(NSInteger)streamId data:(NSData*)data callback:(RCTResponseSenderBlock)callback){ +  int err = [self.rtcEngine sendStreamMessage:(streamId) data:data]; +  callback(@[[NSNumber numberWithInteger:err]]); +} + //获取版本号 RCT_EXPORT_METHOD(getSdkVersion:(RCTResponseSenderBlock)callback){ callback(@[[AgoraRtcEngineKit getSdkVersion]]); @@ -252,7 +269,7 @@ - (void)rtcEngine:(AgoraRtcEngineKit *)engine didOccurError:(AgoraRtcErrorCode)e NSMutableDictionary *params = @{}.mutableCopy; params[@"type"] = @"onError"; params[@"err"] = [NSNumber numberWithInteger:errorCode];; - + [self sendEvent:params]; } @@ -263,7 +280,7 @@ - (void)rtcEngine:(AgoraRtcEngineKit *)engine didOccurWarning:(AgoraRtcWarningCo NSMutableDictionary *params = @{}.mutableCopy; params[@"type"] = @"onWarning"; params[@"err"] = [NSNumber numberWithInteger:warningCode];; - + [self sendEvent:params]; } @@ -277,7 +294,7 @@ - (void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinChannel:(NSString*)channel params[@"type"] = @"onJoinChannelSuccess"; params[@"uid"] = [NSNumber numberWithInteger:uid]; params[@"channel"] = channel; - + [self sendEvent:params]; } @@ -285,11 +302,11 @@ - (void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinChannel:(NSString*)channel 远端首帧视频接收解码回调 */ - (void)rtcEngine:(AgoraRtcEngineKit *)engine firstRemoteVideoDecodedOfUid:(NSUInteger)uid size:(CGSize)size elapsed:(NSInteger)elapsed { - + NSMutableDictionary *params = @{}.mutableCopy; params[@"type"] = @"onFirstRemoteVideoDecoded"; params[@"uid"] = [NSNumber numberWithInteger:uid]; - + [self sendEvent:params]; } @@ -301,7 +318,7 @@ - (void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinedOfUid:(NSUInteger)uid ela NSMutableDictionary *params = @{}.mutableCopy; params[@"type"] = @"onUserJoined"; params[@"uid"] = [NSNumber numberWithInteger:uid]; - + [self sendEvent:params]; } @@ -312,7 +329,7 @@ - (void)rtcEngine:(AgoraRtcEngineKit *)engine didOfflineOfUid:(NSUInteger)uid re NSMutableDictionary *params = @{}.mutableCopy; params[@"type"] = @"onUserOffline"; params[@"uid"] = [NSNumber numberWithInteger:uid]; - + [self sendEvent:params]; } @@ -323,18 +340,44 @@ - (void)rtcEngine:(AgoraRtcEngineKit *)engine didOfflineOfUid:(NSUInteger)uid re - (void)rtcEngine:(AgoraRtcEngineKit *)engine reportAudioVolumeIndicationOfSpeakers:(NSArray*)speakers totalVolume:(NSInteger)totalVolume { NSMutableDictionary *params = @{}.mutableCopy; params[@"type"] = @"onAudioVolumeIndication"; - + NSMutableArray *arr = [NSMutableArray array]; for (AgoraRtcAudioVolumeInfo *obj in speakers) { [arr addObject:@{@"uid":[NSNumber numberWithInteger:obj.uid], @"volume":[NSNumber numberWithInteger:obj.volume]}]; } - + params[@"speakers"] = arr; params[@"totalVolume"] = [NSNumber numberWithInteger:totalVolume]; - + [self sendEvent:params]; } +/* +接受数据流 +*/ + +- (void)rtcEngine:(AgoraRtcEngineKit * _Nonnull)engine receiveStreamMessageFromUid:(NSUInteger)uid streamId:(NSInteger)streamId data:(NSData * _Nonnull)data{ +  NSMutableDictionary *params = @{}.mutableCopy; +  params[@"type"] = @"onStreamMessage"; +  params[@"uid"] = [NSNumber numberWithInteger:uid]; +  params[@"streamId"] = [NSNumber numberWithInteger:streamId]; +  params[@"data"] = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; + +  [self sendEvent:params]; +} + +- (void)rtcEngine:(AgoraRtcEngineKit *)engine didOccurStreamMessageErrorFromUid:(NSUInteger)uid streamId:(NSInteger)streamId error:(NSInteger)error missed:(NSInteger)missed cached:(NSInteger)cached{ +  NSMutableDictionary *params = @{}.mutableCopy; +  params[@"type"] = @"onStreamMessageError"; +  params[@"uid"] = [NSNumber numberWithInteger:uid]; +  params[@"streamId"] = [NSNumber numberWithInteger:streamId]; +  params[@"error"] = [NSNumber numberWithInteger:error]; +  params[@"missed"] = [NSNumber numberWithInteger:missed]; +  params[@"cached"] = [NSNumber numberWithInteger:cached]; + +  [self sendEvent:params]; +} + - (void)sendEvent:(NSDictionary *)params { [_bridge.eventDispatcher sendDeviceEventWithName:@"agoraEvent" body:params]; } @@ -344,10 +387,10 @@ - (dispatch_queue_t)methodQueue { } //RCT_EXPORT_METHOD(getViewWithTag:(nonnull NSNumber *)reactTag) { -// +// // UIView *view = [self.bridge.uiManager viewForReactTag:reactTag]; // NSLog(@"%@",view); -// +// //} @end diff --git a/package.json b/package.json index 47f444893..a9248a555 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-agora", - "version": "1.1.0", + "version": "1.1.1", "description": "声网Agora", "main": "index.js", "scripts": {