Skip to content

Commit

Permalink
Fix: allow loading an empty URL string with peaks (katspaugh#3326)
Browse files Browse the repository at this point in the history
* Fix: allow loading an empty URL string with peaks

* Fix tests
  • Loading branch information
katspaugh committed Nov 8, 2023
1 parent 1280065 commit fbb1bae
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 31 deletions.
3 changes: 1 addition & 2 deletions cypress/e2e/options.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -544,9 +544,8 @@ describe('WaveSurfer options tests', () => {
duration: 12.5,
})

expect(wavesurfer.getDuration().toFixed(2)).to.equal('12.50')

wrapReady(wavesurfer, 'redraw').then(() => {
expect(wavesurfer.getDuration().toFixed(2)).to.equal('12.50')
cy.get(id).matchImageSnapshot('pre-decoded-no-audio')
done()
})
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/minimap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ class MinimapPlugin extends BasePlugin<MinimapPluginEvents, MinimapPluginOptions
const media = this.wavesurfer.getMediaElement()
if (!data || !media) return

const peaks = [];
const peaks = []
for (let i = 0; i < data.numberOfChannels; i++) {
peaks.push(data.getChannelData(i));
peaks.push(data.getChannelData(i))
}

this.miniWavesurfer = WaveSurfer.create({
Expand Down
39 changes: 12 additions & 27 deletions src/wavesurfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,11 @@ class WaveSurfer extends Player<WaveSurferEvents> {
this.initTimerEvents()
this.initPlugins()

// Load audio if URL is passed or an external media with an src
const url = this.options.url || this.getSrc()
if (url) {
// Load audio if URL or an external media with an src is passed,
// of render w/o audio if pre-decoded peaks and duration are provided
const url = this.options.url || this.getSrc() || ''
if (url || (this.options.peaks && this.options.duration)) {
this.load(url, this.options.peaks, this.options.duration)
} else if (this.options.peaks && this.options.duration) {
// If pre-decoded peaks and duration are provided, render a waveform w/o loading audio
this.loadPredecoded()
}
}

Expand Down Expand Up @@ -329,21 +327,6 @@ class WaveSurfer extends Player<WaveSurferEvents> {
return this.plugins
}

private async loadPredecoded() {
if (this.options.peaks && this.options.duration) {
this.decodedData = Decoder.createBuffer(this.options.peaks, this.options.duration)
await Promise.resolve() // wait for event listeners to subscribe
this.renderDecoded()
}
}

private async renderDecoded() {
if (this.decodedData) {
this.emit('decode', this.getDuration())
this.renderer.render(this.decodedData)
}
}

private async loadAudio(url: string, blob?: Blob, channelData?: WaveSurferOptions['peaks'], duration?: number) {
this.emit('load', url)

Expand All @@ -362,22 +345,24 @@ class WaveSurfer extends Player<WaveSurferEvents> {

// Wait for the audio duration
// It should be a promise to allow event listeners to subscribe to the ready and decode events
duration =
const audioDuration =
(await Promise.resolve(duration || this.getDuration())) ||
(await new Promise((resolve) => {
this.onceMediaEvent('loadedmetadata', () => resolve(this.getDuration()))
})) ||
(await Promise.resolve(0))
}))

// Decode the audio data or use user-provided peaks
if (channelData) {
this.decodedData = Decoder.createBuffer(channelData, duration)
this.decodedData = Decoder.createBuffer(channelData, audioDuration || 0)
} else if (blob) {
const arrayBuffer = await blob.arrayBuffer()
this.decodedData = await Decoder.decode(arrayBuffer, this.options.sampleRate)
}

this.renderDecoded()
if (this.decodedData) {
this.emit('decode', this.getDuration())
this.renderer.render(this.decodedData)
}

this.emit('ready', this.getDuration())
}
Expand Down Expand Up @@ -464,7 +449,7 @@ class WaveSurfer extends Player<WaveSurferEvents> {
this.setTime(this.getCurrentTime() + seconds)
}

/** Empty the waveform by loading a tiny silent audio */
/** Empty the waveform */
public empty() {
this.load('', [[0]], 0.001)
}
Expand Down

0 comments on commit fbb1bae

Please sign in to comment.