diff --git a/channel.js b/channel.js index 9e2abf55..e49b030c 100644 --- a/channel.js +++ b/channel.js @@ -276,8 +276,7 @@ Channel.prototype.userJoin = function(user) { // Set the new guy up this.sendPlaylist(user); - if(user.playerReady) - this.sendMediaUpdate(user); + this.sendMediaUpdate(user); user.socket.emit("queueLock", {locked: this.qlocked}); this.sendUserlist(user); this.sendRecentChat(user); @@ -473,26 +472,26 @@ Channel.prototype.broadcastMotd = function() { // The server autolead function function mediaUpdate(chan, id) { // Bail cases - video changed, someone's leader, no video playing - if(chan.currentMedia == null || - id != chan.currentMedia.id || + if(chan.media == null || + id != chan.media.id || chan.leader != null) { return; } - chan.currentMedia.currentTime += (new Date().getTime() - chan.time) / 1000.0; + chan.media.currentTime += (new Date().getTime() - chan.time) / 1000.0; chan.time = new Date().getTime(); // Show's over, move on to the next thing - if(chan.currentMedia.currentTime > chan.currentMedia.seconds) { + if(chan.media.currentTime > chan.media.seconds) { chan.playNext(); } // Send updates about every 5 seconds else if(chan.i % 5 == 0) { - chan.sendAll("mediaUpdate", chan.currentMedia.packupdate()); + chan.sendAll("mediaUpdate", chan.media.packupdate()); } chan.i++; - setTimeout(function() { channelVideoUpdate(chan, id); }, 1000); + setTimeout(function() { mediaUpdate(chan, id); }, 1000); } Channel.prototype.enqueue = function(data) { @@ -534,7 +533,7 @@ Channel.prototype.enqueue = function(data) { }); break; case "tw": - var media = new Media(data.id, "Twitch ~ " + data.id, "--:--", "li"); + var media = new Media(data.id, "Twitch ~ " + data.id, "--:--", "tw"); this.queue.splice(idx, 0, media); this.sendAll("queue", { media: media.pack(), @@ -730,10 +729,10 @@ Channel.prototype.move = function(data) { }); // Account for moving things around the active video - if(data.src < this.position && data.dest >= this.currentPosition) { + if(data.src < this.position && data.dest >= this.position) { this.position--; } - else if(data.src > this.position && data.dest < this.currentPosition) { + else if(data.src > this.position && data.dest < this.position) { this.position++ } else if(data.src == this.position) { diff --git a/www/assets/js/callbacks.js b/www/assets/js/callbacks.js index 6193c201..1035592b 100644 --- a/www/assets/js/callbacks.js +++ b/www/assets/js/callbacks.js @@ -208,18 +208,13 @@ function initCallbacks() { $("#currenttitle").text("Currently Playing: " + data.title); if(data.type != "sc" && MEDIATYPE == "sc") fixSoundcloudShit(); - if(data.type == "yt") - updateYT(data); - else if(data.type == "tw") - loadTwitch(data.id); - else if(data.type == "li") - loadLivestream(data.id); - else if(data.type == "sc") - updateSC(data); - else if(data.type == "vi") - updateVI(data); - else if(data.type == "dm") - updateDM(data); + if(data.type != MEDIATYPE) { + MEDIATYPE = data.type; + PLAYER = new Media(data); + } + else { + PLAYER.update(data); + } }); socket.on("userlist", function(data) { @@ -239,6 +234,16 @@ function initCallbacks() { if(LEADER) { // I'm a leader! Set up sync function sendVideoUpdate = function() { + PLAYER.getTime(function(seconds) { + socket.emit("mediaUpdate", { + id: PLAYER.id, + seconds: seconds, + paused: false, + type: PLAYER.type + }); + }); + + /* if(MEDIATYPE == "yt") { socket.emit("mediaUpdate", { id: parseYTURL(PLAYER.getVideoUrl()), @@ -275,6 +280,7 @@ function initCallbacks() { 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 9d6bc0d0..1bd8e686 100644 --- a/www/assets/js/client.js +++ b/www/assets/js/client.js @@ -102,17 +102,6 @@ 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") { socket.emit("login", { name: uname, @@ -391,45 +380,7 @@ function synchtubeLayout() { } function onYouTubeIframeAPIReady() { - PLAYER = new YT.Player("ytapiplayer", { - height: VHEIGHT, - width: VWIDTH, - videoId: "", - playerVars: { - "autoplay": 0, - "controls": 1, - }, - events: { - "onReady": onPlayerReady, - "onStateChange": onPlayerStateChange - } - }); -} - -function onPlayerReady() { - socket.emit("playerReady"); -} - -function onPlayerStateChange(state) { - if(LEADER && state.data == YT.PlayerState.ENDED) { - socket.emit("playNext"); - } - else if(LEADER && state.data == YT.PlayerState.PAUSED) { - socket.emit("mediaUpdate", { - id: parseYTURL(PLAYER.getVideoUrl()), - seconds: PLAYER.getCurrentTime(), - type: "yt", - paused: true - }); - } - if(LEADER && state.data == YT.PlayerState.PLAYING) { - socket.emit("mediaUpdate", { - id: parseYTURL(PLAYER.getVideoUrl()), - seconds: PLAYER.getCurrentTime(), - type: "yt", - paused: false - }); - } + PLAYER = new Media({id: "", type: "yt"}); } function createCookie(name,value,days) { diff --git a/www/assets/js/functions.js b/www/assets/js/functions.js index 93e02cc7..e162efd3 100644 --- a/www/assets/js/functions.js +++ b/www/assets/js/functions.js @@ -317,172 +317,6 @@ function moveVideo(src, dest, noanim) { POSITION++; } -// YouTube Synchronization -function updateYT(data) { - if(MEDIATYPE != "yt") { - removeCurrentPlayer(); - MEDIATYPE = "yt"; - // Note to Soundcloud/Vimeo API designers: - // YouTube"s API is actually nice to use - PLAYER = new YT.Player("ytapiplayer", { - height: VHEIGHT, - width: VWIDTH, - videoId: "", - playerVars: { - "autoplay": 0, - "controls": 1, - }, - events: { - "onReady": onPlayerReady, - "onStateChange": onPlayerStateChange - } - }); - } - // Load new video - if(PLAYER.getVideoUrl && data.id != parseYTURL(PLAYER.getVideoUrl())) { - PLAYER.loadVideoById(data.id, data.currentTime, $("#quality").val()); - if(data.paused) - PLAYER.pauseVideo(); - } - // Sync playback time - else if(PLAYER.seekTo) { - if(Math.abs(PLAYER.getCurrentTime() - data.currentTime) > SYNC_THRESHOLD) - PLAYER.seekTo(data.currentTime, true); - if(!data.paused) - PLAYER.playVideo(); - } -} - -// Soundcloud synchronization -function updateSC(data) { - if(MEDIATYPE != "sc") { - unfixSoundcloudShit(); - var currentEmbed = $("#ytapiplayer"); - var iframe = $(""; - // $f() is defined by froogaloop, Vimeo"s API wrapper - PLAYER = $f($("iframe")[0]); - // So we can retrieve the ID synchronously instead of waiting for - // getVideoId with a callback - PLAYER.videoid = data.id; - PLAYER.addEvent("ready", function() { - // Autoplay - PLAYER.api("play"); - }); - MEDIATYPE = "vi"; -} - -function loadTwitch(channel) { - MEDIATYPE = "tw"; - - removeCurrentPlayer(); - var url = "http://www.twitch.tv/widgets/live_embed_player.swf?channel="+channel; - var params = { - allowFullScreen:"true", - allowScriptAccess:"always", - allowNetworking:"all", - movie:"http://www.twitch.tv/widgets/live_embed_player.swf", - id: "live_embed_player_flash", - flashvars:"hostname=www.twitch.tv&channel="+channel+"&auto_play=true&start_volume=100" - }; - swfobject.embedSWF( url, "ytapiplayer", VWIDTH, VHEIGHT, "8", null, null, params, {} ); -} - -function loadLivestream(channel) { - MEDIATYPE = "li"; - removeCurrentPlayer(); - flashvars = { channel: channel }; - params = { AllowScriptAccess: "always" }; - swfobject.embedSWF("http://cdn.livestream.com/chromelessPlayer/v20/playerapi.swf", "ytapiplayer", VWIDTH, VHEIGHT, "9.0.0", "expressInstall.swf", flashvars, params); -} - -function removeCurrentPlayer(){ - var currentEmbed = $("#ytapiplayer"); - var placeholder = $("
").insertBefore(currentEmbed); - currentEmbed.remove(); - placeholder.attr("id","ytapiplayer"); -} - function parseVideoURL(url){ url = url.trim() if(typeof(url) != "string") diff --git a/www/assets/js/media.js b/www/assets/js/media.js new file mode 100644 index 00000000..ad6db78f --- /dev/null +++ b/www/assets/js/media.js @@ -0,0 +1,243 @@ +var Media = function(data) { + this.id = data.id; + this.type = data.type; + + switch(this.type) { + case "yt": + this.initYouTube(); + break; + case "vi": + this.initVimeo(); + break; + case "dm": + this.initDailymotion(); + break; + case "sc": + this.initSoundcloud(); + break; + case "li": + this.initLivestream(); + break; + case "tw": + this.initTwitch(); + break; + default: + break; + } +} + +Media.prototype.initYouTube = function() { + this.removeOld(); + this.player = new YT.Player("ytapiplayer", { + height: VHEIGHT, + width: VWIDTH, + videoId: this.id, + playerVars: { + "autoplay": 1, + "controls": 1, + }, + events: { + onPlayerReady: function() { + socket.emit("playerReady"); + } + } + }); + + this.load = function(data) { + this.player.loadVideoById(data.id, data.currentTime); + this.id = data.id; + } + + this.pause = function() { + this.player.pauseVideo(); + } + + this.play = function() { + this.player.playVideo(); + } + + this.getTime = function(callback) { + callback(this.player.getCurrentTime()); + } + + this.seek = function(time) { + this.player.seekTo(time, true); + } +} + +Media.prototype.initVimeo = function() { + + var iframe = $("