Browse Source

android add sdk

邓博 7 years ago
parent
commit
15c2526e32

BIN
android/libs/agora-rtc-sdk.jar View File


+ 17
- 0
android/proguard-rules.pro View File

@@ -0,0 +1,17 @@
1
+# Add project specific ProGuard rules here.
2
+# By default, the flags in this file are appended to flags specified
3
+# in /Users/DB/Library/Android/sdk/tools/proguard/proguard-android.txt
4
+# You can edit the include path and order by changing the proguardFiles
5
+# directive in build.gradle.
6
+#
7
+# For more details, see
8
+#   http://developer.android.com/guide/developing/tools/proguard.html
9
+
10
+# Add any project specific keep options here:
11
+
12
+# If your project uses WebView with JS, uncomment the following
13
+# and specify the fully qualified class name to the JavaScript interface
14
+# class:
15
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16
+#   public *;
17
+#}

+ 10
- 8
android/react-native-agora.iml View File

@@ -67,14 +67,6 @@
67 67
       <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
68 68
       <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
69 69
       <sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
70
-      <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
71
-      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
72
-      <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
73
-      <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
74
-      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
75
-      <sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
76
-      <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
77
-      <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
78 70
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
79 71
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
80 72
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
@@ -83,6 +75,15 @@
83 75
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
84 76
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
85 77
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
78
+      <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
79
+      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
80
+      <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
81
+      <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
82
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
83
+      <sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
84
+      <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
85
+      <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
86
+      <excludeFolder url="file://$MODULE_DIR$/build/.DS_Store" />
86 87
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotations" />
87 88
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
88 89
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
@@ -132,6 +133,7 @@
132 133
     <orderEntry type="library" exported="" name="okhttp-3.4.1" level="project" />
133 134
     <orderEntry type="library" exported="" name="staticlayout-proxy-1.0" level="project" />
134 135
     <orderEntry type="library" exported="" name="react-native-0.44.3" level="project" />
136
+    <orderEntry type="library" exported="" name="agora-rtc-sdk" level="project" />
135 137
     <orderEntry type="library" exported="" name="support-v4-23.0.1" level="project" />
136 138
     <orderEntry type="library" exported="" name="imagepipeline-okhttp3-1.0.1" level="project" />
137 139
     <orderEntry type="library" exported="" name="appcompat-v7-23.0.1" level="project" />

+ 9
- 0
android/src/main/AndroidManifest.xml View File

@@ -1,5 +1,14 @@
1 1
 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.syan.agora">
2 2
 
3
+    <uses-permission android:name="android.permission.INTERNET" />
4
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
5
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
6
+    <uses-permission android:name="android.permission.CAMERA" />
7
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
8
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
9
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
10
+    <uses-permission android:name="android.permission.BLUETOOTH" />
11
+
3 12
     <application android:allowBackup="true" android:label="@string/app_name"
4 13
         android:supportsRtl="true">
5 14
 

+ 227
- 0
android/src/main/java/com/syan/agora/AgoraModule.java View File

@@ -1,15 +1,140 @@
1 1
 package com.syan.agora;
2 2
 
3
+import android.content.Context;
4
+import android.os.Handler;
3 5
 import android.util.Log;
6
+import android.view.SurfaceView;
7
+import android.view.View;
4 8
 
5 9
 import com.facebook.react.bridge.ReactApplicationContext;
6 10
 import com.facebook.react.bridge.ReactContextBaseJavaModule;
7 11
 import com.facebook.react.bridge.ReactMethod;
8 12
 import com.facebook.react.bridge.ReadableMap;
13
+import com.facebook.react.modules.core.DeviceEventManagerModule;
14
+import com.facebook.react.uimanager.NativeViewHierarchyManager;
15
+import com.facebook.react.uimanager.UIBlock;
16
+import com.facebook.react.uimanager.UIManagerModule;
17
+import com.facebook.react.views.view.ReactViewGroup;
18
+
19
+import io.agora.rtc.Constants;
20
+import io.agora.rtc.IRtcEngineEventHandler;
21
+import io.agora.rtc.RtcEngine;
22
+import io.agora.rtc.video.VideoCanvas;
9 23
 
10 24
 public class AgoraModule extends ReactContextBaseJavaModule {
11 25
 
26
+    private RtcEngine mRtcEngine;
27
+
28
+    private Context mContext;
29
+
30
+    private static ReactApplicationContext mRAC;
31
+
32
+    private IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
33
+
34
+        /**
35
+         * 当获取用户uid的远程视频的回调
36
+         */
37
+        @Override
38
+        public void onFirstRemoteVideoDecoded(final int uid, int width, int height, int elapsed) {
39
+//            runOnUiThread(new Runnable() {
40
+//                @Override
41
+//                public void run() {
42
+//                    mRAC
43
+//                            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
44
+//                            .emit("onFirstRemoteVideoDecoded", uid);
45
+//                }
46
+//            });
47
+
48
+            new Handler().post(new Runnable() {
49
+                @Override
50
+                public void run() {
51
+                    mRAC.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
52
+                            .emit("onFirstRemoteVideoDecoded", uid);
53
+                }
54
+            });
55
+
56
+
57
+
58
+        }
59
+
60
+        /**
61
+         * 加入频道成功的回调
62
+         */
63
+        @Override
64
+        public void onJoinChannelSuccess(String channel,final int uid, int elapsed) {
65
+
66
+            Log.i("Agora", "加入房间成功---");
67
+            mRAC
68
+                    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
69
+                    .emit("onJoinChannelSuccess",uid);
70
+
71
+//            new Handler().post(new Runnable() {
72
+//                @Override
73
+//                public void run() {
74
+//                    mRAC
75
+//                            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
76
+//                            .emit("onJoinChannelSuccess",uid);
77
+//                }
78
+//            });
79
+
80
+
81
+        }
82
+
83
+        /**
84
+         * 其他用户加入当前频道
85
+         */
86
+        @Override
87
+        public void onUserJoined(final int uid, int elapsed) {
88
+
89
+            Log.i("Agora", "有人来了----");
90
+
91
+            new Handler().post(new Runnable() {
92
+                @Override
93
+                public void run() {
94
+                    mRAC
95
+                            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
96
+                            .emit("onUserJoined", uid);
97
+                }
98
+            });
99
+
100
+        }
101
+
102
+        /**
103
+         * 错误信息
104
+         */
105
+        @Override
106
+        public void onError(int err) {
107
+            Log.i("Agora", err + "错误---");
108
+        }
109
+
110
+        /**
111
+         * 警告
112
+         */
113
+        @Override
114
+        public void onWarning(int warn) {
115
+            Log.i("Agora", warn + "警告---");
116
+        }
117
+
118
+        /**
119
+         * 退出频道
120
+         */
121
+        @Override
122
+        public void onLeaveChannel(RtcStats stats) {
123
+
124
+        }
125
+
126
+        /**
127
+         * 用户uid离线时的回调
128
+         */
129
+        @Override
130
+        public void onUserOffline(int uid, int reason) {
131
+
132
+        }
133
+    };
134
+
135
+
12 136
     public AgoraModule(ReactApplicationContext context) {
137
+
13 138
         super(context);
14 139
     }
15 140
 
@@ -18,9 +143,111 @@ public class AgoraModule extends ReactContextBaseJavaModule {
18 143
         return "RCTAgora";
19 144
     }
20 145
 
146
+
21 147
     @ReactMethod
22 148
     public void loadAgoraKit(ReadableMap options) {
23 149
         Log.i("Agora", options.toString());
150
+
151
+        mContext = getCurrentActivity();
152
+        mRAC = getReactApplicationContext();
153
+
154
+        mRtcEngine = RtcEngine.create(mContext, options.getString("appid"), mRtcEventHandler);
155
+        mRtcEngine.enableVideo();
156
+//        mRtcEngine.setChannelProfile(options.getInt("channelProfile"));
157
+//        mRtcEngine.setVideoProfile(options.getInt("videoProfile"), true);
158
+
159
+        mRtcEngine.enableWebSdkInteroperability(true);
160
+        mRtcEngine.setVideoProfile(Constants.VIDEO_PROFILE_360P, false);
161
+        mRtcEngine.setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING);
162
+
163
+        mRtcEngine.joinChannel(null, options.getString("channelName"), options.getString("info"), 0);
164
+
165
+
166
+
167
+    }
168
+
169
+    @ReactMethod
170
+    public void setupLocalVideo(final int uid, final int tag) {
171
+
172
+        final UIManagerModule uiManager = getReactApplicationContext().getNativeModule
173
+                (UIManagerModule.class);
174
+        uiManager.addUIBlock(new UIBlock() {
175
+            @Override
176
+            public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
177
+
178
+                ReactViewGroup dView = (ReactViewGroup)nativeViewHierarchyManager.resolveView(tag);
179
+
180
+                Log.i("Agora", dView.getWidth() + "dView");
181
+                Log.i("Agora", dView.getHeight() + "dView");
182
+
183
+                SurfaceView surfaceView = RtcEngine.CreateRendererView(getReactApplicationContext());
184
+
185
+                Log.i("Agora", surfaceView.getWidth() + "surfaceView");
186
+                Log.i("Agora", getReactApplicationContext().toString());
187
+                Log.i("Agora", surfaceView.toString());
188
+
189
+                dView.addView(surfaceView);
190
+
191
+                mRtcEngine.setupLocalVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_HIDDEN, uid));
192
+                mRtcEngine.startPreview();
193
+
194
+            }
195
+        });
24 196
     }
25 197
 
198
+
199
+    @ReactMethod
200
+    public void setupRemoteVideo(final int uid, final int tag) {
201
+
202
+        final UIManagerModule uiManager = getReactApplicationContext().getNativeModule
203
+                (UIManagerModule.class);
204
+        uiManager.addUIBlock(new UIBlock() {
205
+            @Override
206
+            public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
207
+
208
+                View dView = nativeViewHierarchyManager.resolveView(tag);
209
+
210
+                SurfaceView surfaceView = RtcEngine.CreateRendererView(dView.getContext());
211
+
212
+//                ViewGroup gView = (ViewGroup) dView;
213
+//                gView.addView(surfaceView);
214
+
215
+//                Log.i("Agora", surfaceView.getWidth() + "");
216
+//                Log.i("Agora", uid+"---"+tag);
217
+//
218
+                mRtcEngine.setupRemoteVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_HIDDEN, uid));
219
+
220
+            }
221
+        });
222
+    }
26 223
 }
224
+
225
+//                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
226
+//                surfaceView.setZOrderOnTop(false);
227
+//                surfaceView.setZOrderMediaOverlay(false);
228
+
229
+//                int w = dView.getWidth();
230
+//                int h = dView.getHeight();
231
+//                surfaceView.measure(w, h);
232
+//                int height =surfaceView.getMeasuredHeight();
233
+
234
+//                ViewGroup.LayoutParams params = (ViewGroup.LayoutParams) surfaceView.getLayoutParams();
235
+//                params.width = 120;
236
+//                params.height = 120;
237
+//                surfaceView.setLayoutParams(params);
238
+
239
+//                Log.i("Agora", surfaceView.getWidth() + "surfaceView");
240
+//                Log.i("Agora", uid+"---"+tag);
241
+
242
+//                ViewGroup gView = (ViewGroup) dView;
243
+//                Log.i("Agora", gView.getWidth() + "gView");
244
+//                Log.i("Agora", gView.getHeight() + "gView");
245
+//
246
+//                gView.addView(surfaceView);
247
+//Button button = new Button(dView.getContext());
248
+//button.setText("123");
249
+//
250
+//        dView.addView(button);
251
+//                ArrayList<View> list = new ArrayList<>();
252
+//                list.add(surfaceView);
253
+//                dView.addChildrenForAccessibility(list);

+ 1
- 0
android/src/main/java/com/syan/agora/AgoraPackage.java View File

@@ -11,6 +11,7 @@ import java.util.Collections;
11 11
 import java.util.List;
12 12
 
13 13
 public class AgoraPackage implements ReactPackage {
14
+
14 15
     @Override
15 16
     public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
16 17
         return Arrays.asList(new NativeModule[]{

BIN
android/src/main/jniLibs/arm64-v8a/libHDACEngine.so View File


BIN
android/src/main/jniLibs/arm64-v8a/libagora-crypto.so View File


BIN
android/src/main/jniLibs/arm64-v8a/libagora-rtc-sdk-jni.so View File


BIN
android/src/main/jniLibs/armeabi-v7a/libHDACEngine.so View File


BIN
android/src/main/jniLibs/armeabi-v7a/libagora-crypto.so View File


BIN
android/src/main/jniLibs/armeabi-v7a/libagora-rtc-sdk-jni.so View File


+ 175
- 0
android/src/main/jniLibs/include/IAgoraMediaEngine.h View File

@@ -0,0 +1,175 @@
1
+#ifndef AGORA_MEDIA_ENGINE_H
2
+#define AGORA_MEDIA_ENGINE_H
3
+#if defined _WIN32 || defined __CYGWIN__
4
+typedef __int64 int64_t;
5
+typedef unsigned __int64 uint64_t;
6
+#else
7
+#include <stdint.h>
8
+#endif
9
+
10
+namespace agora
11
+{
12
+namespace media
13
+{
14
+
15
+class IAudioFrameObserver
16
+{
17
+public:
18
+  enum AUDIO_FRAME_TYPE {
19
+    FRAME_TYPE_PCM16 = 0,  //PCM 16bit little endian
20
+  };
21
+  struct AudioFrame {
22
+    AUDIO_FRAME_TYPE type;
23
+    int samples;  //number of samples in this frame
24
+    int bytesPerSample;  //number of bytes per sample: 2 for PCM16
25
+    int channels;  //number of channels (data are interleaved if stereo)
26
+    int samplesPerSec;  //sampling rate
27
+    void* buffer;  //data buffer
28
+    int64_t renderTimeMs;
29
+  };
30
+public:
31
+  virtual bool onRecordAudioFrame(AudioFrame& audioFrame) = 0;
32
+  virtual bool onPlaybackAudioFrame(AudioFrame& audioFrame) = 0;
33
+  virtual bool onMixedAudioFrame(AudioFrame& audioFrame) = 0;
34
+  virtual bool onPlaybackAudioFrameBeforeMixing(unsigned int uid, AudioFrame& audioFrame) = 0;
35
+};
36
+
37
+class IVideoFrameObserver
38
+{
39
+public:
40
+  enum VIDEO_FRAME_TYPE {
41
+    FRAME_TYPE_YUV420 = 0,  //YUV 420 format
42
+  };
43
+  struct VideoFrame {
44
+    VIDEO_FRAME_TYPE type;
45
+    int width;  //width of video frame
46
+    int height;  //height of video frame
47
+    int yStride;  //stride of Y data buffer
48
+    int uStride;  //stride of U data buffer
49
+    int vStride;  //stride of V data buffer
50
+    void* yBuffer;  //Y data buffer
51
+    void* uBuffer;  //U data buffer
52
+    void* vBuffer;  //V data buffer
53
+    int rotation; // rotation of this frame (0, 90, 180, 270)
54
+    int64_t renderTimeMs;
55
+  };
56
+public:
57
+  virtual bool onCaptureVideoFrame(VideoFrame& videoFrame) = 0;
58
+  virtual bool onRenderVideoFrame(unsigned int uid, VideoFrame& videoFrame) = 0;
59
+};
60
+
61
+class IVideoFrame
62
+{
63
+public:
64
+  enum PLANE_TYPE {
65
+    Y_PLANE = 0,
66
+    U_PLANE = 1,
67
+    V_PLANE = 2,
68
+    NUM_OF_PLANES = 3
69
+  };
70
+  enum VIDEO_TYPE {
71
+    VIDEO_TYPE_UNKNOWN = 0,
72
+    VIDEO_TYPE_I420 = 1,
73
+    VIDEO_TYPE_IYUV = 2,
74
+    VIDEO_TYPE_RGB24 = 3,
75
+    VIDEO_TYPE_ABGR = 4,
76
+    VIDEO_TYPE_ARGB = 5,
77
+    VIDEO_TYPE_ARGB4444 = 6,
78
+    VIDEO_TYPE_RGB565 = 7,
79
+    VIDEO_TYPE_ARGB1555 = 8,
80
+    VIDEO_TYPE_YUY2 = 9,
81
+    VIDEO_TYPE_YV12 = 10,
82
+    VIDEO_TYPE_UYVY = 11,
83
+    VIDEO_TYPE_MJPG = 12,
84
+    VIDEO_TYPE_NV21 = 13,
85
+    VIDEO_TYPE_NV12 = 14,
86
+    VIDEO_TYPE_BGRA = 15,
87
+    VIDEO_TYPE_RGBA = 16,
88
+  };
89
+  virtual void release() = 0;
90
+  virtual const unsigned char* buffer(PLANE_TYPE type) const = 0;
91
+
92
+  // Copy frame: If required size is bigger than allocated one, new buffers of
93
+  // adequate size will be allocated.
94
+  // Return value: 0 on success ,-1 on error.
95
+  virtual int copyFrame(IVideoFrame** dest_frame) const = 0;
96
+
97
+  // Convert frame
98
+  // Input:
99
+  //   - src_frame        : Reference to a source frame.
100
+  //   - dst_video_type   : Type of output video.
101
+  //   - dst_sample_size  : Required only for the parsing of MJPG.
102
+  //   - dst_frame        : Pointer to a destination frame.
103
+  // Return value: 0 if OK, < 0 otherwise.
104
+  // It is assumed that source and destination have equal height.
105
+  virtual int convertFrame(VIDEO_TYPE dst_video_type, int dst_sample_size, unsigned char* dst_frame) const = 0;
106
+
107
+  // Get allocated size per plane.
108
+  virtual int allocated_size(PLANE_TYPE type) const = 0;
109
+
110
+  // Get allocated stride per plane.
111
+  virtual int stride(PLANE_TYPE type) const = 0;
112
+
113
+  // Get frame width.
114
+  virtual int width() const = 0;
115
+
116
+  // Get frame height.
117
+  virtual int height() const = 0;
118
+
119
+  // Get frame timestamp (90kHz).
120
+  virtual unsigned int timestamp() const = 0;
121
+
122
+  // Get render time in milliseconds.
123
+  virtual int64_t render_time_ms() const = 0;
124
+
125
+  // Return true if underlying plane buffers are of zero size, false if not.
126
+  virtual bool IsZeroSize() const = 0;
127
+};
128
+
129
+class IExternalVideoRenderCallback
130
+{
131
+public:
132
+  virtual void onViewSizeChanged(int width, int height) = 0;
133
+  virtual void onViewDestroyed() = 0;
134
+};
135
+
136
+struct ExternalVideoRenerContext
137
+{
138
+  IExternalVideoRenderCallback* renderCallback;
139
+  void* view;
140
+  int renderMode;
141
+  int zOrder;
142
+  float left;
143
+  float top;
144
+  float right;
145
+  float bottom;
146
+};
147
+
148
+class IExternalVideoRender
149
+{
150
+public:
151
+  virtual void release() = 0;
152
+  virtual int initialize() = 0;
153
+  virtual int deliverFrame(const IVideoFrame& videoFrame, int rotation, bool mirrored) = 0;
154
+};
155
+
156
+class IExternalVideoRenderFactory
157
+{
158
+public:
159
+  virtual IExternalVideoRender* createRenderInstance(const ExternalVideoRenerContext& context) = 0;
160
+};
161
+
162
+class IMediaEngine
163
+{
164
+public:
165
+  virtual void release() = 0;
166
+  virtual int registerAudioFrameObserver(IAudioFrameObserver* observer) = 0;
167
+  virtual int registerVideoFrameObserver(IVideoFrameObserver* observer) = 0;
168
+  virtual int registerVideoRenderFactory(IExternalVideoRenderFactory* factory) = 0;
169
+};
170
+
171
+} //media
172
+
173
+} //agora
174
+
175
+#endif //AGORA_MEDIA_ENGINE_H

+ 1964
- 0
android/src/main/jniLibs/include/IAgoraRtcEngine.h
File diff suppressed because it is too large
View File


BIN
android/src/main/jniLibs/x86/libHDACEngine.so View File


BIN
android/src/main/jniLibs/x86/libagora-crypto.so View File


BIN
android/src/main/jniLibs/x86/libagora-rtc-sdk-jni.so View File


BIN
ios/RCTAgora.xcodeproj/project.xcworkspace/xcuserdata/DB.xcuserdatad/UserInterfaceState.xcuserstate View File


+ 153
- 9
ios/RCTAgora/RCTAgora.m View File

@@ -23,9 +23,8 @@ RCT_EXPORT_MODULE();
23 23
 
24 24
 @synthesize bridge = _bridge;
25 25
 
26
-- (void)dealloc
27
-{
28
-    //销毁引擎实例
26
+//销毁引擎实例
27
+- (void)dealloc {
29 28
     [AgoraRtcEngineKit destroy];
30 29
 }
31 30
 
@@ -46,8 +45,7 @@ RCT_EXPORT_MODULE();
46 45
  *  @param reactTag        绑定view的tag
47 46
  *  @return 0 when executed successfully. return negative value if failed.
48 47
  */
49
-RCT_EXPORT_METHOD(loadAgoraKit:(NSDictionary *)options)
50
-{
48
+RCT_EXPORT_METHOD(loadAgoraKit:(NSDictionary *)options callback:(RCTResponseSenderBlock)callback) {
51 49
     
52 50
     self.rtcEngine = [AgoraRtcEngineKit sharedEngineWithAppId:options[@"appid"] delegate:self];
53 51
     
@@ -64,6 +62,13 @@ RCT_EXPORT_METHOD(loadAgoraKit:(NSDictionary *)options)
64 62
     
65 63
     [self.rtcEngine joinChannelByKey:nil channelName:options[@"channelName"] info:options[@"info"] uid:0 joinSuccess:^(NSString *channel, NSUInteger uid, NSInteger elapsed) {
66 64
         
65
+        NSMutableDictionary *params = [NSMutableDictionary dictionary];
66
+        
67
+        params[@"channel"] = channel;
68
+        params[@"uid"] = [NSNumber numberWithInteger:uid];
69
+        params[@"elapsed"] = [NSNumber numberWithInteger:elapsed];
70
+        callback(@[params]);
71
+        
67 72
         //绑定本地视图
68 73
         AgoraRtcVideoCanvas *canvas = [[AgoraRtcVideoCanvas alloc] init];
69 74
         canvas.uid = uid;
@@ -78,17 +83,156 @@ RCT_EXPORT_METHOD(loadAgoraKit:(NSDictionary *)options)
78 83
     
79 84
 }
80 85
 
86
+
87
+//离开频道
88
+RCT_EXPORT_METHOD(leaveChannel){
89
+    [AgoraRtcEngineKit destroy];
90
+    [self.rtcEngine leaveChannel:^(AgoraRtcStats *stat) {
91
+        
92
+    }];
93
+}
94
+
95
+//设置 本地 视频显示属性
96
+RCT_EXPORT_METHOD(setupLocalVideo:(NSDictionary *)options){
97
+    AgoraRtcVideoCanvas *canvas = [[AgoraRtcVideoCanvas alloc] init];
98
+    canvas.uid = [options[@"uid"] integerValue];
99
+    canvas.view = [self.bridge.uiManager viewForReactTag:options[@"reactTag"]];
100
+    canvas.renderMode = [options[@"renderMode"] integerValue];
101
+    [self.rtcEngine setupLocalVideo:canvas];
102
+}
103
+
104
+//设置 远端 视频显示视图
105
+RCT_EXPORT_METHOD(setupRemoteVideo:(NSDictionary *)options){
106
+    AgoraRtcVideoCanvas *canvas = [[AgoraRtcVideoCanvas alloc] init];
107
+    canvas.uid = [options[@"uid"] integerValue];
108
+    canvas.view = [self.bridge.uiManager viewForReactTag:options[@"reactTag"]];
109
+    canvas.renderMode = [options[@"renderMode"] integerValue];
110
+    [self.rtcEngine setupRemoteVideo:canvas];
111
+}
112
+
113
+//切换前置/后置摄像头
114
+RCT_EXPORT_METHOD(switchCamera){
115
+    [self.rtcEngine switchCamera];
116
+}
117
+
118
+//开启视频模式
119
+RCT_EXPORT_METHOD(enableVideo){
120
+    [self.rtcEngine enableVideo];
121
+}
122
+
123
+//关闭视频
124
+RCT_EXPORT_METHOD(disableVideo){
125
+    [self.rtcEngine disableVideo];
126
+}
127
+
128
+//开启扬声器  Yes: 音频输出至扬声器  No: 音频输出至听筒
129
+RCT_EXPORT_METHOD(setEnableSpeakerphone:(BOOL)enableSpeaker){
130
+    [self.rtcEngine setEnableSpeakerphone: enableSpeaker];
131
+}
132
+
133
+//将自己静音
134
+RCT_EXPORT_METHOD(muteLocalAudioStream:(BOOL)mute){
135
+    [self.rtcEngine muteLocalAudioStream:mute];
136
+}
137
+
138
+//静音所有远端 音频
139
+RCT_EXPORT_METHOD(muteAllRemoteAudioStreams:(BOOL)mute){
140
+    [self.rtcEngine muteAllRemoteAudioStreams:mute];
141
+}
142
+
143
+//静音指定用户 音频
144
+RCT_EXPORT_METHOD(muteRemoteAudioStream:(NSUInteger)uid muted:(BOOL)mute){
145
+    [self.rtcEngine muteRemoteAudioStream:uid mute:mute];
146
+}
147
+
148
+//暂停发送本地 视频流
149
+RCT_EXPORT_METHOD(muteLocalVideoStream:(BOOL)muted){
150
+    [self.rtcEngine muteLocalVideoStream:muted];
151
+}
152
+
153
+//禁用本地视频功能
154
+RCT_EXPORT_METHOD(enableLocalVideo:(BOOL)enabled){
155
+    [self.rtcEngine enableLocalVideo:enabled];
156
+}
157
+
158
+//暂停所有远端视频流
159
+RCT_EXPORT_METHOD(muteAllRemoteVideoStreams:(BOOL)muted){
160
+    [self.rtcEngine muteAllRemoteVideoStreams:muted];
161
+}
162
+
163
+//暂停指定远端视频流
164
+RCT_EXPORT_METHOD(muteRemoteVideoStream:(NSUInteger)uid mute:(BOOL)mute){
165
+    [self.rtcEngine muteRemoteVideoStream:uid mute:mute];
166
+}
167
+
168
+//启动服务端录制服务
169
+RCT_EXPORT_METHOD(startRecordingService:(NSString*)recordingKey){
170
+    [self.rtcEngine startRecordingService:recordingKey];
171
+}
172
+
173
+//停止服务端录制服务
174
+RCT_EXPORT_METHOD(stopRecordingService:(NSString*)recordingKey){
175
+    [self.rtcEngine stopRecordingService:recordingKey];
176
+}
177
+
178
+/*
179
+ 该回调方法表示SDK运行时出现了(网络或媒体相关的)错误。通常情况下,SDK上报的错误意味着SDK无法自动恢复,需要应用程序干预或提示用户。
180
+ 比如启动通话失败时,SDK会上报AgoraRtc_Error_StartCall(1002)错误。
181
+ 应用程序可以提示用户启动通话失败,并调用leaveChannel退出频道。
182
+ */
81 183
 - (void)rtcEngine:(AgoraRtcEngineKit *)engine didOccurError:(AgoraRtcErrorCode)errorCode{
82 184
     
83 185
 }
84 186
 
85
-- (dispatch_queue_t)methodQueue
86
-{
187
+/*
188
+ 客户端成功加入了指定的频道
189
+ */
190
+- (void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinChannel:(NSString*)channel withUid:(NSUInteger)uid elapsed:(NSInteger) elapsed {
191
+    
192
+}
193
+
194
+/*
195
+ 远端首帧视频接收解码回调
196
+ */
197
+- (void)rtcEngine:(AgoraRtcEngineKit *)engine firstRemoteVideoDecodedOfUid:(NSUInteger)uid size:(CGSize)size elapsed:(NSInteger)elapsed {
198
+    
199
+    NSMutableDictionary *params = [NSMutableDictionary dictionary];
200
+    
201
+    params[@"uid"] = [NSNumber numberWithInteger:uid];
202
+    params[@"size"] = @{@"width": [NSString stringWithFormat:@"%f", size.width], @"height": [NSString stringWithFormat:@"%f", size.height]};
203
+    params[@"elapsed"] = [NSNumber numberWithInteger:elapsed];
204
+    
205
+    [_bridge.eventDispatcher sendDeviceEventWithName:@"firstRemoteVideoDecodedOfUid" body:params];
206
+
207
+}
208
+
209
+/*
210
+ 用户加入回调
211
+ */
212
+- (void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinedOfUid:(NSUInteger)uid elapsed:(NSInteger)elapsed {
213
+ 
214
+    [_bridge.eventDispatcher sendDeviceEventWithName:@"didJoinedOfUid" body:[NSNumber numberWithInteger:uid]];
215
+}
216
+
217
+/*
218
+ 用户离线回调
219
+ */
220
+- (void)rtcEngine:(AgoraRtcEngineKit *)engine didOfflineOfUid:(NSUInteger)uid reason:(AgoraRtcUserOfflineReason)reason {
221
+    
222
+}
223
+
224
+/*
225
+ 报告本地用户的网络质量,该回调方法每两秒触发一次
226
+ */
227
+- (void)rtcEngine:(AgoraRtcEngineKit *)engine lastmileQuality:(AgoraRtcQuality)quality {
228
+    
229
+}
230
+
231
+- (dispatch_queue_t)methodQueue {
87 232
     return dispatch_get_main_queue();
88 233
 }
89 234
 
90
-RCT_EXPORT_METHOD(getViewWithTag:(nonnull NSNumber *)reactTag)
91
-{
235
+RCT_EXPORT_METHOD(getViewWithTag:(nonnull NSNumber *)reactTag) {
92 236
     
93 237
     UIView *view = [self.bridge.uiManager viewForReactTag:reactTag];
94 238
     NSLog(@"%@",view);

+ 4
- 2
package.json View File

@@ -1,6 +1,6 @@
1 1
 {
2 2
   "name": "react-native-agora",
3
-  "version": "1.0.1",
3
+  "version": "1.0.2",
4 4
   "description": "声网Agora",
5 5
   "main": "index.js",
6 6
   "scripts": {
@@ -11,7 +11,9 @@
11 11
     "url": "git+https://github.com/DBshaoYan/react-native-agora.git"
12 12
   },
13 13
   "keywords": [
14
-    "agora"
14
+    "agora",
15
+    "react-native",
16
+    "react-native-agora"
15 17
   ],
16 18
   "author": "",
17 19
   "license": "ISC",