核心概念
在开始之前,先理解几个基本概念:

-
输入:FFmpeg 可以从多种来源获取音视频数据,
- 本地文件:
-i my_video.mp4 - 摄像头/采集卡:
-i video=0:audio=1(Windows) 或-i /dev/video0(Linux) - 桌面/屏幕:
-f gdigrab -i desktop(Windows) 或-f x11grab -i :0.0(Linux) - RTSP 摄像头流:
-i rtsp://username:password@ip:port/stream
- 本地文件:
-
编码:将原始的音视频数据压缩成特定格式(如 H.264/H.265 视频, AAC 音频)。
-c:v:指定视频编码器,常用libx264(H.264),libx265(H.265),copy(不转码,直接复制)。-c:a:指定音频编码器,常用aac,copy。
-
封装:将编码后的音视频数据打包成特定的流格式。
-f:指定输出格式,常用flv(用于 RTMP),mpegts(用于 HLS),rtmp。
-
输出:将处理好的流推送到指定的服务器或地址。
(图片来源网络,侵删)- RTMP 协议:
rtmp://server/live/stream_key - HLS 协议:
output.m3u8(会生成一个 .m3u8 播放列表文件和多个 .ts 分片文件)
- RTMP 协议:
最简单的推流命令(推本地文件到 RTMP 服务器)
这是最常见的用法,假设你有一个 MP4 文件,想把它推送到一个支持 RTMP 的直播服务器(如 Nginx-RTMP, SRS, 或 Bilibili/YouTube 的推流地址)。
ffmpeg -re -i my_video.mp4 -c copy -f flv rtmp://live.example.com/live/stream_key
命令分解:
ffmpeg: 执行程序。-re: 非常重要! 以本地文件的帧率读取数据,模拟一个实时流,如果不加,FFmpeg 会以最快的速度读取文件并推流,导致服务器拒绝连接。-i my_video.mp4: 输入文件。-c copy: 不进行转码,直接复制流,这是最高效的方式,要求你的文件编码格式和目标服务器兼容(通常是 H.264/AAC),如果需要转码,请参考下面的“进阶用法”。-f flv: 指定输出格式为 FLV,这是 RTMP 协议最常用的封装格式。rtmp://live.example.com/live/stream_key: 推流服务器的地址和串流密钥,你需要将其替换成你自己的服务器地址。
进阶用法(转码推流)
很多时候,原始文件的编码格式、分辨率、码率并不适合直接推流,这时就需要 FFmpeg 进行转码。
场景1:转码为通用 H.264/AAC 格式推流
ffmpeg -re -i my_video.mp4 \ -c:v libx264 -preset veryfast -b:v 3000k -maxrate 3000k -bufsize 6000k -pix_fmt yuv420p \ -c:a aac -b:a 128k \ -f flv rtmp://live.example.com/live/stream_key
参数详解:

-
视频参数 (
-c:v ...):-c:v libx264: 使用 x264 编码器生成 H.264 视频。-preset veryfast: 编码预设。veryfast是一个速度和质量的平衡点,还有ultrafast,superfast,faster,fast,medium(默认),slow,slower,veryslow,速度越快,CPU 占用越低,但压缩效率也越低。-b:v 3000k: 视频平均码率,单位是比特/秒 (bps),这里是 3Mbps。-maxrate 3000k: 最大码率,通常与平均码率相同。-bufsize 6000k: 码率控制缓冲区大小,通常设置为平均码率的 2 倍。-pix_fmt yuv420p: 非常重要! 强制使用 yuv420p 像素格式,这是目前绝大多数播放器(尤其是移动端)都兼容的格式。
-
音频参数 (
-c:a ...):-c:a aac: 使用 AAC 编码器。-b:a 128k: 音频码率,这里是 128kbps。
场景2:推摄像头和麦克风(实时采集)
这个命令可以从你的摄像头和麦克风采集音视频,并实时推流。
Windows (DirectShow):
ffmpeg -f dshow -i video="你的摄像头名称" -f dshow -i audio="你的麦克风名称" \ -c:v libx264 -preset ultrafast -tune zerolatency -b:v 3000k -pix_fmt yuv420p \ -c:a aac -b:a 128k \ -f flv rtmp://live.example.com/live/stream_key
Linux (V4L2 / ALSA):
# 假设摄像头是 /dev/video0,麦克风是 hw:0 ffmpeg -f v4l2 -i /dev/video0 -f alsa -i hw:0 \ -c:v libx264 -preset ultrafast -tune zerolatency -b:v 3000k -pix_fmt yuv420p \ -c:a aac -b:a 128k \ -f flv rtmp://live.example.com/live/stream_key
参数详解:
-tune zerolatency: 针对低延迟场景优化的编码器参数,会减少编码延迟。-f dshow/-f v4l2: 指定输入设备格式。-i "设备名称": 指定输入设备,你可以在命令行运行ffmpeg -f dshow -list_devices true -i dummy(Windows) 或ffmpeg -f v4l2 -list_formats all -i /dev/video0(Linux) 来查看可用的设备列表。
推流到不同协议的服务器
推流到 RTMP (最常用)
见上面的所有例子,这是最经典的推流方式。
推流到 HLS (用于 HTTP 点播/低延迟直播)
HLS 是苹果的方案,通过 HTTP 协议传输,兼容性极好,但延迟较高(10-30 秒)。
ffmpeg -re -i my_video.mp4 \ -c:v h264 -c:a aac \ -f hls -hls_time 10 -hls_list_size 6 -hls_flags delete_segments output.m3u8
-f hls: 指定输出格式为 HLS。-hls_time 10: 每个分片的时长为 10 秒。-hls_list_size 6: 播放列表中保留 6 个分片信息。-hls_flags delete_segments: 当生成新的分片时,删除旧的分片文件,防止磁盘被占满。output.m3u8: 输出的 HLS 播放列表文件,执行后,FFmpeg 会生成output.m3u8和output0.ts,output1.ts等一系列视频分片。
推流到 WebRTC (超低延迟)
WebRTC 是现代网页和 App 实现超低延迟直播(<1秒)的首选方案,但配置相对复杂,通常需要一个 SFU (Selective Forwarding Unit) 服务器,如 Janus, Mediasoup, 或自建的 SRS。
FFmpeg 本身不直接支持完整的 WebRTC 协议,但可以作为信令和媒体流的输入/输出端,与 SFU 配合使用。
实用技巧与排错
查看可用设备和编解码器
- 查看摄像头/麦克风设备:
# Windows ffmpeg -f dshow -list_devices true -i dummy # Linux ffmpeg -f v4l2 -list_formats all -i /dev/video0
- 查看支持的编解码器:
ffmpeg -codecs
推流时显示详细日志
默认情况下,FFmpeg 的日志信息较少,使用 -loglevel 参数可以获取更详细的调试信息,方便排查问题。
# 将日志级别设置为 "verbose" 或 "debug" ffmpeg -re -i my_video.mp4 -c copy -f flv rtmp://... -loglevel verbose
常见错误及解决方法
Invalid data found when processing input: 输入文件已损坏或格式不支持,尝试用ffprobe my_video.mp4检查文件信息。Connection refused: 推流地址错误、服务器未启动、防火墙阻止了端口(通常是 1935 for RTMP)或串流密钥错误。Input/output error: 对于采集设备,可能是设备被其他程序占用,或者设备路径错误。Bitrate is too high for the server: 你的推流码率超过了服务器的限制,降低-b:v的值。Unsupported pixel format: 播放器不支持你视频的像素格式,强制使用-pix_fmt yuv420p。
后台运行
如果你想在 Linux 或 macOS 上让推流命令在后台持续运行,可以使用 nohup 和 &。
nohup ffmpeg -re -i my_video.mp4 -c copy -f flv rtmp://... > ffmpeg.log 2>&1 &
nohup: 让命令在用户退出登录后仍然运行。&: 将命令放入后台执行。> ffmpeg.log 2>&1: 将标准输出和标准错误都重定向到ffmpeg.log文件中,方便查看日志。
希望这份详细的指南能帮助你掌握 FFmpeg 推流!如果你有更具体的需求,可以随时提问。
