我正在使用[youtube api] [1]来了解视频何时完全缓冲player.getVideoLoadedFraction()
当分数为1时,视频是完全缓冲的,但我必须轮询此函数以检查它是否为1然后得到时间,如:
setInterval(display_fraction,1);
因为视频可能需要几十分钟。
此轮询是否会对浏览器/客户端造成沉重负担,从而影响视频流?有什么其他更好的轮询方法或方法来检测youtube何时完成缓冲?
BTW,youtube api的链接是: https://developers.google.com/youtube/flash_api_reference#Playback_controls
答案 0 :(得分:4)
人类开始感知时间间隔介于20到10秒之间,因此尝试以1ms的值进行轮询既不必要也不可取(任何现代浏览器都会将其舍入到5ms或10ms)。像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
});
我提倡链接系列setTimeout
而不是setInterval
的原因是:
您可以轻松地将迭代从迭代更改为迭代。例如,在上面,我会尽快启动检查第一次时间,然后在每次后续100ms后启动检查。你可以做更复杂的事情而不是时间,灵活性就在那里。
由于代码必须明确触发下一个循环,因此无意中最终导致多次运行会更加困难。
setInterval
因浏览器是否从最后一次调用的 start 或 end 测量界面而异。如果您使用上述模式,则始终确保它来自上次检查的 end 。
如果您的代码在下一个间隔发生时仍在运行,则会跳过它。这可能会造成间隙(例如,如果你每100毫秒做一次事情,而你之前的循环需要102毫秒才能完成,下一个循环不会尽快启动,它会等待剩余的98毫秒),至少在某些浏览器上是这样。 / p>
但是,这取决于您,当然,通过setInterval
和clearInterval
调用以及setTimeout
次调用链,可以轻松完成上述操作。
答案 1 :(得分: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);