安装 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

最新文章

  1. 【解决】AWS服务控制台中上传文件失败
  2. 基于cmake编译安装MySQL-5.5
  3. Libgdx 开发指南(1.3) 应用框架——查询、日志
  4. python代码中指定时区获取时间方法
  5. JSP学习——原理
  6. phpstorm-file watcher
  7. python学习笔记二--列表
  8. ASP.NET Boilerplate 工作单元
  9. Solr系列一:Solr与Tomcat的整合
  10. Lua 基础知识-面向对象
  11. 运维必备:Oracle自备份精简教程(linux及win)
  12. MVC 5 + EF6 完整教程16 -- 控制器详解
  13. 数据库中有的字段为null时,反馈到页面上是什么也不显示?如何用一个【无】字来代替呢?
  14. HDU2425:Hiking Trip(BFS+优先队列)
  15. 【最小生成树】Bzoj1232 [Usaco2008Nov]安慰奶牛cheer
  16. Java平台
  17. git与github区别与简介
  18. 【TP3.2.X】linux环境下TP3.2.X的各个目录权限
  19. redis系列之数据库与缓存数据一致性解决方案
  20. 数据仓库基础(八)Informatica 小例子

热门文章

  1. Linux系统管理_网络管理
  2. 各大厂 C/C++ 编程规范详解
  3. String基础: String两种创建对象方式的比较
  4. Linux下MMDetection环境配置
  5. 安装 TypeScript 并编译成JS
  6. 2.3 Goland快捷键
  7. 谷歌、微软、Meta?谁才是 Python 最大的金主?
  8. 小米mini路由器刷breed不死鸟和潘多拉固件
  9. Linux 使用打印机
  10. SSH(一)架包的引入