Fix for google docs changing their video player:

This commit is contained in:
Calvin Montgomery 2014-08-06 20:12:57 -07:00
parent d94c596063
commit b7edfc31f9
6 changed files with 97 additions and 69 deletions

View file

@ -21,6 +21,10 @@ MediaRefresherModule.prototype.onPreMediaChange = function (data, cb) {
return this.initGoogleDocs(data, function () { return this.initGoogleDocs(data, function () {
cb(null, ChannelModule.PASSTHROUGH); cb(null, ChannelModule.PASSTHROUGH);
}); });
case "gp":
return this.initGooglePlus(data, function () {
cb(null, ChannelModule.PASSTHROUGH);
});
case "vi": case "vi":
return this.initVimeo(data, function () { return this.initVimeo(data, function () {
cb(null, ChannelModule.PASSTHROUGH); cb(null, ChannelModule.PASSTHROUGH);
@ -116,4 +120,52 @@ MediaRefresherModule.prototype.refreshGoogleDocs = function (media, cb) {
}); });
}; };
MediaRefresherModule.prototype.initGooglePlus = function (media, cb) {
var self = this;
if (self.dead || self.channel.dead) {
return;
}
self.channel.activeLock.lock();
InfoGetter.getMedia(media.id, "gp", function (err, data) {
if (self.dead || self.channel.dead) {
return;
}
switch (err) {
case "HTTP 302":
case "Video not found":
case "Private video":
self.channel.logger.log("[mediarefresher] Google+ refresh failed: " +
err);
self.channel.activeLock.release();
if (cb) cb();
return;
default:
if (err) {
self.channel.logger.log("[mediarefresher] Google+ refresh failed: " +
err);
Logger.errlog.log("Google+ refresh failed for ID " + media.id +
": " + err);
self.channel.activeLock.release();
if (cb) cb();
return;
}
}
if (media !== self._media) {
self.channel.activeLock.release();
if (cb) cb();
return;
}
self.channel.logger.log("[mediarefresher] Refreshed Google+ video with ID " +
media.id);
media.meta = data.meta;
self.channel.activeLock.release();
if (cb) cb();
});
};
module.exports = MediaRefresherModule; module.exports = MediaRefresherModule;

View file

@ -426,8 +426,7 @@ module.exports = {
var meta = JSON.stringify({ var meta = JSON.stringify({
bitrate: media.meta.bitrate, bitrate: media.meta.bitrate,
codec: media.meta.codec, codec: media.meta.codec
gpdirect: media.meta.gpdirect
}); });
db.query("INSERT INTO `channel_libraries` " + db.query("INSERT INTO `channel_libraries` " +

View file

@ -703,71 +703,52 @@ var Getters = {
return callback("HTTP " + status, null); return callback("HTTP " + status, null);
} }
var m = res.match(/main\((.*?)\);<\/script>/); var m = res.match(/(\[\s*\[[^\[].*?\]\s*\])/);
if (m) { try {
try { var propertyList = JSON.parse(m[1]);
var data = m[1]; var data = {};
data = data.substring(data.indexOf(",") + 1); propertyList.forEach(function (kv) {
data = data.replace(/'(.*?)'([:\,\}\]])/g, "\"$1\"$2"); data[kv[0]] = kv[1];
/* Fixes an issue with certain characters represented as \xkk */ });
data = data.replace(/\\x(\d*)/g, function (sub, s1) {
return String.fromCharCode(parseInt(s1, 16));
});
data = "[" + data + "]";
var js = JSON.parse(data);
if (js[1].videoplay.status === "QUOTA_DENIED") { var title = data.title;
return callback("Google Docs error: Video has exceeded quota", null); var seconds = parseInt(data.length_seconds);
}
var title = js[0].title; var videos = {};
var seconds = js[1].videodetails.duration / 1000; data.fmt_stream_map.split(",").forEach(function (stream) {
var meta = {}; var parts = stream.split("|");
var fv = js[1].videoplay.flashVars; videos[parts[0]] = parts[1];
var fvstr = ""; });
for (var k in fv) {
if (k === "autoplay")
fv[k] = "1";
fvstr += "&" + k + "=" + encodeURIComponent(fv[k]);
}
fvstr = fvstr.substring(1);
var url = js[1].videoplay.swfUrl + "&enablejsapi=1"; /*
meta.object = { * Preference map of quality => youtube formats.
type: "application/x-shockwave-flash", * see https://en.wikipedia.org/wiki/Youtube#Quality_and_codecs
allowscriptaccess: "always", */
allowfullscreen: "true", const preference = {
wmode: "opaque", "hd1080": [46, 37],
data: url "hd720": [22, 45],
}; "large": [44, 35],
"medium": [43, 18],
"small": [5]
};
meta.params = [ var direct = {};
{
name: "allowFullScreen", for (var key in preference) {
value: "true" for (var i = 0; i < preference[key].length; i++) {
}, var format = preference[key][i];
{
name: "allowScriptAccess", if (format in videos) {
value: "always" direct[key] = videos[format];
}, break;
{
name: "wmode",
value: "opaque"
},
{
name: "flashvars",
value: fvstr
} }
]; }
var med = new Media(id, title, seconds, "gd", meta);
callback(false, med);
} catch (e) {
callback("Parsing of Google Docs output failed", null);
} }
} else {
callback(res, null); callback(null, new Media(id, title, seconds, "gd", { gpdirect: direct }));
} catch (e) {
console.error(e);
return callback("Failed to parse Google Docs output", null);
} }
}); });
}, },

View file

@ -32,8 +32,6 @@ Media.prototype = {
duration: this.duration, duration: this.duration,
type: this.type, type: this.type,
meta: { meta: {
object: this.meta.object,
params: this.meta.params,
direct: this.meta.direct, direct: this.meta.direct,
gpdirect: this.meta.gpdirect, gpdirect: this.meta.gpdirect,
restricted: this.meta.restricted, restricted: this.meta.restricted,

View file

@ -878,7 +878,10 @@ Callbacks = {
data = vimeoSimulator2014(data); data = vimeoSimulator2014(data);
} }
if (data.type === "gp") { /*
* Google Docs now uses the same simulator as Google+
*/
if (data.type === "gp" || data.type === "gd") {
data = googlePlusSimulator2014(data); data = googlePlusSimulator2014(data);
} }

View file

@ -2737,11 +2737,6 @@ function googlePlusSimulator2014(data) {
/* Google+ Simulator uses the raw file player */ /* Google+ Simulator uses the raw file player */
data.type = "fi"; data.type = "fi";
/* For browsers that don't support native h264 playback */
if (USEROPTS.no_h264) {
data.forceFlash = true;
}
if (!data.meta.gpdirect) { if (!data.meta.gpdirect) {
data.url = ""; data.url = "";
return data; return data;