菜鸟科技网

ffmpeg推流命令参数如何正确配置?

核心概念

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

ffmpeg推流命令参数如何正确配置?-图1
(图片来源网络,侵删)
  1. 输入: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
  2. 编码:将原始的音视频数据压缩成特定格式(如 H.264/H.265 视频, AAC 音频)。

    • -c:v:指定视频编码器,常用 libx264 (H.264), libx265 (H.265), copy (不转码,直接复制)。
    • -c:a:指定音频编码器,常用 aac, copy
  3. 封装:将编码后的音视频数据打包成特定的流格式。

    • -f:指定输出格式,常用 flv (用于 RTMP), mpegts (用于 HLS), rtmp
  4. 输出:将处理好的流推送到指定的服务器或地址。

    ffmpeg推流命令参数如何正确配置?-图2
    (图片来源网络,侵删)
    • RTMP 协议:rtmp://server/live/stream_key
    • HLS 协议:output.m3u8 (会生成一个 .m3u8 播放列表文件和多个 .ts 分片文件)

最简单的推流命令(推本地文件到 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

参数详解:

ffmpeg推流命令参数如何正确配置?-图3
(图片来源网络,侵删)
  • 视频参数 (-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.m3u8output0.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 推流!如果你有更具体的需求,可以随时提问。

分享:
扫描分享到社交APP
上一篇
下一篇