From d626463060da6033b799b45d0fdf171cde273759 Mon Sep 17 00:00:00 2001 From: Randomnicode Date: Wed, 30 Oct 2019 22:43:32 -0700 Subject: [PATCH] Fix DLNA port, and expose them in Docker Signed-off-by: Andrew DeMaria --- .../player/service/SettingsService.java | 6 +++ .../airsonic/player/service/UPnPService.java | 9 ++-- .../upnp/ApacheUpnpServiceConfiguration.java | 51 ------------------- install/docker/Dockerfile | 6 ++- install/docker/run.sh | 1 + 5 files changed, 18 insertions(+), 55 deletions(-) delete mode 100644 airsonic-main/src/main/java/org/airsonic/player/service/upnp/ApacheUpnpServiceConfiguration.java diff --git a/airsonic-main/src/main/java/org/airsonic/player/service/SettingsService.java b/airsonic-main/src/main/java/org/airsonic/player/service/SettingsService.java index ed7ec770..b4fb4564 100644 --- a/airsonic-main/src/main/java/org/airsonic/player/service/SettingsService.java +++ b/airsonic-main/src/main/java/org/airsonic/player/service/SettingsService.java @@ -209,6 +209,8 @@ public class SettingsService { private static final String DEFAULT_DATABASE_CONFIG_JNDI_NAME = null; private static final Integer DEFAULT_DATABASE_MYSQL_VARCHAR_MAXLENGTH = 512; private static final String DEFAULT_DATABASE_USERTABLE_QUOTE = null; + + private static final int DEFAULT_UPNP_PORT = 4041; // Array of obsolete keys. Used to clean property file. private static final List OBSOLETE_KEYS = Arrays.asList("PortForwardingPublicPort", "PortForwardingLocalPort", @@ -287,6 +289,10 @@ public class SettingsService { public static String getDefaultJDBCUrl() { return "jdbc:hsqldb:file:" + getAirsonicHome().getPath() + "/db/" + getFileSystemAppName(); } + + public static int getDefaultUPnpPort() { + return Optional.ofNullable(System.getProperty("UPNP_PORT")).map(x -> Integer.parseInt(x)).orElse(DEFAULT_UPNP_PORT); + } public static File getLogFile() { File airsonicHome = SettingsService.getAirsonicHome(); diff --git a/airsonic-main/src/main/java/org/airsonic/player/service/UPnPService.java b/airsonic-main/src/main/java/org/airsonic/player/service/UPnPService.java index 2c0cfbc6..827decd6 100644 --- a/airsonic-main/src/main/java/org/airsonic/player/service/UPnPService.java +++ b/airsonic-main/src/main/java/org/airsonic/player/service/UPnPService.java @@ -19,10 +19,10 @@ */ package org.airsonic.player.service; -import org.airsonic.player.service.upnp.ApacheUpnpServiceConfiguration; import org.airsonic.player.service.upnp.CustomContentDirectory; import org.airsonic.player.service.upnp.MSMediaReceiverRegistrarService; import org.airsonic.player.util.FileUtil; +import org.fourthline.cling.DefaultUpnpServiceConfiguration; import org.fourthline.cling.UpnpService; import org.fourthline.cling.UpnpServiceImpl; import org.fourthline.cling.binding.annotations.AnnotationLocalServiceBinder; @@ -61,10 +61,13 @@ public class UPnPService { @Autowired private SettingsService settingsService; + private UpnpService upnpService; + @Autowired @Qualifier("dispatchingContentDirectory") private CustomContentDirectory dispatchingContentDirectory; + private AtomicReference running = new AtomicReference<>(false); @PostConstruct @@ -112,14 +115,14 @@ public class UPnPService { try { LOG.info("Starting UPnP service..."); createService(); - LOG.info("Starting UPnP service - Done!"); + LOG.info("Successfully started UPnP service on port {}!", SettingsService.getDefaultUPnpPort()); } catch (Throwable x) { LOG.error("Failed to start UPnP service: " + x, x); } } private synchronized void createService() { - upnpService = new UpnpServiceImpl(new ApacheUpnpServiceConfiguration()); + upnpService = new UpnpServiceImpl(new DefaultUpnpServiceConfiguration(SettingsService.getDefaultUPnpPort())); // Asynch search for other devices (most importantly UPnP-enabled routers for port-mapping) upnpService.getControlPoint().search(); diff --git a/airsonic-main/src/main/java/org/airsonic/player/service/upnp/ApacheUpnpServiceConfiguration.java b/airsonic-main/src/main/java/org/airsonic/player/service/upnp/ApacheUpnpServiceConfiguration.java deleted file mode 100644 index 966c3c45..00000000 --- a/airsonic-main/src/main/java/org/airsonic/player/service/upnp/ApacheUpnpServiceConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - This file is part of Airsonic. - - Airsonic is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Airsonic is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Airsonic. If not, see . - - Copyright 2016 (C) Airsonic Authors - Based upon Subsonic, Copyright 2013 (C) Sindre Mehus - */ -package org.airsonic.player.service.upnp; - -import org.fourthline.cling.DefaultUpnpServiceConfiguration; -import org.fourthline.cling.transport.impl.apache.StreamClientConfigurationImpl; -import org.fourthline.cling.transport.impl.apache.StreamClientImpl; -import org.fourthline.cling.transport.impl.apache.StreamServerConfigurationImpl; -import org.fourthline.cling.transport.impl.apache.StreamServerImpl; -import org.fourthline.cling.transport.spi.NetworkAddressFactory; -import org.fourthline.cling.transport.spi.StreamClient; -import org.fourthline.cling.transport.spi.StreamServer; - -import java.util.concurrent.Executors; - -/** - * UPnP configuration which uses Apache HttpComponents. Needed to make UPnP work - * when deploying on Tomcat. - * - * @author Sindre Mehus - * @version $Id$ - */ -public class ApacheUpnpServiceConfiguration extends DefaultUpnpServiceConfiguration { - - @Override - public StreamClient createStreamClient() { - return new StreamClientImpl(new StreamClientConfigurationImpl(Executors.newCachedThreadPool())); - } - - @Override - public StreamServer createStreamServer(NetworkAddressFactory networkAddressFactory) { - return new StreamServerImpl(new StreamServerConfigurationImpl(networkAddressFactory.getStreamListenPort())); - } -} diff --git a/install/docker/Dockerfile b/install/docker/Dockerfile index 1bc78bff..25323170 100644 --- a/install/docker/Dockerfile +++ b/install/docker/Dockerfile @@ -3,7 +3,7 @@ FROM alpine:3.9 LABEL description="Airsonic is a free, web-based media streamer, providing ubiquitious access to your music." \ url="https://github.com/airsonic/airsonic" -ENV AIRSONIC_PORT=4040 AIRSONIC_DIR=/airsonic CONTEXT_PATH=/ +ENV AIRSONIC_PORT=4040 AIRSONIC_DIR=/airsonic CONTEXT_PATH=/ UPNP_PORT=4041 WORKDIR $AIRSONIC_DIR @@ -27,6 +27,10 @@ COPY target/dependency/airsonic-main.war airsonic.war EXPOSE $AIRSONIC_PORT +# Default DLNA/UPnP ports +EXPOSE $UPNP_PORT +EXPOSE 1900/udp + VOLUME $AIRSONIC_DIR/data $AIRSONIC_DIR/music $AIRSONIC_DIR/playlists $AIRSONIC_DIR/podcasts HEALTHCHECK --interval=15s --timeout=3s CMD wget -q http://localhost:"$AIRSONIC_PORT""$CONTEXT_PATH"rest/ping -O /dev/null || exit 1 diff --git a/install/docker/run.sh b/install/docker/run.sh index f1a7809c..4c7630ec 100755 --- a/install/docker/run.sh +++ b/install/docker/run.sh @@ -20,6 +20,7 @@ if [[ $# -lt 1 ]] || [[ ! "$1" == "java"* ]]; then -Dairsonic.defaultMusicFolder=$AIRSONIC_DIR/music \ -Dairsonic.defaultPodcastFolder=$AIRSONIC_DIR/podcasts \ -Dairsonic.defaultPlaylistFolder=$AIRSONIC_DIR/playlists \ + -DUPNP_PORT=$UPNP_PORT \ -Djava.awt.headless=true \ "${java_opts_array[@]}" \ -jar airsonic.war "$@"