package org.jaudiotagger.audio.mp3;
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
import java.nio.ByteBuffer;
public class ByteArrayMP3AudioHeader extends MP3AudioHeader {
public ByteArrayMP3AudioHeader(byte[] fileBytes) {
// This is substantially faster than updating the filechannels position
long filePointerCount = 0;
// Read into Byte Buffer in Chunks
ByteBuffer bb = ByteBuffer.wrap(fileBytes);
boolean syncFound = false;
do {
if (MPEGFrameHeader.isMPEGFrame(bb)) {
try {
mp3FrameHeader = MPEGFrameHeader.parseMPEGHeader(bb);
syncFound = true;
if (XingFrame.isXingFrame(bb, mp3FrameHeader)) {
try {
// Parses Xing frame without modifying position of main buffer
mp3XingFrame = XingFrame.parseXingFrame();
} catch (InvalidAudioFrameException ex) {
// We Ignore because even if Xing Header is corrupted
// doesn't mean file is corrupted
}
break;
}
// There is a small but real chance that an unsynchronised ID3 Frame could fool the MPEG
// Parser into thinking it was an MPEG Header. If this happens the chances of the next bytes
// forming a Xing frame header are very remote. On the basis that most files these days have
// Xing headers we do an additional check for when an apparent frame header has been found
// but is not followed by a Xing Header:We check the next header this wont impose a large
// overhead because wont apply to most Mpegs anyway ( Most likely to occur if audio
// has an APIC frame which should have been unsynchronised but has not been) , or if the frame
// has been encoded with as Unicode LE because these have a BOM of 0xFF 0xFE
else {
syncFound = isNextFrameValid(bb);
if (syncFound == true) {
break;
}
}
} catch (InvalidAudioFrameException ex) {
// We Ignore because likely to be incorrect sync bits ,
// will just continue in loop
}
}
bb.position(bb.position() + 1);
filePointerCount++;
}
while (!syncFound);
setFileSize(fileBytes.length);
setMp3StartByte(filePointerCount);
setTimePerFrame();
setNumberOfFrames();
setTrackLength();
setBitRate();
setEncoder();
}
private boolean isNextFrameValid(ByteBuffer bb) {
boolean result = false;
int currentPosition = bb.position();
bb.position(bb.position() + mp3FrameHeader.getFrameLength());
if (MPEGFrameHeader.isMPEGFrame(bb)) {
try {
MPEGFrameHeader.parseMPEGHeader(bb);
// MP3AudioHeader.logger.finer("Check next frame confirms is an audio header ");
result = true;
} catch (InvalidAudioFrameException ex) {
// MP3AudioHeader.logger.finer("Check next frame has identified this is not an audio header");
result = false;
}
}
// Set back to the start of the previous frame
bb.position(currentPosition);
return result;
}
}