Java 将mp3文件输入流转换为字节输出流时的性能问题

Java 将mp3文件输入流转换为字节输出流时的性能问题,java,audio,Java,Audio,我想从给定的mp3文件中提取字节数组,以便对后者应用快速傅立叶变换。执行的FFT将为我的宠物项目音乐推荐系统提供一些功能 我编写了以下代码来从给定的mp3文件中提取字节: public class TrackSample { private static byte[] readBytesInPredefinedFormat(TargetDataLine format, InputStream inStream) throws IOException { ByteArrayOutputS

我想从给定的mp3文件中提取字节数组,以便对后者应用快速傅立叶变换。执行的FFT将为我的宠物项目音乐推荐系统提供一些功能

我编写了以下代码来从给定的mp3文件中提取字节:

public class TrackSample {

private static byte[] readBytesInPredefinedFormat(TargetDataLine format, InputStream inStream) throws IOException {
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    byte[] buffer = new byte[8192];
    int bytesRead;
    while ((bytesRead = inStream.read(buffer)) > 0) {
        int count = format.read(buffer, 0, buffer.length);
        if (count > 0) {
            byteArrayOutputStream.write(buffer, 0, count);
        }
        byteArrayOutputStream.write(buffer, 0, bytesRead);
    }
    byte[] bytes = byteArrayOutputStream.toByteArray();
    byteArrayOutputStream.close();
    inStream.close();
    return bytes;
}

public static byte[] getTrackBytes(String pathToTrackSample) throws IOException, LineUnavailableException {
    FileInputStream fileInputStream = new FileInputStream(pathToTrackSample);
    final AudioFormat format = CurrentAudioFormat.getAudioFormat(); //Fill AudioFormat with the wanted settings
    DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);

    TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
    line.open(format);
    line.start();

    return readBytesInPredefinedFormat(line, fileInputStream);
    }
}
File type ID:   MPG3
Num Tracks:     1
----
Data format:     2 ch,  44100 Hz, '.mp3' (0x00000000) 0 bits/channel, 0 bytes/packet, 1152 frames/packet, 0 bytes/frame
                no channel layout.
estimated duration: 104.176325 sec
audio bytes: 4167053
audio packets: 3988
bit rate: 320000 bits per second
packet size upper bound: 1052
maximum packet size: 1045
audio data file offset: 3169
optimized
audio 4591692 valid frames + 576 priming + 1908 remainder = 4594176
指定的音频格式为

public class CurrentAudioFormat {

    public static AudioFormat getAudioFormat(){
        float sampleRate = 44100;
        int sampleSizeInBits = 8;
        int channels = 1; //mono
        boolean signed = true;
        boolean bigEndian = true;
        return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
    }
}
我尝试在以下mp3文件上测试此代码:

public class TrackSample {

private static byte[] readBytesInPredefinedFormat(TargetDataLine format, InputStream inStream) throws IOException {
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    byte[] buffer = new byte[8192];
    int bytesRead;
    while ((bytesRead = inStream.read(buffer)) > 0) {
        int count = format.read(buffer, 0, buffer.length);
        if (count > 0) {
            byteArrayOutputStream.write(buffer, 0, count);
        }
        byteArrayOutputStream.write(buffer, 0, bytesRead);
    }
    byte[] bytes = byteArrayOutputStream.toByteArray();
    byteArrayOutputStream.close();
    inStream.close();
    return bytes;
}

public static byte[] getTrackBytes(String pathToTrackSample) throws IOException, LineUnavailableException {
    FileInputStream fileInputStream = new FileInputStream(pathToTrackSample);
    final AudioFormat format = CurrentAudioFormat.getAudioFormat(); //Fill AudioFormat with the wanted settings
    DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);

    TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
    line.open(format);
    line.start();

    return readBytesInPredefinedFormat(line, fileInputStream);
    }
}
File type ID:   MPG3
Num Tracks:     1
----
Data format:     2 ch,  44100 Hz, '.mp3' (0x00000000) 0 bits/channel, 0 bytes/packet, 1152 frames/packet, 0 bytes/frame
                no channel layout.
estimated duration: 104.176325 sec
audio bytes: 4167053
audio packets: 3988
bit rate: 320000 bits per second
packet size upper bound: 1052
maximum packet size: 1045
audio data file offset: 3169
optimized
audio 4591692 valid frames + 576 priming + 1908 remainder = 4594176
该系统的特点是:

  • 处理器:Intel core i5,1.4 GHz
  • 内存:DDR3,4Gb
  • 操作系统:Mac操作系统X El Captain
从这个mp3文件中提取字节数组大约需要5分钟


可能的瓶颈是什么?我如何改进它们?

阅读您所需的字节

while ((bytesRead = inStream.read(buffer)) > -1) {
    byteArrayOutputStream.write(buffer, 0, bytesRead);
}
我不知道你为什么要读两遍

为了确保您得到的是正确的,请尝试将其重新保存到新的音频文件中

--

读取音频文件的标准方法是

AudioInputStream audioInputStream=null;
  try {
    audioInputStream=AudioSystem.getAudioInputStream(new File(file));
  }
  catch(UnsupportedAudioFileException auf) { auf.printStackTrace(); }

然后您将此音频输入流传递给您的读取方法。

以读取您所需的字节

while ((bytesRead = inStream.read(buffer)) > -1) {
    byteArrayOutputStream.write(buffer, 0, bytesRead);
}
我不知道你为什么要读两遍

为了确保您得到的是正确的,请尝试将其重新保存到新的音频文件中

--

读取音频文件的标准方法是

AudioInputStream audioInputStream=null;
  try {
    audioInputStream=AudioSystem.getAudioInputStream(new File(file));
  }
  catch(UnsupportedAudioFileException auf) { auf.printStackTrace(); }

然后将此音频输入流传递给您的读取方法。

为什么不使用
AudioSystem.getAudioInputStream(文件)
读取文件?我不知道
AudioSystem.getAudioInputStream(文件)
。你能给我举一个使用这种格式的例子吗?我在DataLine.Info=newdataline.Info(TargetDataLine.class,format)行中得到一个编译类型错误;和line.open(格式);有时缓冲区未写入到最后一位,并使用format.read(buffer,0,buffer.length);如果要读取以前不应读取的块,则应使用format.read(缓冲区,0,字节读取);我不是说这是个问题,但它会给你一个有噪音的坏音频样本。你为什么不使用
AudioSystem.getAudioInputStream(文件)
来读取文件?我不知道
AudioSystem.getAudioInputStream(文件)
。你能给我举一个使用这种格式的例子吗?我在DataLine.Info=newdataline.Info(TargetDataLine.class,format)行中得到一个编译类型错误;和line.open(格式);有时缓冲区未写入到最后一位,并使用format.read(buffer,0,buffer.length);如果要读取以前不应读取的块,则应使用format.read(缓冲区,0,字节读取);我不是说这是个问题,但它会给你一个带有噪音的坏音频样本,作为关于将数据保存回mp3文件的建议。我做到了,但不能演奏。我认为AudioFormat类存在一个问题,即我没有正确指定它。您如何读/写mp3?java无法做到这一点,所以必须有一些外部库。int count=format.read(buffer,0,buffer.length);其中format是AudioFormat类的实例-这是我读的mp3文件。我只是将字节[]保存到mp3文件中。你能建议任何第三方LIB使用java的mp3格式吗?有一个我用过,但也有一个我没用过但其他人用过的mp3agic-在这里或网上搜索-现在你可以用.wav fileThx测试关于将数据保存回mp3文件的建议。我做到了,但不能演奏。我认为AudioFormat类存在一个问题,即我没有正确指定它。您如何读/写mp3?java无法做到这一点,所以必须有一些外部库。int count=format.read(buffer,0,buffer.length);其中format是AudioFormat类的实例-这是我读的mp3文件。我只是将字节[]保存到mp3文件中。你能推荐任何第三方LIB使用java的mp3格式吗?有一个我用过,但也有一个mp3agic我没用过,但其他人用过-在这里或网上搜索-现在你可以用.wav文件进行测试