技术人看《长安十二时辰》的正确姿势是?

技术人看《长安十二时辰》的正确姿势是?
阿里妹导读:从“叉手礼”、“水盆羊汤”、“酒晕妆”这些唐朝人的生活细节,到精美的坊间造型、充满意境的诗词歌赋,《长安十二时辰》不仅以缜密剧情赢得赞誉,更还原了一个真实的大唐长安。在精良制作之上,技术人如何让观众感受1000多年前的长安风情、更深度的理解剧情呢?今天,咱们揭秘《长安十二时辰》背后的酷看体验,解读技术人看剧的正确姿势。

想必细心的观众已经发现,《长安十二时辰》中出现了很多有人情味的“黑科技“,比如百科Tips、角色伴侣、剧情进展图等,让用户“边看剧边互动”,这就是优酷的酷看模式。酷看模式在移动端采用了多路流的同屏展示、智能平滑切换、精准同步和动态化渲染等技术。其中动态化渲染、子母屏和多路流同步播放是酷看模式在端侧的核心能力,能够做到多路流、多机位视频帧级同步播放。本文接下来要讲一讲和《长安十二时辰》相关的背后的一些核心技术。

播放器业务框架

这里必须要提一下优酷的播放器业务框架,该框架以一个简单而优雅的模型解构了所有的播放器业务,我们称之为OnePlayer,通过技术架构的解耦带来了与之相关的技术团队的组织架构的解耦,很好地适应了优酷复杂的播放业务场景,在该框架下酷看的功能其实是由一组彼此独立的插件组合实现的。

播放器视图模型

技术人看《长安十二时辰》的正确姿势是?

如上图所示,该模型可以用简单的几句话加以描述:

  • 播放器由多个层组成
  • 层容器中布局插件
  • 播放器发布消息
  • 插件订阅消息
  • 层和插件信息来自配置文件

核心特性

该框架在设计之初就确定了一系列的优良特性作为设计目标,这些特性为我们后续实现酷看模式带来了极大的便利。

  • 基于消息,事件驱动:引入发布/订阅的消息机制,插件按需订阅播放器的事件,根据优先级响应和消费消息。
  • 插件结构,互不依赖:将所有的播放功能及业务模块解耦为彼此独立的插件,插件之间以消息机制进行通信。
  • 按需配置,*组合:支持从xml配置文件加载层和插件的配置信息,各个业务方在接入业务框架时以搭积木的方式排列组合业务模块构造播放器。
  • 插件丰富,支持扩展:框架会提供一批功能丰富的标准插件,业务方可根据自己的需求定制插件来替换默认实现,也可以新增插件。
  • 多例共存,彼此隔离:即可有多个播放器在一个页面内同时运行,并且从不同的配置创建。

技术升级赋能业务开发

| 技术架构开放化

以插件的形式隔离和封装不同的业务,清除业务之间的显式依赖。基于新的业务框架,业务方一方面可以将标准插件排列组合创建个性化的播放器,尤其是一些基础插件避免重复劳动;另一方面可以自定义新插件替换默认实现或者添加新业务插件,技术框架层面上支持业务团队独立完成播放器一整套的个性化定制。

| 业务开发标准化

在该播放器框架下,业务插件的顶层设计是统一的、标准化的。包括一致的构造函数、一致的创建过程、一致的生命周期、一致的播放器事件响应机制等。对于不同团队业务代码之间的相互理解和跨团队统一作战都有极大的优势。在标准化的过程中,更容易产出一些通用插件被更多的业务所复用。

| 播放能力服务化

播放服务与播放业务边界逐渐清晰,彻底结束业务代码与播放能力代码犬牙交错的局面,彼此松绑,并行前进。播放服务内聚收敛具备了向OTT等业务类库级输出的可能性。

二、酷看百科

顾名思义,酷看百科主要是在视频播放过程中给出一些类似百科的辅助用户观看的介绍性内容。例如剧中通过酷看百科说明“时辰计时制”和现在“24小时计时制”的对应关系,时辰制是看懂该剧的关键要素之一,无法理解各个时辰对应的时间自然也就无法体会剧情的紧张节奏。

技术人看《长安十二时辰》的正确姿势是?

技术特性上的需求来自两个方面:

  • 面向运营,运营希望有一个常态化的运营工具,简单的通过运营后台修改配置就完成投放,无需技术同学辅助,也不需要发版本;
  • 面向用户体验,产品希望能够根据用户的偏好和视频的内容做到UI风格多样可动态调整的展示,能够较好的与内容融合。

核心点

为了实现“动态化的内容投放和播放模式切换”,就必须解决两个具体问题。即:

  • 播放器如何进行不同播放模式的切换
  • 端侧采用什么技术来实现动态化的投放

对于问题1,我们将百科相关的业务也作为一组插件来实现,并且对播放器的业务插件进行了分组,利用了业务框架的插件管理器的基础能力,能够动态的启用和禁用不同组的业务插件。

对于问题2,我们采用了阿里开源的Weex来实现UI动态化渲染,无需发版即可实现动态化布局,再结合后端的定投能力,就能够实现按照不同样式模版来动态的投放组件。

技术人看《长安十二时辰》的正确姿势是?

三、酷看子母屏

子母屏是酷看中使用较多的一种形态,所谓子母屏就是将设备区域划分为两大部分,同时投放多屏内容,较大的占据主视频焦点的区域称为母屏,一般用来播放正片;侧边的占据较小的视频区域称为子屏,一般用来投放与正片内容相关的辅助或者互动性的内容,这有点类似电视在直播比赛时在画面里引入场边的教练采访画面或者简要的赛况数据。

分离母屏和子屏的资源

按照以往的做法会直接将要在副屏中展示的内容通过后期制作以合流的方式直接压入正片视频流中,不过在《长安十二时辰》中我们没有采用这种方式。因为这种方式的缺点还是相对明显:

  • 对用户不够友好,难以按照用户的偏好智能投放
  • 对制作不够友好,互动资源和正片资源直接耦合
  • 对运营不够友好,严重依赖后期制作无法独立运营
  • 对商业化不够友好,内容广告和媒体资源直接固化

以上缺点的根本就在于合流的方式导致相关内容以一种较为粗放的固化的方式投放给观众,无视观众的偏好;同样也无视了多层次精细化的运营需求,这种绑定关系一次性消费掉了好内容。我们围绕这个问题展开工作,分离母屏和子屏的资源,即不再需要在制作时合流而是让正片内容和运营内容严格分离分开存储和投放。副屏的内容投放将完全交由运营同学来完成,运营同学从模版库中选择相应的模版即可快速预览和投放,不再依赖后期制作。

技术人看《长安十二时辰》的正确姿势是?

以上即为《长安十二时辰》中的一处子母屏投放效果,左侧母屏为该剧集的正片,右侧副屏是我们投放的张小敬所穿服饰的视频介绍,丰富用户的观看体验。

核心点

我们这里只讲一个较为核心的点即播放器双屏容器,双屏的内容投放是彼此分离的,它是我们后续各种玩法的载体。

| 播放器双屏容器

对于双屏容器有一些具体的特性要求:

  • 母屏的缩放尺寸能够根据不同的屏幕宽度和视频资源宽度自适应;
  • 子屏同母屏一样具有交互性,能够响应用户的手势;
  • 母屏缩放和子屏移入的动效同步。

设计师给出了母屏和子屏可以相互交错叠压的酷炫方案,甚至还有延伸至背景的异形遮罩效果,对于动效同步的要求也较高。为了解决缩放适配问题,我们写了一套自适应的容器布局算法,能够基于服务端下发的配置和视频的尺寸计算出最终子母屏容器的布局模型和动效参数,然后再根据这套模型驱动渲染视图以达到预期效果。

双屏想要具备交互性响应用户手势主要的阻碍在于Z轴上有覆盖在视频层上的诸如弹幕等其他的遮罩层会拦截掉系统的触屏事件,为此我们设计了OnePlayer手势插件作为触屏事件的代理,由这个代理按照优先级转发手势事件相关的订阅者,这样就突破了视图层级对手势的限制。

副屏的互动性作为通用能力,也被使用在其他的头部节目中,例如在《这就是街舞2》中观众可以边看街舞边给支持的选手投毛巾。

技术人看《长安十二时辰》的正确姿势是?

四、双流同步播放

在解决了子母屏的自动布局和交互性问题之后,用子母屏来承载双路流的视频同步播放则是更具挑战的问题。双路流的播放有两个备选方案:

  • 单播放器实例,子屏和母屏共同作为一个或者一组播放器插件存在,共享上下文;
  • 双播放器实例,子屏和母屏各作为一个播放器实例存在,具有各自的上下文;

我们选择了双实例的方案,因为 :

  • 产品形体来看,主副屏之间的主从关系是相对明确的,体现为副屏对主屏的单向状态订阅和同步;
  • 工程角度来看,保持模型的简单性是有益的,避免因为有两个播放器引入复杂的上下文结构;

双路流的观影体验设计时较为超前的,在当前的硬件条件下,能够让配置不是很高的用户也能够畅享酷看模式是非常有挑战的。

主要的困难点在于:

1.系统性的误差控制,需要全链路来保证

从视频生产开始,视频剪辑工具可能就具有10ms的以上误差,然后再经过运营平台录入锚点,如果运营工具做不到帧对齐级别的锚点自动计算,那么最终对齐的效果也会受人工录入数据偏差的影响;事实上,从生产到投放,再到端侧解码渲染,这个系统误差一直在累积传递,对于这个误差的控制是个系统工程。

2.播放器对做精准对齐提供的工具有限

播放器基础Api本身执行也在10ms这个量级,例如启动、暂停、Seek、变速等接口以及一些状态回调都是异步的,甚至系统的sleep精度也是有限的,这些方法本身的执行时机和耗时都是不确定的,调用这些Api实现40ms级别的同步就好像大象捉老鼠一般困难。

3.设备多样性和运行时随机性适配困难

Android设备碎片化严重,性能分布频谱宽广,在单次追帧同步过程中,运行时状态满随机性较大,无法事先给出全局通用的经验值作为参数进行补偿。

双流同步的基本思路

| 要解决同步位置的锚定

这个位置目前是以主视频时间轴为基准,这里采纳主视频的时钟,有音频时钟,视频时钟或者外部时钟三种选择;

| 要解决对齐的技术手段本身不精准的问题

对齐的技术手段较多,对齐的过程根本上是一个“调节-反馈-修正”的递归过程,虽然模型相对简单,但是需要达到想要的效果具体实现并不容易,涉及较多的实现技巧,例如提供更加精准的seek接口,尽量让这些Api产生的误差偏离方向一致,这样我们就便于在累积误差上做补偿;

| 解决客户端运行时的随机性因素干扰

由于机型千差万别,运行时状态又充满随机性。这里就需要逐一梳理,消除随机性的影响。例如,为了适应网络状态的随机性,实现全局统一的缓存策略;为了平抑个体性能差异,我们引入了部分统计学的方法来做追帧补偿,统计当前设备最近几次追帧差值的方差和标准差作为下一次补偿追帧的参数;针对人眼对播放速度变化的敏感性,训练变速追帧的最佳变速曲线等。

我们通过架构设计、工程优化、算法升级和有针对性适配,打出全链路的组合拳,实现了多路流精准的同步播放,最终呈现了不错的效果。这在下面《这就是街舞2》的示例中同步效果看起来更直观。

技术人看《长安十二时辰》的正确姿势是?

“浮沙之上难筑高台”,酷看模式在技术上创新是一个量变引起质变的过程,它得益于优酷乃至阿里集团在一些基础核心技术上的积累,酷看模式给用户提供更为舒适的沉浸式观看体验和丰富多样的互动方式,是非常有意义的探索,其中遇到的技术挑战让我们看到了一些不足,也为整个播放技术链路的发展指明了方向,希望“酷看”是一只“会下金蛋的老母鸡”。在解决了子母屏的自动布局和交互性问题之后,用子母屏来承载双路流的视频同步播放则是更具挑战的问题。

原文发布时间为:2019-09-20
作者:酷看模式
本文来自云栖社区合作伙伴“阿里技术”,了解相关信息可以关注“阿里技术”。

上一篇:ConcurrentHashMap 有十个提升性能的地方,你都知道吗?


下一篇:java.io.File实现批量创建,递归目录查询、删除操作