From aeabfa1044daa45ff29badc40ab5e37f2fd7e697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois-Xavier=20Thomas?= Date: Sun, 14 Apr 2019 19:44:40 +0200 Subject: [PATCH] Add internet radio source cache This helps us avoid loading and parsing the external playlists each time we try to load an internet radio. --- .../player/ajax/PlayQueueService.java | 41 +++++++++---------- .../player/domain/InternetRadioSource.java | 11 +++++ .../player/service/InternetRadioService.java | 32 ++++++++++++--- 3 files changed, 57 insertions(+), 27 deletions(-) create mode 100644 airsonic-main/src/main/java/org/airsonic/player/domain/InternetRadioSource.java diff --git a/airsonic-main/src/main/java/org/airsonic/player/ajax/PlayQueueService.java b/airsonic-main/src/main/java/org/airsonic/player/ajax/PlayQueueService.java index 4bf713d0..2baf89f7 100644 --- a/airsonic-main/src/main/java/org/airsonic/player/ajax/PlayQueueService.java +++ b/airsonic-main/src/main/java/org/airsonic/player/ajax/PlayQueueService.java @@ -449,6 +449,7 @@ public class PlayQueueService { } private PlayQueueInfo doPlayInternetRadio(HttpServletRequest request, Player player, InternetRadio radio) throws Exception { + internetRadioService.clearInternetRadioSourceCache(radio.getId()); player.getPlayQueue().clear(); player.getPlayQueue().setRandomSearchCriteria(null); player.getPlayQueue().setInternetRadio(radio); @@ -742,35 +743,31 @@ public class PlayQueueService { final String radioName = radio.getName(); List entries = new ArrayList<>(); - for (String streamUrl : internetRadioService.getStreamUrls(radio)) { - // Fake stream title using the URL - String streamTitle = streamUrl; - String streamAlbum = radioName; - String streamGenre = "Internet Radio"; - // Fake entry id so that the source can be selected + for (InternetRadioSource streamSource: internetRadioService.getInternetRadioSources(radio)) { + // Fake entry id so that the source can be selected in the UI Integer streamId = -(1+entries.size()); Integer streamTrackNumber = entries.size(); - Integer streamYear = 0; + String streamUrl = streamSource.getStreamUrl(); entries.add(new PlayQueueInfo.Entry( streamId, // Entry id streamTrackNumber, // Track number - streamTitle, // Use URL as stream title - "", - streamAlbum, // Album name - streamGenre, - streamYear, - "", - 0, - "", - "", - "", - "", - false, - radioHomepageUrl, // Album URL + streamUrl, // Track title (use radio stream URL for now) + "", // Track artist + radioName, // Album name (use radio name) + "Internet Radio", // Genre + 0, // Year + "", // Bit rate + 0, // Duration + "", // Duration (as string) + "", // Format + "", // Content Type + "", // File size + false, // Starred + radioHomepageUrl, // Album URL (use radio home page URL) streamUrl, // Stream URL streamUrl, // Remote stream URL - null, - null + null, // Cover art URL + null // Remote cover art URL )); } diff --git a/airsonic-main/src/main/java/org/airsonic/player/domain/InternetRadioSource.java b/airsonic-main/src/main/java/org/airsonic/player/domain/InternetRadioSource.java new file mode 100644 index 00000000..5058dc4c --- /dev/null +++ b/airsonic-main/src/main/java/org/airsonic/player/domain/InternetRadioSource.java @@ -0,0 +1,11 @@ +package org.airsonic.player.domain; + +public class InternetRadioSource { + private String streamUrl; + + public InternetRadioSource(String streamUrl) { + this.streamUrl = streamUrl; + } + + public String getStreamUrl() { return streamUrl; } +} diff --git a/airsonic-main/src/main/java/org/airsonic/player/service/InternetRadioService.java b/airsonic-main/src/main/java/org/airsonic/player/service/InternetRadioService.java index 8a15989d..9a978a39 100644 --- a/airsonic-main/src/main/java/org/airsonic/player/service/InternetRadioService.java +++ b/airsonic-main/src/main/java/org/airsonic/player/service/InternetRadioService.java @@ -2,21 +2,41 @@ package org.airsonic.player.service; import chameleon.playlist.*; import org.airsonic.player.domain.InternetRadio; +import org.airsonic.player.domain.InternetRadioSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.net.URL; -import java.util.ArrayList; -import java.util.List; +import java.util.*; @Service public class InternetRadioService { private static final Logger LOG = LoggerFactory.getLogger(InternetRadioService.class); - public List getStreamUrls(InternetRadio radio) throws Exception { + private Map> cachedSources; + public InternetRadioService() { + this.cachedSources = new HashMap<>(); + } + + public void clearInternetRadioSourceCache() { + cachedSources.clear(); + } + + public List getInternetRadioSources(InternetRadio radio) throws Exception { + List sources; + if (cachedSources.containsKey(radio.getId())) { + sources = cachedSources.get(radio.getId()); + } else { + sources = retrieveInternetRadioSources(radio); + cachedSources.put(radio.getId(), sources); + } + return sources; + } + + private List retrieveInternetRadioSources(InternetRadio radio) throws Exception { // Retrieve radio playlist and parse it URL playlistUrl = new URL(radio.getStreamUrl()); SpecificPlaylist inputPlaylist = null; @@ -33,7 +53,7 @@ public class InternetRadioService { } // Retrieve stream URLs - List entries = new ArrayList<>(); + List entries = new ArrayList<>(); inputPlaylist.toPlaylist().acceptDown(new PlaylistVisitor() { @Override public void beginVisitPlaylist(Playlist playlist) throws Exception { @@ -69,7 +89,9 @@ public class InternetRadioService { public void beginVisitMedia(Media media) throws Exception { String streamUrl = media.getSource().getURI().toString(); LOG.info("Got source media at {}...", streamUrl); - entries.add(streamUrl); + entries.add(new InternetRadioSource( + streamUrl + )); } @Override