示例:在H5中使用video结合canvas来录制视频和上传

2021-04-29 15:17:21 浏览数 (1)

1.背景

对于正在播放的视频,期望做到 录制这个视频流,并上传到后端服务。

2.实现思路:

1.通过 video 播放视频,不过video设置为不可见。 2.将 video里的视频帧展示在 canvas 上。 3.录制 canvas 上的绘制的内容 并生成 字节blob 包。 4.上传 字节数据包到 后端

3.实现方式

播放 video, 并将视频流 呈现在 canvas 上

写页面 注意 video 是不可见的,canvas 是可见的。

代码语言:javascript复制
    <div style="text-align: center;margin-top:10px;">
      <canvas id="theCanvas" height=360 width=640 style="width:640px;margin:auto;"></canvas>
      <video src="hmbb.mp4" id="theVideo" autoplay=true style="display:none;"></video>
    </div>

点击播放按钮开始播放

1、初始视频操作 2、播放

其实就是获得 cavas 的绘制 context , 利用 requestAnimationFrame 的帧回调,不断的刷新和绘制 视频的内容到 canas

代码语言:javascript复制
      $("#openBtn").click(function(){
        console.log("# 点击 openBtn");
        _chunks = [];
        _theVideo.play()
        _playID = playCanvas(_theVideo, _ctx);

        setRecorder();
      });


  // 一些初始化操作
    var init = function() {
      _theVideo = $("#theVideo").get(0);
      _theCanvas = $("#theCanvas").get(0);
      console.log(_theCanvas);
      const ctx = _theCanvas.getContext('2d');
      ctx.fillStyle = 'white';
      ctx.fillRect(0, 0, _theCanvas.width, _theCanvas.height);
      _ctx = ctx;

    };// end init

    // 通过类似定时器的方式,将 视频流的内容 逐帧写入到 canvas
    function playCanvas(srcvideo, ctx) {
      //console.log("# playCanvas... ");
      ctx.drawImage(srcvideo, 0, 0, 640, 360)
      _playID = requestAnimationFrame(() => {
        //console.log("# ctx.drawImage... id=" _playID);
        playCanvas(srcvideo, ctx)
      })
    }

录制

  1. 通过 _theCanvas.captureStream(60); 获得一个 视频流
  2. 将视频流作为参数,生成一个 MediaStreamRecorder 录制器。
  3. 调用 录制器 的 start() 方法开始录制。
  4. _mediaRecorder.ondataavailable 的回调方法中 追加保持字节。
  5. 将字节(录制的数据)上传
代码语言:javascript复制
      $("#openBtn").click(function(){
        console.log("# 点击 openBtn");
        _chunks = [];
        _theVideo.play()
        _playID = playCanvas(_theVideo, _ctx);

        setRecorder();
      });

      $("#startBtn").click(function(){
        console.log("# 点击 startBtn");
        _mediaRecorder.start(); //录像
      });

      $("#stopBtn").click(function(){
        console.log("# 点击 stopBtn");
        _mediaRecorder.stop(); //停止录像
      });

  // 初始化录制器
    var setRecorder = function(mediaStream){
      console.log("# 初始化 mediaRecorder");
      _chunks = [];
      // 视频格式
      let VIDEO_FORMAT = 'video/webm';
      if(!MediaRecorder.isTypeSupported(VIDEO_FORMAT)){
            alert(format)
            alert("当前浏览器不支持该编码类型");
            return;
      }
      // 初始化 录像 mediaRecorder
      _mediaStream= _theCanvas.captureStream(60); // 60 FPS recording
      console.log(_mediaStream);
      _mediaRecorder = new MediaStreamRecorder(_mediaStream);
      _mediaRecorder.mimeType = VIDEO_FORMAT;
      _mediaRecorder.ondataavailable = function (data) {
          console.log("# 产生录制数据...");
          console.log(data);
          console.log("# ondataavailable, size = "   parseInt(data.size/1024)   "KB");
          _chunks.push(data);
      };
      _mediaRecorder.onstop = function(e) {
          console.log("# 录制终止 ...");
          const fullBlob = new Blob(_chunks);
          const blobURL = window.URL.createObjectURL(fullBlob);
          console.log("blob is ?, size=" parseInt(fullBlob.size/1024) "KB. "); console.log(fullBlob);
          console.log("blobURL ="   blobURL);

          uploadFile(fullBlob);
        }
    }// end initMediaRecorder

方法:开始和停止动画(视频流)

播放

window.requestAnimationFrame() : 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。

该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。

停止 问:怎么停止requestAnimationFrame? 答:使用 cancelAnimationFrame() 接收一个参数 requestAnimationFrame默认返回一个id,cancelAnimationFrame只需要传入这个id就可以停止了。

https://www.jianshu.com/p/fa5512dfb4f5

4. 我的示例代码

文字说明: 代码放在githb::https://github.com/vir56k/demo/blob/master/video2/public/index3.html

参考

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame

https://www.jianshu.com/p/fa5512dfb4f5

https://www.w3school.com.cn/jsref/dom_obj_video.asp

https://www.cnblogs.com/scarecrowlxb/p/9573976.html

最好建议看下这个 https://cloud.tencent.com/developer/article/1366886 下文的视频演示的源码值得一看 https://wendychengc.github.io/media-recorder-video-canvas/videocanvas.html

http://www.zuidaima.com/blog/3819727543307264.htm

0 人点赞