diff --git a/airsonic-main/src/main/webapp/WEB-INF/jsp/externalPlayer.jsp b/airsonic-main/src/main/webapp/WEB-INF/jsp/externalPlayer.jsp index 1349d9ab..a354f560 100644 --- a/airsonic-main/src/main/webapp/WEB-INF/jsp/externalPlayer.jsp +++ b/airsonic-main/src/main/webapp/WEB-INF/jsp/externalPlayer.jsp @@ -4,68 +4,18 @@ <%@ include file="head.jsp" %> - - - - + + + + "> - - - +

@@ -78,16 +28,38 @@

-
+

${empty model.share.description ? model.songs[0].albumName : fn:escapeXml(model.share.username)}

-
Streaming by Airsonic
- -
-
- -
-
+ + + +
Streaming by Airsonic
+ + + diff --git a/airsonic-main/src/main/webapp/script/mediaelement/playlist-controls.svg b/airsonic-main/src/main/webapp/script/mediaelement/playlist-controls.svg new file mode 100644 index 00000000..e066d656 --- /dev/null +++ b/airsonic-main/src/main/webapp/script/mediaelement/playlist-controls.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/airsonic-main/src/main/webapp/script/mediaelement/playlist.min.css b/airsonic-main/src/main/webapp/script/mediaelement/playlist.min.css new file mode 100644 index 00000000..ac0fbaa5 --- /dev/null +++ b/airsonic-main/src/main/webapp/script/mediaelement/playlist.min.css @@ -0,0 +1 @@ +.mejs-container.mejs-video,.mejs__container.mejs__video{overflow:hidden}.mejs-container.mejs-audio,.mejs__container.mejs__audio{min-height:200px}.mejs-container.mejs-audio.mejs__no-playlist,.mejs__container.mejs__audio.mejs__no-playlist{min-height:60px}.mejs-playlist-button,.mejs__playlist-button{position:relative}.mejs-loop-button>button,.mejs-next-button>button,.mejs-playlist-button>button,.mejs-prev-button>button,.mejs-shuffle-button>button,.mejs__loop-button>button,.mejs__next-button>button,.mejs__playlist-button>button,.mejs__prev-button>button,.mejs__shuffle-button>button{background:url(playlist-controls.svg) transparent no-repeat}.mejs-playlist-button>button,.mejs__playlist-button>button{background-position:-80px 0}.mejs-next-button>button,.mejs__next-button>button{background-position:0 0}.mejs-prev-button>button,.mejs__prev-button>button{background-position:-20px 0}.mejs-loop-button>button,.mejs__loop-button>button{background-position:-120px 0}.mejs-shuffle-button>button,.mejs__shuffle-button>button{background-position:-100px 0}.mejs-loop-button.mejs-loop-off>button,.mejs-shuffle-button.mejs-shuffle-off>button,.mejs__loop-button.mejs__loop-off>button,.mejs__shuffle-button.mejs__shuffle-off>button{opacity:.7}.mejs-playlist-button>.mejs-playlist-selector,.mejs__playlist-button>.mejs__playlist-selector{background:rgba(50,50,50,.7);border:1px solid transparent;border-radius:0;bottom:100%;margin-right:-43px;overflow:hidden;padding:0;position:absolute;right:50%;visibility:visible;width:86px}.mejs-playlist-selector-list,.mejs__playlist-selector-list{height:100%;list-style-type:none!important;margin:0;overflow-y:auto;padding:0}.mejs-playlist-selector-list-item,.mejs__playlist-selector-list-item{border-bottom:1px solid #c8c8c8;border-collapse:collapse;cursor:pointer;display:table;list-style-type:none!important;position:relative;width:100%}.mejs__playlist-item-inner{display:table-row;overflow:hidden}.mejs-playlist-selector-list-item:hover,.mejs__playlist-selector-list-item:hover{background-color:#c8c8c8!important;background-color:hsla(0,0%,100%,.4)!important}.mejs-playlist-selector-list-item:focus,.mejs__playlist-selector-list-item:focus{outline:none}.mejs-playlist-selector-input,.mejs__playlist-selector-input{left:-1000px;position:absolute}.mejs-playlist-selector-label,.mejs__playlist-selector-label{cursor:pointer;float:left;font-size:1.3em;margin:0}.mejs-playlist-selector-label>span,.mejs__playlist-selector-label>span{-webkit-background-clip:text;background-clip:text;background-color:#eb5802;background-image:-webkit-linear-gradient(top,#eb5802,#f3ad39);background-image:linear-gradient(180deg,#eb5802,#f3ad39);color:transparent;font-size:.65em;vertical-align:middle}.mejs-playlist-selected,.mejs__playlist-selected{background-color:#3a3a3a}.mejs-playlist-layer,.mejs__playlist-layer{background:#222;bottom:40px;color:#fff;font-size:12px;height:calc(100% - 40px)!important;overflow:hidden;position:absolute;right:0;text-align:center;top:0;-webkit-transition:.5s;transition:.5s;width:33.33333%!important;z-index:1}.mejs-container.mejs-audio .mejs-playlist-layer,.mejs__container.mejs__audio .mejs__playlist-layer{bottom:85px;height:calc(100% - 85px)!important;overflow:auto;width:100%!important}.mejs-playlist-hidden,.mejs__playlist-hidden{right:-33.33333%;-webkit-transition:.5s;transition:.5s}.mejs-playlist-item-thumbnail,.mejs__playlist-item-thumbnail{display:table-cell;padding:7px 5px;vertical-align:top;width:30%}.mejs-container.mejs-audio .mejs-playlist-item-thumbnail,.mejs__container.mejs__audio .mejs__playlist-item-thumbnail{padding:5px;width:15%}.mejs-playlist-item-thumbnail>img,.mejs__playlist-item-thumbnail>img{height:auto;width:100%}.mejs-playlist-item-content,.mejs__playlist-item-content{display:table-cell;padding:10px;width:70%}.mejs-container.mejs-audio .mejs-playlist-item-content,.mejs__container.mejs__audio .mejs__playlist-item-content{margin:0;width:85%}.mejs-playlist-item-description,.mejs__playlist-item-description{clear:left;padding:5px 0;text-align:left}.mejs-playlist-current,.mejs__playlist-current{background:#000;bottom:34px;height:auto!important;left:0;position:absolute;z-index:2}.mejs-playlist-current p,.mejs__playlist-current p{color:#fff;font-size:.8em;margin:15px 10px}.mejs-playlist-current>img,.mejs__playlist-current>img{float:left;margin:5px 10px;max-height:35px}.mejs-playlist-current-description,.mejs-playlist-current-title,.mejs__playlist-current-description,.mejs__playlist-current-title{font-style:italic} \ No newline at end of file diff --git a/airsonic-main/src/main/webapp/script/mediaelement/playlist.min.js b/airsonic-main/src/main/webapp/script/mediaelement/playlist.min.js new file mode 100644 index 00000000..59d0dcfe --- /dev/null +++ b/airsonic-main/src/main/webapp/script/mediaelement/playlist.min.js @@ -0,0 +1,12 @@ +/*! + * MediaElement.js + * http://www.mediaelementjs.com/ + * + * Wrapper that mimics native HTML5 MediaElement (audio and video) + * using a variety of technologies (pure JavaScript, Flash, iframe) + * + * Copyright 2010-2017, John Dyer (http://j.hn/) + * License: MIT + * + */ +!function t(e,l,s){function i(a,o){if(!l[a]){if(!e[a]){var r="function"==typeof require&&require;if(!o&&r)return r(a,!0);if(n)return n(a,!0);var p=new Error("Cannot find module '"+a+"'");throw p.code="MODULE_NOT_FOUND",p}var c=l[a]={exports:{}};e[a][0].call(c.exports,function(t){var l=e[a][1][t];return i(l||t)},c,c.exports,t,e,l,s)}return l[a].exports}for(var n="function"==typeof require&&require,a=0;a'),a.innerHTML+="

"+t.options.currentMessage+' '+t.playlist[t.currentPlaylistItem].title+"",void 0!==t.playlist[t.currentPlaylistItem].description&&(a.innerHTML+=' - '+t.playlist[t.currentPlaylistItem].description+""),a.innerHTML+="

",t.resetSize()};a.className=t.options.classPrefix+"playlist-current "+t.options.classPrefix+"layer",o(),l.insertBefore(a,l.firstChild),s.addEventListener("play",o)}if(t.options.showPlaylist){t.playlistLayer=document.createElement("div"),t.playlistLayer.className=t.options.classPrefix+"playlist-layer "+t.options.classPrefix+"layer "+(t.isVideo?t.options.classPrefix+"playlist-hidden":"")+" "+t.options.classPrefix+"playlist-selector",t.playlistLayer.innerHTML='',l.insertBefore(t.playlistLayer,l.firstChild);for(var r=0,p=t.listItems.length;r',t.playlistButton.addEventListener("click",function(){mejs.Utils.toggleClass(t.playlistLayer,t.options.classPrefix+"playlist-hidden")}),t.addControlElement(t.playlistButton,"playlist");else{var c=t.playlistLayer.querySelectorAll("li");if(c.length<=10){for(var u=0,f=0,y=c.length;f▶ "+this.closest("."+t.options.classPrefix+"playlist-selector-list-item").querySelector("label").innerHTML,mejs.Utils.addClass(this.closest("."+t.options.classPrefix+"playlist-selector-list-item"),t.options.classPrefix+"playlist-selected"),t.currentPlaylistItem=this.getAttribute("data-playlist-index"),t.setSrc(this.value),t.load(),t.play(),t.isVideo&&!0===t.options.autoClosePlaylist&&mejs.Utils.toggleClass(t.playlistLayer,t.options.classPrefix+"playlist-hidden")});for(var h=0,P=d.length;h',t.prevPlaylistCallback=function(){t.playlist[--t.currentPlaylistItem]?(t.setSrc(t.playlist[t.currentPlaylistItem].src),t.load(),t.play()):++t.currentPlaylistItem},t.prevButton.addEventListener("click",t.prevPlaylistCallback),t.addControlElement(t.prevButton,"prevtrack")},cleanprevtrack:function(t){t.prevButton.removeEventListener("click",t.prevPlaylistCallback)},buildnexttrack:function(t){var e=mejs.i18n.t("mejs.playlist-next"),l=mejs.Utils.isString(t.options.nextText)?t.options.nextText:e;t.nextButton=document.createElement("div"),t.nextButton.className=t.options.classPrefix+"button "+t.options.classPrefix+"next-button",t.nextButton.innerHTML='',t.nextPlaylistCallback=function(){t.playlist[++t.currentPlaylistItem]?(t.setSrc(t.playlist[t.currentPlaylistItem].src),t.load(),t.play()):--t.currentPlaylistItem},t.nextButton.addEventListener("click",t.nextPlaylistCallback),t.addControlElement(t.nextButton,"nexttrack")},cleannexttrack:function(t){t.nextButton.removeEventListener("click",t.nextPlaylistCallback)},buildloop:function(t){var e=mejs.i18n.t("mejs.playlist-loop"),l=mejs.Utils.isString(t.options.loopText)?t.options.loopText:e;t.loopButton=document.createElement("div"),t.loopButton.className=t.options.classPrefix+"button "+t.options.classPrefix+"loop-button "+(t.options.loop?t.options.classPrefix+"loop-on":t.options.classPrefix+"loop-off"),t.loopButton.innerHTML='',t.loopCallback=function(){t.options.loop=!t.options.loop,t.options.loop?(mejs.Utils.removeClass(t.loopButton,t.options.classPrefix+"loop-off"),mejs.Utils.addClass(t.loopButton,t.options.classPrefix+"loop-on")):(mejs.Utils.removeClass(t.loopButton,t.options.classPrefix+"loop-on"),mejs.Utils.addClass(t.loopButton,t.options.classPrefix+"loop-off"))},t.loopButton.addEventListener("click",t.loopCallback),t.addControlElement(t.loopButton,"loop")},cleanloop:function(t){t.loopButton.removeEventListener("click",t.loopCallback)},buildshuffle:function(t){var e=mejs.i18n.t("mejs.playlist-shuffle"),l=mejs.Utils.isString(t.options.shuffleText)?t.options.shuffleText:e;t.shuffleButton=document.createElement("div"),t.shuffleButton.className=t.options.classPrefix+"button "+t.options.classPrefix+"shuffle-button "+t.options.classPrefix+"shuffle-off",t.shuffleButton.innerHTML='',t.shuffleButton.style.display="none",t.media.addEventListener("play",function(){t.shuffleButton.style.display="",t.resetSize()});var s=!1,i=[],n=function(){if(!t.options.loop){var e=Math.floor(Math.random()*t.playlist.length);-1===i.indexOf(e)?(t.setSrc(t.playlist[e].src),t.load(),t.play(),t.currentPlaylistItem=e,i.push(e)):i.length
':"",u=o["data-playlist-description"]?'
'+o["data-playlist-description"]+"
":"";r.tabIndex=0,r.className=t.options.classPrefix+"playlist-selector-list-item"+(0===n?" "+t.options.classPrefix+"playlist-selected":""),r.innerHTML='
'+c+'
"+u+"
",t.listItems.push(r.outerHTML)}}}})},{}]},{},[1]); \ No newline at end of file