Methods Summary |
---|
public int | getDataLength()
return length - HEADER_LENGTH;
|
public java.lang.String | getEncoding()
return CHARSET_UTF_8;
|
public long | getFilePos()
return filePos;
|
public java.nio.ByteBuffer | getHeaderData()
dataBuffer.rewind();
return dataBuffer;
|
public java.lang.String | getId()
return id;
|
public int | getLength()
return length;
|
public static org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader | seekWithinLevel(java.io.RandomAccessFile raf, java.lang.String id)Seek for box with the specified id starting from the current location of filepointer,
Note it wont find the box if it is contained with a level below the current level, nor if we are
at a parent atom that also contains data and we havent yet processed the data. It will work
if we are at the start of a child box even if it not the required box as long as the box we are
looking for is the same level (or the level above in some cases).
logger.finer("Started searching for:" + id + " in file at:" + raf.getChannel().position());
Mp4BoxHeader boxHeader = new Mp4BoxHeader();
ByteBuffer headerBuffer = ByteBuffer.allocate(HEADER_LENGTH);
int bytesRead = raf.getChannel().read(headerBuffer);
if (bytesRead != HEADER_LENGTH)
{
return null;
}
headerBuffer.rewind();
boxHeader.update(headerBuffer);
while (!boxHeader.getId().equals(id))
{
logger.finer("Found:" + boxHeader.getId() + " Still searching for:" + id + " in file at:" + raf.getChannel().position());
//Something gone wrong probably not at the start of an atom so return null;
if (boxHeader.getLength() < Mp4BoxHeader.HEADER_LENGTH)
{
return null;
}
int noOfBytesSkipped = raf.skipBytes(boxHeader.getDataLength());
logger.finer("Skipped:" + noOfBytesSkipped);
if (noOfBytesSkipped < boxHeader.getDataLength())
{
return null;
}
headerBuffer.rewind();
bytesRead = raf.getChannel().read(headerBuffer);
logger.finer("Header Bytes Read:" + bytesRead);
headerBuffer.rewind();
if (bytesRead == Mp4BoxHeader.HEADER_LENGTH)
{
boxHeader.update(headerBuffer);
}
else
{
return null;
}
}
return boxHeader;
|
public static org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader | seekWithinLevel(java.nio.ByteBuffer data, java.lang.String id)Seek for box with the specified id starting from the current location of filepointer,
Note it won't find the box if it is contained with a level below the current level, nor if we are
at a parent atom that also contains data and we havent yet processed the data. It will work
if we are at the start of a child box even if it not the required box as long as the box we are
looking for is the same level (or the level above in some cases).
logger.finer("Started searching for:" + id + " in bytebuffer at" + data.position());
Mp4BoxHeader boxHeader = new Mp4BoxHeader();
if (data.remaining() >= Mp4BoxHeader.HEADER_LENGTH)
{
boxHeader.update(data);
}
else
{
return null;
}
while (!boxHeader.getId().equals(id))
{
logger.finer("Found:" + boxHeader.getId() + " Still searching for:" + id + " in bytebuffer at" + data.position());
//Something gone wrong probably not at the start of an atom so return null;
if (boxHeader.getLength() < Mp4BoxHeader.HEADER_LENGTH)
{
return null;
}
if(data.remaining()<(boxHeader.getLength() - HEADER_LENGTH))
{
//i.e Could happen if Moov header had size incorrectly recorded
return null;
}
data.position(data.position() + (boxHeader.getLength() - HEADER_LENGTH));
if (data.remaining() >= Mp4BoxHeader.HEADER_LENGTH)
{
boxHeader.update(data);
}
else
{
return null;
}
}
logger.finer("Found:" + id + " in bytebuffer at" + data.position());
return boxHeader;
|
public void | setFilePos(long filePos)Set location in file of the start of file header (i.e where the 4 byte length field starts)
this.filePos = filePos;
|
public void | setId(int length)Set the Id.
Allows you to manully create a header
This will modify the databuffer accordingly
byte[] headerSize = Utils.getSizeBEInt32(length);
dataBuffer.put(5, headerSize[0]);
dataBuffer.put(6, headerSize[1]);
dataBuffer.put(7, headerSize[2]);
dataBuffer.put(8, headerSize[3]);
this.length = length;
|
public void | setLength(int length)Set the length.
This will modify the databuffer accordingly
byte[] headerSize = Utils.getSizeBEInt32(length);
dataBuffer.put(0, headerSize[0]);
dataBuffer.put(1, headerSize[1]);
dataBuffer.put(2, headerSize[2]);
dataBuffer.put(3, headerSize[3]);
this.length = length;
|
public java.lang.String | toString()
return "Box " + id + ":length" + length + ":filepos:" + filePos;
|
public void | update(java.nio.ByteBuffer headerData)Create header using headerdata, expected to find header at headerdata current position
Note after processing adjusts position to immediately after header
//Read header data into byte array
byte[] b = new byte[HEADER_LENGTH];
headerData.get(b);
//Keep reference to copy of RawData
dataBuffer = ByteBuffer.wrap(b);
//Calculate box size
this.length = Utils.getIntBE(b, OFFSET_POS, OFFSET_LENGTH - 1);
//Calculate box id
this.id = Utils.getString(b, IDENTIFIER_POS, IDENTIFIER_LENGTH, "ISO-8859-1");
logger.finest("Mp4BoxHeader id:"+id+":length:"+length);
if (id.equals("\0\0\0\0"))
{
throw new NullBoxIdException(ErrorMessage.MP4_UNABLE_TO_FIND_NEXT_ATOM_BECAUSE_IDENTIFIER_IS_INVALID.getMsg(id));
}
if(length<HEADER_LENGTH)
{
throw new InvalidBoxHeaderException(ErrorMessage.MP4_UNABLE_TO_FIND_NEXT_ATOM_BECAUSE_IDENTIFIER_IS_INVALID.getMsg(id,length));
}
|