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

标签 java audio

我想从给定的 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);
    }
}

指定的音频格式为

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 文件上测试此代码:

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 酷睿 i5,1.4 GHz;
  • 内存:DDR3、4Gb
  • 操作系统:Mac OS 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(); }

然后你将这个audioInputStream传递给你的阅读方法。

关于java - 将 mp3 文件输入流转换为字节输出流的性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35828216/

相关文章:

ruby - Ruby 中的波形可视化

iphone - 使用音频队列服务将音频录制到数据

c# - 如何让我的 Java 应用程序与控制台 C# 应用程序交互?

java - Json中getString()和optString()的区别

Java 为有限和给出无穷大

html - 如何使网站启动音频移动友好?

html - 从 soundcloud 获取音频播放列表

java - Apache Solr - 这是处理提交的最佳方式

java - 从请求中提取json参数

r - 使用R进行实时音频分析