use of org.webrtc.SessionDescription in project matrix-android-sdk by matrix-org.
the class MXWebRtcCall method answer.
// user actions
/**
* The call is accepted.
*/
@Override
public void answer() {
super.answer();
Log.d(LOG_TAG, "answer " + getCallState());
if (!CALL_STATE_CREATED.equals(getCallState()) && (null != mPeerConnection)) {
mUIThreadHandler.post(() -> {
if (null == mPeerConnection) {
Log.d(LOG_TAG, "answer the connection has been closed");
return;
}
dispatchOnStateDidChange(CALL_STATE_CREATE_ANSWER);
MediaConstraints constraints = new MediaConstraints();
constraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
constraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", isVideo() ? "true" : "false"));
mPeerConnection.createAnswer(new SdpObserver() {
@Override
public void onCreateSuccess(SessionDescription sessionDescription) {
Log.d(LOG_TAG, "createAnswer onCreateSuccess");
final SessionDescription sdp = new SessionDescription(sessionDescription.type, sessionDescription.description);
mUIThreadHandler.post(() -> {
if (mPeerConnection != null) {
// must be done to before sending the invitation message
mPeerConnection.setLocalDescription(new SdpObserver() {
@Override
public void onCreateSuccess(SessionDescription sessionDescription1) {
Log.d(LOG_TAG, "setLocalDescription onCreateSuccess");
}
@Override
public void onSetSuccess() {
Log.d(LOG_TAG, "setLocalDescription onSetSuccess");
sendAnswer(sdp);
dispatchOnStateDidChange(IMXCall.CALL_STATE_CONNECTING);
}
@Override
public void onCreateFailure(String s) {
Log.e(LOG_TAG, "setLocalDescription onCreateFailure " + s);
dispatchOnCallError(CALL_ERROR_CAMERA_INIT_FAILED);
hangup(null);
}
@Override
public void onSetFailure(String s) {
Log.e(LOG_TAG, "setLocalDescription onSetFailure " + s);
dispatchOnCallError(CALL_ERROR_CAMERA_INIT_FAILED);
hangup(null);
}
}, sdp);
}
});
}
@Override
public void onSetSuccess() {
Log.d(LOG_TAG, "createAnswer onSetSuccess");
}
@Override
public void onCreateFailure(String s) {
Log.e(LOG_TAG, "createAnswer onCreateFailure " + s);
dispatchOnCallError(CALL_ERROR_CAMERA_INIT_FAILED);
hangup(null);
}
@Override
public void onSetFailure(String s) {
Log.e(LOG_TAG, "createAnswer onSetFailure " + s);
dispatchOnCallError(CALL_ERROR_CAMERA_INIT_FAILED);
hangup(null);
}
}, constraints);
});
}
}
use of org.webrtc.SessionDescription in project matrix-android-sdk by matrix-org.
the class MXWebRtcCall method onCallAnswer.
/**
* The callee accepts the call.
*
* @param event the event
*/
private void onCallAnswer(final Event event) {
Log.d(LOG_TAG, "onCallAnswer : call state " + getCallState());
if (!CALL_STATE_CREATED.equals(getCallState()) && (null != mPeerConnection)) {
mUIThreadHandler.post(() -> {
dispatchOnStateDidChange(IMXCall.CALL_STATE_CONNECTING);
SessionDescription aDescription = null;
// extract the description
try {
JsonObject eventContent = event.getContentAsJsonObject();
if (eventContent.has("answer")) {
JsonObject answer = eventContent.getAsJsonObject("answer");
String type = answer.get("type").getAsString();
String sdp = answer.get("sdp").getAsString();
if (!TextUtils.isEmpty(type) && !TextUtils.isEmpty(sdp) && type.equals("answer")) {
aDescription = new SessionDescription(SessionDescription.Type.ANSWER, sdp);
}
}
} catch (Exception e) {
Log.e(LOG_TAG, "onCallAnswer : " + e.getMessage(), e);
}
mPeerConnection.setRemoteDescription(new SdpObserver() {
@Override
public void onCreateSuccess(SessionDescription sessionDescription) {
Log.d(LOG_TAG, "setRemoteDescription onCreateSuccess");
}
@Override
public void onSetSuccess() {
Log.d(LOG_TAG, "setRemoteDescription onSetSuccess");
}
@Override
public void onCreateFailure(String s) {
Log.e(LOG_TAG, "setRemoteDescription onCreateFailure " + s);
dispatchOnCallError(CALL_ERROR_CAMERA_INIT_FAILED);
}
@Override
public void onSetFailure(String s) {
Log.e(LOG_TAG, "setRemoteDescription onSetFailure " + s);
dispatchOnCallError(CALL_ERROR_CAMERA_INIT_FAILED);
}
}, aDescription);
});
}
}
use of org.webrtc.SessionDescription in project matrix-android-sdk by matrix-org.
the class MXWebRtcCall method createLocalStream.
/**
* create the local stream
*/
private void createLocalStream() {
Log.d(LOG_TAG, "## createLocalStream(): IN");
// check there is at least one stream to start a call
if ((null == mLocalVideoTrack) && (null == mLocalAudioTrack)) {
Log.d(LOG_TAG, "## createLocalStream(): CALL_ERROR_CALL_INIT_FAILED");
dispatchOnCallError(CALL_ERROR_CALL_INIT_FAILED);
hangup("no_stream");
terminate(IMXCall.END_CALL_REASON_UNDEFINED);
return;
}
// create our local stream to add our audio and video tracks
mLocalMediaStream = mPeerConnectionFactory.createLocalMediaStream("ARDAMS");
// add video track to local stream
if (null != mLocalVideoTrack) {
mLocalMediaStream.addTrack(mLocalVideoTrack);
}
// add audio track to local stream
if (null != mLocalAudioTrack) {
mLocalMediaStream.addTrack(mLocalAudioTrack);
}
if (null != mFullScreenRTCView) {
mFullScreenRTCView.setStream(mLocalMediaStream);
mFullScreenRTCView.setVisibility(View.VISIBLE);
}
// build ICE servers list
List<PeerConnection.IceServer> iceServers = getIceServers();
if (iceServers.isEmpty() && defaultIceServer != null) {
iceServers.add(defaultIceServer);
}
// define at least on server
if (iceServers.isEmpty()) {
Log.d(LOG_TAG, "## createLocalStream(): No iceServers found ");
}
// define constraints
PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers);
rtcConfig.enableRtpDataChannel = true;
// start connecting to the other peer by creating the peer connection
mPeerConnection = mPeerConnectionFactory.createPeerConnection(rtcConfig, new PeerConnection.Observer() {
@Override
public void onSignalingChange(PeerConnection.SignalingState signalingState) {
Log.d(LOG_TAG, "## mPeerConnection creation: onSignalingChange state=" + signalingState);
}
@Override
public void onIceConnectionChange(final PeerConnection.IceConnectionState iceConnectionState) {
Log.d(LOG_TAG, "## mPeerConnection creation: onIceConnectionChange " + iceConnectionState);
mUIThreadHandler.post(() -> {
if (iceConnectionState == PeerConnection.IceConnectionState.CONNECTED) {
if ((null != mLocalVideoTrack) && mUsingLargeLocalRenderer && isVideo()) {
mLocalVideoTrack.setEnabled(false);
// the local attendee video is sent by the server among the others conference attendees.
if (!isConference()) {
// add local preview, only for 1:1 call
// mLocalVideoTrack.addRenderer(mSmallLocalRenderer);
mPipRTCView.setStream(mLocalMediaStream);
mPipRTCView.setVisibility(View.VISIBLE);
// to be able to display the avatar video above the large one
mPipRTCView.setZOrder(1);
}
mLocalVideoTrack.setEnabled(true);
mUsingLargeLocalRenderer = false;
mCallView.post(() -> {
if (null != mCallView) {
mCallView.invalidate();
}
});
}
dispatchOnStateDidChange(IMXCall.CALL_STATE_CONNECTED);
} else /*else if (iceConnectionState == PeerConnection.IceConnectionState.DISCONNECTED) {
// TODO warn the user ?
hangup(null);
} else if (iceConnectionState == PeerConnection.IceConnectionState.CLOSED) {
// TODO warn the user ?
terminate();
}*/
if (iceConnectionState == PeerConnection.IceConnectionState.FAILED) {
dispatchOnCallError(CALL_ERROR_ICE_FAILED);
hangup("ice_failed");
}
});
}
@Override
public void onIceConnectionReceivingChange(boolean var1) {
Log.d(LOG_TAG, "## mPeerConnection creation: onIceConnectionReceivingChange " + var1);
}
@Override
public void onIceCandidatesRemoved(IceCandidate[] var1) {
Log.d(LOG_TAG, "## mPeerConnection creation: onIceCandidatesRemoved " + Arrays.toString(var1));
}
@Override
public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {
Log.d(LOG_TAG, "## mPeerConnection creation: onIceGatheringChange " + iceGatheringState);
}
@Override
public void onAddTrack(RtpReceiver var1, MediaStream[] var2) {
Log.d(LOG_TAG, "## mPeerConnection creation: onAddTrack " + var1 + " -- " + Arrays.toString(var2));
}
@Override
public void onIceCandidate(final IceCandidate iceCandidate) {
Log.d(LOG_TAG, "## mPeerConnection creation: onIceCandidate " + iceCandidate);
mUIThreadHandler.post(() -> {
if (!isCallEnded()) {
JsonObject content = new JsonObject();
content.addProperty("version", 0);
content.addProperty("call_id", mCallId);
JsonArray candidates = new JsonArray();
JsonObject cand = new JsonObject();
cand.addProperty("sdpMLineIndex", iceCandidate.sdpMLineIndex);
cand.addProperty("sdpMid", iceCandidate.sdpMid);
cand.addProperty("candidate", iceCandidate.sdp);
candidates.add(cand);
content.add("candidates", candidates);
boolean addIt = true;
// merge candidates
if (mPendingEvents.size() > 0) {
try {
Event lastEvent = mPendingEvents.get(mPendingEvents.size() - 1);
if (TextUtils.equals(lastEvent.getType(), Event.EVENT_TYPE_CALL_CANDIDATES)) {
// return the content cast as a JsonObject
// it is not a copy
JsonObject lastContent = lastEvent.getContentAsJsonObject();
JsonArray lastContentCandidates = lastContent.get("candidates").getAsJsonArray();
JsonArray newContentCandidates = content.get("candidates").getAsJsonArray();
Log.d(LOG_TAG, "Merge candidates from " + lastContentCandidates.size() + " to " + (lastContentCandidates.size() + newContentCandidates.size() + " items."));
lastContentCandidates.addAll(newContentCandidates);
// replace the candidates list
lastContent.remove("candidates");
lastContent.add("candidates", lastContentCandidates);
// don't need to save anything, lastContent is a reference not a copy
addIt = false;
}
} catch (Exception e) {
Log.e(LOG_TAG, "## createLocalStream(): createPeerConnection - onIceCandidate() Exception Msg=" + e.getMessage(), e);
}
}
if (addIt) {
Event event = new Event(Event.EVENT_TYPE_CALL_CANDIDATES, content, mSession.getCredentials().userId, mCallSignalingRoom.getRoomId());
mPendingEvents.add(event);
sendNextEvent();
}
}
});
}
@Override
public void onAddStream(final MediaStream mediaStream) {
Log.d(LOG_TAG, "## mPeerConnection creation: onAddStream " + mediaStream);
mUIThreadHandler.post(() -> {
if ((mediaStream.videoTracks.size() == 1) && !isCallEnded()) {
mRemoteVideoTrack = mediaStream.videoTracks.get(0);
mRemoteVideoTrack.setEnabled(true);
mFullScreenRTCView.setStream(mediaStream);
mFullScreenRTCView.setVisibility(View.VISIBLE);
}
});
}
@Override
public void onRemoveStream(final MediaStream mediaStream) {
Log.d(LOG_TAG, "## mPeerConnection creation: onRemoveStream " + mediaStream);
mUIThreadHandler.post(() -> {
if (null != mRemoteVideoTrack) {
mRemoteVideoTrack.dispose();
mRemoteVideoTrack = null;
mediaStream.videoTracks.get(0).dispose();
}
});
}
@Override
public void onDataChannel(DataChannel dataChannel) {
Log.d(LOG_TAG, "## mPeerConnection creation: onDataChannel " + dataChannel);
}
@Override
public void onRenegotiationNeeded() {
Log.d(LOG_TAG, "## mPeerConnection creation: onRenegotiationNeeded");
}
});
if (null == mPeerConnection) {
dispatchOnCallError(CALL_ERROR_ICE_FAILED);
hangup("cannot create peer connection");
return;
}
// send our local video and audio stream to make it seen by the other part
mPeerConnection.addStream(mLocalMediaStream);
MediaConstraints constraints = new MediaConstraints();
constraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
constraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", isVideo() ? "true" : "false"));
// call createOffer only for outgoing calls
if (!isIncoming()) {
Log.d(LOG_TAG, "## createLocalStream(): !isIncoming() -> createOffer");
mPeerConnection.createOffer(new SdpObserver() {
@Override
public void onCreateSuccess(SessionDescription sessionDescription) {
Log.d(LOG_TAG, "createOffer onCreateSuccess");
final SessionDescription sdp = new SessionDescription(sessionDescription.type, sessionDescription.description);
mUIThreadHandler.post(() -> {
if (mPeerConnection != null) {
// must be done to before sending the invitation message
mPeerConnection.setLocalDescription(new SdpObserver() {
@Override
public void onCreateSuccess(SessionDescription sessionDescription1) {
Log.d(LOG_TAG, "setLocalDescription onCreateSuccess");
}
@Override
public void onSetSuccess() {
Log.d(LOG_TAG, "setLocalDescription onSetSuccess");
sendInvite(sdp);
dispatchOnStateDidChange(IMXCall.CALL_STATE_INVITE_SENT);
}
@Override
public void onCreateFailure(String s) {
Log.e(LOG_TAG, "setLocalDescription onCreateFailure " + s);
dispatchOnCallError(CALL_ERROR_CAMERA_INIT_FAILED);
hangup(null);
}
@Override
public void onSetFailure(String s) {
Log.e(LOG_TAG, "setLocalDescription onSetFailure " + s);
dispatchOnCallError(CALL_ERROR_CAMERA_INIT_FAILED);
hangup(null);
}
}, sdp);
}
});
}
@Override
public void onSetSuccess() {
Log.d(LOG_TAG, "createOffer onSetSuccess");
}
@Override
public void onCreateFailure(String s) {
Log.d(LOG_TAG, "createOffer onCreateFailure " + s);
dispatchOnCallError(CALL_ERROR_CAMERA_INIT_FAILED);
}
@Override
public void onSetFailure(String s) {
Log.d(LOG_TAG, "createOffer onSetFailure " + s);
dispatchOnCallError(CALL_ERROR_CAMERA_INIT_FAILED);
}
}, constraints);
dispatchOnStateDidChange(IMXCall.CALL_STATE_WAIT_CREATE_OFFER);
}
}
use of org.webrtc.SessionDescription in project matrix-android-sdk by matrix-org.
the class MXWebRtcCall method setRemoteDescription.
/**
* Set the remote description
*
* @param callInviteParams the invitation params
*/
private void setRemoteDescription(final JsonObject callInviteParams) {
Log.d(LOG_TAG, "setRemoteDescription " + callInviteParams);
SessionDescription aDescription = null;
// extract the description
try {
if (callInviteParams.has("offer")) {
JsonObject answer = callInviteParams.getAsJsonObject("offer");
String type = answer.get("type").getAsString();
String sdp = answer.get("sdp").getAsString();
if (!TextUtils.isEmpty(type) && !TextUtils.isEmpty(sdp)) {
aDescription = new SessionDescription(SessionDescription.Type.OFFER, sdp);
}
}
} catch (Exception e) {
Log.e(LOG_TAG, "## setRemoteDescription(): Exception Msg=" + e.getMessage(), e);
}
mPeerConnection.setRemoteDescription(new SdpObserver() {
@Override
public void onCreateSuccess(SessionDescription sessionDescription) {
Log.d(LOG_TAG, "setRemoteDescription onCreateSuccess");
}
@Override
public void onSetSuccess() {
Log.d(LOG_TAG, "setRemoteDescription onSetSuccess");
mIsIncomingPrepared = true;
mUIThreadHandler.post(() -> checkPendingCandidates());
}
@Override
public void onCreateFailure(String s) {
Log.e(LOG_TAG, "setRemoteDescription onCreateFailure " + s);
dispatchOnCallError(CALL_ERROR_CAMERA_INIT_FAILED);
}
@Override
public void onSetFailure(String s) {
Log.e(LOG_TAG, "setRemoteDescription onSetFailure " + s);
dispatchOnCallError(CALL_ERROR_CAMERA_INIT_FAILED);
}
}, aDescription);
}
use of org.webrtc.SessionDescription in project flutter-webrtc by flutter-webrtc.
the class MethodCallHandlerImpl method peerConnectionSetLocalDescription.
public void peerConnectionSetLocalDescription(ConstraintsMap sdpMap, final String id, final Result result) {
PeerConnection peerConnection = getPeerConnection(id);
if (peerConnection != null) {
SessionDescription sdp = new SessionDescription(Type.fromCanonicalForm(sdpMap.getString("type")), sdpMap.getString("sdp"));
peerConnection.setLocalDescription(new SdpObserver() {
@Override
public void onCreateSuccess(final SessionDescription sdp) {
}
@Override
public void onSetSuccess() {
result.success(null);
}
@Override
public void onCreateFailure(String s) {
}
@Override
public void onSetFailure(String s) {
resultError("peerConnectionSetLocalDescription", "WEBRTC_SET_LOCAL_DESCRIPTION_ERROR: " + s, result);
}
}, sdp);
} else {
resultError("peerConnectionSetLocalDescription", "WEBRTC_SET_LOCAL_DESCRIPTION_ERROR: peerConnection is null", result);
}
}
Aggregations