Initial improvements to playback system

This commit is contained in:
Calvin Montgomery 2014-07-09 21:20:14 -07:00
parent a97db09928
commit 3f959087af
4 changed files with 128 additions and 64 deletions

View File

@ -114,6 +114,7 @@ Channel.prototype.initModules = function () {
"./opts" : "options", "./opts" : "options",
"./library" : "library", "./library" : "library",
"./playlist" : "playlist", "./playlist" : "playlist",
"./mediarefresher": "mediarefresher",
"./voteskip" : "voteskip", "./voteskip" : "voteskip",
"./poll" : "poll", "./poll" : "poll",
"./kickban" : "kickban", "./kickban" : "kickban",

View File

@ -0,0 +1,93 @@
var ChannelModule = require("./module");
var Config = require("../config");
var InfoGetter = require("../get-info");
function MediaRefresherModule(channel) {
ChannelModule.apply(this, arguments);
this._interval = false;
this._media = null;
}
MediaRefresherModule.prototype = Object.create(ChannelModule.prototype);
MediaRefresherModule.prototype.onMediaChange = function (data) {
if (this._interval) clearInterval(this._interval);
this._media = data;
switch (data.type) {
case "gd":
return this.initGoogleDocs(data);
case "vi":
return this.initVimeo(data);
}
};
MediaRefresherModule.prototype.initGoogleDocs = function (data) {
var self = this;
self.refreshGoogleDocs(data, true);
/*
* Refresh every 55 minutes.
* The expiration is 1 hour, but refresh 5 minutes early to be safe
*/
self._interval = setInterval(function () {
self.refreshGoogleDocs(data, false);
}, 55 * 60 * 1000);
};
MediaRefresherModule.prototype.initVimeo = function (data) {
if (!Config.get("vimeo-workaround")) {
return;
}
var self = this;
self.channel.activeLock.lock();
InfoGetter.vimeoWorkaround(data.id, function (hack) {
if (self._media === data) {
self.channel.logger.log("[mediarefresher] Refreshed vimeo video with ID " +
data.id);
data.meta.direct = hack;
self.channel.broadcastAll("changeMedia", data.getFullUpdate());
}
self.channel.activeLock.release();
});
};
MediaRefresherModule.prototype.refreshGoogleDocs = function (media, update) {
var self = this;
if (self.dead || self.channel.dead) {
return;
}
self.channel.activeLock.lock();
InfoGetter.getMedia(media.id, "gd", function (err, data) {
switch (err) {
case "HTTP 302":
case "Video not found":
case "Private video":
return;
default:
if (err) {
Logger.errlog.log("Google Docs refresh failed for ID " + media.id +
": " + err);
return self.channel.activeLock.release();
}
}
if (media !== self._media) {
return self.channel.activeLock.release();
}
self.channel.logger.log("[mediarefresher] Refreshed Google Docs video with ID " +
media.id);
media.meta = data.meta;
if (update) {
self.channel.broadcastAll("changeMedia", data.getFullUpdate());
}
self.channel.activeLock.release();
});
};
module.exports = MediaRefresherModule;

View File

@ -977,72 +977,34 @@ PlaylistModule.prototype.startPlayback = function (time) {
var media = self.current.media; var media = self.current.media;
media.reset(); media.reset();
var continuePlayback = function () { if (self.leader != null) {
if (self.leader != null) { media.paused = false;
media.paused = false; media.currentTime = time || 0;
media.currentTime = time || 0;
self.sendChangeMedia(self.channel.users);
self.channel.notifyModules("onMediaChange", self.current.media);
return;
}
/* Lead-in time of 3 seconds to allow clients to buffer */
time = time || -3;
media.paused = time < 0;
media.currentTime = time;
/* Module was already leading, stop the previous timer */
if (self._leadInterval) {
clearInterval(self._leadInterval);
self._leadInterval = false;
}
self.sendChangeMedia(self.channel.users); self.sendChangeMedia(self.channel.users);
self.channel.notifyModules("onMediaChange", self.current.media); self.channel.notifyModules("onMediaChange", [self.current.media]);
/* Only start the timer if the media item is not live, i.e. has a duration */
if (media.seconds > 0) {
self._lastUpdate = Date.now();
self._leadInterval = setInterval(function() {
self._leadLoop();
}, 1000);
}
/* Google Docs autorefresh */
if (self._gdRefreshTimer) {
clearInterval(self._gdRefreshTimer);
self._gdRefreshTimer = false;
}
if (media.type === "gd") {
self._gdRefreshTimer = setInterval(self.refreshGoogleDocs.bind(self), 3600000);
if (media.meta.expiration && media.meta.expiration < Date.now() + 3600000) {
setTimeout(self.refreshGoogleDocs.bind(self), media.meta.expiration - Date.now());
}
}
};
if (media.type === "vi" && !media.meta.direct && Config.get("vimeo-workaround")) {
self.channel.activeLock.lock();
vimeoWorkaround(media.id, function (direct) {
self.channel.activeLock.release();
if (self.current && self.current.media === media) {
self.current.media.meta.direct = direct;
continuePlayback();
}
});
return; return;
} else if (media.type === "gd" && isExpired(media) && !media.meta.failed) { }
self.channel.activeLock.lock();
self.refreshGoogleDocs(function () { /* Lead-in time of 3 seconds to allow clients to buffer */
self.channel.activeLock.release(); time = time || -3;
if (self.current && self.current.media === media) { media.paused = time < 0;
continuePlayback(); media.currentTime = time;
}
}); /* Module was already leading, stop the previous timer */
return; if (self._leadInterval) {
} else { clearInterval(self._leadInterval);
continuePlayback(); self._leadInterval = false;
}
self.sendChangeMedia(self.channel.users);
self.channel.notifyModules("onMediaChange", [self.current.media]);
/* Only start the timer if the media item is not live, i.e. has a duration */
if (media.seconds > 0) {
self._lastUpdate = Date.now();
self._leadInterval = setInterval(function() {
self._leadLoop();
}, 1000);
} }
} }

View File

@ -1002,7 +1002,15 @@ var GoogleDocsPlayer = function (data) {
self.videoLength = data.seconds; self.videoLength = data.seconds;
self.paused = false; self.paused = false;
var wmode = USEROPTS.wmode_transparent ? "transparent" : "opaque"; var wmode = USEROPTS.wmode_transparent ? "transparent" : "opaque";
var meta = data.meta; var meta = data.meta;
if (!meta || !meta.object || !meta.params) {
// Reset videoId so that a changeMedia with the appropriate data
// will properly reset the player
self.videoId = "";
return;
}
self.player = $("<object/>", meta.object)[0]; self.player = $("<object/>", meta.object)[0];
$(self.player).attr("data", meta.object.data); $(self.player).attr("data", meta.object.data);
$(self.player).attr("width", VWIDTH) $(self.player).attr("width", VWIDTH)