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.tsx119
1 files changed, 92 insertions, 27 deletions
diff --git a/src/client/views/AudioWaveform.tsx b/src/client/views/AudioWaveform.tsx
index 7ff9c1071..8f3b7c2cd 100644
--- a/src/client/views/AudioWaveform.tsx
+++ b/src/client/views/AudioWaveform.tsx
@@ -6,56 +6,121 @@ import Waveform from "react-audio-waveform";
import { Doc } from "../../fields/Doc";
import { List } from "../../fields/List";
import { listSpec } from "../../fields/Schema";
-import { Cast } from "../../fields/Types";
+import { Cast, NumCast } from "../../fields/Types";
import { numberRange } from "../../Utils";
import "./AudioWaveform.scss";
+import { Colors } from "./global/globalEnums";
export interface AudioWaveformProps {
duration: number;
mediaPath: string;
- dataDoc: Doc;
+ layoutDoc: Doc;
+ trimming: boolean;
PanelHeight: () => number;
}
@observer
export class AudioWaveform extends React.Component<AudioWaveformProps> {
public static NUMBER_OF_BUCKETS = 100;
- @computed get _waveHeight() { return Math.max(50, this.props.PanelHeight()); }
+ @computed get _waveHeight() {
+ return Math.max(50, this.props.PanelHeight());
+ }
componentDidMount() {
- const audioBuckets = Cast(this.props.dataDoc.audioBuckets, listSpec("number"), []);
+ const audioBuckets = Cast(
+ this.props.layoutDoc.audioBuckets,
+ listSpec("number"),
+ []
+ );
if (!audioBuckets.length) {
- this.props.dataDoc.audioBuckets = new List<number>([0, 0]); /// "lock" to prevent other views from computing the same data
+ this.props.layoutDoc.audioBuckets = new List<number>([0, 0]); /// "lock" to prevent other views from computing the same data
setTimeout(this.createWaveformBuckets);
}
}
+
// decodes the audio file into peaks for generating the waveform
createWaveformBuckets = async () => {
- axios({ url: this.props.mediaPath, responseType: "arraybuffer" })
- .then(response => {
+ axios({ url: this.props.mediaPath, responseType: "arraybuffer" }).then(
+ (response) => {
const context = new window.AudioContext();
- context.decodeAudioData(response.data,
- action(buffer => {
+ context.decodeAudioData(
+ response.data,
+ action((buffer) => {
const decodedAudioData = buffer.getChannelData(0);
- const bucketDataSize = Math.floor(decodedAudioData.length / AudioWaveform.NUMBER_OF_BUCKETS);
+
+ const bucketDataSize = Math.floor(
+ decodedAudioData.length / AudioWaveform.NUMBER_OF_BUCKETS
+ );
const brange = Array.from(Array(bucketDataSize));
- this.props.dataDoc.audioBuckets = new List<number>(
- numberRange(AudioWaveform.NUMBER_OF_BUCKETS).map((i: number) =>
- brange.reduce((p, x, j) => Math.abs(Math.max(p, decodedAudioData[i * bucketDataSize + j])), 0) / 2));
- }));
- });
+ this.props.layoutDoc.audioBuckets = new List<number>(
+ numberRange(AudioWaveform.NUMBER_OF_BUCKETS).map(
+ (i: number) =>
+ brange.reduce(
+ (p, x, j) =>
+ Math.abs(
+ Math.max(p, decodedAudioData[i * bucketDataSize + j])
+ ),
+ 0
+ ) / 2
+ )
+ );
+ })
+ );
+ }
+ );
+ }
+
+ @action
+ createTrimBuckets = () => {
+ const audioBuckets = Cast(
+ this.props.layoutDoc.audioBuckets,
+ listSpec("number"),
+ []
+ );
+
+ const start = Math.floor(
+ (NumCast(this.props.layoutDoc.clipStart) / this.props.duration) * 100
+ );
+ const end = Math.floor(
+ (NumCast(this.props.layoutDoc.clipEnd) / this.props.duration) * 100
+ );
+ return audioBuckets.slice(start, end);
}
render() {
- const audioBuckets = Cast(this.props.dataDoc.audioBuckets, listSpec("number"), []);
- return <div className="audioWaveform">
- <Waveform
- color={"darkblue"}
- height={this._waveHeight}
- barWidth={0.1}
- pos={this.props.duration}
- duration={this.props.duration}
- peaks={audioBuckets.length === AudioWaveform.NUMBER_OF_BUCKETS ? audioBuckets : undefined}
- progressColor={"blue"} />
- </div>;
+ const audioBuckets = Cast(
+ this.props.layoutDoc.audioBuckets,
+ listSpec("number"),
+ []
+ );
+
+ return (
+ <div className="audioWaveform">
+ {this.props.trimming || !this.props.layoutDoc.clipEnd ? (
+ <Waveform
+ color={Colors.MEDIUM_BLUE}
+ height={this._waveHeight}
+ barWidth={0.1}
+ pos={this.props.duration}
+ duration={this.props.duration}
+ peaks={
+ audioBuckets.length === AudioWaveform.NUMBER_OF_BUCKETS
+ ? audioBuckets
+ : undefined
+ }
+ progressColor={Colors.MEDIUM_BLUE}
+ />
+ ) : (
+ <Waveform
+ color={Colors.MEDIUM_BLUE}
+ height={this._waveHeight}
+ barWidth={0.1}
+ pos={this.props.duration}
+ duration={this.props.duration}
+ peaks={this.createTrimBuckets()}
+ progressColor={Colors.MEDIUM_BLUE}
+ />
+ )}
+ </div>
+ );
}
-} \ No newline at end of file
+}