ffmpeg 推流

完全取消延遲

ffmpeg -loglevel error \
  -probesize 32 -analyzeduration 0 \
  -fflags nobuffer+igndts+genpts -flags low_delay \
  -use_wallclock_as_timestamps 1 \
  -max_delay 0 -reorder_queue_size 0 \
  -buffer_size 102400 \
  -rtsp_transport tcp \
  -i 'rtsp://admin:pwd@192.168.31.160:554/profile3/media.smp' \
  -c copy \
  -f flv -flvflags no_duration_filesize \
  -flush_packets 1 \
  "rtmp://127.0.0.1:1935/live/liveQQ"

-probesize 32 -analyzeduration 0:(最關鍵!)預設 FFmpeg 會讀取約 5 秒(5,000,000 microseconds)的封包來分析 Codec 資訊。將這兩個值歸零/極小化,可以立刻省下 2~3 秒的開頭延遲

-fflags nobuffer+igndts+genpts -flags low_delay:強制停用輸入與內部的 Packet 緩衝區,資料一進來就立刻往輸出端拋。

完全不留存任何輸入封包(nobuffer),放棄耗時的解碼時間戳排序(igndts),並用即時產生的時間戳補齊格式(genpts)。」

這是 FFmpeg 在做 Stream Copy (不重新編碼) 轉推時,既能達到零記憶體滯留(最低延遲),又能確保串流時間軸不崩潰的黃金組合之一。

-use_wallclock_as_timestamps 1: 在 -i 之前加上此參數。這會告訴 FFmpeg 完全拋棄攝影機傳過來的 RTSP PTS/DTS,直接以 FFmpeg 收到封包當下的系統時鐘(Wallclock) 作為時間戳。這能省去 FFmpeg 解析與運算原始 RTP Header 時間戳的邏輯開銷。

-flvflags no_duration_filesize:避免 RTMP/FLV 封裝時為了寫入長度資訊而累積 Header 緩衝。

-max_delay 0:強制將 muxing/demuxing 的最大延遲設為 0(預設為 0.7 秒)。

-buffer_size 102400(或更小):限制 RTSP 輸入端的 Socket Receive Buffer。預設的接收緩衝區較大,當網路有微小波動時容易在 Socket 層積壓資料;縮小 Buffer 能強制 Socket 有資料就立刻拋給 FFmpeg。

-reorder_queue_size 0(極重要) 告訴 FFmpeg 關閉 RTP 封包重排佇列。如果你的攝影機原本就不含 B-frame(不需 PTS/DTS 重排),開啟這個參數可以省去 1~2 個 Frame 的等待緩衝(約 33~66ms)。

-flush_packets 1:這是 FFmpeg 核心層級的通用參數,強制要求 Muxer 每收到一個影音 Packet 就立刻寫入 Socket 拋出,不留在 Userspace 的 Buffer 中。