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

1.背景

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

2.实现思路:

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

3.实现方式

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

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

<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

$("#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. 将字节(录制的数据)上传
$("#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

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值