目的:通过对 audio 和 audioContext 的使用,加深对音频的处理

  • 使用 标签播放音频
  • 使用 AudioContext 对象播放音频
  • <进阶>通过 AudioContext 对音频进行精细化处理:失真、滤波,变调
  • <进阶>通过 AudioContext.createBuffer()生成一段音频

最终源码

使用 audio 标签播放音频

使用 audio 标签播放音乐, 加载音频文件可以通过直接在标签上的 src 写好,
或通过 audio.setAttribute(“src”,"./love105.mp3");此方法来设置

<audio id="audio" src="./love105.mp3"></audio>
<button onclick="play()">play</button>
<button onclick="suspend()">suspend</button><script>var audio = document.getElementById("audio");function play() {audio.play();}function suspend() {audio.pause();}
</script>

限制,chrome 已经不支持自动播放音频,规定只有用户与页面交互之后,比如点击了页面任意地方之后才会自动播放。而自动播放的需求非常常见,因此需要设计师根据场景去设计交互,交互之后进行音频得播放

示例:每秒检测是否已经开始播放,没有那么一直检测下去,直到播放。
在示例中,你会发现一直检测,一直报错,直到你与页面交互(点击)之后,那么播放限制解除,才会真正开始播放。

<audio id="audio" src="./love105.mp3" auto loop></audio>
<button onclick="play()">play</button>
<button onclick="suspend()">suspend</button><script>var audio = document.getElementById("audio");var isPlaying = false;checkIsPlaying();function checkIsPlaying() {setTimeout(() => {if (!isPlaying) {console.log("检测中,未播放");play();checkIsPlaying();}}, 1000);}// 使用异步确保开始播放async function play() {await audio.play();isPlaying = true;console.log("开始播放");}function suspend() {audio.pause();}
</script>

使用 audioContext 对象播放音频

使用 audioContext 播放也并不复杂,主要需要理解这一个方法 audioContext.createBufferSource()方法.

可以将音频视作竹子,一段完整得音频,由一个又一个节点相连而成。

audioContext 上有一个方法 var source = ctx.createBufferSource()用于生成音频头部节点.
audioContext 上有一个属性叫做 ctx.destination,标识音频尾节点.
source 上的一个方法source.connet(),可以对头尾进行链接 source.connet(ctx.destination)
接下来,头尾链接,就成为了一根完整的竹子,也就是一个完整的音频。

<button onclick="playAudio()">playAudio</button>
<button onclick="resumeAudio()">resumeAudio</button>
<button onclick="stopAudio()">stopAudio</button>
<script>var ctx = new (window.AudioContext || window.webkitAudioContext())();let source = ctx.createBufferSource(); // 创建音频源头姐点// 播放async function playAudio() {const audioBuffer = await loadAudio();playSound(audioBuffer);}// 暂停async function resumeAudio() {if (ctx.state === "running") {ctx.suspend();} else if (ctx.state === "suspended") {ctx.resume();}}// 停止async function stopAudio() {source.stop();}async function loadAudio() {const audioUrl = "love105.mp3";const res = await fetch(audioUrl);const arrayBuffer = await res.arrayBuffer(); // byte array字节数组const audioBuffer = await ctx.decodeAudioData(arrayBuffer, function(decodeData) {return decodeData;});return audioBuffer;}async function playSound(audioBuffer) {source.buffer = audioBuffer; // 设置数据source.loop = true; //设置,循环播放source.connect(ctx.destination); // 头尾相连// 可以对音频做任何控制source.start(0); //立即播放}
</script>

使用 audioContext 对象,对音频进行细化处理

以下内容非专业音乐人士或感兴趣者可以跳过了.

以下内容用到了这几个 API

  • var gainNode = ctx.createGain();。音量控制节点,控制音量变大变小

  • var biquadFilter = ctx.createBiquadFilter();。滤波节点,过滤指定频段波形

  • var distortion = ctx.createWaveShaper();。非线性失真节点,又称之为畸变节点

  • var convolver = ctx.createConvolver();。混音节点

当我们挺一段音频(音乐)时,调子有时很高,譬如歌曲<青藏高原>,有时又很低<慢慢>,这在音频上时如何标识的呢?我们使用一段频谱均匀的音频来演示

  1. 生成一段音频,生成一段最简单的白噪音音频,也就是很熟悉的电视雪花音

在上面 audioContext 代码的基础上添加一个按钮和一个方法

async function playSound(audioBuffer) {var myArrayBuffer = getDefineBuffer(); // 数据源使用刚生成的白噪音source.buffer = myArrayBuffer;source.loop = true; //设置,循环播放source.connect(ctx.destination); // 头尾相连// 可以对音频做任何控制source.start(0); //立即播放
}function getDefineBuffer() {// 立体声var channels = 2;// 创建一个 采样率与音频环境(AudioContext)相同的 时长5秒的 音频片段。var frameCount = ctx.sampleRate * 5.0; // ctx.sampleRate:缓存区内,PCM数据每秒钟的采样率var myArrayBuffer = ctx.createBuffer(channels, frameCount, ctx.sampleRate);// 使用白噪声填充;就是 -1.0 到 1.0 之间的随机数for (var channel = 0; channel < channels; channel++) {// 向myArrayBuffer的频道中填充数据。// 此方法myArrayBuffer.getChannelData()设计的与常见理解相反,nowBuffering内一旦填充了数据,myArrayBuffer内部评到也就填充了var nowBuffering = myArrayBuffer.getChannelData(channel);for (var i = 0; i < frameCount; i++) {nowBuffering[i] = Math.random() * 2 - 1;}}return myArrayBuffer;
}

音频细化处理方法

  1. 细化处理之 对音频进行音量设置
<script>var ctx = new (window.AudioContext || window.webkitAudioContext())();let source = ctx.createBufferSource();let gainNode = ctx.createGain(); // 创建音量控制节点addEventListenerlGainNode();async function playSound(audioBuffer) {var myArrayBuffer = getDefineBuffer(); // 数据源使用刚生成的白噪音source.buffer = myArrayBuffer;source.loop = true; //循环播放// 音频头 ->链接到 ->音量控制节点// 音量控制节点 ->链接到 -> 音频尾source.connect(gainNode);gainNode.connect(ctx.destination);source.start(0); //立即播放}function addEventListenerlGainNode() {var max = window.innerHeight;document.addEventListener("mousemove", function(event) {var y = event.clientY; //取得纵坐标var volume = (y / max).toFixed(2);gainNode.gain.value = volume;});}
</script>
  1. 细化处理之 对音频进行滤波处理

在上面 audioContext 代码的基础上创建一个低频滤波器,并连接到头尾节点
滤波器,默认是含有默认滤波处理值得,所以一旦链接,再播放音频,能明显听出声音有所变化。

<script>var ctx = new (window.AudioContext || window.webkitAudioContext())();let source = ctx.createBufferSource();let gainNode = ctx.createGain();let biquadFilter = ctx.createBiquadFilter(); // 创建低频滤波器, 返回 BiquadFilterNode。async function playSound(audioBuffer) {var myArrayBuffer = getDefineBuffer();source.buffer = myArrayBuffer;source.loop = true;// 音频头 ->链接到 ->音量控制节点// 音量控制节点 ->链接到 ->滤波器// 滤波器 ->链接到 ->音频尾source.connect(gainNode);gainNode.connect(biquadFilter);biquadFilter.connect(ctx.destination);source.start(0);}
</script>
  1. 细化处理之 对音频进行失真

在上面代码的基础上创建一个双二阶滤波器,并连接到头尾节点.
添加一个点击按钮,点击则让音频失真, makeDistortionCurve()
细心得同学发现了,使用 connect()得时候,只需要向首尾得中间添加各种控制节点,就可以对音频进行处理并返回

<button onclick="controlDistortion()">失真</button>
<script>var ctx = new (window.AudioContext || window.webkitAudioContext())();let source = ctx.createBufferSource();let gainNode = ctx.createGain();let biquadFilter = ctx.createBiquadFilter();let distortion = ctx.createWaveShaper(); // 创建双二阶滤波器,返回 WaveShaperNode.常用于添加失真效果async function playSound(audioBuffer) {var myArrayBuffer = getDefineBuffer();source.buffer = myArrayBuffer;source.loop = true;// 音频头 ->链接到 ->滤波器// 滤波器 ->链接到 ->失真器// 失真器 ->链接到 ->音频尾source.connect(gainNode);gainNode.connect(biquadFilter);biquadFilter.connect(distortion);distortion.connect(ctx.destination);source.start(0); //立即播放}let controlDistortion = function(value) {distortion.curve = makeDistortionCurve(400);};// 失真function makeDistortionCurve(amount) {var k = typeof amount === "number" ? amount : 50,n_samples = 44100,curve = new Float32Array(n_samples),deg = Math.PI / 180,i = 0,x;for (; i < n_samples; ++i) {x = (i * 2) / n_samples - 1;curve[i] = ((3 + k) * x * 20 * deg) / (Math.PI + k * Math.abs(x));}return curve;}
</script>
  1. 细化处理之 对音频进行混音,也就是常见得大厅效果,厕所,客厅等场景效果

混音比较特殊,能够创造距离,空间感

<button onclick="controlConvolver()">混音</button>
<script>var ctx = new (window.AudioContext || window.webkitAudioContext())();let source = ctx.createBufferSource();let gainNode = ctx.createGain();let biquadFilter = ctx.createBiquadFilter();let distortion = ctx.createWaveShaper();var convolver = ctx.createConvolver(); // 创建一个ConvolverNode,通常用来应用混响效果// 添加混响let controlConvolver = function (value) {biquadFilter.disconnect(0);biquadFilter.connect(convolver)}async function playSound(audioBuffer) {var myArrayBuffer = getDefineBuffer(); // 数据源使用刚生成的白噪音source.buffer = myArrayBuffer;// 混音节点必须要设置音频数据!!!convolver.buffer = myArrayBuffer;source.loop = true; //循环播放// 节点顺序改变source.connect(distortion);distortion.connect(biquadFilter);biquadFilter.connect(gainNode);// 节点顺序会音响混音效果convolver.connect(gainNode);gainNode.connect(ctx.destination);source.start(0); //立即播放}
</script>

扩展

音响分类为:1.0,2.0,2.1, 5.1, 7.1,其实就是混音得区别。所以只有电影院才能真正感受到环绕音,电影院设置5个以上喇叭环绕在观众周围是标准配置,家里没有那么多喇叭。

  • 1.0 单声道 :单声道
  • 2.0 双声道 :left, right。 左前,右前 各一个喇叭
  • 2.1 立体音 : left, right。 在 2.0 得基础上加了一个低音喇叭
  • 5.1 环绕音 : left, right,left around, right around,left behind,right behind 。 在 2.1 得基础上细分了一下,左前,右前,左侧,右侧 ,低音喇叭 共 5 喇叭放声音
  • 7.1 环绕音 : left, right,left around, right around,left behind,right behind .再 5.1 得基础上细分了一下,左前,右前,左侧,右侧,左后,右后 ,低音喇叭 共 7 喇叭放声音

参考资料

MDN AudioBuffer
失真
voice-change-o-matic
voice-change-o-matic srouce

------ 如果文章对你有用,感谢右上角 >>>点赞 | 收藏 <<<

audioContext audio 音频播放相关推荐

  1. html5 audio音频播放全解析

    html5开启了一个新时代,因为它让浏览器本身变得不那么被动,audio api就是一个典型的列子,在html5还没确定之前,如果想要在网页上听音乐看视频唯一的办法就是用flash 意思是当你没有给浏 ...

  2. audio音频播放标签样式优化自定义

    自定义audio音频播放样式实现进度监听,这是效果图 v-audio.vue <template><!-- audio音频组件 src:音频路径 longTime:音频时长, sou ...

  3. H5学习之路之audio音频播放

    为什么突然写这个呢?很简单,H5学习本身应该是一个系统的学习过程,虽然很多的东西都是会的,但是没有总结过,也不知道自己究竟对H5了解多少,爱有多深,所以在这里装作自己好像对H5很了解的样子,写一个记录 ...

  4. html5 audio音频播放器

    html5开启了一个新时代,因为它让浏览器本身变得不那么被动,audio api就是一个典型的列子,在html5还没确定之前,如果想要在网页上听音乐看视频唯一的办法就是用flash 意思是当你没有给浏 ...

  5. html audio播放本地语音文件,HTML5+ - audio音频播放及网络音频文件播放

    1.介绍常用方法 createPlayer()创建音频对象 play: 开始播放音频 pause: 暂停播放音频 resume: 恢复播放音频 stop: 停止播放音频 seekTo: 跳到指定位置播 ...

  6. Html5添加audio音频播放器插件教程

    2019独角兽企业重金招聘Python工程师标准>>> 一.方法: 使用Material design风格音频播放器插件需要引入jQuery和jaudio.min.js. <s ...

  7. html5 仿微信语音播放器,Material design风格HTML5 audio音频播放器

    jAudio.js是一款基于HTML5 audio的Material design风格音频播放器jQuery插件.该音频播放器可以设置音频播放列表,每首曲子的封面,标题等,还可以控制歌曲的播放和快进, ...

  8. html 语音播放插件,Html5添加audio音频播放器插件教程

    一.方法: 使用Material design风格音频播放器插件需要引入jQuery和jaudio.min.js. 二.HTML结构 00:00 00:00 三.CSS样式 下面是该音频播放器的主要C ...

  9. 上传声音 微信小程序_微信小程序之----audio音频播放

    audio audio为音频组件,我们可以轻松的在小程序中播放音频. audio组件属性如下: 属性名类型默认值说明 id String video 组件的唯一标识符, src String 要播放音 ...

最新文章

  1. 从产品经理到创业者如何拿到第一个1000万融资
  2. axure中怎么做出固定首行_办公软件操作技巧078:如何在excel表格中冻结行与列...
  3. redis基础之订阅发布、主从复制和事务(四)
  4. Cool!15个创意的 CSS3 文本效果【下篇】
  5. ubuntu 18.10无法locate boot-repair
  6. 还原virtual函数的本质-----C++
  7. 前端学习(2080):计算属性和methods得对比
  8. java语言factory_一个简单例子解释 Java factory
  9. 虚拟机linux和主机网络连接,linux虚拟机中和主机三种网络连接方式的区别
  10. Windows环境下Docker常用命令
  11. python 中self
  12. 热更新_UnityXlua热更新
  13. android 自动发彩信,Android编程实现定时发短信功能示例
  14. 函数间的调用_三个数求最大值
  15. HTML 6种空格nbsp;ensp;emsp;thinsp;zwnj;zwj;空白空格的区别
  16. 对象转二进制--》二进制转对象
  17. Ubuntu 16.04 LTS 安装libvips出现”Package vips was not found in the pkg-config search path”
  18. ue4 怎么修改骨骼动画_【2017 GDC挖坟】守望先锋动画制作管线(下篇)
  19. 对接第三方《大华摄像头》
  20. 微信公众号获取事件监听

热门文章

  1. 中创公益|中创算力荣获“2022年度突出贡献爱心企业”
  2. ASN.Net 发布后访问报:<customErrors> 标记的“mode”属性设置为“Off”的错误问题的解决方案
  3. CF题目:1238C. Standard Free2play(思维,数论)
  4. 【java小练习】#for循环运用#打印*三角阵列
  5. 360正式回归A股市场;马化腾成全球华人首富;链家遭购房者起诉丨价值早报
  6. 不会吧不会吧?真的有人认为程序员很轻松么!如何对抗编码焦虑?
  7. Cocos精品《我叫MT3》强势来袭 引爆魔幻团队大战
  8. Proteus8仿真:51单片机LCD1602显示
  9. php 微信支付企业付款
  10. 全自动照片增强器:Photolemur 3 Mac中文版