mirror of https://github.com/calzoneman/sync.git
Fixes; start refactoring clientside
This commit is contained in:
parent
42a76c4632
commit
5880be6f68
21
channel.js
21
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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 = $("<iframe/>").insertBefore(currentEmbed);
|
||||
currentEmbed.remove();
|
||||
iframe.attr("id","ytapiplayer");
|
||||
iframe.attr("src", "https://w.soundcloud.com/player/?url=");
|
||||
iframe.css("width", "100%").attr("height", "166")
|
||||
.attr("frameborder", "no");
|
||||
|
||||
PLAYER = SC.Widget("ytapiplayer");
|
||||
MEDIATYPE = "sc";
|
||||
}
|
||||
// Server is on a different soundcloud track than client
|
||||
if(PLAYER.mediaId != data.id) {
|
||||
PLAYER.load(data.id, {
|
||||
auto_play: true
|
||||
});
|
||||
// Keep track of current ID
|
||||
PLAYER.mediaId = data.id;
|
||||
}
|
||||
// Soundcloud"s API is async
|
||||
// Query the playback position and compare that with the sync packet
|
||||
PLAYER.getPosition(function(pos) {
|
||||
if(Math.abs(pos / 1000 - data.currentTime) > SYNC_THRESHOLD) {
|
||||
PLAYER.seekTo(data.currentTime * 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Dailymotion synchronization
|
||||
function updateDM(data) {
|
||||
if(MEDIATYPE != "dm") {
|
||||
removeCurrentPlayer();
|
||||
PLAYER = DM.player("ytapiplayer", {
|
||||
video: data.id,
|
||||
width: parseInt(VWIDTH),
|
||||
height: parseInt(VHEIGHT),
|
||||
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);
|
||||
}
|
||||
else if(PLAYER.currentTime > data.seconds || PLAYER.currentTime+"" == "NaN") {
|
||||
PLAYER.api("load", data.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Vimeo synchronization
|
||||
// URGH building a synchronizing tool is so frustrating when
|
||||
// these APIs are designed to be async
|
||||
function updateVI(data) {
|
||||
if(MEDIATYPE != "vi") {
|
||||
initVI(data);
|
||||
}
|
||||
// Either vimeo"s API doesn"t support loading a new video
|
||||
// or their terrible documentation doesn"t document it
|
||||
else if(data.id != PLAYER.videoid) {
|
||||
initVI(data);
|
||||
}
|
||||
|
||||
PLAYER.api("getCurrentTime", function(time) {
|
||||
if(Math.abs(time - data.currentTime) > SYNC_THRESHOLD) {
|
||||
PLAYER.api("seekTo", data.currentTime);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Loads up a Vimeo player
|
||||
function initVI(data) {
|
||||
var currentEmbed = $("#ytapiplayer");
|
||||
var div = currentEmbed.parent();
|
||||
currentEmbed.remove();
|
||||
// Ugly but it"s the only way I managed to get the API calls to work
|
||||
div[0].innerHTML += "<iframe id=\"ytapiplayer\" src=\"http://player.vimeo.com/video/" + data.id + "?api=1&player_id=ytapiplayer\" width=\"" + VWIDTH + "\" height=\"" + VHEIGHT + "\" frameborder=\"0\" webkitAllowFullScreen mozallowfullscreen allowFullScreen></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 = $("<div/>").insertBefore(currentEmbed);
|
||||
currentEmbed.remove();
|
||||
placeholder.attr("id","ytapiplayer");
|
||||
}
|
||||
|
||||
function parseVideoURL(url){
|
||||
url = url.trim()
|
||||
if(typeof(url) != "string")
|
||||
|
|
|
@ -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 = $("<iframe/>").insertBefore($("#ytapiplayer"));
|
||||
$("#ytapiplayer").remove();
|
||||
iframe.attr("id", "ytapiplayer");
|
||||
iframe.attr("width", VWIDTH);
|
||||
iframe.attr("height", VHEIGHT);
|
||||
iframe.attr("src", "http://player.vimeo.com/video/"+this.id+"?api=1&player_id=ytapiplayer");
|
||||
iframe.attr("webkitAllowFullScreen", "");
|
||||
iframe.attr("mozallowfullscreen", "");
|
||||
iframe.attr("allowFullScreen", "");
|
||||
iframe.css("border", "none");
|
||||
|
||||
this.player = $f(iframe[0]);
|
||||
$f(iframe[0]).addEvent("ready", function() {
|
||||
this.player = $f(iframe[0]);
|
||||
this.play();
|
||||
}.bind(this));
|
||||
|
||||
this.load = function(data) {
|
||||
this.id = data.id;
|
||||
this.initVimeo();
|
||||
}
|
||||
|
||||
this.pause = function() {
|
||||
this.player.api("pause");
|
||||
}
|
||||
|
||||
this.play = function() {
|
||||
this.player.api("play");
|
||||
}
|
||||
|
||||
this.getTime = function(callback) {
|
||||
this.player.api("getCurrentTime", callback);
|
||||
}
|
||||
|
||||
this.seek = function(time) {
|
||||
this.player.api("seekTo", time);
|
||||
}
|
||||
}
|
||||
|
||||
Media.prototype.initDailymotion = function() {
|
||||
this.removeOld();
|
||||
this.player = DM.player("ytapiplayer", {
|
||||
video: this.id,
|
||||
width: parseInt(VWIDTH),
|
||||
height: parseInt(VHEIGHT),
|
||||
params: {autoplay: 1}
|
||||
});
|
||||
|
||||
this.load = function(data) {
|
||||
this.id = data.id;
|
||||
this.player.api("load", data.id);
|
||||
}
|
||||
|
||||
this.pause = function() {
|
||||
this.player.api("pause");
|
||||
}
|
||||
|
||||
this.play = function() {
|
||||
this.player.api("play");
|
||||
}
|
||||
|
||||
this.getTime = function(callback) {
|
||||
callback(this.player.currentTime);
|
||||
}
|
||||
|
||||
this.seek = function(seconds) {
|
||||
this.player.api("seek", seconds);
|
||||
}
|
||||
}
|
||||
|
||||
Media.prototype.initSoundcloud = function() {
|
||||
unfixSoundcloudShit();
|
||||
var iframe = $("<iframe/>").insertBefore($("#ytapiplayer"));
|
||||
$("#ytapiplayer").remove();
|
||||
|
||||
iframe.attr("id", "ytapiplayer");
|
||||
iframe.attr("src", "https://w.soundcloud.com/player/?url=" + this.id);
|
||||
iframe.css("width", "100%").attr("height", "166");
|
||||
iframe.css("border", "none");
|
||||
|
||||
this.player = SC.Widget("ytapiplayer");
|
||||
setTimeout(function() { this.play(); }.bind(this), 1000);
|
||||
|
||||
this.load = function(data) {
|
||||
this.id = data.id;
|
||||
this.player.load(data.id, {auto_play: true});
|
||||
}
|
||||
|
||||
this.pause = function() {
|
||||
this.player.pause();
|
||||
}
|
||||
|
||||
this.play = function() {
|
||||
this.player.play();
|
||||
}
|
||||
|
||||
this.getTime = function(callback) {
|
||||
this.player.getPosition(function(pos) {
|
||||
callback(pos / 1000);
|
||||
});
|
||||
}
|
||||
|
||||
this.seek = function(seconds) {
|
||||
this.player.seekTo(seconds * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
Media.prototype.initLivestream = function() {
|
||||
this.removeOld();
|
||||
var flashvars = {channel: this.id};
|
||||
var params = {AllowScriptAccess: "always"};
|
||||
swfobject.embedSWF("http://cdn.livestream.com/chromelessPlayer/v20/playerapi.swf", "ytapiplayer", VWIDTH, VHEIGHT, "9.0.0", "expressInstall.swf", flashvars, params);
|
||||
|
||||
this.load = function(data) {
|
||||
this.id = data.id;
|
||||
this.initLivestream();
|
||||
}
|
||||
|
||||
this.pause = function() { }
|
||||
|
||||
this.play = function() { }
|
||||
|
||||
this.getTime = function() { }
|
||||
|
||||
this.seek = function() { }
|
||||
}
|
||||
|
||||
Media.prototype.initTwitch = function() {
|
||||
this.removeOld();
|
||||
var url = "http://www.twitch.tv/widgets/live_embed_player.swf?channel="+this.id;
|
||||
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="+this.id+"&auto_play=true&start_volume=100"
|
||||
};
|
||||
swfobject.embedSWF( url, "ytapiplayer", VWIDTH, VHEIGHT, "8", null, null, params, {} );
|
||||
|
||||
this.load = function(data) {
|
||||
this.id = data.id;
|
||||
this.initTwitch();
|
||||
}
|
||||
|
||||
this.pause = function() { }
|
||||
|
||||
this.play = function() { }
|
||||
|
||||
this.getTime = function() { }
|
||||
|
||||
this.seek = function() { }
|
||||
}
|
||||
|
||||
Media.prototype.update = function(data) {
|
||||
if(data.id != this.id) {
|
||||
this.load(data);
|
||||
}
|
||||
if(data.paused) {
|
||||
this.pause();
|
||||
}
|
||||
this.getTime(function(seconds) {
|
||||
if(Math.abs(data.currentTime - seconds) > SYNC_THRESHOLD) {
|
||||
this.seek(data.currentTime);
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
Media.prototype.removeOld = function() {
|
||||
var old = $("#ytapiplayer");
|
||||
var placeholder = $("<div/>").insertBefore(old);
|
||||
old.remove();
|
||||
placeholder.attr("id", "ytapiplayer");
|
||||
}
|
|
@ -208,6 +208,7 @@
|
|||
<script src="./assets/js/functions.js"></script>
|
||||
<script src="./assets/js/callbacks.js"></script>
|
||||
<script src="./assets/js/iourl.js"></script>
|
||||
<script src="./assets/js/media.js"></script>
|
||||
<script src="./assets/js/client.js"></script>
|
||||
<script src="./assets/js/swf.js"></script>
|
||||
|
||||
|
|
Loading…
Reference in New Issue