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:
- Reproducción de un video local de aplicación (.mp4) en una vista web
- Moov átomo en android MeidaRecorder datos registrados
- Aplicación de falla en la fusión de videoclips MP4
- Android VideoView error (1,16) y muestra la pantalla en negro
- ¿Cómo cargar videos de la carpeta de activos? (Para reproducirlas con VideoView)
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();
- Cómo comprimir mp4 video con MediaCodec Android?
- Mp4 vídeo en html5 etiqueta de vídeo no se reproduce en el cromo móvil y safari móvil
- Apoye la velocidad de reproducción usando ExoPlayer
- Android: lee y escribe metadatos .mp4 -Tag
- Fusionar archivos de video mp4 en Android
- Guarda la grabación de vídeo en tiempo real en la tarjeta sd mediante el Socket local en Android - El vídeo no se puede reproducir
- Vista web de Android cargando la página html5 de la tarjeta SD con videos mp4 en varios API
- Error de codificación de vídeo que utiliza datos OnAudioFilterRead
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:
- Enlaces Java para el nativo AAC encorder
- Codificador AAC precompilado .so library
- Ejemplo de uso (codificación de voz)
Debe ser capaz de adaptar fácilmente el ejemplo a su código.
- ¿Cómo puedo colocar dos TextView en una misma línea, en un diseño vertical
- Recuperación de datos del último evento agregado del calendario android