最近项目要求做一个录音功能,要可以暂停的,然后对音频进行加密解密,还要根据声音大小做一个自定义的柱形图,废话不多说,下面进行录音功能实现:
项目大概长这样:
设计的思路:
由于自带的AudioRecord没有pauseRecord()方法,我把开始录音-->(暂停/继续录音)...-->停止录音叫做一次录音,点击一次暂停就会产生一个文件(.pcm),再点击的时候对文件进行继续写入。
对类的说明:
- AudioRecorder:封装了录音的方法:创建录音对象、开始、暂停、停止、取消,使用静态枚举类Status来记录录音的状态。
- AudioFileUtils:文件工具类,用于文件路径的获取
- AudioEncoder:对文件进行转码的父类,采用mvp模式,具体实现看子类的
- AmrEncoder:继承AudioEncoder,实现父类的转码方法,amr格式。
- WavEncoder:继承AudioEncoder,实现父类的转码方法,wav格式。
- WaveHeader: wav文件头
- onVoluneListener:监听录音分贝大小,用于拓展业务的处理。
- RecordService:将录音功能集成封装在服务里面,暴露几个方法调用的接口
- AESUtils:用aes对音频文件进行加解密,提高用户信息的安全性。
开始之前记得添加权限:
<!-- 获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 假如我们要保存录音,还需要以下权限 -->
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- SD卡权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
接下来就是关键代码:
1、AudioRecorder类:
package com.zqr.snake.mytest.record3;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class AudioRecorder {
private static final String TAG = "AudioRecorder";
private int audioInput = MediaRecorder.AudioSource.MIC;//来源
private int audioSampleRate = 8000;//频率
private int audioChannel = AudioFormat.CHANNEL_IN_MONO;//声道
private int audioEncode = AudioFormat.ENCODING_PCM_16BIT;//编码样式
private int bufferSizeInBytes = 0;
private AudioRecord audioRecord;
private Status status = Status.STATUS_NO_READY;
protected String pcmFileName;
private Timer timer;
private TimerTask timerTask;
private int currentPosition = 0;
private CallBack callBack;
private int lastVolumn = 0;//录音的分贝
private AudioEncoder encoder;//编码格式
public AudioRecorder(CallBack callBack, AudioEncoder encoder) {
String fileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
pcmFileName = AudioFileUtils.getPcmFileAbsolutePath(fileName);
this.encoder = encoder;
// encoder.init(audioSampleRate, 16, 1);
File file = new File(pcmFileName);
if (file.exists()) {
file.delete();
}
status = Status.STATUS_READY;
this.callBack = callBack;
}
public void setAudioInput(int audioInput) {
this.audioInput = audioInput;
}
public void setAudioSampleRate(int audioSampleRate) {
this.audioSampleRate = audioSampleRate;
}
public void setAudioChannel(int audioChannel) {
this.audioChannel = audioChannel;
}
public void setEncoder(AudioEncoder encoder) {
this.encoder = encoder;
}
private void startTimer() {
if (timer == null)
timer = new Timer();
if (timerTask != null) {
timerTask.cancel();
}
timerTask = new TimerTask() {
@Override
public void run() {
currentPosition++;
if (callBack != null && status == Status.STATUS_START) {
callBack.recordProgress(currentPosition);
callBack.volumn(lastVolumn);
}
}
};
timer.schedule(timerTask, 0, 100);
}
private void stopTimer() {
if (timer != null) {
timer.cancel();
timer = null;
}
if (timerTask != null) {
timerTask.cancel();
timerTask = null;
}
}
public void startRecord() {
bufferSizeInBytes = AudioRecord.getMinBufferSize(audioSampleRate,
audioChannel, audioEncode);
audioRecord = new AudioRecord(audioInput, audioSampleRate, audioChannel, audioEncode, bufferSizeInBytes);
if (status == Status.STATUS_NO_READY) {
return;
// throw new IllegalStateException("not init");
}
if (status == Status.STATUS_START) {
return;
// throw new IllegalStateException("is recording ");
}
Log.d("AudioRecorder2", "===startRecord===" + audioRecord.getState());
audioRecord.startRecording();
new Thread(new Runnable() {
@Override
public void run() {
recordToFile();
}
}).start();
startTimer();
}
public void stop() {
currentPosition = 0;
if (status != Status.STATUS_START && status != Status.STATUS_PAUSE) {
return;
// throw new IllegalStateException("not recording");
} else {
stopRecorder();
makeDestFile();
status = Status.STATUS_READY;
}
}
//文件进行转码
private void makeDestFile() {
if (encoder == null)
return;
new Thread() {
@Override
public void run() {
encoder.init(audioSampleRate, audioSampleRate * 16 * audioRecord.getChannelCount(), audioRecord.getChannelCount());
encoder.encode(pcmFileName);
releaseRecorder();
}
}.run();
}
/**
* 取消录音
*/
public void release() {
Log.d("AudioRecorder2", "===release===");
stopRecorder();
releaseRecorder();
status = Status.STATUS_READY;
clearFiles();
}
//释放资源
private void releaseRecorder() {
if (audioRecord != null) {
audioRecord.release();
audioRecord = null;
}
}
//停止录音
private void stopRecorder() {
stopTimer();
if (audioRecord != null) {
try {
audioRecord.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 清除文件
*/
public void clearFiles() {
try {
File pcmfile = new File(pcmFileName);
if (pcmfile.exists())
pcmfile.delete();
if (encoder != null && !TextUtils.isEmpty(encoder.getDestFile())) {
File file = new File(encoder.getDestFile());
if (file.exists())
file.delete();
}
}catch (Exception e){
e.printStackTrace();
}
}
//将音频写入文件
private void recordToFile() {
byte[] audiodata = new byte[bufferSizeInBytes];
FileOutputStream fos = null;
int readsize = 0;
try {
fos = new FileOutputStream(pcmFileName, true);
} catch (FileNotFoundException e) {
Log.e("AudioRecorder", e.getMessage());
}
status = Status.STATUS_START;
while (status == Status.STATUS_START && audioRecord != null) {
readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);
if (AudioRecord.ERROR_INVALID_OPERATION != readsize && fos != null) {
try {
//get the volumn 1--10
int sum = 0;
for (int i = 0; i < readsize; i++) {
sum += Math.abs(audiodata[i]);
}
if (readsize > 0) {
int raw = sum / readsize;
lastVolumn = raw > 10 ? raw - 10 : 0;
Log.i(TAG, "writeDataTOFile: volumn -- " + raw + " / lastvolumn -- " + lastVolumn);
}
if (readsize > 0 && readsize <= audiodata.length)
fos.write(audiodata, 0, readsize);
} catch (IOException e) {
Log.e("AudioRecorder", e.getMessage());
}
}
}
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
Log.e("AudioRecorder", e.getMessage());
}
}
public int getCurrentPosition() {
return currentPosition;
}
/**
* 获取当前的录音状态
* @return
*/
public Status getStatus() {
return status;
}
/**
* 获取当前的录音文件的位置
* @return
*/
public String getVoiceFilePath() {
return encoder == null ? pcmFileName : encoder.getDestFile();
}
/**
* 录音的状态
*/
public enum Status {
STATUS_NO_READY,
STATUS_READY,
STATUS_START,
STATUS_PAUSE,
STATUS_STOP
}
public interface CallBack {
public void recordProgress(int progress);
public void volumn(int volumn);
}
/**
* 暂停录音
*/
public void pauseRecord() {
Log.d("AudioRecorder2","===pauseRecord===");
if (status != Status.STATUS_START) {
throw new IllegalStateException("没有在录音");
} else {
stopRecorder();
// audioRecord.stop();
status = Status.STATUS_PAUSE;
}
}
}
2.AudioEncoder类:
package com.zqr.snake.mytest.record3;
import android.annotation.TargetApi;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.os.Build;
import android.support.annotation.NonNull;
import java.io.IOException;
/**
*
*/
public abstract class AudioEncoder {
protected int SAMPLE_RATE = 8000;
protected int BIT_RATE = 64;
protected int CHANNEL_COUNT = 1;
protected String destinationFile;
public void init(int SAMPLE_RATE, int BIT_RATE, int CHANNEL_COUNT) {
this.SAMPLE_RATE = SAMPLE_RATE;
this.BIT_RATE = BIT_RATE;
this.CHANNEL_COUNT = CHANNEL_COUNT;
}
public String getDestFile() {
return destinationFile;
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@NonNull
protected MediaFormat getMediaFormat(String sourceFile) throws IOException {
MediaExtractor mex = new MediaExtractor();
mex.setDataSource(sourceFile);
return mex.getTrackFormat(0);
}
public abstract void encode(String sourceFile);
}
3.AmrEncoder(这里我只分享amr的类)
package com.zqr.snake.mytest.record3;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.os.Build;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
*
*/
public class AmrEncoder extends AudioEncoder {
private static byte[] header = new byte[]{'#', '!', 'A', 'M', 'R', '\n'};
@Override
public void init(int SAMPLE_RATE, int BIT_RATE, int CHANNEL_COUNT) {
super.init(SAMPLE_RATE, BIT_RATE, CHANNEL_COUNT);
String fileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
destinationFile = AudioFileUtils.getAmrFileAbsolutePath(fileName);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@SuppressLint("WrongConstant")
@Override
public void encode(String sourceFile) {
try {
MediaCodec encoder = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_AUDIO_AMR_NB);
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AMR_NB);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, SAMPLE_RATE);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, CHANNEL_COUNT);
format.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
File pcmFile = new File(sourceFile);
FileInputStream fis = new FileInputStream(pcmFile);
File armFIle = new File(destinationFile);
FileOutputStream fos = new FileOutputStream(armFIle);
fos.write(header);
encoder.start();
ByteBuffer[] codecInputBuffers = encoder.getInputBuffers();
ByteBuffer[] codecOutputBuffers = encoder.getOutputBuffers();
byte[] tempBuffer = new byte[88200];
boolean hasMoreData = true;
MediaCodec.BufferInfo outBuffInfo = new MediaCodec.BufferInfo();
double presentationTimeUs = 0;
int totalBytesRead = 0;
do {
int inputBufIndex = 0;
while (inputBufIndex != -1 && hasMoreData) {
inputBufIndex = encoder.dequeueInputBuffer(0);
if (inputBufIndex >= 0) {
ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
dstBuf.clear();
int bytesRead = fis.read(tempBuffer, 0, dstBuf.limit());
if (bytesRead == -1) { // -1 implies EOS
hasMoreData = false;
encoder.queueInputBuffer(inputBufIndex, 0, 0, (long) presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
} else {
totalBytesRead += bytesRead;
dstBuf.put(tempBuffer, 0, bytesRead);
encoder.queueInputBuffer(inputBufIndex, 0, bytesRead, (long) presentationTimeUs, 0);
presentationTimeUs = 1000000l * (totalBytesRead / 2) / SAMPLE_RATE;
}
}
}
// Drain audio
int outputBufIndex = 0;
while (outputBufIndex != MediaCodec.INFO_TRY_AGAIN_LATER) {
outputBufIndex = encoder.dequeueOutputBuffer(outBuffInfo, 0);
if (outputBufIndex >= 0) {
ByteBuffer encodedData = codecOutputBuffers[outputBufIndex];
encodedData.position(outBuffInfo.offset);
encodedData.limit(outBuffInfo.offset + outBuffInfo.size);
byte[] outData = new byte[outBuffInfo.size];
encodedData.get(outData, 0, outBuffInfo.size);
fos.write(outData, 0, outBuffInfo.size);
encoder.releaseOutputBuffer(outputBufIndex, false);
}
}
} while (outBuffInfo.flags != MediaCodec.BUFFER_FLAG_END_OF_STREAM);
if (fis != null) {
fis.close();
fis = null;
}
if (fos != null) {
fos.flush();
fos.close();
}
File oldfile = new File(sourceFile);
if (oldfile.exists()) {
oldfile.delete();
}
AESUtils.Encrypt(destinationFile,"key");
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.AudioFileUtils(文件管理的类)
package com.zqr.snake.mytest.record3;
import android.os.Environment;
import android.text.TextUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AudioFileUtils {
private static String rootPath = "audiorecord";
private final static String AUDIO_PCM_BASEPATH = "/" + rootPath + "/pcm/";
private final static String AUDIO_WAV_BASEPATH = "/" + rootPath + "/wav/";
private final static String AUDIO_AMR_BASEPATH = "/" + rootPath + "/amr/";
private final static String AUDIO_TEMP_BASEPATH = "/" + rootPath + "/temp/";//临时文件
public static void setRootPath(String rootPath) {
AudioFileUtils.rootPath = rootPath;
}
public static String getPcmFileAbsolutePath(String fileName) {
if (TextUtils.isEmpty(fileName)) {
throw new NullPointerException("fileName isEmpty");
}
String mAudioRawPath = "";
if (!fileName.endsWith(".pcm")) {
fileName = fileName + ".pcm";
}
String fileBasePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + rootPath + "/pcm/";
File file = new File(fileBasePath);
if (!file.exists()) {
file.mkdirs();
}
mAudioRawPath = fileBasePath + fileName;
return mAudioRawPath;
}
public static String getWavFileAbsolutePath(String fileName) {
if (fileName == null) {
throw new NullPointerException("fileName can't be null");
}
String mAudioWavPath = "";
if (!fileName.endsWith(".wav")) {
fileName = fileName + ".wav";
}
String fileBasePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + rootPath + "/wav/";
File file = new File(fileBasePath);
if (!file.exists()) {
file.mkdirs();
}
mAudioWavPath = fileBasePath + fileName;
return mAudioWavPath;
}
public static String getAmrFileAbsolutePath(String fileName) {
if (fileName == null) {
throw new NullPointerException("fileName can't be null");
}
String mAudioWavPath = "";
if (!fileName.endsWith(".amr")) {
fileName = fileName + ".amr";
}
String fileBasePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + rootPath + "/amr/";
File file = new File(fileBasePath);
if (!file.exists()) {
file.mkdirs();
}
mAudioWavPath = fileBasePath + fileName;
return mAudioWavPath;
}
//获取临时文件的方法名字
public static String getTempFileAbsolutePath(String fileName) {
if (fileName == null) {
throw new NullPointerException("fileName can't be null");
}
String mAudioWavPath = "";
if (!fileName.endsWith(".amr")) {
fileName = fileName + ".amr";
}
String fileBasePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + rootPath + "/temp/";
File file = new File(fileBasePath);
if (!file.exists()) {
file.mkdirs();
}
mAudioWavPath = fileBasePath + fileName;
return mAudioWavPath;
}
/**
* 获取全部amr文件列表
*
* @return
*/
public static List<File> getAmrFiles() {
List<File> list = new ArrayList<>();
String fileBasePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + rootPath + "/amr/";
File rootFile = new File(fileBasePath);
if (!rootFile.exists()) {
} else {
File[] files = rootFile.listFiles();
for (File file : files) {
list.add(file);
}
}
Collections.reverse(list); //倒序排列
return list;
}
}
5.对音频文件进行加解密的类AESUtils:
package com.zqr.snake.mytest.record3;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AESUtils {
/* 加密 */
private static byte[] encryptVoice(String seed, byte[] clearbyte)
throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, clearbyte);
return result;
}
/* 解密 */
private static byte[] decryptVoice(String seed, byte[] encrypted)
throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = decrypt(rawKey, encrypted);
return result;
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
sr.setSeed(seed);
kgen.init(128, sr);
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(
new byte[cipher.getBlockSize()]));
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private static byte[] decrypt(byte[] raw, byte[] encrypted)
throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(
new byte[cipher.getBlockSize()]));
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
/**
* 加密 - AES
*/
public static void Encrypt(String Path,String seed) {
// Log.d("加密 - AES", "----加密开始时间: " + new Date().getTime()/1000);
FileInputStream fis = null;
FileOutputStream fos = null;
boolean isSuccess = true;
try {
File oldFile = new File(Path);
fis = new FileInputStream(oldFile);
byte[] oldByte = new byte[(int) oldFile.length()];
fis.read(oldByte); // 读取
byte[] newByte = AESUtils.encryptVoice(seed, oldByte);
// 加密
fos = new FileOutputStream(oldFile);
fos.write(newByte);
} catch (FileNotFoundException e) {
isSuccess = false;
e.printStackTrace();
} catch (IOException e) {
isSuccess = false;
e.printStackTrace();
} catch (Exception e) {
isSuccess = false;
e.printStackTrace();
} finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (isSuccess)
Log.d("加密 - AES", "加密成功");
else
Log.d("加密 - AES", "加密失败");
// Log.d("加密 - AES", "----加密结束时间: " + new Date().getTime()/1000);
// Log.i("加密 - AES", "保存成功");
}
/**
* 解密 - AES
*/
public static String Decrypt(String playerPath,String seed) {
// Log.d("解密 - AES", "----解密开始时间: " + new Date().getTime());
File oldFile = new File(playerPath);
// File tempFile = new File(AudioFileUtils.getTempFileAbsolutePath(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())));
File tempFile = new File(AudioFileUtils.getTempFileAbsolutePath(oldFile.getName()));
FileInputStream fis = null;
FileOutputStream fos = null;
boolean isSuccess = true;
byte[] oldByte = new byte[(int) oldFile.length()];
try {
fis = new FileInputStream(oldFile);
fis.read(oldByte);
byte[] newByte = AESUtils.decryptVoice(seed, oldByte);
// 解密
fos = new FileOutputStream(tempFile);
fos.write(newByte);
} catch (FileNotFoundException e) {
isSuccess = false;
e.printStackTrace();
} catch (IOException e) {
isSuccess = false;
e.printStackTrace();
} catch (Exception e) {
isSuccess = false;
e.printStackTrace();
}
try {
fis.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
// Log.d("解密 - AES", "----解密结束时间: " + new Date().getTime());
if (isSuccess){
Log.i("解密 - AES", "解密成功");
return tempFile.getPath();
} else {
Log.i("解密 - AES", "解密失败");
return "";
}
}
}
最后就是对这些功能进行封装在服务RecordService:
package com.zqr.snake.mytest.record3;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
public class RecordService extends Service {
private MyIBinder myIBinder;
private AudioRecorder audioRecorder;
private MediaPlayer mediaPlayer;
private int mVolume;
private String currentPlayPath;
/**
* 更新分贝的回调接口
*/
private onVoluneListener listener;
/**
* 注册回调接口的方法,供外部调用
* @param onProgressListener
*/
public void setOnProgressListener(onVoluneListener onProgressListener) {
this.listener = onProgressListener;
}
@Override
public IBinder onBind(Intent intent) {
return myIBinder; //返回的MyIBinder对象会在onServiceConnected()中调用
}
@Override
public void onCreate() {
super.onCreate();
myIBinder =new MyIBinder();//启动服务时即创建Binder对象
initRecorder();
initPlayer();
}
@Override
public void onDestroy() {
super.onDestroy();
}
private void initPlayer() {
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
if (!TextUtils.isEmpty(currentPlayPath)){
File file = new File(currentPlayPath);
if (file.exists()) file.delete();
currentPlayPath = "";
}
}
});
}
private void initRecorder() {
audioRecorder = new AudioRecorder(new AudioRecorder.CallBack() {
@Override
public void recordProgress(final int progress) {
if (listener != null){
listener.recordProgress(progress);
}
}
@Override
public void volumn(int volumn) {
if (listener != null){
listener.volume(volumn);
}
}
}, new AmrEncoder());
}
//代理人
public class MyIBinder extends Binder implements RecordInterface{
/**
* 获取当前Service的实例
* @return
*/
public RecordService getService(){
return RecordService.this;
}
/**
* 开始录制
*/
@Override
public void start() {
RecordService.this.startReecrd();
}
/**
* 暂停录制
*/
@Override
public AudioRecorder.Status pause() {
return RecordService.this.pauseReecrd();
}
/**
* 开始播放
*/
@Override
public void paly() {
RecordService.this.palyReecrd();
}
/**
* 取消录制
*/
@Override
public void cancle() {
RecordService.this.cancleReecrd();
}
/**
* 停止录制
*/
@Override
public void stop() {
RecordService.this.stopReecrd();
}
/**
* 获取实时分贝大小
*/
@Override
public int getVolume() {
return mVolume;
}
/**
* 设置录制保存路径
*/
@Override
public void setPath(String path) {
RecordService.this.setRootPath(path);
}
/**
* 停止播放
*/
@Override
public void stopPlay() {
RecordService.this.stopPalyReecrd();
}
}
public void startReecrd(){
audioRecorder.startRecord();
}
public void cancleReecrd(){
audioRecorder.release();
}
public AudioRecorder.Status pauseReecrd(){
try {
if (audioRecorder.getStatus() == AudioRecorder.Status.STATUS_START) {
//暂停录音
audioRecorder.pauseRecord();
// btn_pause.setText("继续录音");
} else {
audioRecorder.startRecord();
// btn_pause.setText("暂停录音");
}
} catch (IllegalStateException e) {
e.printStackTrace();
}finally {
return audioRecorder.getStatus();
}
}
public void stopReecrd(){
audioRecorder.stop();
}
public void setRootPath(String path){
AudioFileUtils.setRootPath(path);
}
public void palyReecrd(){
try {
if (mediaPlayer == null) initPlayer();
String path = AESUtils.Decrypt(audioRecorder.getVoiceFilePath(),"key");
if (TextUtils.isEmpty(path)) return;
mediaPlayer.reset();
mediaPlayer.setDataSource(path);
currentPlayPath = path;
mediaPlayer.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopPalyReecrd(){
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
}
public interface RecordInterface {
void start();
AudioRecorder.Status pause();
void paly();
void cancle();
void stop();
int getVolume();
void setPath(String path);
void stopPlay();
}
}
最后项目源码下载地址:https://download.csdn.net/download/zqr772791008/11197086
欢迎大家一起来学习!!!