Подтвердить что ты не робот

Android: требуется запись микрофонного входа

Есть ли способ записи микрофонного входа в Android во время процесса воспроизведения/просмотра в реальном времени? Я пытался использовать AudioRecord и AudioTrack для этого, но проблема в том, что мое устройство не может воспроизвести записанный аудиофайл. На самом деле, ни одно приложение для Android-проигрывателя не может воспроизвести записанный аудиофайл.

С другой стороны, использование Media.Recorder для записи создает хороший записанный аудиофайл, который может быть воспроизведен любым приложением проигрывателя. Но дело в том, что я не могу сделать предварительный просмотр/прослушивание во время записи микрофонного входа в режиме реального времени.

4b9b3361

Ответ 1

Для записи и воспроизведения аудио в (почти) реальном времени вы можете запустить отдельный поток и использовать AudioRecord и AudioTrack.

Просто будьте осторожны с обратной связью. Если динамики достаточно громко подключены к вашему устройству, обратная связь может стать довольно неприятной довольно быстро.

/*
 * Thread to manage live recording/playback of voice input from the device microphone.
 */
private class Audio extends Thread
{ 
    private boolean stopped = false;

    /**
     * Give the thread high priority so that it not canceled unexpectedly, and start it
     */
    private Audio()
    { 
        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
        start();
    }

    @Override
    public void run()
    { 
        Log.i("Audio", "Running Audio Thread");
        AudioRecord recorder = null;
        AudioTrack track = null;
        short[][]   buffers  = new short[256][160];
        int ix = 0;

        /*
         * Initialize buffer to hold continuously recorded audio data, start recording, and start
         * playback.
         */
        try
        {
            int N = AudioRecord.getMinBufferSize(8000,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT);
            recorder = new AudioRecord(AudioSource.MIC, 8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, N*10);
            track = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, 
                    AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, N*10, AudioTrack.MODE_STREAM);
            recorder.startRecording();
            track.play();
            /*
             * Loops until something outside of this thread stops it.
             * Reads the data from the recorder and writes it to the audio track for playback.
             */
            while(!stopped)
            { 
                Log.i("Map", "Writing new data to buffer");
                short[] buffer = buffers[ix++ % buffers.length];
                N = recorder.read(buffer,0,buffer.length);
                track.write(buffer, 0, buffer.length);
            }
        }
        catch(Throwable x)
        { 
            Log.w("Audio", "Error reading voice audio", x);
        }
        /*
         * Frees the thread resources after the loop completes so that it can be run again
         */
        finally
        { 
            recorder.stop();
            recorder.release();
            track.stop();
            track.release();
        }
    }

    /**
     * Called from outside of the thread in order to stop the recording/playback loop
     */
    private void close()
    { 
         stopped = true;
    }

}

ИЗМЕНИТЬ

Звук на самом деле не записывается в файл. Объект AudioRecord кодирует аудио как 16-битные данные PCM и помещает его в буфер. Затем объект AudioTrack считывает данные из этого буфера и воспроизводит его через динамики. На SD-карте нет файла, к которому вы сможете получить доступ позже.

Вы не можете читать и записывать файл с SD-карты одновременно, чтобы получить воспроизведение/просмотр в режиме реального времени, поэтому вам нужно использовать буферы.

Ответ 2

Требуется следующее разрешение в манифесте:

<uses-permission android:name="android.permission.RECORD_AUDIO" ></uses-permission>

Кроме того, 2d буферный массив не нужен. Логика кода действительна даже с одним буфером, например:

short[] buffer = new short[160];
while (!stopped) {
    //Log.i("Map", "Writing new data to buffer");
    int n = recorder.read(buffer, 0, buffer.length);
    track.write(buffer, 0, n);
}