开发遇到棘手的难题该怎么办?

1,522 阅读6分钟

概述

本文主要讲的是笔者近期遇到一个难题,从遇上,到尝试各种方案,踩各种坑,最后解决的心路旅程,供作参考借鉴。

前文

我们的产品是一个工具类软件(使用nwjs的桌面应用),用户可以提交自己感兴趣的链接,我们去帮忙采集里面的视频。

最近一个用户常使用的一个网站上的视频加了非常严格的水印(动态位置,从左到右移动的水印,而且还是很多个水印)

类似这样:

demo.jpg

在检查了视频链接无法逆向到无水印视频的链接之后(视频链接是一个UUID),就有了本文。

笔者技能介绍

一个前端,自认为编程基础还行,写过JAVA(crud boy)。

第一步

一开始,毫无疑问,我当然是跟产品说,不行,这个做不了,去水印不现实。不过,链接里面不是有图片么,我们自己把图片合成视频,你觉得这样的降级方案怎么样? 经过一番激烈讨(si)论(bi),产品勉强同意了。但是,需要我在图片上做一些动画效果,例如图片之间的动画图片什么的,不能单纯一张图片静止不动播放几秒。

为了省钱且开发时间赶(线上急着用),我首先尝试了有没有方案能在前端直接生成视频,结果还真的有~

Whammy 这个库能将你的canvas动画转成webp(视频格式的一种)

他的原理其实就是将canvas逐帧保存到webp,最后将一组webp转成webm格式的视频)

我很快就把canvas动画写好了,然后逐帧保存,嗯,就这样搞定了~写的时候还是很easy的

但是嘛~~~缺点就出来了,速度实在是太特么慢了,视频体积也太特么大了。

在当时至少也勉强解决了一点问题,给部署上去了(又不是不能用.jpg)

第二步

前面的方案部署上线之后,我便立刻开始了优化之路,经过一下午的摸索,我发现………………这玩意没的优化空间,撑死就是把canvas动画改成webgl渲染,渲染速度快一点。

但是上面说到的两个缺点跟动画渲染速度没啥关系,把一帧动画转成webp的速度实在是慢到令人发指,最后的webp转成webm的速度也是无法忍受,最最无法忍受的是还极度吃CPU和内存。

所以,我很快就放弃了优化方案,准备重构!既然你JS速度这么慢,C++速度快啊,我用C++写不就行了嘛~自己写一个c++扩展,再打包成nodejs原生模块。

emmm,听起来似乎可行,但是,我没写过C++啊!(只在菜鸟教程上看过C++入门)

自己从0开始写是不太现实的,所以借助了搜索引擎,

先看了看C++通过图片转成视频的方案(从stackoverflow上扒了不少代码),又看了一些nodejs原生模块的教程,又看了FFMPEG,嗯,这个好强大!

一番血和泪,最后把拷贝出来的代码修修改改,使用了freeImg 打开图片,进行图片操作,逐帧编辑操作,最后调用FFMPEG合成MP4导出,

当然了,把这个C++最终编译到nwjs客户端上去执行,也是踩了不少坑。

到这里,还是存在一个致命问题,懂图像处理的同学到这里是不是发现一个问题了,没错,由于我的弱鸡,我没有用到GPU!!!这样重构出来的性能并没有比原来的方案提升太多,还是没有解决问题。

到这里,我已经快熬不住了,功能性能好歹是优化了一些,先上线吧。

第三步

后面其实一直想的是把C++改成调用GPU去实现,但是一直没时间,而且中途有统计过我们用户电脑的配置,大部分用户的电脑都没什么独立显卡……

而且不少用户都不满意这种降级方案的实现……

早在第一步的时候我就跟产品说过视频去水印的可能解决方案,深度学习标记出视频水印位置,然后使用水印原图的差值叠加的方式去水印,嗯,理论上是可行的。但是,我们团队只有一个前端和后端啊, 上哪去给你生出一个会深度学习的!

迫于产品天天给我压力,我开始去了解一些深度学习的方案了,不看不知道一看吓一跳。

似乎好像没有想象中那么难,深度学习框架都已经封装的那么完全了,似乎不懂深度学习的人也可以调用框架来训练自己的模型?

到这里的时候,其实我已经跟产品夸下海口了233333

根据网上的一大堆教程和介绍,最后决定选用tensorflow object detect api,使用官方提供的预训练模型,花了两三天终于把tensorflow-gpu版本下载了下来, 又花了几天跑了官方demo和别人开源训练好的模型,嗯,可行!

期间最痛苦的事情是自己标了几十张图片,太折磨人了。。

公司电脑显卡不太行,我拿了自己的战神笔记本1060跑了好几天,终于!!!!

用opencv调用训练出来的数据模型,识别水印位置,进行修复,保存到一个新视频里,再使用FFMPEG将音频合过来。

圆满解决了问题了。

后续

由于涉及到产品隐私问题,就不提供代码和示例了~

整个过程中,给我帮助最大的是谷歌,github,阅读英文技术文章的能力。遇到问题就谷歌一下(强烈推荐英文搜索!!!),查找解决方案,

想了解/使用一个技术框架/第三方库的最好的方法是上官网看教程,到github看issue,都找不到就看看下源码吧,说不定就有思路了。

不要把自己局限在某个技术范围上,敢想敢做233333

受限于文笔和技术水平,写的可能不是很好,如果错误请指出。

我的github blog,欢迎watch/star~~~ github.com/zuluoaaa/bl…