首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跳过指定字节数的SourceDataLine (JavaSound)

跳过指定字节数的SourceDataLine (JavaSound)
EN

Stack Overflow用户
提问于 2018-04-09 11:26:37
回答 1查看 173关注 0票数 0

由于某些原因,我需要使用SourceDataLine而不是Clip来播放我的程序中的音频。将framePosition (我想跳过)赋给Clip很容易,但是SourceDataLine没有这个方便的API。

我想使用AudioInputStream.skip(n),其中n是请求跳过的字节数。但是如果我想跳过1.25秒,我不知道如何正确设置n。我该怎么做呢?

我的代码来自这个site(MP3 player sample)

请检查函数stream中的in.skip()

代码语言:javascript
复制
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);
    }
}}
EN

回答 1

Stack Overflow用户

发布于 2018-04-09 15:13:21

每个AudioInputStream都有一个AudioFormat对象,您可以通过format()方法获取该对象。要找出多少字节是1.25秒,您需要计算1.25秒有多少帧,以及帧有多大:

代码语言:javascript
复制
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.

解释如下:

  • 一帧是所有通道的一个完整采样。因此,如果你有一个立体声信号,一个帧是两个样本,左,right.
  • FrameSize是一个帧使用的字节数。对于CD质量,这将是每个通道2个字节,即每个帧4个字节(在stereo).
  • FrameRate的情况下是每个second.
  • Since的帧数,您不应该拆分必须舍入到整个帧的帧。

请注意,上面的代码假设您有PCM编码的音频。如果你有其他的东西,首先使用像pcmStream = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED, audioInputStream)这样的东西转码到PCM。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49725091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档