【问题标题】:How to play a sound continuously without break?如何不间断地连续播放声音?
【发布时间】:2017-08-15 14:01:00
【问题描述】:

我正在尝试在基于浏览器的游戏中播放车辆驱动的声音(连续不间断)。
我的 .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>

【问题讨论】:

  • 您在控制台看到的错误是什么
  • 控制台没有错误。我的问题是下一次迭代之前的声音中断。

标签: javascript html audio html5-audio audio-streaming


【解决方案1】:

Bee Cool,只需几行代码

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

function playSound()
{
var myAudio = new Audio('http://ithmbwp.com/feedback/SoundsTest/sounds/tank_driven.wav'); 

myAudio.volume = 0.3 ;

var tank_driven_sound = setInterval(function()
{
	myAudio.currentTime = 0;
	myAudio.play();
}, 800);

}
&lt;h3 style="font-family:verdana;"&gt;Please listen, it's continuous.&lt;/h3&gt;

【讨论】:

  • 只是为了好玩,在播放声音的同时尝试滚动页面... setInterval 不可靠。
【解决方案2】:

使用 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>

或者用你的 sn-p :

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();
}
&lt;h3 id="out"&gt;&lt;/h3&gt;

【讨论】:

  • @Rashid,您是否允许我将您的音频文件复制到我的 Dropbox 帐户中以便在编辑时使用它?
  • @Rashid,所以在没有您回复的情况下,我冒昧地这样做了,因为您在问题中链接到它,但如果您介意,请随时告诉我删除它。跨度>
  • 非常感谢@Kaiido。没关系
猜你喜欢
  • 1970-01-01
  • 2023-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 2013-04-04
  • 2018-10-15
  • 1970-01-01
相关资源
最近更新 更多