是否可以创建一个包含 wav 文件“循环”的临时文件?
或者是否可以操纵发送到流读取器/写入器的流?
基本上我想播放一些 wav 文件一段时间,如果该时间大于 wav 文件提供的时间长度,我想循环播放。
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
Clip clip = AudioSystem.getClip();
clip.loop((int)(Math.ceil(timeRequested / audioIn.getFrameLength())));
我不确定我是否理解您实施解决方案的确切限制,但似乎最干净的方法是在您第一次播放文件时将音频数据存储在缓冲区中。然后,如果用户需要更多迭代(全部或部分),只需将缓存的数据重写回 SourceDataLine 所需的次数。
这是一个示例声音文件播放器 (PCM) 的链接,它的代码应该很容易修改(或只是从中学习)。我还修改了一些(注意:未经测试)代码,这些代码仅显示了我上面描述的逻辑:(您可能还想修改我在下面的内容以符合仅写入大小为倍数的数据块的规则帧大小。)
public void playSoundFile(SourceDataLine line, InputStream inputStream, AudioFormat format, long length, float times)
{
int index = 0;
int size = length * format.getFrameSize();
int currentSize = 0;
byte[] buffer = new byte[size];
AudioInputStream audioInputStream = new AudioInputStream(inputStream, format, length);
while (index < size)
{
currentSize = audioInputStream.read(buffer, index, size - index);
line.write(buffer, index, currentSize);
index += currentSize;
}
float currentTimes = 1.0;
while (currentTimes < times)
{
float timesLeft = times - currentTimes;
int writeBlockSize = line.available();
index = 0;
if (timesLeft >= 1.0)
{
while (index < size)
{
currentSize = ((size - index) < writeBlockSize) ? size - index : writeBlockSize;
line.write(buffer, index, currentSize);
index += currentSize;
}
currentTimes += 1.0;
}
else
{
int partialSize = (int)(timesLeft * ((float) size) + 0.5f);
while (index < partialSize)
{
currentSize = ((partialSize - index) < writeBlockSize) ? partialSize - index : writeBlockSize;
line.write(buffer, index, currentSize);
index += currentSize;
}
currentTimes += timesLeft;
}
}
}
希望有帮助!
我想我会使用音频输入流中的每秒帧数和帧大小信息来解决这个问题。其他有用的信息在 SourceDataLine 对象的 getMicrosecondPosition() 方法中,以确定到目前为止播放的时间/持续时间。
这与音频输入流中的标记和重置方法一起可能会处理这一切。