01 背景
高光的业务定位和业务价值
在当今数字化时代,直播已经成为一种重要的传播形式,而直播回放作为直播的重要延伸功能,扮演着不可或缺的角色。
直播高光,顾名思义,指的是主播在直播过程中展现的精彩瞬间和亮点。这些高光片段不仅吸引观众的注意力,还能有效增强粉丝的粘性和互动感。这些亮点的呈现并非单纯依赖技术,而是结合创意与技巧的成果。从选题的精准策划,到直播风格的生动呈现,再到与观众的实时互动,每一个环节都至关重要,共同促成了一场成功的直播表现。
此外,直播回放的功能极大地提高了观看的灵活性,既为主播和观众提供了便利,也为主播创造了主播与观众持续互动的机会。同时,这些回放内容也是内容创作者进行研究和数据分析的宝贵素材,帮助他们不断优化策略、改进内容质量。
综上所述,直播回放在提升用户体验、加强传播效果以及挖掘数据价值等方面,展现出了不可替代的作用,为直播生态的持续创新提供了重要支持。
02 系统概述
下图所展示的业务架构是当前业务中比较重要的部分, 忽略了部分细节. 但从此图可以让我们对业务全貌有个初步认知,更好的理解决策时的一些思考。
【业务架构图】
在以上业务架构图上, 我们能看到高光业务承载了多维度的数据源
从数据层面来看:涵盖了弹幕、互动、进房记录、营收等指标数据。
从业务层面来看:包括各种类型的PK玩法、连麦互动、语音聊天等多种直播业务数据。
从AI/算法层面来看:有主播口播, 唱歌, 跳舞等类型类型。
从用户行为来看:用户可手动标记高光点位,还可授权粉丝剪辑属于自己的高光内容。
从技术视角来看,高光系统需要同时应对多样化的业务场景与复杂的数据形态。这意味着系统必须具备对异构数据源的统一接入能力,并能够在接入后执行复杂的计算与优化逻辑,确保数据的处理效率与结果的准确性。在数据的输出环节,例如主播授权粉丝剪辑高光的场景,系统还需支持高并发操作以适应C端用户的流量需求。所以高光系统的技术架构设计不仅要满足当前的业务需求,还需具有较高的扩展能力与可靠性,以支持未来的业务发展和技术演进。
接下来我将从高光生命周期、高光优化及业务创新等方面,逐步解析直播高光系统的相关内容。
03 系统架构
通过前面的概述,我们已经对直播高光的基本架构有了一定的理解。接下来,我将从高光的生命周期出发,详细讲解高光系统的建设过程。
1 数据生成
目前,直播高光数据的生成依赖于两种触发机制:主动触发和被动触发。
主动触发 是指在主播完成直播后,主播或粉丝通过各个平台的高光入口主动请求生成主播的高光数据。在这个过程中,系统会首先检查是否已经生成了该场次的高光内容。如果系统检测到该类型高光尚未生成,它会自动创建一个任务,并通知高光生成系统开始处理相关数据,生成该场次的不同类型的高光内容。这种触发方式通常由主播或观众根据需求发起,保证了在有需求的情况下及时生成高光内容。
被动触发 主要用于直播过程中需要即时生成高光内容的场景。在此机制下,系统通过RPC接口或消息队列(MQ)实时接收来自主播端或其他系统的指令,迅速生成并存储高光数据。此种方式针对那些需要快速响应的直播时刻,例如主播主动标记某个精彩片段或有AI实时识别的事件高光生成,能够确保高光数据的时效性和精准性。这种触发方式大大增强了系统对实时性需求的响应能力。
结合这两种触发机制,系统能够根据不同的使用场景灵活应对,确保既能满足观众和主播的事后回顾需求,又能实时捕捉直播中的高光瞬间。这种高效的生成方式不仅优化了用户体验,还提升了直播互动的整体质量,进一步增强了用户与主播之间的互动感。
【高光接入图】
在高光生成的过程中,不同业务方的输入数据格式通常存在差异。然而,通过同构处理技术,我们能够将这些异构数据统一转换为标准结构,从而大幅提升系统的兼容性与可扩展性。
同构处理的核心在于对数据的抽象与归一化。例如,对于不同业务方提交的高光数据,系统会统一提取关键特征(如片段开始和结束时间、高光类型标题等),并将其存储为标准化的数据结构。这种方式使得高光生成流程的核心逻辑可以被直接复用,而无需针对每个新业务重复开发。
更重要的是,同构处理还为后续业务接入提供了良好的技术支持。每当有新的高光需求接入时,开发者只需实现数据转换模块,其余通用逻辑即可直接沿用。
2 数据存储
由于业务数据已经实现统一接入,高光系统的数据结构也因此具备了通用性。在选择数据存储架构时,我们结合了基础设施的现状与自身业务的特点,决定采用 MySQL 和 Redis 作为存储解决方案。
-
MySQL 作为持久化存储系统,用于保障数据的可靠性和长期存储。
-
Redis 作为缓存系统,提供高效的实时数据读取和快速响应。
这种组合方式在确保数据一致性的同时,也大大提升了系统的性能和扩展性。持久化和缓存相辅相成的架构设计既满足了系统的高性能需求,也确保了数据的完整性和安全性。
MySQL存储
高光的mysql表主要是两张
1. 高光查询记录表
该表专用于记录在主动触发模式下,主播场次中已查询的高光数据状态。其主要作用是防止重复查询同一数据,从而避免后续请求再次触发相同的查询操作,减少对下游接口的压力和负担。
最主要的一些字段如下:
CREATE TABLE `highlight_get_record` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`uid` bigint(20) NOT NULL DEFAULT '0' COMMENT '用户ID',
`roomid` bigint(20) NOT NULL DEFAULT '0' COMMENT '用户ID',
`live_key` varchar(100) NOT NULL DEFAULT '' COMMENT '场次id',
`highlight_type` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '高光类型',
`status` tinyint(20) unsigned NOT NULL DEFAULT '0' COMMENT '查询状态 0 未成功 1成功',
// ......
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='高光查询记录表'
其中 uid, live_key是标识直播场次的唯一键 能确定高光属于哪个场次, 这个就不再赘述.
当用户请求高光列表接口时,系统首先根据用户权限判定其可查询的高光类型,并通过查询相关表确定哪些高光数据已处理。如果目标高光数据未处理,系统会利用协程并发调用各类型高光对应的下游业务接口以获取相关数据。在查询过程中,status 字段用于记录处理结果:当某类型高光数据成功获取后,status 字段被设置为 1;若查询失败,则设置为 0。
在后续的请求中,系统会依据 status 字段的值进行逻辑判断。对于已成功处理(status = 1)的高光类型,系统跳过重复调用,从而减少接口冗余请求并优化资源使用;对于未处理(status = 0)的类型,系统会继续发起请求以完成数据获取。
2. 高光数据表
高光数据表存的是同构后的高光数据, 最主要的一些字段如下:
CREATE TABLE `highlight_data` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`uid` bigint(20) NOT NULL DEFAULT '0' COMMENT '用户ID',
`roomid` bigint(20) NOT NULL DEFAULT '0' COMMENT '用户ID',
`live_key` varchar(100) NOT NULL DEFAULT '' COMMENT '场次id',
`highlight_type`int(11) unsigned NOT NULL DEFAULT '0' COMMENT '高光类型',
`title` varchar(256) NOT NULL DEFAULT '' COMMENT '标题',
`start_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '高光片段开始时间',
`end_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '高光片段结束时间',
`score` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '高光打分',
`status` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '高光状态',
// ......
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='高光查询记录表'
在系统中,uid 和 live_key 共同作为标识直播场次的唯一键,用于明确高光所属的具体场次信息。这两个字段的联合使用可以确保高光数据的唯一性和准确性。此外,start_time、end_time、title 和 score 是高光内容的核心属性,分别表示高光的开始时间、结束时间、标题以及相关评分,这些字段主要用于高光的外显展示。
值得注意的是,start_time、end_time、title 和 score 字段将在后续章节中被优化,以进一步提升高光数据的表现力和实用性。而 status 字段则作为高光处理的状态机,记录了优化和处理的状态。在接下来的内容中,将详细介绍 status 字段的作用及其在优化流程中的具体实现。因此,这里不再赘述相关细节,为下文的深入探讨做铺垫。通过这些关键字段的合理设计与优化,系统能够更高效地管理和展示高光内容,提升业务功能的整体表现。
Redis存储
在系统设计中,Redis 用于缓存 查询记录表 中的状态数据,其结果以 int 类型存储。Redis 的键由 uid、场次标识(live_key) 和高光类型(highlight_type)组成的组合键生成,确保每个高光数据的状态唯一可定位。通过这一缓存机制,每次用户请求时可以直接从 Redis 获取状态数据,大幅减少对数据库的访问频次,降低 DB 的负载,提升系统的查询效率和响应速度。
3 高光区间优化
主播的直播表演一般具有时间长、随机性强的特点,如何在平均6小时以上的直播内容中快速找到几个优质片段,就成为了我们辅助主播复盘高光、投稿精彩内容的重要课题。
当前我们使用的高光片段主要是基于提取整场直播回放的某些指标数据的最大值,按照“前1后2”的逻辑划分时间区段。经过对历史数据的分析,我们最终采用了进房观看人数(PCU)、弹幕互动、主播营收三个核心指标。
不过通过对主播使用高光区间的统计和观察,发现直接使用最大值周边的时间区段虽有一定的效果,但也会因遗漏部分其他高光区段,导致主播的选择范围变窄。基于此,我们需要实现一种算法,对时间轴上的数据点进行统计打分,通过加权平均的算法,最终能更精准的找到开始结束时间点,也能找到除最高点外的高光时间区段。
1.对于直播回放片段指标趋势曲线的技术实现
1.1 数据获取:从数仓中获取弹幕、PCU和营收等关键业务指标的原始数据。这些数据可以通过数仓的API接口进行实时获取。
1.2 数据聚合:对获取到的原始数据进行分钟级别的实时聚合操作,将数据聚合为分钟级别的指标数据。聚合操作可以通过多个协程并行计算实现。
1.3 数据存储:将聚合后的分钟级别指标数据存储在内存中,以便前端页面进行实时查询和展示更新。
1.4 数据展示:前端页面通过调用服务端实时高光数据的API接口,获取分钟级别的指标数据,并以曲线图的形式进行展示。
2.对于直播回放高光片段算法选择的技术实现
当前待解决的问题放到数学层面上,即抽象为如何在一个长时间区段的不规则曲线内,找到几个高数值的时间区间。
2.1 相同时间区段内寻找 TOP N区间
以整场6小时直播为例,一分钟输出一个数据点,最终输出360个坐标点,其中取3个点用于计算,可类似用微分的算法用“面积”的方式计算面积。如下图所示:
x∈[10,12]对应的面积,近似可以表达为三个绿色方框的面积,即这段区段的面积近似为:
(无规则曲线中三个点对应的近似面积公式)
类似地,任意起点的n个点之间的面积即为对应坐标值的和,即:
(任意起点的n点之间围成的近似面积公式)
2.2 如何合理对比不同时间区段的高值
按照以上的结论用点数近似等于对应区段的面积。假设 ai+ai+1+ai+2 的平均值是时间窗口为3的最大值,对比比较 ai+ai+1+ai+2 的平均值和 ai+ai+1+ai+2+ai+3 的平均值的大小。
(三点均值和四点均值的比较)
如图所示,当 ai+3 处于不同位置,4点均值和3点均值的结果如下(n∈[0,1]):
条件 | 结果对比 | 对应业务场景 |
ai+3 > 平均值 | 后三者的平均值大于前三者,假设不成立 | - |
ai+3 = 平均值 | 4点均值 = 3点均值 | 第四分钟仍为高互动点,应当判定为“高光时段”区间 |
n(平均值)< ai+3 < 平均值 | 4点均值 < 3点均值 | 第四分钟略低于高互动区间的均值,但仍有一定的活跃度,可以做适当的延伸 |
ai+3 < n(平均值) | 4点均值 < 3点均值 | 第四分钟明显低于高互动区间的均值,活跃度较低,不应当作为“高光时段”区间 |
2.3 n值的选取和计算
同样地,以3点均值和4点均值为例,如下图所示,令 ai+3 = n*(3点均值),不难得出:
给4点均值配置一个系数用于平衡第四分钟略低于3点均值的结果,令系数为 k,即有:
即,4点均值的结果如果是k倍的3点均值结果,也应当被采纳。对点数进行拓展不难得出,4点均值和5点均值的关系为:
3点均值和5点均值的关系即为:
推导到3点均值和x点均值的关系,不难得出:
应用在本例中,即如果 k1 倍的4点均值大于3点均值,就应当使用最高的4点均值区间;k2倍的5点均值大于k1倍的4点均值或3点均值,就应当使用5点均值的区间。
代入不同的 n值,不难得出 ki 的序列值如下:
n | 含义 | 0.7 | 0.8 |
k1 | 3点均值对比4点均值 | 1.081081081 | 1.052631579 |
k2 | 3点均值对比5点均值 | 1.150086256 | 1.096491228 |
k3 | 3点均值对比6点均值 | 1.210617112 | 1.13430127 |
k4 | 3点均值对比7点均值 | 1.264823848 | 1.167663072 |
k5 | 3点均值对比8点均值 | 1.3141027 | 1.197603151 |
3.代码实现逻辑
高光片段区间计算配置:
{
"valid_type": [ # 可处理的高光类型
1
],
"formula": {
"1": {
"title": "弹幕高光", # 高光标题
"top_n": 5, # Top K
"window_min": 3, # 滑动大小窗口 min
"window_max": 10, # 滑动大小窗口 max
"ratio": 80 # 计算系数
}
}
}
在实施业务数据分析的过程中,首先需要从数据仓库中提取出业务曲线的所有节点数值。为了提高处理效率,我们需要对这些节点数值进行聚合操作,将相邻的节点数值进行合并,从而减少后续计算的数据量。
在进行滑动窗口计算时,并行计算配置大小的滑动窗口是关键。窗口大小通过配置获取,我们需要根据业务需求和硬件资源配置,选择合适大小的滑动窗口,以在保证计算精度的同时,提高计算速度。
滑动窗口确定后,接下来我们需要根据相关系数公式,计算每个滑动窗口内的节点数值之间的相关系数。这部份计算系数已被提前配置进配置中心,可以实时获取并计算。这将帮助我们分析业务曲线的趋势变化和相关性。
在计算出相关系数后,我们需要对每个滑动窗口内的节点数值进行统计分析,计算出片段的总值、平均值、权重等重要指标。这些指标将为后续的高光区间筛选提供依据。
最后,根据堆排序算法,我们可以对计算出的各个滑动窗口的指标进行排序,并返回排名前K的高光区间。这些高光区间将帮助业务人员快速发现业务曲线中的重要变化和趋势,为决策提供数据支持。
选出对应的高光片段后, 通过服务端的接口聚合返回给主播, 通过主播投稿等用户行为操作后回收稿件引流效果,进一步收益反哺算法。
【高光区间优化效果图】
4 高光AI优化
在直播场景下,高光数据的生成与优化一直是提升用户体验的重要环节。然而,传统的高光生成方式存在诸多不足,如标题缺失、内容质量难以量化以及高光区间不准确等问题。结合AI技术,我们提出了一系列创新解决方案,以解决这些业务痛点并优化高光区间的生成和展示。
高光标题缺失
高光片段默认无标题,只展示高光类型,导致用户缺乏兴趣参与投稿和互动。为解决这一问题,我们引入了B站的AI大语言模型,通过对高光片段中的音频进行ASR(Automatic Speech Recognition)字幕识别,生成吸引用户的个性化标题。这种标题生成机制不仅提升了高光的吸引力,还显著降低了用户手动编辑的门槛。
高光内容质量难以量化
如何判断高光片段的优劣是另一个关键难点。我们给出的解决方案是对高光视频进行音频提取,并通过ASR生成字幕。随后,AI模型对每个高光片段进行评分,将同类型片段按照评分排序,并优先向用户推荐高评分的内容。这一策略确保了用户能够看到质量更高、更具吸引力的高光片段。
高光区间划分不够精准
部分数据高光(如: 弹幕)按照分钟级别进行聚合,导致高光生成的片段缺乏连贯性,影响观看体验。对此,我们采用了字幕粒度的评分方法。通过剥离视频音频并生成ASR字幕,AI模型逐句分析字幕内容,为每一句字幕打分。系统以平均分最高的字幕片段作为最终的高光区间,确保生成的高光片段在逻辑和内容上更连贯、更合理。
以上优化虽显成效,但仍伴随一些技术挑战,有待进一步探索与解决。
1. AI大语言模型承载能力
-
难点:在高并发场景下,AI模型容易面临QPS 压力,影响响应时间。
-
解决方案:
-
异步消息消费流:引入消息队列,通过消息队列机制削峰填谷,将高频请求分批处理。
-
并发控制:配置模型实例的动态扩展策略,确保在高峰期保持平稳性能。
2. 缓存与分片机制
-
难点:频繁请求的字幕生成与标题生成操作可能造成重复计算,增加系统负担。
-
解决方案:
-
缓存策略:针对生成结果设置合理的过期时间,并为常用的高光类型启用热点缓存。
-
分片机制:将高光数据按类型或事件分片处理,减少全量计算的时间。
3. 模型优化与评估
-
难点: 生成标题和评分模型需要兼顾业务多样性和用户个性化需求。
-
解决方案:
-
模型调优:和AI平台合作,利用线上数据表现状态动态更新模型参数,使其适应实时的业务变化。
-
指标评估:通过线上AB测试对不同模型版本进行对比,选择点击率、播放时长等关键指标表现最优的版本。
【高光优化架构图】
【高光AI标题效果图】
5 优化状态机
【状态机】
通过将生命周期中的多个优化模块整合为统一的共用状态机,我们将相似的模块逻辑抽象为可复用的状态机组件。这种方式避免了为每个模块单独实现和维护状态机,从而显著降低了开发和运维成本。当系统需要进行状态机调整、修复bug或进行功能扩展时,开发者只需在统一的状态机框架中进行修改,而无需逐个模块进行调整。这不仅提升了系统的可维护性和灵活性,还有效避免了重复劳动,减少了潜在的错误和不一致性。此外,通过这种共用状态机架构,可以确保系统在扩展时仍保持高稳定性和可靠性,进一步优化了业务流程和技术支持的效率。
6 数据展示
在对外提供高光数据的接口中,处理流程主要包括以下几个步骤:
1. 系统会获取当前直播场次的所有高光数据。
2. 根据业务配置中的高光类型对高光数据进行排序。如果多个高光具有相同的类型,则进一步根据AI评分(如有的话)或时长进行排序。
3. 系统计算各个高光之间的重合度,对于那些重合度超过预设阈值的高光,低权重的高光将被排除,以避免重复展示。
4. 返回经过处理后的高光列表。
【高光数据展示流程】
可能有读者会问: 为什么排序和重合度计算的逻辑要放在获取高光数据的接口中,而不是在所有高光生成完成后再进行排序?
这一设计背后的原因是,随着高光业务的快速迭代,业务产品或运营对高光的权重分配会发生变化,这直接影响到高光的展示顺序及其重合度的计算。因此,每次获取高光数据时,必须动态地根据最新的业务需求调整排序和重合度,而不能依赖于预先生成的静态排序结果。
尽管这种方法会导致接口性能有所下降,但考虑到每个场次的高光数量是有限的,当前的性能消耗仍在可接受范围内。我们力求在业务需求的灵活性和系统性能之间找到合理的平衡点,以确保既能快速响应业务变动,又能兼具系统的稳定性和高效性。
7 整体架构图
【整体系统架构图】
这里引用一个内部的高光简化版整体架构图,仅供参考。
04 未来规划
尽管当前系统已奠定良好基础,但仍有优化潜力。针对现有问题,我们将在后续迭代中进行持续改进,重点关注以下几个领域
服务稳定性优化:目前服务框架的鲁棒性和实现细节存在优化空间,需要关注代码质量和读写性能等方面的改进,以应对灾难级故障,增强系统的稳定性。
持续故障演练: 未来需要进行更多故障演练,以确保服务在突发事件中的稳定运行,并持续维护和提升服务的稳定性。
服务治理工具建设:由于业务快速迭代,当前生产配套工具滞后,需要建设一站式的全链路追踪、监控、排障等能力,减少研发人员的排查成本。
B站的核心价值观之一是社区优先。用户的体验对我们来说至关重要。我们不仅会致力于持续提升高光服务的稳定性,还不断迭代优化高光业务,以便用户能够看到更优质的高光内容,从而增强认同感和使用意愿,提供更好的直播体验。
-End-
作者丨AndyZhu