diff --git a/player/update.coffee b/player/update.coffee index 4601949c..6ad06541 100644 --- a/player/update.coffee +++ b/player/update.coffee @@ -40,6 +40,12 @@ window.loadMediaPlayer = (data) -> window.handleMediaUpdate = (data) -> PLAYER = window.PLAYER + #bodge for fcyp.js layout + handleWindowResize() + + #update airdate + dispSTimes(); + # Do not update if the current time is past the end of the video, unless # the video has length 0 (which is a special case for livestreams) if typeof PLAYER.mediaLength is 'number' and diff --git a/src/channel/anonymouscheck.js b/src/channel/anonymouscheck.js index 0b946b93..f7aa648d 100644 --- a/src/channel/anonymouscheck.js +++ b/src/channel/anonymouscheck.js @@ -15,14 +15,15 @@ AnonymousCheck.prototype.onUserPreJoin = function (user, data, cb) { return cb("User disconnected", ChannelModule.DENY); } - if(anonymousBanned && user.isAnonymous()) { + //if(anonymousBanned && user.isAnonymous()) { + if(anonymousBanned && user.account.globalRank <= 0) { user.socket.on("disconnect", function () { if (!user.is(Flags.U_IN_CHANNEL)) { cb("User disconnected", ChannelModule.DENY); } }); - user.socket.emit("errorMsg", { msg : "This channel has blocked anonymous users. Please provide a user name to join."}); + user.socket.emit("errorMsg", { msg : "Welcome to ourfore.st! Register to start chatting/streaming!"}); user.waitFlag(Flags.U_LOGGED_IN, function () { cb(null, ChannelModule.PASSTHROUGH); }); diff --git a/src/channel/playlist.js b/src/channel/playlist.js index 649e4912..2f54e636 100644 --- a/src/channel/playlist.js +++ b/src/channel/playlist.js @@ -37,7 +37,8 @@ const TYPE_SET_TEMP = { const TYPE_MOVE_MEDIA = { from: "number", - after: "string,number" + after: "string,number", + sTimes: [[],[]] }; const TYPE_ASSIGN_LEADER = { @@ -90,6 +91,7 @@ function PlaylistModule(_channel) { this.meta = { count: 0, rawTime: 0, + sTimes: [[],[]], time: util.formatTime(0) }; this.current = null; @@ -641,6 +643,10 @@ PlaylistModule.prototype.handleMoveMedia = function (user, data) { const self = this; self.channel.refCounter.ref("PlaylistModule::handleMoveMedia"); self.semaphore.queue(function (lock) { + var sTime = self.items.find(data.from).media.startTime; + var sDur = self.items.find(data.from).media.seconds; + var sIndx = self.items.getIndex(data.from); + var tempST = 0; if (!self.items.remove(data.from)) { self.channel.refCounter.unref("PlaylistModule::handleMoveMedia"); return lock.release(); @@ -657,12 +663,33 @@ PlaylistModule.prototype.handleMoveMedia = function (user, data) { return lock.release(); } } else { + if (!self.items.insertAfter(from, data.after)) { self.channel.refCounter.unref("PlaylistModule::handleMoveMedia"); return lock.release(); } } + + self.items.forEach(function (item){//iterate items + self.items.find(item.uid).media.startTime = tempST;//current item start time = tempST + tempST += item.media.seconds; + }); + + + var sTemp = [[],[]]; + + self.items.forEach(function (item){ + sTemp[0].push(item.uid); + sTemp[1].push(item.media.startTime); + + }); + + + self.channel.modules.playlist.meta.sTimes = sTemp; + + data.sTimes = sTemp; + self.channel.broadcastAll("moveVideo", data); self.channel.logger.log("[playlist] " + user.getName() + " moved " + @@ -886,12 +913,30 @@ PlaylistModule.prototype._delete = function (uid) { return false; } var next = item.next || this.items.first; - + var indx = this.items.getIndex(uid) - 1; + var success = self.items.remove(uid); if (success) { self.meta.count--; self.meta.rawTime -= item.media.seconds; + //set startTime for items after deleted item + self.items.forEach(function (itm){//iterate items + if(itm.media.startTime > item.media.startTime){//if cur item start time is moar than deleted items start time + itm.media.startTime -= item.media.seconds;//subtract deleted item's duration from current item's start time + } + }); + + var sTemp = [[],[]]; + + self.items.forEach(function (item){ + sTemp[0].push(item.uid); + sTemp[1].push(item.media.startTime); + + }); + + self.meta.sTimes = sTemp; + self.meta.time = util.formatTime(self.meta.rawTime); self.channel.users.forEach(function (u) { if (perms.canSeePlaylist(u)) { @@ -1007,19 +1052,37 @@ PlaylistModule.prototype._addItem = function (media, data, user, cb) { } var success = function () { - var packet = { - item: item.pack(), - after: item.prev ? item.prev.uid : "prepend" - }; + //var packet = { + // item: item.pack(), + // after: item.prev ? item.prev.uid : "prepend" + //}; self.meta.count++; + media.startTime = self.meta.rawTime; self.meta.rawTime += media.seconds; self.meta.time = util.formatTime(self.meta.rawTime); + + var sTemp = [[],[]]; + + self.items.forEach(function (item){ + sTemp[0].push(item.uid); + sTemp[1].push(item.media.startTime); + + }); + + self.meta.sTimes = sTemp; + var m = item.media; self.channel.logger.log("[playlist] " + (data.queueby || "(anonymous)") + " added " + m.title + " (" + m.type + ":" + m.id + ")"); var perms = self.channel.modules.permissions; + + var packet = { + item: item.pack(), + after: item.prev ? item.prev.uid : "prepend" + }; + self.channel.users.forEach(function (u) { if (perms.canSeePlaylist(u)) { u.socket.emit("queue", packet); diff --git a/src/media.js b/src/media.js index 6829f7c9..bd1818b1 100644 --- a/src/media.js +++ b/src/media.js @@ -10,6 +10,7 @@ function Media(id, title, seconds, type, meta) { this.seconds = seconds === "--:--" ? 0 : parseInt(seconds); this.duration = util.formatTime(seconds); + this.startTime = 0; this.type = type; this.meta = meta; this.currentTime = 0; @@ -30,6 +31,7 @@ Media.prototype = { title: this.title, seconds: this.seconds, duration: this.duration, + startTime: this.startTime, type: this.type, meta: { restricted: this.meta.restricted, diff --git a/src/ullist.js b/src/ullist.js index 405aaafd..d453245b 100644 --- a/src/ullist.js +++ b/src/ullist.js @@ -178,4 +178,28 @@ ULList.prototype.findAll = function(fn) { return result; }; + +//RAINBOW WUZ ERE' + +/* return index of item if it exists in the list by UID */ +ULList.prototype.getIndex = function(uid) { + var i = 0;//index + // Can't possibly find it in an empty list + if(this.first === null) + return false; + + var item = this.first; + var iter = this.first; + while(iter !== null && item.uid != uid) { + i++;//add index + item = iter; + iter = iter.next; + } + + if(item && item.uid == uid) + return i;//return index + return false; +}; + + module.exports = ULList; diff --git a/src/user.js b/src/user.js index c3699d83..1c0bacb2 100644 --- a/src/user.js +++ b/src/user.js @@ -149,7 +149,8 @@ User.prototype.handleLogin = function handleLogin(data) { } if (!pw) { - this.guestLogin(name); + //this.guestLogin(name);disable guest logins + console.log("Guest login attempt! user: " + data.name + " ip: " + this.realip); } else { this.login(name, pw); } diff --git a/src/web/routes/about.js b/src/web/routes/about.js new file mode 100644 index 00000000..43b26e70 --- /dev/null +++ b/src/web/routes/about.js @@ -0,0 +1,7 @@ +import { sendPug } from '../pug'; + +export default function initialize(app) { + app.get('/about', (req, res) => { + return sendPug(res, 'about'); + }); +} diff --git a/src/web/webserver.js b/src/web/webserver.js index f81781cb..bb897e20 100644 --- a/src/web/webserver.js +++ b/src/web/webserver.js @@ -200,6 +200,7 @@ module.exports = { require('./routes/contact')(app, webConfig); require('./auth').init(app, captchaConfig, captchaController); require('./account').init(app, globalMessageBus, emailConfig, emailController, captchaConfig); + require('./routes/about')(app); require('./routes/account/delete-account')( app, csrf.verify, diff --git a/templates/about.pug b/templates/about.pug new file mode 100644 index 00000000..feb5ab41 --- /dev/null +++ b/templates/about.pug @@ -0,0 +1,21 @@ +extends layout.pug + +block content + .col-md-8.col-md-offset-2 + .aboutText + h1 Welcome to ourfore.st! + h3 about fore.st/ourfore.st + p. + fore.st is a fork of cytube built for the TTN community post-shutdown. TTN was a community based streaming service for cannabis enthusiasts. After eight years, the man behind the site went on to greener pastures. In it's place stands this, and many other community efforts such as Treezone, and the community discord. While it may not be the same, we aim to provide a similiar service for the same people. The refrence instance for fore.st is hosted at ourfore.st. + h3 ourfore.st instance rules + ul + li + | Don't be a dick + li + | Don't post, or explain where to find pirated content in the chat + li + | Do not upload content to the internet you do not have permission to for purpose of using it on ourfore.st + li + | No spamming submit channel or chat + p. + Comments? Questions? Feature requests? DMCA Notices? Email us! diff --git a/templates/channel.pug b/templates/channel.pug index e6e641d5..7497096e 100644 --- a/templates/channel.pug +++ b/templates/channel.pug @@ -48,8 +48,8 @@ html(lang="en") form(action="javascript:void(0)") input#chatline.form-control(type="text", maxlength="320", style="display: none") #guestlogin.input-group - span.input-group-addon Guest login - input#guestname.form-control(type="text", placeholder="Name") + span.input-group-addon Registration Required! + //input#guestname.form-control(type="text", placeholder="Name") #videowrap.col-lg-7.col-md-7 p#videowrap-header span#resize-video-smaller.glyphicon.glyphicon-minus.pointer(title="Make the video smaller") @@ -249,6 +249,7 @@ html(lang="en") script(src="/js/paginator.js") script(src="/js/ui.js") script(src="/js/callbacks.js") + script(src="/js/fschd.js") script(defer, src="https://www.youtube.com/iframe_api") script(defer, src="https://api.dmcdn.net/all.js") script(defer, src="https://player.vimeo.com/api/player.js") @@ -260,3 +261,5 @@ html(lang="en") script(defer, src="/js/dash.all.min.js") script(defer, src="/js/videojs-dash.js") script(defer, src="https://player.twitch.tv/js/embed/v1.js") + script(type='text/javascript'). + handleWindowResize(); diff --git a/templates/nav.pug b/templates/nav.pug index 0fb212d2..e52c5ba8 100644 --- a/templates/nav.pug +++ b/templates/nav.pug @@ -11,7 +11,6 @@ mixin navdefaultlinks() a(href="/") Home li.dropdown a.dropdown-toggle(href="#", data-toggle="dropdown") Account - b.caret ul.dropdown-menu if loggedIn li: a(href="javascript:$('#logoutform').submit();") Log out @@ -23,6 +22,8 @@ mixin navdefaultlinks() else li: a(href="/login") Login li: a(href="/register") Register + li + a(href="/about") About mixin navsuperadmin(newTab) if superadmin diff --git a/www/css/themes/fore.st.css b/www/css/themes/fore.st.css index 01368d79..c4310663 100644 --- a/www/css/themes/fore.st.css +++ b/www/css/themes/fore.st.css @@ -19,7 +19,12 @@ body { } .nick-highlight { - background-color: #555555; + background-color: #262626; + color: #ffffff; +} + +.server-whisper{ + color: #ffffff; } .nick-hover { @@ -69,7 +74,6 @@ input.form-control[type="email"], textarea.form-control { #chatheader, #videowrap-header { border: 1px solid #cccccc; border-bottom-width: 0; - border-radius: 5px; border-bottom-left-radius: 0; border-bottom-right-radius: 0; } @@ -96,3 +100,26 @@ input.form-control[type="email"], textarea.form-control { background-color: #111111C0; } +.qe_sTime{ + float: right; + font-family: Monospace; +} +.aboutText{ + background-color: #111111C0; + padding: 10px; + border: 1px solid #aaaaaa; +} + +#chatwrap, #videowrap{ + padding-right: 0px; + padding-left: 0px; +} + +.navbar{ + margin-bottom: 0px; +} + +#filei{ + background-color: #710404; + +} diff --git a/www/cyp/fcyp.js b/www/cyp/fcyp.js index a3080d86..8842754a 100644 --- a/www/cyp/fcyp.js +++ b/www/cyp/fcyp.js @@ -103,14 +103,14 @@ UI_FontsBtn = 0; // button displaying box with clickable chat fonts // [ REQUIRE: INSTALLATION (see above) ] UI_UnicodeChars = 0; // [&] additional buttons in the fonts panel with unicode characters // [ REQUIRE: UI_FontsBtn enabled ] -UI_EmotesBtn = 1; // button displaying box with clickable chat emotes +UI_EmotesBtn = 0; // button displaying box with clickable chat emotes UI_GroupEmotes = 1; // [&] emotes panel pagination, display limited number of emotes at one time // [ REQUIRE: UI_EmotesBtn enabled ] -UI_CommandsBtn = 1; // button displaying modal window with chat commands help +UI_CommandsBtn = 0; // button displaying modal window with chat commands help UI_ModPanel = 0; // [&] panel with messages and help for moderators UI_CustomCaptions = 0; // [&] custom captions for add, refresh, voteskip buttons, and welcome text -UI_PlayerOptions = 1; // [&] additional player options -UI_TransformationBtns = 1; // player transformation buttons +UI_PlayerOptions = 0; // [&] additional player options +UI_TransformationBtns = 0; // player transformation buttons UI_ChannelDatabase = 1; // [&] box with embed additional media database UI_ChannelGalleries = 0; // [&] box with embed galleries UI_DisplayModeSel = 1; // selector with player display modes @@ -662,48 +662,49 @@ function setLayout() { refreshPlayer(); } +//-----STOP BREAKIN SHIT! // fit player height function fitPlayer() { - VW=$("#videowrap").width()+''; - VH=Math.floor(parseInt(VW)*9/16+1)+''; - $("#ytapiplayer").width(VW).height(VH); + //VW=$("#videowrap").width()+''; + //VH=Math.floor(parseInt(VW)*9/16+1)+''; + //$("#ytapiplayer").width(VW).height(VH); } // fit chat height function fitChat(a) { - if (a=="auto") { + /*if (a=="auto") { VW=$("#messagebuffer").width(); VH=Math.floor(parseInt(VW)*9/16+1); } else { VH=a; } $("#messagebuffer").height(VH); - $("#userlist").height(VH); + $("#userlist").height(VH);*/ } // display mode helper functions function bigPlayer() { - $("#videowrap").removeClass().addClass("col-lg-12 col-md-12"); - fitPlayer(); + //$("#videowrap").removeClass().addClass("col-lg-12 col-md-12"); + //fitPlayer(); } function bigChat() { - $("#chatwrap").removeClass().addClass('col-lg-12 col-md-12'); - fitChat("auto"); + //$("#chatwrap").removeClass().addClass('col-lg-12 col-md-12'); + //fitChat("auto"); } function normalPlayer() { - $("#videowrap").removeClass().addClass("col-lg-7 col-md-7"); - fitPlayer(); + //$("#videowrap").removeClass().addClass("col-lg-7 col-md-7"); + //fitPlayer(); } function normalChat() { - c = (PINNED && USERCONFIG.qsize=="wide") ? 'col-lg-7 col-md-7' : 'col-lg-5 col-md-5'; + /*c = (PINNED && USERCONFIG.qsize=="wide") ? 'col-lg-7 col-md-7' : 'col-lg-5 col-md-5'; $("#chatwrap").removeClass().addClass(c); - fitChat(338); + fitChat(338);*/ } // set display mode @@ -731,10 +732,10 @@ function setMode(a) { normalPlayer(); c = (PINNED && USERCONFIG.qsize=="wide") ? 'col-lg-7 col-md-7' : 'col-lg-5 col-md-5'; - $("#chatwrap").removeClass().addClass(c); - H=parseInt(VH)-$("#chatline").outerHeight()-1; - $("#messagebuffer").height(H); - $("#userlist").height(H); + //$("#chatwrap").removeClass().addClass(c); + //H=parseInt(VH)-$("#chatline").outerHeight()-1; + //$("#messagebuffer").height(H); + //$("#userlist").height(H); USERCONFIG.player=="center" ? playerLocation("center") : ''; PINNED ? pinUp() : ''; @@ -2147,15 +2148,15 @@ function pinUp() { $("#videowrap").before($("#rightpane").detach()); } if (USERCONFIG.queue=="left") { - $("#leftpane").before($("#chatwrap").detach()); + //$("#leftpane").before($("#chatwrap").detach()); } else if (USERCONFIG.queue=="right") { - $("#leftpane").after($("#chatwrap").detach()); + //$("#leftpane").after($("#chatwrap").detach()); } $("#rightpane").removeClass().addClass('col-lg-5 col-md-5'); if (USERCONFIG.qsize=="wide") { - $("#chatwrap").removeClass().addClass('col-lg-7 col-md-7'); + //$("#chatwrap").removeClass().addClass('col-lg-7 col-md-7'); } else { - $("#chatwrap").removeClass().addClass('col-lg-5 col-md-5'); + //$("#chatwrap").removeClass().addClass('col-lg-5 col-md-5'); } $("#pinup-btn").attr('title', 'Unpin playlist'); $("#config-btn, #configbtnwrap br").hide(); @@ -3580,9 +3581,13 @@ $("#chatbtn").on("click", function() { // fix layout behaviour after resizing // DEV NOTE: this is extended function from CyTube "util.js" file +// + + function resizeStuff() { VWIDTH = $("#videowrap").width() + ""; + console.log("resize stuff called"); VHEIGHT = Math.floor(parseInt(VWIDTH) * 9 / 16 + 1) + ""; $("#ytapiplayer").width(VWIDTH).height(VHEIGHT); @@ -3591,8 +3596,8 @@ function resizeStuff() { } var h = parseInt(VHEIGHT) - $("#chatline").outerHeight() - 1; - $("#messagebuffer").height(h); - $("#userlist").height(h); + //$("#messagebuffer").height(h);//fixin shit + //$("#userlist").height(h); if (UI_DisplayModeSel=="1") { m=modesel.val(); @@ -3605,23 +3610,23 @@ function resizeStuff() { $("#videowrap div, #videowrap p").hide(); $("#ytapiplayer").width(1).height(1); } - fitChat("auto"); + // fitChat("auto"); } else if (m=="syMode" && USERCONFIG.player=="center") { - fitChat(200); + // fitChat(200); } else if (m=="sMode") { // DEV NOTE: current function is called in "changeMedia" callback (condition race) VW=$("#messagebuffer").width(); VH=Math.floor(parseInt(VW)*9/16+1); - $("#messagebuffer, #userlist").height(VH); + //$("#messagebuffer, #userlist").height(VH); } } } // bind new resizing function -$(window).unbind("resize"); -$(window).resize(resizeStuff); +//$(window).unbind("resize"); +//$(window).resize(resizem); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -3646,6 +3651,7 @@ if (FLUID) { $("#fontspanel, #emotespanel").addClass('fluidpanel'); } +console.log("WTF"); // finishing variable LOADED=true; @@ -3666,3 +3672,5 @@ if (UI_ExternalScript=="1" && ExternalScript_URL!="") { } /* ----- END OF LIBRARY ----- */ + + diff --git a/www/cyp/fcyp.old b/www/cyp/fcyp.old index c914bf94..a3080d86 100644 --- a/www/cyp/fcyp.old +++ b/www/cyp/fcyp.old @@ -446,7 +446,7 @@ var USERCONFIG = { "modhash":getOrDefault(CHANNEL.name+"_modhash", ""), } var USERTHEME = getOrDefault(CHANNEL.name+"_theme", DEFTHEME); -var FLUID = getOrDefault(CHANNEL.name+"_fluid", false); +var FLUID = getOrDefault(CHANNEL.name+"_fluid", true); var LAYOUTBOX = getOrDefault(CHANNEL.name+"_layoutbox", true); var SOUNDSLVL = getOrDefault(CHANNEL.name+"_soundslvl", 3); var EMBEDIMG = getOrDefault(CHANNEL.name+"_embedimg", true); @@ -659,6 +659,7 @@ function setLayout() { logoInsert(USERCONFIG.logo); headerMode(USERCONFIG.header); customCSS(USERCONFIG.css); + refreshPlayer(); } // fit player height diff --git a/www/js/callbacks.js b/www/js/callbacks.js index 24f90ac3..d86c1994 100644 --- a/www/js/callbacks.js +++ b/www/js/callbacks.js @@ -676,6 +676,9 @@ Callbacks = { li.attr("title", data[i].queueby ? ("Added by: " + data[i].queueby) : "Added by: Unknown"); + if(data[i].media.type === "fi"){ + li.attr("id", "filei"); + } li.appendTo(q); } @@ -688,14 +691,22 @@ Callbacks = { c += "s"; $("#plcount").text(c); $("#pllength").text(data.time); + startTimes = data.sTimes; + dispSTimes(); }, queue: function(data) { PL_ACTION_QUEUE.queue(function (plq) { stopQueueSpinner(data.item.media); var li = makeQueueEntry(data.item, true); - if (data.item.uid === PL_CURRENT) + if (data.item.uid === PL_CURRENT){ li.addClass("queue_active"); + activeItem = data.uid; + } + if(data.item.media.type === "fi"){ + li.attr("id", "filei"); + } + li.hide(); var q = $("#queue"); li.attr("title", data.item.queueby @@ -774,6 +785,7 @@ Callbacks = { moveVideo: function(data) { PL_ACTION_QUEUE.queue(function (plq) { + startTimes = data.sTimes; playlistMove(data.from, data.after, function () { plq.release(); }); @@ -786,6 +798,7 @@ Callbacks = { var li = $(".pluid-" + uid); if (li.length !== 0) { li.addClass("queue_active"); + activeItem = uid; var tmr = setInterval(function () { if (!PL_WAIT_SCROLL) { scrollQueue(); diff --git a/www/js/fschd.js b/www/js/fschd.js new file mode 100644 index 00000000..65c08bed --- /dev/null +++ b/www/js/fschd.js @@ -0,0 +1,38 @@ +var startTimes = [[],[]]//UID's, StartTimes +var activeItem = 0;//active UID; +var rptime = 0;//reference playlist time +var rltime = 0;//refernce local time(epoch) +var ctime = 0; + +const st = new Date();//scratchtime + +function dispSTimes(){//update sTimes + var ptimeString, ltimeString; + calcRefs();//iterate and findRefs before calcTime + + //iterate and print + for(var i = 0; i < startTimes[0].length; i++){//for every item startTime + var rdif = startTimes[1][i] - rptime; + st.setTime(rltime + (rdif * 1000)); + ltimeString = "airdate: " + st.toLocaleTimeString() + " " + st.toLocaleDateString() + "
"; + ptimeString = "(pref time) " + formatTime(startTimes[1][i]);// create ptimeString + + if(document.getElementsByClassName("pluid-" + startTimes[0][i])[0] != null || document.getElementsByClassName("pluid-" + startTimes[0][i])[0] != undefined){//if current item isnt null or undefined + + document.getElementsByClassName("pluid-" + startTimes[0][i])[0].getElementsByClassName("qe_sTime")[0].innerHTML = ltimeString + ptimeString;// set current item qe_sTime innerHTML to ptimeString + + } + } + +} + +function calcRefs(){ + ld = new Date();//localdate + for(var i = 0; i < startTimes[0].length; i++){//for every item startTime/until activeItem + if(startTimes[0][i] == activeItem){ + rptime = startTimes[1][i]; + } + } + PLAYER.getTime(function(seek){ctime = seek}); + rltime = ld.getTime() - (ctime * 1000); +} diff --git a/www/js/player.js b/www/js/player.js index 2c15fedc..58bce3b1 100644 --- a/www/js/player.js +++ b/www/js/player.js @@ -1624,6 +1624,8 @@ window.handleMediaUpdate = function(data) { var PLAYER, waiting; PLAYER = window.PLAYER; + handleWindowResize(); + dispSTimes(); if (typeof PLAYER.mediaLength === 'number' && PLAYER.mediaLength > 0 && data.currentTime > PLAYER.mediaLength) { return; } diff --git a/www/js/playerjs-0.0.12.js b/www/js/playerjs-0.0.12.js deleted file mode 100644 index f91b54fa..00000000 --- a/www/js/playerjs-0.0.12.js +++ /dev/null @@ -1,1187 +0,0 @@ -/*! Player.js - v0.0.12 - 2016-10-20 -* http://github.com/embedly/player.js -* Copyright (c) 2016 Embedly; Licensed BSD */ -(function(window, document){ -var playerjs = {}; - -playerjs.DEBUG = false; -playerjs.VERSION = '0.0.11'; -playerjs.CONTEXT = 'player.js'; -playerjs.POST_MESSAGE = !!window.postMessage; - -/* -* Utils. -*/ -playerjs.origin = function(url){ - // Grab the origin of a URL - if (url.substr(0, 2) === '//'){ - url = window.location.protocol + url; - } - - return url.split('/').slice(0,3).join('/'); -}; - -playerjs.addEvent = function(elem, type, eventHandle) { - if (!elem) { return; } - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, eventHandle ); - } else { - elem["on"+type]=eventHandle; - } -}; - -// usage: log('inside coolFunc',this,arguments); -// http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/ -playerjs.log = function(){ - playerjs.log.history = playerjs.log.history || []; // store logs to an array for reference - playerjs.log.history.push(arguments); - if(window.console && playerjs.DEBUG){ - window.console.log( Array.prototype.slice.call(arguments) ); - } -}; - -// isFunctions -playerjs.isString = function (obj) { - return Object.prototype.toString.call(obj) === '[object String]'; -}; - -playerjs.isObject = function(obj){ - return Object.prototype.toString.call(obj) === "[object Object]"; -}; - -playerjs.isArray = function(obj){ - return Object.prototype.toString.call(obj) === "[object Array]"; -}; - -playerjs.isNone = function(obj){ - return (obj === null || obj === undefined); -}; - -playerjs.has = function(obj, key){ - return Object.prototype.hasOwnProperty.call(obj, key); -}; - -// ie8 doesn't support indexOf in arrays, based on underscore. -playerjs.indexOf = function(array, item) { - if (array == null){ return -1; } - var i = 0, length = array.length; - if (Array.prototype.IndexOf && array.indexOf === Array.prototype.IndexOf) { - return array.indexOf(item); - } - for (; i < length; i++) { - if (array[i] === item) { return i; } - } - return -1; -}; - -// Assert -playerjs.assert = function(test, msg) { - if (!test) { - throw msg || "Player.js Assert Failed"; - } -}; -/* -* Keeper is just a method for keeping track of all the callbacks. -*/ - -playerjs.Keeper = function(){ - this.init(); -}; - -playerjs.Keeper.prototype.init = function(){ - this.data = {}; -}; - -playerjs.Keeper.prototype.getUUID = function(){ - // Create a random id. #http://stackoverflow.com/a/2117523/564191 - return 'listener-xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8); - return v.toString(16); - }); -}; - -playerjs.Keeper.prototype.has = function(event, id){ - if (!this.data.hasOwnProperty(event)){ - return false; - } - - if (playerjs.isNone(id)){ - return true; - } - - // Figure out if we have the event. - var events = this.data[event]; - - for (var i = 0; i < events.length; i++){ - if (events[i].id === id){ - return true; - } - } - - return false; -}; - -playerjs.Keeper.prototype.add = function(id, event, cb, ctx, one){ - var d = { - id: id, - event: event, - cb: cb, - ctx: ctx, - one: one - }; - - if (this.has(event)){ - this.data[event].push(d); - } else { - this.data[event] = [d]; - } -}; - -playerjs.Keeper.prototype.execute = function(event, id, data, ctx){ - if (!this.has(event, id)){ - return false; - } - - var keep = [], - execute = []; - - for (var i=0; i< this.data[event].length; i++){ - var d = this.data[event][i]; - - // There are omni events, in that they do not have an id. i.e "ready". - // Or there is an ID and we only want to execute the right id'd method. - if (playerjs.isNone(id) || (!playerjs.isNone(id) && d.id === id )){ - - execute.push({ - cb: d.cb, - ctx: d.ctx? d.ctx: ctx, - data: data - }); - - // If we only wanted to execute this once. - if (d.one === false){ - keep.push(d); - } - } else { - keep.push(d); - } - } - - if (keep.length === 0){ - delete this.data[event]; - } else { - this.data[event] = keep; - } - - // We need to execute everything after we deal with the one stuff. otherwise - // we have issues to order of operations. - for (var n=0; n < execute.length; n++){ - var e = execute[n]; - e.cb.call(e.ctx, e.data); - } -}; - -playerjs.Keeper.prototype.on = function(id, event, cb, ctx){ - this.add(id, event, cb, ctx, false); -}; - -playerjs.Keeper.prototype.one = function(id, event, cb, ctx){ - this.add(id, event, cb, ctx, true); -}; - -playerjs.Keeper.prototype.off = function(event, cb){ - // We should probably restructure so this is a bit less of a pain. - var listeners = []; - - if (!this.data.hasOwnProperty(event)){ - return listeners; - } - - var keep = []; - - // Loop through everything. - for (var i=0; i< this.data[event].length; i++){ - var data = this.data[event][i]; - // If we only keep if there was a CB and the CB is there. - if (!playerjs.isNone(cb) && data.cb !== cb) { - keep.push(data); - } else if (!playerjs.isNone(data.id)) { - listeners.push(data.id); - } - } - - if (keep.length === 0){ - delete this.data[event]; - } else { - this.data[event] = keep; - } - - return listeners; -}; - -/* -* Player.js is a javascript library for interacting with iframes via -* postMessage that use an Open Player Spec -* -*/ - -playerjs.Player = function(elem, options){ - if (!(this instanceof playerjs.Player)) { - return new playerjs.Player(elem, options); - } - this.init(elem, options); -}; - -playerjs.EVENTS = { - READY: 'ready', - PLAY: 'play', - PAUSE: 'pause', - ENDED: 'ended', - TIMEUPDATE: 'timeupdate', - PROGRESS: 'progress', - ERROR: 'error' -}; - -playerjs.EVENTS.all = function(){ - var all = []; - for (var key in playerjs.EVENTS) { - if (playerjs.has(playerjs.EVENTS, key) && playerjs.isString(playerjs.EVENTS[key])) { - all.push(playerjs.EVENTS[key]); - } - } - return all; -}; - -playerjs.METHODS = { - PLAY: 'play', - PAUSE: 'pause', - GETPAUSED: 'getPaused', - MUTE: 'mute', - UNMUTE: 'unmute', - GETMUTED: 'getMuted', - SETVOLUME: 'setVolume', - GETVOLUME: 'getVolume', - GETDURATION: 'getDuration', - SETCURRENTTIME: 'setCurrentTime', - GETCURRENTTIME:'getCurrentTime', - SETLOOP: 'setLoop', - GETLOOP: 'getLoop', - REMOVEEVENTLISTENER: 'removeEventListener', - ADDEVENTLISTENER: 'addEventListener' -}; - -playerjs.METHODS.all = function(){ - var all = []; - for (var key in playerjs.METHODS) { - if (playerjs.has(playerjs.METHODS, key) && playerjs.isString(playerjs.METHODS[key])) { - all.push(playerjs.METHODS[key]); - } - } - return all; -}; - -playerjs.READIED = []; - -playerjs.Player.prototype.init = function(elem, options){ - - var self = this; - - if (playerjs.isString(elem)){ - elem = document.getElementById(elem); - } - - this.elem = elem; - - // Figure out the origin of where we are sending messages. - this.origin = playerjs.origin(elem.src); - - // Event handling. - this.keeper = new playerjs.Keeper(); - - // Queuing before ready. - this.isReady = false; - this.queue = []; - - // Assume that everything is supported, unless we know otherwise. - this.events = playerjs.EVENTS.all(); - this.methods = playerjs.METHODS.all(); - - if (playerjs.POST_MESSAGE){ - // Set up the reciever. - playerjs.addEvent(window, 'message', function(e){ - self.receive(e); - }); - } else { - playerjs.log('Post Message is not Available.'); - } - - // See if we caught the src event first, otherwise assume we haven't loaded - if (playerjs.indexOf(playerjs.READIED, elem.src) > -1){ - self.loaded = true; - } else { - // Try the onload event, just lets us give another test. - this.elem.onload = function(){ - self.loaded = true; - }; - } -}; - -playerjs.Player.prototype.send = function(data, callback, ctx){ - // Add the context and version to the data. - data.context = playerjs.CONTEXT; - data.version = playerjs.VERSION; - - // We are expecting a response. - if (callback) { - // Create a UUID - var id = this.keeper.getUUID(); - - // Set the listener. - data.listener = id; - - // Only hang on to this listener once. - this.keeper.one(id, data.method, callback, ctx); - } - - if (!this.isReady && data.value !== 'ready'){ - playerjs.log('Player.queue', data); - this.queue.push(data); - return false; - } - - playerjs.log('Player.send', data, this.origin); - - if (this.loaded === true){ - this.elem.contentWindow.postMessage(JSON.stringify(data), this.origin); - } - - return true; -}; - -playerjs.Player.prototype.receive = function(e){ - playerjs.log('Player.receive', e); - - if (e.origin !== this.origin){ - return false; - } - - var data; - try { - data = JSON.parse(e.data); - } catch (err){ - // Not a valid response. - return false; - } - - // abort if this message wasn't a player.js message - if (data.context !== playerjs.CONTEXT) { - return false; - } - - // We need to determine if we are ready. - if (data.event === 'ready' && data.value && data.value.src === this.elem.src){ - this.ready(data); - } - - if (this.keeper.has(data.event, data.listener)){ - this.keeper.execute(data.event, data.listener, data.value, this); - } -}; - - -playerjs.Player.prototype.ready = function(data){ - - if (this.isReady === true){ - return false; - } - - // If we got a list of supported methods, we should set them. - if (data.value.events){ - this.events = data.value.events; - } - if (data.value.methods){ - this.methods = data.value.methods; - } - - // set ready. - this.isReady = true; - this.loaded = true; - - // Clear the queue - for (var i=0; i 0) { - for (var i in listeners){ - this.send({ - method: 'removeEventListener', - value: event, - listener: listeners[i] - }); - return true; - } - } - - return false; -}; - -// Based on what ready passed back, we can determine if the events/method are -// supported by the player. -playerjs.Player.prototype.supports = function(evtOrMethod, names){ - - playerjs.assert(playerjs.indexOf(['method', 'event'], evtOrMethod) > -1, - 'evtOrMethod needs to be either "event" or "method" got ' + evtOrMethod); - - // Make everything an array. - names = playerjs.isArray(names) ? names : [names]; - - var all = evtOrMethod === 'event' ? this.events : this.methods; - - for (var i=0; i < names.length; i++){ - if (playerjs.indexOf(all, names[i]) === -1){ - return false; - } - } - - return true; -}; - -//create function to add to the Player prototype -function createPrototypeFunction(name) { - - return function() { - - var data = { - method: name - }; - - var args = Array.prototype.slice.call(arguments); - - //for getters add the passed parameters to the arguments for the send call - if (/^get/.test(name)) { - playerjs.assert(args.length > 0, 'Get methods require a callback.'); - args.unshift(data); - } else { - //for setter add the first arg to the value field - if (/^set/.test(name)) { - playerjs.assert(args.length !== 0, 'Set methods require a value.'); - data.value = args[0]; - } - args = [data]; - } - - this.send.apply(this, args); - }; -} - -// Loop through the methods to add them to the prototype. -for (var i = 0, l = playerjs.METHODS.all().length; i < l; i++) { - var methodName = playerjs.METHODS.all()[i]; - - // We don't want to overwrite existing methods. - if (!playerjs.Player.prototype.hasOwnProperty(methodName)){ - playerjs.Player.prototype[methodName] = createPrototypeFunction(methodName); - } -} - -// We need to catch all ready events in case the iframe is ready before the -// player is invoked. -playerjs.addEvent(window, 'message', function(e){ - var data; - try { - data = JSON.parse(e.data); - } catch (err){ - return false; - } - - // abort if this message wasn't a player.js message - if (data.context !== playerjs.CONTEXT) { - return false; - } - - // We need to determine if we are ready. - if (data.event === 'ready' && data.value && data.value.src){ - playerjs.READIED.push(data.value.src); - } -}); - -/* -* Does all the wiring up for the backend. -* -* var receiver = new playerjs.Receiver(); -* receiver.on('play', function(){ video.play() }); -* receiver.on('getDuration', function(callback){ callback(video.duration) }); -* receiver.emit('timeupdate', {}); -*/ - -playerjs.Receiver = function(events, methods){ - this.init(events, methods); -}; - -playerjs.Receiver.prototype.init = function(events, methods){ - var self = this; - - // Deal with the ready crap. - this.isReady = false; - - // Bind the window message. - this.origin = playerjs.origin(document.referrer); - - //Create a holder for all the methods. - this.methods = {}; - - // holds all the information about what's supported - this.supported = { - events: events ? events : playerjs.EVENTS.all(), - methods: methods ? methods : playerjs.METHODS.all() - }; - - // Deals with the adding and removing of event listeners. - this.eventListeners = {}; - - // We can't send any messages. - this.reject = !(window.self !== window.top && playerjs.POST_MESSAGE); - - // We aren't in an iframe, don't listen. - if (!this.reject){ - playerjs.addEvent(window, 'message', function(e){ - self.receive(e); - }); - } -}; - -playerjs.Receiver.prototype.receive = function(e){ - // Only want to listen to events that came from our origin. - if (e.origin !== this.origin){ - return false; - } - - // Browsers that support postMessage also support JSON. - var data = {}; - if (playerjs.isObject(e.data)){ - data = e.data; - } else { - try { - data = window.JSON.parse(e.data); - } catch (err){ - playerjs.log('JSON Parse Error', err); - } - } - - playerjs.log('Receiver.receive', e, data); - - // Nothing for us to do. - if (!data.method){ - return false; - } - - // make sure the context is correct. - if (data.context !== playerjs.CONTEXT){ - return false; - } - - // Make sure we have a valid method. - if (playerjs.indexOf(playerjs.METHODS.all(), data.method) === -1){ - this.emit('error', { - code: 2, - msg: 'Invalid Method "'+data.method+'"' - }); - return false; - } - - // See if we added a listener - var listener = !playerjs.isNone(data.listener) ? data.listener : null; - - // Add Event Listener. - if (data.method === 'addEventListener') { - if (this.eventListeners.hasOwnProperty(data.value)) { - //If the listener is the same, i.e. null only add it once. - if (playerjs.indexOf(this.eventListeners[data.value], listener) === -1){ - this.eventListeners[data.value].push(listener); - } - } else { - this.eventListeners[data.value] = [listener]; - } - - if (data.value === 'ready' && this.isReady){ - this.ready(); - } - } - // Remove the event listener. - else if (data.method === 'removeEventListener') { - if (this.eventListeners.hasOwnProperty(data.value)) { - var index = playerjs.indexOf(this.eventListeners[data.value], listener); - - // if we find the element, remove it. - if (index > -1){ - this.eventListeners[data.value].splice(index, 1); - } - - if (this.eventListeners[data.value].length === 0){ - delete this.eventListeners[data.value]; - } - } - } - // Go get it. - else { - this.get(data.method, data.value, listener); - } -}; - -playerjs.Receiver.prototype.get = function(method, value, listener){ - var self = this; - - // Now lets do it. - if (!this.methods.hasOwnProperty(method)){ - this.emit('error', { - code: 3, - msg: 'Method Not Supported"'+method+'"' - }); - return false; - } - - var func = this.methods[method]; - - if (method.substr(0,3) === 'get') { - var callback = function(val){ - self.send(method, val, listener); - }; - func.call(this, callback); - } else { - func.call(this, value); - } -}; - -playerjs.Receiver.prototype.on = function(event, callback){ - this.methods[event] = callback; -}; - -playerjs.Receiver.prototype.send = function(event, value, listener){ - - playerjs.log('Receiver.send', event, value, listener); - - if (this.reject){ - // We are not in a frame, or we don't support POST_MESSAGE - playerjs.log('Receiver.send.reject', event, value, listener); - return false; - } - - var data = { - context: playerjs.CONTEXT, - version: playerjs.VERSION, - event: event - }; - - if (!playerjs.isNone(value)){ - data.value = value; - } - - if (!playerjs.isNone(listener)){ - data.listener = listener; - } - - var msg = JSON.stringify(data); - window.parent.postMessage(msg, this.origin === "" ? '*' : this.origin); -}; - -playerjs.Receiver.prototype.emit = function(event, value){ - - if (!this.eventListeners.hasOwnProperty(event)){ - return false; - } - - playerjs.log('Instance.emit', event, value, this.eventListeners[event]); - - for (var i=0; i < this.eventListeners[event].length; i++){ - var listener = this.eventListeners[event][i]; - this.send(event, value, listener); - } - - return true; -}; - -playerjs.Receiver.prototype.ready = function(){ - playerjs.log('Receiver.ready'); - this.isReady = true; - - var data = { - src: window.location.toString(), - events: this.supported.events, - methods: this.supported.methods - }; - - if (!this.emit('ready', data)){ - this.send('ready', data); - } - -}; - -playerjs.HTML5Adapter = function(video){ - if (!(this instanceof playerjs.HTML5Adapter)) { - return new playerjs.HTML5Adapter(video); - } - this.init(video); -}; - -playerjs.HTML5Adapter.prototype.init = function(video){ - - playerjs.assert(video, 'playerjs.VideoJSReceiver requires a video element'); - - // Set up the actual receiver - var receiver = this.receiver = new playerjs.Receiver(); - - /* EVENTS */ - video.addEventListener('playing', function(){ - receiver.emit('play'); - }); - - video.addEventListener('pause', function(){ - receiver.emit('pause'); - }); - - video.addEventListener('ended', function(){ - receiver.emit('ended'); - }); - - video.addEventListener('timeupdate', function(){ - receiver.emit('timeupdate', { - seconds: video.currentTime, - duration: video.duration - }); - }); - - video.addEventListener('progress', function(){ - receiver.emit('buffered', { - percent: video.buffered.length - }); - }); - - /* Methods */ - receiver.on('play', function(){ - video.play(); - }); - - receiver.on('pause', function(){ - video.pause(); - }); - - receiver.on('getPaused', function(callback){ - callback(video.paused); - }); - - receiver.on('getCurrentTime', function(callback){ - callback(video.currentTime); - }); - - receiver.on('setCurrentTime', function(value){ - video.currentTime = value; - }); - - receiver.on('getDuration', function(callback){ - callback(video.duration); - }); - - receiver.on('getVolume', function(callback){ - callback(video.volume * 100); - }); - - receiver.on('setVolume', function(value){ - video.volume = value/100; - }); - - receiver.on('mute', function(){ - video.muted = true; - }); - - receiver.on('unmute', function(){ - video.muted = false; - }); - - receiver.on('getMuted', function(callback){ - callback(video.muted); - }); - - receiver.on('getLoop', function(callback){ - callback(video.loop); - }); - - receiver.on('setLoop', function(value){ - video.loop = value; - }); -}; - -/* Call when the video has loaded */ -playerjs.HTML5Adapter.prototype.ready = function(){ - this.receiver.ready(); -}; -//http://www.longtailvideo.com/support/jw-player/28851/javascript-api-reference -playerjs.JWPlayerAdapter = function(player){ - if (!(this instanceof playerjs.JWPlayerAdapter)) { - return new playerjs.JWPlayerAdapter(player); - } - this.init(player); -}; - -playerjs.JWPlayerAdapter.prototype.init = function(player){ - - playerjs.assert(player, 'playerjs.JWPlayerAdapter requires a player object'); - - // Set up the actual receiver - var receiver = this.receiver = new playerjs.Receiver(); - - // JWPlayer doesn't have a seLoop, so we can do it ourself. - this.looped = false; - - /* EVENTS */ - player.onPause(function(){ - receiver.emit('pause'); - }); - - player.onPlay(function(){ - receiver.emit('play'); - }); - - player.onTime(function(e){ - var seconds = e.position, - duration = e.duration; - - if (!seconds || !duration){ - return false; - } - - var value = { - seconds: seconds, - duration: duration - }; - receiver.emit('timeupdate', value); - }); - - var self = this; - player.onComplete(function(){ - // Fake the looping - if (self.looped === true){ - // By default jwplayer seeks after play. - player.seek(0); - } else { - // Else throw the ended event. - receiver.emit('ended'); - } - }); - - player.onError(function(){ - receiver.emit('error'); - }); - - - /* METHODS */ - receiver.on('play', function(){ - player.play(true); - }); - - receiver.on('pause', function(){ - player.pause(true); - }); - - receiver.on('getPaused', function(callback){ - callback(player.getState().toLowerCase() !== 'PLAYING'.toLowerCase()); - }); - - receiver.on('getCurrentTime', function(callback){ - callback(player.getPosition()); - }); - - receiver.on('setCurrentTime', function(value){ - player.seek(value); - }); - - receiver.on('getDuration', function(callback){ - callback(player.getDuration()); - }); - - receiver.on('getVolume', function(callback){ - callback(player.getVolume()); - }); - - receiver.on('setVolume', function(value){ - player.setVolume(value); - }); - - receiver.on('mute', function(){ - player.setMute(true); - }); - - receiver.on('unmute', function(){ - player.setMute(false); - }); - - receiver.on('getMuted', function(callback){ - callback(player.getMute() === true); - }); - - receiver.on('getLoop', function(callback){ - callback(this.looped); - }, this); - - receiver.on('setLoop', function(value){ - this.looped = value; - }, this); -}; - -/* Call when the video.js is ready */ -playerjs.JWPlayerAdapter.prototype.ready = function(){ - this.receiver.ready(); -}; - -playerjs.MockAdapter = function(){ - if (!(this instanceof playerjs.MockAdapter)) { - return new playerjs.MockAdapter(); - } - this.init(); -}; - -playerjs.MockAdapter.prototype.init = function(){ - - // Our mock video - var video = { - duration: 20, - currentTime: 0, - interval: null, - timeupdate: function(){}, - volume: 100, - mute: false, - playing: false, - loop : false, - play: function(){ - video.interval = setInterval(function(){ - video.currentTime += 0.25; - video.timeupdate({ - seconds: video.currentTime, - duration: video.duration - }); - }, 250); - video.playing = true; - }, - pause: function(){ - clearInterval(video.interval); - video.playing = false; - } - }; - - // Set up the actual receiver - var receiver = this.receiver = new playerjs.Receiver(); - - receiver.on('play', function(){ - var self = this; - video.play(); - this.emit('play'); - video.timeupdate = function(data){ - self.emit('timeupdate', data); - }; - }); - - receiver.on('pause', function(){ - video.pause(); - this.emit('pause'); - }); - - receiver.on('getPaused', function(callback){ - callback(!video.playing); - }); - - receiver.on('getCurrentTime', function(callback){ - callback(video.currentTime); - }); - - receiver.on('setCurrentTime', function(value){ - video.currentTime = value; - }); - - receiver.on('getDuration', function(callback){ - callback(video.duration); - }); - - receiver.on('getVolume', function(callback){ - callback(video.volume); - }); - - receiver.on('setVolume', function(value){ - video.volume = value; - }); - - receiver.on('mute', function(){ - video.mute = true; - }); - - receiver.on('unmute', function(){ - video.mute = false; - }); - - receiver.on('getMuted', function(callback){ - callback(video.mute); - }); - - receiver.on('getLoop', function(callback){ - callback(video.loop); - }); - - receiver.on('setLoop', function(value){ - video.loop = value; - }); -}; - -/* Call when the video has loaded */ -playerjs.MockAdapter.prototype.ready = function(){ - this.receiver.ready(); -}; -playerjs.VideoJSAdapter = function(player){ - if (!(this instanceof playerjs.VideoJSAdapter)) { - return new playerjs.VideoJSAdapter(player); - } - this.init(player); -}; - -playerjs.VideoJSAdapter.prototype.init = function(player){ - - playerjs.assert(player, 'playerjs.VideoJSReceiver requires a player object'); - - // Set up the actual receiver - var receiver = this.receiver = new playerjs.Receiver(); - - /* EVENTS */ - player.on("pause", function(){ - receiver.emit('pause'); - }); - - player.on("play", function(){ - receiver.emit('play'); - }); - - player.on("timeupdate", function(e){ - var seconds = player.currentTime(), - duration = player.duration(); - - if (!seconds || !duration){ - return false; - } - - var value = { - seconds: seconds, - duration: duration - }; - receiver.emit('timeupdate', value); - }); - - player.on("ended", function(){ - receiver.emit('ended'); - }); - - player.on("error", function(){ - receiver.emit('error'); - }); - - - /* METHODS */ - receiver.on('play', function(){ - player.play(); - }); - - receiver.on('pause', function(){ - player.pause(); - }); - - receiver.on('getPaused', function(callback){ - callback(player.paused()); - }); - - receiver.on('getCurrentTime', function(callback){ - callback(player.currentTime()); - }); - - receiver.on('setCurrentTime', function(value){ - player.currentTime(value); - }); - - receiver.on('getDuration', function(callback){ - callback(player.duration()); - }); - - receiver.on('getVolume', function(callback){ - callback(player.volume() * 100); - }); - - receiver.on('setVolume', function(value){ - player.volume(value/100); - }); - - receiver.on('mute', function(){ - player.volume(0); - }); - - receiver.on('unmute', function(){ - player.volume(1); - }); - - receiver.on('getMuted', function(callback){ - callback(player.volume() === 0); - }); - - receiver.on('getLoop', function(callback){ - callback(player.loop()); - }); - - receiver.on('setLoop', function(value){ - player.loop(value); - }); -}; - -/* Call when the video.js is ready */ -playerjs.VideoJSAdapter.prototype.ready = function(){ - this.receiver.ready(); -}; - - if (typeof define === 'function' && define.amd) { - define(function () { - return playerjs - }) - } else if (typeof module === 'object' && module.exports) { - module.exports = playerjs - } else { - window.playerjs = playerjs; - } -})(window, document); diff --git a/www/js/ui.js b/www/js/ui.js index 2db2ea35..f625c65e 100644 --- a/www/js/ui.js +++ b/www/js/ui.js @@ -320,7 +320,8 @@ $("#queue").sortable({ PL_AFTER = $(prev[0]).data("uid"); socket.emit("moveMedia", { from: PL_FROM, - after: PL_AFTER + after: PL_AFTER, + sTimes: [[],[]] }); $("#queue").sortable("cancel"); } @@ -938,3 +939,4 @@ $("#resize-video-smaller").click(function () { console.error(error); } }); + diff --git a/www/js/util.js b/www/js/util.js index 70df5ffe..9f21940c 100644 --- a/www/js/util.js +++ b/www/js/util.js @@ -466,6 +466,7 @@ function scrollQueue() { function makeQueueEntry(item, addbtns) { var video = item.media; var li = $("
  • "); + console.log(item); li.addClass("queue_entry"); li.addClass("pluid-" + item.uid); li.data("uid", item.uid); @@ -482,7 +483,11 @@ function makeQueueEntry(item, addbtns) { .attr("href", formatURL(video)) .attr("target", "_blank"); var time = $("").addClass("qe_time").appendTo(li); - time.text(video.duration); + time.text("airtime: " + video.duration); + $("
    ").appendTo(li); + var sTime = $("").addClass("qe_sTime").appendTo(li); + sTime.text(" \n"); + //dispSTimes(); var clear = $("
    ").addClass("qe_clear").appendTo(li); if(item.temp) { li.addClass("queue_temp"); @@ -533,7 +538,8 @@ function addQueueButtons(li) { .click(function() { socket.emit("moveMedia", { from: li.data("uid"), - after: PL_CURRENT + after: PL_CURRENT, + sTimes: [[],[]] }); }) .appendTo(menu); @@ -2890,6 +2896,7 @@ function checkScriptAccess(viewSource, type, cb) { setOpt("channel_js_pref", JSPREF); } cb("ALLOW"); + handleVideoResize(); }); $("#chanjs-deny").click(function () {