Я хочу сохранить изменения, сделанные с помощью API веб-аудио, в новый файл, который можно будет загрузить. На данный момент я просто хочу, чтобы он сохранялся во втором элементе <audio>
.
Я применяю 3 фильтра к представленному аудио, которые могут изменять высокие, низкие частоты и панорамирование. Я хотел бы, чтобы внесенные изменения были перенесены в новый аудиоэлемент, который будет представлять отредактированный / сохраненный аудиофайл (чтобы позже сохранить его на моем express сервере).
Я не знаю, как это сделать go о сохранении этих изменений в новом аудиоэлементе.
class Home extends Component {
constructor(props) {
super(props)
this.state = {
submittedAudio: false,
fileName: '',
audioFile: '',
submitInfo: '',
savedAudioFile: '',
}
}
componentDidUpdate({ prevProps }, prevState) {
if (prevState.fileName === this.state.fileName) {
console.log('same shit')
return
}
console.log('Home.js updated')
this.mountAudioContext()
}
mountAudioContext() {
this.chunks = []
this.audioContext = new AudioContext()
this.track = this.audioContext.createMediaElementSource(this.audioPlayer.current)
this.track.connect(this.audioContext.destination)
this.gainNode = this.audioContext.createGain()
this.baseFilter = this.audioContext.createBiquadFilter()
this.baseFilter.type = 'lowshelf'
this.baseFilter.frequency.value = 200
this.trebleFilter = this.audioContext.createBiquadFilter()
this.trebleFilter.type = 'highshelf'
this.trebleFilter.frequency.value = 2000
this.pannerOptions = { pan: 0 }
this.panner = new StereoPannerNode(this.audioContext, this.pannerOptions)
this.track.connect(this.gainNode).connect(this.trebleFilter).connect(this.baseFilter).connect(this.panner).connect(this.audioContext.destination)
this.dest = this.audioContext.createMediaStreamDestination()
this.recorder = new MediaRecorder(this.dest.stream)
this.recorder.ondataavailable = (evt) => {
this.chunks.push(evt.data)
}
this.recorder.onstop = (evt) => {
let blob = new Blob(this.chunks, { 'type': 'audio/ogg; codecs=opus' })
let outSide = URL.createObjectURL(blob)
this.setState(state => ({
savedAudioFile: outSide
}))
}
}
async handleSubmit(event) {
event.preventDefault()
try {
const inpFile = this.fileInput.current.files[0]
let outSide = URL.createObjectURL(inpFile)
this.setState(state => ({
submittedAudio: true,
audioFile: outSide,
fileName: this.fileInput.current.files[0].name,
}))
} catch (error) {
console.log('No file provided', error)
this.setState(state => ({
submittedAudio: false,
}))
}
}
handlePlayButton(event) {
if (!this.state.submittedAudio) return
const playButton = this.playButton.current
const audioPlayer = this.audioPlayer.current
if (this.audioContext.state === 'suspended') {
this.audioContext.resume()
}
if (playButton.dataset.playing === 'false') {
audioPlayer.play()
playButton.dataset.playing = 'true'
} else if (playButton.dataset.playing === 'true') {
audioPlayer.pause()
playButton.dataset.playing = 'false'
}
}
handleVolume(event) {
if (!this.state.submittedAudio) return
this.gainNode.gain.value = this.volumeRange.current.value
}
handlePanning(event) {
if (!this.state.submittedAudio) return
console.log(this.pannerRange.current.value)
this.panner.pan.value = this.pannerRange.current.value
}
handleBassFilter(event) {
if (!this.state.submittedAudio) return
this.baseFilter.gain.value = this.bassRange.current.value
console.log(this.baseFilter)
}
handleTrebleFilter(event) {
if (!this.state.submittedAudio) return
this.trebleFilter.gain.value = this.trebleRange.current.value
console.log(this.trebleFilter)
}
handleFinishedAudio(event) {
const playButton = this.playButton.current
playButton.dataset.playing = 'false'
}
handleRecord(event) {
this.recorder.start()
}
handleRecordStop(event) {
this.recorder.stop()
this.chunks.push()
}
render() {
return (
<div style={{ backgroundColor: "gray" }}>
<p>Home</p>
<form onSubmit={this.handleSubmit}
encType="multipart/form-data">
<input type="file" ref={this.fileInput} />
<input type="submit" value="Submit" />
</form>
<div>
{this.state.submittedAudio && <p>{this.state.fileName} submitted.</p>}
{!this.state.submittedAudio && <p>No file submitted</p>}
</div>
<audio controls
crossOrigin=""
ref={this.audioPlayer}
src={this.state.audioFile}
onEnded={this.handleFinishedAudio}>
</audio>
<br />
<Button data-playing="false"
role="switch"
aria-checked="false"
onClick={this.handlePlayButton}
ref={this.playButton}>
<span>Player/Pause</span></Button>
<br />
<RangeSlider min={0} max={10} size={"sm"}></RangeSlider>
<br />
Volume<input type="range"
min="-1"
max="3.4"
step="0.01"
defaultValue="1"
onInput={this.handleVolume}
ref={this.volumeRange}></input>
<br />
<br />
Steroe panning<input type="range"
min="-1"
max="1"
defaultValue="0"
step="0.01"
onInput={this.handlePanning}
ref={this.pannerRange}
></input>
<br />
<br />
Filter Base<input type="range"
min="-3.4"
max="10"
defaultValue="0"
step="0.01"
onInput={this.handleBassFilter}
ref={this.bassRange}
></input>
<br />
<br />
Filter Treble<input type="range"
min="-20"
max="20"
defaultValue="0"
step="0.01"
onInput={this.handleTrebleFilter}
ref={this.trebleRange}
></input>
<br />
<Button onClick={this.postFile}>
PostFile
</Button>
<Button onClick={this.handleRecord}>
Record
</Button>
<Button onClick={this.handleRecordStop}>
Stop record
</Button>
<audio controls
crossOrigin=""
ref={this.savedAudioPlayer}
src={this.state.savedAudioFile}
>
</audio>
</div>
);
}
}