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

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

使用方法:

1.在xml文件中添加

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">

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文件,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

android 录音的格式转换,Android仿微信录音功能(录音后的raw文件转mp3文件)相关推荐

  1. android 录音amr格式转换,android – 以AMR文件格式录制音频

    我想以AMR文件格式录制音频.我目前正在使用波纹管代码来录制音频: outputFile = Environment.getExternalStorageDirectory().getAbsolute ...

  2. android 英语时间格式转换,android 时间格式解析转换关键点

    中文格式 "yyyy-MM-dd" SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd" ...

  3. Android 仿微信语音录音小控件

    Android 仿微信语音录音小控件 前段时间一直在做IM聊天这方面的撸码工作,涉及到了很多小控件,有时间我会慢慢给大家分享一下我的小成果,希望大家一起学习,一起进步,今天来和大家来说一下Androi ...

  4. android录音raw格式转换,android录音格式raw转mp3

    主要使用到LAME 这个东东,需要用到jni;要装NDK ,要编译so库文件.要这个那个.. 麻烦的很.... 果断各种google,然后找到个别人编译好的so和jar包,爽歪歪; 用非很简单: FL ...

  5. Android仿微信录音功能,自定义控件的设计技巧

    欢迎各位加入我的Android开发群[257053751] 最近由于需要做一个录音功能(/嘘 悄悄透露一下,千万别告诉红薯,就是新版本的OSC客户端噢),起初打算采用仿微信的录音方式,最后又改成了QQ ...

  6. Android使用LAME将pcm文件转mp3文件

    Android使用LAME将pcm格式转mp3格式 lame介绍:LAME是一款开源的MP3编码器,被认为是中高比特率和VBR的最佳MP3编码器,质量和速度方面的改进仍在继续,可能使LAME成为仍在积 ...

  7. 如何将微信amr文件转换为mp3文件

    本篇经验将介绍,如何将微信的amr文件转换为mp3文件. 工具/原料 电脑 电脑软件:silk2mp3 amr文件 方法/步骤 下载软件,解压. 进入以下目录,打开软件. silk-v3-decode ...

  8. Android利用MedioRecorder使用仿微信语音录音以及播放(总结)

    今天模仿着微信的发送语音功能做了一下,现将步骤以及其中遇到的问题记录一下,以便以后查看. 实现功能:1.录制语音并显示到列表中:2.点击列表中的语音自动进行播放:3.录制语音时以及播放语音时的动画效果 ...

  9. android录音raw格式转换,android录音raw用lame转换成mp3

    1.用android进行录音上传到服务器,录音往往有这几种: a. 用MediaRecorder进行录音,示例代码如下: MediaRecorder recorder = new MediaRecor ...

最新文章

  1. 解决:VS 2005/2008 中 fstream 不能处理带有中文路径的问题
  2. eclipse上配置Maven
  3. Bootstrap 文档类型
  4. Node.js下载安装及各种npm、cnpm、nvm、nrm配置(保姆式教程—提供全套安装包)—nrm的安装与配置(5)
  5. 【BlackHat】速修复!有人正在扫描 Exchange 服务器寻找 ProxyShell 漏洞
  6. 转-TabHost组件(二)(实现底部菜单导航)
  7. 基于隐式调用风格的kwic实现
  8. php 天气小偷程序,天气小偷程序,自动采集信息入库
  9. dnf mysql密码多少_CentOS7 使用 dnf 安装 mysql
  10. 1.4版走迷宫小游戏
  11. java pem 签名_如何在Java中验证PEM格式证书
  12. JD-获得JD商品评论
  13. win10怎么用计算机,win10专业版如何通过简单设置,让你的电脑更流畅
  14. C# 实现视频监控系统(附源码)
  15. 再没时间 创业时也要读下这十本经典书
  16. 农民伯伯android,[同人]墨水儿哥哥乡下小山村的农民伯伯生活.avi
  17. 计算机网络教程第五版课后答案(第二章)
  18. 数据库存储列表(List)/数组(Array)型数据的两种方式
  19. 计算机基础知识上教案,第一章 计算机基础知识教案
  20. 解决idea卡顿问题

热门文章

  1. FocusBI:租房分析星型模型
  2. 【VBA研究】保存和打开Excel文件的代码
  3. 微软等数据结构+算法面试100题全部答案完整亮相
  4. 输入4个整数,要求按由小到大的顺序输出。C语言
  5. 使用ITK读写DICOM序列
  6. Python 时间日期(datetime)
  7. 移除集合效率高还是add高_HashMap存取效率高原因、ArrayList和LinkedList区别、JAVA实现链表的基本功能...
  8. Nginx/Apache/PHP 防止恶意User-Agent方法
  9. 创新案例分享 | 高效建设一体化智能化公共数据平台,全方位赋能城市治理
  10. Android FFmpeg源码编译及在Android studio的集成