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>