Last active
January 15, 2017 18:08
-
-
Save Galadirith/4aa04210d361e59ffa615983d3ef3623 to your computer and use it in GitHub Desktop.
capture.js with workerScript not workerPath
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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