javascript - 如何不间断地连续播放声音?

标签 javascript html audio html5-audio audio-streaming

我正在尝试在基于浏览器的游戏中播放车辆驱动的声音(连续不间断)。
我的.wav文件长度是1秒,而且从头到尾的频率都一样。但在下一次迭代之前,声音会稍作休息。
这是代码:

function playSound()
{
    //alert("");
    myAudio = new Audio('http://ithmbwp.com/feedback/SoundsTest/sounds/tank_driven.wav'); 
    if (typeof myAudio.loop == 'boolean')
    {
        myAudio.loop = true;
    }
    else
    {
        myAudio.addEventListener('ended', function() {
            this.currentTime = 0;
            this.play();
        }, false);
    }
    myAudio.volume = 0.3;
    myAudio.play();
}

谁能帮我连续播放声音?

版本

您可以访问我的页面here观察问题。

window.onload = function() {
  playSound();
};

function playSound()
{
	//alert("");
	myAudio = new Audio('http://ithmbwp.com/feedback/SoundsTest/sounds/tank_driven.wav'); 
	if (typeof myAudio.loop == 'boolean')
	{
		myAudio.loop = true;
	}
	else
	{
		myAudio.addEventListener('ended', function() {
			this.currentTime = 0;
			this.play();
		}, false);
	}
	myAudio.volume = 0.3;
	myAudio.play();
}
<h3 style="font-family:verdana;">Please listen the sound break.</h3>
<h3 style="font-family:verdana;">It should be continuous.</h3>

最佳答案

使用 AudioContext API 及其 bufferSourceNode界面,以获得无缝循环的声音。

请注意,您还需要正确编辑音频以避免爆裂声和声音片段,但您的看起来不错。

const aCtx = new AudioContext();
let source = aCtx.createBufferSource();
let buf;
fetch('https://dl.dropboxusercontent.com/s/knpo4d2yooe2u4h/tank_driven.wav') // can be XHR as well
  .then(resp => resp.arrayBuffer())
  .then(buf => aCtx.decodeAudioData(buf)) // can be callback as well
  .then(decoded => {
    source.buffer = buf = decoded;
    source.loop = true;
    source.connect(aCtx.destination);
    check.disabled = false;
  });

check.onchange = e => {
  if (check.checked) {
    source.start(0); // start our bufferSource
  } else {
    source.stop(0); // this destroys the buffer source
    source = aCtx.createBufferSource(); // so we need to create a new one
    source.buffer = buf;
    source.loop = true;
    source.connect(aCtx.destination);
  }
};
<label>play audioBuffer</label>
<input type="checkbox" id="check" disabled><br><br>
Just to compare <audio src="https://dl.dropboxusercontent.com/s/knpo4d2yooe2u4h/tank_driven.wav" loop controls>

或使用您的代码段:

window.onload = function() {
  playSound();
};

function playSound() {
  if (AudioContext) {
    out.textContent = "yeah now it's continuous !!!";
    playAsAudioBuffer();
  } else {
    out.textContent = "you should consider updating your browser...";
    playNormally();
  }
}

function playAsAudioBuffer() {
  var aCtx = new AudioContext();
  // here is the real audioBuffer to sound part
  function ondecoded(buf) {
    var source = aCtx.createBufferSource();
    source.buffer = buf;
    source.loop = true;
    var gainNode = aCtx.createGain();
    gainNode.gain.value = .3; // here you set the volume
    source.connect(gainNode);
    gainNode.connect(aCtx.destination);
    source.start(0);
  }

  var xhr = new XMLHttpRequest();
  xhr.onload = function() {
    aCtx.decodeAudioData(this.response, ondecoded);
  };
  xhr.onerror = playNormally;
  xhr.responseType = 'arraybuffer';
  xhr.open('get', 'https://dl.dropboxusercontent.com/s/knpo4d2yooe2u4h/tank_driven.wav');
  xhr.send();
}

// An ugly workaround in case of old browsers
function playNormally() {
  var myAudios = [new Audio('https://dl.dropboxusercontent.com/s/knpo4d2yooe2u4h/tank_driven.wav')];
  myAudios.push(new Audio(myAudios[0].src));
  myAudios.forEach(function(a){
    a.addEventListener('timeupdate', checkTime);
    a.volume = 0.3;
    });
   
  function checkTime(){
    if(this.currentTime > this.duration - 0.4){
      startNext(this);
      }
    }
  var current = 0;
  function startNext(el){
    current = (current + 1) % 2;
    myAudios[current].play();
    el.currentTime = 0;
    el.pause();
    }
  myAudios[0].play();
}
<h3 id="out"></h3>

关于javascript - 如何不间断地连续播放声音?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42968873/

相关文章:

javascript - 如何将输出从一个任务切换到另一个任务

javascript - 变换 : translateY Not Working on Style Attribute in IE/Edge

html - IE10 中的绝对位置和 z 索引

javascript - 抓取通过 JavaScript 呈现的网页。 PhantomJs 或任何其他工具?

javascript - 如何将加载的音频设置为 HTML 音频标签 Controller ?

actionscript-3 - 我在哪里可以找到关于编写音频 DSP 滤波器(低通等)的好的教程?

iphone - "Cannot convert ' float ' to float**"错误

javascript - Jquery:- 计算每个 tr 中 td 的数量

javascript - 在javascript中通过路径将值插入数组

javascript - 隐藏、取消隐藏选项卡上的内容更改