Android上封装的一个音频工具类

来源:互联网 发布:弱网络测试 编辑:程序博客网 时间:2024/05/16 11:48
package washpan.record.tool.audio;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import android.content.ContentValues;import android.content.Context;import android.database.Cursor;import android.media.MediaPlayer;import android.media.MediaRecorder;import android.net.Uri;import android.os.Handler;import android.os.Message;import android.provider.MediaStore;/** * @author 陆扬 washpan * @管理音频的工具类, 单例模式,包括录音,停止录音,播放录音,设置音量,获取实时麦克风音量  Audio Manager class, singleton design, it *            can record audio,stop record,play audio,set volume,get microphone input stream real time * */public enum AudioTool {INSTANCE;private static final int PREPARE = 0x00001;/** * @得到实例 Get instance * */public static AudioTool getInstance() {return INSTANCE;}private AudioTool() {}/** * @录音播放器 Audio player * */private MediaPlayer recordPlayer;/** * @录音管理类 Recorder manager * */private MediaRecorder mMediaRecorder;/** * @麦克风实时数据接口 Microphone real time data interface * */public interface MicRealTimeListener {/** * @得到麦克风的实时大小 get size of microphone real time * @param size *            获取的实时音量大小 volume of microphone real time * */public void getMicRealTimeSize(float size);}/** * @开始录音 Start record audio * @param file *            录音文件 record file * */public void startRecord(File file,final MicRealTimeListener realTimeListener) {if (file.exists()) {file.delete();}mMediaRecorder = new MediaRecorder();mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);mMediaRecorder.setOutputFile(file.getAbsolutePath());try {mMediaRecorder.prepare();} catch (Exception e) {e.printStackTrace();}// 开始录音mMediaRecorder.start();// 开始计时和计算波形Timecounter = new SecondCounter();stoprecord = false;handlerConuter.post(Timecounter);// 开始计算波形mirophone = new MicrophoneThread(realTimeListener);handlerConuter.post(mirophone);}/** * @ 停止录音 Stop record audio *  * @param file *            录音文件 record file * */public void stopRecorder(Context context, File file) {if (file != null) {{// 停止计时器Message msg = new Message();msg.what = STOP_RECORDER;handlerConuter.sendMessage(msg);mMediaRecorder.stop();mMediaRecorder.reset();mMediaRecorder.release();Uri uri = MediaStore.Audio.Media.getContentUriForPath(file.getAbsolutePath());Cursor cursor = context.getContentResolver().query(uri, null,MediaStore.MediaColumns.DATA + "=?",new String[] { file.getAbsolutePath() }, null);boolean newdata = false;if (cursor.moveToFirst() && cursor.getCount() > 0) {} else {newdata = true;}ContentValues values = new ContentValues();values.put(MediaStore.Audio.Media.DATE_ADDED,(int) System.currentTimeMillis() / 1000);values.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath());values.put(MediaStore.MediaColumns.TITLE, file.getName());values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/3gp");values.put(MediaStore.MediaColumns.DISPLAY_NAME, file.getName());values.put(MediaStore.Audio.Media.DURATION, millionSeconds);if (newdata) {context.getContentResolver().insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,values);} else {context.getContentResolver().update(uri, values,MediaStore.MediaColumns.DATA + "=?",new String[] { file.getAbsolutePath() });}millionSeconds = 0;}}}/** * @停止播放录音 Stop audio player * */public void StopPlayRecord() {if (null != recordPlayer) {if (recordPlayer.isPlaying()) {recordPlayer.stop();recordPlayer.release();recordPlayer = null;}}}/** * @用于预设播放器 Prepare player * */private Handler handlerPlayer = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case PREPARE:try {recordPlayer.prepareAsync();} catch (IllegalStateException e) {e.printStackTrace();}break;}}};/** * @播放录音完毕后的监听类 Audio player has played completed listener * */private android.media.MediaPlayer.OnCompletionListener mListener;/** * @播放录音 Play audio * @param context *            某个Activity的上下文 Activity's context * @param listener *            监听录音文件播放完毕,并进行回调 Audio player has played completed listener * @param file *            录音文件 record file * */public void playAudioFileAsy(Context context,android.media.MediaPlayer.OnCompletionListener listener, File file) {this.mListener = listener;if (file != null && file.exists()) {if (null != recordPlayer) {recordPlayer.stop();recordPlayer.release();recordPlayer = null;}// 这里之前要注意释放资源,最好不要用系统提供的静态方式初始化recordPlayer = new MediaPlayer();FileInputStream fis = null;;try {fis = new FileInputStream(file);} catch (FileNotFoundException e1) {e1.printStackTrace();}try {recordPlayer.setDataSource(fis.getFD());} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalStateException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}Message msg = new Message();msg.what = PREPARE;handlerPlayer.sendMessage(msg);// 这里必须是监听prepared事件之后才开始播放,否则将会有异常出现recordPlayer.setOnPreparedListener(new android.media.MediaPlayer.OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mp) {mp.start();if (null != mListener) {mListener.onCompletion(mp);}}});}}/** * @设置录音音量 * @param vol *            音量值,范围为0.0到1.0 Set volume, Value range 0.0 to 1.0 * */public void setVolume(float vol) {if (recordPlayer != null)recordPlayer.setVolume(vol, vol);}/** * @SD卡是否存在 SD card exist * @return 存在返回true,否则false Return true if exist,otherwise return false * */public boolean isSDCardExist() {return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);}/** * @param context *            某个Activity的上下文 Activity's context * @param displayName *            文件名 File Name * @return 文件播放总时间的毫秒数 Million seconds of audio file * */public String getAudioTime(Context context, String displayName) {String time = "unKnow";String selection = MediaStore.Audio.Media.DISPLAY_NAME + "=?";String[] projection = { MediaStore.Audio.Media.DURATION };Cursor cursor = null;cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection,selection, new String[] { displayName }, null);if (null != cursor) {cursor.moveToFirst();time = "" + cursor.getLong(0);}return time;}/** * @录音时长 Record seconds * */private long millionSeconds = 0;/** * @计时器 Timer counter * */private SecondCounter Timecounter;/** * @麦克风监听线程 Microphone thread * */private MicrophoneThread mirophone;/** * @终止计时器标志位 Stop counter * */private boolean stoprecord = false;/** * @同步线程锁 Lock object * */private static Object objLock = new Object();/** * @终止计时消息 Message of stop recorder * */private static final int STOP_RECORDER = 0x00002;/** * @控制计数器和录音流 Control counter and microphone stream * */private Handler handlerConuter = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case STOP_RECORDER:stoprecord = true;break;}}};final float minAngle = (float) Math.PI / 8;final float maxAngle = (float) Math.PI * 7 / 8;float angle = minAngle;float mCurrentAngle = angle;static final float DROPOFF_STEP = 0.18f;/** * @实时监听麦克风的音量大小 Monitor microphone's input stream size * */class MicrophoneThread implements Runnable {private MicRealTimeListener realTimeListener;public MicrophoneThread(MicRealTimeListener l) {realTimeListener = l;}@Overridepublic void run() {synchronized (objLock) {if (stoprecord)return;if (null != mMediaRecorder)angle = (float) (maxAngle - minAngle)* mMediaRecorder.getMaxAmplitude() / 32768;if (angle > mCurrentAngle)mCurrentAngle = angle;elsemCurrentAngle = Math.max(angle, mCurrentAngle- DROPOFF_STEP);mCurrentAngle = Math.min(maxAngle, mCurrentAngle);if (null != realTimeListener) {realTimeListener.getMicRealTimeSize(mCurrentAngle);}handlerConuter.postDelayed(mirophone, 100);}}}/** * @计时器 Time counter * */class SecondCounter implements Runnable {@Overridepublic void run() {synchronized (objLock) {if (stoprecord) {return;}millionSeconds++;handlerConuter.postDelayed(Timecounter, 1);}}}}