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

Pas*_* C. 27 streaming ffmpeg delay http-live-streaming webm

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

  1. 我启动了ffserver并且它可以工作.
  2. 从另一个终端我使用此命令启动ffmpeg流,它可以工作:

    sudo ffmpeg -re -f video4linux2 -i /dev/video0 -fflags nobuffer -an http://localhost:8090/feed1.ffm
    
    Run Code Online (Sandbox Code Playgroud)
  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>
    
    Run Code Online (Sandbox Code Playgroud)
  4. 我用它启动流

    ffplay http:// 192.168.1.2:8090/test.webm它可以工作,但我有4秒的延迟,我会尽量减少这个延迟,因为这对我的应用程序至关重要.谢谢

小智 16

FFMpeg的流媒体指南有一个关于如何减少延迟的特定部分.我还没有尝试过他们所有的建议.http://ffmpeg.org/trac/ffmpeg/wiki/StreamingGuide#Latency

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

默认情况下,ffplay推出了自己的一个小的延迟,也是有用的mplayer,其-nocache用于测试延迟(或-benchmark).使用SDL out也可以查看具有最小延迟的帧:ffmpeg ... -f sdl -

  • 谢谢,来自链接的`ffplay -probesize 32 -sync ext INPUT`为我做了诀窍! (7认同)

Teo*_*cci 15

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

1.基本使用 -fflags nobuffer

该格式标志减少了在初始输入流分析期间由缓冲引入的等待时间。此命令将减少明显的延迟,并且不会引入音频干扰。

ffplay -fflags nobuffer -rtsp_transport tcp rtsp://<host>:<port>
Run Code Online (Sandbox Code Playgroud)

2.高级-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>
Run Code Online (Sandbox Code Playgroud)

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

您也可以尝试添加:* -avioflags direct减少缓冲,* -fflags discardcorrupt丢弃损坏的数据包,但是我认为这是非常积极的方法。这可能会中断音视频同步

ffplay -fflags nobuffer -fflags discardcorrupt -flags low_delay \ 
-framedrop -avioflags direct -rtsp_transport tcp rtsp://<host>:<port>
Run Code Online (Sandbox Code Playgroud)

3. hacky选项(可在旧文档中找到)

这是基于设置-probesize-analyzeduration较低值的调试解决方案,以帮助您的流更快地启动。

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

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

-rtsp_transport作为可以设置udptcp根据您的流。在此示例中,我使用tcp


ajl*_*u13 7

考虑使用过滤器选项-vf setpts=0。这使得所有帧尽快显示,而不会增加帧速率的任何延迟。这将使流能够赶上,以防它落后,我发现如果我移动 ffplay 窗口或调整 ffplay 窗口的大小,就会发生这种情况。但是,如果您的视频数据以不一致的速率接收,这可能会使视频看起来断断续续。

  • 我最终得到以下命令:`ffplay -flags low_delay -vf setpts=0 udp://127.0.0.1:10000`。添加“-vf setpts=0”将延迟减少了 6 帧。其他解决方案不起作用(就我而言)。谢谢你!!! (2认同)

wda*_*xna 5

尽量设定flagsAVFormatContextAVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS

AVFormatContext *ctx;
...
ctx->flags = AVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS;
Run Code Online (Sandbox Code Playgroud)

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

AVCodecContext *ctx;
...
ctx->thread_count = 1;
Run Code Online (Sandbox Code Playgroud)