• 纯js实现录屏并保存视频到本地的尝试


    前言:先了解下:navigator.mediaDevices,mediaDevices 是 Navigator 只读属性,返回一个 MediaDevices 对象,该对象可提供对相机和麦克风等媒体输入设备的连接访问,也包括屏幕共享。
    const media = navigator.mediaDevices;

    通过原型链可以查找到一些方法,如下图所示:通过打印如下:

    其中 getDisplayMedia 方法来获取用户的屏幕分享或屏幕捕获流,通常用于制作屏幕录像或视频会议等应用。

    1. navigator.mediaDevices.getDisplayMedia({
    2. video: true,
    3. });

    在这段代码中,请求获取包含视频流的媒体许可,并将其存储在名为 stream 的变量中,以便后续使用。这个流可以用于在网页上显示屏幕共享或进行其他媒体处理操作。

    又因为该方法是异步的,我们要编写如下代码:

    1. <button>共享屏幕button>
    2. <script>
    3. const button = document.querySelector("button");
    4. button.addEventListener("click", async () => {
    5. const stream = await navigator.mediaDevices.getDisplayMedia({
    6. video: true,
    7. });
    8. });
    9. script>

    通过点击 button 按钮后会如下图所示效果:

    这个时候 stream 流我们是拿到了。 

                                            MediaRecorder

    MediaRecorder 是一个 Web API,用于在浏览器中进行媒体录制,主要用于录制音频和视频。它允许你从不同的来源,例如麦克风、摄像头、屏幕共享或其他媒体元素,捕获音频和视频数据,并将其保存为文件或进行实时流媒体传输。通过调用 MediaRecorder.isTypeSupported() 方法会判断其 MIME 格式能否被客户端录制。它支持的类型主要有以下几种方式:

    1. const types = [
    2. "video/webm",
    3. "audio/webm",
    4. "video/webm;codecs=vp8",
    5. "video/webm;codecs=daala",
    6. "video/webm;codecs=h264",
    7. "audio/webm;codecs=opus",
    8. "video/mpeg",
    9. ];

    通过这种方式来查看当前浏览器是否支持该类型,如下代码所示:

    1. const mime = MediaRecorder.isTypeSupported("video/webm;codecs=h264")
    2. ? "video/webm;codecs=h264"
    3. : "video/webm";

    结果如下图所示:

    const mediaRecorder = new MediaRecorder(stream, { mimeType: mime });

    在这段代码里面,执行 new 关键字实例化 MediaRecorder 对象。该对象的结构如下图所示:

    我们可以通过监听它的事件来进行不同的操作,如下代码所示:

    1. const chunks = [];
    2. mediaRecorder.addEventListener("dataavailable", function (e) {
    3. chunks.push(e.data);
    4. });
    5. mediaRecorder.addEventListener("stop", () => {
    6. const blob = new Blob(chunks, { type: chunks[0].type });
    7. const url = URL.createObjectURL(blob);
    8. const a = document.createElement("a");
    9. a.href = url;
    10. a.download = "video.webm";
    11. a.click();
    12. });

    接下来我们来看看段代码的详细步骤:

    • dataavailable 事件的监听器。当 MediaRecorder 有可用的音频/视频数据块时,它会触发此事件。在这里,每当数据可用时,将数据块(e.data)添加到 chunks 数组中。这是为了在录制完成后将这些数据块合并成一个完整的媒体文件。

    • stop 事件的监听器。当录制停止时,MediaRecorder 会触发此事件。

    • const blob = new Blob(chunks, { type: chunks[0].type });:使用 Blob 构造函数将 chunks 数组中的数据块合并成一个二进制对象(Blob 对象)。chunks[0].type 用于指定 Blob 的媒体类型,通常是 WebM。

    • const url = URL.createObjectURL(blob);使用 URL.createObjectURL 方法将 Blob 对象转换为一个临时 URL。这个 URL 可以用于创建下载链接。通过这个 url 传递给新创建的 a 元素用于下载功能。

    • a.click() 通过模拟点击超链接来触发下载操作。用户将看到一个下载对话框,允许他们保存录制的媒体文件

    这样就实现了一个屏幕录制功能了,并且通过该方法实现了一个音视频下载的功能。

    完整代码

    该功能的完整代码如下所示:

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8" />
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    6. <title>Documenttitle>
    7. head>
    8. <body>
    9. <button>共享屏幕button>
    10. <script>
    11. const button = document.querySelector("button");
    12. button.addEventListener("click", async () => {
    13. const stream = await navigator.mediaDevices.getDisplayMedia({
    14. video: true,
    15. });
    16. const mime = MediaRecorder.isTypeSupported("video/webm;codecs=h264")
    17. ? "video/webm;codecs=h264"
    18. : "video/webm";
    19. const mediaRecorder = new MediaRecorder(stream, { mimeType: mime });
    20. const chunks = [];
    21. mediaRecorder.addEventListener("dataavailable", function (e) {
    22. chunks.push(e.data);
    23. });
    24. mediaRecorder.addEventListener("stop", () => {
    25. const blob = new Blob(chunks, { type: chunks[0].type });
    26. const url = URL.createObjectURL(blob);
    27. const a = document.createElement("a");
    28. a.href = url;
    29. a.download = "video.webm";
    30. a.click();
    31. });
    32. mediaRecorder.start();
    33. });
    34. script>
    35. body>
    36. html>

    完整效果如下图所示:

    你也可以直接在其他任何一个页面,将 js 代码修改一下,然后直接复制粘贴到控制台上,并点击页面,如下所示:

    diff

    1. -const button = document.querySelector("button");
    2. -button.addEventListener("click", async () => {
    3. ...
    4. })
    5. +const body = document.body;
    6. +body.addEventListener("click", async () => {
    7. ....
    8. })

     紧接着将代码复制粘贴到浏览器控制台上面,并点击页面的空白处:

    1. const body = document.body;
    2. body.addEventListener("click", async () => {
    3. const stream = await navigator.mediaDevices.getDisplayMedia({
    4. video: true,
    5. });
    6. const mime = MediaRecorder.isTypeSupported("video/webm;codecs=h264")
    7. ? "video/webm;codecs=h264"
    8. : "video/webm";
    9. const mediaRecorder = new MediaRecorder(stream, { mimeType: mime });
    10. const chunks = [];
    11. mediaRecorder.addEventListener("dataavailable", function (e) {
    12. chunks.push(e.data);
    13. });
    14. mediaRecorder.addEventListener("stop", () => {
    15. const blob = new Blob(chunks, { type: chunks[0].type });
    16. const url = URL.createObjectURL(blob);
    17. const a = document.createElement("a");
    18. a.href = url;
    19. a.download = "video.mp4";
    20. a.click();
    21. });
    22. mediaRecorder.start();
    23. });

    通过这种方式就实现了一种屏幕录制或者屏幕分享的功能了。 

  • 相关阅读:
    单目全景图像深度估计方法
    Python基础分享之面向对象的进一步拓展
    Python程序生成斐波那契数列
    【obs】obsqsv11 硬编 及与metartc codec对比
    视频转文字怎么操作?这三种转换方法你该学会
    DB-GPT发布:用私有LLM技术彻底改革数据库互动
    大话西游2游戏搬砖可行性分析
    FlashDB 移植
    IO的演进
    大数据学习:使用Java API操作HDFS
  • 原文地址:https://blog.csdn.net/qq_41646249/article/details/134684834