在Opencv中处理摄像头流,使用FFMPEG将其推送到RTMP(NGINX RTMP模块)上
输出视频: 说明: 我想:在Opencv中处理相机流,并将其推送到RTMP服务器。我已经安装了NGINX(RTMP模块),并用RTMP(Flash播放器)和HLS测试了流媒体视频 我在循环中读取帧,并使用python中的“subprocess”执行ffmpeg命令。下面是我正在使用的命令:在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',
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