Длина аудио файла в Java
У меня проблемы с анализом данных из mp3-файла на основе его байтов.
Первая часть выводится правильно, у меня есть mp3-файл, длина которого составляет 254 секунды, и я получаю его информацию из библиотеки mp3agic для анализа mp3 из Github.
Однако вторая часть информации, касающейся длины и продолжительности кадра, является неверной.
Length of this mp3 is: 254 seconds
Bitrate: 320 kbps (CBR)
Sample rate: 44100 Hz
Has ID3v1 tag?: NO
Has ID3v2 tag?: YES
Has custom tag?: NO
framelength -1
framerate 38.28125
duration -271265.06
Код, который я использую, чтобы получить длину кадра, частоту кадров и длительность:
File file = musicFile.getFileValue();
this.audioStream.startMusicStream(file);
try {
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));
System.out.println("framelength "+frameSize);
System.out.println("framerate "+frameRate);
System.out.println("duration "+durationInSeconds);
this.setDurationLabel(durationInSeconds);
} catch (Exception e) {
e.printStackTrace();
}
Прежде всего, почему длина кадра и другие измерения даже отрицательны? Что это хотя бы значит? И как я могу точно рассчитать продолжительность mp3-файла, используя информацию из audioinputstream и audioformat?
1 ответ
Работаю на меня, спасибо библиотеке JAAD http://jaadec.sourceforge.net/:
import net.sourceforge.jaad.aac.Decoder;
import net.sourceforge.jaad.aac.SampleBuffer;
import net.sourceforge.jaad.adts.ADTSDemultiplexer;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import java.io.*;
public class AACHelper {
public static AudioInputStream decodeAAC(File inputFile) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
AudioFormat audioFormat;
try {
final FileInputStream audioInputStream = new FileInputStream(inputFile);
final ADTSDemultiplexer adts = new ADTSDemultiplexer(audioInputStream);
final Decoder dec = new Decoder(adts.getDecoderSpecificInfo());
final SampleBuffer buf = new SampleBuffer();
byte[] b;
while (true) {
try {
b = adts.readNextFrame();
}
catch (Exception e) {
break;
}
dec.decodeFrame(b, buf);
outputStream.write(buf.getData());
}
audioFormat = new AudioFormat(buf.getSampleRate(), buf.getBitsPerSample(), buf.getChannels(), true, buf.isBigEndian());
LogUtils.i("FrameRate: " + audioFormat.getFrameRate());
LogUtils.i("FrameSize: " + audioFormat.getFrameSize());
LogUtils.i("SampleRate: " + buf.getSampleRate());
LogUtils.i("BitsPerSample: " + buf.getBitsPerSample());
LogUtils.i("Bitrate: " + buf.getBitrate());
LogUtils.i("Length: " + buf.getLength());
} finally {
// nop
}
byte[] outputStreamByteArray = outputStream.toByteArray();
ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStreamByteArray);
AudioInputStream audioInputStream = new AudioInputStream(inputStream, audioFormat, outputStreamByteArray.length);
long audioFileLength = audioInputStream.getFrameLength();
int frameSize = audioFormat.getFrameSize();
float frameRate = audioFormat.getFrameRate();
double durationInSeconds = (audioFileLength / (frameSize * frameRate));
LogUtils.i("Duration: " + durationInSeconds);
return audioInputStream;
}
}
Для длины и продолжительности кадра вы можете использовать:
long frameLen = audioInputStream.getFrameLength();
double durationInSeconds = (frameLen+0.0) / format.getFrameRate();
Описание функции:
getFrameLength:Obtains the length of the stream, expressed in sample frames rather than bytes.Returns:the length in sample frames
getFrameRate:Obtains the frame rate in frames per second.Returns:the number of frames per second, or AudioSystem.NOT_SPECIFIED
Рекомендации:
а также