使用内部的开关盒 for 循环播放音频太快



我试图通过循环播放数组并将数组拆分为每个数组来播放声音,然后使用开关大小写来检测数组中的内容。 函数守护者() {

number2 = get.num;
sNumber = number2.toString();
output = [];

for ( i = 0, len = sNumber.length; i < len; i ++) {
output.push(+sNumber.charAt(i));
console.log(output);
switch (output[i]){
case 0:
console.log('0');
audio0 = new Audio('logo/Q0.wav');
audio0.play();
break;
case 1:
console.log('1');
audio1 = new Audio('logo/Q1.wav');
audio1.play();
break;
case 2:
console.log('2');
audio2 = new Audio('logo/Q2.wav');
audio2.play();
break;
case 3:
console.log('3');
audio3 = new Audio('logo/Q3.wav');
audio3.play();
break;
case 4:
console.log('4');
audio4 = new Audio('logo/Q4.wav');
audio4.play();
break;
case 5:
console.log('5');
audio5 = new Audio('logo/Q5.wav');
audio5.play();
break;
}
}}

它的功能工作得很好,但显然播放的声音太快了。 有什么解决方案可以解决这个问题吗?

我假设你想听到彼此的声音?

这样行不通。 假设数组中的第一个数字是:0.
所以播放声音 0。
但是,由于您遍历数组,并且到达下一个数字,例如。2:声音 2 紧随其后播放。
循环不会等待第一个声音结束,然后再开始下一个播放()。

您可以做的是修改循环以等待音频结束事件。
例如:

var audio0 = document.getElementById("myAudio");
audio0.onended = function() {
alert("The audio has ended");
};

尝试使用音频精灵。我确定有一个应用程序或任何以编程方式执行某些任务的东西,但请注意步骤 1 和 2 是手动完成的。

  1. 获取一组音频文件,然后使用 Audacity 或在线服务将它们合并为一个文件。

  2. 接下来,获取音频文件每个剪辑的开始时间并将它们存储在数组中。

  3. 下面的演示将获取文件和数组,生成 HTML 布局,为每个剪辑创建一个与数组参数对应的按钮。因此,当单击按钮时,它将仅播放音频精灵(音频文件)的剪辑。

  4. 这个演示中的音频精灵没有编辑得很好,我只是为了演示一切是如何工作的。计时依赖于 timeupdate 事件,该事件大约每 250 毫秒检查一次播放时间。因此,如果您想制作更准确的开始和结束时间,请尝试在剪辑之间留出 250 毫秒的间隔。

演示中注释的详细信息

演示

// Store path to audio file in a variable
var xFile = 'https://storage04.dropshots.com/photos7000/photos/1381926/20180318/175955.mp4'
// Store cues of each start time of each clip in an array
var xMap = [0, 1.266, 2.664, 3.409, 4.259,4.682,  5.311, 7.169, 7.777, 9.575, 10.88,11.883,13.64, 15.883, 16.75, 17, 17.58];
/* Register doc to act when the DOM is ready but before the images
|| are fully loaded. When that occurs, call loadAudio()
*/
document.addEventListener('DOMContentLoaded', function(e) {
loadAudio(e, xFile, xMap);
});
/* Pass the Event Object, file, and array through
|| Make a Template Literal of the HTML layout and the hidden
|| <audio> tag. Interpolate the ${file} into the <audio> tag.
|| Insert the TL into the <body> and parse it into HTML.
== Call generateBtn() function...
*/
function loadAudio(e, file, map) {
var template = `
<fieldset class='set'>
<legend>Sound FX Test Panel</legend>
</fieldset>
<audio id='sndFX' hidden>
<source src='${file}' type='audio/wav'>
</audio>`;
document.body.insertAdjacentHTML('beforeend', template);
generateBtn(e, map);
}
/* Pass the Event Object and the array through
|| Reference fieldset.set
|| create a documentFragment in order to speedup appending
|| map() the array...
|| create a <button>
|| Set btn class to .btn
|| Set button.btn data-idx to the corresponding index value of
|| map array.
|| Set button.btn text to its index number.
|| Add button.btn to the documentFragment...
|| return an array of .btn (not used in this demo)
== Call the eventBinder() function...
*/
function generateBtn(e, map) {
var set = document.querySelector('.set');
var frag = document.createDocumentFragment();
map.map(function(mark, index, map) {
var btn = document.createElement('button');
btn.className = 'btn';
btn.dataset.idx = map[index];
btn.textContent = index;
frag.appendChild(btn);
return btn;
});
set.appendChild(frag);
eventBinder(e, set, map);
}
/* Pass EventObject, fieldset.set, and map array through
|| Reference the <audio> tag.
|| Register fieldset.set to the click event
|| if the clicked node (e.target) class is .btn...
|| Determine the start and end time of the audio clip.
== Call playClip() function
*/
function eventBinder(e, set, map) {
var sFX = document.getElementById('sndFX');
set.addEventListener('click', function(e) {
if (e.target.className === 'btn') {
var cue = parseFloat(e.target.textContent);
var start = parseFloat(e.target.dataset.idx);
if (cue !== (map.length - 1)) {
var end = parseFloat(e.target.nextElementSibling.dataset.idx);
} else {
var end = parseFloat(sFX.duration);
}
playClip.call(this, sFX, start, end);
} else {
return false;
}
});
}
/* Pass the reference to the <audio> tag, start and end of clip
|| pause audio
|| Set the currentTime to the start parameter
|| Listen for timeupdate event...
|| should currentTime meet or exceed the end parameter...
|| pause <audio> tag.
*/
function playClip(sFX, start, end) {
sFX.pause();
sFX.currentTime = start;
sFX.play();
sFX.ontimeupdate = function() {
if (sFX.currentTime >= end) {
sFX.pause();
}
}
return false;
}

尝试使用计时器:

for (var i = 1; i <= 3; i++) {
(function(index) {
setTimeout(function() { alert(index); }, i * 1000);
})(i);
}

像这样使用setTimeout函数

最新更新