Flask视频流接口读取帧到PyCharm仅获首帧的解决求助
解决Flask视频流客户端仅读取第一帧的问题
问题根源
你的客户端脚本每次循环都重新发起HTTP请求,服务器每次都会从指定的start_frame开始返回第一帧,导致你看到的始终是同一帧;同时resp.read()会一次性读取当前可用的响应数据,但流式响应需要持续读取而非重复请求。
另外服务器端的Content-Type设置有误,应该为image/jpeg而非text/plain,虽然浏览器能兼容,但规范上需要修正。
修正后的客户端代码
使用持续连接读取流式响应,逐帧解析multipart数据:
import urllib.request import numpy as np import cv2 url = "http://127.0.0.1:8000/video_feed/?start_frame=4000&end_frame=5001" # 建立一次连接,获取流式响应对象 resp = urllib.request.urlopen(url) boundary = b'--frame' # 对应服务器端的boundary buffer = b'' while True: # 逐块读取数据,直到遇到边界 chunk = resp.read(4096) if not chunk: break # 响应结束 buffer += chunk # 分割出完整的帧数据 while boundary in buffer: # 分割边界和帧内容 part, buffer = buffer.split(boundary, 1) if b'\r\n\r\n' in part: # 提取图片数据部分 header, img_data = part.split(b'\r\n\r\n', 1) # 去除末尾的换行符 img_data = img_data.rstrip(b'\r\n') if img_data: # 解码图片 i = np.frombuffer(img_data, dtype=np.uint8) img = cv2.imdecode(i, cv2.IMREAD_UNCHANGED) cv2.imshow("frame", img) if cv2.waitKey(16) & 0xFF == ord('q'): resp.close() cv2.destroyAllWindows() exit() cv2.destroyAllWindows()
服务器端小修正
将Content-Type改为image/jpeg,符合规范:
yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + stringData + b'\r\n')
代码说明
- 持续连接:只发起一次HTTP请求,保持连接读取服务器的流式输出,避免重复请求导致的重复第一帧问题。
- 分帧解析:通过
boundary分割multipart响应,逐帧提取图片数据,处理流式数据的分块特性。 - 缓冲区处理:用缓冲区累积读取的数据,确保能分割出完整的帧,避免因分块读取导致的帧数据不完整。
内容的提问来源于stack exchange,提问作者JonnyN64
相关产品推荐
相关产品推荐

