Android MediaRecorder在API 24以下版本的暂停实现方案问询
Great question—supporting pause/resume functionality for audio recording on older Android versions (pre-API 24) is a common challenge, but there are two reliable approaches you can implement in your app.
1. Segmented Recording + Post-Recording Merge (Simplest Approach)
This is the most straightforward method, since it leverages the MediaRecorder API you're already familiar with, just with extra steps to manage multiple audio files and combine them later.
How it works:
- When pause is triggered: Stop the current
MediaRecorderinstance, save the recorded audio as a temporary file (e.g.,temp_recording_1.mp3), then release the recorder. - When resume is triggered: Initialize a new
MediaRecorderwith the exact same configuration (sample rate, audio encoder, output format, etc.) as the original, start recording to a new temporary file (e.g.,temp_recording_2.mp3). - When recording finishes: Merge all temporary audio files into a single final audio file, then delete the temporary files to free up storage.
Example code snippets:
Stopping a recording to a temp file:
// Pause logic if (mediaRecorder != null && isRecording) { mediaRecorder.stop(); mediaRecorder.release(); mediaRecorder = null; isRecording = false; // Add the temp file path to a list for later merging tempRecordingFiles.add(currentTempFilePath); }
Merging files with MediaExtractor & MediaMuxer (native Android API):
You'll need to iterate through each temp file, extract its audio track, and write it to a single output file using MediaMuxer. Here's a simplified outline:
MediaMuxer muxer = new MediaMuxer(finalOutputPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); int audioTrackIndex = -1; for (String tempFile : tempRecordingFiles) { MediaExtractor extractor = new MediaExtractor(); extractor.setDataSource(tempFile); // Find the audio track for (int i = 0; i < extractor.getTrackCount(); i++) { MediaFormat format = extractor.getTrackFormat(i); String mime = format.getString(MediaFormat.KEY_MIME); if (mime.startsWith("audio/")) { extractor.selectTrack(i); if (audioTrackIndex == -1) { audioTrackIndex = muxer.addTrack(format); muxer.start(); } break; } } // Write the track data to the muxer ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024); MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); int readSampleSize; while ((readSampleSize = extractor.readSampleData(buffer, 0)) > 0) { bufferInfo.offset = 0; bufferInfo.size = readSampleSize; bufferInfo.presentationTimeUs = extractor.getSampleTime(); bufferInfo.flags = extractor.getSampleFlags(); muxer.writeSampleData(audioTrackIndex, buffer, bufferInfo); extractor.advance(); } extractor.release(); } muxer.stop(); muxer.release();
Pros & Cons:
- ✅ Easy to implement with minimal changes to existing
MediaRecordercode - ✅ No need to handle low-level audio encoding
- ❌ Minor audio gaps might occur between segments (mitigated by matching recorder config exactly)
- ❌ Requires managing temporary files and cleaning them up post-merge
2. Use AudioRecord with Manual Encoding (More Flexible)
For seamless pause/resume (no gaps between pause and resume), you can use the lower-level AudioRecord API, which gives you direct access to raw PCM audio data. You'll need to handle encoding this raw data into a playable format (like AAC or MP3) yourself.
How it works:
- Initialize
AudioRecord: Configure it with your desired sample rate, channel config, and audio format (e.g.,ENCODING_PCM_16BIT). - Start recording: Read raw PCM data from
AudioRecordin a background thread. - Pause: Stop writing the PCM data to your output file, but keep
AudioRecordrunning (or stop it and restart on resume—just note that restarting might cause a tiny gap). - Resume: Resume writing PCM data to the same output file.
- Finish: Stop
AudioRecord, then encode the accumulated PCM data into your target audio format (usingMediaCodecfor native encoding, or a library like LAME for MP3).
Key Notes:
- You'll need to handle audio encoding separately. For AAC,
MediaCodecis a good native option. For MP3, you'll likely need to integrate a third-party library like LAME (since Android's native codecs don't support MP3 encoding by default on older versions). - Always run the
AudioRecordread/write logic on a background thread to avoid blocking the main thread.
Pros & Cons:
- ✅ Seamless pause/resume with no audio gaps
- ✅ Full control over the recording process
- ❌ Higher complexity, especially with encoding
- ❌ More boilerplate code to handle thread management and encoding errors
Final Recommendations
- If you want a quick, low-maintenance solution, go with the segmented recording + merge approach. It's reliable and requires the least amount of new code.
- If you need professional-grade, gapless pause/resume, invest time in the AudioRecord + manual encoding method. Just be prepared to handle the encoding complexity.
Don't forget to handle runtime storage permissions (especially on Android 6.0+) and test thoroughly on older devices to ensure compatibility!
内容的提问来源于stack exchange,提问作者Dishonered




