Python使用rtsp协议录制视频并上传至trueNAS的SMB

因捡回来的摄像头不支持直连NAS,但支持rtsp,所以自己用python写了一个录像功能

1.需要自己改代码中的smb和rtsp的连接配置

2.需要设备支持rtsp协议,笔者部署了一个支持rtsp的海康威视摄像头。需要一个支持SMB的机器存放文件

3.程序运行会产生大量本地硬盘读写,待优化

version >= python3.9

requirements.txt:

anyio==3.7.1
certifi==2023.7.22
cffi==1.15.1
colorama==0.4.6
cryptography==41.0.3
exceptiongroup==1.1.3
h11==0.14.0
httpcore==0.17.3
httpx==0.24.1
idna==3.4
numpy==1.25.2
opencv-python==4.8.0.76
pyasn1==0.5.0
pycparser==2.21
pysmb==1.2.9.1
pyspnego==0.9.1
sniffio==1.3.0
tqdm==4.66.1

record.py

import cv2
import logging
from datetime import datetime
import ctypes
import os
import platform
from smb.SMBConnection import SMBConnection
from concurrent.futures import ProcessPoolExecutor
import time
def smb_connect(user_name, passwd, ip, port):
    '''
    建立smb服务连接
    :param user_name:
    :param passwd:
    :param ip:
    :param port: 445或者139
    :return:
    '''
    samba = None
    status = False
    try:
        samba = SMBConnection(user_name, passwd, '', '', use_ntlm_v2=True)
        samba.connect(ip, port)
        status = samba.auth_result

    except:
        samba.close()
    return samba, status
def video_record(formatted_time,record_second):
    # 海康威视rtsp的url,需要修改user:password@ip:port
    cap = cv2.VideoCapture("rtsp://user:password@ip:port/Streaming/Channels/101")
    frame_s = cap.get(5)
    # 打印帧率
    # print("the frame is:" + str(frame_s))
    fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
    size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
    ret, frame = cap.read()
    time_frame = frame_s * record_second
    num = 0
    while ret:
        if num == 0:
            filename = str(formatted_time) + ".mp4"
            video_writer = cv2.VideoWriter(filename, fourcc, frame_s, size, True)
        ret, frame = cap.read()
        img = cv2.resize(frame, (640, 360), interpolation=cv2.INTER_LINEAR)
        video_writer.write(frame)
        num = num + 1
        if num == time_frame:
            video_writer.release()
            # 上传视频到 SMB 目录
            with open(filename, 'rb') as video_file:
                # 打开一个smb连接
                # smb 需要填写登录账户密码,ip,端口默认445
                samba, status = smb_connect('user', 'password', '192.168.50.87', 445)
                service_name = "monitor"
                smb_dir = 'MonitorSave'
                samba.storeFile(service_name, os.path.join(smb_dir, filename), video_file)
                samba.close()
            num = 0
            os.remove(filename)  # 删除本地视频文件
            break
    #samba.storeFile(service_name, os.path.join(smb_dir, filename), frame)
    video_writer.release()
    cv2.destroyAllWindows()
    cap.release()
def get_free_space_mb(folder):
    if platform.system() == 'Windows':
        free_bytes = ctypes.c_ulonglong(0)
        ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(folder), None, None, ctypes.pointer(free_bytes))
        return free_bytes.value / 1024 / 1024 / 1024
    else:
        st = os.statvfs(folder)
        return st.f_bavail * st.f_frsize / 1024 / 1024

if __name__ == '__main__':
    # 当前目录
    file_path = os.path.abspath('.')
    # 获取目录的剩余空间,单位mb
    storage_space = get_free_space_mb(file_path)
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    pool = ProcessPoolExecutor(max_workers=10)
    while(storage_space>=50):
        try:
            # 获取当前时间
            current_time = datetime.now()
            # 格式化时间为 "年月日时分" 格式
            formatted_time = current_time.strftime("%Y%m%d%H%M%S")
            logging.info("recording: "+str(formatted_time)+".mp4")
            # 单个视频文件持续记录时间,单位秒
            record_time = 60
            #video_record(formatted_time,record_time)
            pool.submit(video_record,formatted_time,record_time)
            # 错位1s,防止录像缺漏
            time.sleep(record_time-1)
        except(Exception) as e:
            logging.error(str(e))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用 Python 推送 RTSP 流,你可以使用 `opencv-python` 库来捕获视频帧并将其编码为视频流,然后使用 `ffmpeg` 库将视频流发送到 RTSP 服务器。 首先,你需要安装 `opencv-python` 和 `ffmpeg` 库。你可以在命令行中使用以下命令来安装它们: ``` pip install opencv-python pip install ffmpeg-python ``` 接下来,你可以使用以下代码来捕获摄像头视频并将其编码为视频流: ```python import cv2 import numpy as np import ffmpeg # 捕获摄像头视频 cap = cv2.VideoCapture(0) # 设置视频编码器 fourcc = cv2.VideoWriter_fourcc(*'XVID') # 获取视频帧大小 frame_width = int(cap.get(3)) frame_height = int(cap.get(4)) # 创建视频编写对象 out = cv2.VideoWriter('output.avi', fourcc, 20.0, (frame_width, frame_height)) # 不断读取并编写视频帧 while True: ret, frame = cap.read() if not ret: break out.write(frame) # 显示视频帧 cv2.imshow('frame', frame) if cv2.waitKey(1) == ord('q'): break # 释放资源 cap.release() out.release() cv2.destroyAllWindows() ``` 一旦你有一个视频流,你就可以使用 `ffmpeg` 库将其发送到 RTSP 服务器。以下是一个使用 `ffmpeg` 的示例代码: ```python import ffmpeg # 输入视频流 input_stream = ffmpeg.input('output.avi') # 设置输出格式和编码器 output_stream = ffmpeg.output(input_stream, 'rtsp://localhost:8554/test', vcodec='copy') # 开始推流 ffmpeg.run(output_stream) ``` 在上面的代码中,`input()` 函数用于指定输入流,`output()` 函数用于指定输出流。在这里,我们将输入流设置为刚刚捕获的视频帧,并将输出流设置为 RTSP 流。最后,我们使用 `run()` 函数开始推流。 请注意,上面的代码仅提供一个基本示例,你需要根据你的具体情况进行修改。例如,你需要使用适当的 RTSP URL,并且可能需要对视频编码进行更改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值