wavesurfer.js 7.0.0-beta.13 → 7.0.0-beta.15
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 +5 -2
- package/dist/base-plugin.js +1 -0
- package/dist/decoder.js +17 -6
- package/dist/draggable.js +5 -2
- package/dist/fetcher.js +13 -2
- package/dist/plugins/envelope.d.ts +2 -2
- package/dist/plugins/envelope.js +13 -7
- package/dist/plugins/envelope.min.cjs +1 -1
- package/dist/plugins/hover.d.ts +2 -2
- package/dist/plugins/hover.min.cjs +1 -1
- package/dist/plugins/minimap.d.ts +2 -2
- package/dist/plugins/minimap.js +8 -13
- package/dist/plugins/minimap.min.cjs +1 -1
- package/dist/plugins/record.d.ts +2 -2
- package/dist/plugins/record.js +48 -32
- package/dist/plugins/record.min.cjs +1 -1
- package/dist/plugins/regions.d.ts +2 -2
- package/dist/plugins/regions.js +20 -19
- package/dist/plugins/regions.min.cjs +1 -1
- package/dist/plugins/spectrogram.d.ts +2 -2
- package/dist/plugins/spectrogram.js +1 -0
- package/dist/plugins/spectrogram.min.cjs +1 -1
- package/dist/plugins/timeline.d.ts +5 -3
- package/dist/plugins/timeline.js +20 -17
- package/dist/plugins/timeline.min.cjs +1 -1
- package/dist/renderer.js +5 -3
- package/dist/wavesurfer.js +59 -40
- package/dist/wavesurfer.min.cjs +1 -1
- package/package.json +1 -1
|
@@ -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()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var e={d:(t,r)=>{for(var i in r)e.o(r,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:r[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{default:()=>n});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),i=this.on(e,(()=>{r(),i()}));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)))}},i=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()))}}
|
|
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()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var e={d:(t,r)=>{for(var i in r)e.o(r,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:r[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{default:()=>n});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),i=this.on(e,(()=>{r(),i()}));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)))}},i=class extends r{constructor(e){super(),this.subscriptions=[],this.options=e}onInit(){}init(e){this.wavesurfer=e,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((e=>e()))}};const o=["audio/webm","audio/wav","audio/mpeg","audio/mp4","audio/mp3"];class s extends i{constructor(){super(...arguments),this.mediaRecorder=null,this.recordedUrl=""}static create(e){return new s(e||{})}loadBlob(e,t){var r;const i=new Blob(e,{type:t});this.recordedUrl=URL.createObjectURL(i),null===(r=this.wavesurfer)||void 0===r||r.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 i=r.getContext("2d"),o=new AudioContext,s=o.createMediaStreamSource(e),n=o.createAnalyser();let d;s.connect(n);const a=()=>{var e;if(!i)return;i.clearRect(0,0,r.width,r.height);const t=n.frequencyBinCount,o=new Uint8Array(t);n.getByteTimeDomainData(o),i.lineWidth=this.options.lineWidth||2;const s=this.options.realtimeWaveColor||(null===(e=this.wavesurfer)||void 0===e?void 0:e.options.waveColor)||"";i.strokeStyle=Array.isArray(s)?s[0]:s,i.beginPath();const c=1*r.width/t;let l=0;for(let e=0;e<t;e++){const t=o[e]/128*r.height/2;0===e?i.moveTo(l,t):i.lineTo(l,t),l+=c}i.lineTo(r.width,r.height/2),i.stroke(),d=requestAnimationFrame(a)};return a(),()=>{d&&cancelAnimationFrame(d),s&&(s.disconnect(),s.mediaStream.getTracks().forEach((e=>e.stop()))),o&&o.close(),null==r||r.remove()}}cleanUp(){var e;this.stopRecording(),null===(e=this.wavesurfer)||void 0===e||e.empty(),this.recordedUrl&&(URL.revokeObjectURL(this.recordedUrl),this.recordedUrl="")}startRecording(){return e=this,t=void 0,i=function*(){let e;this.cleanUp();try{e=yield 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,{mimeType:this.options.mimeType||o.find((e=>MediaRecorder.isTypeSupported(e))),audioBitsPerSecond:this.options.audioBitsPerSecond}),i=[];r.addEventListener("dataavailable",(e=>{e.data.size>0&&i.push(e.data)})),r.addEventListener("stop",(()=>{t(),this.loadBlob(i,r.mimeType),this.emit("stopRecording")})),r.start(),this.emit("startRecording"),this.mediaRecorder=r},new((r=void 0)||(r=Promise))((function(o,s){function n(e){try{a(i.next(e))}catch(e){s(e)}}function d(e){try{a(i.throw(e))}catch(e){s(e)}}function a(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(n,d)}a((i=i.apply(e,t||[])).next())}));var e,t,r,i}isRecording(){var e;return"recording"===(null===(e=this.mediaRecorder)||void 0===e?void 0:e.state)}stopRecording(){var e;this.isRecording()&&(null===(e=this.mediaRecorder)||void 0===e||e.stop())}getRecordedUrl(){return this.recordedUrl}destroy(){super.destroy(),this.cleanUp()}}const n=s;return t.default})()));
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* Regions can be clicked on, dragged and resized.
|
|
4
4
|
* You can set the color and content of each region, as well as their HTML content.
|
|
5
5
|
*/
|
|
6
|
-
import BasePlugin from '../base-plugin.js';
|
|
6
|
+
import BasePlugin, { type BasePluginEvents } from '../base-plugin.js';
|
|
7
7
|
import EventEmitter from '../event-emitter.js';
|
|
8
8
|
export type RegionsPluginOptions = undefined;
|
|
9
|
-
export type RegionsPluginEvents = {
|
|
9
|
+
export type RegionsPluginEvents = BasePluginEvents & {
|
|
10
10
|
'region-created': [region: Region];
|
|
11
11
|
'region-updated': [region: Region];
|
|
12
12
|
'region-clicked': [region: Region, e: MouseEvent];
|
package/dist/plugins/regions.js
CHANGED
|
@@ -8,18 +8,19 @@ import { makeDraggable } from '../draggable.js';
|
|
|
8
8
|
import EventEmitter from '../event-emitter.js';
|
|
9
9
|
export class Region extends EventEmitter {
|
|
10
10
|
constructor(params, totalDuration) {
|
|
11
|
+
var _a, _b, _c, _d, _e, _f;
|
|
11
12
|
super();
|
|
12
13
|
this.totalDuration = totalDuration;
|
|
13
|
-
this.minLength = 0
|
|
14
|
+
this.minLength = 0;
|
|
14
15
|
this.maxLength = Infinity;
|
|
15
16
|
this.id = params.id || `region-${Math.random().toString(32).slice(2)}`;
|
|
16
17
|
this.start = params.start;
|
|
17
|
-
this.end = params.end
|
|
18
|
-
this.drag = params.drag
|
|
19
|
-
this.resize = params.resize
|
|
20
|
-
this.color = params.color
|
|
21
|
-
this.minLength = params.minLength
|
|
22
|
-
this.maxLength = params.maxLength
|
|
18
|
+
this.end = (_a = params.end) !== null && _a !== void 0 ? _a : params.start;
|
|
19
|
+
this.drag = (_b = params.drag) !== null && _b !== void 0 ? _b : true;
|
|
20
|
+
this.resize = (_c = params.resize) !== null && _c !== void 0 ? _c : true;
|
|
21
|
+
this.color = (_d = params.color) !== null && _d !== void 0 ? _d : 'rgba(0, 0, 0, 0.1)';
|
|
22
|
+
this.minLength = (_e = params.minLength) !== null && _e !== void 0 ? _e : this.minLength;
|
|
23
|
+
this.maxLength = (_f = params.maxLength) !== null && _f !== void 0 ? _f : this.maxLength;
|
|
23
24
|
this.element = this.initElement(params.content);
|
|
24
25
|
this.renderPosition();
|
|
25
26
|
this.initMouseEvents();
|
|
@@ -123,7 +124,7 @@ export class Region extends EventEmitter {
|
|
|
123
124
|
const length = newEnd - newStart;
|
|
124
125
|
if (newStart > 0 &&
|
|
125
126
|
newEnd < this.totalDuration &&
|
|
126
|
-
newStart
|
|
127
|
+
newStart <= newEnd &&
|
|
127
128
|
length >= this.minLength &&
|
|
128
129
|
length <= this.maxLength) {
|
|
129
130
|
this.start = newStart;
|
|
@@ -157,6 +158,7 @@ export class Region extends EventEmitter {
|
|
|
157
158
|
}
|
|
158
159
|
/** Update the region's options */
|
|
159
160
|
setOptions(options) {
|
|
161
|
+
var _a, _b;
|
|
160
162
|
if (options.color) {
|
|
161
163
|
this.color = options.color;
|
|
162
164
|
this.element.style.backgroundColor = this.color;
|
|
@@ -173,8 +175,8 @@ export class Region extends EventEmitter {
|
|
|
173
175
|
});
|
|
174
176
|
}
|
|
175
177
|
if (options.start !== undefined || options.end !== undefined) {
|
|
176
|
-
this.start = options.start
|
|
177
|
-
this.end = options.end
|
|
178
|
+
this.start = (_a = options.start) !== null && _a !== void 0 ? _a : this.start;
|
|
179
|
+
this.end = (_b = options.end) !== null && _b !== void 0 ? _b : this.end;
|
|
178
180
|
this.renderPosition();
|
|
179
181
|
}
|
|
180
182
|
}
|
|
@@ -238,7 +240,7 @@ export class RegionsPlugin extends BasePlugin {
|
|
|
238
240
|
const width = reg.element.scrollWidth;
|
|
239
241
|
return labelLeft < left + width && left < labelLeft + labelWidth;
|
|
240
242
|
})
|
|
241
|
-
.map((reg) => reg.content
|
|
243
|
+
.map((reg) => { var _a; return ((_a = reg.content) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().height) || 0; })
|
|
242
244
|
.reduce((sum, val) => sum + val, 0);
|
|
243
245
|
div.style.marginTop = `${overlap}px`;
|
|
244
246
|
}
|
|
@@ -253,8 +255,9 @@ export class RegionsPlugin extends BasePlugin {
|
|
|
253
255
|
this.emit('region-updated', region);
|
|
254
256
|
}),
|
|
255
257
|
region.on('play', () => {
|
|
256
|
-
|
|
257
|
-
this.wavesurfer
|
|
258
|
+
var _a, _b;
|
|
259
|
+
(_a = this.wavesurfer) === null || _a === void 0 ? void 0 : _a.play();
|
|
260
|
+
(_b = this.wavesurfer) === null || _b === void 0 ? void 0 : _b.setTime(region.start);
|
|
258
261
|
}),
|
|
259
262
|
region.on('click', (e) => {
|
|
260
263
|
this.emit('region-clicked', region, e);
|
|
@@ -293,7 +296,8 @@ export class RegionsPlugin extends BasePlugin {
|
|
|
293
296
|
* Returns a function to disable the drag selection.
|
|
294
297
|
*/
|
|
295
298
|
enableDragSelection(options) {
|
|
296
|
-
|
|
299
|
+
var _a, _b;
|
|
300
|
+
const wrapper = (_b = (_a = this.wavesurfer) === null || _a === void 0 ? void 0 : _a.getWrapper()) === null || _b === void 0 ? void 0 : _b.querySelector('div');
|
|
297
301
|
if (!wrapper)
|
|
298
302
|
return () => undefined;
|
|
299
303
|
const initialSize = 5;
|
|
@@ -320,11 +324,8 @@ export class RegionsPlugin extends BasePlugin {
|
|
|
320
324
|
// Give the region a small initial size
|
|
321
325
|
const end = ((x + initialSize) / width) * duration;
|
|
322
326
|
// Create a region but don't save it until the drag ends
|
|
323
|
-
region = new Region({
|
|
324
|
-
|
|
325
|
-
start,
|
|
326
|
-
end,
|
|
327
|
-
}, duration);
|
|
327
|
+
region = new Region(Object.assign(Object.assign({}, options), { start,
|
|
328
|
+
end }), duration);
|
|
328
329
|
// Just add it to the DOM for now
|
|
329
330
|
this.regionsContainer.appendChild(region.element);
|
|
330
331
|
},
|
|
@@ -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.Regions=t():e.Regions=t()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var e={d:(t,i)=>{for(var n in i)e.o(i,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:i[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{default:()=>a});const i=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 i=this.on(e,t),n=this.on(e,(()=>{i(),n()}));return i}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)))}},n=class extends i{constructor(e){super(),this.subscriptions=[],this.options=e}onInit(){}init(e){this.wavesurfer=e,this.onInit()}destroy(){this.subscriptions.forEach((e=>e()))}};function s(e,t,i,n,s=5){let r=()=>{};if(!e)return r;const o=o=>{o.preventDefault(),o.stopPropagation();let a=o.clientX,
|
|
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()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var e={d:(t,i)=>{for(var n in i)e.o(i,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:i[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{default:()=>a});const i=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 i=this.on(e,t),n=this.on(e,(()=>{i(),n()}));return i}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)))}},n=class extends i{constructor(e){super(),this.subscriptions=[],this.options=e}onInit(){}init(e){this.wavesurfer=e,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((e=>e()))}};function s(e,t,i,n,s=5){let r=()=>{};if(!e)return r;const o=o=>{if(2===o.button)return;o.preventDefault(),o.stopPropagation();let a=o.clientX,l=o.clientY,d=!1;const h=n=>{n.preventDefault(),n.stopPropagation();const r=n.clientX,o=n.clientY;if(d||Math.abs(r-a)>=s||Math.abs(o-l)>=s){const{left:n,top:s}=e.getBoundingClientRect();d||(d=!0,null==i||i(a-n,l-s)),t(r-a,o-l,r-n,o-s),a=r,l=o}},u=e=>{d&&(e.preventDefault(),e.stopPropagation())},c=()=>{d&&(null==n||n()),r()},p=e=>e.preventDefault(),g={passive:!1};document.addEventListener("touchmove",p,g),document.addEventListener("pointermove",h),document.addEventListener("pointerup",c),document.addEventListener("pointerleave",c),document.addEventListener("click",u,!0),r=()=>{document.removeEventListener("touchmove",p,g),document.removeEventListener("pointermove",h),document.removeEventListener("pointerup",c),document.removeEventListener("pointerleave",c),setTimeout((()=>{document.removeEventListener("click",u,!0)}),10)}};return e.addEventListener("pointerdown",o),()=>{r(),e.removeEventListener("pointerdown",o)}}class r extends i{constructor(e,t){var i,n,s,r,o,a;super(),this.totalDuration=t,this.minLength=0,this.maxLength=1/0,this.id=e.id||`region-${Math.random().toString(32).slice(2)}`,this.start=e.start,this.end=null!==(i=e.end)&&void 0!==i?i:e.start,this.drag=null===(n=e.drag)||void 0===n||n,this.resize=null===(s=e.resize)||void 0===s||s,this.color=null!==(r=e.color)&&void 0!==r?r:"rgba(0, 0, 0, 0.1)",this.minLength=null!==(o=e.minLength)&&void 0!==o?o:this.minLength,this.maxLength=null!==(a=e.maxLength)&&void 0!==a?a:this.maxLength,this.element=this.initElement(e.content),this.renderPosition(),this.initMouseEvents()}initElement(e){const t=document.createElement("div"),i=this.start===this.end;if(t.setAttribute("part",`${i?"marker":"region"} ${this.id}`),t.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 `),e&&("string"==typeof e?(this.content=document.createElement("div"),this.content.style.padding=`0.2em ${i?.2:.4}em`,this.content.textContent=e):this.content=e,this.content.setAttribute("part","region-content"),t.appendChild(this.content)),!i){const e=document.createElement("div");e.setAttribute("data-resize","left"),e.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 `),e.setAttribute("part","region-handle region-handle-left");const i=e.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"),t.appendChild(e),t.appendChild(i)}return t}renderPosition(){const e=this.start/this.totalDuration,t=(this.totalDuration-this.end)/this.totalDuration;this.element.style.left=100*e+"%",this.element.style.right=100*t+"%"}initMouseEvents(){const{element:e}=this;e&&(e.addEventListener("click",(e=>this.emit("click",e))),e.addEventListener("mouseenter",(e=>this.emit("over",e))),e.addEventListener("mouseleave",(e=>this.emit("leave",e))),e.addEventListener("dblclick",(e=>this.emit("dblclick",e))),s(e,(e=>this.onMove(e)),(()=>this.onStartMoving()),(()=>this.onEndMoving())),s(e.querySelector('[data-resize="left"]'),(e=>this.onResize(e,"start")),(()=>null),(()=>this.onEndResizing()),1),s(e.querySelector('[data-resize="right"]'),(e=>this.onResize(e,"end")),(()=>null),(()=>this.onEndResizing()),1))}onStartMoving(){this.drag&&(this.element.style.cursor="grabbing")}onEndMoving(){this.drag&&(this.element.style.cursor="grab",this.emit("update-end"))}_onUpdate(e,t){if(!this.element.parentElement)return;const i=e/this.element.parentElement.clientWidth*this.totalDuration,n=t&&"start"!==t?this.start:this.start+i,s=t&&"end"!==t?this.end:this.end+i,r=s-n;n>0&&s<this.totalDuration&&n<=s&&r>=this.minLength&&r<=this.maxLength&&(this.start=n,this.end=s,this.renderPosition(),this.emit("update"))}onMove(e){this.drag&&this._onUpdate(e)}onResize(e,t){this.resize&&this._onUpdate(e,t)}onEndResizing(){this.resize&&this.emit("update-end")}_setTotalDuration(e){this.totalDuration=e,this.renderPosition()}play(){this.emit("play")}setOptions(e){var t,i;e.color&&(this.color=e.color,this.element.style.backgroundColor=this.color),void 0!==e.drag&&(this.drag=e.drag,this.element.style.cursor=this.drag?"grab":"default"),void 0!==e.resize&&(this.resize=e.resize,this.element.querySelectorAll("[data-resize]").forEach((e=>{e.style.cursor=this.resize?"ew-resize":"default"}))),void 0===e.start&&void 0===e.end||(this.start=null!==(t=e.start)&&void 0!==t?t:this.start,this.end=null!==(i=e.end)&&void 0!==i?i:this.end,this.renderPosition())}remove(){this.emit("remove"),this.element.remove(),this.element=null}}class o extends n{constructor(e){super(e),this.regions=[],this.regionsContainer=this.initRegionsContainer()}static create(e){return new o(e)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.wavesurfer.getWrapper().appendChild(this.regionsContainer)}initRegionsContainer(){const e=document.createElement("div");return e.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 "),e}getRegions(){return this.regions}avoidOverlapping(e){if(!e.content)return;const t=e.content,i=t.getBoundingClientRect().left,n=e.element.scrollWidth,s=this.regions.filter((t=>{if(t===e||!t.content)return!1;const s=t.content.getBoundingClientRect().left,r=t.element.scrollWidth;return i<s+r&&s<i+n})).map((e=>{var t;return(null===(t=e.content)||void 0===t?void 0:t.getBoundingClientRect().height)||0})).reduce(((e,t)=>e+t),0);t.style.marginTop=`${s}px`}saveRegion(e){this.regionsContainer.appendChild(e.element),this.avoidOverlapping(e),this.regions.push(e),this.emit("region-created",e);const t=[e.on("update-end",(()=>{this.avoidOverlapping(e),this.emit("region-updated",e)})),e.on("play",(()=>{var t,i;null===(t=this.wavesurfer)||void 0===t||t.play(),null===(i=this.wavesurfer)||void 0===i||i.setTime(e.start)})),e.on("click",(t=>{this.emit("region-clicked",e,t)})),e.on("dblclick",(t=>{this.emit("region-double-clicked",e,t)})),e.once("remove",(()=>{t.forEach((e=>e())),this.regions=this.regions.filter((t=>t!==e))}))];this.subscriptions.push(...t)}addRegion(e){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const t=this.wavesurfer.getDuration(),i=new r(e,t);return t?this.saveRegion(i):this.subscriptions.push(this.wavesurfer.once("ready",(e=>{i._setTotalDuration(e),this.saveRegion(i)}))),i}enableDragSelection(e){var t,i;const n=null===(i=null===(t=this.wavesurfer)||void 0===t?void 0:t.getWrapper())||void 0===i?void 0:i.querySelector("div");if(!n)return()=>{};let o=null,a=0;return s(n,((e,t,i)=>{o&&o._onUpdate(e,i>a?"end":"start")}),(t=>{if(a=t,!this.wavesurfer)return;const i=this.wavesurfer.getDuration(),n=this.wavesurfer.getWrapper().clientWidth,s=t/n*i,l=(t+5)/n*i;o=new r(Object.assign(Object.assign({},e),{start:s,end:l}),i),this.regionsContainer.appendChild(o.element)}),(()=>{o&&(this.saveRegion(o),o=null)}))}clearRegions(){this.regions.forEach((e=>e.remove()))}destroy(){this.clearRegions(),super.destroy()}}const a=o;return t.default})()));
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
/**
|
|
21
21
|
* Spectrogram plugin for wavesurfer.
|
|
22
22
|
*/
|
|
23
|
-
import BasePlugin from '../base-plugin.js';
|
|
23
|
+
import BasePlugin, { type BasePluginEvents } from '../base-plugin.js';
|
|
24
24
|
export type SpectrogramPluginOptions = {
|
|
25
25
|
/** Selector of element or element in which to render */
|
|
26
26
|
container: string | HTMLElement;
|
|
@@ -49,7 +49,7 @@ export type SpectrogramPluginOptions = {
|
|
|
49
49
|
*/
|
|
50
50
|
colorMap?: number[][];
|
|
51
51
|
};
|
|
52
|
-
export type SpectrogramPluginEvents = {
|
|
52
|
+
export type SpectrogramPluginEvents = BasePluginEvents & {
|
|
53
53
|
ready: [];
|
|
54
54
|
click: [relativeX: number];
|
|
55
55
|
};
|
|
@@ -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.Spectrogram=e():t.Spectrogram=e()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var t={d:(e,s)=>{for(var i in s)t.o(s,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:s[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>n});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 s=this.on(t,e),i=this.on(t,(()=>{s(),i()}));return s}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)))}},i=class extends s{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.subscriptions.forEach((t=>t()))}};function a(t,e,s,i){switch(this.bufferSize=t,this.sampleRate=e,this.bandwidth=2/t*(e/2),this.sinTable=new Float32Array(t),this.cosTable=new Float32Array(t),this.windowValues=new Float32Array(t),this.reverseTable=new Uint32Array(t),this.peakBand=0,this.peak=0,s){case"bartlett":for(a=0;a<t;a++)this.windowValues[a]=2/(t-1)*((t-1)/2-Math.abs(a-(t-1)/2));break;case"bartlettHann":for(a=0;a<t;a++)this.windowValues[a]=.62-.48*Math.abs(a/(t-1)-.5)-.38*Math.cos(2*Math.PI*a/(t-1));break;case"blackman":for(i=i||.16,a=0;a<t;a++)this.windowValues[a]=(1-i)/2-.5*Math.cos(2*Math.PI*a/(t-1))+i/2*Math.cos(4*Math.PI*a/(t-1));break;case"cosine":for(a=0;a<t;a++)this.windowValues[a]=Math.cos(Math.PI*a/(t-1)-Math.PI/2);break;case"gauss":for(i=i||.25,a=0;a<t;a++)this.windowValues[a]=Math.pow(Math.E,-.5*Math.pow((a-(t-1)/2)/(i*(t-1)/2),2));break;case"hamming":for(a=0;a<t;a++)this.windowValues[a]=.54-.46*Math.cos(2*Math.PI*a/(t-1));break;case"hann":case void 0:for(a=0;a<t;a++)this.windowValues[a]=.5*(1-Math.cos(2*Math.PI*a/(t-1)));break;case"lanczoz":for(a=0;a<t;a++)this.windowValues[a]=Math.sin(Math.PI*(2*a/(t-1)-1))/(Math.PI*(2*a/(t-1)-1));break;case"rectangular":for(a=0;a<t;a++)this.windowValues[a]=1;break;case"triangular":for(a=0;a<t;a++)this.windowValues[a]=2/t*(t/2-Math.abs(a-(t-1)/2));break;default:throw Error("No such window function '"+s+"'")}for(var a,r=1,n=t>>1;r<t;){for(a=0;a<r;a++)this.reverseTable[a+r]=this.reverseTable[a]+n;r<<=1,n>>=1}for(a=0;a<t;a++)this.sinTable[a]=Math.sin(-Math.PI/a),this.cosTable[a]=Math.cos(-Math.PI/a);this.calculateSpectrum=function(t){var e,s,i,a=this.bufferSize,r=this.cosTable,n=this.sinTable,h=this.reverseTable,o=new Float32Array(a),l=new Float32Array(a),c=2/this.bufferSize,f=Math.sqrt,p=new Float32Array(a/2),u=Math.floor(Math.log(a)/Math.LN2);if(Math.pow(2,u)!==a)throw"Invalid buffer size, must be a power of 2.";if(a!==t.length)throw"Supplied buffer is not the same size as defined FFT. FFT Size: "+a+" Buffer Size: "+t.length;for(var d,w,b,M,g,m,y,v,x=1,S=0;S<a;S++)o[S]=t[h[S]]*this.windowValues[h[S]],l[S]=0;for(;x<a;){d=r[x],w=n[x],b=1,M=0;for(var k=0;k<x;k++){for(S=k;S<a;)m=b*o[g=S+x]-M*l[g],y=b*l[g]+M*o[g],o[g]=o[S]-m,l[g]=l[S]-y,o[S]+=m,l[S]+=y,S+=x<<1;b=(v=b)*d-M*w,M=v*w+M*d}x<<=1}S=0;for(var q=a/2;S<q;S++)(i=c*f((e=o[S])*e+(s=l[S])*s))>this.peak&&(this.peakBand=S,this.peak=i),p[S]=i;return p}}class r extends i{static create(t){return new r(t||{})}constructor(t){if(super(t),this.utils={style:(t,e)=>Object.assign(t.style,e)},this.drawSpectrogram=t=>{isNaN(t[0][0])||(t=[t]);const e=this.spectrCc,s=this.height,i=this.width,a=this.buffer.sampleRate/2,r=this.frequencyMin,n=this.frequencyMax;if(e){for(let h=0;h<t.length;h++){const o=this.resample(t[h]),l=new ImageData(i,s);for(let t=0;t<o.length;t++)for(let e=0;e<o[t].length;e++){const a=this.colorMap[o[t][e]],r=4*((s-e)*i+t);l.data[r]=255*a[0],l.data[r+1]=255*a[1],l.data[r+2]=255*a[2],l.data[r+3]=255*a[3]}createImageBitmap(l).then((t=>{e.drawImage(t,0,s*(1-n/a),i,s*(n-r)/a,0,s*h,i,s)}))}this.emit("ready")}},this.frequenciesDataUrl=t.frequenciesDataUrl,this.container="string"==typeof t.container?document.querySelector(t.container):t.container,t.colorMap){if(t.colorMap.length<256)throw new Error("Colormap must contain 256 elements");for(let e=0;e<t.colorMap.length;e++)if(4!==t.colorMap[e].length)throw new Error("ColorMap entries must contain 4 values");this.colorMap=t.colorMap}else{this.colorMap=[];for(let t=0;t<256;t++){const e=(255-t)/256;this.colorMap.push([e,e,e,1])}}this.fftSamples=t.fftSamples||512,this.height=t.height||this.fftSamples/2,this.noverlap=t.noverlap,this.windowFunc=t.windowFunc,this.alpha=t.alpha,this.channels=1,this.frequencyMin=t.frequencyMin||0,this.frequencyMax=t.frequencyMax||0,this.createWrapper(),this.createCanvas()}onInit(){this.container=this.container||this.wavesurfer.getWrapper(),this.container.appendChild(this.wrapper),this.wavesurfer.options.fillParent&&this.utils.style(this.wrapper,{width:"100%",overflowX:"hidden",overflowY:"hidden"}),this.width=this.wavesurfer.getWrapper().offsetWidth,this.subscriptions.push(this.wavesurfer.on("redraw",(()=>this.render())))}destroy(){this.unAll(),this.wavesurfer.un("ready",this._onReady),this.wavesurfer.un("redraw",this._onRender),this.wavesurfer=null,this.util=null,this.options=null,this.wrapper&&(this.wrapper.remove(),this.wrapper=null)}createWrapper(){if(this.wrapper=document.createElement("div"),this.utils.style(this.wrapper,{display:"block",position:"relative",userSelect:"none",webkitUserSelect:"none",height:this.height*this.channels+"px"}),this.options.labels){const t=document.createElement("canvas");t.setAttribute("part","spec-labels"),t.classList.add("spec-labels"),this.utils.style(t,{position:"absolute",zIndex:9,width:"55px",height:"100%"}),this.wrapper.appendChild(t),this.labelsEl=t}this.wrapper.addEventListener("click",this._onWrapperClick)}_wrapperClickHandler(t){t.preventDefault();const e="offsetX"in t?t.offsetX:t.layerX;this.emit("click",e/this.width||0)}createCanvas(){const t=document.createElement("canvas");this.wrapper.appendChild(t),this.spectrCc=t.getContext("2d"),this.utils.style(t,{position:"absolute",left:0,top:0,width:"100%",height:"100%",zIndex:4}),this.canvas=t}render(){this.canvas.width=this.width,this.canvas.height=this.height,this.frequenciesDataUrl?this.loadFrequenciesData(this.frequenciesDataUrl):this.getFrequencies(this.drawSpectrogram),this.loadLabels(this.options.labelsBackground,"12px","12px","",this.options.labelsColor,this.options.labelsHzColor||this.options.labelsColor,"center","#specLabels")}getFrequencies(t){const e=this.fftSamples,s=this.wavesurfer.getDecodedData(),i=this.channels;if(this.frequencyMax=this.frequencyMax||s.sampleRate/2,!s)return;this.buffer=s;const r=s.sampleRate,n=[];let h=this.noverlap;if(!h){const t=s.length/this.canvas.width;h=Math.max(0,Math.round(e-t))}const o=new a(e,r,this.windowFunc,this.alpha);for(let t=0;t<i;t++){const i=s.getChannelData(t),a=[];let r=0;for(;r+e<i.length;){const t=i.slice(r,r+e),s=o.calculateSpectrum(t),n=new Uint8Array(e/2);let l;for(l=0;l<e/2;l++)n[l]=Math.max(-255,45*Math.log10(s[l]));a.push(n),r+=e-h}n.push(a)}t(n,this)}loadFrequenciesData(t){return fetch(t).then((t=>t.json())).then(this.drawSpectrogram)}freqType(t){return t>=1e3?(t/1e3).toFixed(1):Math.round(t)}unitType(t){return t>=1e3?"KHz":"Hz"}loadLabels(t,e,s,i,a,r,n,h){t=t||"rgba(68,68,68,0)",e=e||"12px",s=s||"12px",i=i||"Helvetica",a=a||"#fff",r=r||"#fff",n=n||"center",h=h||"#specLabels";const o=this.height||512,l=o/256*5,c=this.frequencyMin,f=(this.frequencyMax-c)/l,p=this.labelsEl.getContext("2d"),u=window.devicePixelRatio;if(this.labelsEl.height=this.height*this.channels*u,this.labelsEl.width=55*u,p.scale(u,u),p)for(let h=0;h<this.channels;h++){let u;for(p.fillStyle=t,p.fillRect(0,h*o,55,(1+h)*o),p.fill(),u=0;u<=l;u++){p.textAlign=n,p.textBaseline="middle";const t=c+f*u,l=this.freqType(t),d=this.unitType(t),w=16;let b;b=0==u?(1+h)*o+u-10:(1+h)*o-50*u+2,p.fillStyle=r,p.font=s+" "+i,p.fillText(d,w+24,b),p.fillStyle=a,p.font=e+" "+i,p.fillText(l,w,b)}}}resample(t){const e=this.width,s=[],i=1/t.length,a=1/e;let r;for(r=0;r<e;r++){const e=new Array(t[0].length);let n;for(n=0;n<t.length;n++){const s=n*i,h=s+i,o=r*a,l=o+a,c=h<=o||l<=s?0:Math.min(Math.max(h,o),Math.max(l,s))-Math.max(Math.min(h,o),Math.min(l,s));let f;if(c>0)for(f=0;f<t[0].length;f++)null==e[f]&&(e[f]=0),e[f]+=c/a*t[n][f]}const h=new Uint8Array(t[0].length);let o;for(o=0;o<t[0].length;o++)h[o]=e[o];s.push(h)}return s}}const n=r;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.Spectrogram=e():t.Spectrogram=e()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var t={d:(e,s)=>{for(var i in s)t.o(s,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:s[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>n});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 s=this.on(t,e),i=this.on(t,(()=>{s(),i()}));return s}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)))}},i=class extends s{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}};function a(t,e,s,i){switch(this.bufferSize=t,this.sampleRate=e,this.bandwidth=2/t*(e/2),this.sinTable=new Float32Array(t),this.cosTable=new Float32Array(t),this.windowValues=new Float32Array(t),this.reverseTable=new Uint32Array(t),this.peakBand=0,this.peak=0,s){case"bartlett":for(a=0;a<t;a++)this.windowValues[a]=2/(t-1)*((t-1)/2-Math.abs(a-(t-1)/2));break;case"bartlettHann":for(a=0;a<t;a++)this.windowValues[a]=.62-.48*Math.abs(a/(t-1)-.5)-.38*Math.cos(2*Math.PI*a/(t-1));break;case"blackman":for(i=i||.16,a=0;a<t;a++)this.windowValues[a]=(1-i)/2-.5*Math.cos(2*Math.PI*a/(t-1))+i/2*Math.cos(4*Math.PI*a/(t-1));break;case"cosine":for(a=0;a<t;a++)this.windowValues[a]=Math.cos(Math.PI*a/(t-1)-Math.PI/2);break;case"gauss":for(i=i||.25,a=0;a<t;a++)this.windowValues[a]=Math.pow(Math.E,-.5*Math.pow((a-(t-1)/2)/(i*(t-1)/2),2));break;case"hamming":for(a=0;a<t;a++)this.windowValues[a]=.54-.46*Math.cos(2*Math.PI*a/(t-1));break;case"hann":case void 0:for(a=0;a<t;a++)this.windowValues[a]=.5*(1-Math.cos(2*Math.PI*a/(t-1)));break;case"lanczoz":for(a=0;a<t;a++)this.windowValues[a]=Math.sin(Math.PI*(2*a/(t-1)-1))/(Math.PI*(2*a/(t-1)-1));break;case"rectangular":for(a=0;a<t;a++)this.windowValues[a]=1;break;case"triangular":for(a=0;a<t;a++)this.windowValues[a]=2/t*(t/2-Math.abs(a-(t-1)/2));break;default:throw Error("No such window function '"+s+"'")}for(var a,r=1,n=t>>1;r<t;){for(a=0;a<r;a++)this.reverseTable[a+r]=this.reverseTable[a]+n;r<<=1,n>>=1}for(a=0;a<t;a++)this.sinTable[a]=Math.sin(-Math.PI/a),this.cosTable[a]=Math.cos(-Math.PI/a);this.calculateSpectrum=function(t){var e,s,i,a=this.bufferSize,r=this.cosTable,n=this.sinTable,h=this.reverseTable,o=new Float32Array(a),l=new Float32Array(a),c=2/this.bufferSize,f=Math.sqrt,p=new Float32Array(a/2),u=Math.floor(Math.log(a)/Math.LN2);if(Math.pow(2,u)!==a)throw"Invalid buffer size, must be a power of 2.";if(a!==t.length)throw"Supplied buffer is not the same size as defined FFT. FFT Size: "+a+" Buffer Size: "+t.length;for(var d,w,b,M,g,m,y,v,x=1,S=0;S<a;S++)o[S]=t[h[S]]*this.windowValues[h[S]],l[S]=0;for(;x<a;){d=r[x],w=n[x],b=1,M=0;for(var k=0;k<x;k++){for(S=k;S<a;)m=b*o[g=S+x]-M*l[g],y=b*l[g]+M*o[g],o[g]=o[S]-m,l[g]=l[S]-y,o[S]+=m,l[S]+=y,S+=x<<1;b=(v=b)*d-M*w,M=v*w+M*d}x<<=1}S=0;for(var q=a/2;S<q;S++)(i=c*f((e=o[S])*e+(s=l[S])*s))>this.peak&&(this.peakBand=S,this.peak=i),p[S]=i;return p}}class r extends i{static create(t){return new r(t||{})}constructor(t){if(super(t),this.utils={style:(t,e)=>Object.assign(t.style,e)},this.drawSpectrogram=t=>{isNaN(t[0][0])||(t=[t]);const e=this.spectrCc,s=this.height,i=this.width,a=this.buffer.sampleRate/2,r=this.frequencyMin,n=this.frequencyMax;if(e){for(let h=0;h<t.length;h++){const o=this.resample(t[h]),l=new ImageData(i,s);for(let t=0;t<o.length;t++)for(let e=0;e<o[t].length;e++){const a=this.colorMap[o[t][e]],r=4*((s-e)*i+t);l.data[r]=255*a[0],l.data[r+1]=255*a[1],l.data[r+2]=255*a[2],l.data[r+3]=255*a[3]}createImageBitmap(l).then((t=>{e.drawImage(t,0,s*(1-n/a),i,s*(n-r)/a,0,s*h,i,s)}))}this.emit("ready")}},this.frequenciesDataUrl=t.frequenciesDataUrl,this.container="string"==typeof t.container?document.querySelector(t.container):t.container,t.colorMap){if(t.colorMap.length<256)throw new Error("Colormap must contain 256 elements");for(let e=0;e<t.colorMap.length;e++)if(4!==t.colorMap[e].length)throw new Error("ColorMap entries must contain 4 values");this.colorMap=t.colorMap}else{this.colorMap=[];for(let t=0;t<256;t++){const e=(255-t)/256;this.colorMap.push([e,e,e,1])}}this.fftSamples=t.fftSamples||512,this.height=t.height||this.fftSamples/2,this.noverlap=t.noverlap,this.windowFunc=t.windowFunc,this.alpha=t.alpha,this.channels=1,this.frequencyMin=t.frequencyMin||0,this.frequencyMax=t.frequencyMax||0,this.createWrapper(),this.createCanvas()}onInit(){this.container=this.container||this.wavesurfer.getWrapper(),this.container.appendChild(this.wrapper),this.wavesurfer.options.fillParent&&this.utils.style(this.wrapper,{width:"100%",overflowX:"hidden",overflowY:"hidden"}),this.width=this.wavesurfer.getWrapper().offsetWidth,this.subscriptions.push(this.wavesurfer.on("redraw",(()=>this.render())))}destroy(){this.unAll(),this.wavesurfer.un("ready",this._onReady),this.wavesurfer.un("redraw",this._onRender),this.wavesurfer=null,this.util=null,this.options=null,this.wrapper&&(this.wrapper.remove(),this.wrapper=null),super.destroy()}createWrapper(){if(this.wrapper=document.createElement("div"),this.utils.style(this.wrapper,{display:"block",position:"relative",userSelect:"none",webkitUserSelect:"none",height:this.height*this.channels+"px"}),this.options.labels){const t=document.createElement("canvas");t.setAttribute("part","spec-labels"),t.classList.add("spec-labels"),this.utils.style(t,{position:"absolute",zIndex:9,width:"55px",height:"100%"}),this.wrapper.appendChild(t),this.labelsEl=t}this.wrapper.addEventListener("click",this._onWrapperClick)}_wrapperClickHandler(t){t.preventDefault();const e="offsetX"in t?t.offsetX:t.layerX;this.emit("click",e/this.width||0)}createCanvas(){const t=document.createElement("canvas");this.wrapper.appendChild(t),this.spectrCc=t.getContext("2d"),this.utils.style(t,{position:"absolute",left:0,top:0,width:"100%",height:"100%",zIndex:4}),this.canvas=t}render(){this.canvas.width=this.width,this.canvas.height=this.height,this.frequenciesDataUrl?this.loadFrequenciesData(this.frequenciesDataUrl):this.getFrequencies(this.drawSpectrogram),this.loadLabels(this.options.labelsBackground,"12px","12px","",this.options.labelsColor,this.options.labelsHzColor||this.options.labelsColor,"center","#specLabels")}getFrequencies(t){const e=this.fftSamples,s=this.wavesurfer.getDecodedData(),i=this.channels;if(this.frequencyMax=this.frequencyMax||s.sampleRate/2,!s)return;this.buffer=s;const r=s.sampleRate,n=[];let h=this.noverlap;if(!h){const t=s.length/this.canvas.width;h=Math.max(0,Math.round(e-t))}const o=new a(e,r,this.windowFunc,this.alpha);for(let t=0;t<i;t++){const i=s.getChannelData(t),a=[];let r=0;for(;r+e<i.length;){const t=i.slice(r,r+e),s=o.calculateSpectrum(t),n=new Uint8Array(e/2);let l;for(l=0;l<e/2;l++)n[l]=Math.max(-255,45*Math.log10(s[l]));a.push(n),r+=e-h}n.push(a)}t(n,this)}loadFrequenciesData(t){return fetch(t).then((t=>t.json())).then(this.drawSpectrogram)}freqType(t){return t>=1e3?(t/1e3).toFixed(1):Math.round(t)}unitType(t){return t>=1e3?"KHz":"Hz"}loadLabels(t,e,s,i,a,r,n,h){t=t||"rgba(68,68,68,0)",e=e||"12px",s=s||"12px",i=i||"Helvetica",a=a||"#fff",r=r||"#fff",n=n||"center",h=h||"#specLabels";const o=this.height||512,l=o/256*5,c=this.frequencyMin,f=(this.frequencyMax-c)/l,p=this.labelsEl.getContext("2d"),u=window.devicePixelRatio;if(this.labelsEl.height=this.height*this.channels*u,this.labelsEl.width=55*u,p.scale(u,u),p)for(let h=0;h<this.channels;h++){let u;for(p.fillStyle=t,p.fillRect(0,h*o,55,(1+h)*o),p.fill(),u=0;u<=l;u++){p.textAlign=n,p.textBaseline="middle";const t=c+f*u,l=this.freqType(t),d=this.unitType(t),w=16;let b;b=0==u?(1+h)*o+u-10:(1+h)*o-50*u+2,p.fillStyle=r,p.font=s+" "+i,p.fillText(d,w+24,b),p.fillStyle=a,p.font=e+" "+i,p.fillText(l,w,b)}}}resample(t){const e=this.width,s=[],i=1/t.length,a=1/e;let r;for(r=0;r<e;r++){const e=new Array(t[0].length);let n;for(n=0;n<t.length;n++){const s=n*i,h=s+i,o=r*a,l=o+a,c=h<=o||l<=s?0:Math.min(Math.max(h,o),Math.max(l,s))-Math.max(Math.min(h,o),Math.min(l,s));let f;if(c>0)for(f=0;f<t[0].length;f++)null==e[f]&&(e[f]=0),e[f]+=c/a*t[n][f]}const h=new Uint8Array(t[0].length);let o;for(o=0;o<t[0].length;o++)h[o]=e[o];s.push(h)}return s}}const n=r;return e.default})()));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The Timeline plugin adds timestamps and notches under the waveform.
|
|
3
3
|
*/
|
|
4
|
-
import BasePlugin from '../base-plugin.js';
|
|
4
|
+
import BasePlugin, { type BasePluginEvents } from '../base-plugin.js';
|
|
5
5
|
export type TimelinePluginOptions = {
|
|
6
6
|
/** The height of the timeline in pixels, defaults to 20 */
|
|
7
7
|
height?: number;
|
|
@@ -19,11 +19,14 @@ export type TimelinePluginOptions = {
|
|
|
19
19
|
secondaryLabelInterval?: number;
|
|
20
20
|
/** Custom inline style to apply to the container */
|
|
21
21
|
style?: Partial<CSSStyleDeclaration> | string;
|
|
22
|
+
/** Turn the time into a suitable label for the time. */
|
|
23
|
+
formatTimeCallback?: (seconds: number) => string;
|
|
22
24
|
};
|
|
23
25
|
declare const defaultOptions: {
|
|
24
26
|
height: number;
|
|
27
|
+
formatTimeCallback: (seconds: number) => string;
|
|
25
28
|
};
|
|
26
|
-
export type TimelinePluginEvents = {
|
|
29
|
+
export type TimelinePluginEvents = BasePluginEvents & {
|
|
27
30
|
ready: [];
|
|
28
31
|
};
|
|
29
32
|
export declare class TimelinePlugin extends BasePlugin<TimelinePluginEvents, TimelinePluginOptions> {
|
|
@@ -36,7 +39,6 @@ export declare class TimelinePlugin extends BasePlugin<TimelinePluginEvents, Tim
|
|
|
36
39
|
/** Unmount */
|
|
37
40
|
destroy(): void;
|
|
38
41
|
private initTimelineWrapper;
|
|
39
|
-
private formatTime;
|
|
40
42
|
private defaultTimeInterval;
|
|
41
43
|
private defaultPrimaryLabelInterval;
|
|
42
44
|
private defaultSecondaryLabelInterval;
|
package/dist/plugins/timeline.js
CHANGED
|
@@ -4,6 +4,17 @@
|
|
|
4
4
|
import BasePlugin from '../base-plugin.js';
|
|
5
5
|
const defaultOptions = {
|
|
6
6
|
height: 20,
|
|
7
|
+
formatTimeCallback: (seconds) => {
|
|
8
|
+
if (seconds / 60 > 1) {
|
|
9
|
+
// calculate minutes and seconds from seconds count
|
|
10
|
+
const minutes = Math.floor(seconds / 60);
|
|
11
|
+
seconds = Math.round(seconds % 60);
|
|
12
|
+
const paddedSeconds = `${seconds < 10 ? '0' : ''}${seconds}`;
|
|
13
|
+
return `${minutes}:${paddedSeconds}`;
|
|
14
|
+
}
|
|
15
|
+
const rounded = Math.round(seconds * 1000) / 1000;
|
|
16
|
+
return `${rounded}`;
|
|
17
|
+
},
|
|
7
18
|
};
|
|
8
19
|
export class TimelinePlugin extends BasePlugin {
|
|
9
20
|
constructor(options) {
|
|
@@ -16,10 +27,11 @@ export class TimelinePlugin extends BasePlugin {
|
|
|
16
27
|
}
|
|
17
28
|
/** Called by wavesurfer, don't call manually */
|
|
18
29
|
onInit() {
|
|
30
|
+
var _a;
|
|
19
31
|
if (!this.wavesurfer) {
|
|
20
32
|
throw Error('WaveSurfer is not initialized');
|
|
21
33
|
}
|
|
22
|
-
const container = this.options.container
|
|
34
|
+
const container = (_a = this.options.container) !== null && _a !== void 0 ? _a : this.wavesurfer.getWrapper();
|
|
23
35
|
if (this.options.insertPosition) {
|
|
24
36
|
;
|
|
25
37
|
(container.firstElementChild || container).insertAdjacentElement(this.options.insertPosition, this.timelineWrapper);
|
|
@@ -32,7 +44,8 @@ export class TimelinePlugin extends BasePlugin {
|
|
|
32
44
|
}
|
|
33
45
|
else {
|
|
34
46
|
this.subscriptions.push(this.wavesurfer.on('redraw', () => {
|
|
35
|
-
|
|
47
|
+
var _a;
|
|
48
|
+
this.initTimeline(((_a = this.wavesurfer) === null || _a === void 0 ? void 0 : _a.getDuration()) || 0);
|
|
36
49
|
}));
|
|
37
50
|
}
|
|
38
51
|
}
|
|
@@ -46,17 +59,6 @@ export class TimelinePlugin extends BasePlugin {
|
|
|
46
59
|
div.setAttribute('part', 'timeline');
|
|
47
60
|
return div;
|
|
48
61
|
}
|
|
49
|
-
formatTime(seconds) {
|
|
50
|
-
if (seconds / 60 > 1) {
|
|
51
|
-
// calculate minutes and seconds from seconds count
|
|
52
|
-
const minutes = Math.floor(seconds / 60);
|
|
53
|
-
seconds = Math.round(seconds % 60);
|
|
54
|
-
const paddedSeconds = `${seconds < 10 ? '0' : ''}${seconds}`;
|
|
55
|
-
return `${minutes}:${paddedSeconds}`;
|
|
56
|
-
}
|
|
57
|
-
const rounded = Math.round(seconds * 1000) / 1000;
|
|
58
|
-
return `${rounded}`;
|
|
59
|
-
}
|
|
60
62
|
// Return how many seconds should be between each notch
|
|
61
63
|
defaultTimeInterval(pxPerSec) {
|
|
62
64
|
if (pxPerSec >= 25) {
|
|
@@ -97,10 +99,11 @@ export class TimelinePlugin extends BasePlugin {
|
|
|
97
99
|
return 2;
|
|
98
100
|
}
|
|
99
101
|
initTimeline(duration) {
|
|
102
|
+
var _a, _b, _c;
|
|
100
103
|
const pxPerSec = this.timelineWrapper.scrollWidth / duration;
|
|
101
|
-
const timeInterval = this.options.timeInterval
|
|
102
|
-
const primaryLabelInterval = this.options.primaryLabelInterval
|
|
103
|
-
const secondaryLabelInterval = this.options.secondaryLabelInterval
|
|
104
|
+
const timeInterval = (_a = this.options.timeInterval) !== null && _a !== void 0 ? _a : this.defaultTimeInterval(pxPerSec);
|
|
105
|
+
const primaryLabelInterval = (_b = this.options.primaryLabelInterval) !== null && _b !== void 0 ? _b : this.defaultPrimaryLabelInterval(pxPerSec);
|
|
106
|
+
const secondaryLabelInterval = (_c = this.options.secondaryLabelInterval) !== null && _c !== void 0 ? _c : this.defaultSecondaryLabelInterval(pxPerSec);
|
|
104
107
|
const isTop = this.options.insertPosition === 'beforebegin';
|
|
105
108
|
const timeline = document.createElement('div');
|
|
106
109
|
timeline.setAttribute('style', `
|
|
@@ -146,7 +149,7 @@ export class TimelinePlugin extends BasePlugin {
|
|
|
146
149
|
if (isPrimary || isSecondary) {
|
|
147
150
|
notch.style.height = '100%';
|
|
148
151
|
notch.style.textIndent = '3px';
|
|
149
|
-
notch.textContent = this.
|
|
152
|
+
notch.textContent = this.options.formatTimeCallback(i);
|
|
150
153
|
if (isPrimary)
|
|
151
154
|
notch.style.opacity = '1';
|
|
152
155
|
}
|
|
@@ -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.Timeline=e():t.Timeline=e()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>o});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),n=this.on(t,(()=>{i(),n()}));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 i{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.subscriptions.forEach((t=>t()))}},s={height:20};class r extends n{constructor(t){super(t||{}),this.options=Object.assign({},s,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
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Timeline=e():t.Timeline=e()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>o});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),n=this.on(t,(()=>{i(),n()}));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 i{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}},s={height:20,formatTimeCallback:t=>t/60>1?`${Math.floor(t/60)}:${(t=Math.round(t%60))<10?"0":""}${t}`:""+Math.round(1e3*t)/1e3};class r extends n{constructor(t){super(t||{}),this.options=Object.assign({},s,t),this.timelineWrapper=this.initTimelineWrapper()}static create(t){return new r(t)}onInit(){var t;if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const e=null!==(t=this.options.container)&&void 0!==t?t:this.wavesurfer.getWrapper();this.options.insertPosition?(e.firstElementChild||e).insertAdjacentElement(this.options.insertPosition,this.timelineWrapper):e.appendChild(this.timelineWrapper),this.options.duration?this.initTimeline(this.options.duration):this.subscriptions.push(this.wavesurfer.on("redraw",(()=>{var t;this.initTimeline((null===(t=this.wavesurfer)||void 0===t?void 0:t.getDuration())||0)})))}destroy(){this.timelineWrapper.remove(),super.destroy()}initTimelineWrapper(){const t=document.createElement("div");return t.setAttribute("part","timeline"),t}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){var e,i,n;const s=this.timelineWrapper.scrollWidth/t,r=null!==(e=this.options.timeInterval)&&void 0!==e?e:this.defaultTimeInterval(s),o=null!==(i=this.options.primaryLabelInterval)&&void 0!==i?i:this.defaultPrimaryLabelInterval(s),l=null!==(n=this.options.secondaryLabelInterval)&&void 0!==n?n:this.defaultSecondaryLabelInterval(s),a="beforebegin"===this.options.insertPosition,h=document.createElement("div");if(h.setAttribute("style",`\n height: ${this.options.height}px;\n overflow: hidden;\n display: flex;\n justify-content: space-between;\n align-items: ${a?"flex-start":"flex-end"};\n font-size: ${this.options.height/2}px;\n white-space: nowrap;\n `),a){const t="\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 2;\n ";h.setAttribute("style",h.getAttribute("style")+t)}"string"==typeof this.options.style?h.setAttribute("style",h.getAttribute("style")+this.options.style):"object"==typeof this.options.style&&Object.assign(h.style,this.options.style);const p=document.createElement("div");p.setAttribute("style",`\n width: 1px;\n height: 50%;\n display: flex;\n flex-direction: column;\n justify-content: ${a?"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+=r){const t=p.cloneNode(),i=Math.round(100*e)/100%o==0,n=Math.round(100*e)/100%l==0;(i||n)&&(t.style.height="100%",t.style.textIndent="3px",t.textContent=this.options.formatTimeCallback(e),i&&(t.style.opacity="1")),h.appendChild(t)}this.timelineWrapper.innerHTML="",this.timelineWrapper.appendChild(h),this.emit("ready")}}const o=r;return e.default})()));
|
package/dist/renderer.js
CHANGED
|
@@ -160,8 +160,9 @@ class Renderer extends EventEmitter {
|
|
|
160
160
|
return this.scrollContainer.scrollLeft;
|
|
161
161
|
}
|
|
162
162
|
destroy() {
|
|
163
|
+
var _a;
|
|
163
164
|
this.container.remove();
|
|
164
|
-
this.resizeObserver
|
|
165
|
+
(_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
165
166
|
}
|
|
166
167
|
createDelay(delayMs = 10) {
|
|
167
168
|
const context = {};
|
|
@@ -215,6 +216,7 @@ class Renderer extends EventEmitter {
|
|
|
215
216
|
}
|
|
216
217
|
}
|
|
217
218
|
const vScale = (halfHeight / max) * barHeight;
|
|
219
|
+
const rectFn = barRadius && 'roundRect' in ctx ? 'roundRect' : 'rect';
|
|
218
220
|
ctx.beginPath();
|
|
219
221
|
let prevX = 0;
|
|
220
222
|
let maxTop = 0;
|
|
@@ -231,7 +233,7 @@ class Renderer extends EventEmitter {
|
|
|
231
233
|
y = 0;
|
|
232
234
|
else if (options.barAlign === 'bottom')
|
|
233
235
|
y = height - barHeight;
|
|
234
|
-
ctx
|
|
236
|
+
ctx[rectFn](prevX * (barWidth + barGap), y, barWidth, barHeight, barRadius);
|
|
235
237
|
prevX = x;
|
|
236
238
|
maxTop = 0;
|
|
237
239
|
maxBottom = 0;
|
|
@@ -354,7 +356,7 @@ class Renderer extends EventEmitter {
|
|
|
354
356
|
if (this.options.splitChannels) {
|
|
355
357
|
// Render a waveform for each channel
|
|
356
358
|
for (let i = 0; i < audioData.numberOfChannels; i++) {
|
|
357
|
-
const options = {
|
|
359
|
+
const options = Object.assign(Object.assign({}, this.options), this.options.splitChannels[i]);
|
|
358
360
|
this.renderWaveform([audioData.getChannelData(i)], options, width);
|
|
359
361
|
}
|
|
360
362
|
}
|
package/dist/wavesurfer.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
import Decoder from './decoder.js';
|
|
2
11
|
import Fetcher from './fetcher.js';
|
|
3
12
|
import Player from './player.js';
|
|
@@ -21,6 +30,7 @@ export class WaveSurfer extends Player {
|
|
|
21
30
|
}
|
|
22
31
|
/** Create a new WaveSurfer instance */
|
|
23
32
|
constructor(options) {
|
|
33
|
+
var _a, _b;
|
|
24
34
|
super({
|
|
25
35
|
media: options.media,
|
|
26
36
|
autoplay: options.autoplay,
|
|
@@ -37,7 +47,7 @@ export class WaveSurfer extends Player {
|
|
|
37
47
|
this.initRendererEvents();
|
|
38
48
|
this.initTimerEvents();
|
|
39
49
|
this.initPlugins();
|
|
40
|
-
const url = this.options.url || this.options.media
|
|
50
|
+
const url = this.options.url || ((_a = this.options.media) === null || _a === void 0 ? void 0 : _a.currentSrc) || ((_b = this.options.media) === null || _b === void 0 ? void 0 : _b.src);
|
|
41
51
|
if (url) {
|
|
42
52
|
this.load(url, this.options.peaks, this.options.duration);
|
|
43
53
|
}
|
|
@@ -113,7 +123,8 @@ export class WaveSurfer extends Player {
|
|
|
113
123
|
}
|
|
114
124
|
}
|
|
115
125
|
initPlugins() {
|
|
116
|
-
|
|
126
|
+
var _a;
|
|
127
|
+
if (!((_a = this.options.plugins) === null || _a === void 0 ? void 0 : _a.length))
|
|
117
128
|
return;
|
|
118
129
|
this.options.plugins.forEach((plugin) => {
|
|
119
130
|
this.registerPlugin(plugin);
|
|
@@ -123,6 +134,10 @@ export class WaveSurfer extends Player {
|
|
|
123
134
|
registerPlugin(plugin) {
|
|
124
135
|
plugin.init(this);
|
|
125
136
|
this.plugins.push(plugin);
|
|
137
|
+
// Unregister plugin on destroy
|
|
138
|
+
this.subscriptions.push(plugin.once('destroy', () => {
|
|
139
|
+
this.plugins = this.plugins.filter((p) => p !== plugin);
|
|
140
|
+
}));
|
|
126
141
|
return plugin;
|
|
127
142
|
}
|
|
128
143
|
/** For plugins only: get the waveform wrapper div */
|
|
@@ -138,42 +153,44 @@ export class WaveSurfer extends Player {
|
|
|
138
153
|
return this.plugins;
|
|
139
154
|
}
|
|
140
155
|
/** Load an audio file by URL, with optional pre-decoded audio data */
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
this.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
duration
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
else if (blob) {
|
|
164
|
-
const arrayBuffer = await blob.arrayBuffer();
|
|
165
|
-
this.decodedData = await Decoder.decode(arrayBuffer, this.options.sampleRate);
|
|
166
|
-
// Fall back to the decoded data duration if the media duration is incorrect
|
|
167
|
-
if (this.duration === 0 || this.duration === Infinity) {
|
|
168
|
-
this.duration = this.decodedData.duration;
|
|
156
|
+
load(url, channelData, duration) {
|
|
157
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
158
|
+
if (this.isPlaying())
|
|
159
|
+
this.pause();
|
|
160
|
+
this.decodedData = null;
|
|
161
|
+
this.duration = null;
|
|
162
|
+
this.emit('load', url);
|
|
163
|
+
// Fetch the entire audio as a blob if pre-decoded data is not provided
|
|
164
|
+
const blob = channelData ? undefined : yield Fetcher.fetchBlob(url, this.options.fetchParams);
|
|
165
|
+
// Set the mediaelement source to the URL
|
|
166
|
+
this.setSrc(url, blob);
|
|
167
|
+
// Wait for the audio duration
|
|
168
|
+
this.duration =
|
|
169
|
+
duration ||
|
|
170
|
+
this.getDuration() ||
|
|
171
|
+
(yield new Promise((resolve) => {
|
|
172
|
+
this.onceMediaEvent('loadedmetadata', () => resolve(this.getDuration()));
|
|
173
|
+
})) ||
|
|
174
|
+
0;
|
|
175
|
+
// Decode the audio data or use user-provided peaks
|
|
176
|
+
if (channelData) {
|
|
177
|
+
this.decodedData = Decoder.createBuffer(channelData, this.duration);
|
|
169
178
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
179
|
+
else if (blob) {
|
|
180
|
+
const arrayBuffer = yield blob.arrayBuffer();
|
|
181
|
+
this.decodedData = yield Decoder.decode(arrayBuffer, this.options.sampleRate);
|
|
182
|
+
// Fall back to the decoded data duration if the media duration is incorrect
|
|
183
|
+
if (this.duration === 0 || this.duration === Infinity) {
|
|
184
|
+
this.duration = this.decodedData.duration;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
this.emit('decode', this.duration);
|
|
188
|
+
// Render the waveform
|
|
189
|
+
if (this.decodedData) {
|
|
190
|
+
this.renderer.render(this.decodedData);
|
|
191
|
+
}
|
|
192
|
+
this.emit('ready', this.duration);
|
|
193
|
+
});
|
|
177
194
|
}
|
|
178
195
|
/** Zoom the waveform by a given pixels-per-second factor */
|
|
179
196
|
zoom(minPxPerSec) {
|
|
@@ -203,8 +220,10 @@ export class WaveSurfer extends Player {
|
|
|
203
220
|
this.setTime(time);
|
|
204
221
|
}
|
|
205
222
|
/** Play or pause the audio */
|
|
206
|
-
|
|
207
|
-
return this
|
|
223
|
+
playPause() {
|
|
224
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
225
|
+
return this.isPlaying() ? this.pause() : this.play();
|
|
226
|
+
});
|
|
208
227
|
}
|
|
209
228
|
/** Stop the audio and go to the beginning */
|
|
210
229
|
stop() {
|
|
@@ -222,8 +241,8 @@ export class WaveSurfer extends Player {
|
|
|
222
241
|
/** Unmount wavesurfer */
|
|
223
242
|
destroy() {
|
|
224
243
|
this.emit('destroy');
|
|
225
|
-
this.subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
226
244
|
this.plugins.forEach((plugin) => plugin.destroy());
|
|
245
|
+
this.subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
227
246
|
this.timer.destroy();
|
|
228
247
|
this.renderer.destroy();
|
|
229
248
|
super.destroy();
|