简体   繁体   English

在HTML5中,我可以同时多次播放同一个声音吗?

[英]In HTML5, can I play the same sound more than once at the same time?

I'm making a game, in which sounds are often played.我正在制作一个游戏,其中经常播放声音。 I noticed that a sound wont play again while it is being played.我注意到声音在播放时不会再次播放。 For example, the player collides with a wall, a "thump" sound is played.例如,玩家与墙壁发生碰撞,播放“砰”的一声。 But, if the player collides with one wall, and then quickly collides with another wall, only one "thump" sound is played, and I believe that this happens because the first sound didn't finish.但是,如果玩家撞到一堵墙,然后又迅速撞到另一堵墙,只会播放“砰”的一声,我相信这是因为第一个声音没有结束。 Is that true?真的吗? How should I avoid this?我应该如何避免这种情况? I thought of preloading the sound three times, always playing a different copy of that sound, but this seems rather stupid...我想将声音预加载三次,总是播放那个声音的不同副本,但这似乎很愚蠢......

SOLVED:解决了:

Turns out I was right... You need to preload multiple versions of the sound and then circularly play them.事实证明我是对的......你需要预加载多个版本的声音然后循环播放它们。

THE CODE:代码:

var ns = 3; //The number of sounds to preload. This depends on how often the sounds need to be played, but if too big it will probably cause lond loading times.
var sounds = []; //This will be a matrix of all the sounds

for (i = 0; i < ns; i ++) //We need to have ns different copies of each sound, hence:
    sounds.push([]);

for (i = 0; i < soundSources.length; i ++)
    for (j = 0; j < ns; j ++)
        sounds[j].push(new Audio(sources[i])); //Assuming that you hold your sound sauces in a "sources" array, for example ["bla.wav", "smile.dog" "scream.wav"] 

var playing = []; //This will be our play index, so we know which version has been played the last.

for (i = 0; i < soundSources.length; i ++)
    playing[i] = 0; 

playSound = function(id, vol) //id in the sounds[i] array., vol is a real number in the [0, 1] interval
{
    if (vol <= 1 && vol >= 0)
        sounds[playing[id]][id].volume = vol;
    else
        sounds[playing[id]][id].volume = 1;

    sounds[playing[id]][id].play();
    ++ playing[id]; //Each time a sound is played, increment this so the next time that sound needs to be played, we play a different version of it,

    if (playing[id] >= ns)
        playing[id] = 0;
}

You can clone the audio element. 您可以克隆音频元素。 I don't know if you can play them more than once simultaneously, but here is how you can play a sound more than once without downloading it more than once. 我不知道您是否可以同时播放多个声音,但是这是您可以多次播放声音而不下载一次的方法。

var sound = document.getElementById("incomingMessageSound")
var sound2 = sound.cloneNode()
sound.play()
sound2.play()

I know this works for chrome, which is the only place I needed it. 我知道这适用于chrome,这是我唯一需要的地方。 Good luck! 祝好运!

Load the sound several times to simulate polyphony. 多次加载声音以模拟复音。 Play them in round-robin fashion. 以循环方式播放它们。 Check out my demo at matthewtoledo.com . matthewtoledo.com上查看我的演示。 Specifically, the function _initSoundBank() 具体来说,函数_initSoundBank()

Yes, a single <audio> object can only play one track at a time. 是的,单个<audio>对象一次只能播放一个曲目。 Consider that the <audio> object has a currentTime attribute that indicates the current position of the audio track: if an <audio> object could play multiple tracks are once, what value would currentTime reflect? 请考虑<audio>对象具有currentTime属性,该属性指示音频轨道的当前位置:如果<audio>对象可以播放多个轨道一次,那么currentTime将反映什么值?

See my solution for a superset of this problem on Is playing sound in Javascript performance heavy? 请参阅我的解决方案,以获取有关此问题的超集,有关Java演奏中的声音播放是否繁重? . (Basically, add duplicate <audio> tags with the same sound.) (基本上,添加具有相同声音的重复<audio>标签。)

Although it is only implemented in FireFox and Chrome right now, in the future you should use the WebAudio API , which is specifically designed for games and audio applications in the browser. 尽管目前仅在FireFox和Chrome中实现,但将来您应该使用WebAudio API ,该API专为浏览器中的游戏和音频应用程序而设计。

There you can play back any sound multiple times and do several other fun stuff with it. 您可以在那里多次播放任何声音,并用它来做其他有趣的事情。

A good tutorial for that is here: http://www.html5rocks.com/en/tutorials/webaudio/games/ 一个很好的教程在这里: http : //www.html5rocks.com/en/tutorials/webaudio/games/

class SoundPool {
  pool : HTMLAudioElement[] = [];
  constructor(sound:HTMLAudioElement) {
    this.pool.push(sound);
  }

  play() {
    let found = false;
    for(var i=0; i<this.pool.length; i++) {
      if( this.pool[i].paused) {
        this.pool[i].play();
        found=true;
        break;
      }
    }
    if(!found) {
      let a = this.pool[0].cloneNode() as HTMLAudioElement;
      a.play();
      this.pool.push(a);
    }

  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM