@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 +51 -2
- package/dist/@meersagor-wavesurfer-vue.js +306 -54
- package/dist/@meersagor-wavesurfer-vue.umd.cjs +14 -1
- package/dist/types/components/WaveSurferPlayer.vue.d.ts +16 -0
- package/dist/types/composables/useWaveSurfer.d.ts +2 -0
- package/dist/types/composables/useWaveSurferInstance.d.ts +495 -0
- package/dist/types/composables/useWaveSurferRecorder.d.ts +525 -0
- package/dist/types/composables/useWaveSurferState.d.ts +8 -0
- package/dist/types/eventsEmitter/index.d.ts +2 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/types/index.d.ts +10 -0
- package/dist/vite.config.d.ts +2 -0
- package/package.json +4 -8
- package/dist/index.d.ts +0 -3
- package/dist/tsconfig.app.tsbuildinfo +0 -1
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
|
-
##
|
|
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
|
|
2
|
-
import
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
container:
|
|
7
|
-
...
|
|
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
|
-
},
|
|
10
|
-
|
|
9
|
+
}, r = () => {
|
|
10
|
+
t.value && (t.value.destroy(), t.value = null);
|
|
11
11
|
};
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
}),
|
|
15
|
-
|
|
16
|
-
}), { waveSurfer:
|
|
17
|
-
},
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
},
|
|
25
|
-
|
|
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
|
|
28
|
-
}, f = () => {
|
|
29
|
-
l.value = !1, a.value = !1;
|
|
29
|
+
e.value = !1, t.value = !1;
|
|
30
30
|
};
|
|
31
|
-
return
|
|
32
|
-
|
|
33
|
-
}),
|
|
34
|
-
|
|
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:
|
|
37
|
-
isPlaying:
|
|
38
|
-
currentTime:
|
|
39
|
-
totalDuration:
|
|
36
|
+
isReady: e,
|
|
37
|
+
isPlaying: t,
|
|
38
|
+
currentTime: i,
|
|
39
|
+
totalDuration: r
|
|
40
40
|
};
|
|
41
|
-
}, k = ({ containerRef:
|
|
42
|
-
const { waveSurfer:
|
|
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:
|
|
45
|
-
isReady:
|
|
46
|
-
totalDuration:
|
|
47
|
-
isPlaying:
|
|
48
|
-
currentTime:
|
|
44
|
+
waveSurfer: t,
|
|
45
|
+
isReady: i,
|
|
46
|
+
totalDuration: r,
|
|
47
|
+
isPlaying: s,
|
|
48
|
+
currentTime: o
|
|
49
49
|
};
|
|
50
|
-
},
|
|
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(
|
|
56
|
-
const
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
}),
|
|
64
|
-
}), (
|
|
62
|
+
}), r?.emit("waveSurfer", i.value);
|
|
63
|
+
}), (s, o) => (D(), M("div", {
|
|
65
64
|
ref_key: "containerRef",
|
|
66
|
-
ref:
|
|
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
|
-
|
|
72
|
-
k as useWaveSurfer
|
|
322
|
+
q as WaveSurferPlayer,
|
|
323
|
+
k as useWaveSurfer,
|
|
324
|
+
C as useWaveSurferRecorder
|
|
73
325
|
};
|
|
@@ -1 +1,14 @@
|
|
|
1
|
-
(function(
|
|
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
|
+
};
|