Skip to content

Commit

Permalink
Feat: restore the "backend: 'WebAudio'" option (#3281)
Browse files Browse the repository at this point in the history
* Feat: webaudio "backend"

* Prettier

* Tests

* Update readme

* Fix test
  • Loading branch information
katspaugh authored Oct 19, 2023
1 parent b305634 commit c912f85
Show file tree
Hide file tree
Showing 8 changed files with 626 additions and 495 deletions.
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,15 @@ See [this example](https://wavesurfer.xyz/examples/?styling.js) for play around
Most options, events, and methods are similar to those in previous versions.

### Notable differences
* The `backend` option is removed – [HTML5 audio (or video) is the only playback mechanism](https://github.com/katspaugh/wavesurfer.js/discussions/2762#discussioncomment-5669347). However, you can still connect wavesurfer to Web Audio via `MediaElementSourceNode`. See this [example](https://wavesurfer.xyz/examples/?webaudio.js).
* The Markers plugin is removed – you should use the Regions plugin with just a `startTime`.
* No Microphone plugin – superseded by the new Record plugin with more features.
* The Cursor plugin is replaced by the Hover plugin.

### Removed options
* `backend`, `audioContext`, `closeAudioContext`, `audioScriptProcessor` – there's no Web Audio backend, so no AudioContext
* `audioContext`, `closeAudioContext`, `audioScriptProcessor`
* `autoCenterImmediately``autoCenter` is now always immediate unless the audio is playing
* `backgroundColor`, `hideCursor` – this can be easily set via CSS
* `mediaType`, `mediaControls` – you should instead pass an entire media element in the `media` option. [Example](https://wavesurfer.xyz/examples/?video.js).
* `mediaType` – you should instead pass an entire media element in the `media` option. [Example](https://wavesurfer.xyz/examples/?video.js).
* `partialRender` – done by default
* `pixelRatio``window.devicePixelRatio` is used by default
* `renderer` – there's just one renderer for now, so no need for this option
Expand All @@ -117,7 +116,7 @@ Most options, events, and methods are similar to those in previous versions.
* `barMinHeight` - the minimum bar height is now 1 pixel by default

### Removed methods
* `getFilters`, `setFilter`as there's no Web Audio "backend"
* `getFilters`, `setFilter`see the [Web Audio example](https://wavesurfer.xyz/examples/?webaudio.js)
* `drawBuffer` – to redraw the waveform, use `setOptions` instead and pass new rendering options
* `cancelAjax` – you can pass an [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) in `fetchParams`
* `skipForward`, `skipBackward`, `setPlayEnd` – can be implemented using `setTime(time)`
Expand Down
52 changes: 21 additions & 31 deletions cypress/e2e/basic.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,41 +177,37 @@ describe('WaveSurfer basic tests', () => {
})
})

describe('setMediaElement', () => {
const MEDIA_EVENTS = ['timeupdate', 'play', 'pause', 'emptied', 'ended', 'seeking']
let orignalMedia

describe.only('setMediaElement', () => {
// Mock add/remove event listeners for `media` elements
const attachMockListeners = (el) => {
el.eventListenerList = {}
el.addEventListener = (eventName, callback, options) => {
if (!el.eventListenerList[eventName]) el.eventListenerList[eventName] = [];
el.eventListenerList[eventName].push(callback);
};
el.eventCount = 0

const addEventListener = el.addEventListener
el.addEventListener = (eventName, callback, options) => {
if (!options || !options.once) el.eventCount++
addEventListener.call(el, eventName, callback, options)
}
const removeEventListener = el.removeEventListener
el.removeEventListener = (eventName, callback) => {
if (el.eventListenerList[eventName]) delete el.eventListenerList[eventName]
el.eventCount--
removeEventListener.call(el, eventName, callback)
}
}

beforeEach((done) => {
cy.window().then((win) => {
win.wavesurfer.destroy()

orignalMedia = document.createElement('audio')
attachMockListeners(orignalMedia)

const waitForReady = new Promise((resolve) => {
win.wavesurfer = win.WaveSurfer.create({
container: '#waveform',
url: '../../examples/audio/demo.wav',
media: orignalMedia
})
const originalMedia = document.createElement('audio')
attachMockListeners(originalMedia)

win.wavesurfer.once('ready', () => resolve())
win.wavesurfer = win.WaveSurfer.create({
container: '#waveform',
url: '../../examples/audio/demo.wav',
media: originalMedia,
})

cy.wrap(waitForReady).then(done)
win.wavesurfer.once('ready', () => done())
})
})

Expand All @@ -226,15 +222,13 @@ describe('WaveSurfer basic tests', () => {

it('should unsubscribe events from removed media element', () => {
cy.window().then((win) => {
const originalMedia = win.wavesurfer.getMediaElement()
const media = document.createElement('audio')

MEDIA_EVENTS.forEach((event) => {
expect(orignalMedia.eventListenerList[event]).to.exist
expect(orignalMedia.eventListenerList[event].length).to.equal(1)
})
expect(originalMedia.eventCount).to.be.greaterThan(0)

win.wavesurfer.setMediaElement(media)
expect(orignalMedia.eventListenerList).to.be.empty
expect(originalMedia.eventCount).to.equal(0)
})
})

Expand All @@ -244,13 +238,9 @@ describe('WaveSurfer basic tests', () => {
attachMockListeners(newMedia)

win.wavesurfer.setMediaElement(newMedia)
MEDIA_EVENTS.forEach((event) => {
expect(newMedia.eventListenerList[event]).to.exist
expect(newMedia.eventListenerList[event].length).to.equal(1)
})
expect(newMedia.eventCount).to.be.greaterThan(0)
})
})

})

it('should return true when calling isPlaying() after play()', (done) => {
Expand Down
Loading

0 comments on commit c912f85

Please sign in to comment.