@es-joy/jsoe 0.8.0 → 0.9.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/.nyc_output/out.json +11255 -6080
- package/CHANGES.md +9 -0
- package/README.md +3 -2
- package/demo/index.js +16 -3
- package/package.json +1 -1
- package/src/formats/structuredCloning.js +9 -11
- package/src/fundamentalTypes/arrayType.js +4 -1
- package/src/fundamentalTypes/blobType.js +1001 -0
- package/src/fundamentalTypes/fileType.js +1 -101
- package/src/jsoe.css +4 -0
- package/src/types.js +3 -1
- package/src/utils/media.js +103 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {jml} from '../vendor-imports.js';
|
|
2
2
|
import {$e} from '../utils/templateUtils.js';
|
|
3
|
+
import {visualize, getUserMedia, startScreenCapture} from '../utils/media.js';
|
|
3
4
|
import dialogs from '../utils/dialogs.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -13,107 +14,6 @@ import dialogs from '../utils/dialogs.js';
|
|
|
13
14
|
* @typedef {(file: FileInfo) => void} SetValue
|
|
14
15
|
*/
|
|
15
16
|
|
|
16
|
-
/** @type {AudioContext} */
|
|
17
|
-
let audioCtx;
|
|
18
|
-
/**
|
|
19
|
-
* @param {MediaStream} stream
|
|
20
|
-
* @param {HTMLCanvasElement} canvas
|
|
21
|
-
* @see Adapted from {@link https://mdn.github.io/dom-examples/media/web-dictaphone/}
|
|
22
|
-
* @returns {void}
|
|
23
|
-
*/
|
|
24
|
-
function visualize (stream, canvas) {
|
|
25
|
-
if (!audioCtx) {
|
|
26
|
-
audioCtx = new AudioContext();
|
|
27
|
-
}
|
|
28
|
-
const canvasCtx = /** @type {CanvasRenderingContext2D} */ (
|
|
29
|
-
canvas.getContext('2d')
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
const source = audioCtx.createMediaStreamSource(stream);
|
|
33
|
-
|
|
34
|
-
const analyser = audioCtx.createAnalyser();
|
|
35
|
-
analyser.fftSize = 2048;
|
|
36
|
-
const bufferLength = analyser.frequencyBinCount;
|
|
37
|
-
const dataArray = new Uint8Array(bufferLength);
|
|
38
|
-
|
|
39
|
-
source.connect(analyser);
|
|
40
|
-
// analyser.connect(audioCtx.destination);
|
|
41
|
-
|
|
42
|
-
draw();
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* @returns {void}
|
|
46
|
-
*/
|
|
47
|
-
function draw () {
|
|
48
|
-
const WIDTH = canvas.width;
|
|
49
|
-
const HEIGHT = canvas.height;
|
|
50
|
-
|
|
51
|
-
requestAnimationFrame(draw);
|
|
52
|
-
|
|
53
|
-
analyser.getByteTimeDomainData(dataArray);
|
|
54
|
-
|
|
55
|
-
canvasCtx.fillStyle = 'rgb(200, 200, 200)';
|
|
56
|
-
canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);
|
|
57
|
-
|
|
58
|
-
canvasCtx.lineWidth = 2;
|
|
59
|
-
canvasCtx.strokeStyle = 'rgb(0, 0, 0)';
|
|
60
|
-
|
|
61
|
-
canvasCtx.beginPath();
|
|
62
|
-
|
|
63
|
-
const sliceWidth = WIDTH * 1 / bufferLength;
|
|
64
|
-
let x = 0;
|
|
65
|
-
|
|
66
|
-
for (let i = 0; i < bufferLength; i++) {
|
|
67
|
-
const v = dataArray[i] / 128;
|
|
68
|
-
const y = v * HEIGHT / 2;
|
|
69
|
-
|
|
70
|
-
if (i === 0) {
|
|
71
|
-
canvasCtx.moveTo(x, y);
|
|
72
|
-
} else {
|
|
73
|
-
canvasCtx.lineTo(x, y);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
x += sliceWidth;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
canvasCtx.lineTo(canvas.width, canvas.height / 2);
|
|
80
|
-
canvasCtx.stroke();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* @param {MediaStreamConstraints} constraints
|
|
86
|
-
* @returns {Promise<MediaStream|null>}
|
|
87
|
-
*/
|
|
88
|
-
async function getUserMedia (constraints) {
|
|
89
|
-
let stream = null;
|
|
90
|
-
try {
|
|
91
|
-
stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
92
|
-
/* c8 ignore next 4 */
|
|
93
|
-
} catch (err) {
|
|
94
|
-
console.error('err', err);
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
return stream;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* @param {DisplayMediaStreamOptions|undefined} displayMediaOptions
|
|
102
|
-
* @returns {Promise<MediaStream|null>}
|
|
103
|
-
*/
|
|
104
|
-
async function startScreenCapture (displayMediaOptions) {
|
|
105
|
-
let captureStream = null;
|
|
106
|
-
|
|
107
|
-
try {
|
|
108
|
-
captureStream =
|
|
109
|
-
await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
|
|
110
|
-
/* c8 ignore next 3 */
|
|
111
|
-
} catch (err) {
|
|
112
|
-
console.error(`Error: ${err}`);
|
|
113
|
-
}
|
|
114
|
-
return captureStream;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
17
|
/**
|
|
118
18
|
* @param {number} timestamp
|
|
119
19
|
* @returns {string}
|
package/src/jsoe.css
CHANGED
package/src/types.js
CHANGED
|
@@ -35,6 +35,7 @@ import SpecialNumberSuperType from './superTypes/SpecialNumberType.js';
|
|
|
35
35
|
import errorType from './fundamentalTypes/errorType.js';
|
|
36
36
|
import errorsSpecialType from './superTypes/errorsSpecialType.js';
|
|
37
37
|
import fileType from './fundamentalTypes/fileType.js';
|
|
38
|
+
import blobType from './fundamentalTypes/blobType.js';
|
|
38
39
|
|
|
39
40
|
/**
|
|
40
41
|
* Utility to retrieve the property value given a legend element.
|
|
@@ -388,6 +389,7 @@ Types.availableTypes = {
|
|
|
388
389
|
filelist: {
|
|
389
390
|
option: ['FileList']
|
|
390
391
|
},
|
|
392
|
+
blob: blobType,
|
|
391
393
|
blobHTML: blobHTMLType,
|
|
392
394
|
arraybuffer: {
|
|
393
395
|
option: ['ArrayBuffer']
|
|
@@ -470,7 +472,7 @@ Types.availableTypes = {
|
|
|
470
472
|
* "int8array"|"uint8array"|"uint8clampedarray"|"int16array"|"uint16array"|
|
|
471
473
|
* "int32array"|"uint32array"|"float32array"|"float64array"|"IntlCollator"|
|
|
472
474
|
* "IntlDateTimeFormat"|"IntlNumberFormat"|"ValidDate"|
|
|
473
|
-
* "arrayNonindexKeys"|"error"|"errors"} AvailableType
|
|
475
|
+
* "arrayNonindexKeys"|"error"|"errors"|"blob"} AvailableType
|
|
474
476
|
*/
|
|
475
477
|
|
|
476
478
|
/**
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/** @type {AudioContext} */
|
|
2
|
+
let audioCtx;
|
|
3
|
+
/**
|
|
4
|
+
* @param {MediaStream} stream
|
|
5
|
+
* @param {HTMLCanvasElement} canvas
|
|
6
|
+
* @see Adapted from {@link https://mdn.github.io/dom-examples/media/web-dictaphone/}
|
|
7
|
+
* @returns {void}
|
|
8
|
+
*/
|
|
9
|
+
function visualize (stream, canvas) {
|
|
10
|
+
if (!audioCtx) {
|
|
11
|
+
audioCtx = new AudioContext();
|
|
12
|
+
}
|
|
13
|
+
const canvasCtx = /** @type {CanvasRenderingContext2D} */ (
|
|
14
|
+
canvas.getContext('2d')
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
const source = audioCtx.createMediaStreamSource(stream);
|
|
18
|
+
|
|
19
|
+
const analyser = audioCtx.createAnalyser();
|
|
20
|
+
analyser.fftSize = 2048;
|
|
21
|
+
const bufferLength = analyser.frequencyBinCount;
|
|
22
|
+
const dataArray = new Uint8Array(bufferLength);
|
|
23
|
+
|
|
24
|
+
source.connect(analyser);
|
|
25
|
+
// analyser.connect(audioCtx.destination);
|
|
26
|
+
|
|
27
|
+
draw();
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @returns {void}
|
|
31
|
+
*/
|
|
32
|
+
function draw () {
|
|
33
|
+
const WIDTH = canvas.width;
|
|
34
|
+
const HEIGHT = canvas.height;
|
|
35
|
+
|
|
36
|
+
requestAnimationFrame(draw);
|
|
37
|
+
|
|
38
|
+
analyser.getByteTimeDomainData(dataArray);
|
|
39
|
+
|
|
40
|
+
canvasCtx.fillStyle = 'rgb(200, 200, 200)';
|
|
41
|
+
canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);
|
|
42
|
+
|
|
43
|
+
canvasCtx.lineWidth = 2;
|
|
44
|
+
canvasCtx.strokeStyle = 'rgb(0, 0, 0)';
|
|
45
|
+
|
|
46
|
+
canvasCtx.beginPath();
|
|
47
|
+
|
|
48
|
+
const sliceWidth = WIDTH * 1 / bufferLength;
|
|
49
|
+
let x = 0;
|
|
50
|
+
|
|
51
|
+
for (let i = 0; i < bufferLength; i++) {
|
|
52
|
+
const v = dataArray[i] / 128;
|
|
53
|
+
const y = v * HEIGHT / 2;
|
|
54
|
+
|
|
55
|
+
if (i === 0) {
|
|
56
|
+
canvasCtx.moveTo(x, y);
|
|
57
|
+
} else {
|
|
58
|
+
canvasCtx.lineTo(x, y);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
x += sliceWidth;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
canvasCtx.lineTo(canvas.width, canvas.height / 2);
|
|
65
|
+
canvasCtx.stroke();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @param {MediaStreamConstraints} constraints
|
|
72
|
+
* @returns {Promise<MediaStream|null>}
|
|
73
|
+
*/
|
|
74
|
+
async function getUserMedia (constraints) {
|
|
75
|
+
let stream = null;
|
|
76
|
+
try {
|
|
77
|
+
stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
78
|
+
/* c8 ignore next 4 */
|
|
79
|
+
} catch (err) {
|
|
80
|
+
console.error('err', err);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
return stream;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @param {DisplayMediaStreamOptions|undefined} displayMediaOptions
|
|
88
|
+
* @returns {Promise<MediaStream|null>}
|
|
89
|
+
*/
|
|
90
|
+
async function startScreenCapture (displayMediaOptions) {
|
|
91
|
+
let captureStream = null;
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
captureStream =
|
|
95
|
+
await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
|
|
96
|
+
/* c8 ignore next 3 */
|
|
97
|
+
} catch (err) {
|
|
98
|
+
console.error(`Error: ${err}`);
|
|
99
|
+
}
|
|
100
|
+
return captureStream;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export {visualize, getUserMedia, startScreenCapture};
|