写点什么

边看边互动!优酷酷看模式技术揭秘

  • 2020-05-20
  • 本文字数:3951 字

    阅读完需:约 13 分钟

边看边互动!优酷酷看模式技术揭秘

从“叉手礼”、“水盆羊汤”、“酒晕妆”这些唐朝人生活细节,到精美的坊间造型、充满意境的诗词歌赋,《长安十二时辰》不仅以缜密剧情赢得赞誉,更还原了一个真实的大唐长安。在精良制作之上,如何让观众感受 1000 多年前的长安风情、更深度的理解剧情呢?


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

一、播放器业务框架

优酷的播放器业务框架以一个简单而优雅的模型解构了所有的播放器业务,在该框架下播放业务是由一组彼此独立的插件组合实现的。它适应了复杂的播放业务场景,支持着众多围绕播放业务的团队并行开发。通过技术架构的解耦带来与之相关的技术团队的组织架构的解耦。


  1. 播放器视图模型



如上图所示,该模型可以描述为:


1)播放器由多个层组成;


2)层容器中布局插件;


3)播放器发布消息;


4)插件订阅消息;


5)层和插件信息来自配置文件。


  1. 核心特性


该框架在设计之初就确定了一系列的优良特性作为设计目标,核心的特性列举如下:


1)基于消息,事件驱动


引入事件/订阅的消息机制,插件按需订阅播放器的事件,根据优先级响应和消费消息;


2)按需配置,自由组合


支持从 xml 配置文件加载层和插件的配置信息,各个业务方在接入业务框架时以搭积木的方式排列组合构造播放器;


3)插件解耦,互不依赖


将所有的播放功能及业务模块解耦为彼此独立的插件,插件之间以消息机制进行通信;


4)标准明确,支持扩展


框架会提供一批功能丰富的标准插件,插件可分组管理,业务方可根据自己的需求定制插件来替换默认实现,也可以新增插件;


5)多例共存,彼此隔离


即可有多个播放器在一个页面内同时运行,并且从不同的配置创建。


  1. 为业务开发带来的变化


1)技术架构开放化


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


2)业务开发标准化


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


3)播放能力服务化


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

二、酷看百科

酷看百科主要是在视频播放过程中给出一些类似百科的,辅助用户观看的介绍性内容。技术上的需求主要来自两个方面:


一方面面向运营,运营希望有一个常态化的运营工具,简单的通过运营后台修改配置就完成投放,无需技术同学辅助,客户端也不需要频繁发版本;


另一方面面向用户体验,产品希望能够根据用户的偏好和视频的内容做到 UI 风格多样可动态调整的展示,能够较好的与内容融合。



【图片】剧中关于不良人的解释即为一处百科的投放


核心技术点


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


1)播放器如何进行不同播放模式的切换;


2)端侧采用什么技术来实现动态化渲染。


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


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



weex 架构示意图

三、子母屏

子母屏是酷看中使用较多的一种形态。


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


核心思想:分离母屏正片和子屏的可运营资源


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


1)对用户不友好,缺乏互动性且难以按照用户的偏好差异投放;


2)对制作不友好,互动资源和正片资源直接耦合;


3)对运营不友好,严重依赖后期制作无法独立运营;


4)对商业化不友好,广告内容和正片资源直接固化。


这些问题的症结在于合流的方式导致相关内容以一种较为粗放的、固化的方式投放给观众,无视观众的偏好;同样也忽略了多层次精细化的运营需求,这种基于媒体资源的强绑定关系使得正片内容和运营内容组合关系变得固化且单一。


基于此,我们将母屏和子屏的资源解耦。即不在制作时合流,而是让正片内容和运营内容严格分离,分开存储和投放。副屏的内容投放将完全交由运营同学,运营同学从模版库中选择相应的模版即可快速预览和投放,不再依赖后期制作。


核心技术点


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


  1. 播放器双屏容器


首先要解决的是子母屏容器的搭建问题。


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


1)母屏的缩放尺寸能够根据不同的屏幕宽度和视频资源宽度自适应;


2)子屏同母屏一样具有交互性,能够响应用户的手势;


3)母屏上下区域都是可投放可交互的运营位;


4)弹幕、进度条等组件可以根据需求跟随或者脱离母屏。


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


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



《这就是街舞 2》,边看街舞边给选手投毛巾。

四、双流同步播放

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


双路流播放有两个备选方案:


1)单播放器实例,子屏和母屏共同作为一个或者一组播放器插件存在,共享上下文;


2)双播放器实例,子屏和母屏各作为一个播放器实例存在,具有各自的上下文;


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


1)产品形体来看,主副屏之间的主从关系是相对明确的,体现为副屏对主屏的单向状态订阅和同步;


2)工程角度来看,保持模型的简单性是有益的,避免因为有两个播放器引入复杂的上下文结构;


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



《长安十二时辰》双流投放效果,母屏为正片,副屏为张小敬服饰介绍


  1. 主要的困难点


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


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


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


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


3)设备多样性和运行时随机性造成的适配困难


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


  1. 两个播放器同步的解决思路:


1)首先要解决同步位置的锚定,这个位置目前是以主视频时间轴为基准,这里采纳主视频的时钟,有音频时钟,视频时钟或者外部时钟三种选择;


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


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


通过架构设计、工程优化、算法升级和有针对性适配,打出全链路的组合拳,最终实现了多路流精准的同步播放,呈现了不错的效果。



《这就是街舞 2》中的同步效果


作者 | 阿里文娱无线开发专家 卜道


2020-05-20 17:571360

评论

发布
暂无评论
发现更多内容

如果你听说过 Elastic Certified Engineer

escray

七日更 28天写作 死磕Elasticsearch 60天通过Elastic认证考试

VUE项目性能优化实践——通过懒加载提升页面响应速度

葡萄城技术团队

Vue

代码也能“杀”虫:此虫,真虫非Bug也

华为云开发者联盟

代码 华为云 modelarts

Java中定时器Timer致命缺点(附学习方法)

叫练

学习 定时任务 多线程 定时器 技术学习

ETL都没弄懂,谈什么大数据 ?我用一分钟给你整明白

智分析

ETL

新思科技网络安全研究中心发现Bouncy Castle中的漏洞

InfoQ_434670063458

新思科技 Bouncy Castle

软件界旷世之架:测试驱动开发(TDD)之争

华为云开发者联盟

软件 测试 TDD 代码 devcloud

Spark HistoryServer日志解析&清理异常

kwang

大数据 spark hdfs

大作业一:架构设计方案评审

Nick~毓

如何使用Eclipse内存分析工具定位内存泄露

AI乔治

Java eclipse 架构

LeetCode题解:111. 二叉树的最小深度,BFS,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

开始的开始-可能是最早提交的28天写作活动作品

石君

28天写作

一个正确的编程思维

程序员吴师兄

28天写作

SpringCloud从入门到精通02---支付模块01

Felix

俯瞰Dubbo全局,阅读源码前必须掌握这些!!

冰河

架构 分布式 微服务 dubbo 服务治理

杜绝标题党,好的标题是成功的99%

xcbeyond

方法论 28天写作 写作技巧

云算力矿机租赁挖矿APP系统开发|云算力矿机租赁挖矿软件开发

系统开发

技术实录 | 灵雀云基于 OVN 的 Kubernetes 网络架构解析

York

灵雀云 Kubernetes k8s Kube-OVN

还在手动写数据库文档吗?试试这个工具,划水干活儿两不误!

我爱娃哈哈😍

数据库 文档生成

从七日更,到28天写作挑战,我无法拒绝的原因

梁龙先森

大前端 编程语言 28天写作

要想软件“一想之美”,UI测试少不了

华为云开发者联盟

软件 测试 华为云

【CSS】CSS对大小写敏感吗?

德育处主任

28天写作

【Mysql-InnoDB系列】InnoDB架构

程序员架构进阶

MySQL 架构 innodb 28天写作

文档驱动开发模式在 AIMS 中的应用与实践

华为云开发者联盟

Web 代码 API 文档

volatile 关键字精讲

伯阳

Java volatile 后端 关键字 多线程与高并发

Hive的调优你都知道那些?

大数据老哥

大数据 hadoop hive

如何使用Eclipse内存分析工具定位内存泄露

Java老k

Java 内存泄露

边缘计算安全技术研究

华为云原生团队

云计算 大数据 云原生 边缘计算 华为云

价值 - 价值的底色(一)

石云升

读书笔记 投资 28天写作 价值

SpringCloud从入门到精通01---父项目创建

Felix

SpringCloud Eureka 高可用架构

灵雀云Kube-OVN:基于OVN的开源Kubernetes网络实践

York

灵雀云 Kubernetes k8s Kube-OVN

边看边互动!优酷酷看模式技术揭秘_文化 & 方法_阿里巴巴文娱技术_InfoQ精选文章