etro 0.7.0 → 0.8.0
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/.github/workflows/nodejs.yml +1 -1
- package/CHANGELOG.md +45 -1
- package/CONTRIBUTING.md +23 -19
- package/README.md +81 -26
- package/dist/effect/base.d.ts +38 -0
- package/dist/effect/brightness.d.ts +16 -0
- package/dist/effect/channels.d.ts +23 -0
- package/dist/effect/chroma-key.d.ts +23 -0
- package/dist/effect/contrast.d.ts +15 -0
- package/dist/effect/elliptical-mask.d.ts +31 -0
- package/dist/effect/gaussian-blur.d.ts +60 -0
- package/dist/effect/grayscale.d.ts +7 -0
- package/dist/effect/index.d.ts +15 -0
- package/dist/effect/pixelate.d.ts +18 -0
- package/dist/effect/shader.d.ts +99 -0
- package/dist/effect/stack.d.ts +23 -0
- package/dist/effect/transform.d.ts +73 -0
- package/dist/etro-cjs.js +9337 -3331
- package/dist/etro-iife.js +9279 -3273
- package/dist/etro.d.ts +7 -0
- package/dist/event.d.ts +35 -0
- package/dist/index.d.ts +6 -0
- package/dist/layer/audio-source.d.ts +24 -0
- package/dist/layer/audio.d.ts +14 -0
- package/dist/layer/base.d.ts +69 -0
- package/dist/layer/image.d.ts +6 -0
- package/dist/layer/index.d.ts +11 -0
- package/dist/layer/text.d.ts +60 -0
- package/dist/layer/video.d.ts +11 -0
- package/dist/layer/visual-source.d.ts +32 -0
- package/dist/layer/visual.d.ts +58 -0
- package/dist/movie.d.ts +192 -0
- package/dist/object.d.ts +12 -0
- package/dist/util.d.ts +125 -0
- package/eslint.conf.js +0 -8
- package/eslint.example-conf.js +9 -0
- package/eslint.typescript-conf.js +5 -0
- package/examples/application/readme-screenshot.html +12 -9
- package/examples/application/video-player.html +7 -7
- package/examples/application/webcam.html +6 -6
- package/examples/introduction/audio.html +30 -18
- package/examples/introduction/effects.html +14 -10
- package/examples/introduction/export.html +32 -25
- package/examples/introduction/functions.html +6 -4
- package/examples/introduction/hello-world1.html +9 -5
- package/examples/introduction/hello-world2.html +5 -5
- package/examples/introduction/keyframes.html +35 -23
- package/examples/introduction/media.html +26 -18
- package/examples/introduction/text.html +9 -5
- package/karma.conf.js +1 -1
- package/package.json +29 -13
- package/rollup.config.js +15 -4
- package/scripts/gen-effect-samples.html +29 -25
- package/scripts/save-effect-samples.js +14 -15
- package/spec/assets/effect/gaussian-blur-horizontal.png +0 -0
- package/spec/assets/effect/gaussian-blur-vertical.png +0 -0
- package/spec/assets/effect/grayscale.png +0 -0
- package/spec/assets/effect/original.png +0 -0
- package/spec/assets/effect/pixelate.png +0 -0
- package/spec/assets/effect/transform/multiply.png +0 -0
- package/spec/assets/effect/transform/rotate.png +0 -0
- package/spec/assets/effect/transform/scale-fraction.png +0 -0
- package/spec/assets/effect/transform/scale.png +0 -0
- package/spec/assets/effect/transform/translate-fraction.png +0 -0
- package/spec/assets/effect/transform/translate.png +0 -0
- package/spec/effect.spec.js +126 -57
- package/spec/event.spec.js +14 -0
- package/spec/layer.spec.js +175 -18
- package/spec/movie.spec.js +191 -7
- package/spec/util.spec.js +14 -5
- package/src/effect/base.ts +96 -0
- package/src/effect/brightness.ts +43 -0
- package/src/effect/channels.ts +50 -0
- package/src/effect/chroma-key.ts +82 -0
- package/src/effect/contrast.ts +42 -0
- package/src/effect/elliptical-mask.ts +75 -0
- package/src/effect/gaussian-blur.ts +232 -0
- package/src/effect/grayscale.ts +34 -0
- package/src/effect/index.ts +22 -0
- package/src/effect/pixelate.ts +59 -0
- package/src/effect/shader.ts +561 -0
- package/src/effect/stack.ts +74 -0
- package/src/effect/transform.ts +194 -0
- package/src/etro.ts +26 -0
- package/src/event.ts +118 -0
- package/src/index.ts +8 -0
- package/src/layer/audio-source.ts +217 -0
- package/src/layer/audio.ts +35 -0
- package/src/layer/base.ts +156 -0
- package/src/layer/image.ts +8 -0
- package/src/layer/index.ts +13 -0
- package/src/layer/text.ts +138 -0
- package/src/layer/video.ts +15 -0
- package/src/layer/visual-source.ts +150 -0
- package/src/layer/visual.ts +198 -0
- package/src/movie.ts +709 -0
- package/src/object.ts +14 -0
- package/src/util.ts +473 -0
- package/tsconfig.json +8 -0
- package/screenshots/2019-08-17_0.png +0 -0
- package/src/effect.js +0 -1268
- package/src/event.js +0 -78
- package/src/index.js +0 -23
- package/src/layer.js +0 -897
- package/src/movie.js +0 -637
- package/src/util.js +0 -505
|
@@ -2,14 +2,18 @@
|
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
4
|
<title>Media in Etro</title>
|
|
5
|
+
<script src="../../dist/etro-iife.js"></script>
|
|
5
6
|
<style> img, video {display: none;} </style>
|
|
6
7
|
</head>
|
|
7
8
|
<body>
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
<img src="../assets/lake.jpg"/>
|
|
10
|
+
<video src="../assets/desert.mp4"></video>
|
|
11
|
+
<audio src="../assets/strings.wav"></audio>
|
|
12
|
+
<button>Start</button>
|
|
13
|
+
<script>
|
|
14
|
+
const button = document.querySelector('button')
|
|
15
|
+
button.addEventListener('click', () => {
|
|
16
|
+
button.disabled = true
|
|
13
17
|
const canvas = document.createElement('canvas')
|
|
14
18
|
canvas.width = 600
|
|
15
19
|
canvas.height = 400
|
|
@@ -19,37 +23,41 @@
|
|
|
19
23
|
})
|
|
20
24
|
|
|
21
25
|
const initMovie = canvas => {
|
|
22
|
-
movie = new etro.Movie(canvas)
|
|
26
|
+
const movie = new etro.Movie({ canvas })
|
|
23
27
|
const video = document.querySelector('video')
|
|
24
28
|
movie.width = video.videoWidth
|
|
25
29
|
movie.height = video.videoHeight
|
|
26
30
|
movie
|
|
27
|
-
.addLayer(new etro.layer.Image(
|
|
31
|
+
.addLayer(new etro.layer.Image({
|
|
32
|
+
startTime: 0,
|
|
33
|
+
duration: 3,
|
|
34
|
+
source: document.querySelector('img'),
|
|
28
35
|
// crop @ (150, 150) extending (200, 200)
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
sourceX: 100,
|
|
37
|
+
sourceY: 100,
|
|
38
|
+
sourceWidth: 400,
|
|
39
|
+
sourceHeight: 400,
|
|
31
40
|
x: 100,
|
|
32
41
|
y: 100,
|
|
33
|
-
clipWidth: 400,
|
|
34
|
-
clipHeight: 400,
|
|
35
42
|
width: 400,
|
|
36
43
|
height: 400
|
|
37
44
|
}))
|
|
38
|
-
.addLayer(new etro.layer.Video(
|
|
45
|
+
.addLayer(new etro.layer.Video({
|
|
46
|
+
source: video,
|
|
47
|
+
startTime: 3,
|
|
39
48
|
// trim video to only include 3 seconds starting 2 minutes into the video in the video
|
|
40
|
-
|
|
49
|
+
sourceStartTime: 5,
|
|
41
50
|
duration: 3
|
|
42
51
|
}))
|
|
43
|
-
.addLayer(new etro.layer.Audio(
|
|
44
|
-
|
|
52
|
+
.addLayer(new etro.layer.Audio({
|
|
53
|
+
startTime: 6,
|
|
54
|
+
source: document.querySelector('audio'),
|
|
55
|
+
sourceStartTime: 9, // start audio at 9s
|
|
45
56
|
duration: 3 // last 3s
|
|
46
57
|
// volume: 0.25 // 25% of default volume (same as setting volume attribute on audio element)
|
|
47
58
|
}))
|
|
48
59
|
.play()
|
|
49
60
|
}
|
|
50
61
|
</script>
|
|
51
|
-
<img src="../assets/sample.jpg"/>
|
|
52
|
-
<video src="../assets/sample.ogv"></video>
|
|
53
|
-
<audio src="../assets/sample.wav"></audio>
|
|
54
62
|
</body>
|
|
55
63
|
</html>
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
4
|
<title>Text in Etro</title>
|
|
5
|
+
<script src="../../dist/etro-iife.js"></script>
|
|
5
6
|
</head>
|
|
6
7
|
<body>
|
|
7
|
-
<script
|
|
8
|
-
import etro from '../../src/index.js'
|
|
8
|
+
<script>
|
|
9
9
|
let movie
|
|
10
10
|
window.addEventListener('load', () => {
|
|
11
11
|
const canvas = document.createElement('canvas')
|
|
@@ -17,9 +17,13 @@
|
|
|
17
17
|
})
|
|
18
18
|
|
|
19
19
|
const initMovie = canvas => {
|
|
20
|
-
movie = new etro.Movie(canvas)
|
|
21
|
-
movie.addLayer(new etro.layer.Text(
|
|
22
|
-
|
|
20
|
+
movie = new etro.Movie({ canvas })
|
|
21
|
+
movie.addLayer(new etro.layer.Text({
|
|
22
|
+
startTime: 0,
|
|
23
|
+
duration: 4,
|
|
24
|
+
text: 'Hello world',
|
|
25
|
+
font: '24px monospace',
|
|
26
|
+
color: 'blue'
|
|
23
27
|
})).play()
|
|
24
28
|
}
|
|
25
29
|
</script>
|
package/karma.conf.js
CHANGED
|
@@ -30,7 +30,7 @@ module.exports = function (config) {
|
|
|
30
30
|
// test results reporter to use
|
|
31
31
|
// possible values: 'dots', 'progress'
|
|
32
32
|
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
|
|
33
|
-
reporters: ['
|
|
33
|
+
reporters: ['dots'],
|
|
34
34
|
|
|
35
35
|
// web server port
|
|
36
36
|
port: 9876,
|
package/package.json
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "etro",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
6
|
-
"
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "An extendable video-editing framework for the browser and Node",
|
|
5
|
+
"browser": "dist/etro-cjs.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
7
|
"directories": {
|
|
8
8
|
"doc": "docs",
|
|
9
9
|
"example": "examples",
|
|
10
10
|
"test": "spec"
|
|
11
11
|
},
|
|
12
|
-
"dependencies": {
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"standardized-audio-context": "^25.1.13"
|
|
14
|
+
},
|
|
13
15
|
"devDependencies": {
|
|
16
|
+
"@types/dom-mediacapture-record": "^1.0.7",
|
|
17
|
+
"@typescript-eslint/eslint-plugin": "^4.15.2",
|
|
18
|
+
"@typescript-eslint/parser": "^4.15.2",
|
|
14
19
|
"docdash": "^1.1.1",
|
|
15
20
|
"ecstatic": ">=4.1.3",
|
|
16
21
|
"eslint": "^6.5.1",
|
|
@@ -25,24 +30,29 @@
|
|
|
25
30
|
"jasmine": "^3.4.0",
|
|
26
31
|
"jsdoc": "^3.6.3",
|
|
27
32
|
"jsdoc-export-default-interop": "^0.3.1",
|
|
28
|
-
"karma": "^
|
|
33
|
+
"karma": "^6.1.1",
|
|
29
34
|
"karma-chrome-launcher": "^3.1.0",
|
|
30
35
|
"karma-jasmine": "^2.0.1",
|
|
36
|
+
"karma-super-dots-reporter": "^0.2.0",
|
|
31
37
|
"puppeteer": "^2.0.0",
|
|
32
38
|
"rollup": "^1.19.4",
|
|
39
|
+
"rollup-plugin-cleaner": "^1.0.0",
|
|
33
40
|
"rollup-plugin-eslint": "^7.0.0",
|
|
34
41
|
"rollup-plugin-node-resolve": "^5.2.0",
|
|
35
|
-
"rollup-plugin-
|
|
42
|
+
"rollup-plugin-typescript2": "^0.29.0",
|
|
43
|
+
"rollup-plugin-uglify-es": "^0.0.1",
|
|
44
|
+
"typedoc": "^0.20.34",
|
|
45
|
+
"typescript": "^4.1.3"
|
|
36
46
|
},
|
|
37
47
|
"scripts": {
|
|
38
48
|
"build": "rollup -c",
|
|
39
|
-
"doc": "rm -rf docs && npx
|
|
49
|
+
"doc": "rm -rf docs && npx typedoc src/etro.ts --excludePrivate --readme none --theme minimal",
|
|
50
|
+
"assets": "git fetch origin example-assets:example-assets && git cherry-pick example-assets && git reset --soft HEAD^ && git reset HEAD examples/assets",
|
|
40
51
|
"effects": "node scripts/save-effect-samples.js",
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"lint": "npm run --silent lint:main && npm run --silent lint:test",
|
|
44
|
-
"lint:main": "eslint -c eslint.conf.js --ext .js,.html src examples",
|
|
52
|
+
"lint": "npm run --silent lint:main && npm run --silent lint:test && npm run --silent lint:examples",
|
|
53
|
+
"lint:main": "eslint -c eslint.typescript-conf.js --ext .ts src",
|
|
45
54
|
"lint:test": "eslint -c eslint.test-conf.js spec",
|
|
55
|
+
"lint:examples": "eslint -c eslint.example-conf.js --ext .html examples",
|
|
46
56
|
"start": "http-server",
|
|
47
57
|
"test": "karma start"
|
|
48
58
|
},
|
|
@@ -51,10 +61,16 @@
|
|
|
51
61
|
"url": "git+https://github.com/etro-js/etro.git"
|
|
52
62
|
},
|
|
53
63
|
"keywords": [
|
|
64
|
+
"video",
|
|
65
|
+
"audio",
|
|
66
|
+
"blob",
|
|
54
67
|
"video-editing",
|
|
55
68
|
"video-editor",
|
|
69
|
+
"video-manipulation",
|
|
56
70
|
"browser",
|
|
57
|
-
"
|
|
71
|
+
"nodejs",
|
|
72
|
+
"api-driven",
|
|
73
|
+
"etro"
|
|
58
74
|
],
|
|
59
75
|
"author": "Caleb Sacks (https://calebsacks.me)",
|
|
60
76
|
"license": "GPL-3.0",
|
package/rollup.config.js
CHANGED
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
// import uglify from "rollup-plugin-uglify-es";
|
|
2
|
+
import cleaner from 'rollup-plugin-cleaner'
|
|
2
3
|
import resolve from 'rollup-plugin-node-resolve'
|
|
4
|
+
import typescript from 'rollup-plugin-typescript2'
|
|
3
5
|
|
|
4
6
|
export default [
|
|
5
7
|
// iife bundle
|
|
6
8
|
{
|
|
7
|
-
input: 'src/index.
|
|
9
|
+
input: 'src/index.ts',
|
|
8
10
|
output: { file: 'dist/etro-iife.js', format: 'iife', name: 'etro' },
|
|
9
|
-
plugins: [
|
|
11
|
+
plugins: [
|
|
12
|
+
cleaner({
|
|
13
|
+
targets: ['dist']
|
|
14
|
+
}),
|
|
15
|
+
typescript(),
|
|
16
|
+
resolve()
|
|
17
|
+
]
|
|
10
18
|
},
|
|
11
19
|
{
|
|
12
|
-
input: 'src/index.
|
|
20
|
+
input: 'src/index.ts',
|
|
13
21
|
output: { file: 'dist/etro-cjs.js', format: 'cjs' },
|
|
14
|
-
plugins: [
|
|
22
|
+
plugins: [
|
|
23
|
+
typescript(),
|
|
24
|
+
resolve()
|
|
25
|
+
]
|
|
15
26
|
}
|
|
16
27
|
// // es6 module bundle
|
|
17
28
|
// {
|
|
@@ -50,12 +50,14 @@
|
|
|
50
50
|
buffer.height = original.height
|
|
51
51
|
const ctx = buffer.getContext('2d')
|
|
52
52
|
ctx.drawImage(original, 0, 0)
|
|
53
|
-
|
|
54
|
-
// do effect
|
|
55
|
-
effect.apply({
|
|
53
|
+
const movie = {
|
|
56
54
|
canvas: buffer, cctx: ctx,
|
|
57
55
|
width: original.width, height: original.height
|
|
58
|
-
}
|
|
56
|
+
}
|
|
57
|
+
// for util.cache()
|
|
58
|
+
effect._target = { movie }
|
|
59
|
+
// Run effect
|
|
60
|
+
effect.apply(movie)
|
|
59
61
|
|
|
60
62
|
save(buffer, path)
|
|
61
63
|
}
|
|
@@ -65,34 +67,36 @@
|
|
|
65
67
|
save(original, 'original.png')
|
|
66
68
|
|
|
67
69
|
const samples = {
|
|
68
|
-
'gaussian-blur-horizontal.png': new etro.effect.GaussianBlurHorizontal(5),
|
|
69
|
-
'gaussian-blur-vertical.png': new etro.effect.GaussianBlurVertical(5),
|
|
70
|
-
'
|
|
71
|
-
'
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
70
|
+
'gaussian-blur-horizontal.png': new etro.effect.GaussianBlurHorizontal({ radius: 5 }),
|
|
71
|
+
'gaussian-blur-vertical.png': new etro.effect.GaussianBlurVertical({ radius: 5 }),
|
|
72
|
+
'grayscale.png': new etro.effect.Grayscale(),
|
|
73
|
+
'pixelate.png': new etro.effect.Pixelate({ pixelSize: 3 }),
|
|
74
|
+
'transform/translate.png': new etro.effect.Transform({
|
|
75
|
+
matrix: new etro.effect.Transform.Matrix().translate(-3, 5)
|
|
76
|
+
}),
|
|
77
|
+
'transform/translate-fraction.png': new etro.effect.Transform({
|
|
78
|
+
matrix: new etro.effect.Transform.Matrix().translate(0.5, 0.5)
|
|
79
|
+
}),
|
|
80
|
+
'transform/scale.png': new etro.effect.Transform({
|
|
81
|
+
matrix: new etro.effect.Transform.Matrix().scale(2, 2)
|
|
82
|
+
}),
|
|
83
|
+
'transform/scale-fraction.png': new etro.effect.Transform({
|
|
84
|
+
matrix: new etro.effect.Transform.Matrix().scale(0.5, 0.5)
|
|
85
|
+
}),
|
|
86
|
+
'transform/rotate.png': new etro.effect.Transform({
|
|
87
|
+
matrix: new etro.effect.Transform.Matrix().rotate(Math.PI / 6)
|
|
88
|
+
}),
|
|
89
|
+
'transform/multiply.png': new etro.effect.Transform({
|
|
90
|
+
matrix: new etro.effect.Transform.Matrix().scale(2, 2)
|
|
88
91
|
.multiply(new etro.effect.Transform.Matrix().translate(-3, 5))
|
|
89
|
-
)
|
|
92
|
+
})
|
|
90
93
|
}
|
|
91
94
|
|
|
92
95
|
for (let path in samples) {
|
|
93
96
|
const effect = samples[path]
|
|
94
97
|
saveSample(original, effect, path)
|
|
95
98
|
}
|
|
99
|
+
window.done = true
|
|
96
100
|
}
|
|
97
101
|
</script>
|
|
98
102
|
</body>
|
|
@@ -23,21 +23,20 @@ function createDirs(filePath) {
|
|
|
23
23
|
const browser = await puppeteer.launch()
|
|
24
24
|
const page = await browser.newPage()
|
|
25
25
|
|
|
26
|
-
page.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
26
|
+
await page.goto(`file://${__dirname}/gen-effect-samples.html`)
|
|
27
|
+
await page.waitForFunction(() => window.done);
|
|
28
|
+
|
|
29
|
+
const items = await page.$$eval('p', elems => elems.map(p => {
|
|
30
|
+
return { data: p.innerHTML, path: p.dataset.path }
|
|
31
|
+
}))
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
})
|
|
40
|
-
await browser.close()
|
|
33
|
+
items.forEach(item => {
|
|
34
|
+
// remove prefix and save to png
|
|
35
|
+
const buffer = Buffer.from(item.data.replace(/^data:image\/png;base64,/, ''), 'base64')
|
|
36
|
+
console.log(`writing ${item.path} ...`)
|
|
37
|
+
const path = projectDir + '/spec/assets/effect/' + item.path
|
|
38
|
+
createDirs(path)
|
|
39
|
+
fs.writeFileSync(path, buffer)
|
|
41
40
|
})
|
|
42
|
-
await
|
|
41
|
+
await browser.close()
|
|
43
42
|
})()
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|