diff --git a/airsonic-main/src/main/java/org/airsonic/player/controller/PlayerSettingsController.java b/airsonic-main/src/main/java/org/airsonic/player/controller/PlayerSettingsController.java index 852749cb..499b5234 100644 --- a/airsonic-main/src/main/java/org/airsonic/player/controller/PlayerSettingsController.java +++ b/airsonic-main/src/main/java/org/airsonic/player/controller/PlayerSettingsController.java @@ -99,7 +99,7 @@ public class PlayerSettingsController { command.setActiveTranscodingIds(activeTranscodingIds); } - command.setTranscodingSupported(transcodingService.isDownsamplingSupported(null)); + command.setTranscodingSupported(transcodingService.isTranscodingSupported(null)); command.setTranscodeDirectory(transcodingService.getTranscodeDirectory().getPath()); command.setTranscodeSchemes(TranscodeScheme.values()); command.setTechnologies(PlayerTechnology.values()); diff --git a/airsonic-main/src/main/java/org/airsonic/player/controller/TranscodingSettingsController.java b/airsonic-main/src/main/java/org/airsonic/player/controller/TranscodingSettingsController.java index 671e7cbf..b20a96a0 100644 --- a/airsonic-main/src/main/java/org/airsonic/player/controller/TranscodingSettingsController.java +++ b/airsonic-main/src/main/java/org/airsonic/player/controller/TranscodingSettingsController.java @@ -57,7 +57,6 @@ public class TranscodingSettingsController { map.put("transcodings", transcodingService.getAllTranscodings()); map.put("transcodeDirectory", transcodingService.getTranscodeDirectory()); - map.put("downsampleCommand", settingsService.getDownsamplingCommand()); map.put("hlsCommand", settingsService.getHlsCommand()); map.put("brand", settingsService.getBrand()); @@ -133,7 +132,6 @@ public class TranscodingSettingsController { return error; } } - settingsService.setDownsamplingCommand(StringUtils.trim(request.getParameter("downsampleCommand"))); settingsService.setHlsCommand(StringUtils.trim(request.getParameter("hlsCommand"))); settingsService.save(); return null; diff --git a/airsonic-main/src/main/java/org/airsonic/player/controller/UserSettingsController.java b/airsonic-main/src/main/java/org/airsonic/player/controller/UserSettingsController.java index 52f06124..0c49fdd5 100644 --- a/airsonic-main/src/main/java/org/airsonic/player/controller/UserSettingsController.java +++ b/airsonic-main/src/main/java/org/airsonic/player/controller/UserSettingsController.java @@ -96,7 +96,7 @@ public class UserSettingsController { command = (UserSettingsCommand) model.asMap().get("command"); } command.setUsers(securityService.getAllUsers()); - command.setTranscodingSupported(transcodingService.isDownsamplingSupported(null)); + command.setTranscodingSupported(transcodingService.isTranscodingSupported(null)); command.setTranscodeDirectory(transcodingService.getTranscodeDirectory().getPath()); command.setTranscodeSchemes(TranscodeScheme.values()); command.setLdapEnabled(settingsService.isLdapEnabled()); 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 5189ab1f..0dc669ab 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 @@ -84,7 +84,6 @@ public class SettingsService { private static final String KEY_PODCAST_EPISODE_DOWNLOAD_COUNT = "PodcastEpisodeDownloadCount"; private static final String KEY_DOWNLOAD_BITRATE_LIMIT = "DownloadBitrateLimit"; private static final String KEY_UPLOAD_BITRATE_LIMIT = "UploadBitrateLimit"; - private static final String KEY_DOWNSAMPLING_COMMAND = "DownsamplingCommand4"; private static final String KEY_HLS_COMMAND = "HlsCommand3"; private static final String KEY_JUKEBOX_COMMAND = "JukeboxCommand2"; private static final String KEY_VIDEO_IMAGE_COMMAND = "VideoImageCommand"; @@ -168,7 +167,6 @@ public class SettingsService { private static final int DEFAULT_PODCAST_EPISODE_DOWNLOAD_COUNT = 1; private static final long DEFAULT_DOWNLOAD_BITRATE_LIMIT = 0; private static final long DEFAULT_UPLOAD_BITRATE_LIMIT = 0; - private static final String DEFAULT_DOWNSAMPLING_COMMAND = "ffmpeg -i %s -map 0:0 -b:a %bk -v 0 -f mp3 -"; private static final String DEFAULT_HLS_COMMAND = "ffmpeg -ss %o -t %d -i %s -async 1 -b:v %bk -s %wx%h -ar 44100 -ac 2 -v 0 -f mpegts -c:v libx264 -preset superfast -c:a libmp3lame -threads 0 -"; private static final String DEFAULT_JUKEBOX_COMMAND = "ffmpeg -ss %o -i %s -map 0:0 -v 0 -ar 44100 -ac 2 -f s16be -"; private static final String DEFAULT_VIDEO_IMAGE_COMMAND = "ffmpeg -r 1 -ss %o -t 1 -i %s -s %wx%h -v 0 -f mjpeg -"; @@ -216,8 +214,8 @@ public class SettingsService { // Array of obsolete keys. Used to clean property file. private static final List OBSOLETE_KEYS = Arrays.asList("PortForwardingPublicPort", "PortForwardingLocalPort", - "DownsamplingCommand", "DownsamplingCommand2", "DownsamplingCommand3", "AutoCoverBatch", "MusicMask", - "VideoMask", "CoverArtMask, HlsCommand", "HlsCommand2", "JukeboxCommand", + "DownsamplingCommand", "DownsamplingCommand2", "DownsamplingCommand3", "DownsamplingCommand4", + "AutoCoverBatch", "MusicMask", "VideoMask", "CoverArtMask, HlsCommand", "HlsCommand2", "JukeboxCommand", "CoverArtFileTypes", "UrlRedirectCustomHost", "CoverArtLimit", "StreamPort", "PortForwardingEnabled", "RewriteUrl", "UrlRedirectCustomUrl", "UrlRedirectContextPath", "UrlRedirectFrom", "UrlRedirectionEnabled", "UrlRedirectType", "Port", "HttpsPort", @@ -638,14 +636,6 @@ public class SettingsService { setLong(KEY_UPLOAD_BITRATE_LIMIT, limit); } - public String getDownsamplingCommand() { - return getProperty(KEY_DOWNSAMPLING_COMMAND, DEFAULT_DOWNSAMPLING_COMMAND); - } - - public void setDownsamplingCommand(String command) { - setProperty(KEY_DOWNSAMPLING_COMMAND, command); - } - public String getHlsCommand() { return getProperty(KEY_HLS_COMMAND, DEFAULT_HLS_COMMAND); } diff --git a/airsonic-main/src/main/java/org/airsonic/player/service/TranscodingService.java b/airsonic-main/src/main/java/org/airsonic/player/service/TranscodingService.java index 61b8c0fe..59adff71 100644 --- a/airsonic-main/src/main/java/org/airsonic/player/service/TranscodingService.java +++ b/airsonic-main/src/main/java/org/airsonic/player/service/TranscodingService.java @@ -45,7 +45,7 @@ import java.util.List; /** * Provides services for transcoding media. Transcoding is the process of - * converting an audio stream to a different format and/or bit rate. The latter is + * converting a media file/stream to a different format and/or bit rate. The latter is * also called downsampling. * * @author Sindre Mehus @@ -81,6 +81,7 @@ public class TranscodingService { * @return All active transcodings for the player. */ public List getTranscodingsForPlayer(Player player) { + // FIXME - This should probably check isTranscodingInstalled() return transcodingDao.getTranscodingsForPlayer(player.getId()); } @@ -173,13 +174,10 @@ public class TranscodingService { } /** - * Creates parameters for a possibly transcoded or downsampled input stream for the given media file and player combination. + * Creates parameters for a possibly transcoded input stream for the given media file and player combination. *

* A transcoding is applied if it is applicable for the format of the given file, and is activated for the - * given player. - *

- * If no transcoding is applicable, the file may still be downsampled, given that the player is configured - * with a bit rate limit which is higher than the actual bit rate of the file. + * given player, and either the desired format or bitrate needs changing. *

* Otherwise, a normal input stream to the original file is returned. * @@ -232,10 +230,6 @@ public class TranscodingService { if (transcoding != null && ((maxBitRate != 0 && (bitRate == 0 || bitRate > maxBitRate)) || (preferredTargetFormat != null && ! mediaFile.getFormat().equalsIgnoreCase(preferredTargetFormat)))) { parameters.setTranscoding(transcoding); - } else if (isDownsamplingSupported(mediaFile)) { - if (bitRate > maxBitRate) { - parameters.setDownsample(true); - } } parameters.setMaxBitRate(maxBitRate == 0 ? null : maxBitRate); @@ -266,10 +260,6 @@ public class TranscodingService { return createTranscodedInputStream(parameters); } - if (parameters.downsample) { - return createDownsampledInputStream(parameters); - } - } catch (IOException x) { LOG.warn("Transcoder failed: {}. Using original: " + parameters.getMediaFile().getFile().getAbsolutePath(), x.toString()); } catch (Exception x) { @@ -467,33 +457,27 @@ public class TranscodingService { } /** - * Returns a downsampled input stream to the music file. + * Returns whether transcoding is supported (i.e. whether ffmpeg is installed or not). * - * @param parameters Downsample parameters. - * @throws IOException If an I/O error occurs. + * @param mediaFile If not null, returns whether transcoding is supported for this file. + * @return Whether transcoding is supported. */ - private InputStream createDownsampledInputStream(Parameters parameters) throws IOException { - String command = settingsService.getDownsamplingCommand(); - return createTranscodeInputStream(command, parameters.getMaxBitRate(), parameters.getVideoTranscodingSettings(), - parameters.getMediaFile(), null); - } - - /** - * Returns whether downsampling is supported (i.e., whether ffmpeg is installed or not.) - * - * @param mediaFile If not null, returns whether downsampling is supported for this file. - * @return Whether downsampling is supported. - */ - public boolean isDownsamplingSupported(MediaFile mediaFile) { - if (mediaFile != null) { - boolean isMp3 = "mp3".equalsIgnoreCase(mediaFile.getFormat()); - if (!isMp3) { - return false; + public boolean isTranscodingSupported(MediaFile mediaFile) { + List transcodings = getAllTranscodings(); + for (Transcoding transcoding : transcodings) { + if (! isTranscodingInstalled(transcoding)) { + continue; + } + if (mediaFile == null) { + return true; + } + for (String sourceFormat : transcoding.getSourceFormatsAsArray()) { + if (sourceFormat.equalsIgnoreCase(mediaFile.getFormat())) { + return true; + } } } - - String commandLine = settingsService.getDownsamplingCommand(); - return isTranscodingStepInstalled(commandLine); + return false; } private boolean isTranscodingInstalled(Transcoding transcoding) { @@ -518,7 +502,7 @@ public class TranscodingService { private Long getExpectedLength(Parameters parameters) { MediaFile file = parameters.getMediaFile(); - if (!parameters.isDownsample() && !parameters.isTranscode()) { + if (!parameters.isTranscode()) { return file.getFileSize(); } Integer duration = file.getDurationSeconds(); @@ -543,10 +527,8 @@ public class TranscodingService { List steps = Arrays.asList(); if (transcoding != null) { steps = Arrays.asList(transcoding.getStep3(), transcoding.getStep2(), transcoding.getStep1()); - } else if (parameters.isDownsample()) { - steps = Arrays.asList(settingsService.getDownsamplingCommand()); } else { - return true; // neither transcoding nor downsampling + return true; // not transcoding } // Verify that were able to predict the length @@ -609,14 +591,6 @@ public class TranscodingService { this.maxBitRate = maxBitRate; } - public boolean isDownsample() { - return downsample; - } - - public void setDownsample(boolean downsample) { - this.downsample = downsample; - } - public boolean isTranscode() { return transcoding != null; } diff --git a/airsonic-main/src/main/resources/liquibase/10.3/add-mp3-to-transcode.xml b/airsonic-main/src/main/resources/liquibase/10.3/add-mp3-to-transcode.xml new file mode 100644 index 00000000..8a4cb3bb --- /dev/null +++ b/airsonic-main/src/main/resources/liquibase/10.3/add-mp3-to-transcode.xml @@ -0,0 +1,16 @@ + + + + + + + + source_formats = 'ogg oga aac m4a flac wav wma aif aiff ape mpc shn' + + + + + diff --git a/airsonic-main/src/main/resources/liquibase/10.3/changelog.xml b/airsonic-main/src/main/resources/liquibase/10.3/changelog.xml new file mode 100644 index 00000000..21e9d8a5 --- /dev/null +++ b/airsonic-main/src/main/resources/liquibase/10.3/changelog.xml @@ -0,0 +1,6 @@ + + + diff --git a/airsonic-main/src/main/resources/liquibase/db-changelog.xml b/airsonic-main/src/main/resources/liquibase/db-changelog.xml index cddd1401..bc49b021 100644 --- a/airsonic-main/src/main/resources/liquibase/db-changelog.xml +++ b/airsonic-main/src/main/resources/liquibase/db-changelog.xml @@ -13,5 +13,6 @@ + diff --git a/airsonic-main/src/main/webapp/WEB-INF/jsp/transcodingSettings.jsp b/airsonic-main/src/main/webapp/WEB-INF/jsp/transcodingSettings.jsp index 14a8462b..0257e9f0 100644 --- a/airsonic-main/src/main/webapp/WEB-INF/jsp/transcodingSettings.jsp +++ b/airsonic-main/src/main/webapp/WEB-INF/jsp/transcodingSettings.jsp @@ -57,15 +57,6 @@ - - - -
- - - - -