Convertir PCM a AAC o MP4 archivo sin MediaMuxer

Tengo que convertir un archivo PCM a AAC o MP4 archivo. Hasta ahora, lo hice con MediaCodec y MediaMuxer , pero MediaMuxer es compatible con Android 4.3. ¿Existe un método para realizar la conversión sin el uso de MediaMuxer ?

Mi código es este:

 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(); 

Como ya señaló, no hay ninguna API del sistema público compatible con la versión anterior de Android para este tipo de trabajo.

De todos modos, puede perseguir una solución personalizada utilizando un codificador nativo (como FFMPEG ). Puedo sugerirle lo siguiente: timsu / android-aac-enc

Proyecto de codificador AAC de Android

Extracción de Android Stagefright VO AAC codificador con una API de Java agradable.

Este proyecto ofrece una API Java sencilla para el codificador JNI subyacente , y debería estar listo para usar ya que la biblioteca nativa ya está compilada para arquitecturas ARM genéricas (tenga en cuenta que no lo he probado). Toda la biblioteca es sólo 500kb por lo que no engordar su APK que mucho.

Para una prueba rápida, importe en su proyecto las siguientes partes:

  1. Enlaces Java para el nativo AAC encorder
  2. Codificador AAC precompilado .so library
  3. Ejemplo de uso (codificación de voz)

Debe ser capaz de adaptar fácilmente el ejemplo a su código.

  • Mediacodec jelly-bean
  • Adición de un recurso de imagen sobre archivo de vídeo desde la tarjeta sd mediante ffmpeg o MediaMuxer para android
  • Android descifrar y reproducir mp4 en tiempo de ejecución
  • Metadatos de rotación de vídeo Mp4
  • Reproducir vídeo Mp4 desde el servidor android
  • Uso de jcodec SequenceEncoder
  • Android, ¿cómo establecer los metadatos en el archivo MP4?
  • Biblioteca para apoyar H.264 AVC. Mp4 en Android 2.2, 2.3?
  • Cómo combinar múltiples archivos .mp4 en .mp4 simple ffmpeg android
  • Android: guarda una secuencia rtsp (h264) en un archivo mp4
  • Decodificar mp4 / h.264 usando MediaCodec sin MediaExtractor, formato de unidad de acceso esperado
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.