您可以使用
MediaRecorder将流直接记录到AAC,但似乎没有办法将现有的PCM / WAV文件编码到AAC.编码到AAC的能力在Android中本身存在,我想使用它.有没有办法用预先存在的音频文件?
解决方法
看看这个美丽(和完美的)例子:
Mp4ParserSample
Mp4ParserSample
看看类的最后一部分(335-442行),转换Runnable对象只是做这个工作!您必须根据需要调整代码,调整输入和输出文件路径以及转换参数(采样率,比特率等).
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,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,dstBuf.limit()); Log.e("bytesRead","Readed "+bytesRead); if (bytesRead == -1) { // -1 implies EOS hasMoreData = false; codec.queueInputBuffer(inputBufIndex,(long) presentationTimeUs,MediaCodec.BUFFER_FLAG_END_OF_STREAM); } else { totalBytesRead += bytesRead; dstBuf.put(tempBuffer,bytesRead); codec.queueInputBuffer(inputBufIndex,bytesRead,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... } };