Use web player as default, but keep links

General discussions.

Moderator: moderators

Use web player as default, but keep links

Postby aphuey » Sat Nov 22, 2008 4:35 am

Does anyone know how hard it would be to modify the code so that even when the web player is set up to be used by default, you still have access to all the links to manage playlists, etc.?

When I select to use the web player by default, I wish most of the playlist functionality didn't go away. Also, there's no way to detach the player when you have selected to use it by default, correct?

Would it be hard to customize so that the playlist functionality is still available?
aphuey
 
Posts: 102
Joined: Mon Nov 17, 2008 6:25 pm

Postby zeekay » Sat Nov 22, 2008 7:39 am

The best part about subsonic is that it's easy to modify/hack to fit your purposes, sindre has done a great job of separating the logic from the layout, so you can easily modify it by editing various .jsp files in /WEB-INF/jsp/. I sorta hacked this in, but broke support for regular streaming (with .m3u/.pls). Basically you'll want to edit the playlist.jsp and force it into a "webplayer only mode". I posted elsewhere about switching in jwplayer, which is what this uses. You'll need to edit the xspfPlaylist.jsp if you want to take advantage of that. Hopefully this will give you some idea about how to do what you want. Just mess around with the code, you'll figure it out.

The way I have things setup the playlist editor is visible at the bottom, however the bottom frame is set to a slim view by default. To reveal it you have to click the resize icon, which reveals a scrollable playlist editor. Setup like this, you'll actually leave use webplayer by default off in settings (if you want to set it to always use a popup you can turn it on, but it'll disable the playlist). You can still detach normally, use playlists, load/save etc.

This script communicates with JW Player, is unneccesary, you can safely ignore that. I am still trying to figure out how to take advantage of the javascript API in JW Player. In terms of layout I've changed subsonic a bit, so keep that in mind, and take what you need. Using JW Player 3.16.

playlist.jsp

Code: Select all
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="iso-8859-1" %>

<html>
<head>
    <%@ include file="head.jsp" %>
    <title>subs0nic</title>

    <script type="text/javascript" src="<c:url value="/dwr/util.js"/>"></script>


    <c:choose>
        <c:when test="${model.detached}">
      
       <c:set var="width" value="400"/>
       <c:set var="height" value="150"/>

        </c:when>
        <c:otherwise>
   
       <c:set var="width" value="300"/>
       <c:set var="height" value="20"/>

        </c:otherwise>
    </c:choose>

    <script type="text/javascript" src="<c:url value="/script/scripts.js"/>"></script>

    <c:choose>
        <c:when test="${model.detached}">

        </c:when>
        <c:otherwise>

    <script type="text/javascript" language="javascript">

        function detach() {
            popupSize("webPlayer.view?detached=",'player','toolbar=no,statusbar=no,location=no,scrollbars=no,width=400,height=150');
            location.href = "empty.html";
        }

    </script>

        </c:otherwise>
    </c:choose>

</head>

<c:url var="playlistUrl" value="/xspfPlaylist.view">
    <%-- Hack to force Flash player to reload playlist. --%>
    <c:param name="dummy" value="${model.dummy}"/>
</c:url>


   <c:choose>
        <c:when test="${model.detached}">

      <body width="400" height="150" onload="window.focus();window.moveTo(300, 200);"style="background: black; margin: 0 auto; padding: 0">
      
      <div style="position: fixed; top: 0; left: 0; width: 395px; height: 140px; margin: 0 auto; padding: 0;">

      <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
              codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0"
              width="${width}" height="${height}">
          <param name="allowScriptAccess" value="sameDomain"/>
          <param name="movie" value="player.swf"/>
          <param name="quality" value="high"/>
          <param name="bgcolor" value="#000000"/>
          <embed id="xspf_player" src="player.swf" quality="high" bgcolor="#000000" name="xspf_player" allowscriptaccess="sameDomain"
                 type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"
                 height="${height}" width="${width}" flashvars="file=${playlistUrl}&autostart=true&frontcolor=0x999999&lightcolor=0xfafafa&backcolor=0x000000&searchbar=false&enablejs=true&javascriptid=xspf_player&height=150&width=400&autoscroll=false&displaywidth=130&overstretch=true&thumbsinplaylist=false&showicons=false&fullscreen=false"></embed>
      </object>
      </div>

        </c:when>
        <c:otherwise>

<!-- This script communicates with JW Player -->

<script type="text/javascript">
// some variables to save
var currentPosition;
var currentRemaining;
var currentVolume;
var currentItem;
var currentState;
var currentLoad;
var currentXsize;
var currentYsize;

// this function is caught by the JavascriptView object of the player.
function sendEvent(typ,prm) { thisMovie("xspf_player").sendEvent(typ,prm); };


// these functions is called by the JavascriptView object of the player.
function getUpdate(typ,pr1,pr2,swf) {
   if(typ == "time") { currentPosition = pr1; pr2 == undefined ? null: currentRemaining = Math.round(pr2); }
   else if(typ == "volume") { currentVolume = pr1; }
   else if(typ == "item") { currentItem = pr1; setTimeout("getItemData(currentItem)",100);}
   else if(typ == "state") { currentState = pr1; }
   else if(typ == "load") { currentLoad = pr1; }
   else if(typ == "size") { currentXsize = "X=" + pr1; pr2 == undefined ? null: currentYsize = "Y=" + Math.round(pr2); }

   var tmp = document.getElementById("pid"); if ((tmp)&&(swf != "null")) { tmp.innerHTML = "(received from the player with the id: <i><b>"+swf+"</b></i>)"; }
      
   var tmp = document.getElementById("time"); if (tmp) { tmp.innerHTML = "<b>Time:</b> " + currentPosition + "&nbsp;&nbsp;<b>Remaining:</b> " + currentRemaining; }
   var tmp = document.getElementById("volume"); if (tmp) { tmp.innerHTML = "<b>Volume:</b> " + currentVolume; }
   var tmp = document.getElementById("item"); if (tmp) { tmp.innerHTML = "<b>Item:</b> " + currentItem; }
   var tmp = document.getElementById("state"); if (tmp) { tmp.innerHTML = "<b>State:</b> " + currentState + "&nbsp;&nbsp; (0:ready/paused, 1:loading, 2:playing, 3:finished)"; }
   var tmp = document.getElementById("load"); if (tmp) { tmp.innerHTML = "<b>Load:</b> " + currentLoad; }
   var tmp = document.getElementById("size"); if (tmp) { tmp.innerHTML = "<b>Size:</b> " + currentXsize + ", " + currentYsize; }
};

function getItemData(idx) {
   var obj = thisMovie("xspf_player").itemData(idx);

   var tmp = document.getElementById("file"); if (tmp) { tmp.innerHTML = "<b>File:</b> " + obj["file"]; }
   var tmp = document.getElementById("title"); if (tmp) { tmp.innerHTML = obj["title"]; }
   var tmp = document.getElementById("link"); if (tmp) { tmp.innerHTML = "<b>Link:</b> " + obj["link"]; }
   var tmp = document.getElementById("type"); if (tmp) { tmp.innerHTML = "<b>Type:</b> " + obj["type"]; }
   var tmp = document.getElementById("id"); if (tmp) { tmp.innerHTML = "<b>Id:</b> " + obj["id"]; }
   var tmp = document.getElementById("image"); if (tmp) { tmp.innerHTML = "<b>Image:</b> " + obj["image"]; }
   var tmp = document.getElementById("author"); if (tmp) { tmp.innerHTML = "<b>Author:</b> " + obj["author"]; }
   var tmp = document.getElementById("captions"); if (tmp) { tmp.innerHTML = "<b>Captions:</b> " + obj["captions"]; }
   var tmp = document.getElementById("audio"); if (tmp) { tmp.innerHTML = "<b>Audio:</b> " + obj["audio"]; }
   var tmp = document.getElementById("start"); if (tmp) { tmp.innerHTML = "<b>Start:</b> " + obj["start"]; } 
   var tmp = document.getElementById("category"); if (tmp) { tmp.innerHTML = "<b>Category:</b> " + obj["category"]; }
   var tmp = document.getElementById("description"); if (tmp) { tmp.innerHTML = "<b>Description:</b> " + obj["description"]; }
   var tmp = document.getElementById("latitude"); if (tmp) { tmp.innerHTML = "<b>Latitude:</b> " + obj["latitude"]; }
   var tmp = document.getElementById("longitude"); if (tmp) { tmp.innerHTML = "<b>Longitude:</b> " + obj["longitude"]; }
   var tmp = document.getElementById("city"); if (tmp) { tmp.innerHTML = "<b>City:</b> " + obj["city"]; }
   var tmp = document.getElementById("date"); if (tmp) { tmp.innerHTML = "<b>Date:</b> " + obj["date"]; } 
};

// These functions are caught by the feeder object of the player.
function loadFile(obj) { thisMovie("xspf_player").loadFile(obj); };

function addItem(obj,idx) { thisMovie("xspf_player").addItem(obj,idx); };

function removeItem(idx) { thisMovie("xspf_player").removeItem(idx); };

function getLength(swf) { return(thisMovie(swf).getLength()); };


// This is a javascript handler for the player and is always needed.
function thisMovie(movieName) {
   if(navigator.appName.indexOf("Microsoft") != -1) {
      return window[movieName];
   } else {
      return document[movieName];
   }
}

</script>

<!-- actionSelected() is invoked when the users selects from the "More actions..." combo box. -->
<script type="text/javascript" language="javascript">
    var N = ${fn:length(model.songs)};
    var downloadEnabled = ${model.user.downloadRole ? "true" : "false"};

    function actionSelected(id) {
        if (id == "top") {
            return;
       } else if (id == "RepeatOn") {
            location.href = "playlist.view?repeat";
       } else if (id == "RepeatOff") {
            location.href = "playlist.view?repeat";
       } else if (id == "Shuffle") {
            location.href = "playlist.view?shuffle";
       } else if (id == "Clear") {
            location.href = "empty.html";
        } else if (id == "loadPlaylist") {
            parent.frames.main.location.href = "loadPlaylist.view?";
        } else if (id == "savePlaylist") {
            parent.frames.main.location.href = "savePlaylist.view?";
        } else if (id == "downloadPlaylist") {
            location.href = "download.view?player=${model.player.id}";
        } else if (id == "sortByTrack") {
            location.href = "playlist.view?sortByTrack";
        } else if (id == "sortByArtist") {
            location.href = "playlist.view?sortByArtist";
        } else if (id == "sortByAlbum") {
            location.href = "playlist.view?sortByAlbum";
        } else if (id == "selectAll") {
            selectAll(true);
            onSelectionChange();
        } else if (id == "selectNone") {
            selectAll(false);
            onSelectionChange();
        } else if (id == "remove") {
            location.href = "playlist.view?remove=" + getSelectedIndexes();
        } else if (id == "download") {
            location.href = "download.view?player=${model.player.id}&indexes=" + getSelectedIndexes();
       } else if (id == "Undo") {
            location.href = "playlist.view?undo";
}
        $("moreActions").selectedIndex = 0;
    }

    function getSelectedIndexes() {
        var result = "";
        for (var i = 0; i < N; i++) {
            if ($("songIndex" + i).checked) {
                result += (i + " ");
            }
        }
        return result;
    }

    function selectAll(b) {
        for (var i = 0; i < N; i++) {
            $("songIndex" + i).checked = b;
        }
    }

    function isSelectionEmpty() {
        for (var i = 0; i < N; i++) {
            if ($("songIndex" + i).checked) {
                return false;
            }
        }
        return true;
    }

    function onSelectionChange() {
        var selectionEmpty = isSelectionEmpty();

        var remove = $("moreActions").options["remove"];
        remove.disabled = selectionEmpty ? "disabled" : "";

        var download = $("moreActions").options["download"];
        if (download) {
            download.disabled = (selectionEmpty || !downloadEnabled) ? "disabled" : "";
        }
    }

</script>

<body id="footer">

<div id="footer_left">
        <table width=116>
            <tr>
   <td width=16 valign=top valign=left><a href="javascript:parent.resizeFrame('42,*,190')"><img src="icons/bullet_arrow_up.png" title="Playlist"/></a></td>
      <td width=100 valign=top valign=left>
        <select id="moreActions" onchange="actionSelected(this.options[selectedIndex].id)">
            <option id="top" selected="selected">Playlist</option>
        <c:if test="${not model.player.clientSidePlaylist}">
            <c:choose>
                <c:when test="${model.repeatEnabled}">
               <option id="RepeatOn">&nbsp;&nbsp;&nbsp;&nbsp;Repeat [Off]</option>
                </c:when>
                <c:otherwise>
               <option id="RepeatOff">&nbsp;&nbsp;&nbsp;&nbsp;Repeat [On]</option>
                </c:otherwise>
            </c:choose>
        </c:if>


       <option id="Shuffle">&nbsp;&nbsp;&nbsp;&nbsp;Shuffle</option>
            <option id="loadPlaylist">&nbsp;&nbsp;&nbsp;&nbsp;<fmt:message key="playlist.load"/></option>
            <c:if test="${model.user.playlistRole}">
                <option id="savePlaylist">&nbsp;&nbsp;&nbsp;&nbsp;<fmt:message key="playlist.save"/></option>
            </c:if>
            <c:if test="${model.user.downloadRole}">
                <option id="downloadPlaylist">&nbsp;&nbsp;&nbsp;&nbsp;<fmt:message key="common.download"/></option>
            </c:if>
            <option id="sortByTrack">&nbsp;&nbsp;&nbsp;&nbsp;<fmt:message key="playlist.more.sortbytrack"/></option>
            <option id="sortByAlbum">&nbsp;&nbsp;&nbsp;&nbsp;<fmt:message key="playlist.more.sortbyalbum"/></option>
            <option id="sortByArtist">&nbsp;&nbsp;&nbsp;&nbsp;<fmt:message key="playlist.more.sortbyartist"/></option>
            <option disabled="disabled">--</option>
            <option id="selectAll">&nbsp;&nbsp;&nbsp;&nbsp;<fmt:message key="playlist.more.selectall"/></option>
            <option id="selectNone">&nbsp;&nbsp;&nbsp;&nbsp;<fmt:message key="playlist.more.selectnone"/></option>
            <option id="remove">&nbsp;&nbsp;&nbsp;&nbsp;<fmt:message key="playlist.remove"/></option>
            <c:if test="${model.user.downloadRole}">
                <option id="download">&nbsp;&nbsp;&nbsp;&nbsp;<fmt:message key="common.download"/></option>
            </c:if>
            <option disabled="disabled">--</option>
            <option id="Undo">&nbsp;&nbsp;&nbsp;&nbsp;Undo</option>
            <option id="Clear">&nbsp;&nbsp;&nbsp;&nbsp;Clear</option>
        </select>
        </td>
   </tr>
   </table>
</div>
<div id="footer_right">
   <div id="player">
   <table style="border:0;margin:0auto;padding:0">
   <tr>
      <td align=right><div id="title"></div></td>
      <td width=20><a href="javascript:detach()"><img src="/icons/detach.png" title="Detach"/></a></td>
      <td width=300 align=right>
      <div style=padding-top:4px;>
      <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
           codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0"
           width="${width}" height="${height}">
          <param name="allowScriptAccess" value="sameDomain"/>
          <param name="movie" value="player.swf"/>
          <param name="quality" value="high"/>
          <param name="bgcolor" value="#000000"/>
          <embed id="xspf_player" src="player.swf" quality="high" bgcolor="#000000" name="xspf_player" allowscriptaccess="sameDomain"
                 type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"
                 height="${height}" width="${width}" flashvars="file=${playlistUrl}&autostart=true&frontcolor=0x999999&lightcolor=0xfafafa&backcolor=0x000000&enablejs=true&javascriptid=xspf_player&showicons=false&fullscreen=false"></embed>
      </object>
      </div>
       </td>
   </tr>
   </table>
   </div>
</div>

<div id="playlist_editor">

<c:choose>
    <c:when test="${empty model.songs}">

        <div id="empty_playlist">Playlist is Empty.</div>
    </c:when>
    <c:otherwise>
        <table width=100% style="text-align: left;border-collapse:collapse;white-space:nowrap;">
            <c:set var="cutoff" value="${model.visibility.captionCutoff}"/>
            <c:forEach items="${model.songs}" var="song" varStatus="loopStatus">
                <c:set var="i" value="${loopStatus.count - 1}"/>
                <tr style="margin:0;padding:0;border:0">
         <td width=1></td>

                    <td width=16><a name="${i}" href="playlist.view?remove=${i}"><img width="16" height="16" src="<spring:theme code="removeImage"/>"
                                                                 alt="<fmt:message key="playlist.remove"/>"
                                                                 title="<fmt:message key="playlist.remove"/>"/></a></td>
                    <td width=16><a href="playlist.view?up=${i}"><img width="16" height="16" src="<spring:theme code="upImage"/>"
                                                             alt="<fmt:message key="playlist.up"/>"
                                                             title="<fmt:message key="playlist.up"/>"/></a></td>
                    <td width=16><a href="playlist.view?down=${i}"><img width="16" height="16" src="<spring:theme code="downImage"/>"
                                                               alt="<fmt:message key="playlist.down"/>"
                                                               title="<fmt:message key="playlist.down"/>"/></a></td>
                    <sub:url value="main.view" var="mainUrl">
                        <sub:param name="path" value="${song.musicFile.parent.path}"/>
                    </sub:url>
                    <c:choose>
                        <c:when test="${i % 2 == 0}">
                            <c:set var="class" value="class='bgcolor2'"/>
                        </c:when>
                        <c:otherwise>
                            <c:set var="class" value=""/>
                        </c:otherwise>
                    </c:choose>

                    <td width=16 style="padding-left: 0.1em"><input type="checkbox" class="checkbox" id="songIndex${i}" onchange="onSelectionChange()"/></td>
                    <td ${class} style="padding-right:0.25em"/>

                    <c:if test="${model.visibility.trackNumberVisible}">
                        <td ${class} style="padding-right:0.5em;text-align:right">
                            <span class="detail">${song.musicFile.metaData.trackNumber}</span>
                        </td>
                    </c:if>

                    <td ${class} style="padding-right:1.25em">
                        <c:choose>
                            <c:when test="${model.player.clientSidePlaylist}">
                                <span style="font-size:.9em; line-height: 1.25em;"" title="${song.musicFile.metaData.title}"><str:truncateNicely upper="${cutoff}">${fn:escapeXml(song.musicFile.title)}</str:truncateNicely></span>
                            </c:when>
                            <c:otherwise>
                                <a href="javascript:sendEvent('playitem',${i})" title="${song.musicFile.metaData.title}"><str:truncateNicely upper="${cutoff}">${fn:escapeXml(song.musicFile.title)}</str:truncateNicely></a>
                            </c:otherwise>
                        </c:choose>
                    </td>

                    <c:if test="${model.visibility.albumVisible}">
                        <td ${class} style="padding-right:1.25em">
                            <span class="detail" title="${song.musicFile.metaData.album}"><a target="main" href="${mainUrl}"><str:truncateNicely upper="${cutoff}">${fn:escapeXml(song.musicFile.metaData.album)}</str:truncateNicely></a></span>
                        </td>
                    </c:if>

                    <c:if test="${model.visibility.artistVisible}">
                        <td ${class} style="padding-right:1.25em">
                            <span class="detail" title="${song.musicFile.metaData.artist}"><str:truncateNicely upper="${cutoff}">${fn:escapeXml(song.musicFile.metaData.artist)}</str:truncateNicely></span>
                        </td>
                    </c:if>

                    <c:if test="${model.visibility.genreVisible}">
                        <td ${class} style="padding-right:1.25em">
                            <span class="detail">${song.musicFile.metaData.genre}</span>
                        </td>
                    </c:if>

                    <c:if test="${model.visibility.yearVisible}">
                        <td ${class} style="padding-right:1.25em">
                            <span class="detail">${song.musicFile.metaData.year}</span>
                        </td>
                    </c:if>

                    <c:if test="${model.visibility.formatVisible}">
                        <td ${class} style="padding-right:1.25em">
                            <span class="detail">${fn:toLowerCase(song.musicFile.metaData.format)}</span>
                        </td>
                    </c:if>

                    <c:if test="${model.visibility.fileSizeVisible}">
                        <td ${class} style="padding-right:1.25em;text-align:right">
                            <span class="detail"><sub:formatBytes bytes="${song.musicFile.metaData.fileSize}"/></span>
                        </td>
                    </c:if>

                    <c:if test="${model.visibility.durationVisible}">
                        <td ${class} style="padding-right:1.25em;text-align:right">
                            <span class="detail">${song.musicFile.metaData.durationAsString}</span>
                        </td>
                    </c:if>

                    <c:if test="${model.visibility.bitRateVisible}">
                        <td ${class} style="padding-right:0.25em">
                            <span class="detail">
                                <c:if test="${not empty song.musicFile.metaData.bitRate}">
                                ${song.musicFile.metaData.bitRate} Kbps ${song.musicFile.metaData.variableBitRate ? "vbr" : ""}
                                </c:if>
                            </span>
                        </td>
                    </c:if>
                   <td width=4></td>

                </tr>
            </c:forEach>
        </table>
    </c:otherwise>
</c:choose>

</div>

        </c:otherwise>
    </c:choose>

</body>
</html>


webPlayer.jsp

Code: Select all
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="iso-8859-1" %>

<html>
<head>
    <%@ include file="head.jsp" %>
    <title>subs0nic</title>

       <c:set var="width" value="400"/>
       <c:set var="height" value="150"/>

<link rel="stylesheet" href="style/black.css" type="text/css"/>

    <script type="text/javascript" src="<c:url value="/script/scripts.js"/>"></script>

    <script type="text/javascript" language="javascript">

        function detach() {
            popupSize("webPlayer.view?detached=",'player','toolbar=no,statusbar=no,location=no,scrollbars=no,width=400,height=150');
        }

    </script>

<script type="text/javascript">
var currentItem;

        function getUpdate(typ,pr1,pr2,pid) {
                if(typ == "item") { currentItem = pr1; setTimeout("getItemData(currentItem)",100); }
        };

        function getItemData(idx) {
                var obj = thisMovie("xspf_player").itemData(idx);
                document.getElementById("songinfo").innerHTML = obj["title"];
        };

        // This is a javascript handler for the player and is always needed.
        function thisMovie(movieName) {
            if(navigator.appName.indexOf("Microsoft") != -1) {
                        return window[movieName];
                } else {
                        return document[movieName];
                }
        };
</script>

</head>

<c:url var="playlistUrl" value="/xspfPlaylist.view">
    <%-- Hack to force Flash player to reload playlist. --%>
    <c:param name="dummy" value="${model.dummy}"/>
</c:url>

<c:url var="playerUrl" value="player.swf?playlist_url=${playlistUrl}&autostart=true"/>

   <c:choose>
        <c:when test="${model.detached}">

      <body width="400" height="150" onload="window.focus();window.moveTo(300, 200);"style="background: black; margin: 0 auto; padding: 0">

                <div style="position: fixed; top: 0; left: 0; width: 395px; height: 140px; margin: 0 auto; padding: 0;">

                <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
                        codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0"
                        width="${width}" height="${height}">
                    <param name="allowScriptAccess" value="sameDomain"/>
                    <param name="movie" value="player.swf"/>
                    <param name="quality" value="high"/>
                    <param name="bgcolor" value="#eee"/>
                    <embed id="xspf_player" src="player.swf" quality="high" bgcolor="#222222" name="xspf_player" allowscriptaccess="sameDomain"
                           type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"
                           height="${height}" width="${width}" flashvars="file=${playlistUrl}&autostart=true&frontcolor=0x999999&lightcolor=0xfafafa&backcolor=0x000000&searchbar=false&height=150&width=400&autoscroll=false&displaywidth=130&overstretch=true&thumbsinplaylist=false&showicons=false&fullscreen=false"></embed>

                </object>
                </div>

        </c:when>
        <c:otherwise>

<body onLoad="detach()" class="bgcolor3"  style="margin: 0 auto; border-top: solid 4px #181A18; font-size: .8em; color: #999;">

<div style="float:right; margin: 0 auto; padding-right: 6px; padding-top: 4px;">
</div>
   
        </c:otherwise>
    </c:choose>

</body>
</html>


xspfPlaylist.jsp

Code: Select all
<%@ include file="include.jsp" %>
<%@ page language="java" contentType="text/xml; charset=utf-8" pageEncoding="iso-8859-1" %>

<playlist version="1" xmlns="http://xspf.org/ns/0/">
    <trackList>

<c:forEach var="song" items="${model.songs}">

    <sub:url value="/stream" var="streamUrl">
        <sub:param name="path" value="${song.musicFile.path}"/>
    </sub:url>

    <sub:url value="coverArt.view" var="coverArtUrl">
        <sub:param name="size" value="200"/>
        <c:if test="${not empty song.coverArtFile}">
            <sub:param name="path" value="${song.coverArtFile.path}"/>
        </c:if>
    </sub:url>

        <track>
            <location>${streamUrl}</location>
            <image>${coverArtUrl}</image>
            <title>${song.musicFile.metaData.artist} - ${song.musicFile.title}</title>
            <meta rel="type">mp3</meta>
        </track>

</c:forEach>

    </trackList>
</playlist>


Again, This will break normal streaming, all music will be played from embedded player. Pretty ugly, but hey, does what I want, :P
Last edited by zeekay on Mon Nov 24, 2008 10:42 pm, edited 1 time in total.
zeekay
 
Posts: 63
Joined: Sun Aug 03, 2008 6:33 pm

Postby aphuey » Mon Nov 24, 2008 7:16 pm

Awesome. Is it just a matter of pasting this code in the various files?

And this code will enable the webplayer to work like the one represented in the screenshot you posted in a similar post recently?
aphuey
 
Posts: 102
Joined: Mon Nov 17, 2008 6:25 pm

Postby zeekay » Mon Nov 24, 2008 10:34 pm

Hmm, I don't know! I wouldn't recommend it. For the resize function to work in the footer, you need to modify the index.jsp, here's mine (don't use this directly, as it will break other parts of subsonic):

Code: Select all
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="iso-8859-1"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">

<html><head><title>subs0nic</title>
    <%@ include file="head.jsp" %>
    <link rel="alternate" type="application/rss+xml" title="Subsonic Podcast" href="podcast.view?suffix=.rss"/>

<script type="text/javascript">

var columntype=""
var defaultsetting=""

function getCurrentSetting(){
if (document.body)
return (document.body.cols)? document.body.cols : document.body.rows
}

function setframevalue(coltype, settingvalue){
if (coltype=="rows")
document.body.rows=settingvalue
else if (coltype=="cols")
document.body.cols=settingvalue
}

function resizeFrame(contractsetting){
if (getCurrentSetting()!=defaultsetting)
setframevalue(columntype, defaultsetting)
else
setframevalue(columntype, contractsetting)
}

function init(){
if (!document.all && !document.getElementById) return
if (document.body!=null){
columntype=(document.body.cols)? "cols" : "rows"
defaultsetting=(document.body.cols)? document.body.cols : document.body.rows
}
else
setTimeout("init()",100)
}

setTimeout("init()",100)

</script>

</head>

<frameset rows="42,*,32" border="0" framespacing="0" frameborder="0">

        <frame noresize="noresize" scrolling="no" name="upper" src="top.view.html">

        <frame name="main" src="home.view.html" marginwidth="0" marginheight="0">

        <frame noresize="noresize" scrolling="no" name="playlist" src="footer.html">

</frameset>

</html>


The key there is using the little bit of javascript at the top, and modifying the frame sizes to suit you (you'll note I'm missing the left frame, which may cause you some trouble). You don't want to use it directly or any of the other snippets I posted, as I changed a few other things with the layout. For instance, in index.jsp, I removed the left frame (I changed the root view to accomodate this, with a list of genres and featured albums). If you look at the index.jsp I have it target static html pages (to speed up loading for me). So you can't use it "as is".

I haven't had the chance to try and integrate my changes into 3.5 (this was all modified from 3.5b1), so there could be problems there. I was just posting to give you some ideas, really. I really don't know much about coding, so you are probably better off trying to use what you can and doing it yourself!
zeekay
 
Posts: 63
Joined: Sun Aug 03, 2008 6:33 pm

Postby aphuey » Tue Nov 25, 2008 12:04 am

Well this definitely gives me something to work with. If I can find some time over the next few weeks, I'll take a stab at it.

Any idea if Sindre has backed off the priority of integrating the improvements with the flash player for the next release? If so, I might just hold off and see what is new in 3.6.

But I thought I read somewhere that he is shifting his current focus away from the integration of a better flash player and dedicating more of his focus to the mobile player...
aphuey
 
Posts: 102
Joined: Mon Nov 17, 2008 6:25 pm

Postby sindre_mehus » Tue Nov 25, 2008 7:45 am

Hi,

I'm still planning to do something with the Flash player in 3.6, but I haven't started on it yet.

Sindre
User avatar
sindre_mehus
 
Posts: 1955
Joined: Tue Nov 29, 2005 6:19 pm
Location: Oslo, Norway


Return to General

Who is online

Users browsing this forum: No registered users and 7 guests