Android中仿微信录音,录音后的raw文件转mp3文件

现在很多时候需要用到录音,然后如果我们的App是ios和android两端的话,就要考虑录音的文件在两端都能使用,这个时候就需要适配,两端的录音文件都要是mp3文件,这样才能保证两边都能播放。

针对这个,封装了一个简单可用的录音控件。

Android中仿微信录音,录音后的raw文件转mp3文件_第1张图片   Android中仿微信录音,录音后的raw文件转mp3文件_第2张图片

使用方法:1.在xml文件中添加



    

2.别忘了申请录音权限

AndPermission.with(MainActivity.this)
                .permission(Manifest.permission.RECORD_AUDIO,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE)
                .onGranted(permissions -> {

                    showSelect();

                })
                .onDenied(permissions -> {
                    Toast.makeText(MainActivity.this,"请同意录音权限",Toast.LENGTH_SHORT).show();
                })
                .start();
private void showSelect() {

        SoundTextView recordAudio = findViewById(R.id.record_audio);
        recordAudio.setOnRecordFinishedListener(new SoundTextView.OnRecordFinishedListener() {
            @Override
            public void newMessage(String path, int duration) {
                int index = path.lastIndexOf("/");
                String fileName = path.substring(index + 1);
                Log.e("录音文件", "path=: "+path );
            }
        });
    }

使用方法如上非常简单:

主要的类

package ant.muxi.com.audiodemo.view;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.widget.AppCompatTextView;


import java.io.File;

import ant.muxi.com.audiodemo.R;
import ant.muxi.com.audiodemo.audio.ProgressTextUtils;
import ant.muxi.com.audiodemo.audio.RecordManager;


public class SoundTextView extends AppCompatTextView {

    private Context mContext;

    private Dialog recordIndicator;

    private TextView mVoiceTime;

    private File file;
    private String type = "1";//默认开始录音 type=2,录音完毕
    RecordManager recordManager;
    File fileto;
    int level;
    private long downT;
    String sountime;


    public SoundTextView(Context context) {
        super(context);
        init();
    }

    public SoundTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.mContext = context;
        init();
    }

    public SoundTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        init();
    }

    private void init() {

        recordIndicator = new Dialog(getContext(), R.style.jmui_record_voice_dialog);
        recordIndicator.setContentView(R.layout.jmui_dialog_record_voice);
        mVoiceTime = (TextView) recordIndicator.findViewById(R.id.voice_time);


        file = new File(Environment.getExternalStorageDirectory() + "/recoder.amr");

        fileto = new File(Environment.getExternalStorageDirectory() + "/recoder.mp3");
        recordManager = new RecordManager(
                (Activity) mContext,
                String.valueOf(file),
                String.valueOf(fileto));
        recordManager.setOnAudioStatusUpdateListener(new RecordManager.OnAudioStatusUpdateListener() {
            @Override
            public void onUpdate(double db) {
                //得到分贝

                if (null != recordIndicator) {
                    level = (int) db;
                    handler.sendEmptyMessage(0x111);

                }

            }
        });


    }


    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {

            super.handleMessage(msg);
            switch (msg.what) {

                case 0x111:


                    sountime = ProgressTextUtils.getSecsProgress(System.currentTimeMillis() - downT);

                    long time = System.currentTimeMillis() - downT;

                    mVoiceTime.setText(ProgressTextUtils.getProgressText(time));
                    //判断时间
                    judetime(Integer.parseInt(sountime));

                    break;
            }


        }
    };


    public void judetime(int time) {

        if (time > 14) {
            //结束录制
            Toast.makeText(mContext, "录音不能超过十五秒", Toast.LENGTH_SHORT).show();
            recordManager.stop_mp3();
            new Thread() {
                @Override
                public void run() {
                    super.run();
                    recordManager.saveData();
                    finishRecord(fileto.getPath(), sountime);
                }
            }.start();

            recordIndicator.dismiss();
            type = "2";
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();

        switch (action) {
            case MotionEvent.ACTION_DOWN:


                if (type.equals("1")) {
                    //开始发送时间
                    downT = System.currentTimeMillis();
                    recordManager.start_mp3();
                    recordIndicator.show();
                } else {
                    Log.e("-log-", "您已经录制完毕: ");
                }
                
                return true;
            case MotionEvent.ACTION_UP:

                if (type.equals("1")) {
                    try {
                        if (Integer.parseInt(sountime) > 2) {
                            recordManager.stop_mp3();
                            new Thread() {
                                @Override
                                public void run() {
                                    super.run();
                                    recordManager.saveData();
                                    finishRecord(fileto.getPath(), sountime);
                                }
                            }.start();

                            if (recordIndicator.isShowing()) {
                                recordIndicator.dismiss();
                            }

                            type = "2";

                        } else {
                            recordManager.stop_mp3();
                            if (recordIndicator.isShowing()) {
                                recordIndicator.dismiss();
                            }
                            sountime = null;
                            Toast.makeText(mContext, "录音时间少于3秒,请重新录制", Toast.LENGTH_SHORT).show();

                        }

                    } catch (Exception e) {

                        recordManager.stop_mp3();
                        if (recordIndicator.isShowing()) {
                            recordIndicator.dismiss();
                        }
                        sountime = null;
                        Toast.makeText(mContext, "录音时间少于3秒,请重新录制", Toast.LENGTH_SHORT).show();


                    }

                }


                break;
            case MotionEvent.ACTION_CANCEL:


                if (recordIndicator.isShowing()) {
                    recordIndicator.dismiss();
                }


                break;
        }

        return super.onTouchEvent(event);
    }


    //录音完毕加载 ListView item
    private void finishRecord(String path, String time) {

        if (onRecordFinishedListener != null) {
            onRecordFinishedListener.newMessage(path, Integer.parseInt(time));
            type = "1";
        }
        //发送语音
        // Toasts.toast(getContext(),"您已经录完了一条语音"+myRecAudioFile);
    }

    private OnRecordFinishedListener onRecordFinishedListener;

    public void setOnRecordFinishedListener(OnRecordFinishedListener onRecordFinishedListener) {
        this.onRecordFinishedListener = onRecordFinishedListener;
    }

    public interface OnRecordFinishedListener {
        void newMessage(String path, int duration);
    }


}

主要的录音管理类

public class RecordManager {
    //录制成MP3格式..............................................
    /**构造时候需要的Activity,主要用于获取文件夹的路径*/
    private Activity activity;
    /**文件代号*/
    public static final int RAW = 0X00000001;
    public static final int MP3 = 0X00000002;
    /**文件路径*/
    private String rawPath = null;
    private String mp3Path = null;
    /**采样频率*/
    private static final int SAMPLE_RATE = 11025;
    /**录音需要的一些变量*/
    private short[] mBuffer;
    private AudioRecord mRecorder;

    /**录音状态*/
    private boolean isRecording = false;
    /**是否转换ok*/
    private boolean convertOk = false;
    public RecordManager(Activity activity, String rawPath, String mp3Path) {
        this.activity = activity;
        this.rawPath = rawPath;
        this.mp3Path = mp3Path;
    }
    /**开始录音*/
    public boolean start_mp3() {
        // 如果正在录音,则返回
        if (isRecording) {
            return isRecording;
        }
        // 初始化
        if (mRecorder == null) {
            initRecorder();
        }
        getFilePath();
        mRecorder.startRecording();
        startBufferedWrite(new File(rawPath));
        isRecording = true;
        return isRecording;
    }
    /**停止录音,并且转换文件,这很可能是个耗时操作,建议在后台中做*/
    public boolean stop_mp3() {
        if (!isRecording) {
            return isRecording;
        }
        // 停止
        mRecorder.stop();


        isRecording = false;
//TODO
        // 开始转换(转换代码就这两句)
//        FLameUtils lameUtils = new FLameUtils(1, SAMPLE_RATE, 96);
//        convertOk = lameUtils.raw2mp3(rawPath, mp3Path);
//        return isRecording ^ convertOk;// convertOk==true,return true
        return isRecording;
    }

    public void saveData(){
        FLameUtils lameUtils = new FLameUtils(1, SAMPLE_RATE, 96);
        convertOk = lameUtils.raw2mp3(rawPath, mp3Path);

    }



    /**获取文件的路径*/
    public String getFilePath(int fileAlias) {
        if (fileAlias == RAW) {
            return rawPath;
        } else if (fileAlias == MP3) {
            return mp3Path;
        } else
            return null;
    }
    /**清理文件*/
    public void cleanFile(int cleanFlag) {
        File f = null;
        try {
            switch (cleanFlag) {
                case MP3:
                    f = new File(mp3Path);
                    if (f.exists())
                        f.delete();
                    break;
                case RAW:
                    f = new File(rawPath);
                    if (f.exists())
                        f.delete();
                    break;
                case RAW | MP3:
                    f = new File(rawPath);
                    if (f.exists())
                        f.delete();
                    f = new File(mp3Path);
                    if (f.exists())
                        f.delete();
                    break;
            }
            f = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**关闭,可以先调用cleanFile来清理文件*/
    public void close() {
        if (mRecorder != null)
            mRecorder.release();
        activity = null;
    }
    /**初始化*/
    private void initRecorder() {
        int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
                AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
        mBuffer = new short[bufferSize];
        mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE,
                AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
                bufferSize);
    }
    /**设置路径,第一个为raw文件,第二个为mp3文件*/
    private void getFilePath() {
        try {
            String folder = "audio_recorder_2_mp3";
            String fileName = String.valueOf(System.currentTimeMillis());
            if (rawPath == null) {
                File raw = new File(activity.getDir(folder,
                        activity.MODE_PRIVATE), fileName + ".raw");
                raw.createNewFile();
                rawPath = raw.getAbsolutePath();
                raw = null;
            }
            if (mp3Path == null) {
                File mp3 = new File(activity.getDir(folder,
                        activity.MODE_PRIVATE), fileName + ".mp3");
                mp3.createNewFile();
                mp3Path = mp3.getAbsolutePath();
                mp3 = null;
            }
            Log.d("rawPath", rawPath);
            Log.d("mp3Path", mp3Path);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**执行cmd命令,并等待结果*/
    private boolean runCommand(String command) {
        boolean ret = false;
        Process process = null;
        try {
            process = Runtime.getRuntime().exec(command);
            process.waitFor();
            ret = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                process.destroy();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ret;


    }

    /**写入到raw文件*/
    private void startBufferedWrite(final File file) {
        Object mLock = new Object();
        new Thread(new Runnable() {
            @Override
            public void run() {
                DataOutputStream output = null;
                try {
                    output = new DataOutputStream(new BufferedOutputStream(
                            new FileOutputStream(file)));
                    while (isRecording) {//开始录制


                        int readSize = mRecorder.read(mBuffer, 0,
                                mBuffer.length);//是实际读取的数据长度
                        for (int i = 0; i < readSize; i++) {
                            output.writeShort(mBuffer[i]);
                        }
                        long v = 0;
                        // 将 buffer 内容取出,进行平方和运算
                        for (int i = 0; i < mBuffer.length; i++) {
                            v += mBuffer[i] * mBuffer[i];
                        }
                        // 平方和除以数据总长度,得到音量大小。
                        double mean = v / (double) readSize;
                        double volume = 10 * Math.log10(mean);


                        synchronized (mLock) {
                            try {

                                if(null != audioStatusUpdateListener) {
                                    audioStatusUpdateListener.onUpdate(volume);
                                }

                                mLock.wait(100);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }




                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (output != null) {
                        try {
                            output.flush();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            try {
                                output.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }).start();
    }



       public RecordManager.OnAudioStatusUpdateListener audioStatusUpdateListener;
     public void setOnAudioStatusUpdateListener(RecordManager.OnAudioStatusUpdateListener audioStatusUpdateListener) {
        this.audioStatusUpdateListener = audioStatusUpdateListener;
    }

    public interface OnAudioStatusUpdateListener {
        public void onUpdate(double db);
    }





}

完整代码:https://download.csdn.net/download/shihuiyun/11980411 

你可能感兴趣的:(android,MP3,录音)