Skip to content

Commit a0ddeb5

Browse files
author
xia ning
authored
Merge pull request #170 from AgoraIO/dev/3.4.5
Dev/3.4.5
2 parents b2096b9 + 85d1b57 commit a0ddeb5

59 files changed

Lines changed: 1842 additions & 372 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
1.16 KB
Loading

Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ChannelEncryption.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import com.yanzhenjie.permission.AndPermission;
2020
import com.yanzhenjie.permission.runtime.Permission;
2121

22+
import java.nio.charset.StandardCharsets;
23+
2224
import io.agora.api.example.MainApplication;
2325
import io.agora.api.example.R;
2426
import io.agora.api.example.annotation.Example;
@@ -34,10 +36,7 @@
3436

3537
import static io.agora.api.example.common.model.Examples.ADVANCED;
3638
import static io.agora.rtc.video.VideoCanvas.RENDER_MODE_HIDDEN;
37-
import static io.agora.rtc.video.VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15;
38-
import static io.agora.rtc.video.VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_ADAPTIVE;
3939
import static io.agora.rtc.video.VideoEncoderConfiguration.STANDARD_BITRATE;
40-
import static io.agora.rtc.video.VideoEncoderConfiguration.VD_640x360;
4140

4241
/**This demo demonstrates how to make a one-to-one video call*/
4342
@Example(
@@ -133,6 +132,7 @@ public void onClick(View v)
133132
config.encryptionMode = EncryptionConfig.EncryptionMode.valueOf(encry_mode.getSelectedItem().toString());
134133
// Sets the encryption key.
135134
config.encryptionKey = et_password.getText().toString();
135+
System.arraycopy(getKdfSaltFromServer(), 0, config.encryptionKdfSalt, 0, config.encryptionKdfSalt.length);
136136
// Enables the built-in encryption.
137137
engine.enableEncryption(true, config);
138138
CommonUtil.hideInputBoard(getActivity(), et_channel);
@@ -183,6 +183,10 @@ public void onClick(View v)
183183
}
184184
}
185185

186+
private byte[] getKdfSaltFromServer() {
187+
return "EncryptionKdfSaltInBase64Strings".getBytes(StandardCharsets.UTF_8);
188+
}
189+
186190
private void joinChannel(String channelId)
187191
{
188192
// Check if the context is valid

Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/JoinMultipleChannel.java

Lines changed: 96 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@
3636
import static io.agora.api.example.common.model.Examples.ADVANCED;
3737
import static io.agora.rtc.video.VideoCanvas.RENDER_MODE_FIT;
3838
import static io.agora.rtc.video.VideoCanvas.RENDER_MODE_HIDDEN;
39-
import static io.agora.rtc.video.VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15;
40-
import static io.agora.rtc.video.VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_ADAPTIVE;
4139
import static io.agora.rtc.video.VideoEncoderConfiguration.STANDARD_BITRATE;
42-
import static io.agora.rtc.video.VideoEncoderConfiguration.VD_640x360;
4340

4441
@Example(
4542
index = 12,
@@ -59,7 +56,8 @@ public class JoinMultipleChannel extends BaseFragment implements View.OnClickLis
5956
private boolean joined = false;
6057
private String channel1;
6158
private String channel2;
62-
private RtcChannel rtcChannel;
59+
private RtcChannel rtcChannel1;
60+
private RtcChannel rtcChannel2;
6361

6462
@Nullable
6563
@Override
@@ -100,6 +98,7 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState)
10098
* @param handler IRtcEngineEventHandler is an abstract class providing default implementation.
10199
* The SDK uses this class to report to the app on SDK runtime events.*/
102100
engine = RtcEngine.create(context.getApplicationContext(), getString(R.string.agora_app_id), iRtcEngineEventHandler);
101+
setupVideo();
103102
}
104103
catch (Exception e)
105104
{
@@ -128,14 +127,16 @@ public void onClick(View v)
128127
{
129128
if (!joined)
130129
{
130+
engine.stopPreview();
131131
CommonUtil.hideInputBoard(getActivity(), et_channel);
132132
// call when join button hit
133133
channel1 = et_channel.getText().toString();
134134
channel2 = channel1 + "-2";
135135
// Check permission
136136
if (AndPermission.hasPermissions(this, Permission.Group.STORAGE, Permission.Group.MICROPHONE, Permission.Group.CAMERA))
137137
{
138-
joinChannel(channel1);
138+
joinFirstChannel();
139+
joinSecondChannel();
139140
return;
140141
}
141142
// Request permission
@@ -146,8 +147,10 @@ public void onClick(View v)
146147
).onGranted(permissions ->
147148
{
148149
// Permissions Granted
149-
joinChannel(channel1);
150+
joinFirstChannel();
151+
joinSecondChannel();
150152
}).start();
153+
join.setEnabled(false);
151154
}
152155
else
153156
{
@@ -169,14 +172,14 @@ public void onClick(View v)
169172
* the onLeaveChannel callback.
170173
* 2:If you call the leaveChannel method during CDN live streaming, the SDK
171174
* triggers the removeInjectStreamUrl method.*/
172-
engine.leaveChannel();
173-
rtcChannel.leaveChannel();
175+
rtcChannel2.leaveChannel();
176+
rtcChannel1.leaveChannel();
174177
join.setText(getString(R.string.join));
175178
}
176179
}
177180
}
178181

179-
private void joinChannel(String channelId)
182+
private void setupVideo()
180183
{
181184
// Check if the context is valid
182185
Context context = getContext();
@@ -195,6 +198,7 @@ private void joinChannel(String channelId)
195198
fl_local.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
196199
// Setup local video to render your local camera preview
197200
engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0));
201+
engine.startPreview();
198202
// Set audio route to microPhone
199203
engine.setDefaultAudioRoutetoSpeakerphone(false);
200204

@@ -217,41 +221,91 @@ private void joinChannel(String channelId)
217221
VideoEncoderConfiguration.ORIENTATION_MODE.valueOf(((MainApplication)getActivity().getApplication()).getGlobalSettings().getVideoEncodingOrientation())
218222
));
219223

220-
/**Please configure accessToken in the string_config file.
221-
* A temporary token generated in Console. A temporary token is valid for 24 hours. For details, see
222-
* https://docs.agora.io/en/Agora%20Platform/token?platform=All%20Platforms#get-a-temporary-token
223-
* A token generated at the server. This applies to scenarios with high-security requirements. For details, see
224-
* https://docs.agora.io/en/cloud-recording/token_server_java?platform=Java*/
225-
String accessToken = getString(R.string.agora_access_token);
226-
if (TextUtils.equals(accessToken, "") || TextUtils.equals(accessToken, "<#YOUR ACCESS TOKEN#>"))
227-
{
228-
accessToken = null;
229-
}
230-
/** Allows a user to join a channel.
231-
if you do not specify the uid, we will generate the uid for you*/
224+
}
232225

233-
ChannelMediaOptions option = new ChannelMediaOptions();
234-
option.autoSubscribeAudio = true;
235-
option.autoSubscribeVideo = true;
236-
int res = engine.joinChannel(accessToken, channelId, "Extra Optional Data", 0, option);
237-
if (res != 0 || !joinSecondChannel())
238-
{
239-
// Usually happens with invalid parameters
240-
// Error code description can be found at:
241-
// en: https://docs.agora.io/en/Voice/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler_1_1_error_code.html
242-
// cn: https://docs.agora.io/cn/Voice/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler_1_1_error_code.html
243-
showAlert(RtcEngine.getErrorDescription(Math.abs(res)));
244-
return;
245-
}
246-
// Prevent repeated entry
247-
join.setEnabled(false);
226+
private boolean joinFirstChannel() {
227+
// 1. Create rtcChannel
228+
rtcChannel1 = engine.createRtcChannel(channel1);
229+
rtcChannel1.setClientRole(Constants.CLIENT_ROLE_BROADCASTER);
230+
// 2. Set rtcChannelEventHandler
231+
rtcChannel1.setRtcChannelEventHandler(new IRtcChannelEventHandler() {
232+
// Override events
233+
/**
234+
* Occurs when the local user joins a specified channel.
235+
* The channel name assignment is based on channelName specified in the joinChannel method.
236+
* If the uid is not specified when joinChannel is called, the server automatically assigns a uid.
237+
*
238+
* @param rtcChannel Channel object
239+
* @param uid User ID
240+
* @param elapsed Time elapsed (ms) from the user calling joinChannel until this callback is triggered
241+
*/
242+
@Override
243+
public void onJoinChannelSuccess(RtcChannel rtcChannel, int uid, int elapsed) {
244+
super.onJoinChannelSuccess(rtcChannel, uid, elapsed);
245+
Log.i(TAG, String.format("onJoinChannelSuccess channel %s uid %d", channel1, uid));
246+
showLongToast(String.format("onJoinChannelSuccess channel %s uid %d", channel1, uid));
247+
myUid = uid;
248+
joined = true;
249+
handler.post(new Runnable() {
250+
@Override
251+
public void run() {
252+
join.setEnabled(true);
253+
join.setText(getString(R.string.leave));
254+
}
255+
});
256+
}
257+
/**
258+
* Occurs when a remote user (Communication)/host (Live Broadcast) joins the channel.
259+
*
260+
* @param uid ID of the user whose audio state changes.
261+
* @param elapsed Time delay (ms) from the local user calling joinChannel/setClientRole
262+
* until this callback is triggered.
263+
*/
264+
@Override
265+
public void onUserJoined(RtcChannel rtcChannel, int uid, int elapsed) {
266+
super.onUserJoined(rtcChannel, uid, elapsed);
267+
Log.i(TAG, "onUserJoined->" + uid);
268+
showLongToast(String.format("user %d joined!", uid));
269+
/**Check if the context is correct*/
270+
Context context = getContext();
271+
if (context == null) {
272+
return;
273+
}
274+
handler.post(() ->
275+
{
276+
/**Display remote video stream*/
277+
SurfaceView surfaceView = null;
278+
if (fl_remote.getChildCount() > 0) {
279+
fl_remote.removeAllViews();
280+
}
281+
// Create render view by RtcEngine
282+
surfaceView = RtcEngine.CreateRendererView(context);
283+
surfaceView.setZOrderMediaOverlay(true);
284+
// Add to the remote container
285+
fl_remote.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
286+
287+
// Setup remote video to render
288+
engine.setupRemoteVideo(new VideoCanvas(surfaceView, RENDER_MODE_FIT, channel1, uid));
289+
});
290+
}
291+
});
292+
// 3. Configurate mediaOptions
293+
ChannelMediaOptions mediaOptions = new ChannelMediaOptions();
294+
mediaOptions.autoSubscribeAudio = true;
295+
mediaOptions.autoSubscribeVideo = true;
296+
mediaOptions.publishLocalAudio = true;
297+
mediaOptions.publishLocalVideo = true;
298+
// 4. Join channel
299+
int ret = rtcChannel1.joinChannel(null, "", 0, mediaOptions);
300+
return (ret == 0);
248301
}
249302

250303
private boolean joinSecondChannel() {
251304
// 1. Create rtcChannel
252-
rtcChannel = engine.createRtcChannel(channel2);
305+
rtcChannel2 = engine.createRtcChannel(channel2);
306+
rtcChannel2.setClientRole(Constants.CLIENT_ROLE_AUDIENCE);
253307
// 2. Set rtcChannelEventHandler
254-
rtcChannel.setRtcChannelEventHandler(new IRtcChannelEventHandler() {
308+
rtcChannel2.setRtcChannelEventHandler(new IRtcChannelEventHandler() {
255309
// Override events
256310
/**
257311
* Occurs when the local user joins a specified channel.
@@ -316,11 +370,14 @@ public void onUserJoined(RtcChannel rtcChannel, int uid, int elapsed) {
316370
ChannelMediaOptions mediaOptions = new ChannelMediaOptions();
317371
mediaOptions.autoSubscribeAudio = true;
318372
mediaOptions.autoSubscribeVideo = true;
373+
mediaOptions.publishLocalVideo = false;
374+
mediaOptions.publishLocalAudio = false;
319375
// 4. Join channel
320-
int ret = rtcChannel.joinChannel(null, "", 0, mediaOptions);
376+
int ret = rtcChannel2.joinChannel(null, "", 0, mediaOptions);
321377
return (ret == 0);
322378
}
323379

380+
324381
/**
325382
* IRtcEngineEventHandler is an abstract class providing default implementation.
326383
* The SDK uses this class to report to the app on SDK runtime events.

Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/MultiProcess.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@
3535

3636
import static io.agora.api.example.common.model.Examples.ADVANCED;
3737
import static io.agora.rtc.video.VideoCanvas.RENDER_MODE_HIDDEN;
38-
import static io.agora.rtc.video.VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15;
38+
import static io.agora.rtc.video.VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_30;
3939
import static io.agora.rtc.video.VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_ADAPTIVE;
4040
import static io.agora.rtc.video.VideoEncoderConfiguration.STANDARD_BITRATE;
41-
import static io.agora.rtc.video.VideoEncoderConfiguration.VD_640x360;
4241

4342
/**This demo demonstrates how to make a one-to-one video call*/
4443
@Example(
@@ -205,7 +204,7 @@ else if (v.getId() == R.id.screenShare){
205204
mSSClient.start(getContext(), getResources().getString(R.string.agora_app_id), null,
206205
channelId, SCREEN_SHARE_UID, new VideoEncoderConfiguration(
207206
getScreenDimensions(),
208-
FRAME_RATE_FPS_15,
207+
FRAME_RATE_FPS_30,
209208
STANDARD_BITRATE,
210209
ORIENTATION_MODE_ADAPTIVE
211210
));
@@ -246,7 +245,8 @@ private void joinChannel(String channelId)
246245
// Setup local video to render your local camera preview
247246
engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0));
248247
// Set audio route to microPhone
249-
engine.setDefaultAudioRoutetoSpeakerphone(false);
248+
engine.disableAudio();
249+
// engine.setDefaultAudioRoutetoSpeakerphone(false);
250250

251251
/** Sets the channel profile of the Agora RtcEngine.
252252
CHANNEL_PROFILE_COMMUNICATION(0): (Default) The Communication profile.
@@ -281,8 +281,8 @@ private void joinChannel(String channelId)
281281
if you do not specify the uid, we will generate the uid for you*/
282282

283283
ChannelMediaOptions option = new ChannelMediaOptions();
284-
option.autoSubscribeAudio = true;
285-
option.autoSubscribeVideo = true;
284+
option.autoSubscribeAudio = false;
285+
option.autoSubscribeVideo = false;
286286
int res = engine.joinChannel(accessToken, channelId, "Extra Optional Data", 0, option);
287287
if (res != 0)
288288
{

0 commit comments

Comments
 (0)