教你如何在 Nuxt 3 中使用 wavesurfer.js
安裝 wavesurfer.js
在項(xiàng)目中安裝 wavesurfer.js
npm install --save wavesurfer.js
常規(guī)方式引入
如果你的根目錄中沒有 components
目錄則需要?jiǎng)?chuàng)建該目錄,并在此目錄中創(chuàng)建 WaveSurfer.vue
內(nèi)容如下:
<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>
然后我們集成該組件,在這個(gè)例子中我們將在 app.vue
直接引用,并且我將測(cè)試音頻文件 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>
現(xiàn)在執(zhí)行 npm run dev
,頁(yè)面將報(bào)錯(cuò) self is not defined
。
這是因?yàn)樵?setup
這個(gè)生命周期中,DOM 節(jié)點(diǎn)并未創(chuàng)建,所以我們需要在mounted
階段進(jìn)行導(dǎo)入。
正確的引入方式
更改 WaveSurfer.vue
文件內(nèi)容如下:
<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>
現(xiàn)在你應(yīng)該能看到已經(jīng)可以正常加載了。
加載插件
加載方式和插件一樣,官方的插件在 wavesurfer.js/dist/plugin
目錄下,這個(gè)例子將加載時(shí)間線插件如下:
<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>
加載波形數(shù)據(jù)
如果音頻文件過(guò)大,使用插件原生的波形生成方式會(huì)非常慢。這個(gè)時(shí)候可以通過(guò)服務(wù)端生成波形數(shù)據(jù),并讓插件直接通過(guò)波形數(shù)據(jù)進(jìn)行渲染。具體生成方式可以參考官方的解決方案FAQ。在這個(gè)項(xiàng)目中,生成波形數(shù)據(jù)文件后,我把它移動(dòng)到項(xiàng)目的public
中,更改 WaveSurfer.vue
內(nèi)容如下:
<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>
暴露插件的方法
現(xiàn)在我們只是正常初始化插件并讓它加載了音頻文件,目前我們并不能操作它。
因?yàn)?Vue3
中,默認(rèn)并不會(huì)暴露 <script setup>
中聲明的綁定。我們需要使用 defineExpose
來(lái)暴露對(duì)應(yīng)的屬性。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
中我們可以這樣調(diào)用:
<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(); // 調(diào)用播放方法 } function pause(){ refWaveSurfer.value.waveSurfer.pause(); // 調(diào)用暫停方法 } </script>
項(xiàng)目
你可以在以下倉(cāng)庫(kù)看到完整的示例
https://github.com/AnyStudy/nuxt-3-wavesurfer-demo
到此這篇關(guān)于如何在 Nuxt 3 中使用 wavesurfer.js的文章就介紹到這了,更多相關(guān)Nuxt 3 使用 wavesurfer.js內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue組件通信中非父子組件傳值知識(shí)點(diǎn)總結(jié)
在本篇文章里小編給大家整理的是關(guān)于Vue組件通信中非父子組件傳值知識(shí)點(diǎn)總結(jié),有興趣的朋友們學(xué)習(xí)下。2019-12-12解決vue build打包之后首頁(yè)白屏的問(wèn)題
下面小編就為大家分享一篇解決vue build打包之后首頁(yè)白屏的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03vue+elementUI中el-radio設(shè)置默認(rèn)值方式
這篇文章主要介紹了vue+elementUI中el-radio設(shè)置默認(rèn)值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12淺談一下Vue生命周期中mounted和created的區(qū)別
每一個(gè)vue實(shí)例從創(chuàng)建到銷毀的過(guò)程,就是這個(gè)vue實(shí)例的生命周期,在這個(gè)過(guò)程中,他經(jīng)歷了從開始創(chuàng)建、初始化數(shù)據(jù)、編譯模板、掛載Dom、渲染→更新→渲染、卸載等一系列過(guò)程,那么這些過(guò)程中,具體vue做了些啥,我們今天來(lái)了解一下2023-05-05使用Bootstrap4 + Vue2實(shí)現(xiàn)分頁(yè)查詢的示例代碼
本篇文章主要介紹了使用Bootstrap4 + Vue2實(shí)現(xiàn)分頁(yè)查詢的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12vue3.0基于views批量實(shí)現(xiàn)動(dòng)態(tài)路由的方法(示例代碼)
以前vue項(xiàng)目中也有很多實(shí)現(xiàn)動(dòng)態(tài)路由的方法,比如有一些項(xiàng)目涉及權(quán)限的可能會(huì)使用api請(qǐng)求路由數(shù)據(jù)在來(lái)createRouter,或者本地構(gòu)建使用routes.push來(lái)動(dòng)態(tài)構(gòu)建路由, 今天介紹一種新的方式來(lái)基于某個(gè)文件夾批量構(gòu)建動(dòng)態(tài)路由的方法,感興趣的朋友一起看看吧2024-12-12