wavesurfer.js 7.0.0-alpha.22 → 7.0.0-alpha.24
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/dist/base-plugin.d.ts +6 -5
- package/dist/base-plugin.js +4 -2
- package/dist/player.d.ts +26 -9
- package/dist/player.js +38 -18
- package/dist/plugins/envelope.d.ts +4 -2
- package/dist/plugins/envelope.js +21 -11
- package/dist/plugins/envelope.min.js +1 -0
- package/dist/plugins/minimap.d.ts +6 -4
- package/dist/plugins/minimap.js +18 -7
- package/dist/plugins/minimap.min.js +1 -0
- package/dist/plugins/multitrack.d.ts +1 -2
- package/dist/plugins/multitrack.js +15 -17
- package/dist/plugins/multitrack.min.js +1 -0
- package/dist/plugins/regions.d.ts +5 -2
- package/dist/plugins/regions.js +26 -10
- package/dist/plugins/regions.min.js +1 -0
- package/dist/plugins/timeline.d.ts +4 -2
- package/dist/plugins/timeline.js +13 -4
- package/dist/plugins/timeline.min.js +1 -0
- package/dist/renderer.d.ts +3 -1
- package/dist/renderer.js +26 -13
- package/dist/{index.d.ts → wavesurfer.d.ts} +18 -35
- package/dist/{index.js → wavesurfer.js} +49 -102
- package/dist/wavesurfer.min.js +1 -1
- package/package.json +20 -5
- package/dist/wavesurfer.Minimap.min.js +0 -1
- package/dist/wavesurfer.Multitrack.min.js +0 -1
- package/dist/wavesurfer.Regions.min.js +0 -1
- package/dist/wavesurfer.Timeline.min.js +0 -1
|
@@ -0,0 +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{wavesurfer;container;wrapper;subscriptions=[];options;constructor(t){super(),this.options=t}init(t){this.wavesurfer=t.wavesurfer,this.container=t.container,this.wrapper=t.wrapper}destroy(){this.subscriptions.forEach((t=>t()))}}const r=n},139:(t,e,i)=>{i.d(e,{Z:()=>s});const s=class{eventTarget;constructor(){this.eventTarget=new EventTarget}emit(t,e){const i=new CustomEvent(String(t),{detail:e});this.eventTarget.dispatchEvent(i)}on(t,e,i){const s=t=>{t instanceof CustomEvent&&e(t.detail)},n=String(t);return this.eventTarget.addEventListener(n,s,{once:i}),()=>this.eventTarget.removeEventListener(n,s)}once(t,e){return this.on(t,e,!0)}}},919:(t,e,i)=>{i.d(e,{default:()=>o});var s=i(284);const n={startTime:0,endTime: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 r extends s.Z{options;svg=null;audioContext=null;gainNode=null;volume=1;isFadingIn=!1;isFadingOut=!1;constructor(t){super(t),this.options=Object.assign({},n,t),this.options.lineColor=this.options.lineColor||n.lineColor,this.options.dragPointFill=this.options.dragPointFill||n.dragPointFill,this.options.dragPointStroke=this.options.dragPointStroke||n.dragPointStroke,this.volume=this.options.volume??1}static create(t){return new r(t)}init(t){if(super.init(t),!this.wavesurfer)throw Error("WaveSurfer is not initialized");let e;this.subscriptions.push(this.wavesurfer.once("decode",(({duration:t})=>{this.options.startTime=this.options.startTime||0,this.options.endTime=this.options.endTime||t,this.options.fadeInEnd=this.options.fadeInEnd||this.options.startTime,this.options.fadeOutStart=this.options.fadeOutStart||this.options.endTime,this.initWebAudio(),this.initSvg(),this.initFadeEffects()}))),this.subscriptions.push(this.wavesurfer.on("zoom",(()=>{e&&clearTimeout(e),e=setTimeout((()=>{this.svg?.remove(),this.initSvg()}),100)})))}makeDraggable(t,e){t.addEventListener("mousedown",(t=>{let i=t.clientX,s=t.clientY;const n=this.wavesurfer?.options.interact||!0;let r;this.wavesurfer?.toggleInteractive(!1);const o=t=>{const n=t.clientX-i,r=t.clientY-s;i=t.clientX,s=t.clientY,e(n,r)},a=()=>{document.removeEventListener("mousemove",o),document.removeEventListener("mouseup",a),r&&clearTimeout(r),r=setTimeout((()=>{this.wavesurfer?.toggleInteractive(n)}),100)};document.addEventListener("mousemove",o),document.addEventListener("mouseup",a),t.preventDefault(),t.stopPropagation()}))}renderPolyline(){if(!this.svg||!this.wrapper||!this.wavesurfer)return;const t=this.svg.querySelector("polyline"),e=t.points,i=e.getItem(1).y,s=this.wrapper.clientWidth,n=this.wavesurfer.getDuration();e.getItem(0).x=this.options.startTime/n*s,e.getItem(3).x=this.options.endTime/n*s;const r=this.svg.querySelector("line");r.setAttribute("x1",e.getItem(1).x.toString()),r.setAttribute("x2",e.getItem(2).x.toString()),r.setAttribute("y1",i.toString()),r.setAttribute("y2",i.toString());const o=this.svg.querySelectorAll("circle");for(let e=0;e<o.length;e++){const s=o[e],n=t.points.getItem(e+1);s.setAttribute("cx",n.x.toString()),s.setAttribute("cy",i.toString())}}initSvg(){if(!this.wrapper||!this.wavesurfer)return;const t=this.wrapper.clientWidth,e=this.wrapper.clientHeight,i=this.wavesurfer.getDuration(),s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("width","100%"),s.setAttribute("height","100%"),s.setAttribute("viewBox",`0 0 ${t} ${e}`),s.setAttribute("preserveAspectRatio","none"),s.setAttribute("style","position: absolute; left: 0; top: 0; z-index: 4; pointer-events: none;"),this.svg=s;const n=document.createElementNS("http://www.w3.org/2000/svg","polyline");n.setAttribute("points","0,0 0,0 0,0 0,0"),n.setAttribute("stroke",this.options.lineColor),n.setAttribute("stroke-width",this.options.lineWidth),n.setAttribute("fill","none"),n.setAttribute("style","pointer-events: none"),s.appendChild(n);const r=document.createElementNS("http://www.w3.org/2000/svg","line");r.setAttribute("stroke","none"),r.setAttribute("stroke-width",(3*this.options.lineWidth).toString()),r.setAttribute("style","cursor: ns-resize; pointer-events: all;"),s.appendChild(r);const o=n.points,a=this.options.dragPointSize/2,d=e-this.volume*e+a;o.getItem(0).x=this.options.startTime/i*t,o.getItem(0).y=e,o.getItem(1).x=this.options.fadeInEnd/i*t,o.getItem(1).y=d,o.getItem(2).x=this.options.fadeOutStart/i*t,o.getItem(2).y=d,o.getItem(3).x=this.options.endTime/i*t,o.getItem(3).y=e,[1,2].forEach((()=>{const t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("r",(this.options.dragPointSize/2).toString()),t.setAttribute("fill",this.options.dragPointFill),t.setAttribute("stroke",this.options.dragPointStroke||this.options.dragPointFill),t.setAttribute("stroke-width","2"),t.setAttribute("style","cursor: ew-resize; pointer-events: all;"),s.appendChild(t)})),this.wrapper.appendChild(s),this.renderPolyline();const h=t=>{const i=o.getItem(1).y+t-a;if(i<-.5||i>e)return;o.getItem(1).y=i+a,o.getItem(2).y=i+a,this.renderPolyline();const s=Math.min(1,Math.max(0,(e-i)/e));this.onVolumeChange(s),this.renderPolyline()},l=(e,s,r)=>{const o=n.points.getItem(r),a=o.x+e,d=a/t*i;1===r&&d>this.options.fadeOutStart||d<this.options.startTime||2===r&&d<this.options.fadeInEnd||d>this.options.endTime||(o.x=a,1===r?(this.options.fadeInEnd=d,this.emit("fade-in-change",{time:d})):2===r&&(this.options.fadeOutStart=d,this.emit("fade-out-change",{time:d})),s>1||s<-1?h(s):this.renderPolyline())};this.makeDraggable(r,((t,e)=>h(e)));const u=s.querySelectorAll("circle");for(let t=0;t<u.length;t++){const e=t+1;this.makeDraggable(u[t],((t,i)=>l(t,i,e)))}}destroy(){this.svg?.remove(),super.destroy()}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.gainNode.gain.value=this.volume,e.createMediaElementSource(t).connect(this.gainNode),this.gainNode.connect(e.destination),this.audioContext=e}naturalVolume(t){return 1e-4+.9999*Math.pow(t,3)}onVolumeChange(t){t=this.naturalVolume(t),this.volume=t,this.emit("volume-change",{volume:t}),this.gainNode&&(this.gainNode.gain.value=t)}initFadeEffects(){if(!this.audioContext||!this.wavesurfer)return;const t=this.wavesurfer.on("timeupdate",(({currentTime: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.startTime&&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.endTime)return this.isFadingOut=!0,void this.gainNode.gain.linearRampToValueAtTime(0,this.audioContext.currentTime+(this.options.endTime-t));let e=!1;this.isFadingIn&&(t<this.options.startTime||t>this.options.fadeInEnd)&&(this.isFadingIn=!1,e=!0),this.isFadingOut&&(t<this.options.fadeOutStart||t>=this.options.endTime)&&(this.isFadingOut=!1,e=!0),e&&(this.gainNode.gain.cancelScheduledValues(this.audioContext.currentTime),this.gainNode.gain.value=this.volume)}));this.subscriptions.push(t)}getCurrentVolume(){return this.gainNode?this.gainNode.gain.value:this.volume}setStartTime(t){this.options.startTime=t,this.renderPolyline()}setEndTime(t){this.options.endTime=t,this.renderPolyline()}}const o=r},76:(t,e,i)=>{i.d(e,{default:()=>d});var s=i(284);const n={dragSelection:!0,draggable:!0,resizable:!0},r=(t,e)=>{for(const i in e)t.style[i]=e[i]||""},o=(t,e)=>{const i=document.createElement(t);return r(i,e),i};class a extends s.Z{dragStart=NaN;regionsContainer;regions=[];createdRegion=null;modifiedRegion=null;isResizingLeft=!1;isMoving=!1;wasInteractive=!0;constructor(t){super(t||{}),this.options=Object.assign({},n,t),this.regionsContainer=this.initRegionsContainer()}static create(t){return new a(t)}init(t){if(super.init(t),!this.wavesurfer||!this.wrapper)throw Error("WaveSurfer is not initialized");this.subscriptions.push(this.wavesurfer.once("decode",(()=>{this.wrapper?.appendChild(this.regionsContainer)}))),this.wrapper.addEventListener("mousedown",this.handleMouseDown),document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("mouseup",this.handleMouseUp)}destroy(){this.wrapper?.removeEventListener("mousedown",this.handleMouseDown),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp,!0),this.regionsContainer.remove(),super.destroy()}initRegionsContainer(){return o("div",{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",zIndex:"3",pointerEvents:"none"})}handleMouseDown=t=>{if(this.options.draggable||this.options.resizable||this.options.dragSelection){if(!this.wrapper)return;this.dragStart=t.clientX-this.wrapper.getBoundingClientRect().left}};handleMouseMove=t=>{if(!this.wrapper)return;const e=this.wrapper.getBoundingClientRect(),{width:i}=e,s=t.clientX-e.left;if(this.options.draggable&&this.modifiedRegion&&this.isMoving)return this.moveRegion(this.modifiedRegion,(s-this.dragStart)/i),void(this.dragStart=s);if(this.options.resizable&&this.modifiedRegion)this.updateRegion(this.modifiedRegion,this.isResizingLeft?s/i:void 0,this.isResizingLeft?void 0:s/i);else if(this.options.dragSelection&&!isNaN(this.dragStart)){const e=t.clientX-this.regionsContainer.getBoundingClientRect().left;e-this.dragStart>=10&&(this.createdRegion?this.updateRegion(this.createdRegion,this.dragStart/i,e/i):(this.wasInteractive=this.wavesurfer?.options.interact||!0,this.wavesurfer?.toggleInteractive(!1),this.createdRegion=this.createRegion(this.dragStart/i,e/i)))}};handleMouseUp=()=>{this.createdRegion&&(this.addRegion(this.createdRegion),this.createdRegion=null),this.modifiedRegion=null,this.isMoving=!1,this.dragStart=NaN,this.wavesurfer?.toggleInteractive(this.wasInteractive)};createRegionElement(t,e,i=""){const s=t===e,n=o("div",{position:"absolute",left:100*t+"%",width:100*(e-t)+"%",height:"100%",backgroundColor:s?"":"rgba(0, 0, 0, 0.1)",borderRadius:"2px",boxSizing:"border-box",borderLeft:s?"2px solid rgba(0, 0, 0, 0.5)":"",transition:"background-color 0.2s ease",cursor:this.options.draggable?"move":"",pointerEvents:"all",whiteSpace:s?"nowrap":"",padding:"0.2em"});n.textContent=i;const a=o("div",{position:"absolute",left:"0",top:"0",width:"6px",height:"100%",cursor:this.options.resizable?"ew-resize":"",pointerEvents:"all",borderLeft:s?"":"2px solid rgba(0, 0, 0, 0.5)",borderRadius:"2px 0 0 2px"});n.appendChild(a);const d=a.cloneNode();r(d,{left:"",right:"0",borderLeft:"",borderRight:s?"":"2px solid rgba(0, 0, 0, 0.5)",borderRadius:"0 2px 2px 0"}),n.appendChild(d),a.addEventListener("mousedown",(t=>{this.options.resizable&&(t.stopPropagation(),this.modifiedRegion=this.regions.find((t=>t.element===n))||null,this.isResizingLeft=!0,this.isMoving=!1)})),d.addEventListener("mousedown",(t=>{this.options.resizable&&(t.stopPropagation(),this.modifiedRegion=this.regions.find((t=>t.element===n))||null,this.isResizingLeft=!1,this.isMoving=!1)})),n.addEventListener("mousedown",(()=>{this.options.draggable&&(this.modifiedRegion=this.regions.find((t=>t.element===n))||null,this.isMoving=!0)})),n.addEventListener("click",(()=>{const t=this.regions.find((t=>t.element===n));t&&this.emit("region-clicked",{region:t})})),this.regionsContainer.appendChild(n);const h=n.getBoundingClientRect().left,l=n.scrollWidth,u=this.regions.filter((t=>{const{left:e}=t.element.getBoundingClientRect(),i=t.element.scrollWidth;return h<e+i&&e<h+l})).map((t=>parseFloat(t.element.style.paddingTop))).reduce(((t,e)=>t+e),0);return u>0&&(n.style.paddingTop=`${u+1}em`),n}createRegion(t,e,i=""){const s=this.wavesurfer?.getDuration()||0;return{element:this.createRegionElement(t,e,i),start:t,end:e,startTime:t*s,endTime:e*s,title:i}}addRegion(t){this.regions.push(t),this.emit("region-created",{region:t})}updateRegion(t,e,i){const s=this.wavesurfer?.getDuration()||0;null!=e&&(t.start=e,t.element.style.left=100*t.start+"%",t.element.style.width=100*(t.end-t.start)+"%",t.startTime=e*s),null!=i&&(t.end=i,t.element.style.width=100*(t.end-t.start)+"%",t.endTime=i*s),this.emit("region-updated",{region:t})}moveRegion(t,e){this.updateRegion(t,t.start+e,t.end+e)}add(t,e,i="",s=""){const n=this.wavesurfer?.getDuration()||0,r=t/n,o=e/n,a=this.createRegion(r,o,i);return this.addRegion(a),s&&this.setRegionColor(a,s),a}setRegionColor(t,e){t.element.style[t.startTime===t.endTime?"borderColor":"backgroundColor"]=e}}const d=a},954:(t,e,i)=>{i.d(e,{default:()=>o});var s=i(284);const n={height:20};class r extends s.Z{timelineWrapper;options;constructor(t){super(t),this.options=Object.assign({},n,t),this.timelineWrapper=this.initTimelineWrapper()}static create(t){return new r(t)}init(t){if(super.init(t),!this.wavesurfer||!this.wrapper)throw Error("WaveSurfer is not initialized");(this.options.container??this.wrapper).appendChild(this.timelineWrapper),this.options.duration?this.initTimeline(this.options.duration):this.subscriptions.push(this.wavesurfer.on("decode",(({duration:t})=>{this.initTimeline(t)})))}destroy(){this.timelineWrapper.remove(),super.destroy()}initTimelineWrapper(){return document.createElement("div")}formatTime(t){return t/60>1?`${Math.round(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=Math.round(this.timelineWrapper.scrollWidth*devicePixelRatio)/t,i=this.options.timeInterval??this.defaultTimeInterval(e),s=this.options.primaryLabelInterval??this.defaultPrimaryLabelInterval(e),n=this.options.secondaryLabelInterval??this.defaultSecondaryLabelInterval(e),r=document.createElement("div");r.setAttribute("style",`\n height: ${this.options.height}px;\n overflow: hidden;\n display: flex;\n justify-content: space-between;\n align-items: flex-end;\n font-size: ${this.options.height/2}px;\n white-space: nowrap;\n `);const o=document.createElement("div");o.setAttribute("style","\n width: 1px;\n height: 50%;\n display: flex;\n flex-direction: column;\n justify-content: 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=o.cloneNode(),i=e%s==0;(i||e%n==0)&&(t.style.height="100%",t.style.textIndent="3px",t.textContent=this.formatTime(e),i&&(t.style.opacity="1")),r.appendChild(t)}this.timelineWrapper.appendChild(r),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:()=>f});var t=i(139);class e extends t.Z{options;container;scrollContainer;wrapper;canvasWrapper;progressWrapper;timeout=null;isScrolling=!1;audioData=null;resizeObserver=null;constructor(t){super(),this.options=t;let e=null;if("string"==typeof this.options.container?e=document.querySelector(this.options.container):this.options.container instanceof HTMLElement&&(e=this.options.container),!e)throw new Error("Container not found");const i=document.createElement("div"),s=i.attachShadow({mode:"open"});s.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 ${this.options.hideScrollbar?"scrollbar-color: transparent;":""}\n }\n :host ::-webkit-scrollbar {\n display: ${this.options.hideScrollbar?"none":"auto"};\n }\n :host .wrapper {\n position: relative;\n min-width: 100%;\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 height: ${this.options.height}px;\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: ${this.options.height}px;\n overflow: hidden;\n box-sizing: border-box;\n border-right-style: solid;\n border-right-width: ${this.options.cursorWidth}px;\n border-right-color: ${this.options.cursorColor||this.options.progressColor};\n }\n </style>\n\n <div class="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress"></div>\n </div>\n </div>\n `,this.container=i,this.scrollContainer=s.querySelector(".scroll"),this.wrapper=s.querySelector(".wrapper"),this.canvasWrapper=s.querySelector(".canvases"),this.progressWrapper=s.querySelector(".progress"),e.appendChild(i),this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",{relativeX:i})})),this.resizeObserver=new ResizeObserver((()=>{this.delay((()=>this.audioData&&this.zoom(this.audioData,this.options.minPxPerSec)),100)})),this.resizeObserver.observe(this.scrollContainer)}getContainer(){return this.scrollContainer}getWrapper(){return this.wrapper}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?this.options.barWidth*s:1,r=null!=this.options.barGap?this.options.barGap*s:this.options.barWidth?n/2:0,o=this.options.barRadius??0,a=t[0],d=a.length,h=Math.floor(e/(n+r))/d,l=i/2,u=1===t.length,c=u?a:t[1],p=u&&c.some((t=>t<0)),m=(t,i)=>{let u=0,m=0,g=0;const v=document.createElement("canvas");v.width=Math.round(e*(i-t)/d),v.height=this.options.height,v.style.width=`${Math.floor(v.width/s)}px`,v.style.left=`${Math.floor(t*e/s/d)}px`,this.canvasWrapper.appendChild(v);const f=v.getContext("2d",{desynchronized:!0});f.beginPath(),f.fillStyle=this.options.waveColor,f.roundRect||(f.roundRect=f.fillRect);for(let e=t;e<i;e++){const i=Math.round((e-t)*h);if(i>u){const t=Math.round(m*l),e=Math.round(g*l);f.roundRect(u*(n+r),l-t,n,t+e||1,o),u=i,m=0,g=0}const s=p?a[e]:Math.abs(a[e]),d=p?c[e]:Math.abs(c[e]);s>m&&(m=s),(p?d<-g:d>g)&&(g=d<0?-d:d)}f.fill(),f.closePath();const y=v.cloneNode();this.progressWrapper.appendChild(y);const b=y.getContext("2d",{desynchronized:!0});b.drawImage(v,0,0),b.globalCompositeOperation="source-in",b.fillStyle=this.options.progressColor,b.fillRect(0,0,v.width,v.height)};this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="";const{scrollLeft:g,scrollWidth:v,clientWidth:f}=this.scrollContainer,y=d/v,b=Math.floor(g*y),w=Math.ceil(Math.min(v,g+f)*y);m(b,w);const C=w-b;for(let t=w;t<d;t+=C)await this.delay((()=>{m(t,Math.min(d,t+C))}));for(let t=b-1;t>=0;t-=C)await this.delay((()=>{m(Math.max(0,t-C),t)}))}render(t){const e=window.devicePixelRatio||1,i=this.options.fillParent?this.scrollContainer.clientWidth*e:0,s=Math.max(1,t.duration*this.options.minPxPerSec),n=s>i?s:i,{height:r}=this.options;this.isScrolling=n>i,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.wrapper.style.width=`${Math.floor(n/e)}px`;const o=[t.getChannelData(0)];t.numberOfChannels>1&&o.push(t.getChannelData(1)),this.renderPeaks(o,n,r,e),this.audioData=t}zoom(t,e){const i=this.progressWrapper.clientWidth;this.options.minPxPerSec=e,this.render(t);const s=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=s-i}renderProgress(t,e=!1){if(this.progressWrapper.style.width=100*t+"%",this.isScrolling){const t=this.scrollContainer.clientWidth,i=t/2,s=this.progressWrapper.clientWidth,n=e?i:t;s>this.scrollContainer.scrollLeft+n&&(this.scrollContainer.scrollLeft=s-i)}}}const n=e;class r extends t.Z{media;subscriptions=[];isExternalMedia=!1;hasPlayedOnce=!1;constructor(t){super(),t.media?(this.media=t.media,this.isExternalMedia=!0):this.media=document.createElement("audio"),this.subscriptions.push(this.onceMediaEvent("play",(()=>{this.hasPlayedOnce=!0}))),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})}loadUrl(t){this.media.src=t}destroy(){this.media.pause(),this.subscriptions.forEach((t=>t())),this.isExternalMedia||this.media.remove()}play(){this.media.play()}pause(){this.media.pause()}isPlaying(){return this.media.currentTime>0&&!this.media.paused&&!this.media.ended}seekTo(t){!this.hasPlayedOnce&&navigator.userAgent.match(/(iPad|iPhone|iPod)/g)&&this.media.play()?.then?.((()=>{setTimeout((()=>this.media.pause()),10)})),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}}const o=r;class a extends t.Z{unsubscribe=()=>{};start(){this.unsubscribe=this.on("tick",(()=>{requestAnimationFrame((()=>{this.emit("tick")}))})),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}}const d=a,h={height:128,waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoCenter:!0};class l extends o{options;fetcher;decoder;renderer;timer;plugins=[];decodedData=null;canPlay=!1;static create(t){return new l(t)}constructor(t){super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.options=Object.assign({},h,t),this.fetcher=new class{async load(t){return fetch(t).then((t=>t.arrayBuffer()))}},this.decoder=new class{audioCtx=null;initAudioContext(t){this.audioCtx=new AudioContext({latencyHint:"playback",sampleRate:t})}constructor(){try{this.initAudioContext(3e3)}catch(t){this.initAudioContext(8e3)}}async decode(t){if(!this.audioCtx)throw new Error("AudioContext is not initialized");return this.audioCtx.decodeAudioData(t)}destroy(){this.audioCtx?.close(),this.audioCtx=null}},this.timer=new d,this.renderer=new n({container:this.options.container,height:this.options.height,waveColor:this.options.waveColor,progressColor:this.options.progressColor,cursorColor:this.options.cursorColor,cursorWidth:this.options.cursorWidth,minPxPerSec:this.options.minPxPerSec,fillParent:this.options.fillParent,barWidth:this.options.barWidth,barGap:this.options.barGap,barRadius:this.options.barRadius,hideScrollbar:this.options.hideScrollbar}),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initReadyEvent(),this.initPlugins();const e=this.options.url||this.options.media?.src;e&&this.load(e,this.options.peaks,this.options.duration)}initPlayerEvents(){this.subscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),this.options.autoCenter&&this.isPlaying()),this.emit("timeupdate",{currentTime:t})})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop()})),this.onMediaEvent("canplay",(()=>{this.canPlay=!0,this.emit("canplay",{duration:this.getDuration()})})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",{currentTime:this.getCurrentTime()})})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(({relativeX:t})=>{if(this.options.interact){const e=this.getDuration()*t;this.seekTo(e),this.emit("seekClick",{currentTime:this.getCurrentTime()})}})))}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),!0),this.emit("timeupdate",{currentTime:t})})))}initReadyEvent(){const t=()=>{this.decodedData&&this.canPlay&&this.emit("ready",{duration:this.getDuration()})};this.subscriptions.push(this.on("decode",t),this.on("canplay",t))}initPlugins(){this.options.plugins?.length&&this.options.plugins.forEach((t=>{this.registerPlugin(t)}))}registerPlugin(t){return t.init({wavesurfer:this,container:this.renderer.getContainer(),wrapper:this.renderer.getWrapper()}),this.plugins.push(t),t.once("destroy",(()=>{this.plugins=this.plugins.filter((e=>e!==t))})),t}async load(t,e,i){if(this.decodedData=null,this.canPlay=!1,this.loadUrl(t),null==e){const e=await this.fetcher.load(t),i=await this.decoder.decode(e);this.decodedData=i}else i||(i=await new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getDuration())))}))||0),this.decodedData={duration:i,numberOfChannels:e.length,sampleRate:e[0].length/i,getChannelData:t=>e[t]};this.renderer.render(this.decodedData),this.emit("decode",{duration:this.decodedData.duration})}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(this.decodedData,t),this.emit("zoom",{minPxPerSec:t})}getDecodedData(){return this.decodedData}getDuration(){return this.decodedData?.duration||this.getMediaElement()?.duration||0}toggleInteractive(t){this.options.interact=t}destroy(){this.emit("destroy"),this.plugins.forEach((t=>t.destroy())),this.timer.destroy(),this.decoder.destroy(),this.renderer.destroy(),super.destroy()}}const u=l;var c=i(76),p=i(954),m=i(919);class g extends t.Z{tracks;options;audios=[];wavesurfers=[];durations=[];currentTime=0;maxDuration=0;rendering;isDragging=!1;frameRequest=null;timer=null;subscriptions=[];timeline=null;static create(t,e){return new g(t,e)}constructor(t,e){super(),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:d}=o,h=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=()=>{h.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:h,setContainerOffsets:l,setMainWidth:(t,r)=>{s=t,i=Math.max(e.minPxPerSec||0,d/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,d=t*n;(d>s+(e?o:i)||d<s)&&(r.scrollLeft=d-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=h[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=v(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.maxDuration)})),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=u.create({...t.options,container:i,minPxPerSec:0,media:this.audios[e],peaks:t.peaks,cursorColor:"transparent",cursorWidth:0,interact:!1}),n=s.registerPlugin(c.default.create({draggable:!1,resizable:!0,dragSelection:!1}));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.add(0,i,"","rgba(0, 0, 0, 0.7)"),o=n.add(s,s+this.durations[e],"","rgba(0, 0, 0, 0.7)");r.element.firstElementChild?.remove(),o.element.lastChild?.remove(),this.subscriptions.push(n.on("region-updated",(({region:e})=>{this.setIsDragging(),e!==r&&e!==o||(e===r?(t.startCue=e.endTime,this.emit("start-cue-change",{id:t.id,startCue:t.startCue})):(t.endCue=e.startTime,this.emit("end-cue-change",{id:t.id,endCue:t.endCue})))})))}if(t.intro){const e=n.add(0,t.intro.endTime,t.intro.label,this.options.trackBackground);e.element.firstElementChild?.remove(),e.element.style.backgroundColor=this.options.trackBackground||"transparent",e.element.parentElement.style.mixBlendMode="plus-lighter",t.intro.color&&(e.element.lastElementChild.style.borderColor=t.intro.color),this.subscriptions.push(n.on("region-updated",(({region:i})=>{i===e&&this.emit("intro-end-change",{id:t.id,endTime:i.endTime})})))}t.markers&&t.markers.forEach((t=>{n.add(t.time,t.time,t.label,t.color)}))})));const r=s.registerPlugin(m.default.create({...this.options.envelopeOptions,startTime:t.startCue,endTime:t.endCue,fadeInEnd:t.fadeInEnd,fadeOutStart:t.fadeOutStart,volume:t.volume}));return this.subscriptions.push(r.on("volume-change",(({volume:e})=>{this.setIsDragging(),this.emit("volume-change",{id:t.id,volume:e})})),r.on("fade-in-change",(({time:e})=>{this.setIsDragging(),this.emit("fade-in-change",{id:t.id,fadeInEnd:e})})),r.on("fade-out-change",(({time: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(p.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),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=v(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.audios.map((e=>{const i=e;return i.setSinkId?i.setSinkId(t):Promise.resolve()})))}}function v(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 f=g})(),s.default})()));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import BasePlugin from '../base-plugin.js';
|
|
2
|
-
import type { WaveSurferPluginParams } from '../
|
|
2
|
+
import type { WaveSurferPluginParams } from '../wavesurfer.js';
|
|
3
3
|
export type RegionsPluginOptions = {
|
|
4
4
|
dragSelection?: boolean;
|
|
5
5
|
draggable?: boolean;
|
|
@@ -32,8 +32,11 @@ declare class RegionsPlugin extends BasePlugin<RegionsPluginEvents, RegionsPlugi
|
|
|
32
32
|
private modifiedRegion;
|
|
33
33
|
private isResizingLeft;
|
|
34
34
|
private isMoving;
|
|
35
|
+
private wasInteractive;
|
|
35
36
|
/** Create an instance of RegionsPlugin */
|
|
36
|
-
constructor(
|
|
37
|
+
constructor(options?: RegionsPluginOptions);
|
|
38
|
+
static create(options?: RegionsPluginOptions): RegionsPlugin;
|
|
39
|
+
init(params: WaveSurferPluginParams): void;
|
|
37
40
|
/** Unmount */
|
|
38
41
|
destroy(): void;
|
|
39
42
|
private initRegionsContainer;
|
package/dist/plugins/regions.js
CHANGED
|
@@ -23,13 +23,23 @@ class RegionsPlugin extends BasePlugin {
|
|
|
23
23
|
modifiedRegion = null;
|
|
24
24
|
isResizingLeft = false;
|
|
25
25
|
isMoving = false;
|
|
26
|
+
wasInteractive = true;
|
|
26
27
|
/** Create an instance of RegionsPlugin */
|
|
27
|
-
constructor(
|
|
28
|
-
super(
|
|
28
|
+
constructor(options) {
|
|
29
|
+
super(options || {});
|
|
29
30
|
this.options = Object.assign({}, defaultOptions, options);
|
|
30
31
|
this.regionsContainer = this.initRegionsContainer();
|
|
32
|
+
}
|
|
33
|
+
static create(options) {
|
|
34
|
+
return new RegionsPlugin(options);
|
|
35
|
+
}
|
|
36
|
+
init(params) {
|
|
37
|
+
super.init(params);
|
|
38
|
+
if (!this.wavesurfer || !this.wrapper) {
|
|
39
|
+
throw Error('WaveSurfer is not initialized');
|
|
40
|
+
}
|
|
31
41
|
this.subscriptions.push(this.wavesurfer.once('decode', () => {
|
|
32
|
-
this.wrapper
|
|
42
|
+
this.wrapper?.appendChild(this.regionsContainer);
|
|
33
43
|
}));
|
|
34
44
|
this.wrapper.addEventListener('mousedown', this.handleMouseDown);
|
|
35
45
|
document.addEventListener('mousemove', this.handleMouseMove);
|
|
@@ -37,7 +47,7 @@ class RegionsPlugin extends BasePlugin {
|
|
|
37
47
|
}
|
|
38
48
|
/** Unmount */
|
|
39
49
|
destroy() {
|
|
40
|
-
this.wrapper
|
|
50
|
+
this.wrapper?.removeEventListener('mousedown', this.handleMouseDown);
|
|
41
51
|
document.removeEventListener('mousemove', this.handleMouseMove);
|
|
42
52
|
document.removeEventListener('mouseup', this.handleMouseUp, true);
|
|
43
53
|
this.regionsContainer.remove();
|
|
@@ -56,10 +66,14 @@ class RegionsPlugin extends BasePlugin {
|
|
|
56
66
|
}
|
|
57
67
|
handleMouseDown = (e) => {
|
|
58
68
|
if (this.options.draggable || this.options.resizable || this.options.dragSelection) {
|
|
69
|
+
if (!this.wrapper)
|
|
70
|
+
return;
|
|
59
71
|
this.dragStart = e.clientX - this.wrapper.getBoundingClientRect().left;
|
|
60
72
|
}
|
|
61
73
|
};
|
|
62
74
|
handleMouseMove = (e) => {
|
|
75
|
+
if (!this.wrapper)
|
|
76
|
+
return;
|
|
63
77
|
const box = this.wrapper.getBoundingClientRect();
|
|
64
78
|
const { width } = box;
|
|
65
79
|
const dragEnd = e.clientX - box.left;
|
|
@@ -76,7 +90,8 @@ class RegionsPlugin extends BasePlugin {
|
|
|
76
90
|
const dragEnd = e.clientX - this.regionsContainer.getBoundingClientRect().left;
|
|
77
91
|
if (dragEnd - this.dragStart >= MIN_WIDTH) {
|
|
78
92
|
if (!this.createdRegion) {
|
|
79
|
-
this.
|
|
93
|
+
this.wasInteractive = this.wavesurfer?.options.interact || true;
|
|
94
|
+
this.wavesurfer?.toggleInteractive(false);
|
|
80
95
|
this.createdRegion = this.createRegion(this.dragStart / width, dragEnd / width);
|
|
81
96
|
}
|
|
82
97
|
else {
|
|
@@ -93,7 +108,7 @@ class RegionsPlugin extends BasePlugin {
|
|
|
93
108
|
this.modifiedRegion = null;
|
|
94
109
|
this.isMoving = false;
|
|
95
110
|
this.dragStart = NaN;
|
|
96
|
-
this.
|
|
111
|
+
this.wavesurfer?.toggleInteractive(this.wasInteractive);
|
|
97
112
|
};
|
|
98
113
|
createRegionElement(start, end, title = '') {
|
|
99
114
|
const noWidth = start === end;
|
|
@@ -181,7 +196,7 @@ class RegionsPlugin extends BasePlugin {
|
|
|
181
196
|
return div;
|
|
182
197
|
}
|
|
183
198
|
createRegion(start, end, title = '') {
|
|
184
|
-
const duration = this.wavesurfer
|
|
199
|
+
const duration = this.wavesurfer?.getDuration() || 0;
|
|
185
200
|
return {
|
|
186
201
|
element: this.createRegionElement(start, end, title),
|
|
187
202
|
start,
|
|
@@ -196,16 +211,17 @@ class RegionsPlugin extends BasePlugin {
|
|
|
196
211
|
this.emit('region-created', { region });
|
|
197
212
|
}
|
|
198
213
|
updateRegion(region, start, end) {
|
|
214
|
+
const duration = this.wavesurfer?.getDuration() || 0;
|
|
199
215
|
if (start != null) {
|
|
200
216
|
region.start = start;
|
|
201
217
|
region.element.style.left = `${region.start * 100}%`;
|
|
202
218
|
region.element.style.width = `${(region.end - region.start) * 100}%`;
|
|
203
|
-
region.startTime = start *
|
|
219
|
+
region.startTime = start * duration;
|
|
204
220
|
}
|
|
205
221
|
if (end != null) {
|
|
206
222
|
region.end = end;
|
|
207
223
|
region.element.style.width = `${(region.end - region.start) * 100}%`;
|
|
208
|
-
region.endTime = end *
|
|
224
|
+
region.endTime = end * duration;
|
|
209
225
|
}
|
|
210
226
|
this.emit('region-updated', { region });
|
|
211
227
|
}
|
|
@@ -214,7 +230,7 @@ class RegionsPlugin extends BasePlugin {
|
|
|
214
230
|
}
|
|
215
231
|
/** Create a region at a given start and end time, with an optional title */
|
|
216
232
|
add(startTime, endTime, title = '', color = '') {
|
|
217
|
-
const duration = this.wavesurfer
|
|
233
|
+
const duration = this.wavesurfer?.getDuration() || 0;
|
|
218
234
|
const start = startTime / duration;
|
|
219
235
|
const end = endTime / duration;
|
|
220
236
|
const region = this.createRegion(start, end, title);
|
|
@@ -0,0 +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.Regions=t():e.Regions=t()}(WaveSurfer,(()=>(()=>{"use strict";var e={284:(e,t,i)=>{i.d(t,{Z:()=>o});var n=i(139);class s extends n.Z{wavesurfer;container;wrapper;subscriptions=[];options;constructor(e){super(),this.options=e}init(e){this.wavesurfer=e.wavesurfer,this.container=e.container,this.wrapper=e.wrapper}destroy(){this.subscriptions.forEach((e=>e()))}}const o=s},139:(e,t,i)=>{i.d(t,{Z:()=>n});const n=class{eventTarget;constructor(){this.eventTarget=new EventTarget}emit(e,t){const i=new CustomEvent(String(e),{detail:t});this.eventTarget.dispatchEvent(i)}on(e,t,i){const n=e=>{e instanceof CustomEvent&&t(e.detail)},s=String(e);return this.eventTarget.addEventListener(s,n,{once:i}),()=>this.eventTarget.removeEventListener(s,n)}once(e,t){return this.on(e,t,!0)}}}},t={};function i(n){var s=t[n];if(void 0!==s)return s.exports;var o=t[n]={exports:{}};return e[n](o,o.exports,i),o.exports}i.d=(e,t)=>{for(var n in t)i.o(t,n)&&!i.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},i.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var n={};return(()=>{i.d(n,{default:()=>a});var e=i(284);const t={dragSelection:!0,draggable:!0,resizable:!0},s=(e,t)=>{for(const i in t)e.style[i]=t[i]||""},o=(e,t)=>{const i=document.createElement(e);return s(i,t),i};class r extends e.Z{dragStart=NaN;regionsContainer;regions=[];createdRegion=null;modifiedRegion=null;isResizingLeft=!1;isMoving=!1;wasInteractive=!0;constructor(e){super(e||{}),this.options=Object.assign({},t,e),this.regionsContainer=this.initRegionsContainer()}static create(e){return new r(e)}init(e){if(super.init(e),!this.wavesurfer||!this.wrapper)throw Error("WaveSurfer is not initialized");this.subscriptions.push(this.wavesurfer.once("decode",(()=>{this.wrapper?.appendChild(this.regionsContainer)}))),this.wrapper.addEventListener("mousedown",this.handleMouseDown),document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("mouseup",this.handleMouseUp)}destroy(){this.wrapper?.removeEventListener("mousedown",this.handleMouseDown),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp,!0),this.regionsContainer.remove(),super.destroy()}initRegionsContainer(){return o("div",{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",zIndex:"3",pointerEvents:"none"})}handleMouseDown=e=>{if(this.options.draggable||this.options.resizable||this.options.dragSelection){if(!this.wrapper)return;this.dragStart=e.clientX-this.wrapper.getBoundingClientRect().left}};handleMouseMove=e=>{if(!this.wrapper)return;const t=this.wrapper.getBoundingClientRect(),{width:i}=t,n=e.clientX-t.left;if(this.options.draggable&&this.modifiedRegion&&this.isMoving)return this.moveRegion(this.modifiedRegion,(n-this.dragStart)/i),void(this.dragStart=n);if(this.options.resizable&&this.modifiedRegion)this.updateRegion(this.modifiedRegion,this.isResizingLeft?n/i:void 0,this.isResizingLeft?void 0:n/i);else if(this.options.dragSelection&&!isNaN(this.dragStart)){const t=e.clientX-this.regionsContainer.getBoundingClientRect().left;t-this.dragStart>=10&&(this.createdRegion?this.updateRegion(this.createdRegion,this.dragStart/i,t/i):(this.wasInteractive=this.wavesurfer?.options.interact||!0,this.wavesurfer?.toggleInteractive(!1),this.createdRegion=this.createRegion(this.dragStart/i,t/i)))}};handleMouseUp=()=>{this.createdRegion&&(this.addRegion(this.createdRegion),this.createdRegion=null),this.modifiedRegion=null,this.isMoving=!1,this.dragStart=NaN,this.wavesurfer?.toggleInteractive(this.wasInteractive)};createRegionElement(e,t,i=""){const n=e===t,r=o("div",{position:"absolute",left:100*e+"%",width:100*(t-e)+"%",height:"100%",backgroundColor:n?"":"rgba(0, 0, 0, 0.1)",borderRadius:"2px",boxSizing:"border-box",borderLeft:n?"2px solid rgba(0, 0, 0, 0.5)":"",transition:"background-color 0.2s ease",cursor:this.options.draggable?"move":"",pointerEvents:"all",whiteSpace:n?"nowrap":"",padding:"0.2em"});r.textContent=i;const a=o("div",{position:"absolute",left:"0",top:"0",width:"6px",height:"100%",cursor:this.options.resizable?"ew-resize":"",pointerEvents:"all",borderLeft:n?"":"2px solid rgba(0, 0, 0, 0.5)",borderRadius:"2px 0 0 2px"});r.appendChild(a);const d=a.cloneNode();s(d,{left:"",right:"0",borderLeft:"",borderRight:n?"":"2px solid rgba(0, 0, 0, 0.5)",borderRadius:"0 2px 2px 0"}),r.appendChild(d),a.addEventListener("mousedown",(e=>{this.options.resizable&&(e.stopPropagation(),this.modifiedRegion=this.regions.find((e=>e.element===r))||null,this.isResizingLeft=!0,this.isMoving=!1)})),d.addEventListener("mousedown",(e=>{this.options.resizable&&(e.stopPropagation(),this.modifiedRegion=this.regions.find((e=>e.element===r))||null,this.isResizingLeft=!1,this.isMoving=!1)})),r.addEventListener("mousedown",(()=>{this.options.draggable&&(this.modifiedRegion=this.regions.find((e=>e.element===r))||null,this.isMoving=!0)})),r.addEventListener("click",(()=>{const e=this.regions.find((e=>e.element===r));e&&this.emit("region-clicked",{region:e})})),this.regionsContainer.appendChild(r);const h=r.getBoundingClientRect().left,g=r.scrollWidth,l=this.regions.filter((e=>{const{left:t}=e.element.getBoundingClientRect(),i=e.element.scrollWidth;return h<t+i&&t<h+g})).map((e=>parseFloat(e.element.style.paddingTop))).reduce(((e,t)=>e+t),0);return l>0&&(r.style.paddingTop=`${l+1}em`),r}createRegion(e,t,i=""){const n=this.wavesurfer?.getDuration()||0;return{element:this.createRegionElement(e,t,i),start:e,end:t,startTime:e*n,endTime:t*n,title:i}}addRegion(e){this.regions.push(e),this.emit("region-created",{region:e})}updateRegion(e,t,i){const n=this.wavesurfer?.getDuration()||0;null!=t&&(e.start=t,e.element.style.left=100*e.start+"%",e.element.style.width=100*(e.end-e.start)+"%",e.startTime=t*n),null!=i&&(e.end=i,e.element.style.width=100*(e.end-e.start)+"%",e.endTime=i*n),this.emit("region-updated",{region:e})}moveRegion(e,t){this.updateRegion(e,e.start+t,e.end+t)}add(e,t,i="",n=""){const s=this.wavesurfer?.getDuration()||0,o=e/s,r=t/s,a=this.createRegion(o,r,i);return this.addRegion(a),n&&this.setRegionColor(a,n),a}setRegionColor(e,t){e.element.style[e.startTime===e.endTime?"borderColor":"backgroundColor"]=t}}const a=r})(),n.default})()));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import BasePlugin from '../base-plugin.js';
|
|
2
|
-
import type { WaveSurferPluginParams } from '../
|
|
2
|
+
import type { WaveSurferPluginParams } from '../wavesurfer.js';
|
|
3
3
|
export type TimelinePluginOptions = {
|
|
4
4
|
/** The height of the timeline in pixels, defaults to 20 */
|
|
5
5
|
height?: number;
|
|
@@ -23,7 +23,9 @@ export type TimelinePluginEvents = {
|
|
|
23
23
|
declare class TimelinePlugin extends BasePlugin<TimelinePluginEvents, TimelinePluginOptions> {
|
|
24
24
|
private timelineWrapper;
|
|
25
25
|
protected options: TimelinePluginOptions & typeof defaultOptions;
|
|
26
|
-
constructor(
|
|
26
|
+
constructor(options: TimelinePluginOptions);
|
|
27
|
+
static create(options: TimelinePluginOptions): TimelinePlugin;
|
|
28
|
+
init(params: WaveSurferPluginParams): void;
|
|
27
29
|
/** Unmount */
|
|
28
30
|
destroy(): void;
|
|
29
31
|
private initTimelineWrapper;
|
package/dist/plugins/timeline.js
CHANGED
|
@@ -5,12 +5,21 @@ const defaultOptions = {
|
|
|
5
5
|
class TimelinePlugin extends BasePlugin {
|
|
6
6
|
timelineWrapper;
|
|
7
7
|
options;
|
|
8
|
-
constructor(
|
|
9
|
-
super(
|
|
8
|
+
constructor(options) {
|
|
9
|
+
super(options);
|
|
10
10
|
this.options = Object.assign({}, defaultOptions, options);
|
|
11
|
-
this.container = this.options.container ?? this.wrapper;
|
|
12
11
|
this.timelineWrapper = this.initTimelineWrapper();
|
|
13
|
-
|
|
12
|
+
}
|
|
13
|
+
static create(options) {
|
|
14
|
+
return new TimelinePlugin(options);
|
|
15
|
+
}
|
|
16
|
+
init(params) {
|
|
17
|
+
super.init(params);
|
|
18
|
+
if (!this.wavesurfer || !this.wrapper) {
|
|
19
|
+
throw Error('WaveSurfer is not initialized');
|
|
20
|
+
}
|
|
21
|
+
const container = this.options.container ?? this.wrapper;
|
|
22
|
+
container.appendChild(this.timelineWrapper);
|
|
14
23
|
if (this.options.duration) {
|
|
15
24
|
this.initTimeline(this.options.duration);
|
|
16
25
|
}
|
|
@@ -0,0 +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.Timeline=t():e.Timeline=t()}(WaveSurfer,(()=>(()=>{"use strict";var e={284:(e,t,i)=>{i.d(t,{Z:()=>s});var n=i(139);class r extends n.Z{wavesurfer;container;wrapper;subscriptions=[];options;constructor(e){super(),this.options=e}init(e){this.wavesurfer=e.wavesurfer,this.container=e.container,this.wrapper=e.wrapper}destroy(){this.subscriptions.forEach((e=>e()))}}const s=r},139:(e,t,i)=>{i.d(t,{Z:()=>n});const n=class{eventTarget;constructor(){this.eventTarget=new EventTarget}emit(e,t){const i=new CustomEvent(String(e),{detail:t});this.eventTarget.dispatchEvent(i)}on(e,t,i){const n=e=>{e instanceof CustomEvent&&t(e.detail)},r=String(e);return this.eventTarget.addEventListener(r,n,{once:i}),()=>this.eventTarget.removeEventListener(r,n)}once(e,t){return this.on(e,t,!0)}}}},t={};function i(n){var r=t[n];if(void 0!==r)return r.exports;var s=t[n]={exports:{}};return e[n](s,s.exports,i),s.exports}i.d=(e,t)=>{for(var n in t)i.o(t,n)&&!i.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},i.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var n={};return(()=>{i.d(n,{default:()=>s});var e=i(284);const t={height:20};class r extends e.Z{timelineWrapper;options;constructor(e){super(e),this.options=Object.assign({},t,e),this.timelineWrapper=this.initTimelineWrapper()}static create(e){return new r(e)}init(e){if(super.init(e),!this.wavesurfer||!this.wrapper)throw Error("WaveSurfer is not initialized");(this.options.container??this.wrapper).appendChild(this.timelineWrapper),this.options.duration?this.initTimeline(this.options.duration):this.subscriptions.push(this.wavesurfer.on("decode",(({duration:e})=>{this.initTimeline(e)})))}destroy(){this.timelineWrapper.remove(),super.destroy()}initTimelineWrapper(){return document.createElement("div")}formatTime(e){return e/60>1?`${Math.round(e/60)}:${(e=Math.round(e%60))<10?"0":""}${e}`:""+Math.round(1e3*e)/1e3}defaultTimeInterval(e){return e>=25?1:5*e>=25?5:15*e>=25?15:60*Math.ceil(.5/e)}defaultPrimaryLabelInterval(e){return e>=25?10:5*e>=25?6:4}defaultSecondaryLabelInterval(e){return e>=25?5:2}initTimeline(e){const t=Math.round(this.timelineWrapper.scrollWidth*devicePixelRatio)/e,i=this.options.timeInterval??this.defaultTimeInterval(t),n=this.options.primaryLabelInterval??this.defaultPrimaryLabelInterval(t),r=this.options.secondaryLabelInterval??this.defaultSecondaryLabelInterval(t),s=document.createElement("div");s.setAttribute("style",`\n height: ${this.options.height}px;\n overflow: hidden;\n display: flex;\n justify-content: space-between;\n align-items: flex-end;\n font-size: ${this.options.height/2}px;\n white-space: nowrap;\n `);const o=document.createElement("div");o.setAttribute("style","\n width: 1px;\n height: 50%;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n overflow: visible;\n border-left: 1px solid currentColor;\n opacity: 0.25;\n ");for(let t=0;t<e;t+=i){const e=o.cloneNode(),i=t%n==0;(i||t%r==0)&&(e.style.height="100%",e.style.textIndent="3px",e.textContent=this.formatTime(t),i&&(e.style.opacity="1")),s.appendChild(e)}this.timelineWrapper.appendChild(s),this.emit("ready")}}const s=r})(),n.default})()));
|
package/dist/renderer.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ type RendererOptions = {
|
|
|
11
11
|
barWidth?: number;
|
|
12
12
|
barGap?: number;
|
|
13
13
|
barRadius?: number;
|
|
14
|
-
|
|
14
|
+
hideScrollbar?: boolean;
|
|
15
15
|
};
|
|
16
16
|
type RendererEvents = {
|
|
17
17
|
click: {
|
|
@@ -27,6 +27,8 @@ declare class Renderer extends EventEmitter<RendererEvents> {
|
|
|
27
27
|
private progressWrapper;
|
|
28
28
|
private timeout;
|
|
29
29
|
private isScrolling;
|
|
30
|
+
private audioData;
|
|
31
|
+
private resizeObserver;
|
|
30
32
|
constructor(options: RendererOptions);
|
|
31
33
|
getContainer(): HTMLElement;
|
|
32
34
|
getWrapper(): HTMLElement;
|
package/dist/renderer.js
CHANGED
|
@@ -8,6 +8,8 @@ class Renderer extends EventEmitter {
|
|
|
8
8
|
progressWrapper;
|
|
9
9
|
timeout = null;
|
|
10
10
|
isScrolling = false;
|
|
11
|
+
audioData = null;
|
|
12
|
+
resizeObserver = null;
|
|
11
13
|
constructor(options) {
|
|
12
14
|
super();
|
|
13
15
|
this.options = options;
|
|
@@ -33,10 +35,10 @@ class Renderer extends EventEmitter {
|
|
|
33
35
|
overflow-y: hidden;
|
|
34
36
|
width: 100%;
|
|
35
37
|
position: relative;
|
|
36
|
-
${this.options.
|
|
38
|
+
${this.options.hideScrollbar ? 'scrollbar-color: transparent;' : ''}
|
|
37
39
|
}
|
|
38
40
|
:host ::-webkit-scrollbar {
|
|
39
|
-
display: ${this.options.
|
|
41
|
+
display: ${this.options.hideScrollbar ? 'none' : 'auto'};
|
|
40
42
|
}
|
|
41
43
|
:host .wrapper {
|
|
42
44
|
position: relative;
|
|
@@ -89,6 +91,11 @@ class Renderer extends EventEmitter {
|
|
|
89
91
|
const relativeX = x / rect.width;
|
|
90
92
|
this.emit('click', { relativeX });
|
|
91
93
|
});
|
|
94
|
+
// Re-render the waveform on container resize
|
|
95
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
96
|
+
this.delay(() => this.audioData && this.zoom(this.audioData, this.options.minPxPerSec), 100);
|
|
97
|
+
});
|
|
98
|
+
this.resizeObserver.observe(this.scrollContainer);
|
|
92
99
|
}
|
|
93
100
|
getContainer() {
|
|
94
101
|
return this.scrollContainer;
|
|
@@ -98,6 +105,7 @@ class Renderer extends EventEmitter {
|
|
|
98
105
|
}
|
|
99
106
|
destroy() {
|
|
100
107
|
this.container.remove();
|
|
108
|
+
this.resizeObserver?.disconnect();
|
|
101
109
|
}
|
|
102
110
|
delay(fn, delayMs = 10) {
|
|
103
111
|
if (this.timeout) {
|
|
@@ -178,11 +186,12 @@ class Renderer extends EventEmitter {
|
|
|
178
186
|
// Clear the canvas
|
|
179
187
|
this.canvasWrapper.innerHTML = '';
|
|
180
188
|
this.progressWrapper.innerHTML = '';
|
|
181
|
-
//
|
|
189
|
+
// Determine the currently visible part of the waveform
|
|
182
190
|
const { scrollLeft, scrollWidth, clientWidth } = this.scrollContainer;
|
|
183
191
|
const scale = len / scrollWidth;
|
|
184
192
|
const start = Math.floor(scrollLeft * scale);
|
|
185
193
|
const end = Math.ceil(Math.min(scrollWidth, scrollLeft + clientWidth) * scale);
|
|
194
|
+
// Draw the visible portion of the waveform
|
|
186
195
|
draw(start, end);
|
|
187
196
|
// Draw the rest of the waveform with a timeout for better performance
|
|
188
197
|
const step = end - start;
|
|
@@ -198,30 +207,34 @@ class Renderer extends EventEmitter {
|
|
|
198
207
|
}
|
|
199
208
|
}
|
|
200
209
|
render(audioData) {
|
|
201
|
-
// Determine the width of the
|
|
210
|
+
// Determine the width of the waveform
|
|
202
211
|
const pixelRatio = window.devicePixelRatio || 1;
|
|
203
212
|
const parentWidth = this.options.fillParent ? this.scrollContainer.clientWidth * pixelRatio : 0;
|
|
204
|
-
const scrollWidth = audioData.duration * this.options.minPxPerSec;
|
|
205
|
-
|
|
206
|
-
const width = Math.max(1, this.isScrolling ? scrollWidth : parentWidth);
|
|
213
|
+
const scrollWidth = Math.max(1, audioData.duration * this.options.minPxPerSec);
|
|
214
|
+
const width = scrollWidth > parentWidth ? scrollWidth : parentWidth;
|
|
207
215
|
const { height } = this.options;
|
|
208
|
-
//
|
|
209
|
-
|
|
216
|
+
// Set the width of the container
|
|
217
|
+
this.isScrolling = width > parentWidth;
|
|
210
218
|
this.scrollContainer.style.overflowX = this.isScrolling ? 'auto' : 'hidden';
|
|
211
219
|
this.wrapper.style.width = `${Math.floor(width / pixelRatio)}px`;
|
|
212
|
-
//
|
|
213
|
-
const newCursortPosition = this.progressWrapper.clientWidth;
|
|
214
|
-
this.scrollContainer.scrollLeft += newCursortPosition - oldCursorPosition;
|
|
215
|
-
// First two channels are used
|
|
220
|
+
// Only the first two channels are used
|
|
216
221
|
const channelData = [audioData.getChannelData(0)];
|
|
217
222
|
if (audioData.numberOfChannels > 1) {
|
|
218
223
|
channelData.push(audioData.getChannelData(1));
|
|
219
224
|
}
|
|
225
|
+
// Render the waveform
|
|
220
226
|
this.renderPeaks(channelData, width, height, pixelRatio);
|
|
227
|
+
this.audioData = audioData;
|
|
221
228
|
}
|
|
222
229
|
zoom(audioData, minPxPerSec) {
|
|
230
|
+
// Remember the current cursor position
|
|
231
|
+
const oldCursorPosition = this.progressWrapper.clientWidth;
|
|
232
|
+
// Set the new zoom level and re-render the waveform
|
|
223
233
|
this.options.minPxPerSec = minPxPerSec;
|
|
224
234
|
this.render(audioData);
|
|
235
|
+
// Adjust the scroll position so that the cursor stays in the same place
|
|
236
|
+
const newCursortPosition = this.progressWrapper.clientWidth;
|
|
237
|
+
this.scrollContainer.scrollLeft += newCursortPosition - oldCursorPosition;
|
|
225
238
|
}
|
|
226
239
|
renderProgress(progress, autoCenter = false) {
|
|
227
240
|
this.progressWrapper.style.width = `${progress * 100}%`;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Player from './player.js';
|
|
2
|
+
import { type GeneralEventTypes } from './event-emitter.js';
|
|
2
3
|
import BasePlugin from './base-plugin.js';
|
|
3
4
|
export type WaveSurferOptions = {
|
|
4
5
|
/** HTML element or CSS selector */
|
|
@@ -34,9 +35,15 @@ export type WaveSurferOptions = {
|
|
|
34
35
|
/** Play the audio on load */
|
|
35
36
|
autoplay?: boolean;
|
|
36
37
|
/** Is the waveform clickable? */
|
|
37
|
-
|
|
38
|
+
interact?: boolean;
|
|
38
39
|
/** Hide scrollbar **/
|
|
39
|
-
|
|
40
|
+
hideScrollbar?: boolean;
|
|
41
|
+
/** Audio rate */
|
|
42
|
+
audioRate?: number;
|
|
43
|
+
/** Keep scroll to the center of the waveform during playback */
|
|
44
|
+
autoCenter?: boolean;
|
|
45
|
+
/** Initialize plugins */
|
|
46
|
+
plugins?: BasePlugin<GeneralEventTypes, unknown>[];
|
|
40
47
|
};
|
|
41
48
|
declare const defaultOptions: {
|
|
42
49
|
height: number;
|
|
@@ -45,7 +52,8 @@ declare const defaultOptions: {
|
|
|
45
52
|
cursorWidth: number;
|
|
46
53
|
minPxPerSec: number;
|
|
47
54
|
fillParent: boolean;
|
|
48
|
-
|
|
55
|
+
interact: boolean;
|
|
56
|
+
autoCenter: boolean;
|
|
49
57
|
};
|
|
50
58
|
export type WaveSurferEvents = {
|
|
51
59
|
decode: {
|
|
@@ -78,16 +86,15 @@ export type WaveSurferPluginParams = {
|
|
|
78
86
|
container: HTMLElement;
|
|
79
87
|
wrapper: HTMLElement;
|
|
80
88
|
};
|
|
81
|
-
declare class WaveSurfer extends
|
|
89
|
+
declare class WaveSurfer extends Player<WaveSurferEvents> {
|
|
82
90
|
options: WaveSurferOptions & typeof defaultOptions;
|
|
83
91
|
private fetcher;
|
|
84
92
|
private decoder;
|
|
85
93
|
private renderer;
|
|
86
|
-
private player;
|
|
87
94
|
private timer;
|
|
88
95
|
private plugins;
|
|
89
|
-
private subscriptions;
|
|
90
96
|
private decodedData;
|
|
97
|
+
private canPlay;
|
|
91
98
|
/** Create a new WaveSurfer instance */
|
|
92
99
|
static create(options: WaveSurferOptions): WaveSurfer;
|
|
93
100
|
/** Create a new WaveSurfer instance */
|
|
@@ -96,40 +103,16 @@ declare class WaveSurfer extends EventEmitter<WaveSurferEvents> {
|
|
|
96
103
|
private initRendererEvents;
|
|
97
104
|
private initTimerEvents;
|
|
98
105
|
private initReadyEvent;
|
|
106
|
+
private initPlugins;
|
|
107
|
+
/** Register a wavesurfer.js plugin */
|
|
108
|
+
registerPlugin<T extends BasePlugin<GeneralEventTypes, unknown>>(plugin: T): T;
|
|
99
109
|
/** Load an audio file by URL, with optional pre-decoded audio data */
|
|
100
110
|
load(url: string, channelData?: Float32Array[], duration?: number): Promise<void>;
|
|
101
111
|
/** Zoom in or out */
|
|
102
112
|
zoom(minPxPerSec: number): void;
|
|
103
|
-
/** Start playing the audio */
|
|
104
|
-
play(): void;
|
|
105
|
-
/** Pause the audio */
|
|
106
|
-
pause(): void;
|
|
107
|
-
/** Skip to a time position in seconds */
|
|
108
|
-
seekTo(time: number): void;
|
|
109
|
-
/** Check if the audio is playing */
|
|
110
|
-
isPlaying(): boolean;
|
|
111
|
-
/** Get the duration of the audio in seconds */
|
|
112
|
-
getDuration(): number;
|
|
113
|
-
/** Get the current audio position in seconds */
|
|
114
|
-
getCurrentTime(): number;
|
|
115
|
-
/** Get the audio volume */
|
|
116
|
-
getVolume(): number;
|
|
117
|
-
/** Set the audio volume */
|
|
118
|
-
setVolume(volume: number): void;
|
|
119
|
-
/** Get the audio muted state */
|
|
120
|
-
getMuted(): boolean;
|
|
121
|
-
/** Mute or unmute the audio */
|
|
122
|
-
setMuted(muted: boolean): void;
|
|
123
|
-
/** Get playback rate */
|
|
124
|
-
getPlaybackRate(): number;
|
|
125
|
-
/** Set playback rate, with an optional parameter to NOT preserve the pitch if false */
|
|
126
|
-
setPlaybackRate(rate: number, preservePitch?: boolean): void;
|
|
127
|
-
/** Register and initialize a plugin */
|
|
128
|
-
registerPlugin<T extends BasePlugin<GeneralEventTypes, Options>, Options>(CustomPlugin: new (params: WaveSurferPluginParams, options: Options) => T, options: Options): T;
|
|
129
113
|
/** Get the decoded audio data */
|
|
130
114
|
getDecodedData(): AudioBuffer | null;
|
|
131
|
-
|
|
132
|
-
getMediaElement(): HTMLMediaElement | null;
|
|
115
|
+
getDuration(): number;
|
|
133
116
|
/** Toggle if the waveform should react to clicks */
|
|
134
117
|
toggleInteractive(isInteractive: boolean): void;
|
|
135
118
|
/** Unmount wavesurfer */
|