视频直播服务器配置推荐

结论: 视频直播服务器配置的核心公式是「出网带宽 = 单路码率 × 并发观看人数」:1080p 按 4 Mbps 估算,100 并发就要 400 Mbps 出网。架构上按「推流—转码—分发」三层拆分,源站 4~8 核起步,多路转码优先用 GPU 硬编,分发层交给 CDN。

引言:直播服务器为什么不能按"建站配置"来买

很多团队第一次搭视频直播服务器,直接照搬网站服务器的选型思路:2 核 4 GB、5 Mbps 带宽。结果推流很稳,一有人进来就卡成 PPT。原因是直播的压力模型和网站完全不同——网站瓶颈通常在 CPU 与数据库,而直播的瓶颈几乎永远在出网带宽和第二层的转码算力。

一台直播源站同时要干三件事:接收主播的推流(上行)、把码流转成多档清晰度(转码)、把流分发给成百上千的观众(下行)。这三层可以挤在一台机器上跑小规模业务,但只要并发超过几百,就必须拆开设计。本文给出可直接套用的配置口径:带宽公式表、CPU/GPU 核数估算、协议选型表、SRS 部署命令与 ffmpeg 实操,全部基于 2026 年主流版本(Ubuntu 24.04 LTS、SRS 5.x、FFmpeg 6.x)。

直播服务器的三层架构分别负责什么?

先给结论:直播系统一定要按「接入层(推流)→ 处理层(转码/录制)→ 分发层(播放)」拆分,三者瓶颈不同、扩容方式也不同。混在一台机器上,只能做 200 并发以下的验证场景。

text
主播端 OBS / 手机 SDK
        │  RTMP / SRT 推流(上行,1 路或几路)
        ▼
【接入层 · 源站】SRS / nginx-rtmp / ZLMediaKit
        │  鉴权、录制、截图、转封装
        ▼
【处理层 · 转码】FFmpeg 软编(libx264)或 GPU 硬编(NVENC / QSV)
        │  输出 1080p / 720p / 480p 多档 + 水印 + 录制切片
        ▼
【分发层】自建边缘节点 或 CDN
        │  HTTP-FLV / HLS / WebRTC 拉流(下行,N 路)
        ▼
观众端 flv.js / hls.js / 原生播放器

三层的关键差异:

  • 接入层吃的是上行带宽与连接数,压力很小(哪怕 50 个主播,也只是 50 路上行)。
  • 处理层吃 CPU 或 GPU,压力与"路数 × 档位数"成正比,与观看人数无关。
  • 分发层吃下行带宽,压力与"码率 × 并发人数"成正比,是唯一的线性放大项。

所以扩容顺序永远是:先把分发甩给 CDN,再考虑转码加 GPU,最后才升级源站 CPU。

直播需要多少带宽?码率 × 并发怎么算?

先给结论:所需出网带宽(Mbps) ≈ 单路码率(Mbps) × 并发观看人数 × 1.1(协议与重传开销)。下面这张表按该公式直接算出常见清晰度下的并发需求(截至 2026 年主流编码 H.264/AV1 参考值)。

清晰度分辨率 / 帧率推荐码率(H.264)100 并发500 并发1000 并发
流畅640×360 @25fps0.8 Mbps88 Mbps440 Mbps880 Mbps
标清854×480 @25fps1.2 Mbps132 Mbps660 Mbps1.32 Gbps
高清1280×720 @30fps2.5 Mbps275 Mbps1.38 Gbps2.75 Gbps
全高清1920×1080 @30fps4 Mbps440 Mbps2.2 Gbps4.4 Gbps
全高清高帧1920×1080 @60fps6 Mbps660 Mbps3.3 Gbps6.6 Gbps
2K2560×1440 @30fps8 Mbps880 Mbps4.4 Gbps8.8 Gbps
4K3840×2160 @30fps16 Mbps1.76 Gbps8.8 Gbps17.6 Gbps

换算与选型要点:

  • 1 Mbps ≈ 128 KB/s。4 Mbps 的 1080p 单路,一个观众每秒吃掉 512 KB 流量;1000 人看 1 小时就是 1.8 TB 出网流量。
  • 看带宽单价,更要看带宽上限。国内云服务器常见 1~200 Mbps 单台上限,10 Gbps 需要专用机型或裸金属;海外 VPS 常给 1 Gbps 端口但按月流量计费,需按上式先算月度流量。
  • 多档码率会放大带宽。如果同时提供 1080p/720p/480p 三档,且观众均匀分布,实际带宽按加权平均算,通常比单档 1080p 低 25%~40%,这也正是转码存在的价值。
  • 推流上行只算路数,不算人数。50 路 1080p 推流上行 ≈ 50 × 4 Mbps = 200 Mbps,与观众数量无关。

CPU 软编还是 GPU 硬编?核数怎么估算?

先给结论:1~3 路转码用 CPU 软编最省心,4 路以上建议上 GPU 硬编或专用转码卡。CPU 软编画质与码率控制最好,但每路成本是硬编的 5~10 倍。

编码方式单路 1080p30 转码开销并发 10 路 1080p 所需画质成本口径
libx264 preset=medium约 4~6 核48~72 核(不现实)最好高
libx264 preset=veryfast约 1.5~2 核18~24 核良好中
libx264 preset=ultrafast约 0.8~1 核10~12 核偏差,码率高低
NVIDIA NVENC(T4/A10/L4)单卡可 10~25 路1 张卡接近 veryfast低(卡贵但摊薄)
Intel Quick Sync(QSV)核显可 3~8 路1 颗带核显的 CPU良好几乎免费
Apple/ARM 硬编视平台而定——边缘场景

核数估算公式(软编):

text
所需物理核数 ≈ 转码路数 × 单路核数 × 档位数 × 1.3(系统+网络中断+冗余)

举例:10 路 1080p 输入,每路输出 1080p + 720p 两档,用 veryfast:

text
10 × 1.8 × 2 × 1.3 ≈ 47 核

这个数字已经远超一台普通 16 核服务器,说明超过 10 路的多档转码必须走 GPU。而如果只是转封装(H.264 原样转发,不改码率不缩放),CPU 占用接近于零,8 核机器扛几百路都没问题——这也是 SRS 默认不做转码、只做 remux 的原因。

选购建议:

  • 100 并发以内的内部培训/活动直播:4 核 8 GB、30~50 Mbps 出网,CPU 转封装即可,不上转码。
  • 500~2000 并发的公开直播:8 核 16 GB 源站 + CDN 分发;如需多档清晰度,加一张入门级 GPU 或直接用云厂商的转码服务。
  • 万人以上或互动连麦:源站集群 + 专用媒体处理(MCU/SFU)+ CDN,自建不再划算。

直播协议怎么选?RTMP、HTTP-FLV、HLS、WebRTC 对比

先给结论:推流用 RTMP(弱网用 SRT),低延迟拉流用 HTTP-FLV,移动端和 CDN 分发用 HLS,连麦互动用 WebRTC。没有一种协议通吃,通常是"上行 RTMP + 下行多协议"的组合。

协议典型端到端延迟传输层主要用途浏览器/客户端支持备注
RTMP1~3 sTCP 1935推流上行事实标准播放需插件,已淘汰下行已被 FLV/HLS 取代
HTTP-FLV1~3 sTCP 80/443国内低延迟拉流主流flv.js(MSE)穿防火墙好,长连接
HLS6~20 s(切片 3~10 s)HTTP移动端、CDN 友好原生(Safari/Android),hls.js延迟高但最稳
LL-HLS / LL-DASH2~5 sHTTP低延迟 + CDN 兼容部分原生需要切片化打包支持
WebRTC200~800 msUDP/SRTP连麦、互动、监控原生分发成本高,规模受限
SRT200 ms~数秒(可配延迟)UDP跨洋/弱网推流、回源需专用客户端抗丢包强,适合跨境
RTSP1~3 sTCP/UDP 554摄像头接入需转换监控场景用,再转 RTMP

选择要点:

  • 国内 PC 端追求"秒开 + 低延迟",HTTP-FLV 是性价比最高的方案,且复用 80/443 端口,不用额外放行 1935。
  • 出海业务优先 HLS:CDN 兼容性最好,iOS Safari 原生支持,不需要额外播放器。
  • 教育/带货连麦必须上 WebRTC,单靠 HTTP-FLV 做不到亚秒级。
  • 弱网或跨洋推流(比如东南亚主播推到国内源站)用 SRT,latency 参数可设 200~2000 ms 换取抗抖动能力。

实操:用 SRS 5.x 部署一台直播源站

先给结论:自建源站最快的路径是 Docker 起 SRS 5.x,一个容器同时具备 RTMP 接入、HTTP-FLV 分发、HLS 切片和 WebRTC 转协议能力,不需要再编译 nginx-rtmp。

bash
# 1. 准备环境(Ubuntu 24.04 LTS)
sudo apt update && sudo apt install -y docker.io docker-compose-plugin
sudo systemctl enable --now docker

# 2. 建目录与配置文件
sudo mkdir -p /opt/srs/{conf,objs}
cd /opt/srs

# 3. 拉起 SRS 容器(1935 推流 / 1985 API / 8080 HTTP-FLV+HLS / 8000 UDP 给 WebRTC)
sudo docker run -d --name srs --restart=always \
  -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 8000:8000/udp \
  -v /opt/srs/conf:/usr/local/srs/conf \
  -v /opt/srs/objs:/usr/local/srs/objs \
  ossrs/srs:5 \
  ./objs/srs -c conf/srs.conf

# 4. 确认端口已在监听
sudo ss -lntup | grep -E '1935|1985|8080|8000'
sudo docker logs --tail 20 srs

对应的 conf/srs.conf(开启 HLS、HTTP-FLV 与 WebRTC 转协议):

nginx
listen              1935;
max_connections     2000;
daemon              off;
srs_log_tank        console;

http_api {
    enabled         on;
    listen          1985;
}

http_server {
    enabled         on;
    listen          8080;
    dir             ./objs/nginx/html;
}

vhost __defaultVhost__ {
    # HLS 切片,移动端与 CDN 回源用
    hls {
        enabled         on;
        hls_fragment    3;
        hls_window      30;
        hls_path        ./objs/nginx/html;
        hls_cleanup     on;
    }

    # HTTP-FLV 低延迟拉流:http://IP:8080/live/stream1.flv
    http_remux {
        enabled     on;
        mount       [vhost]/[app]/[stream].flv;
    }

    # WebRTC:把 RTMP 流转成 RTC 供浏览器亚秒级播放
    rtc {
        enabled     on;
        rtmp_to_rtc on;
        rtc_to_rtmp on;
    }

    # 可选:一路 720p 软编转码(CPU 开销大,按需开启)
    transcode {
        enabled     on;
        ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
        engine hd {
            enabled     on;
            vcodec      libx264;
            vprofile    main;
            vpreset     veryfast;
            vparams { g 60; }
            vfilter { vf scale=1280:-2; }
            acodec      aac;
            abitrate    128;
            asample_rate 44100;
            output      rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
        }
    }
}

播放地址对照(假设服务器 IP 1.2.3.4、应用名 live、流名 stream1):

  • 推流:rtmp://1.2.3.4/live/stream1
  • HTTP-FLV:http://1.2.3.4:8080/live/stream1.flv
  • HLS:http://1.2.3.4:8080/live/stream1.m3u8
  • WebRTC:webrtc://1.2.3.4/live/stream1
  • 服务器状态:http://1.2.3.4:1985/api/v1/streams

用 ffmpeg 推流、拉流转推与链路压测

先给结论:调试阶段用 ffmpeg 的 testsrc2 彩条源代替摄像头,可以完全脱离硬件验证"推流→源站→拉流"整条链路是否通畅;正式运营则用 -c copy 转封装做中继分发,避免不必要的转码开销。

bash
# A. 无摄像头时的彩条测试推流(1080p30 / 4Mbps / 2 秒 GOP)
ffmpeg -re -f lavfi -i testsrc2=size=1920x1080:rate=30 \
       -f lavfi -i sine=frequency=1000:sample_rate=44100 \
       -c:v libx264 -preset veryfast -tune zerolatency \
       -b:v 4000k -maxrate 4500k -bufsize 8000k \
       -g 60 -keyint_min 60 -sc_threshold 0 -pix_fmt yuv420p \
       -c:a aac -b:a 128k -ar 44100 \
       -f flv "rtmp://1.2.3.4/live/stream1"

# B. 推本地文件(务必加 -re 按实时速度读,否则瞬间推完)
ffmpeg -re -stream_loop -1 -i demo.mp4 -c:v libx264 -preset veryfast \
       -b:v 4000k -g 60 -c:a aac -b:a 128k -f flv rtmp://1.2.3.4/live/stream1

# C. 拉流转推(中继到另一台源站或第三方平台,转封装不转码,CPU 近乎为零)
ffmpeg -i rtmp://1.2.3.4/live/stream1 -c copy -f flv rtmp://live.push.example.com/live/stream1

# D. 一路推、多处分发(tee 复用编码结果,比开两个 ffmpeg 省一半 CPU)
ffmpeg -re -i demo.mp4 -c:v libx264 -preset veryfast -b:v 4000k -c:a aac -b:a 128k \
  -f tee "[f=flv]rtmp://a.example.com/live/s1|[f=flv]rtmp://b.example.com/live/s1"

# E. 拉流端验证:看实际码率、帧率与是否有断流
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,r_frame_rate,bit_rate \
        -of default=nw=1 http://1.2.3.4:8080/live/stream1.flv

压测与在线观测命令:

bash
# 实时看网卡出/入带宽(判断分发层是否打满)
sar -n DEV 1
iftop -i eth0 -B          # -B 以字节显示,直观对比码率

# 查看当前在线流与连接数(SRS HTTP API)
curl -s http://127.0.0.1:1985/api/v1/streams | jq '.streams[] | {name: .name, clients: .clients}'

# 用 srs-bench 模拟 500 路并发拉流(压测分发层)
git clone https://github.com/ossrs/srs-bench && cd srs-bench
make && ./objs/sb_rtmp_load -c 500 -r rtmp://1.2.3.4/live/stream1

# 弱网模拟(下行丢包 5%、延迟 100ms,验证 HLS 的抗抖动表现)
sudo tc qdisc add dev eth0 root netem delay 100ms loss 5%
sudo tc qdisc del dev eth0 root   # 测试完务必撤销