如何使用JavaScript轻松生成Beep(通知)声音?

2021年11月29日18:34:20 发表评论 2,281 次浏览

了解如何在浏览器中使用 JavaScript 轻松生成提示音。

如何使用JavaScript轻松生成Beep(通知)声音?
JavaScript生成Beep声音的方法

我知道,我知道,网络应用程序上的声音?哎呀!。除非绝对必要,否则甚至不要考虑在严肃的商业应用程序上使用哔哔声或任何其他声音,大多数情况下,窗口中的简单通知元素(如小模态)就可以解决问题。

JavaScript如何生成Beep(通知)声音?如果你决定在没有任何特殊原因的情况下实现声音,大多数用户会谴责你的应用程序。它应该只发出任何声音来通知用户你的应用程序的消息、警告或错误,当然,这不应该是一个强制性的功能。用户应该在他不注意应用程序时知道后台发生了一些事情(当止损或止盈被触发时,它在日常交易类应用程序中非常有用),所以一定要实现很好的一种方法,可以随时为用户禁用应用程序中的声音。

如果你需要偶尔在你的应用程序中实现类似通知的声音而不会有太多麻烦,本文介绍在Web中实现的两种JavaScript生成Beep声音的方法。

A.使用浏览器的AudioContext

如何使用JavaScript生成Beep声音?借助浏览器的AudioContext类(通过 Web Audio API),模拟 Beep 声音的第一个选项是使用纯 JavaScript 生成音频。此接口表示由链接在一起的音频模块构建的音频处理图,每个模块由一个 AudioNode 表示。

根据 Mozilla 开发者网络,音频上下文控制其包含的节点的创建和音频处理或解码的执行。你需要在做任何其他事情之前创建一个 AudioContext,因为一切都发生在一个上下文中。建议创建一个 AudioContext 并重用它,而不是每次都初始化一个新的,并且可以同时为多个不同的音频源和管道使用单个 AudioContext。

在“beep”实现的情况下,以下函数将使你只需几行代码即可轻松生成此声音:

// The browser will limit the number of concurrent audio contexts
// So be sure to re-use them whenever you can
const myAudioContext = new AudioContext();

/**
 * Helper function to emit a beep sound in the browser using the Web Audio API.
 * 
 * @param {number} duration - The duration of the beep sound in milliseconds.
 * @param {number} frequency - The frequency of the beep sound.
 * @param {number} volume - The volume of the beep sound.
 * 
 * @returns {Promise} - A promise that resolves when the beep sound is finished.
 */
function beep(duration, frequency, volume){
    return new Promise((resolve, reject) => {
        // Set default duration if not provided
        duration = duration || 200;
        frequency = frequency || 440;
        volume = volume || 100;

        try{
            let oscillatorNode = myAudioContext.createOscillator();
            let gainNode = myAudioContext.createGain();
            oscillatorNode.connect(gainNode);

            // Set the oscillator frequency in hertz
            oscillatorNode.frequency.value = frequency;

            // Set the type of oscillator
            oscillatorNode.type= "square";
            gainNode.connect(myAudioContext.destination);

            // Set the gain to the volume
            gainNode.gain.value = volume * 0.01;

            // Start audio with the desired duration
            oscillatorNode.start(myAudioContext.currentTime);
            oscillatorNode.stop(myAudioContext.currentTime + duration * 0.001);

            // Resolve the promise when the sound is finished
            oscillatorNode.onended = () => {
                resolve();
            };
        }catch(error){
            reject(error);
        }
    });
}

你可以像这样使用它,第一个参数提供声音的持续时间(以毫秒为单位),第二个参数提供振荡器的频率以模拟音符,最后提供声音的音量:

// Simple beep
beep(
    // Set the duration to 0.2 second (200 milliseconds)
    200,
    // Set the frequency of the note to A4 (440 Hz)
    440,
    // Set the volume of the beep to 100%
    100
);

JavaScript生成Beep声音的方法:你可以生成低音或高音,将函数的频率调整为你想要的音符(你可以使用以下音频频率图表):

如何使用JavaScript轻松生成Beep(通知)声音?

你也可以创建可链接的“哔哔声”,因为实现使用 JavaScript Promises:

function delay(duration) {
    return new Promise((resolve) => {
        setTimeout(() => resolve(), duration);
    });
}

// Emit a set of beeps
// to simulate a Ready, Set, Go! 
// It goes like: 
// (low pitch) Beep 
// (1 second silence) 
// (low pitch) Beep
// (1 second silence)
// (low pitch) Beep
// (1 second silence)
// (higher pitch) Beep!!!

Promise.resolve()
  .then(() => beep())
  .then(() => delay(1000))
  .then(() => beep())
  .then(() => delay(1000))
  .then(() => beep())
  .then(() => delay(1000))
  .then(() => beep(200, 870));

关于 JavaScript 的 AudioContext 中的频率和音高的详细解释,我建议你阅读来自 Teropa 的这篇文章。你也可以更改音频节点的波形类型:

  • 正弦
  • 正方形
  • 锯齿
  • 三角形

你可以阅读有关波形的另一个很酷的教程是 Josh W. Comeau 的 Waveforms 文章

你可以在以下 Fiddle 中测试此哔声:

B. 播放自定义音频文件

JavaScript如何生成Beep(通知)声音?你拥有的另一种选择,以防你的“哔”声需要更复杂,例如“房间里的汤米·威索(Tommy Wiseau)的“你只是一只鸡”:

你也可以这样做,随意在你的软件中做任何你想做的事!但严重的是,根据你的应用程序的需要,你可以使用 Web Audio API 创建的哔声可能不是最好的。

JavaScript生成Beep声音的方法:如果你已经有一个带有通知声音的 MP3 或 WAV 音频文件,你可以使用纯 JavaScript 将其作为提示音播放。以下函数使用你自己的自定义音频文件表示上述逻辑:

/**
 * Helper function to emit a beep sound in the browser using an Audio File.
 * 
 * @param {number} volume - The volume of the beep sound.
 * 
 * @returns {Promise} - A promise that resolves when the beep sound is finished.
 */
function beep(volume){
    return new Promise((resolve, reject) => {
        volume = volume || 100;

        try{
            // You're in charge of providing a valid AudioFile that can be reached by your web app
            let soundSource = "https://www.w3schools.com/html/horse.mp3";
            let sound = new Audio(soundSource);

            // Set volume
            sound.volume = volume / 100;

            sound.onended = () => {
                resolve();
            };

            sound.play();
        }catch(error){
            reject(error);
        }
    });
}

如何使用JavaScript生成Beep声音?这个实现允许你创建一个链,就像使用 Web Audio API 的 beep 实现一样:

function delay(duration) {
    return new Promise((resolve) => {
        setTimeout(() => resolve(), duration);
    });
}

// Emit 3 horse neighs subsequently!
Promise.resolve()
  .then(() => beep())
  .then(() => delay(1000))
  .then(() => beep())
  .then(() => delay(1000))
  .then(() => beep())
  .then(() => delay(1000))
  .then(() => beep());

你可以在以下小提琴中测试此自定义哔声:

快乐编码❤️!

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: