前端视频分割术

816 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情

前言

这次就不放开头图片了,这个类型的太难找了,嘿嘿嘿。为什么会出现这种奇怪的需求呢?因为目前公司项目涉及到多个视频融合一起后再播放。但是视频到我们前端这里放的时候又希望同时只能看一个画面的视频,害,强人所难。可恶的产品经理!!

设计方案

思考了一段时间后,想了两种方案,第一个是通过样式隐藏,另外一个是通过canvas一帧一帧的绘制。下面我们就分析一下两种实现思路。

css样式隐藏

个人觉得这个确实有点憨憨的,但是不会产生额外的性能开销。首先我们要在video标签外的包裹一层div,div的宽高要固定好,然后video标签的宽高要设置倍数。这个倍数要看视频如何合成,比如我这里是三行两列的融合形式,那就设置宽两倍。那后续如何切换画面呢,这里需要js配合,当我们点击按钮的时候判断当前点击的是第几个画面,下一个画面计算好位置,通过document.xxx.style去修改视频的定位,这样可以实现伪视频切割,虽然方法很烂,而且不能自适应画面,但是好处是没有额外的性能开销。

canvas绘图

我个人是倾向于这个方法,因为使用起来会很舒服。那如何使用这个canvas来绘制呢?首先我们还是要video标签去加载我们的视频,然后需要一个canvas标签来加载我们的绘制画面。接下来第一步要获取到视频的节点信息

<video src="./aaa.mp4" id="video" width="720" height="600" controls></video>
let videoEle = document.getElementById("video");

第二步要获取到canvas标签的节点信息

canvas width="960" height="600" id="myCanvas">1</canvas>
let canvasEle = document.getElementById("myCanvas");

第三步我们要通过canvas的getContext获取上下文信息

let cav = canvasEle.getContext("2d");

第四步我们要知道融合的视频原始的宽高,这里要注意我们通常会给视频设置一个宽高,但是这个宽高并不是视频的本身宽高。知道原始宽高是很重要的一步。

第五步开始绘制视频

function draw() {
        cav.drawImage(
          videoEle,
          0,
          0,
          300,
          200,
          0,
          0,
          canvasEle.width,
          canvasEle.height
        );
        if (!videoEle.paused) {
          requestAnimationFrame(loop);
          return;
        }
      }

因为视频的刷新率基本是20ms一帧,但是不建议使用setIntervel,js提供了requestAnimationFrame来绘制,并且要判断视频是否在播放,在播放才绘制,暂停就不绘制。

最后在监听视频播放的时候添加事件

videoEle.addEventListener("play", draw, false);