@loaders.gl/video 4.0.0-alpha.1 → 4.0.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.d.ts +2 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +2 -2
- package/dist/dist.min.js +2147 -0
- package/dist/es5/bundle.js +6 -0
- package/dist/es5/bundle.js.map +1 -0
- package/dist/es5/gif-builder.js +200 -0
- package/dist/es5/gif-builder.js.map +1 -0
- package/dist/es5/index.js +21 -0
- package/dist/es5/index.js.map +1 -0
- package/dist/es5/lib/gifshot/gifshot-loader.js +67 -0
- package/dist/es5/lib/gifshot/gifshot-loader.js.map +1 -0
- package/dist/es5/lib/gifshot/gifshot.js +1924 -0
- package/dist/es5/lib/gifshot/gifshot.js.map +1 -0
- package/dist/es5/lib/parsers/parse-video.js +31 -0
- package/dist/es5/lib/parsers/parse-video.js.map +1 -0
- package/dist/es5/lib/utils/assert.js +12 -0
- package/dist/es5/lib/utils/assert.js.map +1 -0
- package/dist/es5/video-loader.js +28 -0
- package/dist/es5/video-loader.js.map +1 -0
- package/dist/esm/bundle.js +4 -0
- package/dist/esm/bundle.js.map +1 -0
- package/dist/esm/gif-builder.js +106 -0
- package/dist/esm/gif-builder.js.map +1 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -0
- package/{src → dist/esm}/lib/gifshot/gifshot-loader.js +4 -8
- package/dist/esm/lib/gifshot/gifshot-loader.js.map +1 -0
- package/dist/esm/lib/gifshot/gifshot.js +1915 -0
- package/dist/esm/lib/gifshot/gifshot.js.map +1 -0
- package/dist/esm/lib/parsers/parse-video.js +7 -0
- package/dist/esm/lib/parsers/parse-video.js.map +1 -0
- package/{src → dist/esm}/lib/utils/assert.js +1 -0
- package/dist/esm/lib/utils/assert.js.map +1 -0
- package/dist/esm/video-loader.js +19 -0
- package/dist/esm/video-loader.js.map +1 -0
- package/dist/gif-builder.d.ts +53 -0
- package/dist/gif-builder.d.ts.map +1 -0
- package/dist/gif-builder.js +136 -114
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -3
- package/dist/lib/gifshot/gifshot-loader.d.ts +2 -0
- package/dist/lib/gifshot/gifshot-loader.d.ts.map +1 -0
- package/dist/lib/gifshot/gifshot-loader.js +18 -15
- package/dist/lib/gifshot/gifshot.d.ts +72 -0
- package/dist/lib/gifshot/gifshot.d.ts.map +1 -0
- package/dist/lib/gifshot/gifshot.js +2417 -0
- package/dist/lib/parsers/parse-video.d.ts +2 -0
- package/dist/lib/parsers/parse-video.d.ts.map +1 -0
- package/dist/lib/parsers/parse-video.js +12 -6
- package/dist/lib/utils/assert.d.ts +2 -0
- package/dist/lib/utils/assert.d.ts.map +1 -0
- package/dist/lib/utils/assert.js +8 -5
- package/dist/video-loader.d.ts +17 -0
- package/dist/video-loader.d.ts.map +1 -0
- package/dist/video-loader.js +22 -14
- package/package.json +8 -8
- package/src/{gif-builder.js → gif-builder.ts} +6 -6
- package/src/lib/gifshot/gifshot.ts +2394 -0
- package/dist/bundle.js.map +0 -1
- package/dist/gif-builder.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/gifshot/gifshot-loader.js.map +0 -1
- package/dist/lib/parsers/parse-video.js.map +0 -1
- package/dist/lib/utils/assert.js.map +0 -1
- package/dist/lib/utils/globals.js +0 -16
- package/dist/lib/utils/globals.js.map +0 -1
- package/dist/libs/gifshot.js +0 -2826
- package/dist/video-loader.js.map +0 -1
- package/src/lib/utils/globals.js +0 -25
- package/src/libs/gifshot.js +0 -2826
|
@@ -0,0 +1,1924 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
var _readOnlyError2 = _interopRequireDefault(require("@babel/runtime/helpers/readOnlyError"));
|
|
9
|
+
var utils = {
|
|
10
|
+
URL: globalThis.URL || globalThis.webkitURL || globalThis.mozURL || globalThis.msURL,
|
|
11
|
+
getUserMedia: function () {
|
|
12
|
+
if (!globalThis.navigator) return globalThis.navigator;
|
|
13
|
+
var getUserMedia = globalThis.navigator.getUserMedia || globalThis.navigator.webkitGetUserMedia || globalThis.navigator.mozGetUserMedia || globalThis.navigator.msGetUserMedia;
|
|
14
|
+
return getUserMedia ? getUserMedia.bind(globalThis.navigator) : getUserMedia;
|
|
15
|
+
}(),
|
|
16
|
+
requestAnimFrame: globalThis.requestAnimationFrame || globalThis.webkitRequestAnimationFrame || globalThis.mozRequestAnimationFrame || globalThis.oRequestAnimationFrame || globalThis.msRequestAnimationFrame,
|
|
17
|
+
requestTimeout: function requestTimeout(callback, delay) {
|
|
18
|
+
callback = callback || utils.noop;
|
|
19
|
+
delay = delay || 0;
|
|
20
|
+
if (!utils.requestAnimFrame) {
|
|
21
|
+
return setTimeout(callback, delay);
|
|
22
|
+
}
|
|
23
|
+
var start = new Date().getTime();
|
|
24
|
+
var handle = new Object();
|
|
25
|
+
var requestAnimFrame = utils.requestAnimFrame;
|
|
26
|
+
var loop = function loop() {
|
|
27
|
+
var current = new Date().getTime();
|
|
28
|
+
var delta = current - start;
|
|
29
|
+
delta >= delay ? callback.call() : handle.value = requestAnimFrame(loop);
|
|
30
|
+
};
|
|
31
|
+
handle.value = requestAnimFrame(loop);
|
|
32
|
+
return handle;
|
|
33
|
+
},
|
|
34
|
+
Blob: globalThis.Blob || globalThis.BlobBuilder || globalThis.WebKitBlobBuilder || globalThis.MozBlobBuilder || globalThis.MSBlobBuilder,
|
|
35
|
+
btoa: function () {
|
|
36
|
+
var btoa = globalThis.btoa || function (input) {
|
|
37
|
+
var output = '';
|
|
38
|
+
var i = 0;
|
|
39
|
+
var l = input.length;
|
|
40
|
+
var key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
41
|
+
var chr1 = void 0;
|
|
42
|
+
var chr2 = void 0;
|
|
43
|
+
var chr3 = void 0;
|
|
44
|
+
var enc1 = void 0;
|
|
45
|
+
var enc2 = void 0;
|
|
46
|
+
var enc3 = void 0;
|
|
47
|
+
var enc4 = void 0;
|
|
48
|
+
while (i < l) {
|
|
49
|
+
chr1 = input.charCodeAt(i++);
|
|
50
|
+
chr2 = input.charCodeAt(i++);
|
|
51
|
+
chr3 = input.charCodeAt(i++);
|
|
52
|
+
enc1 = chr1 >> 2;
|
|
53
|
+
enc2 = (chr1 & 3) << 4 | chr2 >> 4;
|
|
54
|
+
enc3 = (chr2 & 15) << 2 | chr3 >> 6;
|
|
55
|
+
enc4 = chr3 & 63;
|
|
56
|
+
if (isNaN(chr2)) {
|
|
57
|
+
enc3 = enc4 = 64;
|
|
58
|
+
} else if (isNaN(chr3)) {
|
|
59
|
+
enc4 = 64;
|
|
60
|
+
}
|
|
61
|
+
output = output + key.charAt(enc1) + key.charAt(enc2) + key.charAt(enc3) + key.charAt(enc4);
|
|
62
|
+
}
|
|
63
|
+
return output;
|
|
64
|
+
};
|
|
65
|
+
return btoa ? btoa.bind(globalThis) : utils.noop;
|
|
66
|
+
}(),
|
|
67
|
+
isObject: function isObject(obj) {
|
|
68
|
+
return obj && Object.prototype.toString.call(obj) === '[object Object]';
|
|
69
|
+
},
|
|
70
|
+
isEmptyObject: function isEmptyObject(obj) {
|
|
71
|
+
return utils.isObject(obj) && !Object.keys(obj).length;
|
|
72
|
+
},
|
|
73
|
+
isArray: function isArray(arr) {
|
|
74
|
+
return arr && Array.isArray(arr);
|
|
75
|
+
},
|
|
76
|
+
isFunction: function isFunction(func) {
|
|
77
|
+
return func && typeof func === 'function';
|
|
78
|
+
},
|
|
79
|
+
isElement: function isElement(elem) {
|
|
80
|
+
return elem && elem.nodeType === 1;
|
|
81
|
+
},
|
|
82
|
+
isString: function isString(value) {
|
|
83
|
+
return typeof value === 'string' || Object.prototype.toString.call(value) === '[object String]';
|
|
84
|
+
},
|
|
85
|
+
isSupported: {
|
|
86
|
+
canvas: function canvas() {
|
|
87
|
+
var el = document.createElement('canvas');
|
|
88
|
+
return el && el.getContext && el.getContext('2d');
|
|
89
|
+
},
|
|
90
|
+
webworkers: function webworkers() {
|
|
91
|
+
return globalThis.Worker;
|
|
92
|
+
},
|
|
93
|
+
blob: function blob() {
|
|
94
|
+
return utils.Blob;
|
|
95
|
+
},
|
|
96
|
+
Uint8Array: function Uint8Array() {
|
|
97
|
+
return globalThis.Uint8Array;
|
|
98
|
+
},
|
|
99
|
+
Uint32Array: function Uint32Array() {
|
|
100
|
+
return globalThis.Uint32Array;
|
|
101
|
+
},
|
|
102
|
+
videoCodecs: function () {
|
|
103
|
+
var testEl = document.createElement('video');
|
|
104
|
+
var supportObj = {
|
|
105
|
+
mp4: false,
|
|
106
|
+
h264: false,
|
|
107
|
+
ogv: false,
|
|
108
|
+
ogg: false,
|
|
109
|
+
webm: false
|
|
110
|
+
};
|
|
111
|
+
try {
|
|
112
|
+
if (testEl && testEl.canPlayType) {
|
|
113
|
+
supportObj.mp4 = testEl.canPlayType('video/mp4; codecs="mp4v.20.8"') !== '';
|
|
114
|
+
supportObj.h264 = (testEl.canPlayType('video/mp4; codecs="avc1.42E01E"') || testEl.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')) !== '';
|
|
115
|
+
supportObj.ogv = testEl.canPlayType('video/ogg; codecs="theora"') !== '';
|
|
116
|
+
supportObj.ogg = testEl.canPlayType('video/ogg; codecs="theora"') !== '';
|
|
117
|
+
supportObj.webm = testEl.canPlayType('video/webm; codecs="vp8, vorbis"') !== -1;
|
|
118
|
+
}
|
|
119
|
+
} catch (e) {}
|
|
120
|
+
return supportObj;
|
|
121
|
+
}()
|
|
122
|
+
},
|
|
123
|
+
noop: function noop() {},
|
|
124
|
+
each: function each(collection, callback) {
|
|
125
|
+
var x = void 0;
|
|
126
|
+
var len = void 0;
|
|
127
|
+
if (utils.isArray(collection)) {
|
|
128
|
+
x = -1;
|
|
129
|
+
len = collection.length;
|
|
130
|
+
while (++x < len) {
|
|
131
|
+
if (callback(x, collection[x]) === false) {
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
} else if (utils.isObject(collection)) {
|
|
136
|
+
for (x in collection) {
|
|
137
|
+
if (collection.hasOwnProperty(x)) {
|
|
138
|
+
if (callback(x, collection[x]) === false) {
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
normalizeOptions: function normalizeOptions(defaultOptions, userOptions) {
|
|
146
|
+
if (!utils.isObject(defaultOptions) || !utils.isObject(userOptions) || !Object.keys) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
var newObj = {};
|
|
150
|
+
utils.each(defaultOptions, function (key, val) {
|
|
151
|
+
newObj[key] = defaultOptions[key];
|
|
152
|
+
});
|
|
153
|
+
utils.each(userOptions, function (key, val) {
|
|
154
|
+
var currentUserOption = userOptions[key];
|
|
155
|
+
if (!utils.isObject(currentUserOption)) {
|
|
156
|
+
newObj[key] = currentUserOption;
|
|
157
|
+
} else if (!defaultOptions[key]) {
|
|
158
|
+
newObj[key] = currentUserOption;
|
|
159
|
+
} else {
|
|
160
|
+
newObj[key] = utils.normalizeOptions(defaultOptions[key], currentUserOption);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
return newObj;
|
|
164
|
+
},
|
|
165
|
+
setCSSAttr: function setCSSAttr(elem, attr, val) {
|
|
166
|
+
if (!utils.isElement(elem)) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (utils.isString(attr) && utils.isString(val)) {
|
|
170
|
+
elem.style[attr] = val;
|
|
171
|
+
} else if (utils.isObject(attr)) {
|
|
172
|
+
utils.each(attr, function (key, val) {
|
|
173
|
+
elem.style[key] = val;
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
removeElement: function removeElement(node) {
|
|
178
|
+
if (!utils.isElement(node)) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (node.parentNode) {
|
|
182
|
+
node.parentNode.removeChild(node);
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
createWebWorker: function createWebWorker(content) {
|
|
186
|
+
if (!utils.isString(content)) {
|
|
187
|
+
return {};
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
var blob = new utils.Blob([content], {
|
|
191
|
+
type: 'text/javascript'
|
|
192
|
+
});
|
|
193
|
+
var objectUrl = utils.URL.createObjectURL(blob);
|
|
194
|
+
var worker = new Worker(objectUrl);
|
|
195
|
+
return {
|
|
196
|
+
objectUrl: objectUrl,
|
|
197
|
+
worker: worker
|
|
198
|
+
};
|
|
199
|
+
} catch (e) {
|
|
200
|
+
return "".concat(e);
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
getExtension: function getExtension(src) {
|
|
204
|
+
return src.substr(src.lastIndexOf('.') + 1, src.length);
|
|
205
|
+
},
|
|
206
|
+
getFontSize: function getFontSize() {
|
|
207
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
208
|
+
if (!document.body || options.resizeFont === false) {
|
|
209
|
+
return options.fontSize;
|
|
210
|
+
}
|
|
211
|
+
var text = options.text;
|
|
212
|
+
var containerWidth = options.gifWidth;
|
|
213
|
+
var fontSize = parseInt(options.fontSize, 10);
|
|
214
|
+
var minFontSize = parseInt(options.minFontSize, 10);
|
|
215
|
+
var div = document.createElement('div');
|
|
216
|
+
var span = document.createElement('span');
|
|
217
|
+
div.setAttribute('width', containerWidth);
|
|
218
|
+
div.appendChild(span);
|
|
219
|
+
span.innerHTML = text;
|
|
220
|
+
span.style.fontSize = "".concat(fontSize, "px");
|
|
221
|
+
span.style.textIndent = '-9999px';
|
|
222
|
+
span.style.visibility = 'hidden';
|
|
223
|
+
document.body.appendChild(span);
|
|
224
|
+
while (span.offsetWidth > containerWidth && fontSize >= minFontSize) {
|
|
225
|
+
span.style.fontSize = "".concat(--fontSize, "px");
|
|
226
|
+
}
|
|
227
|
+
document.body.removeChild(span);
|
|
228
|
+
return "".concat(fontSize, "px");
|
|
229
|
+
},
|
|
230
|
+
webWorkerError: false
|
|
231
|
+
};
|
|
232
|
+
var utils$2 = Object.freeze({
|
|
233
|
+
default: utils
|
|
234
|
+
});
|
|
235
|
+
var error = {
|
|
236
|
+
validate: function validate(skipObj) {
|
|
237
|
+
skipObj = utils.isObject(skipObj) ? skipObj : {};
|
|
238
|
+
var errorObj = {};
|
|
239
|
+
utils.each(error.validators, function (indece, currentValidator) {
|
|
240
|
+
var errorCode = currentValidator.errorCode;
|
|
241
|
+
if (!skipObj[errorCode] && !currentValidator.condition) {
|
|
242
|
+
errorObj = currentValidator;
|
|
243
|
+
errorObj.error = true;
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
delete errorObj.condition;
|
|
248
|
+
return errorObj;
|
|
249
|
+
},
|
|
250
|
+
isValid: function isValid(skipObj) {
|
|
251
|
+
var errorObj = error.validate(skipObj);
|
|
252
|
+
var isValid = errorObj.error !== true;
|
|
253
|
+
return isValid;
|
|
254
|
+
},
|
|
255
|
+
validators: [{
|
|
256
|
+
condition: utils.isFunction(utils.getUserMedia),
|
|
257
|
+
errorCode: 'getUserMedia',
|
|
258
|
+
errorMsg: 'The getUserMedia API is not supported in your browser'
|
|
259
|
+
}, {
|
|
260
|
+
condition: utils.isSupported.canvas(),
|
|
261
|
+
errorCode: 'canvas',
|
|
262
|
+
errorMsg: 'Canvas elements are not supported in your browser'
|
|
263
|
+
}, {
|
|
264
|
+
condition: utils.isSupported.webworkers(),
|
|
265
|
+
errorCode: 'webworkers',
|
|
266
|
+
errorMsg: 'The Web Workers API is not supported in your browser'
|
|
267
|
+
}, {
|
|
268
|
+
condition: utils.isFunction(utils.URL),
|
|
269
|
+
errorCode: 'globalThis.URL',
|
|
270
|
+
errorMsg: 'The globalThis.URL API is not supported in your browser'
|
|
271
|
+
}, {
|
|
272
|
+
condition: utils.isSupported.blob(),
|
|
273
|
+
errorCode: 'globalThis.Blob',
|
|
274
|
+
errorMsg: 'The globalThis.Blob File API is not supported in your browser'
|
|
275
|
+
}, {
|
|
276
|
+
condition: utils.isSupported.Uint8Array(),
|
|
277
|
+
errorCode: 'globalThis.Uint8Array',
|
|
278
|
+
errorMsg: 'The globalThis.Uint8Array function constructor is not supported in your browser'
|
|
279
|
+
}, {
|
|
280
|
+
condition: utils.isSupported.Uint32Array(),
|
|
281
|
+
errorCode: 'globalThis.Uint32Array',
|
|
282
|
+
errorMsg: 'The globalThis.Uint32Array function constructor is not supported in your browser'
|
|
283
|
+
}],
|
|
284
|
+
messages: {
|
|
285
|
+
videoCodecs: {
|
|
286
|
+
errorCode: 'videocodec',
|
|
287
|
+
errorMsg: 'The video codec you are trying to use is not supported in your browser'
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
var error$2 = Object.freeze({
|
|
292
|
+
default: error
|
|
293
|
+
});
|
|
294
|
+
var noop = function noop() {};
|
|
295
|
+
var defaultOptions = {
|
|
296
|
+
sampleInterval: 10,
|
|
297
|
+
numWorkers: 2,
|
|
298
|
+
filter: '',
|
|
299
|
+
gifWidth: 200,
|
|
300
|
+
gifHeight: 200,
|
|
301
|
+
interval: 0.1,
|
|
302
|
+
numFrames: 10,
|
|
303
|
+
frameDuration: 1,
|
|
304
|
+
keepCameraOn: false,
|
|
305
|
+
images: [],
|
|
306
|
+
video: null,
|
|
307
|
+
webcamVideoElement: null,
|
|
308
|
+
cameraStream: null,
|
|
309
|
+
text: '',
|
|
310
|
+
fontWeight: 'normal',
|
|
311
|
+
fontSize: '16px',
|
|
312
|
+
minFontSize: '10px',
|
|
313
|
+
resizeFont: false,
|
|
314
|
+
fontFamily: 'sans-serif',
|
|
315
|
+
fontColor: '#ffffff',
|
|
316
|
+
textAlign: 'center',
|
|
317
|
+
textBaseline: 'bottom',
|
|
318
|
+
textXCoordinate: null,
|
|
319
|
+
textYCoordinate: null,
|
|
320
|
+
progressCallback: noop,
|
|
321
|
+
completeCallback: noop,
|
|
322
|
+
saveRenderingContexts: false,
|
|
323
|
+
savedRenderingContexts: [],
|
|
324
|
+
crossOrigin: 'Anonymous'
|
|
325
|
+
};
|
|
326
|
+
var defaultOptions$2 = Object.freeze({
|
|
327
|
+
default: defaultOptions
|
|
328
|
+
});
|
|
329
|
+
function isSupported() {
|
|
330
|
+
return error.isValid();
|
|
331
|
+
}
|
|
332
|
+
function isWebCamGIFSupported() {
|
|
333
|
+
return error.isValid();
|
|
334
|
+
}
|
|
335
|
+
function isSupported$1() {
|
|
336
|
+
var options = {
|
|
337
|
+
getUserMedia: true
|
|
338
|
+
};
|
|
339
|
+
return error.isValid(options);
|
|
340
|
+
}
|
|
341
|
+
function isExistingVideoGIFSupported(codecs) {
|
|
342
|
+
var hasValidCodec = false;
|
|
343
|
+
if (utils.isArray(codecs) && codecs.length) {
|
|
344
|
+
utils.each(codecs, function (indece, currentCodec) {
|
|
345
|
+
if (utils.isSupported.videoCodecs[currentCodec]) {
|
|
346
|
+
hasValidCodec = true;
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
if (!hasValidCodec) {
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
} else if (utils.isString(codecs) && codecs.length) {
|
|
353
|
+
if (!utils.isSupported.videoCodecs[codecs]) {
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return error.isValid({
|
|
358
|
+
getUserMedia: true
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
function NeuQuant() {
|
|
362
|
+
var netsize = 256;
|
|
363
|
+
var prime1 = 499;
|
|
364
|
+
var prime2 = 491;
|
|
365
|
+
var prime3 = 487;
|
|
366
|
+
var prime4 = 503;
|
|
367
|
+
var minpicturebytes = 3 * prime4;
|
|
368
|
+
var maxnetpos = netsize - 1;
|
|
369
|
+
var netbiasshift = 4;
|
|
370
|
+
var ncycles = 100;
|
|
371
|
+
var intbiasshift = 16;
|
|
372
|
+
var intbias = 1 << intbiasshift;
|
|
373
|
+
var gammashift = 10;
|
|
374
|
+
var gamma = 1 << gammashift;
|
|
375
|
+
var betashift = 10;
|
|
376
|
+
var beta = intbias >> betashift;
|
|
377
|
+
var betagamma = intbias << gammashift - betashift;
|
|
378
|
+
var initrad = netsize >> 3;
|
|
379
|
+
var radiusbiasshift = 6;
|
|
380
|
+
var radiusbias = 1 << radiusbiasshift;
|
|
381
|
+
var initradius = initrad * radiusbias;
|
|
382
|
+
var radiusdec = 30;
|
|
383
|
+
var alphabiasshift = 10;
|
|
384
|
+
var initalpha = 1 << alphabiasshift;
|
|
385
|
+
var alphadec;
|
|
386
|
+
var radbiasshift = 8;
|
|
387
|
+
var radbias = 1 << radbiasshift;
|
|
388
|
+
var alpharadbshift = alphabiasshift + radbiasshift;
|
|
389
|
+
var alpharadbias = 1 << alpharadbshift;
|
|
390
|
+
var thepicture;
|
|
391
|
+
var lengthcount;
|
|
392
|
+
var samplefac;
|
|
393
|
+
var network;
|
|
394
|
+
var netindex = [];
|
|
395
|
+
var bias = [];
|
|
396
|
+
var freq = [];
|
|
397
|
+
var radpower = [];
|
|
398
|
+
function NeuQuantConstructor(thepic, len, sample) {
|
|
399
|
+
var i;
|
|
400
|
+
var p;
|
|
401
|
+
thepicture = thepic;
|
|
402
|
+
lengthcount = len;
|
|
403
|
+
samplefac = sample;
|
|
404
|
+
network = new Array(netsize);
|
|
405
|
+
for (i = 0; i < netsize; i++) {
|
|
406
|
+
network[i] = new Array(4);
|
|
407
|
+
p = network[i];
|
|
408
|
+
p[0] = p[1] = p[2] = (i << netbiasshift + 8) / netsize | 0;
|
|
409
|
+
freq[i] = intbias / netsize | 0;
|
|
410
|
+
bias[i] = 0;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
function colorMap() {
|
|
414
|
+
var map = [];
|
|
415
|
+
var index = new Array(netsize);
|
|
416
|
+
for (var i = 0; i < netsize; i++) {
|
|
417
|
+
index[network[i][3]] = i;
|
|
418
|
+
}
|
|
419
|
+
var k = 0;
|
|
420
|
+
for (var l = 0; l < netsize; l++) {
|
|
421
|
+
var j = index[l];
|
|
422
|
+
map[k++] = network[j][0];
|
|
423
|
+
map[k++] = network[j][1];
|
|
424
|
+
map[k++] = network[j][2];
|
|
425
|
+
}
|
|
426
|
+
return map;
|
|
427
|
+
}
|
|
428
|
+
function inxbuild() {
|
|
429
|
+
var i;
|
|
430
|
+
var j;
|
|
431
|
+
var smallpos;
|
|
432
|
+
var smallval;
|
|
433
|
+
var p;
|
|
434
|
+
var q;
|
|
435
|
+
var previouscol;
|
|
436
|
+
var startpos;
|
|
437
|
+
previouscol = 0;
|
|
438
|
+
startpos = 0;
|
|
439
|
+
for (i = 0; i < netsize; i++) {
|
|
440
|
+
p = network[i];
|
|
441
|
+
smallpos = i;
|
|
442
|
+
smallval = p[1];
|
|
443
|
+
for (j = i + 1; j < netsize; j++) {
|
|
444
|
+
q = network[j];
|
|
445
|
+
if (q[1] < smallval) {
|
|
446
|
+
smallpos = j;
|
|
447
|
+
smallval = q[1];
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
q = network[smallpos];
|
|
451
|
+
if (i != smallpos) {
|
|
452
|
+
j = q[0];
|
|
453
|
+
q[0] = p[0];
|
|
454
|
+
p[0] = j;
|
|
455
|
+
j = q[1];
|
|
456
|
+
q[1] = p[1];
|
|
457
|
+
p[1] = j;
|
|
458
|
+
j = q[2];
|
|
459
|
+
q[2] = p[2];
|
|
460
|
+
p[2] = j;
|
|
461
|
+
j = q[3];
|
|
462
|
+
q[3] = p[3];
|
|
463
|
+
p[3] = j;
|
|
464
|
+
}
|
|
465
|
+
if (smallval != previouscol) {
|
|
466
|
+
netindex[previouscol] = startpos + i >> 1;
|
|
467
|
+
for (j = previouscol + 1; j < smallval; j++) {
|
|
468
|
+
netindex[j] = i;
|
|
469
|
+
}
|
|
470
|
+
previouscol = smallval;
|
|
471
|
+
startpos = i;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
netindex[previouscol] = startpos + maxnetpos >> 1;
|
|
475
|
+
for (j = previouscol + 1; j < 256; j++) {
|
|
476
|
+
netindex[j] = maxnetpos;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
function learn() {
|
|
480
|
+
var i;
|
|
481
|
+
var j;
|
|
482
|
+
var b;
|
|
483
|
+
var g;
|
|
484
|
+
var r;
|
|
485
|
+
var radius;
|
|
486
|
+
var rad;
|
|
487
|
+
var alpha;
|
|
488
|
+
var step;
|
|
489
|
+
var delta;
|
|
490
|
+
var samplepixels;
|
|
491
|
+
var p;
|
|
492
|
+
var pix;
|
|
493
|
+
var lim;
|
|
494
|
+
if (lengthcount < minpicturebytes) {
|
|
495
|
+
samplefac = 1;
|
|
496
|
+
}
|
|
497
|
+
alphadec = 30 + (samplefac - 1) / 3;
|
|
498
|
+
p = thepicture;
|
|
499
|
+
pix = 0;
|
|
500
|
+
lim = lengthcount;
|
|
501
|
+
samplepixels = lengthcount / (3 * samplefac);
|
|
502
|
+
delta = samplepixels / ncycles | 0;
|
|
503
|
+
alpha = initalpha;
|
|
504
|
+
radius = initradius;
|
|
505
|
+
rad = radius >> radiusbiasshift;
|
|
506
|
+
if (rad <= 1) {
|
|
507
|
+
rad = 0;
|
|
508
|
+
}
|
|
509
|
+
for (i = 0; i < rad; i++) {
|
|
510
|
+
radpower[i] = alpha * ((rad * rad - i * i) * radbias / (rad * rad));
|
|
511
|
+
}
|
|
512
|
+
if (lengthcount < minpicturebytes) {
|
|
513
|
+
step = 3;
|
|
514
|
+
} else if (lengthcount % prime1 !== 0) {
|
|
515
|
+
step = 3 * prime1;
|
|
516
|
+
} else if (lengthcount % prime2 !== 0) {
|
|
517
|
+
step = 3 * prime2;
|
|
518
|
+
} else if (lengthcount % prime3 !== 0) {
|
|
519
|
+
step = 3 * prime3;
|
|
520
|
+
} else {
|
|
521
|
+
step = 3 * prime4;
|
|
522
|
+
}
|
|
523
|
+
i = 0;
|
|
524
|
+
while (i < samplepixels) {
|
|
525
|
+
b = (p[pix + 0] & 0xff) << netbiasshift;
|
|
526
|
+
g = (p[pix + 1] & 0xff) << netbiasshift;
|
|
527
|
+
r = (p[pix + 2] & 0xff) << netbiasshift;
|
|
528
|
+
j = contest(b, g, r);
|
|
529
|
+
altersingle(alpha, j, b, g, r);
|
|
530
|
+
if (rad !== 0) {
|
|
531
|
+
alterneigh(rad, j, b, g, r);
|
|
532
|
+
}
|
|
533
|
+
pix += step;
|
|
534
|
+
if (pix >= lim) {
|
|
535
|
+
pix -= lengthcount;
|
|
536
|
+
}
|
|
537
|
+
i++;
|
|
538
|
+
if (delta === 0) {
|
|
539
|
+
delta = 1;
|
|
540
|
+
}
|
|
541
|
+
if (i % delta === 0) {
|
|
542
|
+
alpha -= alpha / alphadec;
|
|
543
|
+
radius -= radius / radiusdec;
|
|
544
|
+
rad = radius >> radiusbiasshift;
|
|
545
|
+
if (rad <= 1) {
|
|
546
|
+
rad = 0;
|
|
547
|
+
}
|
|
548
|
+
for (j = 0; j < rad; j++) {
|
|
549
|
+
radpower[j] = alpha * ((rad * rad - j * j) * radbias / (rad * rad));
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
function map(b, g, r) {
|
|
555
|
+
var i;
|
|
556
|
+
var j;
|
|
557
|
+
var dist;
|
|
558
|
+
var a;
|
|
559
|
+
var bestd;
|
|
560
|
+
var p;
|
|
561
|
+
var best;
|
|
562
|
+
bestd = 1000;
|
|
563
|
+
best = -1;
|
|
564
|
+
i = netindex[g];
|
|
565
|
+
j = i - 1;
|
|
566
|
+
while (i < netsize || j >= 0) {
|
|
567
|
+
if (i < netsize) {
|
|
568
|
+
p = network[i];
|
|
569
|
+
dist = p[1] - g;
|
|
570
|
+
if (dist >= bestd) {
|
|
571
|
+
i = netsize;
|
|
572
|
+
} else {
|
|
573
|
+
i++;
|
|
574
|
+
if (dist < 0) {
|
|
575
|
+
dist = -dist;
|
|
576
|
+
}
|
|
577
|
+
a = p[0] - b;
|
|
578
|
+
if (a < 0) {
|
|
579
|
+
a = -a;
|
|
580
|
+
}
|
|
581
|
+
dist += a;
|
|
582
|
+
if (dist < bestd) {
|
|
583
|
+
a = p[2] - r;
|
|
584
|
+
if (a < 0) {
|
|
585
|
+
a = -a;
|
|
586
|
+
}
|
|
587
|
+
dist += a;
|
|
588
|
+
if (dist < bestd) {
|
|
589
|
+
bestd = dist;
|
|
590
|
+
best = p[3];
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
if (j >= 0) {
|
|
596
|
+
p = network[j];
|
|
597
|
+
dist = g - p[1];
|
|
598
|
+
if (dist >= bestd) {
|
|
599
|
+
j = -1;
|
|
600
|
+
} else {
|
|
601
|
+
j--;
|
|
602
|
+
if (dist < 0) {
|
|
603
|
+
dist = -dist;
|
|
604
|
+
}
|
|
605
|
+
a = p[0] - b;
|
|
606
|
+
if (a < 0) {
|
|
607
|
+
a = -a;
|
|
608
|
+
}
|
|
609
|
+
dist += a;
|
|
610
|
+
if (dist < bestd) {
|
|
611
|
+
a = p[2] - r;
|
|
612
|
+
if (a < 0) {
|
|
613
|
+
a = -a;
|
|
614
|
+
}
|
|
615
|
+
dist += a;
|
|
616
|
+
if (dist < bestd) {
|
|
617
|
+
bestd = dist;
|
|
618
|
+
best = p[3];
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
return best;
|
|
625
|
+
}
|
|
626
|
+
function process() {
|
|
627
|
+
learn();
|
|
628
|
+
unbiasnet();
|
|
629
|
+
inxbuild();
|
|
630
|
+
return colorMap();
|
|
631
|
+
}
|
|
632
|
+
function unbiasnet() {
|
|
633
|
+
var i;
|
|
634
|
+
var j;
|
|
635
|
+
for (i = 0; i < netsize; i++) {
|
|
636
|
+
network[i][0] >>= netbiasshift;
|
|
637
|
+
network[i][1] >>= netbiasshift;
|
|
638
|
+
network[i][2] >>= netbiasshift;
|
|
639
|
+
network[i][3] = i;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
function alterneigh(rad, i, b, g, r) {
|
|
643
|
+
var j;
|
|
644
|
+
var k;
|
|
645
|
+
var lo;
|
|
646
|
+
var hi;
|
|
647
|
+
var a;
|
|
648
|
+
var m;
|
|
649
|
+
var p;
|
|
650
|
+
lo = i - rad;
|
|
651
|
+
if (lo < -1) {
|
|
652
|
+
lo = -1;
|
|
653
|
+
}
|
|
654
|
+
hi = i + rad;
|
|
655
|
+
if (hi > netsize) {
|
|
656
|
+
hi = netsize;
|
|
657
|
+
}
|
|
658
|
+
j = i + 1;
|
|
659
|
+
k = i - 1;
|
|
660
|
+
m = 1;
|
|
661
|
+
while (j < hi || k > lo) {
|
|
662
|
+
a = radpower[m++];
|
|
663
|
+
if (j < hi) {
|
|
664
|
+
p = network[j++];
|
|
665
|
+
try {
|
|
666
|
+
p[0] -= a * (p[0] - b) / alpharadbias | 0;
|
|
667
|
+
p[1] -= a * (p[1] - g) / alpharadbias | 0;
|
|
668
|
+
p[2] -= a * (p[2] - r) / alpharadbias | 0;
|
|
669
|
+
} catch (e) {}
|
|
670
|
+
}
|
|
671
|
+
if (k > lo) {
|
|
672
|
+
p = network[k--];
|
|
673
|
+
try {
|
|
674
|
+
p[0] -= a * (p[0] - b) / alpharadbias | 0;
|
|
675
|
+
p[1] -= a * (p[1] - g) / alpharadbias | 0;
|
|
676
|
+
p[2] -= a * (p[2] - r) / alpharadbias | 0;
|
|
677
|
+
} catch (e) {}
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
function altersingle(alpha, i, b, g, r) {
|
|
682
|
+
var n = network[i];
|
|
683
|
+
var alphaMult = alpha / initalpha;
|
|
684
|
+
n[0] -= alphaMult * (n[0] - b) | 0;
|
|
685
|
+
n[1] -= alphaMult * (n[1] - g) | 0;
|
|
686
|
+
n[2] -= alphaMult * (n[2] - r) | 0;
|
|
687
|
+
}
|
|
688
|
+
function contest(b, g, r) {
|
|
689
|
+
var i;
|
|
690
|
+
var dist;
|
|
691
|
+
var a;
|
|
692
|
+
var biasdist;
|
|
693
|
+
var betafreq;
|
|
694
|
+
var bestpos;
|
|
695
|
+
var bestbiaspos;
|
|
696
|
+
var bestd;
|
|
697
|
+
var bestbiasd;
|
|
698
|
+
var n;
|
|
699
|
+
bestd = ~(1 << 31);
|
|
700
|
+
bestbiasd = bestd;
|
|
701
|
+
bestpos = -1;
|
|
702
|
+
bestbiaspos = bestpos;
|
|
703
|
+
for (i = 0; i < netsize; i++) {
|
|
704
|
+
n = network[i];
|
|
705
|
+
dist = n[0] - b;
|
|
706
|
+
if (dist < 0) {
|
|
707
|
+
dist = -dist;
|
|
708
|
+
}
|
|
709
|
+
a = n[1] - g;
|
|
710
|
+
if (a < 0) {
|
|
711
|
+
a = -a;
|
|
712
|
+
}
|
|
713
|
+
dist += a;
|
|
714
|
+
a = n[2] - r;
|
|
715
|
+
if (a < 0) {
|
|
716
|
+
a = -a;
|
|
717
|
+
}
|
|
718
|
+
dist += a;
|
|
719
|
+
if (dist < bestd) {
|
|
720
|
+
bestd = dist;
|
|
721
|
+
bestpos = i;
|
|
722
|
+
}
|
|
723
|
+
biasdist = dist - (bias[i] >> intbiasshift - netbiasshift);
|
|
724
|
+
if (biasdist < bestbiasd) {
|
|
725
|
+
bestbiasd = biasdist;
|
|
726
|
+
bestbiaspos = i;
|
|
727
|
+
}
|
|
728
|
+
betafreq = freq[i] >> betashift;
|
|
729
|
+
freq[i] -= betafreq;
|
|
730
|
+
bias[i] += betafreq << gammashift;
|
|
731
|
+
}
|
|
732
|
+
freq[bestpos] += beta;
|
|
733
|
+
bias[bestpos] -= betagamma;
|
|
734
|
+
return bestbiaspos;
|
|
735
|
+
}
|
|
736
|
+
NeuQuantConstructor.apply(this, arguments);
|
|
737
|
+
var exports = {};
|
|
738
|
+
exports.map = map;
|
|
739
|
+
exports.process = process;
|
|
740
|
+
return exports;
|
|
741
|
+
}
|
|
742
|
+
function workerCode() {
|
|
743
|
+
var self = this;
|
|
744
|
+
try {
|
|
745
|
+
globalThis.onmessage = function (ev) {
|
|
746
|
+
var data = ev.data || {};
|
|
747
|
+
var response;
|
|
748
|
+
if (data.gifshot) {
|
|
749
|
+
response = workerMethods.run(data);
|
|
750
|
+
postMessage(response);
|
|
751
|
+
}
|
|
752
|
+
};
|
|
753
|
+
} catch (e) {}
|
|
754
|
+
var workerMethods = {
|
|
755
|
+
dataToRGB: function dataToRGB(data, width, height) {
|
|
756
|
+
var length = width * height * 4;
|
|
757
|
+
var i = 0;
|
|
758
|
+
var rgb = [];
|
|
759
|
+
while (i < length) {
|
|
760
|
+
rgb.push(data[i++]);
|
|
761
|
+
rgb.push(data[i++]);
|
|
762
|
+
rgb.push(data[i++]);
|
|
763
|
+
i++;
|
|
764
|
+
}
|
|
765
|
+
return rgb;
|
|
766
|
+
},
|
|
767
|
+
componentizedPaletteToArray: function componentizedPaletteToArray(paletteRGB) {
|
|
768
|
+
paletteRGB = paletteRGB || [];
|
|
769
|
+
var paletteArray = [];
|
|
770
|
+
for (var i = 0; i < paletteRGB.length; i += 3) {
|
|
771
|
+
var r = paletteRGB[i];
|
|
772
|
+
var g = paletteRGB[i + 1];
|
|
773
|
+
var b = paletteRGB[i + 2];
|
|
774
|
+
paletteArray.push(r << 16 | g << 8 | b);
|
|
775
|
+
}
|
|
776
|
+
return paletteArray;
|
|
777
|
+
},
|
|
778
|
+
processFrameWithQuantizer: function processFrameWithQuantizer(imageData, width, height, sampleInterval) {
|
|
779
|
+
var rgbComponents = this.dataToRGB(imageData, width, height);
|
|
780
|
+
var nq = new NeuQuant(rgbComponents, rgbComponents.length, sampleInterval);
|
|
781
|
+
var paletteRGB = nq.process();
|
|
782
|
+
var paletteArray = new Uint32Array(this.componentizedPaletteToArray(paletteRGB));
|
|
783
|
+
var numberPixels = width * height;
|
|
784
|
+
var indexedPixels = new Uint8Array(numberPixels);
|
|
785
|
+
var k = 0;
|
|
786
|
+
for (var i = 0; i < numberPixels; i++) {
|
|
787
|
+
var r = rgbComponents[k++];
|
|
788
|
+
var g = rgbComponents[k++];
|
|
789
|
+
var b = rgbComponents[k++];
|
|
790
|
+
indexedPixels[i] = nq.map(r, g, b);
|
|
791
|
+
}
|
|
792
|
+
return {
|
|
793
|
+
pixels: indexedPixels,
|
|
794
|
+
palette: paletteArray
|
|
795
|
+
};
|
|
796
|
+
},
|
|
797
|
+
run: function run(frame) {
|
|
798
|
+
frame = frame || {};
|
|
799
|
+
var _frame = frame;
|
|
800
|
+
var height = _frame.height;
|
|
801
|
+
var palette = _frame.palette;
|
|
802
|
+
var sampleInterval = _frame.sampleInterval;
|
|
803
|
+
var width = _frame.width;
|
|
804
|
+
var imageData = frame.data;
|
|
805
|
+
return this.processFrameWithQuantizer(imageData, width, height, sampleInterval);
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
return workerMethods;
|
|
809
|
+
}
|
|
810
|
+
function gifWriter(buf, width, height, gopts) {
|
|
811
|
+
var p = 0;
|
|
812
|
+
gopts = gopts === undefined ? {} : gopts;
|
|
813
|
+
var loop_count = gopts.loop === undefined ? null : gopts.loop;
|
|
814
|
+
var global_palette = gopts.palette === undefined ? null : gopts.palette;
|
|
815
|
+
if (width <= 0 || height <= 0 || width > 65535 || height > 65535) throw 'Width/Height invalid.';
|
|
816
|
+
function check_palette_and_num_colors(palette) {
|
|
817
|
+
var num_colors = palette.length;
|
|
818
|
+
if (num_colors < 2 || num_colors > 256 || num_colors & num_colors - 1) throw 'Invalid code/color length, must be power of 2 and 2 .. 256.';
|
|
819
|
+
return num_colors;
|
|
820
|
+
}
|
|
821
|
+
buf[p++] = 0x47;
|
|
822
|
+
buf[p++] = 0x49;
|
|
823
|
+
buf[p++] = 0x46;
|
|
824
|
+
buf[p++] = 0x38;
|
|
825
|
+
buf[p++] = 0x39;
|
|
826
|
+
buf[p++] = 0x61;
|
|
827
|
+
var gp_num_colors_pow2 = 0;
|
|
828
|
+
var background = 0;
|
|
829
|
+
buf[p++] = width & 0xff;
|
|
830
|
+
buf[p++] = width >> 8 & 0xff;
|
|
831
|
+
buf[p++] = height & 0xff;
|
|
832
|
+
buf[p++] = height >> 8 & 0xff;
|
|
833
|
+
buf[p++] = (global_palette !== null ? 0x80 : 0) | gp_num_colors_pow2;
|
|
834
|
+
buf[p++] = background;
|
|
835
|
+
buf[p++] = 0;
|
|
836
|
+
if (loop_count !== null) {
|
|
837
|
+
if (loop_count < 0 || loop_count > 65535) throw 'Loop count invalid.';
|
|
838
|
+
buf[p++] = 0x21;
|
|
839
|
+
buf[p++] = 0xff;
|
|
840
|
+
buf[p++] = 0x0b;
|
|
841
|
+
buf[p++] = 0x4e;
|
|
842
|
+
buf[p++] = 0x45;
|
|
843
|
+
buf[p++] = 0x54;
|
|
844
|
+
buf[p++] = 0x53;
|
|
845
|
+
buf[p++] = 0x43;
|
|
846
|
+
buf[p++] = 0x41;
|
|
847
|
+
buf[p++] = 0x50;
|
|
848
|
+
buf[p++] = 0x45;
|
|
849
|
+
buf[p++] = 0x32;
|
|
850
|
+
buf[p++] = 0x2e;
|
|
851
|
+
buf[p++] = 0x30;
|
|
852
|
+
buf[p++] = 0x03;
|
|
853
|
+
buf[p++] = 0x01;
|
|
854
|
+
buf[p++] = loop_count & 0xff;
|
|
855
|
+
buf[p++] = loop_count >> 8 & 0xff;
|
|
856
|
+
buf[p++] = 0x00;
|
|
857
|
+
}
|
|
858
|
+
var ended = false;
|
|
859
|
+
this.addFrame = function (x, y, w, h, indexed_pixels, opts) {
|
|
860
|
+
if (ended === true) {
|
|
861
|
+
--p;
|
|
862
|
+
ended = false;
|
|
863
|
+
}
|
|
864
|
+
opts = opts === undefined ? {} : opts;
|
|
865
|
+
if (x < 0 || y < 0 || x > 65535 || y > 65535) throw 'x/y invalid.';
|
|
866
|
+
if (w <= 0 || h <= 0 || w > 65535 || h > 65535) throw 'Width/Height invalid.';
|
|
867
|
+
if (indexed_pixels.length < w * h) throw 'Not enough pixels for the frame size.';
|
|
868
|
+
var using_local_palette = true;
|
|
869
|
+
var palette = opts.palette;
|
|
870
|
+
if (palette === undefined || palette === null) {
|
|
871
|
+
using_local_palette = false;
|
|
872
|
+
palette = global_palette;
|
|
873
|
+
}
|
|
874
|
+
if (palette === undefined || palette === null) throw 'Must supply either a local or global palette.';
|
|
875
|
+
var num_colors = check_palette_and_num_colors(palette);
|
|
876
|
+
var min_code_size = 0;
|
|
877
|
+
while (num_colors >>= 1) {
|
|
878
|
+
++min_code_size;
|
|
879
|
+
}
|
|
880
|
+
num_colors = 1 << min_code_size;
|
|
881
|
+
var delay = opts.delay === undefined ? 0 : opts.delay;
|
|
882
|
+
var disposal = opts.disposal === undefined ? 0 : opts.disposal;
|
|
883
|
+
if (disposal < 0 || disposal > 3) throw 'Disposal out of range.';
|
|
884
|
+
var use_transparency = false;
|
|
885
|
+
var transparent_index = 0;
|
|
886
|
+
if (opts.transparent !== undefined && opts.transparent !== null) {
|
|
887
|
+
use_transparency = true;
|
|
888
|
+
transparent_index = opts.transparent;
|
|
889
|
+
if (transparent_index < 0 || transparent_index >= num_colors) throw 'Transparent color index.';
|
|
890
|
+
}
|
|
891
|
+
if (disposal !== 0 || use_transparency || delay !== 0) {
|
|
892
|
+
buf[p++] = 0x21;
|
|
893
|
+
buf[p++] = 0xf9;
|
|
894
|
+
buf[p++] = 4;
|
|
895
|
+
buf[p++] = disposal << 2 | (use_transparency === true ? 1 : 0);
|
|
896
|
+
buf[p++] = delay & 0xff;
|
|
897
|
+
buf[p++] = delay >> 8 & 0xff;
|
|
898
|
+
buf[p++] = transparent_index;
|
|
899
|
+
buf[p++] = 0;
|
|
900
|
+
}
|
|
901
|
+
buf[p++] = 0x2c;
|
|
902
|
+
buf[p++] = x & 0xff;
|
|
903
|
+
buf[p++] = x >> 8 & 0xff;
|
|
904
|
+
buf[p++] = y & 0xff;
|
|
905
|
+
buf[p++] = y >> 8 & 0xff;
|
|
906
|
+
buf[p++] = w & 0xff;
|
|
907
|
+
buf[p++] = w >> 8 & 0xff;
|
|
908
|
+
buf[p++] = h & 0xff;
|
|
909
|
+
buf[p++] = h >> 8 & 0xff;
|
|
910
|
+
buf[p++] = using_local_palette === true ? 0x80 | min_code_size - 1 : 0;
|
|
911
|
+
if (using_local_palette === true) {
|
|
912
|
+
for (var i = 0, il = palette.length; i < il; ++i) {
|
|
913
|
+
var rgb = palette[i];
|
|
914
|
+
buf[p++] = rgb >> 16 & 0xff;
|
|
915
|
+
buf[p++] = rgb >> 8 & 0xff;
|
|
916
|
+
buf[p++] = rgb & 0xff;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
p = GifWriterOutputLZWCodeStream(buf, p, min_code_size < 2 ? 2 : min_code_size, indexed_pixels);
|
|
920
|
+
};
|
|
921
|
+
this.end = function () {
|
|
922
|
+
if (ended === false) {
|
|
923
|
+
buf[p++] = 0x3b;
|
|
924
|
+
ended = true;
|
|
925
|
+
}
|
|
926
|
+
return p;
|
|
927
|
+
};
|
|
928
|
+
function GifWriterOutputLZWCodeStream(buf, p, min_code_size, index_stream) {
|
|
929
|
+
buf[p++] = min_code_size;
|
|
930
|
+
var cur_subblock = p++;
|
|
931
|
+
var clear_code = 1 << min_code_size;
|
|
932
|
+
var code_mask = clear_code - 1;
|
|
933
|
+
var eoi_code = clear_code + 1;
|
|
934
|
+
var next_code = eoi_code + 1;
|
|
935
|
+
var cur_code_size = min_code_size + 1;
|
|
936
|
+
var cur_shift = 0;
|
|
937
|
+
var cur = 0;
|
|
938
|
+
function emit_bytes_to_buffer(bit_block_size) {
|
|
939
|
+
while (cur_shift >= bit_block_size) {
|
|
940
|
+
buf[p++] = cur & 0xff;
|
|
941
|
+
cur >>= 8;
|
|
942
|
+
cur_shift -= 8;
|
|
943
|
+
if (p === cur_subblock + 256) {
|
|
944
|
+
buf[cur_subblock] = 255;
|
|
945
|
+
cur_subblock = p++;
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
function emit_code(c) {
|
|
950
|
+
cur |= c << cur_shift;
|
|
951
|
+
cur_shift += cur_code_size;
|
|
952
|
+
emit_bytes_to_buffer(8);
|
|
953
|
+
}
|
|
954
|
+
var ib_code = index_stream[0] & code_mask;
|
|
955
|
+
var code_table = {};
|
|
956
|
+
emit_code(clear_code);
|
|
957
|
+
for (var i = 1, il = index_stream.length; i < il; ++i) {
|
|
958
|
+
var k = index_stream[i] & code_mask;
|
|
959
|
+
var cur_key = ib_code << 8 | k;
|
|
960
|
+
var cur_code = code_table[cur_key];
|
|
961
|
+
if (cur_code === undefined) {
|
|
962
|
+
cur |= ib_code << cur_shift;
|
|
963
|
+
cur_shift += cur_code_size;
|
|
964
|
+
while (cur_shift >= 8) {
|
|
965
|
+
buf[p++] = cur & 0xff;
|
|
966
|
+
cur >>= 8;
|
|
967
|
+
cur_shift -= 8;
|
|
968
|
+
if (p === cur_subblock + 256) {
|
|
969
|
+
buf[cur_subblock] = 255;
|
|
970
|
+
cur_subblock = p++;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
if (next_code === 4096) {
|
|
974
|
+
emit_code(clear_code);
|
|
975
|
+
next_code = eoi_code + 1;
|
|
976
|
+
cur_code_size = min_code_size + 1;
|
|
977
|
+
code_table = {};
|
|
978
|
+
} else {
|
|
979
|
+
if (next_code >= 1 << cur_code_size) ++cur_code_size;
|
|
980
|
+
code_table[cur_key] = next_code++;
|
|
981
|
+
}
|
|
982
|
+
ib_code = k;
|
|
983
|
+
} else {
|
|
984
|
+
ib_code = cur_code;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
emit_code(ib_code);
|
|
988
|
+
emit_code(eoi_code);
|
|
989
|
+
emit_bytes_to_buffer(1);
|
|
990
|
+
if (cur_subblock + 1 === p) {
|
|
991
|
+
buf[cur_subblock] = 0;
|
|
992
|
+
} else {
|
|
993
|
+
buf[cur_subblock] = p - cur_subblock - 1;
|
|
994
|
+
buf[p++] = 0;
|
|
995
|
+
}
|
|
996
|
+
return p;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
var noop$2 = function noop() {};
|
|
1000
|
+
var AnimatedGIF = function AnimatedGIF(options) {
|
|
1001
|
+
this.canvas = null;
|
|
1002
|
+
this.ctx = null;
|
|
1003
|
+
this.repeat = 0;
|
|
1004
|
+
this.frames = [];
|
|
1005
|
+
this.numRenderedFrames = 0;
|
|
1006
|
+
this.onRenderCompleteCallback = noop$2;
|
|
1007
|
+
this.onRenderProgressCallback = noop$2;
|
|
1008
|
+
this.workers = [];
|
|
1009
|
+
this.availableWorkers = [];
|
|
1010
|
+
this.generatingGIF = false;
|
|
1011
|
+
this.options = options;
|
|
1012
|
+
this.initializeWebWorkers(options);
|
|
1013
|
+
};
|
|
1014
|
+
AnimatedGIF.prototype = {
|
|
1015
|
+
workerMethods: workerCode(),
|
|
1016
|
+
initializeWebWorkers: function initializeWebWorkers(options) {
|
|
1017
|
+
var self = this;
|
|
1018
|
+
var processFrameWorkerCode = "".concat(NeuQuant.toString(), "(").concat(workerCode.toString(), "());");
|
|
1019
|
+
var webWorkerObj = void 0;
|
|
1020
|
+
var objectUrl = void 0;
|
|
1021
|
+
var webWorker = void 0;
|
|
1022
|
+
var numWorkers = void 0;
|
|
1023
|
+
var x = -1;
|
|
1024
|
+
var workerError = '';
|
|
1025
|
+
numWorkers = options.numWorkers;
|
|
1026
|
+
while (++x < numWorkers) {
|
|
1027
|
+
webWorkerObj = utils.createWebWorker(processFrameWorkerCode);
|
|
1028
|
+
if (utils.isObject(webWorkerObj)) {
|
|
1029
|
+
objectUrl = webWorkerObj.objectUrl;
|
|
1030
|
+
webWorker = webWorkerObj.worker;
|
|
1031
|
+
self.workers.push({
|
|
1032
|
+
worker: webWorker,
|
|
1033
|
+
objectUrl: objectUrl
|
|
1034
|
+
});
|
|
1035
|
+
self.availableWorkers.push(webWorker);
|
|
1036
|
+
} else {
|
|
1037
|
+
workerError = webWorkerObj;
|
|
1038
|
+
utils.webWorkerError = Boolean(webWorkerObj);
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
this.workerError = workerError;
|
|
1042
|
+
this.canvas = document.createElement('canvas');
|
|
1043
|
+
this.canvas.width = options.gifWidth;
|
|
1044
|
+
this.canvas.height = options.gifHeight;
|
|
1045
|
+
this.ctx = this.canvas.getContext('2d');
|
|
1046
|
+
this.frames = [];
|
|
1047
|
+
},
|
|
1048
|
+
getWorker: function getWorker() {
|
|
1049
|
+
return this.availableWorkers.pop();
|
|
1050
|
+
},
|
|
1051
|
+
freeWorker: function freeWorker(worker) {
|
|
1052
|
+
this.availableWorkers.push(worker);
|
|
1053
|
+
},
|
|
1054
|
+
byteMap: function () {
|
|
1055
|
+
var byteMap = [];
|
|
1056
|
+
for (var i = 0; i < 256; i++) {
|
|
1057
|
+
byteMap[i] = String.fromCharCode(i);
|
|
1058
|
+
}
|
|
1059
|
+
return byteMap;
|
|
1060
|
+
}(),
|
|
1061
|
+
bufferToString: function bufferToString(buffer) {
|
|
1062
|
+
var numberValues = buffer.length;
|
|
1063
|
+
var str = '';
|
|
1064
|
+
var x = -1;
|
|
1065
|
+
while (++x < numberValues) {
|
|
1066
|
+
str += this.byteMap[buffer[x]];
|
|
1067
|
+
}
|
|
1068
|
+
return str;
|
|
1069
|
+
},
|
|
1070
|
+
onFrameFinished: function onFrameFinished(progressCallback) {
|
|
1071
|
+
var self = this;
|
|
1072
|
+
var frames = self.frames;
|
|
1073
|
+
var options = self.options;
|
|
1074
|
+
var hasExistingImages = Boolean((options.images || []).length);
|
|
1075
|
+
var allDone = frames.every(function (frame) {
|
|
1076
|
+
return !frame.beingProcessed && frame.done;
|
|
1077
|
+
});
|
|
1078
|
+
self.numRenderedFrames++;
|
|
1079
|
+
if (hasExistingImages) {
|
|
1080
|
+
progressCallback(self.numRenderedFrames / frames.length);
|
|
1081
|
+
}
|
|
1082
|
+
self.onRenderProgressCallback(self.numRenderedFrames * 0.75 / frames.length);
|
|
1083
|
+
if (allDone) {
|
|
1084
|
+
if (!self.generatingGIF) {
|
|
1085
|
+
self.generateGIF(frames, self.onRenderCompleteCallback);
|
|
1086
|
+
}
|
|
1087
|
+
} else {
|
|
1088
|
+
utils.requestTimeout(function () {
|
|
1089
|
+
self.processNextFrame();
|
|
1090
|
+
}, 1);
|
|
1091
|
+
}
|
|
1092
|
+
},
|
|
1093
|
+
processFrame: function processFrame(position) {
|
|
1094
|
+
var AnimatedGifContext = this;
|
|
1095
|
+
var options = this.options;
|
|
1096
|
+
var _options = this.options;
|
|
1097
|
+
var progressCallback = _options.progressCallback;
|
|
1098
|
+
var sampleInterval = _options.sampleInterval;
|
|
1099
|
+
var frames = this.frames;
|
|
1100
|
+
var frame = void 0;
|
|
1101
|
+
var worker = void 0;
|
|
1102
|
+
var done = function done() {
|
|
1103
|
+
var ev = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1104
|
+
var data = ev.data;
|
|
1105
|
+
delete frame.data;
|
|
1106
|
+
frame.pixels = Array.prototype.slice.call(data.pixels);
|
|
1107
|
+
frame.palette = Array.prototype.slice.call(data.palette);
|
|
1108
|
+
frame.done = true;
|
|
1109
|
+
frame.beingProcessed = false;
|
|
1110
|
+
AnimatedGifContext.freeWorker(worker);
|
|
1111
|
+
AnimatedGifContext.onFrameFinished(progressCallback);
|
|
1112
|
+
};
|
|
1113
|
+
frame = frames[position];
|
|
1114
|
+
if (frame.beingProcessed || frame.done) {
|
|
1115
|
+
this.onFrameFinished();
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1118
|
+
frame.sampleInterval = sampleInterval;
|
|
1119
|
+
frame.beingProcessed = true;
|
|
1120
|
+
frame.gifshot = true;
|
|
1121
|
+
worker = this.getWorker();
|
|
1122
|
+
if (worker) {
|
|
1123
|
+
worker.onmessage = done;
|
|
1124
|
+
worker.postMessage(frame);
|
|
1125
|
+
} else {
|
|
1126
|
+
done({
|
|
1127
|
+
data: AnimatedGifContext.workerMethods.run(frame)
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
},
|
|
1131
|
+
startRendering: function startRendering(completeCallback) {
|
|
1132
|
+
this.onRenderCompleteCallback = completeCallback;
|
|
1133
|
+
for (var i = 0; i < this.options.numWorkers && i < this.frames.length; i++) {
|
|
1134
|
+
this.processFrame(i);
|
|
1135
|
+
}
|
|
1136
|
+
},
|
|
1137
|
+
processNextFrame: function processNextFrame() {
|
|
1138
|
+
var position = -1;
|
|
1139
|
+
for (var i = 0; i < this.frames.length; i++) {
|
|
1140
|
+
var frame = this.frames[i];
|
|
1141
|
+
if (!frame.done && !frame.beingProcessed) {
|
|
1142
|
+
position = i;
|
|
1143
|
+
break;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
if (position >= 0) {
|
|
1147
|
+
this.processFrame(position);
|
|
1148
|
+
}
|
|
1149
|
+
},
|
|
1150
|
+
generateGIF: function generateGIF(frames, callback) {
|
|
1151
|
+
var buffer = [];
|
|
1152
|
+
var gifOptions = {
|
|
1153
|
+
loop: this.repeat
|
|
1154
|
+
};
|
|
1155
|
+
var options = this.options;
|
|
1156
|
+
var interval = options.interval;
|
|
1157
|
+
var frameDuration = options.frameDuration;
|
|
1158
|
+
var existingImages = options.images;
|
|
1159
|
+
var hasExistingImages = Boolean(existingImages.length);
|
|
1160
|
+
var height = options.gifHeight;
|
|
1161
|
+
var width = options.gifWidth;
|
|
1162
|
+
var gifWriter$$1 = new gifWriter(buffer, width, height, gifOptions);
|
|
1163
|
+
var onRenderProgressCallback = this.onRenderProgressCallback;
|
|
1164
|
+
var delay = hasExistingImages ? interval * 100 : 0;
|
|
1165
|
+
var bufferToString = void 0;
|
|
1166
|
+
var gif = void 0;
|
|
1167
|
+
this.generatingGIF = true;
|
|
1168
|
+
utils.each(frames, function (iterator, frame) {
|
|
1169
|
+
var framePalette = frame.palette;
|
|
1170
|
+
onRenderProgressCallback(0.75 + 0.25 * frame.position * 1.0 / frames.length);
|
|
1171
|
+
for (var i = 0; i < frameDuration; i++) {
|
|
1172
|
+
gifWriter$$1.addFrame(0, 0, width, height, frame.pixels, {
|
|
1173
|
+
palette: framePalette,
|
|
1174
|
+
delay: delay
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
});
|
|
1178
|
+
gifWriter$$1.end();
|
|
1179
|
+
onRenderProgressCallback(1.0);
|
|
1180
|
+
this.frames = [];
|
|
1181
|
+
this.generatingGIF = false;
|
|
1182
|
+
if (utils.isFunction(callback)) {
|
|
1183
|
+
bufferToString = this.bufferToString(buffer);
|
|
1184
|
+
gif = "data:image/gif;base64,".concat(utils.btoa(bufferToString));
|
|
1185
|
+
callback(gif);
|
|
1186
|
+
}
|
|
1187
|
+
},
|
|
1188
|
+
setRepeat: function setRepeat(r) {
|
|
1189
|
+
this.repeat = r;
|
|
1190
|
+
},
|
|
1191
|
+
addFrame: function addFrame(element, gifshotOptions) {
|
|
1192
|
+
gifshotOptions = utils.isObject(gifshotOptions) ? gifshotOptions : {};
|
|
1193
|
+
var self = this;
|
|
1194
|
+
var ctx = self.ctx;
|
|
1195
|
+
var options = self.options;
|
|
1196
|
+
var width = options.gifWidth;
|
|
1197
|
+
var height = options.gifHeight;
|
|
1198
|
+
var fontSize = utils.getFontSize(gifshotOptions);
|
|
1199
|
+
var _gifshotOptions = gifshotOptions;
|
|
1200
|
+
var filter = _gifshotOptions.filter;
|
|
1201
|
+
var fontColor = _gifshotOptions.fontColor;
|
|
1202
|
+
var fontFamily = _gifshotOptions.fontFamily;
|
|
1203
|
+
var fontWeight = _gifshotOptions.fontWeight;
|
|
1204
|
+
var gifHeight = _gifshotOptions.gifHeight;
|
|
1205
|
+
var gifWidth = _gifshotOptions.gifWidth;
|
|
1206
|
+
var text = _gifshotOptions.text;
|
|
1207
|
+
var textAlign = _gifshotOptions.textAlign;
|
|
1208
|
+
var textBaseline = _gifshotOptions.textBaseline;
|
|
1209
|
+
var textXCoordinate = gifshotOptions.textXCoordinate ? gifshotOptions.textXCoordinate : textAlign === 'left' ? 1 : textAlign === 'right' ? width : width / 2;
|
|
1210
|
+
var textYCoordinate = gifshotOptions.textYCoordinate ? gifshotOptions.textYCoordinate : textBaseline === 'top' ? 1 : textBaseline === 'center' ? height / 2 : height;
|
|
1211
|
+
var font = "".concat(fontWeight, " ").concat(fontSize, " ").concat(fontFamily);
|
|
1212
|
+
var imageData = void 0;
|
|
1213
|
+
try {
|
|
1214
|
+
ctx.filter = filter;
|
|
1215
|
+
ctx.drawImage(element, 0, 0, width, height);
|
|
1216
|
+
if (text) {
|
|
1217
|
+
ctx.font = font;
|
|
1218
|
+
ctx.fillStyle = fontColor;
|
|
1219
|
+
ctx.textAlign = textAlign;
|
|
1220
|
+
ctx.textBaseline = textBaseline;
|
|
1221
|
+
ctx.fillText(text, textXCoordinate, textYCoordinate);
|
|
1222
|
+
}
|
|
1223
|
+
imageData = ctx.getImageData(0, 0, width, height);
|
|
1224
|
+
self.addFrameImageData(imageData);
|
|
1225
|
+
} catch (e) {
|
|
1226
|
+
return "".concat(e);
|
|
1227
|
+
}
|
|
1228
|
+
},
|
|
1229
|
+
addFrameImageData: function addFrameImageData() {
|
|
1230
|
+
var imageData = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1231
|
+
var frames = this.frames;
|
|
1232
|
+
var imageDataArray = imageData.data;
|
|
1233
|
+
this.frames.push({
|
|
1234
|
+
data: imageDataArray,
|
|
1235
|
+
width: imageData.width,
|
|
1236
|
+
height: imageData.height,
|
|
1237
|
+
palette: null,
|
|
1238
|
+
dithering: null,
|
|
1239
|
+
done: false,
|
|
1240
|
+
beingProcessed: false,
|
|
1241
|
+
position: frames.length
|
|
1242
|
+
});
|
|
1243
|
+
},
|
|
1244
|
+
onRenderProgress: function onRenderProgress(callback) {
|
|
1245
|
+
this.onRenderProgressCallback = callback;
|
|
1246
|
+
},
|
|
1247
|
+
isRendering: function isRendering() {
|
|
1248
|
+
return this.generatingGIF;
|
|
1249
|
+
},
|
|
1250
|
+
getBase64GIF: function getBase64GIF(completeCallback) {
|
|
1251
|
+
var self = this;
|
|
1252
|
+
var onRenderComplete = function onRenderComplete(gif) {
|
|
1253
|
+
self.destroyWorkers();
|
|
1254
|
+
utils.requestTimeout(function () {
|
|
1255
|
+
completeCallback(gif);
|
|
1256
|
+
}, 0);
|
|
1257
|
+
};
|
|
1258
|
+
self.startRendering(onRenderComplete);
|
|
1259
|
+
},
|
|
1260
|
+
destroyWorkers: function destroyWorkers() {
|
|
1261
|
+
if (this.workerError) {
|
|
1262
|
+
return;
|
|
1263
|
+
}
|
|
1264
|
+
var workers = this.workers;
|
|
1265
|
+
utils.each(workers, function (iterator, workerObj) {
|
|
1266
|
+
var worker = workerObj.worker;
|
|
1267
|
+
var objectUrl = workerObj.objectUrl;
|
|
1268
|
+
worker.terminate();
|
|
1269
|
+
utils.URL.revokeObjectURL(objectUrl);
|
|
1270
|
+
});
|
|
1271
|
+
}
|
|
1272
|
+
};
|
|
1273
|
+
function getBase64GIF(animatedGifInstance, callback) {
|
|
1274
|
+
animatedGifInstance.getBase64GIF(function (image) {
|
|
1275
|
+
callback({
|
|
1276
|
+
error: false,
|
|
1277
|
+
errorCode: '',
|
|
1278
|
+
errorMsg: '',
|
|
1279
|
+
image: image
|
|
1280
|
+
});
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
1283
|
+
function existingImages() {
|
|
1284
|
+
var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1285
|
+
var self = this;
|
|
1286
|
+
var callback = obj.callback;
|
|
1287
|
+
var images = obj.images;
|
|
1288
|
+
var options = obj.options;
|
|
1289
|
+
var imagesLength = obj.imagesLength;
|
|
1290
|
+
var skipObj = {
|
|
1291
|
+
getUserMedia: true,
|
|
1292
|
+
'globalThis.URL': true
|
|
1293
|
+
};
|
|
1294
|
+
var errorObj = error.validate(skipObj);
|
|
1295
|
+
var loadedImages = [];
|
|
1296
|
+
var loadedImagesLength = 0;
|
|
1297
|
+
var tempImage = void 0;
|
|
1298
|
+
var ag = void 0;
|
|
1299
|
+
if (errorObj.error) {
|
|
1300
|
+
return callback(errorObj);
|
|
1301
|
+
}
|
|
1302
|
+
ag = new AnimatedGIF(options);
|
|
1303
|
+
utils.each(images, function (index, image) {
|
|
1304
|
+
var currentImage = image;
|
|
1305
|
+
if (utils.isElement(currentImage)) {
|
|
1306
|
+
if (options.crossOrigin) {
|
|
1307
|
+
currentImage.crossOrigin = options.crossOrigin;
|
|
1308
|
+
}
|
|
1309
|
+
loadedImages[index] = currentImage;
|
|
1310
|
+
loadedImagesLength += 1;
|
|
1311
|
+
if (loadedImagesLength === imagesLength) {
|
|
1312
|
+
addLoadedImagesToGif();
|
|
1313
|
+
}
|
|
1314
|
+
} else if (utils.isString(currentImage)) {
|
|
1315
|
+
tempImage = new Image();
|
|
1316
|
+
if (options.crossOrigin) {
|
|
1317
|
+
tempImage.crossOrigin = options.crossOrigin;
|
|
1318
|
+
}
|
|
1319
|
+
(function (tempImage) {
|
|
1320
|
+
if (image.text) {
|
|
1321
|
+
tempImage.text = image.text;
|
|
1322
|
+
}
|
|
1323
|
+
tempImage.onerror = function (e) {
|
|
1324
|
+
var obj = void 0;
|
|
1325
|
+
--imagesLength;
|
|
1326
|
+
if (imagesLength === 0) {
|
|
1327
|
+
obj = {};
|
|
1328
|
+
obj.error = 'None of the requested images was capable of being retrieved';
|
|
1329
|
+
return callback(obj);
|
|
1330
|
+
}
|
|
1331
|
+
};
|
|
1332
|
+
tempImage.onload = function (e) {
|
|
1333
|
+
if (image.text) {
|
|
1334
|
+
loadedImages[index] = {
|
|
1335
|
+
img: tempImage,
|
|
1336
|
+
text: tempImage.text
|
|
1337
|
+
};
|
|
1338
|
+
} else {
|
|
1339
|
+
loadedImages[index] = tempImage;
|
|
1340
|
+
}
|
|
1341
|
+
loadedImagesLength += 1;
|
|
1342
|
+
if (loadedImagesLength === imagesLength) {
|
|
1343
|
+
addLoadedImagesToGif();
|
|
1344
|
+
}
|
|
1345
|
+
utils.removeElement(tempImage);
|
|
1346
|
+
};
|
|
1347
|
+
tempImage.src = currentImage;
|
|
1348
|
+
})(tempImage);
|
|
1349
|
+
utils.setCSSAttr(tempImage, {
|
|
1350
|
+
position: 'fixed',
|
|
1351
|
+
opacity: '0'
|
|
1352
|
+
});
|
|
1353
|
+
document.body.appendChild(tempImage);
|
|
1354
|
+
}
|
|
1355
|
+
});
|
|
1356
|
+
function addLoadedImagesToGif() {
|
|
1357
|
+
utils.each(loadedImages, function (index, loadedImage) {
|
|
1358
|
+
if (loadedImage) {
|
|
1359
|
+
if (loadedImage.text) {
|
|
1360
|
+
ag.addFrame(loadedImage.img, options, loadedImage.text);
|
|
1361
|
+
} else {
|
|
1362
|
+
ag.addFrame(loadedImage, options);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
});
|
|
1366
|
+
getBase64GIF(ag, callback);
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
var noop$3 = function noop() {};
|
|
1370
|
+
var screenShot = {
|
|
1371
|
+
getGIF: function getGIF() {
|
|
1372
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1373
|
+
var callback = arguments[1];
|
|
1374
|
+
callback = utils.isFunction(callback) ? callback : noop$3;
|
|
1375
|
+
var canvas = document.createElement('canvas');
|
|
1376
|
+
var context = void 0;
|
|
1377
|
+
var existingImages = options.images;
|
|
1378
|
+
var hasExistingImages = Boolean(existingImages.length);
|
|
1379
|
+
var cameraStream = options.cameraStream;
|
|
1380
|
+
var crop = options.crop;
|
|
1381
|
+
var filter = options.filter;
|
|
1382
|
+
var fontColor = options.fontColor;
|
|
1383
|
+
var fontFamily = options.fontFamily;
|
|
1384
|
+
var fontWeight = options.fontWeight;
|
|
1385
|
+
var keepCameraOn = options.keepCameraOn;
|
|
1386
|
+
var numWorkers = options.numWorkers;
|
|
1387
|
+
var progressCallback = options.progressCallback;
|
|
1388
|
+
var saveRenderingContexts = options.saveRenderingContexts;
|
|
1389
|
+
var savedRenderingContexts = options.savedRenderingContexts;
|
|
1390
|
+
var text = options.text;
|
|
1391
|
+
var textAlign = options.textAlign;
|
|
1392
|
+
var textBaseline = options.textBaseline;
|
|
1393
|
+
var videoElement = options.videoElement;
|
|
1394
|
+
var videoHeight = options.videoHeight;
|
|
1395
|
+
var videoWidth = options.videoWidth;
|
|
1396
|
+
var webcamVideoElement = options.webcamVideoElement;
|
|
1397
|
+
var gifWidth = Number(options.gifWidth);
|
|
1398
|
+
var gifHeight = Number(options.gifHeight);
|
|
1399
|
+
var interval = Number(options.interval);
|
|
1400
|
+
var sampleInterval = Number(options.sampleInterval);
|
|
1401
|
+
var waitBetweenFrames = hasExistingImages ? 0 : interval * 1000;
|
|
1402
|
+
var renderingContextsToSave = [];
|
|
1403
|
+
var numFrames = savedRenderingContexts.length ? savedRenderingContexts.length : options.numFrames;
|
|
1404
|
+
var pendingFrames = numFrames;
|
|
1405
|
+
var ag = new AnimatedGIF(options);
|
|
1406
|
+
var fontSize = utils.getFontSize(options);
|
|
1407
|
+
var textXCoordinate = options.textXCoordinate ? options.textXCoordinate : textAlign === 'left' ? 1 : textAlign === 'right' ? gifWidth : gifWidth / 2;
|
|
1408
|
+
var textYCoordinate = options.textYCoordinate ? options.textYCoordinate : textBaseline === 'top' ? 1 : textBaseline === 'center' ? gifHeight / 2 : gifHeight;
|
|
1409
|
+
var font = "".concat(fontWeight, " ").concat(fontSize, " ").concat(fontFamily);
|
|
1410
|
+
var sourceX = crop ? Math.floor(crop.scaledWidth / 2) : 0;
|
|
1411
|
+
var sourceWidth = crop ? videoWidth - crop.scaledWidth : 0;
|
|
1412
|
+
var sourceY = crop ? Math.floor(crop.scaledHeight / 2) : 0;
|
|
1413
|
+
var sourceHeight = crop ? videoHeight - crop.scaledHeight : 0;
|
|
1414
|
+
var captureFrames = function captureSingleFrame() {
|
|
1415
|
+
var framesLeft = pendingFrames - 1;
|
|
1416
|
+
if (savedRenderingContexts.length) {
|
|
1417
|
+
context.putImageData(savedRenderingContexts[numFrames - pendingFrames], 0, 0);
|
|
1418
|
+
finishCapture();
|
|
1419
|
+
} else {
|
|
1420
|
+
drawVideo();
|
|
1421
|
+
}
|
|
1422
|
+
function drawVideo() {
|
|
1423
|
+
try {
|
|
1424
|
+
if (sourceWidth > videoWidth) {
|
|
1425
|
+
sourceWidth = videoWidth;
|
|
1426
|
+
}
|
|
1427
|
+
if (sourceHeight > videoHeight) {
|
|
1428
|
+
sourceHeight = videoHeight;
|
|
1429
|
+
}
|
|
1430
|
+
if (sourceX < 0) {
|
|
1431
|
+
sourceX = 0;
|
|
1432
|
+
}
|
|
1433
|
+
if (sourceY < 0) {
|
|
1434
|
+
sourceY = 0;
|
|
1435
|
+
}
|
|
1436
|
+
context.filter = filter;
|
|
1437
|
+
context.drawImage(videoElement, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, gifWidth, gifHeight);
|
|
1438
|
+
finishCapture();
|
|
1439
|
+
} catch (e) {
|
|
1440
|
+
if (e.name === 'NS_ERROR_NOT_AVAILABLE') {
|
|
1441
|
+
utils.requestTimeout(drawVideo, 100);
|
|
1442
|
+
} else {
|
|
1443
|
+
throw e;
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
function finishCapture() {
|
|
1448
|
+
var imageData = void 0;
|
|
1449
|
+
if (saveRenderingContexts) {
|
|
1450
|
+
renderingContextsToSave.push(context.getImageData(0, 0, gifWidth, gifHeight));
|
|
1451
|
+
}
|
|
1452
|
+
if (text) {
|
|
1453
|
+
context.font = font;
|
|
1454
|
+
context.fillStyle = fontColor;
|
|
1455
|
+
context.textAlign = textAlign;
|
|
1456
|
+
context.textBaseline = textBaseline;
|
|
1457
|
+
context.fillText(text, textXCoordinate, textYCoordinate);
|
|
1458
|
+
}
|
|
1459
|
+
imageData = context.getImageData(0, 0, gifWidth, gifHeight);
|
|
1460
|
+
ag.addFrameImageData(imageData);
|
|
1461
|
+
pendingFrames = framesLeft;
|
|
1462
|
+
progressCallback((numFrames - pendingFrames) / numFrames);
|
|
1463
|
+
if (framesLeft > 0) {
|
|
1464
|
+
utils.requestTimeout(captureSingleFrame, waitBetweenFrames);
|
|
1465
|
+
}
|
|
1466
|
+
if (!pendingFrames) {
|
|
1467
|
+
ag.getBase64GIF(function (image) {
|
|
1468
|
+
callback({
|
|
1469
|
+
error: false,
|
|
1470
|
+
errorCode: '',
|
|
1471
|
+
errorMsg: '',
|
|
1472
|
+
image: image,
|
|
1473
|
+
cameraStream: cameraStream,
|
|
1474
|
+
videoElement: videoElement,
|
|
1475
|
+
webcamVideoElement: webcamVideoElement,
|
|
1476
|
+
savedRenderingContexts: renderingContextsToSave,
|
|
1477
|
+
keepCameraOn: keepCameraOn
|
|
1478
|
+
});
|
|
1479
|
+
});
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
};
|
|
1483
|
+
numFrames = numFrames !== undefined ? numFrames : 10;
|
|
1484
|
+
interval = interval !== undefined ? interval : 0.1;
|
|
1485
|
+
canvas.width = gifWidth;
|
|
1486
|
+
canvas.height = gifHeight;
|
|
1487
|
+
context = canvas.getContext('2d');
|
|
1488
|
+
(function capture() {
|
|
1489
|
+
if (!savedRenderingContexts.length && videoElement.currentTime === 0) {
|
|
1490
|
+
utils.requestTimeout(capture, 100);
|
|
1491
|
+
return;
|
|
1492
|
+
}
|
|
1493
|
+
captureFrames();
|
|
1494
|
+
})();
|
|
1495
|
+
},
|
|
1496
|
+
getCropDimensions: function getCropDimensions() {
|
|
1497
|
+
var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1498
|
+
var width = obj.videoWidth;
|
|
1499
|
+
var height = obj.videoHeight;
|
|
1500
|
+
var gifWidth = obj.gifWidth;
|
|
1501
|
+
var gifHeight = obj.gifHeight;
|
|
1502
|
+
var result = {
|
|
1503
|
+
width: 0,
|
|
1504
|
+
height: 0,
|
|
1505
|
+
scaledWidth: 0,
|
|
1506
|
+
scaledHeight: 0
|
|
1507
|
+
};
|
|
1508
|
+
if (width > height) {
|
|
1509
|
+
result.width = Math.round(width * (gifHeight / height)) - gifWidth;
|
|
1510
|
+
result.scaledWidth = Math.round(result.width * (height / gifHeight));
|
|
1511
|
+
} else {
|
|
1512
|
+
result.height = Math.round(height * (gifWidth / width)) - gifHeight;
|
|
1513
|
+
result.scaledHeight = Math.round(result.height * (width / gifWidth));
|
|
1514
|
+
}
|
|
1515
|
+
return result;
|
|
1516
|
+
}
|
|
1517
|
+
};
|
|
1518
|
+
var videoStream = {
|
|
1519
|
+
loadedData: false,
|
|
1520
|
+
defaultVideoDimensions: {
|
|
1521
|
+
width: 640,
|
|
1522
|
+
height: 480
|
|
1523
|
+
},
|
|
1524
|
+
findVideoSize: function findVideoSizeMethod(obj) {
|
|
1525
|
+
findVideoSizeMethod.attempts = findVideoSizeMethod.attempts || 0;
|
|
1526
|
+
var cameraStream = obj.cameraStream;
|
|
1527
|
+
var completedCallback = obj.completedCallback;
|
|
1528
|
+
var videoElement = obj.videoElement;
|
|
1529
|
+
if (!videoElement) {
|
|
1530
|
+
return;
|
|
1531
|
+
}
|
|
1532
|
+
if (videoElement.videoWidth > 0 && videoElement.videoHeight > 0) {
|
|
1533
|
+
videoElement.removeEventListener('loadeddata', videoStream.findVideoSize);
|
|
1534
|
+
completedCallback({
|
|
1535
|
+
videoElement: videoElement,
|
|
1536
|
+
cameraStream: cameraStream,
|
|
1537
|
+
videoWidth: videoElement.videoWidth,
|
|
1538
|
+
videoHeight: videoElement.videoHeight
|
|
1539
|
+
});
|
|
1540
|
+
} else if (findVideoSizeMethod.attempts < 10) {
|
|
1541
|
+
findVideoSizeMethod.attempts += 1;
|
|
1542
|
+
utils.requestTimeout(function () {
|
|
1543
|
+
videoStream.findVideoSize(obj);
|
|
1544
|
+
}, 400);
|
|
1545
|
+
} else {
|
|
1546
|
+
completedCallback({
|
|
1547
|
+
videoElement: videoElement,
|
|
1548
|
+
cameraStream: cameraStream,
|
|
1549
|
+
videoWidth: videoStream.defaultVideoDimensions.width,
|
|
1550
|
+
videoHeight: videoStream.defaultVideoDimensions.height
|
|
1551
|
+
});
|
|
1552
|
+
}
|
|
1553
|
+
},
|
|
1554
|
+
onStreamingTimeout: function onStreamingTimeout(callback) {
|
|
1555
|
+
if (utils.isFunction(callback)) {
|
|
1556
|
+
callback({
|
|
1557
|
+
error: true,
|
|
1558
|
+
errorCode: 'getUserMedia',
|
|
1559
|
+
errorMsg: 'There was an issue with the getUserMedia API - Timed out while trying to start streaming',
|
|
1560
|
+
image: null,
|
|
1561
|
+
cameraStream: {}
|
|
1562
|
+
});
|
|
1563
|
+
}
|
|
1564
|
+
},
|
|
1565
|
+
stream: function stream(obj) {
|
|
1566
|
+
var existingVideo = utils.isArray(obj.existingVideo) ? obj.existingVideo[0] : obj.existingVideo;
|
|
1567
|
+
var cameraStream = obj.cameraStream;
|
|
1568
|
+
var completedCallback = obj.completedCallback;
|
|
1569
|
+
var streamedCallback = obj.streamedCallback;
|
|
1570
|
+
var videoElement = obj.videoElement;
|
|
1571
|
+
if (utils.isFunction(streamedCallback)) {
|
|
1572
|
+
streamedCallback();
|
|
1573
|
+
}
|
|
1574
|
+
if (existingVideo) {
|
|
1575
|
+
if (utils.isString(existingVideo)) {
|
|
1576
|
+
videoElement.src = existingVideo;
|
|
1577
|
+
videoElement.innerHTML = "<source src=\"".concat(existingVideo, "\" type=\"video/").concat(utils.getExtension(existingVideo), "\" />");
|
|
1578
|
+
} else if (existingVideo instanceof Blob) {
|
|
1579
|
+
try {
|
|
1580
|
+
videoElement.src = utils.URL.createObjectURL(existingVideo);
|
|
1581
|
+
} catch (e) {}
|
|
1582
|
+
videoElement.innerHTML = "<source src=\"".concat(existingVideo, "\" type=\"").concat(existingVideo.type, "\" />");
|
|
1583
|
+
}
|
|
1584
|
+
} else if (videoElement.mozSrcObject) {
|
|
1585
|
+
videoElement.mozSrcObject = cameraStream;
|
|
1586
|
+
} else if (utils.URL) {
|
|
1587
|
+
try {
|
|
1588
|
+
videoElement.srcObject = cameraStream;
|
|
1589
|
+
videoElement.src = utils.URL.createObjectURL(cameraStream);
|
|
1590
|
+
} catch (e) {
|
|
1591
|
+
videoElement.srcObject = cameraStream;
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
videoElement.play();
|
|
1595
|
+
utils.requestTimeout(function checkLoadedData() {
|
|
1596
|
+
checkLoadedData.count = checkLoadedData.count || 0;
|
|
1597
|
+
if (videoStream.loadedData === true) {
|
|
1598
|
+
videoStream.findVideoSize({
|
|
1599
|
+
videoElement: videoElement,
|
|
1600
|
+
cameraStream: cameraStream,
|
|
1601
|
+
completedCallback: completedCallback
|
|
1602
|
+
});
|
|
1603
|
+
videoStream.loadedData = false;
|
|
1604
|
+
} else {
|
|
1605
|
+
checkLoadedData.count += 1;
|
|
1606
|
+
if (checkLoadedData.count > 10) {
|
|
1607
|
+
videoStream.findVideoSize({
|
|
1608
|
+
videoElement: videoElement,
|
|
1609
|
+
cameraStream: cameraStream,
|
|
1610
|
+
completedCallback: completedCallback
|
|
1611
|
+
});
|
|
1612
|
+
} else {
|
|
1613
|
+
checkLoadedData();
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
}, 0);
|
|
1617
|
+
},
|
|
1618
|
+
startStreaming: function startStreaming(obj) {
|
|
1619
|
+
var errorCallback = utils.isFunction(obj.error) ? obj.error : utils.noop;
|
|
1620
|
+
var streamedCallback = utils.isFunction(obj.streamed) ? obj.streamed : utils.noop;
|
|
1621
|
+
var completedCallback = utils.isFunction(obj.completed) ? obj.completed : utils.noop;
|
|
1622
|
+
var crossOrigin = obj.crossOrigin;
|
|
1623
|
+
var existingVideo = obj.existingVideo;
|
|
1624
|
+
var lastCameraStream = obj.lastCameraStream;
|
|
1625
|
+
var options = obj.options;
|
|
1626
|
+
var webcamVideoElement = obj.webcamVideoElement;
|
|
1627
|
+
var videoElement = utils.isElement(existingVideo) ? existingVideo : webcamVideoElement ? webcamVideoElement : document.createElement('video');
|
|
1628
|
+
var cameraStream = void 0;
|
|
1629
|
+
if (crossOrigin) {
|
|
1630
|
+
videoElement.crossOrigin = options.crossOrigin;
|
|
1631
|
+
}
|
|
1632
|
+
videoElement.autoplay = true;
|
|
1633
|
+
videoElement.loop = true;
|
|
1634
|
+
videoElement.muted = true;
|
|
1635
|
+
videoElement.addEventListener('loadeddata', function (event) {
|
|
1636
|
+
videoStream.loadedData = true;
|
|
1637
|
+
if (options.offset) {
|
|
1638
|
+
videoElement.currentTime = options.offset;
|
|
1639
|
+
}
|
|
1640
|
+
});
|
|
1641
|
+
if (existingVideo) {
|
|
1642
|
+
videoStream.stream({
|
|
1643
|
+
videoElement: videoElement,
|
|
1644
|
+
existingVideo: existingVideo,
|
|
1645
|
+
completedCallback: completedCallback
|
|
1646
|
+
});
|
|
1647
|
+
} else if (lastCameraStream) {
|
|
1648
|
+
videoStream.stream({
|
|
1649
|
+
videoElement: videoElement,
|
|
1650
|
+
cameraStream: lastCameraStream,
|
|
1651
|
+
streamedCallback: streamedCallback,
|
|
1652
|
+
completedCallback: completedCallback
|
|
1653
|
+
});
|
|
1654
|
+
} else {
|
|
1655
|
+
utils.getUserMedia({
|
|
1656
|
+
video: true
|
|
1657
|
+
}, function (stream) {
|
|
1658
|
+
videoStream.stream({
|
|
1659
|
+
videoElement: videoElement,
|
|
1660
|
+
cameraStream: stream,
|
|
1661
|
+
streamedCallback: streamedCallback,
|
|
1662
|
+
completedCallback: completedCallback
|
|
1663
|
+
});
|
|
1664
|
+
}, errorCallback);
|
|
1665
|
+
}
|
|
1666
|
+
},
|
|
1667
|
+
startVideoStreaming: function startVideoStreaming(callback) {
|
|
1668
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1669
|
+
var timeoutLength = options.timeout !== undefined ? options.timeout : 0;
|
|
1670
|
+
var originalCallback = options.callback;
|
|
1671
|
+
var webcamVideoElement = options.webcamVideoElement;
|
|
1672
|
+
var noGetUserMediaSupportTimeout = void 0;
|
|
1673
|
+
if (timeoutLength > 0) {
|
|
1674
|
+
noGetUserMediaSupportTimeout = utils.requestTimeout(function () {
|
|
1675
|
+
videoStream.onStreamingTimeout(originalCallback);
|
|
1676
|
+
}, 10000);
|
|
1677
|
+
}
|
|
1678
|
+
videoStream.startStreaming({
|
|
1679
|
+
error: function error() {
|
|
1680
|
+
originalCallback({
|
|
1681
|
+
error: true,
|
|
1682
|
+
errorCode: 'getUserMedia',
|
|
1683
|
+
errorMsg: 'There was an issue with the getUserMedia API - the user probably denied permission',
|
|
1684
|
+
image: null,
|
|
1685
|
+
cameraStream: {}
|
|
1686
|
+
});
|
|
1687
|
+
},
|
|
1688
|
+
streamed: function streamed() {
|
|
1689
|
+
clearTimeout(noGetUserMediaSupportTimeout);
|
|
1690
|
+
},
|
|
1691
|
+
completed: function completed() {
|
|
1692
|
+
var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1693
|
+
var cameraStream = obj.cameraStream;
|
|
1694
|
+
var videoElement = obj.videoElement;
|
|
1695
|
+
var videoHeight = obj.videoHeight;
|
|
1696
|
+
var videoWidth = obj.videoWidth;
|
|
1697
|
+
callback({
|
|
1698
|
+
cameraStream: cameraStream,
|
|
1699
|
+
videoElement: videoElement,
|
|
1700
|
+
videoHeight: videoHeight,
|
|
1701
|
+
videoWidth: videoWidth
|
|
1702
|
+
});
|
|
1703
|
+
},
|
|
1704
|
+
lastCameraStream: options.lastCameraStream,
|
|
1705
|
+
webcamVideoElement: webcamVideoElement,
|
|
1706
|
+
crossOrigin: options.crossOrigin,
|
|
1707
|
+
options: options
|
|
1708
|
+
});
|
|
1709
|
+
},
|
|
1710
|
+
stopVideoStreaming: function stopVideoStreaming(obj) {
|
|
1711
|
+
obj = utils.isObject(obj) ? obj : {};
|
|
1712
|
+
var _obj = obj;
|
|
1713
|
+
var keepCameraOn = _obj.keepCameraOn;
|
|
1714
|
+
var videoElement = _obj.videoElement;
|
|
1715
|
+
var webcamVideoElement = _obj.webcamVideoElement;
|
|
1716
|
+
var cameraStream = obj.cameraStream || {};
|
|
1717
|
+
var cameraStreamTracks = cameraStream.getTracks ? cameraStream.getTracks() || [] : [];
|
|
1718
|
+
var hasCameraStreamTracks = Boolean(cameraStreamTracks.length);
|
|
1719
|
+
var firstCameraStreamTrack = cameraStreamTracks[0];
|
|
1720
|
+
if (!keepCameraOn && hasCameraStreamTracks) {
|
|
1721
|
+
if (utils.isFunction(firstCameraStreamTrack.stop)) {
|
|
1722
|
+
firstCameraStreamTrack.stop();
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
if (utils.isElement(videoElement) && !webcamVideoElement) {
|
|
1726
|
+
videoElement.pause();
|
|
1727
|
+
if (utils.isFunction(utils.URL.revokeObjectURL) && !utils.webWorkerError) {
|
|
1728
|
+
if (videoElement.src) {
|
|
1729
|
+
utils.URL.revokeObjectURL(videoElement.src);
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
utils.removeElement(videoElement);
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
};
|
|
1736
|
+
function stopVideoStreaming(options) {
|
|
1737
|
+
options = utils.isObject(options) ? options : {};
|
|
1738
|
+
videoStream.stopVideoStreaming(options);
|
|
1739
|
+
}
|
|
1740
|
+
function createAndGetGIF(obj, callback) {
|
|
1741
|
+
var options = obj.options || {};
|
|
1742
|
+
var images = options.images;
|
|
1743
|
+
var video = options.video;
|
|
1744
|
+
var gifWidth = Number(options.gifWidth);
|
|
1745
|
+
var gifHeight = Number(options.gifHeight);
|
|
1746
|
+
var numFrames = Number(options.numFrames);
|
|
1747
|
+
var cameraStream = obj.cameraStream;
|
|
1748
|
+
var videoElement = obj.videoElement;
|
|
1749
|
+
var videoWidth = obj.videoWidth;
|
|
1750
|
+
var videoHeight = obj.videoHeight;
|
|
1751
|
+
var cropDimensions = screenShot.getCropDimensions({
|
|
1752
|
+
videoWidth: videoWidth,
|
|
1753
|
+
videoHeight: videoHeight,
|
|
1754
|
+
gifHeight: gifHeight,
|
|
1755
|
+
gifWidth: gifWidth
|
|
1756
|
+
});
|
|
1757
|
+
var completeCallback = callback;
|
|
1758
|
+
options.crop = cropDimensions;
|
|
1759
|
+
options.videoElement = videoElement;
|
|
1760
|
+
options.videoWidth = videoWidth;
|
|
1761
|
+
options.videoHeight = videoHeight;
|
|
1762
|
+
options.cameraStream = cameraStream;
|
|
1763
|
+
if (!utils.isElement(videoElement)) {
|
|
1764
|
+
return;
|
|
1765
|
+
}
|
|
1766
|
+
videoElement.width = gifWidth + cropDimensions.width;
|
|
1767
|
+
videoElement.height = gifHeight + cropDimensions.height;
|
|
1768
|
+
if (!options.webcamVideoElement) {
|
|
1769
|
+
utils.setCSSAttr(videoElement, {
|
|
1770
|
+
position: 'fixed',
|
|
1771
|
+
opacity: '0'
|
|
1772
|
+
});
|
|
1773
|
+
document.body.appendChild(videoElement);
|
|
1774
|
+
}
|
|
1775
|
+
videoElement.play();
|
|
1776
|
+
screenShot.getGIF(options, function (obj) {
|
|
1777
|
+
if ((!images || !images.length) && (!video || !video.length)) {
|
|
1778
|
+
stopVideoStreaming(obj);
|
|
1779
|
+
}
|
|
1780
|
+
completeCallback(obj);
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
function existingVideo() {
|
|
1784
|
+
var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1785
|
+
var callback = obj.callback;
|
|
1786
|
+
var existingVideo = obj.existingVideo;
|
|
1787
|
+
var options = obj.options;
|
|
1788
|
+
var skipObj = {
|
|
1789
|
+
getUserMedia: true,
|
|
1790
|
+
'globalThis.URL': true
|
|
1791
|
+
};
|
|
1792
|
+
var errorObj = error.validate(skipObj);
|
|
1793
|
+
var loadedImages = 0;
|
|
1794
|
+
var videoType = void 0;
|
|
1795
|
+
var videoSrc = void 0;
|
|
1796
|
+
var tempImage = void 0;
|
|
1797
|
+
var ag = void 0;
|
|
1798
|
+
if (errorObj.error) {
|
|
1799
|
+
return callback(errorObj);
|
|
1800
|
+
}
|
|
1801
|
+
if (utils.isElement(existingVideo) && existingVideo.src) {
|
|
1802
|
+
videoSrc = existingVideo.src;
|
|
1803
|
+
videoType = utils.getExtension(videoSrc);
|
|
1804
|
+
if (!utils.isSupported.videoCodecs[videoType]) {
|
|
1805
|
+
return callback(error.messages.videoCodecs);
|
|
1806
|
+
}
|
|
1807
|
+
} else if (utils.isArray(existingVideo)) {
|
|
1808
|
+
utils.each(existingVideo, function (iterator, videoSrc) {
|
|
1809
|
+
if (videoSrc instanceof Blob) {
|
|
1810
|
+
videoType = videoSrc.type.substr(videoSrc.type.lastIndexOf('/') + 1, videoSrc.length);
|
|
1811
|
+
} else {
|
|
1812
|
+
videoType = videoSrc.substr(videoSrc.lastIndexOf('.') + 1, videoSrc.length);
|
|
1813
|
+
}
|
|
1814
|
+
if (utils.isSupported.videoCodecs[videoType]) {
|
|
1815
|
+
existingVideo = videoSrc;
|
|
1816
|
+
return false;
|
|
1817
|
+
}
|
|
1818
|
+
});
|
|
1819
|
+
}
|
|
1820
|
+
videoStream.startStreaming({
|
|
1821
|
+
completed: function completed(obj) {
|
|
1822
|
+
obj.options = options || {};
|
|
1823
|
+
createAndGetGIF(obj, callback);
|
|
1824
|
+
},
|
|
1825
|
+
existingVideo: existingVideo,
|
|
1826
|
+
crossOrigin: options.crossOrigin,
|
|
1827
|
+
options: options
|
|
1828
|
+
});
|
|
1829
|
+
}
|
|
1830
|
+
function existingWebcam() {
|
|
1831
|
+
var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1832
|
+
var callback = obj.callback;
|
|
1833
|
+
var lastCameraStream = obj.lastCameraStream;
|
|
1834
|
+
var options = obj.options;
|
|
1835
|
+
var webcamVideoElement = obj.webcamVideoElement;
|
|
1836
|
+
if (!isWebCamGIFSupported()) {
|
|
1837
|
+
return callback(error.validate());
|
|
1838
|
+
}
|
|
1839
|
+
if (options.savedRenderingContexts.length) {
|
|
1840
|
+
screenShot.getGIF(options, function (obj) {
|
|
1841
|
+
callback(obj);
|
|
1842
|
+
});
|
|
1843
|
+
return;
|
|
1844
|
+
}
|
|
1845
|
+
videoStream.startVideoStreaming(function () {
|
|
1846
|
+
var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1847
|
+
obj.options = options || {};
|
|
1848
|
+
createAndGetGIF(obj, callback);
|
|
1849
|
+
}, {
|
|
1850
|
+
lastCameraStream: lastCameraStream,
|
|
1851
|
+
callback: callback,
|
|
1852
|
+
webcamVideoElement: webcamVideoElement,
|
|
1853
|
+
crossOrigin: options.crossOrigin
|
|
1854
|
+
});
|
|
1855
|
+
}
|
|
1856
|
+
function createGIF(userOptions, callback) {
|
|
1857
|
+
callback = utils.isFunction(userOptions) ? userOptions : callback;
|
|
1858
|
+
userOptions = utils.isObject(userOptions) ? userOptions : {};
|
|
1859
|
+
if (!utils.isFunction(callback)) {
|
|
1860
|
+
return;
|
|
1861
|
+
}
|
|
1862
|
+
var options = utils.normalizeOptions(defaultOptions, userOptions) || {};
|
|
1863
|
+
var lastCameraStream = userOptions.cameraStream;
|
|
1864
|
+
var images = options.images;
|
|
1865
|
+
var imagesLength = images ? images.length : 0;
|
|
1866
|
+
var video = options.video;
|
|
1867
|
+
var webcamVideoElement = options.webcamVideoElement;
|
|
1868
|
+
options = utils.normalizeOptions(options, {
|
|
1869
|
+
gifWidth: Math.floor(options.gifWidth),
|
|
1870
|
+
gifHeight: Math.floor(options.gifHeight)
|
|
1871
|
+
});
|
|
1872
|
+
if (imagesLength) {
|
|
1873
|
+
existingImages({
|
|
1874
|
+
images: images,
|
|
1875
|
+
imagesLength: imagesLength,
|
|
1876
|
+
callback: callback,
|
|
1877
|
+
options: options
|
|
1878
|
+
});
|
|
1879
|
+
} else if (video) {
|
|
1880
|
+
existingVideo({
|
|
1881
|
+
existingVideo: video,
|
|
1882
|
+
callback: callback,
|
|
1883
|
+
options: options
|
|
1884
|
+
});
|
|
1885
|
+
} else {
|
|
1886
|
+
existingWebcam({
|
|
1887
|
+
lastCameraStream: lastCameraStream,
|
|
1888
|
+
callback: callback,
|
|
1889
|
+
webcamVideoElement: webcamVideoElement,
|
|
1890
|
+
options: options
|
|
1891
|
+
});
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
function takeSnapShot(userOptions, callback) {
|
|
1895
|
+
callback = utils.isFunction(userOptions) ? userOptions : callback;
|
|
1896
|
+
userOptions = utils.isObject(userOptions) ? userOptions : {};
|
|
1897
|
+
if (!utils.isFunction(callback)) {
|
|
1898
|
+
return;
|
|
1899
|
+
}
|
|
1900
|
+
var mergedOptions = utils.normalizeOptions(defaultOptions, userOptions);
|
|
1901
|
+
var options = utils.normalizeOptions(mergedOptions, {
|
|
1902
|
+
interval: 0.1,
|
|
1903
|
+
numFrames: 1,
|
|
1904
|
+
gifWidth: Math.floor(mergedOptions.gifWidth),
|
|
1905
|
+
gifHeight: Math.floor(mergedOptions.gifHeight)
|
|
1906
|
+
});
|
|
1907
|
+
createGIF(options, callback);
|
|
1908
|
+
}
|
|
1909
|
+
var API = {
|
|
1910
|
+
utils: utils$2,
|
|
1911
|
+
error: error$2,
|
|
1912
|
+
defaultOptions: defaultOptions$2,
|
|
1913
|
+
createGIF: createGIF,
|
|
1914
|
+
takeSnapShot: takeSnapShot,
|
|
1915
|
+
stopVideoStreaming: stopVideoStreaming,
|
|
1916
|
+
isSupported: isSupported,
|
|
1917
|
+
isWebCamGIFSupported: isWebCamGIFSupported,
|
|
1918
|
+
isExistingVideoGIFSupported: isExistingVideoGIFSupported,
|
|
1919
|
+
isExistingImagesGIFSupported: isSupported$1,
|
|
1920
|
+
VERSION: '0.4.5'
|
|
1921
|
+
};
|
|
1922
|
+
var _default = API;
|
|
1923
|
+
exports.default = _default;
|
|
1924
|
+
//# sourceMappingURL=gifshot.js.map
|