AudioRecorder 录音及播放,音量的获取。

池恩
2023-12-01

AudioUtil 工具类:

public class AudioUtil{
    /**
     * 构造时候需要的Activity,主要用于获取文件夹的路径
     */
    private Activity activity;

    /**
     * 文件代号
     */
    public static final int RAW = 0X00000001;
    public static final int MP3 = 0X00000002;

    /**
     * 文件路径
     */
    private String rawPath = null;
    private String mp3Path = null;

    /**
     * 采样频率 8000
     */
    private static final int SAMPLE_RATE = 8000;

    /**
     * 录音需要的一些变量
     */
    private short[] mBuffer;
    /**
     * 录音状态
     */
    private boolean isRecording = false;
    /**
     * 是否转换ok
     */
    private boolean convertOk = false;
    /**
     * 錄音類
     */
    private AudioRecord mRecorder;
    
    // 录音文件播放
    private MediaPlayer mediaPlayer;
    private double mEMA = 0.0;
    static final private double EMA_FILTER = 0.6;    
    //AudioRecorder的字符
    private int mRecorder_BufferSize;
//    private RecordThread recordThread;
    
    private ThreadCallBack callBack;
    
    public ThreadCallBack getCallBack() {
        return callBack;
    }
    public void setCallBack(ThreadCallBack callBack) {
        this.callBack = callBack;
    }
    /**
     * 构造方法
     * 
     * @param activity
     */
    public AudioUtil(Activity activity) {
        this.activity = activity;
    }
    /**
     * 开始录音
     * @param rawPath 絕對且完整文件路徑 
     * @param mp3Path 絕對且完整絕對路徑
     */
    public boolean startRecording(String rawPath, String mp3Path) {
        // 如果正在录音,则返回
        if (isRecording) {
            return isRecording;
        }
        
        this.rawPath = rawPath;
        this.mp3Path = mp3Path;
        // 初始化
        if (mRecorder == null) {
            initRecorder();
        }
        //產生文件
        createFilePath(rawPath,mp3Path);
        
        mRecorder.startRecording();
        
//        recordThread = new RecordThread(mRecorder,mRecorder_BufferSize);
//        recordThread = new RecordThread();
//        recordThread.setCallBack(this);
//        recordThread.start();
        //開始錄音
        startBufferedWrite(new File(rawPath));

        isRecording = true;
        return isRecording;
    }
    
    /**
     * 停止录音,并且转换文件,<br/>
     * <b>这很可能是个耗时操作,建议在后台中做
     * 
     * @return
     */
    public boolean stopRecordingAndConvertFile() {
        if (!isRecording) {
            return isRecording;
        }
        if(mRecorder != null){
//            recordThread.setRun(false);
            // 停止
            mRecorder.stop();
            mRecorder.release();
            isRecording = false;
            // 开始转换
            FLameUtils lameUtils = new FLameUtils(1, SAMPLE_RATE, 96);
            convertOk = lameUtils.raw2mp3(rawPath, mp3Path);
            mRecorder = null;
            
//            File file = new File(mp3Path);
//            Log.v("123", "AudioUtil stopRecordin轉換="+convertOk+"  amrPath="+rawPath +" length="+file.length());
        
            // amrPath=/storage/emulated/0/Android/data/com.mit.anxin.activity/recorder/AX20141023141409.amr length=1728
            //mp3Path=/storage/emulated/0/Android/data/com.mit.anxin.activity/recorder/AX20141023135126.mp3 length=37440  4秒
        }

        return isRecording ^ convertOk;// convertOk==true,return true
    }
    
    /**
     * 初始化
     */
    private void initRecorder() {
//        int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, 
//                AudioFormat.CHANNEL_IN_MONO, 
//                AudioFormat.ENCODING_PCM_16BIT);
        mRecorder_BufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, 
                AudioFormat.CHANNEL_IN_MONO, 
                AudioFormat.ENCODING_PCM_16BIT);
        mBuffer = new short[mRecorder_BufferSize];
        mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE, 
                AudioFormat.CHANNEL_IN_MONO, 
                AudioFormat.ENCODING_PCM_16BIT,
                mRecorder_BufferSize);
    }
    
    /**
     * 设置路径,第一个为raw文件,第二个为mp3文件
     * 
     * @return
     */
    private void createFilePath(String rawpath,String mp3Path) {
        try{
            File raw = new File(rawpath);
            raw.createNewFile();
            
            File mp3 = new File(mp3Path);
            mp3.createNewFile();
        
//            Log.d("AudioUtil", "rawPath = "+rawPath);
//            Log.d("AudioUtil", "mp3Path = "+mp3Path);

            runCommand("chmod 777 " + rawPath);
            runCommand("chmod 777 " + mp3Path);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 执行cmd命令,并等待结果
     * 
     * @param command
     *            命令
     * @return 是否成功执行
     */
    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文件
     * 
     * @param file
     */
    private void startBufferedWrite(final File file) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                DataOutputStream output = null;
                try {
                    output = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
                    long time1 = System.currentTimeMillis();
                    while (isRecording) {
                        int readSize = mRecorder.read(mBuffer, 0, mBuffer.length);
                        int v = 0;
                        for (int i = 0; i < readSize; i++) {
                            output.writeShort(mBuffer[i]);
//                            output.write(mBuffer[i]);
                            v += mBuffer[i]*mBuffer[i];
                        }
                        long time2 = System.currentTimeMillis();
                        if (time2-time1 >100) {
                            if (!String.valueOf(v / (float) readSize).equals("NaN")) {
//                                float f = Math.abs((v / (float) readSize));
                                float f = (int) (Math.abs((int)(v /(float)readSize)/10000) >> 1);
                                
                                
                                if (null == callBack) {
                                    return;
                                }
                                if (f<=40) {
//                                    Log.i("123456","音量 >> 1");
                                    callBack.onCurrentVoice(1);
                                }else if (f<=80&&f>40) {
//                                    Log.i("123456", "音量 >> 2");
                                    callBack.onCurrentVoice(2);
                                }else if (f<=120&&f>80) {
//                                    Log.i("123456", "音量 >> 3");
                                    callBack.onCurrentVoice(3);
                                }else if (f<=160&&f>120) {
//                                    Log.i("123456", "音量 >> 4");
                                    callBack.onCurrentVoice(4);
                                }else if (f<=200&&f>160) {
//                                    Log.i("123456", "音量 >> 5");
                                    callBack.onCurrentVoice(5);
                                }else if (f<=240&&f>200) {
//                                    Log.i("123456", "音量 >> 6");
                                    callBack.onCurrentVoice(6);
                                }else if (f>240) {
//                                    Log.i("123456", "音量 >> 7");
                                    callBack.onCurrentVoice(7);
                                }
                            }
                            time1 = time2;
                        }
                    }
                } 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();
    }
    
    /**
     * 清理文件
     * 
     * @param cleanFlag
     *            RAW,MP3 or RAW|MP3
     */
    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();
        }
    }

    //开始播放    synchronized
        public void startPlay(String path){
            
            Log.i("startPlay", path);
            
                mediaPlayer = new MediaPlayer();
                try {
                    mediaPlayer.reset();//設置為初始狀態
                    
                    if (mediaPlayer.isPlaying()) {  
                         mediaPlayer.stop();  
                     }  
                    mediaPlayer.setDataSource(path);
                    mediaPlayer.prepare();
                    mediaPlayer.start();
                    /*mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() 
                    {
                        @Override
                        public void onCompletion(MediaPlayer mPlayer) {
                            mPlayer.release();
                            mediaPlayer = null;
                        }
                    });*/
                    
                    mediaPlayer.setOnErrorListener(new android.media.MediaPlayer.OnErrorListener() {
                        @Override
                        public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
                            mediaPlayer.release();//当调用了release()方法后,它就处于End状态
                            mediaPlayer = null;
                            return false;
                        }
                    });
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }
        
        //停止播放
        public void stopPlay(){
            if(mediaPlayer != null){
                if(mediaPlayer.isPlaying()){
                    mediaPlayer.stop();
                    mediaPlayer.release();
                    mediaPlayer = null;
                }
            }
        }
        
//        public double getAmplitude() {
//            if (mRecorder != null){
//                Log.v("123456", "mediaRecorder.getMaxAmplitude()="+mediaRecorder.getMaxAmplitude()+"  "+(mediaRecorder.getMaxAmplitude() / 2700.0));
//                return (mediaRecorder.getMaxAmplitude() / 2700.0);
//            }
//            else
//                return 0;
//        }
//
//        public double getAmplitudeEMA() {
//            double amp = getAmplitude();
//            mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
//            return mEMA;
//        }
//        
        //退出
        public void destory(){
            if(mediaPlayer != null){
                if(mediaPlayer.isPlaying()){
                    mediaPlayer.stop();
                    mediaPlayer.release();
                    mediaPlayer = null;
                }
            }
            if(mRecorder != null){
                mRecorder.release();
                mRecorder = null;
            }
            
        }
        public AudioRecord getmRecorder() {
            return mRecorder;
        }
        public void setmRecorder(AudioRecord mRecorder) {
            this.mRecorder = mRecorder;
        }
        public MediaPlayer getMediaPlayer() {
            return mediaPlayer;
        }
        public void setMediaPlayer(MediaPlayer mediaPlayer) {
            this.mediaPlayer = mediaPlayer;
        }
        public int getmRecorder_BufferSize() {
            return mRecorder_BufferSize;
        }
        public void setmRecorder_BufferSize(int mRecorder_BufferSize) {
            this.mRecorder_BufferSize = mRecorder_BufferSize;
        }
}



ThreadCallBack callBack 这是获取音量的接口,只要类里继承这个接口,就能及时获取变化的音量。

@Override
		public void onCurrentVoice(int currentVolume) {
//			Log.v("currentVoice", currentVolume+"");
			Message msgMessage = mHandler.obtainMessage();
			msgMessage.what = Update_Recorder_Volume;
			msgMessage.arg1 = currentVolume;
			mHandler.sendMessage(msgMessage);
			volumeView.setImageResource(reflectImage(currentVolume));
		}

    private int reflectImage(int image){
            Class<drawable> drawable  =  R.drawable.class;
            Field field = null;
            try {
                field = drawable.getField("amp"+image);
                int r_id = field.getInt(field.getName());
                return r_id;
            } catch (Exception e) {
                Log.e("ERROR", "PICTURE NOT FOUND!");
                return R.drawable.amp1;
            }
        }

public interface ThreadCallBack {
	public void onCurrentVoice(int currentVolume);
}



 类似资料: