Procházet zdrojové kódy

feat. native ios & android integrate

feat. react module integrate
stage 1
matrixbirds před 5 roky
rodič
revize
c7708321cd

+ 1
- 0
android/src/main/java/com/syan/agora/AgoraManager.java Zobrazit soubor

@@ -13,6 +13,7 @@ import java.util.ArrayList;
13 13
 import java.util.List;
14 14
 import java.util.Map;
15 15
 
16
+import io.agora.rtc.IMetadataObserver;
16 17
 import io.agora.rtc.IRtcEngineEventHandler;
17 18
 import io.agora.rtc.RtcEngine;
18 19
 import io.agora.rtc.video.BeautyOptions;

+ 142
- 17
android/src/main/java/com/syan/agora/AgoraModule.java Zobrazit soubor

@@ -17,12 +17,14 @@ import com.facebook.react.bridge.WritableMap;
17 17
 import com.facebook.react.modules.core.DeviceEventManagerModule;
18 18
 
19 19
 
20
+import java.nio.charset.Charset;
20 21
 import java.util.ArrayList;
21 22
 import java.util.HashMap;
22 23
 import java.util.Map;
23 24
 
24 25
 import io.agora.rtc.Constants;
25 26
 import io.agora.rtc.IAudioEffectManager;
27
+import io.agora.rtc.IMetadataObserver;
26 28
 import io.agora.rtc.IRtcEngineEventHandler;
27 29
 import io.agora.rtc.RtcEngine;
28 30
 import io.agora.rtc.internal.LastmileProbeConfig;
@@ -285,6 +287,10 @@ public class AgoraModule extends ReactContextBaseJavaModule {
285 287
     private final static String AGUserEnableVideo = "userEnableVideo";
286 288
     private final static String AGUserEnableLocalVideo = "userEnableLocalVideo";
287 289
     private final static String AGVideoSizeChanged = "videoSizeChanged";
290
+    private final static String AGRtmpStreamingStateChanged = "rtmpStreamingStateChanged";
291
+    private final static String AGNetworkTypeChanged = "networkTypeChanged";
292
+    private final static String AGFirstRemoteAudioDecoded = "firstRemoteAudioDecoded";
293
+    private final static String AGMediaMetaDataRecevied = "mediaMetaDataRecevied";
288 294
     private final static String AGRemoteVideoStateChanged = "remoteVideoStateChanged";
289 295
     private final static String AGLocalPublishFallbackToAudioOnly = "localPublishFallbackToAudioOnly";
290 296
     private final static String AGRemoteSubscribeFallbackToAudioOnly = "remoteSubscribeFallbackToAudioOnly";
@@ -415,6 +421,8 @@ public class AgoraModule extends ReactContextBaseJavaModule {
415 421
                     statsMap.putInt("userCount", stats.users);
416 422
                     statsMap.putDouble("cpuAppUsage", stats.cpuAppUsage);
417 423
                     statsMap.putDouble("cpuTotalUsage", stats.cpuTotalUsage);
424
+                    statsMap.putInt("txPacketLossRate", stats.txPacketLossRate);
425
+                    statsMap.putInt("rxPacketLossRate", stats.rxPacketLossRate);
418 426
 
419 427
                     WritableMap map = Arguments.createMap();
420 428
                     map.putMap("stats", statsMap);
@@ -584,17 +592,17 @@ public class AgoraModule extends ReactContextBaseJavaModule {
584 592
             });
585 593
         }
586 594
 
587
-        @Override
588
-        public void onVideoStopped() {
589
-            runOnUiThread(new Runnable() {
590
-                @Override
591
-                public void run() {
592
-                    WritableMap map = Arguments.createMap();
593
-                    map.putString("message", "VideoStopped");
594
-                    sendEvent(getReactApplicationContext(), AGVideoStopped, map);
595
-                }
596
-            });
597
-        }
595
+//        @Override
596
+//        public void onVideoStopped() {
597
+//            runOnUiThread(new Runnable() {
598
+//                @Override
599
+//                public void run() {
600
+//                    WritableMap map = Arguments.createMap();
601
+//                    map.putString("message", "VideoStopped");
602
+//                    sendEvent(getReactApplicationContext(), AGVideoStopped, map);
603
+//                }
604
+//            });
605
+//        }
598 606
 
599 607
         @Override
600 608
         public void onFirstLocalVideoFrame(final int width, final int height, final int elapsed) {
@@ -710,6 +718,45 @@ public class AgoraModule extends ReactContextBaseJavaModule {
710 718
             });
711 719
         }
712 720
 
721
+        @Override
722
+        public void onRtmpStreamingStateChanged(final String url, final int state, final int errCode) {
723
+            runOnUiThread(new Runnable() {
724
+                @Override
725
+                public void run() {
726
+                    WritableMap map = Arguments.createMap();
727
+                    map.putString("url", url);
728
+                    map.putInt("state", state);
729
+                    map.putInt("errorCode", errCode);
730
+                    sendEvent(getReactApplicationContext(), AGRtmpStreamingStateChanged, map);
731
+                }
732
+            });
733
+        }
734
+
735
+        @Override
736
+        public void onNetworkTypeChanged(final int type) {
737
+            runOnUiThread(new Runnable() {
738
+                @Override
739
+                public void run() {
740
+                    WritableMap map = Arguments.createMap();
741
+                    map.putInt("type", type);
742
+                    sendEvent(getReactApplicationContext(), AGNetworkTypeChanged, map);
743
+                }
744
+            });
745
+        }
746
+
747
+        @Override
748
+        public void onFirstRemoteAudioDecoded(final int uid, final int elapsed) {
749
+            runOnUiThread(new Runnable() {
750
+                @Override
751
+                public void run() {
752
+                    WritableMap map = Arguments.createMap();
753
+                    map.putInt("uid", uid);
754
+                    map.putInt("elapsed", elapsed);
755
+                    sendEvent(getReactApplicationContext(), AGFirstRemoteAudioDecoded, map);
756
+                }
757
+            });
758
+        }
759
+
713 760
         @Override
714 761
         public void onRemoteVideoStateChanged(final int uid, final int state) {
715 762
             runOnUiThread(new Runnable() {
@@ -884,7 +931,8 @@ public class AgoraModule extends ReactContextBaseJavaModule {
884 931
                     WritableMap statsMap = Arguments.createMap();
885 932
                     statsMap.putInt("sentBitrate", stats.sentBitrate);
886 933
                     statsMap.putInt("sentFrameRate", stats.sentFrameRate);
887
-
934
+                    statsMap.putInt("encoderOutputFrameRate", stats.encoderOutputFrameRate);
935
+                    statsMap.putInt("rendererOutputFrameRate", stats.rendererOutputFrameRate);
888 936
                     WritableMap map = Arguments.createMap();
889 937
                     map.putMap("stats", statsMap);
890 938
                     sendEvent(getReactApplicationContext(), AGLocalVideoStats, map);
@@ -902,7 +950,7 @@ public class AgoraModule extends ReactContextBaseJavaModule {
902 950
                     statsMap.putInt("width", stats.width);
903 951
                     statsMap.putInt("height", stats.height);
904 952
                     statsMap.putInt("receivedBitrate", stats.receivedBitrate);
905
-                    statsMap.putInt("receivedFrameRate", stats.receivedFrameRate);
953
+                    statsMap.putInt("rendererOutputFrameRate", stats.rendererOutputFrameRate);
906 954
                     statsMap.putInt("rxStreamType", stats.rxStreamType);
907 955
                     WritableMap map = Arguments.createMap();
908 956
                     map.putMap("stats", statsMap);
@@ -1034,7 +1082,7 @@ public class AgoraModule extends ReactContextBaseJavaModule {
1034 1082
             runOnUiThread(new Runnable() {
1035 1083
                 @Override
1036 1084
                 public void run() {
1037
-                    String msg = new String(data);
1085
+                    String msg = new String(data, Charset.forName("UTF-8"));
1038 1086
                     WritableMap map = Arguments.createMap();
1039 1087
                     map.putInt("uid", uid);
1040 1088
                     map.putInt("streamId", streamId);
@@ -1713,6 +1761,33 @@ public class AgoraModule extends ReactContextBaseJavaModule {
1713 1761
         }
1714 1762
     }
1715 1763
 
1764
+    @ReactMethod
1765
+    public void getAudioMixingPlayoutVolume(Promise promise) {
1766
+        try {
1767
+            int res = AgoraManager.getInstance().mRtcEngine.getAudioMixingPlayoutVolume();
1768
+            if (res < 0) throw new ReactNativeAgoraException("getAudioMixingPlayoutVolume Failed", res);
1769
+            WritableMap map = Arguments.createMap();
1770
+            map.putString("volume", Integer.toString(res));
1771
+            promise.resolve(map);
1772
+        } catch (Exception e) {
1773
+            promise.reject("-1", e);
1774
+        }
1775
+    }
1776
+
1777
+    @ReactMethod
1778
+    public void getAudioMixingPublishVolume(Promise promise) {
1779
+        try {
1780
+            int res = AgoraManager.getInstance().mRtcEngine.getAudioMixingPlayoutVolume();
1781
+            if (res < 0) throw new ReactNativeAgoraException("getAudioMixingPublishVolume Failed", res);
1782
+            WritableMap map = Arguments.createMap();
1783
+            map.putBoolean("success", true);
1784
+            map.putInt("value", res);
1785
+            promise.resolve(map);
1786
+        } catch (Exception e) {
1787
+            promise.reject("-1", e);
1788
+        }
1789
+    }
1790
+
1716 1791
     @ReactMethod
1717 1792
     public void getAudioMixingDuration(Promise promise) {
1718 1793
         try {
@@ -1723,7 +1798,7 @@ public class AgoraModule extends ReactContextBaseJavaModule {
1723 1798
             map.putInt("value", res);
1724 1799
             promise.resolve(map);
1725 1800
         } catch (Exception e) {
1726
-            promise.reject("131004", e);
1801
+            promise.reject("-1", e);
1727 1802
         }
1728 1803
     }
1729 1804
 
@@ -2007,7 +2082,57 @@ public class AgoraModule extends ReactContextBaseJavaModule {
2007 2082
             map.putInt("value", res);
2008 2083
             promise.resolve(map);
2009 2084
         } catch (Exception e) {
2010
-            promise.reject("131030", e);
2085
+            promise.reject("-1", e);
2086
+        }
2087
+    }
2088
+
2089
+    private static final Integer MAX_META_DATA = 1024;
2090
+
2091
+    private byte[] metadata = null;
2092
+
2093
+    @ReactMethod
2094
+    public void sendMediaData(String data) {
2095
+        metadata = data.getBytes(Charset.forName("UTF-8"));
2096
+    }
2097
+
2098
+    @ReactMethod
2099
+    public void registerMediaMetadataObserver(final Promise promise) {
2100
+        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);
2127
+            if (res < 0) {
2128
+                new ReactNativeAgoraException("setRemoteDefaultVideoStreamType Failed", res);
2129
+            }
2130
+            WritableMap map = Arguments.createMap();
2131
+            map.putBoolean("success", true);
2132
+            map.putInt("value", res);
2133
+            promise.resolve(map);
2134
+        } catch (Exception e) {
2135
+            promise.reject("-1", e);
2011 2136
         }
2012 2137
     }
2013 2138
 
@@ -2443,7 +2568,7 @@ public class AgoraModule extends ReactContextBaseJavaModule {
2443 2568
             String data = options.getString("data");
2444 2569
             int streamID = AgoraManager.getInstance().mRtcEngine.createDataStream(reliable, ordered);
2445 2570
             if (streamID < 0) throw new ReactNativeAgoraException("createDataStream Failed", streamID);
2446
-            int res = AgoraManager.getInstance().mRtcEngine.sendStreamMessage(streamID, data.getBytes("utf8"));
2571
+            int res = AgoraManager.getInstance().mRtcEngine.sendStreamMessage(streamID, data.getBytes(Charset.forName("UTF-8")));
2447 2572
             if (res != 0) throw new ReactNativeAgoraException("sendStreamMessage Failed", res);
2448 2573
             WritableMap map = Arguments.createMap();
2449 2574
             map.putBoolean("success", true);

+ 6
- 0
ios/RCTAgora/AgoraConst.h Zobrazit soubor

@@ -29,6 +29,7 @@ static NSString *AGAudioVolumeIndication = @"audioVolumeIndication";
29 29
 static NSString *AGActiveSpeaker = @"activeSpeaker";
30 30
 static NSString *AGFirstLocalAudioFrame = @"firstLocalAudioFrame";
31 31
 static NSString *AGFirstRemoteAudioFrame = @"firstRemoteAudioFrame";
32
+static NSString *AGFirstRemoteAudioDecoded = @"firstRemoteAudioDecoded";
32 33
 static NSString *AGVideoStopped = @"videoStopped";
33 34
 static NSString *AGFirstLocalVideoFrame = @"firstLocalVideoFrame";
34 35
 static NSString *AGFirstRemoteVideoDecoded = @"firstRemoteVideoDecoded";
@@ -77,6 +78,11 @@ static NSString *AGIntervalTest = @"startEchoTestWithInterval";
77 78
 static NSString *AGAudioMixingStateChanged = @"audioMixingStateChanged";
78 79
 static NSString *AGLastmileProbeTestResult = @"lastmileProbeTestResult";
79 80
 
81
+static NSString *AGRtmpStreamingStateChanged = @"rtmpStreamingStateChanged";
82
+static NSString *AGLocalVideoChanged = @"localVideoChanged";
83
+static NSString *AGNetworkTypeChanged = @"networkTypeChanged";
84
+static NSString *AGMediaMetaDataRecevied = @"mediaMetaDataRecevied";
85
+
80 86
 typedef NS_ENUM(NSInteger, AgoraModeType) {
81 87
   AgoraAudioMode,
82 88
   AgoraVideoMode

+ 1
- 0
ios/RCTAgora/RCTAgora.h Zobrazit soubor

@@ -13,4 +13,5 @@
13 13
 
14 14
 @interface RCTAgora : RCTEventEmitter<RCTBridgeModule>
15 15
 
16
++(void) sendEvent:(NSString *)name params:(NSDictionary*)params;
16 17
 @end

+ 156
- 16
ios/RCTAgora/RCTAgora.m Zobrazit soubor

@@ -13,16 +13,62 @@
13 13
 #import <React/RCTView.h>
14 14
 #import "AgoraConst.h"
15 15
 
16
+#define MAX_DATA_LENGTH 1024
17
+
16 18
 @interface RCTAgora ()
17 19
 @property (strong, nonatomic) AgoraRtcEngineKit *rtcEngine;
18 20
 
19 21
 @end
20 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;
30
+
31
+
32
+@end
33
+
34
+@implementation MediaMetaDataObserver
35
+  - (NSInteger) metadataMaxSize {
36
+    return MAX_DATA_LENGTH;
37
+  }
38
+
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;
50
+  }
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
+                                                         }];
59
+  }
60
+@end
61
+
21 62
 @implementation RCTAgora {
22 63
   RCTResponseSenderBlock _block;
23 64
   bool hasListeners;
24 65
 }
25 66
 
67
++(void) sendEvent:(NSString *)name params:(NSDictionary*)params {
68
+  [self sendEvent:name params:params];
69
+  return;
70
+}
71
+
26 72
 +(BOOL)requiresMainQueueSetup {
27 73
   return YES;
28 74
 }
@@ -594,8 +640,8 @@ RCT_EXPORT_METHOD(getAudioMixingDuration
594 640
                   reject:(RCTPromiseRejectBlock)reject) {
595 641
   NSInteger res = [self.rtcEngine getAudioMixingDuration];
596 642
   if (res != 0) {
597
-    reject(@"131004", @"getAudioMixingDuration failed", [self makeNSError:@{
598
-                                                                            @"code": @(131004),
643
+    reject(@"-1", @"getAudioMixingDuration failed", [self makeNSError:@{
644
+                                                                            @"code": @(-1),
599 645
                                                                             @"message":@{
600 646
                                                                                 @"success": @(NO),
601 647
                                                                                 @"value":[NSNumber numberWithInteger:res]
@@ -609,6 +655,49 @@ RCT_EXPORT_METHOD(getAudioMixingDuration
609 655
   }
610 656
 }
611 657
 
658
+// get the volume of local audio mixing
659
+RCT_EXPORT_METHOD(getAudioMixingPlayoutVolume
660
+                  :(RCTPromiseResolveBlock)resolve
661
+                  reject:(RCTPromiseRejectBlock)reject) {
662
+  int res = [_rtcEngine getAudioMixingPlayoutVolume];
663
+  if (res < 0) {
664
+    reject(@"-1", @"getAudioMixingPlayoutVolume failed", [self makeNSError:@{
665
+                                                                            @"code": @(-1),
666
+                                                                            @"message":@{
667
+                                                                                @"success": @(NO),
668
+                                                                                @"value":[NSNumber numberWithInteger:res]
669
+                                                                                }
670
+                                                                            }]);
671
+  } else {
672
+    resolve(@{
673
+              @"success": @(YES),
674
+              @"value": @(res)
675
+              });
676
+  }
677
+}
678
+
679
+// get the volume of remote audio mixing
680
+RCT_EXPORT_METHOD(getAudioMixingPublishVolume
681
+                  :(RCTPromiseResolveBlock)resolve
682
+                  reject:(RCTPromiseRejectBlock)reject) {
683
+  int res = [_rtcEngine getAudioMixingPublishVolume];
684
+  if (res < 0) {
685
+    reject(@"-1", @"getAudioMixingPublishVolume failed", [self makeNSError:@{
686
+                                                                             @"code": @(-1),
687
+                                                                             @"message":@{
688
+                                                                                 @"success": @(NO),
689
+                                                                                 @"value":[NSNumber numberWithInteger:res]
690
+                                                                                 }
691
+                                                                             }]);
692
+  } else {
693
+    resolve(@{
694
+              @"success": @(YES),
695
+              @"value": @(res)
696
+              });
697
+  }
698
+}
699
+
700
+
612 701
 // get audio mixing current position
613 702
 RCT_EXPORT_METHOD(getAudioMixingCurrentPosition
614 703
                   :(RCTPromiseResolveBlock)resolve
@@ -1631,6 +1720,9 @@ RCT_EXPORT_METHOD(setLiveTranscoding:(NSDictionary *)options) {
1631 1720
   if (options[@"videoCodecProfile"] != nil) {
1632 1721
     transcoding.videoCodecProfile = (AgoraVideoCodecProfileType)[options[@"videoCodecProfile"] integerValue];
1633 1722
   }
1723
+  if (options[@"audioCodecProfile"] != nil) {
1724
+    transcoding.audioCodecProfile = (AgoraAudioCodecProfileType)[options[@"audioCodecProfile"] integerValue];
1725
+  }
1634 1726
   if (options[@"transcodingUsers"] != nil) {
1635 1727
     NSMutableArray<AgoraLiveTranscodingUser*> *transcodingUsers = [NSMutableArray new];
1636 1728
     for (NSDictionary *optionUser in options[@"users"]) {
@@ -1885,6 +1977,26 @@ RCT_EXPORT_METHOD(setCameraCapturerConfiguration:(NSDictionary *)config
1885 1977
   }
1886 1978
 }
1887 1979
 
1980
+RCT_EXPORT_METHOD(registerMediaMetadataObserver
1981
+                  :(RCTPromiseResolveBlock)resolve
1982
+                  reject:(RCTPromiseRejectBlock)reject) {
1983
+  MediaMetaDataObserver *observer = [[MediaMetaDataObserver alloc] init];
1984
+  BOOL res = [_rtcEngine setMediaMetadataDataSource:observer withType:AgoraMetadataTypeVideo];
1985
+  if (res == YES) {
1986
+    resolve(@{
1987
+              @"success": @(YES)
1988
+              });
1989
+  } else {
1990
+    reject(@"-1", @"registerMediaMetadataObserver failed", [self makeNSError:@{
1991
+                                                                             @"code": @(-1),
1992
+                                                                             @"message":@{
1993
+                                                                                 @"success": @(NO),
1994
+                                                                                 @"value":[NSNumber numberWithInteger:res]
1995
+                                                                                 }
1996
+                                                                             }]);
1997
+  }
1998
+}
1999
+
1888 2000
 - (NSArray<NSString *> *)supportedEvents {
1889 2001
   return @[
1890 2002
            AGWarning,
@@ -1906,6 +2018,7 @@ RCT_EXPORT_METHOD(setCameraCapturerConfiguration:(NSDictionary *)config
1906 2018
            AGActiveSpeaker,
1907 2019
            AGFirstLocalAudioFrame,
1908 2020
            AGFirstRemoteAudioFrame,
2021
+           AGFirstRemoteAudioDecoded,
1909 2022
            AGVideoStopped,
1910 2023
            AGFirstLocalVideoFrame,
1911 2024
            AGFirstRemoteVideoDecoded,
@@ -1951,7 +2064,12 @@ RCT_EXPORT_METHOD(setCameraCapturerConfiguration:(NSDictionary *)config
1951 2064
            AGMediaEngineStartCall,
1952 2065
            AGIntervalTest,
1953 2066
            AGAudioMixingStateChanged,
1954
-           AGLastmileProbeTestResult
2067
+           AGLastmileProbeTestResult,
2068
+           AGRtmpStreamingStateChanged,
2069
+           AGLocalVideoChanged,
2070
+           AGNetworkTypeChanged,
2071
+           AGFirstRemoteAudioFrame,
2072
+           AGMetaMediaDataRecevied
1955 2073
            ];
1956 2074
 }
1957 2075
 
@@ -2050,6 +2168,12 @@ RCT_EXPORT_METHOD(setCameraCapturerConfiguration:(NSDictionary *)config
2050 2168
                                            }];
2051 2169
 }
2052 2170
 
2171
+- (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine networkTypeChangedToType:(AgoraNetworkType)type {
2172
+  [self sendEvent:AGNetworkTypeChanged params:@{
2173
+                                                @"type": @(type)
2174
+                                                }];
2175
+}
2176
+
2053 2177
 - (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine connectionChangedToState:(AgoraConnectionStateType)state reason:(AgoraConnectionChangedReason)reason {
2054 2178
   [self sendEvent:AGConnectionStateChanged params:@{
2055 2179
                                                     @"state": @(state),
@@ -2114,10 +2238,11 @@ RCT_EXPORT_METHOD(setCameraCapturerConfiguration:(NSDictionary *)config
2114 2238
                                                       }];
2115 2239
 }
2116 2240
 
2117
-- (void)rtcEngineVideoDidStop:(AgoraRtcEngineKit *_Nonnull)engine {
2118
-  [self sendEvent:AGVideoStopped params:@{
2119
-                                        @"message": @"VideoStopped"
2120
-                                        }];
2241
+- (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine firstRemoteAudioFrameDecodedOfUid:(NSUInteger)uid elapsed:(NSInteger)elapsed {
2242
+  [self sendEvent:AGFirstRemoteAudioDecoded params:@{
2243
+                                                     @"uid": @(uid),
2244
+                                                     @"elapsed": @(elapsed)
2245
+                                                     }];
2121 2246
 }
2122 2247
 
2123 2248
 - (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine firstLocalVideoFrameWithSize:(CGSize)size elapsed:(NSInteger)elapsed {
@@ -2208,12 +2333,6 @@ RCT_EXPORT_METHOD(setCameraCapturerConfiguration:(NSDictionary *)config
2208 2333
                                                 }];
2209 2334
 }
2210 2335
 
2211
-- (void)rtcEngineCameraDidReady:(AgoraRtcEngineKit *_Nonnull)engine {
2212
-  [self sendEvent:AGCameraReady params:@{
2213
-                                          @"message": @"CameraDidReady"
2214
-                                          }];
2215
-}
2216
-
2217 2336
 - (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine cameraFocusDidChangedToRect:(CGRect)rect {
2218 2337
   [self sendEvent:AGCameraFocusAreaChanged params:@{
2219 2338
                                                        @"rect": @(rect)
@@ -2242,6 +2361,8 @@ RCT_EXPORT_METHOD(setCameraCapturerConfiguration:(NSDictionary *)config
2242 2361
   [self sendEvent:AGRtcStats params:@{
2243 2362
                                           @"stats": @{
2244 2363
                                               @"duration": @(stats.duration),
2364
+                                              @"txPacketLossRate": @(stats.txPacketLossRate),
2365
+                                              @"rxPacketLossRate": @(stats.rxPacketLossRate),
2245 2366
                                               @"txBytes": @(stats.txBytes),
2246 2367
                                               @"rxBytes": @(stats.rxBytes),
2247 2368
                                               @"txAudioKBitrate": @(stats.txAudioKBitrate),
@@ -2275,7 +2396,10 @@ RCT_EXPORT_METHOD(setCameraCapturerConfiguration:(NSDictionary *)config
2275 2396
                                            @"stats": @{
2276 2397
                                                @"sentBitrate": @(stats.sentBitrate),
2277 2398
                                                @"sentFrameRate": @(stats.sentFrameRate)
2278
-                                               }
2399
+                                               },
2400
+                                           @"encoderOutputFrameRate": @(stats.encoderOutputFrameRate),
2401
+                                           @"rendererOutputFrameRate":
2402
+                                               @(stats.rendererOutputFrameRate)
2279 2403
                                            }];
2280 2404
 }
2281 2405
 
@@ -2286,8 +2410,9 @@ RCT_EXPORT_METHOD(setCameraCapturerConfiguration:(NSDictionary *)config
2286 2410
                                                 @"width": @(stats.width),
2287 2411
                                                 @"height": @(stats.height),
2288 2412
                                                 @"receivedBitrate": @(stats.receivedBitrate),
2289
-                                                @"receivedFrameRate": @(stats.receivedFrameRate),
2290
-                                                @"rxStreamType": @(stats.rxStreamType)
2413
+                                                @"rendererOutputFrameRate": @(stats.rendererOutputFrameRate),
2414
+                                                @"rxStreamType": @(stats.rxStreamType),
2415
+                                                @"decoderOutputFrameRate": @(stats.decoderOutputFrameRate)
2291 2416
                                                 }
2292 2417
                                             }];
2293 2418
 }
@@ -2341,6 +2466,14 @@ RCT_EXPORT_METHOD(setCameraCapturerConfiguration:(NSDictionary *)config
2341 2466
                                            }];
2342 2467
 }
2343 2468
 
2469
+- (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine rtmpStreamingChangedToState:(NSString *_Nonnull)url state:(AgoraRtmpStreamingState)state errorCode:(AgoraRtmpStreamingErrorCode)errorCode {
2470
+  [self sendEvent:AGRtmpStreamingStateChanged params:@{
2471
+                                                       @"url": url,
2472
+                                                       @"state": @(state),
2473
+                                                       @"errorCode": @(errorCode)
2474
+                                                       }];
2475
+}
2476
+
2344 2477
 - (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine streamUnpublishedWithUrl:(NSString *_Nonnull)url {
2345 2478
   [self sendEvent:AGStreamUnpublish params:@{
2346 2479
                                            @"url": url,
@@ -2353,6 +2486,13 @@ RCT_EXPORT_METHOD(setCameraCapturerConfiguration:(NSDictionary *)config
2353 2486
                                               }];
2354 2487
 }
2355 2488
 
2489
+- (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine localVideoStateChange:(AgoraLocalVideoStreamState)state error:(AgoraLocalVideoStreamError)error {
2490
+  [self sendEvent:AGLocalVideoChanged params:@{
2491
+                                               @"state": @(state),
2492
+                                               @"errorCode": @(error)
2493
+                                               }];
2494
+}
2495
+
2356 2496
 - (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine streamInjectedStatusOfUrl:(NSString *_Nonnull)url uid:(NSUInteger)uid status:(AgoraInjectStreamStatus)status {
2357 2497
   [self sendEvent:AGStreamInjectedStatus params:@{
2358 2498
                                                 @"uid": @(uid),

+ 55
- 0
lib/RtcEngine.native.d.ts Zobrazit soubor

@@ -952,5 +952,60 @@ declare class RtcEngine {
952 952
      * @returns Promise<{success, value}>
953 953
      */
954 954
     static setCameraCapturerConfiguration(config: CameraCapturerConfiguration): Promise<any>;
955
+    /**
956
+     * Gets the audio mixing volume for local playback.
957
+     *
958
+     * note:
959
+     * This method helps troubleshoot audio volume related issues.
960
+     *
961
+     * @returns Promise{<success, value}>
962
+     */
963
+    static getAudioMixingPlayoutVolume(): Promise<any>;
964
+    /**
965
+     * Gets the audio mixing volume for publishing.
966
+     *
967
+     * note:
968
+     * This method helps troubleshoot audio volume related issues.
969
+     *
970
+     * @returns Promise{<success, value}>
971
+     */
972
+    static getAudioMixingPublishVolume(): Promise<any>;
973
+    /**
974
+     * sendMediaData for media observer.
975
+     *
976
+     * note:
977
+     * This method needs you invoke registerMediaMetadataObserver success first and you could send media data through interval media observer feature.
978
+     * The data have limit length is 1024 bytes, if you pass data length bigger than limit it will failed.
979
+     * @param data String: 1024 bytes limit
980
+     */
981
+    static sendMediaData(data: String): void;
982
+    /**
983
+     * Registers the metadata observer.
984
+     *
985
+     * note:
986
+     * This method only work in live mode
987
+     * 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
+     * ```javascript
990
+     *      RtcEngine.on("metaMediaDataRecevied", (data) => {
991
+     *        console.log("metaMediaDataRecevied", data);
992
+     *      })
993
+     * ```
994
+     * @returns Promise{<success, value}>
995
+     */
996
+    static registerMediaMetadataObserver(): Promise<any>;
997
+    /**
998
+     * Get local device camera support info
999
+     *
1000
+     * note:
1001
+     * This method returns your current device camera support info.
1002
+     * ```javascript
1003
+     *      RtcEngine.getCameraInfo().then(info => {
1004
+     *         console.log("your currrent camera", info);
1005
+     *      })
1006
+     * ```
1007
+     * @returns Promise{cameraSupportInfo}>
1008
+     */
1009
+    static getCameraInfo(): Promise<any>;
955 1010
 }
956 1011
 export default RtcEngine;

+ 81
- 0
lib/RtcEngine.native.js Zobrazit soubor

@@ -1,5 +1,6 @@
1 1
 "use strict";
2 2
 Object.defineProperty(exports, "__esModule", { value: true });
3
+const tslib_1 = require("tslib");
3 4
 const react_native_1 = require("react-native");
4 5
 const { Agora } = react_native_1.NativeModules;
5 6
 const AgoraEventEmitter = new react_native_1.NativeEventEmitter(Agora);
@@ -1186,6 +1187,86 @@ class RtcEngine {
1186 1187
     static setCameraCapturerConfiguration(config) {
1187 1188
         return Agora.setCameraCapturerConfiguration(config);
1188 1189
     }
1190
+    /**
1191
+     * Gets the audio mixing volume for local playback.
1192
+     *
1193
+     * note:
1194
+     * This method helps troubleshoot audio volume related issues.
1195
+     *
1196
+     * @returns Promise{<success, value}>
1197
+     */
1198
+    static getAudioMixingPlayoutVolume() {
1199
+        return Agora.getAudioMixingPlayoutVolume();
1200
+    }
1201
+    /**
1202
+     * Gets the audio mixing volume for publishing.
1203
+     *
1204
+     * note:
1205
+     * This method helps troubleshoot audio volume related issues.
1206
+     *
1207
+     * @returns Promise{<success, value}>
1208
+     */
1209
+    static getAudioMixingPublishVolume() {
1210
+        return Agora.getAudioMixingPublishVolume();
1211
+    }
1212
+    /**
1213
+     * sendMediaData for media observer.
1214
+     *
1215
+     * note:
1216
+     * This method needs you invoke registerMediaMetadataObserver success first and you could send media data through interval media observer feature.
1217
+     * The data have limit length is 1024 bytes, if you pass data length bigger than limit it will failed.
1218
+     * @param data String: 1024 bytes limit
1219
+     */
1220
+    static sendMediaData(data) {
1221
+        return Agora.sendMediaData(data);
1222
+    }
1223
+    /**
1224
+     * Registers the metadata observer.
1225
+     *
1226
+     * note:
1227
+     * This method only work in live mode
1228
+     * 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
+     * ```javascript
1231
+     *      RtcEngine.on("metaMediaDataRecevied", (data) => {
1232
+     *        console.log("metaMediaDataRecevied", data);
1233
+     *      })
1234
+     * ```
1235
+     * @returns Promise{<success, value}>
1236
+     */
1237
+    static registerMediaMetadataObserver() {
1238
+        return Agora.registerMediaMetadataObserver();
1239
+    }
1240
+    /**
1241
+     * Get local device camera support info
1242
+     *
1243
+     * note:
1244
+     * This method returns your current device camera support info.
1245
+     * ```javascript
1246
+     *      RtcEngine.getCameraInfo().then(info => {
1247
+     *         console.log("your currrent camera", info);
1248
+     *      })
1249
+     * ```
1250
+     * @returns Promise{cameraSupportInfo}>
1251
+     */
1252
+    static getCameraInfo() {
1253
+        return tslib_1.__awaiter(this, void 0, void 0, function* () {
1254
+            let zoomSupported = yield this.isCameraZoomSupported();
1255
+            let torchSupported = yield this.isCameraTorchSupported();
1256
+            let focusSupported = yield this.isCameraFocusSupported();
1257
+            let exposurePositionSupported = yield this.isCameraExposurePositionSupported();
1258
+            let autoFocusFaceModeSupported = yield this.isCameraAutoFocusFaceModeSupported();
1259
+            let maxZoomFactor = yield this.getCameraMaxZoomFactor();
1260
+            return {
1261
+                zoomSupported,
1262
+                torchSupported,
1263
+                focusSupported,
1264
+                exposurePositionSupported,
1265
+                autoFocusFaceModeSupported,
1266
+                maxZoomFactor
1267
+            };
1268
+        });
1269
+    }
1189 1270
 }
1190 1271
 RtcEngine.eventTypes = new Set();
1191 1272
 exports.default = RtcEngine;

+ 1
- 1
lib/RtcEngine.native.js.map
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 84
- 0
src/RtcEngine.native.ts Zobrazit soubor

@@ -1336,6 +1336,90 @@ class RtcEngine {
1336 1336
     static setCameraCapturerConfiguration(config: CameraCapturerConfiguration): Promise<any> {
1337 1337
         return Agora.setCameraCapturerConfiguration(config);
1338 1338
     }
1339
+
1340
+    /**
1341
+     * Gets the audio mixing volume for local playback.
1342
+     * 
1343
+     * note:
1344
+     * This method helps troubleshoot audio volume related issues.
1345
+     * 
1346
+     * @returns Promise{<success, value}>
1347
+     */
1348
+    static getAudioMixingPlayoutVolume(): Promise<any> {
1349
+        return Agora.getAudioMixingPlayoutVolume();
1350
+    }
1351
+
1352
+    /**
1353
+     * Gets the audio mixing volume for publishing.
1354
+     * 
1355
+     * note:
1356
+     * This method helps troubleshoot audio volume related issues.
1357
+     * 
1358
+     * @returns Promise{<success, value}>
1359
+     */
1360
+    static getAudioMixingPublishVolume(): Promise<any> {
1361
+        return Agora.getAudioMixingPublishVolume();
1362
+    }
1363
+
1364
+    /**
1365
+     * sendMediaData for media observer.
1366
+     * 
1367
+     * note:
1368
+     * This method needs you invoke registerMediaMetadataObserver success first and you could send media data through interval media observer feature.
1369
+     * The data have limit length is 1024 bytes, if you pass data length bigger than limit it will failed.
1370
+     * @param data String: 1024 bytes limit
1371
+     */
1372
+    static sendMediaData(data: String): void {
1373
+        return Agora.sendMediaData(data);
1374
+    }
1375
+
1376
+    /**
1377
+     * Registers the metadata observer.
1378
+     * 
1379
+     * note:
1380
+     * This method only work in live mode
1381
+     * 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
+     * ```javascript
1384
+     *      RtcEngine.on("metaMediaDataRecevied", (data) => {
1385
+     *        console.log("metaMediaDataRecevied", data);
1386
+     *      })
1387
+     * ```
1388
+     * @returns Promise{<success, value}>
1389
+     */
1390
+    static registerMediaMetadataObserver(): Promise<any> {
1391
+        return Agora.registerMediaMetadataObserver();
1392
+    }
1393
+
1394
+    /**
1395
+     * Get local device camera support info
1396
+     * 
1397
+     * note:
1398
+     * This method returns your current device camera support info.
1399
+     * ```javascript
1400
+     *      RtcEngine.getCameraInfo().then(info => {
1401
+     *         console.log("your currrent camera", info);
1402
+     *      })
1403
+     * ```
1404
+     * @returns Promise{cameraSupportInfo}>
1405
+     */
1406
+    static async getCameraInfo(): Promise<any> {
1407
+        let zoomSupported = await this.isCameraZoomSupported();
1408
+        let torchSupported = await this.isCameraTorchSupported();
1409
+        let focusSupported = await this.isCameraFocusSupported();
1410
+        let exposurePositionSupported = await this.isCameraExposurePositionSupported();
1411
+        let autoFocusFaceModeSupported = await this.isCameraAutoFocusFaceModeSupported();
1412
+        let maxZoomFactor = await this.getCameraMaxZoomFactor();
1413
+        return {
1414
+            zoomSupported,
1415
+            torchSupported,
1416
+            focusSupported,
1417
+            exposurePositionSupported,
1418
+            autoFocusFaceModeSupported,
1419
+            maxZoomFactor
1420
+        }
1421
+    }
1422
+
1339 1423
 }
1340 1424
 
1341 1425