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);
}
}
}
}
Android上封装的一个音频工具类
最新推荐文章于 2023-04-04 09:38:42 发布