Python读取摄像头视频流存FTP服务器后视频不可读,求解决方案
问题分析与解决方案
你的代码存在两个核心问题,导致生成的视频无法播放:
- 错误的视频存储方式:
frame是单帧图像的numpy数组,直接写入BytesIO再上传,没有遵循MP4的容器格式规范——MP4需要包含编码信息、帧索引等元数据,不是单纯的帧数据堆叠。 - 重复覆盖文件:每次循环执行
ftp.storbinary('STOR video.mp4', flo)都会覆盖之前的文件,最终FTP上的video.mp4只会保留最后一帧的无效数据。
方案1:先本地编码为合法MP4再上传(适合短时长录制)
先使用OpenCV的VideoWriter将帧序列编码为标准MP4文件,再上传到FTP:
from ftplib import FTP import cv2 # FTP连接配置 ftp = FTP('my-ftp-host-server') ftp.login('my-ftp-user-id', 'my-ftp-password') # 摄像头流读取 cap = cv2.VideoCapture('rtsp://camera-username:camera-password@192.168.2.122/1') if not cap.isOpened(): print("无法打开摄像头流") exit() # 获取摄像头参数,初始化VideoWriter frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps = int(cap.get(cv2.CAP_PROP_FPS)) # 使用MP4编码(注意不同系统可能需要调整编码器,比如Windows用'AVC1',Linux用'MP4V') fourcc = cv2.VideoWriter_fourcc(*'mp4v') local_video_path = 'local_video.mp4' out = cv2.VideoWriter(local_video_path, fourcc, fps, (frame_width, frame_height)) # 读取帧并写入本地文件 while cap.isOpened(): ret, frame = cap.read() if ret: out.write(frame) else: break # 释放资源 cap.release() out.release() # 上传本地MP4到FTP with open(local_video_path, 'rb') as f: ftp.storbinary('STOR video.mp4', f) ftp.quit()
方案2:边编码边上传到FTP(适合长时间录制,节省本地空间)
如果不想占用本地磁盘空间,可以将编码后的视频数据直接写入FTP,无需本地文件:
from ftplib import FTP from io import BytesIO import cv2 # FTP连接配置 ftp = FTP('my-ftp-host-server') ftp.login('my-ftp-user-id', 'my-ftp-password') # 摄像头流读取 cap = cv2.VideoCapture('rtsp://camera-username:camera-password@192.168.2.122/1') if not cap.isOpened(): print("无法打开摄像头流") exit() # 获取摄像头参数 frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps = int(cap.get(cv2.CAP_PROP_FPS)) fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 创建内存中的BytesIO对象来存储编码后的视频数据 video_buffer = BytesIO() # 初始化VideoWriter,写入到内存缓冲区 out = cv2.VideoWriter(video_buffer, fourcc, fps, (frame_width, frame_height)) # 读取帧并编码到内存 while cap.isOpened(): ret, frame = cap.read() if ret: out.write(frame) else: break # 释放资源 cap.release() out.release() # 将缓冲区指针移到开头,准备上传 video_buffer.seek(0) ftp.storbinary('STOR video.mp4', video_buffer) ftp.quit() video_buffer.close()
额外注意事项
- 编码器兼容性:不同操作系统对MP4编码器的支持不同,如果
mp4v无效,可以尝试'avc1'(H.264)或'XVID'。 - FTP被动模式:如果处于防火墙或NAT环境下,可能需要启用FTP被动模式:
ftp.set_pasv(True)。 - 流稳定性:RTSP流可能会出现断连情况,建议添加重连逻辑和异常捕获。
内容的提问来源于stack exchange,提问作者Herval NGANYA
相关产品推荐
相关产品推荐

