本地rtsp录制及上传程序
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
import cv2
|
||||
import time
|
||||
from datetime import datetime
|
||||
import os
|
||||
import paramiko
|
||||
|
||||
class SFTPClient:
|
||||
def __init__(self):
|
||||
self.hostname = "222.186.10.253"
|
||||
self.username = "zydi"
|
||||
self.password = "Obscura@2024"
|
||||
self.remote_base_path = "/home/zydi/WEB/recordings"
|
||||
self.sftp = None
|
||||
self.transport = None
|
||||
self.connect()
|
||||
|
||||
def connect(self):
|
||||
try:
|
||||
if self.transport and self.transport.is_active():
|
||||
return
|
||||
self.transport = paramiko.Transport((self.hostname, 22))
|
||||
self.transport.connect(username=self.username, password=self.password)
|
||||
self.sftp = paramiko.SFTPClient.from_transport(self.transport)
|
||||
print("成功连接到SFTP服务器")
|
||||
except Exception as e:
|
||||
print(f"SFTP连接失败: {str(e)}")
|
||||
raise
|
||||
|
||||
def upload_file(self, local_file_path, camera_name):
|
||||
try:
|
||||
if not self.transport or not self.transport.is_active():
|
||||
self.connect()
|
||||
|
||||
remote_camera_dir = f"{self.remote_base_path}/{camera_name}"
|
||||
try:
|
||||
self.sftp.stat(remote_camera_dir)
|
||||
except IOError:
|
||||
self.sftp.mkdir(remote_camera_dir)
|
||||
|
||||
remote_file_path = f"{remote_camera_dir}/{os.path.basename(local_file_path)}"
|
||||
self.sftp.put(local_file_path, remote_file_path)
|
||||
print(f"文件上传成功: {remote_file_path}")
|
||||
except Exception as e:
|
||||
print(f"上传失败: {str(e)}")
|
||||
self.connect() # 尝试重新连接
|
||||
|
||||
# 在主程序开始时创建SFTP客户端实例
|
||||
sftp_client = SFTPClient()
|
||||
|
||||
def record_rtsp_stream(rtsp_url, camera_name, start_delay=0):
|
||||
RECORD_DURATION = 10
|
||||
INTERVAL = 120 # 2分钟的循环
|
||||
UPLOAD_INTERVAL = 600 # 10分钟上传一次
|
||||
last_upload_time = time.time()
|
||||
pending_uploads = [] # 记录待上传的视频文件
|
||||
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
base_output_dir = os.path.join(script_dir, "recordings")
|
||||
output_dir = os.path.join(base_output_dir, camera_name)
|
||||
|
||||
# 创建必要的文件夹
|
||||
for dir_path in [base_output_dir, output_dir]:
|
||||
if not os.path.exists(dir_path):
|
||||
os.makedirs(dir_path)
|
||||
|
||||
time.sleep(start_delay)
|
||||
|
||||
while True:
|
||||
try:
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
output_file = os.path.join(output_dir, f'{camera_name}_{timestamp}.avi')
|
||||
|
||||
# 创建视频捕获对象
|
||||
cap = cv2.VideoCapture(rtsp_url)
|
||||
if not cap.isOpened():
|
||||
raise Exception(f"无法连接到RTSP流: {rtsp_url}")
|
||||
|
||||
# 获取原始视频属性并计算缩放后的尺寸
|
||||
fps = 10
|
||||
original_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
||||
original_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
||||
scale_factor = 0.7
|
||||
width = int(original_width * scale_factor)
|
||||
height = int(original_height * scale_factor)
|
||||
|
||||
# 创建视频写入对象
|
||||
fourcc = cv2.VideoWriter_fourcc(*'XVID')
|
||||
out = cv2.VideoWriter(output_file, fourcc, fps, (width, height))
|
||||
|
||||
print(f"开始录制 {camera_name}: {output_file}")
|
||||
|
||||
frame_count = 0
|
||||
total_frames = fps * RECORD_DURATION
|
||||
|
||||
while frame_count < total_frames:
|
||||
ret, frame = cap.read()
|
||||
if not ret:
|
||||
break
|
||||
resized_frame = cv2.resize(frame, (width, height))
|
||||
out.write(resized_frame)
|
||||
frame_count += 1
|
||||
time.sleep(1/fps)
|
||||
|
||||
cap.release()
|
||||
out.release()
|
||||
|
||||
print(f"录制完成 {camera_name}: {output_file}")
|
||||
pending_uploads.append(output_file) # 添加到待上传列表
|
||||
|
||||
# 检查是否需要批量上传
|
||||
current_time = time.time()
|
||||
if current_time - last_upload_time >= UPLOAD_INTERVAL:
|
||||
print(f"开始批量上传 {camera_name} 的视频文件")
|
||||
# 上传累积的视频文件
|
||||
for file_path in pending_uploads:
|
||||
if os.path.exists(file_path): # 确保文件存在
|
||||
sftp_client.upload_file(file_path, camera_name)
|
||||
pending_uploads = [] # 清空待上传列表
|
||||
last_upload_time = current_time
|
||||
print(f"{camera_name} 的视频文件批量上传完成")
|
||||
|
||||
time.sleep(INTERVAL - RECORD_DURATION)
|
||||
|
||||
except Exception as e:
|
||||
print(f"错误 {camera_name}: {e}")
|
||||
time.sleep(5)
|
||||
|
||||
if __name__ == "__main__":
|
||||
rtsp_url1 = "rtsp://admin:Obscura@[email protected]:554//h264/ch1/main/av_stream"
|
||||
rtsp_url2 = "rtsp://admin:[email protected]:554//h264/ch1/main/av_stream"
|
||||
|
||||
from threading import Thread
|
||||
|
||||
# 创建两个线程,使用固定的摄像头名称
|
||||
t1 = Thread(target=record_rtsp_stream, args=(rtsp_url1, "A01", 0))
|
||||
t2 = Thread(target=record_rtsp_stream, args=(rtsp_url2, "B02", 60))
|
||||
|
||||
t1.start()
|
||||
t2.start()
|
||||
|
||||
t1.join()
|
||||
t2.join()
|
||||
Reference in New Issue
Block a user