(我试图使我之前的问题更加通用,希望能找到解决方案。)
我正在使用 JLayer 库和 example.mp3 文件。我想同时播放和解码文件。
但是,我希望它们同步 - 如果歌曲的一部分被解码,它也会被播放。在播放之前不会对任何内容进行解码,反之亦然(当然,在合理的程度上)。
以下是歌曲的播放和解码方式:
Player p = new Player(InputStream mp3stream);
p.play();
Decoder d = new Decoder();
BitStream bs = new Bitstream(InputStream mp3stream);
SampleBuffer s = (SampleBuffer) d.decodeFrame(bs.readFrame(), bs);
// ... for processing the SampleBuffer but irrelevant for the question
我目前使用:
InputStream mp3stream = new FileInputStream("sample.mp3");
但是这会同时使用整首歌曲,所以我无法同步。有没有办法将sample.mp3分成可以由两个进程操作的片段?如果我有足够小的碎片,我可以将两个碎片都运行到进程中,等到两者都完成,然后捕获下一个小碎片并重复,直到我用完小碎片。
注意:我尝试使用 ByteArrayInputStream 但没有成功 - 但也许我在使用它时的方法不正确。
最佳答案
我希望我能做到这一点:
- 您有一个输入文件
- 您希望两个不同的输入流在某种意义上是同步的,即“它们必须在流中取得相同的进度”。
这是一个有趣的问题。我想出了下面的草图(编译,但没有执行它,所以你可以先做一些测试)。
- 创建一个包装对象“StreamSynchronizer”来控制对底层输入的访问。在所有派生流都读取该字节之前,只会读取一个字节。
- 从中派生任意数量的“SynchronizedStream”实例,将“读取”委托(delegate)回 StreamSynchronizer。
package de.mit.stackoverflow;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class StreamSynchronizer {
final private InputStream inputStream;
private List activeStreams = new ArrayList();
private int lastByte;
private Set waitingStreams = new HashSet();
private Object lock = new Object();
public StreamSynchronizer(InputStream is) throws IOException {
super();
this.inputStream = is;
lastByte = getInputStream().read();
}
public void close(SynchronizedStream stream) {
activeStreams.remove(stream);
}
public SynchronizedStream createStream() {
SynchronizedStream stream = new SynchronizedStream(this);
activeStreams.add(stream);
return stream;
}
public InputStream getInputStream() {
return inputStream;
}
public int read(SynchronizedStream stream) throws IOException {
synchronized (lock) {
while (waitingStreams.contains(stream)) {
if (waitingStreams.size() == activeStreams.size()) {
waitingStreams.clear();
lastByte = getInputStream().read();
lock.notifyAll();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
throw new IOException(e);
}
}
}
waitingStreams.add(stream);
return lastByte;
}
}
}
package de.mit.stackoverflow;
import java.io.IOException;
import java.io.InputStream;
public class SynchronizedStream extends InputStream {
final private StreamSynchronizer synchronizer;
protected SynchronizedStream(StreamSynchronizer synchronizer) {
this.synchronizer = synchronizer;
}
@Override
public void close() throws IOException {
getSynchronizer().close(this);
}
public StreamSynchronizer getSynchronizer() {
return synchronizer;
}
@Override
public int read() throws IOException {
return getSynchronizer().read(this);
}
}
关于java - J层同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4589992/