美文网首页Android-多媒体
Android语音录制简单封装

Android语音录制简单封装

作者: Tyhj | 来源:发表于2018-11-17 22:18 被阅读0次

    录音两个需要注意的地方,一是录音过短的时候会失败,所以要监听录音时间长短,小于一秒的时候就显示失败;二是录音的时候关闭其他声音

    集成方法:

    Step 1. Add the JitPack repository to your build file

    //Add it in your root build.gradle at the end of repositories:
    allprojects {
            repositories {
                ...
                maven { url 'https://jitpack.io' }
            }
        }
    

    Step 2. Add the dependency

    //Add the dependency
    dependencies {
        implementation 'com.github.tyhjh:AudioRecording:v1.0.0'
    }
    

    基本使用

    //设置录音保存位置
    AudioRecordUtil.init(Environment.getExternalStorageDirectory() + "/audio/");
    recordUtil = AudioRecordUtil.getInstance();
    //开始录音
    recordUtil.startRecord(MainActivity.this);
    //取消录音,时间太短须取消
    recordUtil.cancelRecord(MainActivity.this);
    //结束录音(保存录音文件)
    recordUtil.stopRecord(MainActivity.this);  
    //录音监听
            AudioRecordUtil.getInstance().setOnAudioStatusUpdateListener(new AudioRecordUtil.OnAudioStatusUpdateListener() {
                @Override
                public void onUpdate(double db, long time) {
                    //根据分贝值来设置录音时话筒图标的上下波动
                }
    
                @Override
                public void onStop(final String filePath) {
                    //获取录音文件
                }
            });
    

    具体实现

    录音时候关闭或开启其他声音

        public static boolean muteAudioFocus(Context context, boolean bMute) {
            if (context == null) {
                Log.d("ANDROID_LAB", "context is null.");
                return false;
            }
            boolean bool = false;
            AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            //关闭声音
            if (bMute) {
                int result = am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
                bool = result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
            } else {
                    //恢复声音
                int result = am.abandonAudioFocus(null);
                bool = result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
            }
            Log.d("ANDROID_LAB", "pauseMusic bMute=" + bMute + " result=" + bool);
            return bool;
        }
    
    

    一个录音的类

    package tools;
    
    import android.media.MediaRecorder;
    import android.os.Environment;
    import android.os.Handler;
    import android.util.Log;
    
    import java.io.File;
    import java.io.IOException;
    
    
    public class AudioRecoderUtils {
    
        //文件路径
        private String filePath;
        //文件夹路径
        private String FolderPath;
    
        private MediaRecorder mMediaRecorder;
        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/下
            this(Environment.getExternalStorageDirectory()+"/ASchollMsg/record/");
        }
    
        public AudioRecoderUtils(String filePath) {
    
            File path = new File(filePath);
            if(!path.exists())
                path.mkdirs();
    
            this.FolderPath = filePath;
        }
    
        private long startTime;
        private long endTime;
    
        /**
         * 开始录音 使用amr格式
         *      录音文件
         * @return
         */
        public String startRecord() {
            // 开始录音
            /* ①Initial:实例化MediaRecorder对象 */
            if (mMediaRecorder == null)
                mMediaRecorder = new MediaRecorder();
            mMediaRecorder.setOnErrorListener(null);
            try {
                /* ②setAudioSource/setVedioSource */
                mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 设置麦克风
                /* ②设置音频文件的编码:AAC/AMR_NB/AMR_MB/Default 声音的(波形)的采样 */
                mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
                /*
                 * ②设置输出文件的格式:THREE_GPP/MPEG-4/RAW_AMR/Default THREE_GPP(3gp格式
                 * ,H263视频/ARM音频编码)、MPEG-4、RAW_AMR(只支持音频且音频编码要求为AMR_NB)
                 */
                mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    
                filePath = FolderPath + Defined.getTimeName() + ".amr" ;
                /* ③准备 */
                mMediaRecorder.setOutputFile(filePath);
                mMediaRecorder.setMaxDuration(MAX_LENGTH);
                mMediaRecorder.prepare();
                /* ④开始 */
                mMediaRecorder.start();
                // AudioRecord audioRecord.
                /* 获取开始时间* */
                startTime = System.currentTimeMillis();
                updateMicStatus();
                Log.e("fan", "startTime" + startTime);
            } catch (IllegalStateException e) {
                Log.i(TAG, "call startAmr(File mRecAudioFile) failed!" + e.getMessage());
            } catch (IOException e) {
                Log.i(TAG, "call startAmr(File mRecAudioFile) failed!" + e.getMessage());
            }
            return filePath;
        }
    
        /**
         * 停止录音
         */
        public long stopRecord() {
            if (mMediaRecorder == null)
                return 0L;
            endTime = System.currentTimeMillis();
            mMediaRecorder.stop();
            mMediaRecorder.reset();
            mMediaRecorder.release();
            mMediaRecorder = null;
    
            audioStatusUpdateListener.onStop(filePath);
            filePath = "";
            return endTime - startTime;
        }
    
        /**
         * 取消录音
         */
        public void cancelRecord(){
            if(mMediaRecorder==null)
                return;
            mMediaRecorder.setOnErrorListener(null);
            mMediaRecorder.setPreviewDisplay(null);
            try {
                mMediaRecorder.stop();
            }catch (Exception e){
                e.printStackTrace();
            }
    
            mMediaRecorder.reset();
            mMediaRecorder.release();
            mMediaRecorder = null;
            File file = new File(filePath);
            if (file.exists())
                file.delete();
    
            filePath = "";
    
        }
    
        private final Handler mHandler = new Handler();
        private Runnable mUpdateMicStatusTimer = new Runnable() {
            public void run() {
                updateMicStatus();
            }
        };
    
    
        private int BASE = 1;
        private int SPACE = 100;// 间隔取样时间
    
        public void setOnAudioStatusUpdateListener(OnAudioStatusUpdateListener audioStatusUpdateListener) {
            this.audioStatusUpdateListener = audioStatusUpdateListener;
        }
    
        /**
         * 更新麦克状态
         */
        private void updateMicStatus() {
    
            if (mMediaRecorder != null) {
                double ratio = (double)mMediaRecorder.getMaxAmplitude() / BASE;
                double db = 0;// 分贝
                if (ratio > 1) {
                    db = 20 * Math.log10(ratio);
                    if(null != audioStatusUpdateListener) {
                        audioStatusUpdateListener.onUpdate(db, System.currentTimeMillis()-startTime);
                    }
                }
                mHandler.postDelayed(mUpdateMicStatusTimer, SPACE);
            }
        }
    
        public interface OnAudioStatusUpdateListener {
            /**
             * 录音中...
             * @param db 当前声音分贝
             * @param time 录音时长
             */
            public void onUpdate(double db, long time);
    
            /**
             * 停止录音
             * @param filePath 保存路径
             */
            public void onStop(String filePath);
        }
    
    }
    
    

    调用录音的类并实现其中的方法

    //录音回调
            mAudioRecoderUtils.setOnAudioStatusUpdateListener(new AudioRecoderUtils.OnAudioStatusUpdateListener() {
    
                //录音中....db为声音分贝,time为录音时长
                @Override
                public void onUpdate(double db, long time) {
                    //根据分贝值来设置录音时话筒图标的上下波动,下面有讲解
                    mImageView.getDrawable().setLevel((int) (3000 + 6000 * db / 100));
                    mTextView.setText(Defined.getDate(time));
                    time_Long=(int)(time/1000);
                }
    
                //录音结束,filePath为保存路径
                @Override
                public void onStop(String filePath) {
                    //发送语音
                    JSONObject json = null;
                    Defined.muteAudioFocus(SendMessage.this,false);
                    try {
                        json = new JSONObject(getJson.getMsg("null", 2, time_Long, getString(R.string.singleTalk), linkMan.getId()));
                        Messge messge = new Messge(json);
                        messge.setSoundPath(filePath);
                        updateView(messge);
                        sendVoice(filePath,messges.size()-1);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    mTextView.setText("00:00");
                }
            });
    
    
    
    //录音
                        Defined.muteAudioFocus(SendMessage.this,true);
                        switch (event.getAction()){
                            case MotionEvent.ACTION_DOWN:
                                y=event.getRawY();
                                time = System.currentTimeMillis();
                                mPop.showAtLocation(ll_bg, Gravity.CENTER,0,0);
                                try {
                                    mAudioRecoderUtils.startRecord();
                                }catch (RuntimeException e){
                                    e.printStackTrace();
                                    Snackbar.make(iv_sound,"先允许调用系统录音权限",Snackbar.LENGTH_SHORT).show();
                                }
                                iv_sound.startAnimation(expend);
                                break;
                            case MotionEvent.ACTION_UP:
                                if(System.currentTimeMillis()-time<1000){
                                    Snackbar.make(iv_sound,"录音时间过短,请重试",Snackbar.LENGTH_SHORT).show();
                                    mAudioRecoderUtils.cancelRecord();
                                    mPop.dismiss();
                                    iv_sound.startAnimation(noexpend);
                                    break;
                                }else if(y-event.getRawY()>300){
                                    Snackbar.make(iv_sound,"已取消发送语音",Snackbar.LENGTH_SHORT).show();
                                    mAudioRecoderUtils.cancelRecord();
                                    mPop.dismiss();
                                    iv_sound.startAnimation(noexpend);
                                    break;
                                }else {
                                    try{
                                        mAudioRecoderUtils.stopRecord();        //结束录音(保存录音文件)
                                    }catch (Exception e){
                                        e.printStackTrace();
                                        Snackbar.make(iv_sound,"先允许调用系统录音权限",Snackbar.LENGTH_SHORT).show();
                                    }
                                    mPop.dismiss();
                                    iv_sound.startAnimation(noexpend);
                                    break;
                                }
                            case MotionEvent.ACTION_CANCEL:
                                mAudioRecoderUtils.cancelRecord(); //取消录音(不保存录音文件)
                                mPop.dismiss();
                                iv_sound.startAnimation(noexpend);
                                break;
                        }
    
    

    关于录音的时候显示语音声音大小动画
    一个ImageView,设置背景,显示动画

    
    <ImageView
            android:id="@+id/zeffect_recordbutton_dialog_imageview"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:src="@drawable/zeffect_recordbutton_micrphone" />
    

    其中src也是一个xml文件,xml里面的drawable是两张颜色不一样形状一样的图片,我用的是矢量图片。

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:id="@android:id/background"
            android:drawable="@drawable/ic_voice_null" />
        <item android:id="@android:id/progress">
            <clip
                android:clipOrientation="vertical"
                android:drawable="@drawable/ic_voice_full"
                android:gravity="bottom" />
        </item>
    </layer-list>
    
    //录音中....db为声音分贝,time为录音时长
                @Override
                public void onUpdate(double db, long time) {
                    //根据分贝值来设置录音时话筒图标的上下波动
                    mImageView.getDrawable().setLevel((int) (3000 + 6000 * db / 100));
                    mTextView.setText(Defined.getDate(time));
                    time_Long=(int)(time/1000);
                }
    
    

    项目地址:https://github.com/tyhjh/AudioRecording

    相关文章

      网友评论

        本文标题:Android语音录制简单封装

        本文链接:https://www.haomeiwen.com/subject/rnzifqtx.html