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)); }, }, })