音频录制和流媒体的安卓 [英] Audio Recording and Streaming in Android

查看:260
本文介绍了音频录制和流媒体的安卓的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是开发一个Android应用程序。我要完成以下功能。 我会用我的手机内置的麦克风记录,并在同一时间,我想记录的音频或者通过手机的扬声器或耳机播放。 是否可行?如果是,请帮我在这。

I an developing an android app. I want to accomplish below feature. I will use my phone's built-in mic to record and at the same time i want the recorded audio to be played through either phone's speakers or headphones. Is it feasible? If yes, please help me in this.

推荐答案

下面是一个简单的录音和播放应用。
采用了Android AudioRecord 和的 AudioTrack

Here is a simple Recording and Playback application.
Uses Android AudioRecord and AudioTrack,

设计

所记录的音频被写入缓冲器和从相同的缓冲液回放,该机制在一个循环运行(采用Android螺纹)由按钮控制。

The recorded audio is written to a buffer and played back from the same buffer, This mechanism runs in a loop (using Android thread) controlled by buttons.

code

private String TAG = "AUDIO_RECORD_PLAYBACK";
private boolean isRunning = true;
private Thread m_thread;               /* Thread for running the Loop */

private AudioRecord recorder = null;
private AudioTrack track = null;

int bufferSize = 320;                  /* Buffer for recording data */
byte buffer[] = new byte[bufferSize];

/* Method to Enable/Disable Buttons */
private void enableButton(int id,boolean isEnable){
    ((Button)findViewById(id)).setEnabled(isEnable);
}


图形用户界面有两个按钮的开始停止
启用按钮:


The GUI has two Buttons START and STOP.
Enable the Button:

enableButton(R.id.StartButton,true);
enableButton(R.id.StopButton,false);

/* Assign Button Click Handlers */
((Button)findViewById(R.id.StartButton)).setOnClickListener(btnClick);
((Button)findViewById(R.id.StopButton)).setOnClickListener(btnClick);


映射启动和停止按钮OnClickListener


Mapping START and STOP Button for OnClickListener

private View.OnClickListener btnClick = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        switch(v.getId()){
        case R.id.StartButton:
        {
            Log.d(TAG, "======== Start Button Pressed ==========");
            isRunning = true;
            do_loopback(isRunning);
            enableButton(R.id.StartButton,false);
            enableButton(R.id.StopButton,true);
            break;
        }
        case R.id.StopButton:
        {
            Log.d(TAG, "======== Stop Button Pressed ==========");
            isRunning = false;
            do_loopback(isRunning);
            enableButton(R.id.StopButton,false);
            enableButton(R.id.StartButton,true);
            break;
        }
    }
}


启动主题:


Start the Thread:

private void do_loopback(final boolean flag) 
{
    m_thread = new Thread(new Runnable() {
        public void run() {
            run_loop(flag);
        }
    });
    m_thread.start();
}


初​​始化AudioRecord和AudioTrack方法:


Method for Initializing AudioRecord and AudioTrack:

public AudioTrack findAudioTrack (AudioTrack track)
{
    Log.d(TAG, "===== Initializing AudioTrack API ====");
    int m_bufferSize = AudioTrack.getMinBufferSize(8000, 
            AudioFormat.CHANNEL_OUT_MONO, 
            AudioFormat.ENCODING_PCM_16BIT);

    if (m_bufferSize != AudioTrack.ERROR_BAD_VALUE) 
    {
        track = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, 
                AudioFormat.CHANNEL_OUT_MONO, 
                AudioFormat.ENCODING_PCM_16BIT, m_bufferSize, 
                AudioTrack.MODE_STREAM);

        if (track.getState() == AudioTrack.STATE_UNINITIALIZED) {
            Log.e(TAG, "===== AudioTrack Uninitialized =====");
            return null;
        }
    }
    return track;
}

public AudioRecord findAudioRecord (AudioRecord recorder)
{
    Log.d(TAG, "===== Initializing AudioRecord API =====");     
    int m_bufferSize = AudioRecord.getMinBufferSize(8000,
            AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT);

    if (m_bufferSize != AudioRecord.ERROR_BAD_VALUE) 
    {
        recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000, 
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT, m_bufferSize);

        if (recorder.getState() == AudioRecord.STATE_UNINITIALIZED) {
            Log.e(TAG, "====== AudioRecord UnInitilaised ====== ");
            return null;
        }
    }
    return recorder;
}

的值 findAudioRecord findAudioTrack 可以改变基于设备。
请参阅<一href="http://stackoverflow.com/questions/4843739/audiorecord-object-not-initializing?answertab=votes#tab-top">this的问题。

The Values for findAudioRecord or findAudioTrack can change based on device.
Please refer this question.

$ C $下运行循环:

Code for Running the loop:

public void run_loop (boolean isRunning)
{

    /** == If Stop Button is pressed == **/
    if (isRunning == false) {
        Log.d(TAG, "=====  Stop Button is pressed ===== ");

        if (AudioRecord.STATE_INITIALIZED == recorder.getState()){
            recorder.stop();
            recorder.release();
        }
        if (AudioTrack.STATE_INITIALIZED == track.getState()){
            track.stop();
            track.release();
        }
        return;
    }


    /** ======= Initialize AudioRecord and AudioTrack ======== **/
    recorder = findAudioRecord(recorder);
    if (recorder == null) {
        Log.e(TAG, "======== findAudioRecord : Returned Error! =========== ");
        return;
    }

    track = findAudioTrack(track);
    if (track == null) {
        Log.e(TAG, "======== findAudioTrack : Returned Error! ========== ");
        return;
    }

    if ((AudioRecord.STATE_INITIALIZED == recorder.getState()) &&
            (AudioTrack.STATE_INITIALIZED == track.getState()))
    {
        recorder.startRecording();
        Log.d(TAG, "========= Recorder Started... =========");
        track.play();
        Log.d(TAG, "========= Track Started... =========");
    } 
    else 
    {
        Log.d(TAG, "==== Initilazation failed for AudioRecord or AudioTrack =====");
        return;
    }

    /** ------------------------------------------------------ **/

    /* Recording and Playing in chunks of 320 bytes */
    bufferSize = 320;

    while (isRunning == true) 
    {
        /* Read & Write to the Device */
        recorder.read(buffer, 0, bufferSize);
        track.write(buffer, 0, bufferSize);

    }
    Log.i(TAG, "Loopback exit");
    return;
}


请在的Andr​​oidManifest.xml

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

这上面的程序,也可以由写入/从使用同一API的文件中读取。
为什么要使用 audioRecord mediaRecorder - <一个href="http://stackoverflow.com/questions/12780677/android-audiorecord-and-mediarecorder?answertab=votes#tab-top">See这里。

This above procedure is also possible by Writing/Reading from a file using the same APIs.
Why use audioRecord over mediaRecorder - See here.

在code测试(在谷歌Nexus 5),可以正常使用。

The Code is tested (on Google Nexus 5) and working perfectly.

注意:请添加一些错误检查$ C $下 recorder.read track.write ,万一你失败了。同样适用于 findAudioRecord findAudioTrack

Note: Please add some error-checking code for recorder.read and track.write, in case you fail. Same applies for findAudioRecord and findAudioTrack.

这篇关于音频录制和流媒体的安卓的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆