@meersagor/wavesurfer-vue 0.1.1 → 0.1.2
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
|
@@ -122,7 +122,7 @@ const formatTime = (seconds: number):string => [seconds / 60, seconds % 60].map(
|
|
|
122
122
|
|
|
123
123
|
|
|
124
124
|
|
|
125
|
-
## useWaveSurferRecorder
|
|
125
|
+
## use useWaveSurferRecorder composable method
|
|
126
126
|
|
|
127
127
|
```vue
|
|
128
128
|
<script lang="ts" setup>
|
|
@@ -145,6 +145,9 @@ const options = computed(() => ({
|
|
|
145
145
|
const { pauseRecording, startRecording, stopRecording, currentTime, isPauseResume } = useWaveSurferRecorder({
|
|
146
146
|
containerRef,
|
|
147
147
|
options: options.value,
|
|
148
|
+
recordPluginOptions:{
|
|
149
|
+
continuousWaveform: true
|
|
150
|
+
}
|
|
148
151
|
})
|
|
149
152
|
|
|
150
153
|
const startAudioRecordHandler = () => {
|
|
@@ -173,7 +176,7 @@ const stopHandler = async () => {
|
|
|
173
176
|
</div>
|
|
174
177
|
</template>
|
|
175
178
|
```
|
|
176
|
-
|
|
179
|
+
## useWaveSurferRecorder: method Return Types
|
|
177
180
|
### `waveSurfer`
|
|
178
181
|
|
|
179
182
|
- Type: `Ref<WaveSurfer | null>`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("vue"),b=require("wavesurfer.js"),R=({containerRef:n,options:e})=>{const t=u.ref(null),i=()=>{n.value&&(t.value=b.create({container:n.value,...e}))},s=()=>{t.value&&(t.value.destroy(),t.value=null)};return u.onMounted(()=>{i()}),u.onUnmounted(()=>{s()}),{waveSurfer:t}},M=n=>{const e=u.ref(!1),t=u.ref(!1),i=u.ref(0),s=u.ref(0),o=()=>{e.value=!1,t.value=!1,i.value=0},r=f=>{e.value=!0,t.value=!1,i.value=0,s.value=f},a=()=>{t.value=!0},l=()=>{t.value=!1},v=()=>{n.value&&(i.value=n.value.getCurrentTime())},c=()=>{e.value=!1,t.value=!1};return u.onMounted(()=>{n.value&&(n.value.on("load",o),n.value.on("ready",r),n.value.on("play",a),n.value.on("pause",l),n.value.on("timeupdate",v),n.value.on("destroy",c))}),u.onUnmounted(()=>{n.value&&n.value.unAll()}),{isReady:e,isPlaying:t,currentTime:i,totalDuration:s}},y=({containerRef:n,options:e})=>{const{waveSurfer:t}=R({containerRef:n,options:e}),{isReady:i,totalDuration:s,isPlaying:o,currentTime:r}=M(t);return{waveSurfer:t,isReady:i,totalDuration:s,isPlaying:o,currentTime:r}},D=["audioprocess","click","dblclick","decode","drag","finish","init","interaction","load","loading","pause","play","ready","redraw","redrawcomplete","scroll","seeking","timeupdate","zoom"],T=u.defineComponent({__name:"WaveSurferPlayer",props:{options:{}},setup(n){const e=n,t=u.ref(null),{waveSurfer:i}=y({containerRef:t,options:e.options}),s=u.getCurrentInstance();return u.onMounted(()=>{D.forEach(o=>{i.value?.on(o,(...r)=>{s?.emit(o,...r)})}),s?.emit("waveSurfer",i.value)}),(o,r)=>(u.openBlock(),u.createElementBlock("div",{ref_key:"containerRef",ref:t},null,512))}});function w(n,e,t,i){return new(t||(t=Promise))(function(s,o){function r(v){try{l(i.next(v))}catch(c){o(c)}}function a(v){try{l(i.throw(v))}catch(c){o(c)}}function l(v){var c;v.done?s(v.value):(c=v.value,c instanceof t?c:new t(function(f){f(c)})).then(r,a)}l((i=i.apply(n,[])).next())})}class S{constructor(){this.listeners={}}on(e,t,i){if(this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),i?.once){const s=()=>{this.un(e,s),this.un(e,t)};return this.on(e,s),s}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 O extends S{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 A extends S{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 E=["audio/webm","audio/wav","audio/mpeg","audio/mp4","audio/mp3"];class W extends O{constructor(e){var t,i,s,o,r,a;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:(s=e.scrollingWaveformWindow)!==null&&s!==void 0?s:5,continuousWaveform:(o=e.continuousWaveform)!==null&&o!==void 0&&o,renderRecordedAudio:(r=e.renderRecordedAudio)===null||r===void 0||r,mediaRecorderTimeslice:(a=e.mediaRecorderTimeslice)!==null&&a!==void 0?a:void 0})),this.stream=null,this.mediaRecorder=null,this.dataWindow=null,this.isWaveformPaused=!1,this.lastStartTime=0,this.lastDuration=0,this.duration=0,this.timer=new A,this.subscriptions.push(this.timer.on("tick",()=>{const l=performance.now()-this.lastStartTime;this.duration=this.isPaused()?this.duration:this.lastDuration+l,this.emit("record-progress",this.duration)}))}static create(e){return new W(e||{})}renderMicStream(e){var t;const i=new AudioContext,s=i.createMediaStreamSource(e),o=i.createAnalyser();s.connect(o),this.options.continuousWaveform&&(o.fftSize=32);const r=o.frequencyBinCount,a=new Float32Array(r);let l=0;this.wavesurfer&&((t=this.originalOptions)!==null&&t!==void 0||(this.originalOptions=Object.assign({},this.wavesurfer.options)),this.wavesurfer.options.interact=!1,this.options.scrollingWaveform&&(this.wavesurfer.options.cursorWidth=0));const v=setInterval(()=>{var c,f,p,g;if(!this.isWaveformPaused){if(o.getFloatTimeDomainData(a),this.options.scrollingWaveform){const d=Math.floor((this.options.scrollingWaveformWindow||0)*i.sampleRate),h=Math.min(d,this.dataWindow?this.dataWindow.length+r:r),m=new Float32Array(d);if(this.dataWindow){const P=Math.max(0,d-this.dataWindow.length);m.set(this.dataWindow.slice(-h+r),P)}m.set(a,d-r),this.dataWindow=m}else if(this.options.continuousWaveform){if(!this.dataWindow){const h=this.options.continuousWaveformDuration?Math.round(100*this.options.continuousWaveformDuration):((f=(c=this.wavesurfer)===null||c===void 0?void 0:c.getWidth())!==null&&f!==void 0?f:0)*window.devicePixelRatio;this.dataWindow=new Float32Array(h)}let d=0;for(let h=0;h<r;h++){const m=Math.abs(a[h]);m>d&&(d=m)}if(l+1>this.dataWindow.length){const h=new Float32Array(2*this.dataWindow.length);h.set(this.dataWindow,0),this.dataWindow=h}this.dataWindow[l]=d,l++}else this.dataWindow=a;if(this.wavesurfer){const d=((g=(p=this.dataWindow)===null||p===void 0?void 0:p.length)!==null&&g!==void 0?g:0)/100;this.wavesurfer.load("",[this.dataWindow],this.options.scrollingWaveform?this.options.scrollingWaveformWindow:d).then(()=>{this.wavesurfer&&this.options.continuousWaveform&&(this.wavesurfer.setTime(this.getDuration()/1e3),this.wavesurfer.options.minPxPerSec||this.wavesurfer.setOptions({minPxPerSec:this.wavesurfer.getWidth()/this.wavesurfer.getDuration()}))}).catch(h=>{console.error("Error rendering real-time recording data:",h)})}}},10);return{onDestroy:()=>{clearInterval(v),s?.disconnect(),i?.close()},onEnd:()=>{this.isWaveformPaused=!0,clearInterval(v),this.stopMic()}}}startMic(e){return w(this,void 0,void 0,function*(){let t;try{t=yield navigator.mediaDevices.getUserMedia({audio:!e?.deviceId||{deviceId:e.deviceId}})}catch(o){throw new Error("Error accessing the microphone: "+o.message)}const{onDestroy:i,onEnd:s}=this.renderMicStream(t);return this.subscriptions.push(this.once("destroy",i)),this.subscriptions.push(this.once("record-end",s)),this.stream=t,t})}stopMic(){this.stream&&(this.stream.getTracks().forEach(e=>e.stop()),this.stream=null,this.mediaRecorder=null)}startRecording(e){return w(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||E.find(r=>MediaRecorder.isTypeSupported(r)),audioBitsPerSecond:this.options.audioBitsPerSecond});this.mediaRecorder=i,this.stopRecording();const s=[];i.ondataavailable=r=>{r.data.size>0&&s.push(r.data),this.emit("record-data-available",r.data)};const o=r=>{var a;const l=new Blob(s,{type:i.mimeType});this.emit(r,l),this.options.renderRecordedAudio&&(this.applyOriginalOptionsIfNeeded(),(a=this.wavesurfer)===null||a===void 0||a.load(URL.createObjectURL(l)))};i.onpause=()=>o("record-pause"),i.onstop=()=>o("record-end"),i.start(this.options.mediaRecorderTimeslice),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 w(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.setOptions(this.originalOptions),delete this.originalOptions)}}const I=({containerRef:n,options:e,recordPluginOptions:t})=>{const{waveSurfer:i}=R({containerRef:n,options:e}),s=u.ref(null),o=u.ref(0),r=u.ref(!1),a=u.ref(!1),l=u.computed(()=>[Math.floor(o.value%36e5/6e4),Math.floor(o.value%6e4/1e3)].map(d=>d<10?"0"+d:d).join(":")),v=u.computed(()=>r.value||!a.value),c=()=>{s.value&&s.value?.on("record-progress",d=>{o.value=d})},f=()=>{if(s.value?.isRecording()||s.value?.isPaused()){s.value?.stopRecording(),r.value=!1,a.value=!0;return}s.value?.startRecording(),r.value=!0,a.value=!1,c()},p=()=>new Promise(d=>{let h;(s.value?.isRecording()||s.value?.isPaused())&&(s.value?.stopRecording(),r.value=!1,a.value=!1),s.value?.on("record-end",m=>{h=m,d(h)})}),g=()=>{if(s.value?.isPaused()){s.value?.resumeRecording(),r.value=!0,a.value=!1;return}r.value=!1,a.value=!0,s.value?.pauseRecording()};return u.onMounted(()=>{const d=i.value?.registerPlugin(W.create({renderRecordedAudio:!1,...t}));d&&(s.value=d)}),{waveSurfer:i,waveSurferRecorder:s,currentTime:l,startRecording:f,stopRecording:p,pauseRecording:g,isRecording:r,isPaused:a,isPauseResume:v}};exports.WaveSurferPlayer=T;exports.useWaveSurfer=y;exports.useWaveSurferRecorder=I;
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
import { ref as
|
|
1
|
+
import { ref as v, onMounted as w, onUnmounted as S, defineComponent as T, getCurrentInstance as M, openBlock as A, createElementBlock as O, computed as y } from "vue";
|
|
2
2
|
import E from "wavesurfer.js";
|
|
3
3
|
const P = ({ containerRef: n, options: e }) => {
|
|
4
|
-
const
|
|
5
|
-
n.value && (
|
|
4
|
+
const t = v(null), i = () => {
|
|
5
|
+
n.value && (t.value = E.create({
|
|
6
6
|
container: n.value,
|
|
7
7
|
...e
|
|
8
8
|
}));
|
|
9
|
-
},
|
|
10
|
-
|
|
9
|
+
}, s = () => {
|
|
10
|
+
t.value && (t.value.destroy(), t.value = null);
|
|
11
11
|
};
|
|
12
12
|
return w(() => {
|
|
13
|
-
|
|
13
|
+
i();
|
|
14
14
|
}), S(() => {
|
|
15
|
-
|
|
16
|
-
}), { waveSurfer:
|
|
15
|
+
s();
|
|
16
|
+
}), { waveSurfer: t };
|
|
17
17
|
}, I = (n) => {
|
|
18
|
-
const e =
|
|
19
|
-
e.value = !1,
|
|
20
|
-
},
|
|
21
|
-
e.value = !0,
|
|
18
|
+
const e = v(!1), t = v(!1), i = v(0), s = v(0), r = () => {
|
|
19
|
+
e.value = !1, t.value = !1, i.value = 0;
|
|
20
|
+
}, o = (m) => {
|
|
21
|
+
e.value = !0, t.value = !1, i.value = 0, s.value = m;
|
|
22
22
|
}, a = () => {
|
|
23
|
-
|
|
24
|
-
}, u = () => {
|
|
25
|
-
i.value = !1;
|
|
26
|
-
}, l = () => {
|
|
27
|
-
n.value && (t.value = n.value.getCurrentTime());
|
|
23
|
+
t.value = !0;
|
|
28
24
|
}, d = () => {
|
|
29
|
-
|
|
25
|
+
t.value = !1;
|
|
26
|
+
}, h = () => {
|
|
27
|
+
n.value && (i.value = n.value.getCurrentTime());
|
|
28
|
+
}, l = () => {
|
|
29
|
+
e.value = !1, t.value = !1;
|
|
30
30
|
};
|
|
31
31
|
return w(() => {
|
|
32
|
-
n.value && (n.value.on("load", r), n.value.on("ready",
|
|
32
|
+
n.value && (n.value.on("load", r), n.value.on("ready", o), n.value.on("play", a), n.value.on("pause", d), n.value.on("timeupdate", h), n.value.on("destroy", l));
|
|
33
33
|
}), S(() => {
|
|
34
34
|
n.value && n.value.unAll();
|
|
35
35
|
}), {
|
|
36
36
|
isReady: e,
|
|
37
|
-
isPlaying:
|
|
38
|
-
currentTime:
|
|
39
|
-
totalDuration:
|
|
37
|
+
isPlaying: t,
|
|
38
|
+
currentTime: i,
|
|
39
|
+
totalDuration: s
|
|
40
40
|
};
|
|
41
41
|
}, k = ({ containerRef: n, options: e }) => {
|
|
42
|
-
const { waveSurfer:
|
|
42
|
+
const { waveSurfer: t } = P({ containerRef: n, options: e }), { isReady: i, totalDuration: s, isPlaying: r, currentTime: o } = I(t);
|
|
43
43
|
return {
|
|
44
|
-
waveSurfer:
|
|
45
|
-
isReady:
|
|
46
|
-
totalDuration:
|
|
44
|
+
waveSurfer: t,
|
|
45
|
+
isReady: i,
|
|
46
|
+
totalDuration: s,
|
|
47
47
|
isPlaying: r,
|
|
48
|
-
currentTime:
|
|
48
|
+
currentTime: o
|
|
49
49
|
};
|
|
50
50
|
}, x = ["audioprocess", "click", "dblclick", "decode", "drag", "finish", "init", "interaction", "load", "loading", "pause", "play", "ready", "redraw", "redrawcomplete", "scroll", "seeking", "timeupdate", "zoom"], U = /* @__PURE__ */ T({
|
|
51
51
|
__name: "WaveSurferPlayer",
|
|
@@ -53,69 +53,69 @@ const P = ({ containerRef: n, options: e }) => {
|
|
|
53
53
|
options: {}
|
|
54
54
|
},
|
|
55
55
|
setup(n) {
|
|
56
|
-
const e = n,
|
|
56
|
+
const e = n, t = v(null), { waveSurfer: i } = k({ containerRef: t, options: e.options }), s = M();
|
|
57
57
|
return w(() => {
|
|
58
58
|
x.forEach((r) => {
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
i.value?.on(r, (...o) => {
|
|
60
|
+
s?.emit(r, ...o);
|
|
61
61
|
});
|
|
62
|
-
}),
|
|
63
|
-
}), (r,
|
|
62
|
+
}), s?.emit("waveSurfer", i.value);
|
|
63
|
+
}), (r, o) => (A(), O("div", {
|
|
64
64
|
ref_key: "containerRef",
|
|
65
|
-
ref:
|
|
65
|
+
ref: t
|
|
66
66
|
}, null, 512));
|
|
67
67
|
}
|
|
68
68
|
});
|
|
69
|
-
function W(n, e,
|
|
70
|
-
return new (
|
|
71
|
-
function
|
|
69
|
+
function W(n, e, t, i) {
|
|
70
|
+
return new (t || (t = Promise))(function(s, r) {
|
|
71
|
+
function o(h) {
|
|
72
72
|
try {
|
|
73
|
-
|
|
74
|
-
} catch (
|
|
75
|
-
r(
|
|
73
|
+
d(i.next(h));
|
|
74
|
+
} catch (l) {
|
|
75
|
+
r(l);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
function a(
|
|
78
|
+
function a(h) {
|
|
79
79
|
try {
|
|
80
|
-
|
|
81
|
-
} catch (
|
|
82
|
-
r(
|
|
80
|
+
d(i.throw(h));
|
|
81
|
+
} catch (l) {
|
|
82
|
+
r(l);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
-
function
|
|
86
|
-
var
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
})).then(
|
|
85
|
+
function d(h) {
|
|
86
|
+
var l;
|
|
87
|
+
h.done ? s(h.value) : (l = h.value, l instanceof t ? l : new t(function(m) {
|
|
88
|
+
m(l);
|
|
89
|
+
})).then(o, a);
|
|
90
90
|
}
|
|
91
|
-
|
|
91
|
+
d((i = i.apply(n, [])).next());
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
94
|
class b {
|
|
95
95
|
constructor() {
|
|
96
96
|
this.listeners = {};
|
|
97
97
|
}
|
|
98
|
-
on(e,
|
|
99
|
-
if (this.listeners[e] || (this.listeners[e] = /* @__PURE__ */ new Set()), this.listeners[e].add(
|
|
100
|
-
const
|
|
101
|
-
this.un(e,
|
|
98
|
+
on(e, t, i) {
|
|
99
|
+
if (this.listeners[e] || (this.listeners[e] = /* @__PURE__ */ new Set()), this.listeners[e].add(t), i?.once) {
|
|
100
|
+
const s = () => {
|
|
101
|
+
this.un(e, s), this.un(e, t);
|
|
102
102
|
};
|
|
103
|
-
return this.on(e,
|
|
103
|
+
return this.on(e, s), s;
|
|
104
104
|
}
|
|
105
|
-
return () => this.un(e,
|
|
105
|
+
return () => this.un(e, t);
|
|
106
106
|
}
|
|
107
|
-
un(e,
|
|
108
|
-
var
|
|
109
|
-
(
|
|
107
|
+
un(e, t) {
|
|
108
|
+
var i;
|
|
109
|
+
(i = this.listeners[e]) === null || i === void 0 || i.delete(t);
|
|
110
110
|
}
|
|
111
|
-
once(e,
|
|
112
|
-
return this.on(e,
|
|
111
|
+
once(e, t) {
|
|
112
|
+
return this.on(e, t, { once: !0 });
|
|
113
113
|
}
|
|
114
114
|
unAll() {
|
|
115
115
|
this.listeners = {};
|
|
116
116
|
}
|
|
117
|
-
emit(e, ...
|
|
118
|
-
this.listeners[e] && this.listeners[e].forEach((
|
|
117
|
+
emit(e, ...t) {
|
|
118
|
+
this.listeners[e] && this.listeners[e].forEach((i) => i(...t));
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
class B extends b {
|
|
@@ -153,74 +153,74 @@ class _ extends b {
|
|
|
153
153
|
const F = ["audio/webm", "audio/wav", "audio/mpeg", "audio/mp4", "audio/mp3"];
|
|
154
154
|
class R extends B {
|
|
155
155
|
constructor(e) {
|
|
156
|
-
var
|
|
157
|
-
super(Object.assign(Object.assign({}, e), { audioBitsPerSecond: (
|
|
158
|
-
const
|
|
159
|
-
this.duration = this.isPaused() ? this.duration : this.lastDuration +
|
|
156
|
+
var t, i, s, r, o, a;
|
|
157
|
+
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: (s = e.scrollingWaveformWindow) !== null && s !== void 0 ? s : 5, continuousWaveform: (r = e.continuousWaveform) !== null && r !== void 0 && r, renderRecordedAudio: (o = e.renderRecordedAudio) === null || o === void 0 || o, mediaRecorderTimeslice: (a = e.mediaRecorderTimeslice) !== null && a !== void 0 ? a : void 0 })), this.stream = null, this.mediaRecorder = null, this.dataWindow = null, this.isWaveformPaused = !1, this.lastStartTime = 0, this.lastDuration = 0, this.duration = 0, this.timer = new _(), this.subscriptions.push(this.timer.on("tick", () => {
|
|
158
|
+
const d = performance.now() - this.lastStartTime;
|
|
159
|
+
this.duration = this.isPaused() ? this.duration : this.lastDuration + d, this.emit("record-progress", this.duration);
|
|
160
160
|
}));
|
|
161
161
|
}
|
|
162
162
|
static create(e) {
|
|
163
163
|
return new R(e || {});
|
|
164
164
|
}
|
|
165
165
|
renderMicStream(e) {
|
|
166
|
-
var
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
const
|
|
170
|
-
let
|
|
171
|
-
this.wavesurfer && ((
|
|
172
|
-
const
|
|
173
|
-
var
|
|
166
|
+
var t;
|
|
167
|
+
const i = new AudioContext(), s = i.createMediaStreamSource(e), r = i.createAnalyser();
|
|
168
|
+
s.connect(r), this.options.continuousWaveform && (r.fftSize = 32);
|
|
169
|
+
const o = r.frequencyBinCount, a = new Float32Array(o);
|
|
170
|
+
let d = 0;
|
|
171
|
+
this.wavesurfer && ((t = this.originalOptions) !== null && t !== void 0 || (this.originalOptions = Object.assign({}, this.wavesurfer.options)), this.wavesurfer.options.interact = !1, this.options.scrollingWaveform && (this.wavesurfer.options.cursorWidth = 0));
|
|
172
|
+
const h = setInterval(() => {
|
|
173
|
+
var l, m, p, g;
|
|
174
174
|
if (!this.isWaveformPaused) {
|
|
175
175
|
if (r.getFloatTimeDomainData(a), this.options.scrollingWaveform) {
|
|
176
|
-
const
|
|
176
|
+
const u = Math.floor((this.options.scrollingWaveformWindow || 0) * i.sampleRate), c = Math.min(u, this.dataWindow ? this.dataWindow.length + o : o), f = new Float32Array(u);
|
|
177
177
|
if (this.dataWindow) {
|
|
178
|
-
const D = Math.max(0,
|
|
179
|
-
|
|
178
|
+
const D = Math.max(0, u - this.dataWindow.length);
|
|
179
|
+
f.set(this.dataWindow.slice(-c + o), D);
|
|
180
180
|
}
|
|
181
|
-
|
|
181
|
+
f.set(a, u - o), this.dataWindow = f;
|
|
182
182
|
} else if (this.options.continuousWaveform) {
|
|
183
183
|
if (!this.dataWindow) {
|
|
184
|
-
const
|
|
185
|
-
this.dataWindow = new Float32Array(
|
|
184
|
+
const c = this.options.continuousWaveformDuration ? Math.round(100 * this.options.continuousWaveformDuration) : ((m = (l = this.wavesurfer) === null || l === void 0 ? void 0 : l.getWidth()) !== null && m !== void 0 ? m : 0) * window.devicePixelRatio;
|
|
185
|
+
this.dataWindow = new Float32Array(c);
|
|
186
186
|
}
|
|
187
|
-
let
|
|
188
|
-
for (let
|
|
189
|
-
const
|
|
190
|
-
|
|
187
|
+
let u = 0;
|
|
188
|
+
for (let c = 0; c < o; c++) {
|
|
189
|
+
const f = Math.abs(a[c]);
|
|
190
|
+
f > u && (u = f);
|
|
191
191
|
}
|
|
192
|
-
if (
|
|
193
|
-
const
|
|
194
|
-
|
|
192
|
+
if (d + 1 > this.dataWindow.length) {
|
|
193
|
+
const c = new Float32Array(2 * this.dataWindow.length);
|
|
194
|
+
c.set(this.dataWindow, 0), this.dataWindow = c;
|
|
195
195
|
}
|
|
196
|
-
this.dataWindow[
|
|
196
|
+
this.dataWindow[d] = u, d++;
|
|
197
197
|
} else this.dataWindow = a;
|
|
198
198
|
if (this.wavesurfer) {
|
|
199
|
-
const
|
|
200
|
-
this.wavesurfer.load("", [this.dataWindow], this.options.scrollingWaveform ? this.options.scrollingWaveformWindow :
|
|
199
|
+
const u = ((g = (p = this.dataWindow) === null || p === void 0 ? void 0 : p.length) !== null && g !== void 0 ? g : 0) / 100;
|
|
200
|
+
this.wavesurfer.load("", [this.dataWindow], this.options.scrollingWaveform ? this.options.scrollingWaveformWindow : u).then(() => {
|
|
201
201
|
this.wavesurfer && this.options.continuousWaveform && (this.wavesurfer.setTime(this.getDuration() / 1e3), this.wavesurfer.options.minPxPerSec || this.wavesurfer.setOptions({ minPxPerSec: this.wavesurfer.getWidth() / this.wavesurfer.getDuration() }));
|
|
202
|
-
}).catch((
|
|
203
|
-
console.error("Error rendering real-time recording data:",
|
|
202
|
+
}).catch((c) => {
|
|
203
|
+
console.error("Error rendering real-time recording data:", c);
|
|
204
204
|
});
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
}, 10);
|
|
208
208
|
return { onDestroy: () => {
|
|
209
|
-
clearInterval(
|
|
209
|
+
clearInterval(h), s?.disconnect(), i?.close();
|
|
210
210
|
}, onEnd: () => {
|
|
211
|
-
this.isWaveformPaused = !0, clearInterval(
|
|
211
|
+
this.isWaveformPaused = !0, clearInterval(h), this.stopMic();
|
|
212
212
|
} };
|
|
213
213
|
}
|
|
214
214
|
startMic(e) {
|
|
215
215
|
return W(this, void 0, void 0, function* () {
|
|
216
|
-
let
|
|
216
|
+
let t;
|
|
217
217
|
try {
|
|
218
|
-
|
|
218
|
+
t = yield navigator.mediaDevices.getUserMedia({ audio: !e?.deviceId || { deviceId: e.deviceId } });
|
|
219
219
|
} catch (r) {
|
|
220
220
|
throw new Error("Error accessing the microphone: " + r.message);
|
|
221
221
|
}
|
|
222
|
-
const { onDestroy:
|
|
223
|
-
return this.subscriptions.push(this.once("destroy",
|
|
222
|
+
const { onDestroy: i, onEnd: s } = this.renderMicStream(t);
|
|
223
|
+
return this.subscriptions.push(this.once("destroy", i)), this.subscriptions.push(this.once("record-end", s)), this.stream = t, t;
|
|
224
224
|
});
|
|
225
225
|
}
|
|
226
226
|
stopMic() {
|
|
@@ -228,20 +228,20 @@ class R extends B {
|
|
|
228
228
|
}
|
|
229
229
|
startRecording(e) {
|
|
230
230
|
return W(this, void 0, void 0, function* () {
|
|
231
|
-
const
|
|
231
|
+
const t = this.stream || (yield this.startMic(e));
|
|
232
232
|
this.dataWindow = null;
|
|
233
|
-
const
|
|
234
|
-
this.mediaRecorder =
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
233
|
+
const i = this.mediaRecorder || new MediaRecorder(t, { mimeType: this.options.mimeType || F.find((o) => MediaRecorder.isTypeSupported(o)), audioBitsPerSecond: this.options.audioBitsPerSecond });
|
|
234
|
+
this.mediaRecorder = i, this.stopRecording();
|
|
235
|
+
const s = [];
|
|
236
|
+
i.ondataavailable = (o) => {
|
|
237
|
+
o.data.size > 0 && s.push(o.data), this.emit("record-data-available", o.data);
|
|
238
238
|
};
|
|
239
|
-
const r = (
|
|
239
|
+
const r = (o) => {
|
|
240
240
|
var a;
|
|
241
|
-
const
|
|
242
|
-
this.emit(
|
|
241
|
+
const d = new Blob(s, { type: i.mimeType });
|
|
242
|
+
this.emit(o, d), this.options.renderRecordedAudio && (this.applyOriginalOptionsIfNeeded(), (a = this.wavesurfer) === null || a === void 0 || a.load(URL.createObjectURL(d)));
|
|
243
243
|
};
|
|
244
|
-
|
|
244
|
+
i.onpause = () => r("record-pause"), i.onstop = () => r("record-end"), i.start(this.options.mediaRecorderTimeslice), this.lastStartTime = performance.now(), this.lastDuration = 0, this.duration = 0, this.isWaveformPaused = !1, this.timer.start(), this.emit("record-start");
|
|
245
245
|
});
|
|
246
246
|
}
|
|
247
247
|
getDuration() {
|
|
@@ -264,8 +264,8 @@ class R extends B {
|
|
|
264
264
|
this.isActive() && ((e = this.mediaRecorder) === null || e === void 0 || e.stop(), this.timer.stop());
|
|
265
265
|
}
|
|
266
266
|
pauseRecording() {
|
|
267
|
-
var e,
|
|
268
|
-
this.isRecording() && (this.isWaveformPaused = !0, (e = this.mediaRecorder) === null || e === void 0 || e.requestData(), (
|
|
267
|
+
var e, t;
|
|
268
|
+
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);
|
|
269
269
|
}
|
|
270
270
|
resumeRecording() {
|
|
271
271
|
var e;
|
|
@@ -273,7 +273,7 @@ class R extends B {
|
|
|
273
273
|
}
|
|
274
274
|
static getAvailableAudioDevices() {
|
|
275
275
|
return W(this, void 0, void 0, function* () {
|
|
276
|
-
return navigator.mediaDevices.enumerateDevices().then((e) => e.filter((
|
|
276
|
+
return navigator.mediaDevices.enumerateDevices().then((e) => e.filter((t) => t.kind === "audioinput"));
|
|
277
277
|
});
|
|
278
278
|
}
|
|
279
279
|
destroy() {
|
|
@@ -283,47 +283,50 @@ class R extends B {
|
|
|
283
283
|
this.wavesurfer && this.originalOptions && (this.wavesurfer.setOptions(this.originalOptions), delete this.originalOptions);
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
|
-
const q = ({ containerRef: n, options: e }) => {
|
|
287
|
-
const { waveSurfer: i } = P({ containerRef: n, options: e }),
|
|
288
|
-
Math.floor(
|
|
286
|
+
const q = ({ containerRef: n, options: e, recordPluginOptions: t }) => {
|
|
287
|
+
const { waveSurfer: i } = P({ containerRef: n, options: e }), s = v(null), r = v(0), o = v(!1), a = v(!1), d = y(() => [
|
|
288
|
+
Math.floor(r.value % 36e5 / 6e4),
|
|
289
289
|
// minutes
|
|
290
|
-
Math.floor(
|
|
290
|
+
Math.floor(r.value % 6e4 / 1e3)
|
|
291
291
|
// seconds
|
|
292
|
-
].map((
|
|
293
|
-
|
|
294
|
-
|
|
292
|
+
].map((u) => u < 10 ? "0" + u : u).join(":")), h = y(() => o.value || !a.value), l = () => {
|
|
293
|
+
s.value && s.value?.on("record-progress", (u) => {
|
|
294
|
+
r.value = u;
|
|
295
295
|
});
|
|
296
|
-
},
|
|
297
|
-
if (
|
|
298
|
-
|
|
296
|
+
}, m = () => {
|
|
297
|
+
if (s.value?.isRecording() || s.value?.isPaused()) {
|
|
298
|
+
s.value?.stopRecording(), o.value = !1, a.value = !0;
|
|
299
299
|
return;
|
|
300
300
|
}
|
|
301
|
-
|
|
302
|
-
},
|
|
303
|
-
let
|
|
304
|
-
(
|
|
305
|
-
|
|
301
|
+
s.value?.startRecording(), o.value = !0, a.value = !1, l();
|
|
302
|
+
}, p = () => new Promise((u) => {
|
|
303
|
+
let c;
|
|
304
|
+
(s.value?.isRecording() || s.value?.isPaused()) && (s.value?.stopRecording(), o.value = !1, a.value = !1), s.value?.on("record-end", (f) => {
|
|
305
|
+
c = f, u(c);
|
|
306
306
|
});
|
|
307
307
|
}), g = () => {
|
|
308
|
-
if (
|
|
309
|
-
|
|
308
|
+
if (s.value?.isPaused()) {
|
|
309
|
+
s.value?.resumeRecording(), o.value = !0, a.value = !1;
|
|
310
310
|
return;
|
|
311
311
|
}
|
|
312
|
-
|
|
312
|
+
o.value = !1, a.value = !0, s.value?.pauseRecording();
|
|
313
313
|
};
|
|
314
314
|
return w(() => {
|
|
315
|
-
const
|
|
316
|
-
|
|
315
|
+
const u = i.value?.registerPlugin(R.create({
|
|
316
|
+
renderRecordedAudio: !1,
|
|
317
|
+
...t
|
|
318
|
+
}));
|
|
319
|
+
u && (s.value = u);
|
|
317
320
|
}), {
|
|
318
321
|
waveSurfer: i,
|
|
319
|
-
waveSurferRecorder:
|
|
320
|
-
currentTime:
|
|
321
|
-
startRecording:
|
|
322
|
-
stopRecording:
|
|
322
|
+
waveSurferRecorder: s,
|
|
323
|
+
currentTime: d,
|
|
324
|
+
startRecording: m,
|
|
325
|
+
stopRecording: p,
|
|
323
326
|
pauseRecording: g,
|
|
324
|
-
isRecording:
|
|
325
|
-
isPaused:
|
|
326
|
-
isPauseResume:
|
|
327
|
+
isRecording: o,
|
|
328
|
+
isPaused: a,
|
|
329
|
+
isPauseResume: h
|
|
327
330
|
};
|
|
328
331
|
};
|
|
329
332
|
export {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { default as RecordPlugin } from 'wavesurfer.js/dist/plugins/record.js';
|
|
2
|
-
import {
|
|
3
|
-
export declare const useWaveSurferRecorder: ({ containerRef, options }:
|
|
2
|
+
import { UseWaveSurferRecorder } from '../types';
|
|
3
|
+
export declare const useWaveSurferRecorder: ({ containerRef, options, recordPluginOptions }: UseWaveSurferRecorder) => {
|
|
4
4
|
waveSurfer: import('vue').Ref<{
|
|
5
5
|
options: {
|
|
6
6
|
container: HTMLElement | string;
|
|
@@ -2,9 +2,28 @@ import { WaveSurferOptions } from 'wavesurfer.js';
|
|
|
2
2
|
import { Ref } from 'vue';
|
|
3
3
|
import { useWaveSurferInstance } from '../composables/useWaveSurferInstance';
|
|
4
4
|
import { useWaveSurferState } from '../composables/useWaveSurferState';
|
|
5
|
+
import { RecordPluginOptions } from 'wavesurfer.js/dist/plugins/record';
|
|
6
|
+
import { ZoomPluginOptions } from 'wavesurfer.js/dist/plugins/zoom';
|
|
7
|
+
import { TimelinePluginOptions } from 'wavesurfer.js/dist/plugins/timeline';
|
|
8
|
+
import { HoverPluginOptions } from 'wavesurfer.js/dist/plugins/hover';
|
|
9
|
+
import { SpectrogramPluginOptions } from 'wavesurfer.js/dist/plugins/spectrogram';
|
|
10
|
+
import { EnvelopePluginOptions } from 'wavesurfer.js/dist/plugins/envelope';
|
|
11
|
+
import { MinimapPluginOptions } from 'wavesurfer.js/dist/plugins/minimap';
|
|
5
12
|
export type PartialWaveSurferOptions = Partial<Omit<WaveSurferOptions, 'container'>>;
|
|
6
13
|
export type WaveSurferIns = {
|
|
7
14
|
containerRef: Ref<HTMLElement | null>;
|
|
8
15
|
options: PartialWaveSurferOptions;
|
|
9
16
|
};
|
|
10
17
|
export type UseWaveSurfer = ReturnType<typeof useWaveSurferInstance> & ReturnType<typeof useWaveSurferState>;
|
|
18
|
+
export type Plugins = {
|
|
19
|
+
regions: any;
|
|
20
|
+
timeline: TimelinePluginOptions;
|
|
21
|
+
zoom: ZoomPluginOptions;
|
|
22
|
+
minimap: MinimapPluginOptions;
|
|
23
|
+
envelope: EnvelopePluginOptions;
|
|
24
|
+
spectrogram: SpectrogramPluginOptions;
|
|
25
|
+
hover: HoverPluginOptions;
|
|
26
|
+
};
|
|
27
|
+
export type UseWaveSurferRecorder = WaveSurferIns & {
|
|
28
|
+
recordPluginOptions?: RecordPluginOptions;
|
|
29
|
+
};
|