Add initial userscript
This commit is contained in:
parent
d51722c466
commit
4feee02e33
|
@ -8,6 +8,7 @@ var order = [
|
||||||
'youtube.coffee',
|
'youtube.coffee',
|
||||||
'dailymotion.coffee',
|
'dailymotion.coffee',
|
||||||
'videojs.coffee',
|
'videojs.coffee',
|
||||||
|
'gdrive-player.coffee',
|
||||||
'raw-file.coffee',
|
'raw-file.coffee',
|
||||||
'soundcloud.coffee',
|
'soundcloud.coffee',
|
||||||
'embed.coffee',
|
'embed.coffee',
|
||||||
|
|
155
gdrive-userscript/cytube-google-drive.user.js
Normal file
155
gdrive-userscript/cytube-google-drive.user.js
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
// ==UserScript==
|
||||||
|
// @name Google Drive Video Player for {SITENAME}
|
||||||
|
// @namespace gdcytube
|
||||||
|
// @description Play Google Drive videos on {SITENAME}
|
||||||
|
// {INCLUDE_BLOCK}
|
||||||
|
// @grant unsafeWindow
|
||||||
|
// @grant GM_xmlhttpRequest
|
||||||
|
// @connect docs.google.com
|
||||||
|
// @run-at document-end
|
||||||
|
// @version 1.0.0
|
||||||
|
// ==/UserScript==
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
if (!unsafeWindow.enableCyTubeGoogleDriveUserscript) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function debug(message) {
|
||||||
|
if (!unsafeWindow.enableCyTubeGoogleDriveUserscriptDebug) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafeWindow.console.log.apply(unsafeWindow.console, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ITAG_QMAP = {
|
||||||
|
37: 1080,
|
||||||
|
46: 1080,
|
||||||
|
22: 720,
|
||||||
|
45: 720,
|
||||||
|
59: 480,
|
||||||
|
44: 480,
|
||||||
|
35: 480,
|
||||||
|
18: 360,
|
||||||
|
43: 360,
|
||||||
|
34: 360
|
||||||
|
};
|
||||||
|
|
||||||
|
var ITAG_CMAP = {
|
||||||
|
43: 'video/webm',
|
||||||
|
44: 'video/webm',
|
||||||
|
45: 'video/webm',
|
||||||
|
46: 'video/webm',
|
||||||
|
18: 'video/mp4',
|
||||||
|
22: 'video/mp4',
|
||||||
|
37: 'video/mp4',
|
||||||
|
59: 'video/mp4',
|
||||||
|
35: 'video/flv',
|
||||||
|
34: 'video/flv'
|
||||||
|
};
|
||||||
|
|
||||||
|
function getVideoInfo(id, cb) {
|
||||||
|
var url = 'https://docs.google.com/file/d/' + id + '/get_video_info';
|
||||||
|
debug('Fetching ' + url);
|
||||||
|
|
||||||
|
GM_xmlhttpRequest({
|
||||||
|
method: 'GET',
|
||||||
|
url: url,
|
||||||
|
onload: function (res) {
|
||||||
|
var data = {};
|
||||||
|
res.responseText.split('&').forEach(function (kv) {
|
||||||
|
var pair = kv.split('=');
|
||||||
|
data[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (data.status === 'fail') {
|
||||||
|
var error = new Error('Google Docs request failed: ' +
|
||||||
|
'metadata indicated status=fail');
|
||||||
|
error.response = res.responseText;
|
||||||
|
error.reason = 'RESPONSE_STATUS_FAIL';
|
||||||
|
return cb(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.fmt_stream_map) {
|
||||||
|
var error = new Error('Google Docs request failed: ' +
|
||||||
|
'metadata lookup returned no valid links');
|
||||||
|
error.response = res.responseText;
|
||||||
|
error.reason = 'MISSING_LINKS';
|
||||||
|
return cb(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
data.links = {};
|
||||||
|
data.fmt_stream_map.split(',').forEach(function (item) {
|
||||||
|
var pair = item.split('|');
|
||||||
|
data.links[pair[0]] = pair[1];
|
||||||
|
});
|
||||||
|
|
||||||
|
cb(null, data);
|
||||||
|
},
|
||||||
|
|
||||||
|
onerror: function () {
|
||||||
|
var error = new Error('Google Docs request failed: ' +
|
||||||
|
'metadata lookup HTTP request failed');
|
||||||
|
error.reason = 'HTTP_ONERROR';
|
||||||
|
return cb(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapLinks(links) {
|
||||||
|
var videos = {
|
||||||
|
1080: [],
|
||||||
|
720: [],
|
||||||
|
480: [],
|
||||||
|
360: []
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.keys(links).forEach(function (itag) {
|
||||||
|
itag = parseInt(itag, 10);
|
||||||
|
if (!ITAG_QMAP.hasOwnProperty(itag)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
videos[ITAG_QMAP[itag]].push({
|
||||||
|
itag: itag,
|
||||||
|
contentType: ITAG_CMAP[itag],
|
||||||
|
link: links[itag]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return videos;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GoogleDrivePlayer(data) {
|
||||||
|
if (!(this instanceof GoogleDrivePlayer)) {
|
||||||
|
return new GoogleDrivePlayer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setMediaProperties(data);
|
||||||
|
this.load(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
GoogleDrivePlayer.prototype = Object.create(unsafeWindow.VideoJSPlayer.prototype);
|
||||||
|
|
||||||
|
GoogleDrivePlayer.prototype.load = function (data) {
|
||||||
|
var self = this;
|
||||||
|
getVideoInfo(data.id, function (err, videoData) {
|
||||||
|
if (err) {
|
||||||
|
debug(err);
|
||||||
|
var alertBox = unsafeWindow.document.createElement('div');
|
||||||
|
alertBox.className = 'alert alert-danger';
|
||||||
|
alertBox.textContent = err.message;
|
||||||
|
document.getElementById('ytapiplayer').appendChild(alertBox);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug('Retrieved links: ' + JSON.stringify(videoData.links));
|
||||||
|
data.meta.direct = mapLinks(videoData.links);
|
||||||
|
unsafeWindow.VideoJSPlayer.prototype.loadPlayer.call(self, data);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafeWindow.GoogleDrivePlayer = GoogleDrivePlayer;
|
||||||
|
unsafeWindow.console.log('Initialized userscript Google Drive player');
|
||||||
|
})();
|
19
gdrive-userscript/generate-userscript.js
Normal file
19
gdrive-userscript/generate-userscript.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
var sitename = process.argv[2];
|
||||||
|
var includes = process.argv.slice(3).map(function (include) {
|
||||||
|
return '// @include ' + include;
|
||||||
|
}).join('\n');
|
||||||
|
|
||||||
|
var lines = String(fs.readFileSync(
|
||||||
|
path.resolve(__dirname, 'cytube-google-drive.user.js'))).split('\n');
|
||||||
|
lines.forEach(function (line) {
|
||||||
|
if (line.match(/\{INCLUDE_BLOCK\}/)) {
|
||||||
|
console.log(includes);
|
||||||
|
} else if (line.match(/\{SITENAME\}/)) {
|
||||||
|
console.log(line.replace(/\{SITENAME\}/, sitename));
|
||||||
|
} else {
|
||||||
|
console.log(line);
|
||||||
|
}
|
||||||
|
});
|
|
@ -47,7 +47,8 @@
|
||||||
"build-player": "$npm_node_execpath build-player.js",
|
"build-player": "$npm_node_execpath build-player.js",
|
||||||
"build-server": "babel -D --source-maps --loose es6.destructuring,es6.forOf --out-dir lib/ src/",
|
"build-server": "babel -D --source-maps --loose es6.destructuring,es6.forOf --out-dir lib/ src/",
|
||||||
"postinstall": "./postinstall.sh",
|
"postinstall": "./postinstall.sh",
|
||||||
"server-dev": "babel -D --watch --source-maps --loose es6.destructuring,es6.forOf --out-dir lib/ src/"
|
"server-dev": "babel -D --watch --source-maps --loose es6.destructuring,es6.forOf --out-dir lib/ src/",
|
||||||
|
"generate-userscript": "$npm_node_execpath gdrive-userscript/generate-userscript $@ > www/js/cytube-google-drive.user.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"coffee-script": "^1.9.2"
|
"coffee-script": "^1.9.2"
|
||||||
|
|
6
player/gdrive-player.coffee
Normal file
6
player/gdrive-player.coffee
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
window.GoogleDrivePlayer = class GoogleDrivePlayer extends VideoJSPlayer
|
||||||
|
constructor: (data) ->
|
||||||
|
if not (this instanceof GoogleDrivePlayer)
|
||||||
|
return new GoogleDrivePlayer(data)
|
||||||
|
|
||||||
|
super(data)
|
|
@ -2,7 +2,7 @@ TYPE_MAP =
|
||||||
yt: YouTubePlayer
|
yt: YouTubePlayer
|
||||||
vi: VimeoPlayer
|
vi: VimeoPlayer
|
||||||
dm: DailymotionPlayer
|
dm: DailymotionPlayer
|
||||||
gd: GoogleDriveYouTubePlayer
|
gd: GoogleDrivePlayer
|
||||||
gp: VideoJSPlayer
|
gp: VideoJSPlayer
|
||||||
fi: FilePlayer
|
fi: FilePlayer
|
||||||
jw: FilePlayer
|
jw: FilePlayer
|
||||||
|
@ -33,7 +33,7 @@ window.loadMediaPlayer = (data) ->
|
||||||
else if data.type is 'gd'
|
else if data.type is 'gd'
|
||||||
try
|
try
|
||||||
if data.meta.html5hack
|
if data.meta.html5hack
|
||||||
window.PLAYER = new VideoJSPlayer(data)
|
window.PLAYER = new window.GoogleDrivePlayer(data)
|
||||||
else
|
else
|
||||||
window.PLAYER = new GoogleDriveYouTubePlayer(data)
|
window.PLAYER = new GoogleDriveYouTubePlayer(data)
|
||||||
catch e
|
catch e
|
||||||
|
|
|
@ -216,3 +216,6 @@ function eraseCookie(name) {
|
||||||
|
|
||||||
/* to be implemented in callbacks.js */
|
/* to be implemented in callbacks.js */
|
||||||
function setupCallbacks() { }
|
function setupCallbacks() { }
|
||||||
|
|
||||||
|
window.enableCyTubeGoogleDriveUserscript = true;
|
||||||
|
window.enableCyTubeGoogleDriveUserscriptDebug = true;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(function() {
|
(function() {
|
||||||
var CUSTOM_EMBED_WARNING, CustomEmbedPlayer, DEFAULT_ERROR, DailymotionPlayer, EmbedPlayer, FilePlayer, GoogleDriveYouTubePlayer, HITBOX_ERROR, HLSPlayer, HitboxPlayer, ImgurPlayer, LivestreamPlayer, Player, RTMPPlayer, SoundCloudPlayer, TYPE_MAP, TwitchPlayer, USTREAM_ERROR, UstreamPlayer, VideoJSPlayer, VimeoPlayer, YouTubePlayer, codecToMimeType, genParam, sortSources,
|
var CUSTOM_EMBED_WARNING, CustomEmbedPlayer, DEFAULT_ERROR, DailymotionPlayer, EmbedPlayer, FilePlayer, GoogleDrivePlayer, GoogleDriveYouTubePlayer, HITBOX_ERROR, HLSPlayer, HitboxPlayer, ImgurPlayer, LivestreamPlayer, Player, RTMPPlayer, SoundCloudPlayer, TYPE_MAP, TwitchPlayer, USTREAM_ERROR, UstreamPlayer, VideoJSPlayer, VimeoPlayer, YouTubePlayer, codecToMimeType, genParam, sortSources,
|
||||||
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||||||
hasProp = {}.hasOwnProperty;
|
hasProp = {}.hasOwnProperty;
|
||||||
|
|
||||||
|
@ -666,6 +666,20 @@
|
||||||
|
|
||||||
})(Player);
|
})(Player);
|
||||||
|
|
||||||
|
window.GoogleDrivePlayer = GoogleDrivePlayer = (function(superClass) {
|
||||||
|
extend(GoogleDrivePlayer, superClass);
|
||||||
|
|
||||||
|
function GoogleDrivePlayer(data) {
|
||||||
|
if (!(this instanceof GoogleDrivePlayer)) {
|
||||||
|
return new GoogleDrivePlayer(data);
|
||||||
|
}
|
||||||
|
GoogleDrivePlayer.__super__.constructor.call(this, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GoogleDrivePlayer;
|
||||||
|
|
||||||
|
})(VideoJSPlayer);
|
||||||
|
|
||||||
codecToMimeType = function(codec) {
|
codecToMimeType = function(codec) {
|
||||||
switch (codec) {
|
switch (codec) {
|
||||||
case 'mov/h264':
|
case 'mov/h264':
|
||||||
|
@ -1308,7 +1322,7 @@
|
||||||
yt: YouTubePlayer,
|
yt: YouTubePlayer,
|
||||||
vi: VimeoPlayer,
|
vi: VimeoPlayer,
|
||||||
dm: DailymotionPlayer,
|
dm: DailymotionPlayer,
|
||||||
gd: GoogleDriveYouTubePlayer,
|
gd: GoogleDrivePlayer,
|
||||||
gp: VideoJSPlayer,
|
gp: VideoJSPlayer,
|
||||||
fi: FilePlayer,
|
fi: FilePlayer,
|
||||||
jw: FilePlayer,
|
jw: FilePlayer,
|
||||||
|
@ -1345,7 +1359,7 @@
|
||||||
} else if (data.type === 'gd') {
|
} else if (data.type === 'gd') {
|
||||||
try {
|
try {
|
||||||
if (data.meta.html5hack) {
|
if (data.meta.html5hack) {
|
||||||
return window.PLAYER = new VideoJSPlayer(data);
|
return window.PLAYER = new window.GoogleDrivePlayer(data);
|
||||||
} else {
|
} else {
|
||||||
return window.PLAYER = new GoogleDriveYouTubePlayer(data);
|
return window.PLAYER = new GoogleDriveYouTubePlayer(data);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue