Ошибка аудиорегистратора Androide (Wav Recorder)
Я работаю над android-приложением, в котором хочу записать голос пользователя в формате wav и выполнить его обработку. Я хочу частоту дискретизации 22050 Гц и 16-битный подписанный формат с моноканалом. Я получил некоторый код, выполнив поиск в google, и интегрировал его в свое приложение, но когда я запускаю свое приложение, оно дает мне 3 ошибки:
E/AudioRecord: AudioFlinger could not create record track, status: -1 E/AudioRecord-JNI: Error creating AudioRecord instance: initialization check failed with status -1. E/android.media.AudioRecord: Error code -20 when initializing native AudioRecord object.
Я добавил разрешение в манифест, но ошибка сохраняется.
1. Wavrecordnew.java
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.TimerTask; import java.util.Timer; 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.os.Handler; import android.view.View; import android.widget.Button; public class Wavrecordernew { private static final int RECORDER_BPP = 16; private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav"; private static final String AUDIO_RECORDER_FOLDER = "Automator"; private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw"; private static final int RECORDER_SAMPLERATE = 22050; private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO; private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; private static AudioRecord recorder = null; private static int bufferSize = 0; //bufferSize *= 2; private static Thread recordingThread = null; private static boolean isRecording = false; private static String filenme,wavpath; // bufferSize = AudioRecord.getMinBufferSize(8000,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT); private static String getFilename(){ String filepath = wavpath; File file = new File(filepath,AUDIO_RECORDER_FOLDER); if(!file.exists()){ file.mkdirs(); } return (file.getAbsolutePath() + "/" + filenme); } private static String getTempFilename(){ String filepath = wavpath; File file = new File(filepath,AUDIO_RECORDER_FOLDER); if(!file.exists()){ file.mkdirs(); } File tempFile = new File(filepath,AUDIO_RECORDER_TEMP_FILE); if(tempFile.exists()) tempFile.delete(); return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE); } public static void startRecording(String filepathfrmdis, String filenamefrmdis){ bufferSize = (AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT))*200; filenme = filenamefrmdis; wavpath = filepathfrmdis; recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING, bufferSize); int i = recorder.getState(); if(i==1) recorder.startRecording(); isRecording = true; recordingThread = new Thread(new Runnable() { @Override public void run() { writeAudioDataToFile(); } },"AudioRecorder Thread"); recordingThread.start(); new java.util.Timer().schedule( new java.util.TimerTask() { @Override public void run() { stopRecording(); } }, 9000 ); } private static void writeAudioDataToFile(){ byte data[] = new byte[bufferSize]; String filename = getTempFilename(); FileOutputStream os = null; try { os = new FileOutputStream(filename); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } int read = 0; if(null != os){ while(isRecording){ read = recorder.read(data, 0, bufferSize); if(AudioRecord.ERROR_INVALID_OPERATION != read){ try { os.write(data); } catch (IOException e) { e.printStackTrace(); } } } try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } private static void stopRecording(){ if(null != recorder){ isRecording = false; int i = recorder.getState(); if(i==1) recorder.stop(); recorder.release(); recorder = null; recordingThread = null; } copyWaveFile(getTempFilename(),getFilename()); deleteTempFile(); } private static void deleteTempFile() { File file = new File(getTempFilename()); file.delete(); } private static void copyWaveFile(String inFilename,String outFilename){ FileInputStream in = null; FileOutputStream out = null; long totalAudioLen = 0; long totalDataLen = totalAudioLen + 36; long longSampleRate = RECORDER_SAMPLERATE; int channels = 2; long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8; byte[] data = new byte[bufferSize]; try { in = new FileInputStream(inFilename); out = new FileOutputStream(outFilename); totalAudioLen = in.getChannel().size(); totalDataLen = totalAudioLen + 36; //AppLog.logString("File size: " + totalDataLen); WriteWaveFileHeader(out, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate); while(in.read(data) != -1){ out.write(data); } in.close(); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static void WriteWaveFileHeader( FileOutputStream out, long totalAudioLen, long totalDataLen, long longSampleRate, int channels, long byteRate) throws IOException { byte[] header = new byte[44]; header[0] = 'R'; // RIFF/WAVE header header[1] = 'I'; header[2] = 'F'; header[3] = 'F'; header[4] = (byte) (totalDataLen & 0xff); header[5] = (byte) ((totalDataLen >> 8) & 0xff); header[6] = (byte) ((totalDataLen >> 16) & 0xff); header[7] = (byte) ((totalDataLen >> 24) & 0xff); header[8] = 'W'; header[9] = 'A'; header[10] = 'V'; header[11] = 'E'; header[12] = 'f'; // 'fmt ' chunk header[13] = 'm'; header[14] = 't'; header[15] = ' '; header[16] = 16; // 4 bytes: size of 'fmt ' chunk header[17] = 0; header[18] = 0; header[19] = 0; header[20] = 1; // format = 1 header[21] = 0; header[22] = (byte) channels; header[23] = 0; header[24] = (byte) (longSampleRate & 0xff); header[25] = (byte) ((longSampleRate >> 8) & 0xff); header[26] = (byte) ((longSampleRate >> 16) & 0xff); header[27] = (byte) ((longSampleRate >> 24) & 0xff); header[28] = (byte) (byteRate & 0xff); header[29] = (byte) ((byteRate >> 8) & 0xff); header[30] = (byte) ((byteRate >> 16) & 0xff); header[31] = (byte) ((byteRate >> 24) & 0xff); header[32] = (byte) (2 * 16 / 8); // block align header[33] = 0; header[34] = RECORDER_BPP; // bits per sample header[35] = 0; header[36] = 'd'; header[37] = 'a'; header[38] = 't'; header[39] = 'a'; header[40] = (byte) (totalAudioLen & 0xff); header[41] = (byte) ((totalAudioLen >> 8) & 0xff); header[42] = (byte) ((totalAudioLen >> 16) & 0xff); header[43] = (byte) ((totalAudioLen >> 24) & 0xff); out.write(header, 0, 44); } }
2. DisplayRecordingMessageActivity.java (вызов волнового регистратора)
import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.EditText; import android.widget.TextView; import java.io.File; public class DisplayRecordingMessageActivity extends AppCompatActivity { public final static String EXTRA_MESSAGE_USER_NAME = "com.mycompany.myfirstapp.MESSAGE"; private static Wavrecordernew mRecorder; //private static Wavrecordernew mRecordernew; private static int filenum = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_display_recording_message); Intent intentrecordingtranfred = getIntent(); String message = intentrecordingtranfred.getStringExtra(MyActivity.EXTRA_MESSAGE_RECORDING); TextView textView = (TextView) findViewById(R.id.recorderintructionstxtView); textView.setText(message); textView.setTextSize(16); } /** Called when the user clicks the Save button */ public void saveusername(View view) { EditText editUsername = (EditText) findViewById(R.id.edit_username); String username = editUsername.getText().toString(); if (!("").equals(username)) { String filename = username + filenum + ".wav"; String wavfilepath = this.getFilesDir().getPath(); mRecorder.startRecording(wavfilepath,filename); } else { //popup saying please enter username and press save AlertDialog.Builder builder1 = new AlertDialog.Builder(DisplayRecordingMessageActivity.this); builder1.setTitle("Invalid"); builder1.setMessage("Please Enter your name and then press save"); builder1.setCancelable(false); //builder1.setIcon(R.drawable.delete); builder1.setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert11 = builder1.create(); alert11.show(); } } }
3. AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="in.automator.automator"> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MyActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".DisplayRecordingMessageActivity" android:label="@string/title_activity_display_recording_message" android:parentActivityName=".MyActivity" android:theme="@style/AppTheme.NoActionBar"> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="in.automator.automator.MyActivity" /> </activity> </application> <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission> </manifest>
Я ищу решения с последних 5 дней.
Заранее спасибо.
Richard MacCutchan
Что означают эти коды ошибок?
prafull agrawal
Если бы я знал, зачем бы я спрашивал здесь?
Richard MacCutchan
Как ты думаешь, кто-нибудь здесь поймет, что они означают? Мы понятия не имеем, откуда взялся этот код, который вы нашли в интернете, или кто его написал.
prafull agrawal
Привет эти ошибки касаются класса AudioRecorder самого android, и я разместил весь код здесь для справки кодеров, если вы не знаете android, то, пожалуйста, не смотрите в него. Благодарим
Richard MacCutchan
Если вам нужна помощь в решении этой проблемы, пожалуйста, предоставьте полную информацию, а не сбрасывайте весь свой код и ожидайте, что другие люди сделают отладку.
prafull agrawal
Я опубликовал только свой полный код и код wav recorder, который я использовал в своем коде,
Я забыл упомянуть справочную ссылку для кода записи wav http://www.edumobile.org/android/audio-recording-in-wav-format-in-android-programming/