2015-10-12 21 views
6

PCM dosyasını AAC veya MP4 dosyasına dönüştürmem gerekiyor. Şimdiye kadar, ben MediaCodec ve MediaMuxer ile yaptım, ancak MediaMuxer Android 4.3'ten desteklenmektedir. MediaMuxer kullanmadan dönüştürme yapmak için bir yöntem var mı?MediaMuxer olmadan PCM'yi AAC veya MP4 dosyasına dönüştürme

Benim kod şudur: Zaten belirttiği gibi

MediaMuxer mux = null; 
try { 
    File inputFile = new File(filePath + ".pcm"); 
    FileInputStream fis = new FileInputStream(inputFile); 
    mux = new MediaMuxer(filePath + ".mp4", 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); 

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

    ByteBuffer[] codecInputBuffers = codec.getInputBuffers(); 
    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; 

    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()); 
       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("AUDIO", "Output format changed - " + outputFormat); 
       audioTrackIdx = mux.addTrack(outputFormat); 
       mux.start(); 
      } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { 
       Log.e("AUDIO", "Output buffers changed during encode!"); 
      } else if (outputBufIndex != MediaCodec.INFO_TRY_AGAIN_LATER){ 
       Log.e("AUDIO", "Unknown return code from dequeueOutputBuffer - " + outputBufIndex); 
      } 
     } 
     percentComplete = (int) Math.round(((float) totalBytesRead/(float) inputFile.length()) * 100.0); 
     Log.v("AUDIO", "Conversion % - " + percentComplete); 
    } while (outBuffInfo.flags != MediaCodec.BUFFER_FLAG_END_OF_STREAM); 

    fis.close(); 
    mux.stop(); 
    mux.release(); 
+1

Closevoter: Lütfen araçlar öneren cevapların bir soru sorduğunu ve bunun konu dışı olduğunu belirtmez. –

cevap

4

, işin bu tür Android eski sürümü ile uyumlu hiçbir kamu sistem API var.

Neyse, bir yerli kodlayıcı (gibi FFMPEG) kullanarak özel bir çözüm takip edebilirsiniz. Güzel bir Java API ile timsu/android-aac-enc

Android AAC Encoder projesi

Ekstraksiyon Android'in Stagefright VO AAC kodlayıcı: Aşağıdaki size önerilen olabilir.

Bu proje yatan JNI'yı kodlayıcı için kolay bir Java API sunar ve zaten jenerik ARM için derlenmiş yerli kütüphaneye beri kullanıma hazır olmalıdır mimariler (ben cenneti' unutmayın t test etti. Tüm kütüphane sadece 500kb, bu yüzden APK'nızı o kadar şişirmeyecek.

hızlıca denemek için

, projenizde ithalat aşağıdaki parçalar: yerli AAC için

  1. Java bindings Encorder
  2. Önceden derlenmiş AAC encoder .so library kullanım
  3. Example (konuşma kodlaması)

Örneği kodunuza kolayca uyarlayabilirsiniz.

İlgili konular