createAudio() unconditionally sets crossOrigin = 'anonymous' on the audio element it creates:
createAudio() {
if (this.options.audioMode === 'external') {
this.audio = null;
return;
}
this.audio = new Audio();
this.audio.preload = this.options.preload || 'metadata';
this.audio.crossOrigin = 'anonymous';
}
Setting crossOrigin forces the browser to make a CORS request for the media. If the audio file is hosted somewhere that doesn't send Access-Control-Allow-Origin (a common setup: media offloaded to S3/a CDN with default configuration), the request is blocked and playback fails entirely, even though a plain <audio> element would play the same URL fine.
As far as I can tell the attribute isn't needed for the player's core functionality:
- The audio element is never connected to an
AudioContext via createMediaElementSource, so playback doesn't require CORS-clean media.
- Waveform peak analysis goes through a separate
fetch() + decodeAudioData path, which already falls back to placeholder peaks when the fetch fails.
Request: make this configurable, e.g. an options.crossOrigin accepting 'anonymous', 'use-credentials', or null/unset (don't set the attribute). Reading it from a data-cross-origin container attribute like the other options would be ideal. If backwards compatibility allows, defaulting to unset would match what <audio> does natively and avoid the broken-playback failure mode out of the box.
Context: WordPress's Gutenberg Playlist block uses waveform-player and hit this with CDN-hosted media (report: https://core.trac.wordpress.org/ticket/65673). We're currently working around it by clearing audio.crossOrigin right after constructing the player (WordPress/gutenberg#80533), which works because load() is deferred to a requestAnimationFrame callback, but a supported option would let us drop the workaround.
Happy to send a PR if you're open to it.
createAudio()unconditionally setscrossOrigin = 'anonymous'on the audio element it creates:Setting
crossOriginforces the browser to make a CORS request for the media. If the audio file is hosted somewhere that doesn't sendAccess-Control-Allow-Origin(a common setup: media offloaded to S3/a CDN with default configuration), the request is blocked and playback fails entirely, even though a plain<audio>element would play the same URL fine.As far as I can tell the attribute isn't needed for the player's core functionality:
AudioContextviacreateMediaElementSource, so playback doesn't require CORS-clean media.fetch()+decodeAudioDatapath, which already falls back to placeholder peaks when the fetch fails.Request: make this configurable, e.g. an
options.crossOriginaccepting'anonymous','use-credentials', ornull/unset (don't set the attribute). Reading it from adata-cross-origincontainer attribute like the other options would be ideal. If backwards compatibility allows, defaulting to unset would match what<audio>does natively and avoid the broken-playback failure mode out of the box.Context: WordPress's Gutenberg Playlist block uses waveform-player and hit this with CDN-hosted media (report: https://core.trac.wordpress.org/ticket/65673). We're currently working around it by clearing
audio.crossOriginright after constructing the player (WordPress/gutenberg#80533), which works becauseload()is deferred to arequestAnimationFramecallback, but a supported option would let us drop the workaround.Happy to send a PR if you're open to it.