搭建视频服务器,和普通Web服务器完全不是一回事。Nginx搭建网站,调整配置就能正常运行;但视频服务器持续处理流式数据,对时间延迟、丢包、磁盘IO都很敏感。很多新手第一次搭建视频服务,直接用Nginx搭配mp4模块上线,结果三个人同时播放就卡顿严重。
流媒体传输和普通HTTP请求机制不一样
普通网页请求属于一次性交互,服务器发送完HTML、图片资源,连接就断开。视频播放不一样,用户点开视频之后,服务器需要持续推送数据;网络一旦出现波动,用户端就会转圈缓冲。只依靠TCP协议不足以解决问题,TCP丢包后的重传机制会拖慢整个视频流,用户会看到画面卡顿之后突然加速追赶进度,观感很差。所以大部分视频服务器底层使用UDP搭配自研可靠性层,比如QUIC或者基于RTP的私有协议。开发这套协议栈工作量很大,要处理数据包乱序、丢包重传、拥塞控制、抖动缓冲,任意环节调试不到位,都会直接体现在播放画面上。

转码是很难绕开的难点
用户上传视频格式五花八门,手机拍摄大多是H.265,录屏文件多为H.264,分辨率、码率各不相同。想要让所有设备都能正常播放,就必须做转码。转码就是把视频解码成原始帧,再按照目标编码格式重新压缩。这个操作非常消耗CPU,普通四核服务器用软件编码,转码一路1080p视频速度大概只有0.3倍速,十分钟的视频需要半个多小时完成转码。想要同时多路实时转码,就要使用GPU或是专用编码卡,硬件成本会大幅上涨。而且转码不是一次就结束,需要为不同带宽用户生成多档码率,一份视频生成360p、720p、1080p三个版本,工作量直接翻三倍。
存储和回源策略
视频文件体积大,一小时1080p视频文件大小可达几个GB。用户点播时,如果全部直接从源站读取文件,磁盘IO扛不住大量并发访问。所以视频服务器前端一般搭配CDN,把热门资源缓存到边缘节点。但哪些资源缓存、缓存保留时长、什么时候回源读取原文件,这套策略配置起来很繁琐。缓存资源过多会浪费存储和带宽资源,缓存太少会降低命中率,源站压力变大。视频还有一个特点,很多用户不会完整看完,拖动进度条、反复回看片段很常见,这就要求CDN支持Range请求,边缘节点能够处理分片读取。自己开发这套逻辑,远比想象麻烦。
直播和点播的技术栈差异很大
点播可以提前完成转码、切片,依靠HLS或者DASH把视频切分成小段,客户端按需拉取。直播对延迟要求高,切片大小一般控制在2至6秒,切片时间一到服务器就要立刻生成新片段供客户端拉取。编码器实时性要求高,还要处理音视频同步、时间戳对齐、GOP边界对齐等细节。延迟控制到3秒以内算合格,想要压到1秒以内,就要使用WebRTC方案,整体复杂度继续上升。
并发和弹性伸缩
视频服务器并发模型和Web服务器不一样。Web请求属于短连接,处理完成就释放资源。视频属于长连接,单个用户会占用连接几分钟甚至几十分钟。一万人同时在线,服务器要维持一万条活跃连接,每条连接持续收发数据。内存管理、文件句柄、网络缓冲区都需要精细调优。而且流量波动明显,晚上八点访问量可能比凌晨高出几十倍,服务器需要快速扩容。自建方案一般采用容器搭配自动伸缩组,但伸缩触发条件、冷启动耗时、状态同步等问题,调试起来要花费大量时间。
搭建一套可用视频服务器的可选路线
如果不想从零开发协议栈,开源方案足够满足基础需求。点播场景,Nginx搭配nginx-vod-module或者nginx-rtmp-module就能实现基础功能,支持HLS、DASH切片,配置难度不算高。直播场景,国产开源SRS使用人数较多,支持RTMP推流、HLS和HTTP-FLV拉流,单机可以承载几千并发,社区活跃度高。想要更现代的方案,可以选MediaMTX,基于WebRTC,延迟更低,但生态完善程度不如SRS。
自建大致流程:先安装操作系统,Ubuntu、CentOS都可以,配置防火墙和安全组,推流端口和拉流端口分开设置。接着部署流媒体服务端,SRS提供官方一键安装脚本,执行完成即可使用。然后配置推流端,OBS是最常用工具,填写推流地址rtmp://你的服务器IP/live,自定义串流密钥,点击开始推流。服务端收到流之后生成播放地址,HLS地址格式是http://IP/live/密钥.m3u8,HTTP-FLV地址为http://IP/live/密钥.flv。播放端可以使用VLC播放器或是网页播放器拉流。
搭建过程几个常见坑。服务器带宽要充足,一路1080p直播大约需要3到6Mbps上行带宽,十路并发就要几十兆带宽。云服务器按量计费模式下,带宽开销甚至高于服务器本身。磁盘空间要预留充足,HLS切片会持续生成大量小文件,如果不做自动清理,几天就会占满磁盘。推流密钥不要设置简单字符,容易被猜测盗推。如果对外网提供服务,最好增加鉴权机制,SRS支持HTTP回调鉴权,推流和拉流的时候访问业务服务器校验权限。
视频服务器做到能正常运行不难,难的是稳定运行、控制成本、长期维护。上面提到的每一个点单独拿出来都可以写长篇内容。实际动手前,先确定场景是点播还是直播,部署在内网还是公网,预估并发规模,把预算和精力放在影响播放体验的核心环节,不要追求一次性把所有功能做到完美。