Skip to content

Instantly share code, notes, and snippets.

@Galadirith
Last active January 15, 2017 18:08
Show Gist options
  • Save Galadirith/4aa04210d361e59ffa615983d3ef3623 to your computer and use it in GitHub Desktop.
Save Galadirith/4aa04210d361e59ffa615983d3ef3623 to your computer and use it in GitHub Desktop.
capture.js with workerScript not workerPath
function download(t, e, n) {
function i(t) {
var e = t.split(/[:;,]/),
n = e[1],
i = "base64" == e[2] ? atob : decodeURIComponent,
r = i(e.pop()),
o = r.length,
a = 0,
s = new Uint8Array(o);
for (a; a < o; ++a) s[a] = r.charCodeAt(a);
return new m([s], {
type: n
})
}
function r(t, e) {
if ("download" in l) return l.href = t, l.setAttribute("download", w), l.innerHTML = "downloading...", l.style.display = "none", f.body.appendChild(l), setTimeout(function() {
l.click(), f.body.removeChild(l), e === !0 && setTimeout(function() {
h.URL.revokeObjectURL(l.href)
}, 250)
}, 66), !0;
var n = f.createElement("iframe");
f.body.appendChild(n), e || (t = "data:" + t.replace(/^data:([\w\/\-\+]+)/, d)), n.src = t, setTimeout(function() {
f.body.removeChild(n)
}, 333)
}
var o, a, s, h = window,
d = "application/octet-stream",
u = n || d,
c = t,
f = document,
l = f.createElement("a"),
p = function(t) {
return String(t)
},
m = h.Blob || h.MozBlob || h.WebKitBlob || p,
g = h.MSBlobBuilder || h.WebKitBlobBuilder || h.BlobBuilder,
w = e || "download";
if ("true" === String(this) && (c = [c, u], u = c[0], c = c[1]), String(c).match(/^data\:[\w+\-]+\/[\w+\-]+[,;]/)) return navigator.msSaveBlob ? navigator.msSaveBlob(i(c), w) : r(c);
try {
o = c instanceof m ? c : new m([c], {
type: u
})
} catch (t) {
g && (a = new g, a.append([c]), o = a.getBlob(u))
}
if (navigator.msSaveBlob) return navigator.msSaveBlob(o, w);
if (h.URL) r(h.URL.createObjectURL(o), !0);
else {
if ("string" == typeof o || o.constructor === p) try {
return r("data:" + u + ";base64," + h.btoa(o))
} catch (t) {
return r("data:" + u + "," + encodeURIComponent(o))
}
s = new FileReader, s.onload = function(t) {
r(this.result)
}, s.readAsDataURL(o)
}
return !0
}
window.Whammy = function() {
function t(t, n) {
for (var i = e(t), r = 3e4, o = [{
id: 440786851,
data: [{
data: 1,
id: 17030
}, {
data: 1,
id: 17143
}, {
data: 4,
id: 17138
}, {
data: 8,
id: 17139
}, {
data: "webm",
id: 17026
}, {
data: 2,
id: 17031
}, {
data: 2,
id: 17029
}]
}, {
id: 408125543,
data: [{
id: 357149030,
data: [{
data: 1e6,
id: 2807729
}, {
data: "whammy",
id: 19840
}, {
data: "whammy",
id: 22337
}, {
data: c(i.duration),
id: 17545
}]
}, {
id: 374648427,
data: [{
id: 174,
data: [{
data: 1,
id: 215
}, {
data: 1,
id: 29637
}, {
data: 0,
id: 156
}, {
data: "und",
id: 2274716
}, {
data: "V_VP8",
id: 134
}, {
data: "VP8",
id: 2459272
}, {
data: 1,
id: 131
}, {
id: 224,
data: [{
data: i.width,
id: 176
}, {
data: i.height,
id: 186
}]
}]
}]
}, {
id: 475249515,
data: []
}]
}], s = o[1], d = s.data[2], u = 0, f = 0; u < t.length;) {
var l = {
id: 187,
data: [{
data: Math.round(f),
id: 179
}, {
id: 183,
data: [{
data: 1,
id: 247
}, {
data: 0,
size: 8,
id: 241
}]
}]
};
d.data.push(l);
var p = [],
m = 0;
do p.push(t[u]), m += t[u].duration, u++; while (u < t.length && m < r);
var g = 0,
w = {
id: 524531317,
data: [{
data: Math.round(f),
id: 231
}].concat(p.map(function(t) {
var e = h({
discardable: 0,
frame: t.data.slice(4),
invisible: 0,
keyframe: 1,
lacing: 0,
trackNum: 1,
timecode: Math.round(g)
});
return g += t.duration, {
data: e,
id: 163
}
}))
};
s.data.push(w), f += m
}
for (var v = 0, y = 0; y < s.data.length; y++) {
y >= 3 && (d.data[y - 3].data[1].data[1].data = v);
var b = a([s.data[y]], n);
v += b.size || b.byteLength || b.length, 2 != y && (s.data[y] = b)
}
return a(o, n)
}
function e(t) {
for (var e = t[0].width, n = t[0].height, i = t[0].duration, r = 1; r < t.length; r++) {
if (t[r].width != e) throw "Frame " + (r + 1) + " has a different width";
if (t[r].height != n) throw "Frame " + (r + 1) + " has a different height";
if (t[r].duration < 0 || t[r].duration > 32767) throw "Frame " + (r + 1) + " has a weird duration (must be between 0 and 32767)";
i += t[r].duration
}
return {
duration: i,
width: e,
height: n
}
}
function n(t) {
for (var e = []; t > 0;) e.push(255 & t), t >>= 8;
return new Uint8Array(e.reverse())
}
function i(t, e) {
for (var n = new Uint8Array(e), i = e - 1; i >= 0; i--) n[i] = 255 & t, t >>= 8;
return n
}
function r(t) {
for (var e = new Uint8Array(t.length), n = 0; n < t.length; n++) e[n] = t.charCodeAt(n);
return e
}
function o(t) {
var e = [],
n = t.length % 8 ? new Array(9 - t.length % 8).join("0") : "";
t = n + t;
for (var i = 0; i < t.length; i += 8) e.push(parseInt(t.substr(i, 8), 2));
return new Uint8Array(e)
}
function a(t, e) {
for (var h = [], d = 0; d < t.length; d++)
if ("id" in t[d]) {
var u = t[d].data;
if ("object" == typeof u && (u = a(u, e)), "number" == typeof u && (u = "size" in t[d] ? i(u, t[d].size) : o(u.toString(2))), "string" == typeof u && (u = r(u)), u.length);
for (var c = u.size || u.byteLength || u.length, f = 0, l = 56; l > 0; l -= 7)
if (c > Math.pow(2, l) - 2) {
f = l / 7;
break
}
var p = c.toString(2),
m = new Array(8 * (f + 1) + 1).join("0"),
g = new Array(f + 1).join("0") + 1,
w = m.substr(0, m.length - p.length - g.length) + p,
v = g + w;
h.push(n(t[d].id)), h.push(o(v)), h.push(u)
} else h.push(t[d]);
if (e) {
var y = s(h);
return new Uint8Array(y)
}
return new Blob(h, {
type: "video/webm"
})
}
function s(t, e) {
null == e && (e = []);
for (var n = 0; n < t.length; n++) "object" == typeof t[n] ? s(t[n], e) : e.push(t[n]);
return e
}
function h(t) {
var e = 0;
if (t.keyframe && (e |= 128), t.invisible && (e |= 8), t.lacing && (e |= t.lacing << 1), t.discardable && (e |= 1), t.trackNum > 127) throw "TrackNumber > 127 not supported";
var n = [128 | t.trackNum, t.timecode >> 8, 255 & t.timecode, e].map(function(t) {
return String.fromCharCode(t)
}).join("") + t.frame;
return n
}
function d(t) {
for (var e = t.RIFF[0].WEBP[0], n = e.indexOf("*"), i = 0, r = []; i < 4; i++) r[i] = e.charCodeAt(n + 3 + i);
var o, a, s, h, d;
return d = r[1] << 8 | r[0], o = 16383 & d, a = d >> 14, d = r[3] << 8 | r[2], s = 16383 & d, h = d >> 14, {
width: o,
height: s,
data: e,
riff: t
}
}
function u(t) {
for (var e = 0, n = {}; e < t.length;) {
var i = t.substr(e, 4);
if (n[i] = n[i] || [], "RIFF" == i || "LIST" == i) {
var r = parseInt(t.substr(e + 4, 4).split("").map(function(t) {
var e = t.charCodeAt(0).toString(2);
return new Array(8 - e.length + 1).join("0") + e
}).join(""), 2),
o = t.substr(e + 4 + 4, r);
e += 8 + r, n[i].push(u(o))
} else "WEBP" == i ? (n[i].push(t.substr(e + 8)), e = t.length) : (n[i].push(t.substr(e + 4)), e = t.length)
}
return n
}
function c(t) {
return [].slice.call(new Uint8Array(new Float64Array([t]).buffer), 0).map(function(t) {
return String.fromCharCode(t)
}).reverse().join("")
}
function f(t, e) {
this.frames = [], this.duration = 1e3 / t, this.quality = e || .8
}
return f.prototype.add = function(t, e) {
if ("undefined" != typeof e && this.duration) throw "you can't pass a duration if the fps is set";
if ("undefined" == typeof e && !this.duration) throw "if you don't have the fps set, you need to have durations here.";
if (t.canvas && (t = t.canvas), t.toDataURL) t = t.getContext("2d").getImageData(0, 0, t.width, t.height);
else if ("string" != typeof t) throw "frame must be a a HTMLCanvasElement, a CanvasRenderingContext2D or a DataURI formatted string";
if ("string" == typeof t && !/^data:image\/webp;base64,/gi.test(t)) throw "Input must be formatted properly as a base64 encoded DataURI of type image/webp";
this.frames.push({
image: t,
duration: e || this.duration
})
}, f.prototype.encodeFrames = function(t) {
if (this.frames[0].image instanceof ImageData) {
var e = this.frames,
n = document.createElement("canvas"),
i = n.getContext("2d");
n.width = this.frames[0].image.width, n.height = this.frames[0].image.height;
var r = function(o) {
var a = e[o];
i.putImageData(a.image, 0, 0), a.image = n.toDataURL("image/webp", this.quality), o < e.length - 1 ? setTimeout(function() {
r(o + 1)
}, 1) : t()
}.bind(this);
r(0)
} else t()
}, f.prototype.compile = function(e, n) {
this.encodeFrames(function() {
var i = new t(this.frames.map(function(t) {
var e = d(u(atob(t.image.slice(23))));
return e.duration = t.duration, e
}), e);
n(i)
}.bind(this))
}, {
Video: f,
fromImageArray: function(e, n, i) {
return t(e.map(function(t) {
var e = d(u(atob(t.slice(23))));
return e.duration = 1e3 / n, e
}), i)
},
toWebM: t
}
}(),
function() {
"use strict";
function t(t) {
var e, n = new Uint8Array(t);
for (e = 0; e < t; e += 1) n[e] = 0;
return n
}
function e(e, n, i, r) {
var o = n + i,
a = t((parseInt(o / r) + 1) * r);
return a.set(e), a
}
function n(t, e, n) {
return t = t.toString(n || 8), "000000000000".substr(t.length + 12 - e) + t
}
function i(e, n, i) {
var r, o;
for (n = n || t(e.length), i = i || 0, r = 0, o = e.length; r < o; r += 1) n[i] = e.charCodeAt(r), i += 1;
return n
}
function r(t) {
function e(t) {
return o[t >> 18 & 63] + o[t >> 12 & 63] + o[t >> 6 & 63] + o[63 & t]
}
var n, i, r, a = t.length % 3,
s = "";
for (n = 0, r = t.length - a; n < r; n += 3) i = (t[n] << 16) + (t[n + 1] << 8) + t[n + 2], s += e(i);
switch (s.length % 4) {
case 1:
s += "=";
break;
case 2:
s += "=="
}
return s
}
var o = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"];
window.utils = {}, window.utils.clean = t, window.utils.pad = n, window.utils.extend = e, window.utils.stringToUint8 = i, window.utils.uint8ToBase64 = r
}(),
function() {
"use strict";
function t(t, i) {
var r = n.clean(512),
o = 0;
return e.forEach(function(e) {
var n, i, a = t[e.field] || "";
for (n = 0, i = a.length; n < i; n += 1) r[o] = a.charCodeAt(n), o += 1;
o += e.length - n
}), "function" == typeof i ? i(r, o) : r
}
var e, n = window.utils;
e = [{
field: "fileName",
length: 100
}, {
field: "fileMode",
length: 8
}, {
field: "uid",
length: 8
}, {
field: "gid",
length: 8
}, {
field: "fileSize",
length: 12
}, {
field: "mtime",
length: 12
}, {
field: "checksum",
length: 8
}, {
field: "type",
length: 1
}, {
field: "linkName",
length: 100
}, {
field: "ustar",
length: 8
}, {
field: "owner",
length: 32
}, {
field: "group",
length: 32
}, {
field: "majorNumber",
length: 8
}, {
field: "minorNumber",
length: 8
}, {
field: "filenamePrefix",
length: 155
}, {
field: "padding",
length: 12
}], window.header = {}, window.header.structure = e, window.header.format = t
}(),
function() {
"use strict";
function t(t) {
this.written = 0, e = (t || 20) * r, this.out = i.clean(e), this.blocks = [], this.length = 0
}
var e, n = window.header,
i = window.utils,
r = 512;
t.prototype.append = function(t, e, o, a) {
var s, h, d, u, c, f, l;
if ("string" == typeof e) e = i.stringToUint8(e);
else if (e.constructor !== Uint8Array.prototype.constructor) throw "Invalid input type. You gave me: " + e.constructor.toString().match(/function\s*([$A-Za-z_][0-9A-Za-z_]*)\s*\(/)[1];
"function" == typeof o && (a = o, o = {}), o = o || {}, d = o.mode || 4095 & parseInt("777", 8), u = o.mtime || Math.floor(+new Date / 1e3), c = o.uid || 0, f = o.gid || 0, s = {
fileName: t,
fileMode: i.pad(d, 7),
uid: i.pad(c, 7),
gid: i.pad(f, 7),
fileSize: i.pad(e.length, 11),
mtime: i.pad(u, 11),
checksum: " ",
type: "0",
ustar: "ustar ",
owner: o.owner || "",
group: o.group || ""
}, h = 0, Object.keys(s).forEach(function(t) {
var e, n, i = s[t];
for (e = 0, n = i.length; e < n; e += 1) h += i.charCodeAt(e)
}), s.checksum = i.pad(h, 6) + "\0 ", l = n.format(s);
var p = Math.ceil(l.length / r) * r,
m = Math.ceil(e.length / r) * r;
this.blocks.push({
header: l,
input: e,
headerLength: p,
inputLength: m
})
}, t.prototype.save = function() {
var t = [],
e = [],
n = 0,
i = Math.pow(2, 20),
o = [];
return this.blocks.forEach(function(t) {
n + t.headerLength + t.inputLength > i && (e.push({
blocks: o,
length: n
}), o = [], n = 0), o.push(t), n += t.headerLength + t.inputLength
}), e.push({
blocks: o,
length: n
}), e.forEach(function(e) {
var n = new Uint8Array(e.length),
i = 0;
e.blocks.forEach(function(t) {
n.set(t.header, i), i += t.headerLength, n.set(t.input, i), i += t.inputLength
}), t.push(n)
}), t.push(new Uint8Array(2 * r)), new Blob(t, {
type: "octet/stream"
})
}, t.prototype.clear = function() {
this.written = 0, this.out = i.clean(e)
}, window.Tar = t
}(),
function(t) {
function e(t, n) {
if ({}.hasOwnProperty.call(e.cache, t)) return e.cache[t];
var i = e.resolve(t);
if (!i) throw new Error("Failed to resolve module " + t);
var r = {
id: t,
require: e,
filename: t,
exports: {},
loaded: !1,
parent: n,
children: []
};
n && n.children.push(r);
var o = t.slice(0, t.lastIndexOf("/") + 1);
return e.cache[t] = r.exports, i.call(r.exports, r, r.exports, o, t), r.loaded = !0, e.cache[t] = r.exports
}
e.modules = {}, e.cache = {}, e.resolve = function(t) {
return {}.hasOwnProperty.call(e.modules, t) ? e.modules[t] : void 0
}, e.define = function(t, n) {
e.modules[t] = n
};
var n = function(e) {
return e = "/", {
title: "browser",
version: "v0.10.26",
browser: !0,
env: {},
argv: [],
nextTick: t.setImmediate || function(t) {
setTimeout(t, 0)
},
cwd: function() {
return e
},
chdir: function(t) {
e = t
}
}
}();
e.define("/gif.coffee", function(t, n, i, r) {
function o(t, e) {
return {}.hasOwnProperty.call(t, e)
}
function a(t, e) {
for (var n = 0, i = e.length; n < i; ++n)
if (n in e && e[n] === t) return !0;
return !1
}
function s(t, e) {
function n() {
this.constructor = t
}
for (var i in e) o(e, i) && (t[i] = e[i]);
return n.prototype = e.prototype, t.prototype = new n, t.__super__ = e.prototype, t
}
var h, d, u, c, f;
u = e("events", t).EventEmitter, h = e("/browser.coffee", t), f = function(t) {
function e(t) {
var e, n;
this.running = !1, this.options = {}, this.frames = [], this.freeWorkers = [], this.activeWorkers = [], this.setOptions(t);
for (e in d) n = d[e], null != this.options[e] ? this.options[e] : this.options[e] = n
}
return s(e, t), d = {
workerScript: "gif.worker.js",
workers: 2,
repeat: 0,
background: "#fff",
quality: 10,
width: null,
height: null,
transparent: null
}, c = {
delay: 500,
copy: !1
}, e.prototype.setOption = function(t, e) {
return this.options[t] = e, null == this._canvas || "width" !== t && "height" !== t ? void 0 : this._canvas[t] = e
}, e.prototype.setOptions = function(t) {
var e, n;
return function(i) {
for (e in t) o(t, e) && (n = t[e], i.push(this.setOption(e, n)));
return i
}.call(this, [])
}, e.prototype.addFrame = function(t, e) {
var n, i;
null == e && (e = {}), n = {}, n.transparent = this.options.transparent;
for (i in c) n[i] = e[i] || c[i];
if (null != this.options.width || this.setOption("width", t.width), null != this.options.height || this.setOption("height", t.height), "undefined" != typeof ImageData && null != ImageData && t instanceof ImageData) n.data = t.data;
else if ("undefined" != typeof CanvasRenderingContext2D && null != CanvasRenderingContext2D && t instanceof CanvasRenderingContext2D || "undefined" != typeof WebGLRenderingContext && null != WebGLRenderingContext && t instanceof WebGLRenderingContext) e.copy ? n.data = this.getContextData(t) : n.context = t;
else {
if (null == t.childNodes) throw new Error("Invalid image");
e.copy ? n.data = this.getImageData(t) : n.image = t
}
return this.frames.push(n)
}, e.prototype.render = function() {
var t, e;
if (this.running) throw new Error("Already running");
if (null == this.options.width || null == this.options.height) throw new Error("Width and height must be set prior to rendering");
this.running = !0, this.nextFrame = 0, this.finishedFrames = 0, this.imageParts = function(e) {
for (var n = function() {
var t;
t = [];
for (var e = 0; 0 <= this.frames.length ? e < this.frames.length : e > this.frames.length; 0 <= this.frames.length ? ++e : --e) t.push(e);
return t
}.apply(this, arguments), i = 0, r = n.length; i < r; ++i) t = n[i], e.push(null);
return e
}.call(this, []), e = this.spawnWorkers();
for (var n = function() {
var t;
t = [];
for (var n = 0; 0 <= e ? n < e : n > e; 0 <= e ? ++n : --n) t.push(n);
return t
}.apply(this, arguments), i = 0, r = n.length; i < r; ++i) t = n[i], this.renderNextFrame();
return this.emit("start"), this.emit("progress", 0)
}, e.prototype.abort = function() {
for (var t;;) {
if (t = this.activeWorkers.shift(), !(null != t)) break;
console.log("killing active worker"), t.terminate()
}
return this.running = !1, this.emit("abort")
}, e.prototype.spawnWorkers = function() {
var t;
return t = Math.min(this.options.workers, this.frames.length),
function() {
var e;
e = [];
for (var n = this.freeWorkers.length; this.freeWorkers.length <= t ? n < t : n > t; this.freeWorkers.length <= t ? ++n : --n) e.push(n);
return e
}.apply(this, arguments).forEach(function(t) {
return function(e) {
var n;
return console.log("spawning worker " + e), n = new Worker(t.options.workerScript), n.onmessage = function(t) {
return function(e) {
return t.activeWorkers.splice(t.activeWorkers.indexOf(n), 1), t.freeWorkers.push(n), t.frameFinished(e.data)
}
}(t), t.freeWorkers.push(n)
}
}(this)), t
}, e.prototype.frameFinished = function(t) {
return console.log("frame " + t.index + " finished - " + this.activeWorkers.length + " active"), this.finishedFrames++, this.emit("progress", this.finishedFrames / this.frames.length), this.imageParts[t.index] = t, a(null, this.imageParts) ? this.renderNextFrame() : this.finishRendering()
}, e.prototype.finishRendering = function() {
var t, e, n, i, r, o, a;
r = 0;
for (var s = 0, h = this.imageParts.length; s < h; ++s) e = this.imageParts[s], r += (e.data.length - 1) * e.pageSize + e.cursor;
r += e.pageSize - e.cursor, console.log("rendering finished - filesize " + Math.round(r / 1e3) + "kb"), t = new Uint8Array(r), o = 0;
for (var d = 0, u = this.imageParts.length; d < u; ++d) {
e = this.imageParts[d];
for (var c = 0, f = e.data.length; c < f; ++c) a = e.data[c], n = c, t.set(a, o), o += n === e.data.length - 1 ? e.cursor : e.pageSize
}
return i = new Blob([t], {
type: "image/gif"
}), this.emit("finished", i, t)
}, e.prototype.renderNextFrame = function() {
var t, e, n;
if (0 === this.freeWorkers.length) throw new Error("No free workers");
return this.nextFrame >= this.frames.length ? void 0 : (t = this.frames[this.nextFrame++], n = this.freeWorkers.shift(), e = this.getTask(t), console.log("starting frame " + (e.index + 1) + " of " + this.frames.length), this.activeWorkers.push(n), n.postMessage(e))
}, e.prototype.getContextData = function(t) {
return t.getImageData(0, 0, this.options.width, this.options.height).data
}, e.prototype.getImageData = function(t) {
var e;
return null != this._canvas || (this._canvas = document.createElement("canvas"), this._canvas.width = this.options.width, this._canvas.height = this.options.height), e = this._canvas.getContext("2d"), e.setFill = this.options.background, e.fillRect(0, 0, this.options.width, this.options.height), e.drawImage(t, 0, 0), this.getContextData(e)
}, e.prototype.getTask = function(t) {
var e, n;
if (e = this.frames.indexOf(t), n = {
index: e,
last: e === this.frames.length - 1,
delay: t.delay,
transparent: t.transparent,
width: this.options.width,
height: this.options.height,
quality: this.options.quality,
repeat: this.options.repeat,
canTransfer: "chrome" === h.name
}, null != t.data) n.data = t.data;
else if (null != t.context) n.data = this.getContextData(t.context);
else {
if (null == t.image) throw new Error("Invalid frame");
n.data = this.getImageData(t.image)
}
return n
}, e
}(u), t.exports = f
}), e.define("/browser.coffee", function(t, e, n, i) {
var r, o, a, s, h;
s = navigator.userAgent.toLowerCase(), a = navigator.platform.toLowerCase(), h = s.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/) || [null, "unknown", 0], o = "ie" === h[1] && document.documentMode, r = {
name: "version" === h[1] ? h[3] : h[1],
version: o || parseFloat("opera" === h[1] && h[4] ? h[4] : h[2]),
platform: {
name: s.match(/ip(?:ad|od|hone)/) ? "ios" : (s.match(/(?:webos|android)/) || a.match(/mac|win|linux/) || ["other"])[0]
}
}, r[r.name] = !0, r[r.name + parseInt(r.version, 10)] = !0, r.platform[r.platform.name] = !0, t.exports = r
}), e.define("events", function(t, e, i, r) {
n.EventEmitter || (n.EventEmitter = function() {});
var o = e.EventEmitter = n.EventEmitter,
a = "function" == typeof Array.isArray ? Array.isArray : function(t) {
return "[object Array]" === Object.prototype.toString.call(t)
},
s = 10;
o.prototype.setMaxListeners = function(t) {
this._events || (this._events = {}), this._events.maxListeners = t
}, o.prototype.emit = function(t) {
if ("error" === t && (!this._events || !this._events.error || a(this._events.error) && !this._events.error.length)) throw arguments[1] instanceof Error ? arguments[1] : new Error("Uncaught, unspecified 'error' event.");
if (!this._events) return !1;
var e = this._events[t];
if (!e) return !1;
if ("function" != typeof e) {
if (a(e)) {
for (var n = Array.prototype.slice.call(arguments, 1), i = e.slice(), r = 0, o = i.length; r < o; r++) i[r].apply(this, n);
return !0
}
return !1
}
switch (arguments.length) {
case 1:
e.call(this);
break;
case 2:
e.call(this, arguments[1]);
break;
case 3:
e.call(this, arguments[1], arguments[2]);
break;
default:
var n = Array.prototype.slice.call(arguments, 1);
e.apply(this, n)
}
return !0
}, o.prototype.addListener = function(t, e) {
if ("function" != typeof e) throw new Error("addListener only takes instances of Function");
if (this._events || (this._events = {}), this.emit("newListener", t, e), this._events[t])
if (a(this._events[t])) {
if (!this._events[t].warned) {
var n;
n = void 0 !== this._events.maxListeners ? this._events.maxListeners : s, n && n > 0 && this._events[t].length > n && (this._events[t].warned = !0, console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.", this._events[t].length), console.trace())
}
this._events[t].push(e)
} else this._events[t] = [this._events[t], e];
else this._events[t] = e;
return this
}, o.prototype.on = o.prototype.addListener, o.prototype.once = function(t, e) {
var n = this;
return n.on(t, function i() {
n.removeListener(t, i), e.apply(this, arguments)
}), this
}, o.prototype.removeListener = function(t, e) {
if ("function" != typeof e) throw new Error("removeListener only takes instances of Function");
if (!this._events || !this._events[t]) return this;
var n = this._events[t];
if (a(n)) {
var i = n.indexOf(e);
if (i < 0) return this;
n.splice(i, 1), 0 == n.length && delete this._events[t]
} else this._events[t] === e && delete this._events[t];
return this
}, o.prototype.removeAllListeners = function(t) {
return t && this._events && this._events[t] && (this._events[t] = null), this
}, o.prototype.listeners = function(t) {
return this._events || (this._events = {}), this._events[t] || (this._events[t] = []), a(this._events[t]) || (this._events[t] = [this._events[t]]), this._events[t]
}
}), t.GIF = e("/gif.coffee")
}.call(this, this),
function() {
"use strict";
function t(t) {
return t && t.Object === Object ? t : null
}
function e(t) {
return String("0000000" + t).slice(-7)
}
function n() {
function t() {
return Math.floor(65536 * (1 + Math.random())).toString(16).substring(1)
}
return t() + t() + "-" + t() + "-" + t() + "-" + t() + "-" + t() + t() + t()
}
function i(t) {
var e = {};
this.settings = t, this.on = function(t, n) {
e[t] = n
}, this.emit = function(t) {
var n = e[t];
n && n.apply(null, Array.prototype.slice.call(arguments, 1))
}, this.filename = t.name || n(), this.extension = "", this.mimeType = ""
}
function r(t) {
i.call(this, t), this.extension = ".tar", this.mimeType = "application/x-tar", this.fileExtension = "", this.tape = null, this.count = 0
}
function o(t) {
r.call(this, t), this.type = "image/png", this.fileExtension = ".png"
}
function a(t) {
r.call(this, t), this.type = "image/jpeg", this.fileExtension = ".jpg", this.quality = t.quality / 100 || .8
}
function s(t) {
var e = document.createElement("canvas");
"image/webp" !== e.toDataURL("image/webp").substr(5, 10) && console.log("WebP not supported - try another export format"), i.call(this, t), t.quality = t.quality / 100 || .8, this.extension = ".webm", this.mimeType = "video/webm", this.baseFilename = this.filename, this.frames = [], this.part = 1
}
function h(t) {
i.call(this, t), t.quality = t.quality / 100 || .8, this.encoder = new FFMpegServer.Video(t), this.encoder.on("process", function() {
this.emit("process")
}.bind(this)), this.encoder.on("finished", function(t, e) {
var n = this.callback;
n && (this.callback = void 0, n(t, e))
}.bind(this)), this.encoder.on("progress", function(t) {
this.settings.onProgress && this.settings.onProgress(t)
}.bind(this)), this.encoder.on("error", function(t) {
alert(JSON.stringify(t, null, 2))
}.bind(this))
}
function d(t) {
i.call(this, t), this.framerate = this.settings.framerate, this.type = "video/webm", this.extension = ".webm", this.stream = null, this.mediaRecorder = null, this.chunks = []
}
function u(t) {
i.call(this, t), t.quality = 31 - (30 * t.quality / 100 || 10), t.workers = t.workers || 4, this.extension = ".gif", this.mimeType = "image/gif", this.canvas = document.createElement("canvas"), this.ctx = this.canvas.getContext("2d"), this.sizeSet = !1, this.encoder = new GIF({
workers: t.workers,
quality: t.quality,
workerScript: t.workersPath
}), this.encoder.on("progress", function(t) {
this.settings.onProgress && this.settings.onProgress(t)
}.bind(this)), this.encoder.on("finished", function(t) {
var e = this.callback;
e && (this.callback = void 0, e(t))
}.bind(this))
}
function c(t) {
function e() {
function t() {
return this._hooked || (this._hooked = !0, this._hookedTime = this.currentTime || 0, this.pause(), et.push(this)), this._hookedTime + S.startTime
}
b("Capturer start"), A = window.Date.now(), L = A + S.startTime, D = window.performance.now(), E = D + S.startTime, window.Date.prototype.getTime = function() {
return L
}, window.Date.now = function() {
return L
}, window.setTimeout = function(t, e) {
var n = {
callback: t,
time: e,
triggerTime: L + e
};
return B.push(n), b("Timeout set to " + n.time), n
}, window.clearTimeout = function(t) {
for (var e = 0; e < B.length; e++) B[e] != t || (B.splice(e, 1), b("Timeout cleared"))
}, window.setInterval = function(t, e) {
var n = {
callback: t,
time: e,
triggerTime: L + e
};
return j.push(n), b("Interval set to " + n.time), n
}, window.clearInterval = function(t) {
return b("clear Interval"), null
}, window.requestAnimationFrame = function(t) {
U.push(t)
}, window.performance.now = function() {
return E
};
try {
Object.defineProperty(HTMLVideoElement.prototype, "currentTime", {
get: t
}), Object.defineProperty(HTMLAudioElement.prototype, "currentTime", {
get: t
})
} catch (t) {
b(t)
}
}
function n() {
e(), I.start(), M = !0
}
function i() {
M = !1, I.stop(), f()
}
function r(t, e) {
Z(t, 0, e)
}
function c() {
r(v)
}
function f() {
b("Capturer stop"), window.setTimeout = Z, window.setInterval = J, window.clearTimeout = Y, window.requestAnimationFrame = $, window.Date.prototype.getTime = tt, window.Date.now = Q, window.performance.now = X
}
function l() {
var t = R / S.framerate;
(S.frameLimit && R >= S.frameLimit || S.timeLimit && t >= S.timeLimit) && (i(), y());
var e = new Date(null);
e.setSeconds(t), S.motionBlurFrames > 2 ? P.textContent = "CCapture " + S.format + " | " + R + " frames (" + O + " inter) | " + e.toISOString().substr(11, 8) : P.textContent = "CCapture " + S.format + " | " + R + " frames | " + e.toISOString().substr(11, 8)
}
function p(t) {
N.width === t.width && N.height === t.height || (N.width = t.width, N.height = t.height, q = new Uint16Array(N.height * N.width * 4), V.fillStyle = "#0", V.fillRect(0, 0, N.width, N.height))
}
function m(t) {
V.drawImage(t, 0, 0), z = V.getImageData(0, 0, N.width, N.height);
for (var e = 0; e < q.length; e += 4) q[e] += z.data[e], q[e + 1] += z.data[e + 1], q[e + 2] += z.data[e + 2];
O++
}
function g() {
for (var t = z.data, e = 0; e < q.length; e += 4) t[e] = 2 * q[e] / S.motionBlurFrames, t[e + 1] = 2 * q[e + 1] / S.motionBlurFrames, t[e + 2] = 2 * q[e + 2] / S.motionBlurFrames;
V.putImageData(z, 0, 0), I.add(N), R++, O = 0, b("Full MB Frame! " + R + " " + L);
for (var e = 0; e < q.length; e += 4) q[e] = 0, q[e + 1] = 0, q[e + 2] = 0;
gc()
}
function w(t) {
M && (S.motionBlurFrames > 2 ? (p(t), m(t), O >= .5 * S.motionBlurFrames ? g() : c()) : (I.add(t), R++, b("Full Frame! " + R)))
}
function v() {
var t = 1e3 / S.framerate,
e = (R + O / S.motionBlurFrames) * t;
L = A + e, E = D + e, et.forEach(function(t) {
t._hookedTime = e / 1e3
}), l(), b("Frame: " + R + " " + O);
for (var n = 0; n < B.length; n++) L >= B[n].triggerTime && (r(B[n].callback), B.splice(n, 1));
for (var n = 0; n < j.length; n++) L >= j[n].triggerTime && (r(j[n].callback), j[n].triggerTime += j[n].time);
U.forEach(function(t) {
r(t, L - k)
}), U = []
}
function y(t) {
t || (t = function(t) {
return download(t, I.filename + I.extension, I.mimeType), !1
}), I.save(t)
}
function b(t) {
_ && console.log(t)
}
function x(t, e) {
W[t] = e
}
function T(t) {
var e = W[t];
e && e.apply(null, Array.prototype.slice.call(arguments, 1))
}
function C(t) {
T("progress", t)
}
var _, F, L, A, E, D, c, I, S = t || {},
B = (new Date, []),
j = [],
R = 0,
O = 0,
U = [],
M = !1,
W = {};
S.framerate = S.framerate || 60, S.motionBlurFrames = 2 * (S.motionBlurFrames || 1), _ = S.verbose || !1, F = S.display || !1, S.step = 1e3 / S.framerate, S.timeLimit = S.timeLimit || 0, S.frameLimit = S.frameLimit || 0, S.startTime = S.startTime || 0;
var P = document.createElement("div");
P.style.position = "absolute", P.style.left = P.style.top = 0, P.style.backgroundColor = "black", P.style.fontFamily = "monospace", P.style.fontSize = "11px", P.style.padding = "5px", P.style.color = "red", P.style.zIndex = 1e5, S.display && document.body.appendChild(P);
var q, z, N = document.createElement("canvas"),
V = N.getContext("2d");
b("Step is set to " + S.step + "ms");
var H = {
gif: u,
webm: s,
ffmpegserver: h,
png: o,
jpg: a,
"webm-mediarecorder": d
},
G = H[S.format];
if (!G) throw "Error: Incorrect or missing format: Valid formats are " + Object.keys(H).join(", ");
if (I = new G(S), I.step = c, I.on("process", v), I.on("progress", C), "performance" in window == 0 && (window.performance = {}), Date.now = Date.now || function() {
return (new Date).getTime()
}, "now" in window.performance == 0) {
var K = Date.now();
performance.timing && performance.timing.navigationStart && (K = performance.timing.navigationStart), window.performance.now = function() {
return Date.now() - K
}
}
var Z = window.setTimeout,
J = window.setInterval,
Y = window.clearTimeout,
$ = window.requestAnimationFrame,
Q = window.Date.now,
X = window.performance.now,
tt = window.Date.prototype.getTime,
et = [];
return {
start: n,
capture: w,
stop: i,
save: y,
on: x
}
}
var f = {
function: !0,
object: !0
},
l = (parseFloat, parseInt, f[typeof exports] && exports && !exports.nodeType ? exports : void 0),
p = f[typeof module] && module && !module.nodeType ? module : void 0,
m = p && p.exports === l ? l : void 0,
g = t(l && p && "object" == typeof global && global),
w = t(f[typeof self] && self),
v = t(f[typeof window] && window),
y = t(f[typeof this] && this),
b = g || v !== (y && y.window) && v || w || y || Function("return this")();
"gc" in window || (window.gc = function() {}), HTMLCanvasElement.prototype.toBlob || Object.defineProperty(HTMLCanvasElement.prototype, "toBlob", {
value: function(t, e, n) {
for (var i = atob(this.toDataURL(e, n).split(",")[1]), r = i.length, o = new Uint8Array(r), a = 0; a < r; a++) o[a] = i.charCodeAt(a);
t(new Blob([o], {
type: e || "image/png"
}))
}
}),
function() {
if ("performance" in window == 0 && (window.performance = {}), Date.now = Date.now || function() {
return (new Date).getTime()
}, "now" in window.performance == 0) {
var t = Date.now();
performance.timing && performance.timing.navigationStart && (t = performance.timing.navigationStart), window.performance.now = function() {
return Date.now() - t
}
}
}();
var k = window.Date.now();
i.prototype.start = function() {}, i.prototype.stop = function() {}, i.prototype.add = function() {}, i.prototype.save = function() {}, i.prototype.dispose = function() {}, i.prototype.safeToProceed = function() {
return !0
}, i.prototype.step = function() {
console.log("Step not set!")
}, r.prototype = Object.create(i.prototype), r.prototype.start = function() {
this.dispose()
}, r.prototype.add = function(t) {
var n = new FileReader;
n.onload = function() {
this.tape.append(e(this.count) + this.fileExtension, new Uint8Array(n.result)), this.count++, this.step()
}.bind(this), n.readAsArrayBuffer(t)
}, r.prototype.save = function(t) {
t(this.tape.save())
}, r.prototype.dispose = function() {
this.tape = new Tar, this.count = 0
}, o.prototype = Object.create(r.prototype), o.prototype.add = function(t) {
t.toBlob(function(t) {
r.prototype.add.call(this, t)
}.bind(this), this.type)
}, a.prototype = Object.create(r.prototype), a.prototype.add = function(t) {
t.toBlob(function(t) {
r.prototype.add.call(this, t)
}.bind(this), this.type, this.quality)
}, s.prototype = Object.create(i.prototype), s.prototype.start = function(t) {
this.dispose()
}, s.prototype.add = function(t) {
this.frames.push(t.toDataURL("image/webp", this.quality)), this.settings.autoSaveTime > 0 && this.frames.length / this.settings.framerate >= this.settings.autoSaveTime ? this.save(function(t) {
this.filename = this.baseFilename + "-part-" + e(this.part), download(t, this.filename + this.extension, this.mimeType), this.dispose(), this.part++, this.filename = this.baseFilename + "-part-" + e(this.part), this.step()
}.bind(this)) : this.step()
}, s.prototype.save = function(t) {
if (this.frames.length) {
var e = Whammy.fromImageArray(this.frames, this.settings.framerate),
n = new Blob([e], {
type: "octet/stream"
});
t(n)
}
}, s.prototype.dispose = function(t) {
this.frames = []
}, h.prototype = Object.create(i.prototype), h.prototype.start = function() {
this.encoder.start(this.settings)
}, h.prototype.add = function(t) {
this.encoder.add(t)
}, h.prototype.save = function(t) {
this.callback = t, this.encoder.end()
}, h.prototype.safeToProceed = function() {
return this.encoder.safeToProceed()
}, d.prototype = Object.create(i.prototype), d.prototype.add = function(t) {
this.stream || (this.stream = t.captureStream(this.framerate), this.mediaRecorder = new MediaRecorder(this.stream), this.mediaRecorder.start(), this.mediaRecorder.ondataavailable = function(t) {
this.chunks.push(t.data)
}.bind(this)), this.step()
}, d.prototype.save = function(t) {
this.mediaRecorder.onstop = function(e) {
var n = new Blob(this.chunks, {
type: "video/webm"
});
this.chunks = [], t(n)
}.bind(this), this.mediaRecorder.stop()
}, u.prototype = Object.create(i.prototype), u.prototype.add = function(t) {
this.sizeSet || (this.encoder.setOption("width", t.width), this.encoder.setOption("height", t.height), this.sizeSet = !0), this.canvas.width = t.width, this.canvas.height = t.height, this.ctx.drawImage(t, 0, 0), this.encoder.addFrame(this.ctx, {
copy: !0,
delay: this.settings.step
}), this.step()
}, u.prototype.save = function(t) {
this.callback = t, this.encoder.render()
}, (v || w || {}).CCapture = c, "function" == typeof define && "object" == typeof define.amd && define.amd ? define(function() {
return c
}) : l && p ? (m && ((p.exports = c).CCapture = c), l.CCapture = c) : b.CCapture = c
}();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment