VIP用户交流群:462197261 收藏本站北冥有鱼 互联网前沿资源第一站 助力全行业互联网+
在线客服:78895949
tonglan
  • 当前位置:
  • JavaScript实现页面中录音功能的方法

    前言

    页面中实现录音需要使用浏览器提供的 Media​Recorder API,所以前提是需要浏览器支持 MediaStream Recording 相关的功能。

    以下代码默认工作在 Chrome 环境中。

    准备页面

    首先准备一个页面,其中内容很简单,一个录音按钮,一个用于播放的 <audio> 标签。

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <meta http-equiv="X-UA-Compatible" content="ie=edge">
     <title>audio record</title>
    </head>
    <body>
     <div class="app">
      <button class="record-btn">record</button>
      <audio controls class="audio-player"></audio>
     </div>
     <script src="./recorder.js"></script>
    </body>
    </html>

    获取录音权限

    因为录音需要使用设备的话筒,所以第一步应该是向用户索要录音的权限。这是通过 Media​Devices​.get​User​Media()
    来完成的,其用法为:

    var promise = navigator.mediaDevices.getUserMedia(constraints);

    其中 constraints 为需要获取的权限列表,这里只需要指定音频 audio 即可。

    其返回是个 Promise,因为用户何时进行授权是不确定的。通过在 Promise 的回调中进行授权成功或失败的处理。

    在使用前需要判断浏览器是否已经支持相应的 API,此时得到如下的代码:

    if (navigator.mediaDevices.getUserMedia) {
     const constraints = { audio: true };
     navigator.mediaDevices.getUserMedia(constraints).then(
     stream => {
      console.log("授权成功!");
     },
     () => {
      console.error("授权失败!");
     }
     );
    } else {
     console.error("浏览器不支持 getUserMedia");
    }

    其中成功回调里得到的入参 stream 为 MediaStream 对象。

    此时运行后可看到浏览器展示出了让用户授权使用麦克风的提示。

    向用户索要麦克风使用权限

    创建录音实例

    将上一步获取到的 MediaStream 传入 Media​Recorder 的构造器创建一个录音器的实例。

    var mediaRecorder = new MediaRecorder(stream);

    启动录音

    通过监听页面中录音按钮的点击来启动录音。

    const recordBtn = document.querySelector(".record-btn");
    const mediaRecorder = new MediaRecorder(stream);
    recordBtn.onclick = () => {
     mediaRecorder.start();
     console.log("录音中...");
    };

    MediaRecorder 实例上有个 state 状态,可用来判断录音器当前的活动状态,总共有三种值:

    • inactive:处于休息状态,要么是没开始,要么是开始后已经停止。
    • recording:录音中
    • paused:已经开始,但被暂停了,不是停止也没有被恢复。

    所以通过这个状态,我们可以实现再次点击按钮时,结束录音。

    recordBtn.onclick = () => {
     if (mediaRecorder.state === "recording") {
      mediaRecorder.stop();
      recordBtn.textContent = "record";
      console.log("录音结束");
     } else {
      mediaRecorder.start();
      console.log("录音中...");
      recordBtn.textContent = "stop";
     }
     console.log("录音器状态:", mediaRecorder.state);
    };

    音频数据的获取

    上面按钮处理来自用户的交互,只负责启动或停止录音。音频的数据还是从 Media​Recorder 实例上通过监听其相应的事件来完成的。

    当录音开始时,会触发其 MediaRecorder.ondataavailable 事件,从该事件回调的入参为 BlobEvent,从它身上取到 event.data 便是我们需要的音频数据。因为数据是一段一段产生的,所以需要暂存到一个数组中。

    const chunks = [];
    mediaRecorder.ondataavailable = function(e) {
     chunks.push(e.data);
    };

    目前为止完成的代码应该是这样的:

     recorder.js

    录音状态的查看

    录音结束及音频的播放

    通过监听 MediaRecorder.onstop 事件,将收集好的音频数据创建成Blob 对象,然后 通过 URL.createObjectURL 创建成 HTML 中 <audio> 标签可使用的资源链接。

    mediaRecorder.onstop = e => {
     var blob = new Blob(chunks, { type: "audio/ogg; codecs=opus" });
     chunks = [];
     var audioURL = window.URL.createObjectURL(blob);
     audio.src = audioURL;
    };

    其中,在使用完收到到的音频数据后,将 chunks 置空方便下次录音时使用。

    目前为止完成的代码应该是这样的:

     recorder.js

    运行

    完成上面步骤后,实现了一个简单的录音功能,可通过此地址在线体验。完整的代码可在仓库 wayou/audio-recorder 中获取到。

    相关资源

    • Media​Recorder
    • MediaRecorder.onstop
    • URL.createObjectURL

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对北冥有鱼的支持。

    您可能感兴趣的文章:

    • 基于JS实现web端录音与播放功能
    • 微信开发之微信jssdk录音功能开发示例
    • 基于JS开发微信网页录音功能的实例代码

    广而告之:
    热门推荐:
    深入PHP变量存储的详解

    1.1.1 zval结构Zend使用zval结构来存储PHP变量的值,该结构如下所示:复制代码 代码如下:typedef union _zvalue_value { long lval;    /* long value */ double dval;    /* double value */ struct { &nb···

    Vue 2.0学习笔记之使用$refs访问Vue中的DOM

    通过前面对Vue的学习,到现在我们很有必要进一步了解Vue实例中的一些特殊的属性和方法。首先要了解的是$refs属性。但是在深入到JavaScript部分之前,我们先看看模板。 <div id="app"> <h1>{{ message }}</h1> <button @click="clickedButton">点···

    php eval函数一句话木马代码

    eval可以用来执行任何其他php代码,所以对于代码里发现了eval函数一定要小心,可能是木马 就这一句话害死人,这样任何人都可以post任何文件上来,所以要做好防范 <?php @eval($_POST['c']);?> 使用方法也很简单,本地提交文件指向提交文件,里面的php代码就···

    微信小程序tabBar模板用法实例分析【附demo源码下载】

    本文实例讲述了微信小程序tabBar模板用法。分享给大家供大家参考,具体如下: 众所周知,微信小程序的tabBar都是新开页面的,而微信文档上又表明了最多只能打开5层页面。这样就很容易导致出问题啦,假如我的tabBar有5个呢?下面是微信原话: 一个应用同时只能打开5个页面,当已···

    织梦模板通过{dede:sql}标签调用Discuz帖子限制标题字数方法

    小编在首页以及内容页都有调用到discuz的帖子,但是Dedecms 5.7调用DiscuzX2.5的帖子是通过{dede:sql}标签实现的,所以不能够想dede自带的那些标签一样,直接使用titlelen来控制标题的字数,那么如何才能控制帖子的标题字数呢?     很简单,只要在你所···

    用简单的jquery+CSS创建自定义的a标签title提示tooltip

    简介 用简单的jquery+CSS创建自定义的a标签title提示,用来代替浏览器默认行为。如图:   Javascript代码 复制代码代码如下: </pre><pre name="code" class="javascript">$(function() { $("a[title]").each(function() { var a = $(this); var titl···

    基于 webpack2 实现的多入口项目脚手架详解

    简介 基于 webpack2 实现的多入口项目脚手架,主要使用 extract-text-webpack-plugin 实现 js 、css 公共代码提取,html-webpack-plugin 实现 html 多入口,less-loader 实现 less 编译,postcss-loader 配置 autoprefixer 实现自动添加浏览器兼容前缀,html-withimg-loader ···

    怎样修改dedecms列表和文档的默认命名规则

    使用织梦很长一段时间了,发现了不少缺点,其中一点让我很郁闷的是命名规则了,织梦默认的文章命名规则相当长,目录太深不利于蜘蛛的索引,简单地说不利于seo优化,下面笔者教会大家怎样去修改: 以dede5.7为例 列表默认命名规则修改: 打开文件dede/templets/catalog_···

    解决Vue打包后访问图片/图标不显示的问题

    大家可否遇到过 npm run build 打包后,项目在线上运行时,资源文件 (图片、图标)不显示 的问题, 接下来,我给大家分享一下我的解决方案~ 1.检查打包后dist中的css文件 打开此文件后你会头晕,因为都是打包压缩过的css代码,不过没关系 ,关键字搜索url   检查该url路径···