根据音频链接绘制频谱图
封装
// 可以这样使用 也可以 import { AudioContext } from 'standardized-audio-context';
const getAudioContext = window.AudioContext ||window.webkitAudioContext ||window.mozAudioContext ||window.msAudioContext;const clearArr = []export const stopAudio = () => { clearArr.forEach(f => f()) }/*** 获取音频文件频谱数据 */
export function getAuidoData() {let analyser, dataArray;let loadOver = false;var audioCtx = new getAudioContext({latencyHint: "playback"}); // 创建和播放需要间隔一端时间analyser = audioCtx.createAnalyser();analyser.fftSize = 2048;const destroy = () => { audioCtx.close() }let stop = false;const cbs = []const run = () => {if (stop) return;requestAnimationFrame(() => {var bufferLength = analyser.frequencyBinCount;dataArray = new Uint8Array(bufferLength);analyser.getByteFrequencyData(dataArray);cbs.forEach(f => f(dataArray))run()});};const load = (url, data, onended = () => { }) => {let audioBuffer;// 通过fetch 请求音频获取 arrayBuffer 类型数据const getData = () => { // 方法一 使用fetch请求return fetch(url).then((res) => res.arrayBuffer()).then((arrayBuffer) => {return new Promise((resolve, reject) => {// 兼容低版本的iphone7中 audioCtx.decodeAudioData 返回的不是一个promise,必须通过回调函数audioCtx.decodeAudioData(arrayBuffer, resolve, err => {console.log('decodeAudioData-er', err);reject(err)})})}).then((buffer) => (audioBuffer = buffer));// 方法二 把接口返回blob转 arrayBuffer // ios ajax返回的二进制数据没有 arrayBuffer 方法// return data// .arrayBuffer()// .then((arrayBuffer) => audioCtx.decodeAudioData(arrayBuffer))// .then((buffer) => (audioBuffer = buffer));};getData().then(function () {// 创建音频源const source = audioCtx.createBufferSource();source.buffer = audioBuffer;source.connect(analyser);analyser.connect(audioCtx.destination);// 创建音量节点// const gainNode = audioCtx.createGain();// gainNode.gain.value = 1 // 设置声音大小console.log('source.start');source.start(); // 开始播放run();source.onended = () => {console.log('source.onended'); onended()stop = true}; // 播放完成loadOver = true;clearArr.push(() => { source.stop() })}).catch(err => {console.log('getdata-err', err);});};const change = (cb = () => { }) => cbs.push(cb)return { load, change, destroy };
}
方式 1,直接传递二进制音频数据
// 获取二进制数据// data:二进制音频数据
const blobData = new Blob([data], { type: "audio/mpeg" });
const url = window.URL.createObjectURL(blobData);
const upWave = getAuidoData();
upWave.change((data) => {// draw({data}) // 绘制
});
await new Promise((c) => upWave.load(url, "", c));
方式 2 使用音频链接
const upWave = getAuidoData();
upWave.change((data) => {// draw({data}) // 绘制
});
await new Promise((c) => upWave.load("xxx.mp3", "", c));
注意:在有些设备(iphone7)上,录音和播放不能同时进行, 在一些iphone上 同时进行回导致 播放声音音量较小
注意:在有些设备上,
绘制实现
绘制实现