素材牛VIP会员

Recorder实现网页录音html5录音功能

 所属分类:网页特效-音乐视频

 浏览:530次-  下载:2次-  评论:0次-  更新时间:2022-08-19
Recorder实现网页录音html5录音功能
积分说明:注册即送10牛币,每日签到可获得5牛币,成为VIP会员可永久免牛币下载!   充值积分   充值会员   更多说明»
素材描述:提供多个扩展功能支持:拥有丰富的音频可视化、变速变调处理、音频流播放等;搭配上强大的实时处理支持,可用于各种网页应用:从简单的录音,到复杂的实时语音识别(ASR),甚至音频相关的游戏,都能从容应对

详细介绍

Recorder用于html5录音

支持在大部分已实现getUserMedia的移动端、PC端浏览器麦克风录音、实时处理,主要包括:Chrome、Firefox、Safari、IOS 14.3+、Android WebView、腾讯Android X5内核(QQ、微信)、大部分2021年后更新的Android手机自带浏览器;不支持:UC系内核(典型的支付宝),大部分未更新的老旧国产手机自带浏览器,低版本IOS(11.0-14.2)上除Safari外的其他任何形式的浏览器(含PWA、WebClip、任何App内网页)。


支持对任意MediaStream进行音频录制、实时处理,包括:getUserMedia返回的流、WebRTC中的remote流、audio、video标签的captureStream方法返回的流、自己创建的流 等等。


提供多个扩展功能支持:拥有丰富的音频可视化、变速变调处理、音频流播放等;搭配上强大的实时处理支持,可用于各种网页应用:从简单的录音,到复杂的实时语音识别(ASR),甚至音频相关的游戏,都能从容应对。


音频文件的播放:可直接使用常规的Audio HTML标签来播放完整的音频文件,参考文档下面的【快速使用】部分,有播放例子;上传了的录音直接将音频链接赋值给audio.src即可播放;本地的blob音频文件可通过URL.createObjectURL来生成本地链接赋值给audio.src即可播放,或者将blob对象直接赋值给audio.srcObject(兼容性没有src高)。实时的音频片段文件播放,可以使用本库自带的BufferStreamPlayer扩展来播放,简单高效,或者采用别的途径播放。

录音默认输出mp3格式,另外可选wav、pcm格式;有限支持ogg(beta)、webm(beta)、amr(beta)格式;支持任意格式扩展(前提有相应编码器)。


mp3默认16kbps的比特率,2kb每秒的录音大小,音质还可以(如果使用8kbps可达到1kb每秒,不过音质太渣)。主要用于语音录制,双声道语音没有意义,特意仅对单声道进行支持。mp3、wav、pcm格式支持边录边转码,录音结束时转码速度极快,支持实时转码成小片段文件和实时传输,demo中已实现一个语音通话聊天,下面有介绍;其他格式录音结束时可能需要花费比较长的时间进行转码。


mp3使用lamejs编码(CBR),压缩后的recorder.mp3.min.js文件150kb左右(开启gzip后54kb)。如果对录音文件大小没有特别要求,可以仅仅使用录音核心+wav编码器(raw pcm format录音文件超大),压缩后的recorder.wav.min.js不足5kb。录音得到的mp3(CBR)、wav(PCM),均可简单拼接小的二进制录音片段文件来生成长的音频文件,具体参考下面这两种编码器的详细介绍。


快速使用

你可以通过阅读和运行QuickStart.html文件来快速入门学习,直接将QuickStart.htmlcopy到你的(https、localhost)网站中,无需其他文件,就能正常开始测试了;注意:需要在https、localhost等安全环境下才能进行录音。


【1】加载框架

方式一:使用script标签引入

在需要录音功能的页面引入压缩好的recorder.xxx.min.js文件即可,JsDelivr CDN

<script src="recorder.mp3.min.js"></script> <!--已包含recorder-core和mp3格式支持, CDN: https://cdn.jsdelivr.net/gh/xiangyuecn/Recorder@latest/recorder.mp3.min.js-->
或者直接使用源码(src内的为源码、dist内的为压缩后的),可以引用src目录中的recorder-core.js+相应类型的实现文件,比如要mp3录音:
<script src="src/recorder-core.js"></script> <!--必须引入的录音核心,CDN: https://cdn.jsdelivr.net/gh/xiangyuecn/Recorder@latest/dist/recorder-core.js-->
<script src="src/engine/mp3.js"></script> <!--相应格式支持文件;如果需要多个格式支持,把这些格式的编码引擎js文件放到后面统统加载进来即可-->
<script src="src/engine/mp3-engine.js"></script> <!--如果此格式有额外的编码引擎的话,也要加上-->
<script src="src/extensions/waveview.js"></script>  <!--可选的扩展支持项-->

方式二:通过import/require引入

通过 npm/cnpm 进行安装 npm install recorder-core ,如果直接clone的源码下面文件路径调整一下即可

//必须引入的核心,换成require也是一样的。注意:recorder-core会自动往window下挂载名称为Recorder对象,全局可调用window.Recorder,也许可自行调整相关源码清除全局污染
import Recorder from 'recorder-core'
//需要使用到的音频格式编码引擎的js文件统统加载进来
import 'recorder-core/src/engine/mp3'
import 'recorder-core/src/engine/mp3-engine'
//以上三个也可以合并使用压缩好的recorder.xxx.min.js
//比如 import Recorder from 'recorder-core/recorder.mp3.min' //已包含recorder-core和mp3格式支持
//可选的扩展支持项
import 'recorder-core/src/extensions/waveview'

【2】调用录音,播放结果

这里假设只录3秒,录完后立即播放,在线编辑运行此代码>>

//简单控制台直接测试方法:在任意(无CSP限制)页面内加载Recorder,加载成功后再执行一次本代码立即会有效果,import("https://xiangyuecn.gitee.io/recorder/recorder.mp3.min.js").then(function(s){console.log("import ok")}).catch(function(e){console.error("import fail",e)})
var rec;
/**调用open打开录音请求好录音权限**/
var recOpen=function(success){//一般在显示出录音按钮或相关的录音界面时进行此方法调用,后面用户点击开始录音时就能畅通无阻了
    rec=Recorder({ //本配置参数请参考下面的文档,有详细介绍
        type:"mp3",sampleRate:16000,bitRate:16 //mp3格式,指定采样率hz、比特率kbps,其他参数使用默认配置;注意:是数字的参数必须提供数字,不要用字符串;需要使用的type类型,需提前把格式支持文件加载进来,比如使用wav格式需要提前加载wav.js编码引擎
        ,onProcess:function(buffers,powerLevel,bufferDuration,bufferSampleRate,newBufferIdx,asyncEnd){
            //录音实时回调,大约1秒调用12次本回调
            //可实时绘制波形(extensions目录内的waveview.js、wavesurfer.view.js、frequency.histogram.view.js扩展功能)
            //可利用extensions/sonic.js扩展实时变速变调,此扩展计算量巨大,onProcess需要返回true开启异步模式
            //可实时上传(发送)数据,配合Recorder.SampleData方法,将buffers中的新数据连续的转换成pcm上传,或使用mock方法将新数据连续的转码成其他格式上传,可以参考文档里面的:Demo片段列表 -> 实时转码并上传-通用版;基于本功能可以做到:实时转发数据、实时保存数据、实时语音识别(ASR)等
        }
    });
    //var dialog=createDelayDialog(); 我们可以选择性的弹一个对话框:为了防止移动端浏览器存在第三种情况:用户忽略,并且(或者国产系统UC系)浏览器没有任何回调,此处demo省略了弹窗的代码
    rec.open(function(){//打开麦克风授权获得相关资源
        //dialog&&dialog.Cancel(); 如果开启了弹框,此处需要取消
        //rec.start() 此处可以立即开始录音,但不建议这样编写,因为open是一个延迟漫长的操作,通过两次用户操作来分别调用open和start是推荐的最佳流程
        
        success&&success();
    },function(msg,isUserNotAllow){//用户拒绝未授权或不支持
        //dialog&&dialog.Cancel(); 如果开启了弹框,此处需要取消
        console.log((isUserNotAllow?"UserNotAllow,":"")+"无法录音:"+msg);
    });
};
/**开始录音**/
function recStart(){//打开了录音后才能进行start、stop调用
    rec.start();
};
/**结束录音**/
function recStop(){
    rec.stop(function(blob,duration){
        console.log(blob,(window.URL||webkitURL).createObjectURL(blob),"时长:"+duration+"ms");
        rec.close();//释放录音资源,当然可以不释放,后面可以连续调用start;但不释放时系统或浏览器会一直提示在录音,最佳操作是录完就close掉
        rec=null;
        
        //已经拿到blob文件对象想干嘛就干嘛:立即播放、上传
        
        /*** 【立即播放例子】 ***/
        var audio=document.createElement("audio");
        audio.controls=true;
        document.body.appendChild(audio);
        //简单利用URL生成播放地址,注意不用了时需要revokeObjectURL,否则霸占内存
        audio.src=(window.URL||webkitURL).createObjectURL(blob);
        audio.play();
    },function(msg){
        console.log("录音失败:"+msg);
        rec.close();//可以通过stop方法的第3个参数来自动调用close
        rec=null;
    });
};
//我们可以选择性的弹一个对话框:为了防止移动端浏览器存在第三种情况:用户忽略,并且(或者国产系统UC系)浏览器没有任何回调
/*伪代码:
function createDelayDialog(){
    if(Is Mobile){//只针对移动端
        return new Alert Dialog Component
            .Message("录音功能需要麦克风权限,请允许;如果未看到任何请求,请点击忽略~")
            .Button("忽略")
            .OnClick(function(){//明确是用户点击的按钮,此时代表浏览器没有发起任何权限请求
                //此处执行fail逻辑
                console.log("无法录音:权限请求被忽略");
            })
            .OnCancel(NOOP)//自动取消的对话框不需要任何处理
            .Delay(8000); //延迟8秒显示,这么久还没有操作基本可以判定浏览器有毛病
    };
};
*/
//这里假设立即运行,只录3秒,录完后立即播放,本段代码copy到控制台内可直接运行
recOpen(function(){
    recStart();
    setTimeout(recStop,3000);
});

【附】录音上传示例

var TestApi="/test_request";//用来在控制台network中能看到请求数据,测试的请求结果无关紧要
var rec=Recorder();rec.open(function(){rec.start();setTimeout(function(){rec.stop(function(blob,duration){
//-----↓↓↓以下才是主要代码↓↓↓-------
//本例子假设使用jQuery封装的请求方式,实际使用中自行调整为自己的请求方式
//录音结束时拿到了blob文件对象,可以用FileReader读取出内容,或者用FormData上传
var api=TestApi;
/***方式一:将blob文件转成base64纯文本编码,使用普通application/x-www-form-urlencoded表单上传***/
var reader=new FileReader();
reader.onloadend=function(){
    $.ajax({
        url:api //上传接口地址
        ,type:"POST"
        ,data:{
            mime:blob.type //告诉后端,这个录音是什么格式的,可能前后端都固定的mp3可以不用写
            ,upfile_b64:(/.+;\s*base64\s*,\s*(.+)$/i.exec(reader.result)||[])[1] //录音文件内容,后端进行base64解码成二进制
            //...其他表单参数
        }
        ,success:function(v){
            console.log("上传成功",v);
        }
        ,error:function(s){
            console.error("上传失败",s);
        }
    });
};
reader.readAsDataURL(blob);
/***方式二:使用FormData用multipart/form-data表单上传文件***/
var form=new FormData();
form.append("upfile",blob,"recorder.mp3"); //和普通form表单并无二致,后端接收到upfile参数的文件,文件名为recorder.mp3
//...其他表单参数
$.ajax({
    url:api //上传接口地址
    ,type:"POST"
    ,contentType:false //让xhr自动处理Content-Type header,multipart/form-data需要生成随机的boundary
    ,processData:false //不要处理data,让xhr自动处理
    ,data:form
    ,success:function(v){
        console.log("上传成功",v);
    }
    ,error:function(s){
        console.error("上传失败",s);
    }
});
//-----↑↑↑以上才是主要代码↑↑↑-------
},function(msg){console.log("录音失败:"+msg);});},3000);},function(msg){console.log("无法录音:"+msg);});

文件目录结构

  • ┝ index.html
  • js
    • ┝ frequency.histogram.view.js
    • ┝ lib.fft.js
    • ┝ mp3-engine.js
    • ┝ mp3.js
    • ┝ recorder-core.js

讨论这个素材(0)回答他人问题或分享使用心得会奖励牛币

〒_〒 居然一个评论都没有……

 文明上网,理性发言!   😉 阿里云幸运券,戳我领取
我的牛币余额:0 已下载次数:2
所需牛币:50 开始下载

牛币获取:签到、评论、充值    » 在线充值(10牛币=1元)