Skip to content
This repository has been archived by the owner on Sep 8, 2021. It is now read-only.

Commit

Permalink
Merge pull request #563 from biconou/squash
Browse files Browse the repository at this point in the history
Introduction of a new kind of jukebox player based on the javasound api.
  • Loading branch information
biconou committed Sep 11, 2017
2 parents 291e35f + c09acbc commit f5454bb
Show file tree
Hide file tree
Showing 23 changed files with 1,825 additions and 412 deletions.
21 changes: 20 additions & 1 deletion airsonic-main/pom.xml
Expand Up @@ -31,6 +31,25 @@
<version>${project.version}</version>
</dependency>

<!-- Java Audio Player and needed dependencies
-->
<dependency>
<groupId>com.github.biconou</groupId>
<artifactId>AudioPlayer</artifactId>
<version>0.2.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- -->

<!-- Metrics
Metrics is a cool framework used here
to compute musures and statistics during automated testing
Expand Down Expand Up @@ -317,7 +336,7 @@
<version>${cxf.version}</version>
<exclusions>
<exclusion>
<groupId> org.springframework</groupId>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
</exclusions>
Expand Down
Expand Up @@ -89,27 +89,22 @@ public PlayQueueInfo getPlayQueue() throws Exception {
}

public PlayQueueInfo start() throws Exception {
HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
return doStart(request, response);
}

public PlayQueueInfo doStart(HttpServletRequest request, HttpServletResponse response) throws Exception {
Player player = getCurrentPlayer(request, response);
Player player = resolvePlayer();
player.getPlayQueue().setStatus(PlayQueue.Status.PLAYING);
return convert(request, player, true);
if (player.isJukebox()) {
jukeboxService.start(player);
}
return convert(resolveHttpServletRequest(), player, true);
}

public PlayQueueInfo stop() throws Exception {
HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
return doStop(request, response);
}

public PlayQueueInfo doStop(HttpServletRequest request, HttpServletResponse response) throws Exception {
Player player = getCurrentPlayer(request, response);
public PlayQueueInfo stop() throws Exception {
Player player = resolvePlayer();
player.getPlayQueue().setStatus(PlayQueue.Status.STOPPED);
return convert(request, player, true);
if (player.isJukebox()) {
jukeboxService.stop(player);
}
return convert(resolveHttpServletRequest(), player, true);
}

public PlayQueueInfo toggleStartStop() throws Exception {
Expand All @@ -129,16 +124,17 @@ public PlayQueueInfo doToggleStartStop(HttpServletRequest request, HttpServletRe
}

public PlayQueueInfo skip(int index) throws Exception {
HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
return doSkip(request, response, index, 0);
return doSkip(index, 0);
}

public PlayQueueInfo doSkip(HttpServletRequest request, HttpServletResponse response, int index, int offset) throws Exception {
Player player = getCurrentPlayer(request, response);
public PlayQueueInfo doSkip(int index, int offset) throws Exception {
Player player = resolvePlayer();
player.getPlayQueue().setIndex(index);
boolean serverSidePlaylist = !player.isExternalWithPlaylist();
return convert(request, player, serverSidePlaylist, offset);
if (serverSidePlaylist && player.isJukebox()) {
jukeboxService.skip(player,index,offset);
}
return convert(resolveHttpServletRequest(), player, serverSidePlaylist, offset);
}

public PlayQueueInfo reloadSearchCriteria() throws Exception {
Expand Down Expand Up @@ -202,23 +198,24 @@ public PlayQueueInfo loadPlayQueue() throws Exception {

boolean serverSidePlaylist = !player.isExternalWithPlaylist();
if (serverSidePlaylist && currentIndex != -1) {
doSkip(request, response, currentIndex, (int) (positionMillis / 1000L));
doSkip(currentIndex, (int) (positionMillis / 1000L));
}

return result;
}

public PlayQueueInfo play(int id) throws Exception {
HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
HttpServletRequest request = resolveHttpServletRequest();
HttpServletResponse response = resolveHttpServletResponse();

Player player = getCurrentPlayer(request, response);
MediaFile file = mediaFileService.getMediaFile(id);

List<MediaFile> songs;

if (file.isFile()) {
String username = securityService.getCurrentUsername(request);
boolean queueFollowingSongs = settingsService.getUserSettings(username).isQueueFollowingSongs();
List<MediaFile> songs;
if (queueFollowingSongs) {
MediaFile dir = mediaFileService.getParentOf(file);
songs = mediaFileService.getChildrenOf(dir, true, false, true);
Expand All @@ -229,11 +226,10 @@ public PlayQueueInfo play(int id) throws Exception {
} else {
songs = Arrays.asList(file);
}
return doPlay(request, player, songs).setStartPlayerAt(0);
} else {
List<MediaFile> songs = mediaFileService.getDescendantsOf(file, true);
return doPlay(request, player, songs).setStartPlayerAt(0);
songs = mediaFileService.getDescendantsOf(file, true);
}
return doPlay(request, player, songs).setStartPlayerAt(0);
}

/**
Expand Down Expand Up @@ -422,6 +418,9 @@ private PlayQueueInfo doPlay(HttpServletRequest request, Player player, List<Med
}
player.getPlayQueue().addFiles(false, files);
player.getPlayQueue().setRandomSearchCriteria(null);
if (player.isJukebox()) {
jukeboxService.play(player);
}
return convert(request, player, true);
}

Expand Down Expand Up @@ -461,69 +460,81 @@ public PlayQueueInfo addAt(int id, int index) throws Exception {
return doAdd(request, response, new int[]{id}, index);
}

public PlayQueueInfo doAdd(HttpServletRequest request, HttpServletResponse response, int[] ids, Integer index) throws Exception {
Player player = getCurrentPlayer(request, response);
/**
* TODO This method should be moved to a real PlayQueueService not dedicated to Ajax DWR.
* @param playQueue
* @param ids
* @param index
* @return
* @throws Exception
*/
public PlayQueue addMediaFilesToPlayQueue(PlayQueue playQueue,int[] ids, Integer index, boolean removeVideoFiles) throws Exception {
List<MediaFile> files = new ArrayList<MediaFile>(ids.length);
for (int id : ids) {
MediaFile ancestor = mediaFileService.getMediaFile(id);
files.addAll(mediaFileService.getDescendantsOf(ancestor, true));
}
if (player.isWeb()) {
if (removeVideoFiles) {
mediaFileService.removeVideoFiles(files);
}
if (index != null) {
player.getPlayQueue().addFilesAt(files, index);
playQueue.addFilesAt(files, index);
} else {
player.getPlayQueue().addFiles(true, files);
playQueue.addFiles(true, files);
}
player.getPlayQueue().setRandomSearchCriteria(null);
return convert(request, player, false);
playQueue.setRandomSearchCriteria(null);
return playQueue;
}
public PlayQueueInfo doSet(HttpServletRequest request, HttpServletResponse response, int[] ids) throws Exception {

public PlayQueueInfo doAdd(HttpServletRequest request, HttpServletResponse response, int[] ids, Integer index) throws Exception {
Player player = getCurrentPlayer(request, response);
PlayQueue playQueue = player.getPlayQueue();
boolean removeVideoFiles = false;
if (player.isWeb()) {
removeVideoFiles = true;
}
addMediaFilesToPlayQueue(player.getPlayQueue(), ids, index, removeVideoFiles);
return convert(request, player, false);
}

/**
* TODO This method should be moved to a real PlayQueueService not dedicated to Ajax DWR.
* @param playQueue
* @param ids
* @return
* @throws Exception
*/
public PlayQueue resetPlayQueue(PlayQueue playQueue,int[] ids, boolean removeVideoFiles) throws Exception {
MediaFile currentFile = playQueue.getCurrentFile();
PlayQueue.Status status = playQueue.getStatus();

playQueue.clear();
PlayQueueInfo result = doAdd(request, response, ids, null);
addMediaFilesToPlayQueue(playQueue, ids, null,removeVideoFiles);

int index = currentFile == null ? -1 : playQueue.getFiles().indexOf(currentFile);
playQueue.setIndex(index);
playQueue.setStatus(status);
return result;
return playQueue;
}

public PlayQueueInfo clear() throws Exception {
HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
return doClear(request, response);
}

public PlayQueueInfo doClear(HttpServletRequest request, HttpServletResponse response) throws Exception {
Player player = getCurrentPlayer(request, response);
Player player = resolvePlayer();
player.getPlayQueue().clear();
boolean serverSidePlaylist = !player.isExternalWithPlaylist();
return convert(request, player, serverSidePlaylist);
return convert(resolveHttpServletRequest(), player, serverSidePlaylist);
}

public PlayQueueInfo shuffle() throws Exception {
HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
return doShuffle(request, response);
}

public PlayQueueInfo doShuffle(HttpServletRequest request, HttpServletResponse response) throws Exception {
Player player = getCurrentPlayer(request, response);
public PlayQueueInfo shuffle() throws Exception {
Player player = resolvePlayer();
player.getPlayQueue().shuffle();
return convert(request, player, false);
return convert(resolveHttpServletRequest(), player, false);
}


public PlayQueueInfo remove(int index) throws Exception {
HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
return doRemove(request, response, index);
Player player = resolvePlayer();
player.getPlayQueue().removeFileAt(index);
return convert(resolveHttpServletRequest(), player, false);
}

public PlayQueueInfo toggleStar(int index) throws Exception {
Expand Down Expand Up @@ -629,20 +640,16 @@ public PlayQueueInfo sortByAlbum() throws Exception {
return convert(request, player, false);
}

public void setGain(float gain) {
jukeboxService.setGain(gain);
}

private PlayQueueInfo convert(HttpServletRequest request, Player player, boolean serverSidePlaylist) throws Exception {
return convert(request, player, serverSidePlaylist, 0);
}

private PlayQueueInfo convert(HttpServletRequest request, Player player, boolean serverSidePlaylist, int offset) throws Exception {
String url = NetworkService.getBaseUrl(request);

if (serverSidePlaylist && player.isJukebox()) {
jukeboxService.updateJukebox(player, offset);
}
/* if (serverSidePlaylist && player.isJukebox()) {
updateJukebox(player, offset);
} */
boolean isCurrentPlayer = player.getIpAddress() != null && player.getIpAddress().equals(request.getRemoteAddr());

boolean m3uSupported = player.isExternal() || player.isExternalWithPlaylist();
Expand Down Expand Up @@ -671,7 +678,10 @@ private PlayQueueInfo convert(HttpServletRequest request, Player player, boolean
coverArtUrl, remoteCoverArtUrl));
}
boolean isStopEnabled = playQueue.getStatus() == PlayQueue.Status.PLAYING && !player.isExternalWithPlaylist();
float gain = jukeboxService.getGain();

float gain = 0.0f;
gain = jukeboxService.getGain(player);

return new PlayQueueInfo(entries, isStopEnabled, playQueue.isRepeatEnabled(), playQueue.isRadioEnabled(), serverSidePlaylist, gain);
}

Expand Down Expand Up @@ -704,6 +714,43 @@ private Player getCurrentPlayer(HttpServletRequest request, HttpServletResponse
return playerService.getPlayer(request, response);
}

private Player resolvePlayer() {
return getCurrentPlayer(resolveHttpServletRequest(), resolveHttpServletResponse());
}

private HttpServletRequest resolveHttpServletRequest() {
return WebContextFactory.get().getHttpServletRequest();
}

private HttpServletResponse resolveHttpServletResponse() {
return WebContextFactory.get().getHttpServletResponse();
}



//
// Methods dedicated to jukebox
//

public void setGain(float gain) {
HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
Player player = getCurrentPlayer(request, response);
if (player != null) {
jukeboxService.setGain(player,gain);
}
}

public void setJukeboxPosition(int positionInSeconds) {
Player player = resolvePlayer();
jukeboxService.setPosition(player,positionInSeconds);
}


//
// End : Methods dedicated to jukebox
//

public void setPlayerService(PlayerService playerService) {
this.playerService = playerService;
}
Expand Down
Expand Up @@ -52,6 +52,8 @@ public class PlayerSettingsCommand {
private EnumHolder[] transcodeSchemeHolders;
private Player[] players;
private boolean isAdmin;
private String javaJukeboxMixer;
private String[] javaJukeboxMixers;

public String getPlayerId() {
return playerId;
Expand Down Expand Up @@ -209,6 +211,22 @@ public void setAdmin(boolean admin) {
public void setReloadNeeded(boolean reloadNeeded) {
}

public String getJavaJukeboxMixer() {
return javaJukeboxMixer;
}

public void setJavaJukeboxMixer(String javaJukeboxMixer) {
this.javaJukeboxMixer = javaJukeboxMixer;
}

public String[] getJavaJukeboxMixers() {
return javaJukeboxMixers;
}

public void setJavaJukeboxMixers(String[] javaJukeboxMixers) {
this.javaJukeboxMixers = javaJukeboxMixers;
}

/**
* Holds the transcoding and whether it is active for the given player.
*/
Expand Down
Expand Up @@ -70,16 +70,4 @@ protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpSer
map.put("autoHide", userSettings.isAutoHidePlayQueue());
return new ModelAndView("playQueue","model",map);
}

public void setPlayerService(PlayerService playerService) {
this.playerService = playerService;
}

public void setSecurityService(SecurityService securityService) {
this.securityService = securityService;
}

public void setSettingsService(SettingsService settingsService) {
this.settingsService = settingsService;
}
}

0 comments on commit f5454bb

Please sign in to comment.