Canvas实现视频播放器
我们先用Canvas来实现一个基础的具有播放和暂停功能的播放器
首先,Canvas是不能画一个视频的,这是一个画画的工具,他只能一幅一幅图去画,因此用Canvas实现一个播放器本质上就是将视频中的帧每隔一段时间就画出来
我们先画一个和视频等大的canvas画布,并把视频播放器本身消除掉
1 2
| <video src="video/1.mp4" controls="controls" width="800" height="450" style="display: none;"></video> <canvas style="background-color: black;" id="c1" width="800" height="450"></canvas>
|
然后我们需要先把播放和暂停的功能给到canvas上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| var canvas = document.querySelector('#c1') var ctx = canvas.getContext('2d') var video = document.querySelector('video')
ctx.font = "bold 50px 微软雅黑"; ctx.fillStyle = "#ddd" ctx.fillText("💿点击播放", 280, 220)
canvas.onclick = function () { if (video.paused) { video.play() } else { video.pause() clearInterval(intervalId) ctx.font = "bold 50px 微软雅黑"; ctx.fillStyle = "#ddd" ctx.fillText("💿暂停", 280, 220) } }
|
这样我们通过点击画布就可以实现视频的播放和暂停,但注意是视频本身的播放,而并不是画布,画布上除了播放和暂停依然是空无一物,接下来我们要在画布上将播放中的视频帧画出来
我们希望一秒播放60帧,计算一下大概16到17秒就要播放一帧,我们设置一个时间间隔函数让画布定期把视频帧画出来,这样播放器的基本功能就实现了
1 2 3 4 5 6
| video.onplay = function () { intervalId = setInterval(function () { ctx.drawImage(video, 0, 0, 800, 450) }, 16) }
|
视频水印的添加
视频水印本质上就是在画布画出来的那一帧上继续画张图,我们随便找一张图,将它载入 (新建一个img对象,修改src)
1 2
| var img = new Image() img.src = "img.png"
|
这个图片应该要在每一帧画完之后画上
同时,希望水印动起来 (增加别人去水印的难度2333),于是我选择每两百帧把水印换个位置再画上去,所以只需要修改一下video的播放监听函数
1 2 3 4 5 6 7 8 9 10 11
| var cnt = 0; video.onplay = function () { intervalId = setInterval(function () { cnt++; ctx.drawImage(video, 0, 0, 800, 450) if (Math.floor(cnt / 100) % 4 == 0) ctx.drawImage(img, 200, 200, 200, 200) if (Math.floor(cnt / 100) % 4 == 1) ctx.drawImage(img, 400, 0, 200, 200) if (Math.floor(cnt / 100) % 4 == 2) ctx.drawImage(img, 400, 200, 200, 200) if (Math.floor(cnt / 100) % 4 == 3) ctx.drawImage(img, 100, 100, 200, 200) }, 16) }
|
这样子就能实现水印功能
视频弹幕发送
弹幕的发送和水印的原理差不多,就是让文字在每一帧逐渐从最右边移动到最左边
我们需要一个数组将所有发送的弹幕都保存下来,然后让他们从右边飘到左边去
1 2 3 4 5 6
| var sendBtn = document.querySelector('#sendBtn')
var dmInput = document.querySelector('#dmInput');
var danmulist = [];
|
当点击发送弹幕时,我们需要做的就是获取弹幕输入框中的内容,去生成一个弹幕并压入数组,生成的时候初始位置在最后边,同时竖直方向上选取一个随机位置
1 2 3 4 5 6 7 8 9
| sendBtn.onclick = function(){ console.log(sendBtn) var danmu = { value:dmInput.value, x:800, y:Math.random()*450 } danmulist.push(danmu) }
|
弹幕在视频上的移动则需要小修一下之前画帧的函数,在每一帧画出之后,让弹幕列表中的每条弹幕往左移动一丢丢,然后打印在画布上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| video.onplay = function () { intervalId = setInterval(function () { cnt++; ctx.drawImage(video, 0, 0, 800, 450) if (Math.floor(cnt / 100) % 4 == 0) ctx.drawImage(img, 200, 200, 200, 200) if (Math.floor(cnt / 100) % 4 == 1) ctx.drawImage(img, 400, 0, 200, 200) if (Math.floor(cnt / 100) % 4 == 2) ctx.drawImage(img, 400, 200, 200, 200) if (Math.floor(cnt / 100) % 4 == 3) ctx.drawImage(img, 100, 100, 200, 200) ctx.font = "30px 微软雅黑"; ctx.fillStyle = "#fff" danmulist.forEach(function(item,i){ item.x--; ctx.fillText(item.value,item.x,item.y) ctx.strokeText(item.value,item.x,item.y) }) }, 16) }
|
这样就可以愉快地发送弹幕了 (虽然是本地的)