Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Opencv中处理摄像头流,使用FFMPEG将其推送到RTMP(NGINX RTMP模块)上_Opencv_Nginx_Ffmpeg_Rtmp_Http Live Streaming - Fatal编程技术网

在Opencv中处理摄像头流,使用FFMPEG将其推送到RTMP(NGINX RTMP模块)上

在Opencv中处理摄像头流,使用FFMPEG将其推送到RTMP(NGINX RTMP模块)上,opencv,nginx,ffmpeg,rtmp,http-live-streaming,Opencv,Nginx,Ffmpeg,Rtmp,Http Live Streaming,输出视频: 说明: 我想:在Opencv中处理相机流,并将其推送到RTMP服务器。我已经安装了NGINX(RTMP模块),并用RTMP(Flash播放器)和HLS测试了流媒体视频 我在循环中读取帧,并使用python中的“subprocess”执行ffmpeg命令。下面是我正在使用的命令: command = [ffmpeg, '-y', '-f', 'rawvideo', '-vcodec','rawvideo', '-pix_fmt', 'bgr24',

输出视频:

说明:

我想:在Opencv中处理相机流,并将其推送到RTMP服务器。我已经安装了NGINX(RTMP模块),并用RTMP(Flash播放器)和HLS测试了流媒体视频

我在循环中读取帧,并使用python中的“subprocess”执行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   
它在结尾提到了速度。我认为应该接近1倍。我不知道如何实现这一目标

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

编辑

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

这是最终输出,左边是flash,右边是hls。最后我将展示ffmpeg选项。

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

选择1
-使用wallclock\u作为时间戳
告诉ffmepg只获取每一帧的输入,获取系统时间,并将其作为时间戳。我发现当速度降到最低时,这个选项最有效

不管不顾
确保以恒定的帧速率编码。当帧率变化时,ffmpeg可能会变得有点挑剔,因此在输出选项上,使用
-r25
(将25替换为所需的输出帧率)强制ffmpeg使用静态帧率输出

我认为最简单的方法是使用MoviePy模块(顺便说一句,我发现它很棒)。看一看这张照片。它应该写入本地文件,但您也可以将其用于rtmp流,方法是在命令末尾添加
-f flv
,以指定输出格式。要将帧写入流,只需使用方法
write\u frame(您的帧)
。它对我来说工作得很好

我遇到了同样的问题,发现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 

我试着使用-re和-r,但都不起作用。根据以下指南,从直播设备流式传输时不需要-re。我很快会检查你提出的解决方案。是的,帧速率是变化的,我想我可以保持它不变。使用wallclock作为时间戳和-re,速度为1x,但hls并不是真正的流媒体直播。我已经编辑了上面的问题,并添加了输出视频和ffmpeg命令。嗨,先生!我也有同样的问题,希望将mat发送到nginx服务器,但是如何将mat/图像写入输出流?
ffmpeg -use_wallclock_as_timestamps 1 -i <rest of input options>
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