Closed mvmn closed 2 years ago
P.S. Why do I need a framerate? I'm trying to figure out the length of file in seconds - by dividing total number of frames (frameLength) by rate of frames per second (frame rate). For FLAC this works fine:
int lengthSeconds = (int) (audioInputStream.getFrameLength() / audioInputStream.getFormat().getFrameRate());
But not for MP3/M4A
Calculating from samplerate needs a frame size in samples, which is always returned as -1. And may not work with VBR.
P.P.S. Looking at this - https://github.com/hendriks73/ffsampledsp/blob/master/ffsampledsp-java/src/main/java/com/tagtraum/ffsampledsp/FFAudioFileFormat.java - I suppose one workaround to get length (in microseconds) is to do new FFAudioFileReader().getAudioFileFormat(file).properties().get("duration")
Reading compressed audio with the Java Audio API is a two step process:
(1152 / 44100) * 1000 = 26.122449 ms/frame
or 38.28125 frames/s
). The 1152 samples for frame is true for CBR, not so sure about VBR.See for example https://stackoverflow.com/a/41850901/942774
So the frame rate for both mp3 and m4a is correct.
What kind of results do you get when doing
int lengthSeconds = (int) (audioInputStream.getFrameLength() / audioInputStream.getFormat().getFrameRate());
for mp3 and m4a?
And yes, using the property is definitely the recommended way. Whatever you are trying to do in Java, you can save yourself some grief by simply using what FFmpeg provides. This is even officially documented in https://docs.oracle.com/javase/7/docs/api/javax/sound/sampled/AudioFileFormat.html
Doesn't seem right. If you look at the output above, the number of frames for an mp3 file that is about 5 minutes long is returned as 12180096
Total frames: 12180096
FrameSize: -1
FrameRate: 38.28125
12180096 frames / 38.28125 frames/sec ~= 318174 seconds, 3.68 days. For a file that is in reality below 5 minutes long.
Something doesn't add up here
Yeah... looks to me like the number of frames is wrong, not the frame rate.
Updated sample program:
public class TestFramerate {
public static void main(String args[]) throws Exception {
JFileChooser jfc = new JFileChooser();
if (JFileChooser.APPROVE_OPTION == jfc.showOpenDialog(null)) {
File file = jfc.getSelectedFile();
AudioFileFormat format = new FFAudioFileReader().getAudioFileFormat(file);
System.out.println("FF Format Total frames: " + format.getFrameLength());
System.out.println("FF Format Byte length: " + format.getByteLength());
System.out.println("FF Format Format properties " + format.properties());
FFAudioInputStream audioInputStream = (FFAudioInputStream) new FFAudioFileReader().getAudioInputStream(file);
System.out.println("Format: " + audioInputStream.getFormat());
System.out.println("Total frames: " + audioInputStream.getFrameLength());
System.out.println("FrameSize: " + audioInputStream.getFormat().getFrameSize());
System.out.println("FrameRate: " + audioInputStream.getFormat().getFrameRate());
System.out.println("Format properties " + audioInputStream.getFormat().properties());
long lengthSeconds = (long) (audioInputStream.getFrameLength() / audioInputStream.getFormat().getFrameRate());
System.out.println("Calculate duration (seconds): " + lengthSeconds);
System.out.println(
"Duration from properties (converted to seconds): " + (((Long) format.properties().get("duration")) / 1000000));
audioInputStream.close();
}
}
}
Output for MP3:
[mp3 @ 0x7f8b9f97e800] Estimating duration from bitrate, this may be inaccurate
FF Format Total frames: 12180096
FF Format Byte length: 14204470
FF Format Format properties {duration=276192656}
[mp3 @ 0x7f8ba0929800] Estimating duration from bitrate, this may be inaccurate
Format: MPEG-1, Layer 3 44100.0 Hz, 0 bit, stereo, unknown frame size, 38.28125 frames/second,
Total frames: 12180096
FrameSize: -1
FrameRate: 38.28125
Format properties {provider=ffsampledsp, bitrate=320000}
Calculate duration (seconds): 318173
Duration from properties (converted to seconds): 276
the number of frames is wrong
Quite possibly. From the output above:
FF Format Total frames: 12180096
FF Format Byte length: 14204470
These numbers are very close - but a frame must surely be much bigger than one byte.
I have changed this in dev so that getFrameLength()
returns the number of whole (floor), compressed frames.
Framerate is returned incorrectly for MP3 and M4A files. For FLAC correct value of 44100.0 is returned
Example:
Opening an MP3 file:
Opening a FLAC file:
Opening an M4A file: