Android语音录制和播放封装库(提供JS调用demo)

实现功能:
语音录制、播放模块
  • 支持基于Media和Audio的语音录制和播放
  • 支持基于PCM的格式扩展操作
  • 提供Html页面的 JS 互调demo
  • 通过统一的API入口:VoiceManager实现播放以及录音的统一
具体功能类别
  • 语音录制
    • 支持Android直接录制格式:PCM16,PCM8,AMR等
    • 支持基于原始音频格式的包装扩展格式,目前支持WAV
    • Audio录制支持采样频率、通道等参数的自定义
    • Media录制支持自定义编码格式
    • 支持实时麦克风字节数据的传出(可自定义一次采集字节数据大小)
  • 语音播放
    • 支持PCM,AMR,WAV等格式的播放
Git地址:

https://github.com/liyuzero/MaeBundlesVoice

引入方式:
allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

dependencies {
            implementation 'com.github.liyuzero:MaeBundlesVoice:1.0.0'
    }

具体调用(详情见Github demo)

  1. 录音使用方法
    RecordAPI recordAPI = VoiceManager.with(activity).getRecordAPI(VoiceType.PCM_16BIT);
    /* 添加录制参数
    RecordAPI recordAPI = VoiceManager.with(activity).getRecordAPI(VoiceType.PCM_16BIT,
            new AudioRecordParam(16000, AudioRecordParam.AudioInChannel.CHANNEL_IN_MONO));*/
    // 开始录制:outputPath:String 音频录制输出文件路径
    recordAPI.startRecord(outputPath, new RecordListener() {
                            @Override
                            public void onStart() {
                            }
                            @Override
                            public void onFinishRecord(long duration, String filePath) {
                                Toast.makeText(getApplicationContext(), "录音结束,时长: " + duration, Toast.LENGTH_SHORT).show();
                            }

                            @Override
                            public void onCancel() {
                            }

                            @Override
                            public void onError(Exception e) {
                                Toast.makeText(getApplicationContext(), "出错啦 " + e.getMessage(), Toast.LENGTH_SHORT).show();
                            }
                            @Override
                            public void onAmplitudeChanged(int volume) {
                            }
                        });

    //停止并完成录制
    recordAPI.stopRecord();
    //检查是否正在录制
    //recordAPI.isRecording();
    //取消录制
    //recordAPI.cancelRecord();
    //释放资源
    //recordAPI.release();

  1. 播放音频使用方法
    PlayerAPI playerAPI = VoiceManager.with(activity).getPlayerAPI(VoiceType.PCM_16BIT);
    //自定义播放参数【只有Audio需要且可以自定义参数】
    /*playerAPI = VoiceManager.with(activity).getPlayerAPI(VoiceType.PCM_16BIT,
        new AudioPlayParam(16000, AudioRecordParam.AudioInChannel.CHANNEL_IN_MONO));*/
    //originPath:String 音频文件路径
    playerAPI.startPlay(originPath, new PlayListener() {
        @Override
        public void onStart() {
        }
        @Override
        public void onStop() {
        }
        @Override
        public void onError(Exception e) {
        }
    });

    //停止播放
    playerAPI.stopPlay();
    //是否正在播放
    playerAPI.isPlaying();
    //释放资源
    playerAPI.release();
  1. 自定义PCM文件扩展,即提供基于PCM原始文件的文件转换能力
        AudioRecordParam param = DefaultParam.getDefaultAudioRecordParam());
        param.setPcmFileConverter(new WavRecordUtils()); //改成你自己的基于BaseAudioRecordExtendUtils的实现类
        
        /*
         * 文件转换类自行实现文件转换方法,具体实现参考WavRecordUtils
            public class TestFileConvater extends BaseAudioRecordExtendUtils {
                
                public TestFileConvater(VoiceType voiceType, AudioRecordParam audioParam) {
                    super(voiceType, audioParam);
                }
            
                @Override
                //设置临时文件的名字,对应于originFilePath
                protected String getTempFileName() {
                    return null;
                }
            
                //将生成的PCM文件originFilePath:自行转换为outputFilePath所对应的文件,outputFilePath对应于外界指定的文件录音地址
                @Override
                protected String transform(String originFilePath, String outputFilePath) {
                    return null;
                }
            }
         *
         */
        
        recordAPI = VoiceManager.with(RecordNativeTestActivity.this).getRecordAPI(VoiceType.WAV, param);

4、支持不输出文件

    /*
      而只进行录音的PCM原始字节数组的实时传出(字节数组内部进行了一次复制传出,避免了多线程下数据错乱的问题)
      即:只调用 onRecordBytes(byte[] audioData, int len, int audioSeq),而不进行文件写入
    
      该功能能有效支持以下应用场景:
    
      例如我们需要做一个语音转文字功能,或者聊天时将语音发给对方,这时候如果采用录制完后,再将所有语音数据传输给后台,
      将会出现较大的响应延迟,客户端需要经过一个较长的时间才能取得结果。这时候如果不录制文件,而直接通过onRecordBytes
      接收每一帧音频数据直接发送到服务端,实现实时传输,这时候效果会好很多
    */
    
    AudioRecordParam param = DefaultParam.getDefaultAudioRecordParam());
    
    /*
      byte[] audioData【每次通过麦克风采集的录音数据】的数组大小可以通过以下配置自行控制,因为一些语音数据压缩库可能对源字节数组的大小有限制,
      例如opus,会有:
      频率 * 位数 * 通道数 / 位 = B/s /(200ms / 1000ms) = B/200ms
    */
    
    bufferLen = getSampleRate() * 16 * 1 / 8 / 5;
    param.bufferLen = 14000;
    
    /*
      当配置以下参数时,库内部将不再执行文件写入操作,而只会调用
      onRecordBytes(byte[] audioData, int len, int audioSeq) 
      和 onFinishRecord(long duration, String filePath),其中filePath无意义
    */
    param.setIsOutputFile(false); //不输出录音文件
  1. 释放麦克风等资源的方法
   VoiceManager.getInstance().onDestroy();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容