如何减少延迟在直播流与ffmpeg



我有一个问题。我想用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秒的延迟,我会尽量减少这个延迟,因为这对我的应用程序是必不可少的。由于

我发现了三个可以帮助我减少直播延迟的命令。第一个命令是非常基本和直接的,第二个命令结合了其他可能在每个环境中工作不同的选项,最后一个命令是我在文档中发现的一个黑客版本,它在开始时很有用,但目前第一个选项更稳定,更适合我的需要。

1。基本使用-fflags nobuffer

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

ffplay -fflags nobuffer -rtsp_transport tcp rtsp://<host>:<port>

2。高级-flags low_delay和其他选项

我们可以将前面的-fflags nobuffer格式标志与其他通用选项和高级选项结合使用,以生成更详细的命令:

  • -flags low_delay这个编解码器通用标志强制低延迟。
  • -framedrop:当视频不同步时丢弃视频帧。如果主时钟未设置为video,则默认启用。使用此选项为所有主时钟源
  • 启用丢帧
  • -strict experimental,最后-strict规定了如何严格遵循标准,experimental选项允许非标准化的实验事物,实验(未完成/工作进行中/未经过良好测试)解码器和编码器。这个选项是可选的,记住实验解码器可能会带来安全风险,不要使用这个来解码不可信的输入。
ffplay -fflags nobuffer -flags low_delay -framedrop 
-strict experimental -rtsp_transport tcp rtsp://<host>:<port>

这个命令可能会导致一些音频故障,但很少。

也可以尝试添加:

  • -avioflags direct减少缓冲,
  • -fflags discardcorrupt丢弃损坏的数据包,但我认为这是非常激进的方法。这可能会破坏音视频同步
ffplay -fflags nobuffer -fflags discardcorrupt -flags low_delay  
-framedrop -avioflags direct -rtsp_transport tcp rtsp://<host>:<port>

3。一个粗糙的选项(在旧文档中找到)

这是一个基于将-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>

这个命令有时可能会导致一些音频故障。

-rtsp_transport可以根据您的流设置为udptcp。在这个例子中,我使用tcp .

FFMpeg的流指南有一个关于如何减少延迟的特定章节。我还没有把他们所有的建议都试过。

http://ffmpeg.org/trac/ffmpeg/wiki/StreamingGuide延迟

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

默认情况下,ffplay引入了自己的小延迟,mplayer及其-nocache(或-benchmark)用于测试延迟也很有用。使用SDL out也被称为以最小延迟查看帧:ffmpeg ... -f sdl -

Try set flags of AVFormatContext to AVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS

AVFormatContext *ctx;
...
ctx->flags = AVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS;

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

AVCodecContext *ctx;
...
ctx->thread_count = 1;

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

为我解决延迟通过-tune zerolatency

ffmpeg -f rawvideo -i /dev/video0 -preset slow -tune zerolatency -pix_fmt yuv420p -c:v libx264 -f rawvideo /tmp/pipe.h264

使运动矢量的质量有点差,但延迟对我来说更重要,所以…

最新更新