wavesurfer.js 7.0.0-beta.4 → 7.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -2
- package/dist/plugins/minimap.min.js +1 -1
- package/dist/plugins/multitrack.min.js +1 -1
- package/dist/plugins/record.d.ts +1 -1
- package/dist/plugins/record.js +2 -1
- package/dist/plugins/record.min.js +1 -1
- package/dist/renderer.d.ts +8 -21
- package/dist/renderer.js +165 -110
- package/dist/wavesurfer.d.ts +8 -6
- package/dist/wavesurfer.js +1 -1
- package/dist/wavesurfer.min.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,11 +92,26 @@ See [this example](https://wavesurfer.pages.dev/examples/#styling.js) for play a
|
|
|
92
92
|
Most options, events, and methods are similar to those in previous versions.
|
|
93
93
|
|
|
94
94
|
### Notable differences
|
|
95
|
-
* The `backend` option is removed – HTML5 audio (or video) is the only playback mechanism. However, you can still connect wavesurfer to Web Audio via `MediaElementSourceNode`. See this [example](https://wavesurfer.pages.dev/examples/#webaudio.js).
|
|
95
|
+
* The `backend` option is removed – [HTML5 audio (or video) is the only playback mechanism](https://github.com/katspaugh/wavesurfer.js/discussions/2762#discussioncomment-5669347). However, you can still connect wavesurfer to Web Audio via `MediaElementSourceNode`. See this [example](https://wavesurfer.pages.dev/examples/#webaudio.js).
|
|
96
96
|
* The Markers plugin is removed – use the Regions plugin with just a `startTime`.
|
|
97
97
|
* No Microphone plugn – superseded by the new Record plugin with more features.
|
|
98
98
|
* No Cursor and Playhead plugins yet – to be done.
|
|
99
99
|
|
|
100
|
+
### Removed options
|
|
101
|
+
* `backend`, `audioContext`, `closeAudioContext', 'audioScriptProcessor` – there's no Web Audio backend, so no AudioContext
|
|
102
|
+
* `autoCenterImmediately` – `autoCenter` is now always immediate unless the audio is playing
|
|
103
|
+
* `backgroundColor`, `hideCursor` – this can be easily set via CSS
|
|
104
|
+
* `mediaType`, `mediaControls` – you should instead pass an entire media element in the `media` option. [Example](https://wavesurfer-js.org/examples/#video.js).
|
|
105
|
+
* `normalize` – peaks are normalized to -1..1 by default
|
|
106
|
+
* `partialRender` – done by default
|
|
107
|
+
* `pixelRatio` – `window.devicePixelRatio` is used by default
|
|
108
|
+
* `renderer` – there's just one renderer for now, so no need for this option
|
|
109
|
+
* `responsive` – responsiveness is enabled by default
|
|
110
|
+
* `scrollParent` – the container will scroll if `minPxPerSec` is set to a higher value
|
|
111
|
+
* `skipLength` – there's no `skipForward` and `skipBackward` methods anymore
|
|
112
|
+
* `splitChannelsOptions` – you should now use `splitChannels` to pass the channel options. Pass `height: 0` to hide a channel. See [this example](https://wavesurfer-js.org/examples/#split-channels.js).
|
|
113
|
+
* `xhr`, `drawingContextAttributes`, `maxCanvasWidth`, `forceDecode` – removed to reduce code complexity
|
|
114
|
+
|
|
100
115
|
### Removed methods
|
|
101
116
|
* `getFilters`, `setFilter` – as there's no Web Audio "backend"
|
|
102
117
|
* `drawBuffer` – to redraw the waveform, use `setOptions` instead and pass new rendering options
|
|
@@ -111,7 +126,12 @@ See the complete [documentation of the new API](https://wavesurfer-ts.pages.dev/
|
|
|
111
126
|
|
|
112
127
|
## Questions
|
|
113
128
|
|
|
114
|
-
Have a question about integrating wavesurfer.js on your website? Feel free to ask in our forum
|
|
129
|
+
Have a question about integrating wavesurfer.js on your website? Feel free to ask in our [Discussions forum](https://github.com/wavesurfer-js/wavesurfer.js/discussions/categories/q-a).
|
|
130
|
+
|
|
131
|
+
### FAQ
|
|
132
|
+
|
|
133
|
+
* **Q**: Does wavesurfer support large files?
|
|
134
|
+
* **A**: Since wavesurfer decodes audio entirely in the browser, large files may fail to decode due to memory constrains. We recommend using pre-decoded peaks for large files (see [this example](https://wavesurfer-js.org/examples/#predecoded.js)). You can use a tool like [bbc/audiowaveform](https://github.com/bbc/audiowaveform) to generate peaks.
|
|
115
135
|
|
|
116
136
|
## Development
|
|
117
137
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Minimap=e():t.Minimap=e()}(WaveSurfer,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var s in i)t.o(i,s)&&!t.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:i[s]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>g});const i=class{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),s=this.on(t,(()=>{i(),s()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}},s=class extends i{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.subscriptions.forEach((t=>t()))}},r={decode:async function(t,e){const i=new AudioContext({sampleRate:e}),s=i.decodeAudioData(t);return s.finally((()=>i.close())),s},createBuffer:function(t,e){return"number"==typeof t[0]&&(t=[t]),function(t){const e=t[0];if(e.some((t=>t>1||t<-1))){const i=e.length;let s=0;for(let t=0;t<i;t++){const i=Math.abs(e[t]);i>s&&(s=i)}for(const e of t)for(let t=0;t<i;t++)e[t]/=s}}(t),{duration:e,length:t[0].length,sampleRate:t[0].length/e,numberOfChannels:t.length,getChannelData:e=>t?.[e],copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}},n=async function(t){return fetch(t).then((t=>t.arrayBuffer()))},o=class extends i{constructor(t){super(),this.isExternalMedia=!1,t.media?(this.media=t.media,this.isExternalMedia=!0):this.media=document.createElement("audio"),t.autoplay&&(this.media.autoplay=!0),null!=t.playbackRate&&(this.media.playbackRate=t.playbackRate)}onMediaEvent(t,e,i){return this.media.addEventListener(t,e,i),()=>this.media.removeEventListener(t,e)}onceMediaEvent(t,e){return this.onMediaEvent(t,e,{once:!0})}revokeSrc(){(this.media.currentSrc||this.media.src||"").startsWith("blob:")&&URL.revokeObjectURL(this.media.currentSrc)}setSrc(t,e){if((this.media.currentSrc||this.media.src||"")===t)return;this.revokeSrc();const i=e?URL.createObjectURL(new Blob([e],{type:"audio/wav"})):t;this.media.src=i}destroy(){this.media.pause(),this.revokeSrc(),this.isExternalMedia||this.media.remove()}play(){return this.media.play()}pause(){this.media.pause()}isPlaying(){return this.media.currentTime>0&&!this.media.paused&&!this.media.ended}setTime(t){this.media.currentTime=t}getDuration(){return this.media.duration}getCurrentTime(){return this.media.currentTime}getVolume(){return this.media.volume}setVolume(t){this.media.volume=t}getMuted(){return this.media.muted}setMuted(t){this.media.muted=t}getPlaybackRate(){return this.media.playbackRate}setPlaybackRate(t,e){null!=e&&(this.media.preservesPitch=e),this.media.playbackRate=t}getMediaElement(){return this.media}setSinkId(t){return this.media.setSinkId(t)}};class a extends i{constructor(t,e){if(super(),this.options={height:0},this.timeout=null,this.isScrolling=!1,this.audioData=null,this.resizeObserver=null,this.isDragging=!1,this.options={...e},"string"==typeof t&&(t=document.querySelector(t)),!t)throw new Error("Container not found");const[i,s]=this.initHtml();t.appendChild(i),this.container=i,this.scrollContainer=s.querySelector(".scroll"),this.wrapper=s.querySelector(".wrapper"),this.canvasWrapper=s.querySelector(".canvases"),this.progressWrapper=s.querySelector(".progress"),this.cursor=s.querySelector(".cursor"),this.initEvents()}initEvents(){this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",i)})),this.initDrag(),this.scrollContainer.addEventListener("scroll",(()=>{const{scrollLeft:t,scrollWidth:e,clientWidth:i}=this.scrollContainer,s=t/e,r=(t+i)/e;this.emit("scroll",s,r)})),this.resizeObserver=new ResizeObserver((()=>{this.delay((()=>this.reRender()),100)})),this.resizeObserver.observe(this.scrollContainer)}initDrag(){this.wrapper.addEventListener("mousedown",(t=>{const e=t.clientX,i=t=>{if(Math.abs(t.clientX-e)>=5){this.isDragging=!0;const e=this.wrapper.getBoundingClientRect();this.emit("drag",Math.max(0,Math.min(1,(t.clientX-e.left)/e.width)))}},s=()=>{document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",s),this.isDragging=!1};document.addEventListener("mousemove",i),document.addEventListener("mouseup",s)}))}initHtml(){const t=document.createElement("div"),e=t.attachShadow({mode:"open"});return e.innerHTML=`\n <style>\n :host {\n user-select: none;\n }\n :host .scroll {\n overflow-x: auto;\n overflow-y: hidden;\n width: 100%;\n position: relative;\n }\n :host .noScrollbar {\n scrollbar-color: transparent;\n scrollbar-width: none;\n }\n :host .noScrollbar::-webkit-scrollbar {\n display: none;\n -webkit-appearance: none;\n }\n :host .wrapper {\n position: relative;\n overflow: visible;\n z-index: 2;\n }\n :host .canvases {\n position: relative;\n height: ${this.options.height}px;\n }\n :host canvas {\n display: block;\n position: absolute;\n top: 0;\n image-rendering: pixelated;\n height: ${this.options.height}px;\n }\n :host .progress {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n width: 0;\n height: 100%;\n overflow: hidden;\n }\n :host .cursor {\n pointer-events: none;\n position: absolute;\n z-index: 5;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n width: ${this.options.cursorWidth}px;\n background-color: ${this.options.cursorColor||this.options.progressColor};\n }\n </style>\n\n <div class="scroll" part="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress"></div>\n <div class="cursor" part="cursor"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){this.options=t,this.reRender()}getWrapper(){return this.wrapper}getScroll(){return this.scrollContainer.scrollLeft}destroy(){this.container.remove(),this.resizeObserver?.disconnect()}delay(t,e=10){return this.timeout&&clearTimeout(this.timeout),new Promise((i=>{this.timeout=setTimeout((()=>{i(t())}),e)}))}async renderPeaks(t,e,i,s){const r=null==this.options.barWidth||isNaN(this.options.barWidth)?1:this.options.barWidth*s,n=null==this.options.barGap||isNaN(this.options.barGap)?this.options.barWidth?r/2:0:this.options.barGap*s,o=this.options.barRadius||0,h=this.options.barHeight||1,l=t.getChannelData(0),c=l.length,d=Math.floor(e/(r+n))/c,p=i/2,u=1===t.numberOfChannels,m=u?l:t.getChannelData(1),g=u&&m.some((t=>t<0)),f=(t,i)=>{let a=0,u=0,f=0;const v=document.createElement("canvas");v.width=Math.round(e*(i-t)/c),v.height=this.options.height,v.style.width=`${Math.floor(v.width/s)}px`,v.style.height=`${this.options.height}px`,v.style.left=`${Math.floor(t*e/s/c)}px`,this.canvasWrapper.appendChild(v);const y=v.getContext("2d",{desynchronized:!0});y.beginPath(),y.fillStyle=this.options.waveColor??"",y.roundRect||(y.roundRect=y.fillRect);for(let e=t;e<i;e++){const i=Math.round((e-t)*d);if(i>a){const t=Math.round(u*p*h),e=Math.round(f*p*h);y.roundRect(a*(r+n),p-t,r,t+(e||1),o),a=i,u=0,f=0}const s=g?l[e]:Math.abs(l[e]),c=g?m[e]:Math.abs(m[e]);s>u&&(u=s),(g?c<-f:c>f)&&(f=c<0?-c:c)}y.fill(),y.closePath();const b=v.cloneNode();this.progressWrapper.appendChild(b);const w=b.getContext("2d",{desynchronized:!0});v.width>0&&v.height>0&&w.drawImage(v,0,0),w.globalCompositeOperation="source-in",w.fillStyle=this.options.progressColor??"",w.fillRect(0,0,v.width,v.height)};this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="";const{scrollLeft:v,scrollWidth:y,clientWidth:b}=this.scrollContainer,w=c/y;let C=Math.min(a.MAX_CANVAS_WIDTH,b);C-=C%((r+n)/s);const W=Math.floor(Math.abs(v)*w),M=Math.ceil(W+C*w);f(W,M);const E=M-W;for(let t=M;t<c;t+=E)await this.delay((()=>{f(t,Math.min(c,t+E))}));for(let t=W-1;t>=0;t-=E)await this.delay((()=>{f(Math.max(0,t-E),t)}))}render(t){const e=window.devicePixelRatio||1,i=this.scrollContainer.clientWidth,s=Math.ceil(t.duration*(this.options.minPxPerSec||0));this.isScrolling=s>i;const r=this.options.fillParent&&!this.isScrolling,n=(r?i:s)*e,{height:o}=this.options;this.wrapper.style.width=r?"100%":`${s}px`,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.cursor.style.backgroundColor=`${this.options.cursorColor||this.options.progressColor}`,this.cursor.style.width=`${this.options.cursorWidth}px`,this.canvasWrapper.style.height=`${this.options.height}px`,this.renderPeaks(t,n,o,e),this.audioData=t,this.emit("render")}reRender(){if(!this.audioData)return;const t=this.progressWrapper.clientWidth;this.render(this.audioData);const e=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=e-t}zoom(t){this.options.minPxPerSec=t,this.reRender()}scrollIntoView(t,e=!1){const{clientWidth:i,scrollLeft:s,scrollWidth:r}=this.scrollContainer,n=r*t,o=i/2;if(n>s+(e&&this.options.autoCenter&&!this.isDragging?o:i)||n<s)if(this.options.autoCenter&&!this.isDragging){const t=o/20;n-(s+o)>=t&&n<s+i?this.scrollContainer.scrollLeft+=t:this.scrollContainer.scrollLeft=n-o}else if(this.isDragging){const t=10;this.scrollContainer.scrollLeft=n<s?n-t:n-i+t}else this.scrollContainer.scrollLeft=n;{const{scrollLeft:t}=this.scrollContainer,e=t/r,s=(t+i)/r;this.emit("scroll",e,s)}}renderProgress(t,e){isNaN(t)||(this.progressWrapper.style.width=100*t+"%",this.cursor.style.left=100*t+"%",this.cursor.style.marginLeft=100===Math.round(100*t)?`-${this.options.cursorWidth}px`:"",this.isScrolling&&this.options.autoScroll&&this.scrollIntoView(t,e))}}a.MAX_CANVAS_WIDTH=4e3;const h=a,l=class extends i{constructor(){super(...arguments),this.unsubscribe=()=>{}}start(){this.unsubscribe=this.on("tick",(()=>{requestAnimationFrame((()=>{this.emit("tick")}))})),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}},c={height:128,waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoScroll:!0,autoCenter:!0,sampleRate:8e3};class d extends o{static create(t){return new d(t)}constructor(t){super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.subscriptions=[],this.options=Object.assign({},c,t),this.timer=new l,this.renderer=new h(this.options.container,this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initPlugins();const e=this.options.url||this.options.media?.currentSrc||this.options.media?.src;e&&this.load(e,this.options.peaks,this.options.duration)}setOptions(t){this.options={...this.options,...t},this.renderer.setOptions(this.options),t.audioRate&&this.setPlaybackRate(t.audioRate)}initPlayerEvents(){this.subscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),this.isPlaying()),this.emit("timeupdate",t)})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop()})),this.onMediaEvent("ended",(()=>{this.emit("finish")})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",this.getCurrentTime())})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(t=>{this.options.interact&&(this.seekTo(t),this.emit("interaction"),this.emit("click",t))})),this.renderer.on("scroll",((t,e)=>{const i=this.getDuration();this.emit("scroll",t*i,e*i)})),this.renderer.on("render",(()=>{this.emit("redraw")})));{let t;this.subscriptions.push(this.renderer.on("drag",(e=>{this.options.interact&&(this.renderer.renderProgress(e),clearTimeout(t),t=setTimeout((()=>{this.seekTo(e)}),this.isPlaying()?0:200),this.emit("interaction"),this.emit("drag",e))})))}}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),!0),this.emit("timeupdate",t),this.emit("audioprocess",t)})))}initPlugins(){this.options.plugins?.length&&this.options.plugins.forEach((t=>{this.registerPlugin(t)}))}registerPlugin(t){return t.init(this),this.plugins.push(t),t}getWrapper(){return this.renderer.getWrapper()}getScroll(){return this.renderer.getScroll()}getActivePlugins(){return this.plugins}async load(t,e,i){if(this.decodedData=null,this.emit("load",t),e)this.setSrc(t),i||(i=await new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getMediaElement().duration)))}))||0),this.decodedData=r.createBuffer(e,i);else{const e=await n(t);this.setSrc(t,e),this.decodedData=await r.decode(e,this.options.sampleRate)}this.emit("decode",this.getDuration()),this.emit("ready",this.getDuration()),this.renderer.render(this.decodedData)}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",t)}getDecodedData(){return this.decodedData}getDuration(){const t=super.getDuration();return t>0&&t<1/0?t:this.decodedData?.duration||0}toggleInteraction(t){this.options.interact=t}seekTo(t){const e=this.getDuration()*t;this.setTime(e)}playPause(){return this.isPlaying()?(this.pause(),Promise.resolve()):this.play()}stop(){this.pause(),this.setTime(0)}skip(t){this.setTime(this.getCurrentTime()+t)}empty(){this.load("",[[0]],.001)}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.plugins.forEach((t=>t.destroy())),this.timer.destroy(),this.renderer.destroy(),super.destroy()}}const p=d,u={height:50,overlayColor:"rgba(100, 100, 100, 0.1)",insertPosition:"afterend"};class m extends s{constructor(t){super(t),this.miniWavesurfer=null,this.container=null,this.options=Object.assign({},u,t),this.minimapWrapper=this.initMinimapWrapper(),this.overlay=this.initOverlay()}static create(t){return new m(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.options.container?("string"==typeof this.options.container?this.container=document.querySelector(this.options.container):this.options.container instanceof HTMLElement&&(this.container=this.options.container),this.container?.appendChild(this.minimapWrapper)):(this.container=this.wavesurfer.getWrapper().parentElement,this.container?.insertAdjacentElement(this.options.insertPosition,this.minimapWrapper)),this.initWaveSurferEvents()}initMinimapWrapper(){const t=document.createElement("div");return t.style.position="relative",t.setAttribute("part","minimap"),t}initOverlay(){const t=document.createElement("div");return t.setAttribute("style","position: absolute; z-index: 2; left: 0; top: 0; bottom: 0; transition: left 100ms ease-out; pointer-events: none;"),t.style.backgroundColor=this.options.overlayColor,this.minimapWrapper.appendChild(t),t}initMinimap(){if(this.miniWavesurfer&&(this.miniWavesurfer.destroy(),this.miniWavesurfer=null),!this.wavesurfer)return;const t=this.wavesurfer.getDecodedData(),e=this.wavesurfer.getMediaElement();t&&e&&(this.miniWavesurfer=p.create({...this.options,container:this.minimapWrapper,minPxPerSec:0,fillParent:!0,media:e,peaks:[t.getChannelData(0)],duration:t.duration}),this.subscriptions.push(this.miniWavesurfer.on("ready",(()=>{this.emit("ready")})),this.miniWavesurfer.on("interaction",(()=>{this.emit("interaction")}))))}getOverlayWidth(){const t=this.wavesurfer?.getWrapper().clientWidth||1;return Math.round(this.minimapWrapper.clientWidth/t*100)}onRedraw(){const t=this.getOverlayWidth();this.overlay.style.width=`${t}%`}onScroll(t){if(!this.wavesurfer)return;const e=this.wavesurfer.getDuration();this.overlay.style.left=t/e*100+"%"}initWaveSurferEvents(){this.wavesurfer&&this.subscriptions.push(this.wavesurfer.on("decode",(()=>{this.initMinimap()})),this.wavesurfer.on("scroll",(t=>{this.onScroll(t)})),this.wavesurfer.on("redraw",(()=>{this.onRedraw()})))}destroy(){this.miniWavesurfer?.destroy(),this.minimapWrapper.remove(),super.destroy()}}const g=m;return e.default})()));
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Minimap=e():t.Minimap=e()}(WaveSurfer,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var s in i)t.o(i,s)&&!t.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:i[s]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>g});const i=class{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),s=this.on(t,(()=>{i(),s()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}},s=class extends i{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.subscriptions.forEach((t=>t()))}},r={decode:async function(t,e){const i=new AudioContext({sampleRate:e}),s=i.decodeAudioData(t);return s.finally((()=>i.close())),s},createBuffer:function(t,e){return"number"==typeof t[0]&&(t=[t]),function(t){const e=t[0];if(e.some((t=>t>1||t<-1))){const i=e.length;let s=0;for(let t=0;t<i;t++){const i=Math.abs(e[t]);i>s&&(s=i)}for(const e of t)for(let t=0;t<i;t++)e[t]/=s}}(t),{duration:e,length:t[0].length,sampleRate:t[0].length/e,numberOfChannels:t.length,getChannelData:e=>t?.[e],copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}},n=async function(t){return fetch(t).then((t=>t.arrayBuffer()))},o=class extends i{constructor(t){super(),this.isExternalMedia=!1,t.media?(this.media=t.media,this.isExternalMedia=!0):this.media=document.createElement("audio"),t.autoplay&&(this.media.autoplay=!0),null!=t.playbackRate&&(this.media.playbackRate=t.playbackRate)}onMediaEvent(t,e,i){return this.media.addEventListener(t,e,i),()=>this.media.removeEventListener(t,e)}onceMediaEvent(t,e){return this.onMediaEvent(t,e,{once:!0})}revokeSrc(){(this.media.currentSrc||this.media.src||"").startsWith("blob:")&&URL.revokeObjectURL(this.media.currentSrc)}setSrc(t,e){if((this.media.currentSrc||this.media.src||"")===t)return;this.revokeSrc();const i=e?URL.createObjectURL(new Blob([e],{type:"audio/wav"})):t;this.media.src=i}destroy(){this.media.pause(),this.revokeSrc(),this.isExternalMedia||this.media.remove()}play(){return this.media.play()}pause(){this.media.pause()}isPlaying(){return this.media.currentTime>0&&!this.media.paused&&!this.media.ended}setTime(t){this.media.currentTime=t}getDuration(){return this.media.duration}getCurrentTime(){return this.media.currentTime}getVolume(){return this.media.volume}setVolume(t){this.media.volume=t}getMuted(){return this.media.muted}setMuted(t){this.media.muted=t}getPlaybackRate(){return this.media.playbackRate}setPlaybackRate(t,e){null!=e&&(this.media.preservesPitch=e),this.media.playbackRate=t}getMediaElement(){return this.media}setSinkId(t){return this.media.setSinkId(t)}};class a extends i{constructor(t){let e;if(super(),this.timeouts=[],this.isScrolling=!1,this.audioData=null,this.resizeObserver=null,this.isDragging=!1,this.options=t,"string"==typeof t.container?e=document.querySelector(t.container):t.container instanceof HTMLElement&&(e=t.container),!e)throw new Error("Container not found");const[i,s]=this.initHtml();e.appendChild(i),this.container=i,this.scrollContainer=s.querySelector(".scroll"),this.wrapper=s.querySelector(".wrapper"),this.canvasWrapper=s.querySelector(".canvases"),this.progressWrapper=s.querySelector(".progress"),this.cursor=s.querySelector(".cursor"),this.initEvents()}initEvents(){this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",i)})),this.initDrag(),this.scrollContainer.addEventListener("scroll",(()=>{const{scrollLeft:t,scrollWidth:e,clientWidth:i}=this.scrollContainer,s=t/e,r=(t+i)/e;this.emit("scroll",s,r)}));const t=this.createDelay(100);this.resizeObserver=new ResizeObserver((()=>{t((()=>this.reRender()))})),this.resizeObserver.observe(this.scrollContainer)}initDrag(){this.wrapper.addEventListener("mousedown",(t=>{const e=t.clientX,i=t=>{if(Math.abs(t.clientX-e)>=5){this.isDragging=!0;const e=this.wrapper.getBoundingClientRect();this.emit("drag",Math.max(0,Math.min(1,(t.clientX-e.left)/e.width)))}},s=()=>{document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",s),this.isDragging=!1};document.addEventListener("mousemove",i),document.addEventListener("mouseup",s)}))}initHtml(){const t=document.createElement("div"),e=t.attachShadow({mode:"open"});return e.innerHTML=`\n <style>\n :host {\n user-select: none;\n }\n :host .scroll {\n overflow-x: auto;\n overflow-y: hidden;\n width: 100%;\n position: relative;\n }\n :host .noScrollbar {\n scrollbar-color: transparent;\n scrollbar-width: none;\n }\n :host .noScrollbar::-webkit-scrollbar {\n display: none;\n -webkit-appearance: none;\n }\n :host .wrapper {\n position: relative;\n overflow: visible;\n z-index: 2;\n }\n :host .canvases {\n min-height: ${this.options.height}px;\n }\n :host .canvases > div {\n position: relative;\n }\n :host canvas {\n display: block;\n position: absolute;\n top: 0;\n image-rendering: pixelated;\n }\n :host .progress {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n width: 0;\n height: 100%;\n overflow: hidden;\n }\n :host .progress > div {\n position: relative;\n }\n :host .cursor {\n pointer-events: none;\n position: absolute;\n z-index: 5;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n }\n </style>\n\n <div class="scroll" part="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress"></div>\n <div class="cursor" part="cursor"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){this.options=t,this.reRender()}getWrapper(){return this.wrapper}getScroll(){return this.scrollContainer.scrollLeft}destroy(){this.container.remove(),this.resizeObserver?.disconnect()}createDelay(t=10){const e={};return this.timeouts.push(e),i=>{e.timeout&&clearTimeout(e.timeout),e.timeout=setTimeout(i,t)}}convertColorValues(t){if(!Array.isArray(t))return t||"";if(t.length<2)return 1===t.length?t[0]:"";const e=document.createElement("canvas"),i=e.getContext("2d").createLinearGradient(0,0,0,e.height),s=1/(t.length-1);return t.forEach(((t,e)=>{const r=e*s;i.addColorStop(r,t)})),i}renderSingleCanvas(t,e,i,s,r,n,o){const a=window.devicePixelRatio||1,h=e.height||0,l=null==e.barWidth||isNaN(e.barWidth)?1:e.barWidth*a,c=null==e.barGap||isNaN(e.barGap)?e.barWidth?l/2:0:e.barGap*a,d=e.barRadius||0,u=e.barHeight||1,p=1===t.length,m=t[0],g=p?m:t[1],v=p&&g.some((t=>t<0)),f=m.length,y=Math.floor(i/(l+c))/f,b=h/2;let w=0,C=0,W=0;const E=document.createElement("canvas");E.width=Math.round(i*(r-s)/f),E.height=h,E.style.width=`${Math.floor(E.width/a)}px`,E.style.height=`${e.height}px`,E.style.left=`${Math.floor(s*i/a/f)}px`,n.appendChild(E);const M=E.getContext("2d",{desynchronized:!0});M.beginPath(),M.fillStyle=this.convertColorValues(e.waveColor),M.roundRect||(M.roundRect=M.fillRect);for(let t=s;t<r;t++){const e=Math.round((t-s)*y);if(e>w){const t=Math.round(C*b*u),i=Math.round(W*b*u);M.roundRect(w*(l+c),b-t,l,t+(i||1),d),w=e,C=0,W=0}const i=v?m[t]:Math.abs(m[t]),r=v?g[t]:Math.abs(g[t]);i>C&&(C=i),(v?r<-W:r>W)&&(W=r<0?-r:r)}M.fill(),M.closePath();const S=E.cloneNode();o.appendChild(S);const D=S.getContext("2d",{desynchronized:!0});E.width>0&&E.height>0&&D.drawImage(E,0,0),D.globalCompositeOperation="source-in",D.fillStyle=this.convertColorValues(e.progressColor),D.fillRect(0,0,E.width,E.height)}renderWaveform(t,e,i){const s=document.createElement("div");s.style.height=`${e.height}px`,this.canvasWrapper.appendChild(s);const r=s.cloneNode();this.progressWrapper.appendChild(r);const{scrollLeft:n,scrollWidth:o,clientWidth:h}=this.scrollContainer,l=t[0].length,c=l/o,d=Math.min(a.MAX_CANVAS_WIDTH,h),u=Math.floor(Math.abs(n)*c),p=Math.ceil(u+d*c),m=p-u,g=(n,o)=>{this.renderSingleCanvas(t,e,i,Math.max(0,n),Math.min(o,l),s,r)},v=this.createDelay(),f=this.createDelay(),y=(t,e)=>{g(t,e),t>0&&v((()=>{y(t-m,e-m)}))},b=(t,e)=>{g(t,e),e<l&&f((()=>{b(t+m,e+m)}))};y(u,p),p<l&&b(p,p+m)}render(t){this.timeouts.forEach((t=>t.timeout&&clearTimeout(t.timeout))),this.timeouts=[];const e=window.devicePixelRatio||1,i=this.scrollContainer.clientWidth,s=Math.ceil(t.duration*(this.options.minPxPerSec||0));this.isScrolling=s>i;const r=this.options.fillParent&&!this.isScrolling,n=(r?i:s)*e;if(this.wrapper.style.width=r?"100%":`${s}px`,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.cursor.style.backgroundColor=`${this.options.cursorColor||this.options.progressColor}`,this.cursor.style.width=`${this.options.cursorWidth}px`,this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="",this.options.splitChannels)for(let e=0;e<t.numberOfChannels;e++){const i={...this.options,...this.options.splitChannels[e]};this.renderWaveform([t.getChannelData(e)],i,n)}else{const e=[t.getChannelData(0)];t.numberOfChannels>1&&e.push(t.getChannelData(1)),this.renderWaveform(e,this.options,n)}this.audioData=t,this.emit("render")}reRender(){if(!this.audioData)return;const t=this.progressWrapper.clientWidth;this.render(this.audioData);const e=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=e-t}zoom(t){this.options.minPxPerSec=t,this.reRender()}scrollIntoView(t,e=!1){const{clientWidth:i,scrollLeft:s,scrollWidth:r}=this.scrollContainer,n=r*t,o=i/2;if(n>s+(e&&this.options.autoCenter&&!this.isDragging?o:i)||n<s)if(this.options.autoCenter&&!this.isDragging){const t=o/20;n-(s+o)>=t&&n<s+i?this.scrollContainer.scrollLeft+=t:this.scrollContainer.scrollLeft=n-o}else if(this.isDragging){const t=10;this.scrollContainer.scrollLeft=n<s?n-t:n-i+t}else this.scrollContainer.scrollLeft=n;{const{scrollLeft:t}=this.scrollContainer,e=t/r,s=(t+i)/r;this.emit("scroll",e,s)}}renderProgress(t,e){isNaN(t)||(this.progressWrapper.style.width=100*t+"%",this.cursor.style.left=100*t+"%",this.cursor.style.marginLeft=100===Math.round(100*t)?`-${this.options.cursorWidth}px`:"",this.isScrolling&&this.options.autoScroll&&this.scrollIntoView(t,e))}}a.MAX_CANVAS_WIDTH=4e3;const h=a,l=class extends i{constructor(){super(...arguments),this.unsubscribe=()=>{}}start(){this.unsubscribe=this.on("tick",(()=>{requestAnimationFrame((()=>{this.emit("tick")}))})),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}},c={height:128,waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoScroll:!0,autoCenter:!0,sampleRate:8e3};class d extends o{static create(t){return new d(t)}constructor(t){super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.subscriptions=[],this.options=Object.assign({},c,t),this.timer=new l,this.renderer=new h(this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initPlugins();const e=this.options.url||this.options.media?.currentSrc||this.options.media?.src;e&&this.load(e,this.options.peaks,this.options.duration)}setOptions(t){this.options={...this.options,...t},this.renderer.setOptions(this.options),t.audioRate&&this.setPlaybackRate(t.audioRate)}initPlayerEvents(){this.subscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),this.isPlaying()),this.emit("timeupdate",t)})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop()})),this.onMediaEvent("ended",(()=>{this.emit("finish")})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",this.getCurrentTime())})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(t=>{this.options.interact&&(this.seekTo(t),this.emit("interaction"),this.emit("click",t))})),this.renderer.on("scroll",((t,e)=>{const i=this.getDuration();this.emit("scroll",t*i,e*i)})),this.renderer.on("render",(()=>{this.emit("redraw")})));{let t;this.subscriptions.push(this.renderer.on("drag",(e=>{this.options.interact&&(this.renderer.renderProgress(e),clearTimeout(t),t=setTimeout((()=>{this.seekTo(e)}),this.isPlaying()?0:200),this.emit("interaction"),this.emit("drag",e))})))}}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),!0),this.emit("timeupdate",t),this.emit("audioprocess",t)})))}initPlugins(){this.options.plugins?.length&&this.options.plugins.forEach((t=>{this.registerPlugin(t)}))}registerPlugin(t){return t.init(this),this.plugins.push(t),t}getWrapper(){return this.renderer.getWrapper()}getScroll(){return this.renderer.getScroll()}getActivePlugins(){return this.plugins}async load(t,e,i){if(this.decodedData=null,this.emit("load",t),e)this.setSrc(t),i||(i=await new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getMediaElement().duration)))}))||0),this.decodedData=r.createBuffer(e,i);else{const e=await n(t);this.setSrc(t,e),this.decodedData=await r.decode(e,this.options.sampleRate)}this.emit("decode",this.getDuration()),this.emit("ready",this.getDuration()),this.renderer.render(this.decodedData)}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",t)}getDecodedData(){return this.decodedData}getDuration(){const t=super.getDuration();return t>0&&t<1/0?t:this.decodedData?.duration||0}toggleInteraction(t){this.options.interact=t}seekTo(t){const e=this.getDuration()*t;this.setTime(e)}playPause(){return this.isPlaying()?(this.pause(),Promise.resolve()):this.play()}stop(){this.pause(),this.setTime(0)}skip(t){this.setTime(this.getCurrentTime()+t)}empty(){this.load("",[[0]],.001)}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.plugins.forEach((t=>t.destroy())),this.timer.destroy(),this.renderer.destroy(),super.destroy()}}const u=d,p={height:50,overlayColor:"rgba(100, 100, 100, 0.1)",insertPosition:"afterend"};class m extends s{constructor(t){super(t),this.miniWavesurfer=null,this.container=null,this.options=Object.assign({},p,t),this.minimapWrapper=this.initMinimapWrapper(),this.overlay=this.initOverlay()}static create(t){return new m(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.options.container?("string"==typeof this.options.container?this.container=document.querySelector(this.options.container):this.options.container instanceof HTMLElement&&(this.container=this.options.container),this.container?.appendChild(this.minimapWrapper)):(this.container=this.wavesurfer.getWrapper().parentElement,this.container?.insertAdjacentElement(this.options.insertPosition,this.minimapWrapper)),this.initWaveSurferEvents()}initMinimapWrapper(){const t=document.createElement("div");return t.style.position="relative",t.setAttribute("part","minimap"),t}initOverlay(){const t=document.createElement("div");return t.setAttribute("style","position: absolute; z-index: 2; left: 0; top: 0; bottom: 0; transition: left 100ms ease-out; pointer-events: none;"),t.style.backgroundColor=this.options.overlayColor,this.minimapWrapper.appendChild(t),t}initMinimap(){if(this.miniWavesurfer&&(this.miniWavesurfer.destroy(),this.miniWavesurfer=null),!this.wavesurfer)return;const t=this.wavesurfer.getDecodedData(),e=this.wavesurfer.getMediaElement();t&&e&&(this.miniWavesurfer=u.create({...this.options,container:this.minimapWrapper,minPxPerSec:0,fillParent:!0,media:e,peaks:[t.getChannelData(0)],duration:t.duration}),this.subscriptions.push(this.miniWavesurfer.on("ready",(()=>{this.emit("ready")})),this.miniWavesurfer.on("interaction",(()=>{this.emit("interaction")}))))}getOverlayWidth(){const t=this.wavesurfer?.getWrapper().clientWidth||1;return Math.round(this.minimapWrapper.clientWidth/t*100)}onRedraw(){const t=this.getOverlayWidth();this.overlay.style.width=`${t}%`}onScroll(t){if(!this.wavesurfer)return;const e=this.wavesurfer.getDuration();this.overlay.style.left=t/e*100+"%"}initWaveSurferEvents(){this.wavesurfer&&this.subscriptions.push(this.wavesurfer.on("decode",(()=>{this.initMinimap()})),this.wavesurfer.on("scroll",(t=>{this.onScroll(t)})),this.wavesurfer.on("redraw",(()=>{this.onRedraw()})))}destroy(){this.miniWavesurfer?.destroy(),this.minimapWrapper.remove(),super.destroy()}}const g=m;return e.default})()));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Multitrack=e():t.Multitrack=e()}(WaveSurfer,(()=>(()=>{"use strict";var t={284:(t,e,i)=>{i.d(e,{Z:()=>r});var s=i(139);class n extends s.Z{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.subscriptions.forEach((t=>t()))}}const r=n},139:(t,e,i)=>{i.d(e,{Z:()=>s});const s=class{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),s=this.on(t,(()=>{i(),s()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}},919:(t,e,i)=>{i.d(e,{default:()=>h});var s=i(284),n=i(139);const r={fadeInStart:0,fadeOutEnd:0,fadeInEnd:0,fadeOutStart:0,lineWidth:4,lineColor:"rgba(0, 0, 255, 0.5)",dragPointSize:10,dragPointFill:"rgba(255, 255, 255, 0.8)",dragPointStroke:"rgba(255, 255, 255, 0.8)"};class o extends n.Z{constructor(t,e){super(),this.top=0,this.padding=t.dragPointSize/2+1;const i=document.createElementNS("http://www.w3.org/2000/svg","svg");i.setAttribute("width","100%"),i.setAttribute("height","100%"),i.setAttribute("viewBox","0 0 0 0"),i.setAttribute("preserveAspectRatio","none"),i.setAttribute("style","position: absolute; left: 0; top: 0; z-index: 4; pointer-events: none;"),i.setAttribute("part","envelope"),this.svg=i;const s=document.createElementNS("http://www.w3.org/2000/svg","polyline");s.setAttribute("points","0,0 0,0 0,0 0,0"),s.setAttribute("stroke",t.lineColor),s.setAttribute("stroke-width",t.lineWidth),s.setAttribute("fill","none"),s.setAttribute("style","pointer-events: none;"),s.setAttribute("part","polyline"),i.appendChild(s);const n=document.createElementNS("http://www.w3.org/2000/svg","line");n.setAttribute("stroke","transparent"),n.setAttribute("stroke-width",(3*t.lineWidth).toString()),n.setAttribute("style","cursor: ns-resize; pointer-events: all;"),n.setAttribute("part","line"),i.appendChild(n),[0,1].forEach((()=>{const e=document.createElementNS("http://www.w3.org/2000/svg","circle");e.setAttribute("r",(t.dragPointSize/2).toString()),e.setAttribute("fill",t.dragPointFill),e.setAttribute("stroke",t.dragPointStroke||t.dragPointFill),e.setAttribute("stroke-width","2"),e.setAttribute("style","cursor: ew-resize; pointer-events: all;"),e.setAttribute("part","circle"),i.appendChild(e)})),e.appendChild(i);{const t=t=>{const e=this.top+t,{height:s}=i.viewBox.baseVal;if(e<-.5||e>s)return;const n=Math.min(1,Math.max(0,(s-e)/s));this.emit("line-move",n)},e=(t,e)=>{const n=s.points.getItem(t).x+e,{width:r}=i.viewBox.baseVal;this.emit("point-move",t,n/r)};this.makeDraggable(n,((e,i)=>t(i)));const r=this.svg.querySelectorAll("circle");Array.from(r).forEach(((t,i)=>{this.makeDraggable(t,(t=>e(i+1,t)))}))}}makeDraggable(t,e){t.addEventListener("click",(t=>{t.preventDefault(),t.stopPropagation()})),t.addEventListener("mousedown",(t=>{t.preventDefault(),t.stopPropagation();let i=t.clientX,s=t.clientY;const n=t=>{const n=t.clientX-i,r=t.clientY-s;i=t.clientX,s=t.clientY,e(n,r)},r=()=>{document.removeEventListener("mousemove",n),document.removeEventListener("mouseup",r)};document.addEventListener("mousemove",n),document.addEventListener("mouseup",r)}))}update({x1:t,x2:e,x3:i,x4:s,y:n}){const r=this.svg.clientWidth,o=this.svg.clientHeight;this.top=o-n*o;const a=Math.max(this.padding,Math.min(this.top,o-this.padding));this.svg.setAttribute("viewBox",`0 0 ${r} ${o}`);const h=this.svg.querySelector("polyline"),{points:d}=h;d.getItem(0).x=t*r,d.getItem(0).y=o,d.getItem(1).x=e*r,d.getItem(1).y=a,d.getItem(2).x=i*r,d.getItem(2).y=a,d.getItem(3).x=s*r,d.getItem(3).y=o;const l=this.svg.querySelector("line");l.setAttribute("x1",d.getItem(1).x.toString()),l.setAttribute("x2",d.getItem(2).x.toString()),l.setAttribute("y1",a.toString()),l.setAttribute("y2",a.toString());const u=this.svg.querySelectorAll("circle");Array.from(u).forEach(((t,e)=>{const i=d.getItem(e+1);t.setAttribute("cx",i.x.toString()),t.setAttribute("cy",i.y.toString())}))}destroy(){this.svg.remove()}}class a extends s.Z{constructor(t){super(t),this.polyline=null,this.audioContext=null,this.gainNode=null,this.volume=1,this.isFadingIn=!1,this.isFadingOut=!1,this.naturalVolumeExponent=1.5,this.options=Object.assign({},r,t),this.options.lineColor=this.options.lineColor||r.lineColor,this.options.dragPointFill=this.options.dragPointFill||r.dragPointFill,this.options.dragPointStroke=this.options.dragPointStroke||r.dragPointStroke,this.volume=this.options.volume??1}static create(t){return new a(t)}destroy(){this.polyline?.destroy(),super.destroy()}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.initWebAudio(),this.initSvg(),this.initFadeEffects(),this.subscriptions.push(this.wavesurfer.on("redraw",(()=>{const t=this.wavesurfer?.getDuration();t&&(this.options.fadeInStart=this.options.fadeInStart||0,this.options.fadeOutEnd=this.options.fadeOutEnd||t,this.options.fadeInEnd=this.options.fadeInEnd||this.options.fadeInStart,this.options.fadeOutStart=this.options.fadeOutStart||this.options.fadeOutEnd,this.renderPolyline())})))}initSvg(){if(!this.wavesurfer)return;const t=this.wavesurfer.getWrapper();this.polyline=new o(this.options,t),this.subscriptions.push(this.polyline.on("line-move",(t=>{this.setVolume(this.naturalVolume(t))})),this.polyline.on("point-move",((t,e)=>{const i=e*(this.wavesurfer?.getDuration()||0);if(1===t){if(i<this.options.fadeInStart||i>this.options.fadeOutStart)return;this.options.fadeInEnd=i,this.emit("fade-in-change",i)}else if(2===t){if(i>this.options.fadeOutEnd||i<this.options.fadeInEnd)return;this.options.fadeOutStart=i,this.emit("fade-out-change",i)}this.renderPolyline()})))}renderPolyline(){if(!this.polyline||!this.wavesurfer)return;const t=this.wavesurfer.getDuration();t&&this.polyline.update({x1:this.options.fadeInStart/t,x2:this.options.fadeInEnd/t,x3:this.options.fadeOutStart/t,x4:this.options.fadeOutEnd/t,y:this.invertNaturalVolume(this.volume)})}initWebAudio(){const t=this.wavesurfer?.getMediaElement();if(!t)return null;this.volume=this.options.volume??t.volume;const e=new window.AudioContext;this.gainNode=e.createGain(),this.setGainValue(),e.createMediaElementSource(t).connect(this.gainNode),this.gainNode.connect(e.destination),this.audioContext=e}invertNaturalVolume(t){return Math.pow((t-1e-4)/.9999,1/this.naturalVolumeExponent)}naturalVolume(t){return 1e-4+.9999*Math.pow(t,this.naturalVolumeExponent)}setGainValue(){this.gainNode&&(this.gainNode.gain.value=this.volume)}initFadeEffects(){if(!this.audioContext||!this.wavesurfer)return;const t=this.wavesurfer.on("timeupdate",(t=>{if(!this.audioContext||!this.gainNode)return;if(!this.wavesurfer?.isPlaying())return;if("suspended"===this.audioContext.state&&this.audioContext.resume(),!this.isFadingIn&&t>=this.options.fadeInStart&&t<=this.options.fadeInEnd)return this.isFadingIn=!0,this.gainNode.gain.setValueAtTime(0,this.audioContext.currentTime),void this.gainNode.gain.linearRampToValueAtTime(this.volume,this.audioContext.currentTime+(this.options.fadeInEnd-t));if(!this.isFadingOut&&t>=this.options.fadeOutStart&&t<=this.options.fadeOutEnd)return this.isFadingOut=!0,this.gainNode.gain.setValueAtTime(this.volume,this.audioContext.currentTime),void this.gainNode.gain.linearRampToValueAtTime(0,this.audioContext.currentTime+(this.options.fadeOutEnd-t));let e=!1;this.isFadingIn&&(t<this.options.fadeInStart||t>this.options.fadeInEnd)&&(this.isFadingIn=!1,e=!0),this.isFadingOut&&(t<this.options.fadeOutStart||t>=this.options.fadeOutEnd)&&(this.isFadingOut=!1,e=!0),e&&(this.gainNode.gain.cancelScheduledValues(this.audioContext.currentTime),this.setGainValue())}));this.subscriptions.push(t)}getCurrentVolume(){return this.gainNode?this.gainNode.gain.value:this.volume}setStartTime(t,e=!1){if(e){const e=this.options.fadeInEnd-this.options.fadeInStart;this.options.fadeInEnd=t+e}this.options.fadeInStart=t,this.renderPolyline()}setEndTime(t,e=!1){if(e){const e=this.options.fadeOutEnd-this.options.fadeOutStart;this.options.fadeOutStart=t-e}this.options.fadeOutEnd=t,this.renderPolyline()}setVolume(t){this.volume=t,this.setGainValue(),this.renderPolyline(),this.emit("volume-change",t)}}const h=a},76:(t,e,i)=>{i.d(e,{default:()=>h});var s=i(284),n=i(139);function r(t,e,i,s,n=5){if(!t)return()=>{};let r=!1;const o=t=>{r&&t.stopPropagation()},a=t=>{t.stopPropagation();let o=t.clientX,a=0;e(o);const h=t=>{const e=t.clientX,s=e-o;a+=s,o=e,(r||Math.abs(a)>=n)&&(i(r?s:a),r=!0)},d=()=>{r&&(s(),setTimeout((()=>r=!1),10)),document.removeEventListener("mousemove",h),document.removeEventListener("mouseup",d)};document.addEventListener("mousemove",h),document.addEventListener("mouseup",d)};return t.addEventListener("click",o),t.addEventListener("mousedown",a),()=>{t.removeEventListener("click",o),t.removeEventListener("mousedown",a)}}class o extends n.Z{constructor(t,e){super(),this.totalDuration=e,this.id=t.id||`region-${Math.random().toString(32).slice(2)}`,this.start=t.start,this.end=t.end??t.start,this.drag=t.drag??!0,this.resize=t.resize??!0,this.color=t.color??"rgba(0, 0, 0, 0.1)",this.element=this.initElement(t.content),this.renderPosition(),this.initMouseEvents()}initElement(t){const e=document.createElement("div"),i=this.start===this.end;if(e.setAttribute("part",`${i?"marker":"region"} ${this.id}`),e.setAttribute("style",`\n position: absolute;\n height: 100%;\n background-color: ${i?"none":this.color};\n border-left: ${i?"2px solid "+this.color:"none"};\n border-radius: 2px;\n box-sizing: border-box;\n transition: background-color 0.2s ease;\n cursor: ${this.drag?"grab":"default"};\n pointer-events: all;\n padding: 0.2em ${i?.2:.4}em;\n pointer-events: all;\n `),t&&("string"==typeof t?(this.content=document.createElement("div"),this.content.textContent=t):this.content=t,this.content.setAttribute("part","region-content"),e.appendChild(this.content)),!i){const t=document.createElement("div");t.setAttribute("data-resize","left"),t.setAttribute("style",`\n position: absolute;\n z-index: 2;\n width: 6px;\n height: 100%;\n top: 0;\n left: 0;\n border-left: 2px solid rgba(0, 0, 0, 0.5);\n border-radius: 2px 0 0 2px;\n cursor: ${this.resize?"ew-resize":"default"};\n word-break: keep-all;\n `),t.setAttribute("part","region-handle region-handle-left");const i=t.cloneNode();i.setAttribute("data-resize","right"),i.style.left="",i.style.right="0",i.style.borderRight=i.style.borderLeft,i.style.borderLeft="",i.style.borderRadius="0 2px 2px 0",i.setAttribute("part","region-handle region-handle-right"),e.appendChild(t),e.appendChild(i)}return e}renderPosition(){const t=this.start/this.totalDuration,e=this.end/this.totalDuration;this.element.style.left=100*t+"%",this.element.style.width=100*(e-t)+"%"}initMouseEvents(){const{element:t}=this;t.addEventListener("click",(t=>this.emit("click",t))),t.addEventListener("mouseenter",(t=>this.emit("over",t))),t.addEventListener("mouseleave",(t=>this.emit("leave",t))),t.addEventListener("dblclick",(t=>this.emit("dblclick",t))),r(t,(()=>this.onStartMoving()),(t=>this.onMove(t)),(()=>this.onEndMoving())),r(t.querySelector('[data-resize="left"]'),(()=>null),(t=>this.onResize(t,"start")),(()=>this.onEndResizing()),1),r(t.querySelector('[data-resize="right"]'),(()=>null),(t=>this.onResize(t,"end")),(()=>this.onEndResizing()),1)}onStartMoving(){this.drag&&(this.element.style.cursor="grabbing")}onEndMoving(){this.drag&&(this.element.style.cursor="grab",this.emit("update-end"))}onUpdate(t,e){if(!this.element.parentElement)return;const i=t/this.element.parentElement.clientWidth*this.totalDuration;e.forEach((t=>{this[t]+=i,"start"===t?this.start=Math.max(0,Math.min(this.start,this.end)):this.end=Math.max(this.start,Math.min(this.end,this.totalDuration))})),this.renderPosition(),this.emit("update")}onMove(t){this.drag&&this.onUpdate(t,["start","end"])}onResize(t,e){this.resize&&this.onUpdate(t,[e])}onEndResizing(){this.resize&&this.emit("update-end")}_setTotalDuration(t){this.totalDuration=t,this.renderPosition()}play(){this.emit("play")}setOptions(t){t.color&&(this.color=t.color,this.element.style.backgroundColor=this.color),void 0!==t.drag&&(this.drag=t.drag,this.element.style.cursor=this.drag?"grab":"default"),void 0!==t.resize&&(this.resize=t.resize,this.element.querySelectorAll("[data-resize]").forEach((t=>{t.style.cursor=this.resize?"ew-resize":"default"}))),void 0===t.start&&void 0===t.end||(this.start=t.start??this.start,this.end=t.end??this.end,this.renderPosition())}remove(){this.emit("remove"),this.element.remove(),this.element=null}}class a extends s.Z{constructor(t){super(t),this.regions=[],this.regionsContainer=this.initRegionsContainer()}static create(t){return new a(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.wavesurfer.getWrapper().appendChild(this.regionsContainer)}initRegionsContainer(){const t=document.createElement("div");return t.setAttribute("style","\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 3;\n pointer-events: none;\n "),t}getRegions(){return this.regions}avoidOverlapping(t){if(!t.content)return;const e=t.content,i=e.getBoundingClientRect().left,s=t.element.scrollWidth,n=this.regions.filter((e=>{if(e===t||!e.content)return!1;const n=e.content.getBoundingClientRect().left,r=e.element.scrollWidth;return i<n+r&&n<i+s})).map((t=>t.content?.getBoundingClientRect().height||0)).reduce(((t,e)=>t+e),0);e.style.marginTop=`${n}px`}saveRegion(t){this.regionsContainer.appendChild(t.element),this.avoidOverlapping(t),this.regions.push(t),this.emit("region-created",t);const e=[t.on("update-end",(()=>{this.avoidOverlapping(t),this.emit("region-updated",t)})),t.on("play",(()=>{this.wavesurfer?.play(),this.wavesurfer?.setTime(t.start)})),t.on("click",(e=>{this.emit("region-clicked",t,e)})),t.once("remove",(()=>{e.forEach((t=>t())),this.regions=this.regions.filter((e=>e!==t))}))];this.subscriptions.push(...e)}addRegion(t){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const e=this.wavesurfer.getDuration(),i=new o(t,e);return e?this.saveRegion(i):this.subscriptions.push(this.wavesurfer.once("ready",(t=>{i._setTotalDuration(t),this.saveRegion(i)}))),i}enableDragSelection(t){const e=this.wavesurfer?.getWrapper()?.querySelector("div");if(!e)return()=>{};let i=null,s=0,n=0;return r(e,(t=>s=t),(r=>{if(this.wavesurfer){if(!i){const n=this.wavesurfer.getDuration(),a=e.getBoundingClientRect();let h=(s-a.left)/a.width*n,d=(s+r-a.left)/a.width*n;h>d&&([h,d]=[d,h]),i=new o({...t,start:h,end:d},n),this.regionsContainer.appendChild(i.element)}n+=r,i&&i.onUpdate(r,[n>0?"end":"start"])}}),(()=>{if(i&&(this.saveRegion(i),i=null,n=0,this.wavesurfer)){const{interact:t}=this.wavesurfer.options;t&&(this.wavesurfer.toggleInteraction(!1),setTimeout((()=>this.wavesurfer?.toggleInteraction(t)),10))}}))}clearRegions(){this.regions.forEach((t=>t.remove()))}destroy(){this.clearRegions(),super.destroy()}}const h=a},954:(t,e,i)=>{i.d(e,{default:()=>o});var s=i(284);const n={height:20};class r extends s.Z{constructor(t){super(t||{}),this.options=Object.assign({},n,t),this.timelineWrapper=this.initTimelineWrapper()}static create(t){return new r(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const t=this.options.container??this.wavesurfer.getWrapper();this.options.insertPosition?(t.firstElementChild||t).insertAdjacentElement(this.options.insertPosition,this.timelineWrapper):t.appendChild(this.timelineWrapper),this.options.duration?this.initTimeline(this.options.duration):this.subscriptions.push(this.wavesurfer.on("redraw",(()=>{this.initTimeline(this.wavesurfer?.getDuration()||0)})))}destroy(){this.timelineWrapper.remove(),super.destroy()}initTimelineWrapper(){const t=document.createElement("div");return t.setAttribute("part","timeline"),t}formatTime(t){return t/60>1?`${Math.floor(t/60)}:${(t=Math.round(t%60))<10?"0":""}${t}`:""+Math.round(1e3*t)/1e3}defaultTimeInterval(t){return t>=25?1:5*t>=25?5:15*t>=25?15:60*Math.ceil(.5/t)}defaultPrimaryLabelInterval(t){return t>=25?10:5*t>=25?6:4}defaultSecondaryLabelInterval(t){return t>=25?5:2}initTimeline(t){const e=this.timelineWrapper.scrollWidth/t,i=this.options.timeInterval??this.defaultTimeInterval(e),s=this.options.primaryLabelInterval??this.defaultPrimaryLabelInterval(e),n=this.options.secondaryLabelInterval??this.defaultSecondaryLabelInterval(e),r="beforebegin"===this.options.insertPosition,o=document.createElement("div");if(o.setAttribute("style",`\n height: ${this.options.height}px;\n overflow: hidden;\n display: flex;\n justify-content: space-between;\n align-items: ${r?"flex-start":"flex-end"};\n font-size: ${this.options.height/2}px;\n white-space: nowrap;\n `),r){const t="\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 2;\n ";o.setAttribute("style",o.getAttribute("style")+t)}"string"==typeof this.options.style?o.setAttribute("style",o.getAttribute("style")+this.options.style):"object"==typeof this.options.style&&Object.assign(o.style,this.options.style);const a=document.createElement("div");a.setAttribute("style",`\n width: 1px;\n height: 50%;\n display: flex;\n flex-direction: column;\n justify-content: ${r?"flex-start":"flex-end"};\n overflow: visible;\n border-left: 1px solid currentColor;\n opacity: 0.25;\n `);for(let e=0;e<t;e+=i){const t=a.cloneNode(),i=Math.round(100*e)/100%s==0,r=Math.round(100*e)/100%n==0;(i||r)&&(t.style.height="100%",t.style.textIndent="3px",t.textContent=this.formatTime(e),i&&(t.style.opacity="1")),o.appendChild(t)}this.timelineWrapper.innerHTML="",this.timelineWrapper.appendChild(o),this.emit("ready")}}const o=r}},e={};function i(s){var n=e[s];if(void 0!==n)return n.exports;var r=e[s]={exports:{}};return t[s](r,r.exports,i),r.exports}i.d=(t,e)=>{for(var s in e)i.o(e,s)&&!i.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:e[s]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var s={};return(()=>{i.d(s,{default:()=>b});const t={decode:async function(t,e){const i=new AudioContext({sampleRate:e}),s=i.decodeAudioData(t);return s.finally((()=>i.close())),s},createBuffer:function(t,e){return"number"==typeof t[0]&&(t=[t]),function(t){const e=t[0];if(e.some((t=>t>1||t<-1))){const i=e.length;let s=0;for(let t=0;t<i;t++){const i=Math.abs(e[t]);i>s&&(s=i)}for(const e of t)for(let t=0;t<i;t++)e[t]/=s}}(t),{duration:e,length:t[0].length,sampleRate:t[0].length/e,numberOfChannels:t.length,getChannelData:e=>t?.[e],copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}},e=async function(t){return fetch(t).then((t=>t.arrayBuffer()))};var n=i(139);class r extends n.Z{constructor(t){super(),this.isExternalMedia=!1,t.media?(this.media=t.media,this.isExternalMedia=!0):this.media=document.createElement("audio"),t.autoplay&&(this.media.autoplay=!0),null!=t.playbackRate&&(this.media.playbackRate=t.playbackRate)}onMediaEvent(t,e,i){return this.media.addEventListener(t,e,i),()=>this.media.removeEventListener(t,e)}onceMediaEvent(t,e){return this.onMediaEvent(t,e,{once:!0})}revokeSrc(){(this.media.currentSrc||this.media.src||"").startsWith("blob:")&&URL.revokeObjectURL(this.media.currentSrc)}setSrc(t,e){if((this.media.currentSrc||this.media.src||"")===t)return;this.revokeSrc();const i=e?URL.createObjectURL(new Blob([e],{type:"audio/wav"})):t;this.media.src=i}destroy(){this.media.pause(),this.revokeSrc(),this.isExternalMedia||this.media.remove()}play(){return this.media.play()}pause(){this.media.pause()}isPlaying(){return this.media.currentTime>0&&!this.media.paused&&!this.media.ended}setTime(t){this.media.currentTime=t}getDuration(){return this.media.duration}getCurrentTime(){return this.media.currentTime}getVolume(){return this.media.volume}setVolume(t){this.media.volume=t}getMuted(){return this.media.muted}setMuted(t){this.media.muted=t}getPlaybackRate(){return this.media.playbackRate}setPlaybackRate(t,e){null!=e&&(this.media.preservesPitch=e),this.media.playbackRate=t}getMediaElement(){return this.media}setSinkId(t){return this.media.setSinkId(t)}}const o=r;class a extends n.Z{constructor(t,e){if(super(),this.options={height:0},this.timeout=null,this.isScrolling=!1,this.audioData=null,this.resizeObserver=null,this.isDragging=!1,this.options={...e},"string"==typeof t&&(t=document.querySelector(t)),!t)throw new Error("Container not found");const[i,s]=this.initHtml();t.appendChild(i),this.container=i,this.scrollContainer=s.querySelector(".scroll"),this.wrapper=s.querySelector(".wrapper"),this.canvasWrapper=s.querySelector(".canvases"),this.progressWrapper=s.querySelector(".progress"),this.cursor=s.querySelector(".cursor"),this.initEvents()}initEvents(){this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",i)})),this.initDrag(),this.scrollContainer.addEventListener("scroll",(()=>{const{scrollLeft:t,scrollWidth:e,clientWidth:i}=this.scrollContainer,s=t/e,n=(t+i)/e;this.emit("scroll",s,n)})),this.resizeObserver=new ResizeObserver((()=>{this.delay((()=>this.reRender()),100)})),this.resizeObserver.observe(this.scrollContainer)}initDrag(){this.wrapper.addEventListener("mousedown",(t=>{const e=t.clientX,i=t=>{if(Math.abs(t.clientX-e)>=5){this.isDragging=!0;const e=this.wrapper.getBoundingClientRect();this.emit("drag",Math.max(0,Math.min(1,(t.clientX-e.left)/e.width)))}},s=()=>{document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",s),this.isDragging=!1};document.addEventListener("mousemove",i),document.addEventListener("mouseup",s)}))}initHtml(){const t=document.createElement("div"),e=t.attachShadow({mode:"open"});return e.innerHTML=`\n <style>\n :host {\n user-select: none;\n }\n :host .scroll {\n overflow-x: auto;\n overflow-y: hidden;\n width: 100%;\n position: relative;\n }\n :host .noScrollbar {\n scrollbar-color: transparent;\n scrollbar-width: none;\n }\n :host .noScrollbar::-webkit-scrollbar {\n display: none;\n -webkit-appearance: none;\n }\n :host .wrapper {\n position: relative;\n overflow: visible;\n z-index: 2;\n }\n :host .canvases {\n position: relative;\n height: ${this.options.height}px;\n }\n :host canvas {\n display: block;\n position: absolute;\n top: 0;\n image-rendering: pixelated;\n height: ${this.options.height}px;\n }\n :host .progress {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n width: 0;\n height: 100%;\n overflow: hidden;\n }\n :host .cursor {\n pointer-events: none;\n position: absolute;\n z-index: 5;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n width: ${this.options.cursorWidth}px;\n background-color: ${this.options.cursorColor||this.options.progressColor};\n }\n </style>\n\n <div class="scroll" part="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress"></div>\n <div class="cursor" part="cursor"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){this.options=t,this.reRender()}getWrapper(){return this.wrapper}getScroll(){return this.scrollContainer.scrollLeft}destroy(){this.container.remove(),this.resizeObserver?.disconnect()}delay(t,e=10){return this.timeout&&clearTimeout(this.timeout),new Promise((i=>{this.timeout=setTimeout((()=>{i(t())}),e)}))}async renderPeaks(t,e,i,s){const n=null==this.options.barWidth||isNaN(this.options.barWidth)?1:this.options.barWidth*s,r=null==this.options.barGap||isNaN(this.options.barGap)?this.options.barWidth?n/2:0:this.options.barGap*s,o=this.options.barRadius||0,h=this.options.barHeight||1,d=t.getChannelData(0),l=d.length,u=Math.floor(e/(n+r))/l,c=i/2,p=1===t.numberOfChannels,m=p?d:t.getChannelData(1),g=p&&m.some((t=>t<0)),f=(t,i)=>{let a=0,p=0,f=0;const v=document.createElement("canvas");v.width=Math.round(e*(i-t)/l),v.height=this.options.height,v.style.width=`${Math.floor(v.width/s)}px`,v.style.height=`${this.options.height}px`,v.style.left=`${Math.floor(t*e/s/l)}px`,this.canvasWrapper.appendChild(v);const y=v.getContext("2d",{desynchronized:!0});y.beginPath(),y.fillStyle=this.options.waveColor??"",y.roundRect||(y.roundRect=y.fillRect);for(let e=t;e<i;e++){const i=Math.round((e-t)*u);if(i>a){const t=Math.round(p*c*h),e=Math.round(f*c*h);y.roundRect(a*(n+r),c-t,n,t+(e||1),o),a=i,p=0,f=0}const s=g?d[e]:Math.abs(d[e]),l=g?m[e]:Math.abs(m[e]);s>p&&(p=s),(g?l<-f:l>f)&&(f=l<0?-l:l)}y.fill(),y.closePath();const b=v.cloneNode();this.progressWrapper.appendChild(b);const w=b.getContext("2d",{desynchronized:!0});v.width>0&&v.height>0&&w.drawImage(v,0,0),w.globalCompositeOperation="source-in",w.fillStyle=this.options.progressColor??"",w.fillRect(0,0,v.width,v.height)};this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="";const{scrollLeft:v,scrollWidth:y,clientWidth:b}=this.scrollContainer,w=l/y;let E=Math.min(a.MAX_CANVAS_WIDTH,b);E-=E%((n+r)/s);const x=Math.floor(Math.abs(v)*w),C=Math.ceil(x+E*w);f(x,C);const S=C-x;for(let t=C;t<l;t+=S)await this.delay((()=>{f(t,Math.min(l,t+S))}));for(let t=x-1;t>=0;t-=S)await this.delay((()=>{f(Math.max(0,t-S),t)}))}render(t){const e=window.devicePixelRatio||1,i=this.scrollContainer.clientWidth,s=Math.ceil(t.duration*(this.options.minPxPerSec||0));this.isScrolling=s>i;const n=this.options.fillParent&&!this.isScrolling,r=(n?i:s)*e,{height:o}=this.options;this.wrapper.style.width=n?"100%":`${s}px`,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.cursor.style.backgroundColor=`${this.options.cursorColor||this.options.progressColor}`,this.cursor.style.width=`${this.options.cursorWidth}px`,this.canvasWrapper.style.height=`${this.options.height}px`,this.renderPeaks(t,r,o,e),this.audioData=t,this.emit("render")}reRender(){if(!this.audioData)return;const t=this.progressWrapper.clientWidth;this.render(this.audioData);const e=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=e-t}zoom(t){this.options.minPxPerSec=t,this.reRender()}scrollIntoView(t,e=!1){const{clientWidth:i,scrollLeft:s,scrollWidth:n}=this.scrollContainer,r=n*t,o=i/2;if(r>s+(e&&this.options.autoCenter&&!this.isDragging?o:i)||r<s)if(this.options.autoCenter&&!this.isDragging){const t=o/20;r-(s+o)>=t&&r<s+i?this.scrollContainer.scrollLeft+=t:this.scrollContainer.scrollLeft=r-o}else if(this.isDragging){const t=10;this.scrollContainer.scrollLeft=r<s?r-t:r-i+t}else this.scrollContainer.scrollLeft=r;{const{scrollLeft:t}=this.scrollContainer,e=t/n,s=(t+i)/n;this.emit("scroll",e,s)}}renderProgress(t,e){isNaN(t)||(this.progressWrapper.style.width=100*t+"%",this.cursor.style.left=100*t+"%",this.cursor.style.marginLeft=100===Math.round(100*t)?`-${this.options.cursorWidth}px`:"",this.isScrolling&&this.options.autoScroll&&this.scrollIntoView(t,e))}}a.MAX_CANVAS_WIDTH=4e3;const h=a;class d extends n.Z{constructor(){super(...arguments),this.unsubscribe=()=>{}}start(){this.unsubscribe=this.on("tick",(()=>{requestAnimationFrame((()=>{this.emit("tick")}))})),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}}const l=d,u={height:128,waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoScroll:!0,autoCenter:!0,sampleRate:8e3};class c extends o{static create(t){return new c(t)}constructor(t){super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.subscriptions=[],this.options=Object.assign({},u,t),this.timer=new l,this.renderer=new h(this.options.container,this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initPlugins();const e=this.options.url||this.options.media?.currentSrc||this.options.media?.src;e&&this.load(e,this.options.peaks,this.options.duration)}setOptions(t){this.options={...this.options,...t},this.renderer.setOptions(this.options),t.audioRate&&this.setPlaybackRate(t.audioRate)}initPlayerEvents(){this.subscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),this.isPlaying()),this.emit("timeupdate",t)})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop()})),this.onMediaEvent("ended",(()=>{this.emit("finish")})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",this.getCurrentTime())})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(t=>{this.options.interact&&(this.seekTo(t),this.emit("interaction"),this.emit("click",t))})),this.renderer.on("scroll",((t,e)=>{const i=this.getDuration();this.emit("scroll",t*i,e*i)})),this.renderer.on("render",(()=>{this.emit("redraw")})));{let t;this.subscriptions.push(this.renderer.on("drag",(e=>{this.options.interact&&(this.renderer.renderProgress(e),clearTimeout(t),t=setTimeout((()=>{this.seekTo(e)}),this.isPlaying()?0:200),this.emit("interaction"),this.emit("drag",e))})))}}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),!0),this.emit("timeupdate",t),this.emit("audioprocess",t)})))}initPlugins(){this.options.plugins?.length&&this.options.plugins.forEach((t=>{this.registerPlugin(t)}))}registerPlugin(t){return t.init(this),this.plugins.push(t),t}getWrapper(){return this.renderer.getWrapper()}getScroll(){return this.renderer.getScroll()}getActivePlugins(){return this.plugins}async load(i,s,n){if(this.decodedData=null,this.emit("load",i),s)this.setSrc(i),n||(n=await new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getMediaElement().duration)))}))||0),this.decodedData=t.createBuffer(s,n);else{const s=await e(i);this.setSrc(i,s),this.decodedData=await t.decode(s,this.options.sampleRate)}this.emit("decode",this.getDuration()),this.emit("ready",this.getDuration()),this.renderer.render(this.decodedData)}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",t)}getDecodedData(){return this.decodedData}getDuration(){const t=super.getDuration();return t>0&&t<1/0?t:this.decodedData?.duration||0}toggleInteraction(t){this.options.interact=t}seekTo(t){const e=this.getDuration()*t;this.setTime(e)}playPause(){return this.isPlaying()?(this.pause(),Promise.resolve()):this.play()}stop(){this.pause(),this.setTime(0)}skip(t){this.setTime(this.getCurrentTime()+t)}empty(){this.load("",[[0]],.001)}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.plugins.forEach((t=>t.destroy())),this.timer.destroy(),this.renderer.destroy(),super.destroy()}}const p=c;var m=i(76),g=i(954),f=i(919);class v extends n.Z{static create(t,e){return new v(t,e)}constructor(t,e){super(),this.audios=[],this.wavesurfers=[],this.durations=[],this.currentTime=0,this.maxDuration=0,this.isDragging=!1,this.frameRequest=null,this.timer=null,this.subscriptions=[],this.timeline=null,this.tracks=t.map((t=>({...t,startPosition:t.startPosition||0,peaks:t.peaks||(t.url?void 0:[new Float32Array])}))),this.options=e,this.rendering=function(t,e){let i=0,s=[],n=0;const r=document.createElement("div");r.setAttribute("style","width: 100%; overflow-x: scroll; overflow-y: hidden; user-select: none;");const o=document.createElement("div");o.style.position="relative",r.appendChild(o),e.container.appendChild(r);const a=document.createElement("div");a.setAttribute("style","height: 100%; position: absolute; z-index: 10; top: 0; left: 0"),a.style.backgroundColor=e.cursorColor||"#000",a.style.width=`${e.cursorWidth??1}px`,o.appendChild(a);const{clientWidth:h}=o,d=t.map(((t,i)=>{const s=document.createElement("div");if(s.style.position="relative",e.trackBorderColor&&i>0){const t=document.createElement("div");t.setAttribute("style",`width: 100%; height: 2px; background-color: ${e.trackBorderColor}`),o.appendChild(t)}if(e.trackBackground&&t.url&&(s.style.background=e.trackBackground),!t.url){const t=document.createElement("div");t.setAttribute("style",`position: absolute; z-index: 10; left: 10px; top: 10px; right: 10px; bottom: 10px; border: 2px dashed ${e.trackBorderColor};`),t.addEventListener("dragover",(i=>{i.preventDefault(),t.style.background=e.trackBackground||""})),t.addEventListener("dragleave",(e=>{e.preventDefault(),t.style.background=""})),t.addEventListener("drop",(e=>{e.preventDefault(),t.style.background=""})),s.appendChild(t)}return o.appendChild(s),s})),l=()=>{d.forEach(((e,n)=>{const r=t[n].startPosition*i;s[n]&&(e.style.width=s[n]*i+"px"),e.style.transform=`translateX(${r}px)`}))};return{containers:d,setContainerOffsets:l,setMainWidth:(t,r)=>{s=t,i=Math.max(e.minPxPerSec||0,h/r),n=i*r,o.style.width=`${n}px`,l()},updateCursor:(t,e)=>{a.style.left=`${Math.min(100,100*t)}%`;const{clientWidth:i,scrollLeft:s}=r,o=i/2,h=t*n;(h>s+(e?o:i)||h<s)&&(r.scrollLeft=h-o)},addClickHandler:t=>{o.addEventListener("click",(e=>{const i=o.getBoundingClientRect(),s=(e.clientX-i.left)/o.offsetWidth;t(s)}))},destroy:()=>{r.remove()},addDropHandler:e=>{t.forEach(((t,i)=>{if(!t.url){const s=d[i].querySelector("div");s?.addEventListener("drop",(i=>{i.preventDefault(),e(t.id)}))}}))}}}(this.tracks,this.options),this.rendering.addDropHandler((t=>{this.emit("drop",{id:t})})),this.initAllAudios().then((t=>{this.initDurations(t),this.initAllWavesurfers(),this.rendering.containers.forEach(((t,i)=>{const s=y(t,(t=>this.onDrag(i,t)),e.rightButtonDrag);this.wavesurfers[i].once("destroy",(()=>s?.destroy()))})),this.rendering.addClickHandler((t=>{this.isDragging||this.seekTo(t)})),this.emit("canplay")}))}initDurations(t){this.durations=t,this.maxDuration=this.tracks.reduce(((e,i,s)=>Math.max(e,i.startPosition+t[s])),0),this.rendering.setMainWidth(t,this.maxDuration)}initAudio(t){const e=new Audio(t.url);return new Promise((t=>{if(!e.src)return t(e);e.addEventListener("loadedmetadata",(()=>t(e)),{once:!0})}))}async initAllAudios(){return this.audios=await Promise.all(this.tracks.map((t=>this.initAudio(t)))),this.audios.map((t=>t.src?t.duration:0))}initWavesurfer(t,e){const i=this.rendering.containers[e],s=p.create({...t.options,container:i,minPxPerSec:0,media:this.audios[e],peaks:t.peaks,cursorColor:"transparent",cursorWidth:0,interact:!1,hideScrollbar:!0}),n=m.default.create();s.registerPlugin(n),this.subscriptions.push(s.once("decode",(()=>{if(null!=t.startCue||null!=t.endCue){const{startCue:i=0,endCue:s=this.durations[e]}=t,r=n.addRegion({start:0,end:i,color:"rgba(0, 0, 0, 0.7)",drag:!1}),o=n.addRegion({start:s,end:s+this.durations[e],color:"rgba(0, 0, 0, 0.7)",drag:!1});r.element.firstElementChild?.remove(),o.element.lastChild?.remove(),this.subscriptions.push(r.on("update-end",(()=>{t.startCue=r.end,this.emit("start-cue-change",{id:t.id,startCue:t.startCue})})),o.on("update-end",(()=>{t.endCue=o.start,this.emit("end-cue-change",{id:t.id,endCue:t.endCue})})))}if(t.intro){const e=n.addRegion({start:0,end:t.intro.endTime,content:t.intro.label,color:this.options.trackBackground,drag:!1});e.element.querySelector('[data-resize="left"]')?.remove(),e.element.parentElement.style.mixBlendMode="plus-lighter",t.intro.color&&(e.element.querySelector('[data-resize="right"]').style.borderColor=t.intro.color),this.subscriptions.push(e.on("update-end",(()=>{this.emit("intro-end-change",{id:t.id,endTime:e.end})})))}t.markers&&t.markers.forEach((t=>{n.addRegion({start:t.time,content:t.label,color:t.color,resize:!1})}))})));const r=s.registerPlugin(f.default.create({...this.options.envelopeOptions,fadeInStart:t.startCue,fadeInEnd:t.fadeInEnd,fadeOutStart:t.fadeOutStart,fadeOutEnd:t.endCue,volume:t.volume}));return this.subscriptions.push(r.on("volume-change",(e=>{this.setIsDragging(),this.emit("volume-change",{id:t.id,volume:e})})),r.on("fade-in-change",(e=>{this.setIsDragging(),this.emit("fade-in-change",{id:t.id,fadeInEnd:e})})),r.on("fade-out-change",(e=>{this.setIsDragging(),this.emit("fade-out-change",{id:t.id,fadeOutStart:e})})),this.on("start-cue-change",(({id:e,startCue:i})=>{e===t.id&&r.setStartTime(i)})),this.on("end-cue-change",(({id:e,endCue:i})=>{e===t.id&&r.setEndTime(i)}))),s}initAllWavesurfers(){const t=this.tracks.map(((t,e)=>this.initWavesurfer(t,e)));this.wavesurfers=t,this.initTimeline()}initTimeline(){this.timeline&&this.timeline.destroy(),this.timeline=this.wavesurfers[0].registerPlugin(g.default.create({duration:this.maxDuration,container:this.rendering.containers[0].parentElement}))}updatePosition(t,e=!1){const i=!this.isPlaying();t!==this.currentTime&&(this.currentTime=t,this.rendering.updateCursor(t/this.maxDuration,e)),this.tracks.forEach(((e,s)=>{const n=this.audios[s],r=this.durations[s],o=t-e.startPosition;Math.abs(n.currentTime-o)>.3&&(n.currentTime=o),i||o<0||o>r?!n.paused&&n.pause():i||n.paused&&n.play();const a=o>=(e.startCue||0)&&o<(e.endCue||1/0)?1:0;a!==n.volume&&(n.volume=a)}))}setIsDragging(){this.isDragging=!0,this.timer&&clearTimeout(this.timer),this.timer=setTimeout((()=>this.isDragging=!1),300)}onDrag(t,e){this.setIsDragging();const i=this.tracks[t];if(!i.draggable)return;const s=i.startPosition+e*this.maxDuration,n=this.tracks.findIndex((t=>t.url&&!t.draggable)),r=this.tracks[n],o=(r?r.startPosition:0)-this.durations[t],a=r?r.startPosition+this.durations[n]:this.maxDuration;s>=o&&s<=a&&(i.startPosition=s,this.initDurations(this.durations),this.rendering.setContainerOffsets(),this.updatePosition(this.currentTime),this.emit("start-position-change",{id:i.id,startPosition:s}))}findCurrentTracks(){const t=[];if(this.tracks.forEach(((e,i)=>{e.url&&this.currentTime>=e.startPosition&&this.currentTime<e.startPosition+this.durations[i]&&t.push(i)})),0===t.length){const e=Math.min(...this.tracks.filter((t=>t.url)).map((t=>t.startPosition)));t.push(this.tracks.findIndex((t=>t.startPosition===e)))}return t}startSync(){const t=()=>{const e=this.audios.reduce(((t,e,i)=>(e.paused||(t=Math.max(t,e.currentTime+this.tracks[i].startPosition)),t)),this.currentTime);e>this.currentTime&&this.updatePosition(e,!0),this.frameRequest=requestAnimationFrame(t)};t()}play(){this.startSync(),this.findCurrentTracks().forEach((t=>{this.audios[t]?.play()}))}pause(){this.audios.forEach((t=>t.pause()))}isPlaying(){return this.audios.some((t=>!t.paused))}getCurrentTime(){return this.currentTime}seekTo(t){const e=this.isPlaying();this.updatePosition(t*this.maxDuration),e&&this.play()}setTime(t){const e=this.isPlaying();this.updatePosition(t),e&&this.play()}zoom(t){this.options.minPxPerSec=t,this.wavesurfers.forEach(((e,i)=>this.tracks[i].url&&e.zoom(t))),this.rendering.setMainWidth(this.durations,this.maxDuration),this.rendering.setContainerOffsets()}addTrack(t){const e=this.tracks.findIndex((e=>e.id===t.id));-1!==e&&(this.tracks[e]=t,this.initAudio(t).then((i=>{this.audios[e]=i,this.durations[e]=i.duration,this.initDurations(this.durations);const s=this.rendering.containers[e];s.innerHTML="",this.wavesurfers[e].destroy(),this.wavesurfers[e]=this.initWavesurfer(t,e);const n=y(s,(t=>this.onDrag(e,t)),this.options.rightButtonDrag);this.wavesurfers[e].once("destroy",(()=>n?.destroy())),this.initTimeline(),this.emit("canplay")})))}destroy(){this.frameRequest&&cancelAnimationFrame(this.frameRequest),this.rendering.destroy(),this.audios.forEach((t=>{t.pause(),t.src=""})),this.wavesurfers.forEach((t=>{t.destroy()}))}setSinkId(t){return Promise.all(this.wavesurfers.map((e=>e.setSinkId(t))))}}function y(t,e,i=!1){const s=t.parentElement;if(!s)return;let n=null;t.addEventListener("contextmenu",(t=>{i&&t.preventDefault()})),t.addEventListener("mousedown",(e=>{if(i&&2!==e.button)return;const r=s.getBoundingClientRect();n=e.clientX-r.left,t.style.cursor="grabbing"}));const r=e=>{null!=n&&(e.stopPropagation(),n=null,t.style.cursor="")},o=t=>{if(null==n)return;const i=s.getBoundingClientRect(),r=t.clientX-i.left,o=r-n;(o>1||o<-1)&&(n=r,e(o/s.offsetWidth))};return document.body.addEventListener("mouseup",r),document.body.addEventListener("mousemove",o),{destroy:()=>{document.body.removeEventListener("mouseup",r),document.body.removeEventListener("mousemove",o)}}}const b=v})(),s.default})()));
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Multitrack=e():t.Multitrack=e()}(WaveSurfer,(()=>(()=>{"use strict";var t={284:(t,e,i)=>{i.d(e,{Z:()=>r});var s=i(139);class n extends s.Z{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.subscriptions.forEach((t=>t()))}}const r=n},139:(t,e,i)=>{i.d(e,{Z:()=>s});const s=class{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),s=this.on(t,(()=>{i(),s()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}},919:(t,e,i)=>{i.d(e,{default:()=>h});var s=i(284),n=i(139);const r={fadeInStart:0,fadeOutEnd:0,fadeInEnd:0,fadeOutStart:0,lineWidth:4,lineColor:"rgba(0, 0, 255, 0.5)",dragPointSize:10,dragPointFill:"rgba(255, 255, 255, 0.8)",dragPointStroke:"rgba(255, 255, 255, 0.8)"};class o extends n.Z{constructor(t,e){super(),this.top=0,this.padding=t.dragPointSize/2+1;const i=document.createElementNS("http://www.w3.org/2000/svg","svg");i.setAttribute("width","100%"),i.setAttribute("height","100%"),i.setAttribute("viewBox","0 0 0 0"),i.setAttribute("preserveAspectRatio","none"),i.setAttribute("style","position: absolute; left: 0; top: 0; z-index: 4; pointer-events: none;"),i.setAttribute("part","envelope"),this.svg=i;const s=document.createElementNS("http://www.w3.org/2000/svg","polyline");s.setAttribute("points","0,0 0,0 0,0 0,0"),s.setAttribute("stroke",t.lineColor),s.setAttribute("stroke-width",t.lineWidth),s.setAttribute("fill","none"),s.setAttribute("style","pointer-events: none;"),s.setAttribute("part","polyline"),i.appendChild(s);const n=document.createElementNS("http://www.w3.org/2000/svg","line");n.setAttribute("stroke","transparent"),n.setAttribute("stroke-width",(3*t.lineWidth).toString()),n.setAttribute("style","cursor: ns-resize; pointer-events: all;"),n.setAttribute("part","line"),i.appendChild(n),[0,1].forEach((()=>{const e=document.createElementNS("http://www.w3.org/2000/svg","circle");e.setAttribute("r",(t.dragPointSize/2).toString()),e.setAttribute("fill",t.dragPointFill),e.setAttribute("stroke",t.dragPointStroke||t.dragPointFill),e.setAttribute("stroke-width","2"),e.setAttribute("style","cursor: ew-resize; pointer-events: all;"),e.setAttribute("part","circle"),i.appendChild(e)})),e.appendChild(i);{const t=t=>{const e=this.top+t,{height:s}=i.viewBox.baseVal;if(e<-.5||e>s)return;const n=Math.min(1,Math.max(0,(s-e)/s));this.emit("line-move",n)},e=(t,e)=>{const n=s.points.getItem(t).x+e,{width:r}=i.viewBox.baseVal;this.emit("point-move",t,n/r)};this.makeDraggable(n,((e,i)=>t(i)));const r=this.svg.querySelectorAll("circle");Array.from(r).forEach(((t,i)=>{this.makeDraggable(t,(t=>e(i+1,t)))}))}}makeDraggable(t,e){t.addEventListener("click",(t=>{t.preventDefault(),t.stopPropagation()})),t.addEventListener("mousedown",(t=>{t.preventDefault(),t.stopPropagation();let i=t.clientX,s=t.clientY;const n=t=>{const n=t.clientX-i,r=t.clientY-s;i=t.clientX,s=t.clientY,e(n,r)},r=()=>{document.removeEventListener("mousemove",n),document.removeEventListener("mouseup",r)};document.addEventListener("mousemove",n),document.addEventListener("mouseup",r)}))}update({x1:t,x2:e,x3:i,x4:s,y:n}){const r=this.svg.clientWidth,o=this.svg.clientHeight;this.top=o-n*o;const a=Math.max(this.padding,Math.min(this.top,o-this.padding));this.svg.setAttribute("viewBox",`0 0 ${r} ${o}`);const h=this.svg.querySelector("polyline"),{points:d}=h;d.getItem(0).x=t*r,d.getItem(0).y=o,d.getItem(1).x=e*r,d.getItem(1).y=a,d.getItem(2).x=i*r,d.getItem(2).y=a,d.getItem(3).x=s*r,d.getItem(3).y=o;const l=this.svg.querySelector("line");l.setAttribute("x1",d.getItem(1).x.toString()),l.setAttribute("x2",d.getItem(2).x.toString()),l.setAttribute("y1",a.toString()),l.setAttribute("y2",a.toString());const u=this.svg.querySelectorAll("circle");Array.from(u).forEach(((t,e)=>{const i=d.getItem(e+1);t.setAttribute("cx",i.x.toString()),t.setAttribute("cy",i.y.toString())}))}destroy(){this.svg.remove()}}class a extends s.Z{constructor(t){super(t),this.polyline=null,this.audioContext=null,this.gainNode=null,this.volume=1,this.isFadingIn=!1,this.isFadingOut=!1,this.naturalVolumeExponent=1.5,this.options=Object.assign({},r,t),this.options.lineColor=this.options.lineColor||r.lineColor,this.options.dragPointFill=this.options.dragPointFill||r.dragPointFill,this.options.dragPointStroke=this.options.dragPointStroke||r.dragPointStroke,this.volume=this.options.volume??1}static create(t){return new a(t)}destroy(){this.polyline?.destroy(),super.destroy()}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.initWebAudio(),this.initSvg(),this.initFadeEffects(),this.subscriptions.push(this.wavesurfer.on("redraw",(()=>{const t=this.wavesurfer?.getDuration();t&&(this.options.fadeInStart=this.options.fadeInStart||0,this.options.fadeOutEnd=this.options.fadeOutEnd||t,this.options.fadeInEnd=this.options.fadeInEnd||this.options.fadeInStart,this.options.fadeOutStart=this.options.fadeOutStart||this.options.fadeOutEnd,this.renderPolyline())})))}initSvg(){if(!this.wavesurfer)return;const t=this.wavesurfer.getWrapper();this.polyline=new o(this.options,t),this.subscriptions.push(this.polyline.on("line-move",(t=>{this.setVolume(this.naturalVolume(t))})),this.polyline.on("point-move",((t,e)=>{const i=e*(this.wavesurfer?.getDuration()||0);if(1===t){if(i<this.options.fadeInStart||i>this.options.fadeOutStart)return;this.options.fadeInEnd=i,this.emit("fade-in-change",i)}else if(2===t){if(i>this.options.fadeOutEnd||i<this.options.fadeInEnd)return;this.options.fadeOutStart=i,this.emit("fade-out-change",i)}this.renderPolyline()})))}renderPolyline(){if(!this.polyline||!this.wavesurfer)return;const t=this.wavesurfer.getDuration();t&&this.polyline.update({x1:this.options.fadeInStart/t,x2:this.options.fadeInEnd/t,x3:this.options.fadeOutStart/t,x4:this.options.fadeOutEnd/t,y:this.invertNaturalVolume(this.volume)})}initWebAudio(){const t=this.wavesurfer?.getMediaElement();if(!t)return null;this.volume=this.options.volume??t.volume;const e=new window.AudioContext;this.gainNode=e.createGain(),this.setGainValue(),e.createMediaElementSource(t).connect(this.gainNode),this.gainNode.connect(e.destination),this.audioContext=e}invertNaturalVolume(t){return Math.pow((t-1e-4)/.9999,1/this.naturalVolumeExponent)}naturalVolume(t){return 1e-4+.9999*Math.pow(t,this.naturalVolumeExponent)}setGainValue(){this.gainNode&&(this.gainNode.gain.value=this.volume)}initFadeEffects(){if(!this.audioContext||!this.wavesurfer)return;const t=this.wavesurfer.on("timeupdate",(t=>{if(!this.audioContext||!this.gainNode)return;if(!this.wavesurfer?.isPlaying())return;if("suspended"===this.audioContext.state&&this.audioContext.resume(),!this.isFadingIn&&t>=this.options.fadeInStart&&t<=this.options.fadeInEnd)return this.isFadingIn=!0,this.gainNode.gain.setValueAtTime(0,this.audioContext.currentTime),void this.gainNode.gain.linearRampToValueAtTime(this.volume,this.audioContext.currentTime+(this.options.fadeInEnd-t));if(!this.isFadingOut&&t>=this.options.fadeOutStart&&t<=this.options.fadeOutEnd)return this.isFadingOut=!0,this.gainNode.gain.setValueAtTime(this.volume,this.audioContext.currentTime),void this.gainNode.gain.linearRampToValueAtTime(0,this.audioContext.currentTime+(this.options.fadeOutEnd-t));let e=!1;this.isFadingIn&&(t<this.options.fadeInStart||t>this.options.fadeInEnd)&&(this.isFadingIn=!1,e=!0),this.isFadingOut&&(t<this.options.fadeOutStart||t>=this.options.fadeOutEnd)&&(this.isFadingOut=!1,e=!0),e&&(this.gainNode.gain.cancelScheduledValues(this.audioContext.currentTime),this.setGainValue())}));this.subscriptions.push(t)}getCurrentVolume(){return this.gainNode?this.gainNode.gain.value:this.volume}setStartTime(t,e=!1){if(e){const e=this.options.fadeInEnd-this.options.fadeInStart;this.options.fadeInEnd=t+e}this.options.fadeInStart=t,this.renderPolyline()}setEndTime(t,e=!1){if(e){const e=this.options.fadeOutEnd-this.options.fadeOutStart;this.options.fadeOutStart=t-e}this.options.fadeOutEnd=t,this.renderPolyline()}setVolume(t){this.volume=t,this.setGainValue(),this.renderPolyline(),this.emit("volume-change",t)}}const h=a},76:(t,e,i)=>{i.d(e,{default:()=>h});var s=i(284),n=i(139);function r(t,e,i,s,n=5){if(!t)return()=>{};let r=!1;const o=t=>{r&&t.stopPropagation()},a=t=>{t.stopPropagation();let o=t.clientX,a=0;e(o);const h=t=>{const e=t.clientX,s=e-o;a+=s,o=e,(r||Math.abs(a)>=n)&&(i(r?s:a),r=!0)},d=()=>{r&&(s(),setTimeout((()=>r=!1),10)),document.removeEventListener("mousemove",h),document.removeEventListener("mouseup",d)};document.addEventListener("mousemove",h),document.addEventListener("mouseup",d)};return t.addEventListener("click",o),t.addEventListener("mousedown",a),()=>{t.removeEventListener("click",o),t.removeEventListener("mousedown",a)}}class o extends n.Z{constructor(t,e){super(),this.totalDuration=e,this.id=t.id||`region-${Math.random().toString(32).slice(2)}`,this.start=t.start,this.end=t.end??t.start,this.drag=t.drag??!0,this.resize=t.resize??!0,this.color=t.color??"rgba(0, 0, 0, 0.1)",this.element=this.initElement(t.content),this.renderPosition(),this.initMouseEvents()}initElement(t){const e=document.createElement("div"),i=this.start===this.end;if(e.setAttribute("part",`${i?"marker":"region"} ${this.id}`),e.setAttribute("style",`\n position: absolute;\n height: 100%;\n background-color: ${i?"none":this.color};\n border-left: ${i?"2px solid "+this.color:"none"};\n border-radius: 2px;\n box-sizing: border-box;\n transition: background-color 0.2s ease;\n cursor: ${this.drag?"grab":"default"};\n pointer-events: all;\n padding: 0.2em ${i?.2:.4}em;\n pointer-events: all;\n `),t&&("string"==typeof t?(this.content=document.createElement("div"),this.content.textContent=t):this.content=t,this.content.setAttribute("part","region-content"),e.appendChild(this.content)),!i){const t=document.createElement("div");t.setAttribute("data-resize","left"),t.setAttribute("style",`\n position: absolute;\n z-index: 2;\n width: 6px;\n height: 100%;\n top: 0;\n left: 0;\n border-left: 2px solid rgba(0, 0, 0, 0.5);\n border-radius: 2px 0 0 2px;\n cursor: ${this.resize?"ew-resize":"default"};\n word-break: keep-all;\n `),t.setAttribute("part","region-handle region-handle-left");const i=t.cloneNode();i.setAttribute("data-resize","right"),i.style.left="",i.style.right="0",i.style.borderRight=i.style.borderLeft,i.style.borderLeft="",i.style.borderRadius="0 2px 2px 0",i.setAttribute("part","region-handle region-handle-right"),e.appendChild(t),e.appendChild(i)}return e}renderPosition(){const t=this.start/this.totalDuration,e=this.end/this.totalDuration;this.element.style.left=100*t+"%",this.element.style.width=100*(e-t)+"%"}initMouseEvents(){const{element:t}=this;t.addEventListener("click",(t=>this.emit("click",t))),t.addEventListener("mouseenter",(t=>this.emit("over",t))),t.addEventListener("mouseleave",(t=>this.emit("leave",t))),t.addEventListener("dblclick",(t=>this.emit("dblclick",t))),r(t,(()=>this.onStartMoving()),(t=>this.onMove(t)),(()=>this.onEndMoving())),r(t.querySelector('[data-resize="left"]'),(()=>null),(t=>this.onResize(t,"start")),(()=>this.onEndResizing()),1),r(t.querySelector('[data-resize="right"]'),(()=>null),(t=>this.onResize(t,"end")),(()=>this.onEndResizing()),1)}onStartMoving(){this.drag&&(this.element.style.cursor="grabbing")}onEndMoving(){this.drag&&(this.element.style.cursor="grab",this.emit("update-end"))}onUpdate(t,e){if(!this.element.parentElement)return;const i=t/this.element.parentElement.clientWidth*this.totalDuration;e.forEach((t=>{this[t]+=i,"start"===t?this.start=Math.max(0,Math.min(this.start,this.end)):this.end=Math.max(this.start,Math.min(this.end,this.totalDuration))})),this.renderPosition(),this.emit("update")}onMove(t){this.drag&&this.onUpdate(t,["start","end"])}onResize(t,e){this.resize&&this.onUpdate(t,[e])}onEndResizing(){this.resize&&this.emit("update-end")}_setTotalDuration(t){this.totalDuration=t,this.renderPosition()}play(){this.emit("play")}setOptions(t){t.color&&(this.color=t.color,this.element.style.backgroundColor=this.color),void 0!==t.drag&&(this.drag=t.drag,this.element.style.cursor=this.drag?"grab":"default"),void 0!==t.resize&&(this.resize=t.resize,this.element.querySelectorAll("[data-resize]").forEach((t=>{t.style.cursor=this.resize?"ew-resize":"default"}))),void 0===t.start&&void 0===t.end||(this.start=t.start??this.start,this.end=t.end??this.end,this.renderPosition())}remove(){this.emit("remove"),this.element.remove(),this.element=null}}class a extends s.Z{constructor(t){super(t),this.regions=[],this.regionsContainer=this.initRegionsContainer()}static create(t){return new a(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.wavesurfer.getWrapper().appendChild(this.regionsContainer)}initRegionsContainer(){const t=document.createElement("div");return t.setAttribute("style","\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 3;\n pointer-events: none;\n "),t}getRegions(){return this.regions}avoidOverlapping(t){if(!t.content)return;const e=t.content,i=e.getBoundingClientRect().left,s=t.element.scrollWidth,n=this.regions.filter((e=>{if(e===t||!e.content)return!1;const n=e.content.getBoundingClientRect().left,r=e.element.scrollWidth;return i<n+r&&n<i+s})).map((t=>t.content?.getBoundingClientRect().height||0)).reduce(((t,e)=>t+e),0);e.style.marginTop=`${n}px`}saveRegion(t){this.regionsContainer.appendChild(t.element),this.avoidOverlapping(t),this.regions.push(t),this.emit("region-created",t);const e=[t.on("update-end",(()=>{this.avoidOverlapping(t),this.emit("region-updated",t)})),t.on("play",(()=>{this.wavesurfer?.play(),this.wavesurfer?.setTime(t.start)})),t.on("click",(e=>{this.emit("region-clicked",t,e)})),t.once("remove",(()=>{e.forEach((t=>t())),this.regions=this.regions.filter((e=>e!==t))}))];this.subscriptions.push(...e)}addRegion(t){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const e=this.wavesurfer.getDuration(),i=new o(t,e);return e?this.saveRegion(i):this.subscriptions.push(this.wavesurfer.once("ready",(t=>{i._setTotalDuration(t),this.saveRegion(i)}))),i}enableDragSelection(t){const e=this.wavesurfer?.getWrapper()?.querySelector("div");if(!e)return()=>{};let i=null,s=0,n=0;return r(e,(t=>s=t),(r=>{if(this.wavesurfer){if(!i){const n=this.wavesurfer.getDuration(),a=e.getBoundingClientRect();let h=(s-a.left)/a.width*n,d=(s+r-a.left)/a.width*n;h>d&&([h,d]=[d,h]),i=new o({...t,start:h,end:d},n),this.regionsContainer.appendChild(i.element)}n+=r,i&&i.onUpdate(r,[n>0?"end":"start"])}}),(()=>{if(i&&(this.saveRegion(i),i=null,n=0,this.wavesurfer)){const{interact:t}=this.wavesurfer.options;t&&(this.wavesurfer.toggleInteraction(!1),setTimeout((()=>this.wavesurfer?.toggleInteraction(t)),10))}}))}clearRegions(){this.regions.forEach((t=>t.remove()))}destroy(){this.clearRegions(),super.destroy()}}const h=a},954:(t,e,i)=>{i.d(e,{default:()=>o});var s=i(284);const n={height:20};class r extends s.Z{constructor(t){super(t||{}),this.options=Object.assign({},n,t),this.timelineWrapper=this.initTimelineWrapper()}static create(t){return new r(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const t=this.options.container??this.wavesurfer.getWrapper();this.options.insertPosition?(t.firstElementChild||t).insertAdjacentElement(this.options.insertPosition,this.timelineWrapper):t.appendChild(this.timelineWrapper),this.options.duration?this.initTimeline(this.options.duration):this.subscriptions.push(this.wavesurfer.on("redraw",(()=>{this.initTimeline(this.wavesurfer?.getDuration()||0)})))}destroy(){this.timelineWrapper.remove(),super.destroy()}initTimelineWrapper(){const t=document.createElement("div");return t.setAttribute("part","timeline"),t}formatTime(t){return t/60>1?`${Math.floor(t/60)}:${(t=Math.round(t%60))<10?"0":""}${t}`:""+Math.round(1e3*t)/1e3}defaultTimeInterval(t){return t>=25?1:5*t>=25?5:15*t>=25?15:60*Math.ceil(.5/t)}defaultPrimaryLabelInterval(t){return t>=25?10:5*t>=25?6:4}defaultSecondaryLabelInterval(t){return t>=25?5:2}initTimeline(t){const e=this.timelineWrapper.scrollWidth/t,i=this.options.timeInterval??this.defaultTimeInterval(e),s=this.options.primaryLabelInterval??this.defaultPrimaryLabelInterval(e),n=this.options.secondaryLabelInterval??this.defaultSecondaryLabelInterval(e),r="beforebegin"===this.options.insertPosition,o=document.createElement("div");if(o.setAttribute("style",`\n height: ${this.options.height}px;\n overflow: hidden;\n display: flex;\n justify-content: space-between;\n align-items: ${r?"flex-start":"flex-end"};\n font-size: ${this.options.height/2}px;\n white-space: nowrap;\n `),r){const t="\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 2;\n ";o.setAttribute("style",o.getAttribute("style")+t)}"string"==typeof this.options.style?o.setAttribute("style",o.getAttribute("style")+this.options.style):"object"==typeof this.options.style&&Object.assign(o.style,this.options.style);const a=document.createElement("div");a.setAttribute("style",`\n width: 1px;\n height: 50%;\n display: flex;\n flex-direction: column;\n justify-content: ${r?"flex-start":"flex-end"};\n overflow: visible;\n border-left: 1px solid currentColor;\n opacity: 0.25;\n `);for(let e=0;e<t;e+=i){const t=a.cloneNode(),i=Math.round(100*e)/100%s==0,r=Math.round(100*e)/100%n==0;(i||r)&&(t.style.height="100%",t.style.textIndent="3px",t.textContent=this.formatTime(e),i&&(t.style.opacity="1")),o.appendChild(t)}this.timelineWrapper.innerHTML="",this.timelineWrapper.appendChild(o),this.emit("ready")}}const o=r}},e={};function i(s){var n=e[s];if(void 0!==n)return n.exports;var r=e[s]={exports:{}};return t[s](r,r.exports,i),r.exports}i.d=(t,e)=>{for(var s in e)i.o(e,s)&&!i.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:e[s]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var s={};return(()=>{i.d(s,{default:()=>b});const t={decode:async function(t,e){const i=new AudioContext({sampleRate:e}),s=i.decodeAudioData(t);return s.finally((()=>i.close())),s},createBuffer:function(t,e){return"number"==typeof t[0]&&(t=[t]),function(t){const e=t[0];if(e.some((t=>t>1||t<-1))){const i=e.length;let s=0;for(let t=0;t<i;t++){const i=Math.abs(e[t]);i>s&&(s=i)}for(const e of t)for(let t=0;t<i;t++)e[t]/=s}}(t),{duration:e,length:t[0].length,sampleRate:t[0].length/e,numberOfChannels:t.length,getChannelData:e=>t?.[e],copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}},e=async function(t){return fetch(t).then((t=>t.arrayBuffer()))};var n=i(139);class r extends n.Z{constructor(t){super(),this.isExternalMedia=!1,t.media?(this.media=t.media,this.isExternalMedia=!0):this.media=document.createElement("audio"),t.autoplay&&(this.media.autoplay=!0),null!=t.playbackRate&&(this.media.playbackRate=t.playbackRate)}onMediaEvent(t,e,i){return this.media.addEventListener(t,e,i),()=>this.media.removeEventListener(t,e)}onceMediaEvent(t,e){return this.onMediaEvent(t,e,{once:!0})}revokeSrc(){(this.media.currentSrc||this.media.src||"").startsWith("blob:")&&URL.revokeObjectURL(this.media.currentSrc)}setSrc(t,e){if((this.media.currentSrc||this.media.src||"")===t)return;this.revokeSrc();const i=e?URL.createObjectURL(new Blob([e],{type:"audio/wav"})):t;this.media.src=i}destroy(){this.media.pause(),this.revokeSrc(),this.isExternalMedia||this.media.remove()}play(){return this.media.play()}pause(){this.media.pause()}isPlaying(){return this.media.currentTime>0&&!this.media.paused&&!this.media.ended}setTime(t){this.media.currentTime=t}getDuration(){return this.media.duration}getCurrentTime(){return this.media.currentTime}getVolume(){return this.media.volume}setVolume(t){this.media.volume=t}getMuted(){return this.media.muted}setMuted(t){this.media.muted=t}getPlaybackRate(){return this.media.playbackRate}setPlaybackRate(t,e){null!=e&&(this.media.preservesPitch=e),this.media.playbackRate=t}getMediaElement(){return this.media}setSinkId(t){return this.media.setSinkId(t)}}const o=r;class a extends n.Z{constructor(t){let e;if(super(),this.timeouts=[],this.isScrolling=!1,this.audioData=null,this.resizeObserver=null,this.isDragging=!1,this.options=t,"string"==typeof t.container?e=document.querySelector(t.container):t.container instanceof HTMLElement&&(e=t.container),!e)throw new Error("Container not found");const[i,s]=this.initHtml();e.appendChild(i),this.container=i,this.scrollContainer=s.querySelector(".scroll"),this.wrapper=s.querySelector(".wrapper"),this.canvasWrapper=s.querySelector(".canvases"),this.progressWrapper=s.querySelector(".progress"),this.cursor=s.querySelector(".cursor"),this.initEvents()}initEvents(){this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",i)})),this.initDrag(),this.scrollContainer.addEventListener("scroll",(()=>{const{scrollLeft:t,scrollWidth:e,clientWidth:i}=this.scrollContainer,s=t/e,n=(t+i)/e;this.emit("scroll",s,n)}));const t=this.createDelay(100);this.resizeObserver=new ResizeObserver((()=>{t((()=>this.reRender()))})),this.resizeObserver.observe(this.scrollContainer)}initDrag(){this.wrapper.addEventListener("mousedown",(t=>{const e=t.clientX,i=t=>{if(Math.abs(t.clientX-e)>=5){this.isDragging=!0;const e=this.wrapper.getBoundingClientRect();this.emit("drag",Math.max(0,Math.min(1,(t.clientX-e.left)/e.width)))}},s=()=>{document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",s),this.isDragging=!1};document.addEventListener("mousemove",i),document.addEventListener("mouseup",s)}))}initHtml(){const t=document.createElement("div"),e=t.attachShadow({mode:"open"});return e.innerHTML=`\n <style>\n :host {\n user-select: none;\n }\n :host .scroll {\n overflow-x: auto;\n overflow-y: hidden;\n width: 100%;\n position: relative;\n }\n :host .noScrollbar {\n scrollbar-color: transparent;\n scrollbar-width: none;\n }\n :host .noScrollbar::-webkit-scrollbar {\n display: none;\n -webkit-appearance: none;\n }\n :host .wrapper {\n position: relative;\n overflow: visible;\n z-index: 2;\n }\n :host .canvases {\n min-height: ${this.options.height}px;\n }\n :host .canvases > div {\n position: relative;\n }\n :host canvas {\n display: block;\n position: absolute;\n top: 0;\n image-rendering: pixelated;\n }\n :host .progress {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n width: 0;\n height: 100%;\n overflow: hidden;\n }\n :host .progress > div {\n position: relative;\n }\n :host .cursor {\n pointer-events: none;\n position: absolute;\n z-index: 5;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n }\n </style>\n\n <div class="scroll" part="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress"></div>\n <div class="cursor" part="cursor"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){this.options=t,this.reRender()}getWrapper(){return this.wrapper}getScroll(){return this.scrollContainer.scrollLeft}destroy(){this.container.remove(),this.resizeObserver?.disconnect()}createDelay(t=10){const e={};return this.timeouts.push(e),i=>{e.timeout&&clearTimeout(e.timeout),e.timeout=setTimeout(i,t)}}convertColorValues(t){if(!Array.isArray(t))return t||"";if(t.length<2)return 1===t.length?t[0]:"";const e=document.createElement("canvas"),i=e.getContext("2d").createLinearGradient(0,0,0,e.height),s=1/(t.length-1);return t.forEach(((t,e)=>{const n=e*s;i.addColorStop(n,t)})),i}renderSingleCanvas(t,e,i,s,n,r,o){const a=window.devicePixelRatio||1,h=e.height||0,d=null==e.barWidth||isNaN(e.barWidth)?1:e.barWidth*a,l=null==e.barGap||isNaN(e.barGap)?e.barWidth?d/2:0:e.barGap*a,u=e.barRadius||0,c=e.barHeight||1,p=1===t.length,m=t[0],g=p?m:t[1],f=p&&g.some((t=>t<0)),v=m.length,y=Math.floor(i/(d+l))/v,b=h/2;let w=0,E=0,C=0;const x=document.createElement("canvas");x.width=Math.round(i*(n-s)/v),x.height=h,x.style.width=`${Math.floor(x.width/a)}px`,x.style.height=`${e.height}px`,x.style.left=`${Math.floor(s*i/a/v)}px`,r.appendChild(x);const S=x.getContext("2d",{desynchronized:!0});S.beginPath(),S.fillStyle=this.convertColorValues(e.waveColor),S.roundRect||(S.roundRect=S.fillRect);for(let t=s;t<n;t++){const e=Math.round((t-s)*y);if(e>w){const t=Math.round(E*b*c),i=Math.round(C*b*c);S.roundRect(w*(d+l),b-t,d,t+(i||1),u),w=e,E=0,C=0}const i=f?m[t]:Math.abs(m[t]),n=f?g[t]:Math.abs(g[t]);i>E&&(E=i),(f?n<-C:n>C)&&(C=n<0?-n:n)}S.fill(),S.closePath();const k=x.cloneNode();o.appendChild(k);const P=k.getContext("2d",{desynchronized:!0});x.width>0&&x.height>0&&P.drawImage(x,0,0),P.globalCompositeOperation="source-in",P.fillStyle=this.convertColorValues(e.progressColor),P.fillRect(0,0,x.width,x.height)}renderWaveform(t,e,i){const s=document.createElement("div");s.style.height=`${e.height}px`,this.canvasWrapper.appendChild(s);const n=s.cloneNode();this.progressWrapper.appendChild(n);const{scrollLeft:r,scrollWidth:o,clientWidth:h}=this.scrollContainer,d=t[0].length,l=d/o,u=Math.min(a.MAX_CANVAS_WIDTH,h),c=Math.floor(Math.abs(r)*l),p=Math.ceil(c+u*l),m=p-c,g=(r,o)=>{this.renderSingleCanvas(t,e,i,Math.max(0,r),Math.min(o,d),s,n)},f=this.createDelay(),v=this.createDelay(),y=(t,e)=>{g(t,e),t>0&&f((()=>{y(t-m,e-m)}))},b=(t,e)=>{g(t,e),e<d&&v((()=>{b(t+m,e+m)}))};y(c,p),p<d&&b(p,p+m)}render(t){this.timeouts.forEach((t=>t.timeout&&clearTimeout(t.timeout))),this.timeouts=[];const e=window.devicePixelRatio||1,i=this.scrollContainer.clientWidth,s=Math.ceil(t.duration*(this.options.minPxPerSec||0));this.isScrolling=s>i;const n=this.options.fillParent&&!this.isScrolling,r=(n?i:s)*e;if(this.wrapper.style.width=n?"100%":`${s}px`,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.cursor.style.backgroundColor=`${this.options.cursorColor||this.options.progressColor}`,this.cursor.style.width=`${this.options.cursorWidth}px`,this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="",this.options.splitChannels)for(let e=0;e<t.numberOfChannels;e++){const i={...this.options,...this.options.splitChannels[e]};this.renderWaveform([t.getChannelData(e)],i,r)}else{const e=[t.getChannelData(0)];t.numberOfChannels>1&&e.push(t.getChannelData(1)),this.renderWaveform(e,this.options,r)}this.audioData=t,this.emit("render")}reRender(){if(!this.audioData)return;const t=this.progressWrapper.clientWidth;this.render(this.audioData);const e=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=e-t}zoom(t){this.options.minPxPerSec=t,this.reRender()}scrollIntoView(t,e=!1){const{clientWidth:i,scrollLeft:s,scrollWidth:n}=this.scrollContainer,r=n*t,o=i/2;if(r>s+(e&&this.options.autoCenter&&!this.isDragging?o:i)||r<s)if(this.options.autoCenter&&!this.isDragging){const t=o/20;r-(s+o)>=t&&r<s+i?this.scrollContainer.scrollLeft+=t:this.scrollContainer.scrollLeft=r-o}else if(this.isDragging){const t=10;this.scrollContainer.scrollLeft=r<s?r-t:r-i+t}else this.scrollContainer.scrollLeft=r;{const{scrollLeft:t}=this.scrollContainer,e=t/n,s=(t+i)/n;this.emit("scroll",e,s)}}renderProgress(t,e){isNaN(t)||(this.progressWrapper.style.width=100*t+"%",this.cursor.style.left=100*t+"%",this.cursor.style.marginLeft=100===Math.round(100*t)?`-${this.options.cursorWidth}px`:"",this.isScrolling&&this.options.autoScroll&&this.scrollIntoView(t,e))}}a.MAX_CANVAS_WIDTH=4e3;const h=a;class d extends n.Z{constructor(){super(...arguments),this.unsubscribe=()=>{}}start(){this.unsubscribe=this.on("tick",(()=>{requestAnimationFrame((()=>{this.emit("tick")}))})),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}}const l=d,u={height:128,waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoScroll:!0,autoCenter:!0,sampleRate:8e3};class c extends o{static create(t){return new c(t)}constructor(t){super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.subscriptions=[],this.options=Object.assign({},u,t),this.timer=new l,this.renderer=new h(this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initPlugins();const e=this.options.url||this.options.media?.currentSrc||this.options.media?.src;e&&this.load(e,this.options.peaks,this.options.duration)}setOptions(t){this.options={...this.options,...t},this.renderer.setOptions(this.options),t.audioRate&&this.setPlaybackRate(t.audioRate)}initPlayerEvents(){this.subscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),this.isPlaying()),this.emit("timeupdate",t)})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop()})),this.onMediaEvent("ended",(()=>{this.emit("finish")})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",this.getCurrentTime())})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(t=>{this.options.interact&&(this.seekTo(t),this.emit("interaction"),this.emit("click",t))})),this.renderer.on("scroll",((t,e)=>{const i=this.getDuration();this.emit("scroll",t*i,e*i)})),this.renderer.on("render",(()=>{this.emit("redraw")})));{let t;this.subscriptions.push(this.renderer.on("drag",(e=>{this.options.interact&&(this.renderer.renderProgress(e),clearTimeout(t),t=setTimeout((()=>{this.seekTo(e)}),this.isPlaying()?0:200),this.emit("interaction"),this.emit("drag",e))})))}}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),!0),this.emit("timeupdate",t),this.emit("audioprocess",t)})))}initPlugins(){this.options.plugins?.length&&this.options.plugins.forEach((t=>{this.registerPlugin(t)}))}registerPlugin(t){return t.init(this),this.plugins.push(t),t}getWrapper(){return this.renderer.getWrapper()}getScroll(){return this.renderer.getScroll()}getActivePlugins(){return this.plugins}async load(i,s,n){if(this.decodedData=null,this.emit("load",i),s)this.setSrc(i),n||(n=await new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getMediaElement().duration)))}))||0),this.decodedData=t.createBuffer(s,n);else{const s=await e(i);this.setSrc(i,s),this.decodedData=await t.decode(s,this.options.sampleRate)}this.emit("decode",this.getDuration()),this.emit("ready",this.getDuration()),this.renderer.render(this.decodedData)}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",t)}getDecodedData(){return this.decodedData}getDuration(){const t=super.getDuration();return t>0&&t<1/0?t:this.decodedData?.duration||0}toggleInteraction(t){this.options.interact=t}seekTo(t){const e=this.getDuration()*t;this.setTime(e)}playPause(){return this.isPlaying()?(this.pause(),Promise.resolve()):this.play()}stop(){this.pause(),this.setTime(0)}skip(t){this.setTime(this.getCurrentTime()+t)}empty(){this.load("",[[0]],.001)}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.plugins.forEach((t=>t.destroy())),this.timer.destroy(),this.renderer.destroy(),super.destroy()}}const p=c;var m=i(76),g=i(954),f=i(919);class v extends n.Z{static create(t,e){return new v(t,e)}constructor(t,e){super(),this.audios=[],this.wavesurfers=[],this.durations=[],this.currentTime=0,this.maxDuration=0,this.isDragging=!1,this.frameRequest=null,this.timer=null,this.subscriptions=[],this.timeline=null,this.tracks=t.map((t=>({...t,startPosition:t.startPosition||0,peaks:t.peaks||(t.url?void 0:[new Float32Array])}))),this.options=e,this.rendering=function(t,e){let i=0,s=[],n=0;const r=document.createElement("div");r.setAttribute("style","width: 100%; overflow-x: scroll; overflow-y: hidden; user-select: none;");const o=document.createElement("div");o.style.position="relative",r.appendChild(o),e.container.appendChild(r);const a=document.createElement("div");a.setAttribute("style","height: 100%; position: absolute; z-index: 10; top: 0; left: 0"),a.style.backgroundColor=e.cursorColor||"#000",a.style.width=`${e.cursorWidth??1}px`,o.appendChild(a);const{clientWidth:h}=o,d=t.map(((t,i)=>{const s=document.createElement("div");if(s.style.position="relative",e.trackBorderColor&&i>0){const t=document.createElement("div");t.setAttribute("style",`width: 100%; height: 2px; background-color: ${e.trackBorderColor}`),o.appendChild(t)}if(e.trackBackground&&t.url&&(s.style.background=e.trackBackground),!t.url){const t=document.createElement("div");t.setAttribute("style",`position: absolute; z-index: 10; left: 10px; top: 10px; right: 10px; bottom: 10px; border: 2px dashed ${e.trackBorderColor};`),t.addEventListener("dragover",(i=>{i.preventDefault(),t.style.background=e.trackBackground||""})),t.addEventListener("dragleave",(e=>{e.preventDefault(),t.style.background=""})),t.addEventListener("drop",(e=>{e.preventDefault(),t.style.background=""})),s.appendChild(t)}return o.appendChild(s),s})),l=()=>{d.forEach(((e,n)=>{const r=t[n].startPosition*i;s[n]&&(e.style.width=s[n]*i+"px"),e.style.transform=`translateX(${r}px)`}))};return{containers:d,setContainerOffsets:l,setMainWidth:(t,r)=>{s=t,i=Math.max(e.minPxPerSec||0,h/r),n=i*r,o.style.width=`${n}px`,l()},updateCursor:(t,e)=>{a.style.left=`${Math.min(100,100*t)}%`;const{clientWidth:i,scrollLeft:s}=r,o=i/2,h=t*n;(h>s+(e?o:i)||h<s)&&(r.scrollLeft=h-o)},addClickHandler:t=>{o.addEventListener("click",(e=>{const i=o.getBoundingClientRect(),s=(e.clientX-i.left)/o.offsetWidth;t(s)}))},destroy:()=>{r.remove()},addDropHandler:e=>{t.forEach(((t,i)=>{if(!t.url){const s=d[i].querySelector("div");s?.addEventListener("drop",(i=>{i.preventDefault(),e(t.id)}))}}))}}}(this.tracks,this.options),this.rendering.addDropHandler((t=>{this.emit("drop",{id:t})})),this.initAllAudios().then((t=>{this.initDurations(t),this.initAllWavesurfers(),this.rendering.containers.forEach(((t,i)=>{const s=y(t,(t=>this.onDrag(i,t)),e.rightButtonDrag);this.wavesurfers[i].once("destroy",(()=>s?.destroy()))})),this.rendering.addClickHandler((t=>{this.isDragging||this.seekTo(t)})),this.emit("canplay")}))}initDurations(t){this.durations=t,this.maxDuration=this.tracks.reduce(((e,i,s)=>Math.max(e,i.startPosition+t[s])),0),this.rendering.setMainWidth(t,this.maxDuration)}initAudio(t){const e=new Audio(t.url);return new Promise((t=>{if(!e.src)return t(e);e.addEventListener("loadedmetadata",(()=>t(e)),{once:!0})}))}async initAllAudios(){return this.audios=await Promise.all(this.tracks.map((t=>this.initAudio(t)))),this.audios.map((t=>t.src?t.duration:0))}initWavesurfer(t,e){const i=this.rendering.containers[e],s=p.create({...t.options,container:i,minPxPerSec:0,media:this.audios[e],peaks:t.peaks,cursorColor:"transparent",cursorWidth:0,interact:!1,hideScrollbar:!0}),n=m.default.create();s.registerPlugin(n),this.subscriptions.push(s.once("decode",(()=>{if(null!=t.startCue||null!=t.endCue){const{startCue:i=0,endCue:s=this.durations[e]}=t,r=n.addRegion({start:0,end:i,color:"rgba(0, 0, 0, 0.7)",drag:!1}),o=n.addRegion({start:s,end:s+this.durations[e],color:"rgba(0, 0, 0, 0.7)",drag:!1});r.element.firstElementChild?.remove(),o.element.lastChild?.remove(),this.subscriptions.push(r.on("update-end",(()=>{t.startCue=r.end,this.emit("start-cue-change",{id:t.id,startCue:t.startCue})})),o.on("update-end",(()=>{t.endCue=o.start,this.emit("end-cue-change",{id:t.id,endCue:t.endCue})})))}if(t.intro){const e=n.addRegion({start:0,end:t.intro.endTime,content:t.intro.label,color:this.options.trackBackground,drag:!1});e.element.querySelector('[data-resize="left"]')?.remove(),e.element.parentElement.style.mixBlendMode="plus-lighter",t.intro.color&&(e.element.querySelector('[data-resize="right"]').style.borderColor=t.intro.color),this.subscriptions.push(e.on("update-end",(()=>{this.emit("intro-end-change",{id:t.id,endTime:e.end})})))}t.markers&&t.markers.forEach((t=>{n.addRegion({start:t.time,content:t.label,color:t.color,resize:!1})}))})));const r=s.registerPlugin(f.default.create({...this.options.envelopeOptions,fadeInStart:t.startCue,fadeInEnd:t.fadeInEnd,fadeOutStart:t.fadeOutStart,fadeOutEnd:t.endCue,volume:t.volume}));return this.subscriptions.push(r.on("volume-change",(e=>{this.setIsDragging(),this.emit("volume-change",{id:t.id,volume:e})})),r.on("fade-in-change",(e=>{this.setIsDragging(),this.emit("fade-in-change",{id:t.id,fadeInEnd:e})})),r.on("fade-out-change",(e=>{this.setIsDragging(),this.emit("fade-out-change",{id:t.id,fadeOutStart:e})})),this.on("start-cue-change",(({id:e,startCue:i})=>{e===t.id&&r.setStartTime(i)})),this.on("end-cue-change",(({id:e,endCue:i})=>{e===t.id&&r.setEndTime(i)}))),s}initAllWavesurfers(){const t=this.tracks.map(((t,e)=>this.initWavesurfer(t,e)));this.wavesurfers=t,this.initTimeline()}initTimeline(){this.timeline&&this.timeline.destroy(),this.timeline=this.wavesurfers[0].registerPlugin(g.default.create({duration:this.maxDuration,container:this.rendering.containers[0].parentElement}))}updatePosition(t,e=!1){const i=!this.isPlaying();t!==this.currentTime&&(this.currentTime=t,this.rendering.updateCursor(t/this.maxDuration,e)),this.tracks.forEach(((e,s)=>{const n=this.audios[s],r=this.durations[s],o=t-e.startPosition;Math.abs(n.currentTime-o)>.3&&(n.currentTime=o),i||o<0||o>r?!n.paused&&n.pause():i||n.paused&&n.play();const a=o>=(e.startCue||0)&&o<(e.endCue||1/0)?1:0;a!==n.volume&&(n.volume=a)}))}setIsDragging(){this.isDragging=!0,this.timer&&clearTimeout(this.timer),this.timer=setTimeout((()=>this.isDragging=!1),300)}onDrag(t,e){this.setIsDragging();const i=this.tracks[t];if(!i.draggable)return;const s=i.startPosition+e*this.maxDuration,n=this.tracks.findIndex((t=>t.url&&!t.draggable)),r=this.tracks[n],o=(r?r.startPosition:0)-this.durations[t],a=r?r.startPosition+this.durations[n]:this.maxDuration;s>=o&&s<=a&&(i.startPosition=s,this.initDurations(this.durations),this.rendering.setContainerOffsets(),this.updatePosition(this.currentTime),this.emit("start-position-change",{id:i.id,startPosition:s}))}findCurrentTracks(){const t=[];if(this.tracks.forEach(((e,i)=>{e.url&&this.currentTime>=e.startPosition&&this.currentTime<e.startPosition+this.durations[i]&&t.push(i)})),0===t.length){const e=Math.min(...this.tracks.filter((t=>t.url)).map((t=>t.startPosition)));t.push(this.tracks.findIndex((t=>t.startPosition===e)))}return t}startSync(){const t=()=>{const e=this.audios.reduce(((t,e,i)=>(e.paused||(t=Math.max(t,e.currentTime+this.tracks[i].startPosition)),t)),this.currentTime);e>this.currentTime&&this.updatePosition(e,!0),this.frameRequest=requestAnimationFrame(t)};t()}play(){this.startSync(),this.findCurrentTracks().forEach((t=>{this.audios[t]?.play()}))}pause(){this.audios.forEach((t=>t.pause()))}isPlaying(){return this.audios.some((t=>!t.paused))}getCurrentTime(){return this.currentTime}seekTo(t){const e=this.isPlaying();this.updatePosition(t*this.maxDuration),e&&this.play()}setTime(t){const e=this.isPlaying();this.updatePosition(t),e&&this.play()}zoom(t){this.options.minPxPerSec=t,this.wavesurfers.forEach(((e,i)=>this.tracks[i].url&&e.zoom(t))),this.rendering.setMainWidth(this.durations,this.maxDuration),this.rendering.setContainerOffsets()}addTrack(t){const e=this.tracks.findIndex((e=>e.id===t.id));-1!==e&&(this.tracks[e]=t,this.initAudio(t).then((i=>{this.audios[e]=i,this.durations[e]=i.duration,this.initDurations(this.durations);const s=this.rendering.containers[e];s.innerHTML="",this.wavesurfers[e].destroy(),this.wavesurfers[e]=this.initWavesurfer(t,e);const n=y(s,(t=>this.onDrag(e,t)),this.options.rightButtonDrag);this.wavesurfers[e].once("destroy",(()=>n?.destroy())),this.initTimeline(),this.emit("canplay")})))}destroy(){this.frameRequest&&cancelAnimationFrame(this.frameRequest),this.rendering.destroy(),this.audios.forEach((t=>{t.pause(),t.src=""})),this.wavesurfers.forEach((t=>{t.destroy()}))}setSinkId(t){return Promise.all(this.wavesurfers.map((e=>e.setSinkId(t))))}}function y(t,e,i=!1){const s=t.parentElement;if(!s)return;let n=null;t.addEventListener("contextmenu",(t=>{i&&t.preventDefault()})),t.addEventListener("mousedown",(e=>{if(i&&2!==e.button)return;const r=s.getBoundingClientRect();n=e.clientX-r.left,t.style.cursor="grabbing"}));const r=e=>{null!=n&&(e.stopPropagation(),n=null,t.style.cursor="")},o=t=>{if(null==n)return;const i=s.getBoundingClientRect(),r=t.clientX-i.left,o=r-n;(o>1||o<-1)&&(n=r,e(o/s.offsetWidth))};return document.body.addEventListener("mouseup",r),document.body.addEventListener("mousemove",o),{destroy:()=>{document.body.removeEventListener("mouseup",r),document.body.removeEventListener("mousemove",o)}}}const b=v})(),s.default})()));
|
package/dist/plugins/record.d.ts
CHANGED
package/dist/plugins/record.js
CHANGED
|
@@ -39,7 +39,8 @@ class RecordPlugin extends BasePlugin {
|
|
|
39
39
|
const dataArray = new Uint8Array(bufferLength);
|
|
40
40
|
analyser.getByteTimeDomainData(dataArray);
|
|
41
41
|
canvasCtx.lineWidth = this.options.lineWidth || 2;
|
|
42
|
-
|
|
42
|
+
const color = this.options.realtimeWaveColor || this.wavesurfer?.options.waveColor || '';
|
|
43
|
+
canvasCtx.strokeStyle = Array.isArray(color) ? color[0] : color;
|
|
43
44
|
canvasCtx.beginPath();
|
|
44
45
|
const sliceWidth = (canvas.width * 1.0) / bufferLength;
|
|
45
46
|
let x = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Record=t():e.Record=t()}(WaveSurfer,(()=>(()=>{"use strict";var e={d:(t,r)=>{for(var s in r)e.o(r,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:r[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{default:()=>o});const r=class{constructor(){this.listeners={}}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.un(e,t)}once(e,t){const r=this.on(e,t),s=this.on(e,(()=>{r(),s()}));return r}un(e,t){this.listeners[e]&&(t?this.listeners[e].delete(t):delete this.listeners[e])}unAll(){this.listeners={}}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach((e=>e(...t)))}},s=class extends r{constructor(e){super(),this.subscriptions=[],this.options=e}onInit(){}init(e){this.wavesurfer=e,this.onInit()}destroy(){this.subscriptions.forEach((e=>e()))}};class i extends s{constructor(){super(...arguments),this.mediaRecorder=null,this.recordedUrl=""}static create(e){return new i(e||{})}loadBlob(e){const t=new Blob(e,{type:"audio/webm"});this.recordedUrl=URL.createObjectURL(t),this.wavesurfer?.load(this.recordedUrl)}render(e){if(!this.wavesurfer)return()=>{};const t=this.wavesurfer.getWrapper(),r=document.createElement("canvas");r.width=t.clientWidth,r.height=t.clientHeight,r.style.zIndex="10",t.appendChild(r);const s=r.getContext("2d"),i=new AudioContext,o=i.createMediaStreamSource(e),n=i.createAnalyser();let c;o.connect(n);const a=()=>{if(!s)return;s.clearRect(0,0,r.width,r.height);const e=n.frequencyBinCount,t=new Uint8Array(e);n.getByteTimeDomainData(t),s.lineWidth=this.options.lineWidth||2
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Record=t():e.Record=t()}(WaveSurfer,(()=>(()=>{"use strict";var e={d:(t,r)=>{for(var s in r)e.o(r,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:r[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{default:()=>o});const r=class{constructor(){this.listeners={}}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.un(e,t)}once(e,t){const r=this.on(e,t),s=this.on(e,(()=>{r(),s()}));return r}un(e,t){this.listeners[e]&&(t?this.listeners[e].delete(t):delete this.listeners[e])}unAll(){this.listeners={}}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach((e=>e(...t)))}},s=class extends r{constructor(e){super(),this.subscriptions=[],this.options=e}onInit(){}init(e){this.wavesurfer=e,this.onInit()}destroy(){this.subscriptions.forEach((e=>e()))}};class i extends s{constructor(){super(...arguments),this.mediaRecorder=null,this.recordedUrl=""}static create(e){return new i(e||{})}loadBlob(e){const t=new Blob(e,{type:"audio/webm"});this.recordedUrl=URL.createObjectURL(t),this.wavesurfer?.load(this.recordedUrl)}render(e){if(!this.wavesurfer)return()=>{};const t=this.wavesurfer.getWrapper(),r=document.createElement("canvas");r.width=t.clientWidth,r.height=t.clientHeight,r.style.zIndex="10",t.appendChild(r);const s=r.getContext("2d"),i=new AudioContext,o=i.createMediaStreamSource(e),n=i.createAnalyser();let c;o.connect(n);const a=()=>{if(!s)return;s.clearRect(0,0,r.width,r.height);const e=n.frequencyBinCount,t=new Uint8Array(e);n.getByteTimeDomainData(t),s.lineWidth=this.options.lineWidth||2;const i=this.options.realtimeWaveColor||this.wavesurfer?.options.waveColor||"";s.strokeStyle=Array.isArray(i)?i[0]:i,s.beginPath();const o=1*r.width/e;let d=0;for(let i=0;i<e;i++){const e=t[i]/128*r.height/2;0===i?s.moveTo(d,e):s.lineTo(d,e),d+=o}s.lineTo(r.width,r.height/2),s.stroke(),c=requestAnimationFrame(a)};return a(),()=>{c&&cancelAnimationFrame(c),o&&(o.disconnect(),o.mediaStream.getTracks().forEach((e=>e.stop()))),i&&i.close(),r?.remove()}}cleanUp(){this.stopRecording(),this.wavesurfer?.empty(),this.recordedUrl&&(URL.revokeObjectURL(this.recordedUrl),this.recordedUrl="")}async startRecording(){let e;this.cleanUp();try{e=await navigator.mediaDevices.getUserMedia({audio:!0})}catch(e){throw new Error("Error accessing the microphone: "+e.message)}const t=this.render(e),r=new MediaRecorder(e),s=[];r.addEventListener("dataavailable",(e=>{e.data.size>0&&s.push(e.data)})),r.addEventListener("stop",(()=>{t(),this.loadBlob(s),this.emit("stopRecording")})),r.start(),this.emit("startRecording"),this.mediaRecorder=r}isRecording(){return"recording"===this.mediaRecorder?.state}stopRecording(){this.isRecording()&&this.mediaRecorder?.stop()}getRecordedUrl(){return this.recordedUrl}destroy(){super.destroy(),this.cleanUp()}}const o=i;return t.default})()));
|
package/dist/renderer.d.ts
CHANGED
|
@@ -1,20 +1,5 @@
|
|
|
1
1
|
import EventEmitter from './event-emitter.js';
|
|
2
|
-
|
|
3
|
-
height: number;
|
|
4
|
-
waveColor: string;
|
|
5
|
-
progressColor: string;
|
|
6
|
-
cursorColor?: string;
|
|
7
|
-
cursorWidth: number;
|
|
8
|
-
minPxPerSec: number;
|
|
9
|
-
fillParent: boolean;
|
|
10
|
-
barWidth?: number;
|
|
11
|
-
barGap?: number;
|
|
12
|
-
barRadius?: number;
|
|
13
|
-
barHeight?: number;
|
|
14
|
-
hideScrollbar?: boolean;
|
|
15
|
-
autoCenter?: boolean;
|
|
16
|
-
autoScroll?: boolean;
|
|
17
|
-
};
|
|
2
|
+
import type { WaveSurferOptions } from './wavesurfer.js';
|
|
18
3
|
type RendererEvents = {
|
|
19
4
|
click: [relativeX: number];
|
|
20
5
|
drag: [relativeX: number];
|
|
@@ -30,21 +15,23 @@ declare class Renderer extends EventEmitter<RendererEvents> {
|
|
|
30
15
|
private canvasWrapper;
|
|
31
16
|
private progressWrapper;
|
|
32
17
|
private cursor;
|
|
33
|
-
private
|
|
18
|
+
private timeouts;
|
|
34
19
|
private isScrolling;
|
|
35
20
|
private audioData;
|
|
36
21
|
private resizeObserver;
|
|
37
22
|
private isDragging;
|
|
38
|
-
constructor(
|
|
23
|
+
constructor(options: WaveSurferOptions);
|
|
39
24
|
private initEvents;
|
|
40
25
|
private initDrag;
|
|
41
26
|
private initHtml;
|
|
42
|
-
setOptions(options:
|
|
27
|
+
setOptions(options: WaveSurferOptions): void;
|
|
43
28
|
getWrapper(): HTMLElement;
|
|
44
29
|
getScroll(): number;
|
|
45
30
|
destroy(): void;
|
|
46
|
-
private
|
|
47
|
-
private
|
|
31
|
+
private createDelay;
|
|
32
|
+
private convertColorValues;
|
|
33
|
+
private renderSingleCanvas;
|
|
34
|
+
private renderWaveform;
|
|
48
35
|
render(audioData: AudioBuffer): void;
|
|
49
36
|
reRender(): void;
|
|
50
37
|
zoom(minPxPerSec: number): void;
|
package/dist/renderer.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import EventEmitter from './event-emitter.js';
|
|
2
2
|
class Renderer extends EventEmitter {
|
|
3
|
-
constructor(
|
|
3
|
+
constructor(options) {
|
|
4
4
|
super();
|
|
5
|
-
this.
|
|
6
|
-
height: 0,
|
|
7
|
-
};
|
|
8
|
-
this.timeout = null;
|
|
5
|
+
this.timeouts = [];
|
|
9
6
|
this.isScrolling = false;
|
|
10
7
|
this.audioData = null;
|
|
11
8
|
this.resizeObserver = null;
|
|
12
9
|
this.isDragging = false;
|
|
13
|
-
this.options =
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
this.options = options;
|
|
11
|
+
let container;
|
|
12
|
+
if (typeof options.container === 'string') {
|
|
13
|
+
container = document.querySelector(options.container);
|
|
14
|
+
}
|
|
15
|
+
else if (options.container instanceof HTMLElement) {
|
|
16
|
+
container = options.container;
|
|
16
17
|
}
|
|
17
18
|
if (!container) {
|
|
18
19
|
throw new Error('Container not found');
|
|
@@ -45,8 +46,9 @@ class Renderer extends EventEmitter {
|
|
|
45
46
|
this.emit('scroll', startX, endX);
|
|
46
47
|
});
|
|
47
48
|
// Re-render the waveform on container resize
|
|
49
|
+
const delay = this.createDelay(100);
|
|
48
50
|
this.resizeObserver = new ResizeObserver(() => {
|
|
49
|
-
|
|
51
|
+
delay(() => this.reRender());
|
|
50
52
|
});
|
|
51
53
|
this.resizeObserver.observe(this.scrollContainer);
|
|
52
54
|
}
|
|
@@ -99,15 +101,16 @@ class Renderer extends EventEmitter {
|
|
|
99
101
|
z-index: 2;
|
|
100
102
|
}
|
|
101
103
|
:host .canvases {
|
|
104
|
+
min-height: ${this.options.height}px;
|
|
105
|
+
}
|
|
106
|
+
:host .canvases > div {
|
|
102
107
|
position: relative;
|
|
103
|
-
height: ${this.options.height}px;
|
|
104
108
|
}
|
|
105
109
|
:host canvas {
|
|
106
110
|
display: block;
|
|
107
111
|
position: absolute;
|
|
108
112
|
top: 0;
|
|
109
113
|
image-rendering: pixelated;
|
|
110
|
-
height: ${this.options.height}px;
|
|
111
114
|
}
|
|
112
115
|
:host .progress {
|
|
113
116
|
pointer-events: none;
|
|
@@ -119,6 +122,9 @@ class Renderer extends EventEmitter {
|
|
|
119
122
|
height: 100%;
|
|
120
123
|
overflow: hidden;
|
|
121
124
|
}
|
|
125
|
+
:host .progress > div {
|
|
126
|
+
position: relative;
|
|
127
|
+
}
|
|
122
128
|
:host .cursor {
|
|
123
129
|
pointer-events: none;
|
|
124
130
|
position: absolute;
|
|
@@ -127,8 +133,6 @@ class Renderer extends EventEmitter {
|
|
|
127
133
|
left: 0;
|
|
128
134
|
height: 100%;
|
|
129
135
|
border-radius: 2px;
|
|
130
|
-
width: ${this.options.cursorWidth}px;
|
|
131
|
-
background-color: ${this.options.cursorColor || this.options.progressColor};
|
|
132
136
|
}
|
|
133
137
|
</style>
|
|
134
138
|
|
|
@@ -157,116 +161,153 @@ class Renderer extends EventEmitter {
|
|
|
157
161
|
this.container.remove();
|
|
158
162
|
this.resizeObserver?.disconnect();
|
|
159
163
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
164
|
+
createDelay(delayMs = 10) {
|
|
165
|
+
const context = {};
|
|
166
|
+
this.timeouts.push(context);
|
|
167
|
+
return (callback) => {
|
|
168
|
+
context.timeout && clearTimeout(context.timeout);
|
|
169
|
+
context.timeout = setTimeout(callback, delayMs);
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
// Convert array of color values to linear gradient
|
|
173
|
+
convertColorValues(color) {
|
|
174
|
+
if (!Array.isArray(color))
|
|
175
|
+
return color || '';
|
|
176
|
+
if (color.length < 2)
|
|
177
|
+
return color.length === 1 ? color[0] : '';
|
|
178
|
+
const canvasElement = document.createElement('canvas');
|
|
179
|
+
const ctx = canvasElement.getContext('2d');
|
|
180
|
+
const gradient = ctx.createLinearGradient(0, 0, 0, canvasElement.height);
|
|
181
|
+
const colorStopPercentage = 1 / (color.length - 1);
|
|
182
|
+
color.forEach((color, index) => {
|
|
183
|
+
const offset = index * colorStopPercentage;
|
|
184
|
+
gradient.addColorStop(offset, color);
|
|
168
185
|
});
|
|
186
|
+
return gradient;
|
|
169
187
|
}
|
|
170
|
-
|
|
171
|
-
const
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
188
|
+
renderSingleCanvas(channelData, options, width, start, end, canvasContainer, progressContainer) {
|
|
189
|
+
const pixelRatio = window.devicePixelRatio || 1;
|
|
190
|
+
const height = options.height || 0;
|
|
191
|
+
const barWidth = options.barWidth != null && !isNaN(options.barWidth) ? options.barWidth * pixelRatio : 1;
|
|
192
|
+
const barGap = options.barGap != null && !isNaN(options.barGap)
|
|
193
|
+
? options.barGap * pixelRatio
|
|
194
|
+
: options.barWidth
|
|
175
195
|
? barWidth / 2
|
|
176
196
|
: 0;
|
|
177
|
-
const barRadius =
|
|
178
|
-
const
|
|
179
|
-
const
|
|
180
|
-
const
|
|
197
|
+
const barRadius = options.barRadius || 0;
|
|
198
|
+
const barScale = options.barHeight || 1;
|
|
199
|
+
const isMono = channelData.length === 1;
|
|
200
|
+
const leftChannel = channelData[0];
|
|
201
|
+
const rightChannel = isMono ? leftChannel : channelData[1];
|
|
202
|
+
const useNegative = isMono && rightChannel.some((v) => v < 0);
|
|
203
|
+
const length = leftChannel.length;
|
|
181
204
|
const barCount = Math.floor(width / (barWidth + barGap));
|
|
182
|
-
const barIndexScale = barCount /
|
|
205
|
+
const barIndexScale = barCount / length;
|
|
183
206
|
const halfHeight = height / 2;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
ctx.
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
ctx.roundRect(prevX * (barWidth + barGap), halfHeight - leftBarHeight, barWidth, leftBarHeight + (rightBarHeight || 1), barRadius);
|
|
212
|
-
prevX = barIndex;
|
|
213
|
-
prevLeft = 0;
|
|
214
|
-
prevRight = 0;
|
|
215
|
-
}
|
|
216
|
-
const leftValue = useNegative ? leftChannel[i] : Math.abs(leftChannel[i]);
|
|
217
|
-
const rightValue = useNegative ? rightChannel[i] : Math.abs(rightChannel[i]);
|
|
218
|
-
if (leftValue > prevLeft) {
|
|
219
|
-
prevLeft = leftValue;
|
|
220
|
-
}
|
|
221
|
-
// If stereo, both channels are drawn as max values
|
|
222
|
-
// If mono with negative values, the bottom channel will be the min negative values
|
|
223
|
-
if (useNegative ? rightValue < -prevRight : rightValue > prevRight) {
|
|
224
|
-
prevRight = rightValue < 0 ? -rightValue : rightValue;
|
|
225
|
-
}
|
|
207
|
+
let prevX = 0;
|
|
208
|
+
let prevLeft = 0;
|
|
209
|
+
let prevRight = 0;
|
|
210
|
+
const canvas = document.createElement('canvas');
|
|
211
|
+
canvas.width = Math.round((width * (end - start)) / length);
|
|
212
|
+
canvas.height = height;
|
|
213
|
+
canvas.style.width = `${Math.floor(canvas.width / pixelRatio)}px`;
|
|
214
|
+
canvas.style.height = `${options.height}px`;
|
|
215
|
+
canvas.style.left = `${Math.floor((start * width) / pixelRatio / length)}px`;
|
|
216
|
+
canvasContainer.appendChild(canvas);
|
|
217
|
+
const ctx = canvas.getContext('2d', {
|
|
218
|
+
desynchronized: true,
|
|
219
|
+
});
|
|
220
|
+
ctx.beginPath();
|
|
221
|
+
ctx.fillStyle = this.convertColorValues(options.waveColor);
|
|
222
|
+
// Firefox shim until 2023.04.11
|
|
223
|
+
if (!ctx.roundRect)
|
|
224
|
+
ctx.roundRect = ctx.fillRect;
|
|
225
|
+
for (let i = start; i < end; i++) {
|
|
226
|
+
const barIndex = Math.round((i - start) * barIndexScale);
|
|
227
|
+
if (barIndex > prevX) {
|
|
228
|
+
const leftBarHeight = Math.round(prevLeft * halfHeight * barScale);
|
|
229
|
+
const rightBarHeight = Math.round(prevRight * halfHeight * barScale);
|
|
230
|
+
ctx.roundRect(prevX * (barWidth + barGap), halfHeight - leftBarHeight, barWidth, leftBarHeight + (rightBarHeight || 1), barRadius);
|
|
231
|
+
prevX = barIndex;
|
|
232
|
+
prevLeft = 0;
|
|
233
|
+
prevRight = 0;
|
|
226
234
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
this.progressWrapper.appendChild(progressCanvas);
|
|
232
|
-
const progressCtx = progressCanvas.getContext('2d', {
|
|
233
|
-
desynchronized: true,
|
|
234
|
-
});
|
|
235
|
-
if (canvas.width > 0 && canvas.height > 0) {
|
|
236
|
-
progressCtx.drawImage(canvas, 0, 0);
|
|
235
|
+
const leftValue = useNegative ? leftChannel[i] : Math.abs(leftChannel[i]);
|
|
236
|
+
const rightValue = useNegative ? rightChannel[i] : Math.abs(rightChannel[i]);
|
|
237
|
+
if (leftValue > prevLeft) {
|
|
238
|
+
prevLeft = leftValue;
|
|
237
239
|
}
|
|
238
|
-
//
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
240
|
+
// If stereo, both channels are drawn as max values
|
|
241
|
+
// If mono with negative values, the bottom channel will be the min negative values
|
|
242
|
+
if (useNegative ? rightValue < -prevRight : rightValue > prevRight) {
|
|
243
|
+
prevRight = rightValue < 0 ? -rightValue : rightValue;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
ctx.fill();
|
|
247
|
+
ctx.closePath();
|
|
248
|
+
// Draw a progress canvas
|
|
249
|
+
const progressCanvas = canvas.cloneNode();
|
|
250
|
+
progressContainer.appendChild(progressCanvas);
|
|
251
|
+
const progressCtx = progressCanvas.getContext('2d', {
|
|
252
|
+
desynchronized: true,
|
|
253
|
+
});
|
|
254
|
+
if (canvas.width > 0 && canvas.height > 0) {
|
|
255
|
+
progressCtx.drawImage(canvas, 0, 0);
|
|
256
|
+
}
|
|
257
|
+
// Set the composition method to draw only where the waveform is drawn
|
|
258
|
+
progressCtx.globalCompositeOperation = 'source-in';
|
|
259
|
+
progressCtx.fillStyle = this.convertColorValues(options.progressColor);
|
|
260
|
+
// This rectangle acts as a mask thanks to the composition method
|
|
261
|
+
progressCtx.fillRect(0, 0, canvas.width, canvas.height);
|
|
262
|
+
}
|
|
263
|
+
renderWaveform(channelData, options, width) {
|
|
264
|
+
// A container for canvases
|
|
265
|
+
const canvasContainer = document.createElement('div');
|
|
266
|
+
canvasContainer.style.height = `${options.height}px`;
|
|
267
|
+
this.canvasWrapper.appendChild(canvasContainer);
|
|
268
|
+
// A container for progress canvases
|
|
269
|
+
const progressContainer = canvasContainer.cloneNode();
|
|
270
|
+
this.progressWrapper.appendChild(progressContainer);
|
|
247
271
|
// Determine the currently visible part of the waveform
|
|
248
272
|
const { scrollLeft, scrollWidth, clientWidth } = this.scrollContainer;
|
|
273
|
+
const len = channelData[0].length;
|
|
249
274
|
const scale = len / scrollWidth;
|
|
250
|
-
|
|
251
|
-
viewportWidth -= viewportWidth % ((barWidth + barGap) / pixelRatio);
|
|
275
|
+
const viewportWidth = Math.min(Renderer.MAX_CANVAS_WIDTH, clientWidth);
|
|
252
276
|
const start = Math.floor(Math.abs(scrollLeft) * scale);
|
|
253
277
|
const end = Math.ceil(start + viewportWidth * scale);
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
278
|
+
const viewportLen = end - start;
|
|
279
|
+
// Draw a portion of the waveform from start peak to end peak
|
|
280
|
+
const draw = (start, end) => {
|
|
281
|
+
this.renderSingleCanvas(channelData, options, width, Math.max(0, start), Math.min(end, len), canvasContainer, progressContainer);
|
|
282
|
+
};
|
|
283
|
+
// Draw the waveform in viewport chunks, each with a delay
|
|
284
|
+
const headDelay = this.createDelay();
|
|
285
|
+
const tailDelay = this.createDelay();
|
|
286
|
+
const renderHead = (fromIndex, toIndex) => {
|
|
287
|
+
draw(fromIndex, toIndex);
|
|
288
|
+
if (fromIndex > 0) {
|
|
289
|
+
headDelay(() => {
|
|
290
|
+
renderHead(fromIndex - viewportLen, toIndex - viewportLen);
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
const renderTail = (fromIndex, toIndex) => {
|
|
295
|
+
draw(fromIndex, toIndex);
|
|
296
|
+
if (toIndex < len) {
|
|
297
|
+
tailDelay(() => {
|
|
298
|
+
renderTail(fromIndex + viewportLen, toIndex + viewportLen);
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
renderHead(start, end);
|
|
303
|
+
if (end < len) {
|
|
304
|
+
renderTail(end, end + viewportLen);
|
|
267
305
|
}
|
|
268
306
|
}
|
|
269
307
|
render(audioData) {
|
|
308
|
+
// Clear previous timeouts
|
|
309
|
+
this.timeouts.forEach((context) => context.timeout && clearTimeout(context.timeout));
|
|
310
|
+
this.timeouts = [];
|
|
270
311
|
// Determine the width of the waveform
|
|
271
312
|
const pixelRatio = window.devicePixelRatio || 1;
|
|
272
313
|
const parentWidth = this.scrollContainer.clientWidth;
|
|
@@ -276,7 +317,6 @@ class Renderer extends EventEmitter {
|
|
|
276
317
|
const useParentWidth = this.options.fillParent && !this.isScrolling;
|
|
277
318
|
// Width and height of the waveform in pixels
|
|
278
319
|
const width = (useParentWidth ? parentWidth : scrollWidth) * pixelRatio;
|
|
279
|
-
const { height } = this.options;
|
|
280
320
|
// Set the width of the wrapper
|
|
281
321
|
this.wrapper.style.width = useParentWidth ? '100%' : `${scrollWidth}px`;
|
|
282
322
|
// Set additional styles
|
|
@@ -284,9 +324,24 @@ class Renderer extends EventEmitter {
|
|
|
284
324
|
this.scrollContainer.classList.toggle('noScrollbar', !!this.options.hideScrollbar);
|
|
285
325
|
this.cursor.style.backgroundColor = `${this.options.cursorColor || this.options.progressColor}`;
|
|
286
326
|
this.cursor.style.width = `${this.options.cursorWidth}px`;
|
|
287
|
-
|
|
327
|
+
// Clear the canvases
|
|
328
|
+
this.canvasWrapper.innerHTML = '';
|
|
329
|
+
this.progressWrapper.innerHTML = '';
|
|
288
330
|
// Render the waveform
|
|
289
|
-
this.
|
|
331
|
+
if (this.options.splitChannels) {
|
|
332
|
+
// Render a waveform for each channel
|
|
333
|
+
for (let i = 0; i < audioData.numberOfChannels; i++) {
|
|
334
|
+
const options = { ...this.options, ...this.options.splitChannels[i] };
|
|
335
|
+
this.renderWaveform([audioData.getChannelData(i)], options, width);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
// Render a single waveform for the first two channels (left and right)
|
|
340
|
+
const channels = [audioData.getChannelData(0)];
|
|
341
|
+
if (audioData.numberOfChannels > 1)
|
|
342
|
+
channels.push(audioData.getChannelData(1));
|
|
343
|
+
this.renderWaveform(channels, this.options, width);
|
|
344
|
+
}
|
|
290
345
|
this.audioData = audioData;
|
|
291
346
|
this.emit('render');
|
|
292
347
|
}
|
package/dist/wavesurfer.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { GenericPlugin } from './base-plugin.js';
|
|
2
2
|
import Player from './player.js';
|
|
3
|
-
|
|
3
|
+
export type WaveSurferColor = string | string[] | CanvasGradient;
|
|
4
4
|
export type WaveSurferOptions = {
|
|
5
5
|
/** HTML element or CSS selector */
|
|
6
6
|
container: HTMLElement | string;
|
|
7
7
|
/** The height of the waveform in pixels */
|
|
8
8
|
height?: number;
|
|
9
9
|
/** The color of the waveform */
|
|
10
|
-
waveColor?:
|
|
10
|
+
waveColor?: WaveSurferColor;
|
|
11
11
|
/** The color of the progress mask */
|
|
12
|
-
progressColor?:
|
|
12
|
+
progressColor?: WaveSurferColor;
|
|
13
13
|
/** The color of the playpack cursor */
|
|
14
14
|
cursorColor?: string;
|
|
15
15
|
/** The cursor width */
|
|
@@ -48,13 +48,15 @@ export type WaveSurferOptions = {
|
|
|
48
48
|
autoCenter?: boolean;
|
|
49
49
|
/** Decoding sample rate. Doesn't affect the playback. Defaults to 8000 */
|
|
50
50
|
sampleRate?: number;
|
|
51
|
+
/** Render each audio channel as a separate waveform */
|
|
52
|
+
splitChannels?: WaveSurferOptions[];
|
|
51
53
|
/** The list of plugins to initialize on start */
|
|
52
54
|
plugins?: GenericPlugin[];
|
|
53
55
|
};
|
|
54
56
|
declare const defaultOptions: {
|
|
55
57
|
height: number;
|
|
56
|
-
waveColor:
|
|
57
|
-
progressColor:
|
|
58
|
+
waveColor: WaveSurferColor;
|
|
59
|
+
progressColor: WaveSurferColor;
|
|
58
60
|
cursorWidth: number;
|
|
59
61
|
minPxPerSec: number;
|
|
60
62
|
fillParent: boolean;
|
|
@@ -108,7 +110,7 @@ declare class WaveSurfer extends Player<WaveSurferEvents> {
|
|
|
108
110
|
static create(options: WaveSurferOptions): WaveSurfer;
|
|
109
111
|
/** Create a new WaveSurfer instance */
|
|
110
112
|
constructor(options: WaveSurferOptions);
|
|
111
|
-
setOptions(options: Partial<
|
|
113
|
+
setOptions(options: Partial<WaveSurferOptions>): void;
|
|
112
114
|
private initPlayerEvents;
|
|
113
115
|
private initRendererEvents;
|
|
114
116
|
private initTimerEvents;
|
package/dist/wavesurfer.js
CHANGED
|
@@ -32,7 +32,7 @@ class WaveSurfer extends Player {
|
|
|
32
32
|
this.subscriptions = [];
|
|
33
33
|
this.options = Object.assign({}, defaultOptions, options);
|
|
34
34
|
this.timer = new Timer();
|
|
35
|
-
this.renderer = new Renderer(this.options
|
|
35
|
+
this.renderer = new Renderer(this.options);
|
|
36
36
|
this.initPlayerEvents();
|
|
37
37
|
this.initRendererEvents();
|
|
38
38
|
this.initTimerEvents();
|
package/dist/wavesurfer.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.WaveSurfer=e():t.WaveSurfer=e()}(this,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var s in i)t.o(i,s)&&!t.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:i[s]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>d});const i={decode:async function(t,e){const i=new AudioContext({sampleRate:e}),s=i.decodeAudioData(t);return s.finally((()=>i.close())),s},createBuffer:function(t,e){return"number"==typeof t[0]&&(t=[t]),function(t){const e=t[0];if(e.some((t=>t>1||t<-1))){const i=e.length;let s=0;for(let t=0;t<i;t++){const i=Math.abs(e[t]);i>s&&(s=i)}for(const e of t)for(let t=0;t<i;t++)e[t]/=s}}(t),{duration:e,length:t[0].length,sampleRate:t[0].length/e,numberOfChannels:t.length,getChannelData:e=>t?.[e],copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}},s=async function(t){return fetch(t).then((t=>t.arrayBuffer()))},r=class{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),s=this.on(t,(()=>{i(),s()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}},n=class extends r{constructor(t){super(),this.isExternalMedia=!1,t.media?(this.media=t.media,this.isExternalMedia=!0):this.media=document.createElement("audio"),t.autoplay&&(this.media.autoplay=!0),null!=t.playbackRate&&(this.media.playbackRate=t.playbackRate)}onMediaEvent(t,e,i){return this.media.addEventListener(t,e,i),()=>this.media.removeEventListener(t,e)}onceMediaEvent(t,e){return this.onMediaEvent(t,e,{once:!0})}revokeSrc(){(this.media.currentSrc||this.media.src||"").startsWith("blob:")&&URL.revokeObjectURL(this.media.currentSrc)}setSrc(t,e){if((this.media.currentSrc||this.media.src||"")===t)return;this.revokeSrc();const i=e?URL.createObjectURL(new Blob([e],{type:"audio/wav"})):t;this.media.src=i}destroy(){this.media.pause(),this.revokeSrc(),this.isExternalMedia||this.media.remove()}play(){return this.media.play()}pause(){this.media.pause()}isPlaying(){return this.media.currentTime>0&&!this.media.paused&&!this.media.ended}setTime(t){this.media.currentTime=t}getDuration(){return this.media.duration}getCurrentTime(){return this.media.currentTime}getVolume(){return this.media.volume}setVolume(t){this.media.volume=t}getMuted(){return this.media.muted}setMuted(t){this.media.muted=t}getPlaybackRate(){return this.media.playbackRate}setPlaybackRate(t,e){null!=e&&(this.media.preservesPitch=e),this.media.playbackRate=t}getMediaElement(){return this.media}setSinkId(t){return this.media.setSinkId(t)}};class o extends r{constructor(t,e){if(super(),this.options={height:0},this.timeout=null,this.isScrolling=!1,this.audioData=null,this.resizeObserver=null,this.isDragging=!1,this.options={...e},"string"==typeof t&&(t=document.querySelector(t)),!t)throw new Error("Container not found");const[i,s]=this.initHtml();t.appendChild(i),this.container=i,this.scrollContainer=s.querySelector(".scroll"),this.wrapper=s.querySelector(".wrapper"),this.canvasWrapper=s.querySelector(".canvases"),this.progressWrapper=s.querySelector(".progress"),this.cursor=s.querySelector(".cursor"),this.initEvents()}initEvents(){this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",i)})),this.initDrag(),this.scrollContainer.addEventListener("scroll",(()=>{const{scrollLeft:t,scrollWidth:e,clientWidth:i}=this.scrollContainer,s=t/e,r=(t+i)/e;this.emit("scroll",s,r)})),this.resizeObserver=new ResizeObserver((()=>{this.delay((()=>this.reRender()),100)})),this.resizeObserver.observe(this.scrollContainer)}initDrag(){this.wrapper.addEventListener("mousedown",(t=>{const e=t.clientX,i=t=>{if(Math.abs(t.clientX-e)>=5){this.isDragging=!0;const e=this.wrapper.getBoundingClientRect();this.emit("drag",Math.max(0,Math.min(1,(t.clientX-e.left)/e.width)))}},s=()=>{document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",s),this.isDragging=!1};document.addEventListener("mousemove",i),document.addEventListener("mouseup",s)}))}initHtml(){const t=document.createElement("div"),e=t.attachShadow({mode:"open"});return e.innerHTML=`\n <style>\n :host {\n user-select: none;\n }\n :host .scroll {\n overflow-x: auto;\n overflow-y: hidden;\n width: 100%;\n position: relative;\n }\n :host .noScrollbar {\n scrollbar-color: transparent;\n scrollbar-width: none;\n }\n :host .noScrollbar::-webkit-scrollbar {\n display: none;\n -webkit-appearance: none;\n }\n :host .wrapper {\n position: relative;\n overflow: visible;\n z-index: 2;\n }\n :host .canvases {\n position: relative;\n height: ${this.options.height}px;\n }\n :host canvas {\n display: block;\n position: absolute;\n top: 0;\n image-rendering: pixelated;\n height: ${this.options.height}px;\n }\n :host .progress {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n width: 0;\n height: 100%;\n overflow: hidden;\n }\n :host .cursor {\n pointer-events: none;\n position: absolute;\n z-index: 5;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n width: ${this.options.cursorWidth}px;\n background-color: ${this.options.cursorColor||this.options.progressColor};\n }\n </style>\n\n <div class="scroll" part="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress"></div>\n <div class="cursor" part="cursor"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){this.options=t,this.reRender()}getWrapper(){return this.wrapper}getScroll(){return this.scrollContainer.scrollLeft}destroy(){this.container.remove(),this.resizeObserver?.disconnect()}delay(t,e=10){return this.timeout&&clearTimeout(this.timeout),new Promise((i=>{this.timeout=setTimeout((()=>{i(t())}),e)}))}async renderPeaks(t,e,i,s){const r=null==this.options.barWidth||isNaN(this.options.barWidth)?1:this.options.barWidth*s,n=null==this.options.barGap||isNaN(this.options.barGap)?this.options.barWidth?r/2:0:this.options.barGap*s,a=this.options.barRadius||0,h=this.options.barHeight||1,l=t.getChannelData(0),c=l.length,d=Math.floor(e/(r+n))/c,u=i/2,p=1===t.numberOfChannels,m=p?l:t.getChannelData(1),g=p&&m.some((t=>t<0)),f=(t,i)=>{let o=0,p=0,f=0;const y=document.createElement("canvas");y.width=Math.round(e*(i-t)/c),y.height=this.options.height,y.style.width=`${Math.floor(y.width/s)}px`,y.style.height=`${this.options.height}px`,y.style.left=`${Math.floor(t*e/s/c)}px`,this.canvasWrapper.appendChild(y);const v=y.getContext("2d",{desynchronized:!0});v.beginPath(),v.fillStyle=this.options.waveColor??"",v.roundRect||(v.roundRect=v.fillRect);for(let e=t;e<i;e++){const i=Math.round((e-t)*d);if(i>o){const t=Math.round(p*u*h),e=Math.round(f*u*h);v.roundRect(o*(r+n),u-t,r,t+(e||1),a),o=i,p=0,f=0}const s=g?l[e]:Math.abs(l[e]),c=g?m[e]:Math.abs(m[e]);s>p&&(p=s),(g?c<-f:c>f)&&(f=c<0?-c:c)}v.fill(),v.closePath();const b=y.cloneNode();this.progressWrapper.appendChild(b);const w=b.getContext("2d",{desynchronized:!0});y.width>0&&y.height>0&&w.drawImage(y,0,0),w.globalCompositeOperation="source-in",w.fillStyle=this.options.progressColor??"",w.fillRect(0,0,y.width,y.height)};this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="";const{scrollLeft:y,scrollWidth:v,clientWidth:b}=this.scrollContainer,w=c/v;let C=Math.min(o.MAX_CANVAS_WIDTH,b);C-=C%((r+n)/s);const S=Math.floor(Math.abs(y)*w),M=Math.ceil(S+C*w);f(S,M);const E=M-S;for(let t=M;t<c;t+=E)await this.delay((()=>{f(t,Math.min(c,t+E))}));for(let t=S-1;t>=0;t-=E)await this.delay((()=>{f(Math.max(0,t-E),t)}))}render(t){const e=window.devicePixelRatio||1,i=this.scrollContainer.clientWidth,s=Math.ceil(t.duration*(this.options.minPxPerSec||0));this.isScrolling=s>i;const r=this.options.fillParent&&!this.isScrolling,n=(r?i:s)*e,{height:o}=this.options;this.wrapper.style.width=r?"100%":`${s}px`,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.cursor.style.backgroundColor=`${this.options.cursorColor||this.options.progressColor}`,this.cursor.style.width=`${this.options.cursorWidth}px`,this.canvasWrapper.style.height=`${this.options.height}px`,this.renderPeaks(t,n,o,e),this.audioData=t,this.emit("render")}reRender(){if(!this.audioData)return;const t=this.progressWrapper.clientWidth;this.render(this.audioData);const e=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=e-t}zoom(t){this.options.minPxPerSec=t,this.reRender()}scrollIntoView(t,e=!1){const{clientWidth:i,scrollLeft:s,scrollWidth:r}=this.scrollContainer,n=r*t,o=i/2;if(n>s+(e&&this.options.autoCenter&&!this.isDragging?o:i)||n<s)if(this.options.autoCenter&&!this.isDragging){const t=o/20;n-(s+o)>=t&&n<s+i?this.scrollContainer.scrollLeft+=t:this.scrollContainer.scrollLeft=n-o}else if(this.isDragging){const t=10;this.scrollContainer.scrollLeft=n<s?n-t:n-i+t}else this.scrollContainer.scrollLeft=n;{const{scrollLeft:t}=this.scrollContainer,e=t/r,s=(t+i)/r;this.emit("scroll",e,s)}}renderProgress(t,e){isNaN(t)||(this.progressWrapper.style.width=100*t+"%",this.cursor.style.left=100*t+"%",this.cursor.style.marginLeft=100===Math.round(100*t)?`-${this.options.cursorWidth}px`:"",this.isScrolling&&this.options.autoScroll&&this.scrollIntoView(t,e))}}o.MAX_CANVAS_WIDTH=4e3;const a=o,h=class extends r{constructor(){super(...arguments),this.unsubscribe=()=>{}}start(){this.unsubscribe=this.on("tick",(()=>{requestAnimationFrame((()=>{this.emit("tick")}))})),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}},l={height:128,waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoScroll:!0,autoCenter:!0,sampleRate:8e3};class c extends n{static create(t){return new c(t)}constructor(t){super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.subscriptions=[],this.options=Object.assign({},l,t),this.timer=new h,this.renderer=new a(this.options.container,this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initPlugins();const e=this.options.url||this.options.media?.currentSrc||this.options.media?.src;e&&this.load(e,this.options.peaks,this.options.duration)}setOptions(t){this.options={...this.options,...t},this.renderer.setOptions(this.options),t.audioRate&&this.setPlaybackRate(t.audioRate)}initPlayerEvents(){this.subscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),this.isPlaying()),this.emit("timeupdate",t)})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop()})),this.onMediaEvent("ended",(()=>{this.emit("finish")})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",this.getCurrentTime())})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(t=>{this.options.interact&&(this.seekTo(t),this.emit("interaction"),this.emit("click",t))})),this.renderer.on("scroll",((t,e)=>{const i=this.getDuration();this.emit("scroll",t*i,e*i)})),this.renderer.on("render",(()=>{this.emit("redraw")})));{let t;this.subscriptions.push(this.renderer.on("drag",(e=>{this.options.interact&&(this.renderer.renderProgress(e),clearTimeout(t),t=setTimeout((()=>{this.seekTo(e)}),this.isPlaying()?0:200),this.emit("interaction"),this.emit("drag",e))})))}}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),!0),this.emit("timeupdate",t),this.emit("audioprocess",t)})))}initPlugins(){this.options.plugins?.length&&this.options.plugins.forEach((t=>{this.registerPlugin(t)}))}registerPlugin(t){return t.init(this),this.plugins.push(t),t}getWrapper(){return this.renderer.getWrapper()}getScroll(){return this.renderer.getScroll()}getActivePlugins(){return this.plugins}async load(t,e,r){if(this.decodedData=null,this.emit("load",t),e)this.setSrc(t),r||(r=await new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getMediaElement().duration)))}))||0),this.decodedData=i.createBuffer(e,r);else{const e=await s(t);this.setSrc(t,e),this.decodedData=await i.decode(e,this.options.sampleRate)}this.emit("decode",this.getDuration()),this.emit("ready",this.getDuration()),this.renderer.render(this.decodedData)}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",t)}getDecodedData(){return this.decodedData}getDuration(){const t=super.getDuration();return t>0&&t<1/0?t:this.decodedData?.duration||0}toggleInteraction(t){this.options.interact=t}seekTo(t){const e=this.getDuration()*t;this.setTime(e)}playPause(){return this.isPlaying()?(this.pause(),Promise.resolve()):this.play()}stop(){this.pause(),this.setTime(0)}skip(t){this.setTime(this.getCurrentTime()+t)}empty(){this.load("",[[0]],.001)}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.plugins.forEach((t=>t.destroy())),this.timer.destroy(),this.renderer.destroy(),super.destroy()}}const d=c;return e.default})()));
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.WaveSurfer=e():t.WaveSurfer=e()}(this,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var s in i)t.o(i,s)&&!t.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:i[s]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>d});const i={decode:async function(t,e){const i=new AudioContext({sampleRate:e}),s=i.decodeAudioData(t);return s.finally((()=>i.close())),s},createBuffer:function(t,e){return"number"==typeof t[0]&&(t=[t]),function(t){const e=t[0];if(e.some((t=>t>1||t<-1))){const i=e.length;let s=0;for(let t=0;t<i;t++){const i=Math.abs(e[t]);i>s&&(s=i)}for(const e of t)for(let t=0;t<i;t++)e[t]/=s}}(t),{duration:e,length:t[0].length,sampleRate:t[0].length/e,numberOfChannels:t.length,getChannelData:e=>t?.[e],copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}},s=async function(t){return fetch(t).then((t=>t.arrayBuffer()))},r=class{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),s=this.on(t,(()=>{i(),s()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}},n=class extends r{constructor(t){super(),this.isExternalMedia=!1,t.media?(this.media=t.media,this.isExternalMedia=!0):this.media=document.createElement("audio"),t.autoplay&&(this.media.autoplay=!0),null!=t.playbackRate&&(this.media.playbackRate=t.playbackRate)}onMediaEvent(t,e,i){return this.media.addEventListener(t,e,i),()=>this.media.removeEventListener(t,e)}onceMediaEvent(t,e){return this.onMediaEvent(t,e,{once:!0})}revokeSrc(){(this.media.currentSrc||this.media.src||"").startsWith("blob:")&&URL.revokeObjectURL(this.media.currentSrc)}setSrc(t,e){if((this.media.currentSrc||this.media.src||"")===t)return;this.revokeSrc();const i=e?URL.createObjectURL(new Blob([e],{type:"audio/wav"})):t;this.media.src=i}destroy(){this.media.pause(),this.revokeSrc(),this.isExternalMedia||this.media.remove()}play(){return this.media.play()}pause(){this.media.pause()}isPlaying(){return this.media.currentTime>0&&!this.media.paused&&!this.media.ended}setTime(t){this.media.currentTime=t}getDuration(){return this.media.duration}getCurrentTime(){return this.media.currentTime}getVolume(){return this.media.volume}setVolume(t){this.media.volume=t}getMuted(){return this.media.muted}setMuted(t){this.media.muted=t}getPlaybackRate(){return this.media.playbackRate}setPlaybackRate(t,e){null!=e&&(this.media.preservesPitch=e),this.media.playbackRate=t}getMediaElement(){return this.media}setSinkId(t){return this.media.setSinkId(t)}};class o extends r{constructor(t){let e;if(super(),this.timeouts=[],this.isScrolling=!1,this.audioData=null,this.resizeObserver=null,this.isDragging=!1,this.options=t,"string"==typeof t.container?e=document.querySelector(t.container):t.container instanceof HTMLElement&&(e=t.container),!e)throw new Error("Container not found");const[i,s]=this.initHtml();e.appendChild(i),this.container=i,this.scrollContainer=s.querySelector(".scroll"),this.wrapper=s.querySelector(".wrapper"),this.canvasWrapper=s.querySelector(".canvases"),this.progressWrapper=s.querySelector(".progress"),this.cursor=s.querySelector(".cursor"),this.initEvents()}initEvents(){this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",i)})),this.initDrag(),this.scrollContainer.addEventListener("scroll",(()=>{const{scrollLeft:t,scrollWidth:e,clientWidth:i}=this.scrollContainer,s=t/e,r=(t+i)/e;this.emit("scroll",s,r)}));const t=this.createDelay(100);this.resizeObserver=new ResizeObserver((()=>{t((()=>this.reRender()))})),this.resizeObserver.observe(this.scrollContainer)}initDrag(){this.wrapper.addEventListener("mousedown",(t=>{const e=t.clientX,i=t=>{if(Math.abs(t.clientX-e)>=5){this.isDragging=!0;const e=this.wrapper.getBoundingClientRect();this.emit("drag",Math.max(0,Math.min(1,(t.clientX-e.left)/e.width)))}},s=()=>{document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",s),this.isDragging=!1};document.addEventListener("mousemove",i),document.addEventListener("mouseup",s)}))}initHtml(){const t=document.createElement("div"),e=t.attachShadow({mode:"open"});return e.innerHTML=`\n <style>\n :host {\n user-select: none;\n }\n :host .scroll {\n overflow-x: auto;\n overflow-y: hidden;\n width: 100%;\n position: relative;\n }\n :host .noScrollbar {\n scrollbar-color: transparent;\n scrollbar-width: none;\n }\n :host .noScrollbar::-webkit-scrollbar {\n display: none;\n -webkit-appearance: none;\n }\n :host .wrapper {\n position: relative;\n overflow: visible;\n z-index: 2;\n }\n :host .canvases {\n min-height: ${this.options.height}px;\n }\n :host .canvases > div {\n position: relative;\n }\n :host canvas {\n display: block;\n position: absolute;\n top: 0;\n image-rendering: pixelated;\n }\n :host .progress {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n width: 0;\n height: 100%;\n overflow: hidden;\n }\n :host .progress > div {\n position: relative;\n }\n :host .cursor {\n pointer-events: none;\n position: absolute;\n z-index: 5;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n }\n </style>\n\n <div class="scroll" part="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress"></div>\n <div class="cursor" part="cursor"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){this.options=t,this.reRender()}getWrapper(){return this.wrapper}getScroll(){return this.scrollContainer.scrollLeft}destroy(){this.container.remove(),this.resizeObserver?.disconnect()}createDelay(t=10){const e={};return this.timeouts.push(e),i=>{e.timeout&&clearTimeout(e.timeout),e.timeout=setTimeout(i,t)}}convertColorValues(t){if(!Array.isArray(t))return t||"";if(t.length<2)return 1===t.length?t[0]:"";const e=document.createElement("canvas"),i=e.getContext("2d").createLinearGradient(0,0,0,e.height),s=1/(t.length-1);return t.forEach(((t,e)=>{const r=e*s;i.addColorStop(r,t)})),i}renderSingleCanvas(t,e,i,s,r,n,o){const a=window.devicePixelRatio||1,h=e.height||0,l=null==e.barWidth||isNaN(e.barWidth)?1:e.barWidth*a,c=null==e.barGap||isNaN(e.barGap)?e.barWidth?l/2:0:e.barGap*a,d=e.barRadius||0,u=e.barHeight||1,p=1===t.length,m=t[0],g=p?m:t[1],f=p&&g.some((t=>t<0)),v=m.length,y=Math.floor(i/(l+c))/v,b=h/2;let C=0,w=0,S=0;const E=document.createElement("canvas");E.width=Math.round(i*(r-s)/v),E.height=h,E.style.width=`${Math.floor(E.width/a)}px`,E.style.height=`${e.height}px`,E.style.left=`${Math.floor(s*i/a/v)}px`,n.appendChild(E);const M=E.getContext("2d",{desynchronized:!0});M.beginPath(),M.fillStyle=this.convertColorValues(e.waveColor),M.roundRect||(M.roundRect=M.fillRect);for(let t=s;t<r;t++){const e=Math.round((t-s)*y);if(e>C){const t=Math.round(w*b*u),i=Math.round(S*b*u);M.roundRect(C*(l+c),b-t,l,t+(i||1),d),C=e,w=0,S=0}const i=f?m[t]:Math.abs(m[t]),r=f?g[t]:Math.abs(g[t]);i>w&&(w=i),(f?r<-S:r>S)&&(S=r<0?-r:r)}M.fill(),M.closePath();const D=E.cloneNode();o.appendChild(D);const R=D.getContext("2d",{desynchronized:!0});E.width>0&&E.height>0&&R.drawImage(E,0,0),R.globalCompositeOperation="source-in",R.fillStyle=this.convertColorValues(e.progressColor),R.fillRect(0,0,E.width,E.height)}renderWaveform(t,e,i){const s=document.createElement("div");s.style.height=`${e.height}px`,this.canvasWrapper.appendChild(s);const r=s.cloneNode();this.progressWrapper.appendChild(r);const{scrollLeft:n,scrollWidth:a,clientWidth:h}=this.scrollContainer,l=t[0].length,c=l/a,d=Math.min(o.MAX_CANVAS_WIDTH,h),u=Math.floor(Math.abs(n)*c),p=Math.ceil(u+d*c),m=p-u,g=(n,o)=>{this.renderSingleCanvas(t,e,i,Math.max(0,n),Math.min(o,l),s,r)},f=this.createDelay(),v=this.createDelay(),y=(t,e)=>{g(t,e),t>0&&f((()=>{y(t-m,e-m)}))},b=(t,e)=>{g(t,e),e<l&&v((()=>{b(t+m,e+m)}))};y(u,p),p<l&&b(p,p+m)}render(t){this.timeouts.forEach((t=>t.timeout&&clearTimeout(t.timeout))),this.timeouts=[];const e=window.devicePixelRatio||1,i=this.scrollContainer.clientWidth,s=Math.ceil(t.duration*(this.options.minPxPerSec||0));this.isScrolling=s>i;const r=this.options.fillParent&&!this.isScrolling,n=(r?i:s)*e;if(this.wrapper.style.width=r?"100%":`${s}px`,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.cursor.style.backgroundColor=`${this.options.cursorColor||this.options.progressColor}`,this.cursor.style.width=`${this.options.cursorWidth}px`,this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="",this.options.splitChannels)for(let e=0;e<t.numberOfChannels;e++){const i={...this.options,...this.options.splitChannels[e]};this.renderWaveform([t.getChannelData(e)],i,n)}else{const e=[t.getChannelData(0)];t.numberOfChannels>1&&e.push(t.getChannelData(1)),this.renderWaveform(e,this.options,n)}this.audioData=t,this.emit("render")}reRender(){if(!this.audioData)return;const t=this.progressWrapper.clientWidth;this.render(this.audioData);const e=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=e-t}zoom(t){this.options.minPxPerSec=t,this.reRender()}scrollIntoView(t,e=!1){const{clientWidth:i,scrollLeft:s,scrollWidth:r}=this.scrollContainer,n=r*t,o=i/2;if(n>s+(e&&this.options.autoCenter&&!this.isDragging?o:i)||n<s)if(this.options.autoCenter&&!this.isDragging){const t=o/20;n-(s+o)>=t&&n<s+i?this.scrollContainer.scrollLeft+=t:this.scrollContainer.scrollLeft=n-o}else if(this.isDragging){const t=10;this.scrollContainer.scrollLeft=n<s?n-t:n-i+t}else this.scrollContainer.scrollLeft=n;{const{scrollLeft:t}=this.scrollContainer,e=t/r,s=(t+i)/r;this.emit("scroll",e,s)}}renderProgress(t,e){isNaN(t)||(this.progressWrapper.style.width=100*t+"%",this.cursor.style.left=100*t+"%",this.cursor.style.marginLeft=100===Math.round(100*t)?`-${this.options.cursorWidth}px`:"",this.isScrolling&&this.options.autoScroll&&this.scrollIntoView(t,e))}}o.MAX_CANVAS_WIDTH=4e3;const a=o,h=class extends r{constructor(){super(...arguments),this.unsubscribe=()=>{}}start(){this.unsubscribe=this.on("tick",(()=>{requestAnimationFrame((()=>{this.emit("tick")}))})),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}},l={height:128,waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoScroll:!0,autoCenter:!0,sampleRate:8e3};class c extends n{static create(t){return new c(t)}constructor(t){super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.subscriptions=[],this.options=Object.assign({},l,t),this.timer=new h,this.renderer=new a(this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initPlugins();const e=this.options.url||this.options.media?.currentSrc||this.options.media?.src;e&&this.load(e,this.options.peaks,this.options.duration)}setOptions(t){this.options={...this.options,...t},this.renderer.setOptions(this.options),t.audioRate&&this.setPlaybackRate(t.audioRate)}initPlayerEvents(){this.subscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),this.isPlaying()),this.emit("timeupdate",t)})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop()})),this.onMediaEvent("ended",(()=>{this.emit("finish")})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",this.getCurrentTime())})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(t=>{this.options.interact&&(this.seekTo(t),this.emit("interaction"),this.emit("click",t))})),this.renderer.on("scroll",((t,e)=>{const i=this.getDuration();this.emit("scroll",t*i,e*i)})),this.renderer.on("render",(()=>{this.emit("redraw")})));{let t;this.subscriptions.push(this.renderer.on("drag",(e=>{this.options.interact&&(this.renderer.renderProgress(e),clearTimeout(t),t=setTimeout((()=>{this.seekTo(e)}),this.isPlaying()?0:200),this.emit("interaction"),this.emit("drag",e))})))}}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),!0),this.emit("timeupdate",t),this.emit("audioprocess",t)})))}initPlugins(){this.options.plugins?.length&&this.options.plugins.forEach((t=>{this.registerPlugin(t)}))}registerPlugin(t){return t.init(this),this.plugins.push(t),t}getWrapper(){return this.renderer.getWrapper()}getScroll(){return this.renderer.getScroll()}getActivePlugins(){return this.plugins}async load(t,e,r){if(this.decodedData=null,this.emit("load",t),e)this.setSrc(t),r||(r=await new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getMediaElement().duration)))}))||0),this.decodedData=i.createBuffer(e,r);else{const e=await s(t);this.setSrc(t,e),this.decodedData=await i.decode(e,this.options.sampleRate)}this.emit("decode",this.getDuration()),this.emit("ready",this.getDuration()),this.renderer.render(this.decodedData)}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",t)}getDecodedData(){return this.decodedData}getDuration(){const t=super.getDuration();return t>0&&t<1/0?t:this.decodedData?.duration||0}toggleInteraction(t){this.options.interact=t}seekTo(t){const e=this.getDuration()*t;this.setTime(e)}playPause(){return this.isPlaying()?(this.pause(),Promise.resolve()):this.play()}stop(){this.pause(),this.setTime(0)}skip(t){this.setTime(this.getCurrentTime()+t)}empty(){this.load("",[[0]],.001)}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.plugins.forEach((t=>t.destroy())),this.timer.destroy(),this.renderer.destroy(),super.destroy()}}const d=c;return e.default})()));
|