mirror of https://github.com/OpenVidu/openvidu.git
openvidu-browser WebRtcPeer compilation uploaded
parent
863c0bf96a
commit
5fefcdc8a2
|
@ -0,0 +1,63 @@
|
|||
export interface WebRtcPeerConfiguration {
|
||||
mediaConstraints: {
|
||||
audio: boolean;
|
||||
video: boolean;
|
||||
};
|
||||
simulcast: boolean;
|
||||
onicecandidate: (event: any) => void;
|
||||
iceServers: RTCIceServer[] | undefined;
|
||||
mediaStream?: MediaStream;
|
||||
mode?: string;
|
||||
id?: string;
|
||||
}
|
||||
export declare class WebRtcPeer {
|
||||
private configuration;
|
||||
pc: RTCPeerConnection;
|
||||
id: string;
|
||||
remoteCandidatesQueue: RTCIceCandidate[];
|
||||
localCandidatesQueue: RTCIceCandidate[];
|
||||
iceCandidateList: RTCIceCandidate[];
|
||||
private candidategatheringdone;
|
||||
constructor(configuration: WebRtcPeerConfiguration);
|
||||
/**
|
||||
* This function creates the RTCPeerConnection object taking into account the
|
||||
* properties received in the constructor. It starts the SDP negotiation
|
||||
* process: generates the SDP offer and invokes the onsdpoffer callback. This
|
||||
* callback is expected to send the SDP offer, in order to obtain an SDP
|
||||
* answer from another peer.
|
||||
*/
|
||||
start(): Promise<any>;
|
||||
/**
|
||||
* This method frees the resources used by WebRtcPeer
|
||||
*/
|
||||
dispose(): void;
|
||||
/**
|
||||
* 1) Function that creates an offer, sets it as local description and returns the offer param
|
||||
* to send to OpenVidu Server (will be the remote description of other peer)
|
||||
*/
|
||||
generateOffer(): Promise<string>;
|
||||
/**
|
||||
* 2) Function to invoke when a SDP offer is received. Sets it as remote description,
|
||||
* generates and answer and returns it to send it to OpenVidu Server
|
||||
*/
|
||||
processOffer(sdpOffer: string): Promise<ConstrainDOMString>;
|
||||
/**
|
||||
* 3) Function invoked when a SDP answer is received. Final step in SDP negotiation, the peer
|
||||
* just needs to set the answer as its remote description
|
||||
*/
|
||||
processAnswer(sdpAnswer: string): Promise<string>;
|
||||
/**
|
||||
* Callback function invoked when an ICE candidate is received
|
||||
*/
|
||||
addIceCandidate(iceCandidate: RTCIceCandidate): Promise<void>;
|
||||
private streamStop;
|
||||
}
|
||||
export declare class WebRtcPeerRecvonly extends WebRtcPeer {
|
||||
constructor(configuration: WebRtcPeerConfiguration);
|
||||
}
|
||||
export declare class WebRtcPeerSendonly extends WebRtcPeer {
|
||||
constructor(configuration: WebRtcPeerConfiguration);
|
||||
}
|
||||
export declare class WebRtcPeerSendrecv extends WebRtcPeer {
|
||||
constructor(configuration: WebRtcPeerConfiguration);
|
||||
}
|
|
@ -0,0 +1,264 @@
|
|||
"use strict";
|
||||
/*
|
||||
* (C) Copyright 2017-2018 OpenVidu (https://openvidu.io/)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var freeice = require("freeice");
|
||||
var uuid = require("uuid");
|
||||
var platform = require("platform");
|
||||
var WebRtcPeer = /** @class */ (function () {
|
||||
function WebRtcPeer(configuration) {
|
||||
var _this = this;
|
||||
this.configuration = configuration;
|
||||
this.remoteCandidatesQueue = [];
|
||||
this.localCandidatesQueue = [];
|
||||
this.iceCandidateList = [];
|
||||
this.candidategatheringdone = false;
|
||||
this.configuration.iceServers = (!!this.configuration.iceServers && this.configuration.iceServers.length > 0) ? this.configuration.iceServers : freeice();
|
||||
this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers });
|
||||
this.id = !!configuration.id ? configuration.id : uuid.v4();
|
||||
this.pc.onicecandidate = function (event) {
|
||||
var candidate = event.candidate;
|
||||
if (candidate) {
|
||||
_this.localCandidatesQueue.push({ candidate: candidate.candidate });
|
||||
_this.candidategatheringdone = false;
|
||||
_this.configuration.onicecandidate(event.candidate);
|
||||
}
|
||||
else if (!_this.candidategatheringdone) {
|
||||
_this.candidategatheringdone = true;
|
||||
}
|
||||
};
|
||||
this.pc.onsignalingstatechange = function () {
|
||||
if (_this.pc.signalingState === 'stable') {
|
||||
while (_this.iceCandidateList.length > 0) {
|
||||
_this.pc.addIceCandidate(_this.iceCandidateList.shift());
|
||||
}
|
||||
}
|
||||
};
|
||||
this.start();
|
||||
}
|
||||
/**
|
||||
* This function creates the RTCPeerConnection object taking into account the
|
||||
* properties received in the constructor. It starts the SDP negotiation
|
||||
* process: generates the SDP offer and invokes the onsdpoffer callback. This
|
||||
* callback is expected to send the SDP offer, in order to obtain an SDP
|
||||
* answer from another peer.
|
||||
*/
|
||||
WebRtcPeer.prototype.start = function () {
|
||||
var _this = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (_this.pc.signalingState === 'closed') {
|
||||
reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue');
|
||||
}
|
||||
if (!!_this.configuration.mediaStream) {
|
||||
_this.pc.addStream(_this.configuration.mediaStream);
|
||||
}
|
||||
// [Hack] https://code.google.com/p/chromium/issues/detail?id=443558
|
||||
if (_this.configuration.mode === 'sendonly' &&
|
||||
(platform.name === 'Chrome' && platform.version.toString().substring(0, 2) === '39')) {
|
||||
_this.configuration.mode = 'sendrecv';
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* This method frees the resources used by WebRtcPeer
|
||||
*/
|
||||
WebRtcPeer.prototype.dispose = function () {
|
||||
var _this = this;
|
||||
console.debug('Disposing WebRtcPeer');
|
||||
try {
|
||||
if (this.pc) {
|
||||
if (this.pc.signalingState === 'closed') {
|
||||
return;
|
||||
}
|
||||
this.remoteCandidatesQueue = [];
|
||||
this.localCandidatesQueue = [];
|
||||
this.pc.getLocalStreams().forEach(function (str) {
|
||||
_this.streamStop(str);
|
||||
});
|
||||
// FIXME This is not yet implemented in firefox
|
||||
// if(videoStream) pc.removeStream(videoStream);
|
||||
// if(audioStream) pc.removeStream(audioStream);
|
||||
this.pc.close();
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.warn('Exception disposing webrtc peer ' + err);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 1) Function that creates an offer, sets it as local description and returns the offer param
|
||||
* to send to OpenVidu Server (will be the remote description of other peer)
|
||||
*/
|
||||
WebRtcPeer.prototype.generateOffer = function () {
|
||||
var _this = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
var offerAudio, offerVideo = true;
|
||||
// Constraints must have both blocks
|
||||
if (!!_this.configuration.mediaConstraints) {
|
||||
offerAudio = (typeof _this.configuration.mediaConstraints.audio === 'boolean') ?
|
||||
_this.configuration.mediaConstraints.audio : true;
|
||||
offerVideo = (typeof _this.configuration.mediaConstraints.video === 'boolean') ?
|
||||
_this.configuration.mediaConstraints.video : true;
|
||||
}
|
||||
var constraints = {
|
||||
offerToReceiveAudio: +(_this.configuration.mode !== 'sendonly' && offerAudio),
|
||||
offerToReceiveVideo: +(_this.configuration.mode !== 'sendonly' && offerVideo)
|
||||
};
|
||||
console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints));
|
||||
_this.pc.createOffer(constraints).then(function (offer) {
|
||||
console.debug('Created SDP offer');
|
||||
return _this.pc.setLocalDescription(offer);
|
||||
}).then(function () {
|
||||
var localDescription = _this.pc.localDescription;
|
||||
if (!!localDescription) {
|
||||
console.debug('Local description set', localDescription.sdp);
|
||||
resolve(localDescription.sdp);
|
||||
}
|
||||
else {
|
||||
reject('Local description is not defined');
|
||||
}
|
||||
})["catch"](function (error) { return reject(error); });
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 2) Function to invoke when a SDP offer is received. Sets it as remote description,
|
||||
* generates and answer and returns it to send it to OpenVidu Server
|
||||
*/
|
||||
WebRtcPeer.prototype.processOffer = function (sdpOffer) {
|
||||
var _this = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
var offer = {
|
||||
type: 'offer',
|
||||
sdp: sdpOffer
|
||||
};
|
||||
console.debug('SDP offer received, setting remote description');
|
||||
if (_this.pc.signalingState === 'closed') {
|
||||
reject('PeerConnection is closed');
|
||||
}
|
||||
_this.pc.setRemoteDescription(offer)
|
||||
.then(function () {
|
||||
return _this.pc.createAnswer();
|
||||
}).then(function (answer) {
|
||||
console.debug('Created SDP answer');
|
||||
return _this.pc.setLocalDescription(answer);
|
||||
}).then(function () {
|
||||
var localDescription = _this.pc.localDescription;
|
||||
if (!!localDescription) {
|
||||
console.debug('Local description set', localDescription.sdp);
|
||||
resolve(localDescription.sdp);
|
||||
}
|
||||
else {
|
||||
reject('Local description is not defined');
|
||||
}
|
||||
})["catch"](function (error) { return reject(error); });
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 3) Function invoked when a SDP answer is received. Final step in SDP negotiation, the peer
|
||||
* just needs to set the answer as its remote description
|
||||
*/
|
||||
WebRtcPeer.prototype.processAnswer = function (sdpAnswer) {
|
||||
var _this = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
var answer = {
|
||||
type: 'answer',
|
||||
sdp: sdpAnswer
|
||||
};
|
||||
console.debug('SDP answer received, setting remote description');
|
||||
if (_this.pc.signalingState === 'closed') {
|
||||
reject('RTCPeerConnection is closed');
|
||||
}
|
||||
_this.pc.setRemoteDescription(answer).then(function () { return resolve(); })["catch"](function (error) { return reject(error); });
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Callback function invoked when an ICE candidate is received
|
||||
*/
|
||||
WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) {
|
||||
var _this = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
console.debug('Remote ICE candidate received', iceCandidate);
|
||||
_this.remoteCandidatesQueue.push(iceCandidate);
|
||||
switch (_this.pc.signalingState) {
|
||||
case 'closed':
|
||||
reject(new Error('PeerConnection object is closed'));
|
||||
break;
|
||||
case 'stable':
|
||||
if (!!_this.pc.remoteDescription) {
|
||||
_this.pc.addIceCandidate(iceCandidate).then(function () { return resolve(); })["catch"](function (error) { return reject(error); });
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_this.iceCandidateList.push(iceCandidate);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
};
|
||||
WebRtcPeer.prototype.streamStop = function (stream) {
|
||||
stream.getTracks().forEach(function (track) {
|
||||
track.stop();
|
||||
stream.removeTrack(track);
|
||||
});
|
||||
};
|
||||
return WebRtcPeer;
|
||||
}());
|
||||
exports.WebRtcPeer = WebRtcPeer;
|
||||
var WebRtcPeerRecvonly = /** @class */ (function (_super) {
|
||||
__extends(WebRtcPeerRecvonly, _super);
|
||||
function WebRtcPeerRecvonly(configuration) {
|
||||
var _this = this;
|
||||
configuration.mode = 'recvonly';
|
||||
_this = _super.call(this, configuration) || this;
|
||||
return _this;
|
||||
}
|
||||
return WebRtcPeerRecvonly;
|
||||
}(WebRtcPeer));
|
||||
exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly;
|
||||
var WebRtcPeerSendonly = /** @class */ (function (_super) {
|
||||
__extends(WebRtcPeerSendonly, _super);
|
||||
function WebRtcPeerSendonly(configuration) {
|
||||
var _this = this;
|
||||
configuration.mode = 'sendonly';
|
||||
_this = _super.call(this, configuration) || this;
|
||||
return _this;
|
||||
}
|
||||
return WebRtcPeerSendonly;
|
||||
}(WebRtcPeer));
|
||||
exports.WebRtcPeerSendonly = WebRtcPeerSendonly;
|
||||
var WebRtcPeerSendrecv = /** @class */ (function (_super) {
|
||||
__extends(WebRtcPeerSendrecv, _super);
|
||||
function WebRtcPeerSendrecv(configuration) {
|
||||
var _this = this;
|
||||
configuration.mode = 'sendrecv';
|
||||
_this = _super.call(this, configuration) || this;
|
||||
return _this;
|
||||
}
|
||||
return WebRtcPeerSendrecv;
|
||||
}(WebRtcPeer));
|
||||
exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv;
|
||||
//# sourceMappingURL=WebRtcPeer.js.map
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue