由于某些原因,我需要使用SourceDataLine
代替Clip
来播放我的程序中的音频。可以很容易地将framePosition
(我想跳过)分配给Clip
,但SourceDataLine
没有这个方便的API。
我想使用AudioInputStream.skip(n)
,其中n
是要跳过的请求字节数。但我不知道如何正确设置n
,如果我想跳过1.25秒。我怎样才能做到这一点?
我的代码来自site(MP3 player sample)
请检查功能in.skip()
stream
public class AudioFilePlayer {
public static void main(String[] args) {
final AudioFilePlayer player = new AudioFilePlayer ();
player.play("something.mp3");
}
public void play(String filePath) {
final File file = new File(filePath);
try (final AudioInputStream in = getAudioInputStream(file)) {
final AudioFormat outFormat = getOutFormat(in.getFormat());
final Info info = new Info(SourceDataLine.class, outFormat);
try (final SourceDataLine line =
(SourceDataLine) AudioSystem.getLine(info)) {
if (line != null) {
line.open(outFormat);
line.start();
stream(getAudioInputStream(outFormat, in), line);
line.drain();
line.stop();
}
}
} catch (UnsupportedAudioFileException
| LineUnavailableException
| IOException e) {
throw new IllegalStateException(e);
}
}
private AudioFormat getOutFormat(AudioFormat inFormat) {
final int ch = inFormat.getChannels();
final float rate = inFormat.getSampleRate();
return new AudioFormat(PCM_SIGNED, rate, 16, ch, ch * 2, rate, false);
}
private void stream(AudioInputStream in, SourceDataLine line)
throws IOException {
in.skip(proper number); //There is my question
final byte[] buffer = new byte[65536];
for (int n = 0; n != -1; n = in.read(buffer, 0, buffer.length)) {
line.write(buffer, 0, n);
}
}}
答案 0 :(得分:1)
每个AudioInputStream
都有一个AudioFormat
对象,您可以通过format()方法获取该对象。要找出1.25
秒的字节数,您需要计算1.25
秒的帧数和帧的大小:
AudioFormat format = audioInputStream.format();
float b = format.getFrameSize() * format.getFrameRate() * 1.25f;
// round to nearest full frame
long n = (b/format.getFrameSize())*format.getFrameSize();
long skipped = audioInputStream.skip(b);
// you might want to check skipped to see whether the
// requested number of bytes was indeed skipped.
解释:
请注意,上面的代码假设您有PCM编码的音频。如果您还有其他内容,请先使用pcmStream = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED, audioInputStream)
等内容转码为PCM。