@loaders.gl/video 4.2.0-alpha.4 → 4.2.0-alpha.5
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/dist.dev.js +161 -62
- package/dist/dist.min.js +9 -0
- package/dist/gif-builder.js +131 -98
- package/dist/index.cjs +33 -51
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/lib/gifshot/gifshot-loader.js +16 -12
- package/dist/lib/gifshot/gifshot.js +2322 -1819
- package/dist/lib/parsers/parse-video.js +11 -5
- package/dist/lib/utils/assert.js +6 -4
- package/dist/video-loader.js +15 -10
- package/package.json +10 -6
- 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/gifshot/gifshot.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/video-loader.js.map +0 -1
package/dist/gif-builder.js
CHANGED
|
@@ -1,106 +1,139 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
// A GIFBuilder based on the gifshot module
|
|
5
|
+
// @ts-nocheck
|
|
1
6
|
import { assert } from "./lib/utils/assert.js";
|
|
2
|
-
import gifshot from "./lib/gifshot/gifshot.js";
|
|
7
|
+
import gifshot from "./lib/gifshot/gifshot.js"; // TODO - load dynamically to avoid bloating
|
|
8
|
+
// These are gifshot module options
|
|
3
9
|
const GIF_BUILDER_OPTIONS = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
10
|
+
source: 'images',
|
|
11
|
+
width: 200, // Desired width of the image
|
|
12
|
+
height: 200, // Desired height of the image
|
|
13
|
+
crossOrigin: 'Anonymous', // Options are 'Anonymous', 'use-credentials', or a falsy value to not set a CORS attribute.
|
|
14
|
+
// CALLBACKS
|
|
15
|
+
progressCallback: (captureProgress) => { }, // Callback that provides the current progress of the current image
|
|
16
|
+
completeCallback: () => { }, // Callback function that is called when the current image is completed
|
|
17
|
+
// QUALITY SETTINGS
|
|
18
|
+
numWorkers: 2, // how many web workers to use to process the animated GIF frames. Default is 2.
|
|
19
|
+
sampleInterval: 10, // pixels to skip when creating the palette. Default is 10. Less is better, but slower.
|
|
20
|
+
interval: 0.1, // The amount of time (in seconds) to wait between each frame capture
|
|
21
|
+
offset: null, // The amount of time (in seconds) to start capturing the GIF (only for HTML5 videos)
|
|
22
|
+
numFrames: 10, // The number of frames to use to create the animated GIF. Note: Each frame is captured every 100 milliseconds of a video and every ms for existing images
|
|
23
|
+
frameDuration: 1, // The amount of time (10 = 1s) to stay on each frame
|
|
24
|
+
// CSS FILTER OPTIONS
|
|
25
|
+
filter: '', // CSS filter that will be applied to the image (eg. blur(5px))
|
|
26
|
+
// WATERMARK OPTIONS
|
|
27
|
+
waterMark: null, // If an image is given here, it will be stamped on top of the GIF frames
|
|
28
|
+
waterMarkHeight: null, // Height of the waterMark
|
|
29
|
+
waterMarkWidth: null, // Height of the waterMark
|
|
30
|
+
waterMarkXCoordinate: 1, // The X (horizontal) Coordinate of the watermark image
|
|
31
|
+
waterMarkYCoordinate: 1, // The Y (vertical) Coordinate of the watermark image
|
|
32
|
+
// TEXT OPTIONS
|
|
33
|
+
text: '', // The text that covers the animated GIF
|
|
34
|
+
showFrameText: true, // If frame-specific text is supplied with the image array, you can force to not be displayed
|
|
35
|
+
fontWeight: 'normal', // The font weight of the text that covers the animated GIF
|
|
36
|
+
fontSize: '16px', // The font size of the text that covers the animated GIF
|
|
37
|
+
minFontSize: '10px', // The minimum font size of the text that covers the animated GIF
|
|
38
|
+
resizeFont: false, // Whether or not the animated GIF text will be resized to fit within the GIF container
|
|
39
|
+
fontFamily: 'sans-serif', // The font family of the text that covers the animated GIF
|
|
40
|
+
fontColor: '#ffffff', // The font color of the text that covers the animated GIF
|
|
41
|
+
textAlign: 'center', // The horizontal text alignment of the text that covers the animated GIF
|
|
42
|
+
textBaseline: 'bottom', // The vertical text alignment of the text that covers the animated GIF
|
|
43
|
+
textXCoordinate: null, // The X (horizontal) Coordinate of the text that covers the animated GIF
|
|
44
|
+
textYCoordinate: null, // The Y (vertical) Coordinate of the text that covers the animated GIF
|
|
45
|
+
// ADVANCED OPTIONS
|
|
46
|
+
// WEBCAM CAPTURE OPTIONS
|
|
47
|
+
webcamVideoElement: null, // You can pass an existing video element to use for the webcam GIF creation process,
|
|
48
|
+
keepCameraOn: false, // Whether or not you would like the user's camera to stay on after the GIF is created
|
|
49
|
+
cameraStream: null, // Expects a cameraStream Media object
|
|
50
|
+
// CANVAS OPTIMIZATION OPTIONS
|
|
51
|
+
saveRenderingContexts: false, // Whether or not you would like to save all of the canvas image binary data
|
|
52
|
+
savedRenderingContexts: [] // Array of canvas image data
|
|
39
53
|
};
|
|
40
54
|
export default class GIFBuilder {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
constructor(options) {
|
|
52
|
-
this.options = {
|
|
53
|
-
...options
|
|
54
|
-
};
|
|
55
|
-
this.source = options.source;
|
|
56
|
-
delete options.source;
|
|
57
|
-
this.files = [];
|
|
58
|
-
this.gifshot = gifshot;
|
|
59
|
-
}
|
|
60
|
-
async initialize(options) {}
|
|
61
|
-
async add(file) {
|
|
62
|
-
await this.initialize();
|
|
63
|
-
this.files.push(file);
|
|
64
|
-
}
|
|
65
|
-
async build() {
|
|
66
|
-
await this.initialize();
|
|
67
|
-
this._cleanOptions(this.options);
|
|
68
|
-
switch (this.source) {
|
|
69
|
-
case 'images':
|
|
70
|
-
this.options.images = this.files;
|
|
71
|
-
break;
|
|
72
|
-
case 'video':
|
|
73
|
-
this.options.video = this.files;
|
|
74
|
-
break;
|
|
75
|
-
case 'webcam':
|
|
76
|
-
assert(this.files.length === 0);
|
|
77
|
-
break;
|
|
78
|
-
default:
|
|
79
|
-
throw new Error('GIFBuilder: invalid source');
|
|
55
|
+
static get properties() {
|
|
56
|
+
return {
|
|
57
|
+
id: 'gif',
|
|
58
|
+
name: 'GIF',
|
|
59
|
+
extensions: ['gif'],
|
|
60
|
+
mimeTypes: ['image/gif'],
|
|
61
|
+
builder: GIFBuilder,
|
|
62
|
+
options: GIF_BUILDER_OPTIONS
|
|
63
|
+
};
|
|
80
64
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
65
|
+
constructor(options) {
|
|
66
|
+
this.options = { ...options };
|
|
67
|
+
this.source = options.source;
|
|
68
|
+
delete options.source;
|
|
69
|
+
// Allow files to be added
|
|
70
|
+
this.files = [];
|
|
71
|
+
// Expose the gifshot module so that the full gifshot API is available to apps (Experimental)
|
|
72
|
+
this.gifshot = gifshot;
|
|
73
|
+
}
|
|
74
|
+
async initialize(options) {
|
|
75
|
+
// Expose the gifshot module so that the full gifshot API is available to apps (Experimental)
|
|
76
|
+
// this.gifshot = await loadGifshotModule(options);
|
|
77
|
+
}
|
|
78
|
+
async add(file) {
|
|
79
|
+
await this.initialize();
|
|
80
|
+
this.files.push(file);
|
|
81
|
+
}
|
|
82
|
+
async build() {
|
|
83
|
+
await this.initialize();
|
|
84
|
+
this._cleanOptions(this.options);
|
|
85
|
+
switch (this.source) {
|
|
86
|
+
case 'images':
|
|
87
|
+
this.options.images = this.files;
|
|
88
|
+
break;
|
|
89
|
+
case 'video':
|
|
90
|
+
this.options.video = this.files;
|
|
91
|
+
break;
|
|
92
|
+
case 'webcam':
|
|
93
|
+
assert(this.files.length === 0);
|
|
94
|
+
break;
|
|
95
|
+
default:
|
|
96
|
+
throw new Error('GIFBuilder: invalid source');
|
|
97
|
+
}
|
|
98
|
+
return await this._createGIF();
|
|
99
|
+
}
|
|
100
|
+
// PRIVATE
|
|
101
|
+
async _createGIF() {
|
|
102
|
+
return new Promise((resolve, reject) => {
|
|
103
|
+
this.gifshot.createGIF(this.options, (result) => {
|
|
104
|
+
// callback object properties
|
|
105
|
+
// --------------------------
|
|
106
|
+
// image - Base 64 image
|
|
107
|
+
// cameraStream - The webRTC MediaStream object
|
|
108
|
+
// error - Boolean that determines if an error occurred
|
|
109
|
+
// errorCode - Helpful error label
|
|
110
|
+
// errorMsg - Helpful error message
|
|
111
|
+
// savedRenderingContexts - An array of canvas image data (will only be set if the saveRenderingContexts option was used)
|
|
112
|
+
if (result.error) {
|
|
113
|
+
reject(result.errorMsg);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
// image - Base 64 image
|
|
117
|
+
resolve(result.image);
|
|
118
|
+
// var image = obj.image,
|
|
119
|
+
// animatedImage = document.createElement('img');
|
|
120
|
+
// animatedImage.src = image;
|
|
121
|
+
// document.body.appendChild(animatedImage);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
// Remove some gifshot options
|
|
126
|
+
_cleanOptions(options) {
|
|
127
|
+
if (options.video || options.images || options.gifWidth || options.gifHeight) {
|
|
128
|
+
console.warn('GIFBuilder: ignoring options'); // eslint-disable-line
|
|
89
129
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
130
|
+
// We control these through options.source instead
|
|
131
|
+
delete options.video;
|
|
132
|
+
delete options.images;
|
|
133
|
+
// Use width/height props (to standardize across builders)
|
|
134
|
+
options.gifWidth = options.width;
|
|
135
|
+
options.gifHeight = options.height;
|
|
136
|
+
delete options.width;
|
|
137
|
+
delete options.height;
|
|
97
138
|
}
|
|
98
|
-
delete options.video;
|
|
99
|
-
delete options.images;
|
|
100
|
-
options.gifWidth = options.width;
|
|
101
|
-
options.gifHeight = options.height;
|
|
102
|
-
delete options.width;
|
|
103
|
-
delete options.height;
|
|
104
|
-
}
|
|
105
139
|
}
|
|
106
|
-
//# sourceMappingURL=gif-builder.js.map
|
package/dist/index.cjs
CHANGED
|
@@ -17,15 +17,15 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
|
-
//
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
20
|
+
// dist/index.js
|
|
21
|
+
var dist_exports = {};
|
|
22
|
+
__export(dist_exports, {
|
|
23
23
|
GIFBuilder: () => GIFBuilder,
|
|
24
24
|
VideoLoader: () => VideoLoader
|
|
25
25
|
});
|
|
26
|
-
module.exports = __toCommonJS(
|
|
26
|
+
module.exports = __toCommonJS(dist_exports);
|
|
27
27
|
|
|
28
|
-
//
|
|
28
|
+
// dist/lib/parsers/parse-video.js
|
|
29
29
|
async function parseVideo(arrayBuffer) {
|
|
30
30
|
const blob2 = new Blob([arrayBuffer]);
|
|
31
31
|
const video = document.createElement("video");
|
|
@@ -33,8 +33,8 @@ async function parseVideo(arrayBuffer) {
|
|
|
33
33
|
return video;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
//
|
|
37
|
-
var VERSION =
|
|
36
|
+
// dist/video-loader.js
|
|
37
|
+
var VERSION = true ? "4.2.0-alpha.4" : "latest";
|
|
38
38
|
var EXTENSIONS = ["mp4"];
|
|
39
39
|
var MIME_TYPES = ["video/mp4"];
|
|
40
40
|
var DEFAULT_LOADER_OPTIONS = {
|
|
@@ -52,14 +52,14 @@ var VideoLoader = {
|
|
|
52
52
|
options: DEFAULT_LOADER_OPTIONS
|
|
53
53
|
};
|
|
54
54
|
|
|
55
|
-
//
|
|
55
|
+
// dist/lib/utils/assert.js
|
|
56
56
|
function assert(condition, message) {
|
|
57
57
|
if (!condition) {
|
|
58
58
|
throw new Error(message);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
//
|
|
62
|
+
// dist/lib/gifshot/gifshot.js
|
|
63
63
|
var document2 = globalThis.document || {};
|
|
64
64
|
var utils = {
|
|
65
65
|
URL: globalThis.URL || globalThis.webkitURL || globalThis.mozURL || globalThis.msURL,
|
|
@@ -1523,17 +1523,7 @@ var screenShot = {
|
|
|
1523
1523
|
sourceY = 0;
|
|
1524
1524
|
}
|
|
1525
1525
|
context.filter = filter;
|
|
1526
|
-
context.drawImage(
|
|
1527
|
-
videoElement,
|
|
1528
|
-
sourceX,
|
|
1529
|
-
sourceY,
|
|
1530
|
-
sourceWidth,
|
|
1531
|
-
sourceHeight,
|
|
1532
|
-
0,
|
|
1533
|
-
0,
|
|
1534
|
-
gifWidth,
|
|
1535
|
-
gifHeight
|
|
1536
|
-
);
|
|
1526
|
+
context.drawImage(videoElement, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, gifWidth, gifHeight);
|
|
1537
1527
|
finishCapture();
|
|
1538
1528
|
} catch (e) {
|
|
1539
1529
|
if (e.name === "NS_ERROR_NOT_AVAILABLE") {
|
|
@@ -1673,9 +1663,7 @@ var videoStream = {
|
|
|
1673
1663
|
if (existingVideo2) {
|
|
1674
1664
|
if (utils.isString(existingVideo2)) {
|
|
1675
1665
|
videoElement.src = existingVideo2;
|
|
1676
|
-
videoElement.innerHTML = `<source src="${existingVideo2}" type="video/${utils.getExtension(
|
|
1677
|
-
existingVideo2
|
|
1678
|
-
)}" />`;
|
|
1666
|
+
videoElement.innerHTML = `<source src="${existingVideo2}" type="video/${utils.getExtension(existingVideo2)}" />`;
|
|
1679
1667
|
} else if (existingVideo2 instanceof Blob) {
|
|
1680
1668
|
try {
|
|
1681
1669
|
videoElement.src = utils.URL.createObjectURL(existingVideo2);
|
|
@@ -1754,20 +1742,16 @@ var videoStream = {
|
|
|
1754
1742
|
completedCallback
|
|
1755
1743
|
});
|
|
1756
1744
|
} else {
|
|
1757
|
-
utils.getUserMedia(
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
});
|
|
1768
|
-
},
|
|
1769
|
-
errorCallback
|
|
1770
|
-
);
|
|
1745
|
+
utils.getUserMedia({
|
|
1746
|
+
video: true
|
|
1747
|
+
}, function(stream2) {
|
|
1748
|
+
videoStream.stream({
|
|
1749
|
+
videoElement,
|
|
1750
|
+
cameraStream: stream2,
|
|
1751
|
+
streamedCallback,
|
|
1752
|
+
completedCallback
|
|
1753
|
+
});
|
|
1754
|
+
}, errorCallback);
|
|
1771
1755
|
}
|
|
1772
1756
|
},
|
|
1773
1757
|
startVideoStreaming: function startVideoStreaming(callback) {
|
|
@@ -1948,19 +1932,16 @@ function existingWebcam() {
|
|
|
1948
1932
|
});
|
|
1949
1933
|
return;
|
|
1950
1934
|
}
|
|
1951
|
-
videoStream.startVideoStreaming(
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
crossOrigin: options.crossOrigin
|
|
1962
|
-
}
|
|
1963
|
-
);
|
|
1935
|
+
videoStream.startVideoStreaming(function() {
|
|
1936
|
+
const obj2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
|
|
1937
|
+
obj2.options = options || {};
|
|
1938
|
+
createAndGetGIF(obj2, callback);
|
|
1939
|
+
}, {
|
|
1940
|
+
lastCameraStream,
|
|
1941
|
+
callback,
|
|
1942
|
+
webcamVideoElement,
|
|
1943
|
+
crossOrigin: options.crossOrigin
|
|
1944
|
+
});
|
|
1964
1945
|
}
|
|
1965
1946
|
function createGIF(userOptions, callback) {
|
|
1966
1947
|
callback = utils.isFunction(userOptions) ? userOptions : callback;
|
|
@@ -2030,7 +2011,7 @@ var API = {
|
|
|
2030
2011
|
};
|
|
2031
2012
|
var gifshot_default = API;
|
|
2032
2013
|
|
|
2033
|
-
//
|
|
2014
|
+
// dist/gif-builder.js
|
|
2034
2015
|
var GIF_BUILDER_OPTIONS = {
|
|
2035
2016
|
source: "images",
|
|
2036
2017
|
width: 200,
|
|
@@ -2179,3 +2160,4 @@ var GIFBuilder = class {
|
|
|
2179
2160
|
delete options.height;
|
|
2180
2161
|
}
|
|
2181
2162
|
};
|
|
2163
|
+
//# sourceMappingURL=index.cjs.map
|