书又接上文,感觉逼格不够大,所以鼓捣了个音频可视化
Web Audio API
Web Audio API可以获取音频的包括频率、波形的信息,能用于选频、加特效、做可视化、添加空间效果等,就像是音频版的canvas
MDN网站已经给出音频可视化案例了,我只需魔改一下就行了
编码
在MDN的案例基础上加了点自己的个性化需求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| import debounce from "../Tools/debounce.js"
export default (canvas, audio) => { const FFT = 512
const audioCtx = new (window.AudioContext || window.webkitAudioContext)() const analyser = audioCtx.createAnalyser() analyser.fftSize = FFT
const audioSrc = audioCtx.createMediaElementSource(audio) audioSrc.connect(analyser) analyser.connect(audioCtx.destination)
const bufferLength = analyser.frequencyBinCount const dataArray = new Uint8Array(bufferLength) analyser.getByteFrequencyData(dataArray)
const canvasResize = ()=> { canvas.width = window.innerWidth canvas.height = window.innerHeight } canvasResize() window.addEventListener("resize", debounce(canvasResize,100))
if (canvas.getContext) { const ctx = canvas.getContext("2d") ctx.clearRect(0, 0, canvas.width, canvas.height)
const draw = () => { requestAnimationFrame(draw)
analyser.getByteFrequencyData(dataArray)
ctx.clearRect(0, 0, canvas.width, canvas.height)
const barWidth = (canvas.width / bufferLength) let barHeight let x = 0
for (var i = 0; i < bufferLength; i++) { barHeight = ((dataArray[i] * 3) / (FFT)) * canvas.height
ctx.fillStyle = `hsl(${120 + (x / canvas.width) * 120},${10 + (barHeight / canvas.height) * 90}%,60%)`
ctx.fillRect(x, canvas.height - barHeight / 2, barWidth, barHeight)
x += barWidth + 3 } } draw() } }
|
然后是笨办法之轮询等播放器初始化(
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import makeVisual from "./makeVisual.js"
window.addEventListener("load", ()=> {
const timer = setInterval(() => { if(window.fixedap) { const audio = window.fixedap.audio const canvas = document.getElementById("music-visualization") const canplay = ()=> { makeVisual(canvas,audio) window.removeEventListener("click", canplay) } window.addEventListener("click", canplay) clearInterval(timer) } }, 500) })
|
在Meting.js中的恰当位置加一句,否则不能跨域获取音频信息
1
| aplayers.forEach(ap=> {ap.audio.crossOrigin="anonymous"})
|
最后就是把canvas标签加进butterfly inject配置项
1 2 3 4
| inject: head: <canvas id="music-visualization" style="position:fixed;z-index:-900"></canvas>
|
为了让可视化效果更好看,我顺便把原本页面上纯色的内容块改成了半透明,感觉还不错~