教程 · 用于直播视频的 FFmpeg

FFmpeg 推流教程 从一条命令到直播频道

本 FFmpeg 推流教程让你用一条命令就能开播:FFmpeg 读取你的文件、摄像头或屏幕,将其编码为 H.264 视频和 AAC 音频,并通过 RTMP 推送到你的 Primcast 频道。

你会找到每种信号源对应的命令、让观众播放流畅的编码器设置,以及适用于长距离或不稳定连接的 SRT 版本。

ffmpeg · rtmp
ffmpeg -re -i input.mp4 \ -c:v libx264 -preset veryfast \ -b:v 2500k -maxrate 2500k -bufsize 5000k \ -pix_fmt yuv420p \ -force_key_frames "expr:gte(t,n_forced*2)" \ -sc_threshold 0 \ -c:a aac -b:a 128k -ar 44100 -ac 2 \ -f flv "rtmp://USERNAME:PASSWORD@HOST:1935/APP/livestream"

把高亮的词换成你自己的值。第 02 步会解释每个参数。

01

开始之前:FFmpeg 和面板里的四个值

你需要在发送视频的电脑上安装 FFmpeg,并准备好频道的编码器设置。两者都只需要几分钟。

安装 FFmpeg

使用你系统的包管理器安装,然后检查它能否运行。任何当前版本都适用于本页的命令。

安装
# Windowswinget install Gyan.FFmpeg# macOS (Homebrew)brew install ffmpeg# Debian or Ubuntusudo apt install ffmpeg# check itffmpeg -version

复制你的编码器设置

登录后,打开你的视频账户,找到直播卡片。其中的编码器设置列出了 FFmpeg 所需的全部内容:

服务器
形如 rtmp://HOST:1935/APP。你的主机和应用名称。
流名称
通常是 livestream。它位于地址的末尾。
用户名
你的推流登录名。
密码
点击“显示”查看,或点击“新密码”更换。

如果你的面板还显示了最近服务器地址,请使用该地址作为服务器。这样你的编码器会连接到我们最近的位置(纽约、迈阿密、旧金山、阿姆斯特丹或布加勒斯特),然后流会通过我们的网络传输到你的频道。流名称、用户名和密码保持不变。

02

你的第一条 FFmpeg RTMP 推流,逐项参数讲解

把用户名和密码放在主机前面,后面跟一个 @,然后在应用名称后面加上流名称。命令的其余部分告诉 FFmpeg 如何编码。

rtmp 地址
rtmp://USERNAME:PASSWORD@HOST:1935/APP/livestream

保留地址两边的引号。如果你的密码包含 @、: 或 /,请分别写成 %40、%3A 和 %2F,或者点击面板中的“新密码”换一个不含这些字符的密码。

命令中每个 FFmpeg 参数的作用
参数作用
-re按文件的实际播放速度读取。没有它,FFmpeg 会尽可能快地发送文件,导致流中断。摄像头和采集设备本身已是实时运行,可以省略此参数。
-i input.mp4你的输入:文件、设备或其他流。第 03 步为每种输入都提供了示例。
-c:v libx264将视频编码为 H.264,所有播放器和浏览器都能播放。
-preset veryfast用少量画质换取速度,让电脑能实时跟上。如果 CPU 有余量,可以尝试 faster 或 medium。
-b:v 2500k -maxrate 2500k -bufsize 5000k将视频保持在稳定的 2,500 kbps 左右,这样流不会要求超出你上传带宽的速率。第 04 步有各分辨率对应的值。
-pix_fmt yuv420p手机、电视和浏览器所期望的色彩格式。
-force_key_frames "expr:gte(t,n_forced*2)"无论帧率如何,每 2 秒一个关键帧。播放是按关键帧切分的,所以这个参数最重要。
-sc_threshold 0阻止场景切换时产生额外关键帧,让 2 秒的节奏保持固定。
-c:a aac -b:a 128k -ar 44100 -ac 2128 kbps、44.1 kHz 的 AAC 立体声音频。FFmpeg 内置的 AAC 编码器无需额外参数。
-f flv将流封装为 FLV,即 RTMP 所承载的格式。

较早的教程(包括本页的第一个版本)会为 AAC 加上 -strict experimental。FFmpeg 从 3.0 版本起已从 AAC 编码器上移除了 experimental 标签,所以你可以省略它。

03

选择你的信号源:文件、摄像头、屏幕或 IP 摄像头

只有输入部分会变化。在每个示例中,[encoding] 代表第 02 步中的视频和音频参数,RTMP_ADDRESS 代表你带引号的地址。

用 FFmpeg 推流视频文件

在输入前加上 -stream_loop -1,让文件循环播放,直到你停止 FFmpeg。

文件
ffmpeg -re -stream_loop -1 -i video.mp4 \ [encoding] -f flv "RTMP_ADDRESS"

Windows 上的摄像头

先列出你的设备,然后使用它打印出的确切名称。

windows · dshow
ffmpeg -list_devices true -f dshow -i dummy
ffmpeg -f dshow -rtbufsize 256M ^ -i video="Your Camera":audio="Your Microphone" ^ [encoding] -f flv "RTMP_ADDRESS"

macOS 上的摄像头

列表会用编号显示每个摄像头和麦克风。"0:0" 表示摄像头 0 和麦克风 0。

macos · avfoundation
ffmpeg -f avfoundation -list_devices true -i ""
ffmpeg -f avfoundation -framerate 30 \ -video_size 1280x720 -i "0:0" \ [encoding] -f flv "RTMP_ADDRESS"

Linux 上的摄像头

视频来自摄像头设备,声音来自桌面默认输入。

linux · v4l2
ffmpeg -f v4l2 -framerate 30 -video_size 1280x720 \ -i /dev/video0 -f pulse -i default \ [encoding] -f flv "RTMP_ADDRESS"

Windows 上的屏幕

以每秒 30 帧采集整个桌面。如果需要声音,可以再加一个 dshow 输入来采集麦克风。

windows · gdigrab
ffmpeg -f gdigrab -framerate 30 -i desktop ^ [encoding] -f flv "RTMP_ADDRESS"

通过 RTSP 的 IP 摄像头

如果摄像头已经以 2 秒关键帧间隔发送 H.264(在其自带菜单中设置),就直接复制视频流,只对声音进行编码。否则使用完整的编码参数。

rtsp 摄像头
ffmpeg -rtsp_transport tcp \ -i "rtsp://CAM_USER:CAM_PASS@192.168.1.64:554/stream1" \ -c:v copy -c:a aac -b:a 128k \ -f flv "RTMP_ADDRESS"

摄像头没有麦克风?把音频参数替换为 -an。

示例中行尾使用 \(macOS 和 Linux)或 ^(Windows 命令提示符)。在 PowerShell 中,或者如果不确定,就把整条命令写在一行里。

04

经得起直播考验的 FFmpeg 编码器设置

选择一行适合你上传速度的设置。给上传带宽留出三分之一余量:如果测速显示 6 Mbps,发送不要超过约 4。

按分辨率建议的 FFmpeg 视频和音频比特率
画面添加到命令中视频音频所需上传带宽
1080p,30 fps-vf scale=-2:1080 -r 304500k128k7 Mbps
720p,30 fps-vf scale=-2:720 -r 302500k128k4 Mbps
480p,30 fps-vf scale=-2:480 -r 301200k96k2 Mbps

将 -b:v 和 -maxrate 设为视频数值,-bufsize 设为该数值的两倍。步骤 02 中的命令对应 720p 那一行。付费直播套餐可接收最高 5 Mbps 的输入,足以支持 1080p 那一行。

三条规则,避免大多数缓冲

  1. 将关键帧间隔固定为 2 秒。间隔过长或漂移会导致观众端卡顿,而从你这边看却像是服务器故障。
  2. 用 -maxrate 和 -bufsize 保持比特率稳定,这样复杂场景也不会让你的上传带宽瞬间超载。
  3. 留意 FFmpeg 状态行中的 speed= 数值。它应该保持在 1x。低于这个值,说明你的电脑无法实时编码。

让 GPU 来负责编码

如果 speed= 降到 1x 以下,就把 -c:v libx264 -preset veryfast 换成你电脑上的硬件编码器。这样 CPU 就能腾出来处理其他任务。

NVIDIA GPU
-c:v h264_nvenc -preset p4
Intel 核显
-c:v h264_qsv
Mac
-c:v h264_videotoolbox

运行 ffmpeg -encoders 查看你的版本包含哪些编码器。

05

改用 FFmpeg SRT 流传输

SRT 能在长距离或有丢包的链路上保持流稳定,比如场馆 Wi-Fi、移动上行链路或来自另一个大陆的信号源,而这些场景下 RTMP 往往容易卡顿。我们的 视频 CDN 专业版和白金版套餐均包含此功能。

你的直播卡片上会有一个 SRT 接收 区域,显示专属端口和密码短语。复制其中的 单行 URL 并将其用作输出,同时用 MPEG-TS 替代 FLV。编码参数保持不变。

SRT 流以独立名称播放,因此请使用旁边 播放地址 下方显示的播放链接。

ffmpeg · srt
ffmpeg -re -i input.mp4 \ [encoding] \ -f mpegts \ "srt://HOST:PORT?passphrase=PASSPHRASE&pbkeylen=16"

你的 FFmpeg 版本需要支持 SRT。运行 ffmpeg -protocols 检查,并在输出列表中查找 srt。

06

确认直播已上线,并解决未上线的问题

  1. 启动 FFmpeg 并保持窗口打开。状态行持续更新 frame= 和 time= 即表示正在发送。
  2. 打开直播卡片。15 秒内应显示直播中,并展示编码器正在发送的内容,比特率接近你的设定值。
  3. 从同一面板复制播放链接,在 VLC 中打开(媒体,打开网络串流),或运行 ffplay "PLAYBACK_LINK"。面板还会提供用于你自己网站的嵌入代码。
常见 FFmpeg 推流问题及解决方法
你看到的现象应对方法
FFmpeg 立即停止,并提示连接或 I/O 错误逐字检查主机名和应用名称。部分办公和酒店网络会封锁 1935 端口:尝试更换网络连接。
连接成功,但服务器拒绝接收流用户名或密码错误,或密码中含有需要编码的特殊字符。点击“新密码”,更新命令后重试。
处理文件时 speed= 持续远高于 1x你漏掉了 -re。在 -i 之前加上它。
speed= 持续低于 1x使用更快的预设(superfast)、步骤 04 中更低的一行,或改用 GPU 编码器。
FFmpeg 看起来正常,但观众端缓冲检查关键帧参数,然后降低比特率。那个时段你的实际上传速度可能比你想象的要慢。
文件播完流就结束在 -i 之前添加 -stream_loop -1。
07

FFmpeg 直播常见问题

如何用 FFmpeg 推流到 RTMP 服务器?

编码为 H.264 和 AAC,用 -f flv 将输出封装为 FLV,并把 RTMP 地址作为最后一个参数传给 FFmpeg。对于 Primcast 频道,地址由服务器、应用和流名称组成,用户名和密码放在主机前面:rtmp://USERNAME:PASSWORD@HOST:1935/APP/livestream。

在哪里可以找到服务器地址、用户名和密码?

在您的账户中,视频账户的直播卡片下,编码器设置里。密码会保持隐藏,直到您点击显示,而新密码会为您生成一个新的。正在直播的流会继续运行,新密码将应用于下一次连接。

AAC 音频还需要 -strict experimental 吗?

不需要。FFmpeg 自带的 AAC 编码器在 2016 年发布的 FFmpeg 3.0 中已经去掉了实验性标签。普通的 -c:a aac 在所有当前版本上都能正常工作,因此您可以从旧命令中去掉这个标志。

直播时 FFmpeg 应该使用多大的关键帧间隔?

固定为 2 秒。我们按关键帧切分播放片段,所以更长或漂移的间隔会导致观众端卡顿。使用 -force_key_frames "expr:gte(t,n_forced*2)" 配合 -sc_threshold 0,或者将 -g 设置为帧率的两倍。

我应该以什么码率推流?

720p 约 2,500 kbps,1080p 30 帧每秒约 4,500 kbps,再加上 128 kbps 的音频。总码率保持在您实测上传速度的三分之二以内,这样线路短暂变慢时也不会中断直播。

如何用 FFmpeg 全天循环播放一个视频文件?

在 -i 之前加上 -re -stream_loop -1,FFmpeg 就会一直重播该文件,直到您手动停止。不过这样会让一台电脑全天忙碌。付费视频 CDN 套餐包含 24/7 电视台频道,可以从我们这边播放您的视频。

FFmpeg 可以在我的 GPU 上编码直播流吗?

可以。在 NVIDIA GPU 上使用 h264_nvenc,在 Intel 显卡上使用 h264_qsv,在 Mac 上使用 h264_videotoolbox,用来替代 libx264。关键帧和码率标志保持不变。

我可以用 SRT 代替 RTMP 发送吗?

可以,在 Pro 和 Platinum 视频 CDN 套餐上支持。您的面板会提供一个 SRT 端口和密码短语。使用 -f mpegts 并将面板中的单行 srt:// URL 作为输出。

08

更喜欢图形界面而不是命令行?

同一个频道适用于任何支持 RTMP 的编码器。这些教程使用相同的四个参数。

需要一个可以推流的频道吗?

开通一个视频频道,把您的参数粘贴到命令中,亲自看看画面效果。某个参数卡住了?我们的聊天会在几秒内回复,并可以在您等待时查看您的频道,只要您提出,真人客服随时接管。

获取视频直播频道