WebRTC audio/video call and conferencing server.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

160 lines
4.3 KiB

/*
* Spreed WebRTC.
* Copyright (C) 2013-2014 struktur AG
*
* This file is part of Spreed WebRTC.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
define([], function() {
var Utils = function() {}
Utils.prototype.mergeConstraints = function(cons1, cons2) {
var merged = cons1;
var name;
for (name in cons2.mandatory) {
if (cons2.mandatory.hasOwnProperty(name)) {
merged.mandatory[name] = cons2.mandatory[name];
}
}
merged.optional.concat(cons2.optional);
return merged;
};
Utils.prototype.extractSdp = function(sdpLine, pattern) {
var result = sdpLine.match(pattern);
return (result && result.length == 2) ? result[1] : null;
};
Utils.prototype.addStereo = function(sdp) {
// Set Opus in Stereo.
var sdpLines = sdp.split('\r\n');
var opusPayload = "";
var fmtpLineIndex = null;
var i;
// Find opus payload.
for (i = 0; i < sdpLines.length; i++) {
if (sdpLines[i].search('opus/48000') !== -1) {
opusPayload = this.extractSdp(sdpLines[i], /:(\d+) opus\/48000/i);
break;
}
}
// Find the payload in fmtp line.
for (i = 0; i < sdpLines.length; i++) {
if (sdpLines[i].search('a=fmtp') !== -1) {
var payload = this.extractSdp(sdpLines[i], /a=fmtp:(\d+)/);
if (payload === opusPayload) {
fmtpLineIndex = i;
break;
}
}
}
// No fmtp line found.
if (fmtpLineIndex === null) {
console.log("Unable to add stereo (no fmtp line for opus payload)", opusPayload);
return sdp;
}
// Append stereo=1 to fmtp line.
sdpLines[fmtpLineIndex] = sdpLines[fmtpLineIndex].concat(' stereo=1');
sdp = sdpLines.join('\r\n');
console.log("Enabled opus stereo.");
return sdp;
};
Utils.prototype.preferOpus = function(sdp) {
// Set Opus as the preferred codec in SDP if Opus is present.
var sdpLines = sdp.split('\r\n');
var mLineIndex = null;
var i;
// Search for m line.
for (i = 0; i < sdpLines.length; i++) {
if (sdpLines[i].search('m=audio') !== -1) {
mLineIndex = i;
break;
}
}
if (mLineIndex === null) {
return sdp;
}
// If Opus is available, set it as the default in m line.
for (i = 0; i < sdpLines.length; i++) {
if (sdpLines[i].search('opus/48000') !== -1) {
var opusPayload = this.extractSdp(sdpLines[i], /:(\d+) opus\/48000/i);
if (opusPayload) {
sdpLines[mLineIndex] = this.setDefaultCodec(sdpLines[mLineIndex], opusPayload);
}
break;
}
}
// Remove CN in m line and sdp.
sdpLines = this.removeCN(sdpLines, mLineIndex);
sdp = sdpLines.join('\r\n');
return sdp;
};
Utils.prototype.setDefaultCodec = function(mLine, payload) {
// Set the selected codec to the first in m line.
var elements = mLine.split(' ');
var newLine = [];
var index = 0;
for (var i = 0; i < elements.length; i++) {
// Format of media starts from the fourth.
if (index === 3) {
newLine[index++] = payload; // Put target payload to the first.
}
if (elements[i] !== payload) {
newLine[index++] = elements[i];
}
}
return newLine.join(' ');
};
Utils.prototype.removeCN = function(sdpLines, mLineIndex) {
// Strip CN from sdp before CN constraints is ready.
var mLineElements = sdpLines[mLineIndex].split(' ');
// Scan from end for the convenience of removing an item.
for (var i = sdpLines.length - 1; i >= 0; i--) {
var payload = this.extractSdp(sdpLines[i], /a=rtpmap:(\d+) CN\/\d+/i);
if (payload) {
var cnPos = mLineElements.indexOf(payload);
if (cnPos !== -1) {
// Remove CN payload from m line.
mLineElements.splice(cnPos, 1);
}
// Remove CN line in sdp
sdpLines.splice(i, 1);
}
}
sdpLines[mLineIndex] = mLineElements.join(' ');
return sdpLines;
};
var utils = new Utils();
return utils;
});