{"version":3,"sources":["webpack://WaveSurfer/webpack/universalModuleDefinition","webpack://WaveSurfer/webpack/bootstrap","webpack://WaveSurfer/./src/util/index.js","webpack://WaveSurfer/./src/util/observer.js","webpack://WaveSurfer/./src/util/get-id.js","webpack://WaveSurfer/./src/util/style.js","webpack://WaveSurfer/./src/util/request-animation-frame.js","webpack://WaveSurfer/./src/webaudio.js","webpack://WaveSurfer/./src/mediaelement.js","webpack://WaveSurfer/./src/wavesurfer.js","webpack://WaveSurfer/./src/util/ajax.js","webpack://WaveSurfer/./src/util/max.js","webpack://WaveSurfer/./src/util/min.js","webpack://WaveSurfer/./src/util/extend.js","webpack://WaveSurfer/./src/util/frame.js","webpack://WaveSurfer/./node_modules/debounce/index.js","webpack://WaveSurfer/./src/util/prevent-click.js","webpack://WaveSurfer/./src/util/fetch.js","webpack://WaveSurfer/./src/drawer.multicanvas.js","webpack://WaveSurfer/./src/drawer.js","webpack://WaveSurfer/./src/drawer.canvasentry.js","webpack://WaveSurfer/./src/peakcache.js","webpack://WaveSurfer/./src/mediaelement-webaudio.js"],"names":["root","factory","exports","module","define","amd","this","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","_ajax","_interopRequireDefault","require","_getId","_max","_min","_observer","_extend","_style","_requestAnimationFrame","_frame","_debounce","_preventClick","_fetch","obj","default","Observer","_classCallCheck","_disabledEventEmissions","handlers","event","fn","_this","push","callback","un","e","length","splice","handler","_this2","on","_len","arguments","args","Array","_key","apply","setTimeout","eventNames","includes","_len2","_key2","_isDisabledEventEmission","forEach","prefix","undefined","Math","random","toString","substring","el","styles","keys","prop","style","window","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","oRequestAnimationFrame","msRequestAnimationFrame","element","util","_typeof","_getRequireWildcardCache","has","__proto__","a","getOwnPropertyDescriptor","u","set","_interopRequireWildcard","WeakMap","_defineProperty","_toPropertyKey","configurable","writable","_defineProperties","target","props","descriptor","toPrimitive","TypeError","String","Number","_toPrimitive","_callSuper","_getPrototypeOf","self","ReferenceError","_assertThisInitialized","_possibleConstructorReturn","Boolean","valueOf","Reflect","construct","_isNativeReflectConstruct","constructor","setPrototypeOf","getPrototypeOf","_setPrototypeOf","_util$Observer","WebAudio","params","instance","Constructor","audioContext","offlineAudioContext","stateBehaviors","init","addOnAudioProcess","getPlayedPercents","duration","getDuration","getCurrentTime","startPosition","getPlayedTime","removeOnAudioProcess","fireEvent","ac","supportsWebAudio","getAudioContext","lastPlay","currentTime","scheduledPause","states","buffer","filters","gainNode","mergedPeaks","offlineAc","peaks","playbackRate","analyser","scriptNode","source","splitPeaks","state","explicitDuration","destroyed","subClass","superClass","_inherits","protoProps","AudioContext","webkitAudioContext","WaveSurferAudioContext","sampleRate","WaveSurferOfflineAudioContext","OfflineAudioContext","webkitOfflineAudioContext","createVolumeNode","createScriptNode","createAnalyserNode","setState","setPlaybackRate","audioRate","setLength","filter","disconnect","connect","setFilters","disconnectFilters","reduce","prev","curr","audioScriptProcessor","createScriptProcessor","scriptBufferSize","createJavaScriptNode","destination","onaudioprocess","time","pause","createAnalyser","createGain","createGainNode","deviceId","audio","Audio","setSinkId","Promise","reject","Error","autoplay","dest","createMediaStreamDestination","srcObject","stream","gain","setValueAtTime","arraybuffer","errback","getOfflineAudioContext","decodeAudioData","data","channels","numberOfChannels","first","last","splitChannels","newBuffer","createBuffer","sampleSize","sampleStep","chan","getChannelData","start","end","min","max","j","disconnectSource","closeAudioContext","close","isPaused","unAll","destroyWebAudio","createSource","createBufferSource","noteGrainOn","stop","noteOff","resume","adjustedTime","seekTo","resumeAudioContext","play","staticProps","_webaudio","_get","receiver","base","_superPropBase","desc","_WebAudio","MediaElement","media","paused","volume","mediaType","toLowerCase","elementPosition","isMuted","onPlayEnd","mediaListeners","createTimer","error","canplay","ended","seeked","volumechange","muted","id","removeEventListener","addEventListener","_this3","onAudioProcess","frame","url","container","preload","document","createElement","controls","mediaControls","src","width","prevMedia","querySelector","removeChild","appendChild","_load","elt","HTMLMediaElement","load","_setupMediaListeners","setVolume","Infinity","seekable","clearPlayEnd","promise","setPlayEnd","_this4","_onPlayEnd","_this5","removeMediaElementOnDestroy","parentNode","_drawer","_mediaelement","_peakcache","_mediaelementWebaudio","iterator","_createClass","WaveSurfer","defaultParams","autoCenter","autoCenterRate","autoCenterImmediately","backend","backgroundColor","barHeight","barRadius","barGap","barMinHeight","cursorColor","cursorWidth","dragSelection","drawingContextAttributes","desynchronized","fillParent","forceDecode","height","hideScrollbar","interact","loopSelection","maxCanvasWidth","mediaContainer","minPxPerSec","normalize","partialRender","pixelRatio","devicePixelRatio","screen","deviceXDPI","logicalXDPI","plugins","progressColor","renderer","MultiCanvas","responsive","rtl","scrollParent","skipLength","splitChannelsOptions","overlay","channelColors","filterChannels","waveColor","xhr","backends","MediaElementWebAudio","assign","transform","setBackgroundColor","savedVolume","tmpEvents","currentRequest","drawer","peakCache","Drawer","Backend","initialisedPluginList","isDestroyed","isReady","prevWidth","_onResize","debounce","wrapper","clientWidth","registerPlugins","createDrawer","createBackend","createPeakCache","plugin","addPlugin","deferInit","initPlugin","concat","pluginStaticProp","Instance","getOwnPropertyNames","destroyPlugin","destroy","drawBuffer","progress","_this6","newVolume","getVolume","PeakCache","seconds","_this7","position","skip","offset","seekAndCenter","recenter","_this8","isFinite","oldScrollParent","rate","getPlaybackRate","setMute","mute","color","background","updateCursor","setHeight","channelIndices","nominalWidth","round","parentWidth","getWidth","newRanges","addRangeToPeakCache","getPeaks","drawPeaks","pxPerSec","_this9","decodeArrayBuffer","loadDecodedBuffer","blob","_this10","reader","FileReader","onProgress","loadArrayBuffer","result","readAsArrayBuffer","empty","preloadIgnoreReasons","indexOf","activeReasons","reason","console","warn","join","loadBuffer","loadMediaElement","_this11","action","once","getArrayBuffer","setPeaks","urlOrElt","_this12","loadElt","err","_this13","_this14","options","responseType","request","fetchFile","percentComplete","lengthComputable","loaded","total","accuracy","noWindow","arr","map","val","resolve","json","JSON","stringify","open","encodeURIComponent","format","quality","type","getImage","controller","abort","cancelAjax","clearTmpEvents","setWidth","destroyAllPlugins","VERSION","__VERSION__","XMLHttpRequest","fired100","method","requestHeaders","header","setRequestHeader","withCredentials","status","response","send","values","largest","smallest","sources","func","reqAnimationFrame","wait","immediate","timeout","context","timestamp","later","Date","now","debounced","callNow","clear","clearTimeout","flush","preventClickHandler","stopPropagation","body","fetchHeaders","Headers","fetchRequest","Request","AbortController","append","fetchOptions","headers","credentials","cache","redirect","referrer","signal","fetch","then","progressAvailable","contentLength","Response","ReadableStream","ProgressHandler","errMsg","ok","arrayBuffer","text","catch","_reader","getReader","parseInt","read","_ref","done","byteLength","enqueue","_drawer2","_Drawer","maxCanvasElementWidth","hasProgressCanvas","halfPixel","canvases","progressWave","EntryClass","CanvasEntry","canvasContextAttributes","overlap","ceil","createWrapper","createElements","zIndex","left","top","bottom","overflow","display","boxSizing","borderRightStyle","pointerEvents","addCanvas","borderRightWidth","borderRightColor","totalWidth","requiredCanvases","removeCanvas","canvasWidth","lastCanvas","entry","updateDimensions","clearWave","leftOffset","initWave","initProgress","lastEntry","wave","parentElement","pop","elementWidth","channelIndex","prepareDraw","absmax","hasMinVals","offsetY","halfH","peakIndexScale","bar","barWidth","step","scale","peak","floor","h","fillRect","_ref2","reflectedPeaks","len","drawLine","_ref3","setFillStyles","drawLines","x","y","radius","startCanvas","endCanvas","intersection","x1","y1","x2","y2","fillRects","drawIndex","filteredChannels","hideChannel","channelPeaks","some","all","images","lastPos","userSelect","webkitUserSelect","overflowX","overflowY","setupWrapperEvents","noPrevent","preventDefault","clientX","targetTouches","bbox","getBoundingClientRect","right","scrollLeft","scrollWidth","scrollbarHeight","offsetHeight","clientHeight","clientY","handleEvent","drawBars","drawWave","percent","recenterOnPosition","half","maxScroll","updateSize","minPxDelta","pos","newPos","updateProgress","waveCtx","progressCtx","getId","getContext","offsetLeft","elementSize","clearRect","canvas","fillStyle","fillRectToContext","ctx","drawRoundedRect","beginPath","moveTo","lineTo","quadraticCurveTo","closePath","fill","drawLineToContext","canvasStart","canvasEnd","halfOffset","absmaxHalf","toBlob","toDataURL","clearPeakCache","peakCacheRanges","peakCacheLength","uncachedRanges","item","sort","b","uncachedRangePairs","peakCacheRangePairs","_MediaElement","sourceMediaElement","createMediaElementSource","mediaElement"],"mappings":"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","file":"wavesurfer.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"WaveSurfer\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"WaveSurfer\"] = factory();\n\telse\n\t\troot[\"WaveSurfer\"] = factory();\n})(this, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 7);\n","export { default as ajax } from './ajax';\nexport { default as getId } from './get-id';\nexport { default as max } from './max';\nexport { default as min } from './min';\nexport { default as Observer } from './observer';\nexport { default as extend } from './extend';\nexport { default as style } from './style';\nexport { default as requestAnimationFrame } from './request-animation-frame';\nexport { default as frame } from './frame';\nexport { default as debounce } from 'debounce';\nexport { default as preventClick } from './prevent-click';\nexport { default as fetchFile } from './fetch';\n","/**\n * @typedef {Object} ListenerDescriptor\n * @property {string} name The name of the event\n * @property {function} callback The callback\n * @property {function} un The function to call to remove the listener\n */\n\n/**\n * Observer class\n */\nexport default class Observer {\n /**\n * Instantiate Observer\n */\n constructor() {\n /**\n * @private\n * @todo Initialise the handlers here already and remove the conditional\n * assignment in `on()`\n */\n this._disabledEventEmissions = [];\n this.handlers = null;\n }\n /**\n * Attach a handler function for an event.\n *\n * @param {string} event Name of the event to listen to\n * @param {function} fn The callback to trigger when the event is fired\n * @return {ListenerDescriptor} The event descriptor\n */\n on(event, fn) {\n if (!this.handlers) {\n this.handlers = {};\n }\n\n let handlers = this.handlers[event];\n if (!handlers) {\n handlers = this.handlers[event] = [];\n }\n handlers.push(fn);\n\n // Return an event descriptor\n return {\n name: event,\n callback: fn,\n un: (e, fn) => this.un(e, fn)\n };\n }\n\n /**\n * Remove an event handler.\n *\n * @param {string} event Name of the event the listener that should be\n * removed listens to\n * @param {function} fn The callback that should be removed\n */\n un(event, fn) {\n if (!this.handlers) {\n return;\n }\n\n const handlers = this.handlers[event];\n let i;\n if (handlers) {\n if (fn) {\n for (i = handlers.length - 1; i >= 0; i--) {\n if (handlers[i] == fn) {\n handlers.splice(i, 1);\n }\n }\n } else {\n handlers.length = 0;\n }\n }\n }\n\n /**\n * Remove all event handlers.\n */\n unAll() {\n this.handlers = null;\n }\n\n /**\n * Attach a handler to an event. The handler is executed at most once per\n * event type.\n *\n * @param {string} event The event to listen to\n * @param {function} handler The callback that is only to be called once\n * @return {ListenerDescriptor} The event descriptor\n */\n once(event, handler) {\n const fn = (...args) => {\n /* eslint-disable no-invalid-this */\n handler.apply(this, args);\n /* eslint-enable no-invalid-this */\n setTimeout(() => {\n this.un(event, fn);\n }, 0);\n };\n return this.on(event, fn);\n }\n\n /**\n * Disable firing a list of events by name. When specified, event handlers for any event type\n * passed in here will not be called.\n *\n * @since 4.0.0\n * @param {string[]} eventNames an array of event names to disable emissions for\n * @example\n * // disable seek and interaction events\n * wavesurfer.setDisabledEventEmissions(['seek', 'interaction']);\n */\n setDisabledEventEmissions(eventNames) {\n this._disabledEventEmissions = eventNames;\n }\n\n /**\n * plugins borrow part of this class without calling the constructor,\n * so we have to be careful about _disabledEventEmissions\n */\n\n _isDisabledEventEmission(event) {\n return this._disabledEventEmissions && this._disabledEventEmissions.includes(event);\n }\n\n /**\n * Manually fire an event\n *\n * @param {string} event The event to fire manually\n * @param {...any} args The arguments with which to call the listeners\n */\n fireEvent(event, ...args) {\n if (!this.handlers || this._isDisabledEventEmission(event)) {\n return;\n }\n\n const handlers = this.handlers[event];\n handlers &&\n handlers.forEach(fn => {\n fn(...args);\n });\n }\n}\n","/**\n * Get a random prefixed ID\n *\n * @param {String} prefix Prefix to use. Default is `'wavesurfer_'`.\n * @returns {String} Random prefixed ID\n * @example\n * console.log(getId()); // logs 'wavesurfer_b5pors4ru6g'\n *\n * let prefix = 'foo-';\n * console.log(getId(prefix)); // logs 'foo-b5pors4ru6g'\n */\nexport default function getId(prefix) {\n if (prefix === undefined) {\n prefix = 'wavesurfer_';\n }\n return (\n prefix +\n Math.random()\n .toString(32)\n .substring(2)\n );\n}\n","/**\n * Apply a map of styles to an element\n *\n * @param {HTMLElement} el The element that the styles will be applied to\n * @param {Object} styles The map of propName: attribute, both are used as-is\n *\n * @return {HTMLElement} el\n */\nexport default function style(el, styles) {\n Object.keys(styles).forEach(prop => {\n if (el.style[prop] !== styles[prop]) {\n el.style[prop] = styles[prop];\n }\n });\n return el;\n}\n","/* eslint-disable valid-jsdoc */\n/**\n * Returns the `requestAnimationFrame` function for the browser, or a shim with\n * `setTimeout` if the function is not found\n *\n * @return {function} Available `requestAnimationFrame` function for the browser\n */\nexport default (\n window.requestAnimationFrame ||\n window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n ((callback, element) => setTimeout(callback, 1000 / 60))\n).bind(window);\n","import * as util from './util';\n\n// using constants to prevent someone writing the string wrong\nconst PLAYING = 'playing';\nconst PAUSED = 'paused';\nconst FINISHED = 'finished';\n\n/**\n * WebAudio backend\n *\n * @extends {Observer}\n */\nexport default class WebAudio extends util.Observer {\n /** scriptBufferSize: size of the processing buffer */\n static scriptBufferSize = 256;\n /** audioContext: allows to process audio with WebAudio API */\n audioContext = null;\n /** @private */\n offlineAudioContext = null;\n /** @private */\n stateBehaviors = {\n [PLAYING]: {\n init() {\n this.addOnAudioProcess();\n },\n getPlayedPercents() {\n const duration = this.getDuration();\n return this.getCurrentTime() / duration || 0;\n },\n getCurrentTime() {\n return this.startPosition + this.getPlayedTime();\n }\n },\n [PAUSED]: {\n init() {\n this.removeOnAudioProcess();\n },\n getPlayedPercents() {\n const duration = this.getDuration();\n return this.getCurrentTime() / duration || 0;\n },\n getCurrentTime() {\n return this.startPosition;\n }\n },\n [FINISHED]: {\n init() {\n this.removeOnAudioProcess();\n this.fireEvent('finish');\n },\n getPlayedPercents() {\n return 1;\n },\n getCurrentTime() {\n return this.getDuration();\n }\n }\n };\n\n /**\n * Does the browser support this backend\n *\n * @return {boolean} Whether or not this browser supports this backend\n */\n supportsWebAudio() {\n return !!(window.AudioContext || window.webkitAudioContext);\n }\n\n /**\n * Get the audio context used by this backend or create one\n *\n * @return {AudioContext} Existing audio context, or creates a new one\n */\n getAudioContext() {\n if (!window.WaveSurferAudioContext) {\n window.WaveSurferAudioContext = new (window.AudioContext ||\n window.webkitAudioContext)();\n }\n return window.WaveSurferAudioContext;\n }\n\n /**\n * Get the offline audio context used by this backend or create one\n *\n * @param {number} sampleRate The sample rate to use\n * @return {OfflineAudioContext} Existing offline audio context, or creates\n * a new one\n */\n getOfflineAudioContext(sampleRate) {\n if (!window.WaveSurferOfflineAudioContext) {\n window.WaveSurferOfflineAudioContext = new (window.OfflineAudioContext ||\n window.webkitOfflineAudioContext)(1, 2, sampleRate);\n }\n return window.WaveSurferOfflineAudioContext;\n }\n\n /**\n * Construct the backend\n *\n * @param {WavesurferParams} params Wavesurfer parameters\n */\n constructor(params) {\n super();\n /** @private */\n this.params = params;\n /** ac: Audio Context instance */\n this.ac =\n params.audioContext ||\n (this.supportsWebAudio() ? this.getAudioContext() : {});\n /**@private */\n this.lastPlay = this.ac.currentTime;\n /** @private */\n this.startPosition = 0;\n /** @private */\n this.scheduledPause = null;\n /** @private */\n this.states = {\n [PLAYING]: Object.create(this.stateBehaviors[PLAYING]),\n [PAUSED]: Object.create(this.stateBehaviors[PAUSED]),\n [FINISHED]: Object.create(this.stateBehaviors[FINISHED])\n };\n /** @private */\n this.buffer = null;\n /** @private */\n this.filters = [];\n /** gainNode: allows to control audio volume */\n this.gainNode = null;\n /** @private */\n this.mergedPeaks = null;\n /** @private */\n this.offlineAc = null;\n /** @private */\n this.peaks = null;\n /** @private */\n this.playbackRate = 1;\n /** analyser: provides audio analysis information */\n this.analyser = null;\n /** scriptNode: allows processing audio */\n this.scriptNode = null;\n /** @private */\n this.source = null;\n /** @private */\n this.splitPeaks = [];\n /** @private */\n this.state = null;\n /** @private */\n this.explicitDuration = params.duration;\n /**\n * Boolean indicating if the backend was destroyed.\n */\n this.destroyed = false;\n }\n\n /**\n * Initialise the backend, called in `wavesurfer.createBackend()`\n */\n init() {\n this.createVolumeNode();\n this.createScriptNode();\n this.createAnalyserNode();\n\n this.setState(PAUSED);\n this.setPlaybackRate(this.params.audioRate);\n this.setLength(0);\n }\n\n /** @private */\n disconnectFilters() {\n if (this.filters) {\n this.filters.forEach(filter => {\n filter && filter.disconnect();\n });\n this.filters = null;\n // Reconnect direct path\n this.analyser.connect(this.gainNode);\n }\n }\n\n /**\n * @private\n *\n * @param {string} state The new state\n */\n setState(state) {\n if (this.state !== this.states[state]) {\n this.state = this.states[state];\n this.state.init.call(this);\n }\n }\n\n /**\n * Unpacked `setFilters()`\n *\n * @param {...AudioNode} filters One or more filters to set\n */\n setFilter(...filters) {\n this.setFilters(filters);\n }\n\n /**\n * Insert custom Web Audio nodes into the graph\n *\n * @param {AudioNode[]} filters Packed filters array\n * @example\n * const lowpass = wavesurfer.backend.ac.createBiquadFilter();\n * wavesurfer.backend.setFilter(lowpass);\n */\n setFilters(filters) {\n // Remove existing filters\n this.disconnectFilters();\n\n // Insert filters if filter array not empty\n if (filters && filters.length) {\n this.filters = filters;\n\n // Disconnect direct path before inserting filters\n this.analyser.disconnect();\n\n // Connect each filter in turn\n filters\n .reduce((prev, curr) => {\n prev.connect(curr);\n return curr;\n }, this.analyser)\n .connect(this.gainNode);\n }\n }\n /** Create ScriptProcessorNode to process audio */\n createScriptNode() {\n if (this.params.audioScriptProcessor) {\n this.scriptNode = this.params.audioScriptProcessor;\n } else {\n if (this.ac.createScriptProcessor) {\n this.scriptNode = this.ac.createScriptProcessor(\n WebAudio.scriptBufferSize\n );\n } else {\n this.scriptNode = this.ac.createJavaScriptNode(\n WebAudio.scriptBufferSize\n );\n }\n }\n this.scriptNode.connect(this.ac.destination);\n }\n\n /** @private */\n addOnAudioProcess() {\n this.scriptNode.onaudioprocess = () => {\n const time = this.getCurrentTime();\n\n if (time >= this.getDuration()) {\n this.setState(FINISHED);\n this.fireEvent('pause');\n } else if (time >= this.scheduledPause) {\n this.pause();\n } else if (this.state === this.states[PLAYING]) {\n this.fireEvent('audioprocess', time);\n }\n };\n }\n\n /** @private */\n removeOnAudioProcess() {\n this.scriptNode.onaudioprocess = () => {};\n }\n /** Create analyser node to perform audio analysis */\n createAnalyserNode() {\n this.analyser = this.ac.createAnalyser();\n this.analyser.connect(this.gainNode);\n }\n\n /**\n * Create the gain node needed to control the playback volume.\n *\n */\n createVolumeNode() {\n // Create gain node using the AudioContext\n if (this.ac.createGain) {\n this.gainNode = this.ac.createGain();\n } else {\n this.gainNode = this.ac.createGainNode();\n }\n // Add the gain node to the graph\n this.gainNode.connect(this.ac.destination);\n }\n\n /**\n * Set the sink id for the media player\n *\n * @param {string} deviceId String value representing audio device id.\n * @returns {Promise} A Promise that resolves to `undefined` when there\n * are no errors.\n */\n setSinkId(deviceId) {\n if (deviceId) {\n /**\n * The webaudio API doesn't currently support setting the device\n * output. Here we create an HTMLAudioElement, connect the\n * webaudio stream to that element and setSinkId there.\n */\n let audio = new window.Audio();\n if (!audio.setSinkId) {\n return Promise.reject(\n new Error('setSinkId is not supported in your browser')\n );\n }\n audio.autoplay = true;\n var dest = this.ac.createMediaStreamDestination();\n this.gainNode.disconnect();\n this.gainNode.connect(dest);\n audio.srcObject = dest.stream;\n\n return audio.setSinkId(deviceId);\n } else {\n return Promise.reject(new Error('Invalid deviceId: ' + deviceId));\n }\n }\n\n /**\n * Set the audio volume\n *\n * @param {number} value A floating point value between 0 and 1.\n */\n setVolume(value) {\n this.gainNode.gain.setValueAtTime(value, this.ac.currentTime);\n }\n\n /**\n * Get the current volume\n *\n * @return {number} value A floating point value between 0 and 1.\n */\n getVolume() {\n return this.gainNode.gain.value;\n }\n\n /**\n * Decode an array buffer and pass data to a callback\n *\n * @private\n * @param {ArrayBuffer} arraybuffer The array buffer to decode\n * @param {function} callback The function to call on complete.\n * @param {function} errback The function to call on error.\n */\n decodeArrayBuffer(arraybuffer, callback, errback) {\n if (!this.offlineAc) {\n this.offlineAc = this.getOfflineAudioContext(\n this.ac && this.ac.sampleRate ? this.ac.sampleRate : 44100\n );\n }\n this.offlineAc.decodeAudioData(\n arraybuffer,\n data => callback(data),\n errback\n );\n }\n\n /**\n * Set pre-decoded peaks\n *\n * @param {number[]|Number.} peaks Peaks data\n * @param {?number} duration Explicit duration\n */\n setPeaks(peaks, duration) {\n if (duration != null) {\n this.explicitDuration = duration;\n }\n this.peaks = peaks;\n }\n\n /**\n * Set the rendered length (different from the length of the audio)\n *\n * @param {number} length The rendered length\n */\n setLength(length) {\n // No resize, we can preserve the cached peaks.\n if (this.mergedPeaks && length == 2 * this.mergedPeaks.length - 1 + 2) {\n return;\n }\n\n this.splitPeaks = [];\n this.mergedPeaks = [];\n // Set the last element of the sparse array so the peak arrays are\n // appropriately sized for other calculations.\n const channels = this.buffer ? this.buffer.numberOfChannels : 1;\n let c;\n for (c = 0; c < channels; c++) {\n this.splitPeaks[c] = [];\n this.splitPeaks[c][2 * (length - 1)] = 0;\n this.splitPeaks[c][2 * (length - 1) + 1] = 0;\n }\n this.mergedPeaks[2 * (length - 1)] = 0;\n this.mergedPeaks[2 * (length - 1) + 1] = 0;\n }\n\n /**\n * Compute the max and min value of the waveform when broken into subranges.\n *\n * @param {number} length How many subranges to break the waveform into.\n * @param {number} first First sample in the required range.\n * @param {number} last Last sample in the required range.\n * @return {number[]|Number.} Array of 2* peaks or array of arrays of\n * peaks consisting of (max, min) values for each subrange.\n */\n getPeaks(length, first, last) {\n if (this.peaks) {\n return this.peaks;\n }\n if (!this.buffer) {\n return [];\n }\n\n first = first || 0;\n last = last || length - 1;\n\n this.setLength(length);\n\n if (!this.buffer) {\n return this.params.splitChannels\n ? this.splitPeaks\n : this.mergedPeaks;\n }\n\n /**\n * The following snippet fixes a buffering data issue on the Safari\n * browser which returned undefined It creates the missing buffer based\n * on 1 channel, 4096 samples and the sampleRate from the current\n * webaudio context 4096 samples seemed to be the best fit for rendering\n * will review this code once a stable version of Safari TP is out\n */\n if (!this.buffer.length) {\n const newBuffer = this.createBuffer(1, 4096, this.sampleRate);\n this.buffer = newBuffer.buffer;\n }\n\n const sampleSize = this.buffer.length / length;\n const sampleStep = ~~(sampleSize / 10) || 1;\n const channels = this.buffer.numberOfChannels;\n let c;\n\n for (c = 0; c < channels; c++) {\n const peaks = this.splitPeaks[c];\n const chan = this.buffer.getChannelData(c);\n let i;\n\n for (i = first; i <= last; i++) {\n const start = ~~(i * sampleSize);\n const end = ~~(start + sampleSize);\n /**\n * Initialize the max and min to the first sample of this\n * subrange, so that even if the samples are entirely\n * on one side of zero, we still return the true max and\n * min values in the subrange.\n */\n let min = chan[start];\n let max = min;\n let j;\n\n for (j = start; j < end; j += sampleStep) {\n const value = chan[j];\n\n if (value > max) {\n max = value;\n }\n\n if (value < min) {\n min = value;\n }\n }\n\n peaks[2 * i] = max;\n peaks[2 * i + 1] = min;\n\n if (c == 0 || max > this.mergedPeaks[2 * i]) {\n this.mergedPeaks[2 * i] = max;\n }\n\n if (c == 0 || min < this.mergedPeaks[2 * i + 1]) {\n this.mergedPeaks[2 * i + 1] = min;\n }\n }\n }\n\n return this.params.splitChannels ? this.splitPeaks : this.mergedPeaks;\n }\n\n /**\n * Get the position from 0 to 1\n *\n * @return {number} Position\n */\n getPlayedPercents() {\n return this.state.getPlayedPercents.call(this);\n }\n\n /** @private */\n disconnectSource() {\n if (this.source) {\n this.source.disconnect();\n }\n }\n /**\n * Destroy all references with WebAudio, disconnecting audio nodes and closing Audio Context\n */\n destroyWebAudio() {\n this.disconnectFilters();\n this.disconnectSource();\n this.gainNode.disconnect();\n this.scriptNode.disconnect();\n this.analyser.disconnect();\n\n // close the audioContext if closeAudioContext option is set to true\n if (this.params.closeAudioContext) {\n // check if browser supports AudioContext.close()\n if (\n typeof this.ac.close === 'function' &&\n this.ac.state != 'closed'\n ) {\n this.ac.close();\n }\n // clear the reference to the audiocontext\n this.ac = null;\n // clear the actual audiocontext, either passed as param or the\n // global singleton\n if (!this.params.audioContext) {\n window.WaveSurferAudioContext = null;\n } else {\n this.params.audioContext = null;\n }\n // clear the offlineAudioContext\n window.WaveSurferOfflineAudioContext = null;\n }\n }\n /**\n * This is called when wavesurfer is destroyed\n */\n destroy() {\n if (!this.isPaused()) {\n this.pause();\n }\n this.unAll();\n this.buffer = null;\n this.destroyed = true;\n\n this.destroyWebAudio();\n }\n\n /**\n * Loaded a decoded audio buffer\n *\n * @param {Object} buffer Decoded audio buffer to load\n */\n load(buffer) {\n this.startPosition = 0;\n this.lastPlay = this.ac.currentTime;\n this.buffer = buffer;\n this.createSource();\n }\n\n /** @private */\n createSource() {\n this.disconnectSource();\n this.source = this.ac.createBufferSource();\n\n // adjust for old browsers\n this.source.start = this.source.start || this.source.noteGrainOn;\n this.source.stop = this.source.stop || this.source.noteOff;\n\n this.source.playbackRate.setValueAtTime(\n this.playbackRate,\n this.ac.currentTime\n );\n this.source.buffer = this.buffer;\n this.source.connect(this.analyser);\n }\n\n /**\n * @private\n *\n * some browsers require an explicit call to #resume before they will play back audio\n */\n resumeAudioContext() {\n if (this.ac.state == 'suspended') {\n this.ac.resume && this.ac.resume();\n }\n }\n\n /**\n * Used by `wavesurfer.isPlaying()` and `wavesurfer.playPause()`\n *\n * @return {boolean} Whether or not this backend is currently paused\n */\n isPaused() {\n return this.state !== this.states[PLAYING];\n }\n\n /**\n * Used by `wavesurfer.getDuration()`\n *\n * @return {number} Duration of loaded buffer\n */\n getDuration() {\n if (this.explicitDuration) {\n return this.explicitDuration;\n }\n if (!this.buffer) {\n return 0;\n }\n return this.buffer.duration;\n }\n\n /**\n * Used by `wavesurfer.seekTo()`\n *\n * @param {number} start Position to start at in seconds\n * @param {number} end Position to end at in seconds\n * @return {{start: number, end: number}} Object containing start and end\n * positions\n */\n seekTo(start, end) {\n if (!this.buffer) {\n return;\n }\n\n this.scheduledPause = null;\n\n if (start == null) {\n start = this.getCurrentTime();\n if (start >= this.getDuration()) {\n start = 0;\n }\n }\n if (end == null) {\n end = this.getDuration();\n }\n\n this.startPosition = start;\n this.lastPlay = this.ac.currentTime;\n\n if (this.state === this.states[FINISHED]) {\n this.setState(PAUSED);\n }\n\n return {\n start: start,\n end: end\n };\n }\n\n /**\n * Get the playback position in seconds\n *\n * @return {number} The playback position in seconds\n */\n getPlayedTime() {\n return (this.ac.currentTime - this.lastPlay) * this.playbackRate;\n }\n\n /**\n * Plays the loaded audio region.\n *\n * @param {number} start Start offset in seconds, relative to the beginning\n * of a clip.\n * @param {number} end When to stop relative to the beginning of a clip.\n */\n play(start, end) {\n if (!this.buffer) {\n return;\n }\n\n // need to re-create source on each playback\n this.createSource();\n\n const adjustedTime = this.seekTo(start, end);\n\n start = adjustedTime.start;\n end = adjustedTime.end;\n\n this.scheduledPause = end;\n\n this.source.start(0, start);\n\n this.resumeAudioContext();\n\n this.setState(PLAYING);\n\n this.fireEvent('play');\n }\n\n /**\n * Pauses the loaded audio.\n */\n pause() {\n this.scheduledPause = null;\n\n this.startPosition += this.getPlayedTime();\n this.source && this.source.stop(0);\n\n this.setState(PAUSED);\n\n this.fireEvent('pause');\n }\n\n /**\n * Returns the current time in seconds relative to the audio-clip's\n * duration.\n *\n * @return {number} The current time in seconds\n */\n getCurrentTime() {\n return this.state.getCurrentTime.call(this);\n }\n\n /**\n * Returns the current playback rate. (0=no playback, 1=normal playback)\n *\n * @return {number} The current playback rate\n */\n getPlaybackRate() {\n return this.playbackRate;\n }\n\n /**\n * Set the audio source playback rate.\n *\n * @param {number} value The playback rate to use\n */\n setPlaybackRate(value) {\n value = value || 1;\n if (this.isPaused()) {\n this.playbackRate = value;\n } else {\n this.pause();\n this.playbackRate = value;\n this.play();\n }\n }\n\n /**\n * Set a point in seconds for playback to stop at.\n *\n * @param {number} end Position to end at\n * @version 3.3.0\n */\n setPlayEnd(end) {\n this.scheduledPause = end;\n }\n}\n","import WebAudio from './webaudio';\nimport * as util from './util';\n\n/**\n * MediaElement backend\n */\nexport default class MediaElement extends WebAudio {\n /**\n * Construct the backend\n *\n * @param {WavesurferParams} params Wavesurfer parameters\n */\n constructor(params) {\n super(params);\n /** @private */\n this.params = params;\n\n /**\n * Initially a dummy media element to catch errors. Once `_load` is\n * called, this will contain the actual `HTMLMediaElement`.\n * @private\n */\n this.media = {\n currentTime: 0,\n duration: 0,\n paused: true,\n playbackRate: 1,\n play() {},\n pause() {},\n volume: 0\n };\n\n /** @private */\n this.mediaType = params.mediaType.toLowerCase();\n /** @private */\n this.elementPosition = params.elementPosition;\n /** @private */\n this.peaks = null;\n /** @private */\n this.playbackRate = 1;\n /** @private */\n this.volume = 1;\n /** @private */\n this.isMuted = false;\n /** @private */\n this.buffer = null;\n /** @private */\n this.onPlayEnd = null;\n /** @private */\n this.mediaListeners = {};\n }\n\n /**\n * Initialise the backend, called in `wavesurfer.createBackend()`\n */\n init() {\n this.setPlaybackRate(this.params.audioRate);\n this.createTimer();\n }\n\n /**\n * Attach event listeners to media element.\n */\n _setupMediaListeners() {\n this.mediaListeners.error = () => {\n this.fireEvent('error', 'Error loading media element');\n };\n this.mediaListeners.canplay = () => {\n this.fireEvent('canplay');\n };\n this.mediaListeners.ended = () => {\n this.fireEvent('finish');\n };\n // listen to and relay play, pause and seeked events to enable\n // playback control from the external media element\n this.mediaListeners.play = () => {\n this.fireEvent('play');\n };\n this.mediaListeners.pause = () => {\n this.fireEvent('pause');\n };\n this.mediaListeners.seeked = event => {\n this.fireEvent('seek');\n };\n this.mediaListeners.volumechange = event => {\n this.isMuted = this.media.muted;\n if (this.isMuted) {\n this.volume = 0;\n } else {\n this.volume = this.media.volume;\n }\n this.fireEvent('volume');\n };\n\n // reset event listeners\n Object.keys(this.mediaListeners).forEach(id => {\n this.media.removeEventListener(id, this.mediaListeners[id]);\n this.media.addEventListener(id, this.mediaListeners[id]);\n });\n }\n\n /**\n * Create a timer to provide a more precise `audioprocess` event.\n */\n createTimer() {\n const onAudioProcess = () => {\n if (this.isPaused()) {\n return;\n }\n this.fireEvent('audioprocess', this.getCurrentTime());\n\n // Call again in the next frame\n util.frame(onAudioProcess)();\n };\n\n this.on('play', onAudioProcess);\n\n // Update the progress one more time to prevent it from being stuck in\n // case of lower framerates\n this.on('pause', () => {\n this.fireEvent('audioprocess', this.getCurrentTime());\n });\n }\n\n /**\n * Create media element with url as its source,\n * and append to container element.\n *\n * @param {string} url Path to media file\n * @param {HTMLElement} container HTML element\n * @param {number[]|Number.} peaks Array of peak data\n * @param {string} preload HTML 5 preload attribute value\n * @throws Will throw an error if the `url` argument is not a valid media\n * element.\n */\n load(url, container, peaks, preload) {\n const media = document.createElement(this.mediaType);\n media.controls = this.params.mediaControls;\n media.autoplay = this.params.autoplay || false;\n media.preload = preload == null ? 'auto' : preload;\n media.src = url;\n media.style.width = '100%';\n\n const prevMedia = container.querySelector(this.mediaType);\n if (prevMedia) {\n container.removeChild(prevMedia);\n }\n container.appendChild(media);\n\n this._load(media, peaks);\n }\n\n /**\n * Load existing media element.\n *\n * @param {HTMLMediaElement} elt HTML5 Audio or Video element\n * @param {number[]|Number.} peaks Array of peak data\n */\n loadElt(elt, peaks) {\n elt.controls = this.params.mediaControls;\n elt.autoplay = this.params.autoplay || false;\n\n this._load(elt, peaks);\n }\n\n /**\n * Method called by both `load` (from url)\n * and `loadElt` (existing media element) methods.\n *\n * @param {HTMLMediaElement} media HTML5 Audio or Video element\n * @param {number[]|Number.} peaks Array of peak data\n * @throws Will throw an error if the `media` argument is not a valid media\n * element.\n * @private\n */\n _load(media, peaks) {\n // verify media element is valid\n if (\n !(media instanceof HTMLMediaElement) ||\n typeof media.addEventListener === 'undefined'\n ) {\n throw new Error('media parameter is not a valid media element');\n }\n\n // load must be called manually on iOS, otherwise peaks won't draw\n // until a user interaction triggers load --> 'ready' event\n if (typeof media.load == 'function') {\n // Resets the media element and restarts the media resource. Any\n // pending events are discarded. How much media data is fetched is\n // still affected by the preload attribute.\n media.load();\n }\n\n this.media = media;\n this._setupMediaListeners();\n this.peaks = peaks;\n this.onPlayEnd = null;\n this.buffer = null;\n this.isMuted = media.muted;\n this.setPlaybackRate(this.playbackRate);\n this.setVolume(this.volume);\n }\n\n /**\n * Used by `wavesurfer.isPlaying()` and `wavesurfer.playPause()`\n *\n * @return {boolean} Media paused or not\n */\n isPaused() {\n return !this.media || this.media.paused;\n }\n\n /**\n * Used by `wavesurfer.getDuration()`\n *\n * @return {number} Duration\n */\n getDuration() {\n if (this.explicitDuration) {\n return this.explicitDuration;\n }\n let duration = (this.buffer || this.media).duration;\n if (duration >= Infinity) {\n // streaming audio\n duration = this.media.seekable.end(0);\n }\n return duration;\n }\n\n /**\n * Returns the current time in seconds relative to the audio-clip's\n * duration.\n *\n * @return {number} Current time\n */\n getCurrentTime() {\n return this.media && this.media.currentTime;\n }\n\n /**\n * Get the position from 0 to 1\n *\n * @return {number} Current position\n */\n getPlayedPercents() {\n return this.getCurrentTime() / this.getDuration() || 0;\n }\n\n /**\n * Get the audio source playback rate.\n *\n * @return {number} Playback rate\n */\n getPlaybackRate() {\n return this.playbackRate || this.media.playbackRate;\n }\n\n /**\n * Set the audio source playback rate.\n *\n * @param {number} value Playback rate\n */\n setPlaybackRate(value) {\n this.playbackRate = value || 1;\n this.media.playbackRate = this.playbackRate;\n }\n\n /**\n * Used by `wavesurfer.seekTo()`\n *\n * @param {number} start Position to start at in seconds\n */\n seekTo(start) {\n if (start != null) {\n this.media.currentTime = start;\n }\n this.clearPlayEnd();\n }\n\n /**\n * Plays the loaded audio region.\n *\n * @param {number} start Start offset in seconds, relative to the beginning\n * of a clip.\n * @param {number} end When to stop, relative to the beginning of a clip.\n * @emits MediaElement#play\n * @return {Promise} Result\n */\n play(start, end) {\n this.seekTo(start);\n const promise = this.media.play();\n end && this.setPlayEnd(end);\n\n return promise;\n }\n\n /**\n * Pauses the loaded audio.\n *\n * @emits MediaElement#pause\n * @return {Promise} Result\n */\n pause() {\n let promise;\n\n if (this.media) {\n promise = this.media.pause();\n }\n this.clearPlayEnd();\n\n return promise;\n }\n\n /**\n * Set the play end\n *\n * @param {number} end Where to end\n */\n setPlayEnd(end) {\n this.clearPlayEnd();\n\n this._onPlayEnd = time => {\n if (time >= end) {\n this.pause();\n this.seekTo(end);\n }\n };\n this.on('audioprocess', this._onPlayEnd);\n }\n\n /** @private */\n clearPlayEnd() {\n if (this._onPlayEnd) {\n this.un('audioprocess', this._onPlayEnd);\n this._onPlayEnd = null;\n }\n }\n\n /**\n * Compute the max and min value of the waveform when broken into\n * subranges.\n *\n * @param {number} length How many subranges to break the waveform into.\n * @param {number} first First sample in the required range.\n * @param {number} last Last sample in the required range.\n * @return {number[]|Number.} Array of 2* peaks or array of\n * arrays of peaks consisting of (max, min) values for each subrange.\n */\n getPeaks(length, first, last) {\n if (this.buffer) {\n return super.getPeaks(length, first, last);\n }\n return this.peaks || [];\n }\n\n /**\n * Set the sink id for the media player\n *\n * @param {string} deviceId String value representing audio device id.\n * @returns {Promise} A Promise that resolves to `undefined` when there\n * are no errors.\n */\n setSinkId(deviceId) {\n if (deviceId) {\n if (!this.media.setSinkId) {\n return Promise.reject(\n new Error('setSinkId is not supported in your browser')\n );\n }\n return this.media.setSinkId(deviceId);\n }\n\n return Promise.reject(new Error('Invalid deviceId: ' + deviceId));\n }\n\n /**\n * Get the current volume\n *\n * @return {number} value A floating point value between 0 and 1.\n */\n getVolume() {\n return this.volume;\n }\n\n /**\n * Set the audio volume\n *\n * @param {number} value A floating point value between 0 and 1.\n */\n setVolume(value) {\n this.volume = value;\n // no need to change when it's already at that volume\n if (this.media.volume !== this.volume) {\n this.media.volume = this.volume;\n }\n }\n\n /**\n * Enable or disable muted audio\n *\n * @since 4.0.0\n * @param {boolean} muted Specify `true` to mute audio.\n */\n setMute(muted) {\n // This causes a volume change to be emitted too through the\n // volumechange event listener.\n this.isMuted = this.media.muted = muted;\n }\n\n /**\n * This is called when wavesurfer is destroyed\n *\n */\n destroy() {\n this.pause();\n this.unAll();\n this.destroyed = true;\n\n // cleanup media event listeners\n Object.keys(this.mediaListeners).forEach(id => {\n if (this.media) {\n this.media.removeEventListener(id, this.mediaListeners[id]);\n }\n });\n\n if (\n this.params.removeMediaElementOnDestroy &&\n this.media &&\n this.media.parentNode\n ) {\n this.media.parentNode.removeChild(this.media);\n }\n\n this.media = null;\n }\n}\n","import * as util from './util';\nimport MultiCanvas from './drawer.multicanvas';\nimport WebAudio from './webaudio';\nimport MediaElement from './mediaelement';\nimport PeakCache from './peakcache';\nimport MediaElementWebAudio from './mediaelement-webaudio';\n\n/*\n * This work is licensed under a BSD-3-Clause License.\n */\n\n/** @external {HTMLElement} https://developer.mozilla.org/en/docs/Web/API/HTMLElement */\n/** @external {OfflineAudioContext} https://developer.mozilla.org/en-US/docs/Web/API/OfflineAudioContext */\n/** @external {File} https://developer.mozilla.org/en-US/docs/Web/API/File */\n/** @external {Blob} https://developer.mozilla.org/en-US/docs/Web/API/Blob */\n/** @external {CanvasRenderingContext2D} https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D */\n/** @external {MediaStreamConstraints} https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamConstraints */\n/** @external {AudioNode} https://developer.mozilla.org/de/docs/Web/API/AudioNode */\n\n/**\n * @typedef {Object} WavesurferParams\n * @property {AudioContext} audioContext=null Use your own previously\n * initialized AudioContext or leave blank.\n * @property {number} audioRate=1 Speed at which to play audio. Lower number is\n * slower.\n * @property {ScriptProcessorNode} audioScriptProcessor=null Use your own previously\n * initialized ScriptProcessorNode or leave blank.\n * @property {boolean} autoCenter=true If a scrollbar is present, center the\n * waveform on current progress\n * @property {number} autoCenterRate=5 If autoCenter is active, rate at which the\n * waveform is centered\n * @property {boolean} autoCenterImmediately=false If autoCenter is active, immediately\n * center waveform on current progress\n * @property {string} backend='WebAudio' `'WebAudio'|'MediaElement'|'MediaElementWebAudio'` In most cases\n * you don't have to set this manually. MediaElement is a fallback for unsupported browsers.\n * MediaElementWebAudio allows to use WebAudio API also with big audio files, loading audio like with\n * MediaElement backend (HTML5 audio tag). You have to use the same methods of MediaElement backend for loading and\n * playback, giving also peaks, so the audio data are not decoded. In this way you can use WebAudio features, like filters,\n * also with audio with big duration. For example:\n * ` wavesurfer.load(url | HTMLMediaElement, peaks, preload, duration);\n * wavesurfer.play();\n * wavesurfer.setFilter(customFilter);\n * `\n * @property {string} backgroundColor=null Change background color of the\n * waveform container.\n * @property {number} barHeight=1 The height of the wave bars.\n * @property {number} barRadius=0 The radius of the wave bars. Makes bars rounded\n * @property {number} barGap=null The optional spacing between bars of the wave,\n * if not provided will be calculated in legacy format.\n * @property {number} barWidth=null Draw the waveform using bars.\n * @property {number} barMinHeight=null If specified, draw at least a bar of this height,\n * eliminating waveform gaps\n * @property {boolean} closeAudioContext=false Close and nullify all audio\n * contexts when the destroy method is called.\n * @property {!string|HTMLElement} container CSS selector or HTML element where\n * the waveform should be drawn. This is the only required parameter.\n * @property {string} cursorColor='#333' The fill color of the cursor indicating\n * the playhead position.\n * @property {number} cursorWidth=1 Measured in pixels.\n * @property {object} drawingContextAttributes={desynchronized: false} Drawing context\n * attributes.\n * @property {number} duration=null Optional audio length so pre-rendered peaks\n * can be display immediately for example.\n * @property {boolean} fillParent=true Whether to fill the entire container or\n * draw only according to `minPxPerSec`.\n * @property {boolean} forceDecode=false Force decoding of audio using web audio\n * when zooming to get a more detailed waveform.\n * @property {number} height=128 The height of the waveform. Measured in\n * pixels.\n * @property {boolean} hideScrollbar=false Whether to hide the horizontal\n * scrollbar when one would normally be shown.\n * @property {boolean} interact=true Whether the mouse interaction will be\n * enabled at initialization. You can switch this parameter at any time later\n * on.\n * @property {boolean} loopSelection=true (Use with regions plugin) Enable\n * looping of selected regions\n * @property {number} maxCanvasWidth=4000 Maximum width of a single canvas in\n * pixels, excluding a small overlap (2 * `pixelRatio`, rounded up to the next\n * even integer). If the waveform is longer than this value, additional canvases\n * will be used to render the waveform, which is useful for very large waveforms\n * that may be too wide for browsers to draw on a single canvas.\n * @property {boolean} mediaControls=false (Use with backend `MediaElement` or `MediaElementWebAudio`)\n * this enables the native controls for the media element\n * @property {string} mediaType='audio' (Use with backend `MediaElement` or `MediaElementWebAudio`)\n * `'audio'|'video'` ('video' only for `MediaElement`)\n * @property {number} minPxPerSec=20 Minimum number of pixels per second of\n * audio.\n * @property {boolean} normalize=false If true, normalize by the maximum peak\n * instead of 1.0.\n * @property {boolean} partialRender=false Use the PeakCache to improve\n * rendering speed of large waveforms\n * @property {number} pixelRatio=window.devicePixelRatio The pixel ratio used to\n * calculate display\n * @property {PluginDefinition[]} plugins=[] An array of plugin definitions to\n * register during instantiation, they will be directly initialised unless they\n * are added with the `deferInit` property set to true.\n * @property {string} progressColor='#555' The fill color of the part of the\n * waveform behind the cursor. When `progressColor` and `waveColor` are the same\n * the progress wave is not rendered at all.\n * @property {boolean} removeMediaElementOnDestroy=true Set to false to keep the\n * media element in the DOM when the player is destroyed. This is useful when\n * reusing an existing media element via the `loadMediaElement` method.\n * @property {Object} renderer=MultiCanvas Can be used to inject a custom\n * renderer.\n * @property {boolean|number} responsive=false If set to `true` resize the\n * waveform, when the window is resized. This is debounced with a `100ms`\n * timeout by default. If this parameter is a number it represents that timeout.\n * @property {boolean} rtl=false If set to `true`, renders waveform from\n * right-to-left.\n * @property {boolean} scrollParent=false Whether to scroll the container with a\n * lengthy waveform. Otherwise the waveform is shrunk to the container width\n * (see fillParent).\n * @property {number} skipLength=2 Number of seconds to skip with the\n * skipForward() and skipBackward() methods.\n * @property {boolean} splitChannels=false Render with separate waveforms for\n * the channels of the audio\n * @property {string} waveColor='#999' The fill color of the waveform after the\n * cursor.\n * @property {object} xhr={} XHR options. For example:\n * `let xhr = {\n * cache: 'default',\n * mode: 'cors',\n * method: 'GET',\n * credentials: 'same-origin',\n * redirect: 'follow',\n * referrer: 'client',\n * headers: [\n * {\n * key: 'Authorization',\n * value: 'my-token'\n * }\n * ]\n * };`\n */\n\n/**\n * @typedef {Object} PluginDefinition\n * @desc The Object used to describe a plugin\n * @example wavesurfer.addPlugin(pluginDefinition);\n * @property {string} name The name of the plugin, the plugin instance will be\n * added as a property to the wavesurfer instance under this name\n * @property {?Object} staticProps The properties that should be added to the\n * wavesurfer instance as static properties\n * @property {?boolean} deferInit Don't initialise plugin\n * automatically\n * @property {Object} params={} The plugin parameters, they are the first parameter\n * passed to the plugin class constructor function\n * @property {PluginClass} instance The plugin instance factory, is called with\n * the dependency specified in extends. Returns the plugin class.\n */\n\n/**\n * @interface PluginClass\n *\n * @desc This is the interface which is implemented by all plugin classes. Note\n * that this only turns into an observer after being passed through\n * `wavesurfer.addPlugin`.\n *\n * @extends {Observer}\n */\nclass PluginClass {\n /**\n * Plugin definition factory\n *\n * This function must be used to create a plugin definition which can be\n * used by wavesurfer to correctly instantiate the plugin.\n *\n * It returns a `PluginDefinition` object representing the plugin.\n *\n * @param {Object} params={} The plugin params (specific to the plugin)\n */\n create(params) {}\n /**\n * Construct the plugin\n *\n * @param {Object} params={} The plugin params (specific to the plugin)\n * @param {Object} ws The wavesurfer instance\n */\n constructor(params, ws) {}\n /**\n * Initialise the plugin\n *\n * Start doing something. This is called by\n * `wavesurfer.initPlugin(pluginName)`\n */\n init() {}\n /**\n * Destroy the plugin instance\n *\n * Stop doing something. This is called by\n * `wavesurfer.destroyPlugin(pluginName)`\n */\n destroy() {}\n}\n\n/**\n * WaveSurfer core library class\n *\n * @extends {Observer}\n * @example\n * const params = {\n * container: '#waveform',\n * waveColor: 'violet',\n * progressColor: 'purple'\n * };\n *\n * // initialise like this\n * const wavesurfer = WaveSurfer.create(params);\n *\n * // or like this ...\n * const wavesurfer = new WaveSurfer(params);\n * wavesurfer.init();\n *\n * // load audio file\n * wavesurfer.load('example/media/demo.wav');\n */\nexport default class WaveSurfer extends util.Observer {\n /** @private */\n defaultParams = {\n audioContext: null,\n audioScriptProcessor: null,\n audioRate: 1,\n autoCenter: true,\n autoCenterRate: 5,\n autoCenterImmediately: false,\n backend: 'WebAudio',\n backgroundColor: null,\n barHeight: 1,\n barRadius: 0,\n barGap: null,\n barMinHeight: null,\n container: null,\n cursorColor: '#333',\n cursorWidth: 1,\n dragSelection: true,\n drawingContextAttributes: {\n // Boolean that hints the user agent to reduce the latency\n // by desynchronizing the canvas paint cycle from the event\n // loop\n desynchronized: false\n },\n duration: null,\n fillParent: true,\n forceDecode: false,\n height: 128,\n hideScrollbar: false,\n interact: true,\n loopSelection: true,\n maxCanvasWidth: 4000,\n mediaContainer: null,\n mediaControls: false,\n mediaType: 'audio',\n minPxPerSec: 20,\n normalize: false,\n partialRender: false,\n pixelRatio:\n window.devicePixelRatio || screen.deviceXDPI / screen.logicalXDPI,\n plugins: [],\n progressColor: '#555',\n removeMediaElementOnDestroy: true,\n renderer: MultiCanvas,\n responsive: false,\n rtl: false,\n scrollParent: false,\n skipLength: 2,\n splitChannels: false,\n splitChannelsOptions: {\n overlay: false,\n channelColors: {},\n filterChannels: [],\n },\n waveColor: '#999',\n xhr: {}\n };\n\n /** @private */\n backends = {\n MediaElement,\n WebAudio,\n MediaElementWebAudio\n };\n\n /**\n * Instantiate this class, call its `init` function and returns it\n *\n * @param {WavesurferParams} params The wavesurfer parameters\n * @return {Object} WaveSurfer instance\n * @example const wavesurfer = WaveSurfer.create(params);\n */\n static create(params) {\n const wavesurfer = new WaveSurfer(params);\n return wavesurfer.init();\n }\n\n /**\n * The library version number is available as a static property of the\n * WaveSurfer class\n *\n * @type {String}\n * @example\n * console.log('Using wavesurfer.js ' + WaveSurfer.VERSION);\n */\n static VERSION = __VERSION__;\n\n /**\n * Functions in the `util` property are available as a prototype property to\n * all instances\n *\n * @type {Object}\n * @example\n * const wavesurfer = WaveSurfer.create(params);\n * wavesurfer.util.style(myElement, { background: 'blue' });\n */\n util = util;\n\n /**\n * Functions in the `util` property are available as a static property of the\n * WaveSurfer class\n *\n * @type {Object}\n * @example\n * WaveSurfer.util.style(myElement, { background: 'blue' });\n */\n static util = util;\n\n /**\n * Initialise wavesurfer instance\n *\n * @param {WavesurferParams} params Instantiation options for wavesurfer\n * @example\n * const wavesurfer = new WaveSurfer(params);\n * @returns {this} Wavesurfer instance\n */\n constructor(params) {\n super();\n /**\n * Extract relevant parameters (or defaults)\n * @private\n */\n this.params = Object.assign({}, this.defaultParams, params);\n\n /** @private */\n this.container =\n 'string' == typeof params.container\n ? document.querySelector(this.params.container)\n : this.params.container;\n\n if (!this.container) {\n throw new Error('Container element not found');\n }\n\n if (this.params.mediaContainer == null) {\n /** @private */\n this.mediaContainer = this.container;\n } else if (typeof this.params.mediaContainer == 'string') {\n /** @private */\n this.mediaContainer = document.querySelector(\n this.params.mediaContainer\n );\n } else {\n /** @private */\n this.mediaContainer = this.params.mediaContainer;\n }\n\n if (!this.mediaContainer) {\n throw new Error('Media Container element not found');\n }\n\n if (this.params.maxCanvasWidth <= 1) {\n throw new Error('maxCanvasWidth must be greater than 1');\n } else if (this.params.maxCanvasWidth % 2 == 1) {\n throw new Error('maxCanvasWidth must be an even number');\n }\n\n if (this.params.rtl === true) {\n util.style(this.container, { transform: 'rotateY(180deg)' });\n }\n\n if (this.params.backgroundColor) {\n this.setBackgroundColor(this.params.backgroundColor);\n }\n\n /**\n * @private Used to save the current volume when muting so we can\n * restore once unmuted\n * @type {number}\n */\n this.savedVolume = 0;\n\n /**\n * @private The current muted state\n * @type {boolean}\n */\n this.isMuted = false;\n\n /**\n * @private Will hold a list of event descriptors that need to be\n * canceled on subsequent loads of audio\n * @type {Object[]}\n */\n this.tmpEvents = [];\n\n /**\n * @private Holds any running audio downloads\n * @type {Observer}\n */\n this.currentRequest = null;\n /** @private */\n this.arraybuffer = null;\n /** @private */\n this.drawer = null;\n /** @private */\n this.backend = null;\n /** @private */\n this.peakCache = null;\n\n // cache constructor objects\n if (typeof this.params.renderer !== 'function') {\n throw new Error('Renderer parameter is invalid');\n }\n /**\n * @private The uninitialised Drawer class\n */\n this.Drawer = this.params.renderer;\n /**\n * @private The uninitialised Backend class\n */\n // Back compat\n if (this.params.backend == 'AudioElement') {\n this.params.backend = 'MediaElement';\n }\n\n if (\n (this.params.backend == 'WebAudio' ||\n this.params.backend === 'MediaElementWebAudio') &&\n !WebAudio.prototype.supportsWebAudio.call(null)\n ) {\n this.params.backend = 'MediaElement';\n }\n this.Backend = this.backends[this.params.backend];\n\n /**\n * @private map of plugin names that are currently initialised\n */\n this.initialisedPluginList = {};\n /** @private */\n this.isDestroyed = false;\n\n /**\n * Get the current ready status.\n *\n * @example const isReady = wavesurfer.isReady;\n * @return {boolean}\n */\n this.isReady = false;\n\n // responsive debounced event listener. If this.params.responsive is not\n // set, this is never called. Use 100ms or this.params.responsive as\n // timeout for the debounce function.\n let prevWidth = 0;\n this._onResize = util.debounce(\n () => {\n if (\n prevWidth != this.drawer.wrapper.clientWidth &&\n !this.params.scrollParent\n ) {\n prevWidth = this.drawer.wrapper.clientWidth;\n this.drawer.fireEvent('redraw');\n }\n },\n typeof this.params.responsive === 'number'\n ? this.params.responsive\n : 100\n );\n\n return this;\n }\n\n /**\n * Initialise the wave\n *\n * @example\n * var wavesurfer = new WaveSurfer(params);\n * wavesurfer.init();\n * @return {this} The wavesurfer instance\n */\n init() {\n this.registerPlugins(this.params.plugins);\n this.createDrawer();\n this.createBackend();\n this.createPeakCache();\n return this;\n }\n\n /**\n * Add and initialise array of plugins (if `plugin.deferInit` is falsey),\n * this function is called in the init function of wavesurfer\n *\n * @param {PluginDefinition[]} plugins An array of plugin definitions\n * @emits {WaveSurfer#plugins-registered} Called with the array of plugin definitions\n * @return {this} The wavesurfer instance\n */\n registerPlugins(plugins) {\n // first instantiate all the plugins\n plugins.forEach(plugin => this.addPlugin(plugin));\n\n // now run the init functions\n plugins.forEach(plugin => {\n // call init function of the plugin if deferInit is falsey\n // in that case you would manually use initPlugins()\n if (!plugin.deferInit) {\n this.initPlugin(plugin.name);\n }\n });\n this.fireEvent('plugins-registered', plugins);\n return this;\n }\n\n /**\n * Get a map of plugin names that are currently initialised\n *\n * @example wavesurfer.getPlugins();\n * @return {Object} Object with plugin names\n */\n getActivePlugins() {\n return this.initialisedPluginList;\n }\n\n /**\n * Add a plugin object to wavesurfer\n *\n * @param {PluginDefinition} plugin A plugin definition\n * @emits {WaveSurfer#plugin-added} Called with the name of the plugin that was added\n * @example wavesurfer.addPlugin(WaveSurfer.minimap());\n * @return {this} The wavesurfer instance\n */\n addPlugin(plugin) {\n if (!plugin.name) {\n throw new Error('Plugin does not have a name!');\n }\n if (!plugin.instance) {\n throw new Error(\n `Plugin ${plugin.name} does not have an instance property!`\n );\n }\n\n // staticProps properties are applied to wavesurfer instance\n if (plugin.staticProps) {\n Object.keys(plugin.staticProps).forEach(pluginStaticProp => {\n /**\n * Properties defined in a plugin definition's `staticProps` property are added as\n * staticProps properties of the WaveSurfer instance\n */\n this[pluginStaticProp] = plugin.staticProps[pluginStaticProp];\n });\n }\n\n const Instance = plugin.instance;\n\n // turn the plugin instance into an observer\n const observerPrototypeKeys = Object.getOwnPropertyNames(\n util.Observer.prototype\n );\n observerPrototypeKeys.forEach(key => {\n Instance.prototype[key] = util.Observer.prototype[key];\n });\n\n /**\n * Instantiated plugin classes are added as a property of the wavesurfer\n * instance\n * @type {Object}\n */\n this[plugin.name] = new Instance(plugin.params || {}, this);\n this.fireEvent('plugin-added', plugin.name);\n return this;\n }\n\n /**\n * Initialise a plugin\n *\n * @param {string} name A plugin name\n * @emits WaveSurfer#plugin-initialised\n * @example wavesurfer.initPlugin('minimap');\n * @return {this} The wavesurfer instance\n */\n initPlugin(name) {\n if (!this[name]) {\n throw new Error(`Plugin ${name} has not been added yet!`);\n }\n if (this.initialisedPluginList[name]) {\n // destroy any already initialised plugins\n this.destroyPlugin(name);\n }\n this[name].init();\n this.initialisedPluginList[name] = true;\n this.fireEvent('plugin-initialised', name);\n return this;\n }\n\n /**\n * Destroy a plugin\n *\n * @param {string} name A plugin name\n * @emits WaveSurfer#plugin-destroyed\n * @example wavesurfer.destroyPlugin('minimap');\n * @returns {this} The wavesurfer instance\n */\n destroyPlugin(name) {\n if (!this[name]) {\n throw new Error(\n `Plugin ${name} has not been added yet and cannot be destroyed!`\n );\n }\n if (!this.initialisedPluginList[name]) {\n throw new Error(\n `Plugin ${name} is not active and cannot be destroyed!`\n );\n }\n if (typeof this[name].destroy !== 'function') {\n throw new Error(`Plugin ${name} does not have a destroy function!`);\n }\n\n this[name].destroy();\n delete this.initialisedPluginList[name];\n this.fireEvent('plugin-destroyed', name);\n return this;\n }\n\n /**\n * Destroy all initialised plugins. Convenience function to use when\n * wavesurfer is removed\n *\n * @private\n */\n destroyAllPlugins() {\n Object.keys(this.initialisedPluginList).forEach(name =>\n this.destroyPlugin(name)\n );\n }\n\n /**\n * Create the drawer and draw the waveform\n *\n * @private\n * @emits WaveSurfer#drawer-created\n */\n createDrawer() {\n this.drawer = new this.Drawer(this.container, this.params);\n this.drawer.init();\n this.fireEvent('drawer-created', this.drawer);\n\n if (this.params.responsive !== false) {\n window.addEventListener('resize', this._onResize, true);\n window.addEventListener('orientationchange', this._onResize, true);\n }\n\n this.drawer.on('redraw', () => {\n this.drawBuffer();\n this.drawer.progress(this.backend.getPlayedPercents());\n });\n\n // Click-to-seek\n this.drawer.on('click', (e, progress) => {\n setTimeout(() => this.seekTo(progress), 0);\n });\n\n // Relay the scroll event from the drawer\n this.drawer.on('scroll', e => {\n if (this.params.partialRender) {\n this.drawBuffer();\n }\n this.fireEvent('scroll', e);\n });\n }\n\n /**\n * Create the backend\n *\n * @private\n * @emits WaveSurfer#backend-created\n */\n createBackend() {\n if (this.backend) {\n this.backend.destroy();\n }\n\n this.backend = new this.Backend(this.params);\n this.backend.init();\n this.fireEvent('backend-created', this.backend);\n\n this.backend.on('finish', () => {\n this.drawer.progress(this.backend.getPlayedPercents());\n this.fireEvent('finish');\n });\n this.backend.on('play', () => this.fireEvent('play'));\n this.backend.on('pause', () => this.fireEvent('pause'));\n\n this.backend.on('audioprocess', time => {\n this.drawer.progress(this.backend.getPlayedPercents());\n this.fireEvent('audioprocess', time);\n });\n\n // only needed for MediaElement and MediaElementWebAudio backend\n if (\n this.params.backend === 'MediaElement' ||\n this.params.backend === 'MediaElementWebAudio'\n ) {\n this.backend.on('seek', () => {\n this.drawer.progress(this.backend.getPlayedPercents());\n });\n\n this.backend.on('volume', () => {\n let newVolume = this.getVolume();\n this.fireEvent('volume', newVolume);\n\n if (this.backend.isMuted !== this.isMuted) {\n this.isMuted = this.backend.isMuted;\n this.fireEvent('mute', this.isMuted);\n }\n });\n }\n }\n\n /**\n * Create the peak cache\n *\n * @private\n */\n createPeakCache() {\n if (this.params.partialRender) {\n this.peakCache = new PeakCache();\n }\n }\n\n /**\n * Get the duration of the audio clip\n *\n * @example const duration = wavesurfer.getDuration();\n * @return {number} Duration in seconds\n */\n getDuration() {\n return this.backend.getDuration();\n }\n\n /**\n * Get the current playback position\n *\n * @example const currentTime = wavesurfer.getCurrentTime();\n * @return {number} Playback position in seconds\n */\n getCurrentTime() {\n return this.backend.getCurrentTime();\n }\n\n /**\n * Set the current play time in seconds.\n *\n * @param {number} seconds A positive number in seconds. E.g. 10 means 10\n * seconds, 60 means 1 minute\n */\n setCurrentTime(seconds) {\n if (seconds >= this.getDuration()) {\n this.seekTo(1);\n } else {\n this.seekTo(seconds / this.getDuration());\n }\n }\n\n /**\n * Starts playback from the current position. Optional start and end\n * measured in seconds can be used to set the range of audio to play.\n *\n * @param {?number} start Position to start at\n * @param {?number} end Position to end at\n * @emits WaveSurfer#interaction\n * @return {Promise} Result of the backend play method\n * @example\n * // play from second 1 to 5\n * wavesurfer.play(1, 5);\n */\n play(start, end) {\n this.fireEvent('interaction', () => this.play(start, end));\n return this.backend.play(start, end);\n }\n\n /**\n * Set a point in seconds for playback to stop at.\n *\n * @param {number} position Position (in seconds) to stop at\n * @version 3.3.0\n */\n setPlayEnd(position) {\n this.backend.setPlayEnd(position);\n }\n\n /**\n * Stops and pauses playback\n *\n * @example wavesurfer.pause();\n * @return {Promise} Result of the backend pause method\n */\n pause() {\n if (!this.backend.isPaused()) {\n return this.backend.pause();\n }\n }\n\n /**\n * Toggle playback\n *\n * @example wavesurfer.playPause();\n * @return {Promise} Result of the backend play or pause method\n */\n playPause() {\n return this.backend.isPaused() ? this.play() : this.pause();\n }\n\n /**\n * Get the current playback state\n *\n * @example const isPlaying = wavesurfer.isPlaying();\n * @return {boolean} False if paused, true if playing\n */\n isPlaying() {\n return !this.backend.isPaused();\n }\n\n /**\n * Skip backward\n *\n * @param {?number} seconds Amount to skip back, if not specified `skipLength`\n * is used\n * @example wavesurfer.skipBackward();\n */\n skipBackward(seconds) {\n this.skip(-seconds || -this.params.skipLength);\n }\n\n /**\n * Skip forward\n *\n * @param {?number} seconds Amount to skip back, if not specified `skipLength`\n * is used\n * @example wavesurfer.skipForward();\n */\n skipForward(seconds) {\n this.skip(seconds || this.params.skipLength);\n }\n\n /**\n * Skip a number of seconds from the current position (use a negative value\n * to go backwards).\n *\n * @param {number} offset Amount to skip back or forwards\n * @example\n * // go back 2 seconds\n * wavesurfer.skip(-2);\n */\n skip(offset) {\n const duration = this.getDuration() || 1;\n let position = this.getCurrentTime() || 0;\n position = Math.max(0, Math.min(duration, position + (offset || 0)));\n this.seekAndCenter(position / duration);\n }\n\n /**\n * Seeks to a position and centers the view\n *\n * @param {number} progress Between 0 (=beginning) and 1 (=end)\n * @example\n * // seek and go to the middle of the audio\n * wavesurfer.seekTo(0.5);\n */\n seekAndCenter(progress) {\n this.seekTo(progress);\n this.drawer.recenter(progress);\n }\n\n /**\n * Seeks to a position\n *\n * @param {number} progress Between 0 (=beginning) and 1 (=end)\n * @emits WaveSurfer#interaction\n * @emits WaveSurfer#seek\n * @example\n * // seek to the middle of the audio\n * wavesurfer.seekTo(0.5);\n */\n seekTo(progress) {\n // return an error if progress is not a number between 0 and 1\n if (\n typeof progress !== 'number' ||\n !isFinite(progress) ||\n progress < 0 ||\n progress > 1\n ) {\n throw new Error(\n 'Error calling wavesurfer.seekTo, parameter must be a number between 0 and 1!'\n );\n }\n this.fireEvent('interaction', () => this.seekTo(progress));\n\n const paused = this.backend.isPaused();\n // avoid draw wrong position while playing backward seeking\n if (!paused) {\n this.backend.pause();\n }\n // avoid small scrolls while paused seeking\n const oldScrollParent = this.params.scrollParent;\n this.params.scrollParent = false;\n this.backend.seekTo(progress * this.getDuration());\n this.drawer.progress(progress);\n\n if (!paused) {\n this.backend.play();\n }\n this.params.scrollParent = oldScrollParent;\n this.fireEvent('seek', progress);\n }\n\n /**\n * Stops and goes to the beginning.\n *\n * @example wavesurfer.stop();\n */\n stop() {\n this.pause();\n this.seekTo(0);\n this.drawer.progress(0);\n }\n\n /**\n * Sets the ID of the audio device to use for output and returns a Promise.\n *\n * @param {string} deviceId String value representing underlying output\n * device\n * @returns {Promise} `Promise` that resolves to `undefined` when there are\n * no errors detected.\n */\n setSinkId(deviceId) {\n return this.backend.setSinkId(deviceId);\n }\n\n /**\n * Set the playback volume.\n *\n * @param {number} newVolume A value between 0 and 1, 0 being no\n * volume and 1 being full volume.\n * @emits WaveSurfer#volume\n */\n setVolume(newVolume) {\n this.backend.setVolume(newVolume);\n this.fireEvent('volume', newVolume);\n }\n\n /**\n * Get the playback volume.\n *\n * @return {number} A value between 0 and 1, 0 being no\n * volume and 1 being full volume.\n */\n getVolume() {\n return this.backend.getVolume();\n }\n\n /**\n * Set the playback rate.\n *\n * @param {number} rate A positive number. E.g. 0.5 means half the normal\n * speed, 2 means double speed and so on.\n * @example wavesurfer.setPlaybackRate(2);\n */\n setPlaybackRate(rate) {\n this.backend.setPlaybackRate(rate);\n }\n\n /**\n * Get the playback rate.\n *\n * @return {number} The current playback rate.\n */\n getPlaybackRate() {\n return this.backend.getPlaybackRate();\n }\n\n /**\n * Toggle the volume on and off. If not currently muted it will save the\n * current volume value and turn the volume off. If currently muted then it\n * will restore the volume to the saved value, and then rest the saved\n * value.\n *\n * @example wavesurfer.toggleMute();\n */\n toggleMute() {\n this.setMute(!this.isMuted);\n }\n\n /**\n * Enable or disable muted audio\n *\n * @param {boolean} mute Specify `true` to mute audio.\n * @emits WaveSurfer#volume\n * @emits WaveSurfer#mute\n * @example\n * // unmute\n * wavesurfer.setMute(false);\n * console.log(wavesurfer.getMute()) // logs false\n */\n setMute(mute) {\n // ignore all muting requests if the audio is already in that state\n if (mute === this.isMuted) {\n this.fireEvent('mute', this.isMuted);\n return;\n }\n\n if (this.backend.setMute) {\n // Backends such as the MediaElement backend have their own handling\n // of mute, let them handle it.\n this.backend.setMute(mute);\n this.isMuted = mute;\n } else {\n if (mute) {\n // If currently not muted then save current volume,\n // turn off the volume and update the mute properties\n this.savedVolume = this.backend.getVolume();\n this.backend.setVolume(0);\n this.isMuted = true;\n this.fireEvent('volume', 0);\n } else {\n // If currently muted then restore to the saved volume\n // and update the mute properties\n this.backend.setVolume(this.savedVolume);\n this.isMuted = false;\n this.fireEvent('volume', this.savedVolume);\n }\n }\n this.fireEvent('mute', this.isMuted);\n }\n\n /**\n * Get the current mute status.\n *\n * @example const isMuted = wavesurfer.getMute();\n * @return {boolean} Current mute status\n */\n getMute() {\n return this.isMuted;\n }\n\n /**\n * Get the list of current set filters as an array.\n *\n * Filters must be set with setFilters method first\n *\n * @return {array} List of enabled filters\n */\n getFilters() {\n return this.backend.filters || [];\n }\n\n /**\n * Toggles `scrollParent` and redraws\n *\n * @example wavesurfer.toggleScroll();\n */\n toggleScroll() {\n this.params.scrollParent = !this.params.scrollParent;\n this.drawBuffer();\n }\n\n /**\n * Toggle mouse interaction\n *\n * @example wavesurfer.toggleInteraction();\n */\n toggleInteraction() {\n this.params.interact = !this.params.interact;\n }\n\n /**\n * Get the fill color of the waveform after the cursor.\n *\n * @return {string} A CSS color string.\n */\n getWaveColor() {\n return this.params.waveColor;\n }\n\n /**\n * Set the fill color of the waveform after the cursor.\n *\n * @param {string} color A CSS color string.\n * @example wavesurfer.setWaveColor('#ddd');\n */\n setWaveColor(color) {\n this.params.waveColor = color;\n this.drawBuffer();\n }\n\n /**\n * Get the fill color of the waveform behind the cursor.\n *\n * @return {string} A CSS color string.\n */\n getProgressColor() {\n return this.params.progressColor;\n }\n\n /**\n * Set the fill color of the waveform behind the cursor.\n *\n * @param {string} color A CSS color string.\n * @example wavesurfer.setProgressColor('#400');\n */\n setProgressColor(color) {\n this.params.progressColor = color;\n this.drawBuffer();\n }\n\n /**\n * Get the background color of the waveform container.\n *\n * @return {string} A CSS color string.\n */\n getBackgroundColor() {\n return this.params.backgroundColor;\n }\n\n /**\n * Set the background color of the waveform container.\n *\n * @param {string} color A CSS color string.\n * @example wavesurfer.setBackgroundColor('#FF00FF');\n */\n setBackgroundColor(color) {\n this.params.backgroundColor = color;\n util.style(this.container, { background: this.params.backgroundColor });\n }\n\n /**\n * Get the fill color of the cursor indicating the playhead\n * position.\n *\n * @return {string} A CSS color string.\n */\n getCursorColor() {\n return this.params.cursorColor;\n }\n\n /**\n * Set the fill color of the cursor indicating the playhead\n * position.\n *\n * @param {string} color A CSS color string.\n * @example wavesurfer.setCursorColor('#222');\n */\n setCursorColor(color) {\n this.params.cursorColor = color;\n this.drawer.updateCursor();\n }\n\n /**\n * Get the height of the waveform.\n *\n * @return {number} Height measured in pixels.\n */\n getHeight() {\n return this.params.height;\n }\n\n /**\n * Set the height of the waveform.\n *\n * @param {number} height Height measured in pixels.\n * @example wavesurfer.setHeight(200);\n */\n setHeight(height) {\n this.params.height = height;\n this.drawer.setHeight(height * this.params.pixelRatio);\n this.drawBuffer();\n }\n\n /**\n * Hide channels from being drawn on the waveform if splitting channels.\n *\n * For example, if we want to draw only the peaks for the right stereo channel:\n *\n * const wavesurfer = new WaveSurfer.create({...splitChannels: true});\n * wavesurfer.load('stereo_audio.mp3');\n *\n * wavesurfer.setFilteredChannel([0]); <-- hide left channel peaks.\n *\n * @param {array} channelIndices Channels to be filtered out from drawing.\n * @version 4.0.0\n */\n setFilteredChannels(channelIndices) {\n this.params.splitChannelsOptions.filterChannels = channelIndices;\n this.drawBuffer();\n }\n\n /**\n * Get the correct peaks for current wave view-port and render wave\n *\n * @private\n * @emits WaveSurfer#redraw\n */\n drawBuffer() {\n const nominalWidth = Math.round(\n this.getDuration() *\n this.params.minPxPerSec *\n this.params.pixelRatio\n );\n const parentWidth = this.drawer.getWidth();\n let width = nominalWidth;\n // always start at 0 after zooming for scrolling : issue redraw left part\n let start = 0;\n let end = Math.max(start + parentWidth, width);\n // Fill container\n if (\n this.params.fillParent &&\n (!this.params.scrollParent || nominalWidth < parentWidth)\n ) {\n width = parentWidth;\n start = 0;\n end = width;\n }\n\n let peaks;\n if (this.params.partialRender) {\n const newRanges = this.peakCache.addRangeToPeakCache(\n width,\n start,\n end\n );\n let i;\n for (i = 0; i < newRanges.length; i++) {\n peaks = this.backend.getPeaks(\n width,\n newRanges[i][0],\n newRanges[i][1]\n );\n this.drawer.drawPeaks(\n peaks,\n width,\n newRanges[i][0],\n newRanges[i][1]\n );\n }\n } else {\n peaks = this.backend.getPeaks(width, start, end);\n this.drawer.drawPeaks(peaks, width, start, end);\n }\n this.fireEvent('redraw', peaks, width);\n }\n\n /**\n * Horizontally zooms the waveform in and out. It also changes the parameter\n * `minPxPerSec` and enables the `scrollParent` option. Calling the function\n * with a falsey parameter will reset the zoom state.\n *\n * @param {?number} pxPerSec Number of horizontal pixels per second of\n * audio, if none is set the waveform returns to unzoomed state\n * @emits WaveSurfer#zoom\n * @example wavesurfer.zoom(20);\n */\n zoom(pxPerSec) {\n if (!pxPerSec) {\n this.params.minPxPerSec = this.defaultParams.minPxPerSec;\n this.params.scrollParent = false;\n } else {\n this.params.minPxPerSec = pxPerSec;\n this.params.scrollParent = true;\n }\n\n this.drawBuffer();\n this.drawer.progress(this.backend.getPlayedPercents());\n\n this.drawer.recenter(this.getCurrentTime() / this.getDuration());\n this.fireEvent('zoom', pxPerSec);\n }\n\n /**\n * Decode buffer and load\n *\n * @private\n * @param {ArrayBuffer} arraybuffer Buffer to process\n */\n loadArrayBuffer(arraybuffer) {\n this.decodeArrayBuffer(arraybuffer, data => {\n if (!this.isDestroyed) {\n this.loadDecodedBuffer(data);\n }\n });\n }\n\n /**\n * Directly load an externally decoded AudioBuffer\n *\n * @private\n * @param {AudioBuffer} buffer Buffer to process\n * @emits WaveSurfer#ready\n */\n loadDecodedBuffer(buffer) {\n this.backend.load(buffer);\n this.drawBuffer();\n this.isReady = true;\n this.fireEvent('ready');\n }\n\n /**\n * Loads audio data from a Blob or File object\n *\n * @param {Blob|File} blob Audio data\n * @example\n */\n loadBlob(blob) {\n // Create file reader\n const reader = new FileReader();\n reader.addEventListener('progress', e => this.onProgress(e));\n reader.addEventListener('load', e =>\n this.loadArrayBuffer(e.target.result)\n );\n reader.addEventListener('error', () =>\n this.fireEvent('error', 'Error reading file')\n );\n reader.readAsArrayBuffer(blob);\n this.empty();\n }\n\n /**\n * Loads audio and re-renders the waveform.\n *\n * @param {string|HTMLMediaElement} url The url of the audio file or the\n * audio element with the audio\n * @param {number[]|Number.} peaks Wavesurfer does not have to decode\n * the audio to render the waveform if this is specified\n * @param {?string} preload (Use with backend `MediaElement` and `MediaElementWebAudio`)\n * `'none'|'metadata'|'auto'` Preload attribute for the media element\n * @param {?number} duration The duration of the audio. This is used to\n * render the peaks data in the correct size for the audio duration (as\n * befits the current `minPxPerSec` and zoom value) without having to decode\n * the audio.\n * @returns {void}\n * @throws Will throw an error if the `url` argument is empty.\n * @example\n * // uses fetch or media element to load file (depending on backend)\n * wavesurfer.load('http://example.com/demo.wav');\n *\n * // setting preload attribute with media element backend and supplying\n * // peaks\n * wavesurfer.load(\n * 'http://example.com/demo.wav',\n * [0.0218, 0.0183, 0.0165, 0.0198, 0.2137, 0.2888],\n * true\n * );\n */\n load(url, peaks, preload, duration) {\n if (!url) {\n throw new Error('url parameter cannot be empty');\n }\n this.empty();\n if (preload) {\n // check whether the preload attribute will be usable and if not log\n // a warning listing the reasons why not and nullify the variable\n const preloadIgnoreReasons = {\n \"Preload is not 'auto', 'none' or 'metadata'\":\n ['auto', 'metadata', 'none'].indexOf(preload) === -1,\n 'Peaks are not provided': !peaks,\n \"Backend is not of type 'MediaElement' or 'MediaElementWebAudio'\":\n ['MediaElement', 'MediaElementWebAudio'].indexOf(\n this.params.backend\n ) === -1,\n 'Url is not of type string': typeof url !== 'string'\n };\n const activeReasons = Object.keys(preloadIgnoreReasons).filter(\n reason => preloadIgnoreReasons[reason]\n );\n if (activeReasons.length) {\n // eslint-disable-next-line no-console\n console.warn(\n 'Preload parameter of wavesurfer.load will be ignored because:\\n\\t- ' +\n activeReasons.join('\\n\\t- ')\n );\n // stop invalid values from being used\n preload = null;\n }\n }\n\n switch (this.params.backend) {\n case 'WebAudio':\n return this.loadBuffer(url, peaks, duration);\n case 'MediaElement':\n case 'MediaElementWebAudio':\n return this.loadMediaElement(url, peaks, preload, duration);\n }\n }\n\n /**\n * Loads audio using Web Audio buffer backend.\n *\n * @private\n * @param {string} url URL of audio file\n * @param {number[]|Number.} peaks Peaks data\n * @param {?number} duration Optional duration of audio file\n * @returns {void}\n */\n loadBuffer(url, peaks, duration) {\n const load = action => {\n if (action) {\n this.tmpEvents.push(this.once('ready', action));\n }\n return this.getArrayBuffer(url, data => this.loadArrayBuffer(data));\n };\n\n if (peaks) {\n this.backend.setPeaks(peaks, duration);\n this.drawBuffer();\n this.tmpEvents.push(this.once('interaction', load));\n } else {\n return load();\n }\n }\n\n /**\n * Either create a media element, or load an existing media element.\n *\n * @private\n * @param {string|HTMLMediaElement} urlOrElt Either a path to a media file, or an\n * existing HTML5 Audio/Video Element\n * @param {number[]|Number.} peaks Array of peaks. Required to bypass web audio\n * dependency\n * @param {?boolean} preload Set to true if the preload attribute of the\n * audio element should be enabled\n * @param {?number} duration Optional duration of audio file\n */\n loadMediaElement(urlOrElt, peaks, preload, duration) {\n let url = urlOrElt;\n\n if (typeof urlOrElt === 'string') {\n this.backend.load(url, this.mediaContainer, peaks, preload);\n } else {\n const elt = urlOrElt;\n this.backend.loadElt(elt, peaks);\n\n // If peaks are not provided,\n // url = element.src so we can get peaks with web audio\n url = elt.src;\n }\n\n this.tmpEvents.push(\n this.backend.once('canplay', () => {\n // ignore when backend was already destroyed\n if (!this.backend.destroyed) {\n this.drawBuffer();\n this.isReady = true;\n this.fireEvent('ready');\n }\n }),\n this.backend.once('error', err => this.fireEvent('error', err))\n );\n\n // If no pre-decoded peaks provided or pre-decoded peaks are\n // provided with forceDecode flag, attempt to download the\n // audio file and decode it with Web Audio.\n if (peaks) {\n this.backend.setPeaks(peaks, duration);\n }\n\n if (\n (!peaks || this.params.forceDecode) &&\n this.backend.supportsWebAudio()\n ) {\n this.getArrayBuffer(url, arraybuffer => {\n this.decodeArrayBuffer(arraybuffer, buffer => {\n this.backend.buffer = buffer;\n this.backend.setPeaks(null);\n this.drawBuffer();\n this.fireEvent('waveform-ready');\n });\n });\n }\n }\n\n /**\n * Decode an array buffer and pass data to a callback\n *\n * @private\n * @param {Object} arraybuffer The array buffer to decode\n * @param {function} callback The function to call on complete\n */\n decodeArrayBuffer(arraybuffer, callback) {\n this.arraybuffer = arraybuffer;\n this.backend.decodeArrayBuffer(\n arraybuffer,\n data => {\n // Only use the decoded data if we haven't been destroyed or\n // another decode started in the meantime\n if (!this.isDestroyed && this.arraybuffer == arraybuffer) {\n callback(data);\n this.arraybuffer = null;\n }\n },\n () => this.fireEvent('error', 'Error decoding audiobuffer')\n );\n }\n\n /**\n * Load an array buffer using fetch and pass the result to a callback\n *\n * @param {string} url The URL of the file object\n * @param {function} callback The function to call on complete\n * @returns {util.fetchFile} fetch call\n * @private\n */\n getArrayBuffer(url, callback) {\n let options = Object.assign(\n {\n url: url,\n responseType: 'arraybuffer'\n },\n this.params.xhr\n );\n const request = util.fetchFile(options);\n\n this.currentRequest = request;\n\n this.tmpEvents.push(\n request.on('progress', e => {\n this.onProgress(e);\n }),\n request.on('success', data => {\n callback(data);\n this.currentRequest = null;\n }),\n request.on('error', e => {\n this.fireEvent('error', e);\n this.currentRequest = null;\n })\n );\n\n return request;\n }\n\n /**\n * Called while the audio file is loading\n *\n * @private\n * @param {Event} e Progress event\n * @emits WaveSurfer#loading\n */\n onProgress(e) {\n let percentComplete;\n if (e.lengthComputable) {\n percentComplete = e.loaded / e.total;\n } else {\n // Approximate progress with an asymptotic\n // function, and assume downloads in the 1-3 MB range.\n percentComplete = e.loaded / (e.loaded + 1000000);\n }\n this.fireEvent('loading', Math.round(percentComplete * 100), e.target);\n }\n\n /**\n * Exports PCM data into a JSON array and opens in a new window.\n *\n * @param {number} length=1024 The scale in which to export the peaks\n * @param {number} accuracy=10000\n * @param {?boolean} noWindow Set to true to disable opening a new\n * window with the JSON\n * @param {number} start Start index\n * @param {number} end End index\n * @return {Promise} Promise that resolves with array of peaks\n */\n exportPCM(length, accuracy, noWindow, start, end) {\n length = length || 1024;\n start = start || 0;\n accuracy = accuracy || 10000;\n noWindow = noWindow || false;\n const peaks = this.backend.getPeaks(length, start, end);\n const arr = [].map.call(\n peaks,\n val => Math.round(val * accuracy) / accuracy\n );\n return new Promise((resolve, reject) => {\n const json = JSON.stringify(arr);\n\n if (!noWindow) {\n window.open(\n 'data:application/json;charset=utf-8,' +\n encodeURIComponent(json)\n );\n }\n resolve(json);\n });\n }\n\n /**\n * Save waveform image as data URI.\n *\n * The default format is `'image/png'`. Other supported types are\n * `'image/jpeg'` and `'image/webp'`.\n *\n * @param {string} format='image/png' A string indicating the image format.\n * The default format type is `'image/png'`.\n * @param {number} quality=1 A number between 0 and 1 indicating the image\n * quality to use for image formats that use lossy compression such as\n * `'image/jpeg'`` and `'image/webp'`.\n * @param {string} type Image data type to return. Either 'dataURL' (default)\n * or 'blob'.\n * @return {string|string[]|Promise} When using `'dataURL'` type this returns\n * a single data URL or an array of data URLs, one for each canvas. When using\n * `'blob'` type this returns a `Promise` resolving with an array of `Blob`\n * instances, one for each canvas.\n */\n exportImage(format, quality, type) {\n if (!format) {\n format = 'image/png';\n }\n if (!quality) {\n quality = 1;\n }\n if (!type) {\n type = 'dataURL';\n }\n\n return this.drawer.getImage(format, quality, type);\n }\n\n /**\n * Cancel any fetch request currently in progress\n */\n cancelAjax() {\n if (this.currentRequest && this.currentRequest.controller) {\n this.currentRequest.controller.abort();\n this.currentRequest = null;\n }\n }\n\n /**\n * @private\n */\n clearTmpEvents() {\n this.tmpEvents.forEach(e => e.un());\n }\n\n /**\n * Display empty waveform.\n */\n empty() {\n if (!this.backend.isPaused()) {\n this.stop();\n this.backend.disconnectSource();\n }\n this.isReady = false;\n this.cancelAjax();\n this.clearTmpEvents();\n\n // empty drawer\n this.drawer.progress(0);\n this.drawer.setWidth(0);\n this.drawer.drawPeaks({ length: this.drawer.getWidth() }, 0);\n }\n\n /**\n * Remove events, elements and disconnect WebAudio nodes.\n *\n * @emits WaveSurfer#destroy\n */\n destroy() {\n this.destroyAllPlugins();\n this.fireEvent('destroy');\n this.cancelAjax();\n this.clearTmpEvents();\n this.unAll();\n if (this.params.responsive !== false) {\n window.removeEventListener('resize', this._onResize, true);\n window.removeEventListener(\n 'orientationchange',\n this._onResize,\n true\n );\n }\n if (this.backend) {\n this.backend.destroy();\n }\n if (this.drawer) {\n this.drawer.destroy();\n }\n this.isDestroyed = true;\n this.isReady = false;\n this.arraybuffer = null;\n }\n}\n","import Observer from './observer';\n\n/**\n * Perform an ajax request using `XMLHttpRequest`.\n *\n * @deprecated Use `util.fetchFile` instead.\n *\n * @param {Object} options AJAX options to use. See example below for options.\n * @returns {Observer} Observer instance\n * @example\n * // default options\n * let options = {\n * method: 'GET',\n * url: undefined,\n * responseType: 'json',\n * xhr: {}\n * };\n *\n * // override default options\n * options.url = '../media/demo.wav';\n * options.responseType = 'arraybuffer';\n * options.xhr = {\n * requestHeaders: [\n * {\n * key: 'Authorization',\n * value: 'my-token'\n * }\n * ],\n * withCredentials: true\n * };\n *\n * // make ajax call\n * let ajaxCall = util.ajax(options);\n * ajaxCall.on('progress', e => {\n * console.log('progress', e);\n * });\n * ajaxCall.on('success', (data, e) => {\n * console.log('success!', data);\n * });\n * ajaxCall.on('error', e => {\n * console.warn('ajax error: ' + e.target.statusText);\n * });\n */\nexport default function ajax(options) {\n const instance = new Observer();\n const xhr = new XMLHttpRequest();\n let fired100 = false;\n xhr.open(options.method || 'GET', options.url, true);\n xhr.responseType = options.responseType || 'json';\n\n if (options.xhr) {\n if (options.xhr.requestHeaders) {\n // add custom request headers\n options.xhr.requestHeaders.forEach(header => {\n xhr.setRequestHeader(header.key, header.value);\n });\n }\n if (options.xhr.withCredentials) {\n // use credentials\n xhr.withCredentials = true;\n }\n }\n\n xhr.addEventListener('progress', e => {\n instance.fireEvent('progress', e);\n if (e.lengthComputable && e.loaded == e.total) {\n fired100 = true;\n }\n });\n xhr.addEventListener('load', e => {\n if (!fired100) {\n instance.fireEvent('progress', e);\n }\n instance.fireEvent('load', e);\n if (200 == xhr.status || 206 == xhr.status) {\n instance.fireEvent('success', xhr.response, e);\n } else {\n instance.fireEvent('error', e);\n }\n });\n xhr.addEventListener('error', e => instance.fireEvent('error', e));\n xhr.send();\n instance.xhr = xhr;\n return instance;\n}\n","/**\n * Get the largest value\n *\n * @param {Array} values Array of numbers\n * @returns {Number} Largest number found\n * @example console.log(max([1, 2, 3])); // logs 3\n */\nexport default function max(values) {\n let largest = -Infinity;\n Object.keys(values).forEach(i => {\n if (values[i] > largest) {\n largest = values[i];\n }\n });\n return largest;\n}\n","/**\n * Get the smallest value\n *\n * @param {Array} values Array of numbers\n * @returns {Number} Smallest number found\n * @example console.log(min([1, 2, 3])); // logs 1\n */\nexport default function min(values) {\n let smallest = Number(Infinity);\n Object.keys(values).forEach(i => {\n if (values[i] < smallest) {\n smallest = values[i];\n }\n });\n return smallest;\n}\n","/* eslint no-console: [\"error\", { allow: [\"warn\"] }] */\n/**\n * Extend an object shallowly with others\n *\n * @param {Object} dest The target object\n * @param {Object[]} sources The objects to use for extending\n *\n * @return {Object} Merged object\n * @deprecated since version 3.3.0\n */\nexport default function extend(dest, ...sources) {\n console.warn('util.extend is deprecated; use Object.assign instead');\n sources.forEach(source => {\n Object.keys(source).forEach(key => {\n dest[key] = source[key];\n });\n });\n return dest;\n}\n","import reqAnimationFrame from './request-animation-frame';\n\n/**\n * Create a function which will be called at the next requestAnimationFrame\n * cycle\n *\n * @param {function} func The function to call\n *\n * @return {func} The function wrapped within a requestAnimationFrame\n */\nexport default function frame(func) {\n return (...args) => reqAnimationFrame(() => func(...args));\n}\n","/**\n * Returns a function, that, as long as it continues to be invoked, will not\n * be triggered. The function will be called after it stops being called for\n * N milliseconds. If `immediate` is passed, trigger the function on the\n * leading edge, instead of the trailing. The function also has a property 'clear' \n * that is a function which will clear the timer to prevent previously scheduled executions. \n *\n * @source underscore.js\n * @see http://unscriptable.com/2009/03/20/debouncing-javascript-methods/\n * @param {Function} function to wrap\n * @param {Number} timeout in ms (`100`)\n * @param {Boolean} whether to execute at the beginning (`false`)\n * @api public\n */\nfunction debounce(func, wait, immediate){\n var timeout, args, context, timestamp, result;\n if (null == wait) wait = 100;\n\n function later() {\n var last = Date.now() - timestamp;\n\n if (last < wait && last >= 0) {\n timeout = setTimeout(later, wait - last);\n } else {\n timeout = null;\n if (!immediate) {\n result = func.apply(context, args);\n context = args = null;\n }\n }\n };\n\n var debounced = function(){\n context = this;\n args = arguments;\n timestamp = Date.now();\n var callNow = immediate && !timeout;\n if (!timeout) timeout = setTimeout(later, wait);\n if (callNow) {\n result = func.apply(context, args);\n context = args = null;\n }\n\n return result;\n };\n\n debounced.clear = function() {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n };\n \n debounced.flush = function() {\n if (timeout) {\n result = func.apply(context, args);\n context = args = null;\n \n clearTimeout(timeout);\n timeout = null;\n }\n };\n\n return debounced;\n};\n\n// Adds compatibility for ES modules\ndebounce.debounce = debounce;\n\nmodule.exports = debounce;\n","/**\n * Stops propagation of click event and removes event listener\n *\n * @private\n * @param {object} event The click event\n */\nfunction preventClickHandler(event) {\n event.stopPropagation();\n document.body.removeEventListener('click', preventClickHandler, true);\n}\n\n/**\n * Starts listening for click event and prevent propagation\n *\n * @param {object} values Values\n */\nexport default function preventClick(values) {\n document.body.addEventListener('click', preventClickHandler, true);\n}\n","/**\n * @since 3.0.0\n */\n\nimport Observer from './observer';\n\nclass ProgressHandler {\n /**\n * Instantiate ProgressHandler\n *\n * @param {Observer} instance The `fetchFile` observer instance.\n * @param {Number} contentLength Content length.\n * @param {Response} response Response object.\n */\n constructor(instance, contentLength, response) {\n this.instance = instance;\n this.instance._reader = response.body.getReader();\n\n this.total = parseInt(contentLength, 10);\n this.loaded = 0;\n }\n\n /**\n * A method that is called once, immediately after the `ReadableStream``\n * is constructed.\n *\n * @param {ReadableStreamDefaultController} controller Controller instance\n * used to control the stream.\n */\n start(controller) {\n const read = () => {\n // instance._reader.read() returns a promise that resolves\n // when a value has been received\n this.instance._reader\n .read()\n .then(({ done, value }) => {\n // result objects contain two properties:\n // done - true if the stream has already given you all its data.\n // value - some data. Always undefined when done is true.\n if (done) {\n // ensure onProgress called when content-length=0\n if (this.total === 0) {\n this.instance.onProgress.call(this.instance, {\n loaded: this.loaded,\n total: this.total,\n lengthComputable: false\n });\n }\n // no more data needs to be consumed, close the stream\n controller.close();\n return;\n }\n\n this.loaded += value.byteLength;\n this.instance.onProgress.call(this.instance, {\n loaded: this.loaded,\n total: this.total,\n lengthComputable: !(this.total === 0)\n });\n // enqueue the next data chunk into our target stream\n controller.enqueue(value);\n read();\n })\n .catch(error => {\n controller.error(error);\n });\n };\n\n read();\n }\n}\n\n/**\n * Load a file using `fetch`.\n *\n * @param {object} options Request options to use. See example below.\n * @returns {Observer} Observer instance\n * @example\n * // default options\n * let options = {\n * url: undefined,\n * method: 'GET',\n * mode: 'cors',\n * credentials: 'same-origin',\n * cache: 'default',\n * responseType: 'json',\n * requestHeaders: [],\n * redirect: 'follow',\n * referrer: 'client'\n * };\n *\n * // override some options\n * options.url = '../media/demo.wav';\n\n * // available types: 'arraybuffer', 'blob', 'json' or 'text'\n * options.responseType = 'arraybuffer';\n *\n * // make fetch call\n * let request = util.fetchFile(options);\n *\n * // listen for events\n * request.on('progress', e => {\n * console.log('progress', e);\n * });\n *\n * request.on('success', data => {\n * console.log('success!', data);\n * });\n *\n * request.on('error', e => {\n * console.warn('fetchFile error: ', e);\n * });\n */\nexport default function fetchFile(options) {\n if (!options) {\n throw new Error('fetch options missing');\n } else if (!options.url) {\n throw new Error('fetch url missing');\n }\n const instance = new Observer();\n const fetchHeaders = new Headers();\n const fetchRequest = new Request(options.url);\n\n // add ability to abort\n instance.controller = new AbortController();\n\n // check if headers have to be added\n if (options && options.requestHeaders) {\n // add custom request headers\n options.requestHeaders.forEach(header => {\n fetchHeaders.append(header.key, header.value);\n });\n }\n\n // parse fetch options\n const responseType = options.responseType || 'json';\n const fetchOptions = {\n method: options.method || 'GET',\n headers: fetchHeaders,\n mode: options.mode || 'cors',\n credentials: options.credentials || 'same-origin',\n cache: options.cache || 'default',\n redirect: options.redirect || 'follow',\n referrer: options.referrer || 'client',\n signal: instance.controller.signal\n };\n\n fetch(fetchRequest, fetchOptions)\n .then(response => {\n // store response reference\n instance.response = response;\n\n let progressAvailable = true;\n if (!response.body) {\n // ReadableStream is not yet supported in this browser\n // see https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream\n progressAvailable = false;\n }\n\n // Server must send CORS header \"Access-Control-Expose-Headers: content-length\"\n const contentLength = response.headers.get('content-length');\n if (contentLength === null) {\n // Content-Length server response header missing.\n // Don't evaluate download progress if we can't compare against a total size\n // see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Access-Control-Expose-Headers\n progressAvailable = false;\n }\n\n if (!progressAvailable) {\n // not able to check download progress so skip it\n return response;\n }\n\n // fire progress event when during load\n instance.onProgress = e => {\n instance.fireEvent('progress', e);\n };\n\n return new Response(\n new ReadableStream(\n new ProgressHandler(instance, contentLength, response)\n ),\n fetchOptions\n );\n })\n .then(response => {\n let errMsg;\n if (response.ok) {\n switch (responseType) {\n case 'arraybuffer':\n return response.arrayBuffer();\n\n case 'json':\n return response.json();\n\n case 'blob':\n return response.blob();\n\n case 'text':\n return response.text();\n\n default:\n errMsg = 'Unknown responseType: ' + responseType;\n break;\n }\n }\n if (!errMsg) {\n errMsg = 'HTTP error status: ' + response.status;\n }\n throw new Error(errMsg);\n })\n .then(response => {\n instance.fireEvent('success', response);\n })\n .catch(error => {\n instance.fireEvent('error', error);\n });\n\n // return the fetch request\n instance.fetchRequest = fetchRequest;\n return instance;\n}\n","import Drawer from './drawer';\nimport * as util from './util';\nimport CanvasEntry from './drawer.canvasentry';\n\n/**\n * MultiCanvas renderer for wavesurfer. Is currently the default and sole\n * builtin renderer.\n *\n * A `MultiCanvas` consists of one or more `CanvasEntry` instances, depending\n * on the zoom level.\n */\nexport default class MultiCanvas extends Drawer {\n /**\n * @param {HTMLElement} container The container node of the wavesurfer instance\n * @param {WavesurferParams} params The wavesurfer initialisation options\n */\n constructor(container, params) {\n super(container, params);\n\n /**\n * @type {number}\n */\n this.maxCanvasWidth = params.maxCanvasWidth;\n\n /**\n * @type {number}\n */\n this.maxCanvasElementWidth = Math.round(\n params.maxCanvasWidth / params.pixelRatio\n );\n\n /**\n * Whether or not the progress wave is rendered. If the `waveColor`\n * and `progressColor` are the same color it is not.\n *\n * @type {boolean}\n */\n this.hasProgressCanvas = params.waveColor != params.progressColor;\n\n /**\n * @type {number}\n */\n this.halfPixel = 0.5 / params.pixelRatio;\n\n /**\n * List of `CanvasEntry` instances.\n *\n * @type {Array}\n */\n this.canvases = [];\n\n /**\n * @type {HTMLElement}\n */\n this.progressWave = null;\n\n /**\n * Class used to generate entries.\n *\n * @type {function}\n */\n this.EntryClass = CanvasEntry;\n\n /**\n * Canvas 2d context attributes.\n *\n * @type {object}\n */\n this.canvasContextAttributes = params.drawingContextAttributes;\n\n /**\n * Overlap added between entries to prevent vertical white stripes\n * between `canvas` elements.\n *\n * @type {number}\n */\n this.overlap = 2 * Math.ceil(params.pixelRatio / 2);\n\n /**\n * The radius of the wave bars. Makes bars rounded\n *\n * @type {number}\n */\n this.barRadius = params.barRadius || 0;\n }\n\n /**\n * Initialize the drawer\n */\n init() {\n this.createWrapper();\n this.createElements();\n }\n\n /**\n * Create the canvas elements and style them\n *\n */\n createElements() {\n this.progressWave = this.wrapper.appendChild(\n this.style(document.createElement('wave'), {\n position: 'absolute',\n zIndex: 3,\n left: 0,\n top: 0,\n bottom: 0,\n overflow: 'hidden',\n width: '0',\n display: 'none',\n boxSizing: 'border-box',\n borderRightStyle: 'solid',\n pointerEvents: 'none'\n })\n );\n\n this.addCanvas();\n this.updateCursor();\n }\n\n /**\n * Update cursor style\n */\n updateCursor() {\n this.style(this.progressWave, {\n borderRightWidth: this.params.cursorWidth + 'px',\n borderRightColor: this.params.cursorColor\n });\n }\n\n /**\n * Adjust to the updated size by adding or removing canvases\n */\n updateSize() {\n const totalWidth = Math.round(this.width / this.params.pixelRatio);\n const requiredCanvases = Math.ceil(\n totalWidth / (this.maxCanvasElementWidth + this.overlap)\n );\n\n // add required canvases\n while (this.canvases.length < requiredCanvases) {\n this.addCanvas();\n }\n\n // remove older existing canvases, if any\n while (this.canvases.length > requiredCanvases) {\n this.removeCanvas();\n }\n\n let canvasWidth = this.maxCanvasWidth + this.overlap;\n const lastCanvas = this.canvases.length - 1;\n this.canvases.forEach((entry, i) => {\n if (i == lastCanvas) {\n canvasWidth = this.width - this.maxCanvasWidth * lastCanvas;\n }\n this.updateDimensions(entry, canvasWidth, this.height);\n\n entry.clearWave();\n });\n }\n\n /**\n * Add a canvas to the canvas list\n *\n */\n addCanvas() {\n const entry = new this.EntryClass();\n entry.canvasContextAttributes = this.canvasContextAttributes;\n entry.hasProgressCanvas = this.hasProgressCanvas;\n entry.halfPixel = this.halfPixel;\n const leftOffset = this.maxCanvasElementWidth * this.canvases.length;\n\n // wave\n entry.initWave(\n this.wrapper.appendChild(\n this.style(document.createElement('canvas'), {\n position: 'absolute',\n zIndex: 2,\n left: leftOffset + 'px',\n top: 0,\n bottom: 0,\n height: '100%',\n pointerEvents: 'none'\n })\n )\n );\n\n // progress\n if (this.hasProgressCanvas) {\n entry.initProgress(\n this.progressWave.appendChild(\n this.style(document.createElement('canvas'), {\n position: 'absolute',\n left: leftOffset + 'px',\n top: 0,\n bottom: 0,\n height: '100%'\n })\n )\n );\n }\n\n this.canvases.push(entry);\n }\n\n /**\n * Pop single canvas from the list\n *\n */\n removeCanvas() {\n let lastEntry = this.canvases[this.canvases.length - 1];\n\n // wave\n lastEntry.wave.parentElement.removeChild(lastEntry.wave);\n\n // progress\n if (this.hasProgressCanvas) {\n lastEntry.progress.parentElement.removeChild(lastEntry.progress);\n }\n\n // cleanup\n if (lastEntry) {\n lastEntry.destroy();\n lastEntry = null;\n }\n\n this.canvases.pop();\n }\n\n /**\n * Update the dimensions of a canvas element\n *\n * @param {CanvasEntry} entry Target entry\n * @param {number} width The new width of the element\n * @param {number} height The new height of the element\n */\n updateDimensions(entry, width, height) {\n const elementWidth = Math.round(width / this.params.pixelRatio);\n const totalWidth = Math.round(this.width / this.params.pixelRatio);\n\n // update canvas dimensions\n entry.updateDimensions(elementWidth, totalWidth, width, height);\n\n // style element\n this.style(this.progressWave, { display: 'block' });\n }\n\n /**\n * Clear the whole multi-canvas\n */\n clearWave() {\n util.frame(() => {\n this.canvases.forEach(entry => entry.clearWave());\n })();\n }\n\n /**\n * Draw a waveform with bars\n *\n * @param {number[]|Number.} peaks Can also be an array of arrays\n * for split channel rendering\n * @param {number} channelIndex The index of the current channel. Normally\n * should be 0. Must be an integer.\n * @param {number} start The x-offset of the beginning of the area that\n * should be rendered\n * @param {number} end The x-offset of the end of the area that should be\n * rendered\n * @returns {void}\n */\n drawBars(peaks, channelIndex, start, end) {\n return this.prepareDraw(\n peaks,\n channelIndex,\n start,\n end,\n ({ absmax, hasMinVals, height, offsetY, halfH, peaks }) => {\n // if drawBars was called within ws.empty we don't pass a start and\n // don't want anything to happen\n if (start === undefined) {\n return;\n }\n // Skip every other value if there are negatives.\n const peakIndexScale = hasMinVals ? 2 : 1;\n const length = peaks.length / peakIndexScale;\n const bar = this.params.barWidth * this.params.pixelRatio;\n const gap =\n this.params.barGap === null\n ? Math.max(this.params.pixelRatio, ~~(bar / 2))\n : Math.max(\n this.params.pixelRatio,\n this.params.barGap * this.params.pixelRatio\n );\n const step = bar + gap;\n\n const scale = length / this.width;\n const first = start;\n const last = end;\n let i = first;\n\n for (i; i < last; i += step) {\n const peak =\n peaks[Math.floor(i * scale * peakIndexScale)] || 0;\n let h = Math.round((peak / absmax) * halfH);\n\n /* in case of silences, allow the user to specify that we\n * always draw *something* (normally a 1px high bar) */\n if (h == 0 && this.params.barMinHeight)\n h = this.params.barMinHeight;\n\n this.fillRect(\n i + this.halfPixel,\n halfH - h + offsetY,\n bar + this.halfPixel,\n h * 2,\n this.barRadius\n );\n }\n }\n );\n }\n\n /**\n * Draw a waveform\n *\n * @param {number[]|Number.} peaks Can also be an array of arrays\n * for split channel rendering\n * @param {number} channelIndex The index of the current channel. Normally\n * should be 0\n * @param {number?} start The x-offset of the beginning of the area that\n * should be rendered (If this isn't set only a flat line is rendered)\n * @param {number?} end The x-offset of the end of the area that should be\n * rendered\n * @returns {void}\n */\n drawWave(peaks, channelIndex, start, end) {\n return this.prepareDraw(\n peaks,\n channelIndex,\n start,\n end,\n ({ absmax, hasMinVals, height, offsetY, halfH, peaks, channelIndex }) => {\n if (!hasMinVals) {\n const reflectedPeaks = [];\n const len = peaks.length;\n let i = 0;\n for (i; i < len; i++) {\n reflectedPeaks[2 * i] = peaks[i];\n reflectedPeaks[2 * i + 1] = -peaks[i];\n }\n peaks = reflectedPeaks;\n }\n\n // if drawWave was called within ws.empty we don't pass a start and\n // end and simply want a flat line\n if (start !== undefined) {\n this.drawLine(peaks, absmax, halfH, offsetY, start, end, channelIndex);\n }\n\n // always draw a median line\n this.fillRect(\n 0,\n halfH + offsetY - this.halfPixel,\n this.width,\n this.halfPixel,\n this.barRadius\n );\n }\n );\n }\n\n /**\n * Tell the canvas entries to render their portion of the waveform\n *\n * @param {number[]} peaks Peaks data\n * @param {number} absmax Maximum peak value (absolute)\n * @param {number} halfH Half the height of the waveform\n * @param {number} offsetY Offset to the top\n * @param {number} start The x-offset of the beginning of the area that\n * should be rendered\n * @param {number} end The x-offset of the end of the area that\n * should be rendered\n * @param {channelIndex} channelIndex The channel index of the line drawn\n */\n drawLine(peaks, absmax, halfH, offsetY, start, end, channelIndex) {\n const { waveColor, progressColor } = this.params.splitChannelsOptions.channelColors[channelIndex] || {};\n this.canvases.forEach((entry, i) => {\n this.setFillStyles(entry, waveColor, progressColor);\n entry.drawLines(peaks, absmax, halfH, offsetY, start, end);\n });\n }\n\n /**\n * Draw a rectangle on the multi-canvas\n *\n * @param {number} x X-position of the rectangle\n * @param {number} y Y-position of the rectangle\n * @param {number} width Width of the rectangle\n * @param {number} height Height of the rectangle\n * @param {number} radius Radius of the rectangle\n */\n fillRect(x, y, width, height, radius) {\n const startCanvas = Math.floor(x / this.maxCanvasWidth);\n const endCanvas = Math.min(\n Math.ceil((x + width) / this.maxCanvasWidth) + 1,\n this.canvases.length\n );\n let i = startCanvas;\n for (i; i < endCanvas; i++) {\n const entry = this.canvases[i];\n const leftOffset = i * this.maxCanvasWidth;\n\n const intersection = {\n x1: Math.max(x, i * this.maxCanvasWidth),\n y1: y,\n x2: Math.min(\n x + width,\n i * this.maxCanvasWidth + entry.wave.width\n ),\n y2: y + height\n };\n\n if (intersection.x1 < intersection.x2) {\n this.setFillStyles(entry);\n\n entry.fillRects(\n intersection.x1 - leftOffset,\n intersection.y1,\n intersection.x2 - intersection.x1,\n intersection.y2 - intersection.y1,\n radius\n );\n }\n }\n }\n\n /**\n * Returns whether to hide the channel from being drawn based on params.\n *\n * @param {number} channelIndex The index of the current channel.\n * @returns {bool} True to hide the channel, false to draw.\n */\n hideChannel(channelIndex) {\n return this.params.splitChannels && this.params.splitChannelsOptions.filterChannels.includes(channelIndex);\n }\n\n /**\n * Performs preparation tasks and calculations which are shared by `drawBars`\n * and `drawWave`\n *\n * @param {number[]|Number.} peaks Can also be an array of arrays for\n * split channel rendering\n * @param {number} channelIndex The index of the current channel. Normally\n * should be 0\n * @param {number?} start The x-offset of the beginning of the area that\n * should be rendered. If this isn't set only a flat line is rendered\n * @param {number?} end The x-offset of the end of the area that should be\n * rendered\n * @param {function} fn The render function to call, e.g. `drawWave`\n * @param {number} drawIndex The index of the current channel after filtering.\n * @returns {void}\n */\n prepareDraw(peaks, channelIndex, start, end, fn, drawIndex) {\n return util.frame(() => {\n // Split channels and call this function with the channelIndex set\n if (peaks[0] instanceof Array) {\n const channels = peaks;\n\n if (this.params.splitChannels) {\n const filteredChannels = channels.filter((c, i) => !this.hideChannel(i));\n if (!this.params.splitChannelsOptions.overlay) {\n this.setHeight(\n Math.max(filteredChannels.length, 1) *\n this.params.height *\n this.params.pixelRatio\n );\n }\n\n return channels.forEach((channelPeaks, i) =>\n this.prepareDraw(channelPeaks, i, start, end, fn, filteredChannels.indexOf(channelPeaks))\n );\n }\n peaks = channels[0];\n }\n\n // Return and do not draw channel peaks if hidden.\n if (this.hideChannel(channelIndex)) {\n return;\n }\n\n // calculate maximum modulation value, either from the barHeight\n // parameter or if normalize=true from the largest value in the peak\n // set\n let absmax = 1 / this.params.barHeight;\n if (this.params.normalize) {\n const max = util.max(peaks);\n const min = util.min(peaks);\n absmax = -min > max ? -min : max;\n }\n\n // Bar wave draws the bottom only as a reflection of the top,\n // so we don't need negative values\n const hasMinVals = [].some.call(peaks, val => val < 0);\n const height = this.params.height * this.params.pixelRatio;\n const offsetY = height * drawIndex || 0;\n const halfH = height / 2;\n\n return fn({\n absmax: absmax,\n hasMinVals: hasMinVals,\n height: height,\n offsetY: offsetY,\n halfH: halfH,\n peaks: peaks,\n channelIndex: channelIndex,\n });\n })();\n }\n\n /**\n * Set the fill styles for a certain entry (wave and progress)\n *\n * @param {CanvasEntry} entry Target entry\n * @param {string} waveColor Wave color to draw this entry\n * @param {string} progressColor Progress color to draw this entry\n */\n setFillStyles(entry, waveColor = this.params.waveColor, progressColor = this.params.progressColor) {\n entry.setFillStyles(waveColor, progressColor);\n }\n\n /**\n * Return image data of the multi-canvas\n *\n * When using a `type` of `'blob'`, this will return a `Promise`.\n *\n * @param {string} format='image/png' An optional value of a format type.\n * @param {number} quality=0.92 An optional value between 0 and 1.\n * @param {string} type='dataURL' Either 'dataURL' or 'blob'.\n * @return {string|string[]|Promise} When using the default `'dataURL'`\n * `type` this returns a single data URL or an array of data URLs,\n * one for each canvas. When using the `'blob'` `type` this returns a\n * `Promise` that resolves with an array of `Blob` instances, one for each\n * canvas.\n */\n getImage(format, quality, type) {\n if (type === 'blob') {\n return Promise.all(\n this.canvases.map(entry => {\n return entry.getImage(format, quality, type);\n })\n );\n } else if (type === 'dataURL') {\n let images = this.canvases.map(entry =>\n entry.getImage(format, quality, type)\n );\n return images.length > 1 ? images : images[0];\n }\n }\n\n /**\n * Render the new progress\n *\n * @param {number} position X-offset of progress position in pixels\n */\n updateProgress(position) {\n this.style(this.progressWave, { width: position + 'px' });\n }\n}\n","import * as util from './util';\n\n/**\n * Parent class for renderers\n *\n * @extends {Observer}\n */\nexport default class Drawer extends util.Observer {\n /**\n * @param {HTMLElement} container The container node of the wavesurfer instance\n * @param {WavesurferParams} params The wavesurfer initialisation options\n */\n constructor(container, params) {\n super();\n\n this.container = container;\n /**\n * @type {WavesurferParams}\n */\n this.params = params;\n /**\n * The width of the renderer\n * @type {number}\n */\n this.width = 0;\n /**\n * The height of the renderer\n * @type {number}\n */\n this.height = params.height * this.params.pixelRatio;\n\n this.lastPos = 0;\n /**\n * The `` element which is added to the container\n * @type {HTMLElement}\n */\n this.wrapper = null;\n }\n\n /**\n * Alias of `util.style`\n *\n * @param {HTMLElement} el The element that the styles will be applied to\n * @param {Object} styles The map of propName: attribute, both are used as-is\n * @return {HTMLElement} el\n */\n style(el, styles) {\n return util.style(el, styles);\n }\n\n /**\n * Create the wrapper `` element, style it and set up the events for\n * interaction\n */\n createWrapper() {\n this.wrapper = this.container.appendChild(\n document.createElement('wave')\n );\n\n this.style(this.wrapper, {\n display: 'block',\n position: 'relative',\n userSelect: 'none',\n webkitUserSelect: 'none',\n height: this.params.height + 'px'\n });\n\n if (this.params.fillParent || this.params.scrollParent) {\n this.style(this.wrapper, {\n width: '100%',\n overflowX: this.params.hideScrollbar ? 'hidden' : 'auto',\n overflowY: 'hidden'\n });\n }\n\n this.setupWrapperEvents();\n }\n\n /**\n * Handle click event\n *\n * @param {Event} e Click event\n * @param {?boolean} noPrevent Set to true to not call `e.preventDefault()`\n * @return {number} Playback position from 0 to 1\n */\n handleEvent(e, noPrevent) {\n !noPrevent && e.preventDefault();\n\n const clientX = e.targetTouches\n ? e.targetTouches[0].clientX\n : e.clientX;\n const bbox = this.wrapper.getBoundingClientRect();\n\n const nominalWidth = this.width;\n const parentWidth = this.getWidth();\n\n let progress;\n if (!this.params.fillParent && nominalWidth < parentWidth) {\n progress =\n (this.params.rtl ? bbox.right - clientX : clientX - bbox.left) *\n (this.params.pixelRatio / nominalWidth) || 0;\n\n if (progress > 1) {\n progress = 1;\n }\n } else {\n progress =\n ((this.params.rtl\n ? bbox.right - clientX\n : clientX - bbox.left) +\n this.wrapper.scrollLeft) /\n this.wrapper.scrollWidth || 0;\n }\n\n return progress;\n }\n\n setupWrapperEvents() {\n this.wrapper.addEventListener('click', e => {\n const scrollbarHeight =\n this.wrapper.offsetHeight - this.wrapper.clientHeight;\n if (scrollbarHeight !== 0) {\n // scrollbar is visible. Check if click was on it\n const bbox = this.wrapper.getBoundingClientRect();\n if (e.clientY >= bbox.bottom - scrollbarHeight) {\n // ignore mousedown as it was on the scrollbar\n return;\n }\n }\n\n if (this.params.interact) {\n this.fireEvent('click', e, this.handleEvent(e));\n }\n });\n\n this.wrapper.addEventListener('dblclick', e => {\n if (this.params.interact) {\n this.fireEvent('dblclick', e, this.handleEvent(e));\n }\n });\n\n this.wrapper.addEventListener('scroll', e =>\n this.fireEvent('scroll', e)\n );\n }\n\n /**\n * Draw peaks on the canvas\n *\n * @param {number[]|Number.} peaks Can also be an array of arrays\n * for split channel rendering\n * @param {number} length The width of the area that should be drawn\n * @param {number} start The x-offset of the beginning of the area that\n * should be rendered\n * @param {number} end The x-offset of the end of the area that should be\n * rendered\n */\n drawPeaks(peaks, length, start, end) {\n if (!this.setWidth(length)) {\n this.clearWave();\n }\n\n this.params.barWidth\n ? this.drawBars(peaks, 0, start, end)\n : this.drawWave(peaks, 0, start, end);\n }\n\n /**\n * Scroll to the beginning\n */\n resetScroll() {\n if (this.wrapper !== null) {\n this.wrapper.scrollLeft = 0;\n }\n }\n\n /**\n * Recenter the view-port at a certain percent of the waveform\n *\n * @param {number} percent Value from 0 to 1 on the waveform\n */\n recenter(percent) {\n const position = this.wrapper.scrollWidth * percent;\n this.recenterOnPosition(position, true);\n }\n\n /**\n * Recenter the view-port on a position, either scroll there immediately or\n * in steps of 5 pixels\n *\n * @param {number} position X-offset in pixels\n * @param {boolean} immediate Set to true to immediately scroll somewhere\n */\n recenterOnPosition(position, immediate) {\n const scrollLeft = this.wrapper.scrollLeft;\n const half = ~~(this.wrapper.clientWidth / 2);\n const maxScroll = this.wrapper.scrollWidth - this.wrapper.clientWidth;\n let target = position - half;\n let offset = target - scrollLeft;\n\n if (maxScroll == 0) {\n // no need to continue if scrollbar is not there\n return;\n }\n\n // if the cursor is currently visible...\n if (!immediate && -half <= offset && offset < half) {\n // set rate at which waveform is centered\n let rate = this.params.autoCenterRate;\n\n // make rate depend on width of view and length of waveform\n rate /= half;\n rate *= maxScroll;\n\n offset = Math.max(-rate, Math.min(rate, offset));\n target = scrollLeft + offset;\n }\n\n // limit target to valid range (0 to maxScroll)\n target = Math.max(0, Math.min(maxScroll, target));\n // no use attempting to scroll if we're not moving\n if (target != scrollLeft) {\n this.wrapper.scrollLeft = target;\n }\n }\n\n /**\n * Get the current scroll position in pixels\n *\n * @return {number} Horizontal scroll position in pixels\n */\n getScrollX() {\n let x = 0;\n if (this.wrapper) {\n const pixelRatio = this.params.pixelRatio;\n x = Math.round(this.wrapper.scrollLeft * pixelRatio);\n\n // In cases of elastic scroll (safari with mouse wheel) you can\n // scroll beyond the limits of the container\n // Calculate and floor the scrollable extent to make sure an out\n // of bounds value is not returned\n // Ticket #1312\n if (this.params.scrollParent) {\n const maxScroll = ~~(\n this.wrapper.scrollWidth * pixelRatio -\n this.getWidth()\n );\n x = Math.min(maxScroll, Math.max(0, x));\n }\n }\n return x;\n }\n\n /**\n * Get the width of the container\n *\n * @return {number} The width of the container\n */\n getWidth() {\n return Math.round(this.container.clientWidth * this.params.pixelRatio);\n }\n\n /**\n * Set the width of the container\n *\n * @param {number} width The new width of the container\n * @return {boolean} Whether the width of the container was updated or not\n */\n setWidth(width) {\n if (this.width == width) {\n return false;\n }\n\n this.width = width;\n\n if (this.params.fillParent || this.params.scrollParent) {\n this.style(this.wrapper, {\n width: ''\n });\n } else {\n this.style(this.wrapper, {\n width: ~~(this.width / this.params.pixelRatio) + 'px'\n });\n }\n\n this.updateSize();\n return true;\n }\n\n /**\n * Set the height of the container\n *\n * @param {number} height The new height of the container.\n * @return {boolean} Whether the height of the container was updated or not\n */\n setHeight(height) {\n if (height == this.height) {\n return false;\n }\n this.height = height;\n\n this.style(this.wrapper, {\n height: ~~(this.height / this.params.pixelRatio) + 'px'\n });\n\n this.updateSize();\n return true;\n }\n\n /**\n * Called by wavesurfer when progress should be rendered\n *\n * @param {number} progress From 0 to 1\n */\n progress(progress) {\n const minPxDelta = 1 / this.params.pixelRatio;\n const pos = Math.round(progress * this.width) * minPxDelta;\n\n if (pos < this.lastPos || pos - this.lastPos >= minPxDelta) {\n this.lastPos = pos;\n\n if (this.params.scrollParent && this.params.autoCenter) {\n const newPos = ~~(this.wrapper.scrollWidth * progress);\n this.recenterOnPosition(\n newPos,\n this.params.autoCenterImmediately\n );\n }\n\n this.updateProgress(pos);\n }\n }\n\n /**\n * This is called when wavesurfer is destroyed\n */\n destroy() {\n this.unAll();\n if (this.wrapper) {\n if (this.wrapper.parentNode == this.container) {\n this.container.removeChild(this.wrapper);\n }\n this.wrapper = null;\n }\n }\n\n /* Renderer-specific methods */\n\n /**\n * Called after cursor related params have changed.\n *\n * @abstract\n */\n updateCursor() {}\n\n /**\n * Called when the size of the container changes so the renderer can adjust\n *\n * @abstract\n */\n updateSize() {}\n\n /**\n * Draw a waveform with bars\n *\n * @abstract\n * @param {number[]|Number.} peaks Can also be an array of arrays for split channel\n * rendering\n * @param {number} channelIndex The index of the current channel. Normally\n * should be 0\n * @param {number} start The x-offset of the beginning of the area that\n * should be rendered\n * @param {number} end The x-offset of the end of the area that should be\n * rendered\n */\n drawBars(peaks, channelIndex, start, end) {}\n\n /**\n * Draw a waveform\n *\n * @abstract\n * @param {number[]|Number.} peaks Can also be an array of arrays for split channel\n * rendering\n * @param {number} channelIndex The index of the current channel. Normally\n * should be 0\n * @param {number} start The x-offset of the beginning of the area that\n * should be rendered\n * @param {number} end The x-offset of the end of the area that should be\n * rendered\n */\n drawWave(peaks, channelIndex, start, end) {}\n\n /**\n * Clear the waveform\n *\n * @abstract\n */\n clearWave() {}\n\n /**\n * Render the new progress\n *\n * @abstract\n * @param {number} position X-Offset of progress position in pixels\n */\n updateProgress(position) {}\n}\n","/**\n * @since 3.0.0\n */\n\nimport style from './util/style';\nimport getId from './util/get-id';\n\n/**\n * The `CanvasEntry` class represents an element consisting of a wave `canvas`\n * and an (optional) progress wave `canvas`.\n *\n * The `MultiCanvas` renderer uses one or more `CanvasEntry` instances to\n * render a waveform, depending on the zoom level.\n */\nexport default class CanvasEntry {\n constructor() {\n /**\n * The wave node\n *\n * @type {HTMLCanvasElement}\n */\n this.wave = null;\n /**\n * The wave canvas rendering context\n *\n * @type {CanvasRenderingContext2D}\n */\n this.waveCtx = null;\n /**\n * The (optional) progress wave node\n *\n * @type {HTMLCanvasElement}\n */\n this.progress = null;\n /**\n * The (optional) progress wave canvas rendering context\n *\n * @type {CanvasRenderingContext2D}\n */\n this.progressCtx = null;\n /**\n * Start of the area the canvas should render, between 0 and 1\n *\n * @type {number}\n */\n this.start = 0;\n /**\n * End of the area the canvas should render, between 0 and 1\n *\n * @type {number}\n */\n this.end = 1;\n /**\n * Unique identifier for this entry\n *\n * @type {string}\n */\n this.id = getId(\n typeof this.constructor.name !== 'undefined'\n ? this.constructor.name.toLowerCase() + '_'\n : 'canvasentry_'\n );\n /**\n * Canvas 2d context attributes\n *\n * @type {object}\n */\n this.canvasContextAttributes = {};\n }\n\n /**\n * Store the wave canvas element and create the 2D rendering context\n *\n * @param {HTMLCanvasElement} element The wave `canvas` element.\n */\n initWave(element) {\n this.wave = element;\n this.waveCtx = this.wave.getContext('2d', this.canvasContextAttributes);\n }\n\n /**\n * Store the progress wave canvas element and create the 2D rendering\n * context\n *\n * @param {HTMLCanvasElement} element The progress wave `canvas` element.\n */\n initProgress(element) {\n this.progress = element;\n this.progressCtx = this.progress.getContext(\n '2d',\n this.canvasContextAttributes\n );\n }\n\n /**\n * Update the dimensions\n *\n * @param {number} elementWidth Width of the entry\n * @param {number} totalWidth Total width of the multi canvas renderer\n * @param {number} width The new width of the element\n * @param {number} height The new height of the element\n */\n updateDimensions(elementWidth, totalWidth, width, height) {\n // where the canvas starts and ends in the waveform, represented as a\n // decimal between 0 and 1\n this.start = this.wave.offsetLeft / totalWidth || 0;\n this.end = this.start + elementWidth / totalWidth;\n\n // set wave canvas dimensions\n this.wave.width = width;\n this.wave.height = height;\n let elementSize = { width: elementWidth + 'px' };\n style(this.wave, elementSize);\n\n if (this.hasProgressCanvas) {\n // set progress canvas dimensions\n this.progress.width = width;\n this.progress.height = height;\n style(this.progress, elementSize);\n }\n }\n\n /**\n * Clear the wave and progress rendering contexts\n */\n clearWave() {\n // wave\n this.waveCtx.clearRect(\n 0,\n 0,\n this.waveCtx.canvas.width,\n this.waveCtx.canvas.height\n );\n\n // progress\n if (this.hasProgressCanvas) {\n this.progressCtx.clearRect(\n 0,\n 0,\n this.progressCtx.canvas.width,\n this.progressCtx.canvas.height\n );\n }\n }\n\n /**\n * Set the fill styles for wave and progress\n *\n * @param {string} waveColor Fill color for the wave canvas\n * @param {?string} progressColor Fill color for the progress canvas\n */\n setFillStyles(waveColor, progressColor) {\n this.waveCtx.fillStyle = waveColor;\n\n if (this.hasProgressCanvas) {\n this.progressCtx.fillStyle = progressColor;\n }\n }\n\n /**\n * Draw a rectangle for wave and progress\n *\n * @param {number} x X start position\n * @param {number} y Y start position\n * @param {number} width Width of the rectangle\n * @param {number} height Height of the rectangle\n * @param {number} radius Radius of the rectangle\n */\n fillRects(x, y, width, height, radius) {\n this.fillRectToContext(this.waveCtx, x, y, width, height, radius);\n\n if (this.hasProgressCanvas) {\n this.fillRectToContext(\n this.progressCtx,\n x,\n y,\n width,\n height,\n radius\n );\n }\n }\n\n /**\n * Draw the actual rectangle on a `canvas` element\n *\n * @param {CanvasRenderingContext2D} ctx Rendering context of target canvas\n * @param {number} x X start position\n * @param {number} y Y start position\n * @param {number} width Width of the rectangle\n * @param {number} height Height of the rectangle\n * @param {number} radius Radius of the rectangle\n */\n fillRectToContext(ctx, x, y, width, height, radius) {\n if (!ctx) {\n return;\n }\n\n if (radius) {\n this.drawRoundedRect(ctx, x, y, width, height, radius);\n } else {\n ctx.fillRect(x, y, width, height);\n }\n }\n\n /**\n * Draw a rounded rectangle on Canvas\n *\n * @param {CanvasRenderingContext2D} ctx Canvas context\n * @param {number} x X-position of the rectangle\n * @param {number} y Y-position of the rectangle\n * @param {number} width Width of the rectangle\n * @param {number} height Height of the rectangle\n * @param {number} radius Radius of the rectangle\n *\n * @return {void}\n * @example drawRoundedRect(ctx, 50, 50, 5, 10, 3)\n */\n drawRoundedRect(ctx, x, y, width, height, radius) {\n if (height === 0) {\n return;\n }\n // peaks are float values from -1 to 1. Use absolute height values in\n // order to correctly calculate rounded rectangle coordinates\n if (height < 0) {\n height *= -1;\n y -= height;\n }\n ctx.beginPath();\n ctx.moveTo(x + radius, y);\n ctx.lineTo(x + width - radius, y);\n ctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n ctx.lineTo(x + width, y + height - radius);\n ctx.quadraticCurveTo(\n x + width,\n y + height,\n x + width - radius,\n y + height\n );\n ctx.lineTo(x + radius, y + height);\n ctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n ctx.lineTo(x, y + radius);\n ctx.quadraticCurveTo(x, y, x + radius, y);\n ctx.closePath();\n ctx.fill();\n }\n\n /**\n * Render the actual wave and progress lines\n *\n * @param {number[]} peaks Array with peaks data\n * @param {number} absmax Maximum peak value (absolute)\n * @param {number} halfH Half the height of the waveform\n * @param {number} offsetY Offset to the top\n * @param {number} start The x-offset of the beginning of the area that\n * should be rendered\n * @param {number} end The x-offset of the end of the area that\n * should be rendered\n */\n drawLines(peaks, absmax, halfH, offsetY, start, end) {\n this.drawLineToContext(\n this.waveCtx,\n peaks,\n absmax,\n halfH,\n offsetY,\n start,\n end\n );\n\n if (this.hasProgressCanvas) {\n this.drawLineToContext(\n this.progressCtx,\n peaks,\n absmax,\n halfH,\n offsetY,\n start,\n end\n );\n }\n }\n\n /**\n * Render the actual waveform line on a `canvas` element\n *\n * @param {CanvasRenderingContext2D} ctx Rendering context of target canvas\n * @param {number[]} peaks Array with peaks data\n * @param {number} absmax Maximum peak value (absolute)\n * @param {number} halfH Half the height of the waveform\n * @param {number} offsetY Offset to the top\n * @param {number} start The x-offset of the beginning of the area that\n * should be rendered\n * @param {number} end The x-offset of the end of the area that\n * should be rendered\n */\n drawLineToContext(ctx, peaks, absmax, halfH, offsetY, start, end) {\n if (!ctx) {\n return;\n }\n\n const length = peaks.length / 2;\n const first = Math.round(length * this.start);\n\n // use one more peak value to make sure we join peaks at ends -- unless,\n // of course, this is the last canvas\n const last = Math.round(length * this.end) + 1;\n\n const canvasStart = first;\n const canvasEnd = last;\n const scale = this.wave.width / (canvasEnd - canvasStart - 1);\n\n // optimization\n const halfOffset = halfH + offsetY;\n const absmaxHalf = absmax / halfH;\n\n ctx.beginPath();\n ctx.moveTo((canvasStart - first) * scale, halfOffset);\n\n ctx.lineTo(\n (canvasStart - first) * scale,\n halfOffset - Math.round((peaks[2 * canvasStart] || 0) / absmaxHalf)\n );\n\n let i, peak, h;\n for (i = canvasStart; i < canvasEnd; i++) {\n peak = peaks[2 * i] || 0;\n h = Math.round(peak / absmaxHalf);\n ctx.lineTo((i - first) * scale + this.halfPixel, halfOffset - h);\n }\n\n // draw the bottom edge going backwards, to make a single\n // closed hull to fill\n let j = canvasEnd - 1;\n for (j; j >= canvasStart; j--) {\n peak = peaks[2 * j + 1] || 0;\n h = Math.round(peak / absmaxHalf);\n ctx.lineTo((j - first) * scale + this.halfPixel, halfOffset - h);\n }\n\n ctx.lineTo(\n (canvasStart - first) * scale,\n halfOffset -\n Math.round((peaks[2 * canvasStart + 1] || 0) / absmaxHalf)\n );\n\n ctx.closePath();\n ctx.fill();\n }\n\n /**\n * Destroys this entry\n */\n destroy() {\n this.waveCtx = null;\n this.wave = null;\n\n this.progressCtx = null;\n this.progress = null;\n }\n\n /**\n * Return image data of the wave `canvas` element\n *\n * When using a `type` of `'blob'`, this will return a `Promise` that\n * resolves with a `Blob` instance.\n *\n * @param {string} format='image/png' An optional value of a format type.\n * @param {number} quality=0.92 An optional value between 0 and 1.\n * @param {string} type='dataURL' Either 'dataURL' or 'blob'.\n * @return {string|Promise} When using the default `'dataURL'` `type` this\n * returns a data URL. When using the `'blob'` `type` this returns a\n * `Promise` that resolves with a `Blob` instance.\n */\n getImage(format, quality, type) {\n if (type === 'blob') {\n return new Promise(resolve => {\n this.wave.toBlob(resolve, format, quality);\n });\n } else if (type === 'dataURL') {\n return this.wave.toDataURL(format, quality);\n }\n }\n}\n","/**\n * Caches the decoded peaks data to improve rendering speed for large audio\n *\n * Is used if the option parameter `partialRender` is set to `true`\n */\nexport default class PeakCache {\n /**\n * Instantiate cache\n */\n constructor() {\n this.clearPeakCache();\n }\n\n /**\n * Empty the cache\n */\n clearPeakCache() {\n /**\n * Flat array with entries that are always in pairs to mark the\n * beginning and end of each subrange. This is a convenience so we can\n * iterate over the pairs for easy set difference operations.\n * @private\n */\n this.peakCacheRanges = [];\n /**\n * Length of the entire cachable region, used for resetting the cache\n * when this changes (zoom events, for instance).\n * @private\n */\n this.peakCacheLength = -1;\n }\n\n /**\n * Add a range of peaks to the cache\n *\n * @param {number} length The length of the range\n * @param {number} start The x offset of the start of the range\n * @param {number} end The x offset of the end of the range\n * @return {Number.} Array with arrays of numbers\n */\n addRangeToPeakCache(length, start, end) {\n if (length != this.peakCacheLength) {\n this.clearPeakCache();\n this.peakCacheLength = length;\n }\n\n // Return ranges that weren't in the cache before the call.\n let uncachedRanges = [];\n let i = 0;\n // Skip ranges before the current start.\n while (\n i < this.peakCacheRanges.length &&\n this.peakCacheRanges[i] < start\n ) {\n i++;\n }\n // If |i| is even, |start| falls after an existing range. Otherwise,\n // |start| falls between an existing range, and the uncached region\n // starts when we encounter the next node in |peakCacheRanges| or\n // |end|, whichever comes first.\n if (i % 2 == 0) {\n uncachedRanges.push(start);\n }\n while (\n i < this.peakCacheRanges.length &&\n this.peakCacheRanges[i] <= end\n ) {\n uncachedRanges.push(this.peakCacheRanges[i]);\n i++;\n }\n // If |i| is even, |end| is after all existing ranges.\n if (i % 2 == 0) {\n uncachedRanges.push(end);\n }\n\n // Filter out the 0-length ranges.\n uncachedRanges = uncachedRanges.filter((item, pos, arr) => {\n if (pos == 0) {\n return item != arr[pos + 1];\n } else if (pos == arr.length - 1) {\n return item != arr[pos - 1];\n }\n return item != arr[pos - 1] && item != arr[pos + 1];\n });\n\n // Merge the two ranges together, uncachedRanges will either contain\n // wholly new points, or duplicates of points in peakCacheRanges. If\n // duplicates are detected, remove both and extend the range.\n this.peakCacheRanges = this.peakCacheRanges.concat(uncachedRanges);\n this.peakCacheRanges = this.peakCacheRanges\n .sort((a, b) => a - b)\n .filter((item, pos, arr) => {\n if (pos == 0) {\n return item != arr[pos + 1];\n } else if (pos == arr.length - 1) {\n return item != arr[pos - 1];\n }\n return item != arr[pos - 1] && item != arr[pos + 1];\n });\n\n // Push the uncached ranges into an array of arrays for ease of\n // iteration in the functions that call this.\n const uncachedRangePairs = [];\n for (i = 0; i < uncachedRanges.length; i += 2) {\n uncachedRangePairs.push([uncachedRanges[i], uncachedRanges[i + 1]]);\n }\n\n return uncachedRangePairs;\n }\n\n /**\n * For testing\n *\n * @return {Number.} Array with arrays of numbers\n */\n getCacheRanges() {\n const peakCacheRangePairs = [];\n let i;\n for (i = 0; i < this.peakCacheRanges.length; i += 2) {\n peakCacheRangePairs.push([\n this.peakCacheRanges[i],\n this.peakCacheRanges[i + 1]\n ]);\n }\n return peakCacheRangePairs;\n }\n}\n","import MediaElement from './mediaelement';\n\n/**\n * MediaElementWebAudio backend: load audio via an HTML5 audio tag, but playback with the WebAudio API.\n * The advantage here is that the html5