java - Java中音频文件的长度

标签 java audio mp3 audioformat

我在根据字节解析 mp3 文件中的数据时遇到问题。

第一部分输出是正确的,我有一个 254 秒长的 mp3 文件,我从 Github 的 mp3 解析库 mp3agic 中获取它的信息。

但是,关于帧长度和持续时间的信息的第二部分是不正确的。

Length of this mp3 is: 254 seconds
Bitrate: 320 kbps (CBR)
Sample rate: 44100 Hz
Has ID3v1 tag?: NO
Has ID3v2 tag?: YES
Has custom tag?: NO

framelength -1
framerate 38.28125
duration -271265.06

我用来获取帧长、帧率和持续时间的代码是:

File file = musicFile.getFileValue();

    this.audioStream.startMusicStream(file);

    try {
        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);
        AudioFormat format = audioInputStream.getFormat();
        long audioFileLength = file.length();
        int frameSize = format.getFrameSize();
        float frameRate = format.getFrameRate();
        float durationInSeconds = (audioFileLength / (frameSize * frameRate));

        System.out.println("framelength "+frameSize);
        System.out.println("framerate "+frameRate);
        System.out.println("duration "+durationInSeconds);

        this.setDurationLabel(durationInSeconds);
    } catch (Exception e) {
        e.printStackTrace();
    }

首先,为什么 framelength 和其他测量值甚至是负值?那有什么意思?以及如何使用来自 audioinputstream 和 audioformat 的信息准确计算 mp3 文件的持续时间?

最佳答案

为我工作,感谢 JAAD 库 http://jaadec.sourceforge.net/ :

import net.sourceforge.jaad.aac.Decoder;
import net.sourceforge.jaad.aac.SampleBuffer;
import net.sourceforge.jaad.adts.ADTSDemultiplexer;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import java.io.*;

public class AACHelper {

    public static AudioInputStream decodeAAC(File inputFile) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        AudioFormat audioFormat;

        try {
            final FileInputStream audioInputStream = new FileInputStream(inputFile);
            final ADTSDemultiplexer adts = new ADTSDemultiplexer(audioInputStream);
            final Decoder dec = new Decoder(adts.getDecoderSpecificInfo());

            final SampleBuffer buf = new SampleBuffer();
            byte[] b;
            while (true) {
                try {
                    b = adts.readNextFrame();
                }
                catch (Exception e) {
                    break;
                }

                dec.decodeFrame(b, buf);
                outputStream.write(buf.getData());
            }

            audioFormat = new AudioFormat(buf.getSampleRate(), buf.getBitsPerSample(), buf.getChannels(), true, buf.isBigEndian());
            LogUtils.i("FrameRate:     " + audioFormat.getFrameRate());
            LogUtils.i("FrameSize:     " + audioFormat.getFrameSize());
            LogUtils.i("SampleRate:    " + buf.getSampleRate());
            LogUtils.i("BitsPerSample: " + buf.getBitsPerSample());
            LogUtils.i("Bitrate:       " + buf.getBitrate());
            LogUtils.i("Length:        " + buf.getLength());

        } finally {
            // nop
        }

        byte[] outputStreamByteArray = outputStream.toByteArray();
        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStreamByteArray);
        AudioInputStream audioInputStream = new AudioInputStream(inputStream, audioFormat, outputStreamByteArray.length);

        long audioFileLength = audioInputStream.getFrameLength();
        int frameSize = audioFormat.getFrameSize();
        float frameRate = audioFormat.getFrameRate();
        double durationInSeconds = (audioFileLength / (frameSize * frameRate));
        LogUtils.i("Duration:      " + durationInSeconds);

        return audioInputStream;
    }

}

关于java - Java中音频文件的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35822397/

相关文章:

php - HTTP header ,将文件发送到html5 <audio>

java - 在 Java 中播放 .mp3

ios - 在设备上构建时找不到<Accelerate/Accelerate.h>

java - JOptionPane.showMessageDialog 必须退出两次

java - 查找除 - regex 之外的标点符号

c# - Naudio - 将 32 位 wav 转换为 16 位 wav

javascript - Javascript中的Shoutcast流频谱图

android - 如何使用 mp3 音频文件和图像制作 3gp 视频?

java - 具有多种过滤条件的HBase Scan api

java - 将 8kHz mulaw 实时转换为 16KHz PCM