今天玩转黑胶唱片,Audio Web API 接起来~~
Audio Web API 可於网页上操作并播放音讯档案。
根据 MDN 定义:
Web Audio API 是根据模组化路由 (Modular routing) 的概念所设计。所谓的模组化路由,即是以「音讯节点 (Audio nodes)」执行基本的音讯作业,节点又互相连接而构成「音讯路由图 (Audio routing graphs)」。在同一环境 (Audio context) 内,又可支援数个音源与多样的声道配置。此模组化设计可提供更高的灵活度,并能建立复杂的音讯函式与动态效果。
设计想法:当点击时黑胶盘开始转动播音乐,再点击一下暂停,另外有音量条调整音量大小。
<!-- html -->
<body>
<audio id="music" src="音源.mp3"></audio>
<h1>DROP THE MUSIC</h1>
<section>
<div id="disk" data-playing="false"></div>
<input id="volume" type="range" min="0" max="4" step="0.1" value="2" />
<label for="volume">volume</label>
</section>
</body>
CSS 的黑胶动画效果设定
/* css */
#disk {
width: 500px;
height: 500px;
background-image: url('黑胶图片');
background-repeat: no-repeat;
background-size: contain;
background-position: center;
margin-bottom: 50px;
}
/* 将黑胶转动 css 另外写才方便 JS 套用 */
.rotating {
animation: rotate 2s linear infinite;
}
/* 动画为黑胶从 0deg 转动到 360deg 模拟转动画面 */
@keyframes rotate {
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}
基本设定完成,正式进入 JavaScript!
要使用 Web API 首先要创建 audioContext,可以把它想像成一个容器用来装声音,在里面可以对声音进行各种处理。
图片来源MDN
使用建构子 AudioContext 创建
let audioCtx = new AudioContext();
在 audioContext 内需要有音源的输入,可以是根据 url 载入的 audioNode 或者是靠 振荡器 Oscillators 产生的音源,而今天要用 HTML 标签的<audio>
来载入音源。
使用 audioContext.createMediaElementSource(音源节点)
// 先取得 audio tag 的节点
let music = document.querySelector('#music');
// 透过刚刚创建了 audioContext 创建音源节点
let source = audioCtx.createMediaElementSource(music)
gainNode 节点是用来控制音量的大小,透过 gainNode.gain.value
可以知道目前音乐的音量,进而改变数值。
let gainNode = audioCtx.createGain();
透过 connect
将音源的输入和输出串连,这样 Web API 的音源绑定就好罗~
source.connect(gainNode).connect(audioCtx.destination);
决定播放还是暂停可以设定一个属性值 playing 做状态转换,当 playing = 'false'
时点击播放,playing='true'
点击暂停,要撷取这个属性值当前的值使用 dataset.属性名称
。
如:
// html 设定 <div data-playing='false'></div>
document.querySelector('div').dataset.playing // false
点击时透过 classList.toggle
加上 rotating class 启动黑胶转动
disk.addEventListener('click', function (event) {
this.classList.toggle('rotating');
if (audioCtx.state === 'suspended') {
audioCtx.resume();
}
if (this.dataset.playing === 'false') {
music.play();
this.dataset.playing = 'true';
} else if (this.dataset.playing === 'true') {
music.pause();
this.dataset.playing = 'false';
}
});
音量条的 HTML 使用 input
标签的 type='range'
,
加上其他属性 最小值min
、最大值max
、每次移动大小step
、预设显示位置value
,就可以取得拉动时的 value 资讯。
监听事件绑定 input (拉动音量条时), gainNode
节点的 value 值等同於 input
标签上拉动的数值。
let volume = get('#volume');
volume.addEventListener('input', function (event) {
gainNode.gain.value = this.value});
MDN - AudioContext
MDN - gainNode
MDN 实作
初探 Web Audio API
Chapter1-DJ最爱的音频动感图像(III)妈妈叫你不要玩音乐,现在知道当DJ很难了吧
音源来源
Audio Web API 实在有太~多东西可以学了,还不知道如何取网路的 url,只能先引入本地端的 mp3 档案,今天试试水温!之後继续挑战
<<: (特别篇)Documents-Delivered-Data,Data-DrivenDocuments—爬虫D3做成D3(上)
>>: 每日挑战,从Javascript面试题目了解一些你可能忽略的概念 - Day28
正在复习C#~(书 和影片 文章 看到头晕) 发现有些观念真的简单又不简单 一定要用自己的方式搞懂~...
前言 在上一篇介绍了Reactor提供Scheduler来帮助开发者,这篇就是来说明具体是如何使用。...
这边先预祝大家中秋节快乐 连假比较忙的关系今天就挑个简单的主题来写 kotlin对於null的处理相...
在疫情期间相信大家都有在线上上课或会议的经验, 有时候我们会觉得老师上课的声音(或会议应用程序拨放的...
实务上,我们可能并没有自己想的那麽了解系统的真实面,这也造就一些起步上的困难,反思一下,这也关於问题...