我有一个问题。我想用ffmpeg从我的网络摄像头做一个直播。
- 我启动ffserver,它工作了。
-
在另一个终端上,我用这个命令启动ffmpeg流
sudo ffmpeg -re -f video4linux2 -i /dev/video0 -fflags nobuffer -an http://localhost:8090/feed1.ffm
-
在我的配置文件中,我有这个流:
<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>
-
我用
启动流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
可以根据您的流设置为udp
或tcp
。在这个例子中,我使用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
使运动矢量的质量有点差,但延迟对我来说更重要,所以…