当前位置: 移动技术网 > IT编程>移动开发>Android > Android仿微信录音功能(录音后的raw文件转mp3文件)

Android仿微信录音功能(录音后的raw文件转mp3文件)

2020年03月09日  | 移动技术网IT编程  | 我要评论

海王金樽保质期,千岛警察,四议两公开

现在很多时候需要用到录音,然后如果我们的app是ios和android两端的话,就要考虑录音的文件在两端都能使用,这个时候就需要适配,两端的录音文件都要是mp3文件,这样才能保证两边都能播放。

针对这个,封装了一个简单可用的录音控件。

使用方法:

1.在xml文件中添加

<ant.muxi.com.audiodemo.view.soundtextview
 android:id="@+id/record_audio"
 android:text="按住开始录音"
 android:gravity="center"
 android:background="@drawable/bg_round_black"
 android:layout_marginleft="20dp"
 android:layout_marginright="20dp"
 android:layout_marginbottom="40px"
 android:padding="20px"
 android:layout_width="match_parent"
 android:layout_height="wrap_content">
 </ant.muxi.com.audiodemo.view.soundtextview>

2.别忘了申请录音权限

andpermission.with(mainactivity.this)
  .permission(manifest.permission.record_audio,manifest.permission.write_external_storage,manifest.permission.read_external_storage)
  .ongranted(permissions -> {
   showselect();
  })
  .ondenied(permissions -> {
   toast.maketext(mainactivity.this,"请同意录音权限",toast.length_short).show();
  })
  .start();
private void showselect() {
 soundtextview recordaudio = findviewbyid(r.id.record_audio);
 recordaudio.setonrecordfinishedlistener(new soundtextview.onrecordfinishedlistener() {
  @override
  public void newmessage(string path, int duration) {
  int index = path.lastindexof("/");
  string filename = path.substring(index + 1);
  log.e("录音文件", "path=: "+path );
  }
 });
 }

使用方法如上非常简单:

主要的类

package ant.muxi.com.audiodemo.view;
 import android.app.activity;
import android.app.dialog;
import android.content.context;
import android.os.environment;
import android.os.handler;
import android.os.message;
import android.util.attributeset;
import android.util.log;
import android.view.motionevent;
import android.widget.textview;
import android.widget.toast;
import androidx.appcompat.widget.appcompattextview;
import java.io.file;
import ant.muxi.com.audiodemo.r;
import ant.muxi.com.audiodemo.audio.progresstextutils;
import ant.muxi.com.audiodemo.audio.recordmanager;
public class soundtextview extends appcompattextview {
 private context mcontext;
 private dialog recordindicator;
 private textview mvoicetime;
 private file file;
 private string type = "1";//默认开始录音 type=2,录音完毕
 recordmanager recordmanager;
 file fileto;
 int level;
 private long downt;
 string sountime;
 public soundtextview(context context) {
 super(context);
 init();
 }
 public soundtextview(context context, attributeset attrs, int defstyle) {
 super(context, attrs, defstyle);
 this.mcontext = context;
 init();
 }
 public soundtextview(context context, attributeset attrs) {
 super(context, attrs);
 this.mcontext = context;
 init();
 }
 private void init() {
 recordindicator = new dialog(getcontext(), r.style.jmui_record_voice_dialog);
 recordindicator.setcontentview(r.layout.jmui_dialog_record_voice);
 mvoicetime = (textview) recordindicator.findviewbyid(r.id.voice_time);
 file = new file(environment.getexternalstoragedirectory() + "/recoder.amr");
 fileto = new file(environment.getexternalstoragedirectory() + "/recoder.mp3");
 recordmanager = new recordmanager(
  (activity) mcontext,
  string.valueof(file),
  string.valueof(fileto));
 recordmanager.setonaudiostatusupdatelistener(new recordmanager.onaudiostatusupdatelistener() {
  @override
  public void onupdate(double db) {
  //得到分贝
  if (null != recordindicator) {
   level = (int) db;
   handler.sendemptymessage(0x111);
  }
  }
 });
 }
 handler handler = new handler() {
 @override
 public void handlemessage(message msg) {
  super.handlemessage(msg);
  switch (msg.what) {
  case 0x111:
   sountime = progresstextutils.getsecsprogress(system.currenttimemillis() - downt);
   long time = system.currenttimemillis() - downt;
   mvoicetime.settext(progresstextutils.getprogresstext(time));
   //判断时间
   judetime(integer.parseint(sountime));
   break;
  }
 }
 };
 public void judetime(int time) {
 if (time > 14) {
  //结束录制
  toast.maketext(mcontext, "录音不能超过十五秒", toast.length_short).show();
  recordmanager.stop_mp3();
  new thread() {
  @override
  public void run() {
   super.run();
   recordmanager.savedata();
   finishrecord(fileto.getpath(), sountime);
  }
  }.start();
  recordindicator.dismiss();
  type = "2";
 }
 }
 @override
 public boolean ontouchevent(motionevent event) {
 int action = event.getaction();
 switch (action) {
  case motionevent.action_down:
  if (type.equals("1")) {
   //开始发送时间
   downt = system.currenttimemillis();
   recordmanager.start_mp3();
   recordindicator.show();
  } else {
   log.e("-log-", "您已经录制完毕: ");
  }
  return true;
  case motionevent.action_up:
  if (type.equals("1")) {
   try {
   if (integer.parseint(sountime) > 2) {
    recordmanager.stop_mp3();
    new thread() {
    @override
    public void run() {
     super.run();
     recordmanager.savedata();
     finishrecord(fileto.getpath(), sountime);
    }
    }.start();
    if (recordindicator.isshowing()) {
    recordindicator.dismiss();
    }
    type = "2";
   } else {
    recordmanager.stop_mp3();
    if (recordindicator.isshowing()) {
    recordindicator.dismiss();
    }
    sountime = null;
    toast.maketext(mcontext, "录音时间少于3秒,请重新录制", toast.length_short).show();
   }
   } catch (exception e) {
   recordmanager.stop_mp3();
   if (recordindicator.isshowing()) {
    recordindicator.dismiss();
   }
   sountime = null;
   toast.maketext(mcontext, "录音时间少于3秒,请重新录制", toast.length_short).show();
   }
  }
  break;
  case motionevent.action_cancel:
  if (recordindicator.isshowing()) {
   recordindicator.dismiss();
  }
  break;
 }
 return super.ontouchevent(event);
 }
 //录音完毕加载 listview item
 private void finishrecord(string path, string time) {
 if (onrecordfinishedlistener != null) {
  onrecordfinishedlistener.newmessage(path, integer.parseint(time));
  type = "1";
 }
 //发送语音
 // toasts.toast(getcontext(),"您已经录完了一条语音"+myrecaudiofile);
 }
 private onrecordfinishedlistener onrecordfinishedlistener;
 public void setonrecordfinishedlistener(onrecordfinishedlistener onrecordfinishedlistener) {
 this.onrecordfinishedlistener = onrecordfinishedlistener;
 }
 public interface onrecordfinishedlistener {
 void newmessage(string path, int duration);
 }
}

主要的录音管理类

public class recordmanager {
 //录制成mp3格式..............................................
 /**构造时候需要的activity,主要用于获取文件夹的路径*/
 private activity activity;
 /**文件代号*/
 public static final int raw = 0x00000001;
 public static final int mp3 = 0x00000002;
 /**文件路径*/
 private string rawpath = null;
 private string mp3path = null;
 /**采样频率*/
 private static final int sample_rate = 11025;
 /**录音需要的一些变量*/
 private short[] mbuffer;
 private audiorecord mrecorder;
 /**录音状态*/
 private boolean isrecording = false;
 /**是否转换ok*/
 private boolean convertok = false;
 public recordmanager(activity activity, string rawpath, string mp3path) {
 this.activity = activity;
 this.rawpath = rawpath;
 this.mp3path = mp3path;
 }
 /**开始录音*/
 public boolean start_mp3() {
 // 如果正在录音,则返回
 if (isrecording) {
  return isrecording;
 }
 // 初始化
 if (mrecorder == null) {
  initrecorder();
 }
 getfilepath();
 mrecorder.startrecording();
 startbufferedwrite(new file(rawpath));
 isrecording = true;
 return isrecording;
 }
 /**停止录音,并且转换文件,这很可能是个耗时操作,建议在后台中做*/
 public boolean stop_mp3() {
 if (!isrecording) {
  return isrecording;
 }
 // 停止
 mrecorder.stop();
 isrecording = false;
//todo
 // 开始转换(转换代码就这两句)
// flameutils lameutils = new flameutils(1, sample_rate, 96);
// convertok = lameutils.raw2mp3(rawpath, mp3path);
// return isrecording ^ convertok;// convertok==true,return true
 return isrecording;
 }
 public void savedata(){
 flameutils lameutils = new flameutils(1, sample_rate, 96);
 convertok = lameutils.raw2mp3(rawpath, mp3path);
 }
 /**获取文件的路径*/
 public string getfilepath(int filealias) {
 if (filealias == raw) {
  return rawpath;
 } else if (filealias == mp3) {
  return mp3path;
 } else
  return null;
 }
 /**清理文件*/
 public void cleanfile(int cleanflag) {
 file f = null;
 try {
  switch (cleanflag) {
  case mp3:
   f = new file(mp3path);
   if (f.exists())
   f.delete();
   break;
  case raw:
   f = new file(rawpath);
   if (f.exists())
   f.delete();
   break;
  case raw | mp3:
   f = new file(rawpath);
   if (f.exists())
   f.delete();
   f = new file(mp3path);
   if (f.exists())
   f.delete();
   break;
  }
  f = null;
 } catch (exception e) {
  e.printstacktrace();
 }
 }
 /**关闭,可以先调用cleanfile来清理文件*/
 public void close() {
 if (mrecorder != null)
  mrecorder.release();
 activity = null;
 }
 /**初始化*/
 private void initrecorder() {
 int buffersize = audiorecord.getminbuffersize(sample_rate,
  audioformat.channel_in_mono, audioformat.encoding_pcm_16bit);
 mbuffer = new short[buffersize];
 mrecorder = new audiorecord(mediarecorder.audiosource.mic, sample_rate,
  audioformat.channel_in_mono, audioformat.encoding_pcm_16bit,
  buffersize);
 }
 /**设置路径,第一个为raw文件,第二个为mp3文件*/
 private void getfilepath() {
 try {
  string folder = "audio_recorder_2_mp3";
  string filename = string.valueof(system.currenttimemillis());
  if (rawpath == null) {
  file raw = new file(activity.getdir(folder,
   activity.mode_private), filename + ".raw");
  raw.createnewfile();
  rawpath = raw.getabsolutepath();
  raw = null;
  }
  if (mp3path == null) {
  file mp3 = new file(activity.getdir(folder,
   activity.mode_private), filename + ".mp3");
  mp3.createnewfile();
  mp3path = mp3.getabsolutepath();
  mp3 = null;
  }
  log.d("rawpath", rawpath);
  log.d("mp3path", mp3path);
 } catch (exception e) {
  e.printstacktrace();
 }
 }
 /**执行cmd命令,并等待结果*/
 private boolean runcommand(string command) {
 boolean ret = false;
 process process = null;
 try {
  process = runtime.getruntime().exec(command);
  process.waitfor();
  ret = true;
 } catch (exception e) {
  e.printstacktrace();
 } finally {
  try {
  process.destroy();
  } catch (exception e) {
  e.printstacktrace();
  }
 }
 return ret;
 }
 /**写入到raw文件*/
 private void startbufferedwrite(final file file) {
 object mlock = new object();
 new thread(new runnable() {
  @override
  public void run() {
  dataoutputstream output = null;
  try {
   output = new dataoutputstream(new bufferedoutputstream(
    new fileoutputstream(file)));
   while (isrecording) {//开始录制
   int readsize = mrecorder.read(mbuffer, 0,
    mbuffer.length);//是实际读取的数据长度
   for (int i = 0; i < readsize; i++) {
    output.writeshort(mbuffer[i]);
   }
   long v = 0;
   // 将 buffer 内容取出,进行平方和运算
   for (int i = 0; i < mbuffer.length; i++) {
    v += mbuffer[i] * mbuffer[i];
   }
   // 平方和除以数据总长度,得到音量大小。
   double mean = v / (double) readsize;
   double volume = 10 * math.log10(mean);
   synchronized (mlock) {
    try {
    if(null != audiostatusupdatelistener) {
     audiostatusupdatelistener.onupdate(volume);
    }
    mlock.wait(100);
    } catch (interruptedexception e) {
    e.printstacktrace();
    }
   }
   }
  } catch (ioexception e) {
   e.printstacktrace();
  } finally {
   if (output != null) {
   try {
    output.flush();
   } catch (ioexception e) {
    e.printstacktrace();
   } finally {
    try {
    output.close();
    } catch (ioexception e) {
    e.printstacktrace();
    }
   }
   }
  }
  }
 }).start();
 }
 public recordmanager.onaudiostatusupdatelistener audiostatusupdatelistener;
 public void setonaudiostatusupdatelistener(recordmanager.onaudiostatusupdatelistener audiostatusupdatelistener) {
 this.audiostatusupdatelistener = audiostatusupdatelistener;
 }
 public interface onaudiostatusupdatelistener {
 public void onupdate(double db);
 }
}

完整代码:

总结

以上所述是小编给大家介绍的android仿微信录音功能(录音后的raw文件转mp3文件,希望对大家有所帮助

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网