From 4738428c2c205f42200386ae09b44b9ec07b9144 Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Sat, 27 Jul 2013 14:33:25 -0700 Subject: Move subsonic-android to root --- .../subsonic/service/TranscodingService.java | 530 --------------------- 1 file changed, 530 deletions(-) delete mode 100644 subsonic-main/src/main/java/net/sourceforge/subsonic/service/TranscodingService.java (limited to 'subsonic-main/src/main/java/net/sourceforge/subsonic/service/TranscodingService.java') diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/TranscodingService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/TranscodingService.java deleted file mode 100644 index 2c8b9c5e..00000000 --- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/TranscodingService.java +++ /dev/null @@ -1,530 +0,0 @@ -/* - This file is part of Subsonic. - - Subsonic 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. - - Subsonic 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 Subsonic. If not, see . - - Copyright 2009 (C) Sindre Mehus - */ -package net.sourceforge.subsonic.service; - -import net.sourceforge.subsonic.Logger; -import net.sourceforge.subsonic.controller.VideoPlayerController; -import net.sourceforge.subsonic.dao.TranscodingDao; -import net.sourceforge.subsonic.domain.MediaFile; -import net.sourceforge.subsonic.domain.Player; -import net.sourceforge.subsonic.domain.TranscodeScheme; -import net.sourceforge.subsonic.domain.Transcoding; -import net.sourceforge.subsonic.domain.UserSettings; -import net.sourceforge.subsonic.domain.VideoTranscodingSettings; -import net.sourceforge.subsonic.io.TranscodeInputStream; -import net.sourceforge.subsonic.util.StringUtil; -import net.sourceforge.subsonic.util.Util; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.io.filefilter.PrefixFileFilter; -import org.apache.commons.lang.StringUtils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.LinkedList; -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 - * also called downsampling. - * - * @author Sindre Mehus - * @see TranscodeInputStream - */ -public class TranscodingService { - - private static final Logger LOG = Logger.getLogger(TranscodingService.class); - - private TranscodingDao transcodingDao; - private SettingsService settingsService; - private PlayerService playerService; - - /** - * Returns all transcodings. - * - * @return Possibly empty list of all transcodings. - */ - public List getAllTranscodings() { - return transcodingDao.getAllTranscodings(); - } - - /** - * Returns all active transcodings for the given player. Only enabled transcodings are returned. - * - * @param player The player. - * @return All active transcodings for the player. - */ - public List getTranscodingsForPlayer(Player player) { - return transcodingDao.getTranscodingsForPlayer(player.getId()); - } - - /** - * Sets the list of active transcodings for the given player. - * - * @param player The player. - * @param transcodingIds ID's of the active transcodings. - */ - public void setTranscodingsForPlayer(Player player, int[] transcodingIds) { - transcodingDao.setTranscodingsForPlayer(player.getId(), transcodingIds); - } - - /** - * Sets the list of active transcodings for the given player. - * - * @param player The player. - * @param transcodings The active transcodings. - */ - public void setTranscodingsForPlayer(Player player, List transcodings) { - int[] transcodingIds = new int[transcodings.size()]; - for (int i = 0; i < transcodingIds.length; i++) { - transcodingIds[i] = transcodings.get(i).getId(); - } - setTranscodingsForPlayer(player, transcodingIds); - } - - - /** - * Creates a new transcoding. - * - * @param transcoding The transcoding to create. - */ - public void createTranscoding(Transcoding transcoding) { - transcodingDao.createTranscoding(transcoding); - - // Activate this transcoding for all players? - if (transcoding.isDefaultActive()) { - for (Player player : playerService.getAllPlayers()) { - List transcodings = getTranscodingsForPlayer(player); - transcodings.add(transcoding); - setTranscodingsForPlayer(player, transcodings); - } - } - } - - /** - * Deletes the transcoding with the given ID. - * - * @param id The transcoding ID. - */ - public void deleteTranscoding(Integer id) { - transcodingDao.deleteTranscoding(id); - } - - /** - * Updates the given transcoding. - * - * @param transcoding The transcoding to update. - */ - public void updateTranscoding(Transcoding transcoding) { - transcodingDao.updateTranscoding(transcoding); - } - - /** - * Returns whether transcoding is required for the given media file and player combination. - * - * @param mediaFile The media file. - * @param player The player. - * @return Whether transcoding will be performed if invoking the - * {@link #getTranscodedInputStream} method with the same arguments. - */ - public boolean isTranscodingRequired(MediaFile mediaFile, Player player) { - return getTranscoding(mediaFile, player, null) != null; - } - - /** - * Returns the suffix for the given player and media file, taking transcodings into account. - * - * @param player The player in question. - * @param file The media file. - * @param preferredTargetFormat Used to select among multiple applicable transcodings. May be {@code null}. - * @return The file suffix, e.g., "mp3". - */ - public String getSuffix(Player player, MediaFile file, String preferredTargetFormat) { - Transcoding transcoding = getTranscoding(file, player, preferredTargetFormat); - return transcoding != null ? transcoding.getTargetFormat() : file.getFormat(); - } - - /** - * Creates parameters for a possibly transcoded or downsampled 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. - *

- * Otherwise, a normal input stream to the original file is returned. - * - * @param mediaFile The media file. - * @param player The player. - * @param maxBitRate Overrides the per-player and per-user bitrate limit. May be {@code null}. - * @param preferredTargetFormat Used to select among multiple applicable transcodings. May be {@code null}. - * @param videoTranscodingSettings Parameters used when transcoding video. May be {@code null}. - * @return Parameters to be used in the {@link #getTranscodedInputStream} method. - */ - public Parameters getParameters(MediaFile mediaFile, Player player, Integer maxBitRate, String preferredTargetFormat, - VideoTranscodingSettings videoTranscodingSettings) { - - Parameters parameters = new Parameters(mediaFile, videoTranscodingSettings); - - TranscodeScheme transcodeScheme = getTranscodeScheme(player); - if (maxBitRate == null && transcodeScheme != TranscodeScheme.OFF) { - maxBitRate = transcodeScheme.getMaxBitRate(); - } - - Transcoding transcoding = getTranscoding(mediaFile, player, preferredTargetFormat); - if (transcoding != null) { - parameters.setTranscoding(transcoding); - if (maxBitRate == null) { - maxBitRate = mediaFile.isVideo() ? VideoPlayerController.DEFAULT_BIT_RATE : 128; - } - } else if (maxBitRate != null) { - boolean supported = isDownsamplingSupported(mediaFile); - Integer bitRate = mediaFile.getBitRate(); - if (supported && bitRate != null && bitRate > maxBitRate) { - parameters.setDownsample(true); - } - } - - parameters.setMaxBitRate(maxBitRate); - return parameters; - } - - /** - * Returns a possibly transcoded or downsampled input stream for the given music 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. - *

- * Otherwise, a normal input stream to the original file is returned. - * - * @param parameters As returned by {@link #getParameters}. - * @return A possible transcoded or downsampled input stream. - * @throws IOException If an I/O error occurs. - */ - public InputStream getTranscodedInputStream(Parameters parameters) throws IOException { - try { - - if (parameters.getTranscoding() != null) { - return createTranscodedInputStream(parameters); - } - - if (parameters.downsample) { - return createDownsampledInputStream(parameters); - } - - } catch (Exception x) { - LOG.warn("Failed to transcode " + parameters.getMediaFile() + ". Using original.", x); - } - - return new FileInputStream(parameters.getMediaFile().getFile()); - } - - - /** - * Returns the strictest transcoding scheme defined for the player and the user. - */ - private TranscodeScheme getTranscodeScheme(Player player) { - String username = player.getUsername(); - if (username != null) { - UserSettings userSettings = settingsService.getUserSettings(username); - return player.getTranscodeScheme().strictest(userSettings.getTranscodeScheme()); - } - - return player.getTranscodeScheme(); - } - - /** - * Returns an input stream by applying the given transcoding to the given music file. - * - * @param parameters Transcoding parameters. - * @return The transcoded input stream. - * @throws IOException If an I/O error occurs. - */ - private InputStream createTranscodedInputStream(Parameters parameters) - throws IOException { - - Transcoding transcoding = parameters.getTranscoding(); - Integer maxBitRate = parameters.getMaxBitRate(); - VideoTranscodingSettings videoTranscodingSettings = parameters.getVideoTranscodingSettings(); - MediaFile mediaFile = parameters.getMediaFile(); - - TranscodeInputStream in = createTranscodeInputStream(transcoding.getStep1(), maxBitRate, videoTranscodingSettings, mediaFile, null); - - if (transcoding.getStep2() != null) { - in = createTranscodeInputStream(transcoding.getStep2(), maxBitRate, videoTranscodingSettings, mediaFile, in); - } - - if (transcoding.getStep3() != null) { - in = createTranscodeInputStream(transcoding.getStep3(), maxBitRate, videoTranscodingSettings, mediaFile, in); - } - - return in; - } - - /** - * Creates a transcoded input stream by interpreting the given command line string. - * This includes the following: - *

    - *
  • Splitting the command line string to an array.
  • - *
  • Replacing occurrences of "%s" with the path of the given music file.
  • - *
  • Replacing occurrences of "%t" with the title of the given music file.
  • - *
  • Replacing occurrences of "%l" with the album name of the given music file.
  • - *
  • Replacing occurrences of "%a" with the artist name of the given music file.
  • - *
  • Replacing occurrcences of "%b" with the max bitrate.
  • - *
  • Replacing occurrcences of "%o" with the video time offset (used for scrubbing).
  • - *
  • Replacing occurrcences of "%w" with the video image width.
  • - *
  • Replacing occurrcences of "%h" with the video image height.
  • - *
  • Prepending the path of the transcoder directory if the transcoder is found there.
  • - *
- * - * @param command The command line string. - * @param maxBitRate The maximum bitrate to use. May not be {@code null}. - * @param videoTranscodingSettings Parameters used when transcoding video. May be {@code null}. - * @param mediaFile The media file. - * @param in Data to feed to the process. May be {@code null}. @return The newly created input stream. - */ - private TranscodeInputStream createTranscodeInputStream(String command, Integer maxBitRate, - VideoTranscodingSettings videoTranscodingSettings, MediaFile mediaFile, InputStream in) throws IOException { - - String title = mediaFile.getTitle(); - String album = mediaFile.getAlbumName(); - String artist = mediaFile.getArtist(); - - if (title == null) { - title = "Unknown Song"; - } - if (album == null) { - title = "Unknown Album"; - } - if (artist == null) { - title = "Unknown Artist"; - } - - List result = new LinkedList(Arrays.asList(StringUtil.split(command))); - result.set(0, getTranscodeDirectory().getPath() + File.separatorChar + result.get(0)); - - File tmpFile = null; - - for (int i = 1; i < result.size(); i++) { - String cmd = result.get(i); - if (cmd.contains("%b")) { - cmd = cmd.replace("%b", String.valueOf(maxBitRate)); - } - if (cmd.contains("%t")) { - cmd = cmd.replace("%t", title); - } - if (cmd.contains("%l")) { - cmd = cmd.replace("%l", album); - } - if (cmd.contains("%a")) { - cmd = cmd.replace("%a", artist); - } - if (cmd.contains("%o") && videoTranscodingSettings != null) { - cmd = cmd.replace("%o", String.valueOf(videoTranscodingSettings.getTimeOffset())); - } - if (cmd.contains("%w") && videoTranscodingSettings != null) { - cmd = cmd.replace("%w", String.valueOf(videoTranscodingSettings.getWidth())); - } - if (cmd.contains("%h") && videoTranscodingSettings != null) { - cmd = cmd.replace("%h", String.valueOf(videoTranscodingSettings.getHeight())); - } - if (cmd.contains("%s")) { - - // Work-around for filename character encoding problem on Windows. - // Create temporary file, and feed this to the transcoder. - String path = mediaFile.getFile().getAbsolutePath(); - if (Util.isWindows() && !mediaFile.isVideo() && !StringUtils.isAsciiPrintable(path)) { - tmpFile = File.createTempFile("subsonic", "." + FilenameUtils.getExtension(path)); - tmpFile.deleteOnExit(); - FileUtils.copyFile(new File(path), tmpFile); - LOG.debug("Created tmp file: " + tmpFile); - cmd = cmd.replace("%s", tmpFile.getPath()); - } else { - cmd = cmd.replace("%s", path); - } - } - - result.set(i, cmd); - } - return new TranscodeInputStream(new ProcessBuilder(result), in, tmpFile); - } - - /** - * Returns an applicable transcoding for the given file and player, or null if no - * transcoding should be done. - */ - private Transcoding getTranscoding(MediaFile mediaFile, Player player, String preferredTargetFormat) { - - List applicableTranscodings = new LinkedList(); - String suffix = mediaFile.getFormat(); - - for (Transcoding transcoding : getTranscodingsForPlayer(player)) { - for (String sourceFormat : transcoding.getSourceFormatsAsArray()) { - if (sourceFormat.equalsIgnoreCase(suffix)) { - if (isTranscodingInstalled(transcoding)) { - applicableTranscodings.add(transcoding); - } - } - } - } - - if (applicableTranscodings.isEmpty()) { - return null; - } - - for (Transcoding transcoding : applicableTranscodings) { - if (transcoding.getTargetFormat().equalsIgnoreCase(preferredTargetFormat)) { - return transcoding; - } - } - - return applicableTranscodings.get(0); - } - - /** - * Returns a downsampled input stream to the music file. - * - * @param parameters Downsample parameters. - * @throws IOException If an I/O error occurs. - */ - 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 LAME 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; - } - } - - String commandLine = settingsService.getDownsamplingCommand(); - return isTranscodingStepInstalled(commandLine); - } - - private boolean isTranscodingInstalled(Transcoding transcoding) { - return isTranscodingStepInstalled(transcoding.getStep1()) && - isTranscodingStepInstalled(transcoding.getStep2()) && - isTranscodingStepInstalled(transcoding.getStep3()); - } - - private boolean isTranscodingStepInstalled(String step) { - if (StringUtils.isEmpty(step)) { - return true; - } - String executable = StringUtil.split(step)[0]; - PrefixFileFilter filter = new PrefixFileFilter(executable); - String[] matches = getTranscodeDirectory().list(filter); - return matches != null && matches.length > 0; - } - - /** - * Returns the directory in which all transcoders are installed. - */ - public File getTranscodeDirectory() { - File dir = new File(SettingsService.getSubsonicHome(), "transcode"); - if (!dir.exists()) { - boolean ok = dir.mkdir(); - if (ok) { - LOG.info("Created directory " + dir); - } else { - LOG.warn("Failed to create directory " + dir); - } - } - return dir; - } - - public void setTranscodingDao(TranscodingDao transcodingDao) { - this.transcodingDao = transcodingDao; - } - - public void setSettingsService(SettingsService settingsService) { - this.settingsService = settingsService; - } - - public void setPlayerService(PlayerService playerService) { - this.playerService = playerService; - } - - public static class Parameters { - private boolean downsample; - private final MediaFile mediaFile; - private final VideoTranscodingSettings videoTranscodingSettings; - private Integer maxBitRate; - private Transcoding transcoding; - - public Parameters(MediaFile mediaFile, VideoTranscodingSettings videoTranscodingSettings) { - this.mediaFile = mediaFile; - this.videoTranscodingSettings = videoTranscodingSettings; - } - - public void setMaxBitRate(Integer maxBitRate) { - this.maxBitRate = maxBitRate; - } - - public boolean isDownsample() { - return downsample; - } - - public void setDownsample(boolean downsample) { - this.downsample = downsample; - } - - public boolean isTranscode() { - return transcoding != null; - } - - public void setTranscoding(Transcoding transcoding) { - this.transcoding = transcoding; - } - - public Transcoding getTranscoding() { - return transcoding; - } - - public MediaFile getMediaFile() { - return mediaFile; - } - - public Integer getMaxBitRate() { - return maxBitRate; - } - - public VideoTranscodingSettings getVideoTranscodingSettings() { - return videoTranscodingSettings; - } - } -} -- cgit v1.2.3