I wrote the following code to determine the duration of an OGG (Vorbis) file.
public static long calculateDuration(final File file) throws IOException {
long fileSize = (Files.size(file.toPath())); // Bytes
byte[] nominalBitrateBytes = {0, 0, 0, 0, 0, 0, 0, 0};
try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r")) {
for (int i = 0; i < 8; i++) {
randomAccessFile.seek(48L + i);
nominalBitrateBytes[i] = randomAccessFile.readByte();
}
}
long nominalBitrate = ByteBuffer.wrap(nominalBitrateBytes).order(ByteOrder.LITTLE_ENDIAN).getLong();
return fileSize / (nominalBitrate / 8);
}
With this I'm reading the filesize with java.nio library and the nominal bitrate that I found out it's stored in a 64bit value starting at the 48th byte in the music file.
The problem is sometimes that the value comes out wrong and sometimes is actually accurate. For example I took a music file with a duration of 3.55min. The code outputs 227 seconds, which is near 235 of the track. As a second attempt I processed a 2.03min track, and the software's guess was 102 seconds, that is too far low (should be 123). By trying to do this calculations by hand it turns out the same values as the software (taking the filesize with explorer.exe and the bitrate with HxD)