如何使用ffmpeg最小化实时流媒体的延迟

问题描述 投票:22回答:3

我有个问题。我想从我的网络摄像头用ffmpeg进行直播。

  1. 我启动了ffserver并且它可以工作。
  2. 从另一个终端我使用此命令启动ffmpeg流,它可以工作: sudo ffmpeg -re -f video4linux2 -i /dev/video0 -fflags nobuffer -an http://localhost:8090/feed1.ffm
  3. 在我的配置文件中,我有这个流: <Stream test.webm> Feed feed1.ffm Format webm NoAudio VideoCodec libvpx VideoSize 720x576 VideoFrameRate 25 # Video settings VideoCodec libvpx VideoSize 720x576 # Video resolution VideoFrameRate 25 # Video FPS AVOptionVideo flags +global_header # Parameters passed to encoder # (same as ffmpeg command-line parameters) AVOptionVideo cpu-used 0 AVOptionVideo qmin 10 AVOptionVideo qmax 42 #AVOptionVideo quality good PreRoll 5 StartSendOnKey VideoBitRate 400 # Video bitrate </Stream>
  4. 我用它启动流 ffplay http://192.168.1.2:8090/test.webm它有效,但我有4秒的延迟,我会尽量减少这种延迟,因为这对我的应用程序至关重要。谢谢
ffmpeg streaming delay http-live-streaming webm
3个回答
15
投票

FFMpeg流媒体指南有一个关于如何减少延迟的特定部分。我还没有尝试过他们所有的建议。 qazxsw poi

他们特别注意了ffplay引入的延迟:

默认情况下,http://ffmpeg.org/trac/ffmpeg/wiki/StreamingGuide#Latency引入了自己的小延迟,同样有用的是ffplay及其mplayer用于测试延迟(或-nocache)。使用SDL out也可以查看具有最小延迟的帧:-benchmark


8
投票

我找到了三个帮助我减少直播流延迟的命令。第一个命令是非常基本和直接的,第二个命令与其他选项结合使用可能在每个环境中有所不同,最后一个命令是我在文档中找到的hacky版本它在开始时很有用但是现在第一种选择更稳定。

1. Basic using ffmpeg ... -f sdl -

此格式标志减少了在初始输入流分析期间通过缓冲引入的延迟。此命令将减少明显的延迟,并且不会引入音频故障。

-fflags nobuffer

2. Advanced ffplay -fflags nobuffer -rtsp_transport tcp rtsp://<host>:<port> and other options.

我们可以将之前的-flags low_delay格式标志与其他通用选项和高级选项结合使用,以获得更精细的命令:

  • -fflags nobuffer这个编解码器通用标志将强制低延迟。
  • -flags low_delay:如果视频不同步,则丢弃视频帧。如果主时钟未设置为视频,则默认启用。使用此选项可为所有主时钟源启用帧丢弃
  • -framedrop,最后-strict experimental指定严格遵守标准和-strict选项允许非标准化实验事物,实验(未完成/正在进行/未经过良好测试)解码器和编码器。此选项是可选的,请记住实验解码器可能带来安全风险,请勿使用此选项解码不受信任的输入。
experimental

此命令可能会引入一些音频故障,但很少。

你也可以尝试添加:* ffplay -fflags nobuffer -flags low_delay -framedrop \ -strict experimental -rtsp_transport tcp rtsp://<host>:<port> 来减少缓冲,而* -avioflags direct来丢弃损坏的数据包,但我认为是非常积极的方法。这可能会破坏音频 - 视频同步

-fflags discardcorrupt

3. A hacky option (found on the old documentation)

这是一个基于将ffplay -fflags nobuffer -fflags discardcorrupt -flags low_delay \ -framedrop -avioflags direct -rtsp_transport tcp rtsp://<host>:<port> -probesize设置为低值的调试解决方案,可帮助您更快地启动流。

  • -analyzeduration以字节为单位设置探测大小(即要分析的数据大小以获取流信息)。较高的值将允许在分散到流中时检测更多信息,但会增加延迟。必须是不小于32的整数。默认情况下为5000000。
  • -probesize 32指定分析多少微秒来探测输入。较高的值可以检测更准确的信息,但会增加延迟。默认为5000000微秒(5秒)。
  • analyzeduration 0将主时钟设置为外部源以尝试保持实时。默认是音频。主时钟用于控制音频 - 视频同步。这意味着此选项将音频 - 视频同步设置为一种类型(即type = audio / video / ext)。
-sync ext

此命令有时可能会引入一些音频故障。

根据你的流媒体,ffplay -probesize 32 -analyzeduration 0 -sync ext -rtsp_transport tcp rtsp://<host>:<port> 可以设置为-rtsp_transportudp。对于这个例子,我正在使用tcp


2
投票

尝试将tcpflags设置为AVFormatContext

AVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS

然后尝试将解码器线程设置为1.似乎更多线程将导致更多延迟。

AVFormatContext *ctx;
...
ctx->flags = AVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS;
© www.soinside.com 2019 - 2024. All rights reserved.