ソースを参照

feat. native ios & android refactor registerMediaMetaDataObserver

matrixbirds 5 年 前
コミット
e0c2f3033d

+ 16
- 36
android/src/main/java/com/syan/agora/AgoraModule.java ファイルの表示

@@ -290,7 +290,7 @@ public class AgoraModule extends ReactContextBaseJavaModule {
290 290
     private final static String AGRtmpStreamingStateChanged = "rtmpStreamingStateChanged";
291 291
     private final static String AGNetworkTypeChanged = "networkTypeChanged";
292 292
     private final static String AGFirstRemoteAudioDecoded = "firstRemoteAudioDecoded";
293
-    private final static String AGMediaMetaDataRecevied = "mediaMetaDataRecevied";
293
+    private final static String AGMediaMetaDataReceived = "mediaMetaDataReceived";
294 294
     private final static String AGRemoteVideoStateChanged = "remoteVideoStateChanged";
295 295
     private final static String AGLocalPublishFallbackToAudioOnly = "localPublishFallbackToAudioOnly";
296 296
     private final static String AGRemoteSubscribeFallbackToAudioOnly = "remoteSubscribeFallbackToAudioOnly";
@@ -328,6 +328,8 @@ public class AgoraModule extends ReactContextBaseJavaModule {
328 328
     private final static String AGLastmileProbeResult = "lastmileProbeTestResult";
329 329
 //    private final static String AGIntervalTest = "startEchoTestWithInterval";
330 330
 
331
+    private MediaObserver mediaObserver = null;
332
+
331 333
     private IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
332 334
 
333 335
         @Override
@@ -2086,46 +2088,26 @@ public class AgoraModule extends ReactContextBaseJavaModule {
2086 2088
         }
2087 2089
     }
2088 2090
 
2089
-    private static final Integer MAX_META_DATA = 1024;
2090
-
2091
-    private byte[] metadata = null;
2092
-
2093 2091
     @ReactMethod
2094
-    public void sendMediaData(String data) {
2095
-        metadata = data.getBytes(Charset.forName("UTF-8"));
2092
+    public void sendMediaData(String data, final Promise promise) {
2093
+        if (null == mediaObserver) {
2094
+            promise.reject("-1", "sendMediaData failed");
2095
+        } else {
2096
+            mediaObserver.setMetadata(data.getBytes(Charset.forName("UTF-8")));
2097
+            WritableMap map = Arguments.createMap();
2098
+            map.putBoolean("success", true);
2099
+            promise.resolve(map);
2100
+        }
2096 2101
     }
2097 2102
 
2098 2103
     @ReactMethod
2099 2104
     public void registerMediaMetadataObserver(final Promise promise) {
2100 2105
         try {
2101
-            int res = AgoraManager.getInstance().mRtcEngine.registerMediaMetadataObserver(new IMetadataObserver() {
2102
-                @Override
2103
-                public int getMaxMetadataSize() { return MAX_META_DATA; }
2104
-
2105
-                @Override
2106
-                public byte[] onReadyToSendMetadata(long timeStampMs) {
2107
-                    if (metadata == null) {
2108
-                        return null;
2109
-                    }
2110
-                    byte[] toSend = metadata;
2111
-                    if (toSend.length > MAX_META_DATA) {
2112
-                        return null;
2113
-                    }
2114
-                    metadata = null;
2115
-                    return toSend;
2116
-                }
2117
-
2118
-                @Override
2119
-                public void onMetadataReceived(byte[] buffer, int uid, long timeStampMs) {
2120
-                    WritableMap map = Arguments.createMap();
2121
-                    map.putString("data", new String(buffer, Charset.forName("UTF-8")));
2122
-                    map.putString("uid", Integer.toString(uid));
2123
-                    map.putString("ts", Long.toString(timeStampMs));
2124
-                    sendEvent(getReactApplicationContext(), AGMediaMetaDataRecevied, map);
2125
-                }
2126
-            }, IMetadataObserver.VIDEO_METADATA);
2106
+            mediaObserver = new MediaObserver(getReactApplicationContext());
2107
+            int res = AgoraManager.getInstance().mRtcEngine
2108
+                    .registerMediaMetadataObserver(mediaObserver, IMetadataObserver.VIDEO_METADATA);
2127 2109
             if (res < 0) {
2128
-                new ReactNativeAgoraException("setRemoteDefaultVideoStreamType Failed", res);
2110
+                new ReactNativeAgoraException("registerMediaMetadataObserver Failed", res);
2129 2111
             }
2130 2112
             WritableMap map = Arguments.createMap();
2131 2113
             map.putBoolean("success", true);
@@ -2760,7 +2742,6 @@ public class AgoraModule extends ReactContextBaseJavaModule {
2760 2742
     }
2761 2743
 
2762 2744
 
2763
-
2764 2745
     @ReactMethod
2765 2746
 
2766 2747
     private void sendEvent(ReactContext reactContext,
@@ -2770,5 +2751,4 @@ public class AgoraModule extends ReactContextBaseJavaModule {
2770 2751
                 .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
2771 2752
                 .emit(eventName, params);
2772 2753
     }
2773
-
2774 2754
 }

+ 59
- 0
android/src/main/java/com/syan/agora/MediaObserver.java ファイルの表示

@@ -0,0 +1,59 @@
1
+package com.syan.agora;
2
+
3
+import com.facebook.react.bridge.Arguments;
4
+import com.facebook.react.bridge.ReactContext;
5
+import com.facebook.react.bridge.WritableMap;
6
+import com.facebook.react.modules.core.DeviceEventManagerModule;
7
+
8
+import java.nio.charset.Charset;
9
+
10
+import io.agora.rtc.IMetadataObserver;
11
+
12
+public class MediaObserver implements IMetadataObserver {
13
+
14
+    private static final Integer MAX_DATA_LENGT = 1024;
15
+
16
+    private ReactContext reactCtx;
17
+
18
+    public byte[] getMetadata() {
19
+        return metadata;
20
+    }
21
+
22
+    public void setMetadata(byte[] metadata) {
23
+        this.metadata = metadata;
24
+    }
25
+
26
+    private byte[] metadata = null;
27
+
28
+    public MediaObserver(ReactContext reactCtx) {
29
+        this.reactCtx = reactCtx;
30
+    }
31
+
32
+    @Override
33
+    public int getMaxMetadataSize() {
34
+        return MAX_DATA_LENGT;
35
+    }
36
+
37
+    @Override
38
+    public byte[] onReadyToSendMetadata(long timeStampMs) {
39
+        if (metadata == null) {
40
+            return null;
41
+        }
42
+        byte[] toSend = metadata;
43
+        if (toSend.length > MAX_DATA_LENGT) {
44
+            return null;
45
+        }
46
+        metadata = null;
47
+        return toSend;
48
+    }
49
+
50
+    @Override
51
+    public void onMetadataReceived(byte[] buffer, int uid, long timeStampMs) {
52
+        WritableMap map = Arguments.createMap();
53
+        map.putString("data", new String(buffer, Charset.forName("UTF-8")));
54
+        map.putString("uid", Integer.toString(uid));
55
+        map.putString("ts", Long.toString(timeStampMs));
56
+        reactCtx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
57
+                .emit("mediaMetaDataReceived", map);
58
+    }
59
+}

+ 1
- 1
ios/RCTAgora/AgoraConst.h ファイルの表示

@@ -81,7 +81,7 @@ static NSString *AGLastmileProbeTestResult = @"lastmileProbeTestResult";
81 81
 static NSString *AGRtmpStreamingStateChanged = @"rtmpStreamingStateChanged";
82 82
 static NSString *AGLocalVideoChanged = @"localVideoChanged";
83 83
 static NSString *AGNetworkTypeChanged = @"networkTypeChanged";
84
-static NSString *AGMediaMetaDataRecevied = @"mediaMetaDataRecevied";
84
+static NSString *AGMediaMetaDataReceived = @"mediaMetaDataReceived";
85 85
 
86 86
 typedef NS_ENUM(NSInteger, AgoraModeType) {
87 87
   AgoraAudioMode,

+ 6
- 3
ios/RCTAgora/RCTAgora.h ファイルの表示

@@ -10,8 +10,11 @@
10 10
 #import <UIKit/UIKit.h>
11 11
 #import <React/RCTBridgeModule.h>
12 12
 #import <React/RCTEventEmitter.h>
13
+#import <AgoraRtcEngineKit/AgoraRtcEngineKit.h>
13 14
 
14
-@interface RCTAgora : RCTEventEmitter<RCTBridgeModule>
15
-
16
-+(void) sendEvent:(NSString *)name params:(NSDictionary*)params;
15
+@interface RCTAgora : RCTEventEmitter<RCTBridgeModule, AgoraMediaMetadataDelegate, AgoraMediaMetadataDataSource>
16
+- (void) sendEvent:(NSString *)msg params:(NSDictionary *)params;
17
+- (NSInteger) metadataMaxSize;
18
+- (NSData *_Nullable)readyToSendMetadataAtTimestamp:(NSTimeInterval)timestamp;
19
+- (void)receiveMetadata:(NSData *_Nonnull)data fromUser:(NSInteger)uid atTimestamp:(NSTimeInterval)timestamp;
17 20
 @end

+ 46
- 46
ios/RCTAgora/RCTAgora.m ファイルの表示

@@ -17,61 +17,45 @@
17 17
 
18 18
 @interface RCTAgora ()
19 19
 @property (strong, nonatomic) AgoraRtcEngineKit *rtcEngine;
20
-
20
+@property (strong, nonatomic) NSData *metadata;
21 21
 @end
22 22
 
23
-@interface MediaMetaDataObserver : NSObject<AgoraMediaMetadataDataSource, AgoraMediaMetadataDelegate>
24
-  @property (strong, nonatomic) NSData* metadata;
25
-
26
-  - (NSInteger) metadataMaxSize;
27
-
28
-  - (NSData *_Nullable)readyToSendMetadataAtTimestamp:(NSTimeInterval)timestamp;
29
-- (void)receiveMetadata:(NSData *_Nonnull)data fromUser:(NSInteger)uid atTimestamp:(NSTimeInterval)timestamp;
23
+@implementation RCTAgora {
24
+  RCTResponseSenderBlock _block;
25
+  bool hasListeners;
26
+}
30 27
 
28
++(BOOL)requiresMainQueueSetup {
29
+  return YES;
30
+}
31 31
 
32
-@end
33 32
 
34
-@implementation MediaMetaDataObserver
35
-  - (NSInteger) metadataMaxSize {
36
-    return MAX_DATA_LENGTH;
37
-  }
33
+- (NSInteger) metadataMaxSize {
34
+  return MAX_DATA_LENGTH;
35
+}
38 36
 
39
-  - (NSData *_Nullable)readyToSendMetadataAtTimestamp:(NSTimeInterval)timestamp
40
-  {
41
-    if (nil == _metadata) {
42
-      return nil;
43
-    }
44
-    NSData *toSend = [_metadata copy];
45
-    if ([toSend length] > MAX_DATA_LENGTH) {
46
-      return nil;
47
-    }
48
-    _metadata = nil;
49
-    return toSend;
37
+- (NSData *_Nullable)readyToSendMetadataAtTimestamp:(NSTimeInterval)timestamp
38
+{
39
+  if (nil == _metadata) {
40
+    return nil;
50 41
   }
51
-
52
-  - (void)receiveMetadata:(NSData *_Nonnull)data fromUser:(NSInteger)uid atTimestamp:(NSTimeInterval)timestamp {
53
-    NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
54
-    [RCTAgora sendEvent:AGMediaMetaDataRecevied params:@{
55
-                                                         @"uid": @(uid),
56
-                                                         @"data": dataStr,
57
-                                                         @"ts": @(timestamp)
58
-                                                         }];
42
+  NSData *toSend = [_metadata copy];
43
+  if ([toSend length] > MAX_DATA_LENGTH) {
44
+    return nil;
59 45
   }
60
-@end
61
-
62
-@implementation RCTAgora {
63
-  RCTResponseSenderBlock _block;
64
-  bool hasListeners;
46
+  _metadata = nil;
47
+  return toSend;
65 48
 }
66 49
 
67
-+(void) sendEvent:(NSString *)name params:(NSDictionary*)params {
68
-  [self sendEvent:name params:params];
69
-  return;
50
+- (void)receiveMetadata:(NSData *_Nonnull)data fromUser:(NSInteger)uid atTimestamp:(NSTimeInterval)timestamp {
51
+  NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
52
+  [self sendEvent:AGMediaMetaDataReceived params:@{
53
+                                               @"uid": @(uid),
54
+                                               @"data": dataStr,
55
+                                               @"ts": @(timestamp)
56
+                                               }];
70 57
 }
71 58
 
72
-+(BOOL)requiresMainQueueSetup {
73
-  return YES;
74
-}
75 59
 
76 60
 RCT_EXPORT_MODULE();
77 61
 
@@ -1977,11 +1961,27 @@ RCT_EXPORT_METHOD(setCameraCapturerConfiguration:(NSDictionary *)config
1977 1961
   }
1978 1962
 }
1979 1963
 
1964
+RCT_EXPORT_METHOD(sendMediaData:(NSString *)dataStr
1965
+                  resolve:(RCTPromiseResolveBlock)resolve
1966
+                  reject:(RCTPromiseRejectBlock)reject) {
1967
+  if ([self respondsToSelector:@selector(readyToSendMetadataAtTimestamp:)]) {
1968
+    self.metadata = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
1969
+    resolve(@{
1970
+              @"success": @(YES)
1971
+              });
1972
+  } else {
1973
+    reject(@"-1", @"sendMediaData failed", [self makeNSError:@{
1974
+                                                        @"code": @(-1),
1975
+                                                        @"message":@{
1976
+                                                          @"success": @(NO),
1977
+                                                        }}]);
1978
+  }
1979
+}
1980
+
1980 1981
 RCT_EXPORT_METHOD(registerMediaMetadataObserver
1981 1982
                   :(RCTPromiseResolveBlock)resolve
1982 1983
                   reject:(RCTPromiseRejectBlock)reject) {
1983
-  MediaMetaDataObserver *observer = [[MediaMetaDataObserver alloc] init];
1984
-  BOOL res = [_rtcEngine setMediaMetadataDataSource:observer withType:AgoraMetadataTypeVideo];
1984
+  BOOL res = [_rtcEngine setMediaMetadataDataSource:self withType:AgoraMetadataTypeVideo];
1985 1985
   if (res == YES) {
1986 1986
     resolve(@{
1987 1987
               @"success": @(YES)
@@ -2069,7 +2069,7 @@ RCT_EXPORT_METHOD(registerMediaMetadataObserver
2069 2069
            AGLocalVideoChanged,
2070 2070
            AGNetworkTypeChanged,
2071 2071
            AGFirstRemoteAudioFrame,
2072
-           AGMetaMediaDataRecevied
2072
+           AGMediaMetaDataReceived
2073 2073
            ];
2074 2074
 }
2075 2075
 

+ 5
- 4
lib/RtcEngine.native.d.ts ファイルの表示

@@ -977,18 +977,19 @@ declare class RtcEngine {
977 977
      * This method needs you invoke registerMediaMetadataObserver success first and you could send media data through interval media observer feature.
978 978
      * The data have limit length is 1024 bytes, if you pass data length bigger than limit it will failed.
979 979
      * @param data String: 1024 bytes limit
980
+     * @returns Promise<{success}>
980 981
      */
981
-    static sendMediaData(data: String): void;
982
+    static sendMediaData(data: String): Promise<any>;
982 983
     /**
983 984
      * Registers the metadata observer.
984 985
      *
985 986
      * note:
986 987
      * This method only work in live mode
987 988
      * This method enables you to add synchronized metadata in the video stream for more diversified live broadcast interactions, such as sending shopping links, digital coupons, and online quizzes.
988
-     * This method trigger 'metaMediaDataRecevied' event, here is example:
989
+     * This method trigger 'mediaMetaDataReceived' event, here is example:
989 990
      * ```javascript
990
-     *      RtcEngine.on("metaMediaDataRecevied", (data) => {
991
-     *        console.log("metaMediaDataRecevied", data);
991
+     *      RtcEngine.on("mediaMetaDataReceived", (data) => {
992
+     *        console.log("mediaMetaDataReceived", data);
992 993
      *      })
993 994
      * ```
994 995
      * @returns Promise{<success, value}>

+ 4
- 3
lib/RtcEngine.native.js ファイルの表示

@@ -1216,6 +1216,7 @@ class RtcEngine {
1216 1216
      * This method needs you invoke registerMediaMetadataObserver success first and you could send media data through interval media observer feature.
1217 1217
      * The data have limit length is 1024 bytes, if you pass data length bigger than limit it will failed.
1218 1218
      * @param data String: 1024 bytes limit
1219
+     * @returns Promise<{success}>
1219 1220
      */
1220 1221
     static sendMediaData(data) {
1221 1222
         return Agora.sendMediaData(data);
@@ -1226,10 +1227,10 @@ class RtcEngine {
1226 1227
      * note:
1227 1228
      * This method only work in live mode
1228 1229
      * This method enables you to add synchronized metadata in the video stream for more diversified live broadcast interactions, such as sending shopping links, digital coupons, and online quizzes.
1229
-     * This method trigger 'metaMediaDataRecevied' event, here is example:
1230
+     * This method trigger 'mediaMetaDataReceived' event, here is example:
1230 1231
      * ```javascript
1231
-     *      RtcEngine.on("metaMediaDataRecevied", (data) => {
1232
-     *        console.log("metaMediaDataRecevied", data);
1232
+     *      RtcEngine.on("mediaMetaDataReceived", (data) => {
1233
+     *        console.log("mediaMetaDataReceived", data);
1233 1234
      *      })
1234 1235
      * ```
1235 1236
      * @returns Promise{<success, value}>

+ 1
- 1
lib/RtcEngine.native.js.map
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 5
- 4
src/RtcEngine.native.ts ファイルの表示

@@ -1368,8 +1368,9 @@ class RtcEngine {
1368 1368
      * This method needs you invoke registerMediaMetadataObserver success first and you could send media data through interval media observer feature.
1369 1369
      * The data have limit length is 1024 bytes, if you pass data length bigger than limit it will failed.
1370 1370
      * @param data String: 1024 bytes limit
1371
+     * @returns Promise<{success}>
1371 1372
      */
1372
-    static sendMediaData(data: String): void {
1373
+    static sendMediaData(data: String): Promise<any> {
1373 1374
         return Agora.sendMediaData(data);
1374 1375
     }
1375 1376
 
@@ -1379,10 +1380,10 @@ class RtcEngine {
1379 1380
      * note:
1380 1381
      * This method only work in live mode
1381 1382
      * This method enables you to add synchronized metadata in the video stream for more diversified live broadcast interactions, such as sending shopping links, digital coupons, and online quizzes.
1382
-     * This method trigger 'metaMediaDataRecevied' event, here is example:
1383
+     * This method trigger 'mediaMetaDataReceived' event, here is example:
1383 1384
      * ```javascript
1384
-     *      RtcEngine.on("metaMediaDataRecevied", (data) => {
1385
-     *        console.log("metaMediaDataRecevied", data);
1385
+     *      RtcEngine.on("mediaMetaDataReceived", (data) => {
1386
+     *        console.log("mediaMetaDataReceived", data);
1386 1387
      *      })
1387 1388
      * ```
1388 1389
      * @returns Promise{<success, value}>