我正在尝试播放同时显示定时文本的音频文件。当按下“播放”按钮时,将选择一个随机音频文件,并加载其字幕和定时。然后使用setTimeouts循环在正确的时间用适当的文本替换现有文本。
这似乎工作正常,但问题是我需要能够中断音频并停止字幕,并且在按“播放”时可以再次工作。
这是我的代码的最低“有效”版本:
var playing = false;
var timeout;
var allSubs = [
"A1 | A2 | A3",
"B1 | B2 | B3 | B4",
"C1 | C2 | C3 | C4 | C5",
]
var allTimings = [
"0 | 2 | 4",
"0 | 1 | 2 | 3",
"0 | 0.5 | 1 | 1.5 | 2",
]
function playAudio() {
playing = true;
$('#media-control').text('Stop');
index = Math.floor(Math.random() * Math.floor(3));
var subtitleStr = allSubs[index];
var timingStr = allTimings[index];
subtitleArr = subtitleStr.split(' | ');
timingArr = timingStr.split(' | ').map(Number);
for (i = 0; i < subtitleArr.length; i++) {
timeout = setTimeout((function(i) {
return function() {
$('#subtitle-text').text(subtitleArr[i]);
}
})(i), timingArr[i] * 1000);
}
}
function stopAudio() {
playing = false;
clearTimeout(timeout);
$('#media-control').text('Play');
$('#subtitle-text').text('');
}
function toggleMedia(e) {
if (!playing) {
playAudio();
} else {
stopAudio();
}
}
$('#media-control').bind('click', toggleMedia);
https://jsfiddle.net/eshapiro42/bjme90yt/12/
如果您快速连续按“播放” /“停止”足够多次,最终字幕将停止以正确的顺序和正确的时间出现。
有人可以建议一种更好的方式来创建定时文本,还是一种可以中断setTimeout循环的方式,这种方式实际上可以确定地起作用?
答案 0 :(得分:2)
在我看来,您的问题出在playAudio函数中。您要一次遍历所有字幕,并为每个字幕设置超时。设置下一个超时ID时,您将覆盖该超时ID。因此,当您按下暂停键时,唯一真正被取消的超时是最后一个。
您需要做的是存储这些超时ID的数组。设置新的超时时,推送到阵列。当您按下暂停键时,请清除该阵列中的所有超时。
var allTimeouts = [];
...
allTimeouts.push(timeout); // On setting the timeouts
...
for(int i = 0; i < allTimeouts.length; i++){ // On clearing the timeouts
clearTimeout(allTimesouts[i]);
}