UNPKG

sp-streams

Version:

Streamplace Streams for Piping Video Around and Stuff

105 lines (86 loc) 2.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = socketEgressStream; var _net = require("net"); var _net2 = _interopRequireDefault(_net); var _os = require("os"); var _os2 = _interopRequireDefault(_os); var _stream = require("stream"); var _stream2 = _interopRequireDefault(_stream); var _path = require("path"); var _debug = require("debug"); var _debug2 = _interopRequireDefault(_debug); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var log = (0, _debug2.default)("sp:socket-egress-stream"); function socketEgressStream() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$useFirstBuffer = _ref.useFirstBuffer, useFirstBuffer = _ref$useFirstBuffer === undefined ? true : _ref$useFirstBuffer; var tmpDir = _os2.default.tmpdir(); var socketName = "sp-sock-" + Date.now() + "-" + Math.round(Math.random() * 1000) + ".sock"; var socketPath = (0, _path.resolve)(tmpDir, socketName); // Much of this logic is dedicated to combating ffmpeg's socket behavior... it makes one // "probe" connection, expects data, then connects again for the primary data feed. We don't // want to discard the data in the probe, so we don't. var first = useFirstBuffer; var firstBuffer = []; var firstBufferLength = 0; var firstListener = void 0; var stopFirstListener = function stopFirstListener() { if (!firstListener) { return; } log("First buffer size: " + firstBufferLength); socketStream.removeListener("data", firstListener); firstListener = null; }; var server = _net2.default.createServer(function (c) { if (first) { first = false; firstListener = function firstListener(chunk) { c.write(chunk); firstBufferLength += chunk.length; if (!firstBuffer) { throw new Error("Tried to push to firstBuffer after it gone?"); } firstBuffer.push(chunk); }; socketStream.on("data", firstListener); } else { firstBuffer.forEach(function (chunk) { c.write(chunk); }); // firstBuffer = null; socketStream.pipe(c); } log("client connected"); c.on("end", function () { log("client disconnected"); socketStream.unpipe(c); stopFirstListener(); }); c.on("error", function () { log("client errored"); socketStream.unpipe(c); stopFirstListener(); }); }); server.on("error", function (err) { throw err; }); var pathProm = new Promise(function (resolve, reject) { server.listen(socketPath, function () { log("server bound to " + socketPath); resolve(socketPath); }); }); var socketStream = new _stream2.default.PassThrough(); socketStream.getPath = function () { return pathProm; }; socketStream.server = server; socketStream.path = socketPath; return socketStream; }