web-dev-qa-db-fra.com

Android: besoin d'enregistrer l'entrée micro

Existe-t-il un moyen d'enregistrer l'entrée micro dans Android pendant qu'il est en cours de lecture/prévisualisation en temps réel? J'ai essayé d'utiliser AudioRecord et AudioTrack pour ce faire, mais le problème est que mon appareil ne peut pas lire le fichier audio enregistré. En fait, aucune application de lecteur Android ne peut pas lire le fichier audio enregistré.

D'un autre côté, l'utilisation de Media.Recorder pour enregistrer génère un bon fichier audio enregistré qui peut être lu par n'importe quelle application de lecteur. Mais le fait est que je ne peux pas faire de prévisualisation/réglage arrière pendant l'enregistrement de l'entrée micro en temps réel.

40
Erick

Pour enregistrer et lire l'audio en temps (presque) réel, vous pouvez démarrer un thread séparé et utiliser un AudioRecord et un AudioTrack.

Faites juste attention aux commentaires. Si les haut-parleurs sont montés assez fort sur votre appareil, les commentaires peuvent devenir assez méchants assez rapidement.

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

    /**
     * Give the thread high priority so that it's 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's 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;
    }

}

[~ # ~] modifier [~ # ~]

L'audio n'enregistre pas vraiment dans un fichier. L'objet AudioRecord code l'audio comme données PCM 16 bits et le place dans un tampon. Ensuite, l'objet AudioTrack lit les données de ce tampon et les lit via les haut-parleurs. Il n'y a aucun fichier sur la carte SD auquel vous pourrez accéder ultérieurement.

Vous ne pouvez pas lire et écrire un fichier depuis la carte SD en même temps pour obtenir la lecture/prévisualisation en temps réel, vous devez donc utiliser des tampons.

63
theisenp

L'autorisation suivante dans le manifeste est requise pour fonctionner correctement:

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

De plus, un tableau de tampons 2D n'est pas nécessaire. La logique du code est valide même avec un seul tampon, comme ceci:

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);
}
11
KitKat