We are going to edit playlist.jsp and videoPlayer.jsp. Let's start with playlist.jsp.
The goal is to have a warning appear only when a song is playing. When the player is paused or idle or complete, we want to be able to exit the page.
To accomplish this, we need to add a variable "playing". In addition, we are going to add a variable called "playingTitle".
add
- Code: Select all
var playing = 0;
var playingTitle = null;
to
- Code: Select all
var player = null;
var songs = null;
var currentAlbumUrl = null;
var currentStreamUrl = null;
var startPlayer = false;
var repeatEnabled = false;
var slider = null;
Now we need to set the variables at the correct times. Here is the existing code that listens for the state of the player:
- Code: Select all
function stateListener(obj) { // IDLE, BUFFERING, PLAYING, PAUSED, COMPLETED
if (obj.newstate == "COMPLETED") {
onNext(repeatEnabled);
}
}
We're going to replace the whole function with this:
- Code: Select all
function stateListener(obj) { // IDLE, BUFFERING, PLAYING, PAUSED, COMPLETED
if (obj.newstate == "COMPLETED") {
playing = 0;
onNext(repeatEnabled);
} else if (obj.newstate == "PLAYING") {
playing = 1;
} else if (obj.newstate == "PAUSED") {
playing = 0;
} else if (obj.newstate == "IDLE") {
playing = 0;
}
}
Now we need to set playingTitle to the correct title. We are going to add "playingTitle = song.artist + ' - ' + song.title;" to the skip() function like so:
- Code: Select all
function skip(index) {
if (index < 0 || index >= songs.length) {
return;
}
var song = songs[index];
currentStreamUrl = song.streamUrl;
updateCurrentImage();
var list = new Array();
list[0] = {
file:song.streamUrl,
title:song.title,
provider:"sound"
};
if (song.duration != null) {
list[0].duration = song.duration;
}
if (song.format == "aac" || song.format == "m4a") {
list[0].provider = "video";
}
player.sendEvent("LOAD", list);
player.sendEvent("PLAY");
playingTitle = song.artist + ' - ' + song.title;
}
Now we are going to add the actual function that will be called when attempting to exit subsonic:
- Code: Select all
function askConfirm() {
if (playing) {
setTimeout("$('currentPlayer').selected = true;$('playerSelector').blur()",300);
return "You are currently listening to: \n\n" + playingTitle;
}
}
We are also going to replace the player selector dropdown that originally looks like this:
- Code: Select all
<c:if test="${model.user.settingsRole}">
<td><select name="player" onchange="location='playlist.view?player=' + options[selectedIndex].value;">
<c:forEach items="${model.players}" var="player">
<option ${player.id eq model.player.id ? "selected" : ""} value="${player.id}">${player.shortDescription}</option>
</c:forEach>
</select></td>
</c:if>
with this:
- Code: Select all
<c:if test="${model.user.settingsRole}">
<td style="padding-right:10px"><select id="playerSelector" name="player" onchange="location='playlist.view?player=' + options[selectedIndex].value;">
<c:forEach items="${model.players}" var="player">
<option ${player.id eq model.player.id ? "selected" : ""} ${player.id eq model.player.id ? "id='currentPlayer'" : ""} value="${player.id}">${player.shortDescription}</option>
</c:forEach>
</select></td>
</c:if>
This will ensure that after attempting to change the player while a song is playing, if you choose to stay on the page, the dropdown will revert back to showing the current player.
The last and final step (for playlist.jsp) is to add the event handler to the init() function.
Just add "window.onbeforeunload = askConfirm;" to the init() function and save the file.
Now we are going to edit videoPlayer.jsp.
Unlike the playlist, we want a warning when attempting to exit the page even if the video is paused.
This is because when accessing subsonic over a slow connection, you may want to pause the video and let it buffer before playing it, to ensure smooth playback.
We also need to make sure that we can still click the back link and that we can still change the bitrate and offset time without getting the warning dialog.
We need to add two variables, "paused" and "exitOk" to the script like this:
- Code: Select all
var player;
var position;
var maxBitRate = ${model.maxBitRate};
var timeOffset = ${model.timeOffset};
var paused = 1;
var exitOk = 1;
Now we are going to add this function right after the timeListener() function:
- Code: Select all
function stateListener(obj) { // IDLE, BUFFERING, PLAYING, PAUSED, COMPLETED
if (obj.newstate == "PLAYING") {
paused = 0;
exitOk = 0;
} else if (obj.newstate == "PAUSED") {
paused = 1;
exitOk = 0;
} else if (obj.newstate == "BUFFERING") {
paused = 1;
exitOk = 0;
} else if (obj.newstate == "COMPLETED") {
paused = 1;
exitOk = 1;
}
}
We also have to add "player.addModelListener("STATE", "stateListener");" to the end of the playerReady() function like this:
- Code: Select all
function playerReady(thePlayer) {
player = $("player1");
player.addModelListener("TIME", "timeListener");
player.addModelListener("STATE", "stateListener");
<c:if test="${not (model.trial and model.trialExpired)}">
play();
</c:if>
}
Now we need to set "exitOk" to the correct values. This is what the back links and popout link should look like:
- Code: Select all
<c:choose>
<c:when test="${model.popout}">
<div class="back"><a href="javascript:exitOk=1;popin();"><fmt:message key="common.back"/></a></div>
</c:when>
<c:otherwise>
<div class="back" style="float:left;padding-right:2em"><a href="${backUrl}" onclick="javascript:exitOk=1;"><fmt:message key="common.back"/></a></div>
<div class="forward" style="float:left;"><a href="javascript:exitOk=1;popout();"><fmt:message key="videoPlayer.popout"/></a></div>
</c:otherwise>
</c:choose>
Now we have to add the exit warning function:
- Code: Select all
function askConfirm() {
if (!exitOk) {
return "You are currently watching:\n\n${model.video.title}";
}
}
Lastly, we have to add the event handler to the end of the init() function like so:
- Code: Select all
var width = "${model.popout ? '100%' : '600'}";
var height = "${model.popout ? '85%' : '360'}";
swfobject.embedSWF("<c:url value="/flash/jw-player-5.6.swf"/>", "placeholder1", width, height, "9.0.0", false, flashvars, params, attributes);
window.onbeforeunload = askConfirm;
Save the file and enjoy your peace of mind!
Note: The examples in this tutorial are from the unedited source files of the subsonic 4.5 build.
Hope this helps!
