I have some trouble extracting raw AMR audio frames from a .3gp
file. I followed the link: "http://android.amberfog.com/?p=181" but instead of "mdat" box type I've got "moov". I read somewhere that "moov" box and "mdat" box location differ from device to device. Does anyone knows how to correctly skip the .3gp
headers and extract raw AMR data? Below is a code snippet:
public AMRFile convert3GPDataToAmr(String rawAmrFilePath) throws IOException {
if (_3gpFile == null) {
return null;
}
System.out.println("3GP file length: "+_3gpFile.getRawFile().length());
//FileInputStream is = new FileInputStream(_3gpFile.getRawFile());
ByteArrayInputStream bis = new ByteArrayInputStream(FileUtils.readFileToByteArray(_3gpFile.getRawFile()));
// read FileTypeHeader
System.out.println("Available1: "+bis.available());
FileTypeBox ftypHeader = new FileTypeBox(bis);
System.out.println("Available2: "+bis.available());
String header = ftypHeader.getHeaderAsString();
if(!FileTypeBox.HEADER_TYPE.equalsIgnoreCase(header)){
throw new IOException("File is not 3GP. ftyp header missing.");
}
// You can check if it is correct here
// read MediaDataHeader
MediaDataBox mdatHeader = new MediaDataBox(bis);
System.out.println("Available3: "+bis.available());
header = mdatHeader.getHeaderAsString();
if(!MediaDataBox.HEADER_TYPE.equalsIgnoreCase(header)){
//here is THE PROBLEM!!!!! - header is "moov" instead of "mdat" !!!!!!!!!!!!!
throw new IOException("File is not 3GP. mdat header missing.");
}
// You can check if it is correct here
int rawAmrDataLength = mdatHeader.getDataLength();
System.out.println("RAW Amr length: "+bis.available());
int fullAmrDataLength = AMR_MAGIC_HEADER.length + rawAmrDataLength;
byte[] amrData = new byte[fullAmrDataLength];
System.arraycopy(AMR_MAGIC_HEADER, 0, amrData, 0, AMR_MAGIC_HEADER.length);
bis.read(amrData, AMR_MAGIC_HEADER.length, rawAmrDataLength);
bis.close();
//create raw amr file
File rawAmrFile = new File(rawAmrFilePath);
FileOutputStream fos = new FileOutputStream(rawAmrFile);
AMRFile amrFile = null;
try {
fos.write(amrData);
} catch (Exception e) {
Log.e(getClass().getName(), e.getMessage(), e);
}
finally{
fos.close();
amrFile = new AMRFile(rawAmrFile);
}
System.out.println("AMR file length: "+amrFile.getRawFile().length());
return amrFile;
}