使用Firefox setInterval和设置currentTime

时间:2015-05-04 19:13:56

标签: javascript jquery html5 firefox audio

我正在编写一个JS应用程序,突出显示与预先录制的音频同步的单词。这个过程非常简单。我列出了每个单词在音频中开始的时间,我每隔.1秒调用一个JS函数来检查audio.currentTime并查看它是否已达到下一个单词的阈值。我已经尝试过使用音频timeUpdate事件,并且为了我的目的,并没有在平台上频繁触发。单词被跳过。

我已经在移动Chrome,iPad(移动版Safari),Kindle Fire(丝网浏览器或他们现在称之为的任何内容)的Moto E上测试了我的代码,并在Windows上使用最新的Chrome,Firefox和IE 11。

除了一个例外,它一切运行良好:Firefox滞后。同步在FF中工作正常,但每次我将音频提示到一个新的时间,Firefox似乎落后,并在第10页左右(即使我只是按下我的"下一页"重复按钮),滞后是显而易见的。叙述者将完成一个单词,FF将开始突出显示前一个单词。

以下是相关代码:

一旦对书籍信息的AJAX调用回来,就会调用它:

window.setInterval( bundleFunctions.execute, 100 );

bundleFunctions对象只是一种同时调用动态功能组的简单方法。

有两个功能被添加到bundleFunctions。我关心的是highlightWord

var lasthighlight = -1;
function highlightWord() {

    var debug = false;

        // find the last word time that comes before the current time.

    var playerSound     = document.getElementById( "playerSound" );     // audio tag

        // wordTimes is an array of times where each word starts in the recorded audio

    var indexToHighlight = Math.max.apply( Math, $.map( wordTimes, function( time, index ) {

            // only highlight words that start before the current time with a buffer equal to the interval at which this function is called
            // don't highlight word for more than 2 seconds.

        if ( time - .1 > playerSound.currentTime || playerSound.currentTime - time > 2 ) {      
            return null;

            // if this is the last or first wordTime or the preceding word time
            // is less than the current time, return the index of that word time

        } else {
            return index;
        }
    }));

        // minimize lag by not touching the DOM if there's no new word to highlight

    if ( typeof indexToHighlight != "undefined" ) {
        if ( lasthighlight != indexToHighlight ) {
            lasthighlight = indexToHighlight;

            if ( debug ) {
                console.log( "highlighting word [ " + $( ".word.use:eq(" + indexToHighlight + ")" ).text() + "] at this index: [" + indexToHighlight + "]" );
                console.log( indexToHighlight );
            }
            $word = $( ".word:eq(" + indexToHighlight + ")");
            $( ".word" ).css( "color", "black" );
            $word.css( "color", "red" );
        } 
    }
}

你可以看到我添加了一些代码来尝试最小化DOM操作,希望这是FF落后的原因,但它没有任何效果。请注意,页面上一次只有40个左右的单词,所以它不像是一些重型DOM操作,并且延迟似乎与在音频中搜索直接相关,而不是任何问题FF JS引擎已经处理了它的工作量。

bundleFunction调用的另一个函数检查我们是否已到达页面的末尾。这是该函数(override允许我手动跳过下一页):

function checkAdvancePage( override ) {
    var debug = false;
    override = override === true;
    if ( playerSound.currentTime >= timeToSeconds( book.pages.page[ curPage ][ "_f" ]) || override ) {

        if ( book.pages.page.length >= curPage + 2 ) {
            if ( debug ) {
                console.log( "advancing page from [" + curPage + "]" );
            }

            curPage++;

            if ( debug ) {
                console.log( "to [" + curPage + "]" );
            }


                // this book has another page. Keep going.

            startPage( book );

        } else {

                // this book is on its last page

            endScreen( book );
        }
    }
}

正如你所看到的,它非常基本。 99.9%的时间它将评估一行代码 - "是currentTime>当前页面的结束时间?",返回false,结束。

最后,这里是代码,其中包括代码,其中,代码在音频中寻找页面变化的新页面的开头。奇怪的结构化书籍对象就是这样,因为它是从XML转换而来的:

var soundLoaded = false;
var isPlaying   = false;
function queueAudio( book ) {
    var debug           = false;

    var playerSound     = document.getElementById( "playerSound" );     // audio tag
    var playing         = false;
    playerSound.addEventListener( 'canplaythrough', function queue() {

        if ( debug ) {
            console.log( "tracing this page" );
            console.log( book.pages.page[ curPage ]);   
        }

        playerSound.currentTime = timeToSeconds( book.pages.page[ curPage ]["_s" ]);
        playerSound.removeEventListener( 'canplaythrough', queue );
        bundleFunctions.add( checkAdvancePage );
        soundLoaded             = true;
    }); 


    if ( !soundLoaded ) {
        var playerSource    = document.getElementById( "playerSource" );    // source tag
        playerSource.src    = BOOKS_DIR + book.track[ "_src" ];
        playerSound.load();
        playerSound.play();         // has to be called here to link a mobile tap to the play command
        isPlaying = true;
    } else {
        playerSound.currentTime = timeToSeconds( book.pages.page[ curPage ]["_s" ]);
    }

        // manual click to next page. Only add the listener once.
    if ( typeof( document.getElementById( "next" ).onclick ) == "undefined" ) {
        $( "#next" ).click( function() {
            console.log( "next page clicked" );
            checkAdvancePage( true );
        });
    }

        // watches current time of audio and advances to the next page when we get to the end of the audio for that page

    function checkAdvancePage( override ) {
        var debug = false;
        override = override === true;  // if true, advance the page regardless of currentTime
        if ( playerSound.currentTime >= timeToSeconds( book.pages.page[ curPage ][ "_f" ]) || override ) {
            playerSound.removeEventListener( 'timeupdate', checkAdvancePage );

            if ( book.pages.page.length >= curPage + 2 ) {
                if ( debug ) {
                    console.log( "advancing page from [" + curPage + "]" );
                }

                curPage++;

                if ( debug ) {
                    console.log( "to [" + curPage + "]" );
                }


                    // this book has another page. Keep going.

                startPage( book );

            } else {

                    // this book is on its last page

                endScreen( book );
            }
        }
    }
}

如果一个单词在说出的确切时刻不突出显示,则可以接受。什么是不可接受的是之后突出显示 >

最快的单词大概是在0.1秒内说出来的。如果有一段时间,只要突出显示保持同步,就会跳过其中一个超快速的单词。

提前感谢您提供的任何帮助。

0 个答案:

没有答案