How do I get a sound file's total time in Java?
Asked Answered
E

4

33

How do I get a sound file's total time in Java?

--UPDATE

Looks like this code does de work: long audioFileLength = audioFile.length();

    recordedTimeInSec = audioFileLength / (frameSize * frameRate);

I know how to get the file length, but I'm not finding how to get the sound file's frame rate and frame size... Any idea or link?

-- UPDATE

One more working code (using @mdma's hints):

    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));
Evangelical answered 9/6, 2010 at 21:0 Comment(1)
Which jar file are you using for this?Tremble
F
44

Given a File you can write

File file = ...;
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);
AudioFormat format = audioInputStream.getFormat();
long frames = audioInputStream.getFrameLength();
double durationInSeconds = (frames+0.0) / format.getFrameRate();  
Friseur answered 9/6, 2010 at 21:11 Comment(3)
I don't what's wrong, but with a file of 18 seconds your code produce a result 149120 while the new code I posted in the question produce 18.64275 (the correct size in seconds). Anyway, I wouldn't have done this without the hints, thanks!Evangelical
@Friseur : can you please help me in my question #29115889Hardness
com.sun.media.sound.RIFFInvalidDataException: Chunk size too big, bugs.openjdk.java.net/browse/JDK-8132782Undulate
A
0

I have used JAudiotagger library. It is super easy to use and supports almost all audio formats.

Add dependency in pom

<dependency>
    <groupId>net.jthink</groupId>
    <artifactId>jaudiotagger</artifactId>
    <version>3.0.1</version>
</dependency>

Below code is to extract audio file metadata

try {
    AudioFile audioMetadata = AudioFileIO.read(file);
    System.out.println("Audio Metadata {}",audioMetadata.displayStructureAsPlainText());
    System.out.println(audioMetadata.getAudioHeader().getTrackLength());
    System.out.println(audioMetadata.getAudioHeader().getBitRate());
} catch (CannotReadException | IOException | TagException | ReadOnlyFileException
        | InvalidAudioFrameException e) {
    throw new RuntimeException("Error while getting metadata for audio file. Error " +  e.getLocalizedMessage());
}

Reference - https://jthink.net/jaudiotagger/index.jsp

Airily answered 12/3 at 13:53 Comment(0)
F
0

I got the UnsupportedFileFormat exception using the code provided by OP and in the accepted answer. My audio files are normal MP3 files generated by the text-to-speech service ElevenLabs.

The solution below uses ffprobe, so it must be installed and added to the path first.

static String GET_DURATION_COMMAND = "ffprobe -v error -show_entries 
               format=duration -of default=noprint_wrappers=1:nokey=1 $input";

private static double getDuration(File file) throws Exception {
        String command = GET_DURATION_COMMAND.replace("$input", 
                     "\"" + file.getAbsolutePath()) + "\"";
        String durationString = CmdUtil.exec(command);

        return Double.parseDouble(durationString);
 }

public class CmdUtil {
    public static String exec(String command) throws IOException {
        ProcessBuilder builder = new ProcessBuilder(
            "cmd.exe", "/c", command);
        builder.redirectErrorStream(true);
        Process p = builder.start();
        BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
        StringBuilder resultBuilder = new StringBuilder();
        String line;
        while (true) {
            line = r.readLine();
            if (line == null) { break; }
            System.out.println(line);
            resultBuilder.append(line);
        }
        return resultBuilder.toString();
    }
}
Frisco answered 19/4 at 15:44 Comment(0)
L
-1

This is a easy way:

FileInputStream fileInputStream = null;
long duration = 0;

try {
    fileInputStream = new FileInputStream(pathToFile);
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

try {
    duration = Objects.requireNonNull(fileInputStream).getChannel().size() / 128;
} catch (IOException e) {
    e.printStackTrace();
}
System.out.println(duration)
Levana answered 15/9, 2018 at 22:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.