diff options
Diffstat (limited to 'src/client/views/AudioWaveform.tsx')
-rw-r--r-- | src/client/views/AudioWaveform.tsx | 119 |
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 +} |