参考:https://www.cnblogs.com/sowhat4999/p/4439837.html

为什么不直接使用谷歌封装好的MediaRecorder,而使用AudioRecord录音呢?因为项目中需要将语音转成文字,讯飞语音听写只支持PCM和WAV格式的音频,转成wav格式也是为了方便播放语音

下面开始上代码吧;

public class AudioRecorder {//采样率:8000Hz,电话所用采样率, 对于人的说话已经足够public static final int LONG_SAMPLE_RATE = 8000;// 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。  public static final int ENCODING_PCM_16_BIT = AudioFormat.ENCODING_PCM_16BIT;// 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道  public static final int CHANNEL_IN_STEREO = AudioFormat.CHANNEL_IN_STEREO;private int bufferSizeInBytes;//保存裸数据文件路径private String mRawFilePath;//保存WAV文件路径private String mWavFilePath;private AudioRecord mAudioRecord;//是否取消录音private boolean mCancel;//是否正在录音private boolean mRunning;private Context mContext;private static AudioRecorder mAudioRecorder;private final ThreadPoolProxy mThreadPoolProxy;private OnRecordCompleteListener mCompleteListener;private long mStartTimes;private int mLen;private AudioRecorder(Context context) {mContext = context;//初始化线程池,避免线程过多创建,回收困难,内存消耗过多.当然也可以new Thread创建线程mThreadPoolProxy = ThreadPoolProxy.getInstance();//创建一个buffer缓冲区bufferSizeInBytes =AudioRecord.getMinBufferSize(LONG_SAMPLE_RATE, CHANNEL_IN_STEREO,ENCODING_PCM_16_BIT);}public void start() {if (mRunning) {return;}if (mAudioRecord == null) {mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, LONG_SAMPLE_RATE,CHANNEL_IN_STEREO, ENCODING_PCM_16_BIT, bufferSizeInBytes);}mAudioRecord.startRecording();mStartTimes = System.currentTimeMillis();mRunning = true;mCancel = false;mThreadPoolProxy.excute(mRunnable);}private Runnable mRunnable = () -> {writeDateTOFile();rawToWav(mRawFilePath, mWavFilePath);if (mCompleteListener != null) {mCompleteListener.onRecordComplete(mWavFilePath);}};public void stop() {if (mAudioRecord != null) {mLen = (int) (System.currentTimeMillis() - mStartTimes) / 1000;mCompleteListener.onRecordComplete(mLen);mRunning = false;mAudioRecord.stop();mAudioRecord.release();mAudioRecord = null;}}

保存音频数据

 private void writeDateTOFile() {byte[] audiodata = new byte[bufferSizeInBytes];FileOutputStream fos = null;final File dir = new File(FileUtils.getAppCacheDir(mContext) + "/audio");if (!dir.exists()) {dir.mkdir();}final String cacheDir = dir + File.separator + System.currentTimeMillis();mRawFilePath = cacheDir + "R.raw";mWavFilePath = cacheDir + "W.wav";try {fos = new FileOutputStream(mRawFilePath);while (!mCancel) {int readsize = mAudioRecord.read(audiodata, 0, bufferSizeInBytes);if (android.media.AudioRecord.ERROR_INVALID_OPERATION != readsize) {fos.write(audiodata);}}} catch (Exception e) {e.printStackTrace();} finally {ioClose(fos);}}/****raw文件转换成wav文件* @param rawPath 未经处理的音频文件路径* @param wavPath 要保存的wav文件路径*/private void rawToWav(String rawPath, String wavPath) {FileInputStream fis = null;FileOutputStream fos = null;long byteRate = 16 * LONG_SAMPLE_RATE * 2 / 8;try {byte[] audiodata = new byte[bufferSizeInBytes];fis = new FileInputStream(rawPath);fos = new FileOutputStream(wavPath);long totalAudioLen = fis.getChannel().size();long totalDataLen = totalAudioLen + 36;writeWavFileHeader(fos, totalAudioLen, totalDataLen, byteRate);while (fis.read(audiodata) != -1) {//如果取消录音,结束写入文件操作,并将文件删除if (mCancel) {FileUtils.deleteFile(wavPath);break;}fos.write(audiodata);}} catch (Exception e) {e.printStackTrace();} finally {ioClose(fis);ioClose(fos);}File pcm = new File(rawPath);if (pcm.exists()) {pcm.delete();}}/****写入wav格式头数据* @param fos 输出* @param totalAudioLen 音频长度* @param totalDataLen  音频长度+头部字段的大小* @param byteRate* @throws IOException*/private void writeWavFileHeader(FileOutputStream fos, long totalAudioLen, long totalDataLen,long byteRate) throws IOException {byte[] header = new byte[44];header[0] = 'R';header[1] = 'I';header[2] = 'F';header[3] = 'F';header[4] = (byte) (totalDataLen & 0xff);header[5] = (byte) ((totalDataLen >> 8) & 0xff);header[6] = (byte) ((totalDataLen >> 16) & 0xff);header[7] = (byte) ((totalDataLen >> 24) & 0xff);header[8] = 'W';header[9] = 'A';header[10] = 'V';header[11] = 'E';header[12] = 'f';header[13] = 'm';header[14] = 't';header[15] = ' ';header[16] = 16;header[17] = 0;header[18] = 0;header[19] = 0;header[20] = 1;header[21] = 0;header[22] = (byte) 2;header[23] = 0;header[24] = (byte) (LONG_SAMPLE_RATE & 0xff);header[25] = (byte) ((LONG_SAMPLE_RATE >> 8) & 0xff);header[26] = (byte) ((LONG_SAMPLE_RATE >> 16) & 0xff);header[27] = (byte) ((LONG_SAMPLE_RATE >> 24) & 0xff);header[28] = (byte) (byteRate & 0xff);header[29] = (byte) ((byteRate >> 8) & 0xff);header[30] = (byte) ((byteRate >> 16) & 0xff);header[31] = (byte) ((byteRate >> 24) & 0xff);header[32] = (byte) (2 * 16 / 8);header[33] = 0;header[34] = 16;header[35] = 0;header[36] = 'd';header[37] = 'a';header[38] = 't';header[39] = 'a';header[40] = (byte) (totalAudioLen & 0xff);header[41] = (byte) ((totalAudioLen >> 8) & 0xff);header[42] = (byte) ((totalAudioLen >> 16) & 0xff);header[43] = (byte) ((totalAudioLen >> 24) & 0xff);fos.write(header, 0, 44);}public void cancel() {mCancel = true;stop();}public void setOnRecordCompleteListener(OnRecordCompleteListener completeListener) {mCompleteListener = completeListener;}void ioClose(Closeable fos) {try {if (fos != null) {fos.close();}} catch (IOException e) {e.printStackTrace();}}public static AudioRecorder getInstance(Context context) {if (mAudioRecorder == null) {synchronized (AudioRecorder.class) {if (mAudioRecorder == null) {mAudioRecorder = new AudioRecorder(context);}}}return mAudioRecorder;}public boolean isRunning() {return mRunning;}
}

线程池管理

public class ThreadPoolProxy {private final ThreadPoolExecutor mSingleThreadPool;private ThreadPoolProxy(){ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("pool-%d").build();mSingleThreadPool = new ThreadPoolExecutor(3, 6,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());}public static ThreadPoolProxy getInstance(){return  InstanceHolder.threadPoolProxy;}public void excute(Runnable runnable) {mSingleThreadPool.execute(runnable);}public void remove(Runnable runnable) {mSingleThreadPool.remove(runnable);}static class InstanceHolder{private static final ThreadPoolProxy threadPoolProxy  = new ThreadPoolProxy();}
}

Android语音转文字一使用AudioRecord录音相关推荐

  1. android语音输入文字,盘点好用的语音输入APP,懒得打字的时候就说话吧!

    原标题:盘点好用的语音输入APP,懒得打字的时候就说话吧! 本文为「智活范」原创作品,欢迎关注我们! 上次推完好用的录音APP后,立刻就有萌友来问了,能不能直接录音转文字呢,这样说话就能生成文字,多省 ...

  2. Android语音转文字STT(通过第三方程序实现)

    通过第三方程序实现语音转文字功能,如讯飞语音等 首先先检测系统中是否存在支持语音识别功能,如果存在直接启动语音识别,若不存在则引导用户通过应用商店下载讯飞语音助手. 代码如下: /*** 语音助手辅助 ...

  3. Android语音转文字一识别语音

    项目地址:https://github.com/zhanlv/VtDemo 讯飞AndroidSDK文档:https://doc.xfyun.cn/msc_android/%E9%A2%84%E5%A ...

  4. android 语音转换文字(科大讯飞SDK简易封装)

    简介:本地讲解的是 科大讯飞开发平台的语音转换功能的集成方法和封装 准备工作: 1.首先申请平台账号,创建我的应用,新增语音服务,获取Appid 2.下载创建的应用的对应SDK,这条很重要,每一个应用 ...

  5. 语音播报 android,Android 语音播报 文字转语音

    最近收到了结合推送 到的内容 语音播报功能实现 就想到sdk内置 android.speech 已经内置了语音播放功能 开始放代码 //创建自带语音对象 private TextToSpeech te ...

  6. linux下录音识别成文字软件下载,语音转文字专家app-语音转文字专家手机版下载v3.2.0-Linux公社...

    语音转文字专家为用户提供的是非常强大的翻译功能,不仅可以用来记录会议.办公速记而且可以用来记录上课笔记.采访等等,任何场合都可以使用,翻译十分精准,用户可以放心使用,不会耽误办公和学习的哦,此外在语音 ...

  7. 【转】 实时Android语音对讲系统架构

    本文属于Android局域网内的语音对讲项目系列,<通过UDP广播实现Android局域网Peer Discovering>实现了局域网内的广播及多播通信,本文将重点说明系统架构,音频信号 ...

  8. 华为语音解锁设置_华为手机免费语音转文字功能如何开启?手把手教你如何设置,超赞...

    原标题:华为手机免费语音转文字功能如何开启?手把手教你如何设置,超赞 关于华为手机免费语音转文字功能,相信你也有所了解,但还有很大部份华为手机用户表示:我的手机为什么没有语音转文字的功能. 如果你是华 ...

  9. Android多媒体功能开发(11)——使用AudioRecord类录制音频

    AudioRecord类优点是能录制到缓冲区,能够实现边录边播(AudioRecord + AudioTrack)以及对音频的实时处理(如QQ电话).缺点是输出是PCM格式的原始采集数据,如果直接保存 ...

最新文章

  1. 天地图,js 4.0 api,简单调用,高手请绕行
  2. python 04 基础
  3. AIsing Programming Contest 2020 总结
  4. 10大反直觉的数学结论
  5. Steady Cow Assignment
  6. 泛型系列3:获取泛型的类型
  7. tts android,Android系统自带的TTS实现语音播报
  8. 萤火虫算法_一种优化方法:蜂鸟优化算法
  9. 深入了解DSP和ARM的关系(相同与区别)
  10. 电脑右键的新建怎么没有了
  11. linux mint 下如何制作win7启动盘
  12. Aviary发布iOS和Android App 成功从Android插件转型独立应用
  13. 2020 java设计模式之适配器模式
  14. 校园二手物品交易系统
  15. 二维码(生成二维码和扫描二维码)超简单 超简易
  16. Strusts2简单入门教程
  17. 【疯壳·嵌入式平板开发教程5】手把手教你做平板电脑-触摸屏驱动实验教程
  18. 孩子到底是食物过敏?还是食物不耐受?
  19. 微信编辑器哪个更好用
  20. ad走线打过孔_AD过孔开窗输出Gerber文件步骤!

热门文章

  1. 联想win0笔记本电脑相机打不开,提示我们找不到你的相机?
  2. P2P投资理财项目“百强榜”今夏出炉
  3. pte模拟考试_【PTE从零开始学】PTE模拟考与正式考,区别有哪些?
  4. OCR文字识别怎么使用?几个步骤教会你
  5. CRM在2B与2C业务中的应用场景有什么不同?
  6. Excel表格编序号时如何实现相同名称相同序号
  7. Zabbix技术分享——如何使用zabbix监控华为云RDS
  8. rlm sql mysql_FreeRADIUS with rlm_sql_mysql
  9. HCIE-RS与HCEI-Security挂靠
  10. Fecmall多语言外贸商城开源系统