@meersagor/wavesurfer-vue 0.0.4 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,7 +46,6 @@ const options = ref({
46
46
  barWidth: 5,
47
47
  barRadius: 8,
48
48
  duration: 80,
49
- // cursorWidth: 0,
50
49
  url: "https://revews-bucket.s3.ap-southeast-1.amazonaws.com/a06mmMU3sgnzuUkH4OiHvyuUgCFdLSnJaDLBao7y.webm",
51
50
  })
52
51
 
@@ -123,7 +122,57 @@ const formatTime = (seconds: number):string => [seconds / 60, seconds % 60].map(
123
122
 
124
123
 
125
124
 
126
- ## useUseWaveSurferRecorder: composeable method Return Types
125
+ ## useWaveSurferRecorder: composable method Return Types
126
+
127
+ ```vue
128
+ <script lang="ts" setup>
129
+ import { computed, ref } from 'vue'
130
+ import { useWaveSurferRecorder } from '@meersagor/wavesurfer-vue'
131
+ const showAudioRecordButton = ref<boolean>(true)
132
+ const containerRef = ref<HTMLDivElement | null>(null)
133
+
134
+ const options = computed(() => ({
135
+ height: 48,
136
+ waveColor: "#66667D",
137
+ progressColor: "#6A24FF",
138
+ barGap: 5,
139
+ barWidth: 5,
140
+ barRadius: 8,
141
+ cursorWidth: 0,
142
+ url: "https://revews-bucket.s3.ap-southeast-1.amazonaws.com/a06mmMU3sgnzuUkH4OiHvyuUgCFdLSnJaDLBao7y.webm",
143
+ }))
144
+
145
+ const { pauseRecording, startRecording, stopRecording, currentTime, isPauseResume } = useWaveSurferRecorder({
146
+ containerRef,
147
+ options: options.value,
148
+ })
149
+
150
+ const startAudioRecordHandler = () => {
151
+ startRecording()
152
+ showAudioRecordButton.value = false
153
+ }
154
+
155
+ const stopHandler = async () => {
156
+ const blob = await stopRecording()
157
+ console.log('blob =====', blob);
158
+ showAudioRecordButton.value = true
159
+ }
160
+ </script>
161
+
162
+ <template>
163
+ <div>
164
+ <div>
165
+ <div ref="containerRef"></div>
166
+ </div>
167
+ <p>{{ currentTime }}</p>
168
+ <button v-if="showAudioRecordButton" @click="startAudioRecordHandler"> Start Recording </button>
169
+ <div v-else>
170
+ <button @click="pauseRecording">{{ isPauseResume ? 'pause' : 'resume' }}</button>
171
+ <button @click="stopHandler">Stop</button>
172
+ </div>
173
+ </div>
174
+ </template>
175
+ ```
127
176
 
128
177
  ### `waveSurfer`
129
178
 
@@ -1,73 +1,325 @@
1
- import { ref as r, onMounted as c, onUnmounted as i, defineComponent as m, getCurrentInstance as y, openBlock as S, createElementBlock as h } from "vue";
2
- import W from "wavesurfer.js";
3
- const g = ({ containerRef: e, options: l }) => {
4
- const a = r(null), t = () => {
5
- e.value && (a.value = W.create({
6
- container: e.value,
7
- ...l
1
+ import { ref as h, onMounted as p, onUnmounted as y, defineComponent as b, getCurrentInstance as A, openBlock as D, createElementBlock as M, computed as w } from "vue";
2
+ import T from "wavesurfer.js";
3
+ const W = ({ containerRef: n, options: e }) => {
4
+ const t = h(null), i = () => {
5
+ n.value && (t.value = T.create({
6
+ container: n.value,
7
+ ...e
8
8
  }));
9
- }, n = () => {
10
- a.value && (a.value.destroy(), a.value = null);
9
+ }, r = () => {
10
+ t.value && (t.value.destroy(), t.value = null);
11
11
  };
12
- return c(() => {
13
- t();
14
- }), i(() => {
15
- n();
16
- }), { waveSurfer: a };
17
- }, _ = (e) => {
18
- const l = r(!1), a = r(!1), t = r(0), n = r(0), o = () => {
19
- l.value = !1, a.value = !1, t.value = 0;
20
- }, u = (p) => {
21
- l.value = !0, a.value = !1, t.value = 0, n.value = p;
22
- }, s = () => {
23
- a.value = !0;
24
- }, v = () => {
25
- a.value = !1;
12
+ return p(() => {
13
+ i();
14
+ }), y(() => {
15
+ r();
16
+ }), { waveSurfer: t };
17
+ }, O = (n) => {
18
+ const e = h(!1), t = h(!1), i = h(0), r = h(0), s = () => {
19
+ e.value = !1, t.value = !1, i.value = 0;
20
+ }, o = (v) => {
21
+ e.value = !0, t.value = !1, i.value = 0, r.value = v;
22
+ }, l = () => {
23
+ t.value = !0;
24
+ }, a = () => {
25
+ t.value = !1;
26
+ }, u = () => {
27
+ n.value && (i.value = n.value.getCurrentTime());
26
28
  }, d = () => {
27
- e.value && (t.value = e.value.getCurrentTime());
28
- }, f = () => {
29
- l.value = !1, a.value = !1;
29
+ e.value = !1, t.value = !1;
30
30
  };
31
- return c(() => {
32
- e.value && (e.value.on("load", o), e.value.on("ready", u), e.value.on("play", s), e.value.on("pause", v), e.value.on("timeupdate", d), e.value.on("destroy", f));
33
- }), i(() => {
34
- e.value && e.value.unAll();
31
+ return p(() => {
32
+ n.value && (n.value.on("load", s), n.value.on("ready", o), n.value.on("play", l), n.value.on("pause", a), n.value.on("timeupdate", u), n.value.on("destroy", d));
33
+ }), y(() => {
34
+ n.value && n.value.unAll();
35
35
  }), {
36
- isReady: l,
37
- isPlaying: a,
38
- currentTime: t,
39
- totalDuration: n
36
+ isReady: e,
37
+ isPlaying: t,
38
+ currentTime: i,
39
+ totalDuration: r
40
40
  };
41
- }, k = ({ containerRef: e, options: l }) => {
42
- const { waveSurfer: a } = g({ containerRef: e, options: l }), { isReady: t, totalDuration: n, isPlaying: o, currentTime: u } = _(a);
41
+ }, k = ({ containerRef: n, options: e }) => {
42
+ const { waveSurfer: t } = W({ containerRef: n, options: e }), { isReady: i, totalDuration: r, isPlaying: s, currentTime: o } = O(t);
43
43
  return {
44
- waveSurfer: a,
45
- isReady: t,
46
- totalDuration: n,
47
- isPlaying: o,
48
- currentTime: u
44
+ waveSurfer: t,
45
+ isReady: i,
46
+ totalDuration: r,
47
+ isPlaying: s,
48
+ currentTime: o
49
49
  };
50
- }, P = ["audioprocess", "click", "dblclick", "decode", "drag", "finish", "init", "interaction", "load", "loading", "pause", "play", "ready", "redraw", "redrawcomplete", "scroll", "seeking", "timeupdate", "zoom"], T = /* @__PURE__ */ m({
50
+ }, E = ["audioprocess", "click", "dblclick", "decode", "drag", "finish", "init", "interaction", "load", "loading", "pause", "play", "ready", "redraw", "redrawcomplete", "scroll", "seeking", "timeupdate", "zoom"], q = /* @__PURE__ */ b({
51
51
  __name: "WaveSurferPlayer",
52
52
  props: {
53
53
  options: {}
54
54
  },
55
- setup(e) {
56
- const l = e, a = r(null), { waveSurfer: t } = k({ containerRef: a, options: l.options }), n = y();
57
- return c(() => {
58
- P.forEach((o) => {
59
- var u;
60
- (u = t.value) == null || u.on(o, (...s) => {
61
- n == null || n.emit(o, ...s);
55
+ setup(n) {
56
+ const e = n, t = h(null), { waveSurfer: i } = k({ containerRef: t, options: e.options }), r = A();
57
+ return p(() => {
58
+ E.forEach((s) => {
59
+ i.value?.on(s, (...o) => {
60
+ r?.emit(s, ...o);
62
61
  });
63
- }), n == null || n.emit("waveSurfer", t.value);
64
- }), (o, u) => (S(), h("div", {
62
+ }), r?.emit("waveSurfer", i.value);
63
+ }), (s, o) => (D(), M("div", {
65
64
  ref_key: "containerRef",
66
- ref: a
65
+ ref: t
67
66
  }, null, 512));
68
67
  }
69
68
  });
69
+ /*! *****************************************************************************
70
+ Copyright (c) Microsoft Corporation.
71
+
72
+ Permission to use, copy, modify, and/or distribute this software for any
73
+ purpose with or without fee is hereby granted.
74
+
75
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
76
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
77
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
78
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
79
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
80
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
81
+ PERFORMANCE OF THIS SOFTWARE.
82
+ ***************************************************************************** */
83
+ function g(n, e, t, i) {
84
+ return new (t || (t = Promise))(function(r, s) {
85
+ function o(u) {
86
+ try {
87
+ a(i.next(u));
88
+ } catch (d) {
89
+ s(d);
90
+ }
91
+ }
92
+ function l(u) {
93
+ try {
94
+ a(i.throw(u));
95
+ } catch (d) {
96
+ s(d);
97
+ }
98
+ }
99
+ function a(u) {
100
+ var d;
101
+ u.done ? r(u.value) : (d = u.value, d instanceof t ? d : new t(function(v) {
102
+ v(d);
103
+ })).then(o, l);
104
+ }
105
+ a((i = i.apply(n, e || [])).next());
106
+ });
107
+ }
108
+ class S {
109
+ constructor() {
110
+ this.listeners = {};
111
+ }
112
+ on(e, t, i) {
113
+ if (this.listeners[e] || (this.listeners[e] = /* @__PURE__ */ new Set()), this.listeners[e].add(t), i?.once) {
114
+ const r = () => {
115
+ this.un(e, r), this.un(e, t);
116
+ };
117
+ return this.on(e, r), r;
118
+ }
119
+ return () => this.un(e, t);
120
+ }
121
+ un(e, t) {
122
+ var i;
123
+ (i = this.listeners[e]) === null || i === void 0 || i.delete(t);
124
+ }
125
+ once(e, t) {
126
+ return this.on(e, t, { once: !0 });
127
+ }
128
+ unAll() {
129
+ this.listeners = {};
130
+ }
131
+ emit(e, ...t) {
132
+ this.listeners[e] && this.listeners[e].forEach((i) => i(...t));
133
+ }
134
+ }
135
+ class I extends S {
136
+ constructor(e) {
137
+ super(), this.subscriptions = [], this.options = e;
138
+ }
139
+ onInit() {
140
+ }
141
+ _init(e) {
142
+ this.wavesurfer = e, this.onInit();
143
+ }
144
+ destroy() {
145
+ this.emit("destroy"), this.subscriptions.forEach((e) => e());
146
+ }
147
+ }
148
+ class x extends S {
149
+ constructor() {
150
+ super(...arguments), this.unsubscribe = () => {
151
+ };
152
+ }
153
+ start() {
154
+ this.unsubscribe = this.on("tick", () => {
155
+ requestAnimationFrame(() => {
156
+ this.emit("tick");
157
+ });
158
+ }), this.emit("tick");
159
+ }
160
+ stop() {
161
+ this.unsubscribe();
162
+ }
163
+ destroy() {
164
+ this.unsubscribe();
165
+ }
166
+ }
167
+ const B = ["audio/webm", "audio/wav", "audio/mpeg", "audio/mp4", "audio/mp3"];
168
+ class R extends I {
169
+ constructor(e) {
170
+ var t, i, r, s;
171
+ super(Object.assign(Object.assign({}, e), { audioBitsPerSecond: (t = e.audioBitsPerSecond) !== null && t !== void 0 ? t : 128e3, scrollingWaveform: (i = e.scrollingWaveform) !== null && i !== void 0 && i, scrollingWaveformWindow: (r = e.scrollingWaveformWindow) !== null && r !== void 0 ? r : 5, renderRecordedAudio: (s = e.renderRecordedAudio) === null || s === void 0 || s })), this.stream = null, this.mediaRecorder = null, this.dataWindow = null, this.isWaveformPaused = !1, this.lastStartTime = 0, this.lastDuration = 0, this.duration = 0, this.timer = new x(), this.subscriptions.push(this.timer.on("tick", () => {
172
+ const o = performance.now() - this.lastStartTime;
173
+ this.duration = this.isPaused() ? this.duration : this.lastDuration + o, this.emit("record-progress", this.duration);
174
+ }));
175
+ }
176
+ static create(e) {
177
+ return new R(e || {});
178
+ }
179
+ renderMicStream(e) {
180
+ const t = new AudioContext(), i = t.createMediaStreamSource(e), r = t.createAnalyser();
181
+ i.connect(r);
182
+ const s = r.frequencyBinCount, o = new Float32Array(s);
183
+ let l;
184
+ const a = Math.floor((this.options.scrollingWaveformWindow || 0) * t.sampleRate), u = () => {
185
+ var d;
186
+ if (this.isWaveformPaused)
187
+ return void (l = requestAnimationFrame(u));
188
+ if (r.getFloatTimeDomainData(o), this.options.scrollingWaveform) {
189
+ const f = Math.min(a, this.dataWindow ? this.dataWindow.length + s : s), c = new Float32Array(a);
190
+ if (this.dataWindow) {
191
+ const m = Math.max(0, a - this.dataWindow.length);
192
+ c.set(this.dataWindow.slice(-f + s), m);
193
+ }
194
+ c.set(o, a - s), this.dataWindow = c;
195
+ } else
196
+ this.dataWindow = o;
197
+ const v = this.options.scrollingWaveformWindow;
198
+ this.wavesurfer && ((d = this.originalOptions) !== null && d !== void 0 || (this.originalOptions = { cursorWidth: this.wavesurfer.options.cursorWidth, interact: this.wavesurfer.options.interact }), this.wavesurfer.options.cursorWidth = 0, this.wavesurfer.options.interact = !1, this.wavesurfer.load("", [this.dataWindow], v)), l = requestAnimationFrame(u);
199
+ };
200
+ return u(), { onDestroy: () => {
201
+ cancelAnimationFrame(l), i?.disconnect(), t?.close();
202
+ }, onEnd: () => {
203
+ this.isWaveformPaused = !0, cancelAnimationFrame(l), this.stopMic();
204
+ } };
205
+ }
206
+ startMic(e) {
207
+ return g(this, void 0, void 0, function* () {
208
+ let t;
209
+ try {
210
+ t = yield navigator.mediaDevices.getUserMedia({ audio: !e?.deviceId || { deviceId: e.deviceId } });
211
+ } catch (s) {
212
+ throw new Error("Error accessing the microphone: " + s.message);
213
+ }
214
+ const { onDestroy: i, onEnd: r } = this.renderMicStream(t);
215
+ return this.subscriptions.push(this.once("destroy", i)), this.subscriptions.push(this.once("record-end", r)), this.stream = t, t;
216
+ });
217
+ }
218
+ stopMic() {
219
+ this.stream && (this.stream.getTracks().forEach((e) => e.stop()), this.stream = null, this.mediaRecorder = null);
220
+ }
221
+ startRecording(e) {
222
+ return g(this, void 0, void 0, function* () {
223
+ const t = this.stream || (yield this.startMic(e));
224
+ this.dataWindow = null;
225
+ const i = this.mediaRecorder || new MediaRecorder(t, { mimeType: this.options.mimeType || B.find((o) => MediaRecorder.isTypeSupported(o)), audioBitsPerSecond: this.options.audioBitsPerSecond });
226
+ this.mediaRecorder = i, this.stopRecording();
227
+ const r = [];
228
+ i.ondataavailable = (o) => {
229
+ o.data.size > 0 && r.push(o.data);
230
+ };
231
+ const s = (o) => {
232
+ var l;
233
+ const a = new Blob(r, { type: i.mimeType });
234
+ this.emit(o, a), this.options.renderRecordedAudio && (this.applyOriginalOptionsIfNeeded(), (l = this.wavesurfer) === null || l === void 0 || l.load(URL.createObjectURL(a)));
235
+ };
236
+ i.onpause = () => s("record-pause"), i.onstop = () => s("record-end"), i.start(), this.lastStartTime = performance.now(), this.lastDuration = 0, this.duration = 0, this.isWaveformPaused = !1, this.timer.start(), this.emit("record-start");
237
+ });
238
+ }
239
+ getDuration() {
240
+ return this.duration;
241
+ }
242
+ isRecording() {
243
+ var e;
244
+ return ((e = this.mediaRecorder) === null || e === void 0 ? void 0 : e.state) === "recording";
245
+ }
246
+ isPaused() {
247
+ var e;
248
+ return ((e = this.mediaRecorder) === null || e === void 0 ? void 0 : e.state) === "paused";
249
+ }
250
+ isActive() {
251
+ var e;
252
+ return ((e = this.mediaRecorder) === null || e === void 0 ? void 0 : e.state) !== "inactive";
253
+ }
254
+ stopRecording() {
255
+ var e;
256
+ this.isActive() && ((e = this.mediaRecorder) === null || e === void 0 || e.stop(), this.timer.stop());
257
+ }
258
+ pauseRecording() {
259
+ var e, t;
260
+ this.isRecording() && (this.isWaveformPaused = !0, (e = this.mediaRecorder) === null || e === void 0 || e.requestData(), (t = this.mediaRecorder) === null || t === void 0 || t.pause(), this.timer.stop(), this.lastDuration = this.duration);
261
+ }
262
+ resumeRecording() {
263
+ var e;
264
+ this.isPaused() && (this.isWaveformPaused = !1, (e = this.mediaRecorder) === null || e === void 0 || e.resume(), this.timer.start(), this.lastStartTime = performance.now(), this.emit("record-resume"));
265
+ }
266
+ static getAvailableAudioDevices() {
267
+ return g(this, void 0, void 0, function* () {
268
+ return navigator.mediaDevices.enumerateDevices().then((e) => e.filter((t) => t.kind === "audioinput"));
269
+ });
270
+ }
271
+ destroy() {
272
+ this.applyOriginalOptionsIfNeeded(), super.destroy(), this.stopRecording(), this.stopMic();
273
+ }
274
+ applyOriginalOptionsIfNeeded() {
275
+ this.wavesurfer && this.originalOptions && (this.wavesurfer.options.cursorWidth = this.originalOptions.cursorWidth, this.wavesurfer.options.interact = this.originalOptions.interact, delete this.originalOptions);
276
+ }
277
+ }
278
+ const C = ({ containerRef: n, options: e }) => {
279
+ const { waveSurfer: t } = W({ containerRef: n, options: e }), i = h(null), r = h(0), s = h(!1), o = h(!1), l = w(() => [
280
+ Math.floor(r.value % 36e5 / 6e4),
281
+ // minutes
282
+ Math.floor(r.value % 6e4 / 1e3)
283
+ // seconds
284
+ ].map((c) => c < 10 ? "0" + c : c).join(":")), a = w(() => s.value || !o.value), u = () => {
285
+ i.value && i.value?.on("record-progress", (c) => {
286
+ r.value = c;
287
+ });
288
+ }, d = () => {
289
+ if (i.value?.isRecording() || i.value?.isPaused()) {
290
+ i.value?.stopRecording(), s.value = !1, o.value = !0;
291
+ return;
292
+ }
293
+ i.value?.startRecording(), s.value = !0, o.value = !1, u();
294
+ }, v = () => new Promise((c) => {
295
+ let m;
296
+ (i.value?.isRecording() || i.value?.isPaused()) && (i.value?.stopRecording(), s.value = !1, o.value = !1), i.value?.on("record-end", (P) => {
297
+ m = P, c(m);
298
+ });
299
+ }), f = () => {
300
+ if (i.value?.isPaused()) {
301
+ i.value?.resumeRecording(), s.value = !0, o.value = !1;
302
+ return;
303
+ }
304
+ s.value = !1, o.value = !0, i.value?.pauseRecording();
305
+ };
306
+ return p(() => {
307
+ const c = t.value?.registerPlugin(R.create({ renderRecordedAudio: !1 }));
308
+ c && (i.value = c);
309
+ }), {
310
+ waveSurfer: t,
311
+ waveSurferRecorder: i,
312
+ currentTime: l,
313
+ startRecording: d,
314
+ stopRecording: v,
315
+ pauseRecording: f,
316
+ isRecording: s,
317
+ isPaused: o,
318
+ isPauseResume: a
319
+ };
320
+ };
70
321
  export {
71
- T as WaveSurferPlayer,
72
- k as useWaveSurfer
322
+ q as WaveSurferPlayer,
323
+ k as useWaveSurfer,
324
+ C as useWaveSurferRecorder
73
325
  };
@@ -1 +1,14 @@
1
- (function(l,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("wavesurfer.js")):typeof define=="function"&&define.amd?define(["exports","vue","wavesurfer.js"],e):(l=typeof globalThis<"u"?globalThis:l||self,e(l["@meersagor/wavesurfer-vue"]={},l.Vue,l.WaveSurfer))})(this,function(l,e,d){"use strict";const f=({containerRef:n,options:r})=>{const t=e.ref(null),o=()=>{n.value&&(t.value=d.create({container:n.value,...r}))},a=()=>{t.value&&(t.value.destroy(),t.value=null)};return e.onMounted(()=>{o()}),e.onUnmounted(()=>{a()}),{waveSurfer:t}},v=n=>{const r=e.ref(!1),t=e.ref(!1),o=e.ref(0),a=e.ref(0),u=()=>{r.value=!1,t.value=!1,o.value=0},s=W=>{r.value=!0,t.value=!1,o.value=0,a.value=W},i=()=>{t.value=!0},m=()=>{t.value=!1},S=()=>{n.value&&(o.value=n.value.getCurrentTime())},h=()=>{r.value=!1,t.value=!1};return e.onMounted(()=>{n.value&&(n.value.on("load",u),n.value.on("ready",s),n.value.on("play",i),n.value.on("pause",m),n.value.on("timeupdate",S),n.value.on("destroy",h))}),e.onUnmounted(()=>{n.value&&n.value.unAll()}),{isReady:r,isPlaying:t,currentTime:o,totalDuration:a}},c=({containerRef:n,options:r})=>{const{waveSurfer:t}=f({containerRef:n,options:r}),{isReady:o,totalDuration:a,isPlaying:u,currentTime:s}=v(t);return{waveSurfer:t,isReady:o,totalDuration:a,isPlaying:u,currentTime:s}},p=["audioprocess","click","dblclick","decode","drag","finish","init","interaction","load","loading","pause","play","ready","redraw","redrawcomplete","scroll","seeking","timeupdate","zoom"],y=e.defineComponent({__name:"WaveSurferPlayer",props:{options:{}},setup(n){const r=n,t=e.ref(null),{waveSurfer:o}=c({containerRef:t,options:r.options}),a=e.getCurrentInstance();return e.onMounted(()=>{p.forEach(u=>{var s;(s=o.value)==null||s.on(u,(...i)=>{a==null||a.emit(u,...i)})}),a==null||a.emit("waveSurfer",o.value)}),(u,s)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"containerRef",ref:t},null,512))}});l.WaveSurferPlayer=y,l.useWaveSurfer=c,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
1
+ (function(v,o){typeof exports=="object"&&typeof module<"u"?o(exports,require("vue"),require("wavesurfer.js")):typeof define=="function"&&define.amd?define(["exports","vue","wavesurfer.js"],o):(v=typeof globalThis<"u"?globalThis:v||self,o(v["@meersagor/wavesurfer-vue"]={},v.Vue,v.WaveSurfer))})(this,function(v,o,S){"use strict";const R=({containerRef:a,options:e})=>{const t=o.ref(null),i=()=>{a.value&&(t.value=S.create({container:a.value,...e}))},r=()=>{t.value&&(t.value.destroy(),t.value=null)};return o.onMounted(()=>{i()}),o.onUnmounted(()=>{r()}),{waveSurfer:t}},P=a=>{const e=o.ref(!1),t=o.ref(!1),i=o.ref(0),r=o.ref(0),s=()=>{e.value=!1,t.value=!1,i.value=0},n=f=>{e.value=!0,t.value=!1,i.value=0,r.value=f},l=()=>{t.value=!0},u=()=>{t.value=!1},d=()=>{a.value&&(i.value=a.value.getCurrentTime())},c=()=>{e.value=!1,t.value=!1};return o.onMounted(()=>{a.value&&(a.value.on("load",s),a.value.on("ready",n),a.value.on("play",l),a.value.on("pause",u),a.value.on("timeupdate",d),a.value.on("destroy",c))}),o.onUnmounted(()=>{a.value&&a.value.unAll()}),{isReady:e,isPlaying:t,currentTime:i,totalDuration:r}},w=({containerRef:a,options:e})=>{const{waveSurfer:t}=R({containerRef:a,options:e}),{isReady:i,totalDuration:r,isPlaying:s,currentTime:n}=P(t);return{waveSurfer:t,isReady:i,totalDuration:r,isPlaying:s,currentTime:n}},b=["audioprocess","click","dblclick","decode","drag","finish","init","interaction","load","loading","pause","play","ready","redraw","redrawcomplete","scroll","seeking","timeupdate","zoom"],M=o.defineComponent({__name:"WaveSurferPlayer",props:{options:{}},setup(a){const e=a,t=o.ref(null),{waveSurfer:i}=w({containerRef:t,options:e.options}),r=o.getCurrentInstance();return o.onMounted(()=>{b.forEach(s=>{i.value?.on(s,(...n)=>{r?.emit(s,...n)})}),r?.emit("waveSurfer",i.value)}),(s,n)=>(o.openBlock(),o.createElementBlock("div",{ref_key:"containerRef",ref:t},null,512))}});/*! *****************************************************************************
2
+ Copyright (c) Microsoft Corporation.
3
+
4
+ Permission to use, copy, modify, and/or distribute this software for any
5
+ purpose with or without fee is hereby granted.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13
+ PERFORMANCE OF THIS SOFTWARE.
14
+ ***************************************************************************** */function p(a,e,t,i){return new(t||(t=Promise))(function(r,s){function n(d){try{u(i.next(d))}catch(c){s(c)}}function l(d){try{u(i.throw(d))}catch(c){s(c)}}function u(d){var c;d.done?r(d.value):(c=d.value,c instanceof t?c:new t(function(f){f(c)})).then(n,l)}u((i=i.apply(a,e||[])).next())})}class W{constructor(){this.listeners={}}on(e,t,i){if(this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),i?.once){const r=()=>{this.un(e,r),this.un(e,t)};return this.on(e,r),r}return()=>this.un(e,t)}un(e,t){var i;(i=this.listeners[e])===null||i===void 0||i.delete(t)}once(e,t){return this.on(e,t,{once:!0})}unAll(){this.listeners={}}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach(i=>i(...t))}}class A extends W{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())}}class T extends W{constructor(){super(...arguments),this.unsubscribe=()=>{}}start(){this.unsubscribe=this.on("tick",()=>{requestAnimationFrame(()=>{this.emit("tick")})}),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}}const D=["audio/webm","audio/wav","audio/mpeg","audio/mp4","audio/mp3"];class g extends A{constructor(e){var t,i,r,s;super(Object.assign(Object.assign({},e),{audioBitsPerSecond:(t=e.audioBitsPerSecond)!==null&&t!==void 0?t:128e3,scrollingWaveform:(i=e.scrollingWaveform)!==null&&i!==void 0&&i,scrollingWaveformWindow:(r=e.scrollingWaveformWindow)!==null&&r!==void 0?r:5,renderRecordedAudio:(s=e.renderRecordedAudio)===null||s===void 0||s})),this.stream=null,this.mediaRecorder=null,this.dataWindow=null,this.isWaveformPaused=!1,this.lastStartTime=0,this.lastDuration=0,this.duration=0,this.timer=new T,this.subscriptions.push(this.timer.on("tick",()=>{const n=performance.now()-this.lastStartTime;this.duration=this.isPaused()?this.duration:this.lastDuration+n,this.emit("record-progress",this.duration)}))}static create(e){return new g(e||{})}renderMicStream(e){const t=new AudioContext,i=t.createMediaStreamSource(e),r=t.createAnalyser();i.connect(r);const s=r.frequencyBinCount,n=new Float32Array(s);let l;const u=Math.floor((this.options.scrollingWaveformWindow||0)*t.sampleRate),d=()=>{var c;if(this.isWaveformPaused)return void(l=requestAnimationFrame(d));if(r.getFloatTimeDomainData(n),this.options.scrollingWaveform){const y=Math.min(u,this.dataWindow?this.dataWindow.length+s:s),h=new Float32Array(u);if(this.dataWindow){const m=Math.max(0,u-this.dataWindow.length);h.set(this.dataWindow.slice(-y+s),m)}h.set(n,u-s),this.dataWindow=h}else this.dataWindow=n;const f=this.options.scrollingWaveformWindow;this.wavesurfer&&((c=this.originalOptions)!==null&&c!==void 0||(this.originalOptions={cursorWidth:this.wavesurfer.options.cursorWidth,interact:this.wavesurfer.options.interact}),this.wavesurfer.options.cursorWidth=0,this.wavesurfer.options.interact=!1,this.wavesurfer.load("",[this.dataWindow],f)),l=requestAnimationFrame(d)};return d(),{onDestroy:()=>{cancelAnimationFrame(l),i?.disconnect(),t?.close()},onEnd:()=>{this.isWaveformPaused=!0,cancelAnimationFrame(l),this.stopMic()}}}startMic(e){return p(this,void 0,void 0,function*(){let t;try{t=yield navigator.mediaDevices.getUserMedia({audio:!e?.deviceId||{deviceId:e.deviceId}})}catch(s){throw new Error("Error accessing the microphone: "+s.message)}const{onDestroy:i,onEnd:r}=this.renderMicStream(t);return this.subscriptions.push(this.once("destroy",i)),this.subscriptions.push(this.once("record-end",r)),this.stream=t,t})}stopMic(){this.stream&&(this.stream.getTracks().forEach(e=>e.stop()),this.stream=null,this.mediaRecorder=null)}startRecording(e){return p(this,void 0,void 0,function*(){const t=this.stream||(yield this.startMic(e));this.dataWindow=null;const i=this.mediaRecorder||new MediaRecorder(t,{mimeType:this.options.mimeType||D.find(n=>MediaRecorder.isTypeSupported(n)),audioBitsPerSecond:this.options.audioBitsPerSecond});this.mediaRecorder=i,this.stopRecording();const r=[];i.ondataavailable=n=>{n.data.size>0&&r.push(n.data)};const s=n=>{var l;const u=new Blob(r,{type:i.mimeType});this.emit(n,u),this.options.renderRecordedAudio&&(this.applyOriginalOptionsIfNeeded(),(l=this.wavesurfer)===null||l===void 0||l.load(URL.createObjectURL(u)))};i.onpause=()=>s("record-pause"),i.onstop=()=>s("record-end"),i.start(),this.lastStartTime=performance.now(),this.lastDuration=0,this.duration=0,this.isWaveformPaused=!1,this.timer.start(),this.emit("record-start")})}getDuration(){return this.duration}isRecording(){var e;return((e=this.mediaRecorder)===null||e===void 0?void 0:e.state)==="recording"}isPaused(){var e;return((e=this.mediaRecorder)===null||e===void 0?void 0:e.state)==="paused"}isActive(){var e;return((e=this.mediaRecorder)===null||e===void 0?void 0:e.state)!=="inactive"}stopRecording(){var e;this.isActive()&&((e=this.mediaRecorder)===null||e===void 0||e.stop(),this.timer.stop())}pauseRecording(){var e,t;this.isRecording()&&(this.isWaveformPaused=!0,(e=this.mediaRecorder)===null||e===void 0||e.requestData(),(t=this.mediaRecorder)===null||t===void 0||t.pause(),this.timer.stop(),this.lastDuration=this.duration)}resumeRecording(){var e;this.isPaused()&&(this.isWaveformPaused=!1,(e=this.mediaRecorder)===null||e===void 0||e.resume(),this.timer.start(),this.lastStartTime=performance.now(),this.emit("record-resume"))}static getAvailableAudioDevices(){return p(this,void 0,void 0,function*(){return navigator.mediaDevices.enumerateDevices().then(e=>e.filter(t=>t.kind==="audioinput"))})}destroy(){this.applyOriginalOptionsIfNeeded(),super.destroy(),this.stopRecording(),this.stopMic()}applyOriginalOptionsIfNeeded(){this.wavesurfer&&this.originalOptions&&(this.wavesurfer.options.cursorWidth=this.originalOptions.cursorWidth,this.wavesurfer.options.interact=this.originalOptions.interact,delete this.originalOptions)}}const O=({containerRef:a,options:e})=>{const{waveSurfer:t}=R({containerRef:a,options:e}),i=o.ref(null),r=o.ref(0),s=o.ref(!1),n=o.ref(!1),l=o.computed(()=>[Math.floor(r.value%36e5/6e4),Math.floor(r.value%6e4/1e3)].map(h=>h<10?"0"+h:h).join(":")),u=o.computed(()=>s.value||!n.value),d=()=>{i.value&&i.value?.on("record-progress",h=>{r.value=h})},c=()=>{if(i.value?.isRecording()||i.value?.isPaused()){i.value?.stopRecording(),s.value=!1,n.value=!0;return}i.value?.startRecording(),s.value=!0,n.value=!1,d()},f=()=>new Promise(h=>{let m;(i.value?.isRecording()||i.value?.isPaused())&&(i.value?.stopRecording(),s.value=!1,n.value=!1),i.value?.on("record-end",k=>{m=k,h(m)})}),y=()=>{if(i.value?.isPaused()){i.value?.resumeRecording(),s.value=!0,n.value=!1;return}s.value=!1,n.value=!0,i.value?.pauseRecording()};return o.onMounted(()=>{const h=t.value?.registerPlugin(g.create({renderRecordedAudio:!1}));h&&(i.value=h)}),{waveSurfer:t,waveSurferRecorder:i,currentTime:l,startRecording:c,stopRecording:f,pauseRecording:y,isRecording:s,isPaused:n,isPauseResume:u}};v.WaveSurferPlayer=M,v.useWaveSurfer=w,v.useWaveSurferRecorder=O,Object.defineProperty(v,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,16 @@
1
+ import type { PartialWaveSurferOptions } from '../types';
2
+ declare const _default: import("vue").DefineComponent<__VLS_TypePropsToRuntimeProps<{
3
+ options: PartialWaveSurferOptions;
4
+ }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
5
+ options: PartialWaveSurferOptions;
6
+ }>>>, {}, {}>;
7
+ export default _default;
8
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
9
+ type __VLS_TypePropsToRuntimeProps<T> = {
10
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
11
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
12
+ } : {
13
+ type: import('vue').PropType<T[K]>;
14
+ required: true;
15
+ };
16
+ };
@@ -0,0 +1,2 @@
1
+ import type { UseWaveSurfer, WaveSurferIns } from '../types';
2
+ export declare const useWaveSurfer: ({ containerRef, options }: WaveSurferIns) => UseWaveSurfer;