java - J层同步

标签 java inputstream synchronized jlayer

(我试图使我之前的问题更加通用,希望能找到解决方案。)

我正在使用 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/

相关文章:

java - OpenLDAP - 获取密码属性

java - 如何在 impala 中编写 java udf

java.lang.ClassCastException : Creating a synchronized Linked List 异常

对象上的 Java 同步。为什么不会出现这种僵局?

java - 在搜索中查找 HashMap 中的字符串

java - Spring 。验证期间错误 400

java - 使用 TCP/IP 拦截 http 文件上传

android - 如何获取位图信息,然后从 internet-inputStream 解码位图?

java - 如何在 Java 中读取一个 String 后跟一个 int?

java - 线程安全与同步