2014-02-03 02:04:50 +00:00
|
|
|
/*}
|
2013-06-11 15:29:21 +00:00
|
|
|
The MIT License (MIT)
|
|
|
|
Copyright (c) 2013 Calvin Montgomery
|
2013-07-28 14:49:12 +00:00
|
|
|
|
2013-06-11 15:29:21 +00:00
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
2013-07-28 14:49:12 +00:00
|
|
|
|
2013-06-11 15:29:21 +00:00
|
|
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
2013-07-28 14:49:12 +00:00
|
|
|
|
2013-06-11 15:29:21 +00:00
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2013-07-28 14:49:12 +00:00
|
|
|
var VIMEO_FLASH = false;
|
|
|
|
|
2013-08-04 16:16:19 +00:00
|
|
|
function removeOld(replace) {
|
2013-08-07 18:25:08 +00:00
|
|
|
$("#sc_volume").remove();
|
2013-08-04 16:16:19 +00:00
|
|
|
replace = replace || $("<div/>");
|
|
|
|
var old = $("#ytapiplayer");
|
|
|
|
replace.insertBefore(old);
|
|
|
|
old.remove();
|
|
|
|
replace.attr("id", "ytapiplayer");
|
|
|
|
}
|
|
|
|
|
|
|
|
var YouTubePlayer = function (data) {
|
|
|
|
var self = this;
|
|
|
|
waitUntilDefined(window, "YT", function () {
|
2013-08-06 15:42:20 +00:00
|
|
|
waitUntilDefined(YT, "Player", function () {
|
|
|
|
removeOld();
|
|
|
|
self.paused = false;
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 15:42:20 +00:00
|
|
|
var wmode = USEROPTS.wmode_transparent ? "transparent" : "opaque";
|
|
|
|
self.player = new YT.Player("ytapiplayer", {
|
|
|
|
height: VHEIGHT,
|
|
|
|
width: VWIDTH,
|
|
|
|
videoId: data.id,
|
|
|
|
playerVars: {
|
|
|
|
autohide: 1, // Autohide controls
|
|
|
|
autoplay: 1, // Autoplay video
|
|
|
|
controls: 1, // Show controls
|
|
|
|
iv_load_policy: 3, // No annotations
|
|
|
|
rel: 0, // No related videos
|
|
|
|
wmode: wmode
|
2013-08-04 16:16:19 +00:00
|
|
|
},
|
2013-08-06 15:42:20 +00:00
|
|
|
events: {
|
|
|
|
onReady: function () {
|
2014-02-03 02:04:50 +00:00
|
|
|
PLAYER.setVolume(VOLUME);
|
2014-02-28 14:43:04 +00:00
|
|
|
$("#ytapiplayer").width(VWIDTH).height(VHEIGHT);
|
2013-08-06 15:42:20 +00:00
|
|
|
},
|
|
|
|
onStateChange: function (ev) {
|
|
|
|
if(PLAYER.paused && ev.data != YT.PlayerState.PAUSED ||
|
|
|
|
!PLAYER.paused && ev.data == YT.PlayerState.PAUSED) {
|
|
|
|
self.paused = (ev.data == YT.PlayerState.PAUSED);
|
|
|
|
if(CLIENT.leader)
|
|
|
|
sendVideoUpdate();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
self.paused = (ev.data == YT.PlayerState.PAUSED);
|
|
|
|
}
|
|
|
|
if(CLIENT.leader && ev.data == YT.PlayerState.ENDED) {
|
|
|
|
socket.emit("playNext");
|
|
|
|
}
|
2013-08-04 16:16:19 +00:00
|
|
|
}
|
|
|
|
}
|
2013-08-06 15:42:20 +00:00
|
|
|
});
|
|
|
|
$("#ytapiplayer").css("border", "none");
|
2013-08-04 16:16:19 +00:00
|
|
|
});
|
|
|
|
});
|
2013-08-06 15:42:20 +00:00
|
|
|
|
|
|
|
self.load = function (data) {
|
|
|
|
if(self.player && self.player.loadVideoById) {
|
|
|
|
self.player.loadVideoById(data.id, data.currentTime);
|
2014-02-15 18:43:10 +00:00
|
|
|
if (USEROPTS.default_quality) {
|
|
|
|
self.player.setPlaybackQuality(USEROPTS.default_quality);
|
2013-10-17 02:50:31 +00:00
|
|
|
// What's that? Another stupid hack for the HTML5 player?
|
2014-02-15 18:43:10 +00:00
|
|
|
self.player.setPlaybackQuality(USEROPTS.default_quality);
|
2013-10-17 02:50:31 +00:00
|
|
|
}
|
2013-08-06 15:42:20 +00:00
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 15:42:20 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.pause = function () {
|
|
|
|
if(self.player && self.player.pauseVideo)
|
|
|
|
self.player.pauseVideo();
|
|
|
|
};
|
|
|
|
|
|
|
|
self.play = function () {
|
|
|
|
if(self.player && self.player.playVideo)
|
|
|
|
self.player.playVideo();
|
|
|
|
};
|
|
|
|
|
|
|
|
self.isPaused = function (callback) {
|
|
|
|
if(self.player && self.player.getPlayerState) {
|
|
|
|
var state = self.player.getPlayerState();
|
|
|
|
callback(state != YT.PlayerState.PLAYING);
|
|
|
|
} else {
|
|
|
|
callback(false);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.getTime = function (callback) {
|
|
|
|
if(self.player && self.player.getCurrentTime)
|
|
|
|
callback(self.player.getCurrentTime());
|
|
|
|
};
|
|
|
|
|
|
|
|
self.seek = function (time) {
|
|
|
|
if(self.player && self.player.seekTo)
|
|
|
|
self.player.seekTo(time, true);
|
|
|
|
};
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function (cb) {
|
|
|
|
if (!self.player || !self.player.getVolume || !self.player.isMuted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// YouTube's API is strange in the sense that getVolume() returns
|
|
|
|
// the regular (unmuted) volume even if it is muted...
|
|
|
|
// YouTube's volume is 0..100, normalize it to 0..1
|
|
|
|
var vol = self.player.isMuted() ? 0 : (self.player.getVolume() / 100);
|
|
|
|
cb(vol);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.setVolume = function (vol) {
|
|
|
|
if (self.player && self.player.setVolume) {
|
|
|
|
if (vol > 0) {
|
|
|
|
self.player.unMute();
|
|
|
|
}
|
|
|
|
self.player.setVolume(vol * 100);
|
|
|
|
}
|
|
|
|
};
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-08-04 16:16:19 +00:00
|
|
|
|
|
|
|
var VimeoPlayer = function (data) {
|
|
|
|
var self = this;
|
|
|
|
waitUntilDefined(window, "$f", function () {
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-04 16:16:19 +00:00
|
|
|
self.init = function () {
|
|
|
|
var iframe = $("<iframe/>");
|
|
|
|
removeOld(iframe);
|
2013-09-10 22:18:02 +00:00
|
|
|
var prto = location.protocol;
|
|
|
|
iframe.attr("src", prto+"//player.vimeo.com/video/"+self.videoId+"?api=1&player_id=ytapiplayer");
|
2013-08-04 16:16:19 +00:00
|
|
|
iframe.attr("webkitAllowFullScreen", "");
|
|
|
|
iframe.attr("mozallowfullscreen", "");
|
|
|
|
iframe.attr("allowFullScreen", "");
|
2013-08-06 15:42:20 +00:00
|
|
|
if(USEROPTS.wmode_transparent)
|
|
|
|
iframe.attr("wmode", "transparent");
|
2013-08-04 16:16:19 +00:00
|
|
|
iframe.css("border", "none");
|
2014-02-28 14:43:04 +00:00
|
|
|
iframe.width(VWIDTH);
|
|
|
|
iframe.height(VHEIGHT);
|
2013-08-04 16:16:19 +00:00
|
|
|
|
|
|
|
$f(iframe[0]).addEvent("ready", function () {
|
|
|
|
self.player = $f(iframe[0]);
|
|
|
|
self.player.api("play");
|
|
|
|
|
|
|
|
self.player.addEvent("finish", function () {
|
|
|
|
if(CLIENT.leader) {
|
|
|
|
socket.emit("playNext");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
self.player.addEvent("pause", function () {
|
|
|
|
self.paused = true;
|
|
|
|
if(CLIENT.leader)
|
|
|
|
sendVideoUpdate();
|
|
|
|
});
|
|
|
|
|
|
|
|
self.player.addEvent("play", function () {
|
|
|
|
self.paused = false;
|
|
|
|
if(CLIENT.leader)
|
|
|
|
sendVideoUpdate();
|
|
|
|
});
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.setVolume(VOLUME);
|
2013-08-04 16:16:19 +00:00
|
|
|
}.bind(self));
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-08-04 16:16:19 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.load = function (data) {
|
2013-08-04 16:16:19 +00:00
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-04 16:16:19 +00:00
|
|
|
self.init();
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-08-04 16:16:19 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.pause = function () {
|
2013-08-04 16:16:19 +00:00
|
|
|
if(self.player && self.player.api)
|
|
|
|
self.player.api("pause");
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-08-04 16:16:19 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.play = function () {
|
2013-08-04 16:16:19 +00:00
|
|
|
if(self.player && self.player.api)
|
|
|
|
self.player.api("play");
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-08-04 16:16:19 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.isPaused = function (callback) {
|
2013-08-04 16:16:19 +00:00
|
|
|
callback(self.paused);
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-08-04 16:16:19 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.getTime = function (callback) {
|
2013-08-04 16:16:19 +00:00
|
|
|
if(self.player && self.player.api) {
|
|
|
|
// Vimeo api returns time as a string because fuck logic
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player.api("getCurrentTime", function (time) {
|
2013-08-04 16:16:19 +00:00
|
|
|
callback(parseFloat(time));
|
|
|
|
});
|
|
|
|
}
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-08-04 16:16:19 +00:00
|
|
|
|
|
|
|
self.seek = function(time) {
|
|
|
|
if(self.player && self.player.api)
|
|
|
|
self.player.api("seekTo", time);
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function (cb) {
|
|
|
|
if (self.player && self.player.api) {
|
|
|
|
self.player.api("getVolume", cb);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.setVolume = function (vol) {
|
|
|
|
self.player.api("setVolume", vol);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.init();
|
2013-06-11 15:29:21 +00:00
|
|
|
});
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
var VimeoFlashPlayer = function (data) {
|
|
|
|
var self = this;
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-05 04:19:10 +00:00
|
|
|
self.init = function () {
|
|
|
|
removeOld();
|
2013-09-10 22:18:02 +00:00
|
|
|
var prto = location.protocol;
|
|
|
|
var url = prto+"//vimeo.com/moogaloop.swf?clip_id="+self.videoId;
|
2013-08-05 04:19:10 +00:00
|
|
|
url += "&" + [
|
|
|
|
"server=vimeo.com",
|
|
|
|
"api=2",
|
|
|
|
"show_title=0",
|
|
|
|
"show_byline=0",
|
|
|
|
"show_portrait=0",
|
|
|
|
"fullscreen=1",
|
|
|
|
"loop=0"
|
|
|
|
].join("&");
|
|
|
|
var flashvars = {
|
|
|
|
api: 2,
|
|
|
|
player_id: "ytapiplayer"
|
|
|
|
};
|
|
|
|
var params = {
|
|
|
|
allowfullscreen: true,
|
2013-08-06 15:42:20 +00:00
|
|
|
allowScriptAccess: "always",
|
|
|
|
wmode: USEROPTS.wmode_transparent ? "transparent" : undefined
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
|
|
|
swfobject.embedSWF(url,
|
|
|
|
"ytapiplayer",
|
|
|
|
VWIDTH,
|
|
|
|
VHEIGHT,
|
|
|
|
"9.0.0",
|
|
|
|
"expressInstall.swf",
|
|
|
|
flashvars,
|
|
|
|
params);
|
|
|
|
|
|
|
|
self.player = $("#ytapiplayer")[0];
|
|
|
|
waitUntilDefined(self.player, "api_addEventListener", function () {
|
|
|
|
self.player.api_addEventListener("ready", function () {
|
|
|
|
self.player.api_play();
|
2013-07-12 20:34:55 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player.api_addEvent("finish", function () {
|
|
|
|
if(CLIENT.leader)
|
|
|
|
socket.emit("playNext");
|
|
|
|
});
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player.api_addEvent("pause", function () {
|
|
|
|
PLAYER.paused = true;
|
|
|
|
if(CLIENT.leader)
|
|
|
|
sendVideoUpdate();
|
|
|
|
});
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player.api_addEvent("play", function () {
|
|
|
|
PLAYER.paused = false;
|
|
|
|
if(CLIENT.leader)
|
|
|
|
sendVideoUpdate();
|
|
|
|
});
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.setVolume(VOLUME);
|
2013-08-05 04:19:10 +00:00
|
|
|
});
|
2013-06-11 15:29:21 +00:00
|
|
|
});
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.load = function (data) {
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-05 04:19:10 +00:00
|
|
|
self.init();
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.pause = function () {
|
|
|
|
if(self.player && self.player.api_pause)
|
|
|
|
self.player.api_pause();
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.play = function () {
|
|
|
|
if(self.player && self.player.api_play)
|
|
|
|
self.player.api_play();
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.isPaused = function (callback) {
|
|
|
|
callback(self.paused);
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.getTime = function (callback) {
|
|
|
|
if(self.player && self.player.api_getCurrentTime) {
|
|
|
|
var t = parseFloat(self.player.api_getCurrentTime());
|
|
|
|
callback(t);
|
|
|
|
}
|
|
|
|
};
|
2013-07-12 20:34:55 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.seek = function (time) {
|
|
|
|
if(self.player.api_seekTo);
|
|
|
|
self.player.api_seekTo(time);
|
|
|
|
};
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function (cb) {
|
|
|
|
if (self.player && self.player.api_getVolume) {
|
|
|
|
cb(self.player.api_getVolume());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.setVolume = function (vol) {
|
|
|
|
self.player.api_setVolume(vol);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.init();
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
var DailymotionPlayer = function (data) {
|
|
|
|
var self = this;
|
|
|
|
waitUntilDefined(window, "DM", function () {
|
|
|
|
removeOld();
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player = DM.player("ytapiplayer", {
|
|
|
|
video: data.id,
|
2013-08-06 02:55:11 +00:00
|
|
|
width: parseInt(VWIDTH, 10),
|
|
|
|
height: parseInt(VHEIGHT, 10),
|
2013-08-05 04:19:10 +00:00
|
|
|
params: { autoplay: 1 }
|
|
|
|
});
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player.addEventListener("apiready", function (e) {
|
|
|
|
self.player.addEventListener("ended", function (e) {
|
|
|
|
if(CLIENT.leader) {
|
2013-07-28 14:49:12 +00:00
|
|
|
socket.emit("playNext");
|
2013-08-05 04:19:10 +00:00
|
|
|
}
|
2013-07-28 14:49:12 +00:00
|
|
|
});
|
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player.addEventListener("pause", function (e) {
|
2013-07-28 14:49:12 +00:00
|
|
|
PLAYER.paused = true;
|
2013-08-05 04:19:10 +00:00
|
|
|
if(CLIENT.leader)
|
|
|
|
sendVideoUpdate();
|
2013-07-28 14:49:12 +00:00
|
|
|
});
|
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player.addEventListener("playing", function (e) {
|
2013-07-28 14:49:12 +00:00
|
|
|
PLAYER.paused = false;
|
2013-08-05 04:19:10 +00:00
|
|
|
if(CLIENT.leader)
|
|
|
|
sendVideoUpdate();
|
2014-02-03 02:04:50 +00:00
|
|
|
if (!self.volumeIsSet) {
|
|
|
|
try {
|
|
|
|
self.setVolume(VOLUME);
|
|
|
|
self.volumeIsSet = true;
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2013-07-28 14:49:12 +00:00
|
|
|
});
|
2013-06-11 15:29:21 +00:00
|
|
|
});
|
2013-08-05 04:19:10 +00:00
|
|
|
});
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.load = function (data) {
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2014-02-03 02:04:50 +00:00
|
|
|
if (self.player && self.player.api) {
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player.api("load", data.id);
|
2014-02-03 02:04:50 +00:00
|
|
|
}
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.pause = function () {
|
|
|
|
if(self.player && self.player.api)
|
|
|
|
self.player.api("pause");
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.play = function () {
|
|
|
|
if(self.player && self.player.api)
|
|
|
|
self.player.api("play");
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.isPaused = function (callback) {
|
|
|
|
callback(self.paused);
|
|
|
|
};
|
2013-07-12 20:34:55 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.getTime = function (callback) {
|
|
|
|
if(self.player)
|
|
|
|
callback(self.player.currentTime);
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.seek = function (seconds) {
|
|
|
|
if(self.player && self.player.api)
|
|
|
|
self.player.api("seek", seconds);
|
|
|
|
};
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function (cb) {
|
|
|
|
if (self.player) {
|
|
|
|
cb(self.player.volume);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.setVolume = function (vol) {
|
|
|
|
if (self.player && self.player.api) {
|
|
|
|
self.player.api("volume", vol);
|
|
|
|
}
|
|
|
|
};
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
var SoundcloudPlayer = function (data) {
|
|
|
|
var self = this;
|
2014-02-03 02:04:50 +00:00
|
|
|
// The getVolume function on their widget throws TypeErrors
|
|
|
|
// Go figure
|
|
|
|
self.soundcloudIsSeriouslyFuckingBroken = VOLUME;
|
2013-08-05 04:19:10 +00:00
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-05 04:19:10 +00:00
|
|
|
waitUntilDefined(window, "SC", function () {
|
|
|
|
unfixSoundcloudShit();
|
|
|
|
var iframe = $("<iframe/>");
|
|
|
|
removeOld(iframe);
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
iframe.attr("id", "ytapiplayer");
|
|
|
|
iframe.attr("src", "https://w.soundcloud.com/player/?url="+self.videoId);
|
|
|
|
iframe.css("width", "100%").attr("height", "166");
|
|
|
|
iframe.css("border", "none");
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-07 18:25:08 +00:00
|
|
|
var volslider = $("<div/>").attr("id", "sc_volume")
|
|
|
|
.insertAfter(iframe);
|
|
|
|
|
|
|
|
volslider.slider({
|
|
|
|
range: "min",
|
2014-02-03 02:04:50 +00:00
|
|
|
value: VOLUME * 100,
|
2013-08-07 18:25:08 +00:00
|
|
|
stop: function (event, ui) {
|
|
|
|
self.player.setVolume(ui.value);
|
2014-02-03 02:04:50 +00:00
|
|
|
self.soundcloudIsSeriouslyFuckingBroken = ui.value / 100;
|
2013-08-07 18:25:08 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player = SC.Widget("ytapiplayer");
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player.bind(SC.Widget.Events.READY, function () {
|
|
|
|
self.player.load(self.videoId, { auto_play: true });
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player.bind(SC.Widget.Events.PAUSE, function () {
|
|
|
|
PLAYER.paused = true;
|
|
|
|
if(CLIENT.leader)
|
|
|
|
sendVideoUpdate();
|
|
|
|
});
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2014-02-03 02:04:50 +00:00
|
|
|
self.player.bind(SC.Widget.Events.FINISH, function () {
|
|
|
|
if(CLIENT.leader) {
|
|
|
|
socket.emit("playNext");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player.bind(SC.Widget.Events.PLAY, function () {
|
|
|
|
PLAYER.paused = false;
|
|
|
|
if(CLIENT.leader)
|
|
|
|
sendVideoUpdate();
|
|
|
|
});
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2014-02-03 02:04:50 +00:00
|
|
|
// THAT'S RIGHT, YOU CAN'T SET THE VOLUME BEFORE IT STARTS PLAYING
|
|
|
|
var soundcloudNeedsToFuckingFixTheirPlayer = function () {
|
|
|
|
self.setVolume(VOLUME);
|
|
|
|
self.player.unbind(SC.Widget.Events.PLAY_PROGRESS);
|
|
|
|
};
|
|
|
|
self.player.bind(SC.Widget.Events.PLAY_PROGRESS, soundcloudNeedsToFuckingFixTheirPlayer);
|
2013-08-05 04:19:10 +00:00
|
|
|
}.bind(self));
|
|
|
|
});
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.load = function (data) {
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2014-02-03 02:04:50 +00:00
|
|
|
if(self.player && self.player.load) {
|
2013-08-05 04:19:10 +00:00
|
|
|
self.player.load(data.id, { auto_play: true });
|
2014-02-03 02:04:50 +00:00
|
|
|
var soundcloudNeedsToFuckingFixTheirPlayer = function () {
|
|
|
|
self.setVolume(VOLUME);
|
|
|
|
self.player.unbind(SC.Widget.Events.PLAY_PROGRESS);
|
|
|
|
};
|
|
|
|
self.player.bind(SC.Widget.Events.PLAY_PROGRESS, soundcloudNeedsToFuckingFixTheirPlayer);
|
|
|
|
}
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.pause = function () {
|
|
|
|
if(self.player && self.player.pause)
|
|
|
|
self.player.pause();
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.play = function () {
|
|
|
|
if(self.player && self.player.play)
|
|
|
|
self.player.play();
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.isPaused = function (callback) {
|
|
|
|
if(self.player && self.player.isPaused)
|
|
|
|
self.player.isPaused(callback);
|
|
|
|
else
|
|
|
|
callback(false);
|
|
|
|
};
|
2013-07-12 20:34:55 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.getTime = function (callback) {
|
|
|
|
if(self.player && self.player.getPosition) {
|
|
|
|
self.player.getPosition(function (pos) {
|
|
|
|
callback(pos / 1000);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-05 04:19:10 +00:00
|
|
|
self.seek = function (seconds) {
|
|
|
|
if(self.player && self.player.seekTo)
|
|
|
|
self.player.seekTo(seconds * 1000);
|
|
|
|
};
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function (cb) {
|
|
|
|
cb(self.soundcloudIsSeriouslyFuckingBroken);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.setVolume = function (vol) {
|
|
|
|
self.player.setVolume(vol * 100);
|
|
|
|
};
|
2013-08-05 04:19:10 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
var LivestreamPlayer = function (data) {
|
|
|
|
removeOld();
|
|
|
|
var self = this;
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.init = function () {
|
|
|
|
var flashvars = { channel: self.videoId };
|
|
|
|
var params = { AllowScriptAccess: "always" };
|
2013-09-10 22:18:02 +00:00
|
|
|
var prto = location.protocol;
|
2013-08-06 02:46:56 +00:00
|
|
|
swfobject.embedSWF(
|
2013-09-10 22:18:02 +00:00
|
|
|
prto+"//cdn.livestream.com/chromelessPlayer/v20/playerapi.swf",
|
2013-08-06 02:46:56 +00:00
|
|
|
"ytapiplayer",
|
|
|
|
VWIDTH, VHEIGHT,
|
|
|
|
"9.0.0",
|
|
|
|
"expressInstall.swf",
|
|
|
|
flashvars,
|
|
|
|
params
|
|
|
|
);
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.load = function(data) {
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.init();
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.pause = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.play = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.isPaused = function () { };
|
2013-07-12 20:34:55 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.getTime = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.seek = function () { };
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function () { };
|
|
|
|
|
|
|
|
self.setVolume = function () { };
|
|
|
|
|
2014-02-24 05:27:07 +00:00
|
|
|
waitUntilDefined(window, "swfobject", function () {
|
|
|
|
self.init();
|
|
|
|
});
|
2013-08-06 02:55:11 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
var TwitchTVPlayer = function (data) {
|
|
|
|
removeOld();
|
|
|
|
var self = this;
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.init = function () {
|
|
|
|
var url = "http://www.twitch.tv/widgets/live_embed_player.swf?channel="+self.videoId;
|
|
|
|
var params = {
|
|
|
|
allowFullScreen: "true",
|
|
|
|
allowScriptAccess: "always",
|
|
|
|
allowNetworking: "all",
|
|
|
|
movie: "http://www.twitch.tv/widgets/live_embed_player.swf",
|
|
|
|
id: "live_embed_player_flash",
|
2014-02-03 02:04:50 +00:00
|
|
|
flashvars: "hostname=www.twitch.tv&channel="+self.videoId+"&auto_play=true&start_volume=" + VOLUME
|
2013-08-06 02:46:56 +00:00
|
|
|
};
|
|
|
|
swfobject.embedSWF(url,
|
|
|
|
"ytapiplayer",
|
|
|
|
VWIDTH, VHEIGHT,
|
2014-02-03 02:04:50 +00:00
|
|
|
"8",
|
2013-08-06 02:46:56 +00:00
|
|
|
null, null,
|
|
|
|
params,
|
|
|
|
{}
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.load = function (data) {
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.init();
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.pause = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.play = function () { };
|
2013-07-12 20:34:55 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.isPaused = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.getTime = function () { };
|
|
|
|
|
|
|
|
self.seek = function () { };
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function () { };
|
|
|
|
|
|
|
|
self.setVolume = function () { };
|
|
|
|
|
|
|
|
waitUntilDefined(window, "swfobject", function () {
|
|
|
|
self.init();
|
|
|
|
});
|
2013-08-06 02:55:11 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
var JustinTVPlayer = function (data) {
|
|
|
|
removeOld();
|
|
|
|
var self = this;
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.init = function () {
|
2013-09-10 22:18:02 +00:00
|
|
|
var prto = location.protocol;
|
2013-08-06 02:46:56 +00:00
|
|
|
var url = "http://www.justin.tv/widgets/live_embed_player.swf?channel="+self.videoId;
|
|
|
|
var params = {
|
|
|
|
allowFullScreen: "true",
|
|
|
|
allowScriptAccess: "always",
|
|
|
|
allowNetworking: "all",
|
|
|
|
movie: "http://www.justin.tv/widgets/live_embed_player.swf",
|
|
|
|
id: "live_embed_player_flash",
|
2014-02-03 02:04:50 +00:00
|
|
|
flashvars: "hostname=www.justin.tv&channel="+self.videoId+"&auto_play=true&start_volume=" + VOLUME
|
2013-08-06 02:46:56 +00:00
|
|
|
};
|
|
|
|
swfobject.embedSWF(url,
|
|
|
|
"ytapiplayer",
|
|
|
|
VWIDTH, VHEIGHT,
|
2014-02-03 02:04:50 +00:00
|
|
|
"8",
|
2013-08-06 02:46:56 +00:00
|
|
|
null, null,
|
|
|
|
params,
|
|
|
|
{}
|
|
|
|
);
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.load = function (data) {
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.init();
|
|
|
|
};
|
|
|
|
|
|
|
|
self.pause = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.play = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.isPaused = function () { };
|
2013-07-12 20:34:55 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.getTime = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.seek = function () { };
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function () { };
|
|
|
|
|
|
|
|
self.setVolume = function () { };
|
|
|
|
|
|
|
|
waitUntilDefined(window, "swfobject", function () {
|
|
|
|
self.init();
|
|
|
|
});
|
2013-08-06 02:55:11 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2014-02-03 02:04:50 +00:00
|
|
|
function rtmpEventHandler(id, ev, data) {
|
|
|
|
if (ev === "volumechange") {
|
|
|
|
PLAYER.volume = (data.muted ? 0 : data.volume);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
var RTMPPlayer = function (data) {
|
|
|
|
removeOld();
|
2014-02-03 02:04:50 +00:00
|
|
|
var self =this;
|
|
|
|
self.volume = VOLUME;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.init = function () {
|
2013-09-10 22:18:02 +00:00
|
|
|
var prto = location.protocol;
|
|
|
|
var url = prto+"//fpdownload.adobe.com/strobe/FlashMediaPlayback_101.swf";
|
2013-08-06 02:46:56 +00:00
|
|
|
var src = encodeURIComponent(self.videoId);
|
|
|
|
var params = {
|
|
|
|
allowFullScreen: "true",
|
|
|
|
allowScriptAccess: "always",
|
|
|
|
allowNetworking: "all",
|
|
|
|
wMode: "direct",
|
2013-09-10 22:18:02 +00:00
|
|
|
movie: prto+"//fpdownload.adobe.com/strobe/FlashMediaPlayback_101.swf",
|
2014-02-03 02:04:50 +00:00
|
|
|
flashvars: "src="+src+"&streamType=live&javascriptCallbackFunction=rtmpEventHandler&autoPlay=true&volume=" + VOLUME
|
2013-06-11 15:29:21 +00:00
|
|
|
};
|
2013-08-06 02:46:56 +00:00
|
|
|
swfobject.embedSWF(url,
|
|
|
|
"ytapiplayer",
|
|
|
|
VWIDTH, VHEIGHT,
|
|
|
|
"8",
|
|
|
|
null, null,
|
|
|
|
params,
|
|
|
|
{}
|
|
|
|
);
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.load = function (data) {
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.init();
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.pause = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.play = function () { };
|
2013-07-12 20:34:55 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.isPaused = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.getTime = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.seek = function () { };
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function (cb) {
|
|
|
|
cb(self.volume);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.setVolume = function () { };
|
|
|
|
|
|
|
|
waitUntilDefined(window, "swfobject", function () {
|
|
|
|
self.init();
|
|
|
|
});
|
2013-08-06 02:55:11 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2014-03-08 02:37:20 +00:00
|
|
|
function flashEventHandler(id, ev, data) {
|
|
|
|
switch (ev) {
|
|
|
|
case "timeupdate":
|
|
|
|
PLAYER.currentTime = data.currentTime;
|
|
|
|
break;
|
|
|
|
case "pause":
|
|
|
|
PLAYER.paused = data.paused;
|
|
|
|
if (CLIENT.leader)
|
|
|
|
sendVideoUpdate();
|
|
|
|
break;
|
|
|
|
case "play":
|
|
|
|
PLAYER.paused = data.paused;
|
|
|
|
if (CLIENT.leader)
|
|
|
|
sendVideoUpdate();
|
|
|
|
break;
|
|
|
|
case "volumechange":
|
|
|
|
PLAYER.volume = (data.muted ? 0 : data.volume);
|
|
|
|
break;
|
|
|
|
case "progress":
|
|
|
|
break;
|
|
|
|
case "onJavaScriptBridgeCreated":
|
|
|
|
PLAYER.player = $("#ytapiplayer")[0];
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var FlashPlayer = function (data) {
|
|
|
|
removeOld();
|
|
|
|
var self = this;
|
|
|
|
self.volume = VOLUME;
|
|
|
|
self.videoId = data.id;
|
|
|
|
self.videoUrl = data.url;
|
|
|
|
self.videoLength = data.seconds;
|
|
|
|
self.paused = false;
|
|
|
|
self.currentTime = 0;
|
|
|
|
|
|
|
|
self.init = function () {
|
|
|
|
var params = {
|
|
|
|
allowFullScreen: "true",
|
|
|
|
allowScriptAccess: "always",
|
|
|
|
allowNetworking: "all",
|
|
|
|
wMode: "direct"
|
|
|
|
};
|
|
|
|
|
|
|
|
var flashvars = {
|
|
|
|
src: encodeURIComponent(self.videoUrl),
|
|
|
|
// For some reason this param seems not to work
|
|
|
|
clipStartTime: Math.floor(data.currentTime),
|
|
|
|
javascriptCallbackFunction: "flashEventHandler",
|
|
|
|
autoPlay: true,
|
|
|
|
volume: VOLUME
|
|
|
|
};
|
|
|
|
|
|
|
|
if (self.videoUrl.indexOf("rtmp") === 0) {
|
|
|
|
flashvars.streamType = "live";
|
|
|
|
} else {
|
|
|
|
flashvars.streamType = "recorded";
|
|
|
|
}
|
|
|
|
|
|
|
|
swfobject.embedSWF("/StrobeMediaPlayback.swf",
|
|
|
|
"ytapiplayer",
|
|
|
|
VWIDTH, VHEIGHT,
|
|
|
|
"10.1.0",
|
|
|
|
null,
|
|
|
|
flashvars,
|
|
|
|
params,
|
|
|
|
{ name: "ytapiplayer" }
|
|
|
|
);
|
|
|
|
|
|
|
|
self.player = $("#ytapiplayer")[0];
|
|
|
|
};
|
|
|
|
|
|
|
|
self.load = function (data) {
|
|
|
|
self.videoId = data.id;
|
|
|
|
self.videoUrl = data.url;
|
|
|
|
self.videoLength = data.seconds;
|
|
|
|
self.init();
|
|
|
|
};
|
|
|
|
|
|
|
|
self.pause = function () {
|
|
|
|
if (self.player && self.player.pause)
|
|
|
|
self.player.pause();
|
|
|
|
};
|
|
|
|
|
|
|
|
self.play = function () {
|
|
|
|
// Why is it play2? What happened to play1?
|
|
|
|
if (self.player && self.player.play2)
|
|
|
|
self.player.play2();
|
|
|
|
};
|
|
|
|
|
|
|
|
self.isPaused = function (cb) {
|
|
|
|
cb(self.paused);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.getTime = function (cb) {
|
|
|
|
cb(self.currentTime);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.seek = function (to) {
|
|
|
|
if (self.player && self.player.seek) {
|
|
|
|
self.player.seek(Math.floor(to));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.getVolume = function (cb) {
|
|
|
|
cb(self.volume);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.setVolume = function (vol) {
|
|
|
|
if (self.player && self.player.setVolume)
|
|
|
|
self.player.setVolume(vol);
|
|
|
|
};
|
|
|
|
|
|
|
|
waitUntilDefined(window, "swfobject", function () {
|
|
|
|
self.init();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
var JWPlayer = function (data) {
|
|
|
|
var self = this;
|
|
|
|
self.videoId = data.id;
|
2014-02-03 02:04:50 +00:00
|
|
|
if (data.url) {
|
|
|
|
self.videoURL = data.url;
|
|
|
|
} else {
|
|
|
|
self.videoURL = data.id;
|
|
|
|
}
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.init = function () {
|
|
|
|
removeOld();
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
jwplayer("ytapiplayer").setup({
|
2014-02-03 02:04:50 +00:00
|
|
|
file: self.videoURL,
|
2013-08-06 02:46:56 +00:00
|
|
|
width: VWIDTH,
|
|
|
|
height: VHEIGHT,
|
|
|
|
autostart: true
|
|
|
|
});
|
|
|
|
jwplayer().onPlay(function() {
|
|
|
|
self.paused = false;
|
|
|
|
if(CLIENT.leader)
|
|
|
|
sendVideoUpdate();
|
|
|
|
});
|
|
|
|
jwplayer().onPause(function() {
|
|
|
|
self.paused = true;
|
|
|
|
if(CLIENT.leader)
|
|
|
|
sendVideoUpdate();
|
|
|
|
});
|
|
|
|
jwplayer().onComplete(function() {
|
|
|
|
socket.emit("playNext");
|
|
|
|
});
|
2014-02-03 02:04:50 +00:00
|
|
|
self.setVolume(VOLUME);
|
2013-08-06 02:55:11 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.load = function (data) {
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.init();
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.pause = function () {
|
|
|
|
if(jwplayer)
|
|
|
|
jwplayer().pause(true);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.play = function () {
|
|
|
|
if(jwplayer)
|
|
|
|
jwplayer().play(true);
|
|
|
|
};
|
2013-07-12 20:34:55 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.isPaused = function (callback) {
|
|
|
|
if(jwplayer)
|
|
|
|
callback(jwplayer().getState() !== "PLAYING");
|
|
|
|
};
|
|
|
|
|
|
|
|
self.getTime = function (callback) {
|
2013-06-11 15:29:21 +00:00
|
|
|
// Only return time for non-live media
|
2013-08-06 02:46:56 +00:00
|
|
|
if(jwplayer && jwplayer().getDuration() != -1) {
|
2013-06-11 15:29:21 +00:00
|
|
|
callback(jwplayer().getPosition());
|
|
|
|
}
|
2013-08-06 02:46:56 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.seek = function (time) {
|
|
|
|
if(jwplayer)
|
|
|
|
jwplayer().seek(time);
|
|
|
|
};
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function (cb) {
|
|
|
|
cb(jwplayer().getVolume() / 100);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.setVolume = function (vol) {
|
|
|
|
jwplayer().setVolume(vol * 100);
|
|
|
|
};
|
|
|
|
|
|
|
|
waitUntilDefined(window, "jwplayer", function () { self.init(); });
|
2013-08-06 02:55:11 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
var UstreamPlayer = function (data) {
|
|
|
|
var self = this;
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.init = function () {
|
|
|
|
var iframe = $("<iframe/>");
|
|
|
|
removeOld(iframe);
|
|
|
|
iframe.attr("width", VWIDTH);
|
|
|
|
iframe.attr("height", VHEIGHT);
|
2013-09-10 22:18:02 +00:00
|
|
|
var prto = location.protocol;
|
|
|
|
iframe.attr("src", prto+"//www.ustream.tv/embed/"+self.videoId+"?v=3&wmode=direct");
|
2013-08-06 02:46:56 +00:00
|
|
|
iframe.attr("frameborder", "0");
|
|
|
|
iframe.attr("scrolling", "no");
|
|
|
|
iframe.css("border", "none");
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.load = function (data) {
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.init();
|
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.pause = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.play = function () { };
|
2013-07-12 20:34:55 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.isPaused = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.getTime = function () { };
|
|
|
|
|
|
|
|
self.seek = function () { };
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function () { };
|
|
|
|
|
|
|
|
self.setVolume = function () { };
|
|
|
|
|
|
|
|
self.init();
|
2013-08-06 02:55:11 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
var ImgurPlayer = function (data) {
|
|
|
|
var self = this;
|
|
|
|
self.init = function () {
|
|
|
|
var iframe = $("<iframe/>");
|
|
|
|
removeOld(iframe);
|
|
|
|
iframe.attr("width", VWIDTH);
|
|
|
|
iframe.attr("height", VHEIGHT);
|
2013-09-10 22:18:02 +00:00
|
|
|
var prto = location.protocol;
|
|
|
|
iframe.attr("src", prto+"//imgur.com/a/"+self.videoId+"/embed");
|
2013-08-06 02:46:56 +00:00
|
|
|
iframe.attr("frameborder", "0");
|
|
|
|
iframe.attr("scrolling", "no");
|
|
|
|
iframe.css("border", "none");
|
|
|
|
};
|
|
|
|
|
|
|
|
self.load = function (data) {
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:55:11 +00:00
|
|
|
self.init();
|
2013-08-06 02:46:56 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.pause = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.play = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.isPaused = function () { };
|
2013-07-12 20:34:55 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.getTime = function () { };
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.seek = function () { };
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function () { };
|
|
|
|
|
|
|
|
self.setVolume = function () { };
|
|
|
|
|
|
|
|
self.init();
|
2013-08-06 02:55:11 +00:00
|
|
|
};
|
2013-06-11 15:29:21 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
var CustomPlayer = function (data) {
|
|
|
|
var self = this;
|
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:46:56 +00:00
|
|
|
self.init = function () {
|
|
|
|
removeOld();
|
|
|
|
var div = $("#ytapiplayer");
|
|
|
|
div.attr("id", "");
|
|
|
|
div.append(self.videoId);
|
|
|
|
|
2013-08-06 02:55:11 +00:00
|
|
|
self.player = div.find("iframe");
|
2013-08-06 02:46:56 +00:00
|
|
|
if(self.player.length === 0) self.player = div.find("object");
|
|
|
|
if(self.player.length === 0) self.player = div;
|
|
|
|
self.player.attr("id", "ytapiplayer");
|
|
|
|
self.player.attr("width", VWIDTH);
|
|
|
|
self.player.attr("height", VHEIGHT);
|
|
|
|
};
|
2013-08-03 15:12:53 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.load = function (data) {
|
2013-08-06 04:07:54 +00:00
|
|
|
self.videoId = data.id;
|
2013-09-27 02:43:38 +00:00
|
|
|
self.videoLength = data.seconds;
|
2013-08-06 02:55:11 +00:00
|
|
|
self.init();
|
2013-08-06 02:46:56 +00:00
|
|
|
};
|
2013-08-03 15:12:53 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.pause = function () { };
|
2013-08-03 15:12:53 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.play = function () { };
|
2013-08-03 15:12:53 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.isPaused = function () { };
|
2013-08-03 15:12:53 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
self.getTime = function () { };
|
|
|
|
|
|
|
|
self.seek = function () { };
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function () { };
|
|
|
|
|
|
|
|
self.setVolume = function () { };
|
|
|
|
|
|
|
|
self.init();
|
2013-08-06 02:46:56 +00:00
|
|
|
};
|
2013-08-03 15:12:53 +00:00
|
|
|
|
2013-11-07 23:19:36 +00:00
|
|
|
var GoogleDocsPlayer = function (data) {
|
|
|
|
var self = this;
|
|
|
|
self.init = function (data) {
|
|
|
|
self.videoId = data.id;
|
|
|
|
self.videoLength = data.seconds;
|
|
|
|
self.paused = false;
|
|
|
|
var wmode = USEROPTS.wmode_transparent ? "transparent" : "opaque";
|
|
|
|
self.player = $("<object/>", data.object)[0];
|
|
|
|
$(self.player).attr("data", data.object.data);
|
|
|
|
$(self.player).attr("width", VWIDTH)
|
|
|
|
.attr("height", VHEIGHT);
|
|
|
|
data.params.forEach(function (p) {
|
|
|
|
$("<param/>", p).appendTo(self.player);
|
|
|
|
});
|
|
|
|
removeOld($(self.player));
|
2014-02-03 02:04:50 +00:00
|
|
|
self.setVolume(VOLUME);
|
2013-11-07 23:19:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
self.load = function (data) {
|
|
|
|
self.init(data);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.pause = function () {
|
|
|
|
if(self.player && self.player.pauseVideo)
|
|
|
|
self.player.pauseVideo();
|
|
|
|
};
|
|
|
|
|
|
|
|
self.play = function () {
|
|
|
|
if(self.player && self.player.playVideo)
|
|
|
|
self.player.playVideo();
|
|
|
|
};
|
|
|
|
|
|
|
|
self.isPaused = function (callback) {
|
|
|
|
if(self.player && self.player.getPlayerState) {
|
|
|
|
var state = self.player.getPlayerState();
|
|
|
|
callback(state != YT.PlayerState.PLAYING);
|
|
|
|
} else {
|
|
|
|
callback(false);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.getTime = function (callback) {
|
|
|
|
if(self.player && self.player.getCurrentTime)
|
|
|
|
callback(self.player.getCurrentTime());
|
|
|
|
};
|
|
|
|
|
|
|
|
self.seek = function (time) {
|
|
|
|
if(self.player && self.player.seekTo)
|
|
|
|
self.player.seekTo(time, true);
|
|
|
|
};
|
2014-02-03 02:04:50 +00:00
|
|
|
|
|
|
|
self.getVolume = function (cb) {
|
|
|
|
if (!self.player || !self.player.getVolume || !self.player.isMuted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// YouTube's API is strange in the sense that getVolume() returns
|
|
|
|
// the regular (unmuted) volume even if it is muted...
|
|
|
|
// YouTube's volume is 0..100, normalize it to 0..1
|
|
|
|
var vol = self.player.isMuted() ? 0 : (self.player.getVolume() / 100);
|
|
|
|
cb(vol);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.setVolume = function (vol) {
|
|
|
|
if (self.player && self.player.setVolume) {
|
|
|
|
self.player.setVolume(vol * 100);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.init(data);
|
2013-11-07 23:19:36 +00:00
|
|
|
};
|
|
|
|
|
2014-02-03 02:04:50 +00:00
|
|
|
function RawVideoPlayer(data) {
|
|
|
|
var self = this;
|
|
|
|
self.init = function (data) {
|
|
|
|
self.videoId = data.id;
|
|
|
|
self.videoURL = data.url;
|
|
|
|
var video = $("<video/>")
|
|
|
|
.attr("src", self.videoURL)
|
|
|
|
.attr("controls", "controls")
|
|
|
|
.attr("id", "#ytapiplayer")
|
|
|
|
.attr("width", VWIDTH)
|
|
|
|
.attr("height", VHEIGHT)
|
|
|
|
.html("Your browser does not support HTML5 <code><video></code> tags :(");
|
2014-03-08 02:37:20 +00:00
|
|
|
video.error(function (err) {
|
|
|
|
setTimeout(function () {
|
|
|
|
fallbackRaw(data);
|
|
|
|
}, 100);
|
|
|
|
});
|
2014-02-03 02:04:50 +00:00
|
|
|
removeOld(video);
|
|
|
|
self.player = video[0];
|
|
|
|
self.setVolume(VOLUME);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.load = function (data) {
|
|
|
|
self.init(data);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.pause = function () {
|
|
|
|
if (self.player) {
|
|
|
|
self.player.pause();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.play = function () {
|
|
|
|
if (self.player) {
|
|
|
|
self.player.play();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.isPaused = function (callback) {
|
|
|
|
if (self.player) {
|
|
|
|
callback(self.player.paused);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.getTime = function (callback) {
|
|
|
|
if (self.player) {
|
|
|
|
callback(self.player.currentTime);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.seek = function (time) {
|
|
|
|
if (self.player) {
|
|
|
|
self.player.currentTime = time;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.getVolume = function (cb) {
|
|
|
|
if (self.player) {
|
|
|
|
if (self.player.muted) {
|
|
|
|
cb(0);
|
|
|
|
} else {
|
|
|
|
cb(self.player.volume);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.setVolume = function (vol) {
|
|
|
|
if (self.player) {
|
|
|
|
self.player.volume = vol;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.init(data);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
function handleMediaUpdate(data) {
|
2013-09-27 02:43:38 +00:00
|
|
|
// Don't update if the position is past the video length, but
|
|
|
|
// make an exception when the video length is 0 seconds
|
|
|
|
if (typeof PLAYER.videoLength === "number") {
|
2014-02-03 02:04:50 +00:00
|
|
|
if (PLAYER.videoLength > 0 &&
|
2013-09-27 02:43:38 +00:00
|
|
|
data.currentTime > PLAYER.videoLength) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2013-09-22 04:54:29 +00:00
|
|
|
var wait = data.currentTime < 0;
|
2013-08-06 02:46:56 +00:00
|
|
|
// Media change
|
|
|
|
if(data.id && data.id !== PLAYER.videoId) {
|
|
|
|
if(data.currentTime < 0)
|
2013-06-11 15:29:21 +00:00
|
|
|
data.currentTime = 0;
|
2013-08-06 02:46:56 +00:00
|
|
|
PLAYER.load(data);
|
|
|
|
PLAYER.play();
|
2013-06-11 15:29:21 +00:00
|
|
|
}
|
2013-09-22 04:54:29 +00:00
|
|
|
|
|
|
|
if (wait) {
|
2013-10-17 02:50:31 +00:00
|
|
|
var tm = 1;
|
|
|
|
/* Stupid hack -- In this thrilling episode of
|
|
|
|
"the YouTube API developers should eat a boat", the
|
|
|
|
HTML5 player apparently breaks if I play()-seek(0)-pause()
|
|
|
|
quickly (as a "start buffering but don't play yet"
|
|
|
|
mechanism)
|
|
|
|
*/
|
|
|
|
if (PLAYER.type === "yt") {
|
|
|
|
tm = 500;
|
|
|
|
}
|
|
|
|
setTimeout(function () {
|
|
|
|
PLAYER.seek(0);
|
|
|
|
PLAYER.pause();
|
|
|
|
}, tm);
|
2013-09-22 04:54:29 +00:00
|
|
|
return;
|
|
|
|
}
|
2014-02-03 02:04:50 +00:00
|
|
|
|
2013-08-06 02:46:56 +00:00
|
|
|
// Don't synch if leader or synch disabled
|
|
|
|
if(CLIENT.leader || !USEROPTS.synch)
|
2013-06-11 15:29:21 +00:00
|
|
|
return;
|
2013-08-06 02:46:56 +00:00
|
|
|
|
|
|
|
// Handle pause/unpause
|
2013-06-11 15:29:21 +00:00
|
|
|
if(data.paused) {
|
2013-09-22 04:54:29 +00:00
|
|
|
PLAYER.isPaused(function (paused) {
|
|
|
|
if (!paused) {
|
|
|
|
PLAYER.seek(data.currentTime);
|
|
|
|
PLAYER.pause();
|
|
|
|
}
|
|
|
|
});
|
2013-08-06 02:55:11 +00:00
|
|
|
} else {
|
2013-08-06 02:46:56 +00:00
|
|
|
PLAYER.isPaused(function (paused) {
|
2013-08-06 02:55:11 +00:00
|
|
|
if(paused)
|
|
|
|
PLAYER.play();
|
2013-08-06 02:46:56 +00:00
|
|
|
});
|
2013-06-11 15:29:21 +00:00
|
|
|
}
|
2013-08-06 02:46:56 +00:00
|
|
|
|
|
|
|
// Handle time change
|
|
|
|
PLAYER.getTime(function (seconds) {
|
2013-06-11 15:29:21 +00:00
|
|
|
var time = data.currentTime;
|
|
|
|
var diff = time - seconds || time;
|
2013-10-24 22:31:04 +00:00
|
|
|
var acc = USEROPTS.sync_accuracy;
|
|
|
|
// Dailymotion can't seek more accurately than to the nearest
|
|
|
|
// 2 seconds. It gets stuck looping portions of the video
|
|
|
|
// at the default synch accuracy of 2.
|
|
|
|
// I've found 5 works decently.
|
|
|
|
if (PLAYER.type === "dm")
|
|
|
|
acc = Math.max(acc, 5.0);
|
|
|
|
|
|
|
|
if(diff > acc) {
|
2013-08-06 02:46:56 +00:00
|
|
|
PLAYER.seek(time);
|
2013-10-24 22:31:04 +00:00
|
|
|
} else if(diff < -acc) {
|
2013-08-06 02:46:56 +00:00
|
|
|
// Don't synch all the way back, causes buffering problems
|
|
|
|
// because for some dumb reason YouTube erases the buffer
|
|
|
|
// when you seek backwards
|
2013-10-24 22:31:04 +00:00
|
|
|
//
|
|
|
|
// ADDENDUM 2013-10-24 Except for dailymotion because
|
|
|
|
// their player is inaccurate
|
|
|
|
if (PLAYER.type !== "dm")
|
|
|
|
time += 1;
|
|
|
|
PLAYER.seek(time);
|
2013-06-11 15:29:21 +00:00
|
|
|
}
|
2013-08-06 02:46:56 +00:00
|
|
|
});
|
2013-06-11 15:29:21 +00:00
|
|
|
}
|
2013-08-06 03:25:16 +00:00
|
|
|
|
|
|
|
var constructors = {
|
|
|
|
"yt": YouTubePlayer,
|
|
|
|
"vi": VIMEO_FLASH ? VimeoFlashPlayer : VimeoPlayer,
|
|
|
|
"dm": DailymotionPlayer,
|
|
|
|
"sc": SoundcloudPlayer,
|
|
|
|
"li": LivestreamPlayer,
|
|
|
|
"tw": TwitchTVPlayer,
|
|
|
|
"jt": JustinTVPlayer,
|
|
|
|
"us": UstreamPlayer,
|
2014-03-08 02:37:20 +00:00
|
|
|
"rt": FlashPlayer,
|
2013-08-06 03:55:46 +00:00
|
|
|
"jw": JWPlayer,
|
2013-08-06 03:25:16 +00:00
|
|
|
"im": ImgurPlayer,
|
2013-11-07 23:19:36 +00:00
|
|
|
"cu": CustomPlayer,
|
2014-02-03 02:04:50 +00:00
|
|
|
"gd": GoogleDocsPlayer,
|
2014-03-08 02:37:20 +00:00
|
|
|
"rv": RawVideoPlayer,
|
|
|
|
"fl": FlashPlayer
|
2013-08-06 03:25:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
function loadMediaPlayer(data) {
|
|
|
|
if(data.type in constructors) {
|
|
|
|
PLAYER = new constructors[data.type](data);
|
|
|
|
PLAYER.type = data.type;
|
|
|
|
}
|
|
|
|
}
|