標籤:
最近研究個新玩意,叫window.AudioContext;不懂?沒關係,我也是才接觸,這完全可以說個全新領域,
這玩意幹啥的?顧名思義,媒體上下文,也就是你媒體的資料分析,就是一串資料啊?那有啥用呢?對,單純的資料毫無意義,但是如果把資料結合canvas,就會產生神奇的效果(比如百度的echart),這裡的AudioContext結合canvas就能產生一個音樂可視化的效果,就是那種手機MP3播放器的效果,又叫音樂可視化;
首先原理:
前端擷取到buffer資料,然後運用解析對象,把資料解析,把解析結果放到數組裡面,然後串連,最後用canvas畫出來;
後台代碼
const express = require(‘express‘);const fs = require(‘fs‘);const app = express();app.get(‘/app/test‘, function(req,res) { fs.readFile(‘Maksim-克羅地亞狂想曲.mp3‘, (err, name) => { if (err) return res.send(name) })})
html部分
<body><input type="range" id="radio"> //改變音量的<canvas id="mycanvas"></canvas></body>
首先前端發起請求,請求音樂的流
function getdata () { var xhr = new XMLHttpRequest() xhr.open(‘get‘, ‘/app/test‘); xhr.responseType = ‘arraybuffer‘; xhr.onload = function () { // 解析後台傳來的資料,然後把資料複製到前端的buffer上; 第一個連結的必須是分析者,分析者擷取未經處理資料 ac.decodeAudioData(xhr.response, function (buffer){ var buffesource = ac.createBufferSource();// 建立資料,其中buffersource還有個屬性是loop就是音樂是不是迴圈播放
buffesource.buffer = buffer buffesource.connect(analyser) buffesource.start(0) //這裡star可以三個參數,一次意思是,等待多久播放,從哪裡開始播放,播放多久 }, function (err) { console.log(err) }) } xhr.send() }
然後建立音頻控制對象
var ac = new (window.AudioContext || window.webkitAudioContext)() //這是相容瀏覽器的寫法 var gainNode = ac[ac.createGain ? ‘createGain‘ : ‘createGainNode‘]() 這個老式和新式api不同 var analyser = ac.createAnalyser() //建立分析者 var size = 128 analyser.fftSize = size * 2;// 這裡擷取柱子個數就是ffsize的一半 analyser.connect(gainNode) gainNode.connect(ac.destination)
初始化canvas
function caninit () { var line = ctx.createLinearGradient(0,0,0,600) line.addColorStop(0,‘red‘) line.addColorStop(.5, ‘yellow‘) line.addColorStop(1, ‘green‘) ctx.fillStyle = line } caninit()
賦值未經處理資料到數組
function asyc () { var arr = new Uint8Array(analyser.frequencyBinCount) analyser.getByteFrequencyData(arr) draw(arr) nextFrame(asyc) }定一個unit8數組,然後把資料賦值進去.注意這裡不是不是8位無符號數組,那麼analyser.getByteFrequencyData這個方法會報錯,說第一個參數必須uint8array
最後畫出效果
function draw (arr) { ctx.clearRect(0, 0, width, height) var w = width / size for (var i = 0; i < arr.length; i++) { var h = (arr[i] / 512) * height; ctx.fillRect(w * i, height - h, w *.6, h) } }
ok可以了,頁面效果是這樣的
全部代碼正在整理上傳,各位有興趣可以寫幾個echart的類型表玩玩啊
music, let's go