【问题标题】:Processing Camera stream in Opencv, pushing it over RTMP (NGINX RTMP Module) using FFMPEG在 Opencv 中处理相机流,使用 FFMPEG 将其推送到 RTMP(NGINX RTMP 模块)上
【发布时间】:2016-07-25 03:34:44
【问题描述】:

输出视频: https://youtu.be/VxfoBQjoY6E

说明:

我想:在 Opencv 中处理摄像头流并将其推送到 RTMP 服务器。我已经设置了 NGINX(RTMP 模块),并且已经使用 RTMP(Flash Player)和 HLS 测试了流式视频。

我正在循环读取帧并在 python 中使用“子进程”来执行 ffmpeg 命令。这是我正在使用的命令:

command = [ffmpeg,
    '-y',
    '-f', 'rawvideo',
    '-vcodec','rawvideo',
    '-pix_fmt', 'bgr24',
    '-s', dimension,
    '-i', '-',
    '-c:v', 'libx264',
    '-pix_fmt', 'yuv420p',
    '-preset', 'ultrafast',
    '-f', 'flv',
    'rtmp://10.10.10.80/live/mystream']


import subprocess as sp
...
proc = sp.Popen(command, stdin=sp.PIPE,shell=False)
...
proc.stdin.write(frame.tostring()) #frame is read using opencv

问题:

我可以看到流很好,但它经常冻结和恢复。这是FFMPEG终端日志的输出:

Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
frame=  117 fps= 16 q=22.0 size=     344kB time=00:00:04.04 bitrate= 697.8kbits/s speed=0.543x   

最后提到了速度。我相信它应该接近1x。我不确定如何实现。

我和服务器在同一个网络上,如果需要,我可以发布我的 python 代码。需要一些 ffmpeg 大师给我一些建议。

编辑

我的输入 fps 实际上是 ~3。 使用'-use_wallclock_as_timestamps', '1',我可以在日志中看到速度接近 1 倍。 但是 HLS 没有直播,有大约 2 分钟的延迟,它会停止并且 .克里斯的建议部分奏效。我不确定问题到底出在哪里,我开始相信它与 nginx-rtmp 模块有关。

这是最终输出,左边是 flash,右边是 hls。我在最后展示了 ffmpeg 选项。 https://youtu.be/jsm6XNFOUE4

【问题讨论】:

  • 您好,先生!我也有同样的问题,想将 mat 发送到 nginx 服务器,但是如何将 mat/images 写入输出流?

标签: opencv nginx ffmpeg rtmp http-live-streaming


【解决方案1】:

在流式传输原始视频(像您一样)或从 MJPEG 源流式传输之前,我也遇到过类似的问题。有两个输入选项可以尝试使用 ffmpeg 使其保持 1x 速度:

选项 1

ffmpeg -re -i <rest of input options>

-re 告诉 ffmpeg 以本机输入速率读取

选项 2

ffmpeg -use_wallclock_as_timestamps 1 -i <rest of input options>

-use_wallclock_as_timestamps 告诉 ffmepg 只获取每一帧,获取系统时间,并将其设置为时间戳。我发现这个选项在速度减慢时最有效。

不管

确保以恒定帧速率进行编码。当帧率变化时,ffmpeg 会变得有点挑剔,所以在输出选项上,使用-r 25(将 25 替换为您想要的输出帧率)强制 ffmpeg 使用静态帧率输出

【讨论】:

  • 我尝试使用 -re 和 -r 但它不起作用。并且根据以下指南,从实时设备流式传输时不需要 -re。我会尽快检查您提出的解决方案。是的,帧速率会有所不同,我想我可以以某种方式保持它不变。 trac.ffmpeg.org/wiki/StreamingGuide
  • 以挂钟为时间戳,-re 速度为 1 倍,但 hls 并不是真正的实时流式传输。我已经编辑了上面的问题并添加了输出视频和 ffmpeg 命令。
【解决方案2】:

我认为最简单的方法是使用 MoviePy 模块(顺便说一句,我觉得它很棒)。看看MoviePy Video Writer。它应该写入本地文件,但您也可以通过在命令末尾添加-f flv 来指定输出格式,从而将它与 rtmp 流一起使用。要将帧写入流,只需使用方法write_frame(your_frame)。对我来说效果很好

【讨论】:

    【解决方案3】:

    我遇到了同样的问题,发现ffmpeg不能自动填补空白,所以当你以3 fps喂ffmpeg时,客户端仍然会以25 fps播放,所以客户端在播放前需要缓存很多帧和然后快速播放,然后停下来再次缓存帧

    所以当你用这样的代码提供 ffmpeg 时,很容易填补空白

    timeStart = get_time_seconds()
    count = 0
    some loop:
      frame = getimage()
      targetCount = (get_time_seconds()-timeStart)*25
      repeatCount = targetCount - count
      loop for repeatCount times:
         proc.stdin.write(frame.tostring()) 
      count = targetCount 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-30
      • 1970-01-01
      • 1970-01-01
      • 2015-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      相关资源
      最近更新 更多