最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 【SSD系列】五分钟,100余行代码,纯web技术一起实现摄像头和麦克风视频录制,并带历史记录功能

    正文概述 掘金(云的世界)   2021-08-11   421

    这是我参与8月更文挑战的第天,活动详情查看:8月更文挑战。

    前言

    关于关于【SSD系列】:
    前端一些有意思的内容,旨在3-10分钟里, 500-1500字,有所获,又不为所累。

    如题,今天我们用纯web技术,实现摄像头+麦克风 视频的录制功能,代码约100余行, 主要涉及的知识点:

    1. MediaDevices
      提供对连接的媒体输入设备(如照相机和麦克风)的访问,以及屏幕共享等。
    2. MediaRecorder
      录制音频或者视频。
    3. IndexedDB
      储存较大数据结构的事务性数据库。
    4. URL
      用来把视频的Blob数据生成地址,提供给video标签使用。

    效果演示

    真机效果

    【SSD系列】五分钟,100余行代码,纯web技术一起实现摄像头和麦克风视频录制,并带历史记录功能

    PC端 + 模拟移动 + 虚拟摄像头(VCam)

    【SSD系列】五分钟,100余行代码,纯web技术一起实现摄像头和麦克风视频录制,并带历史记录功能

    源码地址

    本文源码-recordAV

    注意:

    1. 权限问题,需要显式的授权
    2. 如果手机端预览,需要启用https,demo已经附带证书

    思路

    1. 利用MediaDevices唤起摄像头和麦克风
    2. 把第一步获取的流,同时用于videoMediaRecorder
      因为录制的同时需要看到我们摄像头的内容
    3. 录制结束后,把录制视频存入indexedDB
    4. 按照keys列出已录制的视频,点击后,获取Blob文件,生成url,提供给video标签播放。

    实现

    唤起摄像头和麦克风并获得其流

    这里需要用的就是MediaDevices,对应的API就是navigator.mediaDevices.getUserMedia

    核心代码如下:

    const stream = await navigator.mediaDevices.getUserMedia({
        video: { facingMode: "environment" },  // 唤起内面的摄像头,
        audio: true  // 需要音频,例如麦克风
    })
    // 把流传给video元素,即可看到摄像头内容
    videoEL.srcObject = stream;  
    // 初始化 MediaRecorder
    mediaRecorder = new MediaRecorder(stream, { mimeType: "video/webm" });
    

    注意事项:

    1. getUserMedia方法的facingMode参数
      user为前置的摄像头,environment为后置摄像头。
    2. new MediaRecorder的参数{ mimeType: "video/webm" }
      如果未设置正确,可能就只有视频,没有麦克风声音了

    录制和保存

    录制必然有开始和停止两个操作,实现方式很多,我们就采用最简单的两个按钮形式, 并分别给注册上相关的事件处理程序。

    代码如下:
    这里有一个小的知识点,任何有id属性的节点,你均可使用id属性对应的变量直接访问该元素。

    <button id="btnRecord" class="btn">录制</button>
    <button id="btnStop"  class="btn" >停止</button>
    
    btnRecord.addEventListener("click", () => {
        startRecord(mediaRecorder);
        mediaRecorder.start();
    });
    
    btnStop.addEventListener("click", () => {
        mediaRecorder.stop();
    })
    
    

    是不是很简单。 注意上面停止按钮点击后,我们调用了mediaRecorder.stop方法,其之后会触发recorder.onstop事件,这个时候,我们唤起弹出框,让用户输入视频的名字,然后将内容保存到indexedDB即可。

    indexedDB的存取有很多封装库,indexedDB 参见部分列出了不少于10个库,这里我们采用 idb-keyval库,其简单且小巧的(~600B)基于 Promise 的键值对存储,使用也是极其简单,get, set就行了。

    具备上面的知识后,看代码:是不是很简单。

    function startRecord(recorder) {
        var chunks = [];
        // 收集数据
        recorder.ondataavailable = function (e) {
            chunks.push(e.data);
        }
        // 监听停止事件
        recorder.onstop = async () => {
            var clipName = prompt('请输入视频的名字');
            var blob = new Blob(chunks, { 'type': 'audio/mp4;' });
            await idbKeyval.set(clipName + ".mp4", blob);
            listHistory();
        }
    }
    

    历史和观看

    历史嘛,那就是读取keys,严格意义上,应该使用indexedDB的游标来读取,本文为了简单,直接读取所有的keys,然后判断文件后缀来过滤。

    async function listHistory() {
        list.innerHTML = null;
        const keys = await idbKeyval.keys();
        console.log("keys:", keys);
    
        keys.filter(k => k.endsWith(".mp4")).forEach(key => {
            const divEl = document.createElement("div");
            divEl.textContent = key;
            divEl.onclick = () => playVideo(key);
    
            list.appendChild(divEl);
        });
    }
    

    到此为止,我们就差点击某个历史视频之后的播放逻辑了,也很简单:

      async function playVideo(key) {
            const blob = await idbKeyval.get(key);
            // 生成地址
            fplayer.src = URL.createObjectURL(blob);
            fplayer.style.display = "block";
            fplayer.play();
        }
    

    到此文本,所有的核心代码都已经实现了。

    小结

    是不是很简单,一切都看起来没那么难,这样,你才容易入坑啊。

    写在最后

    不忘初衷,【SSD系列】,3-5分钟,500-1000字,有所得,而不为所累,如果你觉得不错,你的一赞一评就是我前行的最大动力。

    技术交流群请到 这里来。 或者添加我的微信 cloud-dirge,一起学习。


    起源地下载网 » 【SSD系列】五分钟,100余行代码,纯web技术一起实现摄像头和麦克风视频录制,并带历史记录功能

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元