2013-07-10 9 views
1

.3gp 파일에서 원시 AMR 오디오 프레임을 추출하는 데 문제가 있습니다. 나는 "http://android.amberfog.com/?p=181"이라는 링크를 따라 갔지만 "mdat"상자 유형 대신 "moov"를 얻었다. "moov"상자와 "mdat"상자 위치가 장치마다 다릅니다. 누구든지 정확하게 .3gp 헤더를 건너 뛰고 원시 AMR 데이터를 추출하는 방법을 알고 있습니까? 다음은 코드입니다 : 내가하고 .3gp 파일로보고 일부 HEX 뷰어 도구를 사용3GP 파일에서 AMR 데이터 추출

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; 
    } 
+0

이 실패가 나는 MediaDataBox에게 조금 수정? – Shark

+0

if (! MediaDataBox.HEADER_TYPE.equalsIgnoreCase (header)) { // 여기에 문제가 있습니다 !!!!! - 머리글이 "moov"인 경우 (! MediaDataBox.HEADER_TYPE.equalsIgnoreCase (header)) { –

+0

mdat 대신 헤더가 moov –

답변

1

와 나는 그 MDAT 박스는 알고리즘을 찾았다 한 자리에 없었다보고, 그래서 읽기로 결정 mdat 상자를 찾을 때까지 스트림에서. 이제 압축이 잘됩니다.

public MediaDataBox(FileInputStream is) throws IOException { 
     super(is); 

     //check the mdat header - if not read until mdat if found 
     long last32Int = 0; 
     long curr32Int = 0; 
     long temp; 
     while (is.available()>=8) { 
      temp = curr32Int = readUint32(is);   

      //test like this to avoid low memory issues 
      if((HEADER_TYPE.charAt(0) == (byte)(temp >>> 24)) && 
        (HEADER_TYPE.charAt(1) == (byte)(temp >>> 16)) && 
         (HEADER_TYPE.charAt(2) == (byte)(temp >>> 8)) && 
          (HEADER_TYPE.charAt(3) == (byte)temp)){ 

       size = last32Int; 
       type = curr32Int; 
       boxSize = 8; 
       break; 
      } 
      last32Int = curr32Int; 
     } 
    } 

슈퍼 클래스 :

public _3GPBox(FileInputStream is) throws IOException{ 
     size = readUint32(is); 
     boxSize += 4; 
     type = readUint32(is); 
     boxSize += 4; 
    }