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

问题描述 投票:0回答:1

我正在html + js中构建一个命运之轮,它旋转得很快。每次有新颜色飞过该标记时,转轮都应发出喀哒声。以最快的速度听起来就像是机关枪,因此在旧文件基本完成之前就开始播放新文件。文件本身总是相同的:click.wav

[仅在Chrome中,它在Chrome中工作正常。 Firefox有一个怪异的错误,只有在其他音频源处于活动状态时才播放声音,例如在其他选项卡中播放的youtube视频。 Edge和Safari可以将点击安全地保留到最后,然后同时播放所有点击。一团糟...我使用method described here来克隆<audio>标签

我想这是问题所在:

var sound = new Audio("sounds/click.wav");
sound.preload = 'auto';
sound.load();

function playsound(){
    var click=sound.cloneNode();
    click.volume=1;
    click.play();
}

这是旋转函数的简化版本,每秒仅多次调用playsound()函数:

function rotateWheel(){
  angle = angle + acceleration
  while (angle >= 360) {
    angle = angle - 360
  } 
  var wheel = document.getElementById("wheel")
  wheel.style.transform = "rotate("+angle +"deg)"
  // play the click when a new segment rotates by
  if(Math.floor(angle/21) != previousSegment){
     playsound()
     previousSegment = Math.floor(angle/21)

}

javascript audio cross-browser web-audio-api
1个回答
1
投票

[您使用了answer from here,此方法有时会导致浏览器进程崩溃,因为您要么创建了内存问题,要么用浏览器必须处理的元素填充了DOM-因此,您应该重新考虑您的方法,并且您发现它无法在大多数浏览器(例如Safari或FireFox)中大量使用从标签规范的更深层次来看,很显然,有很多事情是无法完成的,这不足为奇,因为它是为媒体播放而设计的。限制之一包括->没有细粒度的声音计时。

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

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

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

/* 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);

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

© www.soinside.com 2019 - 2024. All rights reserved.