本节摘要:推流是「把管线输出送进服务器」,拉流是「从服务器取流解码播放」。本节给出本地起服务器、ffmpeg 推流、ffplay 拉流的一整套可运行流程,并讲解 -re、-fflags nobuffer、-tune zerolatency 等关键参数的意义。
阅读完本节,你应当能够:
假设你要做一个「摄像头画面推到网页播放」的小项目。链路是:摄像头(或视频文件)→ ffmpeg 推流 → 流媒体服务器 → 播放端拉流。这个链路里的每一段,FFmpeg 都出得上手。
先起一个本地流媒体服务器。Nginx 的 RTMP 模块或 SRS 都行,这里以最简单的 SRS 为例:
# 下载并启动 SRS(单机模式,默认 1935 端口) ./objs/srs -c conf/srs.conf
SRS 起来后,本机就有了一个接受 RTMP 推流的入口 rtmp://127.0.0.1:1935/live。
# 把本地视频按原速推给服务器 ffmpeg -re -i input.mp4 -c copy -f flv rtmp://127.0.0.1:1935/live/stream1
三个关键点:
-re:按视频的原始帧率读取,否则 ffmpeg 会「读得飞快」,几秒就把整个文件推完。它是推流和本地转码最重要的区别。-c copy:直接拷贝编码数据不转码。直播首推,因为转码会拖慢推流速度。-f flv:RTMP 承载的是 FLV 封装,必须显式指定。# ffprobe 确认流已上线 ffprobe -v error -show_entries stream=codec_name,codec_type -of csv rtmp://127.0.0.1:1935/live/stream1 # ffplay 直接播放 ffplay rtmp://127.0.0.1:1935/live/stream1
看到编码信息说明推流成功。
如果服务器配了 HLS 输出,播放端可以走 HTTP:
ffplay https://127.0.0.1:8080/live/stream1.m3u8
HLS 拉流是「HTTP 拉文件」,天然能过 CDN,这是它被广泛用于分发的原因。
拉流端卡顿、花屏,先加这几个参数试试:
# 拉流端:不缓冲、低延迟 ffplay -fflags nobuffer -flags low_delay -framedrop rtmp://127.0.0.1:1935/live/stream1
-fflags nobuffer:不让播放器攒缓冲,响应快,但更容易卡(网络不好时)-flags low_delay:解码端低延迟模式-framedrop:跟不上就丢帧,保住实时性推流端要低延迟转码,给编码器加:
ffmpeg -re -i input.mp4 -c:v libx264 -preset ultrafast -tune zerolatency \ -c:a aac -f flv rtmp://127.0.0.1:1935/live/stream1
-tune zerolatency 是 x264 的「零延迟」调优参数,砍掉 B 帧、禁用延迟缓冲,是直播转码的标准配法。
# 推流断线自动重试 ffmpeg -re -i input.mp4 -c copy -f flv -rw_timeout 5000000 \ rtmp://127.0.0.1:1935/live/stream1
-rw_timeout 设读写超时(微秒),断了之后 ffmpeg 退出,配合外层脚本循环重启即可实现重连。
用一张图记住推拉链路的完整结构:

视频源 → 推流端 → 服务器 → 拉流端,四段职责分明。排错永远从「流上线没有」开始(ffprobe),再逐段定位——推流端卡还是拉流端卡,参数完全不同。
⚠️ 常见坑:忘记
-re会把文件几秒推完;RTMP 地址写错会报Connection refused,先ffprobe确认端口通;服务器没配 HLS 却拉.m3u8会 404。所有「推不上去」「拉不下来」的根因,一半在参数、一半在服务器配置。
💡 关键直觉:推流是「按节奏喂数据」,拉流是「按节奏取数据」。
-re控制喂的节奏,缓冲参数控制取的节奏。把节奏感建立起来,直播问题的排查思路就通了。
推流最容易出现的隐蔽问题是音画不同步——画面已经比声音慢了一拍,但没有任何报错。根源通常在采集端:摄像头采集的帧率不固定(VFR),或者音频设备延迟不稳定,导致时间戳对不齐。
# 采集摄像头推流时强制统一帧率,并给音频和视频都设置同步基准 ffmpeg -f v4l2 -framerate 25 -i /dev/video0 -f alsa -ar 48000 -i default \ -vf "fps=25,setpts=N/(25*TB)" -af "aresample=48000,asetpts=N/SR/TB" \ -c:v libx264 -preset ultrafast -tune zerolatency -c:a aac \ -f flv rtmp://127.0.0.1:1935/live/cam
这条命令的关键在 setpts 和 asetpts:它们把视频和音频的时间戳都改写成「按帧序均匀分布」,从根本上消除采集中引入的时间戳抖动。fps=25 强制视频帧率,aresample=48000 统一音频采样率。推流出现「越来越不同步」的现象时,先检查采集源,再检查时间戳——这比反复调码率有效得多。
下一节回到处理性能本身——推流之前编码能不能再快,第 7 章硬件加速登场。