使用 AudioRecord 实时获取音量
创建一个 AudioRecord 实例并持续读取音频数据,计算音量大小。AudioRecord 适用于需要原始音频数据的场景。
private void startRecording() {
int minBufferSize = AudioRecord.getMinBufferSize(
SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT
);
AudioRecord recorder = new AudioRecord(
MediaRecorder.AudioSource.MIC,
SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
minBufferSize
);
short[] buffer = new short[minBufferSize];
recorder.startRecording();
while (isRecording) {
int readSize = recorder.read(buffer, 0, minBufferSize);
if (readSize > 0) {
double amplitude = calculateAmplitude(buffer, readSize);
// 更新UI或处理音量值
}
}
recorder.stop();
recorder.release();
}
private double calculateAmplitude(short[] buffer, int readSize) {
double sum = 0;
for (int i = 0; i < readSize; i++) {
sum += buffer[i] * buffer[i];
}
return Math.sqrt(sum / readSize);
}
使用 Visualizer 获取音乐播放音量
通过 Visualizer 获取当前媒体播放的音量,适用于音乐播放器等场景。
private void setupVisualizer(int audioSessionId) {
Visualizer visualizer = new Visualizer(audioSessionId);
visualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
visualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
// 波形数据
}
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
// 计算FFT获取音量
float magnitude = (float) Math.log10(Math.abs(fft[0]) + 1);
// 更新UI或处理音量值
}
}, Visualizer.getMaxCaptureRate(), false, true);
visualizer.setEnabled(true);
}
使用 MediaRecorder 获取麦克风音量
通过 MediaRecorder 的 getMaxAmplitude 方法获取当前麦克风输入的最大振幅。
private void startMeasuring() {
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile("/dev/null"); // 不需要实际保存文件
try {
recorder.prepare();
recorder.start();
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
int amplitude = recorder.getMaxAmplitude();
// 更新UI或处理音量值
}
}, 0, 100); // 每隔100毫秒获取一次
} catch (IOException e) {
e.printStackTrace();
}
}
注意事项
- 需要添加麦克风权限:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
- 动态权限检查是必要的,特别是在 Android 6.0 及以上版本
- AudioRecord 和 Visualizer 的方法适用于不同场景,选择适合需求的方案
- 音量数值通常需要根据实际需求进行归一化或对数转换
- 持续获取音频数据可能消耗较多资源,适当调整采样率和缓冲区大小