[关闭]
@Tyhj 2018-11-17T14:17:10.000000Z 字数 7647 阅读 1728

Android录制语音

Android


录音两个需要注意的地方,一是录音过短的时候会失败,所以要监听录音时间长短,小于一秒的时候就显示失败;二是录音的时候关闭其他声音

集成方法:

Step 1. Add the JitPack repository to your build file

  1. //Add it in your root build.gradle at the end of repositories:
  2. allprojects {
  3. repositories {
  4. ...
  5. maven { url 'https://jitpack.io' }
  6. }
  7. }

Step 2. Add the dependency

  1. //Add the dependency
  2. dependencies {
  3. implementation 'com.github.tyhjh:AudioRecording:v1.0.0'
  4. }

基本使用

  1. //设置录音保存位置
  2. AudioRecordUtil.init(Environment.getExternalStorageDirectory() + "/audio/");
  3. recordUtil = AudioRecordUtil.getInstance();
  4. //开始录音
  5. recordUtil.startRecord(MainActivity.this);
  6. //取消录音,时间太短须取消
  7. recordUtil.cancelRecord(MainActivity.this);
  8. //结束录音(保存录音文件)
  9. recordUtil.stopRecord(MainActivity.this);
  10. //录音监听
  11. AudioRecordUtil.getInstance().setOnAudioStatusUpdateListener(new AudioRecordUtil.OnAudioStatusUpdateListener() {
  12. @Override
  13. public void onUpdate(double db, long time) {
  14. //根据分贝值来设置录音时话筒图标的上下波动
  15. }
  16. @Override
  17. public void onStop(final String filePath) {
  18. //获取录音文件
  19. }
  20. });

具体实现

录音时候关闭或开启其他声音

  1. public static boolean muteAudioFocus(Context context, boolean bMute) {
  2. if (context == null) {
  3. Log.d("ANDROID_LAB", "context is null.");
  4. return false;
  5. }
  6. boolean bool = false;
  7. AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
  8. //关闭声音
  9. if (bMute) {
  10. int result = am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
  11. bool = result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
  12. } else {
  13. //恢复声音
  14. int result = am.abandonAudioFocus(null);
  15. bool = result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
  16. }
  17. Log.d("ANDROID_LAB", "pauseMusic bMute=" + bMute + " result=" + bool);
  18. return bool;
  19. }

一个录音的类

  1. package tools;
  2. import android.media.MediaRecorder;
  3. import android.os.Environment;
  4. import android.os.Handler;
  5. import android.util.Log;
  6. import java.io.File;
  7. import java.io.IOException;
  8. public class AudioRecoderUtils {
  9. //文件路径
  10. private String filePath;
  11. //文件夹路径
  12. private String FolderPath;
  13. private MediaRecorder mMediaRecorder;
  14. private final String TAG = "fan";
  15. public static final int MAX_LENGTH = 1000 * 60 * 10;// 最大录音时长1000*60*10;
  16. private OnAudioStatusUpdateListener audioStatusUpdateListener;
  17. /**
  18. * 文件存储默认sdcard/record
  19. */
  20. public AudioRecoderUtils(){
  21. //默认保存路径为/sdcard/record/下
  22. this(Environment.getExternalStorageDirectory()+"/ASchollMsg/record/");
  23. }
  24. public AudioRecoderUtils(String filePath) {
  25. File path = new File(filePath);
  26. if(!path.exists())
  27. path.mkdirs();
  28. this.FolderPath = filePath;
  29. }
  30. private long startTime;
  31. private long endTime;
  32. /**
  33. * 开始录音 使用amr格式
  34. * 录音文件
  35. * @return
  36. */
  37. public String startRecord() {
  38. // 开始录音
  39. /* ①Initial:实例化MediaRecorder对象 */
  40. if (mMediaRecorder == null)
  41. mMediaRecorder = new MediaRecorder();
  42. mMediaRecorder.setOnErrorListener(null);
  43. try {
  44. /* ②setAudioSource/setVedioSource */
  45. mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 设置麦克风
  46. /* ②设置音频文件的编码:AAC/AMR_NB/AMR_MB/Default 声音的(波形)的采样 */
  47. mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
  48. /*
  49. * ②设置输出文件的格式:THREE_GPP/MPEG-4/RAW_AMR/Default THREE_GPP(3gp格式
  50. * ,H263视频/ARM音频编码)、MPEG-4、RAW_AMR(只支持音频且音频编码要求为AMR_NB)
  51. */
  52. mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  53. filePath = FolderPath + Defined.getTimeName() + ".amr" ;
  54. /* ③准备 */
  55. mMediaRecorder.setOutputFile(filePath);
  56. mMediaRecorder.setMaxDuration(MAX_LENGTH);
  57. mMediaRecorder.prepare();
  58. /* ④开始 */
  59. mMediaRecorder.start();
  60. // AudioRecord audioRecord.
  61. /* 获取开始时间* */
  62. startTime = System.currentTimeMillis();
  63. updateMicStatus();
  64. Log.e("fan", "startTime" + startTime);
  65. } catch (IllegalStateException e) {
  66. Log.i(TAG, "call startAmr(File mRecAudioFile) failed!" + e.getMessage());
  67. } catch (IOException e) {
  68. Log.i(TAG, "call startAmr(File mRecAudioFile) failed!" + e.getMessage());
  69. }
  70. return filePath;
  71. }
  72. /**
  73. * 停止录音
  74. */
  75. public long stopRecord() {
  76. if (mMediaRecorder == null)
  77. return 0L;
  78. endTime = System.currentTimeMillis();
  79. mMediaRecorder.stop();
  80. mMediaRecorder.reset();
  81. mMediaRecorder.release();
  82. mMediaRecorder = null;
  83. audioStatusUpdateListener.onStop(filePath);
  84. filePath = "";
  85. return endTime - startTime;
  86. }
  87. /**
  88. * 取消录音
  89. */
  90. public void cancelRecord(){
  91. if(mMediaRecorder==null)
  92. return;
  93. mMediaRecorder.setOnErrorListener(null);
  94. mMediaRecorder.setPreviewDisplay(null);
  95. try {
  96. mMediaRecorder.stop();
  97. }catch (Exception e){
  98. e.printStackTrace();
  99. }
  100. mMediaRecorder.reset();
  101. mMediaRecorder.release();
  102. mMediaRecorder = null;
  103. File file = new File(filePath);
  104. if (file.exists())
  105. file.delete();
  106. filePath = "";
  107. }
  108. private final Handler mHandler = new Handler();
  109. private Runnable mUpdateMicStatusTimer = new Runnable() {
  110. public void run() {
  111. updateMicStatus();
  112. }
  113. };
  114. private int BASE = 1;
  115. private int SPACE = 100;// 间隔取样时间
  116. public void setOnAudioStatusUpdateListener(OnAudioStatusUpdateListener audioStatusUpdateListener) {
  117. this.audioStatusUpdateListener = audioStatusUpdateListener;
  118. }
  119. /**
  120. * 更新麦克状态
  121. */
  122. private void updateMicStatus() {
  123. if (mMediaRecorder != null) {
  124. double ratio = (double)mMediaRecorder.getMaxAmplitude() / BASE;
  125. double db = 0;// 分贝
  126. if (ratio > 1) {
  127. db = 20 * Math.log10(ratio);
  128. if(null != audioStatusUpdateListener) {
  129. audioStatusUpdateListener.onUpdate(db, System.currentTimeMillis()-startTime);
  130. }
  131. }
  132. mHandler.postDelayed(mUpdateMicStatusTimer, SPACE);
  133. }
  134. }
  135. public interface OnAudioStatusUpdateListener {
  136. /**
  137. * 录音中...
  138. * @param db 当前声音分贝
  139. * @param time 录音时长
  140. */
  141. public void onUpdate(double db, long time);
  142. /**
  143. * 停止录音
  144. * @param filePath 保存路径
  145. */
  146. public void onStop(String filePath);
  147. }
  148. }

调用录音的类并实现其中的方法

  1. //录音回调
  2. mAudioRecoderUtils.setOnAudioStatusUpdateListener(new AudioRecoderUtils.OnAudioStatusUpdateListener() {
  3. //录音中....db为声音分贝,time为录音时长
  4. @Override
  5. public void onUpdate(double db, long time) {
  6. //根据分贝值来设置录音时话筒图标的上下波动,下面有讲解
  7. mImageView.getDrawable().setLevel((int) (3000 + 6000 * db / 100));
  8. mTextView.setText(Defined.getDate(time));
  9. time_Long=(int)(time/1000);
  10. }
  11. //录音结束,filePath为保存路径
  12. @Override
  13. public void onStop(String filePath) {
  14. //发送语音
  15. JSONObject json = null;
  16. Defined.muteAudioFocus(SendMessage.this,false);
  17. try {
  18. json = new JSONObject(getJson.getMsg("null", 2, time_Long, getString(R.string.singleTalk), linkMan.getId()));
  19. Messge messge = new Messge(json);
  20. messge.setSoundPath(filePath);
  21. updateView(messge);
  22. sendVoice(filePath,messges.size()-1);
  23. } catch (JSONException e) {
  24. e.printStackTrace();
  25. }
  26. mTextView.setText("00:00");
  27. }
  28. });
  1. //录音
  2. Defined.muteAudioFocus(SendMessage.this,true);
  3. switch (event.getAction()){
  4. case MotionEvent.ACTION_DOWN:
  5. y=event.getRawY();
  6. time = System.currentTimeMillis();
  7. mPop.showAtLocation(ll_bg, Gravity.CENTER,0,0);
  8. try {
  9. mAudioRecoderUtils.startRecord();
  10. }catch (RuntimeException e){
  11. e.printStackTrace();
  12. Snackbar.make(iv_sound,"先允许调用系统录音权限",Snackbar.LENGTH_SHORT).show();
  13. }
  14. iv_sound.startAnimation(expend);
  15. break;
  16. case MotionEvent.ACTION_UP:
  17. if(System.currentTimeMillis()-time<1000){
  18. Snackbar.make(iv_sound,"录音时间过短,请重试",Snackbar.LENGTH_SHORT).show();
  19. mAudioRecoderUtils.cancelRecord();
  20. mPop.dismiss();
  21. iv_sound.startAnimation(noexpend);
  22. break;
  23. }else if(y-event.getRawY()>300){
  24. Snackbar.make(iv_sound,"已取消发送语音",Snackbar.LENGTH_SHORT).show();
  25. mAudioRecoderUtils.cancelRecord();
  26. mPop.dismiss();
  27. iv_sound.startAnimation(noexpend);
  28. break;
  29. }else {
  30. try{
  31. mAudioRecoderUtils.stopRecord(); //结束录音(保存录音文件)
  32. }catch (Exception e){
  33. e.printStackTrace();
  34. Snackbar.make(iv_sound,"先允许调用系统录音权限",Snackbar.LENGTH_SHORT).show();
  35. }
  36. mPop.dismiss();
  37. iv_sound.startAnimation(noexpend);
  38. break;
  39. }
  40. case MotionEvent.ACTION_CANCEL:
  41. mAudioRecoderUtils.cancelRecord(); //取消录音(不保存录音文件)
  42. mPop.dismiss();
  43. iv_sound.startAnimation(noexpend);
  44. break;
  45. }

关于录音的时候显示语音声音大小动画
一个ImageView,设置背景,显示动画

  1. <ImageView
  2. android:id="@+id/zeffect_recordbutton_dialog_imageview"
  3. android:layout_width="30dp"
  4. android:layout_height="30dp"
  5. android:src="@drawable/zeffect_recordbutton_micrphone" />

其中src也是一个xml文件,xml里面的drawable是两张颜色不一样形状一样的图片,我用的是矢量图片。

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item
  4. android:id="@android:id/background"
  5. android:drawable="@drawable/ic_voice_null" />
  6. <item android:id="@android:id/progress">
  7. <clip
  8. android:clipOrientation="vertical"
  9. android:drawable="@drawable/ic_voice_full"
  10. android:gravity="bottom" />
  11. </item>
  12. </layer-list>
  1. //录音中....db为声音分贝,time为录音时长
  2. @Override
  3. public void onUpdate(double db, long time) {
  4. //根据分贝值来设置录音时话筒图标的上下波动
  5. mImageView.getDrawable().setLevel((int) (3000 + 6000 * db / 100));
  6. mTextView.setText(Defined.getDate(time));
  7. time_Long=(int)(time/1000);
  8. }

项目地址:https://github.com/tyhjh/AudioRecording

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注