From cab3f60a2588582a0328a4a8554271da4148b3e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois-Xavier=20Thomas?= Date: Sun, 14 Apr 2019 19:33:19 +0200 Subject: [PATCH] Refactor internet radio loading into a service --- .../player/ajax/PlayQueueService.java | 131 +++++------------- .../player/service/InternetRadioService.java | 87 ++++++++++++ 2 files changed, 121 insertions(+), 97 deletions(-) create mode 100644 airsonic-main/src/main/java/org/airsonic/player/service/InternetRadioService.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 71945b70..4bf713d0 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 @@ -19,8 +19,6 @@ */ package org.airsonic.player.ajax; -import chameleon.playlist.*; -import chameleon.playlist.Playlist; import com.google.common.base.Function; import com.google.common.collect.Lists; import org.airsonic.player.dao.InternetRadioDao; @@ -40,7 +38,6 @@ import org.springframework.web.servlet.support.RequestContextUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.net.URL; import java.util.*; /** @@ -83,6 +80,8 @@ public class PlayQueueService { private InternetRadioDao internetRadioDao; @Autowired private JWTSecurityService jwtSecurityService; + @Autowired + private InternetRadioService internetRadioService; private static final Logger LOG = LoggerFactory.getLogger(PlayQueueService.class); @@ -711,7 +710,7 @@ public class PlayQueueService { Locale locale = RequestContextUtils.getLocale(request); PlayQueue playQueue = player.getPlayQueue(); - List entries = new ArrayList(); + List entries = new ArrayList<>(); for (MediaFile file : playQueue.getFiles()) { String albumUrl = url + "main.view?id=" + file.getId(); @@ -736,105 +735,43 @@ public class PlayQueueService { private List convertInternetRadio(HttpServletRequest request, Player player) throws Exception { - // Retrieve radio playlist and parse it PlayQueue playQueue = player.getPlayQueue(); InternetRadio radio = playQueue.getInternetRadio(); - URL playlistUrl = new URL(radio.getStreamUrl()); - SpecificPlaylist inputPlaylist = null; - try { - LOG.info("Parsing playlist at {}...", playlistUrl.toString()); - inputPlaylist = SpecificPlaylistFactory.getInstance().readFrom(playlistUrl); - } catch (Exception e) { - LOG.error("Unable to parse playlist: {}", playlistUrl.toString(), e); - throw e; - } - if (inputPlaylist == null) { - LOG.error("Unsupported playlist format: {}", playlistUrl.toString()); - throw new Exception("Unsupported playlist format " + playlistUrl.toString()); - } - // Retrieve stream URLs - List entries = new ArrayList<>(); final String radioHomepageUrl = radio.getHomepageUrl(); final String radioName = radio.getName(); - inputPlaylist.toPlaylist().acceptDown(new PlaylistVisitor() { - @Override - public void beginVisitPlaylist(Playlist playlist) throws Exception { - - } - - @Override - public void endVisitPlaylist(Playlist playlist) throws Exception { - } - - @Override - public void beginVisitParallel(Parallel parallel) throws Exception { - - } - - @Override - public void endVisitParallel(Parallel parallel) throws Exception { - - } - - @Override - public void beginVisitSequence(Sequence sequence) throws Exception { - - } - - @Override - public void endVisitSequence(Sequence sequence) throws Exception { - - } - - @Override - public void beginVisitMedia(Media media) throws Exception { - - // Retrieve stream URL - String streamUrl = media.getSource().getURI().toString(); - // 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 - Integer streamId = -(1+entries.size()); - Integer streamTrackNumber = entries.size(); - Integer streamYear = 0; - - LOG.info("Got source media at {}...", streamUrl); - - 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, // Stream URL - streamUrl, // Remote stream URL - null, - null - )); - } - - @Override - public void endVisitMedia(Media media) throws Exception { - - } - }); - - if (entries.isEmpty()) { - LOG.error("Cannot fetch stream URLs from radio source {}", playlistUrl.toString()); + 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 + Integer streamId = -(1+entries.size()); + Integer streamTrackNumber = entries.size(); + Integer streamYear = 0; + 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, // Stream URL + streamUrl, // Remote stream URL + null, + null + )); } return entries; 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 new file mode 100644 index 00000000..8a15989d --- /dev/null +++ b/airsonic-main/src/main/java/org/airsonic/player/service/InternetRadioService.java @@ -0,0 +1,87 @@ +package org.airsonic.player.service; + +import chameleon.playlist.*; +import org.airsonic.player.domain.InternetRadio; +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; + +@Service +public class InternetRadioService { + + private static final Logger LOG = LoggerFactory.getLogger(InternetRadioService.class); + + public List getStreamUrls(InternetRadio radio) throws Exception { + + // Retrieve radio playlist and parse it + URL playlistUrl = new URL(radio.getStreamUrl()); + SpecificPlaylist inputPlaylist = null; + try { + LOG.info("Parsing playlist at {}...", playlistUrl.toString()); + inputPlaylist = SpecificPlaylistFactory.getInstance().readFrom(playlistUrl); + } catch (Exception e) { + LOG.error("Unable to parse playlist: {}", playlistUrl.toString(), e); + throw e; + } + if (inputPlaylist == null) { + LOG.error("Unsupported playlist format: {}", playlistUrl.toString()); + throw new Exception("Unsupported playlist format " + playlistUrl.toString()); + } + + // Retrieve stream URLs + List entries = new ArrayList<>(); + inputPlaylist.toPlaylist().acceptDown(new PlaylistVisitor() { + @Override + public void beginVisitPlaylist(Playlist playlist) throws Exception { + + } + + @Override + public void endVisitPlaylist(Playlist playlist) throws Exception { + + } + + @Override + public void beginVisitParallel(Parallel parallel) throws Exception { + + } + + @Override + public void endVisitParallel(Parallel parallel) throws Exception { + + } + + @Override + public void beginVisitSequence(Sequence sequence) throws Exception { + + } + + @Override + public void endVisitSequence(Sequence sequence) throws Exception { + + } + + @Override + public void beginVisitMedia(Media media) throws Exception { + String streamUrl = media.getSource().getURI().toString(); + LOG.info("Got source media at {}...", streamUrl); + entries.add(streamUrl); + } + + @Override + public void endVisitMedia(Media media) throws Exception { + + } + }); + + if (entries.isEmpty()) { + LOG.warn("No entries found when parsing external playlist."); + } + + return entries; + } +}