Skip to content

Commit 1a3a608

Browse files
author
xia ning
authored
Merge pull request #192 from oOJohn6Oo/lq362
[BGF] 修复RTC实时直播中预览异常的问题
2 parents e22e75e + 2e42201 commit 1a3a608

1 file changed

Lines changed: 85 additions & 58 deletions

File tree

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

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

Lines changed: 85 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838

3939
/**
4040
* This demo demonstrates how to make a one-to-one video call
41+
*
42+
* By default, Everyone is a host, entered a channel will see yourself in the background( the big one ).
43+
* click the frame will switch the position.
44+
* When turn the Co-host on, others will see you.
4145
*/
4246
@Example(
4347
index = 23,
@@ -49,6 +53,8 @@
4953
public class LiveStreaming extends BaseFragment implements View.OnClickListener {
5054
private static final String TAG = LiveStreaming.class.getSimpleName();
5155

56+
// foreground is the small one
57+
// background is the large one
5258
private FrameLayout foreGroundVideo, backGroundVideo;
5359
private Button join, publish;
5460
private Switch cloudGameMode;
@@ -60,11 +66,13 @@ public class LiveStreaming extends BaseFragment implements View.OnClickListener
6066
private boolean isHost = false;
6167
private boolean isLocalVideoForeground = false;
6268

69+
private SurfaceView localView;
70+
private SurfaceView remoteView;
71+
6372
@Nullable
6473
@Override
6574
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
66-
View view = inflater.inflate(R.layout.fragment_live_streaming, container, false);
67-
return view;
75+
return inflater.inflate(R.layout.fragment_live_streaming, container, false);
6876
}
6977

7078
@Override
@@ -73,13 +81,14 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
7381
join = view.findViewById(R.id.btn_join);
7482
publish = view.findViewById(R.id.btn_publish);
7583
et_channel = view.findViewById(R.id.et_channel);
84+
foreGroundVideo = view.findViewById(R.id.foreground_video);
85+
backGroundVideo = view.findViewById(R.id.background_video);
7686
cloudGameMode = view.findViewById(R.id.cloudGameMode);
7787
publish.setEnabled(false);
78-
view.findViewById(R.id.btn_join).setOnClickListener(this);
79-
view.findViewById(R.id.btn_publish).setOnClickListener(this);
80-
view.findViewById(R.id.foreground_video).setOnClickListener(this);
81-
foreGroundVideo = view.findViewById(R.id.background_video);
82-
backGroundVideo = view.findViewById(R.id.foreground_video);
88+
publish.setOnClickListener(this);
89+
join.setOnClickListener(this);
90+
foreGroundVideo.setOnClickListener(this);
91+
backGroundVideo.setOnClickListener(this);
8392
}
8493

8594
@Override
@@ -90,7 +99,7 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
9099
@Override
91100
public void onDestroy() {
92101
super.onDestroy();
93-
/**leaveChannel and Destroy the RtcEngine instance*/
102+
/*leaveChannel and Destroy the RtcEngine instance*/
94103
if (engine != null) {
95104
engine.leaveChannel();
96105
}
@@ -127,15 +136,14 @@ public void onClick(View v) {
127136
engine = RtcEngine.create(rtcEngineConfig);
128137
if(cloudGameMode.isChecked()){
129138
engine.disableAudio();
130-
}
131-
else{
139+
} else{
132140
engine.enableAudio();
133141
}
134142
} catch (Exception e) {
143+
requireActivity().onBackPressed();
135144
e.printStackTrace();
136-
getActivity().onBackPressed();
137145
}
138-
CommonUtil.hideInputBoard(getActivity(), et_channel);
146+
CommonUtil.hideInputBoard(requireActivity(), et_channel);
139147
// call when join button hit
140148
String channelId = et_channel.getText().toString();
141149
// Check permission
@@ -188,45 +196,54 @@ public void onClick(View v) {
188196
publish.setEnabled(false);
189197
publish.setText(isHost ? getString(R.string.disnable_publish) : getString(R.string.enable_publish));
190198

191-
} else if (v.getId() == R.id.foreground_video) {
199+
} else if (v.getId() == R.id.foreground_video || v.getId() == R.id.background_video) {
192200
isLocalVideoForeground = !isLocalVideoForeground;
193-
if (foreGroundVideo.getChildCount() > 0) {
194-
foreGroundVideo.removeAllViews();
195-
}
196-
if (backGroundVideo.getChildCount() > 0) {
197-
backGroundVideo.removeAllViews();
198-
}
199-
// Create render view by RtcEngine
200-
SurfaceView localView = new SurfaceView(getContext());
201-
SurfaceView remoteView = new SurfaceView(getContext());
202-
if (isLocalVideoForeground){
203-
// Add to the local container
204-
foreGroundVideo.addView(localView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
205-
// Add to the remote container
206-
backGroundVideo.addView(remoteView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
207-
// Setup remote video to render
208-
engine.setupRemoteVideo(new VideoCanvas(remoteView, RENDER_MODE_HIDDEN, remoteUid));
209-
// Setup local video to render your local camera preview
210-
engine.setupLocalVideo(new VideoCanvas(localView, RENDER_MODE_HIDDEN, 0));
211-
engine.startPreview();
212-
remoteView.setZOrderMediaOverlay(true);
213-
remoteView.setZOrderOnTop(true);
214-
}
215-
else{
216-
// Add to the local container
217-
foreGroundVideo.addView(remoteView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
218-
// Add to the remote container
219-
backGroundVideo.addView(localView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
220-
// Setup local video to render your local camera preview
221-
engine.setupLocalVideo(new VideoCanvas(localView, RENDER_MODE_HIDDEN, 0));
222-
engine.startPreview();
223-
// Setup remote video to render
224-
engine.setupRemoteVideo(new VideoCanvas(remoteView, RENDER_MODE_HIDDEN, remoteUid));
225-
localView.setZOrderMediaOverlay(true);
226-
localView.setZOrderOnTop(true);
227-
}
201+
switchPreview();
202+
}
203+
204+
}
205+
206+
/**
207+
* Total 3 steps
208+
* Step 1: remove all view
209+
* Step 2: config and add new view
210+
* Step 3: setup engine
211+
*/
212+
private void switchPreview() {
213+
// Step 1
214+
if (foreGroundVideo.getChildCount() > 0) {
215+
foreGroundVideo.removeAllViews();
216+
}
217+
if (backGroundVideo.getChildCount() > 0) {
218+
backGroundVideo.removeAllViews();
228219
}
229220

221+
// Step 2
222+
// Create render view by RtcEngine
223+
SurfaceView localView = new SurfaceView(getContext());
224+
SurfaceView remoteView = new SurfaceView(getContext());
225+
if (isLocalVideoForeground){
226+
// Add to the local container
227+
foreGroundVideo.addView(localView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
228+
// Add to the remote container
229+
backGroundVideo.addView(remoteView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
230+
localView.setZOrderMediaOverlay(true);
231+
}
232+
else{
233+
// Add to the local container
234+
foreGroundVideo.addView(remoteView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
235+
// Add to the remote container
236+
backGroundVideo.addView(localView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
237+
remoteView.setZOrderMediaOverlay(true);
238+
}
239+
240+
// Step 3
241+
242+
// Setup remote video to render
243+
engine.setupRemoteVideo(new VideoCanvas(remoteView, RENDER_MODE_HIDDEN, remoteUid));
244+
// Setup local video to render your local camera preview
245+
engine.setupLocalVideo(new VideoCanvas(localView, RENDER_MODE_HIDDEN, 0));
246+
engine.startPreview();
230247
}
231248

232249
private void joinChannel(String channelId) {
@@ -238,11 +255,17 @@ private void joinChannel(String channelId) {
238255

239256
// Create render view by RtcEngine
240257
SurfaceView surfaceView = new SurfaceView(context);
241-
if (foreGroundVideo.getChildCount() > 0) {
258+
259+
if (backGroundVideo.getChildCount() > 0)
260+
backGroundVideo.removeAllViews();
261+
if (foreGroundVideo.getChildCount() > 0)
242262
foreGroundVideo.removeAllViews();
243-
}
244-
// Add to the local container
245-
foreGroundVideo.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
263+
264+
// Add to the container
265+
if(isLocalVideoForeground)
266+
foreGroundVideo.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
267+
else
268+
backGroundVideo.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
246269
// Setup local video to render your local camera preview
247270
engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0));
248271
engine.startPreview();
@@ -401,15 +424,17 @@ public void onUserJoined(int uid, int elapsed) {
401424
handler.post(() ->
402425
{
403426
/**Display remote video stream*/
404-
SurfaceView surfaceView = null;
405-
if (backGroundVideo.getChildCount() > 0) {
406-
backGroundVideo.removeAllViews();
407-
}
427+
SurfaceView surfaceView;
428+
408429
// Create render view by RtcEngine
409430
surfaceView = new SurfaceView(context);
410-
surfaceView.setZOrderMediaOverlay(true);
411431
// Add to the remote container
412-
backGroundVideo.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
432+
if(isLocalVideoForeground) {
433+
backGroundVideo.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
434+
} else {
435+
foreGroundVideo.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
436+
surfaceView.setZOrderMediaOverlay(true);
437+
}
413438

414439
// Setup remote video to render
415440
engine.setupRemoteVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, remoteUid));
@@ -430,12 +455,14 @@ public void onUserJoined(int uid, int elapsed) {
430455
public void onUserOffline(int uid, int reason) {
431456
Log.i(TAG, String.format("user %d offline! reason:%d", uid, reason));
432457
showLongToast(String.format("user %d offline! reason:%d", uid, reason));
458+
if(uid == remoteUid)
433459
handler.post(new Runnable() {
434460
@Override
435461
public void run() {
436462
/**Clear render view
437463
Note: The video will stay at its last frame, to completely remove it you will need to
438464
remove the SurfaceView from its parent*/
465+
remoteUid = 0;
439466
engine.setupRemoteVideo(new VideoCanvas(null, RENDER_MODE_HIDDEN, uid));
440467
}
441468
});

0 commit comments

Comments
 (0)