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
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; |
|
|
|
});
|
|
|