Retrocompatibility with 2.15.0 with openvidu-server version on joinRoom

pull/600/head
pabloFuente 2020-09-10 12:33:16 +02:00
parent 2d6dfb2363
commit 243dfcee67
6 changed files with 201 additions and 167 deletions

View File

@ -142,7 +142,7 @@ export class Connection {
}; };
// TODO: CLEAN 2.15.0 LEGACY CODE // TODO: CLEAN 2.15.0 LEGACY CODE
// THIS LINE: // THIS LINE:
const stream = this.session.openvidu.openviduServerVersion.startsWith('2.16') ? new Stream(this.session, streamOptions) : new StreamLEGACY(this.session, streamOptions); const stream = !this.session.openvidu.openviduServerVersion ? /*2.15.0 (LEGACY)*/ new StreamLEGACY(this.session, streamOptions) : /*2.16.0 (NORMAL API)*/ new Stream(this.session, streamOptions);
// SHOULD GET BACK TO: // SHOULD GET BACK TO:
// const stream = new Stream(this.session, streamOptions); // const stream = new Stream(this.session, streamOptions);

View File

@ -95,7 +95,7 @@ export class Publisher extends StreamManager {
// TODO: CLEAN 2.15.0 LEGACY CODE // TODO: CLEAN 2.15.0 LEGACY CODE
// THIS LINE: // THIS LINE:
super(openvidu.openviduServerVersion.startsWith('2.16') ? new Stream((!!openvidu.session) ? openvidu.session : new Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }) : new StreamLEGACY((!!openvidu.session) ? openvidu.session : new Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl); super(!openvidu.openviduServerVersion ? /*2.15.0 or 2.16.0 NOT CONNECTED (LEGACY)*/ new StreamLEGACY((!!openvidu.session) ? openvidu.session : new Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }) : /*2.16.0 CONNECTED (NORMAL API)*/ new Stream(openvidu.session, { publisherProperties: properties, mediaConstraints: {} }), targEl);
// SHOULD GET BACK TO: // SHOULD GET BACK TO:
// super(new Stream((!!openvidu.session) ? openvidu.session : new Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl); // super(new Stream((!!openvidu.session) ? openvidu.session : new Session(openvidu), { publisherProperties: properties, mediaConstraints: {} }), targEl);
@ -612,8 +612,8 @@ export class Publisher extends StreamManager {
.then(myConstraints => { .then(myConstraints => {
if (!!myConstraints.videoTrack && !!myConstraints.audioTrack || if (!!myConstraints.videoTrack && !!myConstraints.audioTrack ||
!!myConstraints.audioTrack && myConstraints.constraints?.video === false || !!myConstraints.audioTrack && myConstraints.constraints?.video === false ||
!!myConstraints.videoTrack && myConstraints.constraints?.audio === false) { !!myConstraints.videoTrack && myConstraints.constraints?.audio === false) {
// No need to call getUserMedia at all. MediaStreamTracks already provided // No need to call getUserMedia at all. MediaStreamTracks already provided
successCallback(this.openvidu.addAlreadyProvidedTracks(myConstraints, new MediaStream())); successCallback(this.openvidu.addAlreadyProvidedTracks(myConstraints, new MediaStream()));
// Return as we do not need to process further // Return as we do not need to process further

View File

@ -1154,6 +1154,7 @@ export class Session extends EventDispatcher {
// Initialize local Connection object with values returned by openvidu-server // Initialize local Connection object with values returned by openvidu-server
this.connection = new Connection(this); this.connection = new Connection(this);
this.openvidu.openviduServerVersion = response.openviduServerVersion;
this.connection.connectionId = response.id; this.connection.connectionId = response.id;
this.connection.creationTime = response.createdAt; this.connection.creationTime = response.createdAt;
this.connection.data = response.metadata; this.connection.data = response.metadata;
@ -1312,7 +1313,6 @@ export class Session extends EventDispatcher {
this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; this.openvidu.wsUri = 'wss://' + url.host + '/openvidu';
this.openvidu.httpUri = 'https://' + url.host; this.openvidu.httpUri = 'https://' + url.host;
this.openvidu.openviduServerVersion = openviduServerVersion;
} else { } else {
logger.error('Token "' + token + '" is not valid') logger.error('Token "' + token + '" is not valid')

View File

@ -42,201 +42,228 @@ export class StreamLEGACY extends Stream {
* @hidden * @hidden
*/ */
initWebRtcPeerSend(reconnect: boolean): Promise<any> { initWebRtcPeerSend(reconnect: boolean): Promise<any> {
return new Promise((resolve, reject) => {
if (!reconnect) { if (!!this.session.openvidu.openviduServerVersion) {
this.initHarkEvents(); // Init hark events for the local stream // 2.16.0
} return super.initWebRtcPeerSend(reconnect);
const userMediaConstraints = { } else {
audio: this.isSendAudio(), // 2.15.0
video: this.isSendVideo() return new Promise((resolve, reject) => {
};
const options = { if (!reconnect) {
mediaStream: this.mediaStream, this.initHarkEvents(); // Init hark events for the local stream
mediaConstraints: userMediaConstraints,
onicecandidate: this.connection.sendIceCandidate.bind(this.connection),
iceServers: this.getIceServersConf(),
simulcast: false
};
const successCallback = (sdpOfferParam) => {
logger.debug('Sending SDP offer to publish as '
+ this.streamId, sdpOfferParam);
const method = reconnect ? 'reconnectStream' : 'publishVideo';
let params;
if (reconnect) {
params = {
stream: this.streamId
}
} else {
let typeOfVideo = '';
if (this.isSendVideo()) {
typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (this.isSendScreen() ? 'SCREEN' : 'CAMERA');
}
params = {
doLoopback: this.displayMyRemote() || false,
hasAudio: this.isSendAudio(),
hasVideo: this.isSendVideo(),
audioActive: this.audioActive,
videoActive: this.videoActive,
typeOfVideo,
frameRate: !!this.frameRate ? this.frameRate : -1,
videoDimensions: JSON.stringify(this.videoDimensions),
filter: this.outboundStreamOpts.publisherProperties.filter
}
} }
params['sdpOffer'] = sdpOfferParam;
this.session.openvidu.sendRequest(method, params, (error, response) => { const userMediaConstraints = {
if (error) { audio: this.isSendAudio(),
if (error.code === 401) { video: this.isSendVideo()
reject(new OpenViduError(OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish")); };
} else {
reject('Error on publishVideo: ' + JSON.stringify(error)); const options = {
mediaStream: this.mediaStream,
mediaConstraints: userMediaConstraints,
onicecandidate: this.connection.sendIceCandidate.bind(this.connection),
iceServers: this.getIceServersConf(),
simulcast: false
};
const successCallback = (sdpOfferParam) => {
logger.debug('Sending SDP offer to publish as '
+ this.streamId, sdpOfferParam);
const method = reconnect ? 'reconnectStream' : 'publishVideo';
let params;
if (reconnect) {
params = {
stream: this.streamId
} }
} else { } else {
(<WebRtcPeerLEGACY>this.webRtcPeer).processAnswer(response.sdpAnswer, false) let typeOfVideo = '';
.then(() => { if (this.isSendVideo()) {
this.streamId = response.id; typeOfVideo = (typeof MediaStreamTrack !== 'undefined' && this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) ? 'CUSTOM' : (this.isSendScreen() ? 'SCREEN' : 'CAMERA');
this.creationTime = response.createdAt; }
this.isLocalStreamPublished = true; params = {
this.publishedOnce = true; doLoopback: this.displayMyRemote() || false,
if (this.displayMyRemote()) { hasAudio: this.isSendAudio(),
this.localMediaStreamWhenSubscribedToRemote = this.mediaStream; hasVideo: this.isSendVideo(),
this.remotePeerSuccessfullyEstablished(); audioActive: this.audioActive,
} videoActive: this.videoActive,
if (reconnect) { typeOfVideo,
this.ee.emitEvent('stream-reconnected-by-publisher', []); frameRate: !!this.frameRate ? this.frameRate : -1,
} else { videoDimensions: JSON.stringify(this.videoDimensions),
this.ee.emitEvent('stream-created-by-publisher', []); filter: this.outboundStreamOpts.publisherProperties.filter
} }
this.initWebRtcStats();
logger.info("'Publisher' (" + this.streamId + ") successfully " + (reconnect ? "reconnected" : "published") + " to session");
resolve();
})
.catch(error => {
reject(error);
});
} }
}); params['sdpOffer'] = sdpOfferParam;
};
if (reconnect) { this.session.openvidu.sendRequest(method, params, (error, response) => {
this.disposeWebRtcPeer(); if (error) {
} if (error.code === 401) {
if (this.displayMyRemote()) { reject(new OpenViduError(OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish"));
this.webRtcPeer = new WebRtcPeerSendrecvLEGACY(options); } else {
} else { reject('Error on publishVideo: ' + JSON.stringify(error));
this.webRtcPeer = new WebRtcPeerSendonlyLEGACY(options); }
} } else {
this.webRtcPeer.addIceConnectionStateChangeListener('publisher of ' + this.connection.connectionId); (<WebRtcPeerLEGACY>this.webRtcPeer).processAnswer(response.sdpAnswer, false)
(<WebRtcPeerLEGACY>this.webRtcPeer).generateOffer().then(sdpOffer => { .then(() => {
successCallback(sdpOffer); this.streamId = response.id;
}).catch(error => { this.creationTime = response.createdAt;
reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error))); this.isLocalStreamPublished = true;
this.publishedOnce = true;
if (this.displayMyRemote()) {
this.localMediaStreamWhenSubscribedToRemote = this.mediaStream;
this.remotePeerSuccessfullyEstablished();
}
if (reconnect) {
this.ee.emitEvent('stream-reconnected-by-publisher', []);
} else {
this.ee.emitEvent('stream-created-by-publisher', []);
}
this.initWebRtcStats();
logger.info("'Publisher' (" + this.streamId + ") successfully " + (reconnect ? "reconnected" : "published") + " to session");
resolve();
})
.catch(error => {
reject(error);
});
}
});
};
if (reconnect) {
this.disposeWebRtcPeer();
}
if (this.displayMyRemote()) {
this.webRtcPeer = new WebRtcPeerSendrecvLEGACY(options);
} else {
this.webRtcPeer = new WebRtcPeerSendonlyLEGACY(options);
}
this.webRtcPeer.addIceConnectionStateChangeListener('publisher of ' + this.connection.connectionId);
(<WebRtcPeerLEGACY>this.webRtcPeer).generateOffer().then(sdpOffer => {
successCallback(sdpOffer);
}).catch(error => {
reject(new Error('(publish) SDP offer error: ' + JSON.stringify(error)));
});
}); });
});
}
} }
/** /**
* @hidden * @hidden
*/ */
initWebRtcPeerReceive(reconnect: boolean): Promise<any> { initWebRtcPeerReceive(reconnect: boolean): Promise<any> {
return new Promise((resolve, reject) => {
const offerConstraints = { if (!!this.session.openvidu.openviduServerVersion) {
audio: this.inboundStreamOpts.hasAudio, // 2.16.0
video: this.inboundStreamOpts.hasVideo return super.initWebRtcPeerReceive(reconnect);
};
logger.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer",
offerConstraints);
const options = {
onicecandidate: this.connection.sendIceCandidate.bind(this.connection),
mediaConstraints: offerConstraints,
iceServers: this.getIceServersConf(),
simulcast: false
};
const successCallback = (sdpOfferParam) => { } else {
logger.debug('Sending SDP offer to subscribe to ' // 2.15.0
+ this.streamId, sdpOfferParam); return new Promise((resolve, reject) => {
const method = reconnect ? 'reconnectStream' : 'receiveVideoFrom'; const offerConstraints = {
const params = { sdpOffer: sdpOfferParam }; audio: this.inboundStreamOpts.hasAudio,
params[reconnect ? 'stream' : 'sender'] = this.streamId; video: this.inboundStreamOpts.hasVideo
};
logger.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer",
offerConstraints);
const options = {
onicecandidate: this.connection.sendIceCandidate.bind(this.connection),
mediaConstraints: offerConstraints,
iceServers: this.getIceServersConf(),
simulcast: false
};
this.session.openvidu.sendRequest(method, params, (error, response) => { const successCallback = (sdpOfferParam) => {
if (error) { logger.debug('Sending SDP offer to subscribe to '
reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); + this.streamId, sdpOfferParam);
} else {
// Ios Ionic. Limitation: some bug in iosrtc cordova plugin makes it necessary const method = reconnect ? 'reconnectStream' : 'receiveVideoFrom';
// to add a timeout before calling PeerConnection#setRemoteDescription during const params = { sdpOffer: sdpOfferParam };
// some time (400 ms) from the moment first subscriber stream is received params[reconnect ? 'stream' : 'sender'] = this.streamId;
if (this.session.isFirstIonicIosSubscriber) {
this.session.isFirstIonicIosSubscriber = false; this.session.openvidu.sendRequest(method, params, (error, response) => {
setTimeout(() => { if (error) {
// After 400 ms Ionic iOS subscribers won't need to run reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error)));
// PeerConnection#setRemoteDescription after 250 ms timeout anymore } else {
this.session.countDownForIonicIosSubscribersActive = false; // Ios Ionic. Limitation: some bug in iosrtc cordova plugin makes it necessary
}, 400); // to add a timeout before calling PeerConnection#setRemoteDescription during
// some time (400 ms) from the moment first subscriber stream is received
if (this.session.isFirstIonicIosSubscriber) {
this.session.isFirstIonicIosSubscriber = false;
setTimeout(() => {
// After 400 ms Ionic iOS subscribers won't need to run
// PeerConnection#setRemoteDescription after 250 ms timeout anymore
this.session.countDownForIonicIosSubscribersActive = false;
}, 400);
}
const needsTimeoutOnProcessAnswer = this.session.countDownForIonicIosSubscribersActive;
(<WebRtcPeerLEGACY>this.webRtcPeer).processAnswer(response.sdpAnswer, needsTimeoutOnProcessAnswer).then(() => {
logger.info("'Subscriber' (" + this.streamId + ") successfully " + (reconnect ? "reconnected" : "subscribed"));
this.remotePeerSuccessfullyEstablished();
this.initWebRtcStats();
resolve();
}).catch(error => {
reject(error);
});
} }
const needsTimeoutOnProcessAnswer = this.session.countDownForIonicIosSubscribersActive; });
(<WebRtcPeerLEGACY>this.webRtcPeer).processAnswer(response.sdpAnswer, needsTimeoutOnProcessAnswer).then(() => { };
logger.info("'Subscriber' (" + this.streamId + ") successfully " + (reconnect ? "reconnected" : "subscribed"));
this.remotePeerSuccessfullyEstablished();
this.initWebRtcStats();
resolve();
}).catch(error => {
reject(error);
});
}
});
};
this.webRtcPeer = new WebRtcPeerRecvonlyLEGACY(options); this.webRtcPeer = new WebRtcPeerRecvonlyLEGACY(options);
this.webRtcPeer.addIceConnectionStateChangeListener(this.streamId); this.webRtcPeer.addIceConnectionStateChangeListener(this.streamId);
(<WebRtcPeerLEGACY>this.webRtcPeer).generateOffer() (<WebRtcPeerLEGACY>this.webRtcPeer).generateOffer()
.then(sdpOffer => { .then(sdpOffer => {
successCallback(sdpOffer); successCallback(sdpOffer);
}) })
.catch(error => { .catch(error => {
reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error))); reject(new Error('(subscribe) SDP offer error: ' + JSON.stringify(error)));
}); });
}); });
}
} }
/** /**
* @hidden * @hidden
*/ */
remotePeerSuccessfullyEstablished(): void { remotePeerSuccessfullyEstablished(): void {
this.mediaStream = new MediaStream();
let receiver: RTCRtpReceiver;
for (receiver of this.webRtcPeer.pc.getReceivers()) {
if (!!receiver.track) {
this.mediaStream.addTrack(receiver.track);
}
}
logger.debug('Peer remote stream', this.mediaStream);
if (!!this.mediaStream) { if (!!this.session.openvidu.openviduServerVersion) {
// 2.16.0
super.remotePeerSuccessfullyEstablished();
if (this.streamManager instanceof Subscriber) { } else {
// Apply SubscriberProperties.subscribeToAudio and SubscriberProperties.subscribeToVideo // 2.15.0
if (!!this.mediaStream.getAudioTracks()[0]) { this.mediaStream = new MediaStream();
const enabled = !!((<Subscriber>this.streamManager).properties.subscribeToAudio); let receiver: RTCRtpReceiver;
this.mediaStream.getAudioTracks()[0].enabled = enabled; for (receiver of this.webRtcPeer.pc.getReceivers()) {
} if (!!receiver.track) {
if (!!this.mediaStream.getVideoTracks()[0]) { this.mediaStream.addTrack(receiver.track);
const enabled = !!((<Subscriber>this.streamManager).properties.subscribeToVideo);
this.mediaStream.getVideoTracks()[0].enabled = enabled;
} }
} }
logger.debug('Peer remote stream', this.mediaStream);
if (!!this.mediaStream) {
if (this.streamManager instanceof Subscriber) {
// Apply SubscriberProperties.subscribeToAudio and SubscriberProperties.subscribeToVideo
if (!!this.mediaStream.getAudioTracks()[0]) {
const enabled = !!((<Subscriber>this.streamManager).properties.subscribeToAudio);
this.mediaStream.getAudioTracks()[0].enabled = enabled;
}
if (!!this.mediaStream.getVideoTracks()[0]) {
const enabled = !!((<Subscriber>this.streamManager).properties.subscribeToVideo);
this.mediaStream.getVideoTracks()[0].enabled = enabled;
}
}
this.updateMediaStreamInVideos();
this.initHarkEvents(); // Init hark events for the remote stream
}
this.updateMediaStreamInVideos();
this.initHarkEvents(); // Init hark events for the remote stream
} }
} }

View File

@ -41,6 +41,7 @@ public class ProtocolElements {
public static final String JOINROOM_RECORDER_PARAM = "recorder"; public static final String JOINROOM_RECORDER_PARAM = "recorder";
public static final String JOINROOM_PEERID_PARAM = "id"; public static final String JOINROOM_PEERID_PARAM = "id";
public static final String JOINROOM_OPENVIDUSERVERVERSION_PARAM = "openviduServerVersion";
public static final String JOINROOM_PEERCREATEDAT_PARAM = "createdAt"; public static final String JOINROOM_PEERCREATEDAT_PARAM = "createdAt";
public static final String JOINROOM_PEERSTREAMS_PARAM = "streams"; public static final String JOINROOM_PEERSTREAMS_PARAM = "streams";
public static final String JOINROOM_PEERSTREAMID_PARAM = "id"; public static final String JOINROOM_PEERSTREAMID_PARAM = "id";

View File

@ -40,6 +40,7 @@ import io.openvidu.client.internal.ProtocolElements;
import io.openvidu.java.client.OpenViduRole; import io.openvidu.java.client.OpenViduRole;
import io.openvidu.server.cdr.CallDetailRecord; import io.openvidu.server.cdr.CallDetailRecord;
import io.openvidu.server.config.InfoHandler; import io.openvidu.server.config.InfoHandler;
import io.openvidu.server.config.OpenviduBuildInfo;
import io.openvidu.server.config.OpenviduConfig; import io.openvidu.server.config.OpenviduConfig;
import io.openvidu.server.kurento.core.KurentoParticipant; import io.openvidu.server.kurento.core.KurentoParticipant;
import io.openvidu.server.kurento.endpoint.KurentoFilter; import io.openvidu.server.kurento.endpoint.KurentoFilter;
@ -62,6 +63,9 @@ public class SessionEventsHandler {
@Autowired @Autowired
protected OpenviduConfig openviduConfig; protected OpenviduConfig openviduConfig;
@Autowired
protected OpenviduBuildInfo openviduBuildConfig;
Map<String, Recording> recordingsStarted = new ConcurrentHashMap<>(); Map<String, Recording> recordingsStarted = new ConcurrentHashMap<>();
ReentrantLock lock = new ReentrantLock(); ReentrantLock lock = new ReentrantLock();
@ -156,6 +160,8 @@ public class SessionEventsHandler {
result.addProperty(ProtocolElements.PARTICIPANTJOINED_USER_PARAM, participant.getParticipantPublicId()); result.addProperty(ProtocolElements.PARTICIPANTJOINED_USER_PARAM, participant.getParticipantPublicId());
result.addProperty(ProtocolElements.PARTICIPANTJOINED_CREATEDAT_PARAM, participant.getCreatedAt()); result.addProperty(ProtocolElements.PARTICIPANTJOINED_CREATEDAT_PARAM, participant.getCreatedAt());
result.addProperty(ProtocolElements.PARTICIPANTJOINED_METADATA_PARAM, participant.getFullMetadata()); result.addProperty(ProtocolElements.PARTICIPANTJOINED_METADATA_PARAM, participant.getFullMetadata());
result.addProperty(ProtocolElements.JOINROOM_OPENVIDUSERVERVERSION_PARAM,
openviduBuildConfig.getOpenViduServerVersion());
result.add("value", resultArray); result.add("value", resultArray);
rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, result); rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, result);