对于视频的生产,一般的方案是交由专业机构去创作,但这将花费很多预算,如果我们能提供一个工具,基于知识的通用结构沉淀一些视频模版,让用户快速创作出视频知识内容岂不美哉?让想法再奔放些,如果我们能直接从知识库中抽取结构化的知识内容直接生成视频或是半成品视频,用户只需要稍作调整就能发布,这想想就很酷吧?是的,小蜜视频创作工具我就是想做这样一件事情。本篇分享来自阿里巴巴前端工程师李志成(敦固)在第十六届D2前端技术论坛的分享。
附:第十六届D2前端技术论坛现场分享视频
背景
一、我们为什么要做一个Web端短视频编辑器
阿里小蜜团队负责客服机器人项目,在业务上的需求是根据用户的问题,快速准确的给出答案,从而减少转人工率。
我们发现,图文形式看起来冗长乏味,同时因为文字过多而不易找到重点,尤其对老年人群不友好;相反以视频方式呈现则让内容变得有趣易接受,同时信息密度更高,也更适合老年人群。
当然,将内容视频化也存在制作成本高、制作效率低、专业难上手等问题。
二、如何让短视频制作像做PPT一样简单?
在设计初期的构思:
- 迁移 PPT的使用经验,快速上手;
- 可定制的丰富模板应对不同场景;
- 智能脚本辅助创作;
而简单并且专业的短视频编辑器需要具备以下要素:
- 音视频编辑器的基本能力,包括:时间轴、字幕编排、动画贴纸、转场、滤镜、特效、TTS配音、ASR 语音识别,等等;
- 纯前端实现;
- Web端渲染。
编辑器设计
一、总体架构
如下图所示,编辑器总体架构分为三层,自上而下分别是:应用层、引擎层和依赖层。
编辑器总体架构
- 应用层:可以在编辑器中看到的各种应用,包括素材库、模板库、智能脚本、剧本模型等等;
- 引擎层:包括资源管理器、导演引擎、舞台、渲染器以及服务;
- 依赖层:根据用途大概分成三类,视图、状态管理,动画、特效,音视频处理;
二、编辑器的设计
编辑器的设计首先从编辑器的输入输出考虑。如下图所示:
在编辑器之上,用户上传素材到编辑器进行拖拽、配置、编辑、播放等一系列操作,最后进行渲染输出视频,在这个过程中输入素材输出视频;
在编辑器之下,当用户上传素材对应得到素材的资源描述,并对素材进行加载、解析、缓存。当用户进行编辑时,对应下面的剧本模型编辑;当用户点击输出视频时,对应下面的剧本协议解析,并渲染生成动画。
三、剧本协议的设计
剧本协议是一个非常复杂的套娃结构。
四、以撤销重做功能为例谈变与不变的取舍
在编辑器设计中,选择采用可变数据结构,还是不可变数据结构,从下图的对比可以看出两种方式都各有利弊。鉴于前端会比较倾向函数编辑,最终选择快照式Immutable方式,使用Immer解决对数据结构的高效操作及编辑。
针对快照式的问题可以通过数据结构优化来解决,比如复用没有发生变化的节点,就可以有效节约内存。
编辑器的实现
一、编辑器工作流
如下图所示:左边是渲染器和编辑器,由编辑器提供的AudioStream和VideoStream作为渲染器输入合成视频;
右边最上层是资源管理器,进行资源加载、解析和缓存,舞台基于Konva和Canvas供用户进行拖拽、配置、编辑等操作;
最下层是起核心主导作用的导演引擎,它将脚本模型发送至资源管理器进行资源预加载,然后支持整个舞台运作。
二、导演引擎
从输入输出的角度出发,导演引擎的输入是剧本,从剧本协议中读取剧本后将其中的元素进行排序,并加入segments队列,发送队列至资源管理器进行预加载。当用户点击播放时,内部时钟会不断触发检查元素的入场和离场时间并发送至舞台。这其中对内部时钟的精度要求非常高,尤其是音频,因此选择浏览器中的音频处理器Web Audio API,它提供了理想的外部时钟和一致的时间序列,并通过AudioScheduledSource Node触发。
三、音频的处理与渲染
音频的处理和渲染有以下三个步骤(下图):
1、解封装
把容器里压缩过的音视频流拆出来
音频:AAC/MP3/AC-3/...
视频:H.264/H.265/MPEG2/...
2、解码音视频码流
从压缩的编码中获得视频的像素数据和音频 PCM 数据
音频:PCM
像素:YUV/RGB
3、渲染与音视频同步
将像素数据转为WebGL纹理绘制到Canvas;
将音频原始采样数据 PCM 发送给WebContext.AudioWorklet播放;
根据音频的播放时间来挑选视视频帧并绘制,保证音画同步。
以上步骤中的①和②如何在Web中实现?
传统的方式是使用FFmpeg+WebAssembly,步骤如下:
- 根据实际需求对 FFmpeg 进行裁剪定制;
- 编译FFmpeg到WebAssembly;
- 浏览器加载调用;
这个方式固然可行但也存如占用内存空间、加载成本等问题。
在考察浏览器如何解析和播放视频时发现,在HTMLMediaElement的架构下使用的就是FFmpeg,同时chromium库里也有FFmpeg,是否浏览器已经开放这些能力共享呢?
W3C提供的WebCodecs API就是这样一个可以解决Web端编解码音视频的工具。
在第二步解码使用WebCodecs API,其优势在于不但提供了视频音频解码器,还有图像解码器和视频音频编码器。但唯一的问题是WebCodecs没有提供相应的解封装API,这就需要借助MP4Box.js/mux.js/ffmpeg 之类的工具拿到原始编码数据。
四、渲染出片
渲染包括视频渲染和音频渲染。下图右边部分展示了常规的渲染出片流程。
音频渲染可以通过AudioContext创建MediaStreamDestination节点,将音频文件整合到这个节点上,然后采集所需的AudioSteam。
视频渲染是在Canvas上按一定的帧率捕捉得到VideoStream,将VideoStream和AudioStream输入到MediaRecorder API中,生成webm格式视频,再转换成mp4格式。
常规渲染出片流程
由于WebCodecs也同时提供音视频编辑功能,因此可以代替流程中的new MediaRecorder,编辑解析后经过分装然后,直接输出需要的格式视频。
使用WebCodecs API的渲染出片流程
浏览器实现的问题与挑战
Web上已经具备音视频所需的所有能力,包括提供动画、特效能力的WebGL,提供音视频处理能力的WebCodecs、FFmpeg,以及WebAssembly,因此在浏览器实现音视频编辑是可行的。
如果作为专业的音视频编辑器,浏览器实现的问题和挑战有以下方面:
一、文件处理
尽管使用dexie.js通过indexDB 存储但视频文件和素材通常很大,所以目前的方案仅适用于短视频的创作(60s左右);
解决方案:可以通过能直接访问系统的API,如File System Access API实现对于大文件的编辑,在未来是可以解决的。
二、长视频的渲染
MediaRecorder的方式出片需要和视频一样时长的等待,长视频则会消耗用户大量的等待时间。
解决方案:将长视频拆分,或采用异步处理端侧渲染,FFmpeg录制浏览器拆分渲染再合并。
三、更多格式的支持
需要找很多demuxer、muxer库,但是在W3C没有提供更多可复用API的情况下,可以使用FFmpeg转存WebAssembly的方式。
综上所述,在Web端的音视频编辑器是可以实现的,在未来,编辑器会有更多机会和优化空间,可以真正实现像做PPT一样做视频。