Files
jlibsound/src/main/java/old/Converter.java

188 lines
6.3 KiB
Java

package old;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.BitstreamException;
import sound.util.Utils;
import base.exception.worker.ActivateException;
import base.exception.worker.DeactivateException;
import base.work.Work;
import com.Ostermiller.util.CircularByteBuffer;
public class Converter extends Work {
public static final String COMMAND = "lame --mp3input --cbr %s - - --quiet";
public static final int BYTES = 4096; // bytes
public static final int BUFFER = 30000; // milliseconds
public static final int BUFFERING = 1000; // milliseconds
protected int targetRate;
protected int rate;
protected int buffer;
protected boolean convert;
protected Process process;
protected InputStream sourceInputStream, processInputStream, inputStream;
protected OutputStream processOutputStream;
protected CircularByteBuffer circularByteBuffer;
protected BufferWorker bufferWorker;
public Converter(InputStream inputStream) {
this(inputStream, -1);
}
public Converter(InputStream inputStream, int targetRate) {
super();
this.sourceInputStream = inputStream;
this.targetRate = targetRate;
bufferWorker = new BufferWorker();
convert = false;
}
public void exit() {
super.exit();
bufferWorker.exit();
}
public synchronized void activate() throws ActivateException {
/* Read bitrate */
BufferedInputStream bufferedInputStream = new BufferedInputStream(sourceInputStream);
Bitstream bitStream = new Bitstream(bufferedInputStream);
try {
rate = bitStream.readFrame().bitrate() / 1000;
buffer = BUFFER * rate / 8;
} catch (BitstreamException e) {
logger.error("", e);
throw new ActivateException();
}
/* Check for need to convert */
if (targetRate < 0 || rate == targetRate) {
logger.debug("No conversion required");
inputStream = sourceInputStream;
} else {
logger.debug("Converting from " + rate + "kbps to " + targetRate + "kbps");
try {
String command = String.format(COMMAND, rate > targetRate ? "-B " + targetRate : "-F -b " + targetRate);
logger.debug("Starting process: " + command);
process = Runtime.getRuntime().exec(command);
processInputStream = process.getInputStream();
processOutputStream = process.getOutputStream();
/* Buffer output */
circularByteBuffer = new CircularByteBuffer(CircularByteBuffer.INFINITE_SIZE);
inputStream = circularByteBuffer.getInputStream();
bufferWorker.start();
convert = true;
} catch (IOException e) {
logger.error("", e);
throw new ActivateException();
}
}
super.activate();
notifyAll();
}
public void deactivate() throws DeactivateException {
super.deactivate();
try {
sourceInputStream.close();
bufferWorker.stop();
if (convert) {
circularByteBuffer.clear();
convert = false;
}
inputStream.close();
} catch (IOException e) {
logger.error("", e);
throw new DeactivateException();
}
}
public void work() {
if (!convert) {
try {
synchronized (this) {
wait();
}
} catch (InterruptedException e) {
logger.error("", e);
}
return;
}
byte[] bytes = new byte[BYTES];
int read = 0;
try {
logger.debug("Writing input to process");
// Should be interrupted by stop()/exit()
while ((read = sourceInputStream.read(bytes)) > 0) {
/* Limit buffer size */
while (inputStream.available() > buffer) {
int progress = (int) ((1 - (inputStream.available() - buffer) / (float) buffer) * 100);
logger.trace("Waiting for buffer to empty: " + progress + "%");
sleep(BUFFERING);
}
processOutputStream.write(bytes, 0, read);
}
processOutputStream.close();
logger.debug("Stopped writing input to process");
process.waitFor();
logger.debug("Process finished");
} catch (IOException e) {
} catch (InterruptedException e) {
logger.error("", e);
}
stop();
}
public synchronized InputStream getInputStream() {
if (!active()) {
start();
try {
wait();
} catch (InterruptedException e) {
logger.error("", e);
}
}
return inputStream;
}
public synchronized void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
class BufferWorker extends Work {
public void work() {
byte[] bytes = new byte[BYTES];
int read = 0;
try {
OutputStream bufferOutputStream = circularByteBuffer.getOutputStream();
logger.debug("Start buffering process output");
while ((read = processInputStream.read(bytes, 0, BYTES)) > 0) {
bufferOutputStream.write(bytes, 0, read);
}
logger.debug("Finished buffering process output");
bufferOutputStream.close();
} catch (IOException e) {}
stop();
}
}
public static void main(String[] args) {
Mp3 mp3 = new Mp3(new File("stream.mp3"), 128);
InputStream inputStream = mp3.getInputStream();
/* Play */
//Utils.play(inputStream);
/* Write to file */
Utils.write(inputStream, new File("output.mp3"));
mp3.exit();
}
}