我需要找到一种方法来将ffmpeg帧保存到redis变量中。
目前,我正在将ffmpeg的png图像传递到redis,但是它将所有图像连接在一起:
ffmpeg -re -i udp://127.0.0.1:5545 -c:v png -r 1-更新1-| redis-cli -x HSET sb4up
是否可以每秒用一个新帧更新redis变量?
我一直在想这个。我不是专家,ffmpeg
可能有些事情要简单得多,因此,如果有人使我意识到更好的方法,我可能会删除它。
目前,我的想法是,如果ffmpeg
将JPEG或PNG写为输出,则需要一个能够解析级联流并搜索START-OF-IMAGE / END-OF-IMAGE或(JPEG SOI / EOI或PNG IHDR / IEND)标记,并了解块和节。因此,我认为强制ffmpeg
写入固定长度的图像可能会更简单,然后您就可以N
知道字节对应于一帧就可以读取字节,并且不需要一堆“胶水”代码来编写和维护-只需标准工具即可。
我没有您的UDP流,所以我只使用了一个.mov
文件。然后,我强制RGB24
编码和固定大小的调整后大小的640x480帧。然后,我将其拆分为640x480x3 RGB字节的块,并要求ImageMagick从原始视频创建PNG并将其重打包为PNG到Redis:
#!/bin/bash
# Set height and width of frame, and size in bytes
h=480
w=640
bytes=$((h*w*3))
ffmpeg -i video.mov -r 1 -s ${w}x${h} -update 1 -pix_fmt rgb24 -f rawvideo - 2> /dev/null | \
gsplit -b $bytes --filter="magick -depth 8 -size ${w}x${h} rgb:- png:- | redis-cli -x SET sb4up"
然后,我使用OpenCV每0.5秒从Redis抓取一次图像并显示结果。
#!/usr/bin/env python3
import redis
import cv2
import numpy as np
host='localhost'
port=6379
r = redis.Redis(host,port)
while True:
png=r.get('sb4up')
frame = cv2.imdecode(np.frombuffer(png,np.uint8), cv2.IMREAD_COLOR)
cv2.imshow("Viewer", frame)
cv2.waitKey(500)
注意:我使用gsplit
GNUsplit
是因为我在Mac上。在Linux上,只需使用split
。
注意:显然,只要在代码的两个部分(即ingsplit
和ImageMagick中)都对其进行更新,就可以使用不同大小的框架。
注意:您不一定需要安装ImageMagick和PNG编码每个图像,因为Redis中只有一个最新的图像,因此空间不会成为问题,因为没有成千上万的帧,因此您可以省略ImageMagick并仅将原始RGB24数据写入Redis中而不使用ImageMagick。然后从Redis获取原始数据,并使用np.reshape()
它们将其转换为正确形状的图像。
我仍在思考,可能会想出更好的方法…… Perl可能适合在模式上分割二进制流……
另一个想法是让文件ffmpeg
写入PNG
一个有序号的文件,frame-%03d.png
然后运行fswatch/inotify
以获取各个帧并将其填充到Redis中。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句