@uppy/audio
Version:
Uppy plugin that records audio using the device’s microphone.
86 lines (85 loc) • 2.99 kB
JavaScript
function _classPrivateFieldLooseBase(e, t) { if (!{}.hasOwnProperty.call(e, t)) throw new TypeError("attempted to use private field on non-instance"); return e; }
var id = 0;
function _classPrivateFieldLooseKey(e) { return "__private_" + id++ + "_" + e; }
// eslint-disable-next-line @typescript-eslint/ban-types
function isFunction(v) {
return typeof v === 'function';
}
function result(v) {
return isFunction(v) ? v() : v;
}
var _draw = /*#__PURE__*/_classPrivateFieldLooseKey("draw");
/* Audio Oscilloscope
https://github.com/miguelmota/audio-oscilloscope
*/
export default class AudioOscilloscope {
// eslint-disable-next-line no-use-before-define
constructor(canvas, options) {
if (options === void 0) {
options = {};
}
Object.defineProperty(this, _draw, {
writable: true,
value: () => this.draw()
});
const canvasOptions = options.canvas || {};
const canvasContextOptions = options.canvasContext || {};
this.analyser = null;
this.bufferLength = 0;
this.canvas = canvas;
this.width = result(canvasOptions.width) || this.canvas.width;
this.height = result(canvasOptions.height) || this.canvas.height;
this.canvas.width = this.width;
this.canvas.height = this.height;
this.canvasContext = this.canvas.getContext('2d');
this.canvasContext.fillStyle = result(canvasContextOptions.fillStyle) || 'rgb(255, 255, 255)';
this.canvasContext.strokeStyle = result(canvasContextOptions.strokeStyle) || 'rgb(0, 0, 0)';
this.canvasContext.lineWidth = result(canvasContextOptions.lineWidth) || 1;
this.onDrawFrame = isFunction(options.onDrawFrame) ? options.onDrawFrame : () => {};
}
addSource(streamSource) {
this.streamSource = streamSource;
this.audioContext = this.streamSource.context;
this.analyser = this.audioContext.createAnalyser();
this.analyser.fftSize = 2048;
this.bufferLength = this.analyser.frequencyBinCount;
this.source = this.audioContext.createBufferSource();
this.dataArray = new Uint8Array(this.bufferLength);
this.analyser.getByteTimeDomainData(this.dataArray);
this.streamSource.connect(this.analyser);
}
draw() {
const {
analyser,
dataArray,
bufferLength
} = this;
const ctx = this.canvasContext;
const w = this.width;
const h = this.height;
if (analyser) {
analyser.getByteTimeDomainData(dataArray);
}
ctx.fillRect(0, 0, w, h);
ctx.beginPath();
const sliceWidth = w * 1.0 / bufferLength;
let x = 0;
if (!bufferLength) {
ctx.moveTo(0, this.height / 2);
}
for (let i = 0; i < bufferLength; i++) {
const v = dataArray[i] / 128.0;
const y = v * (h / 2);
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
x += sliceWidth;
}
ctx.lineTo(w, h / 2);
ctx.stroke();
this.onDrawFrame(this);
requestAnimationFrame(_classPrivateFieldLooseBase(this, _draw)[_draw]);
}
}