腾讯开源的酷炫动画播放解决方案Vap初体验

这篇文章发布于 2021年04月18日,星期日,17:55,归类于 JS实例。 阅读 8361 次, 今日 1 次 13 条评论

 

占位图 封面图 vap

同事在群里有提到Vap,播放炫酷动画的,可以让动画背景透明,就去了解了下。

相关效果大家可以这里体验:https://egame.qq.com/vap

也可以看下面的视频播放效果(不动点击播放):

GitHub项目开源地址:https://github.com/Tencent/vap

原本以为是直接弄个视频就可以播放。

后来查看官方案例,为了让动画背景有半透明特质,元素素材不是视频,而是PNG图片序列。

优点和原理这里有详细介绍:Introduction.md

自己就不赘述,我就已通俗易懂方式,站在初次使用者的角度讲讲这个项目。

一、大致的实现思路

如果是让普通MP4视频,以画布的形式播放,则其实2D canvas就可以,video.captureStream()方法可以返回当前播放的视频流,然后在canvas中绘制呈现。

但是,2D canvas的性能是堪忧的,在移动端,如果画面很炫酷,是带不动的。

此时可以使用WebGL进行播放,视频帧作为纹理贴上去,因为WebGL会启动GPU加速,性能可以的,会非常流畅。

Vap底层就是使用的WebGL技术,所以性能有保证。

然而,上面的方式只适用于图片完全不透明的情况。

如果希望炫酷动画希望是半透明,或者部分区域全透明,则上面这种策略就会捉襟见肘。

有什么办法可以解决半透明的问题呢?

以前我曾提过一个CSS解决方案,就是使用CSS mix-blend-mode中的screen,详见:css-mix-blend-mode-screen

优点是成本低廉,效果显著,性价比极高。

不足在于,只适合炫丽的动画效果,动画主体如果有深色的部分,会被误伤被混合掉。以及只适用于web。

Vap的实现思路是什么呢?

“把透明通道信息藏在视频中,这样解析视频的时候,就能知道每个像素点的透明度了。”

上面这句话大家可能不太理解,我再详细解释下。

github项目页面会看到一个素材制作工具,如下图所示:

vaptool工具

一开始我对这个工具是莫名奇妙,这里选择的不是视频,而是放置图片序列的文件夹。

选择

我一脸懵逼,我这边有大把的视频素材,为何还需要图片序列再转视频呢,这不是秃子梳头——多此一举嘛。

后来明白了,通常的MP4视频中是没有透明通道信息的。

所以需要原始的带Alpha透明通道的PNG图像序列,通过工具,把透明通道信息藏在视频文件中。

随意最终生产的视频播放时候,会多出部分黑白的区域,这个区域就是透明通道信息。

当然除了可以藏透明通道信息,还可以藏遮罩信息,相当于视频镂空,方便显示动态信息。

然后,就可以对素材生成的视频进行解析,让该透明度地方透明,让该镂空的地方镂空。

以上就是Vap的实现思路。

明白了原理,我们就知道,其实PNG图片序列无需合成新视频,我们也可以实现类似的效果,也就是VapTool工具是多余的,我们也可以自己写个Node小脚本,读取PNG图片序列每个像素点(也可以四点合一)的Alpha透明通道信息,放在某个文本文件中。

理论上,也可以直接开发个Web版本的VapTool工具,借助ffmpeg.wasm实现类似的事情,性能上会差一些,关键是免安装,特别适合某些一次性的项目。

别看我,我没有精力开发这样一个页面,除非自己团队业务上有这个需求,我是会顺手做一个的。

最近在连载小说,分身乏术。

二、试用初体验

这工具的使用主力一看就是MAC设备。

必须用windows系统体验一番,验证下究竟好不好用。

  1. 需要图片序列。

    自己找了上周画的每日漫画四张素材,命名为000.png,001.png,002.png,003.png。

  2. 下载 VapTool_Java_Win_Full.zip

    里面有 ffmpeg.exe 还有 Jar 资源,反正就是 Java 使用 ffmpeg 搞事情,mp4edit做编辑执行。

  3. 选择图片序列帧所在的文件夹,然后修改fps为1,结果挂了,失败,换成官方demo的序列图也是失败:

    运行失败截图

    这就有点坑犊子了。

    这错误提示也太没有参考价值了,完全不知道哪里有问题。

    后来搜啊搜,历史有人提过类似的问题,原来是 vcruntime140_1.dll 文件缺失导致,扶额。

    从网上下载了个 vcruntime140_1.dll 文件放在 windows/system32文件夹下,终于跑成功了。

    不过1fps没有作用,每秒1帧貌似不支持,也可能是自己哪里使用姿势不对。

  4. 最后就是根据输出的素材执行了。

    会输出一个output文件夹,里面有一个md5.txt、可以用做文件校验,vapc.json是config配置信息,video.mp4就是合成后的视频(里面包含了透明度通道信息,遮罩信息(如果有))。

    此时下面的代码就可以跑起来了。

    HTML部分:

    <div id="container"></div>

    JS代码:

    <script src="./vap.js"></script>
    <script type="module">
    new Vap({
        container: document.querySelector('#container'),
        src: './images/output/video.mp4',
        width: 454,
        height: 340,
        config: {"info":{"v":2,"f":12,"w":454,"h":340,"fps":24,"videoW":464,"videoH":528,"aFrame":[0,344,227,170],"rgbFrame":[0,0,454,340],"isVapx":0,"orien":0}},
        fps: 24
    })
    </script>

    config参数对象就是复制的生成的vapc.json文件内容。

    页面预览下,会是下图这样:
    测试输出效果

不过上面这个测试案例使用的是完全不透明PNG序列了,后来我又使用官方的PNG图测试了下,也是可以跑通的。

三、可能更实用的价值

后来直接拿了个没有处理过的 MP4 视频过来,发现也能播放。

我就想到,vap.js 也可以作为web视频播放解决方案,Android设备中,以UC等浏览器为代表,这些浏览器播放MP4视频的时候,视频层级最高,自带个播放器,怎么都隐藏不掉,很烦人,可以使用这个处理下。

这个可能比带PNG透明通道播放更实用。

不过为什么加了mp3后,只有画面,没有声音呢?预览地址:https://www.zhangxinxu.com/study/202104/vap.html

大家也可以帮忙测试下看看。

我自己测下来结果是这样:

输出的视频有声音,但是在浏览器中播放,无论是Chrome浏览器还是Firefox浏览器都没声音。

iOS 14 下是有声音的,Android 微信和原生浏览器没声音。

我又陷入了沉思。

H5直播使用video方案的时候,视频层级的问题是个老大难问题,如果vap.js 可以很好地解决音频解码问题,说不定可以有更广阔的应用场景。

可惜自己WebGL这块积累还很薄弱,不然自己可以撸一撸。

WebGL和音视频是今年自己的专业学习重点,会陆续有文章输出。

也欢迎大家反馈比较好的相关实践案例,我会开箱评测的。

最后,求转发,求分享。

(本篇完)

分享到:


发表评论(目前13 条评论)

  1. CodeHz说道:

    没声音是因为以前自动播放滥用太多了,于是要求用户点击后才能有声音(chrome倒是给自家产品开了后门,油管可以自动播放)

  2. sky说道:

    请问,这个框架不能加载url资源,只能加载本地资源吗?

  3. 代码如诗如画说道:

    我用win10 chrome测试的有声音

  4. lin说道:

    Win10 Firefox和Chrome都可以有声音,默认是禁掉了。Firefox就在地址左边就有按钮设置,Chrome也在地址左边,选择site settings

  5. 评论区屌丝说道:

    “因为WebGL会启动GUP加速”。是“GPU”,写错字了。

  6. suifeng说道:

    腾讯的感觉干不过 http://svga.io/ 这个的 这个是专业的动画库

  7. 云鸠说道:

    “因为WebGL会启动GUP加速”
    张老师,这一段GPU拼写错误了😂

  8. kido说道:

    mac 谷歌浏览器是有声音的

  9. Xleine说道:

    有时候有声音,有时候没有声音。。。声音是吃披萨的孙燕姿对吧

  10. vince说道:

    https://github.com/phoboslab/jsmpeg
    这个也是通过 webgl 来实现视频播放,可以解决文中说的「我就想到,vap.js 也可以作为web视频播放解决方案…」这个问题,并且兼容性和性能都不错,比较成熟