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

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() {

		@Override
		public 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() {

						@Override
						public 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() {

		@Override
		public 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;
		}

		@Override
		public void run() {
			synchronized (objLock) {
				if (stoprecord)
					return;
				if (null != mMediaRecorder)
					angle = (float) (maxAngle - minAngle)
							* mMediaRecorder.getMaxAmplitude() / 32768;

				if (angle > mCurrentAngle)
					mCurrentAngle = angle;
				else
					mCurrentAngle = 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 {

		@Override
		public void run() {
			synchronized (objLock) {
				if (stoprecord) {
					return;
				}
				millionSeconds++;
				handlerConuter.postDelayed(Timecounter, 1);
			}
		}
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值