您的位置:首页 > 移动开发 > Android开发

Android录音

2016-01-28 11:30 549 查看
基础知识

度量声音强度,大家最熟悉的单位就是分贝(decibel,缩写为dB)。这是一个无纲量的相对单位,计算公式如下:



分子是测量值的声压,分母是参考值的声压(20微帕,人类所能听到的最小声压)。因此日常中说道声音强度是多少多少分贝时,都是默认了一个很小的参考值的。
而Android设备传感器可以提供的物理量是场的幅值(amplitude),常用下列公式计算分贝值:



从SDK中读取了某段音频数据的振幅后,取最大振幅或平均振幅(可以用平方和平均,或绝对值的和平均),代入上述公式的A1。
现在问题是,作为参考值的振幅A0取多少呢?
博主查阅很多帖子、博文,这里是最一团浆糊的地方。有的博文取600,是基于它视噪音的振幅为600的假设,此时算出来的是相对背景噪音的分贝值,要是用户不对麦克风发出声音,算出的基本都是0分贝。而用户实际使用场景下的背景噪音大小千差万别,咱要是也照葫芦画瓢就不对了,尤其是对于那些制作绝对分贝计的需求,应找出20微帕声压值对应的振幅(或者也可以拿一个标准分贝计做校准参考)。
遵循以往的优良传统,还是先上代码吧,下面是布局activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#EEEEEE" >

<LinearLayout
android:id="@+id/record_ll"
android:layout_width="200dp"
android:layout_height="33dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:background="@drawable/recode_language_bg_nor"
android:gravity="center"
android:orientation="horizontal" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按住 录制"
android:textColor="#777777"
android:textSize="14sp" />

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@drawable/record_language_img2" />
</LinearLayout>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/record_ll"
android:layout_marginBottom="10dp"
android:background="#464646" >

<RelativeLayout
android:id="@+id/record_center_rel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" >

<LinearLayout
android:id="@+id/record_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="horizontal" >

<ImageView
android:layout_width="39dp"
android:layout_height="70dp"
android:background="@drawable/record_language_img" />

<ImageView
android:id="@+id/record_language_intensity_img"
android:layout_width="22dp"
android:layout_height="49dp"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="21dp"
android:src="@drawable/record_language_bg" />
</LinearLayout>

<RelativeLayout
android:id="@+id/record_language_complete_rel"
android:layout_width="110dp"
android:layout_height="110dp"
android:layout_centerInParent="true"
android:visibility="gone" >

<ImageView
android:id="@+id/record_language_complete_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/record_language_complete_bg" />

<ImageView
android:id="@+id/record_language_play_img"
android:layout_width="30dp"
android:layout_height="40dp"
android:layout_centerInParent="true"
android:background="@drawable/record_language_stop_img" />

</RelativeLayout>
</RelativeLayout>

<TextView
android:id="@+id/record_note_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/record_center_rel"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="会员可添加\n最长60秒音频介绍"
android:textColor="#ffffff"
android:textSize="14sp" />

<TextView
android:id="@+id/record_language_time_text"
android:layout_width="50dp"
android:layout_height="20dp"
android:background="@drawable/record_language_time_bg"
android:layout_centerHorizontal="true"
android:layout_below="@id/record_center_rel"
android:layout_marginTop="10dp"
android:textSize="12sp"
android:textColor="#ffffff"
android:gravity="center_vertical"
android:text="0"
android:paddingLeft="25dp"
/>

</RelativeLayout>

<TextView
android:id="@+id/min_time_length"
android:layout_width="130dp"
android:layout_height="30dp"
android:background="@drawable/record_language_min_time_bg"
android:text="录音时长不足2秒"
android:gravity="center"
android:textSize="12sp"
android:textColor="#ffffff"
android:layout_centerInParent="true"
android:visibility="visible"
/>

</RelativeLayout>


老规矩,不多说,下面看一下activity的代码:

package com.example.recordlanguage;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import android.app.Activity;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnInfoListener;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.example.recordlanguage.RecordEngine.RecordListener;
import com.example.recordlanguage.RecordEngine.RecordTimeListener;
import com.example.recordlanguage.RecordEngine.VolumnChangeListener;

/**
* 语音简介
*
* @author xiaoyf
*
* @createTime 2016年1月26日 下午5:52:58
*/
public class MainActivity extends Activity implements OnClickListener,
OnTouchListener, RecordListener, OnInfoListener, RecordTimeListener {
private LinearLayout record_ll;
private LinearLayout record_bg;
private ImageView record_language_intensity_img;
private TextView record_note_text;
private RelativeLayout record_language_complete_rel;
private ImageView record_language_complete_img;
private ImageView record_language_play_img;
private TextView record_language_time_text;
private TextView min_time_length;
/**
* 是否正在播放录音: true:正在播放; false:没有正在播放的视频
*/
private boolean isPlaying = false;

private String mLocalRecordFilePath;
private RecordEngine mRecordEngine;
/**
* 录音时间是否超时
*/
private boolean isRecordTimeOut = false;
private int delayTime = 1000;
private Handler mHintHandler = new Handler();
private Runnable mStopHint = new Runnable() {
public void run() {
// 录音按钮不可以点击
record_ll.setClickable(false);
record_ll.setPressed(false);
record_ll.setFocusable(false);
min_time_length.setVisibility(View.GONE);
mHintHandler.removeCallbacks(mStopHint);
}
};

private Runnable mStartHint = new Runnable() {
public void run() {
mHintHandler.removeCallbacks(mStartHint);
}
};
private Animation animation;
private MediaPlayer mediaPlayer;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}

@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
if (mRecordEngine != null) {
mRecordEngine.RecordStop();
mRecordEngine.RecordDelete();
}

if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;

isPlaying = false;
record_language_complete_img.clearAnimation();
record_language_play_img
.setBackgroundResource(R.drawable.record_language_stop_img);
}

}

/**
* 初始化控件
*/
private void initViews() {
// TODO Auto-generated method stub
record_ll = (LinearLayout) findViewById(R.id.record_ll);

record_bg = (LinearLayout) findViewById(R.id.record_bg);
record_language_intensity_img = (ImageView) findViewById(R.id.record_language_intensity_img);
record_note_text = (TextView) findViewById(R.id.record_note_text);

record_language_complete_rel = (RelativeLayout) findViewById(R.id.record_language_complete_rel);
record_language_complete_img = (ImageView) findViewById(R.id.record_language_complete_img);
record_language_play_img = (ImageView) findViewById(R.id.record_language_play_img);
record_language_time_text = (TextView) findViewById(R.id.record_language_time_text);

min_time_length = (TextView) findViewById(R.id.min_time_length);

setVisibility();
record_bg.setVisibility(View.VISIBLE);
record_note_text.setVisibility(View.VISIBLE);

record_language_play_img.setOnClickListener(this);
record_ll.setOnTouchListener(this);

}

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.record_language_play_img:// 播放或暂停录音
if (isPlaying) {// 正在播放
record_language_play_img
.setBackgroundResource(R.drawable.record_language_stop_img);
isPlaying = false;
record_language_complete_img.clearAnimation();
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
} else {// 没有正在播放
record_language_play_img
.setBackgroundResource(R.drawable.record_language_play_img);
isPlaying = true;
if (animation == null) {
animation = AnimationUtils.loadAnimation(this,
R.anim.record_language_play_anim);
animation.setInterpolator(new LinearInterpolator());// 不停顿
}
record_language_complete_img.startAnimation(animation);
mediaPlayer();

}

break;

default:
break;
}
}

/**
* 播放语音简介
*/
private void mediaPlayer() {
// TODO Auto-generated method stub
try {
if (mediaPlayer == null)
mediaPlayer = new MediaPlayer();
boolean isPlay = false;
try {
isPlay = mediaPlayer.isPlaying();
} catch (Exception e) {
// TODO: handle exception
}
if (isPlay) {
mediaPlayer.reset();// 重置为初始状态
}
try {
transferFile(mLocalRecordFilePath + "tmp", mLocalRecordFilePath);
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.setDataSource(mLocalRecordFilePath);
mediaPlayer.prepare();// 缓冲
mediaPlayer.start();// 开始
mediaPlayer
.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {// 播出完毕事件
@Override
public void onCompletion(MediaPlayer arg0) {
mediaPlayer.stop();
mediaPlayer.release();// 释放资源
mediaPlayer = null;

isPlaying = false;
record_language_complete_img.clearAnimation();
record_language_play_img
.setBackgroundResource(R.drawable.record_language_stop_img);
}
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {// 错误处理事件
@Override
public boolean onError(MediaPlayer player, int arg1,
int arg2) {
mediaPlayer.stop();
mediaPlayer.release();// 释放资源
mediaPlayer = null;

Toast.makeText(getApplicationContext(), "语音播放有误",
Toast.LENGTH_LONG).show();
isPlaying = false;
record_language_complete_img.clearAnimation();
record_language_play_img
.setBackgroundResource(R.drawable.record_language_stop_img);
return false;
}
});

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
boolean isPlay = false;
try {
isPlay = mediaPlayer.isPlaying();
} catch (Exception e2) {
// TODO: handle exception
}
if (isPlay) {
mediaPlayer.stop();
mediaPlayer.release();// 释放资源
mediaPlayer = null;
}
Toast.makeText(getApplicationContext(), "语音播放有误", Toast.LENGTH_LONG)
.show();
isPlaying = false;
record_language_complete_img.clearAnimation();
record_language_play_img
.setBackgroundResource(R.drawable.record_language_stop_img);

}
}

@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.record_ll:// 录音
recordLanguage(event);
break;
default:
break;
}

return true;
}

/**
* 开始录音
*
* @param event
*/
private boolean recordLanguage(MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
boolean isPlay = false;
try {
if (mediaPlayer != null)
isPlay = mediaPlayer.isPlaying();
} catch (Exception e2) {
// TODO: handle exception
}
if (isPlay) {
mediaPlayer.stop();
mediaPlayer.release();// 释放资源
mediaPlayer = null;
isPlaying = false;
record_language_complete_img.clearAnimation();
record_language_play_img
.setBackgroundResource(R.drawable.record_language_stop_img);
}

try {
initVoiceModel();
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}

isRecordTimeOut = false;

try {
startRecord();
} catch (Exception e) {
mRecordEngine.RecordStop();
mRecordEngine.RecordDelete();
e.printStackTrace();
Toast.makeText(getApplicationContext(), "语音模块初始化失败,请重试!",
Toast.LENGTH_LONG).show();
break;
}
// 提示框显示: 正在录音...
mHintHandler.removeCallbacks(mStopHint);
mHintHandler.post(mStartHint);
setVisibility();
record_bg.setVisibility(View.VISIBLE);
record_language_time_text.setVisibility(View.VISIBLE);
record_language_time_text.setText("0");
record_language_time_text.setTextColor(0xffffffff);
record_ll.setBackgroundResource(R.drawable.recode_language_bg_sel);

break;
case MotionEvent.ACTION_UP:
// Log.d("bbb", "抬起 MotionEvent.ACTION_UP");
record_language_intensity_img.getDrawable().setLevel(0);
record_ll.setBackgroundResource(R.drawable.recode_language_bg_nor);
if (!mRecordEngine.ismRecording()) {
return false;
}
mRecordEngine.RecordStop();
// 录音结束处理
long recordTime = mRecordEngine.getRecordTime();
if (recordTime < 2000) {
setVisibility();
record_bg.setVisibility(View.VISIBLE);
record_language_time_text.setVisibility(View.VISIBLE);
min_time_length.setVisibility(View.VISIBLE);
mHintHandler.postDelayed(mStopHint, delayTime);
return false;
} else if (!isRecordTimeOut) {
setVisibility();
record_language_complete_rel.setVisibility(View.VISIBLE);
record_language_time_text.setVisibility(View.VISIBLE);

}
break;
case MotionEvent.ACTION_CANCEL:// 当权限访问的时候,弹起权限问询框的时候会调用
record_ll.setBackgroundResource(R.drawable.recode_language_bg_nor);
if (!mRecordEngine.ismRecording()) {
return false;
}
mRecordEngine.RecordStop();
mRecordEngine.RecordDelete();
setVisibility();
record_bg.setVisibility(View.VISIBLE);
record_note_text.setVisibility(View.VISIBLE);

break;
case MotionEvent.ACTION_MOVE:
break;

default:
break;
}

return true;

}

private void setVisibility() {
record_bg.setVisibility(View.GONE);
record_note_text.setVisibility(View.GONE);

record_language_complete_rel.setVisibility(View.GONE);
record_language_time_text.setVisibility(View.GONE);

min_time_length.setVisibility(View.GONE);

}

public boolean pointInView(View view, float localX, float localY) {
return localX >= 0 && localX < (view.getRight() - view.getLeft())
&& localY >= 0 && localY < (view.getBottom() - view.getTop());
}

/**
* 初始化语音模块
*
* @throws FileNotFoundException
*/
private void initVoiceModel() throws FileNotFoundException {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
mLocalRecordFilePath = Environment.getExternalStorageDirectory()
.getAbsolutePath()
+ "/record_voice_"
+ System.currentTimeMillis() + ".amr";
mRecordEngine = new RecordEngine(new File(mLocalRecordFilePath
+ "tmp"), this);
mRecordEngine.setRecordListener(this);
mRecordEngine.setInfoListener(this);
mRecordEngine.setRecordTimeListener(this);

}
}

/**
* 语音录制
*
* @throws IllegalStateException
* @throws IOException
* @throws RuntimeException
*/
private void startRecord() throws IllegalStateException, IOException,
RuntimeException {
// 注册音量变化侦听器
mRecordEngine.SetVolumnChangeListener(new VolumnChangeListener() {
@Override
public void change(int level) {
record_language_intensity_img.getDrawable().setLevel(level);
}
});
// 开始录音
mRecordEngine.RecordStart();
}

@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
// TODO Auto-generated method stub
if (what >= MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
mRecordEngine.RecordStop();
setVisibility();
record_language_complete_rel.setVisibility(View.VISIBLE);
record_language_time_text.setVisibility(View.VISIBLE);
isRecordTimeOut = true;
mHintHandler.post(mStopHint);
record_language_time_text.setText("60");
record_language_time_text.setTextColor(Color.RED);
Toast.makeText(getApplicationContext(), "对不起,最长录音60秒!",
Toast.LENGTH_LONG).show();
}
}

@Override
public void onPrepare() {
// TODO Auto-generated method stub

}

@Override
public void onComplated() {
// TODO Auto-generated method stub

}

@Override
public void refresh(long time) {
// TODO Auto-generated method stub
long recordTime = (time + 500) / 1000;
if (recordTime <= 50) {
record_language_time_text.setText(recordTime + "");
record_language_time_text.setTextColor(0xffffffff);
} else if (recordTime > 50 && recordTime <= 60) {
record_language_time_text.setText(recordTime + "");
record_language_time_text.setTextColor(Color.RED);
} else {
mRecordEngine.RecordStop();
setVisibility();
record_language_complete_rel.setVisibility(View.VISIBLE);
record_language_time_text.setVisibility(View.VISIBLE);
isRecordTimeOut = true;
mHintHandler.post(mStopHint);
}

}

/**
* 通过管道快速复制文件
*
* @param srcFile
* @param dstFile
* @throws IOException
*/
public static void transferFile(String srcFile, String dstFile)
throws IOException {
FileInputStream fin = new FileInputStream(srcFile);
FileOutputStream fout = new FileOutputStream(dstFile);
FileChannel fcin = fin.getChannel();
FileChannel fcout = fout.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024); // 分配1KB作为缓冲区

while (true) {
buffer.clear(); // 每次使用必须置空缓冲区
int r = fcin.read(buffer);
if (r == -1) {
break;
}
buffer.flip(); // 写入前使用flip这个方法
fcout.write(buffer);
}
}

}


其实这个activity也没有过多要强调的,唯一的一点就是,当我们第一次使用这个demo进行录音,我们按下按钮开始录音的时候,Android系统会弹起一个权限问询弹框,这个时候系统会回调我们写的ontouch()方法,其中的action是Action_Cancle,这个时候,我们需要在里面做一些基本的处理。

下面我们来看看这个项目的核心代码:

package com.example.recordlanguage;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import android.app.Service;
import android.content.Context;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnInfoListener;
import android.os.Handler;
import android.util.Log;

/**
* 录音的工具类
*
* @author xiaoyf
*
* @createTime 2016年1月27日 下午3:54:42
*/
public class RecordEngine {
final int MIN_AMPLITUDE_VALUE = 800; // 录音程序可以识别的最小声音振幅
final int MAX_AMPLITUDE_VALUE = 32000;// 最大值有人说[32767]; // 录音程序可以识别的最大声音振幅
final int VOLUMN_LEVEL_MAX = 7; // 音量分成7级
final int ampPerLevel = (MAX_AMPLITUDE_VALUE - MIN_AMPLITUDE_VALUE)
/ VOLUMN_LEVEL_MAX;
private int mVolumnLevel = 0;

private File mRecordFile = null;
private MediaRecorder mMediaRecorder;
private MediaPlayer mMediaPlayer = null;
private boolean mRecording = false;
private VolumnChangeListener mVolumnChangeListener;
private OnInfoListener mInfoListener;
private RecordTimeListener recordTimeListener;
private AudioManager audioManager;
private RecordListener listener;

private Context context;

// 录音音量变化侦听接口
public interface VolumnChangeListener {
public void change(int level);
}

public void SetVolumnChangeListener(VolumnChangeListener listener) {
mVolumnChangeListener = listener;
}

public void setInfoListener(OnInfoListener mInfoListener) {
this.mInfoListener = mInfoListener;
}

public interface RecordTimeListener {
void refresh(long time);
}

public void setRecordTimeListener(RecordTimeListener listener) {
recordTimeListener = listener;
}

/**
* 根据频率计算音量级别
*
* @return 音量级别
*/
private int CaculateVolumnLevel() {
int ratio = mMediaRecorder.getMaxAmplitude() / 600;
int db = 0;// 分贝
if (ratio > 1)
db = (int) (20 * Math.log10(ratio));
db /= 4;
db = Math.min(db, 10);
return db;
}

// 录音定时器,更新状态
private int mTimingDelay = 100;
private long mRecordTime = 0;
Handler timingHandler = new Handler();
/**
* 更新音量级别
*/
Runnable timingRunnable = new Runnable() {
public void run() {
int newLevel = CaculateVolumnLevel();
if (mVolumnLevel != newLevel) {
mVolumnLevel = newLevel;
if (mVolumnChangeListener != null)
mVolumnChangeListener.change(mVolumnLevel);
}

// 循环启动定时器
timingHandler.postDelayed(timingRunnable, mTimingDelay);
}
};
/**
* 记录录音的时间
*/
Runnable recordTimeRunnable = new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
if (recordTimeListener != null) {
long time = System.currentTimeMillis() - mRecordTime;
recordTimeListener.refresh(time);
// 循环启动定时器
timingHandler.postDelayed(recordTimeRunnable, 950);
}
}
};

private void startTiming() {
mRecordTime = System.currentTimeMillis() + 800L;
timingHandler.postDelayed(timingRunnable, mTimingDelay);
timingHandler.postDelayed(recordTimeRunnable, 950);
}

private void stopTiming() {
mRecordTime = System.currentTimeMillis() - mRecordTime;
timingHandler.removeCallbacks(timingRunnable);
timingHandler.removeCallbacks(recordTimeRunnable);
}

/**
* 获取本次录音时间长度
*
* @return
*/
public long getRecordTime() {
return mRecordTime;
}

public RecordEngine(Context mContext) throws FileNotFoundException {
this(null, mContext);
this.context = mContext;
}

public RecordEngine(File recordFile, Context mContext)
throws FileNotFoundException {
if (recordFile != null) {
File dir = recordFile.getParentFile();
if (!dir.exists()) {
dir.mkdirs();
}

// 创建文件
if (!recordFile.exists()) {
try {
recordFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}

mRecordFile = recordFile;
mRecordTime = System.currentTimeMillis();
audioManager = (AudioManager) mContext
.getSystemService(Service.AUDIO_SERVICE);
}

public void setRecordListener(RecordListener listener) {
this.listener = listener;
}

/* 录音 */
public void RecordStart() throws IllegalStateException, IOException,
RuntimeException {
if (listener != null) {
listener.onPrepare();
}
mMediaRecorder = new MediaRecorder();
startTiming();
// AudioRecord audioRecord=new AudioRecord(audioSource, sampleRateInHz,
// channelConfig, audioFormat, bufferSizeInBytes)
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 声源
// 设置音频文件的编码:AAC/AMR_NB/AMR_MB/Default
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);// 编码
mMediaRecorder.setAudioEncodingBitRate(4000);// 比特率
// mMediaRecorder.setAudioSamplingRate(4000);// 采样率
mMediaRecorder.setAudioChannels(1);// 单声道
mMediaRecorder.setOnInfoListener(mInfoListener);
mMediaRecorder.setOutputFile(mRecordFile.getAbsolutePath());
mMediaRecorder.setMaxDuration(60 * 1000);
mMediaRecorder.prepare();
mMediaRecorder.start();
mRecording = true;
}

public void RecordStop() {
if (mRecordFile != null) {
if (mMediaRecorder != null) {
try {
mMediaRecorder.stop();
mMediaRecorder.release();
mMediaRecorder = null;
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
mRecording = false;
stopTiming();
}
if (listener != null) {
listener.onComplated();
}
listener = null;
}

public void RecordPlay(Context mContext) throws IllegalArgumentException,
SecurityException, IllegalStateException, IOException {
// FileInputStream audioFileStream = new FileInputStream(mRecordFile);
if (mRecordFile == null) {
} else {
mMediaPlayer = new MediaPlayer();
// mMediaPlayer = MediaPlayer.create(mContext,
// Uri.fromFile(mRecordFile));
// mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(mRecordFile.getAbsolutePath());
mMediaPlayer.prepare();
mMediaPlayer.start();
}
}

public int getSuitedVolume(int streamType) {
int volume = 10;
if (audioManager != null) {
int currentVolume = audioManager.getStreamVolume(streamType);
int tmpVolume = (int) (audioManager.getStreamMaxVolume(streamType) * 0.6);
// 确保音量至少为60%
volume = currentVolume >= tmpVolume ? currentVolume
: (tmpVolume > volume ? tmpVolume : volume);
}
return volume;
}

public void RecordPlayStop() {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
}

/**
* 设置播放音量
*
* @param volume
*            音量,如果设置为-1则设置为当前系统音量
* */
public void setRecordPlayerVolume(int volume) {
if (audioManager != null) {
volume = volume == -1 ? audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC) : volume;
audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
volume, AudioManager.FLAG_PLAY_SOUND);
}
}

public String RecordGetPath() {
String path = mRecordFile.getPath();
return path;
}

public void RecordDelete() {
if (mRecordFile != null) {
if (mRecordFile.exists())
mRecordFile.delete();
}
}

public MediaPlayer getMediaPlayer() {
return mMediaPlayer;
}

public boolean ismRecording() {
return mRecording;
}

public interface RecordListener {
public void onPrepare();

public void onComplated();
}
}


这个核心方法里面会包含一些,对录音硬件的基本的设置、以及一些回调方法,用来监听音量的变化、录音开始和结束、录音时间

基本到这里就结束啦,我再给大家分享一篇很不错的获取录音分贝的文章:http://blog.csdn.net/greatpresident/article/details/38402147
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: