diff options
author | Scott Jackson <daneren2005@gmail.com> | 2013-07-27 14:33:25 -0700 |
---|---|---|
committer | Scott Jackson <daneren2005@gmail.com> | 2013-07-27 14:33:38 -0700 |
commit | 4738428c2c205f42200386ae09b44b9ec07b9144 (patch) | |
tree | a6402978fe1b4655f90c3c8a181f4d246fbc5e89 /subsonic-main/src/main/java/net/sourceforge/subsonic/io | |
parent | 82ec8315f777c319f2372540098e21111019d629 (diff) | |
download | dsub-4738428c2c205f42200386ae09b44b9ec07b9144.tar.gz dsub-4738428c2c205f42200386ae09b44b9ec07b9144.tar.bz2 dsub-4738428c2c205f42200386ae09b44b9ec07b9144.zip |
Move subsonic-android to root
Diffstat (limited to 'subsonic-main/src/main/java/net/sourceforge/subsonic/io')
5 files changed, 0 insertions, 696 deletions
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/InputStreamReaderThread.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/io/InputStreamReaderThread.java deleted file mode 100644 index 1019f73a..00000000 --- a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/InputStreamReaderThread.java +++ /dev/null @@ -1,63 +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 <http://www.gnu.org/licenses/>. - - Copyright 2009 (C) Sindre Mehus - */ -package net.sourceforge.subsonic.io; - -import net.sourceforge.subsonic.*; -import org.apache.commons.io.*; - -import java.io.*; - -/** - * Utility class which reads everything from an input stream and optionally logs it. - * - * @see TranscodeInputStream - * @author Sindre Mehus - */ -public class InputStreamReaderThread extends Thread { - - private static final Logger LOG = Logger.getLogger(InputStreamReaderThread.class); - - private InputStream input; - private String name; - private boolean log; - - public InputStreamReaderThread(InputStream input, String name, boolean log) { - super(name + " InputStreamLogger"); - this.input = input; - this.name = name; - this.log = log; - } - - public void run() { - BufferedReader reader = null; - try { - reader = new BufferedReader(new InputStreamReader(input)); - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - if (log) { - LOG.debug('(' + name + ") " + line); - } - } - } catch (IOException x) { - // Intentionally ignored. - } finally { - IOUtils.closeQuietly(reader); - IOUtils.closeQuietly(input); - } - } -} diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/PlayQueueInputStream.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/io/PlayQueueInputStream.java deleted file mode 100644 index 3be7fdd9..00000000 --- a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/PlayQueueInputStream.java +++ /dev/null @@ -1,154 +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 <http://www.gnu.org/licenses/>. - - Copyright 2009 (C) Sindre Mehus - */ -package net.sourceforge.subsonic.io; - -import net.sourceforge.subsonic.Logger; -import net.sourceforge.subsonic.domain.MediaFile; -import net.sourceforge.subsonic.domain.VideoTranscodingSettings; -import net.sourceforge.subsonic.service.MediaFileService; -import net.sourceforge.subsonic.service.SearchService; -import net.sourceforge.subsonic.util.FileUtil; -import net.sourceforge.subsonic.domain.Player; -import net.sourceforge.subsonic.domain.PlayQueue; -import net.sourceforge.subsonic.domain.TransferStatus; -import net.sourceforge.subsonic.service.AudioScrobblerService; -import net.sourceforge.subsonic.service.TranscodingService; - -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -/** - * Implementation of {@link InputStream} which reads from a {@link net.sourceforge.subsonic.domain.PlayQueue}. - * - * @author Sindre Mehus - */ -public class PlayQueueInputStream extends InputStream { - - private static final Logger LOG = Logger.getLogger(PlayQueueInputStream.class); - - private final Player player; - private final TransferStatus status; - private final Integer maxBitRate; - private final String preferredTargetFormat; - private final VideoTranscodingSettings videoTranscodingSettings; - private final TranscodingService transcodingService; - private final AudioScrobblerService audioScrobblerService; - private final MediaFileService mediaFileService; - private MediaFile currentFile; - private InputStream currentInputStream; - private SearchService searchService; - - public PlayQueueInputStream(Player player, TransferStatus status, Integer maxBitRate, String preferredTargetFormat, - VideoTranscodingSettings videoTranscodingSettings, TranscodingService transcodingService, - AudioScrobblerService audioScrobblerService, MediaFileService mediaFileService, SearchService searchService) { - this.player = player; - this.status = status; - this.maxBitRate = maxBitRate; - this.preferredTargetFormat = preferredTargetFormat; - this.videoTranscodingSettings = videoTranscodingSettings; - this.transcodingService = transcodingService; - this.audioScrobblerService = audioScrobblerService; - this.mediaFileService = mediaFileService; - this.searchService = searchService; - } - - @Override - public int read() throws IOException { - byte[] b = new byte[1]; - int n = read(b); - return n == -1 ? -1 : b[0]; - } - - @Override - public int read(byte[] b) throws IOException { - return read(b, 0, b.length); - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - prepare(); - if (currentInputStream == null || player.getPlayQueue().getStatus() == PlayQueue.Status.STOPPED) { - return -1; - } - - int n = currentInputStream.read(b, off, len); - - // If end of song reached, skip to next song and call read() again. - if (n == -1) { - player.getPlayQueue().next(); - close(); - return read(b, off, len); - } else { - status.addBytesTransfered(n); - } - return n; - } - - private void prepare() throws IOException { - PlayQueue playQueue = player.getPlayQueue(); - - // If playlist is in auto-random mode, populate it with new random songs. - if (playQueue.getIndex() == -1 && playQueue.getRandomSearchCriteria() != null) { - populateRandomPlaylist(playQueue); - } - - MediaFile result; - synchronized (playQueue) { - result = playQueue.getCurrentFile(); - } - MediaFile file = result; - if (file == null) { - close(); - } else if (!file.equals(currentFile)) { - close(); - LOG.info(player.getUsername() + " listening to \"" + FileUtil.getShortPath(file.getFile()) + "\""); - mediaFileService.incrementPlayCount(file); - if (player.getClientId() == null) { // Don't scrobble REST players. - audioScrobblerService.register(file, player.getUsername(), false); - } - - TranscodingService.Parameters parameters = transcodingService.getParameters(file, player, maxBitRate, preferredTargetFormat, videoTranscodingSettings); - currentInputStream = transcodingService.getTranscodedInputStream(parameters); - currentFile = file; - status.setFile(currentFile.getFile()); - } - } - - private void populateRandomPlaylist(PlayQueue playQueue) throws IOException { - List<MediaFile> files = searchService.getRandomSongs(playQueue.getRandomSearchCriteria()); - playQueue.addFiles(false, files); - LOG.info("Recreated random playlist with " + playQueue.size() + " songs."); - } - - @Override - public void close() throws IOException { - try { - if (currentInputStream != null) { - currentInputStream.close(); - } - } finally { - if (player.getClientId() == null) { // Don't scrobble REST players. - audioScrobblerService.register(currentFile, player.getUsername(), true); - } - currentInputStream = null; - currentFile = null; - } - } -} diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/RangeOutputStream.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/io/RangeOutputStream.java deleted file mode 100644 index 25bc03d2..00000000 --- a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/RangeOutputStream.java +++ /dev/null @@ -1,150 +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 <http://www.gnu.org/licenses/>. - - Copyright 2009 (C) Sindre Mehus - */ -package net.sourceforge.subsonic.io; - -import org.apache.commons.lang.math.Range; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - - -/** - * Special output stream for grabbing only part of a passed stream. - * - * @author Sindre Mehus (based on code found on http://www.koders.com/ - */ -public class RangeOutputStream extends FilterOutputStream { - - /** - * The starting index. - */ - private long start; - - /** - * The ending index. - */ - private long end; - - /** - * The current position. - */ - protected long pos; - - /** - * Wraps the given output stream in a RangeOutputStream, using the values - * in the given range, unless the range is <code>null</code> in which case - * the original OutputStream is returned. - * - * @param out The output stream to wrap in a RangeOutputStream. - * @param range The range, may be <code>null</code>. - * @return The possibly wrapped output stream. - */ - public static OutputStream wrap(OutputStream out, Range range) { - if (range == null) { - return out; - } - return new RangeOutputStream(out, range.getMinimumLong(), range.getMaximumLong()); - } - - /** - * Creates the stream with the passed start and end. - * - * @param out The stream to write to. - * @param start The starting position. - * @param end The ending position. - */ - public RangeOutputStream(OutputStream out, long start, long end) { - super(out); - this.start = start; - this.end = end; - pos = 0; - } - - /** - * Writes the byte IF it is within the range, otherwise it only - * increments the position. - * - * @param b The byte to write. - * @throws IOException Thrown if there was a problem writing to the stream. - */ - @Override - public void write(int b) throws IOException { - if ((pos >= start) && (pos <= end)) { - super.write(b); - } - pos++; - } - - /** - * Writes the bytes IF it is within the range, otherwise it only - * increments the position. - * - * @param b The bytes to write. - * @param off The offset to start at. - * @param len The length to write. - * @throws IOException Thrown if there was a problem writing to the stream. - */ - @Override - public void write(byte[] b, int off, int len) throws IOException { - boolean allowWrite = false; - long newPos = pos + off, newOff = off, newLen = len; - - // Check to see if we are in the range - if (newPos <= end) { - if (newPos >= start) { - // We are so check to make sure we don't leave it - if (newPos + newLen > end) { - newLen = end - newPos; - } - - // Enable writing - allowWrite = true; - } - - // We aren't yet in the range, but if see if the proposed write - // would place us there - else if (newPos + newLen >= start) { - // It would so, update the offset - newOff += start - newPos; - - // New offset means, a new position, so update that too - newPos = newOff + pos; - newLen = len + (pos - newPos); - - // Make sure we don't go past the range - if (newPos + newLen > end) { - newLen = end - newPos; - } - - // Enable writting - allowWrite = true; - } - } - - // If we have enabled writing, do the write! - if (allowWrite) { - out.write(b, (int) newOff, (int) newLen); - } - - // Move the cursor along - pos += off + len; - } -} - diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/ShoutCastOutputStream.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/io/ShoutCastOutputStream.java deleted file mode 100644 index 9a8618c6..00000000 --- a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/ShoutCastOutputStream.java +++ /dev/null @@ -1,205 +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 <http://www.gnu.org/licenses/>. - - Copyright 2009 (C) Sindre Mehus - */ -package net.sourceforge.subsonic.io; - -import net.sourceforge.subsonic.Logger; -import net.sourceforge.subsonic.domain.MediaFile; -import net.sourceforge.subsonic.domain.PlayQueue; -import net.sourceforge.subsonic.service.SettingsService; -import org.apache.commons.lang.StringUtils; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; - -/** - * Implements SHOUTcast support by decorating an existing output stream. - * <p/> - * Based on protocol description found on - * <em>http://www.smackfu.com/stuff/programming/shoutcast.html</em> - * - * @author Sindre Mehus - */ -public class ShoutCastOutputStream extends OutputStream { - - private static final Logger LOG = Logger.getLogger(ShoutCastOutputStream.class); - - /** - * Number of bytes between each SHOUTcast metadata block. - */ - public static final int META_DATA_INTERVAL = 20480; - - /** - * The underlying output stream to decorate. - */ - private OutputStream out; - - /** - * What to write in the SHOUTcast metadata is fetched from the playlist. - */ - private PlayQueue playQueue; - - /** - * Keeps track of the number of bytes written (excluding meta-data). Between 0 and {@link #META_DATA_INTERVAL}. - */ - private int byteCount; - - /** - * The last stream title sent. - */ - private String previousStreamTitle; - - private SettingsService settingsService; - - /** - * Creates a new SHOUTcast-decorated stream for the given output stream. - * - * @param out The output stream to decorate. - * @param playQueue Meta-data is fetched from this playlist. - */ - public ShoutCastOutputStream(OutputStream out, PlayQueue playQueue, SettingsService settingsService) { - this.out = out; - this.playQueue = playQueue; - this.settingsService = settingsService; - } - - /** - * Writes the given byte array to the underlying stream, adding SHOUTcast meta-data as necessary. - */ - public void write(byte[] b, int off, int len) throws IOException { - - int bytesWritten = 0; - while (bytesWritten < len) { - - // 'n' is the number of bytes to write before the next potential meta-data block. - int n = Math.min(len - bytesWritten, ShoutCastOutputStream.META_DATA_INTERVAL - byteCount); - - out.write(b, off + bytesWritten, n); - bytesWritten += n; - byteCount += n; - - // Reached meta-data block? - if (byteCount % ShoutCastOutputStream.META_DATA_INTERVAL == 0) { - writeMetaData(); - byteCount = 0; - } - } - } - - /** - * Writes the given byte array to the underlying stream, adding SHOUTcast meta-data as necessary. - */ - public void write(byte[] b) throws IOException { - write(b, 0, b.length); - } - - /** - * Writes the given byte to the underlying stream, adding SHOUTcast meta-data as necessary. - */ - public void write(int b) throws IOException { - byte[] buf = new byte[]{(byte) b}; - write(buf); - } - - /** - * Flushes the underlying stream. - */ - public void flush() throws IOException { - out.flush(); - } - - /** - * Closes the underlying stream. - */ - public void close() throws IOException { - out.close(); - } - - private void writeMetaData() throws IOException { - String streamTitle = StringUtils.trimToEmpty(settingsService.getWelcomeTitle()); - - MediaFile result; - synchronized (playQueue) { - result = playQueue.getCurrentFile(); - } - MediaFile mediaFile = result; - if (mediaFile != null) { - streamTitle = mediaFile.getArtist() + " - " + mediaFile.getTitle(); - } - - byte[] bytes; - - if (streamTitle.equals(previousStreamTitle)) { - bytes = new byte[0]; - } else { - try { - previousStreamTitle = streamTitle; - bytes = createStreamTitle(streamTitle); - } catch (UnsupportedEncodingException x) { - LOG.warn("Failed to create SHOUTcast meta-data. Ignoring.", x); - bytes = new byte[0]; - } - } - - // Length in groups of 16 bytes. - int length = bytes.length / 16; - if (bytes.length % 16 > 0) { - length++; - } - - // Write the length as a single byte. - out.write(length); - - // Write the message. - out.write(bytes); - - // Write padding zero bytes. - int padding = length * 16 - bytes.length; - for (int i = 0; i < padding; i++) { - out.write(0); - } - } - - private byte[] createStreamTitle(String title) throws UnsupportedEncodingException { - // Remove any quotes from the title. - title = title.replaceAll("'", ""); - - // Convert non-ascii characters to similar ascii characters. - for (char[] chars : ShoutCastOutputStream.CHAR_MAP) { - title = title.replace(chars[0], chars[1]); - } - - title = "StreamTitle='" + title + "';"; - return title.getBytes("US-ASCII"); - } - - /** - * Maps from miscellaneous accented characters to similar-looking ASCII characters. - */ - private static final char[][] CHAR_MAP = { - {'\u00C0', 'A'}, {'\u00C1', 'A'}, {'\u00C2', 'A'}, {'\u00C3', 'A'}, {'\u00C4', 'A'}, {'\u00C5', 'A'}, {'\u00C6', 'A'}, - {'\u00C8', 'E'}, {'\u00C9', 'E'}, {'\u00CA', 'E'}, {'\u00CB', 'E'}, {'\u00CC', 'I'}, {'\u00CD', 'I'}, {'\u00CE', 'I'}, - {'\u00CF', 'I'}, {'\u00D2', 'O'}, {'\u00D3', 'O'}, {'\u00D4', 'O'}, {'\u00D5', 'O'}, {'\u00D6', 'O'}, {'\u00D9', 'U'}, - {'\u00DA', 'U'}, {'\u00DB', 'U'}, {'\u00DC', 'U'}, {'\u00DF', 'B'}, {'\u00E0', 'a'}, {'\u00E1', 'a'}, {'\u00E2', 'a'}, - {'\u00E3', 'a'}, {'\u00E4', 'a'}, {'\u00E5', 'a'}, {'\u00E6', 'a'}, {'\u00E7', 'c'}, {'\u00E8', 'e'}, {'\u00E9', 'e'}, - {'\u00EA', 'e'}, {'\u00EB', 'e'}, {'\u00EC', 'i'}, {'\u00ED', 'i'}, {'\u00EE', 'i'}, {'\u00EF', 'i'}, {'\u00F1', 'n'}, - {'\u00F2', 'o'}, {'\u00F3', 'o'}, {'\u00F4', 'o'}, {'\u00F5', 'o'}, {'\u00F6', 'o'}, {'\u00F8', 'o'}, {'\u00F9', 'u'}, - {'\u00FA', 'u'}, {'\u00FB', 'u'}, {'\u00FC', 'u'}, {'\u2013', '-'} - }; -} diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/TranscodeInputStream.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/io/TranscodeInputStream.java deleted file mode 100644 index b7a5e31e..00000000 --- a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/TranscodeInputStream.java +++ /dev/null @@ -1,124 +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 <http://www.gnu.org/licenses/>. - - Copyright 2009 (C) Sindre Mehus - */ -package net.sourceforge.subsonic.io; - -import net.sourceforge.subsonic.*; - -import org.apache.commons.io.*; - -import java.io.*; - -/** - * Subclass of {@link InputStream} which provides on-the-fly transcoding. - * Instances of <code>TranscodeInputStream</code> can be chained together, for instance to convert - * from OGG to WAV to MP3. - * - * @author Sindre Mehus - */ -public class TranscodeInputStream extends InputStream { - - private static final Logger LOG = Logger.getLogger(TranscodeInputStream.class); - - private InputStream processInputStream; - private OutputStream processOutputStream; - private Process process; - private final File tmpFile; - - /** - * Creates a transcoded input stream by executing an external process. If <code>in</code> is not null, - * data from it is copied to the command. - * - * @param processBuilder Used to create the external process. - * @param in Data to feed to the process. May be {@code null}. - * @param tmpFile Temporary file to delete when this stream is closed. May be {@code null}. - * @throws IOException If an I/O error occurs. - */ - public TranscodeInputStream(ProcessBuilder processBuilder, final InputStream in, File tmpFile) throws IOException { - this.tmpFile = tmpFile; - - StringBuffer buf = new StringBuffer("Starting transcoder: "); - for (String s : processBuilder.command()) { - buf.append('[').append(s).append("] "); - } - LOG.debug(buf); - - process = processBuilder.start(); - processOutputStream = process.getOutputStream(); - processInputStream = process.getInputStream(); - - // Must read stderr from the process, otherwise it may block. - final String name = processBuilder.command().get(0); - new InputStreamReaderThread(process.getErrorStream(), name, true).start(); - - // Copy data in a separate thread - if (in != null) { - new Thread(name + " TranscodedInputStream copy thread") { - public void run() { - try { - IOUtils.copy(in, processOutputStream); - } catch (IOException x) { - // Intentionally ignored. Will happen if the remote player closes the stream. - } finally { - IOUtils.closeQuietly(in); - IOUtils.closeQuietly(processOutputStream); - } - } - }.start(); - } - } - - /** - * @see InputStream#read() - */ - public int read() throws IOException { - return processInputStream.read(); - } - - /** - * @see InputStream#read(byte[]) - */ - public int read(byte[] b) throws IOException { - return processInputStream.read(b); - } - - /** - * @see InputStream#read(byte[], int, int) - */ - public int read(byte[] b, int off, int len) throws IOException { - return processInputStream.read(b, off, len); - } - - /** - * @see InputStream#close() - */ - public void close() throws IOException { - IOUtils.closeQuietly(processInputStream); - IOUtils.closeQuietly(processOutputStream); - - if (process != null) { - process.destroy(); - } - - if (tmpFile != null) { - if (!tmpFile.delete()) { - LOG.warn("Failed to delete tmp file: " + tmpFile); - } - } - } -} |