"use strict";

function timeSpan(a) {
    return a.length < 2 ? 0 : Math.abs(a[a.length - 1].timestamp - a[0].timestamp);
}

Object.defineProperty(exports, "__esModule", {
    value: !0
});

var utils_1 = require("./utils"), kMinInputTimeout = .03, LiveStreamer = function() {
    function a(a) {
        void 0 === a && (a = "LiveStreamer-" + utils_1.time()), this.name = a, this.maxBufferTime = 5, this.maxLocalBufferTime = 5, this.inputTimeout = 7, this.bytesRead = 0, 
        this.packetDropRatio = 0, this._isRunning = !1, this._startTime = 0, this._startBuffer = [], this._clients = new Set(), this._lastInputTime = 0, this._inputTimer = null, 
        this._onReadable = this._onReadable.bind(this), this._onSrcEnd = this._onSrcEnd.bind(this), this._onSrcAbort = this._onSrcAbort.bind(this), this._onInputTimeout = this._onInputTimeout.bind(this);
    }
    return Object.defineProperty(a.prototype, "isRunning", {
        get: function() {
            return this._isRunning;
        },
        enumerable: !0,
        configurable: !0
    }), a.prototype.start = function() {
        console.log("LiveStreamer::start: name=" + this.name), this._isRunning || (this._lastInputTime = utils_1.time(), this._resetTimer(), this._isRunning = !0);
    }, a.prototype.onInputTimeout = function() {
        console.warn("LiveStreamer::onInputTimeout");
    }, a.prototype.push = function(a) {
        var b = this;
        if (this._isRunning) {
            var c = utils_1.time();
            this._startTime || (this._startTime = c);
            var d = c - this._lastInputTime;
            if (d > 1e3 * kMinInputTimeout && (this._resetTimer(), this._lastInputTime = c), this.packetDropRatio >= 1) return console.warn("LiveStreamer:drop"), !1;
            if (this.packetDropRatio > 0 && Math.random() < this.packetDropRatio) return console.warn("LiveStreamer:drop:" + this.packetDropRatio), !1;
            var e = c - this._startTime, f = {
                data: a,
                timestamp: e
            };
            if (this._startBuffer) {
                var g = timeSpan(this._startBuffer) / 1e3;
                g > .6 * this.maxBufferTime ? (this._startBuffer = null, console.warn("[" + this.name + "/" + e + "] LiveStreamer::push: startBuffer is full, drop " + g + "s")) : this._startBuffer.push(f);
            }
            return this._clients.forEach(function(a) {
                function c() {
                    if (!a.sending && a.queue.length) {
                        var b = a.queue.shift();
                        a.sending = !0, a.dest.write(b.data, function(b) {
                            b && console.error("[error] LiveStreamer::push:res.wirte:id:" + a.id, b), a.sending = !1, c();
                        });
                    }
                }
                var d = timeSpan(a.queue) / 1e3, g = a.isLocal ? Math.min(b.maxBufferTime, b.maxLocalBufferTime) : b.maxBufferTime;
                d > g && (console.warn("[" + b.name + "/" + e + "] LiveStreamer::push:dropt data of " + d + " s, id: " + a.id), a.queue.length = 0), a.queue.push(f), c();
            }), !0;
        }
    }, a.prototype.readSource = function(a, b) {
        var c = this;
        return this._onSrcEnd(), this._src = a, this._srcOptions = b, b && b.needStartBuffer && (this._startBuffer = []), new Promise(function(b, d) {
            a.on("readable", c._onReadable), a.on("end", c._onSrcEnd), a.on("aborted", c._onSrcAbort), c._srcResolve = b, c._srcReject = d;
        });
    }, a.prototype.addClient = function(a, b, c) {
        var d = this;
        if (console.log("LiveStreamer::addClient:name=" + this.name + ", id=" + c), !this._isRunning) throw new Error("not running");
        var e = {
            id: c,
            dest: a,
            sending: !1,
            isLocal: b,
            queue: this._startBuffer ? this._startBuffer.slice(0) : []
        };
        this._clients.add(e);
        var f = function() {
            d._clients.has(e) && (d._clients["delete"](e), console.log("LiveStreamer::addClient:name=" + d.name + ", on end remove, id=" + c));
        };
        a.on("close", f), a.on("finish", f);
    }, a.prototype.stop = function(a) {
        if (console.log("LiveStreamer::stop: name=" + this.name), this._isRunning) {
            if (this._src) {
                if (this._src.destroy) try {
                    this._src.destroy();
                } catch (b) {}
                this._onSrcEnd();
            }
            return this._clients.forEach(function(b) {
                try {
                    a && b.dest.destroy ? b.dest.destroy() : b.dest.end();
                } catch (c) {}
            }), this._clients.clear(), this._startBuffer = [], this._startTime = 0, clearTimeout(this._inputTimer), this._inputTimer = null, this._isRunning = !1, Promise.resolve();
        }
    }, a.prototype._onReadable = function() {
        for (var a, b = this._src, c = this._srcOptions, d = c && c.chunkSize; a = b.read(d); ) this.bytesRead += a.length, this.push(a);
    }, a.prototype._clearSrc = function() {
        var a = this._src;
        a && (a.removeListener("readable", this._onReadable), a.removeListener("end", this._onSrcEnd), a.removeListener("aborted", this._onSrcAbort), this._src = null, 
        this._srcOptions = null, this._srcReject = null, this._srcResolve = null);
    }, a.prototype._onSrcEnd = function() {
        this._clearSrc(), this._srcResolve && this._srcResolve();
    }, a.prototype._onSrcAbort = function() {
        this._clearSrc(), this._srcReject && this._srcReject(new Error("Aborted"));
    }, a.prototype._resetTimer = function() {
        clearTimeout(this._inputTimer), this._inputTimer = null, this.inputTimeout > kMinInputTimeout && (this._inputTimer = setTimeout(this._onInputTimeout, 1e3 * this.inputTimeout));
    }, a.prototype._onInputTimeout = function() {
        try {
            this.onInputTimeout();
        } catch (a) {}
    }, a;
}();

exports.LiveStreamer = LiveStreamer;
//# sourceMappingURL=LiveStreamer.js.map