1. 直播的工作原理
【拉流】
直播内容是通过 流媒体播放器 播放出来,而流媒体播放器通过 流地址 来拉取 流数据,再处理相关 解码 工作,最后呈现出画面和声音。
为了保证全国甚至海外用户都能够流畅的观看直播内容,就需要比较强大的物理网络覆盖。
流媒体数据通过上游CDN源站推(或推拉结合)到所有边缘节点。
不同地域的用户通过 全局CDN-DNS 调度后,就近访问CDN节点。
推流】
通常开播都有一个开播工具,开播工具是专门用来采集流媒体(音视频设备)信息及媒体流合成的,也可以用 OBS 等强大的推流工具。
当开播工具采集到媒体信息之后会进行本地压缩,然后通过 RTMP(Real Time Message Protocol) 协议将数据推送到RTMP服务器。
RTMP服务器收到流媒体数据之后,会将流信息解码并且进行 HLS(HTTP Live Streaming) 文件切片。
1.1 为什么拉流使用 HLS 而不是 RTMP?
1. 播端使用RTMP,是因为RTMP基于TCP的实时协议,可以保证推流的可靠性和实时性。
2. 看端使用HLS是因为HLS是基于静态小文件,这就比较方便在大规模百万 PCU(Peak concurrent users ) 时,利用静态CDN容易分发的优势来覆盖。
3. 使用HLS同时也便于在不同码率之间进行动态切换,以此来达到根据用户的网络情况选择最优的观看体验。
比如,用户处于弱网下,我们就切到低码率下观看。
用户网络良好时,我们就切到高码率下观看,同时也可以使用一些高级的观看体验和交互。
当然,HLS还有非常多的优势,在压缩、加解密等方面都非常成熟。
在2C大规模直播场景下,flv是过去时,HLS才是未来。
【P2P】(具体可以了解 WebRTC 入门了解,基本使用记录_webrtc 如何使用-CSDN博客)
为了尽可能节省CDN带来的巨大成本,会使用 P2P(Peer to Peer) 技术来减少公有云带宽使用。
1.2 常见流媒体协议
1)RTP实时传输协议(Real-time Transport Protocol或简写RTP): 用于直接封装音视频数据的封装载体,支持UDP或者TCP传输。
2)RTCP RTP Control Protocol: 一种调整协议,一般配合RTP使用。例如一对一通话时,接收端网络不好,那么接收端会将卡顿的问题通过RTCP协议发送给发送端,发送端收到后调整发送速率,例如降低码率、分辨率等等。
3)RTSP (Real Time Streaming Protocol),RFC2326,实时流传输协议: 安防方面使用最多,例如海康、大华、宇视等品牌都支持取rtsp流播放。可认为是一个容器,内部最终使用RTP、RTCP实现。因为RTP支持TCP、UDP,所以RTSP也是支持的,但也因为这样,所以会比较复杂。
例如rtsp的端口不管tcp还是udp,都只占用配置好的554端口。而在TCP下,RTCP视频、RTCP音频、RTP视频、RTP音频也是共同占用一个端口,并且也是554。
但是在UDP下,RTCP在音视频各自占1个,是独立的,RTP也是音视频各自一个,也是独立的。
此外,RTSP的交互还需要用到信令,它基于SDP协议。
4)RTMP RTMP是Real Time Messaging Protocol(实时消息传输协议): 主要用于推流,拉流比较少,因为需要flash插件,所以在拉流方面逐渐被HTTP-FLV、HLS、WebRTC淘汰。
并且,RTMP目前主流是TCP,很少会有人支持UDP,如果使用UDP传输的话,那么你就不要选择RTMP。因为RTMP 内部没有处理数据丢包重传,如果用UDP的话,需要自己处理数据重传的问题,所以有的公司把数据传输这块改成quic的协议。
5)HTTP-FLV: HTTP-FLV可以推拉流,但是很少用于推流(估计是效果不如RTMP这些),主要用于拉流,通过http协议,拉取flv协议格式的文件进行播放。flv不能直接在html的video标签播放,需要使用flv.js第三方插件处理。
6)HTTP-MP4: 主要用在点播,没办法用于直播。因为mp4必须要读到尾部即要等mp4流全部下载完后才能播放,而实时流你根本无法读到像文件末尾这样的尾部。
点播、录播、直播的区别:
点播就是我们平常点击视频后,它就可以播放,并且我们可以想放就放,可以想暂停就暂停,相当于播放一个文件,时长一般比较短。
而录播则是对直播的回放,它也是一个名义上的直播,我们不能想放就放,不能想暂停就暂停,例如央视回放某足球赛事,时长一般比较长,因为这类直播是知道视频的固定大小的,MP4对于完整的视频可以把box提到头部去,所以理论上HTTP-MP4应该也是支持录播的(可以自行百度,笔者未验证过)。
直播比较简单,就是我们平时在某鱼、某牙等等看到的直播。
7)HLS: 苹果公司推出的协议,该协议会将音视频数据切割成多个ts文件,m3u8文件会统计这些ts文件。电视播放目前主要就是使用这种协议。
优点:流畅度好,跨平台性好,rtmp不能在手机端播放,而http-flv在手机端支持也不是特别友好,而hls可以在web(html原生支持)、手机app(苹果原生的Safari浏览器原生支持)、手机小程序播放。可以无缝切换高清 / 标清的清晰度。例如,当切换清晰度时,后台在推流时会提前准备几套不同码率的视频,即高清、标清的推流。此时假设用户在读取一个时长为5秒的ts文件,在第二秒时,用户切换清晰度,那么下一秒(更具体点应该是下一帧)只需要换成高清的流即可。
缺点:正因为将音视频数据切成多个ts文件,所以延时比较大,一般在30s到2min左右。
8)WebRTC:Web的实时通话,如果你想要实时通话的话,那么WebRTC是唯一的方案,因为WebRTC才是双向交流的,而其它协议例如RTMP、HTTP-FLV这些要么只适合推流要么只适合拉流。在使用场景方面,在一对一实时通话、安防、云游戏等方面都已经在使用了。例如流媒体服务器SRS、ZLMEDIAKIT,安防方面的LiveGbs等等都已经在使用了。
因为目前前景都是趋于web化,例如人们看视频直播不想下载手机app、电脑客户端,而是想直接在网页就能观看,所以这个协议目前算是最火的一个。
额外提醒:
1. 视频在传输时不需要再使用zip压缩,效果不大,并且视频在传输前已经使用h264、h265等编码技术进行压缩了。
2. WebRTC不能大规模直播(同时在线5000或者10000人以上算大规模)使用。因为WebRTC走UDP,如果中间转发节点多且网络不好,那么一层一层丢包下来,会导致画面严重失真。
如果直播并且不需要双向通话的话,那么使用rtmp推流,HTTP-FLV、HLS拉流是个很好的选择。
2. 功能拆分,范例抖音界面功能。
2.1 短视频界面功能
功能 | 说明 |
用户头像 | |
点赞数 | |
弹幕(发言,发言列表(根据时间展示)以及弹幕开关) | |
评论数(点击评论) | |
收藏数 | |
转发数 | |
相关视频 | |
视频 - 视频流 | |
视频 - 视频详情(时间,up 名,内容,标签,视频时长) | |
播放(暂停) | |
。。。其他功能 |
2.2 直播界面
2.3 直播界面功能拆分
功能 | 说明 |
up 头像(详情信息) | |
当前用户关注状态 | 未登录默认展示未关注 |
直播时长排行榜 | |
购物车 | 列表,物品详情、购买等 |
礼物 | |
当前送礼榜单 | |
在线观众 | 人数、人数列表信息 |
弹幕 | |
直播pk | |
...其他 |
【发送弹幕】
功能:观看直播时非常重要的一个诉求就是与主播互动,而弹幕是信息承载量最大的互动方式。
弹幕从发送到接受,依赖 长连接 中间件。
考虑到平台可用性,长连接服务整体需要支持容灾,整个架构需要支持多机房混合部署。
在弹幕消息投递端需要做机房线路探活,根据探活后的相关数据择优选择机房。
使用公有云还有一个好处,可以享受一定额度 “对等连接” 增值服务。
整体架构越来越趋向混合云,就是为了尽可能平衡私有云的核心数据闭环,同时借助公有云强大的网络覆盖。
公有云高性能主机一般在低频下能扛个百万连接,瓶颈基本在内存和带宽。
机器成本其实还好,因为机器理论上可以无限扩展,但是带宽是有物理上限的,所以比较贵。
【整体链路】
我们将整个链路分两层,第一层是售卖业务层,该层由一系列售卖单元组成,比如商城、促销中心等。
在直播领域,送礼系统就是位于这一层,送礼物可以认为是一种虚拟商品的交易。
送礼场景可以非常多样化,但都是在变相的促进交易的达成。
一旦当商品售卖成功之后,根据业务性质的不同,确认收入的金额和时间点也不同。
在直播送礼中,送出去的礼物基本就是近实时确认收入,此时就需要交易订单(或叫业务订单)来承载这部分交易职责。
在售卖业务层下层是交易结算层,是收入的分账、结算、打款部分。
该部分的核心是支撑业务售卖的交易,清结算各个角色的收入。是交易结算系统最复杂的地方,也是及容易出现资损的地方。
不论我们售卖什么,要想在交易系统里完整的跑起来,首先就需要将虚拟的售卖概念进行商品化。
有了商品之后就可以通过售卖层上架去销售。
送礼本身业务比较简单,将个人账户的虚拟资产进行扣除,加到主播账户中去,就完成了业务上的基本流程。
这一步完成之后,紧接着就需要对这笔交易订单进行分账处理。需要分别计算平台、外部商家/机构等各个角色参与者分别得多少钱。
送礼成功之后至少是需要平台、主播(或工会)进行一定分成。
该部分是清结算系统中的清算部分职责,该部分通过计费、分摊分别计算好各个角色结算明细。
结算系统再通过定期捞取合同签订的结算周期(T+N/月结等)给商家结算并且打款,该部分多数是有账期的。
简言之,送礼打赏偏交易结算领域,整个系统的核心在于账务、交易、财务等业务知识。
同时在系统设计上,数据一致性、对账流程和场景是整个系统架构设计的核心。
【房间互动】
在直播间里,送礼不管对主播还是平台来说,都是最终目的。但是这个最终目的不可能一步达到,是需要不断的通过其他场景来转化。
直播用户的绝大部分需求是荷尔蒙需求,如何通过各种互动工具、互动形式,让用户与主播彼此多互动,才能促进送礼。
从用户视角来看互动形式主要分为三类,弹幕、手势/摇杆、送礼、视频连线。
我们先来看前三种互动方式。
如抖/快双击屏幕点赞,虎牙的长按唤起快捷面板,B站的发送特殊弹幕触发“热力风暴”特效等。
同时基本每家都有的特殊礼物互动,通过赠送特殊礼物来达到房间主题变化、主播装扮变化等。
所有的互动形式我们都需要统一的进行抽象管理,可以用一句话概括: “在指定的房间指定的时间段,启用一个或多个互动活动/玩法”。
至于某个具体的互动玩法,该玩法需要哪些素材,需要哪些触发媒介,除了通道部分可以走订阅方式,其他都需要定制开发。
比如,弹幕互动中的蓄力类的,除了通用的弹幕通道之后,哪些词,在多少时间窗口内命中多少次,然后触发什么业务逻辑。
或连击送礼蓄力类,除了送礼通道是通用部分之外,哪些礼物,在多少时间窗口内送出多少个,金额满足多少都属于业务逻辑需要捕获和处理的地方。
整个互动是需要打通看端和播端。
看端特效和播端特效是有明显区别的,看端多数是在直播间里可以交互的特效元素,而播端特效最终是在流里体现的。
比如,一个送礼互动特效,用户“连续”赠送礼物到达一定的阈值就触发播端的互动逻辑,最终将消息输入到流里,同时看需求是否添加 SEI(Supplemental Enhancement Information) 信息。
【视频连线】
与前三种互动方式不一样的是,视频连线是基于音视频技术的通用能力,强依赖多媒体技术栈,涉及到编解码、合流等。
不仅可以用在用户与主播连线,主播与主播也可以基于视频连线能力扩展很多互动形式,如视频PK(Battle)等。
我们看下主播与主播的视频连线整体流程。
整个流程基于频道(channel)做为外部供应商和内部服务的一个逻辑上下文,用来串联客户端、服务端、外部sdk。
该架构通过外部sdk合流,会增加一定的带宽成本,属于不那么经济的方案,最大的好处是实现简单并且可以保证观看端音画同步。
【房间主题】
如果我们将直播间比喻成现实中的房间,我们希望是千人千面的,并且具有一定的定制性。
同时,我们希望房间可以根据日历自动感知到节日的 娱乐性 、 严肃性 。
如果将直播间比喻成线上的社区单元,那此地也不是法外之地,需要受到不同程度的舆情、社敏性、法律安全监管。
直播间按照业务形态划分,有非常多的维度去分,比如商业化房间(带货/电商/分销)、游戏房间、K歌房、放映厅等。
最终,不同的房间需要开放、管制一些能力,互动娱乐,送礼,主播行为等。
日历和主题管理是整个房间生成的基础基因。
需要对房间整个架构进行工程化设计,要面向接口、面向开放标准。
只有这样才能具备定制性和扩展性。
整个房间大概有几个核心区域, ___送礼区、播放器区、弹幕区、互动区。
这几个区域的实现需要分成两层,第一层实现最核心的内核基础功能。
这部分功能可以直接排除主题相关性。
第二层是其他带有装饰的功能,这部分实现需要具备主题感知能力。
在此基础之上,我们假设实现一个弹幕区的特殊弹幕效果。
该实现插件通过工程化接口和标准,拿到日历&主题便可以感知到节日的属性。在实现上可以分离出基础功能和效果功能。
这样设计还便于将效果类功能做全年的特殊节日的自动化测试和业务巡检。
房间推荐算法需要加入日历推荐因子,这部分是比较好理解的。比较有意思的是房间构造中心才是房间成品的出口。
【活动保障】
最后分享下技术保障方面的内容。
这部分就精简总结下,不叙述过程。
简言之,保障主要关注两个重点。
第一个重点是我们大多数比较熟悉的应用系统常规的抗高并发,这里包括一系列的中间件、DB、缓存、微服务套件等。
第二个重点是跟PCU相关的线性资源CDN带宽、P2P带宽、长连带宽、打点、实时报表计算等。
按照看、播两端分别来看。
播端,需要重点保障推流的可用性,所以基本上在推流侧至少有两路流互相backup。
看端,QPS、TPS相关接口基本是斜率或突增流量相关。
(注:某接口峰值可以扛住10wQPS,到达这个峰值是每秒钟加1w缓慢增加,还是1s到达10w是不一样的。)
斜率本质考验的是后端相关资源的扩容速度。
在大并发场景下,有时候我们需要提前扩容就是为了防止突增流量。
这也是按照斜率来评估扩容资源的难点。
另外一方面是跟PCU线性相关的。
PCU直接带来的是相关公有云带宽、连接池等比例增加,这部分需要做好资源预购。
当在线的人数非常高时,数据上报、实时数据处理也都是线性增加的。
这部分存储资源是需要提前预备好,计算资源可以适当弹性调度。
所有上述场景在合理的容量范围内系统都可以承载,但是一旦有非预期的流量进来我们也要有自我保护的机制和拉闸能力。
这部分相关的,限流、降级能力也是必不可少的。
引用文献:
大型直播平台应用架构浅谈_直播paas平台-CSDN博客(https://blog.csdn.net/wangqingpei557/article/details/122908851 )
go语言实战-----31-----流媒体架构设计之直播架构、音视频通话(常见 流媒体协议 解释)_go 音视频-CSDN博客(https://blog.csdn.net/weixin_44517656/article/details/124330093)