网站首页 > 知识剖析 正文
要实现音频可视化,实现一些炫酷的效果需要借助 Web Audio API提供的一些方法 AudioContext。
- AudioContext接口表示由链接在一起的音频模块构建的音频处理图,每个模块由一个AudioNode表示。音频上下文控制它包含的节点的创建和音频处理或解码的执行。
- 在做任何其他操作之前,您需要创建一个AudioContext对象,因为所有事情都是在上下文中发生的。建议创建一个AudioContext对象并复用它,而不是每次初始化一个新的AudioContext对象,并且可以对多个不同的音频源和管道同时使用一个AudioContext对象。
准备 audio 和 canvas 标签
<audio class="audio" ref='audio' :src='tune' @ended='ended'></audio>
<canvas ref='canvas' width='300px' height='300px'></canvas>
创建并返回一个新的AudioContext对象。
const ctx = new AudioContext();
创建一个新的MediaElementAudioSourceNode对象
- AudioContext 接口的 createMediaElementSource() 方法用于创建一个新的MediaElementAudioSourceNode对象,输入某个存在的 HTML<audio>or<video>` 元素, 对应的音频即可被播放或者修改.
const audioSrc = ctx.createMediaElementSource(this.audioElement);
创建AnalyserNode对象
- AudioContext 的createAnalyser()方法能创建一个AnalyserNode,可以用来获取音频时间和频率数据,以及实现数据可视化。
const analyser = ctx.createAnalyser();
设置 fftSize 属性
- AnalyserNode 接口的 fftSize 属性的值是一个无符号长整型的值, 表示(信号)样本的窗口大小。当执行快速傅里叶变换(Fast Fourier Transfor (FFT))时,这些(信号)样本被用来获取频域数据。
- fftSize 属性的值必须是从32到32768范围内的2的非零幂; 其默认值为2048。
analyser.fftSize = 512;
audioSrc 和 analyser 进行链接
AudioNode 接口的 connect() 方法使你能将一个节点的输出连接到一个指定目标,这个指定的目标可能是另一个 AudioNode(从而将音频数据引导到下一个指定节点)或一个AudioParam, 以便上一个节点的输出数据随着时间流逝能自动地对下一个参数值进行改变。
audioSrc.connect(analyser);
analyser 和 ctx.destination 进行链接
- AudioContext 的 destination 属性返回一个 AudioDestinationNode 表示context中所有音频(节点)的最终目标节点,一般是音频渲染设备,比如扬声器。
analyser.connect(ctx.destination)
歌曲播放进行中
- Uint8Array 数组类型表示一个8位无符号整型数组,创建时内容被初始化为0。创建完后,可以以对象的方式或使用数组下标索引的方式引用数组中的元素。
- AnalyserNode接口的 getByteFrequencyData() 方法将当前频率数据复制到传入的Uint8Array(无符号字节数组)中。
- 如果数组的长度小于 AnalyserNode.frequencyBinCount, 那么Analyser多出的元素会被删除. 如果是大于, 那么数组多余的元素会被忽略.
visualization() {
const arr = new Uint8Array(this.analyser.frequencyBinCount);
this.analyser.getByteFrequencyData(arr);
this.draw(arr);
},
使用canvas绘制音频图谱
- HTMLCanvasElement.getContext() 方法返回canvas 的上下文,如果上下文没有定义则返回 null .
- 2d建立一个 CanvasRenderingContext2D 二维渲染上下文。
this.canvas = this.$refs.canvas.getContext('2d');
draw(arr) {
canvas.clearRect(0, 0, document.body.clientWidth, this.canvasHeight);
const start = ((document.body.clientWidth / 2) - ((arr.length / 2) * 3));
arr.forEach((item, index) => {
this.canvas.beginPath();
this.canvas.strokeStyle = '#B2AFF4';
this.canvas.lineWidth = 3;
this.canvas.moveTo(start + (index * 4), this.canvasHeight);
this.canvas.lineTo(start + (index * 4), this.canvasHeight - item / 2);
this.canvas.stroke();
});
}
效果展示
- 上一篇: Canvas学习笔记 | 图片操作
- 下一篇: canvas基础知识大全
猜你喜欢
- 2025-01-05 如何实现使用鼠标绘制直线?
- 2025-01-05 leaferjs,全新的 Canvas 渲染引擎
- 2025-01-05 「从头到脚」WebRTC + Canvas 实现一个双人协作的共享画板
- 2025-01-05 一文解读前端实现电子签名
- 2025-01-05 Javascript图形(一):阿基米德螺线
- 2025-01-05 有趣的分形(二):六边形雪花
- 2025-01-05 HTML5学习笔记-绘制变形图形之组合效果
- 2025-01-05 游戏开发之旅-JavaScript绘制图形
- 2025-01-05 用三角函数sin和cos画模拟雷达示意图的html代码解析
- 2025-01-05 如何用2 KB代码实现3D赛车游戏?2kPlus Jam大赛了解一下
- 最近发表
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)