如何在Android中使用AudioRecorder录制音频 [英] How to record audio using AudioRecorder in Android

查看:177
本文介绍了如何在Android中使用AudioRecorder录制音频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想捕捉音频从Android设备。下面我的code似乎已成功使SD卡上的 WAV 的文件,但它不能播放。我试着用不同的媒体播放器,但没有工作,发挥它。有一个在我的code,是造成这一问题的问题。

code

 公共类MainActivity扩展ActionBarActivity {    私有静态最后弦乐LOG_TAG =AudioRecordTest;    静态最终诠释AUDIO_PORT = 2048;
    静态最终诠释SAMPLE_RATE = 8000;
    静态最终诠释SAMPLE_INTERVAL = 20; //毫秒
    静态最终诠释SAMPLE_SIZE = 2;每个样本//字节
    静态最终诠释BUF_SIZE = SAMPLE_INTERVAL * SAMPLE_INTERVAL * SAMPLE_SIZE * 2;    私有静态诠释[] = mSampleRates新INT [] {44100,44056,47250,48000,22050,16000,11025,8000};
    私人主题recordingThread = NULL;
    私人布尔isRecording = FALSE;    INT BufferElements2Rec = 1024; //想打2048(2K),因为2个字节,我们
    //仅使用1024
    INT BytesPerElement = 2; // 2字节的16位格式    私人诠释缓冲区大小;    私人AudioRecord记录;    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);
        的StartRecording();
    }
    @覆盖
    公共布尔onCreateOptionsMenu(菜单菜单){        //充气菜单;如果是present这增加了项目操作栏。
        。getMenuInflater()膨胀(R.menu.main,菜单);
        返回true;
    }
    私人无效的startRecording(){        录音机= findAudioRecord();        recorder.startRecording();
        isRecording = TRUE;
        recordingThread =新主题(新的Runnable(){
            公共无效的run(){
                writeAudioDataToFile();
            }
        },AudioRecorder线程);
        recordingThread.start();
    }    //转换短字节
    私人字节[] short2byte(短[] SDATA){
        INT shortArrsize = sData.length;
        字节[]字节=新的字节[shortArrsize * 2];
        的for(int i = 0; I< shortArrsize;我++){
            字节[我* 2] =(字节)(SDATA [1] - 安培;设为0x00FF);
            字节[(我* 2)+ 1] =(字节)(SDATA [Ⅰ]≥→8);
            SDATA [I] = 0;
        }
        返回字节;    }    公共AudioRecord findAudioRecord(){
        对于(INT率:mSampleRates){
            对于(短AudioFormat的:新的短[] {AudioFormat.ENCODING_PCM_8BIT,AudioFormat.ENCODING_PCM_16BIT}){
                对于(短channelConfig:新的短[] {AudioFormat.CHANNEL_IN_MONO,AudioFormat.CHANNEL_IN_STEREO}){
                    尝试{
                        Log.d(LOG_TAG,试图率+速度+赫兹,位:+ AudioFormat的+,声道:
                                + channelConfig);
                        BUFFERSIZE = AudioRecord.getMinBufferSize(速率,channelConfig,AudioFormat的);                        如果(缓冲区大小!= AudioRecord.ERROR_BAD_VALUE){
                            //检查是否我们可以实例,有一个成功
                            记录=新AudioRecord(MediaRecorder.AudioSource.DEFAULT,速度,channelConfig,AudioFormat的,缓冲区大小);
                            如果(recorder.getState()== AudioRecord.STATE_INITIALIZED)
                                返回记录;
                        }
                    }赶上(例外五){
                        Log.e(LOG_TAG,房价+异常,继续努力。E);
                    }
                }
            }
        }
        返回null;
    }    私人无效writeAudioDataToFile(){
        / * //写字节输出音频
        短SDATA [] =新的短[BufferElements2Rec]        而(isRecording){
            //获取声音输出麦克风字节格式
            recorder.read(SDATA,0,BufferElements2Rec);
            的System.out.println(短wirting到文件+ sData.toString());
            // //存储声音缓冲区
            字节BDATA [] = short2byte(SDATA);
            sendLiveAudio(BDATA);
        } * /        字符串文件路径=/sdcard/test.wav;
        短SDATA [] =新的短[BUFFERSIZE / 2];        FileOutputStream中OS = NULL;
        尝试{
            OS =新的FileOutputStream(文件路径);
        }赶上(FileNotFoundException异常五){
            e.printStackTrace();
        }        而(isRecording){
            //获取声音输出麦克风字节格式            recorder.read(SDATA,0,缓冲区大小/ 2);
            Log.d(ERAY,短wirting到文件+ sData.toString());
            尝试{
                // //从写入缓冲区文件中的数据
                // //存储声音缓冲区
                字节BDATA [] = short2byte(SDATA);
                os.write(BDATA,0,缓冲区大小);
            }赶上(IOException异常五){
                e.printStackTrace();
            }
        }
        尝试{
            os.close();
        }赶上(IOException异常五){
            e.printStackTrace();
        }
    }    私人无效STO precording(){
        //停止记录活动
        如果(NULL!=录像机){
            isRecording = FALSE;
            recorder.stop();
            recorder.release();
            记录= NULL;
            recordingThread = NULL;
        }
    }    @覆盖
    公共布尔onOptionsItemSelected(菜单项项){
        //处理动作栏项目点击这里。操作栏会
        //自动处理上点击主页/向上按钮,只要
        //你在AndroidManifest.xml中指定一个父活动。
        INT ID = item.getItemId();
        如果(ID == R.id.action_settings){
            返回true;
        }
        返回super.onOptionsItemSelected(项目);
    }
    @覆盖
    公共无效onBack pressed(){
        super.onBack pressed();
        STO precording();
    }
}


解决方案

试试这个.....

 公共类Audio_Record延伸活动{
私有静态最终诠释RECORDER_SAMPLERATE = 8000;
私有静态最终诠释RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
私有静态最终诠释RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
私人AudioRecord记录= NULL;
私人主题recordingThread = NULL;
私人布尔isRecording = FALSE;@覆盖
公共无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.main);    setButtonHandlers();
    enableButtons(假);    INT缓冲区大小= AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
            RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING);
}私人无效setButtonHandlers(){
    ((按钮)findViewById(R.id.btnStart))setOnClickListener(btnClick)。
    ((按钮)findViewById(R.id.btnStop))setOnClickListener(btnClick)。
}私人无效enableButton(INT ID,布尔isEnable){
    ((按钮)findViewById(ID))的setEnabled(isEnable)。
}私人无效enableButtons(布尔isRecording){
    enableButton(R.id.btnStart,isRecording!);
    enableButton(R.id.btnStop,isRecording);
}INT BufferElements2Rec = 1024; //想打2048(2K),因为2个字节,我们只用1024
INT BytesPerElement = 2; // 2字节的16位格式私人无效的startRecording(){    记录=新AudioRecord(MediaRecorder.AudioSource.MIC,
            RECORDER_SAMPLERATE,RECORDER_CHANNELS,
            RECORDER_AUDIO_ENCODING,BufferElements2Rec * BytesPerElement);    recorder.startRecording();
    isRecording = TRUE;
    recordingThread =新主题(新的Runnable(){
        公共无效的run(){
            writeAudioDataToFile();
        }
    },AudioRecorder线程);
    recordingThread.start();
}    //转换短字节
私人字节[] short2byte(短[] SDATA){
    INT shortArrsize = sData.length;
    字节[]字节=新的字节[shortArrsize * 2];
    的for(int i = 0; I< shortArrsize;我++){
        字节[我* 2] =(字节)(SDATA [1] - 安培;设为0x00FF);
        字节[(我* 2)+ 1] =(字节)(SDATA [Ⅰ]≥→8);
        SDATA [I] = 0;
    }
    返回字节;}私人无效writeAudioDataToFile(){
    //写字节输出音频    字符串文件路径=/sdcard/voice8K16bitmono.pcm;
    短SDATA [] =新的短[BufferElements2Rec]    FileOutputStream中OS = NULL;
    尝试{
        OS =新的FileOutputStream(文件路径);
    }赶上(FileNotFoundException异常五){
        e.printStackTrace();
    }    而(isRecording){
        //获取声音输出麦克风字节格式        recorder.read(SDATA,0,BufferElements2Rec);
        的System.out.println(短wirting到文件+ sData.toString());
        尝试{
            // //从写入缓冲区文件中的数据
            // //存储声音缓冲区
            字节BDATA [] = short2byte(SDATA);
            os.write(BDATA,0,BufferElements2Rec * BytesPerElement);
        }赶上(IOException异常五){
            e.printStackTrace();
        }
    }
    尝试{
        os.close();
    }赶上(IOException异常五){
        e.printStackTrace();
    }
}私人无效STO precording(){
    //停止记录活动
    如果(NULL!=录像机){
        isRecording = FALSE;
        recorder.stop();
        recorder.release();
        记录= NULL;
        recordingThread = NULL;
    }
}私人View.OnClickListener btnClick =新View.OnClickListener(){
    公共无效的onClick(视图v){
        开关(v.getId()){
        案例R.id.btnStart:{
            enableButtons(真);
            的StartRecording();
            打破;
        }
        案例R.id.btnStop:{
            enableButtons(假);
            STO precording();
            打破;
        }
        }
    }
};@覆盖
公共布尔的onkeydown(INT键code,KeyEvent的事件){
    如果(键code == KeyEvent.KEY code_BACK){
        完();
    }
    返回super.onKeyDown(键code,事件);
}
}

I want to capture audio from an Android device. My code below seems to successfully make a wav file on the SD card but it cannot be played. I tried to play it using different media players but none work. There is an issue in my code that is causing this problem.

code

public class MainActivity extends ActionBarActivity {

    private static final String LOG_TAG = "AudioRecordTest";

    static final int AUDIO_PORT = 2048;
    static final int SAMPLE_RATE = 8000;
    static final int SAMPLE_INTERVAL = 20; // milliseconds
    static final int SAMPLE_SIZE = 2; // bytes per sample
    static final int BUF_SIZE = SAMPLE_INTERVAL * SAMPLE_INTERVAL * SAMPLE_SIZE * 2;

    private static int[] mSampleRates = new int[]{44100, 44056, 47250, 48000, 22050, 16000, 11025, 8000};
    private Thread recordingThread = null;
    private boolean isRecording = false;

    int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we
    // use only 1024
    int BytesPerElement = 2; // 2 bytes in 16bit format

    private int bufferSize;

    private AudioRecord recorder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startRecording();
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }


    private void startRecording() {

        recorder = findAudioRecord();

        recorder.startRecording();
        isRecording = true;
        recordingThread = new Thread(new Runnable() {
            public void run() {
                writeAudioDataToFile();
            }
        }, "AudioRecorder Thread");
        recordingThread.start();
    }

    // convert short to byte
    private byte[] short2byte(short[] sData) {
        int shortArrsize = sData.length;
        byte[] bytes = new byte[shortArrsize * 2];
        for (int i = 0; i < shortArrsize; i++) {
            bytes[i * 2] = (byte) (sData[i] & 0x00FF);
            bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
            sData[i] = 0;
        }
        return bytes;

    }

    public AudioRecord findAudioRecord() {
        for (int rate : mSampleRates) {
            for (short audioFormat : new short[]{AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT}) {
                for (short channelConfig : new short[]{AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO}) {
                    try {
                        Log.d(LOG_TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: "
                                + channelConfig);
                        bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);

                        if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
                            // check if we can instantiate and have a success
                            recorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize);
                            if (recorder.getState() == AudioRecord.STATE_INITIALIZED)
                                return recorder;
                        }
                    } catch (Exception e) {
                        Log.e(LOG_TAG, rate + "Exception, keep trying.", e);
                    }
                }
            }
        }
        return null;
    }

    private void writeAudioDataToFile() {
        /*// Write the output audio in byte
        short sData[] = new short[BufferElements2Rec];

        while (isRecording) {
            // gets the voice output from microphone to byte format
            recorder.read(sData, 0, BufferElements2Rec);
            System.out.println("Short wirting to file" + sData.toString());
            // // stores the voice buffer
            byte bData[] = short2byte(sData);
            sendLiveAudio(bData);
        }*/

        String filePath = "/sdcard/test.wav";
        short sData[] = new short[bufferSize / 2];

        FileOutputStream os = null;
        try {
            os = new FileOutputStream(filePath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        while (isRecording) {
            // gets the voice output from microphone to byte format

            recorder.read(sData, 0, bufferSize / 2);
            Log.d("eray", "Short wirting to file" + sData.toString());
            try {
                // // writes the data to file from buffer
                // // stores the voice buffer
                byte bData[] = short2byte(sData);
                os.write(bData, 0, bufferSize);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void stopRecording() {
        // stops the recording activity
        if (null != recorder) {
            isRecording = false;
            recorder.stop();
            recorder.release();
            recorder = null;
            recordingThread = null;
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }


    @Override
    public void onBackPressed() {
        super.onBackPressed();
        stopRecording();
    }


}

解决方案

Try This.....

public class Audio_Record extends Activity {
private static final int RECORDER_SAMPLERATE = 8000;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private AudioRecord recorder = null;
private Thread recordingThread = null;
private boolean isRecording = false;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    setButtonHandlers();
    enableButtons(false);

    int bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
            RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING); 
}

private void setButtonHandlers() {
    ((Button) findViewById(R.id.btnStart)).setOnClickListener(btnClick);
    ((Button) findViewById(R.id.btnStop)).setOnClickListener(btnClick);
}

private void enableButton(int id, boolean isEnable) {
    ((Button) findViewById(id)).setEnabled(isEnable);
}

private void enableButtons(boolean isRecording) {
    enableButton(R.id.btnStart, !isRecording);
    enableButton(R.id.btnStop, isRecording);
}

int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024
int BytesPerElement = 2; // 2 bytes in 16bit format

private void startRecording() {

    recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
            RECORDER_SAMPLERATE, RECORDER_CHANNELS,
            RECORDER_AUDIO_ENCODING, BufferElements2Rec * BytesPerElement);

    recorder.startRecording();
    isRecording = true;
    recordingThread = new Thread(new Runnable() {
        public void run() {
            writeAudioDataToFile();
        }
    }, "AudioRecorder Thread");
    recordingThread.start();
}

    //convert short to byte
private byte[] short2byte(short[] sData) {
    int shortArrsize = sData.length;
    byte[] bytes = new byte[shortArrsize * 2];
    for (int i = 0; i < shortArrsize; i++) {
        bytes[i * 2] = (byte) (sData[i] & 0x00FF);
        bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
        sData[i] = 0;
    }
    return bytes;

}

private void writeAudioDataToFile() {
    // Write the output audio in byte

    String filePath = "/sdcard/voice8K16bitmono.pcm";
    short sData[] = new short[BufferElements2Rec];

    FileOutputStream os = null;
    try {
        os = new FileOutputStream(filePath);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    while (isRecording) {
        // gets the voice output from microphone to byte format

        recorder.read(sData, 0, BufferElements2Rec);
        System.out.println("Short wirting to file" + sData.toString());
        try {
            // // writes the data to file from buffer
            // // stores the voice buffer
            byte bData[] = short2byte(sData);
            os.write(bData, 0, BufferElements2Rec * BytesPerElement);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    try {
        os.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void stopRecording() {
    // stops the recording activity
    if (null != recorder) {
        isRecording = false;
        recorder.stop();
        recorder.release();
        recorder = null;
        recordingThread = null;
    }
}

private View.OnClickListener btnClick = new View.OnClickListener() {
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btnStart: {
            enableButtons(true);
            startRecording();
            break;
        }
        case R.id.btnStop: {
            enableButtons(false);
            stopRecording();
            break;
        }
        }
    }
};

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        finish();
    }
    return super.onKeyDown(keyCode, event);
}
}

这篇关于如何在Android中使用AudioRecorder录制音频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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