Skip to content

Commit

Permalink
MediaElement safari fixes (#1964)
Browse files Browse the repository at this point in the history
* rewrite mediaelement-webaudio comment

* resume audiocontext for Safari + mediaelement/webaudio

this was happening in the webaudio backend, but due to the odd
inheritance layout of mediaelement-webaudio it wasn't happening here.

* add changelog entry

* hoist common code into utility function

* generalize comment
  • Loading branch information
osheroff committed Jun 15, 2020
1 parent 52e7ac7 commit f96f3b3
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -4,6 +4,7 @@ wavesurfer.js changelog
4.0.0 (unreleased)
------------------

- Fixed mediaelement-webaudio playback under Safari (#1964)
- Fixed the `destroy` method of the `MediaElementWebAudio` backend. Instead of
destroying only the media element, the audio nodes are disconnected and the
audio context is closed. This was done by splitting the `destroy` method of the
Expand Down
16 changes: 10 additions & 6 deletions src/mediaelement-webaudio.js
@@ -1,12 +1,11 @@
import MediaElement from './mediaelement';

/**
* MediaElementWebAudio backend: allows to load audio as HTML5 audio tag and use it with WebAudio API.
* Setting the MediaElementWebAudio backend, there is the possibility to load audio of big dimensions, using the WebAudio API features.
* The audio to load is an HTML5 audio tag, so you have to use the same methods of MediaElement backend for loading and playback.
* In this way, the audio resource is not loaded entirely from server, but in ranges, since you load an HTML5 audio tag.
* In this way, filters and other functionalities can be performed like with WebAudio backend, but without decoding
* internally audio data, that caused crashing of the browser. You have to give also peaks, so the audio data are not decoded.
* MediaElementWebAudio backend: load audio via an HTML5 audio tag, but playback with the WebAudio API.
* The advantage here is that the html5 <audio> tag can perform range requests on the server and not
* buffer the entire file in one request, and you still get the filtering and scripting functionality
* of the webaudio API.
* Note that in order to use range requests and prevent buffering, you must provide peak data.
*
* @since 3.2.0
*/
Expand Down Expand Up @@ -60,6 +59,11 @@ export default class MediaElementWebAudio extends MediaElement {
this.sourceMediaElement.connect(this.analyser);
}

play(start, end) {
this.resumeAudioContext();
return super.play(start, end);
}

/**
* This is called when wavesurfer is destroyed
*
Expand Down
15 changes: 12 additions & 3 deletions src/webaudio.js
Expand Up @@ -575,6 +575,17 @@ export default class WebAudio extends util.Observer {
this.source.connect(this.analyser);
}

/**
* @private
*
* some browsers require an explicit call to #resume before they will play back audio
*/
resumeAudioContext() {
if (this.ac.state == 'suspended') {
this.ac.resume && this.ac.resume();
}
}

/**
* Used by `wavesurfer.isPlaying()` and `wavesurfer.playPause()`
*
Expand Down Expand Up @@ -670,9 +681,7 @@ export default class WebAudio extends util.Observer {

this.source.start(0, start);

if (this.ac.state == 'suspended') {
this.ac.resume && this.ac.resume();
}
this.resumeAudioContext();

this.setState(PLAYING);

Expand Down

0 comments on commit f96f3b3

Please sign in to comment.