写点什么

你负责看比赛,其他的放着我来 | 苏宁体育赛事直播频道化运营关键技术

2018 年 6 月 11 日

频道化直播背景介绍

苏宁体育近年来购买了大量的体育赛事版权,尤其是足球赛事版权,囊括了欧洲五大联赛、中超、亚冠等顶级版权。此外还有 WWE、UFC、NFL 等热门赛事版权。

运营这些优质的赛事资源,给用户提供优质且方便的直播服务,我们依托苏宁视频云 (PP 云) 的直播编码平台,提出了频道化直播运营理念。根据赛事类别分门别类的建立专业化频道,比如:英超频道、亚冠频道、中超频道等,把同类比赛直播及其相关的花絮、新闻短视频集中在一个频道,通过高质量的节目编排,提供 24 小时连续直播服务。给用户提供优质服务的同时,一站化服务可节省用户精力,消除其选择困难。

PP 云直播平台介绍

PP 云直播平台架构

直播平台由管理后台、分布式直播转码系统、流媒体服务集群组成。

管理后台:面向运营人员提供频道管理面板,且与转码集群的 Master 通过 HTTP API 交互。

分布式直播转码系统:由 Master 和转码节点 Node 组成集群,Master 与 Node 间通过 WebSocket 进行通信,Master 控制任务的分发与调度。Master 通过主备实现高可用,Node 基于 FFMpeg API 开发,可通过加机器横向扩展算力。

流媒体服务集群:与 Node 间通过 RTMP 进行推拉流,作为直播源站为后续的切片服务或 CDN 平台提供直播源。三者间交互及架构如下图:

PP 云直播平台主要功能

直播平台提供直播流转码、本地视频转成直播进行轮播、无缝切换直播源、动态切换 logo、动态改变节目编排、多码流输出、动态改变频道参数等。

直播转码节点实现

直播转码节点基于 FFMpeg API 实现,其大致流程如下:对视频源进行解封装、解码,然后把音视频原始数据送入 Filter Graph,对音频进行重采样、变换声道等滤镜操作,对视频进行遮标、缩放、FPS 变换等滤镜操作,然后进行时戳调整、变换,最后加上 Logo 并分别送入不同档次的编码器进行编码、推流,流程如下图所示:

后台管理页面实现

后台管理页是供运营人员进行频道管理的操作面板,提供了频道新建 / 删除、参数配置、Logo 更换、节目列表更新、频道启用 / 禁用、直播流监控面板等功能,见下图:

频道化直播关键技术点

无缝切源

切换直播源时,要使用户端无感,不出现卡顿,就需要切换视频源时,尽量缩短打开下一个视频源的耗时。打开视频源最耗时的部分在于获取视频信息,在 FFMpeg 中对应 avformat_find_stream_info 函数,对有些无法从视频信息头中获取所需参数的视频,该函数会尝试解码音视频数据来获取,会大幅增加耗时,尤其是直播源,因此可优化该函数,如果一直某路直播源的一些信息,就可直接填充相关结构体而无需调用该函数,可降低耗时。

如果是循环直播某个本地文件时,可不重新打开该文件,而是通过 Rewind 的方式,seek 到文件开头重新解码,这时需要注意处理时戳。

时戳处理

时戳处理在直播转码中尤其重要,是消除直播卡顿或花屏的关键点。首先是切换视频源时的时戳处理,其过程如下:首先建立一个参考时间轴,记录直播流当前的时间点,该时间为视频源当前音频 / 视频时间戳的较大者,并变换到参考时间轴的时基,假设音视频时戳变换到参考时间的变换函数为 f(t),则当前时间为: T_max=Max(f(t_a ),f(t_v )) 。当切换新的视频源时,以视频轨为例,当前时戳应为上个视频源的最大时戳加上当前视频的相对时戳,然后反变换到视频轨时基,假设视频轨起始时戳变换到参考时间轴为:T_start,经过整理得到视频轨当前时戳为:V_t=ftv(T_max-T_start )+t,同理可得音频轨的时戳。

当视频源中存在时戳突变时,也需要时戳处理,我们知道,直播中音视频时戳应该是单调递增的,如果直播过程中时戳突然变小,会导致直播花屏,如果时戳突然变大,虽然不会导致视频画面出问题,但会导致时戳变大,减小 RTMP 连续直播的时长,因为 RTMP 的时戳由于字段取值范围限制,最多能支持连续 24 天的直播。切换视频源的时戳处理过程如下图所示:

Buffer 管理

Buffer 管理分两部分:一是在 Encoder 里维护一个 Frame Buffer,解码线程与编码线程的交互即可通过该 Buffer 进行。当上行网络不好时,编码器需做丢帧处理,丢帧时,优先保障音频,先丢视频帧,这样可使直播中音频保持流畅且连续。

另外一个 Buffer 是在发布流的时候,维护一个 packet buffer,用于控制流的时延,有些应用场景,有延播需求,比如电视台的直播一般都会延迟 50 秒左右播出。

Logo 动态更换

采用 Front/Back 两个 Frame Buffer 来保存 Logo 图像,在往视频帧上叠加 Logo 的函数 (Render) 时,采用 Front Buffer,当接收到更换 Logo 的命令式,启动线程来加载新的 Logo 到 Back Buffer,加载完成时,通知 Render 函数交换 Buffer,Front Buffer 就是新的 Logo 图像 Buffer 了,就完成了 Logo 切换。这样可保证 Logo 切换无缝,做到让用户无感。

错误处理

直播过程中不可避免的会遇到错误,常见的有以下几类:

  1. 时戳无效或突变问题,可用上述时戳处理的方法加以修正。
  2. 推流遇到网络错误,比如 -10053、-10054、-104 等错误,这些错误需要重启编码器,但解码器保持不变。其中 -10054 可能是流媒体服务器宕机,这时重启编码器时需改变推流目标机器。
  3. 遇到解码错误,重启解码器,保持编码器不变。
  4. 遇到非致命错误时,可设定该错误连续出现 10 次再当做错误处理。

另外,当出现错误,经过处理恢复直播时,需全速转码,追赶处理错误消耗的时间,保证直播的流畅性。

稳定性与可靠性

高可用性

高可用性可由以下的架构及部署来保证:

  1. 直播转码集群多机房部署,从更高的层次上来保证服务的高可用性。
  2. 集群内的 Master 要有热备,方案为:用 zookeeper 服务 (ZK),部署于两台机器上的 Master 向 ZK 抢主,成功者作为集群 Master,且定期向 ZK 发送心跳,当主 Master 挂掉后,备用 Master 则会抢主成功,这样可保证 Master 的高可用性。
  3. 流媒体服务器也用集群部署,防止单点。

故障转移

直播转码集群内,Master 会感知各个节点的状态,如果某个节点挂掉,则 Master 会自动将这个节点上的任务转移到其他空闲节点,保证任务及时恢复,故障转移可以在数秒内完成,基本不影响直播观感。

监控

对整个集群的服务状况及直播流的状态监控是保证系统可靠性的重要且必要的手段。

首先在 Master 及各个节点运行过程中产生日志,每个 5 秒钟记录一次各个输入流及输出流的码率及帧率状况,然后汇报给监控平台,再由监控平台进行计算分析,输出报表或者产生报警。如果系统中发生致命错误则直接报警,可最大限度的实时报出致命错误,比如宕机,以便运维人员及时处理。日志、监控及报警流程如下图所示:

监控实例

直播平台中的某个频道的帧率监控报表如下图所示:

直播平台中的某个频道的码率监控报表如下图所示:

稳定性实测

直播平台实施以上的架构及处理措施后,系统表现出了预期的稳定性,以其中一个频道为例,无故障的连续直播了约 122W 秒,大约为 14 天,稳定性及可靠性达到了设计目的,实际播放测试结果如下图所示:

总结

直播平台上线后,极大的方便了运营苏宁体育的优质赛事资源,在直播平台上建立电视化的直播频道。平台的稳定性、高可用性及方便的运维性,保证了直播频道给用户提供优质稳定的直播服务。

作者简介

朱明亮,同济大学计算机仿真方向硕士毕业,苏宁易购视频云资深架构师,主要负责苏宁视频云的音视频基础平台架构设计及研发。在音视频编解码、流媒体应用等领域有十余年的架构设计及研发经验,对视频编解码、流媒体、WebRTC 低延时直播、编解码与 AI 结合方面深有研究。

感谢张婵对本文的审校。

2018 年 6 月 11 日 18:19899

评论

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

牛匹!吃透这份阿里高级专家的《Java面试手册》拿下了腾讯offer

Crud的程序员

Java 程序员 架构

Java 程序经验小结:避免使用终结方法

后台技术汇

28天写作

Spring Boot 中集成ActiveMQ

武哥聊编程

Java springboot SpringBoot 2 28天写作 Activemq

2021面试脚本!夜读互联网Java开发27大专题,终入P7

比伯

Java 程序员 面试 计算机 技术宅

首发!腾讯开源“百万级”Netty进阶指南(2021最新)

程序员小毕

Java Netty 网络 框架 异步编程

腾讯T3大佬亲自教你!一起刷完了这份1307页的安卓面试宝典吧,吐血整理

欢喜学安卓

android 程序员 面试 移动开发

如何成为一名优秀的技术Leader?

架构精进之路

成长笔记 七日更 28天写作

高效学习:如何制定有价值的学习目标

石云升

28天写作 学习目标

架构师 3 期 3 班 -week9- 总结

zbest

总结 week9

AQS之ReentrantReadWriteLock写锁

伯阳

读写锁 ReentrantReadWriteLock 多线程与高并发 lock

知乎获赞5K+的面试总结,蚂蚁高级工程师的技术笔记,共12W字

Java成神之路

Java 程序员 架构 面试 编程语言

Redis中哈希分布不均匀该怎么办

云流

Java 数据库 编程 程序员 面试

全球城市ZoneId和UTC时间偏移量的最全对照表

YourBatman

GMT UTC ZoneId 时区

还热乎的面经

书旅

百度 面试 面经

架构师 3 期 3 班 -week9- 作业

zbest

作业 week9

阿里大佬整理的526页Netty笔记,面试大厂不再被网络通信难倒

Java成神之路

Java 程序员 架构 面试 编程语言

程序员的简历,要注意以下几点

田维常

简历

全网最详细的负载均衡原理图解

程序员小毕

Java 负载均衡 性能优化 运维 服务器

深度模型的日志异常检测,还有谁不会?

华为云开发者社区

运维 日志 网络 AIOPS 系统

k8s 上运行我们的 springboot 服务之——springboot服务https请求

柠檬

Java k8s https Istio,

渣硕试水字节跳动,本以为简历都过不了,123+HR面直接拿到意向书

Crud的程序员

Java spring 架构

mq消费幂等总结

A

MQ 幂等性 db

数字钱包系统软件开发|数字钱包APP开发

开發I852946OIIO

系统开发

关注直播 解锁采集器新功能

滴滴云

运维 可观测性 直播技术 滴滴夜莺

[JetPack] LiveData源码解析

Changing Lin

android 技术 JetPack

朋友不讲武德急催我给他Java干货教程,我劝他耗子尾汁并丢给他一份GitHub上标星115k+的Java教程,他看了之后连忙向我道歉!

Java成神之路

Java 程序员 架构 面试 编程语言

FFMpeg解码API以及在解码过程中存在的丢帧问题

wangwei1237

ffmpeg 视频解码

数据结构与算法 - 哈夫曼树

ios 数据结构与算法

爱了爱了!带着问题深入学习Handler,吊打面试官系列!

欢喜学安卓

android 程序员 面试 移动开发

持币生息钱包APP系统开发|持币生息钱包软件开发

开發I852946OIIO

系统开发

Pulsar vs Kafka,CTO 如何抉择?

Apache Pulsar

大数据 pulsar 消息中间件

低代码的认知误区与落地实践

低代码的认知误区与落地实践

你负责看比赛,其他的放着我来 | 苏宁体育赛事直播频道化运营关键技术-InfoQ