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

简介: 关于关于【SSD系列】:前端一些有意思的内容,旨在3-10分钟里, 500-1500字,有所获,又不为所累。如题,今天我们用纯web技术,实现摄像头+麦克风 视频的录制功能,代码约100余行

前言


关于关于【SSD系列】


前端一些有意思的内容,旨在3-10分钟里, 500-1500字,有所获,又不为所累。

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


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


效果演示


真机效果


1.JPG


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


2.JPG


源码地址


本文源码-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字,有所得,而不为所累,如果你觉得不错,你的一赞一评就是我前行的最大动力。

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


相关文章
|
26天前
|
前端开发 JavaScript 关系型数据库
从前端到后端:构建现代化Web应用的技术探索
在当今互联网时代,Web应用的开发已成为了各行各业不可或缺的一部分。从前端到后端,这篇文章将带你深入探索如何构建现代化的Web应用。我们将介绍多种技术,包括前端开发、后端开发以及各种编程语言(如Java、Python、C、PHP、Go)和数据库,帮助你了解如何利用这些技术构建出高效、安全和可扩展的Web应用。
|
2月前
|
JSON JavaScript 数据格式
jwt-auth插件实现了基于JWT(JSON Web Tokens)进行认证鉴权的功能。
jwt-auth插件实现了基于JWT(JSON Web Tokens)进行认证鉴权的功能。
44 1
|
3天前
|
存储 前端开发 搜索推荐
13:Session机制实现用户登录与注销功能-Java Web
13:Session机制实现用户登录与注销功能-Java Web
15 3
|
3天前
|
存储 前端开发 安全
13:会话跟踪技术Session的深度应用与实践-Java Web
13:会话跟踪技术Session的深度应用与实践-Java Web
15 3
|
3天前
|
存储 前端开发 搜索推荐
12:会话跟踪技术Cookie的深度应用与实践-Java Web
12:会话跟踪技术Cookie的深度应用与实践-Java Web
15 4
|
3天前
|
安全 前端开发 Java
10:基于Servlet模拟用户登录功能的实现与解析-Java Web
10:基于Servlet模拟用户登录功能的实现与解析-Java Web
15 3
|
4天前
|
缓存 移动开发 前端开发
【专栏:HTML与CSS前端技术趋势篇】HTML与CSS在PWA(Progressive Web Apps)中的应用
【4月更文挑战第30天】PWA(Progressive Web Apps)结合现代Web技术,提供接近原生应用的体验。HTML在PWA中构建页面结构和内容,响应式设计、语义化标签、Manifest文件和离线页面的创建都离不开HTML。CSS则用于定制主题样式、实现动画效果、响应式布局和管理字体图标。两者协同工作,保证PWA在不同设备和网络环境下的快速、可靠和一致性体验。随着前端技术进步,HTML与CSS在PWA中的应用将更广泛。
|
4天前
|
前端开发 JavaScript UED
【专栏:HTML 与 CSS 前端技术趋势篇】Web 性能优化:CSS 与 HTML 的未来趋势
【4月更文挑战第30天】本文探讨了CSS和HTML在Web性能优化中的关键作用,包括样式表压缩、选择器优化、DOM操作减少等策略。随着未来趋势发展,CSS模块系统、自定义属性和响应式设计将得到强化,HTML新特性也将支持复杂组件构建。同时,应对浏览器兼容性、代码复杂度和性能功能平衡的挑战是优化过程中的重要任务。通过案例分析和持续创新,我们可以提升Web应用性能,创造更好的用户体验。
|
4天前
|
前端开发 JavaScript 搜索推荐
【专栏:HTML 与 CSS 前端技术趋势篇】HTML 与 CSS 在 Web 组件化中的应用
【4月更文挑战第30天】本文探讨了HTML和CSS在Web组件化中的应用及其在前端趋势中的重要性。组件化提高了代码复用、维护性和扩展性。HTML提供组件结构,语义化标签增进可读性,支持用户交互;CSS实现样式封装、布局控制和主题定制。案例展示了导航栏、卡片和模态框组件的创建。响应式设计、动态样式、CSS预处理器和Web组件标准等趋势影响HTML/CSS在组件化中的应用。面对兼容性、代码复杂度和性能优化挑战,需采取相应策略。未来,持续发掘HTML和CSS潜力,推动组件化开发创新,提升Web应用体验。
|
5天前
|
开发框架 JavaScript 前端开发
【JavaScript 与 TypeScript 技术专栏】TypeScript 在 Web 开发中的前沿应用
【4月更文挑战第30天】TypeScript在Web开发中日益重要,以其强大的类型系统提升代码质量,支持组件化开发,与React、Vue、Angular等框架良好集成。在大型项目管理中,TypeScript助于代码组织和优化,提高团队协作效率。此外,它提升开发体验,提供智能提示和错误检测。众多成功案例证明其前沿应用,未来将在Web开发领域持续发挥关键作用。