2013-02-18 16 views
20

Android(Jelly Bean)のメディアコーデッククラスを使用して、PCM形式をAACにエンコードします。ファイルはエンコードされましたが、音楽プレーヤーはそのファイルを再生できません。私はネット上で作業コードや適切な文書を見つけることができませんでした。mediacodecを使用したPCMからAACへの変換

これは私のコードです:

public void doConvert() 
{ 

    new AsyncTask<Void, Void, Void>() 
    { 

     @Override 
     protected Void doInBackground(Void... params) 
     { 
      try 
      { 
       int codecCount = MediaCodecList.getCodecCount(); 

       for (int i=0; i < codecCount; i++) 
       { 
        MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i); 
        Logger.getLogger(MainActivity.class.getSimpleName()).log(Level.INFO, info.getName()); 
        for (String type : info.getSupportedTypes()) 
        { 
         Logger.getLogger(MainActivity.class.getSimpleName()).log(Level.INFO, type); 
        } 

       } 

       File inputFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download/Ghajini27_Mono_8Khz.wav"); 
       //File inputFile = new File(sampleFD.get); 
       Log.e("File", String.valueOf(inputFile.length())); 
       FileInputStream fis = new FileInputStream(inputFile); 
       fis.skip(44);//remove wav header 

       File outputFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download/out.m4a"); 
       if (outputFile.exists()) outputFile.delete(); 

       FileOutputStream fos = new FileOutputStream(outputFile); 

       //BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(outputFile)); 
       MediaCodec codec = MediaCodec.createEncoderByType("audio/mp4a-latm"); 
       MediaFormat outputFormat = MediaFormat.createAudioFormat("audio/mp4a-latm", 22050, 1); 
       outputFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC); 
      // outputFormat.setInteger(MediaFormat.KEY_CHANNEL_MASK, AudioFormat.CHANNEL_CONFIGURATION_MONO); 
       outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, 22050 ); 
       outputFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1); 
       //outputFormat.setLong(MediaFormat.KEY_MAX_INPUT_SIZE, inputFile.length()); 
       double durationInMs = (inputFile.length()/16000)*1000; 
       Log.e("duration",String.valueOf((long)durationInMs)); 
       outputFormat.setLong(MediaFormat.KEY_DURATION, (long)durationInMs); 


       codec.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); 
       codec.start(); 

       ByteBuffer[] inputBuffers = codec.getInputBuffers(); 
       ByteBuffer[] outputBuffer = codec.getOutputBuffers(); 

       boolean hasMoreData = true; 
       MediaCodec.BufferInfo outBuffInfo = new BufferInfo(); 
       byte readBuffer[] = new byte[48000]; 
       byte writeBuffer[] = new byte[48000]; 

       do 
       { 
        int nextBuffer = codec.dequeueInputBuffer(5000); 
        Log.e("NextBuffer","nextInputBuffer = "+nextBuffer); 

        if (nextBuffer >= 0) 
        { 



         ByteBuffer inBuf = inputBuffers[nextBuffer]; 
         inBuf.clear(); 
         int bytesRead = fis.read(readBuffer,0, inBuf.capacity()); 

         Log.e("bytesread","Read = "+bytesRead); 

         if (bytesRead < inBuf.capacity()) 
         { 
          hasMoreData = false; 
         } 

         inBuf.put(readBuffer, 0, bytesRead); 

         codec.queueInputBuffer(nextBuffer, 0, bytesRead, 0, hasMoreData?0:MediaCodec.BUFFER_FLAG_END_OF_STREAM); 
        } 


        int outputBufferIndex = codec.dequeueOutputBuffer(outBuffInfo, 3000); 
       /* logger.log(Level.INFO,"nextOutputBuffer = "+outputBufferIndex); 
        logger.log(Level.INFO,"outBuffInfo offset = "+outBuffInfo.offset); 
        logger.log(Level.INFO,"outBuffInfo size = "+outBuffInfo.size); 
        logger.log(Level.INFO,"outBuffInfo flags = "+outBuffInfo.flags);*/ 


        //while (outputBufferIndex > -1) 
        //{ 

         outputBuffer[outputBufferIndex].position(outBuffInfo.offset); 
         outputBuffer[outputBufferIndex].get(writeBuffer,0,outBuffInfo.size); 

         fos.write(writeBuffer,0, outBuffInfo.size); 
         // logger.log(Level.INFO,"Writing = "+outBuffInfo.size+" bytes"); 


         outputBuffer[outputBufferIndex].clear(); 

         codec.releaseOutputBuffer(outputBufferIndex, false); 

         if (outBuffInfo.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) 
         { 
          codec.flush(); 
          codec.stop(); 
          codec.release(); 
          break; 
         } 

         //outputBufferIndex = codec.dequeueOutputBuffer(outBuffInfo, 1000); 
         //logger.log(Level.INFO,"nextOutputBuffer = "+outputBufferIndex); 
        //} 

       } while (outBuffInfo.flags != MediaCodec.BUFFER_FLAG_END_OF_STREAM); 

       fis.close(); 
       fos.flush(); 
       fos.close(); 



      } 
      catch (Exception e) 
      { 
       //Logger.getLogger(MainActivity.class.getSimpleName()).log(Level.INFO, "Codec Error",e); 
      } 

      //logger.log(Level.INFO,"Done"); 

      return null; 
     } 

    }.execute(); 
} 
+0

コードの関連部分を投稿する必要があります。さもなければ、あなたが間違っているかもしれないことを他の人が理解することは、ほぼ不可能になります。 – Michael

+0

エンコードされたファイルには、その生のファイルのヘッダがありません – tikson

+0

このファイルを作成できましたか? – Soham

答えて

3

アンドロイドAACライブラリ https://github.com/timsu/android-aac-enc

は、このライブラリを通して、あなたのバッファを渡して試してみてくださいあります。それは助けるかもしれない。

9

コンテナを選択する必要があります。私はadtsを好む。

コンテナに十分な大きさのレイにペイロードデータをコピーしてください。ビットを追加してください。だから私のソリューションのためのインターネットを精練した後、私はいくつかのスニペットを働いていた場所に

方法 'fillInADTSHeader'

profile =(configParams[0]>>3)&0x1f; 

    frequency_index = (this.configParams[0]&0x7) <<1 | (this.configParams[1]>>7) &0x1; 

    channel_config = (this.configParams[1]>>3) &0xf; 

    int finallength = encoded_length + 7;  
    ENCodedByteArray[0] = (byte) 0xff; 
    ENCodedByteArray[1] = (byte) 0xf1; 
    ENCodedByteArray[2] = (byte) (((profile - 1) << 6) + (frequency_index << 2) +(channel_config >> 2)); 
    ENCodedByteArray[3] = (byte) (((channel_config & 0x3) << 6) + (finallength >> 11)); 
    ENCodedByteArray[4] = (byte)((finallength & 0x7ff) >> 3); 
    ENCodedByteArray[5] = (byte) (((finallength & 7) << 5) + 0x1f) ; 
    ENCodedByteArray[6] = (byte) 0xfc; 

  byte chunkADTS[]=new byte[info.size + 7]; 
      fillInADTSHeader(chunkADTS,info.size); 
      outputBuffers[bR].get(chunkADTS,7,info.size); 
      buffer.pushData(chunkADTS); 

のようなものを使用して...など、Shoutcastはで

を果たすべき
関連する問題