[英]How to use Android media recorder to get max amplitude?
我從MediaRecorder看到過各種帖子,都解決了方法getMaxAmplitude()的問題,但仍然無法解決我的問題。 我想用分貝的聲音幅度不斷更新TextView。 我試圖通過使用調用此方法的函數每隔1秒鍾運行一個處理程序來實現這一目標,但似乎MediaRecorder對象即使在初始化它之后也總是為null(我覺得很奇怪)。 順便說一句,我已經添加了在android中進行音頻錄制的所有必要權限。 我需要在代碼中進行哪些更改才能訪問getMaxAmplitude()方法?
package com.inversepalindrome.sensorbox;
import com.cardiomood.android.controls.gauge.SpeedometerGauge;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Build;
import android.os.Handler;
import android.content.pm.PackageManager;
import android.widget.TextView;
import android.media.MediaRecorder;
import android.support.v4.app.ActivityCompat;
import android.widget.Toast;
import java.io.IOException;
import java.util.Locale;
public class SoundActivity extends AppCompatActivity {
private MediaRecorder mediaRecorder;
private SpeedometerGauge speedometer;
private TextView soundAmplitudeText;
private final int AUDIO_REQUEST_CODE = 200;
private final int AUDIO_RECORDING_DELAY = 1000;
private final double referenceAmplitude = 0.0001;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sound);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.RECORD_AUDIO,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, AUDIO_REQUEST_CODE);
}
speedometer = findViewById(R.id.speedometer);
speedometer.setLabelConverter(new SpeedometerGauge.LabelConverter() {
@Override
public String getLabelFor(double progress, double maxProgress) {
return String.format(Locale.US, "%.1f", progress);
}
});
speedometer.setMaxSpeed(120);
speedometer.setMajorTickStep(20);
speedometer.setMinorTicks(1);
speedometer.setLabelTextSize(32);
speedometer.addColoredRange(0, 40, Color.GREEN);
speedometer.addColoredRange(40, 80, Color.YELLOW);
speedometer.addColoredRange(80, 120, Color.RED);
soundAmplitudeText = findViewById(R.id.soundAmplitudeValueText);
}
@Override
public void onResume(){
super.onResume();
startRecording();
}
@Override
public void onPause(){
super.onPause();
stopRecording();
}
@Override
public void onRequestPermissionsResult(final int requestCode, String[] permissions, int[] grantResults) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (requestCode == AUDIO_REQUEST_CODE) {
startRecording();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
final double amplitude = getAmplitude();
speedometer.setSpeed(amplitude);
soundAmplitudeText.setText(String.format(Locale.US, "%.1f", amplitude));
handler.postDelayed(this, AUDIO_RECORDING_DELAY);
}
}, AUDIO_RECORDING_DELAY);
} else {
Toast.makeText(this, "No audio recording permissions given!", Toast.LENGTH_LONG).show();
}
}
}
private void startRecording(){
if(mediaRecorder != null)
{
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setOutputFile("/dev/null");
try {
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void stopRecording(){
if(mediaRecorder != null) {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
}
}
private double getAmplitude(){
if(mediaRecorder != null){
final double maxAmplitude = mediaRecorder.getMaxAmplitude();
final double amplitude = 20 * Math.log10(maxAmplitude / referenceAmplitude);
return amplitude;
}
else{
return 0.0;
}
}
}
編輯:修復了指出的一些問題之后,我的應用程序在具有以下調試消息的getMaxAmplitudeCall上崩潰:
1501-6480/? E/AudioFlinger: createRecordTrack_l() initCheck failed -12; no control block?
2019-01-18 15:23:54.983 2362-10949/com.google.android.googlequicksearchbox:search E/AudioRecord: AudioFlinger could not create record track, status: -12
2019-01-18 15:23:54.987 2362-10949/com.google.android.googlequicksearchbox:search E/AudioRecord-JNI: Error creating AudioRecord instance: initialization check failed with status -12.
2019-01-18 15:23:54.987 2362-10949/com.google.android.googlequicksearchbox:search E/android.media.AudioRecord: Error code -20 when initializing native AudioRecord object.
if(mediaRecorder != null)
{
mediaRecorder = new MediaRecorder();
您有向后檢查。 所以它永遠不會初始化
答案在我的評論中,但您的問題是您正在呼叫onPause停止錄制,停止並釋放MediaRecorder。 如果您沒有錄制權限,可能會發生這種情況。 當出現詢問權限的對話框時,stopRecording被調用,因此您的錄音機為空並被釋放。
如果您已經具有權限,則不會發生。 試試看。
另外,在startRecording方法中,檢查您的媒體記錄器是否為null。 您是否擁有null的其他區別。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.