From c0fc363f1b69f8f9c0a3f5f531daf5e9560bfdc0 Mon Sep 17 00:00:00 2001 From: calzoneman Date: Sat, 23 Mar 2013 13:17:39 -0500 Subject: [PATCH] Dailymotion support --- channel.js | 19 ++++++++++++++++ get-info.js | 37 +++++++++++++++++++++++++++++- www/assets/js/callbacks.js | 10 +++++++++ www/assets/js/client.js | 9 ++++++++ www/assets/js/functions.js | 46 +++++++++++++++++++++++++++++++++----- www/index.html | 1 + 6 files changed, 116 insertions(+), 6 deletions(-) diff --git a/channel.js b/channel.js index eef5a9e5..b849d731 100644 --- a/channel.js +++ b/channel.js @@ -419,6 +419,25 @@ Channel.prototype.enqueue = function(data) { InfoGetter.getVIInfo(data.id, callback); } + // Dailymotion + else if(data.type == "dm") { + var callback = (function(chan, id) { return function(res, data) { + if(res != 200) { + return; + } + + var seconds = data.duration; + var title = data.title; + var vid = new Media(id, title, seconds, "dm"); + chan.queue.splice(idx, 0, vid); + chan.sendAll('queue', { + media: vid.pack(), + pos: idx + }); + chan.addToLibrary(vid); + }})(this, data.id); + InfoGetter.getDMInfo(data.id, callback); + } } // Removes a media from the play queue diff --git a/get-info.js b/get-info.js index 2554d06b..3287fd7c 100644 --- a/get-info.js +++ b/get-info.js @@ -7,6 +7,7 @@ */ var http = require('http'); +var https = require('https'); // Helper function for making an HTTP request and getting the result // as JSON @@ -22,7 +23,30 @@ function getJSON(options, callback) { var data = JSON.parse(buffer); } catch(e) { - console.log("JSON fail: " + options); + console.log("JSON fail: ", options); + return; + } + callback(res.statusCode, data); + }); + }); + + req.end(); +}; + +// Dailymotion uses HTTPS for anonymous requests... [](/picard) +function getJSONHTTPS(options, callback) { + var req = https.request(options, function(res){ + var buffer = ''; + res.setEncoding('utf8'); + res.on('data', function (chunk) { + buffer += chunk; + }); + res.on('end', function() { + try { + var data = JSON.parse(buffer); + } + catch(e) { + console.log("JSON fail: ", options); return; } callback(res.statusCode, data); @@ -81,3 +105,14 @@ exports.getVIInfo = function(id, callback) { timeout: 1000}, callback); } +// Look up Dailymotion info +exports.getDMInfo = function(id, callback) { + var fields = "duration,title" + getJSONHTTPS({ + host: "api.dailymotion.com", + port: 443, + path: "/video/" + id + "?fields=" + fields, + method: "GET", + dataType: "jsonp", + timeout: 1000}, callback); +} diff --git a/www/assets/js/callbacks.js b/www/assets/js/callbacks.js index 6f96cdcc..6c9b1057 100644 --- a/www/assets/js/callbacks.js +++ b/www/assets/js/callbacks.js @@ -199,6 +199,8 @@ function initCallbacks() { updateSC(data); else if(data.type == "vi") updateVI(data); + else if(data.type == "dm") + updateDM(data); }); socket.on('userlist', function(data) { @@ -245,6 +247,14 @@ function initCallbacks() { }); }); } + else if(MEDIATYPE == "dm") { + socket.emit('mediaUpdate', { + id: PLAYER.mediaId, + seconds: PLAYER.currentTime, + paused: PLAYER.paused, + type: "dm" + }); + } }; } // I'm not a leader. Don't send syncs to the server diff --git a/www/assets/js/client.js b/www/assets/js/client.js index 33848229..7af06e9c 100644 --- a/www/assets/js/client.js +++ b/www/assets/js/client.js @@ -81,6 +81,15 @@ tag.src = "http://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); +// Load the Dailymotion iframe API + +/* +var tag = document.createElement('script'); +tag.src = "http://api.dmcdn.net/all.js"; +var firstScriptTag = document.getElementsByTagName('script')[0]; +firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); +*/ + if(uname != null && pw != null && pw != "false") { diff --git a/www/assets/js/functions.js b/www/assets/js/functions.js index aa997488..d426cbe0 100644 --- a/www/assets/js/functions.js +++ b/www/assets/js/functions.js @@ -335,6 +335,32 @@ function updateSC(data) { }); } +// Dailymotion synchronization +function updateDM(data) { + if(MEDIATYPE != "dm") { + console.log("updateDM: MEDIATYPE=", MEDIATYPE); + removeCurrentPlayer(); + PLAYER = DM.player("ytapiplayer", { + video: data.id, + width: 640, + height: 390, + params: {autoplay: 1} + }); + + PLAYER.mediaId = data.id; + MEDIATYPE = "dm"; + } + else if(PLAYER.mediaId != data.id) { + PLAYER.api("load", data.id); + PLAYER.mediaId = data.id; + } + else { + if(Math.abs(data.currentTime - PLAYER.currentTime) > SYNC_THRESHOLD) { + PLAYER.api("seek", data.currentTime); + } + } +} + // Vimeo synchronization // URGH building a synchronizing tool is so frustrating when // these APIs are designed to be async @@ -408,16 +434,18 @@ function removeCurrentPlayer(){ function parseVideoURL(url){ if(typeof(url) != "string") return null; - if(url.indexOf("youtu") != -1) + if(url.indexOf("youtu.be") != -1 || url.indexOf("youtube.com") != -1) return [parseYTURL(url), "yt"]; - else if(url.indexOf("twitch") != -1) + else if(url.indexOf("twitch.tv") != -1) return [parseTwitch(url), "tw"]; - else if(url.indexOf("livestream") != -1) + else if(url.indexOf("livestream.com") != -1) return [parseLivestream(url), "li"]; - else if(url.indexOf("soundcloud") != -1) + else if(url.indexOf("soundcloud.com") != -1) return [url, "sc"]; - else if(url.indexOf("vimeo") != -1) + else if(url.indexOf("vimeo.com") != -1) return [parseVimeo(url), "vi"]; + else if(url.indexOf("dailymotion.com") != -1) + return [parseDailymotion(url), "dm"]; } function parseYTURL(url) { @@ -470,6 +498,14 @@ function parseVimeo(url) { return null; } +function parseDailymotion(url) { + var m = url.match(/dailymotion\.com\/video\/([a-zA-Z0-9_-]+)/); + if(m) { + return m[1]; + } + return null; +} + function closePoll() { if($('#pollcontainer .active').length != 0) { var poll = $('#pollcontainer .active'); diff --git a/www/index.html b/www/index.html index 275b80a6..14677710 100644 --- a/www/index.html +++ b/www/index.html @@ -137,6 +137,7 @@ +