zoukankan      html  css  js  c++  java
  • WebRTC本地分享屏幕,录制屏幕

    WebRTC有分享屏幕的功能。使用的是getDisplayMedia方法。用户同意分享屏幕后,可以拿到视频流。
    再结合MediaRecorderBlob,把视频流数据存下来,就能得到录制屏幕的视频。

    html

    照例先来摆放一些元素在界面上

    <div id="container">
    <h3>WebRTC捕捉屏幕示例 getDisplayMedia</span></h1>
    
        <video id="gum-local" autoplay playsinline muted></video>
        <button id="startBtn" disabled>开始预览</button>
        <button id="recordBtn" disabled>开始录制</button>
        <button id="downloadBtn" disabled>下载</button>
    
        <div id="msg"></div>
    </div>
    
    <!-- 使用本地的适配器 -->
    <script src="../js/adapter-latest.js" async></script>
    <script src="js/main.js"></script>
    

    因为我的网速不是很好,把adapter文件下载到本地来用了。
    如果要使用官方的适配器adapter,按下边的地址来引入

    <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
    
    • video 用来预览视频。开始分享视频后,把视频流交给它
    • 放置一些按钮,处理交互
    • div#msg 用来显示信息

    控制

    main.js文件里写上我们的控制逻辑

    先把获取元素

    'use strict';
    
    const startBtn = document.getElementById('startBtn');
    const recordBtn = document.getElementById('recordBtn');
    const downloadBtn = document.getElementById('downloadBtn');
    const video = document.querySelector('video'); // 预览用的
    
    let mediaRecorder;
    let isRecording = false;
    let recordedBlobs = []; // 暂存视频数据的地方
    

    启动屏幕分享

    主要利用getDisplayMedia方法。我们这里只使用视频video: true

    startBtn.addEventListener('click', () => {
      navigator.mediaDevices.getDisplayMedia({video: true})
          .then(gotDisplayStream, onErr);
    });
    
    // 拿到屏幕数据流
    function gotDisplayStream(stream) {
      startBtn.disabled = true;
      video.srcObject = stream; // 显示出来
      window.stream = stream;   // 缓存一下
    
      stream.getVideoTracks()[0].addEventListener('ended', () => {
        showMsg('用户停止了分享屏幕');
        startBtn.disabled = false;
        recordBtn.disabled = true;
      });
      recordBtn.disabled = false;
    }
    
    function onErr(error) {
      showMsg(`getDisplayMedia on err: ${error.name}`, error);
    }
    
    function showMsg(msg, error) {
      const msgEle = document.querySelector('#msg');
      msgEle.innerHTML += `<p>${msg}</p>`;
      if (typeof error !== 'undefined') {
        console.error(error);
      }
    }
    

    拿到视频流后,交给video显示。
    给视频流添加事件监听器,如果停止了分享,我们能获得事件。

    在这一步,把其它ui元素注释掉,已经可以测试分享屏幕的效果了。
    Chrome和edge会询问用户是否分享屏幕,并让用户选择要分享的界面。mac会需要用户修改隐私设定。
    同意后,就能看到分享屏幕的效果了。

    ???+ note "移动端"
    在手机chrome上无法分享

    录屏

    上一步我们拿到了视频流。可以仿照之前的方法把视频流数据存下来

    先来找到浏览器支持的视频格式。为了简化操作,后面我们只选用第一种支持的格式。

    // 找到支持的格式
    function getSupportedMimeTypes() {
      const possibleTypes = [
        'video/webm;codecs=vp9,opus',
        'video/webm;codecs=vp8,opus',
        'video/webm;codecs=h264,opus',
        'video/mp4;codecs=h264,aac',
      ];
      return possibleTypes.filter(mimeType => {
        return MediaRecorder.isTypeSupported(mimeType);
      });
    }
    

    开始录制

    把视频流数据推进recordedBlobs

    当然这里只是试用,实际上这么多数据存在内存里不妥。

    function startRecording() {
      recordedBlobs = [];
      const mimeType = getSupportedMimeTypes()[0];
      const options = { mimeType };
    
      try {
        mediaRecorder = new MediaRecorder(window.stream, options);
      } catch (e) {
        showMsg(`创建MediaRecorder出错: ${JSON.stringify(e)}`);
        return;
      }
      recordBtn.textContent = '停止录制';
      isRecording = true;
      downloadBtn.disabled = true;
      mediaRecorder.onstop = (event) => {
        showMsg('录制停止了: ' + event);
      };
      mediaRecorder.ondataavailable = handleDataAvailable;
      mediaRecorder.start();
      showMsg('录制开始 mediaRecorder: ' + mediaRecorder);
    }
    
    function handleDataAvailable(event) {
      console.log('handleDataAvailable', event);
      if (event.data && event.data.size > 0) {
        recordedBlobs.push(event.data);
      }
    }
    

    停止录制

    mediaRecorder.stop()

    function stopRecord() {
      isRecording = false;
      mediaRecorder.stop();
      downloadBtn.disabled = false;
      recordBtn.textContent = "开始录制";
    }
    

    下载

    recordedBlobs里的数据打包好下载下来

    downloadBtn.addEventListener('click', () => {
      const blob = new Blob(recordedBlobs, { type: 'video/webm' });
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.style.display = 'none';
      a.href = url;
      a.download = '录屏_' + new Date().getTime() + '.webm';
      document.body.appendChild(a);
      a.click();
      setTimeout(() => {
        document.body.removeChild(a);
        window.URL.revokeObjectURL(url);
      }, 100);
    });
    

    小结

    我们使用了WebRTC的getDisplayMedia方法分享屏幕。并结合之前了解的下载视频方法,实现了简易的录屏下载效果。

    效果

    效果预览界面

    原文链接 WebRTC本地分享屏幕,录制屏幕

    一个软件工程师的记录
  • 相关阅读:
    first root
    C r and n(组合数)
    学习笔记
    zabbix历史数据全部清楚
    Jetson TX2安装固态硬盘(原创)
    Jetson TX2安装tensorflow(原创)
    机器视觉编程作业02(01)(原创)
    机器视觉编程作业02(00)EM算法
    机器视觉 编程作业题 第一题(01)(原创)
    动态代理
  • 原文地址:https://www.cnblogs.com/rustfisher/p/15646958.html
Copyright © 2011-2022 走看看