在官网加一个视频 -- 小短文

1,615 阅读5分钟

我们做官网有时候会要求做视频播放,这时候我们需要注意一些问题,绝不是我们想的 放一个video标签 里面加src就可以的

经过我的研究 我发现视频播放器和页面渲染 色彩解析会有偏差 比如说你用一个灰色的视频 这时候 rgb比如是220, 220, 220, 但是渲染的时候 这个颜色和你的硬件设备有关系

这个偏差用户可能看不出来,但是,如果这是一个背景,视频只是其中一个区域,页面也是灰色 220,220,220. 用户就可能发现,怎么有一个断层。

你在开发的时候可能遇到不了,因为你发现颜色不对就给改了,这时候你设备没问题,但是其他设备就不一定了,比如你用windows开发,等你好好欣赏你的作品,等发布后,老板打开Mac一看,这什么鬼 一个纯色区域怎么有一个断层,你就收到了一张毕业证。

你想这简单啊,你判断mac电脑,就用不同的页面颜色来和视频同步色彩。你又提交给老板,老板打开手机一看。 ? 这什么情况,你又收到一个毕业请求。

于是你又判断设备,iOS设备。。。 然后还有安卓, 安卓可以了 发现华为不行, 华为可以了, 发现qq浏览器不行,这时候你觉得你的职业生涯到了尽头。 你想把video标签改成gif,把mp4用网页在线转换改成gif,然后老板一看 这视频怎么变短了,于是你找个专业的人帮你转换,老板一看 怎么加载这么慢(gif压缩算法比video差)

最后 你求设计师小姐姐能不能不要局部视频 给我全视频算了,可是设计是个外国人,你跟她解释了半天,她无法理解你的意图,你心一横,你成功通过出卖自己的身体获得了一个证明自己的机会。

等你拿到全视频改好了,已经是晚上了,但是你觉得值了,今天晚上的月亮格外的明亮,你依稀可以通过写字楼的落地玻璃看到外面的木棉花和黄花风铃树叶金灿灿得像金子,如果你的人生春暖花开的时候 可能就是这个时候。

修改完成后你拿出手机一看 哎 完美 找老板去了 老板打开iOS一看,怎么动不了? 你吓得赶紧去找原因,之前你在windows也遇到过,你通过加muted属性静音就可以自动播放,现在怎么不行了,你开始打开谷歌找问题,于是你发现 和range有关系,你换一个视频,还是不行,最后看了Video IOS政策 发现可以加playsInline 果然可以,这时候终于完成了,提交。

老板这时候打开ios一看,果然可以,于是打开qq浏览器,怎么有一条线? 再华为打开 怎么全黑了, 你满脸黑线,你已经错了几次了,你没有机会了,在你的卑微祈求下 老板决定再给你一次机会。

你这时候开始认真反思,视频渲染差异,iOS无法播放,qq有奇怪的问题,都是因为video,你下定决心 放弃video,你郁郁的心情再这时候得到扫空,为什么总要依赖别人的东西,要自己做一个播放器,男子汉大丈夫 生于天地之间 岂能郁郁久居人下 你出去抽了根烟回来 撸起来了袖子 开始思考 怎么做 哦 我好像不会写 于是你打开了flv.js插件 查看怎么使用

等你写完了,一看 这货好像也是video播放,你傻眼了。 这时你还不死心,比较辞职可能找不到工作,还有房贷需要还,一咬牙,决定自己写,你觉得理论上无非就是请求然后渲染,请求可以用axios,渲染可以用canvas,这有什么不能做的,于是你写下了 axios.get ... responseType: 'arraybuffer' ... res ... 等下 返回的Arraybuffer你看不懂,你开始百度,开始谷歌,但是没有结果 大家都不会,于是你问chatgpt,他跟你说用video。

你出门抽了一根烟,你开始想起了 你还有很多道友,于是你打开了微信群,开始说问题,发现没人理你。

你走上了天台 你想不明白 你都干了几年前端了 为什么官网放个视频都做不了 你不能原谅自己 也不能原谅大家的冷漠 更原谅不了那么多浏览器开发商 最最原谅的不了的是为什么产品要提出这个需求 你怀着悲愤的心情越过了天台 看到扫地阿姨不让你过

你觉得连扫地阿姨都欺负你 你开始哭了 阿姨吓一跳 小伙子 你这是做什么 于是给你安慰 说没什么过不去的坎 她家还有几栋别墅 但是她还是来做保洁了 工作主要是开心 你就把工作的事情说了

阿姨笑着说 这个简单 我以前也是做开发的 说着就放下手中的扫把 解开扣子 把衣服往后一甩 颇有高手风范得说道 做不了就不做了 你把Video只当一个解析器 然后获取实例 不断获取数据再渲染到canvas上面。

你一想 有道理 这是万能的解法

于是你写下了如下Rect代码

function videoTimerCallback(video: HTMLVideoElement, ctx: CanvasRenderingContext2D, width: number, height: number) {
  if (video.paused || video.ended) {
    return;
  }
  VideoComputeFrame(video, ctx, width, height);
  setTimeout(function () {
    videoTimerCallback(video, ctx, width, height);
  }, 10);
}

function VideoComputeFrame(video: HTMLVideoElement, ctx: CanvasRenderingContext2D, width: number, height: number) {
  ctx.drawImage(video, 0, 0, width, height);
  return;
}
export const VideoCanvasPlay: FC<{ src: string }> = ({ src }) => {
 useEffect(() => {
   setTimeout(() => {
     const video = document.getElementById('video') as HTMLVideoElement | null
     if(video){
       setTimeout(() => {
         video.play()
       }, 0)
       let loop = () => {
         if(!video.readyState){
          setTimeout(() => loop(), 100)
         }
         
         const width = video.videoWidth
         const height = video.videoHeight
         if(width < 1){
           return
         }
         const canvas = document.getElementById('leftCat-video-canvas') as HTMLCanvasElement | null
         if(canvas){
            const ctx = canvas.getContext('2d') as CanvasRenderingContext2D
            let isRun = false
            const run = () => {
              if(isRun) return
              isRun = true
              canvas.width = width;
              canvas.height = height;
              videoTimerCallback(video as HTMLVideoElement, ctx, width, height);
            }
            run()
            video.addEventListener('play', run, false);
         }
       }
       loop()
     }
   }, 500)

 }, [])
  return (
    <Box sx={{
      position: 'relative',
      '& video': {
        opacity: 0,
      },
    }}>
      <video src={src} id="video" muted  autoPlay loop playsInline />
      <canvas id="leftCat-video-canvas" />
    </Box>
  );
};

用的时候 <VideoCanvasPlay src="xx.mp4" />

哎 完美

最后你继续忙碌其他任务去了 一切都得靠自己 再也不记得楼下陪伴你的的黄花风铃树 也不记得设计小姐姐的柔情 你怀着对技术的执着 开始研究新得方案去了

--完--