HTML5 音频标签 onplaying 甚至在 android 中的音频播放之前触发
HTML5 audio tag onplaying even is triggered before audio play in android
我写了一段根据音频高亮文本的代码。在这个逻辑中,当音频开始播放时,我们会触发一个高亮功能。在给定的时间内突出显示每个单词。
它在 window PC 和台式机上运行良好。但是在 android 中,突出显示功能在音频开始之前触发,这就是音频和突出显示不同步的原因。
下面是代码。
function highlight(start,totalWords,aid) {
var wtime = data[start]/defaultPlayback;
$("#W"+start).css("color",'yellow');
setTimeout(function (){
$("#W"+start).css("color",'');
start++;
if (start <= totalWords) {highlight(start,totalWords,aid);}
else{return false;}
}, wtime);
}
<audio preload='auto' controls id='a2' onplaying="highlight(10,18,'bookread4');" onended="completed('a3')" >
<source src="http://arbordalepublishing.com/eBooks2/Animalogy/Animalogy p7.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
<span id="W10" class="calibre2">Chick </span>
<span id="W11" class="calibre2">is </span>
<span id="W12" class="calibre2">to </span>
<span id="W13" class="calibre2">feathery,</span>
<span id="W14" class="calibre2">as </span>
<span id="W15" class="calibre2">bear </span>
<span id="W16" class="calibre2">is </span>
<span id="W17" class="calibre2">to </span>
<span id="W18" class="calibre2">furry.</span>
不要使用无法保证同步的 timer/counter 驱动文本,而应使用音频元素的 currentTime
属性。这将强制正确的时间独立于开始。
属性 returns 当前绝对时间(以小数秒为单位)。利用这段时间检查要突出显示的单词的时间范围。
例如(这里只是任意次数,因为原始数据不可用):
var words = [
{
id: "W10", // or use reference to element
start: 0, // time in seconds
end: 0.2,
highlighted: false // to reduce DOM updates
},
{
id: "W11",
start: 0.22,
end: 0.4,
highlighted: false
},
... etc. ...
];
然后在高亮中:
function highlight() {
var time = a2.currentTime,
i = 0, word;
for(; word = words[i++];) {
if (time >= word.start && time <= word.end)
if (!word.highlighted) {
word.highlighted = true; // to reduce the need to update DOM
// ... set CSS for highlighted here...
}
}
else if (word.highlighted) {
// ... set CSS for not highlighted here...
word.highlighted = false;
}
}
}
现场演示
尝试在播放过程中暂停,您会发现继续播放时文本仍然能够同步。
// NOTE: these are not 100% synchronized - they are just for example
var words = [
{id: "W10", start: 0, end: 0.7, highlighted: false},
{id: "W11", start: 0.76, end: 1.1, highlighted: false},
{id: "W12", start: 1.2, end: 1.3, highlighted: false},
{id: "W13", start: 1.4, end: 2.1, highlighted: false},
{id: "W14", start: 2.1, end: 2.3, highlighted: false},
{id: "W15", start: 2.3, end: 2.7, highlighted: false},
{id: "W16", start: 2.7, end: 3.0, highlighted: false},
{id: "W17", start: 3.0, end: 3.2, highlighted: false},
{id: "W18", start: 3.2, end: 3.4, highlighted: false}],
audio = document.getElementById("a2");
audio.onplaying = highlight;
function highlight() {
var time = a2.currentTime, i = 0, word;
for(; word = words[i++];) {
if (time >= word.start && time < word.end) {
if (!word.highlighted) {
word.highlighted = true; // to reduce the need to update DOM
document.getElementById(word.id).style.color = "orange";
}
}
else if (word.highlighted) {
document.getElementById(word.id).style.color = "black";
word.highlighted = false;
}
}
// you should listen to end event and stop the loop using that, here, for simplicity:
if (!audio.paused) setTimeout(highlight, 17);
//else alert("done");
}
body {font: bold 16px sans-serif}
<audio preload='auto' controls id='a2'>
<source src="http://arbordalepublishing.com/eBooks2/Animalogy/Animalogy p7.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
<br>
<span id="W10">Chick </span>
<span id="W11">is </span>
<span id="W12">to </span>
<span id="W13">feathery,</span>
<span id="W14">as </span>
<span id="W15">bear </span>
<span id="W16">is </span>
<span id="W17">to </span>
<span id="W18">furry.</span>
我写了一段根据音频高亮文本的代码。在这个逻辑中,当音频开始播放时,我们会触发一个高亮功能。在给定的时间内突出显示每个单词。
它在 window PC 和台式机上运行良好。但是在 android 中,突出显示功能在音频开始之前触发,这就是音频和突出显示不同步的原因。
下面是代码。
function highlight(start,totalWords,aid) {
var wtime = data[start]/defaultPlayback;
$("#W"+start).css("color",'yellow');
setTimeout(function (){
$("#W"+start).css("color",'');
start++;
if (start <= totalWords) {highlight(start,totalWords,aid);}
else{return false;}
}, wtime);
}
<audio preload='auto' controls id='a2' onplaying="highlight(10,18,'bookread4');" onended="completed('a3')" >
<source src="http://arbordalepublishing.com/eBooks2/Animalogy/Animalogy p7.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
<span id="W10" class="calibre2">Chick </span>
<span id="W11" class="calibre2">is </span>
<span id="W12" class="calibre2">to </span>
<span id="W13" class="calibre2">feathery,</span>
<span id="W14" class="calibre2">as </span>
<span id="W15" class="calibre2">bear </span>
<span id="W16" class="calibre2">is </span>
<span id="W17" class="calibre2">to </span>
<span id="W18" class="calibre2">furry.</span>
不要使用无法保证同步的 timer/counter 驱动文本,而应使用音频元素的 currentTime
属性。这将强制正确的时间独立于开始。
属性 returns 当前绝对时间(以小数秒为单位)。利用这段时间检查要突出显示的单词的时间范围。
例如(这里只是任意次数,因为原始数据不可用):
var words = [
{
id: "W10", // or use reference to element
start: 0, // time in seconds
end: 0.2,
highlighted: false // to reduce DOM updates
},
{
id: "W11",
start: 0.22,
end: 0.4,
highlighted: false
},
... etc. ...
];
然后在高亮中:
function highlight() {
var time = a2.currentTime,
i = 0, word;
for(; word = words[i++];) {
if (time >= word.start && time <= word.end)
if (!word.highlighted) {
word.highlighted = true; // to reduce the need to update DOM
// ... set CSS for highlighted here...
}
}
else if (word.highlighted) {
// ... set CSS for not highlighted here...
word.highlighted = false;
}
}
}
现场演示
尝试在播放过程中暂停,您会发现继续播放时文本仍然能够同步。
// NOTE: these are not 100% synchronized - they are just for example
var words = [
{id: "W10", start: 0, end: 0.7, highlighted: false},
{id: "W11", start: 0.76, end: 1.1, highlighted: false},
{id: "W12", start: 1.2, end: 1.3, highlighted: false},
{id: "W13", start: 1.4, end: 2.1, highlighted: false},
{id: "W14", start: 2.1, end: 2.3, highlighted: false},
{id: "W15", start: 2.3, end: 2.7, highlighted: false},
{id: "W16", start: 2.7, end: 3.0, highlighted: false},
{id: "W17", start: 3.0, end: 3.2, highlighted: false},
{id: "W18", start: 3.2, end: 3.4, highlighted: false}],
audio = document.getElementById("a2");
audio.onplaying = highlight;
function highlight() {
var time = a2.currentTime, i = 0, word;
for(; word = words[i++];) {
if (time >= word.start && time < word.end) {
if (!word.highlighted) {
word.highlighted = true; // to reduce the need to update DOM
document.getElementById(word.id).style.color = "orange";
}
}
else if (word.highlighted) {
document.getElementById(word.id).style.color = "black";
word.highlighted = false;
}
}
// you should listen to end event and stop the loop using that, here, for simplicity:
if (!audio.paused) setTimeout(highlight, 17);
//else alert("done");
}
body {font: bold 16px sans-serif}
<audio preload='auto' controls id='a2'>
<source src="http://arbordalepublishing.com/eBooks2/Animalogy/Animalogy p7.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
<br>
<span id="W10">Chick </span>
<span id="W11">is </span>
<span id="W12">to </span>
<span id="W13">feathery,</span>
<span id="W14">as </span>
<span id="W15">bear </span>
<span id="W16">is </span>
<span id="W17">to </span>
<span id="W18">furry.</span>