Revision control
Copy as Markdown
Other Tools
var toIntIfInt = function (v) {
return String(Number(v)) === v ? Number(v) : v;
};
var attachProperties = function (match, location, names, rawName) {
if (rawName && !names) {
location[rawName] = toIntIfInt(match[1]);
}
else {
for (var i = 0; i < names.length; i += 1) {
if (match[i+1] != null) {
location[names[i]] = toIntIfInt(match[i+1]);
}
}
}
};
var parseReg = function (obj, location, content) {
var needsBlank = obj.name && obj.names;
if (obj.push && !location[obj.push]) {
location[obj.push] = [];
}
else if (needsBlank && !location[obj.name]) {
location[obj.name] = {};
}
var keyLocation = obj.push ?
{} : // blank object that will be pushed
needsBlank ? location[obj.name] : location; // otherwise, named location or root
attachProperties(content.match(obj.reg), keyLocation, obj.names, obj.name);
if (obj.push) {
location[obj.push].push(keyLocation);
}
};
var grammar = require('./grammar');
var validLine = RegExp.prototype.test.bind(/^([a-z])=(.*)/);
exports.parse = function (sdp) {
var session = {}
, media = []
, location = session; // points at where properties go under (one of the above)
// parse lines we understand
sdp.split(/(\r\n|\r|\n)/).filter(validLine).forEach(function (l) {
var type = l[0];
var content = l.slice(2);
if (type === 'm') {
media.push({rtp: [], fmtp: []});
location = media[media.length-1]; // point at latest media line
}
for (var j = 0; j < (grammar[type] || []).length; j += 1) {
var obj = grammar[type][j];
if (obj.reg.test(content)) {
return parseReg(obj, location, content);
}
}
});
session.media = media; // link it up
return session;
};
var paramReducer = function (acc, expr) {
var s = expr.split(/=(.+)/, 2);
if (s.length === 2) {
acc[s[0]] = toIntIfInt(s[1]);
} else if (s.length === 1 && expr.length > 1) {
acc[s[0]] = undefined;
}
return acc;
};
exports.parseParams = function (str) {
return str.split(/;\s?/).reduce(paramReducer, {});
};
// For backward compatibility - alias will be removed in 3.0.0
exports.parseFmtpConfig = exports.parseParams;
exports.parsePayloads = function (str) {
return str.toString().split(' ').map(Number);
};
exports.parseRemoteCandidates = function (str) {
var candidates = [];
var parts = str.split(' ').map(toIntIfInt);
for (var i = 0; i < parts.length; i += 3) {
candidates.push({
component: parts[i],
ip: parts[i + 1],
port: parts[i + 2]
});
}
return candidates;
};
exports.parseImageAttributes = function (str) {
return str.split(' ').map(function (item) {
return item.substring(1, item.length-1).split(',').reduce(paramReducer, {});
});
};
exports.parseSimulcastStreamList = function (str) {
return str.split(';').map(function (stream) {
return stream.split(',').map(function (format) {
var scid, paused = false;
if (format[0] !== '~') {
scid = toIntIfInt(format);
} else {
scid = toIntIfInt(format.substring(1, format.length));
paused = true;
}
return {
scid: scid,
paused: paused
};
});
});
};