WaveSurfer.js是一个开源的音频可视化库,用于创建交互式、可定制的波形。文章详细介绍了配置选项,包括播放速度、音频渲染、波形样式、交互性等,并提供了事件处理方法如播放、暂停、音量控制等。本文要实现的效果图如下:
安装
按照官方文档步骤
1.安装
- npm install --save wavesurfer.js
复制代码 2.引入
- import WaveSurfer from 'wavesurfer.js'
- //需要时间轴的话需要引入
- import Timeline from 'wavesurfer.js/dist/plugins/timeline.esm.js'
复制代码 封装Vue 组件
接下来,我们将 WaveSurfer.js 封装成一个 Vue 组件,方便在项目中复用。以下是完整的组件代码- <template>
- <div id="aiccAudio">
- <el-card>
- <div id="wavefrom" ref="wavefrom" @click="getTime">
- </div>
- </el-card>
- <div class="audio-controlBar">
- <!-- 播放/暂停按钮 -->
- <button @click="playMusic">
- <i v-if="videoPlay" class="el-icon-video-play"></i>
- <i v-else class="el-icon-video-pause"></i>
- </button>
- <!-- 时间 -->
- <div class="audio-time">
- <div class="audio-current-time" aria-label="time">{{ currentTime }}</div>
- <span class="audio-fen-line">|</span>
- <div class="audio-duration" aria-label="duration">{{ duration }}</div>
- </div>
- <!-- 倍速 -->
- <span style="margin-left: 80px;margin-right: 10px;">倍速</span>
- <el-select class="audio-speed" v-model="speedValue" @change="speedChange">
- <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
- </el-option>
- </el-select>
- <!-- <span class="audio-line">|</span> -->
- <!-- 音量 -->
- <div class="audio-volume">
- <img v-if="audioVolumeStatus == true" @click="volumeStatusChange('open')" class="audio-volume-img"
- src="../../../../public/images/voice_open.png">
- <img v-else class="audio-volume-img" @click="volumeStatusChange('close')"
- src="../../../../public/images/voice_close.png">
- <el-slider class="audio-volume-slider" v-model="volume" @input="volumeChange"></el-slider>
- </div>
- </div>
- </div>
- </template>
- <script>
- import WaveSurfer from 'wavesurfer.js' //导入wavesurfer.js
- import Timeline from 'wavesurfer.js/dist/plugins/timeline.esm.js' //导入时间轴插件
- export default {
- name: 'AiccAudio',
- props: {
- src: {
- type: String
- },
- recordPath: {
- type: String
- }
- },
- data() {
- return {
- wavesurfer: null,
- timer: null,
- options: [
- {
- value: '0.5',
- label: '0.5',
- }, {
- value: '1.0',
- label: '1.0',
- }, {
- value: '1.5',
- label: '1.5',
- }, {
- value: '2.0',
- label: '2.0',
- }
- ],
- speedValue: '1.0',
- currentTime: '00:00:00', //当前播放
- duration: '00:00:00', //总时长
- volume: 30,//音量,
- audioVolumeStatus: false, //是否静音
- videoPlay: true,
- }
- },
- created() {
- this.keyDown();
- },
- mounted() {
- this.$nextTick(() => {
- if (this.recordPath != null && this.recordPath != '') {
- this.wavesurfer = WaveSurfer.create({
- container: this.$refs.wavefrom,
- height: 128,
- waveColor: 'rgb(200, 0, 200)',
- progressColor: '#00f2fe',
- cursorColor: '#00f2fe', //指示播放头位置的光标填充颜色
- cursorWidth: 2,
- // backend: 'MediaElement',
- mediaControls: false,
- audioRate: this.speedValue,
- hideScrollbar: true,
- setPlaybackRate: [0.5, 1.0, 1.5, 2.0],
- //使用时间轴插件
- plugins: [Timeline.create()],
- })
- this.wavesurfer.load('http://localhost:9527/89A3099B9253566.mp3')
- console.log(this.wavesurfer)
- //音频加载完成触发
- this.wavesurfer.on("ready", () => {
- this.wavesurfer.setVolume(this.volume / 100);
- this.duration = this.formatSecond(this.wavesurfer.getDuration())
- });
- this.wavesurfer.on('click', () => {
- this.wavesurfer.play()
- this.videoPlay = false
- })
- }
- })
- },
- methods: {
- getSoundUrl(options) {
- // 具体请求怎么写就看每个人的项目用的是什么了
- return axios.get(url, { responseType: 'blob' })
- .then(res => {
- if (!res.headers['content-disposition']) {
- return console.error('文件名称不存在');
- }
- // 获取到的blob类型文件地址
- return URL.createObjectURL(res.data);
- })
- .catch(err => {
- console.error('文件获取失败');
- })
- },
- playMusic() {
- if (this.recordPath != null && this.recordPath != '') {
- //"播放/暂停"按钮的单击触发事件,暂停的话单击则播放,正在播放的话单击则暂停播放
- this.wavesurfer.playPause.bind(this.wavesurfer)();
- //每秒获取进度 有时间轴时使用
- // this.getProcess();
- //判断是否播放
- this.videoPlay = this.wavesurfer.isPlaying() == true ? false : true;
- //音频播放时触发
- this.wavesurfer.on("audioprocess", () => {
- this.currentTime = this.formatSecond(this.wavesurfer.getCurrentTime())
- })
- //结束播放
- this.wavesurfer.on("finish", () => {
- this.wavesurfer.stop();
- this.videoPlay = true;
- this.currentTime = '00:00:00'
- });
- }
- },
- formatSecond(seconds) {
- // console.log(seconds)
- // 确保输入是数字类型
- if (typeof seconds !== 'number' || isNaN(seconds)) {
- this.$message.error('error')
- }
- // 将秒数拆分为小时、分钟和秒
- const totalSeconds = Math.floor(seconds); // 只保留整数部分
- const hours = String(Math.floor(totalSeconds / 3600)).padStart(2, '0'); // 计算小时并补零
- const minutes = String(Math.floor((totalSeconds % 3600) / 60)).padStart(2, '0'); // 计算分钟并补零
- const secs = String(totalSeconds % 60).padStart(2, '0'); // 计算秒并补零
- return `${hours}:${minutes}:${secs}`;
- },
- //有时间轴时使用
- // getProcess(){
- // if(this.wavesurfer.isPlaying()){
- // this.timer=setInterval(()=>{
- // this.percent=(this.wavesurfer.getCurrentTime().toFixed(0)/this.wavesurfer.getDuration()*100).toFixed(0)
- // this.config={
- // value:this.percent
- // }
- // },1000)
- // }else{
- // clearInterval(this.timer)
- // }
- // },
- //点击获取点击进度
- getTime() {
- if (this.recordPath != null && this.recordPath != '') {
- //加定时器,不然获取的是点击前的播放时间
- setTimeout(() => {
- this.currentTime = this.formatSecond(this.wavesurfer.getCurrentTime())
- ///有时间轴时使用
- // this.percent=(this.wavesurfer.getCurrentTime()/this.wavesurfer.getDuration()*100).toFixed(0)
- // this.config={
- // value:this.percent
- // }
- }, 100)
- }
- },
- //按键跳转进度
- // jump(e){
- // this.wavesurfer.play([e.target.innerHTML-0])
- // this.percent=(this.wavesurfer.getCurrentTime().toFixed(0)/this.wavesurfer.getDuration()*100).toFixed(0)
- // this.config={
- // value:this.percent
- // }
- // this.getProcess()
- // },
- // 监听键盘
- keyDown() {
- if (this.recordPath != null && this.recordPath != '') {
- document.onkeydown = (e) => {
- //事件对象兼容
- var eCode = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode;
- //键盘按键判断:左箭头-37;上箭头-38;右箭头-39;下箭头-40
- //左
- if (eCode == 37) {
- // 按下左箭头
- this.wavesurfer.skip(-6)
- this.getTime()
- } else if (eCode == 39) {
- // 按下右箭头
- this.wavesurfer.skip(6)
- this.getTime()
- }
- }
- }
- },
- //倍速
- speedChange(val) {
- if (this.recordPath != null && this.recordPath != '') {
- this.speedValue = val;
- this.wavesurfer.setPlaybackRate(this.speedValue)
- }
- },
- //音量大小改变
- volumeChange(val) {
- if (this.recordPath != null && this.recordPath != '') {
- this.volume = val;
- if (this.wavesurfer != null) {
- this.wavesurfer.setVolume(val / 100);
- }
- if (val == '0') {
- this.audioVolumeStatus = false
- } else {
- this.audioVolumeStatus = true
- }
- }
- },
- //静音开启关闭
- volumeStatusChange(status) {
- if (this.recordPath != null && this.recordPath != '') {
- if (status == 'open') {
- this.audioVolumeStatus = false
- this.volume = 0;
- this.wavesurfer.setVolume(0);
- } else {
- this.audioVolumeStatus = true
- this.volume = 30;
- this.wavesurfer.setVolume(30 / 100);
- }
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .audio-controlBar {
- background-color: #f4f6f9;
- padding: 0 10px;
- border-radius: 10px;
- button {
- border: none;
- background-color: #f4f6f9;
- }
- i {
- //color: #95979f;
- color: #1053ee;
- }
- }
- //时间
- .audio-time {
- display: inline-block;
- font-size: 12px;
- color: #95979f;
- margin: 0 10px;
- }
- .audio-current-time {
- display: inline-block;
- color: #1053ee;
- }
- .audio-fen-line {
- margin: 0 5px;
- }
- .audio-duration {
- display: inline-block;
- }
- //倍速
- .audio-speed {
- width: 68px;
- // margin-left: 85px;
- .el-input__inner {
- background-color: #f4f6f9;
- }
- }
- .audio-line {
- color: #95979f;
- margin-right: 5px;
- }
- //音量条
- .audio-volume {
- width: 166px;
- float: right;
- .audio-volume-slider {
- width: 110px;
- float: right;
- }
- }
- .audio-volume-img {
- width: 18px;
- margin-top: 12px;
- }
- </style>
复制代码 我为了方便测试,音频路径是写在里面的,有用的同学可以根据项目需求传入组件中,样式功能啥的可以自行调整。
总结
通过 WaveSurfer.js,我们可以轻松实现音频的可视化与播放控制。本文介绍的 Vue 组件封装了常见的音频播放功能,包括播放/暂停、倍速控制、音量调节等,方便在项目中复用。根据项目需求,可以进一步调整样式和功能。
以上就是Vue使用wavesurfer.js实现音频可视化的示例详解的详细内容,更多关于Vue wavesurfer.js音频可视化的资料请关注脚本之家其它相关文章!
来源:https://www.jb51.net/javascript/339416vkx.htm
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |