From abe25b0c70e15248741133a66eb2c438d82c43e2 Mon Sep 17 00:00:00 2001 From: Riant Date: Sat, 24 Feb 2018 11:12:08 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=B5=81=E7=9B=B8=E5=85=B3=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 ++- .../main/java/com/syan/agora/AgoraModule.java | 33 ++++++- ios/RCTAgora/RCTAgora.m | 85 ++++++++++++++----- package.json | 2 +- 4 files changed, 109 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 27bd41bd7..9a217fa7c 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Add following to `AndroidManifest.xml` | Property | Type | Description | | -------------------------------- | ---------------------------------------- | ------------------------------------- | -| init | object {appid: 'agora注册的应用id', channelProfile: '频道模式', videoProfile: '视频模式', clientRole: '角色', swapWidthAndHeight: 'bool值'} | 初始化Agora引擎 | +| init | object {appid: 'agora注册的应用id', channelProfile: '频道模式', videoProfile: '视频模式', clientRole: '角色', swapWidthAndHeight: 'bool值', reliable: 'bool值 - 默认数据流通道创建参数,参考 createDataStream', ordered: 'bool值 - 默认数据流通道创建参数,参考 createDataStream'} | 初始化Agora引擎 | | joinChannel | string channelName (房间名称) number uid (用户设置的uid 传0系统会自动分配) | 加入房间 | | leaveChannel | | 离开频道 | | destroy | | 销毁引擎实例 | @@ -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,8 @@ RtcEngine.eventEmitter({ onError: data => {}, onWarning: data => {}, onLeaveChannel: data => {}, - onAudioVolumeIndication: data => {} + onAudioVolumeIndication: data => {}, + onStreamMessage: ({uid, streamId, data}) => {} }) ``` @@ -135,6 +138,7 @@ RtcEngine.eventEmitter({ | onWarning | 警告 | | onLeaveChannel | 退出频道 | | onAudioVolumeIndication | 音量提示回调 | +| onStreamMessage | 接收到对方数据流消息的回调 | ##### AgoraView 组件 @@ -158,6 +162,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..4ca21a80c 100644 --- a/android/src/main/java/com/syan/agora/AgoraModule.java +++ b/android/src/main/java/com/syan/agora/AgoraModule.java @@ -21,6 +21,7 @@ import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread; public class AgoraModule extends ReactContextBaseJavaModule { + private int defaultStreamId = -1; public AgoraModule(ReactApplicationContext context) { @@ -91,6 +92,23 @@ 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); + } + }); + } + /** * 说话声音音量提示回调 */ @@ -188,6 +206,7 @@ public void run() { @ReactMethod public void init(ReadableMap options) { AgoraManager.getInstance().init(getReactApplicationContext(), mRtcEventHandler, options); + this.defaultStreamId = AgoraManager.getInstance().mRtcEngine.createDataStream(options.getBoolean("reliable"), options.getBoolean("ordered")); } //进入房间 @@ -347,6 +366,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 > 0 ? streamId : this.defaultStreamId, message.getBytes())); + } + //销毁引擎实例 @ReactMethod public void destroy() { @@ -371,4 +402,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..cae77e5d4 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 > 0 ? streamId : defaultDataStreamId) 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": { From 83cd3ba517882076ba9668dd25edffd3f56f92dc Mon Sep 17 00:00:00 2001 From: Riant Date: Sat, 24 Feb 2018 15:38:02 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E6=95=B0=E6=8D=AE=E6=B5=81=E9=80=9A=E9=81=93?= =?UTF-8?q?=E7=9A=84=E5=8F=82=E6=95=B0=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- android/src/main/java/com/syan/agora/AgoraModule.java | 2 +- ios/RCTAgora/RCTAgora.m | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9a217fa7c..4fdbb7ffa 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Add following to `AndroidManifest.xml` | Property | Type | Description | | -------------------------------- | ---------------------------------------- | ------------------------------------- | -| init | object {appid: 'agora注册的应用id', channelProfile: '频道模式', videoProfile: '视频模式', clientRole: '角色', swapWidthAndHeight: 'bool值', reliable: 'bool值 - 默认数据流通道创建参数,参考 createDataStream', ordered: 'bool值 - 默认数据流通道创建参数,参考 createDataStream'} | 初始化Agora引擎 | +| init | object {appid: 'agora注册的应用id', channelProfile: '频道模式', videoProfile: '视频模式', clientRole: '角色', swapWidthAndHeight: 'bool值'} | 初始化Agora引擎 | | joinChannel | string channelName (房间名称) number uid (用户设置的uid 传0系统会自动分配) | 加入房间 | | leaveChannel | | 离开频道 | | destroy | | 销毁引擎实例 | diff --git a/android/src/main/java/com/syan/agora/AgoraModule.java b/android/src/main/java/com/syan/agora/AgoraModule.java index 4ca21a80c..4bab5f88b 100644 --- a/android/src/main/java/com/syan/agora/AgoraModule.java +++ b/android/src/main/java/com/syan/agora/AgoraModule.java @@ -206,7 +206,7 @@ public void run() { @ReactMethod public void init(ReadableMap options) { AgoraManager.getInstance().init(getReactApplicationContext(), mRtcEventHandler, options); - this.defaultStreamId = AgoraManager.getInstance().mRtcEngine.createDataStream(options.getBoolean("reliable"), options.getBoolean("ordered")); + this.defaultStreamId = AgoraManager.getInstance().mRtcEngine.createDataStream(false, false); } //进入房间 diff --git a/ios/RCTAgora/RCTAgora.m b/ios/RCTAgora/RCTAgora.m index cae77e5d4..93ba426f5 100644 --- a/ios/RCTAgora/RCTAgora.m +++ b/ios/RCTAgora/RCTAgora.m @@ -34,6 +34,8 @@ - (NSDictionary *)constantsToExport { return @{}; } +NSInteger defaultDataStreamId = -1; + /** * 初始化AgoraKit * @@ -62,6 +64,9 @@ - (NSDictionary *)constantsToExport { [self.rtcEngine setVideoProfile:[options[@"videoProfile"] integerValue]swapWidthAndHeight:[options[@"swapWidthAndHeight"]boolValue]]; [self.rtcEngine setClientRole:[options[@"clientRole"] integerValue] withKey:nil]; + // 创建默认数据通道 + [self.rtcEngine createDataStream:&dataChannelId reliable:0 ordered:0]; + //Agora Native SDK 与 Agora Web SDK 间的互通 [self.rtcEngine enableWebSdkInteroperability:YES]; From d032457aaf28bec8796597aaff55b034fa7570ec Mon Sep 17 00:00:00 2001 From: Riant Date: Tue, 27 Feb 2018 10:31:07 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=96=B0=E5=BB=BA=E6=95=B0=E6=8D=AE=E6=B5=81=E9=80=9A=E9=81=93?= =?UTF-8?q?=E7=9A=84=E6=94=AF=E6=8C=81=EF=BC=8C=E4=BB=A5=E4=BE=BF=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E8=80=85=E6=8C=89=E9=9C=80=E8=87=AA=E4=B8=BB=E5=88=9B?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/src/main/java/com/syan/agora/AgoraModule.java | 4 +--- ios/RCTAgora/RCTAgora.m | 7 +------ 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/android/src/main/java/com/syan/agora/AgoraModule.java b/android/src/main/java/com/syan/agora/AgoraModule.java index 4bab5f88b..a3dd9ddbd 100644 --- a/android/src/main/java/com/syan/agora/AgoraModule.java +++ b/android/src/main/java/com/syan/agora/AgoraModule.java @@ -21,7 +21,6 @@ import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread; public class AgoraModule extends ReactContextBaseJavaModule { - private int defaultStreamId = -1; public AgoraModule(ReactApplicationContext context) { @@ -206,7 +205,6 @@ public void run() { @ReactMethod public void init(ReadableMap options) { AgoraManager.getInstance().init(getReactApplicationContext(), mRtcEventHandler, options); - this.defaultStreamId = AgoraManager.getInstance().mRtcEngine.createDataStream(false, false); } //进入房间 @@ -375,7 +373,7 @@ public void createDataStream(boolean reliable, boolean ordered, Callback callbac // 发送数据 @ReactMethod public void sendStreamMessage(int streamId, String message, Callback onError) { - onError.invoke(AgoraManager.getInstance().mRtcEngine.sendStreamMessage(streamId > 0 ? streamId : this.defaultStreamId, message.getBytes())); + onError.invoke(AgoraManager.getInstance().mRtcEngine.sendStreamMessage(streamId, message.getBytes())); } //销毁引擎实例 diff --git a/ios/RCTAgora/RCTAgora.m b/ios/RCTAgora/RCTAgora.m index 93ba426f5..e5214b1c2 100644 --- a/ios/RCTAgora/RCTAgora.m +++ b/ios/RCTAgora/RCTAgora.m @@ -34,8 +34,6 @@ - (NSDictionary *)constantsToExport { return @{}; } -NSInteger defaultDataStreamId = -1; - /** * 初始化AgoraKit * @@ -64,9 +62,6 @@ - (NSDictionary *)constantsToExport { [self.rtcEngine setVideoProfile:[options[@"videoProfile"] integerValue]swapWidthAndHeight:[options[@"swapWidthAndHeight"]boolValue]]; [self.rtcEngine setClientRole:[options[@"clientRole"] integerValue] withKey:nil]; - // 创建默认数据通道 - [self.rtcEngine createDataStream:&dataChannelId reliable:0 ordered:0]; - //Agora Native SDK 与 Agora Web SDK 间的互通 [self.rtcEngine enableWebSdkInteroperability:YES]; @@ -255,7 +250,7 @@ - (NSDictionary *)constantsToExport { 发送数据流 */ RCT_EXPORT_METHOD(sendStreamMessage:(NSInteger)streamId data:(NSData*)data callback:(RCTResponseSenderBlock)callback){ -  int err = [self.rtcEngine sendStreamMessage:(streamId > 0 ? streamId : defaultDataStreamId) data:data]; +  int err = [self.rtcEngine sendStreamMessage:(streamId) data:data];   callback(@[[NSNumber numberWithInteger:err]]); } From a43e70aac423d654bf746e41745a2e4637b568c0 Mon Sep 17 00:00:00 2001 From: Riant Date: Wed, 28 Feb 2018 09:46:57 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E4=B8=BA=20Android=20=E6=B7=BB=E5=8A=A0=20?= =?UTF-8?q?onStreamMessageError=20=E7=9B=91=E5=90=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/syan/agora/AgoraModule.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/android/src/main/java/com/syan/agora/AgoraModule.java b/android/src/main/java/com/syan/agora/AgoraModule.java index a3dd9ddbd..1a079042c 100644 --- a/android/src/main/java/com/syan/agora/AgoraModule.java +++ b/android/src/main/java/com/syan/agora/AgoraModule.java @@ -108,6 +108,24 @@ public void run() { }); } + // 接收对方数据流消息错误的回调 + @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); + } + }); + } + /** * 说话声音音量提示回调 */ From 1ac3395e26a3224a7a3647952e112fa56d79dbf3 Mon Sep 17 00:00:00 2001 From: Riant Date: Wed, 28 Feb 2018 09:50:37 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=AF=B4=E6=98=8E?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4fdbb7ffa..2449ef0bc 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,8 @@ RtcEngine.eventEmitter({ onWarning: data => {}, onLeaveChannel: data => {}, onAudioVolumeIndication: data => {}, - onStreamMessage: ({uid, streamId, data}) => {} + onStreamMessage: ({uid, streamId, data}) => {}, + onStreamMessageError: ({uid, streamId, error, missed, cached}) => {}, }) ``` @@ -139,6 +140,7 @@ RtcEngine.eventEmitter({ | onLeaveChannel | 退出频道 | | onAudioVolumeIndication | 音量提示回调 | | onStreamMessage | 接收到对方数据流消息的回调 | +| onStreamMessageError | 接收到对方数据流消息错误的回调 | ##### AgoraView 组件