title: How to decode AAC format(mp4 audio file) to PCM format in Android
body: <p>I have an mp4 file with only one audio track in AAC format. I would like to convert this mp4 file to an audio file in PCM format. I can extract the audio file in AAC format from the mp4 file successfully. But I can not decode AAC format to PCM format. </p>
  
  <p>The following code works without any errors and saves the PCM data to a file. But this audio in PCM format can not be opened with any media player. It says that the file is corrupted. I tried to decode AAC format to PCM format with ffmpeg and there is no problem with ffmpeg. But I do not want to use ffmpeg library because of the library size. </p>
  
  <p>Firstly, I tried to give the mp4 file path to inputfilePath and the output file is created and saved successfully. But this output file is not opened in any media player. </p>
  
  <p>extractAudioFromVideo(".../input.mp4", ".../output.wav");</p>
  
  <p>Secondly, I extracted the AAC audio file from the mp4 file successfully. And I tried to give the ACC file path to inputfilePath and nothing changed in the output. </p>
  
  <p>extractAudioFromVideo(".../input.aac", ".../output.wav");</p>
  
  <p>static void extractAudioFromVideo(@NonNull String inputfilePath, @NonNull String outputFilePath) {</p>
  
  <pre><code>    try
      {
          OutputStream outputStream = new FileOutputStream(outputFilePath);
  
          MediaExtractor extractor = new MediaExtractor();
          extractor.setDataSource(inputfilePath);
  
          MediaCodec mediaCodec = null;
          for(int index = 0; index &lt; extractor.getTrackCount(); index++)
          {
              MediaFormat format = extractor.getTrackFormat(index);
              String mime = format.getString(MediaFormat.KEY_MIME);
              if(mime.startsWith("audio/"))
              {
                  extractor.selectTrack(index);
                  mediaCodec = MediaCodec.createDecoderByType(mime);
                  mediaCodec.configure(format, null, null, 0);
                  break;
              }
          }
  
          if (mediaCodec == null)
          {
              Log.e("Converter", "Can't find audio info");
              return;
          }
  
          mediaCodec.start();
  
          MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
          ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
          ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers();
  
          boolean isEOS = false;
          while (true)
          {
              if (!isEOS)
              {
                  int inputIndex = mediaCodec.dequeueInputBuffer(10000);
                  if (inputIndex &gt;= 0)
                  {
                      ByteBuffer buffer = inputBuffers[inputIndex];
                      int sampleSize = extractor.readSampleData(buffer, 0);
                      if (sampleSize &lt; 0)
                      {
                          Log.d("Converter", "InputBuffer BUFFER_FLAG_END_OF_STREAM");
                          mediaCodec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                          isEOS = true;
                      }
                      else
                      {
                          mediaCodec.queueInputBuffer(inputIndex, 0, sampleSize, extractor.getSampleTime(), 0);
                          extractor.advance();
                      }
                  }
              }
  
              int outputIndex = mediaCodec.dequeueOutputBuffer(info, 10000);
              switch (outputIndex)
              {
                  case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
                      Log.d("Converter", "INFO_OUTPUT_BUFFERS_CHANGED");
                      outputBuffers = mediaCodec.getOutputBuffers();
                      break;
                  case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
                      Log.d("Converter", "New format " + mediaCodec.getOutputFormat());
                      break;
                  case MediaCodec.INFO_TRY_AGAIN_LATER:
                      Log.d("Converter", "dequeueOutputBuffer timed out!");
                      break;
                  default:
                      ByteBuffer buffer = outputBuffers[outputIndex];
                      /*
                      // I tried this line of code but it gives the same result.
                      byte[] chunk = new byte[info.size-info.offset];
                      int position = buffer.position();
                      buffer.get(chunk);
                      buffer.position(position);
                      outputStream.write(chunk,0,info.size-info.offset);
                      */
                      final byte[] chunk = new byte[info.size - info.offset];
                      buffer.get(chunk);
                      buffer.clear();
  
                      if (chunk.length &gt; 0)
                      {
                          outputStream.write(chunk,0,info.size - info.offset);
                      }
  
                      mediaCodec.releaseOutputBuffer(outputIndex, true);
                      break;
              }
  
              if ((info.flags &amp; MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0)
              {
                  Log.d("Converter", "OutputBuffer BUFFER_FLAG_END_OF_STREAM");
                  break;
              }
          }
  
          outputStream.flush();
          outputStream.close();
  
          mediaCodec.stop();
          mediaCodec.release();
  
          extractor.release();
      }
      catch (Exception exception)
      {
          exception.printStackTrace();
      }
  }
  </code></pre>
  
  <p>Should I do something more than this line of code to save it in PCM format or Did I do something wrong?</p>