diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2021-03-11 14:38:02 +0100 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2021-03-11 14:38:02 +0100 |
| commit | 37896f6960f8145a13e2943fbb0cde52da430d30 (patch) | |
| tree | 40cb7ca2a6b470dc397dd0ba99998ad899a212b0 /animism-align/frontend/app/views/editor/sidebar/components/waveUpload.component.js | |
| parent | 64cd37eae81845dc5eaace17739a72299cfc6c67 (diff) | |
move sidebar and timeline out of align folder
Diffstat (limited to 'animism-align/frontend/app/views/editor/sidebar/components/waveUpload.component.js')
| -rw-r--r-- | animism-align/frontend/app/views/editor/sidebar/components/waveUpload.component.js | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/animism-align/frontend/app/views/editor/sidebar/components/waveUpload.component.js b/animism-align/frontend/app/views/editor/sidebar/components/waveUpload.component.js new file mode 100644 index 0000000..3ca19f0 --- /dev/null +++ b/animism-align/frontend/app/views/editor/sidebar/components/waveUpload.component.js @@ -0,0 +1,191 @@ +import React, { Component } from 'react' +import { connect } from 'react-redux' +import extractPeaks from 'webaudio-peaks' + +import actions from 'app/actions' +import { formatSize, timestampHMS } from 'app/utils' +import { Loader } from 'app/common' + +class WaveUpload extends Component { + state = { + working: false, + status: "", + filename: "", + duration: 0, + } + + upload(e) { + e.preventDefault() + document.body.className = '' + const files = e.dataTransfer ? e.dataTransfer.files : e.target.files + let i + let file + for (i = 0; i < files.length; i++) { + file = files[i] + if (file && file.type.match('image.*')) break + } + if (!file) { + console.log('No file specified') + return + } + this.setState({ working: true, status: "Loading MP3...", filename: file.name, size: file.size, duration: 0 }) + const fileReader = new FileReader() + fileReader.onload = event => { + fileReader.onload = null + this.processAudioFile(file, event.target.result) + } + fileReader.readAsArrayBuffer(file) + } + + processAudioFile(audioFile, arrayBuffer) { + this.setState({ working: true, status: "Extracting peaks..." }) + var audioContext = new (window.AudioContext || window.webkitAudioContext)(); + audioContext.decodeAudioData(arrayBuffer, (audioBuffer) => { + // buffer, samplesPerPixel, isMono, startOffset, endOffset, bitResolution + this.setState({ duration: audioBuffer.duration }) + var peaks = extractPeaks(audioBuffer, 441, true); + console.log(peaks) + const array = Array.from(peaks.data[0]) + const peaksBlob = new Blob([ JSON.stringify(array) ], {type: "application/json"}); + this.uploadAudioAndPeaks(audioFile, peaksBlob) + }) + } + + uploadAudioAndPeaks(audioFile, peaksBlob) { + const { episode } = this.props + const updatedEpisode = { ...episode } + this.setState({ status: "Removing old files..." }) + this.destroyTaggedFile('peaks') + this.destroyTaggedFile('audio') + .then(() => { + return ( + this.uploadTaggedFile( + peaksBlob, + 'peaks', + 'episode-' + this.props.episode.id + '-peaks.json', + {} + ) + ) + }) + .then(peaksResult => { + updatedEpisode.settings.peaks = peaksResult + return ( + this.uploadTaggedFile( + audioFile, + 'audio', + this.state.filename, + { + size: this.state.size, + duration: this.state.duration, + } + ) + ) + }) + .then(audioResult => { + updatedEpisode.settings.audio = audioResult + return actions.episode.update(updatedEpisode) + }) + .then(res => { + this.setState({ + status: "Upload complete", + working: false, + filename: null, + duration: null, + size: null, + }) + }) + } + + uploadTaggedFile(file, tag, fn, meta) { + return new Promise((resolve, reject) => { + this.setState({ status: "Uploading " + tag + "..." }) + const uploadData = { + tag, + file, + __file_filename: fn, + username: this.props.currentUser.username, + } + // console.log(uploadData) + return actions.upload.upload(uploadData).then(data => { + // console.log(data) + resolve({ + ...data.res, + ...meta + }) + }) + }) + } + + destroyTaggedFile(tag) { + return new Promise((resolve, reject) => { + if (!this.props.episode.settings[tag]) { + return resolve(); + } + actions.upload.destroy(this.props.episode.settings[tag]) + .then(() => { + console.log('Destroy successful') + resolve() + }) + .catch(() => { + console.log('Error deleting the image') + reject() + }) + }) + } + + render() { + const { episode, peaks } = this.props + // console.log(episode) + return ( + <div className="sidebar-content wave-upload"> + {episode.settings.audio && ( + <div> + <small>{episode.settings.audio.fn}</small> + <small>{'Size: '}{formatSize(episode.settings.audio.size)}</small> + <small>{'Duration: '}{timestampHMS(episode.settings.audio.duration)}</small> + </div> + )} + {peaks.length && ( + <div> + Peaks: {peaks.length} + </div> + )} + <div className="uploadButton"> + <button> + <span> + {episode.settings.audio + ? "Upload a new audio file" + : "Upload an audio file" + } + </span> + </button> + <input + type="file" + accept="audio/mp3" + onChange={this.upload.bind(this)} + required={this.props.required} + /> + </div> + <small>Upload an MP3, encoded 192kbit constant bitrate, 44.1kHz stereo</small> + {this.state.status && ( + <div className='status'> + {this.state.working && <Loader />} + <div className='status-message'>{this.state.status}</div> + {this.state.filename && <small>{this.state.filename}</small>} + {this.state.size && <small>{'Size: '}{formatSize(this.state.size)}</small>} + {!!this.state.duration && <small>{'Duration: '}{timestampHMS(this.state.duration)}</small>} + </div> + )} + </div> + ) + } +} + +const mapStateToProps = state => ({ + peaks: state.align.peaks, + currentUser: state.auth.user, + project: state.site.project, + episode: state.site.episode, +}) + +export default connect(mapStateToProps)(WaveUpload) |
