1

我正在使用 [youtube api][1] 来了解视频何时完全缓冲player.getVideoLoadedFraction()

当分数为 1 时,视频已完全缓冲,但我必须轮询此函数以检查它是否为 1,然后获取时间,例如:

setInterval(display_fraction,1);

因为一个视频可能有几十分钟。

这种轮询是否会在浏览器/客户端上造成沉重的负载,从而影响视频流?有没有其他更好的轮询方法或方法来检测 youtube 何时完成缓冲?

顺便说一句,youtube api 的链接是: https ://developers.google.com/youtube/flash_api_reference#Playback_controls

4

2 回答 2

4

人类开始感知时间间隔在 20 到 10 秒之间,因此尝试使用 1 毫秒的值进行轮询既没有必要也不可取(任何现代浏览器都会将其舍入到 5 毫秒或 10 毫秒)。像 50 或 100 这样的值会更合适。

我还强烈建议使用链接的一系列setTimeout调用而不是setInterval调用,如下所示:

function onVideoReady(callback) {

    // Do first check as soon as the JavaScript engine is available to do it
    setTimeout(checkVideoReady, 0);

    // Our check function
    function checkVideoReady() {
        if (videoIsReady) {
            // The video is ready, notify calling code
            callback();
        }
        else {
            // Not ready yet, wait a 10th of a second
            setTimeout(checkVideoReady, 100);
        }
    }
}

...然后您可以像这样使用它:

onVideoReady(function() {
    // The video is ready, do something
});

我提倡链式系列的原因setTimeoutsetInterval

  1. 您可以轻松地在迭代之间更改延迟。例如在上面,我第一次尽快触发检查,然后在每次 100 毫秒后触发。你可以用时间做比这更复杂的事情,灵活性就在那里。

  2. 由于代码必须显式地触发下一个循环,因此无意中运行多个循环要困难得多。

  3. setInterval浏览器之间的差异在于它是从最后一次调用的开始还是结束时测量界面。如果您使用上述模式,您始终可以确定它是从最后一次检查结束时开始的。

  4. 如果您的代码在下一个间隔发生时仍在运行,它就会被跳过。这可能会导致间隙(例如,如果您每 100 毫秒执行一次操作,而您的上一个循环需要 102 毫秒才能完成,下一个循环不会尽快开始,它会等待剩余的 98 毫秒),至少在某些浏览器上是这样。

但这取决于你,当然,上面的操作可以像使用调用链一样简单地使用setIntervaland调用来完成。clearIntervalsetTimeout

于 2012-11-05T12:05:22.410 回答
1

链式超时的替代方案是链式Promises。以下实现了定期轮询以及超时。

var Promise = require('bluebird');

/**
 * Periodically poll a signal function until either it returns true or    a timeout is reached.
 *
 * @param signal function that returns true when the polled operation is complete
 * @param interval time interval between polls in milliseconds
 * @param timeout period of time before giving up on polling
 * @returns true if the signal function returned true, false if the operation timed out
 */
function poll(signal, interval, timeout) {
    function pollRecursive() {
        return signal() ? Promise.resolve(true) : Promise.delay(interval).then(pollRecursive);
    }

    return pollRecursive()
        .cancellable()
        .timeout(timeout)
        .catch(Promise.TimeoutError, Promise.CancellationError,function () {
            return false;
        });
}

你这样称呼它。

poll(isVideoReady, pollingInterval, timeout).then(console.log);

请参阅Javascript polling with promises

于 2015-07-04T20:30:41.283 回答