• webRTC初接触,使用canvas绘制视频流,并添加颜色滤镜


    效果:(左边是canvas绘制的视频,右边是经过滤镜处理后的canvas视频)

    几个关键点:

    requestAnimationFrame 用于重复绘制图像,形成动态视频
    ctx.drawImage 在canvas中绘制图像(支持跨域)
    getImageData 获取canvas内的图像数据
    putImageData 图像数据付给canvas
     
    源码:
    html:2个canvas,2个按钮事件
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>使用canvas绘制视频流</title>
      <script src="./vue.js"></script>
      <style>
        .canvas {
          width: 300px;
          height: 300px;
          background-color: #000;
          border: 1px solid #000;
        }
      </style>
    </head>
    <body>
      <div id="app">
        <canvas ref='preview' class="canvas"></canvas>
        <canvas ref='preview2' class="canvas"></canvas>
        <div>
          <button @click="btnplay">播放</button>
          <button @click="btnpause">暂停</button>
        </div>
      </div>
      <script src="3.js"></script>
    </body>
    </html>

    js:

    new Vue({
      el: '#app',
      mounted() {
        //canvas ctx对象
        this.ctx = this.$refs.preview.getContext('2d');
        //滤镜的canvas ctx对象
        this.ctx2 = this.$refs.preview2.getContext('2d');
        //创建video对象
        this.video = document.createElement('video');
        this.video.src = './movie.mp4';
        //canvas宽高
        this.previewWidth = this.$refs.preview.width
        this.previewHeight = this.$refs.preview.height
    
        //重复执行
        // this.animationFrame()
        requestAnimationFrame(this.animationFrame.bind(this));
      },
      methods: {
        //播放
        btnplay() {
          this.video.play()
        },
        //暂停
        btnpause() {
          this.video.pause()
        },
    
        //绘制视频到canvas
        animationFrame() {
          this.ctx.drawImage(this.video, 0, 0, this.previewWidth, this.previewHeight)//绘制图片 这个是支持跨域的
          /**
           * getImageData/putImageData 只支持同源 不支持跨域
           */
          const imageData = this.ctx.getImageData(0, 0, this.previewWidth, this.previewHeight);//获取canvas内的图像数据
          let imageData2 = this.ctx2.createImageData(imageData.width, imageData.height)//创建一个空的canvas图像数据
    
          //拷贝canvas1中的数据并改成黑白颜色
          const data = imageData.data
          for (let i = 0; i < data.byteLength; i += 4) {
            let c = Math.floor((data[i] + data[i + 1] + data[i + 2]) / 3)
            imageData2.data[i] = c //r
            imageData2.data[i + 1] = c //g
            imageData2.data[i + 2] = c //b
            imageData2.data[i + 3] = 255 //a
          }
    
          //改成反转颜色
          const data2 = imageData2.data
          for (var i = 0; i < data2.length; i += 4) {
            imageData2.data[i] = 255 - data2[i];
            imageData2.data[i + 1] = 255 - data2[i + 1];
            imageData2.data[i + 2] = 255 - data2[i + 2];
            imageData2.data[i + 3] = 255;
          }
          
          this.ctx2.putImageData(imageData2, 0, 0);//图像数据付给canvas2
          requestAnimationFrame(this.animationFrame.bind(this));
        },
      },
    })
     
     
     
  • 相关阅读:
    codesmith
    moment.js
    select2
    Lodash js数据操作库
    angular.js
    vue.js
    axios.js
    RoutePrefix和Route 路由前缀
    Tuple元组 C#
    ningx访问日志切割
  • 原文地址:https://www.cnblogs.com/wuhairui/p/15801119.html
Copyright © 2020-2023  润新知