46

我有个问题。我会从我的网络摄像头使用 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 秒的延迟,我会尽量减少这种延迟,因为这对我的应用程序至关重要。谢谢

4

4 回答 4

51

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

1.基本使用-fflags nobuffer

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

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

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>

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

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

ffplay -fflags nobuffer -fflags discardcorrupt -flags low_delay \ 
-framedrop -avioflags direct -rtsp_transport tcp rtsp://<host>:<port>

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>

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

-rtsp_transport可以根据您的流媒体udp进行设置。tcp对于这个例子,我使用tcp.

于 2018-03-14T08:47:17.047 回答
20

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

他们对延迟 ffplay 进行了特别说明:

默认情况下,ffplay它会引入一个小的延迟,它也可以mplayer用于-nocache测试延迟(或-benchmark)。据说使用 SDL out 可以以最小的延迟查看帧:ffmpeg ... -f sdl -

于 2013-07-09T02:47:40.027 回答
5

尝试设置flagsAVFormatContextAVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS

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

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

AVCodecContext *ctx;
...
ctx->thread_count = 1;
于 2019-03-05T09:01:03.530 回答
0

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

于 2022-03-04T14:18:51.780 回答