added audioplayer contrib module
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
import loadScript from 'load-script';
|
||||
|
||||
/**
|
||||
* @typedef {Object} InitParams
|
||||
* @property {WavesurferParams} [defaults={backend: 'MediaElement,
|
||||
* mediaControls: true}] The default wavesurfer initialisation parameters
|
||||
* @property {string|NodeList} containers='wavesurfer' Selector or NodeList of
|
||||
* elements to attach instances to
|
||||
* @property {string}
|
||||
* pluginCdnTemplate='//localhost:8080/dist/plugin/wavesurfer.[name].js' URL
|
||||
* template for the dynamic loading of plugins
|
||||
* @property {function} loadPlugin If set overwrites the default ajax function,
|
||||
* can be used to inject plugins differently.
|
||||
*/
|
||||
/**
|
||||
* The HTML initialisation API is not part of the main library bundle file and
|
||||
* must be additionally included.
|
||||
*
|
||||
* The API attaches wavesurfer instances to all `<wavesurfer>` (can be
|
||||
* customised), parsing their `data-` attributes to construct an options object
|
||||
* for initialisation. Among other things it can dynamically load plugin code.
|
||||
*
|
||||
* The automatic initialisation can be prevented by setting the
|
||||
* `window.WS_StopAutoInit` flag to true. The `html-init[.min].js` file exports
|
||||
* the `Init` class, which can be called manually.
|
||||
*
|
||||
* Site-wide defaults can be added by setting `window.WS_InitOptions`.
|
||||
*
|
||||
* @example
|
||||
* <!-- with minimap and timeline plugin -->
|
||||
* <wavesurfer
|
||||
* data-url="../media/demo.wav"
|
||||
* data-plugins="minimap,timeline"
|
||||
* data-minimap-height="30"
|
||||
* data-minimap-wave-color="#ddd"
|
||||
* data-minimap-progress-color="#999"
|
||||
* data-timeline-font-size="13px"
|
||||
* data-timeline-container="#timeline"
|
||||
* >
|
||||
* </wavesurfer>
|
||||
* <div id="timeline"></div>
|
||||
*
|
||||
* <!-- with regions plugin -->
|
||||
* <wavesurfer
|
||||
* data-url="../media/demo.wav"
|
||||
* data-plugins="regions"
|
||||
* data-regions-regions='[{"start": 1,"end": 3,"color": "hsla(400, 100%, 30%, 0.5)"}]'
|
||||
* >
|
||||
* </wavesurfer>
|
||||
*/
|
||||
class Init {
|
||||
/**
|
||||
* Instantiate Init class and initialise elements
|
||||
*
|
||||
* This is done automatically if `window` is defined and
|
||||
* `window.WS_StopAutoInit` is not set to true
|
||||
*
|
||||
* @param {WaveSurfer} WaveSurfer The WaveSurfer library object
|
||||
* @param {InitParams} params initialisation options
|
||||
*/
|
||||
constructor(WaveSurfer, params = {}) {
|
||||
if (!WaveSurfer) {
|
||||
throw new Error('WaveSurfer is not available!');
|
||||
}
|
||||
|
||||
/**
|
||||
* cache WaveSurfer
|
||||
* @private
|
||||
*/
|
||||
this.WaveSurfer = WaveSurfer;
|
||||
|
||||
/**
|
||||
* build parameters, cache them in _params so minified builds are smaller
|
||||
* @private
|
||||
*/
|
||||
const _params = this.params = WaveSurfer.util.extend({}, {
|
||||
// wavesurfer parameter defaults so by default the audio player is
|
||||
// usable with native media element controls
|
||||
defaults: {
|
||||
backend: 'MediaElement',
|
||||
mediaControls: true
|
||||
},
|
||||
// containers to instantiate on, can be selector string or NodeList
|
||||
containers: 'wavesurfer',
|
||||
// @TODO insert plugin CDN URIs
|
||||
pluginCdnTemplate: '//localhost:8080/dist/plugin/wavesurfer.[name].js',
|
||||
// loadPlugin function can be overriden to inject plugin definition
|
||||
// objects, this default function uses load-script to load a plugin
|
||||
// and pass it to a callback
|
||||
loadPlugin(name, cb) {
|
||||
const src = _params.pluginCdnTemplate.replace('[name]', name);
|
||||
loadScript(src, { async: false }, (err, plugin) => {
|
||||
if (err) {
|
||||
return console.error(`WaveSurfer plugin ${name} not found at ${src}`);
|
||||
}
|
||||
cb(window.WaveSurfer[name]);
|
||||
});
|
||||
}
|
||||
}, params);
|
||||
/**
|
||||
* The nodes that should have instances attached to them
|
||||
* @type {NodeList}
|
||||
*/
|
||||
this.containers = typeof _params.containers == 'string'
|
||||
? document.querySelectorAll(_params.containers)
|
||||
: _params.containers;
|
||||
/** @private */
|
||||
this.pluginCache = {};
|
||||
/**
|
||||
* An array of wavesurfer instances
|
||||
* @type {Object[]}
|
||||
*/
|
||||
this.instances = [];
|
||||
|
||||
this.initAllEls();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise all container elements
|
||||
*/
|
||||
initAllEls() {
|
||||
// iterate over all the container elements
|
||||
Array.prototype.forEach.call(this.containers, el => {
|
||||
// load the plugins as an array of plugin names
|
||||
const plugins = el.dataset.plugins
|
||||
? el.dataset.plugins.split(',')
|
||||
: [];
|
||||
|
||||
// no plugins to be loaded, just render
|
||||
if (!plugins.length) {
|
||||
return this.initEl(el);
|
||||
}
|
||||
// … or: iterate over all the plugins
|
||||
plugins.forEach((name, i) => {
|
||||
// plugin is not cached already, load it
|
||||
if (!this.pluginCache[name]) {
|
||||
this.params.loadPlugin(name, lib => {
|
||||
this.pluginCache[name] = lib;
|
||||
// plugins were all loaded, render the element
|
||||
if (i + 1 === plugins.length) {
|
||||
this.initEl(el, plugins);
|
||||
}
|
||||
});
|
||||
} else if (i === plugins.length) {
|
||||
// plugin was cached and this plugin was the last
|
||||
this.initEl(el, plugins);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise a single container element and add to `this.instances`
|
||||
*
|
||||
* @param {HTMLElement} el The container to instantiate wavesurfer to
|
||||
* @param {PluginDefinition[]} plugins An Array of plugin names to initialise with
|
||||
* @return {Object} Wavesurfer instance
|
||||
*/
|
||||
initEl(el, plugins = []) {
|
||||
const jsonRegex = /^[[|{]/;
|
||||
// initialise plugins with the correct options
|
||||
const initialisedPlugins = plugins.map(plugin => {
|
||||
const options = {};
|
||||
// the regex to find this plugin attributes
|
||||
const attrNameRegex = new RegExp('^' + plugin);
|
||||
let attrName;
|
||||
// iterate over all the data attributes and find ones for this
|
||||
// plugin
|
||||
for (attrName in el.dataset) {
|
||||
const regexResult = attrNameRegex.exec(attrName);
|
||||
if (regexResult) {
|
||||
const attr = el.dataset[attrName];
|
||||
// if the string begins with a [ or a { parse it as JSON
|
||||
const prop = jsonRegex.test(attr) ? JSON.parse(attr) : attr;
|
||||
// this removes the plugin prefix and changes the first letter
|
||||
// of the resulting string to lower case to follow the naming
|
||||
// convention of ws params
|
||||
const unprefixedOptionName = attrName.slice(plugin.length, plugin.length + 1).toLowerCase()
|
||||
+ attrName.slice(plugin.length + 1);
|
||||
options[unprefixedOptionName] = prop;
|
||||
}
|
||||
}
|
||||
return this.pluginCache[plugin].create(options);
|
||||
});
|
||||
// build parameter object for this container
|
||||
const params = this.WaveSurfer.util.extend(
|
||||
{ container: el },
|
||||
this.params.defaults,
|
||||
el.dataset,
|
||||
{ plugins: initialisedPlugins }
|
||||
);
|
||||
|
||||
// @TODO make nicer
|
||||
el.style.display = 'block';
|
||||
|
||||
// initialise wavesurfer, load audio (with peaks if provided)
|
||||
const instance = this.WaveSurfer.create(params);
|
||||
const peaks = params.peaks ? JSON.parse(params.peaks) : undefined;
|
||||
instance.load(params.url, peaks);
|
||||
|
||||
// push this instance into the instances cache
|
||||
this.instances.push(instance);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
// if window object exists and window.WS_StopAutoInit is not true
|
||||
if (typeof window === 'object' && !window.WS_StopAutoInit) {
|
||||
// call init when document is ready, apply any custom default settings
|
||||
// in window.WS_InitOptions
|
||||
if (document.readyState === 'complete') {
|
||||
window.WaveSurferInit = new Init(window.WaveSurfer, window.WS_InitOptions);
|
||||
} else {
|
||||
window.addEventListener('load', () => {
|
||||
window.WaveSurferInit = new Init(window.WaveSurfer, window.WS_InitOptions);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// export init for manual usage
|
||||
export default Init;
|
||||
Reference in New Issue
Block a user