2011-12-15 34 views
12

Bạn có thể sử dụng MediaRecorder để ghi luồng trực tiếp vào AAC nhưng dường như không có cách nào để mã hóa tệp PCM/WAV hiện có thành AAC. Khả năng mã hóa thành AAC tồn tại nguyên bản trong Android và tôi muốn sử dụng nó. Không có cách nào để làm điều đó với một tập tin âm thanh có sẵn từ trước?Mã hóa wav thành AAC trên Android

Trả lời

1

bạn có thể bị bẩn tay với mã gốc và sử dụng giao diện IOMX C++ cho bộ giải mã trong khung công tác. Nhưng điều này là xây dựng nhạy cảm và sẽ không hoạt động trên các điện thoại khác và hương vị Android.

Tùy chọn khác là cổng mã hóa aac mã nguồn mở như ffmpeg và viết ứng dụng lên trên jni. Sẽ làm việc ít nhất với các điện thoại có cùng kiến ​​trúc (arm-9, cortex a8 ..).

JB có MediaCodec chỉ để thực hiện mong muốn của bạn. Nhưng vấn đề sẽ là cơ sở cài đặt cho các thiết bị với JB sẽ được nạc cho một số thời gian hơn.

http://developer.android.com/about/versions/android-4.1.html#Multimedia

+0

Có ví dụ nào về cách sử dụng MediaCodec không? – Taras

3

Nhìn vào đẹp (và hoàn toàn làm việc) ví dụ này: Mp4ParserSample

Nhìn vào phần cuối cùng của lớp (hàng 335-442), các đối tượng Runnable convert chỉ cần làm công việc! Bạn phải định dạng mã đó theo nhu cầu của mình, điều chỉnh đầu vào và đường dẫn tệp đầu ra và các tham số chuyển đổi (tỷ lệ lấy mẫu, tốc độ bit, v.v.).

public static final String AUDIO_RECORDING_FILE_NAME = "audio_Capturing-190814-034638.422.wav"; // Input PCM file 
public static final String COMPRESSED_AUDIO_FILE_NAME = "convertedmp4.m4a"; // Output MP4/M4A file 
public static final String COMPRESSED_AUDIO_FILE_MIME_TYPE = "audio/mp4a-latm"; 
public static final int COMPRESSED_AUDIO_FILE_BIT_RATE = 64000; // 64kbps 
public static final int SAMPLING_RATE = 48000; 
public static final int BUFFER_SIZE = 48000; 
public static final int CODEC_TIMEOUT_IN_MS = 5000; 
String LOGTAG = "CONVERT AUDIO"; 
Runnable convert = new Runnable() { 
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) 
    @Override 
    public void run() { 
     android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND); 
     try { 
      String filePath = Environment.getExternalStorageDirectory().getPath() + "/" + AUDIO_RECORDING_FILE_NAME; 
      File inputFile = new File(filePath); 
      FileInputStream fis = new FileInputStream(inputFile); 

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

      MediaMuxer mux = new MediaMuxer(outputFile.getAbsolutePath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); 

      MediaFormat outputFormat = MediaFormat.createAudioFormat(COMPRESSED_AUDIO_FILE_MIME_TYPE,SAMPLING_RATE, 1); 
      outputFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC); 
      outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, COMPRESSED_AUDIO_FILE_BIT_RATE); 
      outputFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 16384); 

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

      ByteBuffer[] codecInputBuffers = codec.getInputBuffers(); // Note: Array of buffers 
      ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers(); 

      MediaCodec.BufferInfo outBuffInfo = new MediaCodec.BufferInfo(); 
      byte[] tempBuffer = new byte[BUFFER_SIZE]; 
      boolean hasMoreData = true; 
      double presentationTimeUs = 0; 
      int audioTrackIdx = 0; 
      int totalBytesRead = 0; 
      int percentComplete = 0; 
      do { 
       int inputBufIndex = 0; 
       while (inputBufIndex != -1 && hasMoreData) { 
        inputBufIndex = codec.dequeueInputBuffer(CODEC_TIMEOUT_IN_MS); 

        if (inputBufIndex >= 0) { 
         ByteBuffer dstBuf = codecInputBuffers[inputBufIndex]; 
         dstBuf.clear(); 

         int bytesRead = fis.read(tempBuffer, 0, dstBuf.limit()); 
         Log.e("bytesRead","Readed "+bytesRead); 
         if (bytesRead == -1) { // -1 implies EOS 
          hasMoreData = false; 
          codec.queueInputBuffer(inputBufIndex, 0, 0, (long) presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM); 
         } else { 
          totalBytesRead += bytesRead; 
          dstBuf.put(tempBuffer, 0, bytesRead); 
          codec.queueInputBuffer(inputBufIndex, 0, bytesRead, (long) presentationTimeUs, 0); 
          presentationTimeUs = 1000000l * (totalBytesRead/2)/SAMPLING_RATE; 
         } 
        } 
       } 
       // Drain audio 
       int outputBufIndex = 0; 
       while (outputBufIndex != MediaCodec.INFO_TRY_AGAIN_LATER) { 
        outputBufIndex = codec.dequeueOutputBuffer(outBuffInfo, CODEC_TIMEOUT_IN_MS); 
        if (outputBufIndex >= 0) { 
         ByteBuffer encodedData = codecOutputBuffers[outputBufIndex]; 
         encodedData.position(outBuffInfo.offset); 
         encodedData.limit(outBuffInfo.offset + outBuffInfo.size); 
         if ((outBuffInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0 && outBuffInfo.size != 0) { 
          codec.releaseOutputBuffer(outputBufIndex, false); 
         }else{ 
          mux.writeSampleData(audioTrackIdx, codecOutputBuffers[outputBufIndex], outBuffInfo); 
          codec.releaseOutputBuffer(outputBufIndex, false); 
         } 
        } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { 
         outputFormat = codec.getOutputFormat(); 
         Log.v(LOGTAG, "Output format changed - " + outputFormat); 
         audioTrackIdx = mux.addTrack(outputFormat); 
         mux.start(); 
        } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { 
         Log.e(LOGTAG, "Output buffers changed during encode!"); 
        } else if (outputBufIndex == MediaCodec.INFO_TRY_AGAIN_LATER) { 
         // NO OP 
        } else { 
         Log.e(LOGTAG, "Unknown return code from dequeueOutputBuffer - " + outputBufIndex); 
        } 
       } 
       percentComplete = (int) Math.round(((float) totalBytesRead/(float) inputFile.length()) * 100.0); 
       Log.v(LOGTAG, "Conversion % - " + percentComplete); 
      } while (outBuffInfo.flags != MediaCodec.BUFFER_FLAG_END_OF_STREAM); 
      fis.close(); 
      mux.stop(); 
      mux.release(); 
      Log.v(LOGTAG, "Compression done ..."); 
     } catch (FileNotFoundException e) { 
      Log.e(LOGTAG, "File not found!", e); 
     } catch (IOException e) { 
      Log.e(LOGTAG, "IO exception!", e); 
     } 

     //mStop = false; 
     // Notify UI thread... 
    } 
}; 
Các vấn đề liên quan