教你如何在 Nuxt 3 中使用 wavesurfer.js
作者:GanymedeNil
安装 wavesurfer.js
在项目中安装 wavesurfer.js
npm install --save wavesurfer.js
常规方式引入
如果你的根目录中没有 components
目录则需要创建该目录,并在此目录中创建 WaveSurfer.vue
内容如下:
<template> <div ref="wavesurferMain"></div> </template> <script setup> import WaveSurfer from 'wavesurfer.js' const props = defineProps({ src:{ type:String, required:true }, options:{ type:Object, } }); const wavesurferMain = ref(null); const waveSurfer = ref(null); let options = props.options; let wsOptions = Object.assign({ container: wavesurferMain.value }, options); waveSurfer.value = new WaveSurfer.create(wsOptions); waveSurfer.value.load(props.src); </script>
然后我们集成该组件,在这个例子中我们将在 app.vue
直接引用,并且我将测试音频文件 demo.wav
,放在根目录的public
中。
<template> <div> <WaveSurfer src="/demo.wav":options="waveSurferOption" /> </div> </template> <script setup> const waveSurferOption = { height: 340, progressColor: '#e03639', waveColor: '#e7e7e7', cursorColor: '#FFDDDD', barWidth: 2, mediaControls: true, backend: 'MediaElement', scrollParent:true, xhr: { mode: 'no-cors' } }; </script>
现在执行 npm run dev
,页面将报错 self is not defined
。
这是因为在 setup
这个生命周期中,DOM 节点并未创建,所以我们需要在mounted
阶段进行导入。
正确的引入方式
更改 WaveSurfer.vue
文件内容如下:
<template> <div ref="wavesurferMain"></div> </template> <script setup> const props = defineProps({ src:{ type:String, required:true }, options:{ type:Object, } }); const wavesurferMain = ref(null); const waveSurfer = ref(null); onMounted(async ()=>{ const WaveSurfer = (await import('wavesurfer.js')).default; const options = props.options; const wsOptions = Object.assign({ container: wavesurferMain.value }, options); waveSurfer.value = new WaveSurfer.create(wsOptions); waveSurfer.value.load(props.src); }); </script>
现在你应该能看到已经可以正常加载了。
加载插件
加载方式和插件一样,官方的插件在 wavesurfer.js/dist/plugin
目录下,这个例子将加载时间线插件如下:
<template> <div ref="wavesurferMain"></div> <div ref="waveTimeline"></div> </template> <script setup> const props = defineProps({ src:{ type:String, required:true }, options:{ type:Object, } }); const wavesurferMain = ref(null); const waveTimeline = ref(null); const waveSurfer = ref(null); onMounted(async ()=>{ const WaveSurfer = (await import('wavesurfer.js')).default; const Timeline = (await import('wavesurfer.js/dist/plugin/wavesurfer.timeline')).default; const options = props.options; const wsOptions = Object.assign({ container: wavesurferMain.value, plugins:[ Timeline.create({container:waveTimeline.value}) ] }, options); waveSurfer.value = new WaveSurfer.create(wsOptions); waveSurfer.value.load(props.src); }); </script>
加载波形数据
如果音频文件过大,使用插件原生的波形生成方式会非常慢。这个时候可以通过服务端生成波形数据,并让插件直接通过波形数据进行渲染。具体生成方式可以参考官方的解决方案FAQ。在这个项目中,生成波形数据文件后,我把它移动到项目的public
中,更改 WaveSurfer.vue
内容如下:
<template> <div ref="wavesurferMain"></div> <div ref="waveTimeline"></div> </template> <script setup> const props = defineProps({ src:{ type:String, required:true }, peaksData:{ type:String, }, options:{ type:Object, } }); const wavesurferMain = ref(null); const waveTimeline = ref(null); const waveSurfer = ref(null); onMounted(async ()=>{ const WaveSurfer = (await import('wavesurfer.js')).default; const Timeline = (await import('wavesurfer.js/dist/plugin/wavesurfer.timeline')).default; const options = props.options; const wsOptions = Object.assign({ container: wavesurferMain.value, plugins:[ Timeline.create({container:waveTimeline.value}) ] }, options); waveSurfer.value = new WaveSurfer.create(wsOptions); fetch(props.peaksData) .then(response => { if (!response.ok) { throw new Error("HTTP error " + response.status); } return response.json(); }) .then(peaks => { waveSurfer.value.load(props.src,peaks.data); }) .catch((e) => { console.error('error', e); }); }); </script>
在 app.vue
中变更如下:
<template> <div> <WaveSurfer src="/demo.wav" peaks-data="/demo.json" :options="waveSurferOption" /> </div> </template> <script setup> const waveSurferOption = { height: 340, progressColor: '#e03639', waveColor: '#e7e7e7', cursorColor: '#FFDDDD', barWidth: 2, mediaControls: false, backend: 'MediaElement', scrollParent:true, xhr: { mode: 'no-cors' } } </script>
暴露插件的方法
现在我们只是正常初始化插件并让它加载了音频文件,目前我们并不能操作它。
因为 Vue3
中,默认并不会暴露 <script setup>
中声明的绑定。我们需要使用 defineExpose
来暴露对应的属性。WaveSurfer.vue
如下变更:
<template> <div ref="wavesurferMain"></div> <div ref="waveTimeline"></div> </template> <script setup> const props = defineProps({ src:{ type:String, required:true }, peaksData:{ type:String, }, options:{ type:Object, } }); const wavesurferMain = ref(null); const waveTimeline = ref(null); const waveSurfer = ref(null); onMounted(async ()=>{ // 省略逻辑 }); defineExpose( { waveSurfer } ) </script>
在 app.vue
中我们可以这样调用:
<template> <div> <WaveSurfer ref="refWaveSurfer" src="/demo.wav" peaks-data="/demo.json" :options="waveSurferOption"/> <button @click="play">play</button> <button @click="pause">pause</button> </div> </template> <script setup> const waveSurferOption = { height: 340, progressColor: '#e03639', waveColor: '#e7e7e7', cursorColor: '#FFDDDD', barWidth: 2, mediaControls: false, backend: 'MediaElement', scrollParent:true, xhr: { mode: 'no-cors' } } const refWaveSurfer = ref(null); function play() { refWaveSurfer.value.waveSurfer.play(); // 调用播放方法 } function pause(){ refWaveSurfer.value.waveSurfer.pause(); // 调用暂停方法 } </script>
项目
你可以在以下仓库看到完整的示例
https://github.com/AnyStudy/nuxt-3-wavesurfer-demo
到此这篇关于如何在 Nuxt 3 中使用 wavesurfer.js的文章就介绍到这了,更多相关Nuxt 3 使用 wavesurfer.js内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!