From fe9ebfa6b1f386243ce486fbf416ec37d05b6ebd Mon Sep 17 00:00:00 2001 From: calzoneman Date: Fri, 15 May 2015 00:03:05 -0500 Subject: [PATCH] Start working on VideoJS for Google Drive --- lib/get-info.js | 109 ++++++----------------------- player/update.coffee | 1 + player/videojs.coffee | 121 +++++++++++++++++++++++++++++++- templates/channel.jade | 2 + www/js/player-new.js | 154 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 293 insertions(+), 94 deletions(-) diff --git a/lib/get-info.js b/lib/get-info.js index 52a36813..f610afe4 100644 --- a/lib/get-info.js +++ b/lib/get-info.js @@ -7,7 +7,7 @@ var CustomEmbedFilter = require("./customembed").filter; var Server = require("./server"); var Config = require("./config"); var ffmpeg = require("./ffmpeg"); -require("cytube-mediaquery"); // Initialize sourcemaps +var mediaquery = require("cytube-mediaquery"); var YouTube = require("cytube-mediaquery/lib/provider/youtube"); /* @@ -62,6 +62,17 @@ var urlRetrieve = function (transport, options, callback) { req.end(); }; +var mediaTypeMap = { + "youtube": "yt", + "googledrive": "gd", + "google+": "gp" +}; + +function convertMedia(media) { + return new Media(media.id, media.title, media.duration, mediaTypeMap[media.type], + media.meta); +} + var Getters = { /* youtube.com */ yt: function (id, callback) { @@ -506,96 +517,16 @@ var Getters = { /* google docs */ gd: function (id, callback) { - /* WARNING: hacks inbound */ - var options = { - host: "docs.google.com", - path: "/file/d/" + id + "/get_video_info?sle=true", - port: 443 + var data = { + type: "googledrive", + kind: "single", + id: id }; - urlRetrieve(https, options, function (status, res) { - switch (status) { - case 200: - break; /* Request is OK, skip to handling data */ - case 400: - return callback("Invalid request", null); - case 403: - return callback("Private video", null); - case 404: - return callback("Video not found", null); - case 500: - case 503: - return callback("Service unavailable", null); - default: - return callback("HTTP " + status, null); - } - - try { - - var data = {}; - res.split("&").forEach(function (urlparam) { - var pair = urlparam.split("=").map(decodeURIComponent).map( - function (s) { return s.replace(/\+/g, ' '); }); - data[pair[0]] = pair[1]; - }); - - if (data.hasOwnProperty("reason")) { - var reason = data.reason; - if (reason.indexOf("Unable to play this video at this time.") === 0) { - reason = "There is currently a bug with Google Drive which prevents playback " + - "of videos 1 hour long or longer."; - } else if (reason.indexOf( - "You must be signed in to access this video") >= 0) { - reason = "This video is not shared properly"; - } - - - return callback(reason); - } - - if (!data.hasOwnProperty("title")) { - return callback("Returned HTML is missing the video title. Are you " + - "sure the video is done processing?"); - } - - if (!data.hasOwnProperty("length_seconds")) { - return callback("Returned HTML is missing the video duration. Are you " + - "sure the video is done processing?"); - } - - var title = data.title; - var seconds = parseInt(data.length_seconds); - - var videos = {}; - data.fmt_stream_map.split(",").forEach(function (stream) { - var parts = stream.split("|"); - videos[parts[0]] = parts[1]; - }); - - var direct = {}; - - for (var key in GOOGLE_PREFERENCE) { - for (var i = 0; i < GOOGLE_PREFERENCE[key].length; i++) { - var format = GOOGLE_PREFERENCE[key][i]; - - if (format in videos) { - direct[key] = { - url: videos[format], - contentType: CONTENT_TYPES[format] - }; - break; - } - } - } - - if (Object.keys(direct).length === 0) { - return callback("No valid links could be extracted", null); - } - - callback(null, new Media(id, title, seconds, "gd", { gpdirect: direct })); - } catch (e) { - return callback("Failed to parse Google Docs output", null); - } + mediaquery.lookup(data).then(function (video) { + callback(null, convertMedia(video)); + }).catch(function (err) { + callback(err.message || err); }); }, diff --git a/player/update.coffee b/player/update.coffee index 4a22c42f..2f8a5cfc 100644 --- a/player/update.coffee +++ b/player/update.coffee @@ -2,6 +2,7 @@ TYPE_MAP = yt: YouTubePlayer vi: VimeoPlayer dm: DailymotionPlayer + gd: VideoJSPlayer window.loadMediaPlayer = (data) -> if data.type of TYPE_MAP diff --git a/player/videojs.coffee b/player/videojs.coffee index 0def6f76..ea745146 100644 --- a/player/videojs.coffee +++ b/player/videojs.coffee @@ -1,6 +1,121 @@ -class VideoJSPlayer extends Player +sortSources = (sources) -> + if not sources + console.error('sortSources() called with null source list') + return [] + + qualities = ['1080', '720', '480', '360', '240'] + pref = String(USEROPTS.default_quality) + idx = qualities.indexOf(pref) + if idx < 0 + pref = '480' + + qualityOrder = qualities.slice(idx).concat(qualities.slice(0, idx)) + sourceOrder = [] + flvOrder = [] + for quality in qualityOrder + if quality of sources + flv = [] + nonflv = [] + sources[quality].forEach((source) -> + if source.contentType == 'flv' + flv.push(source) + else + nonflv.push(source) + ) + sourceOrder = sourceOrder.concat(nonflv) + flvOrder = flvOrder.concat(flv) + + return sourceOrder.concat(flvOrder).map((source) -> + type: "video/#{source.contentType}" + src: source.link + ) + +window.VideoJSPlayer = class VideoJSPlayer extends Player constructor: (data) -> + if not (this instanceof VideoJSPlayer) + return new VideoJSPlayer(data) + + @setMediaProperties(data) + + waitUntilDefined(window, 'videojs', => + video = $('