Объекта осуществление аудиозаписи не инициализации
ниже мой код audioRecord
объект не инициализируется. Я попытался переместить его в onCreate
метод и сделал его глобальным. Я зарегистрировал состояние, и это возвращает значение 1
что означает готовность к использованию. Отладчик говорит, что startRecording
вызывается на неинициализированный объект. Он также говорит, что он не может получить источник звука.
почему я получаю эти ошибки?
package com.tecmark;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class recorder extends Activity {
private Thread thread;
private boolean isRecording;
private AudioRecord recorder;
private FileOutputStream os;
private BufferedOutputStream bos;
private DataOutputStream dos;
private TextView text;
private int audioSource = MediaRecorder.AudioSource.MIC;
private int sampleRate = 22050;
private int channel = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int encoding = AudioFormat.ENCODING_PCM_16BIT;
private int result = 0;
private int bufferSize;
private byte[] buffer;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.v("onCreate", "layout set, about to init audiorec obj");
text = (TextView)findViewById(R.id.TextView01);
bufferSize = AudioRecord.getMinBufferSize(sampleRate,channel,encoding);
buffer = new byte[bufferSize];
recorder = new AudioRecord(audioSource, sampleRate,channel,encoding,
AudioRecord.getMinBufferSize(sampleRate, channel,encoding));
Log.i("recorder obj state",""+recorder.getRecordingState());
}
public void onClickPlay(View v){
}
public void record(){
Log.i("inside record method", "******");
File path = Environment.getExternalStorageDirectory();
Log.v("file path", ""+path.getAbsolutePath());
File file = new File(path, "test.wav");
if(file.exists()){
file.delete();
}
path.mkdirs();
Log.v("file path", ""+file.getAbsolutePath());
try {
os = new FileOutputStream(file);
bos = new BufferedOutputStream(os);
dos = new DataOutputStream(bos);
} catch (Exception e1) {
e1.printStackTrace();
}
int bufferSize = AudioRecord.getMinBufferSize(sampleRate,channel,encoding);
byte[] buffer = new byte[bufferSize];
recorder.startRecording();
isRecording = true;
try{
while (isRecording){
result = recorder.read(buffer, 0, bufferSize);
for(int a=0; a<result;a++){
dos.write(buffer[a]);
if(!isRecording){
recorder.stop();
break;
}
}
}
dos.flush();
dos.close();
}catch(Exception e){
e.printStackTrace();
}
}// end of record method
public void onClickStop(View v){
Log.v("onClickStop", "stop clicked");
isRecording=false;
}
public void onClickReverse(View v){
Log.v("onClickReverse", "reverse clicked");
}
public void onClickRecord(View v){
Log.v("onClickRecourd", "record clicked, thread gona start");
text.setText("recording");
thread = new Thread(new Runnable() {
public void run() {
isRecording = true;
record();
}
});
thread.start();
isRecording = false;
}
}//end of class
Logcat
01-30 15:23:16.724: ERROR/AudioRecord(12817): Could not get audio input for record source 1 01-30 15:23:16.729:
ERROR/AudioRecord-JNI(12817): Error creating AudioRecord instance: initialization check failed. 01-30 15:23:16.729:
ERROR/AudioRecord-Java(12817): [ android.media.AudioRecord ] Error code
-20 when initializing native AudioRecord object. 01-30 15:23:16.729: INFO/recorder obj state(12817): 1 01-30 15:23:16.729:
WARN/dalvikvm(12817): threadid=13: thread exiting with uncaught exception (group=0x4001b180) 01-30 15:23:16.729:
ERROR/AndroidRuntime(12817): Uncaught handler: thread Thread-7 exiting due to uncaught exception 01-30 15:23:16.739:
ERROR/AndroidRuntime(12817): java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord. 01-30 15:23:16.739:
ERROR/AndroidRuntime(12817): at android.media.AudioRecord.startRecording(AudioRecord.java:495) 01-30 15:23:16.739:
ERROR/AndroidRuntime(12817): at com.tecmark.recorder.record(recorder.java:114) 01-30 15:23:16.739:
ERROR/AndroidRuntime(12817): at com.tecmark.recorder.run(recorder.java:175) 01-30 15:23:16.739:
ERROR/AndroidRuntime(12817): at java.lang.Thread.run(Thread.java:1096)
12 ответов:
трюк с использованием AudioRecord заключается в том, что каждое устройство может иметь разные настройки инициализации, поэтому вам придется создать метод, который будет перебирать все возможные комбинации битовых скоростей, кодирования и т. д.
private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 }; public AudioRecord findAudioRecord() { for (int rate : mSampleRates) { for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT }) { for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) { try { Log.d(C.TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: " + channelConfig); int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat); if (bufferSize != AudioRecord.ERROR_BAD_VALUE) { // check if we can instantiate and have a success AudioRecord recorder = new AudioRecord(AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize); if (recorder.getState() == AudioRecord.STATE_INITIALIZED) return recorder; } } catch (Exception e) { Log.e(C.TAG, rate + "Exception, keep trying.",e); } } } } return null; } AudioRecord recorder = findAudioRecord(); recorder.release();
У меня была такая же проблема, она была решена путем помещения
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
в манифест.
Так как леденец, вы также должны специально попросить пользователя для каждого разрешения. Как они могли их отозвать. Убедитесь, что разрешение.
согласно javadocs, все устройства гарантированно поддерживают этот формат (для записи):
44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT.
изменить на CHANNEL_OUT_MONO для воспроизведения.
теперь, с lollipop, вам нужно специально попросить пользователя для каждого разрешения. Убедитесь, что разрешение.
проблема с инициализацией нескольких объектов AudioRecord может быть исправлена с помощью
audioRecord.release();
перед созданием следующего объекта... Подробнее здесь: Android AudioRecord - не будет инициализировать 2-й раз
даже после выполнения всех вышеперечисленных шагов я получал тот же вопрос, что работало для меня было то, что мой ОС был зефир, и я должен был попросить разрешения.
просто была такая же проблема. Решение состояло в том, чтобы перезагрузить устройство. Во время игры с кодом я не выпустил объект AudioRecord, который, очевидно, вызвал застревание аудиоустройства. Чтобы проверить, работает ли аудиоустройство или нет, я загрузил Audalyzer из Google Play.
Если ваша система мобильного телефона Android M или выше, возможно, вам нужно применить разрешение на запись звука в Android M.http://developer.android.com/guide/topics/security/permissions.html
Я заметил, что когда SDCard на avd, который я запускаю, заполняется, конструктор AudioRecord возвращает null. Вы пробовали очистить SD-карту?
в моем случае мне пришлось вручную разрешить разрешение в android 7 для микрофона, как прокомментировал Шон Чжу.
Я думаю, что это связано с потоком, не зная, что вы приостановили основное действие и все еще пытаетесь записать после остановки рекордера.
Я решил это, изменив мои методы onResume() и onPause() для изменения логического значения isRecording.
public void onResume() { ... isRecording = true; } public void onPause() { ... isRecording = false; }
затем в вашем потоке, окружите оба ваших
startRecording()
иstop()
С помощью if-операторов, проверяющих isRecording:if(isRecording) recorder.startRecording(); ... if(isRecording) recorder.stop(); // which you've done
я переписал ответ от @DustinB для всех, кто использует Xamarin Android AudioRecord с C#.
int[] sampleRates = new int[] { 44100, 22050, 11025, 8000 }; Encoding[] encodings = new Encoding[] { Encoding.Pcm8bit, Encoding.Pcm16bit }; ChannelIn[] channelConfigs = new ChannelIn[]{ ChannelIn.Mono, ChannelIn.Stereo }; //Not all of the formats are supported on each device foreach (int sampleRate in sampleRates) { foreach (Encoding encoding in encodings) { foreach (ChannelIn channelConfig in channelConfigs) { try { Console.WriteLine("Attempting rate " + sampleRate + "Hz, bits: " + encoding + ", channel: " + channelConfig); int bufferSize = AudioRecord.GetMinBufferSize(sampleRate, channelConfig, encoding); if (bufferSize > 0) { // check if we can instantiate and have a success AudioRecord recorder = new AudioRecord(AudioSource.Mic, sampleRate, channelConfig, encoding, bufferSize); if (recorder.State == State.Initialized) { mBufferSize = bufferSize; mSampleRate = sampleRate; mChannelConfig = channelConfig; mEncoding = encoding; recorder.Release(); recorder = null; return true; } } } catch (Exception ex) { Console.WriteLine(sampleRate + "Exception, keep trying." + ex.Message); } } } }