Student
Student

Reputation: 28345

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

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

Upvotes: 33

Views: 36230

Answers (4)

Yuriy N.
Yuriy N.

Reputation: 6067

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

Upvotes: 0

Harsh Kanakhara
Harsh Kanakhara

Reputation: 1153

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

Upvotes: 1

Milo Banks
Milo Banks

Reputation: 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)

Upvotes: -1

mdma
mdma

Reputation: 57707

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

Upvotes: 45

Related Questions