aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/AudioWaveform.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/AudioWaveform.tsx')
-rw-r--r--src/client/views/AudioWaveform.tsx137
1 files changed, 22 insertions, 115 deletions
diff --git a/src/client/views/AudioWaveform.tsx b/src/client/views/AudioWaveform.tsx
index 8a3c3c319..525c0ce5a 100644
--- a/src/client/views/AudioWaveform.tsx
+++ b/src/client/views/AudioWaveform.tsx
@@ -1,16 +1,26 @@
import React = require("react");
import axios from "axios";
-import { action, computed, reaction, IReactionDisposer } from "mobx";
+import { action, computed, IReactionDisposer, reaction } from "mobx";
import { observer } from "mobx-react";
import Waveform from "react-audio-waveform";
import { Doc } from "../../fields/Doc";
import { List } from "../../fields/List";
import { listSpec } from "../../fields/Schema";
-import { Cast, NumCast } from "../../fields/Types";
+import { Cast } from "../../fields/Types";
import { numberRange } from "../../Utils";
import "./AudioWaveform.scss";
import { Colors } from "./global/globalEnums";
-import Color = require("color");
+
+
+/**
+ * AudioWaveform
+ *
+ * Used in CollectionStackedTimeline to render a canvas with a visual of an audio waveform for AudioBox and VideoBox documents.
+ * Uses react-audio-waveform package.
+ * Bins the audio data into audioBuckets which are passed to package to render the lines.
+ * Calculates new buckets each time a new zoom factor or new set of trim bounds is created and stores it in a field on the layout doc with a title indicating the bounds and zoom for that list (see audioBucketField)
+ */
+
export interface AudioWaveformProps {
duration: number; // length of media clip
@@ -26,19 +36,24 @@ export interface AudioWaveformProps {
@observer
export class AudioWaveform extends React.Component<AudioWaveformProps> {
- public static NUMBER_OF_BUCKETS = 100;
+ public static NUMBER_OF_BUCKETS = 100; // number of buckets data is divided into to draw waveform lines
+
_disposer: IReactionDisposer | undefined;
+
@computed get waveHeight() { return Math.max(50, this.props.PanelHeight); }
+
@computed get clipStart() { return this.props.clipStart; }
@computed get clipEnd() { return this.props.clipEnd; }
@computed get zoomFactor() { return this.props.zoomFactor; }
- @computed get audioBuckets() { return Cast(this.props.layoutDoc[this.audioBucketField(this.clipStart, this.clipEnd, this.zoomFactor)], listSpec("number"), []); }
+ @computed get audioBuckets() { return Cast(this.props.layoutDoc[this.audioBucketField(this.clipStart, this.clipEnd, this.zoomFactor)], listSpec("number"), []); }
audioBucketField = (start: number, end: number, zoomFactor: number) => "audioBuckets/" + "/" + start.toFixed(2).replace(".", "_") + "/" + end.toFixed(2).replace(".", "_") + "/" + (zoomFactor * 10);
+
componentWillUnmount() {
this._disposer?.();
}
+
componentDidMount() {
this._disposer = reaction(() => ({ clipStart: this.clipStart, clipEnd: this.clipEnd, fieldKey: this.audioBucketField(this.clipStart, this.clipEnd, this.zoomFactor), zoomFactor: this.props.zoomFactor }),
({ clipStart, clipEnd, fieldKey, zoomFactor }) => {
@@ -49,7 +64,6 @@ export class AudioWaveform extends React.Component<AudioWaveformProps> {
setTimeout(() => this.createWaveformBuckets(fieldKey, clipStart, clipEnd, zoomFactor));
}
}, { fireImmediately: true });
-
}
// decodes the audio file into peaks for generating the waveform
@@ -86,16 +100,10 @@ export class AudioWaveform extends React.Component<AudioWaveformProps> {
}
);
}
+
render() {
return (
<div className="audioWaveform">
- {/* <Waveform
- barWidth={2}
- width={() => this.props.PanelWidth}
- height={this.props.PanelHeight}
- peaks={this.audioBuckets}
- color={Colors.MEDIUM_BLUE}
- /> */}
<Waveform
color={Colors.MEDIUM_BLUE_ALT}
height={this.waveHeight}
@@ -108,105 +116,4 @@ export class AudioWaveform extends React.Component<AudioWaveformProps> {
</div>
);
}
-}
-
-
-export interface WaveformProps {
- barWidth: number;
- width: () => number;
- height: () => number;
- peaks: number[];
- color: string;
-}
-
-// @observer
-// export class Waveform extends React.Component<WaveformProps> {
-// private _canvas: HTMLCanvasElement | null = null;
-
-// get width() { return this.props.width(); }
-// get height() { return this.props.height(); }
-// get peaks() { return this.props.peaks; }
-
-// componentDidMount() {
-// this.drawBars();
-// }
-
-// drawBars() {
-// const waveCanvasCtx = this._canvas?.getContext("2d");
-
-// if (waveCanvasCtx) {
-// const pixelRatio = window.devicePixelRatio;
-// console.log(pixelRatio);
-
-// const displayWidth = Math.round(this.width);
-// const displayHeight = Math.round(this.height);
-// waveCanvasCtx.canvas.width = this.width;
-// waveCanvasCtx.canvas.height = this.height;
-// waveCanvasCtx.canvas.style.width = `${displayWidth}px`;
-// waveCanvasCtx.canvas.style.height = `${displayHeight}px`;
-
-// waveCanvasCtx.clearRect(0, 0, this.width, this.height);
-
-// const hasMinVals = [].some.call(this.peaks, (val) => val < 0);
-// let filteredPeaks = this.peaks;
-// if (hasMinVals) {
-// // If the first value is negative, add 1 to the filtered indices
-// let indexOffset = 0;
-// if (this.peaks[0] < 0) {
-// indexOffset = 1;
-// }
-// filteredPeaks = [].filter.call(
-// this.peaks,
-// (_, index) => (index + indexOffset) % 2 == 0
-// );
-// }
-
-// const $ = 0.5;
-// const height = this.height;
-// const offsetY = 0;
-// const halfH = this.height / 2;
-// const length = filteredPeaks.length;
-// const bar = this.props.barWidth;
-// const gap = 2;
-// const step = bar + gap;
-
-// let absmax = 1;
-// absmax = this.absMax(filteredPeaks);
-
-// const scale = length / this.width;
-
-// waveCanvasCtx.fillStyle = this.props.color;
-
-// for (let i = 0; i < this.width; i += step) {
-// let h = Math.round(filteredPeaks[Math.floor(i * scale)] / absmax * halfH)
-// if (h === 0) {
-// h = 1
-// }
-// waveCanvasCtx.fillRect(i + $, halfH - h + offsetY, bar + $, h * 2)
-// }
-// }
-// }
-
-// absMax = (values: number[]) => {
-// let max = -Infinity;
-// for (const i in values) {
-// const num = Math.abs(values[i]);
-// if (num > max) {
-// max = num;
-// }
-// }
-
-// return max;
-// }
-
-
-// render() {
-// return this.props.peaks ? (
-// <canvas
-// ref={(instance) => {
-// this._canvas = instance;
-// }}
-// />
-// ) : null
-// }
-// } \ No newline at end of file
+} \ No newline at end of file