杨子荣归隐山林 發表於 2025-11-13 09:11:00

Web前端入门第 90 问:JavaScript 也能无中生有的创建音频

<p>网页播放音乐这个常识应该都知道,毕竟百度 MP3 搜索可是风靡一时!</p>
<p>但使用浏览器无中生有的创建音频,在 HTML5 规范落地之前可是一片空白。</p>
<p><code>AudioContext</code> 的体量与 <code>Canvas</code> 差不了多少,一个针对图形图像,一个用于音频,两者结合起来就把 <code>flash</code> 给拉下了神坛~~</p>
<hr>
<p>本文源之于一次技术研究,曾经有一个需求要用 H5 搞一个网页 K 歌,技术难点在于要将原唱、伴唱、录音的音频数据进行合并,后来寻寻觅觅的找到了 <code>AudioContext</code> 这个 API,虽然最终没用 H5 去实现,不过还是涨了见识!!</p>
<p>不废话,直接看代码:</p>
<pre><code class="language-html">&lt;button id="button"&gt;经过我&lt;/button&gt;

&lt;script&gt;
window.AudioContext = window.AudioContext || window.webkitAudioContext;
(function () {
    if (!window.AudioContext) {
      alert('当前浏览器不支持Web Audio API');
      return;
    }

    // 按钮元素
    var eleButton = document.getElementById('button');

    // 创建新的音频上下文接口
    var audioCtx = new AudioContext();

    // 发出的声音频率数据,表现为音调的高低
    var arrFrequency = ;

    // 音调依次递增或者递减处理需要的参数
    var start = 0, direction = 1;

    // 鼠标hover我们的按钮的时候
    eleButton.addEventListener('mouseenter', function () {
      // 当前频率
      var frequency = arrFrequency;
      // 如果到头,改变音调的变化规则(增减切换)
      if (!frequency) {
      direction = -1 * direction;
      start = start + 2 * direction;
      frequency = arrFrequency;
      }
      // 改变索引,下一次hover时候使用
      start = start + direction;

      // 创建一个OscillatorNode, 它表示一个周期性波形(振荡),基本上来说创造了一个音调
      var oscillator = audioCtx.createOscillator();
      // 创建一个GainNode,它可以控制音频的总音量
      var gainNode = audioCtx.createGain();
      // 把音量,音调和终节点进行关联
      oscillator.connect(gainNode);
      // audioCtx.destination返回AudioDestinationNode对象,表示当前audio context中所有节点的最终节点,一般表示音频渲染设备
      gainNode.connect(audioCtx.destination);
      // 指定音调的类型,其他还有square|triangle|sawtooth
      oscillator.type = 'sine';
      // 设置当前播放声音的频率,也就是最终播放声音的调调
      oscillator.frequency.value = frequency;
      // 当前时间设置音量为0
      gainNode.gain.setValueAtTime(0, audioCtx.currentTime);
      // 0.01秒后音量为1
      gainNode.gain.linearRampToValueAtTime(1, audioCtx.currentTime + 0.01);
      // 音调从当前时间开始播放
      oscillator.start(audioCtx.currentTime);
      // 1秒内声音慢慢降低,是个不错的停止声音的方法
      gainNode.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 1);
      // 1秒后完全停止声音
      oscillator.stop(audioCtx.currentTime + 1);
    });
})();
&lt;/script&gt;
</code></pre>
<p>以上代码内容来源于大佬<strong>张鑫旭</strong>的博客:https://www.zhangxinxu.com/wordpress/2017/06/html5-web-audio-api-js-ux-voice/</p>
<p>注意:<code>AudioContext</code> 必须要在在用户有交互之后才能创建!!意思就是用户在网页上有点击操作之后才能开始播放音频。</p>
<p>否则报错警告:</p>
<pre><code class="language-text">The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.
</code></pre>
<h3 id="效果预览">效果预览</h3>
<p>可长按以下二维码跳转到大佬的体验地址:</p>
<p>{% asset_img qrcode.jpg %}</p>
<p>二维码链接:https://www.zhangxinxu.com/study/201706/button-hover-web-audio.html</p>
<h3 id="其他示例">其他示例</h3>
<p>1、 <code>oscillator.type</code> 不同波形带来的声音效果:</p>
<p>https://codepen.io/gregh/pen/LxJEaj</p>
<p>2、又有大佬使用 <code>AudioContext</code> 搞出了小时候玩的游戏音乐:</p>
<p>https://codepen.io/gregh/pen/xqWwqz</p>
<h2 id="写在最后">写在最后</h2>
<p><code>AudioContext</code> 的 API 绝不止用来创建音频这么简单,往大了想一下,Canvas 可以把 PS 搬到浏览器,那些专业的音频处理软件是不是也可以搬到线上?</p>
<p>看看大佬对 <code>AudioContext</code> 的看法:</p>
<p><img src="https://img2024.cnblogs.com/blog/596097/202511/596097-20251113091125413-35303275.png"></p>
<blockquote>
<p>参考资料<br>
https://www.zhangxinxu.com/wordpress/2017/06/html5-web-audio-api-js-ux-voice/<br>
https://developer.mozilla.org/zh-CN/docs/Web/API/AudioContext</p>
</blockquote>


</div>
<div id="MySignature" role="contentinfo">
    <p>&nbsp;</p>
<p style="font-size: 18px;font-weight: bold;">文章首发于微信公众号【<span style="color:rgb(255, 71, 87)">前端路引</span>】,欢迎 <span style="color:#4ec259">微信扫一扫</span> 查看更多文章。</p>
<p>
<img style="max-width: 320px;" src="https://images.cnblogs.com/cnblogs_com/linx/2447020/o_250228035031_%E5%85%AC%E4%BC%97%E5%8F%B7%E4%BA%8C%E7%BB%B4%E7%A0%81.png"/>
</p>
<p>本文来自博客园,作者:前端路引,转载请注明原文链接:https://www.cnblogs.com/linx/p/19216408</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/linx/p/19216408
頁: [1]
查看完整版本: Web前端入门第 90 问:JavaScript 也能无中生有的创建音频