Android录音
2016-01-28 11:30
549 查看
基础知识
度量声音强度,大家最熟悉的单位就是分贝(decibel,缩写为dB)。这是一个无纲量的相对单位,计算公式如下:
分子是测量值的声压,分母是参考值的声压(20微帕,人类所能听到的最小声压)。因此日常中说道声音强度是多少多少分贝时,都是默认了一个很小的参考值的。
而Android设备传感器可以提供的物理量是场的幅值(amplitude),常用下列公式计算分贝值:
从SDK中读取了某段音频数据的振幅后,取最大振幅或平均振幅(可以用平方和平均,或绝对值的和平均),代入上述公式的A1。
现在问题是,作为参考值的振幅A0取多少呢?
博主查阅很多帖子、博文,这里是最一团浆糊的地方。有的博文取600,是基于它视噪音的振幅为600的假设,此时算出来的是相对背景噪音的分贝值,要是用户不对麦克风发出声音,算出的基本都是0分贝。而用户实际使用场景下的背景噪音大小千差万别,咱要是也照葫芦画瓢就不对了,尤其是对于那些制作绝对分贝计的需求,应找出20微帕声压值对应的振幅(或者也可以拿一个标准分贝计做校准参考)。
遵循以往的优良传统,还是先上代码吧,下面是布局activity_main.xml:
老规矩,不多说,下面看一下activity的代码:
其实这个activity也没有过多要强调的,唯一的一点就是,当我们第一次使用这个demo进行录音,我们按下按钮开始录音的时候,Android系统会弹起一个权限问询弹框,这个时候系统会回调我们写的ontouch()方法,其中的action是Action_Cancle,这个时候,我们需要在里面做一些基本的处理。
下面我们来看看这个项目的核心代码:
这个核心方法里面会包含一些,对录音硬件的基本的设置、以及一些回调方法,用来监听音量的变化、录音开始和结束、录音时间
基本到这里就结束啦,我再给大家分享一篇很不错的获取录音分贝的文章:http://blog.csdn.net/greatpresident/article/details/38402147
度量声音强度,大家最熟悉的单位就是分贝(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
相关文章推荐
- android studio奇淫巧计
- android ndk 入门笔记
- Android手机拍照或选取图库图片作为头像
- MVC框架模式在Android中的应用
- android完美实现 拍照 选择图片 剪裁等代码分享
- Android用canvas画哆啦A梦
- Android启动相机拍照并返回图片
- android图像绘制获取本地图片或拍照图片等图片资源
- 安卓内存泄露之context使用不当
- mac android studio clone github项目到本地.txt
- Android拍照保存在系统相册不显示的问题解决方法
- Android的ListView数据更新后,如何使最新的条目可以自动滚动到可视范围内
- Android 使用Gallery实现3D相册(附效果图+Demo源码)
- Android从系统Gallery获取图片具体实现
- 关于android和gradle的环境搭建
- android权限
- Android 全局异常捕获之CrashHandler
- Android控件之Gallery用法实例分析
- Android Studio调试功能使用总结
- 关于android4.0以后,SD卡路径获取问题