视频云的web团队是一个偏多媒体前端技术的团队,致力于为客户提供更多创新的场景化云服务,近期我们在视频制作领域中有一些实践经验,我觉得和前端技术以及大会的主题都比较契合,所以非常有意愿来这与大家做一次分享。

我的分享主要分为四部分:第一部分介绍下业务背景;第二部分介绍云剪,这是一个web端的视频制作平台;第三部分介绍微剪,是一个小程序端的视频编辑插件;最后会分享后续的一些规划以及前端的技术挑战。

首先为大家介绍一下腾讯视频云正在大力发展的制作云框架。随着数字化的不断推进,可以看到内容媒体行业云端化、智能化变革已成趋势,制作云是依托于腾讯云强大的直播、点播、视频ai等能力,为行业提供的一体化内容制作分发云服务。包括有云剪辑、云导播、云转推、云媒资等丰富的场景化应用,助力客户实现"采、编、播、发、存"等全链路云化改造升级,提升从业者内容制作分发效率。我今天分享的云剪、微剪是这个大框架中的重要一环。

先介绍云剪,可以看到界面很酷,这是一个web端的在线视频剪辑工具,和Mac客户端iMovie类似,提供音视频剪切、画面调整,添加标题、音乐、字幕、贴片、特效、滤镜、转场等功能,能够满足绝大部分视频非线编需求。

说到视频剪辑,大家一般会联想到原生客户端的软件app,在原生端技术上一般是如何实现的呢,这里我以安卓的流程图为例介绍一下,其他平台基础原理上也类似。

首先对视频需要解封装,提取出视频轨进行解码,并使用opengl绘制画面数据。这是由于视频的后期处理,需要使用到opengl强大的图形渲染能力,便于添加特效、滤镜及更多多媒体元素等。然后将opengl绘制内容进行编码,最后与音频一起封装成媒体文件。这只一个基础原理,在实际应用中当然会复杂很多。

那么在浏览器端如何实现,浏览器原生并不支持编解码这种高级接口,与mediaExtractor、mediaMuxer相对应的倒是有mediaStream,是否能为之所用,整体如何设计?

带着疑问,我分享三个问题:如何渲染视频帧,如上述流程里如何将视频绘制在浏览器webgl中;如何实时操作预览,即如何设计代码架构,做到方便实时预览视频剪辑各种操作;以及分享导出的几种方式。

渲染视频帧的第一个方案,我们可以使用ffmpeg的webassembly版本对视频进行解码,解出yuv数据转rgb再绘制到canvas上,业界也有很多使用这种方案来播放h265编码和flv等不支持的格式视频。有两点需要注意的是:第一虽然wasm性能比js好,但也是软解,每帧需要耗时25-30ms左右;第二需要实现类似浏览器video的音画同步方案,整体会很复杂。

第二个方案是我们正在使用的,在webgl接口中,texImage2D指定纹理是可以接收video对象的,那么我们可以通过离屏video绘制到webgl中。浏览器video是原生硬件解码,性能更好,而wasm的方案只能做到30帧,在视频编辑场景肉眼就能看到并不流畅,加上比较复杂,所以video纹理的方案性价比更佳。当然大家会说也可以使用2d canvas drawImage,但是这不便于我们使用webgl的更多能力。

再来看如何实时操作预览,做过游戏的同学可能会意识到,其实视频编辑软件,和游戏或动画制作工具有一定相似性。都有时间轴序列,拖拽生成实时预览,并有一个主计时器去驱动。我们目前的播放器采用的就是游戏开发的思路,通过操作时间轴实时输入轨道数据,播放器管理调度场景中剪辑对象,最终形成影片序列。

说下最重要的导出,前端是否可以导出,答案是可以的!