From 0e05a8648404d48fb974bb069e1b465219165a44 Mon Sep 17 00:00:00 2001
From: Robin Appelman <icewind1991@gmail.com>
Date: Tue, 26 Jul 2011 16:04:57 +0200
Subject: [PATCH] some refactoring of the media player code

---
 apps/media/appinfo/app.php      |   7 +-
 apps/media/css/jplayer.css      | 461 --------------------------------
 apps/media/css/music.css        |   9 +
 apps/media/css/player.css       |  29 ++
 apps/media/css/style.css        |  36 ---
 apps/media/index.php            |   9 +
 apps/media/js/files.js          |  50 ++++
 apps/media/js/music.js          | 379 ++++----------------------
 apps/media/js/player.js         | 120 +++++++++
 apps/media/templates/music.php  |  35 +--
 apps/media/templates/player.php |  23 ++
 11 files changed, 297 insertions(+), 861 deletions(-)
 delete mode 100644 apps/media/css/jplayer.css
 create mode 100644 apps/media/css/music.css
 create mode 100644 apps/media/css/player.css
 delete mode 100644 apps/media/css/style.css
 create mode 100644 apps/media/js/files.js
 create mode 100644 apps/media/js/player.js
 create mode 100644 apps/media/templates/player.php

diff --git a/apps/media/appinfo/app.php b/apps/media/appinfo/app.php
index 9eab03b631..22cb10d789 100644
--- a/apps/media/appinfo/app.php
+++ b/apps/media/appinfo/app.php
@@ -22,10 +22,9 @@
 
 require_once('apps/media/lib_media.php');
 
-OC_UTIL::addScript('media','music');
-OC_UTIL::addScript('media','jquery.jplayer.min');
-OC_UTIL::addStyle('media','style');
-OC_UTIL::addStyle('media','jplayer');
+if(OC_APP::getCurrentApp()=='files'){
+	OC_UTIL::addScript('media','files');
+}
 
 OC_APP::register( array( 'order' => 3, 'id' => 'media', 'name' => 'Media' ));
 
diff --git a/apps/media/css/jplayer.css b/apps/media/css/jplayer.css
deleted file mode 100644
index c47d20c722..0000000000
--- a/apps/media/css/jplayer.css
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * Skin for jPlayer Plugin (jQuery JavaScript Library)
- * http://www.happyworm.com/jquery/jplayer
- *
- * Skin Name: Blue Monday
- *
- * Copyright (c) 2010 Happyworm Ltd
- * Dual licensed under the MIT and GPL licenses.
- *  - http://www.opensource.org/licenses/mit-license.php
- *  - http://www.gnu.org/copyleft/gpl.html
- *
- * Author: Silvia Benvenuti
- * Skin Version: 3.0 (jPlayer 2.0.0)
- * Date: 20th December 2010
- */
-
-div.jp-audio,
-div.jp-video {
-	
-	/* Edit the font-size to counteract inherited font sizing.
-	 * Eg. 1.25em = 1 / 0.8em
-	 */
-	
-	font-size:1.25em;
-	
-	font-family:Verdana, Arial, sans-serif;
-	line-height:1.6;
-	color: #000;
-}
-div.jp-audio {
-	position:relative;
-	margin-left:70ex;
-	margin-right:0px;
-	top:0px;
-	margin-top:-30px;
-}
-div.jp-video-270p {
-	width:480px;
-}
-div.jp-video-360p {
-	width:640px;
-}
-div.jp-interface {
-	position: fixed;
-	z-index:100;
-	width:25em;
-	left:201px;
-	top:-10px;
-}
-div.jp-type-playlist{
-	width:100%;
-}
-div.jp-audio div.jp-type-single div.jp-interface {
-	height:80px;
-	border-bottom:none;
-}
-div.jp-audio div.jp-type-playlist div.jp-interface {
-	height:80px;
-}
-div.jp-video div.jp-type-single div.jp-interface {
-	height:60px;
-	border-bottom:none;
-}
-div.jp-video div.jp-type-playlist div.jp-interface {
-	height:60px;
-}
-div.jp-interface ul.jp-controls {
-	list-style-type:none;
-	padding:0;
-}
-div.jp-interface ul.jp-controls li {
-	/* position: absolute; */
-	display:inline;
-}
-div.jp-interface ul.jp-controls a {
-	position: absolute;
-	overflow:hidden;
-	text-indent:-9999px;
-}
-a.jp-play,
-a.jp-pause {
-	width:40px;
-	height:40px;
-	z-index:1;
-}
-div.jp-audio div.jp-type-single a.jp-play,
-div.jp-audio div.jp-type-single a.jp-pause {
-	top:20px;
-	left:40px;
-}
-div.jp-audio div.jp-type-playlist a.jp-play,
-div.jp-audio div.jp-type-playlist a.jp-pause {
-	top:20px;
-	left:48px;
-}
-div.jp-video a.jp-play,
-div.jp-video a.jp-pause {
-	top:15px;
-}
-div.jp-video-270p div.jp-type-single a.jp-play,
-div.jp-video-270p div.jp-type-single a.jp-pause {
-	left:195px;
-}
-div.jp-video-270p div.jp-type-playlist a.jp-play,
-div.jp-video-270p div.jp-type-playlist a.jp-pause {
-	left:220px;
-}
-div.jp-video-360p div.jp-type-single a.jp-play,
-div.jp-video-360p div.jp-type-single a.jp-pause {
-	left:275px;
-}
-div.jp-video-360p div.jp-type-playlist a.jp-play,
-div.jp-video-360p div.jp-type-playlist a.jp-pause {
-	left:300px;
-}
-a.jp-play {
-	background: url("../img/jplayer.blue.monday.png") 0 0 no-repeat;
-}
-a.jp-play:hover {
-	background: url("../img/jplayer.blue.monday.png") -41px 0 no-repeat;
-}
-a.jp-pause {
-	background: url("../img/jplayer.blue.monday.png") 0 -42px no-repeat;
-	display: none;
-}
-a.jp-pause:hover {
-	background: url("../img/jplayer.blue.monday.png") -41px -42px no-repeat;
-}
-div.jp-audio div.jp-type-single a.jp-stop {
-	top:26px;
-	left:90px;
-}
-div.jp-audio div.jp-type-playlist a.jp-stop {
-	top:26px;
-	left:126px;
-}
-div.jp-video a.jp-stop {
-	top:21px;
-}
-div.jp-video-270p div.jp-type-single a.jp-stop {
-	left:245px;
-}
-div.jp-video-270p div.jp-type-playlist a.jp-stop {
-	left:298px;
-}
-div.jp-video-360p div.jp-type-single a.jp-stop {
-	left:325px;
-}
-div.jp-video-360p div.jp-type-playlist a.jp-stop {
-	left:378px;
-}
-a.jp-stop {
-	background: url("../img/jplayer.blue.monday.png") 0 -83px no-repeat;
-	width:28px;
-	height:28px;
-	z-index:1;
-}
-a.jp-stop:hover {
-	background: url("../img/jplayer.blue.monday.png") -29px -83px no-repeat;
-}
-div.jp-audio div.jp-type-playlist a.jp-previous {
-	left:20px;
-	top:26px;
-}
-div.jp-video div.jp-type-playlist a.jp-previous {
-	top:21px;
-}
-div.jp-video-270p div.jp-type-playlist a.jp-previous {
-	left:192px;
-}
-div.jp-video-360p div.jp-type-playlist a.jp-previous {
-	left:272px;
-}
-a.jp-previous {
-	background: url("../img/jplayer.blue.monday.png") 0 -112px no-repeat;
-	width:28px;
-	height:28px;
-}
-a.jp-previous:hover {
-	background: url("../img/jplayer.blue.monday.png") -29px -112px no-repeat;
-}
-div.jp-audio div.jp-type-playlist a.jp-next {
-	left:88px;
-	top:26px;
-}
-div.jp-video div.jp-type-playlist a.jp-next {
-	top:21px;
-}
-div.jp-video-270p div.jp-type-playlist a.jp-next {
-	left:260px;
-}
-div.jp-video-360p div.jp-type-playlist a.jp-next {
-	left:340px;
-}
-a.jp-next {
-	background: url("../img/jplayer.blue.monday.png") 0 -141px no-repeat;
-	width:28px;
-	height:28px;
-}
-a.jp-next:hover {
-	background: url("../img/jplayer.blue.monday.png") -29px -141px no-repeat;
-}
-div.jp-progress {
-	position: absolute;
-	overflow:hidden;
-	background-color: #293b51;
-}
-div.jp-audio div.jp-type-single div.jp-progress {
-	top:32px;
-	left:130px;
-	width:122px;
-	height:15px;
-}
-div.jp-audio div.jp-type-playlist div.jp-progress {
-	top:32px;
-	left:164px;
-	width:122px;
-	height:15px;
-}
-div.jp-video div.jp-progress {
-	top:0px;
-	left:0px;
-	width:100%;
-	height:10px;
-}
-div.jp-seek-bar {
-	background: url("../img/jplayer.blue.monday.png") 0 -202px repeat-x;
-	width:0px;
-	/* height:15px; */
-	height:100%;
-	cursor: pointer;
-}
-div.jp-play-bar {
-	background: url("../img/jplayer.blue.monday.png") 0 -218px repeat-x ;
-	width:0px;
-	/* height:15px; */
-	height:100%;
-}
-
-/* The seeking class is added/removed inside jPlayer */
-div.jp-seeking-bg {
-	background: url("../img/pbar-ani.gif");
-}
-
-a.jp-mute,
-a.jp-unmute {
-	width:18px;
-	height:15px;
-}
-div.jp-audio div.jp-type-single a.jp-mute,
-div.jp-audio div.jp-type-single a.jp-unmute {
-	top:32px;
-	left:274px;
-}
-div.jp-audio div.jp-type-playlist a.jp-mute,
-div.jp-audio div.jp-type-playlist a.jp-unmute {
-	top:32px;
-	left:296px;
-}
-div.jp-video a.jp-mute,
-div.jp-video a.jp-unmute {
-	top:27px;
-}
-div.jp-video-270p div.jp-type-single a.jp-mute,
-div.jp-video-270p div.jp-type-single a.jp-unmute {
-	left:304px;
-}
-div.jp-video-270p div.jp-type-playlist a.jp-unmute,
-div.jp-video-270p div.jp-type-playlist a.jp-mute {
-	left:363px;
-}
-div.jp-video-360p div.jp-type-single a.jp-mute,
-div.jp-video-360p div.jp-type-single a.jp-unmute {
-	left:384px;
-}
-div.jp-video-360p div.jp-type-playlist a.jp-mute,
-div.jp-video-360p div.jp-type-playlist a.jp-unmute {
-	left:443px;
-}
-a.jp-mute {
-	background: url("../img/jplayer.blue.monday.png") 0 -186px no-repeat;
-}
-a.jp-mute:hover {
-	background: url("../img/jplayer.blue.monday.png") -19px -170px no-repeat;
-}
-a.jp-unmute {
-	background: url("../img/jplayer.blue.monday.png") 0 -170px no-repeat;
-	display: none;
-}
-a.jp-unmute:hover {
-	background: url("../img/jplayer.blue.monday.png") -19px -186px no-repeat;
-}
-div.jp-volume-bar {
-	position: absolute;
-	overflow:hidden;
-	background: url("../img/jplayer.blue.monday.png") 0 -250px repeat-x;
-	width:46px;
-	height:5px;
-	cursor: pointer;
-}
-div.jp-audio div.jp-type-single div.jp-volume-bar {
-	top:37px;
-	left:302px;
-}
-div.jp-audio div.jp-type-playlist div.jp-volume-bar {
-	top:37px;
-	left:324px;
-}
-div.jp-video div.jp-volume-bar {
-	top:32px;
-}
-div.jp-video-270p div.jp-type-single div.jp-volume-bar {
-	left:332px;
-}
-div.jp-video-270p div.jp-type-playlist div.jp-volume-bar {
-	left:391px;
-}
-div.jp-video-360p div.jp-type-single div.jp-volume-bar {
-	left:412px;
-}
-div.jp-video-360p div.jp-type-playlist div.jp-volume-bar {
-	left:471px;
-}
-div.jp-volume-bar-value {
-	background: url("../img/jplayer.blue.monday.png") 0 -256px repeat-x;
-	width:0px;
-	height:5px;
-}
-div.jp-current-time,
-div.jp-duration {
-	position: absolute;
-	font-size:.64em;
-	font-style:oblique;
-}
-div.jp-duration {
-	text-align: right;
-}
-div.jp-audio div.jp-type-single div.jp-current-time,
-div.jp-audio div.jp-type-single div.jp-duration {
-	top:49px;
-	left:130px;
-	width:122px;
-}
-div.jp-audio div.jp-type-playlist div.jp-current-time,
-div.jp-audio div.jp-type-playlist div.jp-duration {
-	top:49px;
-	left:164px;
-	width:122px;
-}
-div.jp-video div.jp-current-time,
-div.jp-video div.jp-duration {
-	top:10px;
-	left:0px;
-	width:98%;
-	padding:0 1%;
-}
-div.jp-playlist {
-	/* width:418px; */
-/* 	width:400px; */
-	margin-top:6.3em;
-	right:0px;
-}
-div.jp-playlist ul {
-	list-style-type:none;
-	margin:0;
-	padding:0 20px;
-	/* background-color:#ccc; */
-	/* border:1px solid #009be3; */
-	/* border-top:none; */
-	/* width:378px; */
-	font-size:.72em;
-}
-
-
-div.jp-type-single div.jp-playlist li {
-	padding:5px 0 5px 20px;
-	font-weight:bold;
-}
-div.jp-type-playlist div.jp-playlist li {
-	padding:5px 0 4px 20px;
-	border-bottom:1px solid #eee;
-}
-/*
- d *iv.jp-video div.jp-playlist li {
-	 padding:5px 0 5px 20px;
-	 font-weight:bold;
- }
- */
-div.jp-type-playlist div.jp-playlist li.jp-playlist-last {
-	padding:5px 0 5px 20px;
-	border-bottom:none;
-}
-div.jp-type-playlist div.jp-playlist li.jp-playlist-current {
-	list-style-type:square;
-	list-style-position:inside;
-	padding-left:8px;
-}
-div.jp-type-playlist div.jp-playlist a {
-	color: #666;
-	text-decoration: none;
-}
-div.jp-type-playlist div.jp-playlist a:hover {
-	color:#0d88c1;
-}
-div.jp-type-playlist div.jp-playlist a.jp-playlist-current {
-	color:#0d88c1;
-}
-div.jp-type-playlist div.jp-playlist div.jp-free-media {
-	display:inline;
-	margin-left:20px;
-}
-
-div.jp-video div.jp-video-play {
-	background: transparent url("../img/jplayer.blue.monday.video.play.png") no-repeat center;
-	/* position: relative; */
-	position: absolute;
-	cursor:pointer;
-	z-index:2;
-}
-div.jp-video div.jp-video-play:hover {
-	background: transparent url("../img/jplayer.blue.monday.video.play.hover.png") no-repeat center;
-}
-div.jp-video-270p div.jp-video-play {
-	top:-270px;
-	width:480px;
-	height:270px;
-}
-div.jp-video-360p div.jp-video-play {
-	top:-360px;
-	width:640px;
-	height:360px;
-}
-
-div.jp-jplayer {
-	width:0px;
-	height:0px;
-}
-div.jp-video div.jp-jplayer {
-	border:1px solid #009be3;
-	border-bottom:none;
-	z-index:1;
-}
-div.jp-video-270p div.jp-jplayer {
-	width:480px;
-	height:270px;
-}
-div.jp-video-360p div.jp-jplayer {
-	width:640px;
-	height:360px;
-}
-div.jp-jplayer {
-	background-color: #000000;
-}
-
-div.jp-playlist ul li button{
-	display:none;
-}
-
-div.jp-playlist ul li:hover button{
-	display:inline;
-}
\ No newline at end of file
diff --git a/apps/media/css/music.css b/apps/media/css/music.css
new file mode 100644
index 0000000000..92a4ea5e14
--- /dev/null
+++ b/apps/media/css/music.css
@@ -0,0 +1,9 @@
+#folderlist li{list-style-type:none;margin-bottom:10px;}
+#folderlist button.prettybutton{font-size:1em;width:10ex;}
+li button.right.prettybutton{font-size:1em;}
+#collection{padding-top:1em;position:relative;width:70ex;float:left;}
+#collection li.album,#collection li.song{margin-left:3ex;}
+#playlist{margin-left:72ex;}
+#playlist li.current{background-color:#ccc;}
+#collection li button{float:right;}
+#collection li,#playlist li{list-style-type:none;}
diff --git a/apps/media/css/player.css b/apps/media/css/player.css
new file mode 100644
index 0000000000..bf404f515f
--- /dev/null
+++ b/apps/media/css/player.css
@@ -0,0 +1,29 @@
+#jp-interface{position:fixed;z-index:100;width:25em;left:201px;top:-10px;height:80px;border-bottom:none;}
+#jp-interface.player{display:hidden;}
+#jp-interface ul.jp-controls{list-style-type:none;padding:0;}
+#jp-interface ul.jp-controls li{display:inline;}
+#jp-interface ul.jp-controls a{position:absolute;overflow:hidden;text-indent:-9999px;}
+a.jp-play,a.jp-pause{width:40px;height:40px;z-index:1;top:20px;left:48px;}
+a.jp-play{background:url("../img/jplayer.blue.monday.png") 0 0 no-repeat;}
+a.jp-play:hover{background:url("../img/jplayer.blue.monday.png") -41px 0 no-repeat;}
+a.jp-pause{background:url("../img/jplayer.blue.monday.png") 0 -42px no-repeat;display:none;}
+a.jp-pause:hover{background:url("../img/jplayer.blue.monday.png") -41px -42px no-repeat;}
+a.jp-stop{top:26px;left:126px;background:url("../img/jplayer.blue.monday.png") 0 -83px no-repeat;width:28px;height:28px;z-index:1;}
+a.jp-stop:hover{background:url("../img/jplayer.blue.monday.png") -29px -83px no-repeat;}
+a.jp-previous{left:20px;top:26px;background:url("../img/jplayer.blue.monday.png") 0 -112px no-repeat;width:28px;height:28px;}
+a.jp-previous:hover{background:url("../img/jplayer.blue.monday.png") -29px -112px no-repeat;}
+a.jp-next{left:88px;top:26px;background:url("../img/jplayer.blue.monday.png") 0 -141px no-repeat;width:28px;height:28px;}
+a.jp-next:hover{background:url("../img/jplayer.blue.monday.png") -29px -141px no-repeat;}
+div.jp-progress{position:absolute;overflow:hidden;background-color:#293b51;top:32px;left:164px;width:122px;height:15px;}
+div.jp-seek-bar{background:url("../img/jplayer.blue.monday.png") 0 -202px repeat-x;width:0;height:100%;cursor:pointer;}
+div.jp-play-bar{background:url("../img/jplayer.blue.monday.png") 0 -218px repeat-x;width:0;height:100%;}
+div.jp-seeking-bg{background:url("../img/pbar-ani.gif");}
+a.jp-mute,a.jp-unmute{height:15px;width:18px;top:32px;left:296px;}
+a.jp-mute{background:url("../img/jplayer.blue.monday.png") 0 -186px no-repeat;}
+a.jp-mute:hover{background:url("../img/jplayer.blue.monday.png") -19px -170px no-repeat;}
+a.jp-unmute{background:url("../img/jplayer.blue.monday.png") 0 -170px no-repeat;display:none;}
+a.jp-unmute:hover{background:url("../img/jplayer.blue.monday.png") -19px -186px no-repeat;}
+div.jp-volume-bar{position:absolute;overflow:hidden;background:url("../img/jplayer.blue.monday.png") 0 -250px repeat-x;width:46px;height:5px;cursor:pointer;top:37px;left:324px;}
+div.jp-volume-bar-value{background:url("../img/jplayer.blue.monday.png") 0 -256px repeat-x;width:0;height:5px;}
+div.jp-current-time,div.jp-duration{position:absolute;font-size:.64em;font-style:oblique;top:49px;left:164px;width:122px;}
+div.jp-duration{text-align:right;}
diff --git a/apps/media/css/style.css b/apps/media/css/style.css
deleted file mode 100644
index 9fb61c55c5..0000000000
--- a/apps/media/css/style.css
+++ /dev/null
@@ -1,36 +0,0 @@
-.right{
-	float:right;
-}
-
-#folderlist li{
-	list-style-type:none;
-	margin-bottom:10px;
-}
-
-#folderlist button.prettybutton{
-	font-size:1em;
-	width:10ex;
-}
-
-li button.right.prettybutton{
-	font-size:1em;
-}
-
-#collection{
-	padding-top:1em;
-	position:relative;
-	width:70ex;
-	float:left;
-}
-
-#collection li{
-	list-style-type:none;
-}
-
-#collection li button{
-	float:right;
-}
-
-#collection li.album, #collection li.song{
-	margin-left:3ex;
-}
\ No newline at end of file
diff --git a/apps/media/index.php b/apps/media/index.php
index 956a709ca6..26e008acab 100644
--- a/apps/media/index.php
+++ b/apps/media/index.php
@@ -34,9 +34,18 @@ require_once('lib_collection.php');
 require_once('lib_scanner.php');
 require_once('template.php');
 
+OC_UTIL::addScript('media','player');
+OC_UTIL::addScript('media','music');
+OC_UTIL::addScript('media','jquery.jplayer.min');
+OC_UTIL::addStyle('media','player');
+OC_UTIL::addStyle('media','music');
+
 OC_APP::setActiveNavigationEntry( 'media_index' );
 
 $tmpl = new OC_TEMPLATE( 'media', 'music', 'user' );
+
+$player = new OC_TEMPLATE( 'media', 'player');
+$tmpl->assign('player',$player->fetchPage());
 $tmpl->printPage();
 ?>
  
diff --git a/apps/media/js/files.js b/apps/media/js/files.js
new file mode 100644
index 0000000000..d699a96db7
--- /dev/null
+++ b/apps/media/js/files.js
@@ -0,0 +1,50 @@
+function musicTypeFromFile(file){
+	var extention=file.substr(file.indexOf('.')+1);
+	if(extention=='ogg'){
+		return 'oga'
+	}
+	//TODO check for more specific cases
+	return extention;
+}
+
+function playAudio(filename){
+	loadPlayer(musicTypeFromFile(filename),function(){
+		PlayList.add($('#dir').val()+'/'+filename);
+		PlayList.play(PlayList.items.length-1);
+	});
+}
+
+function addAudio(filename){
+	loadPlayer(musicTypeFromFile(filename),function(){
+		PlayList.add($('#dir').val()+'/'+filename);
+	});
+}
+
+function loadPlayer(type,ready){
+	if(!loadPlayer.done){
+		OC.addScript('media','jquery.jplayer.min',function(){
+			OC.addScript('media','player',function(){
+				$('body').append($('<div id="playerPlaceholder"/>'))
+				$('#playerPlaceholder').append($('<div/>')).load(OC.filePath('media','templates','player.php'),function(){
+					loadPlayer.done=true;
+					PlayList.init(type,ready);
+				});
+			});
+		});
+		OC.addStyle('media','player');
+	}else{
+		ready();
+	}
+}
+
+$(document).ready(function() {
+	loadPlayer.done=false
+
+	FileActions.register('audio','Add to playlist',addAudio);
+	FileActions.register('application/ogg','Add to playlist',addAudio);
+
+	FileActions.register('audio','Play',playAudio);
+	FileActions.register('application/ogg','Play',playAudio);
+	FileActions.setDefault('audio','Play');
+	FileActions.setDefault('application/ogg','Play');
+});
\ No newline at end of file
diff --git a/apps/media/js/music.js b/apps/media/js/music.js
index 19b23b8779..ba34e66c3b 100644
--- a/apps/media/js/music.js
+++ b/apps/media/js/music.js
@@ -1,330 +1,13 @@
-var audioPlaylist;
-var URLBASE='ajax/api.php?action=play&path=';
-
-$(document).ready(function() {
-	if(typeof FileActions!=='undefined'){
-		URLBASE='../apps/media/ajax/api.php?action=play&path=';
-		var playerLoaded=false;
-		function playFile(filename){
-			audioPlaylist.playlist=[];
-			audioPlaylist.addToPlaylist({
-				song_name:filename,
-				song_path:$('#dir').val()+'/'+filename
-			},true);
-			audioPlaylist.playlistChange(audioPlaylist.playlist.length-1);
-		}
-		function playAudio(filename){
-			if(!playerLoaded){
-				var parent=$('body').append('<div id="media_container"/>');
-				$('#media_container').load('../apps/media/templates/music.php',function(){
-					playerLoaded=true;
-					//remove playlist and collection view
-					$('#jp_playlist_1').remove();
-					$('collection').remove();
-					//init the audio player
-					audioPlaylist =initPlayList(false,false,function(){
-						//play the file
-						playFile(filename);
-					});
-				});
-			}else{
-				playFile(filename);
-			}
-		}
-		FileActions.register('audio','Play',playAudio);
-		FileActions.register('application/ogg','Play',playAudio);
-		FileActions.setDefault('audio','Play');
-		FileActions.setDefault('application/ogg','Play');
-	}
-	Playlist = function(instance, playlist, options) {
-		var self = this;
-		
-		this.instance = instance; // String: To associate specific HTML with this playlist
-		this.playlist = playlist; // Array of Objects: The playlist
-		this.options = options; // Object: The jPlayer constructor options for this playlist
-		
-		this.current = -1;
-		
-		this.cssId = {
-			jPlayer: "jplayer_",
-			interface: "jp_interface_",
-			playlist: "jp_playlist_"
-		};
-		this.cssSelector = {};
-		
-		$.each(this.cssId, function(entity, id) {
-			self.cssSelector[entity] = "#" + id + self.instance;
-		});
-		
-		if(!this.options.cssSelectorAncestor) {
-			this.options.cssSelectorAncestor = this.cssSelector.interface;
-		}
-		
-		$(this.cssSelector.jPlayer).jPlayer(this.options);
-		
-		$(this.cssSelector.interface + " .jp-previous").click(function() {
-			self.playlistPrev();
-			$(this).blur();
-			return false;
-		});
-		
-		$(this.cssSelector.interface + " .jp-next").click(function() {
-			self.playlistNext();
-			$(this).blur();
-			return false;
-		});
-	};
-	
-	Playlist.prototype = {
-		displayPlaylist: function() {
-			var self = this;
-			$(this.cssSelector.playlist + " ul").empty();
-			for (i=0; i < this.playlist.length; i++) {
-				var listItem = (i === this.playlist.length-1) ? "<li class='jp-playlist-last'>" : "<li>";
-				listItem += "<a href='#' id='" + this.cssId.playlist + this.instance + "_item_" + i +"' tabindex='1'>"+ this.playlist[i].name +"</a>";
-				
-				// Create links to free media
-				if(this.playlist[i].free) {
-					var first = true;
-					listItem += "<div class='jp-free-media'>(";
-					$.each(this.playlist[i], function(property,value) {
-						if($.jPlayer.prototype.format[property]) { // Check property is a media format.
-							if(first) {
-								first = false;
-							} else {
-								listItem += " | ";
-							}
-							listItem += "<a id='" + self.cssId.playlist + self.instance + "_item_" + i + "_" + property + "' href='" + value + "' tabindex='1'>" + property + "</a>";
-						}
-					});
-					listItem += ")</span>";
-				}
-				listItem += "<button class='right prettybutton remove'>Remove</button>";
-				
-				listItem += "</li>";
-				
-				// Associate playlist items with their media
-				$(this.cssSelector.playlist + " ul").append(listItem);
-				$(this.cssSelector.playlist + "_item_" + i).data("index", i).click(function() {
-					var index = $(this).data("index");
-					if(self.current !== index) {
-						self.playlistChange(index);
-					} else {
-						$(self.cssSelector.jPlayer).jPlayer("play");
-					}
-					$(this).blur();
-					return false;
-				});
-				$(this.cssSelector.playlist + "_item_" + i).parent().children('button').data("index", i).click(function() {
-					var index = $(this).data("index");
-					self.removeFromPlaylist(index);
-				});
-				
-				// Disable free media links to force access via right click
-				if(this.playlist[i].free) {
-					$.each(this.playlist[i], function(property,value) {
-						if($.jPlayer.prototype.format[property]) { // Check property is a media format.
-							$(self.cssSelector.playlist + "_item_" + i + "_" + property).data("index", i).click(function() {
-								var index = $(this).data("index");
-								$(self.cssSelector.playlist + "_item_" + index).click();
-								$(this).blur();
-								return false;
-							});
-						}
-					});
-				}
-			}
-		},
-		playlistInit: function(autoplay) {
-			if(autoplay) {
-				this.playlistChange(this.current);
-			} else {
-				this.playlistConfig(this.current);
-			}
-		},
-		playlistConfig: function(index,play) {
-			$(this.cssSelector.playlist + "_item_" + this.current).removeClass("jp-playlist-current").parent().removeClass("jp-playlist-current");
-			$(this.cssSelector.playlist + "_item_" + index).addClass("jp-playlist-current").parent().addClass("jp-playlist-current");
-			this.current = index;
-			var that=this;
-			if(this.playlist[this.current]){
-				if($(this.cssSelector.jPlayer).data('jPlayer').options.supplied!=this.playlist[this.current].type){//the the audio type changes we need to reinitialize jplayer
-					$(this.cssSelector.jPlayer).jPlayer("destroy");
-					$(this.cssSelector.jPlayer).jPlayer({
-						ended:this.options.ended,
-						play:this.options.play,
-						supplied:this.playlist[this.current].type,
-						ready:function(){
-							that.playlistConfig(index);
-							if(play){
-								$(that.cssSelector.jPlayer).jPlayer("play");
-							}
-						}
-					});
-				}else{
-					$(this.cssSelector.jPlayer).jPlayer("setMedia", this.playlist[this.current]);
-				}
-			}
-		},
-		playlistChange: function(index) {
-			this.playlistConfig(index,true);
-			$(this.cssSelector.jPlayer).jPlayer("play");
-		},
-		playlistNext: function() {
-			var index = (this.current + 1 < this.playlist.length) ? this.current + 1 : 0;
-			this.playlistChange(index);
-		},
-		playlistPrev: function() {
-			var index = (this.current - 1 >= 0) ? this.current - 1 : this.playlist.length - 1;
-			this.playlistChange(index);
-		},
-		removeFromPlaylist: function(index){
-			this.playlist.splice(index,1);
-			this.displayPlaylist();
-			if(index==this.current){
-				this.playlistConfig((index<this.playlist.length)?index:0);
-			}else{
-				$(this.cssSelector.playlist + "_item_" + this.current).addClass("jp-playlist-current").parent().addClass("jp-playlist-current");
-			}
-		},
-		addToPlaylist : function(stuff,dontRedraw){
-			var self=this;
-			if(!stuff){
-				return;
-			}
-			if(stuff.artist_name){
-				$.each(stuff.albums,function(index,album){
-					self.addToPlaylist(album,true);
-				});
-			}
-			if(stuff.album_name){
-				$.each(stuff.songs,function(index,song){
-					self.addToPlaylist(song,true);
-				});
-			}
-			if(stuff.song_name){
-				var extention=stuff.song_path.split('.').pop();
-				var type=musicTypeFromExtention(extention);
-				var item={name:stuff.song_name,type:type};
-				item[type]=URLBASE+stuff.song_path;
-				this.playlist.push(item);
-			}
-			if(!dontRedraw){
-				this.displayPlaylist();
-			}
+$(document).ready(function(){
+	//load the collection
+	$.ajax({
+		url: OC.linkTo('media','ajax/api.php')+'?action=get_collection',
+		dataType: 'json',
+		success: function(collection){
+			displayCollection(collection);
 		}
-	};
-
-	if($('#jp-audio')){//only do this when we're actually in the media player
-		//load the collection
-		$.ajax({
-			url: 'ajax/api.php?action=get_collection',
-			dataType: 'json',
-			success: function(collection){
-				var playlist=[];
-				var types=[];
-				for(var i=0;i<collection.length;i++){
-					var artist=collection[i];
-					for(var j=0;j<artist.albums.length;j++){
-						var album=artist.albums[j];
-						for(var n=0;n<album.songs.length;n++){
-							var song=album.songs[n];
-							var extention=song.song_path.split('.').pop();
-							var type=musicTypeFromExtention(extention);
-							if(types.indexOf(type)==-1){
-								types.push(type);
-							}
-						}
-					}
-				}
-				displayCollection(collection);
-				audioPlaylist =initPlayList(true,true);
-			}
-		});
-	}
-});
-
-function initPlayList(display,enableAutoPlay,ready){
-	return new Playlist('1', [],{
-		ready: function() {
-			if(display){
-				audioPlaylist.displayPlaylist();
-			}
-			if(enableAutoPlay){
-				if(window.location.href.indexOf('#')>-1){//autoplay passed arist/album/song
-					var vars=getUrlVars();
-					var play;
-					if(vars['artist']){
-						$.each(collection,function(index,artist){
-							if(artist.artist_name==vars['artist']){
-								play=artist;
-								if(vars['album']){
-									$.each(artist.albums,function(index,album){
-										if(album.album_name==vars['album']){
-											play=album;
-											if(vars['song']){
-												$.each(album.songs,function(index,song){
-													if(song.song_name==vars['song']){
-														play=song;
-													}
-												});
-											}
-										}
-									});
-								}
-							}
-						});
-					}
-					audioPlaylist.addToPlaylist(play);
-					audioPlaylist.playlistInit(true);
-				}else{
-					audioPlaylist.playlistInit(false); // Parameter is a boolean for autoplay.
-				}
-			}else{
-				audioPlaylist.playlistInit(false);
-			}
-			if(ready){
-				ready();
-			}
-		},
-		ended: function() {
-			audioPlaylist.playlistNext();
-		},
-		play: function() {
-			$(this).jPlayer("pauseOthers");
-		},
 	});
-}
-
-function musicTypeFromExtention(extention){
-	if(extention=='ogg'){
-		return 'oga'
-	}
-	//TODO check for more specific cases
-	return extention;
-}
-
-// indexOf implemententation for browsers that don't support it
-if (!Array.prototype.indexOf){
-	Array.prototype.indexOf = function(elt /*, from*/)	{
-		var len = this.length;
-		
-		var from = Number(arguments[1]) || 0;
-		from = (from < 0)
-		? Math.ceil(from)
-		: Math.floor(from);
-		if (from < 0)
-			from += len;
-		
-		for (; from < len; from++)
-		{
-			if (from in this &&
-				this[from] === elt)
-				return from;
-		}
-		return -1;
-	};
-}
+});
 
 function displayCollection(collection){
 	$('#collection').data('collection',collection);
@@ -340,6 +23,8 @@ function displayCollection(collection){
 			artistNode.children('ul').append(albumNode);
 			$.each(album.songs,function(index,song){
 				var songNode=$('<li class="song">'+song.song_name+'<button class="add">Add</button></li>');
+				song.artist_name=artist.artist_name;
+				song.album_name=album.album_name;
 				songNode.data('name',song.song_name);
 				songNode.data('stuff',song);
 				albumNode.children('ul').append(songNode);
@@ -360,9 +45,40 @@ function displayCollection(collection){
 		return false;
 	});
 	$('li>button.add').click(function(){
-		audioPlaylist.addToPlaylist($(this).parent().data('stuff'));
+		PlayList.add($(this).parent().data('stuff'));
+		PlayList.render($('#playlist'));
 		return false;
-	})
+	});
+	if(window.location.href.indexOf('#')>-1){//autoplay passed arist/album/song
+		var vars=getUrlVars();
+		var play;
+		if(vars['artist']){
+			$.each(collection,function(index,artist){
+				if(artist.artist_name==vars['artist']){
+					play=artist;
+					if(vars['album']){
+						$.each(artist.albums,function(index,album){
+							if(album.album_name==vars['album']){
+								play=album;
+								if(vars['song']){
+									$.each(album.songs,function(index,song){
+										if(song.song_name==vars['song']){
+											play=song;
+										}
+									});
+								}
+							}
+						});
+					}
+				}
+			});
+		}
+		PlayList.add(play);
+		PlayList.play();
+	}else{
+		PlayList.init();
+	}
+	
 }
 
 function getUrlVars(){
@@ -375,4 +91,13 @@ function getUrlVars(){
 		vars[hash[0]] = decodeURIComponent(hash[1]).replace(/\+/g,' ');
 	}
 	return vars;
+}
+
+function musicTypeFromFile(file){
+	var extention=file.substr(file.indexOf('.')+1);
+	if(extention=='ogg'){
+		return 'oga'
+	}
+	//TODO check for more specific cases
+	return extention;
 }
\ No newline at end of file
diff --git a/apps/media/js/player.js b/apps/media/js/player.js
new file mode 100644
index 0000000000..f638b86e19
--- /dev/null
+++ b/apps/media/js/player.js
@@ -0,0 +1,120 @@
+var PlayList={
+	urlBase:OC.linkTo('media','ajax/api.php')+'?action=play&path=',
+	current:-1,
+	items:[],
+	player:null,
+	parent:null,
+	next:function(){
+		var next=PlayList.current+1;
+		if(next>=PlayList.items.length){
+			next=0;
+		}
+		PlayList.play(next);
+	},
+	previous:function(){
+		var next=PlayList.current-1;
+		if(next<0){
+			next=PlayList.items.length-1;
+		}
+		PlayList.play(next);
+	},
+	play:function(index){
+		if(index==null){
+			index=PlayList.current;
+		}
+		if(index>-1 && index<PlayList.items.length){
+			PlayList.current=index;
+			if(PlayList.player){
+				if(PlayList.player.data('jPlayer').options.supplied!=PlayList.items[index].type){//the the audio type changes we need to reinitialize jplayer
+					PlayList.player.jPlayer("destroy");
+					PlayList.init(PlayList.items[index].type,PlayList.play);
+				}else{
+					PlayList.player.jPlayer("setMedia", PlayList.items[PlayList.current]);
+					PlayList.player.jPlayer("play");
+				}
+			}else{
+				PlayList.init(PlayList.items[index].type,PlayList.play);
+			}
+		}
+	},
+	init:function(type,ready){
+		if(!PlayList.player){
+			$(".jp-previous").click(function() {
+				PlayList.previous();
+				$(this).blur();
+				PlayList.render();
+				return false;
+			});
+			$(".jp-next").click(function() {
+				PlayList.next();
+				$(this).blur();
+				PlayList.render();
+				return false;
+			});
+			PlayList.player=$('#jp-interface div.player');
+		}
+		$(PlayList.player).jPlayer({
+			ended:PlayList.next,
+			supplied:type,
+			ready:function(){
+				if(ready){
+					ready();
+				}
+			},
+			cssSelectorAncestor:'#jp-interface',
+		});
+	},
+	add:function(song){
+		if(song.substr){//we are passed a string, asume it's a url to a song
+			PlayList.addFile(song);
+		}
+		if(song.albums){//a artist object was passed, add all albums inside it
+			$.each(song.albums,function(index,album){
+				PlayList.add(album);
+			});
+		}
+		if(song.songs){//a album object was passed, add all songs inside it
+			$.each(song.songs,function(index,song){
+				PlayList.add(song);
+			});
+		}
+		if(song.song_name){
+			var type=musicTypeFromFile(song.song_path);
+			var item={name:song.song_name,type:type,artist:song.artist_name,album:song.album_name};
+			item[type]=PlayList.urlBase+encodeURIComponent(song.song_path);
+			PlayList.items.push(item);
+		}
+	},
+	addFile:function(path){
+		var type=musicTypeFromFile(path);
+		var item={name:'unknown',artist:'unknown',album:'unknwon',type:type};//todo get song data
+		item[type]=PlayList.urlBase+encodeURIComponent(path);
+		PlayList.items.push(item);
+	},
+	render:function(parent){//parent should be an ul element
+		if(parent){
+			PlayList.parent=parent;
+		}else{
+			parent=PlayList.parent;
+		}
+		if(parent){
+			parent.empty();
+			for(var i=0;i<PlayList.items.length;i++){
+				var song=PlayList.items[i];
+				var item=$('<li>'+song.artist+' - '+song.album+' - '+song.name+'</li>');
+				item.data('artist',song.artist);
+				item.data('album',song.album);
+				item.data('name',song.name);
+				item.data('index',i);
+				item.click(function(){
+					PlayList.play($(this).data('index'));
+					PlayList.render();
+				});
+				if(i==PlayList.current){
+					item.addClass('current');
+				}
+				parent.append(item);
+			}
+		}
+	}
+}
diff --git a/apps/media/templates/music.php b/apps/media/templates/music.php
index 06cc1f5615..47ad64fa7c 100644
--- a/apps/media/templates/music.php
+++ b/apps/media/templates/music.php
@@ -1,34 +1,3 @@
-<div id='jplayer_1'></div>
+<?php echo $_['player'];?>
 <div id='collection'><ul/></div>
-<div class="jp-audio">
-	<div class="jp-type-playlist">
-		<div id="jp_interface_1" class="jp-interface">
-			<ul class="jp-controls">
-				<li><a href="#" class="jp-play" tabindex="1">play</a></li>
-				<li><a href="#" class="jp-pause" tabindex="1">pause</a></li>
-				<li><a href="#" class="jp-stop" tabindex="1">stop</a></li>
-				<li><a href="#" class="jp-mute" tabindex="1">mute</a></li>
-				<li><a href="#" class="jp-unmute" tabindex="1">unmute</a></li>
-				<li><a href="#" class="jp-previous" tabindex="1">previous</a></li>
-				<li><a href="#" class="jp-next" tabindex="1">next</a></li>
-			</ul>
-			<div class="jp-progress">
-				<div class="jp-seek-bar">
-					<div class="jp-play-bar"></div>
-				</div>
-			</div>
-			<div class="jp-volume-bar">
-				<div class="jp-volume-bar-value"></div>
-			</div>
-			<div class="jp-current-time"></div>
-			<div class="jp-current-time"></div>
-			<div class="jp-duration"></div>
-		</div>
-		<div id="jp_playlist_1" class="jp-playlist">
-			<ul>
-				<!-- The method Playlist.displayPlaylist() uses this unordered list -->
-				<li></li>
-			</ul>
-		</div>
-	</div>
-</div>
\ No newline at end of file
+<ul id="playlist"/>
\ No newline at end of file
diff --git a/apps/media/templates/player.php b/apps/media/templates/player.php
new file mode 100644
index 0000000000..abba806510
--- /dev/null
+++ b/apps/media/templates/player.php
@@ -0,0 +1,23 @@
+<div id="jp-interface">
+	<ul class="jp-controls">
+		<li><a href="#" class="jp-play" tabindex="1">play</a></li>
+		<li><a href="#" class="jp-pause" tabindex="1">pause</a></li>
+		<li><a href="#" class="jp-stop" tabindex="1">stop</a></li>
+		<li><a href="#" class="jp-mute" tabindex="1">mute</a></li>
+		<li><a href="#" class="jp-unmute" tabindex="1">unmute</a></li>
+		<li><a href="#" class="jp-previous" tabindex="1">previous</a></li>
+		<li><a href="#" class="jp-next" tabindex="1">next</a></li>
+	</ul>
+	<div class="jp-progress">
+		<div class="jp-seek-bar">
+			<div class="jp-play-bar"></div>
+		</div>
+	</div>
+	<div class="jp-volume-bar">
+		<div class="jp-volume-bar-value"></div>
+	</div>
+	<div class="jp-current-time"></div>
+	<div class="jp-current-time"></div>
+	<div class="jp-duration"></div>
+	<div class='player'></div>
+</div>
\ No newline at end of file
-- 
GitLab