我想将一个Raspberry PI的屏幕流到多个其他Raspberry PI(所有内部有线网络)。有没有一个简单的,甚至上船的解决方案?
谢谢!
发布于 2022-01-26 16:49:42
你可以读到关于ffserver的..。发现它已经停产了。你可以读到关于转播服务器的消息.发现你必须付出代价。你可以读到多播..。并发现存在着巨大的延误和滞后。
因此,我有一个基于Redis的简单解决方案,它是一个简单、重量轻、安装方便、速度快、内存中数据结构的服务器。它可以在所有不同的平台上共享整数、字符串、集合、图像、数组、列表、集合、有序集和散列,并具有C/C++、Python、bash、PHP、Go、Perl的客户端绑定。
我在一个Mac上运行它,以使负载远离Raspberry Pis。
这就是我的方法:
ffmpeg
。
下面是Raspberry Pi的代码:
#!/usr/bin/env python3
import numpy as np
import cv2
import redis
import subprocess
# Set height and width of frame, and size in bytes
w, h = 1920, 1080
bytes = w * h * 3
# IP address of machine where Redis is running
host='192.168.0.8'
port=6379
# Connect to Redis
r = redis.Redis(host,port)
# Formulate our "ffmpeg" command
cmd = [
'ffmpeg', # ffmpeg
'-r', '20', # 20 fps
'-f', 'x11grab', # grab using X11
'-i', ':0', # equivalent of DISPLAY=0:0
'-vf', f'scale={w}x{h}', # make all frames fixed size so we know how many bytes to read
'-pix_fmt', 'bgr24', # BGR888 like OpenCV prefers
'-f', 'rawvideo', # output rawvideo
'pipe:1' # to stdout
]
# Set up JPEG quality outside loop - note it will affect network bandwidth
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 75]
# Start ffmpeg grabbing the screen
with subprocess.Popen(cmd, stdin=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
stdout=subprocess.PIPE, shell=False) as sp:
while True:
# Read frame from ffmpeg
frame = sp.stdout.read(bytes)
if not frame:
break
# Convert the screen into JPEG
frameNP = np.frombuffer(frame, np.uint8).reshape((h,w,3))
_, JPG = cv2.imencode('.jpg', frameNP, encode_param)
# Stuff the frame into Redis
r.set('frame', JPG.tobytes())以下是客户端的视图代码:
#!/usr/bin/env python3
import redis
import cv2
import numpy as np
# IP address where Redis is running
host="192.168.0.8"
port=6379
# Connect to Redis
r = redis.Redis(host,port)
# Grab frames from Redis continually and display locally
while True:
# Grab frame from Redis
im = r.get('frame')
if im:
# Convert JPEG into Numpy array
frame = cv2.imdecode(np.frombuffer(im, np.uint8), cv2.IMREAD_COLOR)
# Display
cv2.imshow("Viewer", frame)
# Allow a little while for a keypress and to update display
if cv2.waitKey(50) == ord("q"):
breakhttps://stackoverflow.com/questions/70834021
复制相似问题