UNPKG

krtp

Version:

Node implementation of rdp protocol. RFC 3550

192 lines (191 loc) 7.55 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Session = exports.WriteRTPStream = exports.ReadRTPStream = void 0; /* * +=============================================== * | Author: Parham Alvani (parham.alvani@gmail.com) * | * | Creation Date: 01-06-2017 * | * | File Name: session.ts * +=============================================== */ var crypto_1 = require("crypto"); var dgram = __importStar(require("dgram")); var events_1 = require("events"); var rxjs_1 = require("rxjs"); var Packet_1 = require("./Packet"); var Control_1 = require("./Control"); var stream_1 = require("stream"); var ReadRTPStream = /** @class */ (function (_super) { __extends(ReadRTPStream, _super); function ReadRTPStream(session) { var _this = _super.call(this) || this; _this.session = session; _this.session.on("close", function () { return _this.push(null); }); _this.onMessage = function (msg) { if (!_this.push(msg.payload)) { _this.session.removeListener("message", _this.onMessage); } }; return _this; } ReadRTPStream.prototype._read = function (_size) { if (this.session.listeners("message").indexOf(this.onMessage) === -1) { this.session.on("message", this.onMessage); } }; return ReadRTPStream; }(stream_1.Readable)); exports.ReadRTPStream = ReadRTPStream; var WriteRTPStream = /** @class */ (function (_super) { __extends(WriteRTPStream, _super); function WriteRTPStream(session, destination) { var _this = _super.call(this) || this; _this.session = session; _this.destination = destination; return _this; } WriteRTPStream.prototype._write = function (chunk, _encoding, callback) { this.session.send(chunk, this.destination).then(function () { return callback(); }, function (err) { return callback(err); }); }; WriteRTPStream.prototype._destroy = function (err, callback) { this.session.close(); callback(err); }; return WriteRTPStream; }(stream_1.Writable)); exports.WriteRTPStream = WriteRTPStream; /** * RTP session: an association among a set of participants * communicating with RTP. */ var Session = /** @class */ (function (_super) { __extends(Session, _super); /** * creates a RTP session with RTCP. please note that the port + 1 is used for rtcp communication. * @param port - RTP port * @param packetType - RTP packet type: This field identifies the format of the RTP * payload and determines its interpretation by the application. */ function Session(port, packetType) { if (packetType === void 0) { packetType = 95; } var _this = _super.call(this) || this; _this.port = port; _this.packetType = packetType; _this.timestamp = (Date.now() / 1000) | 0; _this._sequenceNumber = crypto_1.randomBytes(2).readUInt16BE(0); _this.ssrc = crypto_1.randomBytes(4).readUInt32BE(0); _this._packetCount = 0; _this._octetCount = 0; _this.socket = dgram.createSocket("udp4"); _this.socket.on("message", function (msg, rinfo) { var packet = Packet_1.Packet.deserialize(msg); _this.emit("message", packet, rinfo); }); _this.socket.bind(_this.port, "0.0.0.0"); _this.controlSocket = dgram.createSocket("udp4"); _this.controlSocket.bind(_this.port + 1); return _this; } Object.defineProperty(Session.prototype, "sequenceNumber", { get: function () { return this._sequenceNumber; }, enumerable: false, configurable: true }); Object.defineProperty(Session.prototype, "packetCount", { get: function () { return this._packetCount; }, enumerable: false, configurable: true }); Object.defineProperty(Session.prototype, "octetCount", { get: function () { return this._octetCount; }, enumerable: false, configurable: true }); Session.prototype.sendSR = function (address, timestamp) { var _this = this; if (address === void 0) { address = "127.0.0.1"; } if (timestamp === void 0) { timestamp = ((Date.now() / 1000) | 0) - this.timestamp; } var packet = new Control_1.ControlSR(this._packetCount, this._octetCount, this.ssrc, timestamp); return new Promise(function (resolve, reject) { _this.controlSocket.send(packet.serialize(), _this.port + 1, address, function (err) { if (err) { return reject(err); } return resolve(); }); }); }; Session.prototype.send = function (payload, address, timestamp) { var _this = this; if (address === void 0) { address = "127.0.0.1"; } if (timestamp === void 0) { timestamp = ((Date.now() / 1000) | 0) - this.timestamp; } var packet = new Packet_1.Packet(payload, this._sequenceNumber, this.ssrc, timestamp, this.packetType); this._sequenceNumber = (this._sequenceNumber + 1) % (1 << 16); this._packetCount += 1; this._octetCount += payload.length; return new Promise(function (resolve, reject) { _this.socket.send(packet.serialize(), _this.port, address, function (err) { if (err) { return reject(err); } return resolve(); }); }); }; Session.prototype.close = function () { var _this = this; this.socket.close(function () { _this.emit("close"); }); this.controlSocket.close(); }; Object.defineProperty(Session.prototype, "message$", { get: function () { return rxjs_1.fromEvent(this, "message", function (msg) { return msg; }); }, enumerable: false, configurable: true }); return Session; }(events_1.EventEmitter)); exports.Session = Session;