我正试图通过网络传输一段视频。我已经使用了和uvicorn,它工作得很好,但现在我移动到无线网络,网络无法处理流,我得到2-3fps和5秒的滞后。我看到gstreamer是流帧的最佳方式,虽然我需要在流的接收端有一个解码器。

这是我的发件人:

Sender.py

代码语言:javascript复制import time

import cv2

fps = 52

frame_width = 640

frame_height = 360

flip = 0

camSet='v4l2src device=/dev/video0 ! video/x-raw,width=640,height=360 ! nvvidconv flip-method='+str(flip)+' \

! video/x-raw(memory:NVMM), format=I420, width=640, height=360 ! nvvidconv ! video/x-raw, format=BGRx ! videoconvert \

! video/x-raw, format=BGR enable-max-performance=1 ! appsink '

cam=cv2.VideoCapture(camSet,cv2.CAP_GSTREAMER)

gst_str_rtp = " appsrc ! videoconvert ! videoscale ! video/x-raw,format=I420,width=640,height=360,framerate=52/1 ! videoconvert !\

x264enc tune=zerolatency bitrate=500 speed-preset=superfast ! rtph264pay ! \

udpsink host=0.0.0.0 port=8000"

if cam.isOpened() is not True:

print("Cannot open camera. Exiting.")

quit()

fourcc = cv2.VideoWriter_fourcc(*'H264')

out = cv2.VideoWriter(gst_str_rtp, fourcc, 52, (frame_width, frame_height), True)

while True:

ret, frame = cam.read()

cv2.imshow('webcam',frame)

out.write(frame)

cv2.moveWindow('webcam',0,0)

if cv2.waitKey(1)==ord('q'):

break

cam.release()

out.release()

cv2.destroyAllWindows()我有几个关于out的例子,但我不确定哪一个有效,如下所示:

代码语言:javascript复制gst_str_rtp ="appsrc ! videoconvert ! video/x-raw,width=1280,height=720 ! queue ! x264enc ! h264parse\

! rtph264pay ! udpsink host=127.0.0.1 port=8000"或

代码语言:javascript复制gst_str_rtp = "appsrc ! video/x-raw, format=I420 ! queue ! videoconvert ! \

width=640,height=360,framerate=52/1 ! nvvidconv ! omxh264enc ! \

video/x-h264, stream-format=byte-stream ! h264parse ! rtph264pay pt=96 config-interval=1 ! \

udpsink host=127.0.0.1 port=8000"我的接收器是:receiver.py

代码语言:javascript复制global video_frame

video_frame = None

cv2.namedWindow('stream')

# Use locks for thread-safe viewing of frames in multiple browsers

# locks prevent the program from getting user inputs from multiple sources

# lock helps syncronize the program

global thread_lock

thread_lock = threading.Lock()

app = FastAPI()

def main():

global video_frame

camSet='udpsrc host=0.0.0.0 port=8000 caps = "application/x-rtp, media=(string)video, clock-rate=(int)90000, \

encoding-name=(string)H264,\

payload=(int)96" ! rtph264depay ! decodebin ! videoconvert ! appsink'

video_capture = cv2.VideoCapture(camSet ,cv2.CAP_GSTREAMER)#initalizes our video feed

# video_capture.set(cv2.CAP_PROP_BUFFERSIZE, 0)#sets camera buffer to 0 meaning we wont get double frames

print("reading frames")

while True:

ret, frame = video_capture.read()

if not ret:

print('empty frame')

break

cv2.imshow(frame,'stream')

# with thread_lock:

# video_frame = frame.copy()

def encodeFrame():#encode frame function takes the frames and encoding them to jpg and encodes them again to bytes so we can stream them

global thread_lock

while True:

# Acquire thread_lock to access the global video_frame object

with thread_lock:

global video_frame

if video_frame is None:

continue

return_key, encoded_image = cv2.imencode(".jpg", video_frame)

if not return_key:

continue

# Output image as a byte array

yield(b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' +

bytearray(encoded_image) + b'\r\n')

@app.get("/")

async def video_feed():#our stream function, streams the frames encodeFrame has made to the IP and port we chose

return StreamingResponse(encodeFrame(), media_type="multipart/x-mixed-replace;boundary=frame")

if __name__ == '__main__':

# Create a thread and attach the method that captures the image frames, to it

process_thread = threading.Thread(target=main)

# Start the thread

process_thread.start()

uvicorn.run(app, host="0.0.0.0", port=9000, access_log=True)我正在使用烧瓶和uvicorn重新流图像到我的java服务器可以读取它们。或者我的发送者编码或接收者解码不起作用,或者两者都是错误的,而且我不确定是哪一个,或者即使我是正确的方向,我对gstreamer和管道相当陌生。我希望在这方面的任何帮助和建议,不需要我重新流也是必要的。