ice-breaker
Version:
Set of helper methods to ease the WebRTC Media connection process.
171 lines (149 loc) • 6.61 kB
JavaScript
;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Constants = require('./constants');
function _validateSDPTransportFilter(_filter) {
var filter = _filter;
if (!filter) return false;
if (typeof filter === 'string') {
filter = [filter];
}
if (Array.isArray(filter)) {
var validTransports = Object.keys(Constants.transport).map(function (k) {
return Constants.transport[k];
});
var isValid = filter.every(function (f) {
return validTransports.indexOf(f) > -1;
});
return isValid ? filter : false;
}
return false;
}
function _getTransportFilterRegexp(filter) {
var filterRegexp = void 0;
filter.forEach(function (f) {
if (!filterRegexp) filterRegexp = '\\b(' + f + ')';else filterRegexp += '|(' + f + ')';
});
filterRegexp += '\\b';
return new RegExp(filterRegexp);
}
var IceBreaker = function () {
function IceBreaker() {
_classCallCheck(this, IceBreaker);
}
_createClass(IceBreaker, null, [{
key: 'candidateToJson',
/**
* Parses the received ICE candidate string into a JSON object
* @param {string} iceCandidate
* @returns {object} ICE candidate parsed
*/
value: function candidateToJson(iceCandidate) {
var iceCandidateJson = null;
if (iceCandidate && typeof iceCandidate === 'string') {
var ICE_CANDIDATE_PATTERN = new RegExp('candidate:(' + Constants.pattern.FOUNDATION + ')' + ( // 10
'\\s(' + Constants.pattern.COMPONENT_ID + ')') + ( // 1
'\\s(' + Constants.pattern.TRANSPORT + ')') + ( // UDP
'\\s(' + Constants.pattern.PRIORITY + ')') + ( // 1845494271
'\\s(' + Constants.pattern.CONNECTION_ADDRESS + ')') + ( // 13.93.107.159
'\\s(' + Constants.pattern.PORT + ')') + // 53705
'\\s' + 'typ' + ('\\s(' + Constants.pattern.CANDIDATE_TYPE + ')') + // typ prflx
'(?:\\s' + 'raddr' + ('\\s(' + Constants.pattern.CONNECTION_ADDRESS + ')') + // raddr 10.1.221.7
'\\s' + 'rport' + ('\\s(' + Constants.pattern.PORT + '))?') // rport 54805
);
var iceCandidateFields = iceCandidate.match(ICE_CANDIDATE_PATTERN);
if (iceCandidateFields) {
iceCandidateJson = {};
Object.keys(Constants.candidateFieldName).forEach(function (key, i) {
// i+1 because match returns the entire match result
// and the parentheses-captured matched results.
if (iceCandidateFields.length > i + 1 && iceCandidateFields[i + 1]) {
iceCandidateJson[Constants.candidateFieldName[key]] = iceCandidateFields[i + 1];
}
});
}
}
return iceCandidateJson;
}
/**
* Returns a new SDP containing only the ICE candidates that match the
* transport protocol provided in the filter.
* - The SDP must be a string, with every field in a new line. (See RFC-4566 -
* https://tools.ietf.org/html/rfc4566 for SDP details).
* - The SDP will remain the same if it is not a string or no filter
* is provided.
*
* @param {string} SDP to filter, with every field in a new line
* @param {string|Array} filter IceBreaker.transport (UDP|TCP)
* @returns {string} SDP with only the filtered ICE candidates
*/
}, {
key: 'filterSDPCandidatesByTransport',
value: function filterSDPCandidatesByTransport(sdp, _filter) {
var filteredSdp = sdp;
var filter = _validateSDPTransportFilter(_filter);
if (typeof sdp === 'string' && filter) {
var transportRegex = _getTransportFilterRegexp(filter);
var sdpLines = sdp.split('\n');
var filteredSdpLines = sdpLines.filter(function (l) {
return l.indexOf('a=candidate') > -1 && l.search(transportRegex) > -1 || l.indexOf('a=candidate') < 0;
});
filteredSdp = filteredSdpLines.join('\n');
}
return filteredSdp;
}
/**
* Returns an array of the ICE candidates (as objects) present in the provided sdp.
* - The SDP must be a string, with every field in a new line. (See RFC-4566 -
* https://tools.ietf.org/html/rfc4566 for SDP details).
*
* @param {string} SDP, with every field in a new line
* @returns {Array} ICE candidates present in the provided sdp (returned as objects)
*/
}, {
key: 'getCandidatesFromSDP',
value: function getCandidatesFromSDP(sdp) {
var iceCandidates = [];
if (typeof sdp === 'string') {
var sdpLines = sdp.split('\n');
var iceCandidatesLines = sdpLines.filter(function (l) {
return l.indexOf('a=candidate') > -1;
});
iceCandidates = iceCandidatesLines.map(function (l) {
// remove 'a='
var candidate = l.substr(2);
return IceBreaker.candidateToJson(candidate);
});
}
return iceCandidates;
}
/**
* Returns an array of the ICE candidates (as strings) present in the provided sdp.
* - The SDP must be a string, with every field in a new line. (See RFC-4566 -
* https://tools.ietf.org/html/rfc4566 for SDP details).
*
* @param {string} SDP, with every field in a new line
* @returns {Array} ICE candidates present in the provided sdp (returned as strings)
*/
}, {
key: 'getUnparsedCandidatesFromSDP',
value: function getUnparsedCandidatesFromSDP(sdp) {
var iceCandidates = [];
if (typeof sdp === 'string') {
var sdpLines = sdp.split('\n');
var iceCandidatesLines = sdpLines.filter(function (l) {
return l.indexOf('a=candidate') > -1;
});
iceCandidates = iceCandidatesLines.map(function (l) {
// remove 'a='
var candidate = l.substr(2).replace('\r', '');
return candidate;
});
}
return iceCandidates;
}
}]);
return IceBreaker;
}();
IceBreaker.transport = Constants.transport;
module.exports = IceBreaker;