播放器视频后处理实践(二)氛围模式
01 前言
在日常视频播放中,我们经常会遇到这样的问题:视频的长宽比例与设备屏幕不一致,导致画面上下或左右出现黑边。虽然这并不影响视频的正常播放,但从用户体验的角度来看,这些黑边往往打断了视觉的沉浸感,显得格外突兀。
为了解决这一问题,业界主流播放器(如 YouTube、Netflix)引入了一种被称为氛围模式(Ambient Mode)的视觉增强效果。它的核心思路是:
通过实时识别视频画面的主色调,并动态将其填充到黑边区域,使边缘色彩与视频内容保持一致,提升整体视觉统一性,从而营造出与视频内容相协调的氛围效果,让观众的观看体验更加自然和沉浸。
下面是 YouTube 的氛围模式效果:
youtube 竖屏效果
youtube 横屏效果
百度播放内核团队也将氛围模式效果应用到了视频播放场景,用于提升用户观看视频沉浸感,同时在百度 App、好看 App 两款产品完成上线。本文将详细说明视频场景氛围模式技术方案。
02 整体技术方案
氛围模式通过在播放内核视频后处理通道(FilterChain)添加一个 AmbientFilter 滤镜实现,其核心思路:通过 AmbientFilter 滤镜先将视频帧数据从 GPU 下载到 CPU,然后将视频帧数据按块进行区域划分,划分完成后再通过颜色量化算法提取每个区域主色调,最后将各个区域主色调传给平台层,平台层拿到主色调进行绘制视频四周氛围效果。整体方案流程大致如下图所示:
氛围模式整体方案
2.1 视频帧采样
为了提取视频的主色调,需要获取视频帧数据。但提取主色调并不要求每帧都下载,太频繁下载会拖垮应用性能,在视觉上也不会带来特别好的体验。因此我们对视频帧进行采样下载:在 25 FPS 的视频下,每隔约 50 帧(约 2 秒)采集一次帧数据。
同时,为了避免将视频帧数据从 GPU 下载到 CPU 时阻塞渲染线程,我们采取了以下优化:
1. FBO 压缩:先将视频帧渲染到较低分辨率的 FBO(例如将 1080p 压缩到 108p),大幅减少待传输的数据量。
2. PBO 异步传输:利用 PBO 异步将帧数据从 GPU 下载到 CPU,从而避免阻塞主渲染线程。
通过这种方式,我们既能保证主色调提取的效率,又不会影响视频的流畅播放。渲染线程和氛围模式工作线程两个线程工作流程如下图:
线程核心职责
2.2 主色调提取
2.2.1 视频帧区域划分
拿到视频帧数据后,我们先将视频帧划分出几个区域。项目中我们是将视频帧画面划分为:TopLeft, TopCenter, TopRight, BottomLeft, BottomCenter, BottomRight 六个区域,如下图所示:
视频区域块划分
接下来我们提取出每块区域的主色调。
2.2.2 提取主色调
要提取画面主色调,我们是通过颜色量化技术实现的。颜色量化(Color Quantization) 是一种图像处理技术,目的是减少图像中使用的颜色数量,同时尽量保持原图的视觉效果。代表性的颜色量化算法有:
1. 中值切割法(Median Cut):将颜色空间递归分割成小立方体,取每个立方体的颜色中位数作为调色板颜色。
2. K-means 聚类:将颜色按相似性分组,取每组的中心作为调色板颜色。
3. 八叉树算法:通过构建八叉树分层合并颜色,逐层减少叶子节点数量,最终保留高频颜色。
4. 流行色算法(Popularity):统计原图颜色出现的频率,选取高频颜色作为调色板。
这几种算法从各维度对比情况如下:
从算法的速度、精度以及实现复杂度等多维度考虑,氛围模式场景我们选用中值切割法完成视频画面主色调的提取。
2.2.3 中值切割法
中值切割法(Median Cut)是一种用于图像颜色量化的算法,算法核心思想是将颜色空间递归地分割成更小的区域,以减少图像中颜色数量。该算法的目标是在颜色空间中选择一组代表性的颜色,这些颜色可以用于生成调色板,从而减少图像的颜色数量,同时尽量保留图像的视觉效果。算法核心步骤如下:
1. 初始化颜色盒
a. 首先,将所有颜色视为一个大的颜色盒(即整个颜色空间的一个区域)。
b. 颜色盒包含图像中所有像素的颜色。
2. 选择分割轴
a. 在每次迭代中,选择颜色分量(红、绿、蓝)中范围最大的分量作为分割轴。这是为了最大限度地减少颜色空间的不均匀性。
3. 按中值分割
a. 沿着选定的分割轴,根据颜色值的中值,将颜色盒分成两个较小的盒。
b. 这种方法确保每个新盒子中包含的颜色数量尽可能相等。
4. 递归分割
a. 对每个新的颜色盒重复步骤 2 和 3,直到达到所需的颜色盒数量(通常是所需调色板的大小)。
5. 生成调色板
a. 一旦颜色盒的数量达到预期的数量,对每个盒子计算平均颜色或中值颜色,将其作为代表颜色添加到调色板中。
6. 颜色映射
a. 使用生成的调色板,重新映射原始图像中的每个像素到最接近的调色板颜色。
中值切割算法核心流程如下图:
中值切割算法
03 平台渲染氛围效果
当 native 层提取完视频帧各区域主色调后,将色值传给平台层(Android/iOS)。平台层收到色值后,将色值渲染到视频四周以产生氛围效果。为保证各个区域色值过渡自然,以及前后两帧的色值平滑过渡,需要借助平台层渐变、动画、rgb 插值等技术实现。 下面结合 Android 和 iOS 两个平台分别介绍具体思路。
3.1 Android 平台
Android 使用自定义 view 技术,完成氛围色值的渲染。我们提供一个自定义 view 名为 AmbientView 来完成这个功能。有了 AmbientView 之后,布局结构大致如下:
上面为视频横屏下布局大致情况,id 为 video_container 的 FrameLayout 是播放器容器,在播放器容器左右各摆放一个 AmbientView 渲染氛围模式,AmbientView 的宽度会根据播放器的尺寸的变化在代码中动态调整。
AmbientView 核心功能:
1. 相邻区域的主色调,使用 LinearGradient 拉出线形渐变。对于横屏视频,我们渐变方向就是从上至下。所以更新氛围色值的代码如下:
2. 前后两帧氛围色值的切换,为了颜色切换不显得生硬,我们借助 Android 属性动画以及 RGB 插值实现色值缓慢渐变效果,核心代码如下:
mColorAnimator 是一个 ValueAnimator 对象,通过 ValueAnimator 我们创建一个 1500ms 的动画,在动画的更新函数里面,我们调用了 interpolateColors,这个方法内部就是用 ArgbEvaluator 完成 RGB 颜色插值,更新到 mColors 数组中。最后调用 updateGradient 方法触发 AmbientView 重绘。
3. 渐变遮罩:最后我们还要在上面添加一层黑色渐变遮罩,保证氛围区域不要太突兀,以免过度吸引用户眼球,导致用户注意力不在视频内容本身上面。黑色遮罩实现也非常简单,代码如下所示:
3.2 iOS 平台
iOS 端同样提供了一个自定义的 AmbientView(氛围视图),为视频播放场景提供动态渐变背景和遮罩效果,增强视觉沉浸感。
1. 双图层架构设计:采用主渐变层与遮罩层分离的架构方案,确保色彩渲染与边缘遮罩效果互不干扰,提升整体渲染效率。
2. 流畅动画引擎:基于 CADisplayLink 构建动画循环,通过实时颜色插值计算,实现细腻流畅的色彩过渡效果。
3. 渐变遮罩:采用多段式渐变遮罩配合加速曲线算法,打造自然的边缘过渡,有效增强视觉层次感。
该实现确保了氛围渲染的高性能和优美视觉效果,为用户提供了沉浸式的观看体验。
04 效果展示
氛围模式已在百度内包括百度 App 和好看 App 两款 App 完成上线,其中百度 App 主要集中在搜索三方影视场景,好看 App 所有视频横屏场景(排除广告视频)。同时在视频观看时长、分发、完播率等 UBS 指标取得了正向收益,说明氛围模式给用户带来了不错的沉浸式观影体验。
下面是百度 App 和好看 App 效果展示:
百度 App 氛围模式
好看 App 氛围模式
5. 总结
氛围模式是一种视觉增强功能,通过技术手段有效解决了视频比例不匹配导致的黑边问题,显著提升了用户视觉体验,主要表现在如下几个方面:
1. 视觉沉浸:氛围模式通过在视频周围添加柔和的背景颜色,使屏幕的边缘与视频内容更好地融合。这种设计使得用户在观看视频时感觉更加沉浸,减少了视频与周围环境之间的视觉割裂
2. 舒适观看:这种模式可以减少长时间观看视频时的眼睛疲劳。通过在视频周围使用柔和的色彩过渡,可以缓解亮度差异带来的视觉刺激,从而提高观看舒适度。
3. 提升观感:氛围模式通过智能地调整背景色彩,使其与视频中的主要色调相匹配,提升整体观感。这使得视频内容更加突出,同时为观看者提供一种更为和谐的视觉体验。
通过本文介绍的技术方案,开发者可以实现类似主流视频平台的高质量氛围模式效果,为用户带来更加沉浸的观看体验。







评论