mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-19 19:49:33 +01:00
Progress
Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
parent
8eee14d32f
commit
855ed05cf6
@ -34,6 +34,8 @@ import android.util.TypedValue;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.widget.GridLayout;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
|
||||||
import com.bluelinelabs.logansquare.LoganSquare;
|
import com.bluelinelabs.logansquare.LoganSquare;
|
||||||
import com.nextcloud.talk.R;
|
import com.nextcloud.talk.R;
|
||||||
@ -52,7 +54,7 @@ import com.nextcloud.talk.events.MediaStreamEvent;
|
|||||||
import com.nextcloud.talk.events.SessionDescriptionSendEvent;
|
import com.nextcloud.talk.events.SessionDescriptionSendEvent;
|
||||||
import com.nextcloud.talk.persistence.entities.UserEntity;
|
import com.nextcloud.talk.persistence.entities.UserEntity;
|
||||||
import com.nextcloud.talk.webrtc.MagicAudioManager;
|
import com.nextcloud.talk.webrtc.MagicAudioManager;
|
||||||
import com.nextcloud.talk.webrtc.PeerConnectionWrapper;
|
import com.nextcloud.talk.webrtc.MagicPeerConnectionWrapper;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringEscapeUtils;
|
import org.apache.commons.lang3.StringEscapeUtils;
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
@ -104,8 +106,8 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
@BindView(R.id.pip_video_view)
|
@BindView(R.id.pip_video_view)
|
||||||
SurfaceViewRenderer pipVideoView;
|
SurfaceViewRenderer pipVideoView;
|
||||||
|
|
||||||
@BindView(R.id.fullscreen_video_view)
|
@BindView(R.id.videos_grid_view)
|
||||||
SurfaceViewRenderer fullScreenVideoView;
|
GridLayout videosGrid;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
NcApi ncApi;
|
NcApi ncApi;
|
||||||
@ -125,7 +127,9 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
VideoCapturer videoCapturer;
|
VideoCapturer videoCapturer;
|
||||||
VideoRenderer localRenderer;
|
VideoRenderer localRenderer;
|
||||||
VideoRenderer remoteRenderer;
|
VideoRenderer remoteRenderer;
|
||||||
|
HashMap<String, VideoRenderer> videoRendererHashMap = new HashMap<>();
|
||||||
PeerConnection localPeer;
|
PeerConnection localPeer;
|
||||||
|
EglBase rootEglBase;
|
||||||
boolean leavingCall = false;
|
boolean leavingCall = false;
|
||||||
BooleanSupplier booleanSupplier = () -> leavingCall;
|
BooleanSupplier booleanSupplier = () -> leavingCall;
|
||||||
Disposable signalingDisposable;
|
Disposable signalingDisposable;
|
||||||
@ -138,7 +142,7 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
private MediaStream localMediaStream;
|
private MediaStream localMediaStream;
|
||||||
|
|
||||||
private String credentials;
|
private String credentials;
|
||||||
private List<PeerConnectionWrapper> peerConnectionWrapperList = new ArrayList<>();
|
private List<MagicPeerConnectionWrapper> magicPeerConnectionWrapperList = new ArrayList<>();
|
||||||
|
|
||||||
private static int getSystemUiVisibility() {
|
private static int getSystemUiVisibility() {
|
||||||
int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
|
int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
|
||||||
@ -224,16 +228,11 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
public void initViews() {
|
public void initViews() {
|
||||||
pipVideoView.setMirror(true);
|
pipVideoView.setMirror(true);
|
||||||
fullScreenVideoView.setMirror(false);
|
rootEglBase = EglBase.create();
|
||||||
EglBase rootEglBase = EglBase.create();
|
|
||||||
pipVideoView.init(rootEglBase.getEglBaseContext(), null);
|
pipVideoView.init(rootEglBase.getEglBaseContext(), null);
|
||||||
pipVideoView.setZOrderMediaOverlay(true);
|
pipVideoView.setZOrderMediaOverlay(true);
|
||||||
fullScreenVideoView.init(rootEglBase.getEglBaseContext(), null);
|
|
||||||
fullScreenVideoView.setZOrderMediaOverlay(true);
|
|
||||||
fullScreenVideoView.setEnableHardwareScaler(true);
|
|
||||||
pipVideoView.setEnableHardwareScaler(true);
|
pipVideoView.setEnableHardwareScaler(true);
|
||||||
pipVideoView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT);
|
pipVideoView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT);
|
||||||
fullScreenVideoView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
@ -435,7 +434,7 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
NCSignalingMessage ncSignalingMessage = LoganSquare.parse(signaling.getMessageWrapper().toString(),
|
NCSignalingMessage ncSignalingMessage = LoganSquare.parse(signaling.getMessageWrapper().toString(),
|
||||||
NCSignalingMessage.class);
|
NCSignalingMessage.class);
|
||||||
if (ncSignalingMessage.getRoomType().equals("video")) {
|
if (ncSignalingMessage.getRoomType().equals("video")) {
|
||||||
PeerConnectionWrapper peerConnectionWrapper = alwaysGetPeerConnectionWrapperForSessionId
|
MagicPeerConnectionWrapper magicPeerConnectionWrapper = alwaysGetPeerConnectionWrapperForSessionId
|
||||||
(ncSignalingMessage.getFrom(), ncSignalingMessage.getFrom().equals(callSession));
|
(ncSignalingMessage.getFrom(), ncSignalingMessage.getFrom().equals(callSession));
|
||||||
|
|
||||||
String type = null;
|
String type = null;
|
||||||
@ -450,8 +449,8 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case "offer":
|
case "offer":
|
||||||
case "answer":
|
case "answer":
|
||||||
peerConnectionWrapper.setNick(ncSignalingMessage.getPayload().getNick());
|
magicPeerConnectionWrapper.setNick(ncSignalingMessage.getPayload().getNick());
|
||||||
peerConnectionWrapper.getPeerConnection().setRemoteDescription(peerConnectionWrapper
|
magicPeerConnectionWrapper.getPeerConnection().setRemoteDescription(magicPeerConnectionWrapper
|
||||||
.getMagicSdpObserver(), new SessionDescription(SessionDescription.Type.fromCanonicalForm(type),
|
.getMagicSdpObserver(), new SessionDescription(SessionDescription.Type.fromCanonicalForm(type),
|
||||||
ncSignalingMessage.getPayload().getSdp()));
|
ncSignalingMessage.getPayload().getSdp()));
|
||||||
break;
|
break;
|
||||||
@ -459,11 +458,11 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
NCIceCandidate ncIceCandidate = ncSignalingMessage.getPayload().getIceCandidate();
|
NCIceCandidate ncIceCandidate = ncSignalingMessage.getPayload().getIceCandidate();
|
||||||
IceCandidate iceCandidate = new IceCandidate(ncIceCandidate.getSdpMid(),
|
IceCandidate iceCandidate = new IceCandidate(ncIceCandidate.getSdpMid(),
|
||||||
ncIceCandidate.getSdpMLineIndex(), ncIceCandidate.getCandidate());
|
ncIceCandidate.getSdpMLineIndex(), ncIceCandidate.getCandidate());
|
||||||
peerConnectionWrapper.addCandidate(iceCandidate);
|
magicPeerConnectionWrapper.addCandidate(iceCandidate);
|
||||||
break;
|
break;
|
||||||
case "endOfCandidates":
|
case "endOfCandidates":
|
||||||
peerConnectionWrapper.drainIceCandidates();
|
magicPeerConnectionWrapper.drainIceCandidates();
|
||||||
peerConnectionWrapper.sendLocalCandidates();
|
magicPeerConnectionWrapper.sendLocalCandidates();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -496,9 +495,9 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PeerConnectionWrapper peerConnectionWrapper : peerConnectionWrapperList) {
|
for (MagicPeerConnectionWrapper magicPeerConnectionWrapper : magicPeerConnectionWrapperList) {
|
||||||
if (!peerConnectionWrapper.getSessionId().equals(callSession)) {
|
if (!magicPeerConnectionWrapper.getSessionId().equals(callSession)) {
|
||||||
oldSesssions.add(peerConnectionWrapper.getSessionId());
|
oldSesssions.add(magicPeerConnectionWrapper.getSessionId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,12 +512,12 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PeerConnectionWrapper peerConnectionWrapper;
|
MagicPeerConnectionWrapper magicPeerConnectionWrapper;
|
||||||
|
|
||||||
for (String sessionId : newSessions) {
|
for (String sessionId : newSessions) {
|
||||||
if (getPeerConnectionWrapperForSessionId(sessionId) == null) {
|
if (getPeerConnectionWrapperForSessionId(sessionId) == null) {
|
||||||
if (sessionId.compareTo(callSession) < 0) {
|
if (sessionId.compareTo(callSession) < 0) {
|
||||||
PeerConnectionWrapper connectionWrapper = alwaysGetPeerConnectionWrapperForSessionId(sessionId,
|
MagicPeerConnectionWrapper connectionWrapper = alwaysGetPeerConnectionWrapperForSessionId(sessionId,
|
||||||
false);
|
false);
|
||||||
if (connectionWrapper.getPeerConnection() != null) {
|
if (connectionWrapper.getPeerConnection() != null) {
|
||||||
connectionWrapper.getPeerConnection().createOffer(connectionWrapper.getMagicSdpObserver(),
|
connectionWrapper.getPeerConnection().createOffer(connectionWrapper.getMagicSdpObserver(),
|
||||||
@ -532,33 +531,33 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (String sessionId : leftSessions) {
|
for (String sessionId : leftSessions) {
|
||||||
if ((peerConnectionWrapper = getPeerConnectionWrapperForSessionId(sessionId)) != null) {
|
if ((magicPeerConnectionWrapper = getPeerConnectionWrapperForSessionId(sessionId)) != null) {
|
||||||
if (peerConnectionWrapper.getPeerConnection() != null) {
|
if (magicPeerConnectionWrapper.getPeerConnection() != null) {
|
||||||
peerConnectionWrapper.getPeerConnection().close();
|
magicPeerConnectionWrapper.getPeerConnection().close();
|
||||||
}
|
}
|
||||||
peerConnectionWrapperList.remove(peerConnectionWrapper);
|
magicPeerConnectionWrapperList.remove(magicPeerConnectionWrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private PeerConnectionWrapper alwaysGetPeerConnectionWrapperForSessionId(String sessionId, boolean isLocalPeer) {
|
private MagicPeerConnectionWrapper alwaysGetPeerConnectionWrapperForSessionId(String sessionId, boolean isLocalPeer) {
|
||||||
PeerConnectionWrapper peerConnectionWrapper;
|
MagicPeerConnectionWrapper magicPeerConnectionWrapper;
|
||||||
if ((peerConnectionWrapper = getPeerConnectionWrapperForSessionId(sessionId)) != null) {
|
if ((magicPeerConnectionWrapper = getPeerConnectionWrapperForSessionId(sessionId)) != null) {
|
||||||
return peerConnectionWrapper;
|
return magicPeerConnectionWrapper;
|
||||||
} else {
|
} else {
|
||||||
peerConnectionWrapper = new PeerConnectionWrapper(peerConnectionFactory,
|
magicPeerConnectionWrapper = new MagicPeerConnectionWrapper(peerConnectionFactory,
|
||||||
iceServers, sdpConstraints, sessionId);
|
iceServers, sdpConstraints, sessionId);
|
||||||
peerConnectionWrapper.getPeerConnection().addStream(localMediaStream);
|
magicPeerConnectionWrapper.getPeerConnection().addStream(localMediaStream);
|
||||||
peerConnectionWrapperList.add(peerConnectionWrapper);
|
magicPeerConnectionWrapperList.add(magicPeerConnectionWrapper);
|
||||||
return peerConnectionWrapper;
|
return magicPeerConnectionWrapper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PeerConnectionWrapper getPeerConnectionWrapperForSessionId(String sessionId) {
|
private MagicPeerConnectionWrapper getPeerConnectionWrapperForSessionId(String sessionId) {
|
||||||
for (PeerConnectionWrapper peerConnectionWrapper : peerConnectionWrapperList) {
|
for (MagicPeerConnectionWrapper magicPeerConnectionWrapper : magicPeerConnectionWrapperList) {
|
||||||
if (peerConnectionWrapper.getSessionId().equals(sessionId)) {
|
if (magicPeerConnectionWrapper.getSessionId().equals(sessionId)) {
|
||||||
return peerConnectionWrapper;
|
return magicPeerConnectionWrapper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -570,9 +569,9 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
dispose(null);
|
dispose(null);
|
||||||
|
|
||||||
for (PeerConnectionWrapper peerConnectionWrapper : peerConnectionWrapperList) {
|
for (MagicPeerConnectionWrapper magicPeerConnectionWrapper : magicPeerConnectionWrapperList) {
|
||||||
if (peerConnectionWrapper.getPeerConnection() != null) {
|
if (magicPeerConnectionWrapper.getPeerConnection() != null) {
|
||||||
peerConnectionWrapper.getPeerConnection().close();
|
magicPeerConnectionWrapper.getPeerConnection().close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,7 +580,6 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pipVideoView.release();
|
pipVideoView.release();
|
||||||
fullScreenVideoView.release();
|
|
||||||
|
|
||||||
String credentials = ApiHelper.getCredentials(userEntity.getUsername(), userEntity.getToken());
|
String credentials = ApiHelper.getCredentials(userEntity.getUsername(), userEntity.getToken());
|
||||||
ncApi.leaveCall(credentials, ApiHelper.getUrlForCall(userEntity.getBaseUrl(), roomToken))
|
ncApi.leaveCall(credentials, ApiHelper.getUrlForCall(userEntity.getBaseUrl(), roomToken))
|
||||||
@ -610,7 +608,7 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void gotRemoteStream(MediaStream stream) {
|
private void gotRemoteStream(MediaStream stream, String session) {
|
||||||
//we have remote video stream. add to the renderer.
|
//we have remote video stream. add to the renderer.
|
||||||
if (stream.videoTracks.size() < 2 && stream.audioTracks.size() < 2) {
|
if (stream.videoTracks.size() < 2 && stream.audioTracks.size() < 2) {
|
||||||
if (stream.videoTracks.size() == 1) {
|
if (stream.videoTracks.size() == 1) {
|
||||||
@ -621,8 +619,26 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
public void run() {
|
public void run() {
|
||||||
if (stream.videoTracks.size() == 1) {
|
if (stream.videoTracks.size() == 1) {
|
||||||
try {
|
try {
|
||||||
remoteRenderer = new VideoRenderer(fullScreenVideoView);
|
RelativeLayout relativeLayout = (RelativeLayout)
|
||||||
|
getLayoutInflater().inflate(R.layout.surface_renderer, videosGrid,
|
||||||
|
false);
|
||||||
|
relativeLayout.setTag(session);
|
||||||
|
SurfaceViewRenderer surfaceViewRenderer = relativeLayout.findViewById(R.id
|
||||||
|
.surface_view);
|
||||||
|
surfaceViewRenderer.setMirror(false);
|
||||||
|
surfaceViewRenderer.init(rootEglBase.getEglBaseContext(), null);
|
||||||
|
surfaceViewRenderer.setZOrderMediaOverlay(true);
|
||||||
|
surfaceViewRenderer.setEnableHardwareScaler(true);
|
||||||
|
surfaceViewRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);
|
||||||
|
VideoRenderer remoteRenderer = new VideoRenderer(surfaceViewRenderer);
|
||||||
|
videoRendererHashMap.put(session, remoteRenderer);
|
||||||
videoTrack.addRenderer(remoteRenderer);
|
videoTrack.addRenderer(remoteRenderer);
|
||||||
|
videosGrid.addView(relativeLayout);
|
||||||
|
|
||||||
|
GridLayout.LayoutParams param = new GridLayout.LayoutParams(GridLayout.spec(
|
||||||
|
GridLayout.UNDEFINED,GridLayout.FILL,1f),
|
||||||
|
GridLayout.spec(GridLayout.UNDEFINED,GridLayout.FILL,1f));
|
||||||
|
relativeLayout.setLayoutParams(param);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -676,7 +692,7 @@ public class CallActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
||||||
public void onMessageEvent(MediaStreamEvent mediaStreamEvent) {
|
public void onMessageEvent(MediaStreamEvent mediaStreamEvent) {
|
||||||
gotRemoteStream(mediaStreamEvent.getMediaStream());
|
gotRemoteStream(mediaStreamEvent.getMediaStream(), mediaStreamEvent.getSession());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
||||||
|
@ -33,4 +33,11 @@ public class DataChannelMessage {
|
|||||||
|
|
||||||
@JsonField(name = "payload")
|
@JsonField(name = "payload")
|
||||||
String payload;
|
String payload;
|
||||||
|
|
||||||
|
public DataChannelMessage(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataChannelMessage() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,10 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class MediaStreamEvent {
|
public class MediaStreamEvent {
|
||||||
private final MediaStream mediaStream;
|
private final MediaStream mediaStream;
|
||||||
|
private final String session;
|
||||||
|
|
||||||
public MediaStreamEvent(MediaStream mediaStream) {
|
public MediaStreamEvent(MediaStream mediaStream, String session) {
|
||||||
this.mediaStream = mediaStream;
|
this.mediaStream = mediaStream;
|
||||||
|
this.session = session;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
|
|
||||||
package com.nextcloud.talk.webrtc;
|
package com.nextcloud.talk.webrtc;
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.webrtc.DataChannel;
|
import org.webrtc.DataChannel;
|
||||||
import org.webrtc.IceCandidate;
|
import org.webrtc.IceCandidate;
|
||||||
import org.webrtc.MediaStream;
|
import org.webrtc.MediaStream;
|
||||||
@ -35,7 +33,6 @@ public class MagicPeerConnectionObserver implements PeerConnection.Observer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSignalingChange(PeerConnection.SignalingState signalingState) {
|
public void onSignalingChange(PeerConnection.SignalingState signalingState) {
|
||||||
Log.d("MARIO", signalingState.name());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -22,6 +22,7 @@ package com.nextcloud.talk.webrtc;
|
|||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.bluelinelabs.logansquare.LoganSquare;
|
||||||
import com.nextcloud.talk.api.models.json.signaling.DataChannelMessage;
|
import com.nextcloud.talk.api.models.json.signaling.DataChannelMessage;
|
||||||
import com.nextcloud.talk.api.models.json.signaling.NCIceCandidate;
|
import com.nextcloud.talk.api.models.json.signaling.NCIceCandidate;
|
||||||
import com.nextcloud.talk.events.MediaStreamEvent;
|
import com.nextcloud.talk.events.MediaStreamEvent;
|
||||||
@ -36,12 +37,13 @@ import org.webrtc.PeerConnection;
|
|||||||
import org.webrtc.PeerConnectionFactory;
|
import org.webrtc.PeerConnectionFactory;
|
||||||
import org.webrtc.SessionDescription;
|
import org.webrtc.SessionDescription;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class PeerConnectionWrapper {
|
public class MagicPeerConnectionWrapper {
|
||||||
private static String TAG = "PeerConnectionWrapper";
|
private static String TAG = "MagicPeerConnectionWrapper";
|
||||||
private static PeerConnection peerConnection;
|
private static PeerConnection peerConnection;
|
||||||
List<IceCandidate> iceCandidates = new ArrayList<>();
|
List<IceCandidate> iceCandidates = new ArrayList<>();
|
||||||
List<PeerConnection.IceServer> iceServers;
|
List<PeerConnection.IceServer> iceServers;
|
||||||
@ -49,11 +51,11 @@ public class PeerConnectionWrapper {
|
|||||||
private String sessionId;
|
private String sessionId;
|
||||||
private String nick;
|
private String nick;
|
||||||
private MediaConstraints mediaConstraints;
|
private MediaConstraints mediaConstraints;
|
||||||
private DataChannel dataChannel;
|
private DataChannel magicDataChannel;
|
||||||
private MagicSdpObserver magicSdpObserver;
|
private MagicSdpObserver magicSdpObserver;
|
||||||
private MagicPeerConnectionObserver magicPeerConnectionObserver;
|
private MagicPeerConnectionObserver magicPeerConnectionObserver;
|
||||||
|
|
||||||
public PeerConnectionWrapper(PeerConnectionFactory peerConnectionFactory,
|
public MagicPeerConnectionWrapper(PeerConnectionFactory peerConnectionFactory,
|
||||||
List<PeerConnection.IceServer> iceServerList,
|
List<PeerConnection.IceServer> iceServerList,
|
||||||
MediaConstraints mediaConstraints,
|
MediaConstraints mediaConstraints,
|
||||||
String sessionId) {
|
String sessionId) {
|
||||||
@ -61,27 +63,9 @@ public class PeerConnectionWrapper {
|
|||||||
this.iceServers = iceServerList;
|
this.iceServers = iceServerList;
|
||||||
|
|
||||||
magicPeerConnectionObserver = new MagicPeerConnectionObserver() {
|
magicPeerConnectionObserver = new MagicPeerConnectionObserver() {
|
||||||
@Override
|
|
||||||
public void onIceConnectionReceivingChange(boolean b) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAddStream(MediaStream mediaStream) {
|
public void onAddStream(MediaStream mediaStream) {
|
||||||
EventBus.getDefault().post(new MediaStreamEvent(mediaStream));
|
EventBus.getDefault().post(new MediaStreamEvent(mediaStream, sessionId));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSignalingChange(PeerConnection.SignalingState signalingState) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -90,12 +74,15 @@ public class PeerConnectionWrapper {
|
|||||||
ncIceCandidate.setSdpMid(iceCandidate.sdpMid);
|
ncIceCandidate.setSdpMid(iceCandidate.sdpMid);
|
||||||
ncIceCandidate.setSdpMLineIndex(iceCandidate.sdpMLineIndex);
|
ncIceCandidate.setSdpMLineIndex(iceCandidate.sdpMLineIndex);
|
||||||
ncIceCandidate.setCandidate(iceCandidate.sdp);
|
ncIceCandidate.setCandidate(iceCandidate.sdp);
|
||||||
if (peerConnection.getRemoteDescription() == null) {
|
/*if (peerConnection.getRemoteDescription() == null) {
|
||||||
localCandidates.add(ncIceCandidate);
|
localCandidates.add(ncIceCandidate);
|
||||||
} else {
|
} else {
|
||||||
EventBus.getDefault().post(new SessionDescriptionSendEvent(null, sessionId,
|
EventBus.getDefault().post(new SessionDescriptionSendEvent(null, sessionId,
|
||||||
"candidate", ncIceCandidate));
|
"candidate", ncIceCandidate));
|
||||||
}
|
}*/
|
||||||
|
EventBus.getDefault().post(new SessionDescriptionSendEvent(null, sessionId,
|
||||||
|
"candidate", ncIceCandidate));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -103,6 +90,11 @@ public class PeerConnectionWrapper {
|
|||||||
peerConnection = peerConnectionFactory.createPeerConnection(iceServerList, mediaConstraints,
|
peerConnection = peerConnectionFactory.createPeerConnection(iceServerList, mediaConstraints,
|
||||||
magicPeerConnectionObserver);
|
magicPeerConnectionObserver);
|
||||||
|
|
||||||
|
DataChannel.Init init = new DataChannel.Init();
|
||||||
|
init.negotiated = false;
|
||||||
|
magicDataChannel = peerConnection.createDataChannel("status", init);
|
||||||
|
magicDataChannel.registerObserver(new MagicDataChannelObserver());
|
||||||
|
|
||||||
this.sessionId = sessionId;
|
this.sessionId = sessionId;
|
||||||
this.mediaConstraints = mediaConstraints;
|
this.mediaConstraints = mediaConstraints;
|
||||||
|
|
||||||
@ -120,6 +112,7 @@ public class PeerConnectionWrapper {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreateSuccess(SessionDescription sessionDescription) {
|
public void onCreateSuccess(SessionDescription sessionDescription) {
|
||||||
super.onCreateSuccess(sessionDescription);
|
super.onCreateSuccess(sessionDescription);
|
||||||
|
|
||||||
peerConnection.setLocalDescription(magicSdpObserver, sessionDescription);
|
peerConnection.setLocalDescription(magicSdpObserver, sessionDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,8 +174,13 @@ public class PeerConnectionWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void sendChannelData(DataChannelMessage dataChannelMessage) {
|
private void sendChannelData(DataChannelMessage dataChannelMessage) {
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(dataChannelMessage.toString().getBytes());
|
ByteBuffer buffer = null;
|
||||||
dataChannel.send(new DataChannel.Buffer(buffer, false));
|
try {
|
||||||
|
buffer = ByteBuffer.wrap(LoganSquare.serialize(dataChannelMessage).getBytes());
|
||||||
|
magicDataChannel.send(new DataChannel.Buffer(buffer, false));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -191,7 +189,7 @@ public class PeerConnectionWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void setPeerConnection(PeerConnection peerConnection) {
|
public static void setPeerConnection(PeerConnection peerConnection) {
|
||||||
PeerConnectionWrapper.peerConnection = peerConnection;
|
MagicPeerConnectionWrapper.peerConnection = peerConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSessionId() {
|
public String getSessionId() {
|
||||||
@ -209,4 +207,35 @@ public class PeerConnectionWrapper {
|
|||||||
public void setNick(String nick) {
|
public void setNick(String nick) {
|
||||||
this.nick = nick;
|
this.nick = nick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class MagicDataChannelObserver implements DataChannel.Observer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBufferedAmountChange(long l) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStateChange() {
|
||||||
|
if (magicDataChannel.state().equals(DataChannel.State.OPEN) &&
|
||||||
|
magicDataChannel.label().equals("status")) {
|
||||||
|
sendChannelData(new DataChannelMessage("videoOn"));
|
||||||
|
sendChannelData(new DataChannelMessage("audioOn"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(DataChannel.Buffer buffer) {
|
||||||
|
if (buffer.binary) {
|
||||||
|
Log.d(TAG, "Received binary msg over " + TAG + " " + sessionId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ByteBuffer data = buffer.data;
|
||||||
|
final byte[] bytes = new byte[data.capacity()];
|
||||||
|
data.get(bytes);
|
||||||
|
String strData = new String(bytes);
|
||||||
|
Log.d(TAG, "Got msg: " + strData + " over " + TAG + " " + sessionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -26,6 +26,15 @@
|
|||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
tools:context=".activities.CallActivity">
|
tools:context=".activities.CallActivity">
|
||||||
|
|
||||||
|
<GridLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/videos_grid_view"
|
||||||
|
android:columnCount="4"
|
||||||
|
android:rowCount="2">
|
||||||
|
|
||||||
|
</GridLayout>
|
||||||
|
|
||||||
<org.webrtc.SurfaceViewRenderer
|
<org.webrtc.SurfaceViewRenderer
|
||||||
android:id="@+id/pip_video_view"
|
android:id="@+id/pip_video_view"
|
||||||
android:layout_width="120dp"
|
android:layout_width="120dp"
|
||||||
@ -34,9 +43,4 @@
|
|||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_margin="16dp"/>
|
android:layout_margin="16dp"/>
|
||||||
|
|
||||||
<org.webrtc.SurfaceViewRenderer
|
|
||||||
android:id="@+id/fullscreen_video_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
33
app/src/main/res/layout/surface_renderer.xml
Normal file
33
app/src/main/res/layout/surface_renderer.xml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Nextcloud Talk application
|
||||||
|
~
|
||||||
|
~ @author Mario Danic
|
||||||
|
~ Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
|
||||||
|
~
|
||||||
|
~ This program is free software: you can redistribute it and/or modify
|
||||||
|
~ it under the terms of the GNU General Public License as published by
|
||||||
|
~ the Free Software Foundation, either version 3 of the License, or
|
||||||
|
~ at your option) any later version.
|
||||||
|
~
|
||||||
|
~ This program is distributed in the hope that it will be useful,
|
||||||
|
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
~ GNU General Public License for more details.
|
||||||
|
~
|
||||||
|
~ You should have received a copy of the GNU General Public License
|
||||||
|
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/relative_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<org.webrtc.SurfaceViewRenderer
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/surface_view"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
Loading…
Reference in New Issue
Block a user