教你如何在 Nuxt 3 中使用 wavesurfer.js

安裝 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內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: