sdp-jingle-json
Version:
A parser/serializer for SDP to JSON. Useful for converting SDP to other formats like Jingle for WebRTC signalling
270 lines (236 loc) • 6.6 kB
JavaScript
exports.lines = function (sdp) {
return sdp.split(/\r?\n/).filter(function (line) {
return line.length > 0;
});
};
exports.findLine = function (prefix, mediaLines, sessionLines) {
var prefixLength = prefix.length;
for (var i = 0; i < mediaLines.length; i++) {
if (mediaLines[i].substr(0, prefixLength) === prefix) {
return mediaLines[i];
}
}
// Continue searching in parent session section
if (!sessionLines) {
return false;
}
for (var j = 0; j < sessionLines.length; j++) {
if (sessionLines[j].substr(0, prefixLength) === prefix) {
return sessionLines[j];
}
}
return false;
};
exports.findLines = function (prefix, mediaLines, sessionLines) {
var results = [];
var prefixLength = prefix.length;
for (var i = 0; i < mediaLines.length; i++) {
if (mediaLines[i].substr(0, prefixLength) === prefix) {
results.push(mediaLines[i]);
}
}
if (results.length || !sessionLines) {
return results;
}
for (var j = 0; j < sessionLines.length; j++) {
if (sessionLines[j].substr(0, prefixLength) === prefix) {
results.push(sessionLines[j]);
}
}
return results;
};
exports.mline = function (line) {
var parts = line.substr(2).split(' ');
var parsed = {
media: parts[0],
port: parts[1],
proto: parts[2],
formats: []
};
for (var i = 3; i < parts.length; i++) {
if (parts[i]) {
parsed.formats.push(parts[i]);
}
}
return parsed;
};
exports.rtpmap = function (line) {
var parts = line.substr(9).split(' ');
var parsed = {
id: parts.shift()
};
parts = parts[0].split('/');
parsed.name = parts[0];
parsed.clockrate = parts[1];
parsed.channels = parts.length == 3 ? parts[2] : '1';
return parsed;
};
exports.sctpmap = function (line) {
// based on -05 draft
var parts = line.substr(10).split(' ');
var parsed = {
number: parts.shift(),
protocol: parts.shift(),
streams: parts.shift()
};
return parsed;
};
exports.fmtp = function (line) {
var kv, key, value;
var parts = line.substr(line.indexOf(' ') + 1).split(';');
var parsed = [];
for (var i = 0; i < parts.length; i++) {
kv = parts[i].split('=');
key = kv[0].trim();
value = kv[1];
if (key && value) {
parsed.push({key: key, value: value});
} else if (key) {
parsed.push({key: '', value: key});
}
}
return parsed;
};
exports.crypto = function (line) {
var parts = line.substr(9).split(' ');
var parsed = {
tag: parts[0],
cipherSuite: parts[1],
keyParams: parts[2],
sessionParams: parts.slice(3).join(' ')
};
return parsed;
};
exports.fingerprint = function (line) {
var parts = line.substr(14).split(' ');
return {
hash: parts[0],
value: parts[1]
};
};
exports.extmap = function (line) {
var parts = line.substr(9).split(' ');
var parsed = {};
var idpart = parts.shift();
var sp = idpart.indexOf('/');
if (sp >= 0) {
parsed.id = idpart.substr(0, sp);
parsed.senders = idpart.substr(sp + 1);
} else {
parsed.id = idpart;
parsed.senders = 'sendrecv';
}
parsed.uri = parts.shift() || '';
return parsed;
};
exports.rtcpfb = function (line) {
var parts = line.substr(10).split(' ');
var parsed = {};
parsed.id = parts.shift();
parsed.type = parts.shift();
if (parsed.type === 'trr-int') {
parsed.value = parts.shift();
} else {
parsed.subtype = parts.shift() || '';
}
parsed.parameters = parts;
return parsed;
};
exports.candidate = function (line) {
var parts;
if (line.indexOf('a=candidate:') === 0) {
parts = line.substring(12).split(' ');
} else { // no a=candidate
parts = line.substring(10).split(' ');
}
var candidate = {
foundation: parts[0],
component: parts[1],
protocol: parts[2].toLowerCase(),
priority: parts[3],
ip: parts[4],
port: parts[5],
// skip parts[6] == 'typ'
type: parts[7],
generation: '0'
};
for (var i = 8; i < parts.length; i += 2) {
if (parts[i] === 'raddr') {
candidate.relAddr = parts[i + 1];
} else if (parts[i] === 'rport') {
candidate.relPort = parts[i + 1];
} else if (parts[i] === 'generation') {
candidate.generation = parts[i + 1];
} else if (parts[i] === 'tcptype') {
candidate.tcpType = parts[i + 1];
}
}
candidate.network = '1';
return candidate;
};
exports.sourceGroups = function (lines) {
var parsed = [];
for (var i = 0; i < lines.length; i++) {
var parts = lines[i].substr(13).split(' ');
parsed.push({
semantics: parts.shift(),
sources: parts
});
}
return parsed;
};
exports.sources = function (lines) {
// http://tools.ietf.org/html/rfc5576
var parsed = [];
var sources = {};
for (var i = 0; i < lines.length; i++) {
var parts = lines[i].substr(7).split(' ');
var ssrc = parts.shift();
if (!sources[ssrc]) {
var source = {
ssrc: ssrc,
parameters: []
};
parsed.push(source);
// Keep an index
sources[ssrc] = source;
}
parts = parts.join(' ').split(':');
var attribute = parts.shift();
var value = parts.join(':') || null;
sources[ssrc].parameters.push({
key: attribute,
value: value
});
}
return parsed;
};
exports.groups = function (lines) {
// http://tools.ietf.org/html/rfc5888
var parsed = [];
var parts;
for (var i = 0; i < lines.length; i++) {
parts = lines[i].substr(8).split(' ');
parsed.push({
semantics: parts.shift(),
contents: parts
});
}
return parsed;
};
exports.bandwidth = function (line) {
var parts = line.substr(2).split(':');
var parsed = {};
parsed.type = parts.shift();
parsed.bandwidth = parts.shift();
return parsed;
};
exports.msid = function (line) {
var data = line.substr(7);
var parts = data.split(' ');
return {
msid: data,
mslabel: parts[0],
label: parts[1]
};
};