Use VideoJSPlayer for vimeo workaround

This commit is contained in:
calzoneman 2015-06-28 09:42:21 -07:00
parent b34f972629
commit 7fee1414e2
6 changed files with 43 additions and 120 deletions

View file

@ -1,3 +1,4 @@
var Vimeo = require("cytube-mediaquery/lib/provider/vimeo");
var ChannelModule = require("./module"); var ChannelModule = require("./module");
var Config = require("../config"); var Config = require("../config");
var InfoGetter = require("../get-info"); var InfoGetter = require("../get-info");
@ -7,6 +8,7 @@ function MediaRefresherModule(channel) {
ChannelModule.apply(this, arguments); ChannelModule.apply(this, arguments);
this._interval = false; this._interval = false;
this._media = null; this._media = null;
this._playlist = channel.modules.playlist;
} }
MediaRefresherModule.prototype = Object.create(ChannelModule.prototype); MediaRefresherModule.prototype = Object.create(ChannelModule.prototype);
@ -15,18 +17,26 @@ MediaRefresherModule.prototype.onPreMediaChange = function (data, cb) {
if (this._interval) clearInterval(this._interval); if (this._interval) clearInterval(this._interval);
this._media = data; this._media = data;
var pl = this._playlist;
switch (data.type) { switch (data.type) {
case "gd": case "gd":
pl._refreshing = true;
return this.initGoogleDocs(data, function () { return this.initGoogleDocs(data, function () {
pl._refreshing = false;
cb(null, ChannelModule.PASSTHROUGH); cb(null, ChannelModule.PASSTHROUGH);
}); });
case "gp": case "gp":
pl._refreshing = true;
return this.initGooglePlus(data, function () { return this.initGooglePlus(data, function () {
pl._refreshing = false;
cb(null, ChannelModule.PASSTHROUGH); cb(null, ChannelModule.PASSTHROUGH);
}); });
case "vi": case "vi":
pl._refreshing = true;
return this.initVimeo(data, function () { return this.initVimeo(data, function () {
pl._refreshing = false;
cb(null, ChannelModule.PASSTHROUGH); cb(null, ChannelModule.PASSTHROUGH);
}); });
default: default:
@ -55,18 +65,20 @@ MediaRefresherModule.prototype.initVimeo = function (data, cb) {
var self = this; var self = this;
self.channel.activeLock.lock(); self.channel.activeLock.lock();
InfoGetter.vimeoWorkaround(data.id, function (hack) { Vimeo.extract(data.id).then(function (direct) {
if (self.dead || self.channel.dead) { if (self.dead || self.channel.dead)
return; return;
}
if (self._media === data) { if (self._media === data) {
data.meta.direct = direct;
self.channel.logger.log("[mediarefresher] Refreshed vimeo video with ID " + self.channel.logger.log("[mediarefresher] Refreshed vimeo video with ID " +
data.id); data.id);
data.meta.direct = hack;
} }
self.channel.activeLock.release(); self.channel.activeLock.release();
if (cb) cb();
}).catch(function (err) {
Logger.errlog.log("Unexpected vimeo::extract() fail: " + err.stack);
if (cb) cb(); if (cb) cb();
}); });
}; };

View file

@ -3,7 +3,6 @@ var AsyncQueue = require("../asyncqueue");
var Media = require("../media"); var Media = require("../media");
var util = require("../utilities"); var util = require("../utilities");
var InfoGetter = require("../get-info"); var InfoGetter = require("../get-info");
var vimeoWorkaround = InfoGetter.vimeoWorkaround;
var Config = require("../config"); var Config = require("../config");
var Flags = require("../flags"); var Flags = require("../flags");
var db = require("../database"); var db = require("../database");
@ -90,7 +89,7 @@ function PlaylistModule(channel) {
this._leadInterval = false; this._leadInterval = false;
this._lastUpdate = 0; this._lastUpdate = 0;
this._counter = 0; this._counter = 0;
this._gdRefreshTimer = false; this._refreshing = false;
if (this.channel.modules.chat) { if (this.channel.modules.chat) {
this.channel.modules.chat.registerCommand("/clean", this.handleClean.bind(this)); this.channel.modules.chat.registerCommand("/clean", this.handleClean.bind(this));
@ -167,11 +166,6 @@ PlaylistModule.prototype.unload = function () {
this._leadInterval = false; this._leadInterval = false;
} }
if (this._gdRefreshTimer) {
clearInterval(this._gdRefreshTimer);
this._gdRefreshTimer = false;
}
this.channel = null; this.channel = null;
}; };
@ -265,7 +259,7 @@ PlaylistModule.prototype.sendPlaylist = function (users) {
}; };
PlaylistModule.prototype.sendChangeMedia = function (users) { PlaylistModule.prototype.sendChangeMedia = function (users) {
if (!this.current || !this.current.media) { if (!this.current || !this.current.media || this._refreshing) {
return; return;
} }
@ -1116,8 +1110,6 @@ PlaylistModule.prototype.refreshGoogleDocs = function (cb) {
} }
var abort = function () { var abort = function () {
clearInterval(self._gdRefreshTimer);
self._gdRefreshTimer = false;
if (self.current) { if (self.current) {
self.current.media.meta.object = self.current.media.meta.object || null; self.current.media.meta.object = self.current.media.meta.object || null;
self.current.media.meta.failed = true; self.current.media.meta.failed = true;

View file

@ -832,97 +832,6 @@ var Getters = {
}, },
}; };
/**
* Function to workaround Vimeo being a dick and blocking my domain from embeds.
* Retrieves the player page and extracts the direct links to the MP4 encoded videos.
*/
function vimeoWorkaround(id, cb) {
if (typeof cb !== "function") {
return;
}
var failcount = 0;
var inner = function () {
var options = {
host: "player.vimeo.com",
path: "/video/" + id,
headers: {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:29.0) Gecko/20100101 Firefox/29.0",
"Referrer": "player.vimeo.com"
}
};
var parse = function (data) {
var i = data.indexOf("{\"cdn_url\"");
if (i === -1) {
setImmediate(function () {
cb({});
});
return;
}
var j = data.indexOf("};", i);
var json = data.substring(i, j+1);
try {
json = JSON.parse(json);
if (!json.request.files) {
setImmediate(function () {
cb({});
});
return;
}
var codec = json.request.files.codecs[0];
var files = json.request.files[codec];
setImmediate(function () {
cb(files);
});
} catch (e) {
// This shouldn't happen due to the user-agent, but just in case
if (data.indexOf("crawler") !== -1) {
Logger.syslog.log("Warning: vimdeoWorkaround got crawler response");
failcount++;
if (failcount > 4) {
Logger.errlog.log("vimeoWorkaround got bad response 5 times!"+
" Giving up.");
setImmediate(function () {
cb({});
});
} else {
setImmediate(function () {
inner();
});
}
return;
} else if (data.indexOf("This video does not exist.") !== -1) {
cb({});
return;
} else if (data.indexOf("Because of its privacy settings, this video cannot be played here.") !== -1) {
cb({});
}
Logger.errlog.log("Vimeo workaround error: ");
Logger.errlog.log(e);
Logger.errlog.log("http://vimeo.com/" + id);
setImmediate(function () {
cb({});
});
}
};
urlRetrieve(http, options, function (status, buffer) {
if (status !== 200) {
setImmediate(function () {
cb({});
});
return;
}
parse(buffer);
});
};
inner();
}
module.exports = { module.exports = {
Getters: Getters, Getters: Getters,
getMedia: function (id, type, callback) { getMedia: function (id, type, callback) {
@ -931,7 +840,5 @@ module.exports = {
} else { } else {
callback("Unknown media type '" + type + "'", null); callback("Unknown media type '" + type + "'", null);
} }
}, }
vimeoWorkaround: vimeoWorkaround
}; };

View file

@ -14,7 +14,9 @@ TYPE_MAP =
im: ImgurPlayer im: ImgurPlayer
window.loadMediaPlayer = (data) -> window.loadMediaPlayer = (data) ->
if data.type of TYPE_MAP if data.meta.direct
window.PLAYER = new VideoJSPlayer(data)
else if data.type of TYPE_MAP
try try
window.PLAYER = TYPE_MAP[data.type](data) window.PLAYER = TYPE_MAP[data.type](data)
catch e catch e

View file

@ -17,6 +17,7 @@ sortSources = (sources) ->
flv = [] flv = []
nonflv = [] nonflv = []
sources[quality].forEach((source) -> sources[quality].forEach((source) ->
source.quality = quality
if source.contentType == 'flv' if source.contentType == 'flv'
flv.push(source) flv.push(source)
else else
@ -28,6 +29,7 @@ sortSources = (sources) ->
return sourceOrder.concat(flvOrder).map((source) -> return sourceOrder.concat(flvOrder).map((source) ->
type: "video/#{source.contentType}" type: "video/#{source.contentType}"
src: source.link src: source.link
quality: source.quality
) )
window.VideoJSPlayer = class VideoJSPlayer extends Player window.VideoJSPlayer = class VideoJSPlayer extends Player
@ -45,18 +47,17 @@ window.VideoJSPlayer = class VideoJSPlayer extends Player
sources = sortSources(data.meta.direct) sources = sortSources(data.meta.direct)
if sources.length == 0 if sources.length == 0
# Temporary fix for race condition caused by channel playlist console.error('VideoJSPlayer::constructor(): data.meta.direct
# sending a changeMedia in onPostUserJoin before mediarefresher has no sources!')
# has refreshed it.
# TODO: Actually fix this on the server side rather than this
# hack.
@mediaType = null @mediaType = null
return return
sources.forEach((source) -> sources.forEach((source) ->
$('<source/>').attr('src', source.src) $('<source/>').attr(
.attr('type', source.type) src: source.src
.appendTo(video) type: source.type
'data-quality': source.quality
).appendTo(video)
) )
@player = videojs(video[0], autoplay: true, controls: true) @player = videojs(video[0], autoplay: true, controls: true)

View file

@ -465,6 +465,7 @@
flv = []; flv = [];
nonflv = []; nonflv = [];
sources[quality].forEach(function(source) { sources[quality].forEach(function(source) {
source.quality = quality;
if (source.contentType === 'flv') { if (source.contentType === 'flv') {
return flv.push(source); return flv.push(source);
} else { } else {
@ -478,7 +479,8 @@
return sourceOrder.concat(flvOrder).map(function(source) { return sourceOrder.concat(flvOrder).map(function(source) {
return { return {
type: "video/" + source.contentType, type: "video/" + source.contentType,
src: source.link src: source.link,
quality: source.quality
}; };
}); });
}; };
@ -501,11 +503,16 @@
removeOld(video); removeOld(video);
sources = sortSources(data.meta.direct); sources = sortSources(data.meta.direct);
if (sources.length === 0) { if (sources.length === 0) {
console.error('VideoJSPlayer::constructor(): data.meta.direct has no sources!');
_this.mediaType = null; _this.mediaType = null;
return; return;
} }
sources.forEach(function(source) { sources.forEach(function(source) {
return $('<source/>').attr('src', source.src).attr('type', source.type).appendTo(video); return $('<source/>').attr({
src: source.src,
type: source.type,
'data-quality': source.quality
}).appendTo(video);
}); });
_this.player = videojs(video[0], { _this.player = videojs(video[0], {
autoplay: true, autoplay: true,
@ -983,7 +990,9 @@
window.loadMediaPlayer = function(data) { window.loadMediaPlayer = function(data) {
var e; var e;
if (data.type in TYPE_MAP) { if (data.meta.direct) {
return window.PLAYER = new VideoJSPlayer(data);
} else if (data.type in TYPE_MAP) {
try { try {
return window.PLAYER = TYPE_MAP[data.type](data); return window.PLAYER = TYPE_MAP[data.type](data);
} catch (_error) { } catch (_error) {