使用了一年多的另一个 SVGA Web 播放器现分享给大家 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
LancerComet

使用了一年多的另一个 SVGA Web 播放器现分享给大家

  •  
  •   LancerComet
    LancerComet 2020 年 8 月 24 日 2949 次点击
    这是一个创建于 2070 天前的主题,其中的信息可能已经有所发展或是发生改变。

    SVGA

    SVGA ( https://svga.io) 是 YY 研发的一套很棒的动画方案,这个方案在公司内大规模使用,因为是一套从设计到研发一套打通的方案,所以效率和整体体验都算不错.

    不过官方的 Web 版播放器使用起来有几个痛点:

    1. SVGA 最初应该没有考虑太多的流程控制,不过现实业务中经常性的是通过多个 SVGA 组合进行逻辑动画播放,比如 A 播 XX 帧之后再播放 B,然后再播放 C ;或者 A 原地 n 到 m 帧循环,用户点击后跳转到 p 帧播一次;官方的 API 在处理这个情景上不是那么自然,当场景复杂了之后需要写额外的封装处理.

    2. 官方播放器提供了多种缩放模式,但使用起来有些别扭,而且没有办法使用 CSS 样式控制舞台尺寸,当使用 CSS 设定宽高时舞台内容会出现没有规律的奇怪变形,灵活性稍微差了点,我们平常使用 CSS 的 scale 来处理.

    3. 某些版本的 IOS 平台会发热(现可能已修复)

    针对以上问题,去年年中的时候就决定重新编写一套新的 SVGA 播放器给内部使用,希望能够解决上面三个问题。经过一年多的修改和生产环境验证,目前个人认为可以分享出来和使用 SVGA 的朋友一起使用(说来也巧,官方的 Lite 版播放器差不多也是这个时候开始编写,有点撞车)

    处理痛点

    问题 1

    针对第一个问题,我们假设一个场景:载入一个 SVGA 文件后播放两段动画,第一段先播 10 帧,然后播放完成后再播 10 帧

    // 官方 SVGA Web 播放器播放两段动画. const parser = new SVGA.Parser('#stage') const player = new SVGA.Player('#stage') player.onload('/file.svga', videoItem => { player.setVideoItem(videoItem) let isSection2Played = false player.onFinished(() => { if (!isSection2Played) { playSection2() isSection2Played = true } else { console.log('done') } }) playSection1() }) function playSection1 () { player.startAnimationWithRange({ location: 0, length: 10 }) } function playSection2 () { player.startAnimationWithRange({ location: 10, length: 10 }) } 

    我们实践下来当业务复杂时,需要外层再写一层封装来帮助进行流程控制,否则会比较别扭,要手工使用变量维护播放状态.

    对于业务来说,个人理想中的 API 应该是类似这样:

    // SVGAPlus 播放两段动画. import { SVGAPlus } from '@svgaplus/core' const player = new SVGAPlus({ element: document.querySelector('#stage'), buffer: await SVGAPlus.loadSvgaFile('/file.svga') }) await player.init() await player.playOnce(0, 9) await player.playOnce(10, 19) console.log('done') 

    将状态控制保持在播放器内部,使得业务在使用时无需自行维护一套状态,同时 API 应当保持一种形式同步,来消弱心智负担.

    问题 2

    针对第二个问题,其实不需要做什么特殊处理,也不用提供缩放 API,舞台( Canvas )的缩放让业务方在外部直接使用 css 进行设置,这样行为和 是完全一致的,毕竟对于切图仔来讲图片的 css 样式是刻在基因中的,设计其他 API 反而有点复杂.

    <!-- 直接使用样式表控制尺寸才是追吼的. --> <canvas width="1200" height="1800" style="width: 300px"></canvas> 

    问题 3

    针对第三个问题,最早遇到这个问题时个人在业务中复写了 requetAnimationFrame 方法,在 IOS 平台下限制执行频率来降低手机发热;当自己在编写这套新的播放器时,用于控制绘制的 Ticker 本身可设定帧率,所以原本打算使用这个特性为 IOS 做限制,但使用下来发现就算使用满帧率绘制也没有发生严重的发热问题,所以应该是官方某个版本中有些小问题,现在应该已经修复了吧.

    其他的呢

    Worker Parser

    我们在业务中发现当页面足够复杂时,页面其他逻辑加上 SVGA 的初始化逻辑可能会使得界面阻塞,所以对 SVGA 的 Parser 加入了 Worker 支持,将吃资源的初始化逻辑放入 Worker 中执行来保证主线程通畅. 这个特性是可选的,因为 Worker 会增加一些初始化时间,在简单的页面中依然可以使用主线程进行解析来保证加载速度.

    Pixi Renderer

    我们后来加入了一个叫做 PixiRenderer 的模块,使用 Pixi.js 代替原生 Canvas API (个人称之为 VanillaRenderer) 进行渲染,这样就得到了 Pixi 的所有好处,比如 WebGL 加持、自定义 Shader 、滤镜、叠加其他 Sprite 等特性,给胡乱瞎搞打下了坚实的基础.

    import { SVGAPlus } from '@svgaplus/core' import { PixiRenderer } from '@svgaplus/renderer.pixi' import * as Filters from 'pixi-filters' const player = new SVGAPlus({ element: document.querySelector('#stage'), buffer: await SVGAPlus.loadSvgaFile('/file.svga'), renderer: PixiRenderer }) await player.init() // Pixi 的 App 和 Container 可以这样访问: // player.renderer.pixiApp // player.renderer.pixiContainer // 瞎搞个滤镜瞅瞅. player.renderer.pixiContainer.filters = [ new Filters.RGBSplitFilter() ] player.play() 

    更多的信息

    官方播放器给的信息有时候不够用,所以这次将更多的信息暴露了出来.

    SVGAPlus

    个人起名为 SVGAPlus,只是希望解决一些问题,毕竟平平淡淡才是真,解决问题才算好.

    欢迎大家一起贡献: https://github.com/SVGAPlus/SVGAPlus

    请注意

    SVGAPlus 没有实现 SVGA 的一些特性,比如音频播放,因为我们在播放音频 + 视频的场景都是直接使用 .mp4 ,个人也比较推荐使用视频这样的通用做法.

    3 条回复    2020-08-25 11:00:55 +08:00
    LawlietZ
        1
    LawlietZ  
       2020 年 8 月 25 日
    不错
    LawlietZ
        2
    LawlietZ  
       2020 年 8 月 25 日
    话说这种可以实现透明视频,svga 是新格式吧,该怎么导出呢
    LancerComet
        3
    LancerComet  
    OP
       2020 年 8 月 25 日
    @LawlietZ 是可以实现透明效果,SVGA 本质就是一堆 PNG / SVG 然后再加上帧信息,通过 AE 做完之后使用插件导出 https://svga.io/designer.html
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1402 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 38ms UTC 17:05 PVG 01:05 LAX 10:05 JFK 13:05
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86