且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在javascript中快速播放声音文件的多个副本

更新时间:2022-06-14 22:59:08

您使用了

You used an answer from here this methods cause at some point to crash the browser process because you either create a memory issue or you fill up the DOM with elements the browser has to handle - so you should re-think your approach AND as you found out it will not work for heavy use in most browsers like safari or FireFox
Looking deeper into the <audio> tag specification, it becomes clear that there are many things that simply can't be done with it, which isn't surprising, since it was designed for media playback. One of the limitations includes -> No fine-grained timing of sound.

因此,您必须找到所需的另一种方法,我们使用为在线视频游戏设计的Web Audio API.
网络音频API
AudioContext用于管理和播放所有声音.要使用Web Audio API产生声音,请创建一个或多个声音源,并将它们连接到AudioContext实例(通常是扬声器)提供的声音目标. AudioBuffer
使用Web Audio API,只有将音频文件加载到缓冲区后才能播放音频文件.加载声音需要花费时间,因此在动画/游戏中使用的资产应在页面加载时,游戏或关卡开始时加载,或者在玩家玩游戏时逐步加载.
基本步骤

So you have to find another method for what you want we use Web Audio API designed for online video games.
Web Audio API
An AudioContext is for managing and playing all sounds. To produce a sound using the Web Audio API, create one or more sound sources and connect them to the sound destination provided by the AudioContext instance (usually the speaker). The AudioBuffer
With the Web Audio API, audio files can be played only after they’ve been loaded into a buffer. Loading sounds takes time, so assets that are used in the animation/game should be loaded on page load, at the start of the game or level, or incrementally while the player is playing.
The basic steps

  • 我们使用XMLHttpRequest将数据从音频文件加载到缓冲区中.
  • 接下来,我们进行异步回调并发送实际请求以进行加载.
  • 一旦声音被缓冲和解码,就可以立即触发.
  • 每次触发时,都会创建一个不同的缓冲声音实例.

游戏中音效的关键特征是可以同时存在许多音效. 因此,以机枪"为例:假设您正处于射击机枪的交战中. 机关枪每秒发射多次,导致同时播放数十种声音效果.这是Web Audio API真正发挥作用的地方. 您的应用程序的简单示例:

A key feature of sound effects in games is that there can be many of them simultaneously. So to take your example of the "machine gun": Imagine you're in the middle of a gunfight a shooting machine gun. The machine gun fires many times per second, causing tens of sound effects to be played at the same time. This is where Web Audio API really shines. A simple example for your application:

/* global AudioContext:true,
*/

var clickingBuffer = null;
// Fix up prefixing
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();

function loadClickSound(url) {
    var request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.responseType = 'arraybuffer';
    // Decode asynchronously
    request.onload = function() {
        context.decodeAudioData(request.response, function(buffer) {
            if (!buffer) {
                console.log('Error decoding file data: ' + url);
                return;
            }
        clickingBuffer = buffer;
        });
    request.onerror = function() {
        console.log('BufferLoader: XHR error');        
        };
    request.send();
    };
}

function playSound(buffer, time, volume) {              
  var source = context.createBufferSource();   // creates a sound source
  source.buffer = buffer;                     // tell the source which sound to play
  source.connect(context.destination);          // connect the source to the context's destination (the speakers)
  var gainNode = context.createGain();          // Create a gain node
  source.connect(gainNode);                     // Connect the source to the gain node
  gainNode.connect(context.destination);        // Connect the gain node to the destination
  gainNode.gain.value = volume;                  // Set the volume
  source.start(time);                           // play the source at the deisred time 0=now    
}

// You call with in your document ready
   loadClickSound('sounds/click.wav');
//and this plays the sound
   playSound(clickingBuffer, 0, 1);

现在,您可以通过引入随机因素来应对不同的时机和音量变化 如果您需要一个更复杂的解决方案,该解决方案具有不同的点击声音(存储在缓冲区阵列中)和音量/距离变化,那么这将是一段较长的代码.

Now you can play around with different timings and volume variations for example by intoducing a random factor If you need a more complex solution with different clicking sounds (stored in a buffer array) and volume/ distance variations this would be a longer piece of code.