01 浅谈创端业务
B站创作端承载了稿件生产的职能,而创作工具是稿件生产的首个环节,承担了Up主最重要的丰富视频内容、提高视频质量的职责,创端提供了基础剪辑能力、智能成片、AI玩法、视频模板等生产工具,适用于不同剪辑场景,服务于不同创作能力的Up主,帮助Up主锦上添花,并持续提升有消费价值的稿件量。
对于剪辑上层业务层而言,有工具品类之分,对于剪辑底层,则会拆解成不同的原子素材和原子能力,如视频、音频、图片、字幕、滤镜、贴纸、转场等素材,不同的素材对应不同的属性,不同的属性可以渲染出不同的效果,如字幕包含花字、动画、气泡、字体、字号等效果。而这一切效果的呈现,都依赖了更为底层的剪辑引擎内核。
02 为什么要接入自研剪辑引擎
长期以来,B站创作端的剪辑引擎采购自第三方,随着上层剪辑业务的迭代,我们也发现了一些问题
1. 第三方引擎缺少定制化,由于时间线模型固定,可以描述的剪辑内容有限,业务扩展性受限
2. 第三方引擎的技术支持粒度不够,响应不够及时,B站、必剪、星辰三个app的剪辑问题都会集中给到友商提供的一个研发身上,问题答疑和解决受限,由于是线上沟通,经常因为难复现而搁置
3. 第三方引擎的采购成本,由于B站、必剪app需要各自按年付费,且一些功能需要额外采购(如HDR),公司每年就存在一个固定的支出
针对以上问题,公司决定自研剪辑引擎,来解决现有引擎存在的问题,提供更多的自由度、更高的开发效率、更低的沟通成本,虽然短期会增加研发成本投入,但长期来看,随着剪辑业务矩阵的增加,边际成本趋近于零
03 接入遇到的挑战
前几年伴随着互联网的野蛮生长,为了实现业务快速更迭,技术上做了很多妥协,比如为了减少对业务的影响,快速上线,存在很多AB实验,类似的页面相似的引擎调用通过CV实现,导致存在多套类似的代码。部分对代码设计有自我约束的同学,封装了一些管理类,但由于需求的局限性,又很难被其他模块复用。诸如此类问题,我们整理了如下情况
● 业务侵入严重,由于此前只有一套引擎,业务上很多地方直接调用底层api,分散裸调API 3007处
● 缺少体系化的封装,各种剪辑Utils类,Manager类层出不穷,共15个,业务穿透调用明显,需要进行整合
● 缺少引擎生命周期的统一管理、每个业务自行初始化和销毁,第三方引擎实例是单例,存在多业务调用时销毁与创建不协同导致异常case
● 再接入新的自研引擎后,如何保证第三方引擎生产的草稿能在新引擎下正常打开,对于用户而言,需要能无感切换
● 本次引擎改造涉及业务品类12个,原子能力150种,底层API 3000+,怎么对齐每个api的效果、怎么实现引擎切换、怎么降低业务影响是必须要解决的问题
鉴于这个需求涉及业务之广,改动影响之深,我们决定分期开发、分模块灰度
● 一期:粉创业务引擎调用改造
● 二期:主编辑器接入自研引擎/草稿支持升降级
● 三期:支持封面编辑、拍摄、AI故事、王者战报灰度自研引擎
● 四期:支持动态、会员购、小游戏、一键投稿灰度自研引擎
04 架构设计
针对以上所列问题,我们要接入新的自研引擎,就必须对现有引擎调用重新设计,考虑到如下三个方面
● 可扩展性:首先我们需要抽象出一套接口层,和原有剪辑引擎api一一对应,便于业务引擎的调用改为对接口的调用,实现业务和具体引擎能力的解耦,这样我们就可以根据不同的业务场景注入不同的剪辑引擎内核
● 可管理性:我们需要将原有的剪辑操作进行聚合,模块化,根据功能模块进行封装,如字幕相关的操作从原来的xxxUtil、xxxManager整合到CaptionTrack里,便于不同业务统一调用
● 可控性:由于涉及到的业务场景较多,我们需要先小范围的去灰度,并对重要技术指标和业务指标进行监控,当各项指标符合放量预期后,我们再进行其他业务场景的灰度和放量,这样能保证对线上业务无损或尽可能低损替换
于是,就有了新的业务层引擎架构设计
05 业务改造
在设计完新的业务引擎架构后,我们首先在重编辑场景的主编辑器场景落地,因为主编辑器有着最全的引擎api调用,最复杂的剪辑业务关系,这里梳理接入好,其他业务场景则可以更方便快捷地复用封装好的剪辑功能模块
主编辑改造前:
● 此前裸调第三方剪辑SDK,业务直接持有第三方引擎
● 职责不分明,主编辑器定义了StreamingVideo来充当引擎管理,但其他业务没有用到这个类,功能不全
● 调用比较混乱,没有唯一可信数据源,轨道的操作各自实现了一个很薄的Engine,然后单独去操作timeline或者timeline的一个包装类
主编辑改造后:
● 业务不关心具体的引擎,通过接口去操作剪辑能力通过UpperVideoEditEngine创建指定引擎
● 具体api操作收敛到各自xxxTrack里,不同业务可复用
● 删除多余的Engine层,由UpperStreaingVideo来管理
一期主编辑器引擎架构改造的同时,也有其他主编辑业务需求的并行迭代,为了减少代码合入的成本,一期需要先合入上线,底层引擎内核使用的还是原引擎,这也降低了对用户使用体验的影响,同时保留了引擎内核替换的可能
随着一期的上线,二期替换底层为自研引擎,更多的工作重心放在了api的兼容性适配、引擎内核切换,那怎么实现原引擎和新引擎的切换呢?
Step1:通知灰度管理刷新当前灰度状态,并刷新各业务Scene持有的引擎类型
Step2:通知引擎构造业务对应的剪辑管理类
Step3: 获取并返回业务Scene
Step4:引擎检查 | 切换 | 销毁 | 创建
Step5: 得到当前业务的剪辑引擎管理对象:UpperStreamingVideo
在完成主编辑器和各业务场景支持引擎切换后,还有一个重要的点,即原来第三方引擎生产的草稿怎么在新的自研引擎上正常打开
Step1:获取草稿里所有素材类型及素材id
Step2:根据素材类型、素材id、引擎类型去素材中台请求新的素材信息(包含下载地址)
Step3: 下载新的素材
Step4:回填新的素材地址到草稿
Step5: 适配新旧引擎的数值(如字幕坐标系、旋转角度、字幕模板结构的兼容等,过于细节就不一一介绍了)
06 可观测
在架构设计章节我们提到了可控性,引擎上线表现如何,是否可以灰度放量、是否需要回滚止损,需要有数据支撑,先定量后定性,由于这是一个技术需求,技术指标必不可少,如卡顿率、导出成功率、导出速度、APM指标,而决定这个自研引擎是否可以放量并替换原第三方引擎,我们最终看的是业务指标,技术终究是为了驱动业务更好的发展,那业务指标更多的是关心转化率,我们梳理了几个关键链路的转化率: 主编辑器的转化率、发布页的转化率,为了后续更好的细分转化率影响因子,我们会分维度建立转化率可视化看板
建成后的部分指标看板:
上线后,逐步放量,由于前期数据量较少,自研引擎的投稿转化率一直要好于第三方引擎,但在放量到20%时,我们发现自研引擎的投稿转化率比第三方引擎低近2个百分点,需要去分析下钻影响转化率的因子
-> 从整体转化率开始,我们发现转化率折损主要在主编辑器内
-> 而主编辑器主要是普通编辑器模式和智能成片模式,智能成片模式转化率较低些
->而智能成片是一种使用模板进行一键成片的业务,模板主要由不同的素材如视频、字幕、贴纸、转场、滤镜组成,于是我们对素材纬度的转化率进行分析
-> 发现一些使用了mp4视频的转场转化率较低,原因是这类转场文件较大,容易导致卡顿,另外某些场景下转场的overlap没设置对,导致交叠转场不生效,于是我们对着两个case进行优化
-> 视频预览的卡顿率和投稿转化率明显成负相关,卡顿率越高,转化率越低,于是我们对素材纬度的卡顿率进行下钻分析并定向优化
-> 另外我们还引入了组合纬度贡献度来自动分析出异动指标,就可以直观看到是哪个版本哪端的哪个业务导致转化率大盘出现明显差异
在经过定向优化后,自研引擎在崩溃率、Timeline初始化耗时、预览首帧耗时等方面已经优于原第三方引擎,且投稿转化率已经稳定高于第三方引擎了0.1pp,已进一步放量至50%,后续我们会继续配自研引擎团队,持续优化自研引擎性能和体验
07 结束语
从项目立项到支持所有业务模块灰度新引擎,创端团队和多媒体团队历时近一年,由于所有接口层要对齐第三方引擎,而第三方引擎实现又是黑盒,很多api只能按效果猜测着实现,边开发边查漏补缺,为了保证业务调用方式的对齐,自研引擎也做了设计上的妥协,如异步改同步。同时测试团队也前置介入原子能力的多轮摸排测试,及时发现问题,多个团队的协作鏖战,保证了这个需求的稳定上线,此间不易不胜枚举。
立足于B站生产的广受用户喜欢的内容,我们不断丰富特色素材库、剪辑智能化、提升创作灵感、开发更多易用的工具品类来降低创作门槛提供,我们仍将致力于打造好适用于B站的剪辑工具,帮助更多的用户成为UP主。