RTMP直播协议详解
又有人问RTMP?这都是上个世纪的古董了啊...
刚才顺手点开论坛,发现又有个小白在求教rtmp怎么搞。我这会儿正好在等C++这破玩意儿编译,风扇转得跟直升机起飞似的,就随便敲两句吧。说真的,看到这四个字母我脑瓜子就嗡嗡的,当年为了调这个bug我发际线又后移了两厘米!!!
Adobe留下的烂摊子
先说说背景吧,RTMP全称Real Time Messaging Protocol。听着挺高大上是吧?其实就是Adobe当年为了推Flash搞出来的私有协议。现在Flash坟头草都两米高了,结果这玩意儿在直播协议界居然还活着,而且还被同行们用各种姿势魔改,简直就是个打不死的僵尸。
这破文档写得跟天书一样,官方规范里连个图都懒得画,当年我看的时候由于过于激动甚至想写个死循环把Adobe的服务器炸了。
但没办法,老板要搞直播,你不用它用啥?
核心概念:切西瓜与握手
这协议的核心逻辑,就像你穿着燕尾服在泥坑里抓泥鳅,看着讲究其实特别别扭。它非要把好好的数据流切成一块一块的,叫Chunk。为什么?因为当年网络差呗,怕一个大包把带宽堵死。这设计放现在看简直绝绝子。
- 握手(Handshake): 客户端和服务器先对个暗号。C0,C1,C2...搞得跟地下党接头一样,其实就是互相发点随机数确认眼神。
- 分块(Chunking): 把视频帧大卸八块。你要是Chunk Size设置得不对,画面卡得能让你想砸键盘。
哎不对,刚才说岔了,回来回来。其实这玩意的优势还是有的,就是推流稳,各大CDN对它的支持那是相当成熟。
从烂尾项目扒出来的祖传代码
给你们看一段我前几年写的代码。那是个做了一半老板就跑路了的直播app,代码我都懒得重构,直接拿来当反面教材。
def start_rtmp_handshake(socket_conn):
# 别问为什么这么写,问就是为了上线 tmp_c0_c1 = generate_random_crap(1537) socket_conn.send(tmp_c0_c1) legacy_data = socket_conn.recv(1537) if len(legacy_data) < 1537: # 我心态崩了,网络又抖动了!!! return False # 凑合验证一下得了,反正也没人真查 if legacy_data[0] != 0x03: print("version error!!!") return False c2_payload = legacy_data[1:] # just copy it... socket_conn.send(c2_payload) return True警告各位新人:千万别在生产环境这么写!!!上面这坨代码没有处理粘包,没有异常重试,遇到弱网环境直接原地爆炸。我当时赶着半夜三点发版,能跑通就谢天谢地了。
性能对比:同行全靠衬托
最后随便扯扯性能。现在市面上的直播协议,RTMP算是中庸之道。延迟大概在1到3秒之间。你要是遇到那种要求HLS协议还要做到0延迟的产品经理,建议直接拿键盘拍他脸上。HLS那种切片协议,延迟起步就10秒,就像你在早高峰的地铁上试图吃韭菜盒子,怎么可能快得起来?
至于WebRTC,那是现在的新宠,延迟能干到毫秒级,yyds。但服务器带宽成本高得能让财务大姐天天找你喝茶。所以目前国内推流还是RTMP的天下,拉流再转成FLV或者HLS。这就叫妥协,懂不懂?
别白嫖了,赶紧点关注
行了,编译终于跑完了,满屏的Warning我都当没看见。今天就给你们这帮菜鸟指点到这里。要是觉得我这篇老油条的经验之谈帮你避了坑,赶紧把关注点上!别逼我顺着网线过去在你的代码里埋个内存泄漏的雷,到时候你连怎么死的都不知道。记得一键三连,下次再给你们扒点更劲爆的架构内幕!
更多推荐
所有评论(0)