首页 文章

Android:需要录制麦克风输入

提问于
浏览
37

有没有办法记录Android中的麦克风输入,同时它是实时播放/预览的过程?我试图使用 AudioRecord 和AudioTrack来做到这一点,但问题是我的设备无法播放录制的音频文件 . 实际上,任何Android播放器应用程序都无法播放录制的音频文件 .

另一方面,使用Media.Recorder进行录制可以生成一个可以由任何播放器应用程序播放的良好录制的音频文件 . 但问题是我在实时录制麦克风输入时无法进行预览/播放 .

任何反馈都非常感谢!提前致谢!

2 回答

  • 10

    要(几乎)实时录制和播放音频,您可以启动一个单独的线程并使用 AudioRecordAudioTrack .

    请小心反馈 . 如果您的设备上的扬声器声音很大,那么反馈可能非常快 .

    /*
     * 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;
        }
    
    }
    

    EDIT

    音频并没有真正录制到文件中 . AudioRecord 对象将音频编码为16 bit PCM data并将其放在缓冲区中 . 然后 AudioTrack 对象从该缓冲区读取数据并通过扬声器播放 . SD卡上没有您以后可以访问的文件 .

    您无法同时从SD卡读取和写入文件以实时进行播放/预览,因此您必须使用缓冲区 .

  • 62

    清单中的以下权限需要正常工作:

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

相关问题