6.2 推流与拉流:让管线跑在网络上


6.2 推流与拉流:让管线跑在网络上

本节摘要:推流是「把管线输出送进服务器」,拉流是「从服务器取流解码播放」。本节给出本地起服务器、ffmpeg 推流、ffplay 拉流的一整套可运行流程,并讲解 -re、-fflags nobuffer、-tune zerolatency 等关键参数的意义。

学习目标

阅读完本节,你应当能够:

  1. 在本地搭一个可用的流媒体服务器
  2. 用 ffmpeg 完成推流,用 ffplay/ffprobe 完成拉流与验证
  3. 解释 -re、-tune zerolatency、-fflags nobuffer 各自解决什么问题

一、场景代入:从零推一路直播

假设你要做一个「摄像头画面推到网页播放」的小项目。链路是:摄像头(或视频文件)→ 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 流(从 RTMP 转 HLS 的场景)

如果服务器配了 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 退出,配合外层脚本循环重启即可实现重连。

用一张图记住推拉链路的完整结构:

06-02-fig01

图说明:一条完整的直播链路

视频源 → 推流端 → 服务器 → 拉流端,四段职责分明。排错永远从「流上线没有」开始(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

这条命令的关键在 setptsasetpts:它们把视频和音频的时间戳都改写成「按帧序均匀分布」,从根本上消除采集中引入的时间戳抖动。fps=25 强制视频帧率,aresample=48000 统一音频采样率。推流出现「越来越不同步」的现象时,先检查采集源,再检查时间戳——这比反复调码率有效得多。

要点回顾

  • 推流三件套:-re(按原速)、-c copy(不转码)、-f flv(RTMP 封装)
  • 验证先行:ffprobe 确认流上线,ffplay 确认能播,再谈参数
  • 低延迟参数:拉流端 -fflags nobuffer,推流端 -tune zerolatency
  • 断流重连:-rw_timeout 设置超时,配合外层循环实现重试
  • 排错顺序:流上线 → 能播 → 卡顿优化 → 断流重连,逐段定位

下一节回到处理性能本身——推流之前编码能不能再快,第 7 章硬件加速登场。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U