Como posso pegar o tempo de um arquivo com o Java?

Olá pessoal queria saber se existe alguma maneira de pegar o tempo de uma musica por exemplo, no java?
Tentei fazer isso por metadados mas o máximo que consegui foi pegar o número de bytes do arquivo. Agradeço quem poder ajudar.

Em JavaFX Media

    player.getCurrentTime();
    player.getMedia().getDuration();
1 curtida

Um arquivo de áudio PCM (pulse-code modulation) tem algumas características interessantes. Calcular a duração do arquivo é trivial depois que você entende como ele funciona.

  1. Sample: Um sample nada mais é, como o nome diz, uma amostra do som. Essa amostra geralmente é muito pequena, tipo 8 bits. Uma forma de imaginar (incorreta, mas vale o exemplo) é que você tem um microfone capaz de gravar o áudio do ambiente durante uma fração muito pequena de tempo: essa gravação é um sample.

    Cada canal do arquivo PCM é uma sequência de samples. Se um arquivo PCM tem 2 canais, ele vai ter 2 sequências de samples, que devem ser tocadas simultaneamente. Se tiver 4 canais, terá 4 sequências de samples, e assim por diante;

  2. Frame: um frame é um sample de cada canal disponível. Se o arquivo tem 4 canais, um frame consiste de 4 samples. Se os samples desse arquivo tem 8 bits, então o frame size desse arquivo é 4 bytes (4 canais x 8 bits). Diferentemente do sample size, o frame size é medido em bytes, e não em bits. Não sei o motivo, pra mim dá na mesma, parece ser só convenção;

  3. Frame Rate: número de frames que deve ser tocado por segundo. Tem também o sample rate, que é a mesma coisa só que samples ao invés de frames.

Com essas informações você já consegue calcular a duração de um arquivo de áudio. Por exemplo, se seu arquivo tem um frame size de 1 byte, o frame rate de 16000 Hz (Hertz é a unidade de “revoluções por segundo”, ou seja 16000 frames por segundo) e um tamanho total de 32000 bytes, é só fazer a conta:

Total de frames: 32000 bytes / 1 byte por frame = 32000 frames
Duração: 32000 frames / 16000 Hz = 2 segundos.

Todas as informações necessárias pra fazer essas contas estão necessariamente gravadas no arquivo (ou implícitas no formato de áudio). Afinal, os players precisam saber a velocidade de reprodução correta e não tem como adivinhar.

Se seu arquivo for um dos formatos suportados pela classe AudioFileFormat, dá pra fazer assim:

import java.io.File;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioSystem;

class Main {

    static int calculateSongDuration (String filename) throws Exception {
        File song = new File(filename);
        AudioFileFormat format = AudioSystem.getAudioFileFormat(song);
        int bytes = format.getByteLength();
        float frameRate = format.getFormat().getFrameRate();
        float frameSize = format.getFormat().getFrameSize();
        return (int) (bytes / frameSize / frameRate);
    }

    public static void main (String[] args) throws Exception {
        if (args.length != 1) {
            System.exit(1);
        }
        String filename = args[0];
        System.out.printf("Duration of \"%s\": ", filename);
        System.out.printf("%d seconds.%n", calculateSongDuration(filename));
    }
}

Provavelmente existem bibliotecas que fazem essa conta pra você. Só achei que seria legal explicar caso alguém tenha curiosidade. Não precisa reinventar a roda!

2 curtidas