sp-streams
Version:
Streamplace Streams for Piping Video Around and Stuff
105 lines (86 loc) • 2.97 kB
JavaScript
;
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;
}