目录
[多线程保存mp4 rtsp](#多线程保存mp4 rtsp)
单线程保存mp4
python
import cv2
import imageio
cv2.namedWindow('photo', 0) # 0窗口大小可以任意拖动,1自适应
cv2.resizeWindow('photo', 1280, 720)
url ="rtsp://admin:[email protected]/h264/ch1/main/av_stream"
cap = cv2.VideoCapture(1)
ret = cap.isOpened()
imgs = []
fps =30
index = 0
count = 0
strat_record = False
while (ret):
ret, img = cap.read()
if not ret: break
cv2.imshow('photo', img)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
if strat_record:
imgs.append(img)
index +=1
if index %300 == 299 and strat_record:
count+=1
save_video_path = f'lanqiu_{count}.mp4'
imageio.mimsave(save_video_path, imgs, fps=fps, macro_block_size=None)
imgs=[]
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
elif key == ord('s'):
strat_record = True
print("start_record", strat_record)
elif key == ord('e'):
strat_record = False
print("end_record", strat_record)
cap.release()
save_video_path = f'lanqiu_{count}.mp4'
imageio.mimsave(save_video_path, imgs, fps=fps, macro_block_size=None)
多线程保存mp4 rtsp
python
import cv2
import threading
import queue
import time
# 参数设置
url = "rtsp://admin:[email protected]/h264/ch1/main/av_stream"
fps = 30
segment_time = 10 # 每段录制 10 秒
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# 用于保存帧的队列
frame_queue = queue.Queue()
recording = False
stop_signal = False
video_count = 0
# 保存线程函数
def save_video_worker():
global video_count
while True:
if stop_signal and frame_queue.empty():
break
frames = []
start_time = time.time()
while time.time() - start_time < segment_time:
try:
frame = frame_queue.get(timeout=1)
frames.append(frame)
except queue.Empty:
continue
if frames:
h, w = frames[0].shape[:2]
video_count += 1
save_path = f'lanqiu_{video_count}.mp4'
out = cv2.VideoWriter(save_path, fourcc, fps, (w, h))
for f in frames:
out.write(f)
out.release()
print(f"[保存完成] {save_path}")
# 启动摄像头
cap = cv2.VideoCapture(url)
ret = cap.isOpened()
cv2.namedWindow('photo', 0)
cv2.resizeWindow('photo', 1280, 720)
# 开启保存线程(一直运行,直到设置 stop_signal)
thread = threading.Thread(target=save_video_worker)
thread.start()
while ret:
ret, frame = cap.read()
if not ret:
break
cv2.imshow('photo', frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
elif key == ord('s') and not recording:
recording = True
print("[开始录制]")
elif key == ord('e') and recording:
recording = False
print("[停止录制]")
if recording:
frame_queue.put(frame.copy()) # 用 copy 避免线程间冲突
cap.release()
stop_signal = True
thread.join()
cv2.destroyAllWindows()
ffmpeg录制mp4
python
import subprocess
import threading
import queue
import time
import cv2
import numpy as np
# === 参数设置 ===
rtsp_url = "rtsp://admin:[email protected]/h264/ch1/main/av_stream"
width, height = 1280, 720
fps = 25
segment_time = 10 # 每段录制时间(秒)
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
recording = False
stop_signal = False
video_count = 0
frame_queue = queue.Queue()
# === 保存线程函数 ===
def save_video_worker():
global video_count
while not stop_signal or not frame_queue.empty():
frames = []
start_time = time.time()
while time.time() - start_time < segment_time:
try:
frame = frame_queue.get(timeout=1)
frames.append(frame)
except queue.Empty:
continue
if frames:
video_count += 1
out = cv2.VideoWriter(f'video_segment_{video_count}.mp4', fourcc, fps, (width, height))
for f in frames:
out.write(f)
out.release()
print(f"[保存完成] video_segment_{video_count}.mp4")
# === 启动 FFmpeg 读取 RTSP ===
ffmpeg_cmd = [
r'E:\soft\ffmpeg-7.1.1-full_build\ffmpeg-7.1.1-full_build\bin\ffmpeg.exe',
'-rtsp_transport', 'tcp',
'-i', rtsp_url,
'-f', 'rawvideo',
'-pix_fmt', 'bgr24',
'-vf', f'scale={width}:{height}',
'-'
]
pipe = subprocess.Popen(ffmpeg_cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, bufsize=10**8)
# === 启动保存线程 ===
thread = threading.Thread(target=save_video_worker)
thread.start()
# === 实时显示和按键控制 ===
cv2.namedWindow("photo", 0)
cv2.resizeWindow("photo", width, height)
try:
while True:
raw_frame = pipe.stdout.read(width * height * 3)
if not raw_frame:
print("视频读取失败,退出")
break
frame = np.frombuffer(raw_frame, np.uint8).reshape((height, width, 3))
cv2.imshow("photo", frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
elif key == ord('s') and not recording:
recording = True
print("[开始录制]")
elif key == ord('e') and recording:
recording = False
print("[停止录制]")
if recording:
frame_queue.put(frame.copy())
except KeyboardInterrupt:
print("中断退出")
# === 清理资源 ===
stop_signal = True
thread.join()
pipe.terminate()
cv2.destroyAllWindows()