【问题标题】:Android: Need to record mic inputAndroid:需要记录麦克风输入
【发布时间】:2011-10-21 01:20:51
【问题描述】:

有没有办法在实时播放/预览过程中记录 android 中的麦克风输入?我尝试使用AudioRecordAudioTrack 来执行此操作,但问题是我的设备无法播放录制的音频文件。实际上,任何安卓播放器应用程序都无法播放录制的音频文件。

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

【问题讨论】:

  • 我认为您可以在视频视图中播放录制的音频文件。尝试 。 this链接。
  • @Erick “谢谢!”在这里被认为是噪音。有关详细信息,请参阅此链接:meta.stackoverflow.com/questions/267384/…
  • 我有编辑权限,所以我没有从编辑中获得声誉。
  • @Erick 请不要那样做。我认为人们不喜欢问题中的“谢谢”的主要原因是因为它对你的问题没有贡献。如果您想说“谢谢”,您可以在答案下方的评论中说出来,然后将其删除。

标签: android audio audio-recording audiorecord


【解决方案1】:

要(几乎)实时录制和播放音频,您可以启动一个单独的线程并使用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;
    }

}

编辑

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

您不能同时从 SD 卡读取和写入文件以实时播放/预览,因此您必须使用缓冲区。

【讨论】:

  • 感谢您的回答。我只有 1 个问题,录制的音频文件格式是什么?是 wav、mp3、3gp 还是其他音频格式?
  • 嗯..实际上,正如我在问题中所述,我已经在使用 AudioRecord 和 AudioTrack,并且正在将缓冲数据写入 SD 卡。我在我的问题中将这些数据称为录制的音频文件。我的问题是我设备上的任何播放器都无法播放此文件。我想我的问题是,如何将此 PCM 数据转换为 3gp 或其他音频格式?
  • 好吧,看来我误解了你的问题。您希望能够实时播放音频并录制它以供以后播放?然后我会考虑将 WAV 标头添加到您从 AudioRecord 获得的缓冲 PCM 数据中。有一个问题here的讨论,以及使它工作的源代码。
  • 谢谢!我以后会调查的! :)
  • 我不确定你的意思。这个类已经实时获取音频,这就是 AudioRecord 对象的目的。构造函数中的AudioSource.MIC 参数告诉对象从麦克风读取它的数据,循环内对recorder.read() 的调用从麦克风检索音频数据。我的答案中的示例使用AudioTrack 实时播放音频,但您可以轻松地将数据流式传输到服务器。这能回答你的问题吗?
【解决方案2】:

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

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

另外,不需要二维缓冲数组。即使只有一个缓冲区,代码的逻辑也是有效的,如下所示:

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

【讨论】:

  • 带有“好代码!”我猜你是在和@theisenp 说话??考虑到长度,我可以理解您为什么要这样做,但它应该是对 op 的评论或唯一答案。如果其他帖子被删除,则此帖子的意义为零。
  • @ChiefTwoPencils 被动语音激活。
  • @BM,我通过在音频插孔内插入免提装置解决了噪音问题。这是因为移动麦克风的灵敏度。任何高振幅嘈杂的声音在从手机扬声器播放时都会放大。
猜你喜欢
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 2014-02-07
  • 2011-08-09
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多