• 前端实现在浏览器网页中录音


    一、整体实现的思想

    页面中实现录音需要使用浏览器提供的MediaRecorder API,所以要实现页面录音就需要浏览器支持MediaStream Recording相关的功能,即浏览器能够获取浏览器的录音权限。

    页面内容,需要一个记录录音开始和结束的按钮,以及一个用于播放录音的标签<audio>

    然后设计具体的实现细节:首先我们进入页面需要判断浏览器是否支持该API,如果支持的话,然后再获取浏览器的录音权限,获取权限之后,我们的页面上分别由录音按钮和播放音频的标签audio,然后我们就需要设计逻辑,在点击录音按钮的时候就开始记录音频(实现这一步的前提是我们需要创建录音实例),然后实现启动录音和结束录音,录音结束之后,我们就把获取的录音实例放在audio中,当我们点击播放的时候就可以实现将录音播放出来。

    二、具体细节和函数

    浏览器获取录音的权限

    /*获取浏览器的录音权限,contraint是需要获取权限的列表*/
    const constraints = { audio: true };
    //返回的是Promise对象,因为需要等到用户确定授予权限的时候,我们才会处理下面的步骤,navigator是浏览器对象,我们就是通过navigator获取录音权限,成功回调的话就会获取到一个stream,然后将这个stream放入到我们下面创建的录音实例里面去 navigator.mediaDevices.getUserMedia(constraints)

    创建录音实例

    //通过该方法创建录音实例
    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); };

    音频数据的获取

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

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

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

    https://www.houdianzi.com/suzhoulogo/ 苏州logo设计

    录音的结束和音频的播放,通过监听 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;
    };

    三、详细完整代码

    <!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>实现在网页上录音</title>
    </head>
    <body>
    <div class="app">
    <button class="record-btn">record</button>
    <audio controls class="audio-player" >
    </audio>
    <button class="record-btn1">record</button>
    <audio controls class="audio-player1" >
    </audio>
    </div>
    <script>
    if (navigator.mediaDevices.getUserMedia) {
    const constraints = { audio: true };
    navigator.mediaDevices.getUserMedia(constraints).then(
    stream => {
    console.log("授权成功!");
    const recordBtn = document.querySelector(".record-btn");
    const mediaRecorder = new MediaRecorder(stream);
    var chunks = [];
    recordBtn.onclick = () => {
    if (mediaRecorder.state === "recording") {
    mediaRecorder.stop();
    console.log(chunks)
    mediaRecorder.onstop = e => {
    var blob= new Blob(chunks, { type: "audio/ogg; codecs=opus" });
    chunks = [];
    var audioURL = window.URL.createObjectURL(blob);
    const audioSrc = document.querySelector(".audio-player");
    audioSrc.src = audioURL;
    };
    recordBtn.textContent = "record";
    console.log("录音结束");
    } else {
    mediaRecorder.start();
    mediaRecorder.ondataavailable = function(e) {
    chunks.push(e.data);
    };
    console.log(chunks)
    console.log("录音中...");
    recordBtn.textContent = "stop";
    }
    console.log("录音器状态:", mediaRecorder.state);
    };

    },
    () => {
    console.error("授权失败!");
    }
    );
    } else {
    console.error("浏览器不支持 getUserMedia");
    }
    if (navigator.mediaDevices.getUserMedia) {
    const constraints1 = { audio: true };
    navigator.mediaDevices.getUserMedia(constraints1).then(
    stream1 => {
    console.log("授权成功!");
    const recordBtn1 = document.querySelector(".record-btn1");
    const mediaRecorder1 = new MediaRecorder(stream1);
    var chunks1 = [];
    recordBtn1.onclick = () => {
    if (mediaRecorder1.state === "recording") {
    mediaRecorder1.stop();
    //console.log(chunks)
    mediaRecorder1.onstop = e => {
    var blob1 = new Blob(chunks1, { type: "audio/ogg; codecs=opus" });
    chunks1 = [];
    var audioURL1 = window.URL.createObjectURL(blob1);
    const audioSrc1 = document.querySelector(".audio-player1");
    audioSrc1.src = audioURL1;
    };
    recordBtn1.textContent = "record";
    console.log("录音结束");
    } else {
    mediaRecorder1.start();
    mediaRecorder1.ondataavailable = function(e) {
    chunks1.push(e.data);
    };
    //console.log(chunks)
    console.log("录音中...");
    recordBtn1.textContent = "stop";
    }
    console.log("录音器状态:", mediaRecorder1.state);
    };

    },
    () => {
    console.error("授权失败!");
    }
    );
    } else {
    console.error("浏览器不支持 getUserMedia");
    }

    </script>
    </body>
    </html>

    (这个代码可以直接复制粘贴使用,查看效果,然后再一步步的学习细节)

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

    inactive:处于休息状态,要么是没开始,要么是开始后已经停止。

    recording:录音中

    paused:已经开始,但被暂停了,不是停止也没有被恢复。

  • 相关阅读:
    其它运算符
    位运算符
    赋值运算符
    逻辑运算符
    关系运算符
    理解twisted中的reactor和deferred(一)
    修改 Django Administration
    celery 调用scrapy
    flower 时区设置
    Python 过滤HTML实体符号简易方法
  • 原文地址:https://www.cnblogs.com/qianxiaox/p/14973950.html
Copyright © 2020-2023  润新知