使用 ffmpeg 实现低延迟流媒体

使用 ffmpeg 实现低延迟流媒体

最近,我正在尝试使用ffmpeg。目标是能够将一台计算机屏幕上显示的内容发送到另一台计算机,同时能够选择输出分辨率等设置。

这是一个小快要工作了概念验证。完成后,我将能够使用以下方法替换 VNCffmpeg流式传输x2x或者协同作用用于转发键盘和鼠标事件。

现在,我可以使用以下方式开始流式传输:

ffmpeg -f x11grab -s "1600x1200" -i ":0" \
    -f alsa -i pulse \
    -s 800x600 -b 200k -f mpegts - \
    | mplayer -cache 1024 -
#
# I have pulse audio configured so that `-i pulse` will
# The output can sent through for example netcat to another host
#

延迟取决于编码选项。使用这些选项,屏幕更新和视频更新之间的延迟约为 800 毫秒。

我想要实现的目标:

  • 达到延迟100毫秒
  • mplayer执行时,它会抱怨无法在 Lear 流中查找,并且没有音频。当我将输出保存到文件并播放时,仍然有声音。

    编辑:添加后-cache,不再显示线性流中的搜索消息。将输出格式更改为可使-f mpegts音频正常工作。

  • 如果编码不会占用 100% 的 CPU 核心(次要目标),那就太好了。

在网上搜索后,我认为这些问题与我应该使用的编解码器/选项有关。但我不知道现有的可能性之间的区别。你能给我一些可以解决我的问题的选项吗?此外,VLC 是一个好的替代方案吗?如果是,那么从一个桌面流式传输到另一个桌面的等效命令是什么?

答案1

从桌面 A 到桌面 B 的流式传输是一个有趣的问题。如果您不需要视频/音频,那么您可能想检查一下 NX 协议。它比 VNC 效率高得多。FreeNX 是一个服务器,NoMachine 和其他公司制作 NX 客户端。还有其他服务器 - 免费和商业的。

高性能远程桌面 SPICE 功能也正在作为 F/LOSS 项目进行。我认为 Redhat 处于领先地位。http://spice-space.org/

我不知道这些是否有用,但也许只是引出一些更有用的东西?

对于流视频,可能需要避免完整桌面协议的开销。

答案2

我最近需要设置低延迟流媒体,其要求甚至比原始发帖者(OP)更严格。我设计了一个解决方案,效果很好,可以用作笔记本电脑的附加显示器,并具有流畅的鼠标和键盘输入。

在发送端,我使用了以下ffmpeg命令:

ffmpeg -video_size 1920x1080 -r 30 -framerate 30 -f x11grab -i :0.0+0x0 \
    -b:v 40M -maxrate 50M -bufsize 200M \
    -field_order tt -fflags nobuffer -threads 1 \
    -vcodec mpeg4 -g 100 -r 30 -bf 0 -mbd bits -flags +aic+mv4+low_delay \
    -thread_type slice -slices 1 -level 32 -strict experimental -f_strict experimental \
    -syncpoints none -f nut "tcp://10.0.0.1:1234"

该命令的关键部分是 -g 100 参数,它增加了关键帧之间的时间,从而降低了流比特率。

在接收端,我使用ffplay(包含在内ffmpeg)在 Raspberry Pi 3 上显示流:

ffplay -autoexit -flags low_delay -framedrop -strict experimental \
    -vf setpts=0 -tcp_nodelay 1 "tcp://10.0.0.1:1234\?listen"

虽然我意识到最初的问题已经有十多年的历史了,而且从那时起普通用户可用的处理能力已经有了显着提高,但这两个命令为任何想要通过本地网络建立低延迟流的人提供了一个合理的起点,即使在低端硬件上也是如此。

相关内容