wavesurfer.js繪制音頻波形圖的實現(xiàn)
更新時間:2021年04月07日 10:20:31 作者:GuaX
這篇文章主要介紹了wavesurfer.js繪制音頻波形圖的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
1.查看效果圖
向前選中:
向后選中:
代碼如下(示例):
<template> <div class="waveSurfer"> <div class="top"> <span @click="leftSelect">向前選中</span> <span @click="rightSelect">向后選中</span> <span @click="Region">標(biāo)注</span> </div> <!-- 時間軸 --> <div id="wave-timeline" /> <!-- 頻譜圖 --> <div id="waveform"> <progress id="progress" class="progress progress-striped" value="0" max="100" ></progress> </div> <div v-show="ppt" id="wave-spectrogram" class="mt-20" /> <!-- 控制按鈕 --> <div class="title"> <ul> <li> <span @click="zoomIn"></span> </li> <li> <span @click="rew"></span> </li> <li> <span :class="{ on: isPlay }" @click="plays"></span> </li> <li> <span @click="speek"></span> </li> <li> <span @click="zoomOut"></span> </li> <li> <span @click="replay"></span> </li> <li @click="toggleMute" :class="{ on: toggleMutebutton }" class="sound"> <span></span> </li> <li> <input @mouseup="volumeBarHandle" v-model="volValue" type="range" min="0" max="1" value="0.8" step="0.01" /> </li> <li @click="DoubleSpeed(index)"> {{ speed[index] + " X" }} </li> </ul> </div> </div> </template> <script> import WaveSurfer from "wavesurfer.js"; import Timeline from "wavesurfer.js/dist/plugin/wavesurfer.timeline.js"; import Regions from "wavesurfer.js/dist/plugin/wavesurfer.regions.js"; export default { data: function () { return { index: 0, speed: [1.0, 1.5, 2.0, 0.5], isPlay: false, ppt: false, ds: 1.0, zoomValue: 100, zoomMin: 100, fast: 3, back: 3, noteData: [], toggleMutebutton: true, volValue: 0, audioUrl: "", loading: true, }; }, // computed: { // // 計算屬性的 getter // getUrl: function() { // // `this` 指向 vm 實例 // return this.$store.state.voicetrain.url // } // }, // watch: { // getUrl(newUrl) { // this.loading = true // this.audioUrl = newUrl // document.getElementById('waveform').innerHTML = '' // this.init() // } // }, mounted() { this.audioUrl = "http://192.168.1.101:8080/api/files/20201104/62afa213458d44b0a99440b33fb694b9"; this.init(); }, methods: { // 初始化 init() { document.getElementById("progress").style.display = "block"; this.$nextTick(() => { this.wavesurfer = WaveSurfer.create({ container: "#waveform", cursorColor: "#DB7093", // 聲波播放進度線color audioRate: 1, scrollParent: true, backend: "WebAudio", barHeight: 1.5, waveColor: "#43d996", // 聲波color progressColor: "#43d996", // 已播放聲波color loaderColor: "#8B0000", hideScrollbar: false, autoCenter: true, height: 120, splitChannels: true, responsive: true, minPxPerSec: 1, plugins: [ Timeline.create({ container: "#wave-timeline", fontSize: 14, primaryFontColor: "#9191a5", secondaryFontColor: "#9191a5", primaryColor: "#9191a5", secondaryColor: "#9191a5", }), Regions.create({}), ], }); this.wavesurfer.addRegion({ loop: false, drag: false, resize: false, color: "rgba(254, 255, 255, 0.4)", }); // 加載進度條 this.wavesurfer.on("loading", function (percents) { document.getElementById("progress").value = percents; }); this.wavesurfer.load(this.audioUrl); this.value = this.wavesurfer.getVolume() * 100; // 獲取音量 this.zoomValue = this.wavesurfer.params.minPxPerSec; this.zoomMin = this.wavesurfer.params.minPxPerSec; this.wavesurfer.zoom(Number(this.zoomValue)); this.wavesurfer.panner = this.wavesurfer.backend.ac.createPanner(); this.wavesurfer.backend.setFilter(this.wavesurfer.panner); let _this = this; _this.wavesurfer.on("ready", function () { _this.wavesurfer.enableDragSelection({ color: "rgba(0, 180, 0, 0.3)", }); _this.wavesurfer.clearRegions(); _this.wavesurfer.zoom(_this.zoomValue); // 音頻加載完成 document.getElementById("progress").style.display = "none"; document.getElementById("progress").value = 0; _this.isPlay = true; _this.wavesurfer.play(0); }); document.getElementById("waveform").onclick = function () { _this.isPlay = false; _this.wavesurfer.clearRegions(); }; // 更新區(qū)域時。回調(diào)將接收該Region對象。 // this.wavesurfer.on("region-updated", function (region) { // region.playLoop(); // 循環(huán)播放選中區(qū)域 // _this.isPlay = true; // }); _this.wavesurfer.on("region-created", _this.addRegion); _this.wavesurfer.on("region-click", _this.editAnnotation); _this.wavesurfer.on("finish", function () { _this.wavesurfer.play(0); }); }); }, addRegion(params) { this.wavesurfer.clearRegions(); params.handleLeftEl.style.backgroundColor = "transparent"; params.handleRightEl.style.backgroundColor = "transparent"; }, toggleMute() { if (this.toggleMutebutton) { this.volumeCached = this.wavesurfer.getVolume(); this.wavesurfer.setVolume(0); this.toggleMutebutton = false; this.volValue = 0; } else { if (this.volumeCached == 0) this.volumeCached = 1; this.wavesurfer.setVolume(this.volumeCached); this.toggleMutebutton = true; this.volValue = this.volumeCached; } }, volumeBarHandle(e) { if (e.offsetX >= 0 && e.offsetX <= 80) { this.toggleMutebutton = true; this.wavesurfer.setVolume(e.offsetX / 80); } else if (e.offsetX < 0) { this.toggleMutebutton = false; this.wavesurfer.setVolume(0); } else { this.wavesurfer.setVolume(1); this.toggleMutebutton = true; } }, // 標(biāo)注 Region() { console.log( Object.getOwnPropertyNames(this.wavesurfer.regions.list).length ); if ( Object.getOwnPropertyNames(this.wavesurfer.regions.list).length == 0 ) { alert("請選擇波紋"); return; } let start = 0, end = 0; for (var k in this.wavesurfer.regions.list) { let obj = this.wavesurfer.regions.list[k]; start = obj.start.toFixed(2) * 1000; end = obj.end.toFixed(2) * 1000; } console.log(this.wavesurfer); console.log("開始", start); console.log("結(jié)束", end); }, // 播放 plays() { this.isPlay = !this.isPlay; this.wavesurfer.playPause(); //切換播放,應(yīng)用播放或暫停 }, // 回退 rew() { this.wavesurfer.skip(-this.back); this.goPlay(); }, // 快進 speek() { this.wavesurfer.skip(this.fast); this.goPlay(); }, // 重載 replay() { this.isPlay = true; this.wavesurfer.stop(); this.wavesurfer.clearRegions(); this.wavesurfer.play(0); }, // 倍速 DoubleSpeed(index) { if (index === 3) { this.index = 0; this.wavesurfer.setPlaybackRate(this.speed[this.index]); } else { this.index = index + 1; this.wavesurfer.setPlaybackRate(this.speed[this.index]); } console.log(this.wavesurfer); }, // 縮放百分比顯示格式 formatZoom(val) { return val + 100 + " 像素 / 秒"; }, // 點擊縮小 zoomIn() { if (this.zoomValue >= 100) { return; } this.zoomValue += 1; this.wavesurfer.zoom(this.zoomValue); }, // 點擊擴大 zoomOut() { if (this.zoomValue < -100) { return; } this.zoomValue -= 1; this.wavesurfer.zoom(this.zoomValue); }, // 縮放監(jiān)聽 zoomChange() { this.wavesurfer.zoom(Number(this.zoomValue)); }, goPlay() { let start = this.wavesurfer.getCurrentTime(); this.wavesurfer.play(start); }, // 向前選中 leftSelect() { let end = this.wavesurfer.getCurrentTime(); // 獲取當(dāng)前播放位置 this.waveRegion(this.wavesurfer, 0, end, "rgba(0,180,0,.3)", true); }, // 向后選中 rightSelect() { let start = this.wavesurfer.getCurrentTime(); // 獲取當(dāng)前播放位置 let end = this.wavesurfer.getDuration(); // 獲取音頻片段的持續(xù)時間 this.waveRegion(this.wavesurfer, start, end, "rgba(0,180,0,.3)", true); }, waveRegion(wavesurfer, start, end, color, clear) { if (!clear) { wavesurfer.clearRegions(); } wavesurfer.addRegion({ start: start, end: end, color: color, drag: false, }); }, // 區(qū)域點擊事件新建 saveRegions() { console.log("聲紋點擊---"); this.noteData = []; const _this = this; this.noteData = Object.keys(_this.wavesurfer.regions.list).map(function ( id ) { const region = _this.wavesurfer.regions.list[id]; return { id: id, edit: false, start: Math.round(region.start * 10) / 10, end: Math.round(region.end * 10) / 10, attributes: region.attributes, data: { note: region.data.note || "" }, }; }); }, // 區(qū)域點擊 editAnnotation() { this.isPlay = false; }, showNote(region) { if (!this.showNote.el) { this.showNote.el = document.querySelector("#subtitle"); } this.showNote.el.textContent = region.data.note || "–"; }, // 設(shè)置音量 setVolume(val) { console.log(val); this.wavesurfer.setVolume(val / 100); }, // 實例點擊 clearReagion() { this.wavesurfer.clearRegions(); }, }, }; </script> <style lang="scss" scoped> #waveform { position: relative; } .top { width: 100%; flex-basis: 70px; line-height: 40px; flex-shrink: 0; color: white; text-indent: 15px; span, el-slider { color: rgb(39, 39, 39); font-size: 13px; font-weight: 700; margin-right: 20px; padding: 4px 10px; border: 1px solid #ccc; border-radius: 10px; } } .title { width: 100%; flex-basis: 70px; line-height: 40px; text-align: left; flex-shrink: 0; color: white; text-indent: 15px; ul { list-style-type: none; padding-inline-start: 0; .speed { display: flex; flex-direction: column; } li { position: relative; display: inline-block; cursor: default; &:hover { } &:active { } span { display: inline-block; width: 30px; height: 30px; line-height: 30px; } &:nth-child(1) span { width: 27px; height: 27px; background: url("img/縮小.png") right; background-size: cover; } &:nth-child(2) span { background: url("img/kuaitui_bg.png") right; background-size: cover; } &:nth-child(3) { span { background: url("img/bofang_bg.png") right; background-size: cover; } .on { background: url("img/zanting_bg.png") right; background-size: cover; } } &:nth-child(4) span { background: url("img/kuaijin_bg.png") right; background-size: cover; } &:nth-child(5) span { background: url("img/縮放.png") right; background-size: cover; } &:nth-child(6) span { background: url("img/zhongbo.png") right; background-size: cover; } &:nth-child(9) { color: rgb(39, 39, 39); font-size: 13px; font-weight: 700; } &:nth-child(7) { background: none; span { width: 25px; height: 25px; background: url("img/靜音.png") no-repeat; background-size: cover; } &.on { span { width: 25px; height: 25px; background: url("img/喇叭.png") no-repeat; background-size: cover; } } } &:nth-child(8) { width: 80px; background: none; input { -webkit-appearance: none; -moz-appearance: none; -ms-appearance: none; width: 80px; height: 3px; background-color: #bbbbbb; position: absolute; left: 0; top: -14px; &::-webkit-slider-thumb { -webkit-appearance: none; } &::-moz-range-trackpseduo { -moz-appearance: none; } &::-ms-track { width: 100%; cursor: pointer; background: transparent; /* Hides the slider so custom styles can be added */ border-color: transparent; color: transparent; } &:focus { outline: none; } &::-webkit-slider-thumb { -webkit-appearance: none; height: 9px; width: 9px; margin-top: -1px; background: #bbb; border-radius: 50%; border: solid 0.125em rgba(205, 224, 230, 0.5); } &::-moz-range-thumb { -moz-appearance: none; height: 6px; width: 6px; margin-top: -1px; background: #bbb; border-radius: 50%; border: solid 0.125em rgba(205, 224, 230, 0.5); } &::-ms-track { -moz-appearance: none; height: 6px; width: 6px; margin-top: -1px; background: #bbb; border-radius: 50%; border: solid 0.125em rgba(205, 224, 230, 0.5); } } } } } } #wave-timeline { height: 21px; } #waveform { width: 100%; flex-basis: 128px; flex-shrink: 0; position: relative; } #progress { position: absolute; width: 100%; height: 4px; background: #ccc; top: 48%; opacity: 0.7; z-index: 44; } .mt-20 { margin-top: 20px; } .mt-30 { margin-top: 30px; } .waveSurfer { width: 470px; } .waveSurfer >>> .el-slider__runway { margin: 6px 0; } </style>
到此這篇關(guān)于wavesurfer.js繪制音頻波形圖的實現(xiàn)的文章就介紹到這了,更多相關(guān)wavesurfer.js 音頻波形圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
用js統(tǒng)計用戶下載網(wǎng)頁所需時間的腳本
下面的方法是個不錯的思路,建議對于js感興趣的朋友,推薦看2008-10-10layer.msg()去掉默認時間,實現(xiàn)手動關(guān)閉的方法
今天小編就為大家分享一篇layer.msg()去掉默認時間,實現(xiàn)手動關(guān)閉的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09ES6常用小技巧總結(jié)【去重、交換、合并、反轉(zhuǎn)、迭代、計算等】
這篇文章主要介紹了ES6常用小技巧,結(jié)合實例形式總結(jié)分析了ES6常見的數(shù)組去重、交換變量、合并數(shù)組、字符串反轉(zhuǎn)、數(shù)組迭代、數(shù)值計算等相關(guān)操作技巧,需要的朋友可以參考下2019-12-12js+數(shù)組實現(xiàn)網(wǎng)頁上顯示時間/星期幾的實用方法
在網(wǎng)頁上顯示時間(年月日/時分秒),很多新手朋友都想實現(xiàn)這樣的功能,本文整理了一些實用技巧,殺出來與大家分享,感興趣的朋友可以了解下2013-01-01