• 录音器 AudioRecorder


    实现录音器有两种方式可以选择:

    1.AudioRecord(基于字节流录音)
    优点:可以实现语音的实时处理,进行边录边播,对音频的实时处理。
    缺点:输出的是PCM的语音数据,如果保存成音频文件是不能被播放器播放的。要用到AudioTrack这个去进行处理。

    2.MediaRecorder(基于文件录音)
    已集成了录音,编码,压缩等,支持少量的音频格式文件。
    优点:封装度很高,操作简单
    缺点:无法实现实时处理音频,输出的音频格式少。

    权限:

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

    AudioRecorder录音工具类代码如下:

    package com.example.m_evolution.Utils;
    
    import android.media.AudioFormat;
    import android.media.AudioRecord;
    import android.media.MediaRecorder;
    import android.os.Environment;
    import android.os.Handler;
    import android.util.Log;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class AudioRecoderUtils {
    
        //文件路径
        private String filePath;
        //文件夹路径
        private String FolderPath;
    
        //录音的线程
        private Thread mThread;
    
    //    private MediaRecorder mMediaRecorder;
        private AudioRecord audioRecord;
        private boolean isRecording;
        private int channelConfiguration = AudioFormat.CHANNEL_IN_MONO;
        private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
        private int sampleRate = 44100;
        private int bufferSizeInBytes;
    
        private final String TAG = "fan";
        public static final int MAX_LENGTH = 1000 * 60 * 10;// 最大录音时长1000*60*10;
    
        private OnAudioStatusUpdateListener audioStatusUpdateListener;
    
        /**
         * 文件存储默认sdcard/record
         */
        public AudioRecoderUtils(){
    
            //默认保存路径为/sdcard/record/下
            FolderPath = Environment.getExternalStorageDirectory()+"/record/";
            bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRate,
                    channelConfiguration, audioEncoding); // need to be larger than size of a frame
    
            audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    sampleRate, channelConfiguration, audioEncoding,
                    bufferSizeInBytes); //麦克风
        }
    
        public void startRecord(){
            mThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    /* 获取开始时间* */
                    startTime = System.currentTimeMillis();
                    //设置录制指标
                    isRecording = true;
                    //自动更新界面
                    updateMicStatus();
                    //设置存储路径
                    filePath = FolderPath+getCurrentDate("yyyyMMddHHmmss") + ".wav";
                    File recordingFile = new File(filePath);
                    OutputStream out = null;
                    ByteArrayOutputStream baos = null;
                    try {
                        baos = new ByteArrayOutputStream();
                        audioRecord.startRecording();
                        byte[] buffer = new byte[bufferSizeInBytes];
                        int bufferReadResult = 0;
                        while (isRecording) {
                            bufferReadResult = audioRecord.read(buffer, 0,
                                    bufferSizeInBytes);
                            if(bufferReadResult>0){
                                baos.write(buffer, 0, bufferReadResult);
                            }
                        }
                        Log.i(TAG, "stop recording,file=" + recordingFile.getAbsolutePath());
                        buffer = baos.toByteArray();
                        Log.i(TAG, "audio byte len="+buffer.length);
                        out = new FileOutputStream(recordingFile);
                        out.write(getWavHeader(buffer.length));
                        out.write(buffer);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        if (out != null) {
                            try {
                                out.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        if(baos!=null){
                            try {
                                baos.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            });
            mThread.start();
        }
    
        public void stopRecord(){
            stopRecording();
            audioStatusUpdateListener.onStop(filePath);
            filePath = "";
        }
    
        public byte[] getWavHeader(long totalAudioLen){
            int mChannels = 1;
            long totalDataLen = totalAudioLen + 36;
            long longSampleRate = sampleRate;
            long byteRate = sampleRate * 2 * mChannels;
    
            byte[] header = new byte[44];
            header[0] = 'R';  // RIFF/WAVE header
            header[1] = 'I';
            header[2] = 'F';
            header[3] = 'F';
            header[4] = (byte) (totalDataLen & 0xff);
            header[5] = (byte) ((totalDataLen >> 8) & 0xff);
            header[6] = (byte) ((totalDataLen >> 16) & 0xff);
            header[7] = (byte) ((totalDataLen >> 24) & 0xff);
            header[8] = 'W';
            header[9] = 'A';
            header[10] = 'V';
            header[11] = 'E';
            header[12] = 'f';  // 'fmt ' chunk
            header[13] = 'm';
            header[14] = 't';
            header[15] = ' ';
            header[16] = 16;  // 4 bytes: size of 'fmt ' chunk
            header[17] = 0;
            header[18] = 0;
            header[19] = 0;
            header[20] = 1;  // format = 1
            header[21] = 0;
            header[22] = (byte) mChannels;
            header[23] = 0;
            header[24] = (byte) (longSampleRate & 0xff);
            header[25] = (byte) ((longSampleRate >> 8) & 0xff);
            header[26] = (byte) ((longSampleRate >> 16) & 0xff);
            header[27] = (byte) ((longSampleRate >> 24) & 0xff);
            header[28] = (byte) (byteRate & 0xff);
            header[29] = (byte) ((byteRate >> 8) & 0xff);
            header[30] = (byte) ((byteRate >> 16) & 0xff);
            header[31] = (byte) ((byteRate >> 24) & 0xff);
            header[32] = (byte) (2 * mChannels);  // block align
            header[33] = 0;
            header[34] = 16;  // bits per sample
            header[35] = 0;
            header[36] = 'd';
            header[37] = 'a';
            header[38] = 't';
            header[39] = 'a';
            header[40] = (byte) (totalAudioLen & 0xff);
            header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
            header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
            header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
    
            return header;
        }
    
        private long startTime;
        private long endTime;
    
        public static String getCurrentDate(String pattern) {
            SimpleDateFormat formatter = new SimpleDateFormat(pattern);
            Date curDate = new Date(System.currentTimeMillis());// 获取当前时间
            String timestamp = formatter.format(curDate);
            return timestamp;
        }
    
    
        public void stopRecording() {
            try {
                isRecording = false;
                audioRecord.stop();
                audioRecord.release();
                audioRecord = null;
                audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                        sampleRate, channelConfiguration, audioEncoding,
                        bufferSizeInBytes); //麦克风
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private final Handler mHandler = new Handler();
        private Runnable mUpdateMicStatusTimer = new Runnable() {
            public void run() {
                updateMicStatus();
            }
        };
    
        private int SPACE = 100;//显示时间的间隔时间
    
        public void setOnAudioStatusUpdateListener(OnAudioStatusUpdateListener audioStatusUpdateListener) {
            this.audioStatusUpdateListener = audioStatusUpdateListener;
        }
    
        /**
         * 更新麦克状态
         */
        private void updateMicStatus() {
    
            if (isRecording) {
                if(null != audioStatusUpdateListener) {
                    audioStatusUpdateListener.onUpdate(System.currentTimeMillis()-startTime);
                }
                mHandler.postDelayed(mUpdateMicStatusTimer, SPACE);
            }
        }
    
        public interface OnAudioStatusUpdateListener {
            /**
             * 录音中...
             * @param db 当前声音分贝
             * @param time 录音时长
             */
            public void onUpdate(long time);
    
            /**
             * 停止录音
             * @param filePath 保存路径
             */
            public void onStop(String filePath);
        }
    
    }
  • 相关阅读:
    log4net 配置
    Sublime Text 2 安装Package Control和插件的两种方法
    Silverlight中ListBox的数据绑定
    在Silverlight 5 项目中创建单元测试项目
    const V.S readonly
    鼠标和键盘操作的全局钩子库
    数码管图片
    正则表达式
    ToString的格式化字符串
    C# Builder
  • 原文地址:https://www.cnblogs.com/zhaozilongcjiajia/p/10677538.html
Copyright © 2020-2023  润新知