html video使用MediaRecorder实现录屏功能

video视频的录制

在这里插入图片描述

准备h5可以播放的test.mp4 , mp4需要是h264录制的

实现步骤

在这里插入图片描述

  1. onloadedmetadata 在video加载完视频源之后拦截
  2. 使用video.captureStream 对视频流进行抓取 , 并生成MediaRecorder对象 .
  3. mediaRecorder对象使用 ondataavailable将二进制数据写入videoData
    在这里插入图片描述
  4. 根据videoData生成blob对象
  5. 根据blob对象生成录制的视频 videoUrl ,并进行播放

在这里插入图片描述
 ps: RecIntervalListener 类 只是为了增加渲染效果非核心代码

完整GIF 示例代码

<html>

<head>
  <title>video录屏</title>
  <style type="text/css">
    .block-area {
      display: inline-block;
      width: 800px;
      height: 600px;
      margin-left: 100px;
      overflow-y: auto;
      border: 1px solid #ccc;
    }

    .block-area video {
      margin-left: 100px;
      width: 600;
      height: 300;
    }

    blockquote {
      margin-left: 0;
      margin-right: 0;
      padding: 0 15px;
      color: #424242;
      border-left: 4px solid #ddd;
    }

    .captureHoverArea {
      position: absolute;
      z-index: 100;
      left: 600px;
      top: 145px;
      color: red;
      display: none;
    }

    .captureHoverArea button {
      background-color: red;
      border-color: red;
      border-radius: 50%;
      width: 15px;
      height: 15px;
    }
  </style>
</head>

<body>
  <blockquote>
    <h3>ps:请使用server模式测试</h3>
  </blockquote>
  <div class="captureHoverArea">
    <label id="blinkRec"><button></button><b>&nbsp;REC&nbsp;</b></label>
    <label id="recorderTime"></label>
  </div>
  <div class="block-area">
    <h4>原始视频:
      <button id="btnStart" onclick="startCapture()">Start</button>
      <button id="btnStop" disabled='disabled' onclick="endCapture()">Stop</button>
    </h4>
    <video id="mainVideo" playsinline="" webkit-playsinline="1" controls="1" onloadedmetadata="initMediaRecorder()">
      <source src="test.mp4" type="video/mp4">
    </video>
  </div>
  <div class="block-area">
    <h4>
      录制结果:
      <span id="captureResult" style="display:none">
        <span id="captureTime"></span>
        <button id="btnResult" onclick="showCapture()">ShowCapture</button>
      </span>
    </h4>

    <video id="displayVideo" autoplay="autoplay" playsinline="" webkit-playsinline="1" controls="1"></video>
  </div>
</body>

<script>

  var mainVideo = document.getElementById("mainVideo");
  var displayVideo = document.getElementById("displayVideo");

  var videoData = [];
  var recListener;
  var mediaRecorder;

  /**
   *  录屏记录器 
   *  样式效果代码
   */
  class RecIntervalListener {
    constructor() {
      this.start = new Date();
      this.end = null;

      this.btnStart = document.getElementById("btnStart");
      this.btnStop = document.getElementById("btnStop");

      this.recorderTime = document.getElementById("recorderTime");
      this.blinkRec = document.getElementById("blinkRec");
      this.captureTime = document.getElementById("captureTime");

      this.repeat = setInterval(() => {
        this.recorderTime.innerText = parseInt(new Date() - this.start) / 1000 + "s"
      });
      this.repeatBlink = setInterval(() => {
        this.toggleBlink()
      }, 400);
      this.toggleRecArea(true)
      this.toggleDisableButton(true);
    }
    /*
     * 停止
     */
    stop() {
      this.end = new Date();
      clearInterval(this.repeat);
      clearInterval(this.repeatBlink);
      this.toggleRecArea(false)
      this.toggleDisableButton(false);
      this.captureTime.innerText = `Capture Video:${recListener.getLastTime()} s`;


    }
    /*
     * 获取最后时间
     */
    getLastTime() {
      return parseInt(this.end - this.start) / 1000
    }
    /*
     * 控制录屏显示隐藏
     */
    toggleRecArea(isShow) {
      let displayHoverArea = isShow ? 'inline' : 'none'
      let displayCaptureResult = isShow ? 'none' : 'inline'
      document.querySelector('.captureHoverArea').style.display = displayHoverArea;
      document.getElementById("captureResult").style.display = displayCaptureResult;
    }
    /*
     * 控制录屏标识闪烁
    */
    toggleBlink() {
      this.blinkShow = !this.blinkShow;
      let displayAttr = this.blinkShow ? 'hidden' : ''
      this.blinkRec.style.visibility = displayAttr;
    }
    /*
     * 控制按钮是否可用
     */
    toggleDisableButton(isStart) {
      if (isStart) {
        this.btnStart.setAttribute('disabled', 'disabled');
        this.btnStop.removeAttribute('disabled');
      } else {
        this.btnStart.removeAttribute('disabled');
        this.btnStop.setAttribute('disabled', 'disabled');
      }
    }
  }

  /*
   * 拦截二进制流数据
   */
  var initMediaRecorder = function () {
    // Record with 25 fps
    mediaRecorder = new MediaRecorder(mainVideo.captureStream(25));

    mediaRecorder.ondataavailable = function (e) {
      videoData.push(e.data);
    };
  }


  /*
  * 录制
  */
  function startCapture() {
    videoData = [];
    mainVideo.play();
    mediaRecorder.start();
    recListener = new RecIntervalListener();
  };
  /*
   * 停止
   */
  function endCapture() {
    mediaRecorder.stop();
    mainVideo.pause();
    recListener.stop();
  };

  /*
   * 播放录制
   */
  function showCapture() {
    return new Promise(resolve => {
      setTimeout(() => {
        // Wrapping this in setTimeout, so its processed in the next RAF
        let blob = new Blob(videoData, {
          'type': 'video/mp4'
        });
        let videoUrl = window.URL.createObjectURL(blob);
        displayVideo.src = videoUrl;
        resolve();
      }, 0);
    });
  };
</script>

</html>
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值