Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Length of audio file in Java

I'm having issues with parsing the data from an mp3 file based on it's bytes.

The first part the output is correct, I have an mp3 file that is 254 seconds long and I obtain its information from the mp3 parsing library mp3agic from Github.

However, the second part of the information, regarding frame length and duration is incorrect.

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

The code that I use to get framelength, framerate and duration is:

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();
    }

Fist of all, why is framelength and the other measurements even negative? What does that even mean? And how can I accurately calculate the duration of an mp3 file using the information from the audioinputstream and audioformat?

like image 937
waylonion Avatar asked Oct 31 '22 08:10

waylonion


1 Answers

Working for me, thanks to JAAD library 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;
    }

}

like image 168
Christopher Avatar answered Nov 15 '22 03:11

Christopher