UNPKG

rtc-sdp

Version:

rtc.io utility module for patching (munging) SDP

154 lines (121 loc) 4 kB
/* jshint node: true */ 'use strict'; var nub = require('whisk/nub'); var pluck = require('whisk/pluck'); var flatten = require('whisk/flatten'); var reLineBreak = /\r?\n/; var reTrailingNewlines = /\r?\n$/; // list sdp line types that are not "significant" var nonHeaderLines = [ 'a', 'c', 'b', 'k' ]; var parsers = require('./parsers'); /** # rtc-sdp This is a utility module for intepreting and patching sdp. ## Usage The `rtc-sdp` main module exposes a single function that is capable of parsing lines of SDP, and providing an object allowing you to perform operations on those parsed lines: ```js var sdp = require('rtc-sdp')(lines); ``` The currently supported operations are listed below: **/ module.exports = function(sdp) { var ops = {}; var parsed = []; var activeCollector; // initialise the lines var lines = sdp.split(reLineBreak).filter(Boolean).map(function(line) { return line.split('='); }); var inputOrder = nub(lines.filter(function(line) { return line[0] && nonHeaderLines.indexOf(line[0]) < 0; }).map(pluck(0))); var findLine = ops.findLine = function(type, index) { var lineData = parsed.filter(function(line) { return line[0] === type; })[index || 0]; return lineData && lineData[1]; }; // push into parsed sections lines.forEach(function(line) { var customParser = parsers[line[0]]; if (customParser) { activeCollector = customParser(parsed, line); } else if (activeCollector) { activeCollector = activeCollector(line); } else { parsed.push(line); } }); /** ### `sdp.addIceCandidate(data)` Modify the sdp to include candidates as denoted by the data. **/ ops.addIceCandidate = function(data) { var lineIndex = (data || {}).lineIndex || (data || {}).sdpMLineIndex; var mLine = typeof lineIndex != 'undefined' && findLine('m', lineIndex); var candidate = (data || {}).candidate; // if we have the mLine add the new candidate if (mLine && candidate) { mLine.childlines.push(candidate.replace(reTrailingNewlines, '').split('=')); } }; /** ### `sdp.getMediaTypes() => []` Retrieve the list of media types that have been defined in the sdp via `m=` lines. **/ ops.getMediaTypes = function() { function getMediaType(data) { return data[1].def.split(/\s/)[0]; } return parsed.filter(function(parts) { return parts[0] === 'm' && parts[1] && parts[1].def; }).map(getMediaType); }; /** ### `sdp.getMediaIDs() => []` Returns the list of unique media line IDs that have been defined in the sdp via `a=mid:` lines. **/ ops.getMediaIDs = function() { return parsed.filter(function(parts) { return parts[0] === 'm' && parts[1] && parts[1].childlines && parts[1].childlines.length > 0; }).map(function(mediaLine) { var lines = mediaLine[1].childlines; // Default ID to the media type var mediaId = mediaLine[1].def.split(/\s/)[0]; // Look for the media ID for (var i = 0; i < lines.length; i++) { var tokens = lines[i][1].split(':'); if (tokens.length > 0 && tokens[0] === 'mid') { mediaId = tokens[1]; break; } } return mediaId; }); }; /** ### `sdp.toString()` Convert the SDP structure that is currently retained in memory, into a string that can be provided to a `setLocalDescription` (or `setRemoteDescription`) WebRTC call. **/ ops.toString = function() { return parsed.map(function(line) { return typeof line[1].toArray == 'function' ? line[1].toArray() : [ line ]; }).reduce(flatten).map(function(line) { return line.join('='); }).join('\r\n') + '\r\n'; }; /** ## SDP Filtering / Munging Functions There are additional functions included in the module to assign with performing "single-shot" SDP filtering (or munging) operations: **/ return ops; };