萤石开放平台接入摄像头

目录

场景

准备

代码


场景

获取摄像头资源。实时播放以及录制视频的功能需求。此段代码就是对接萤石云视频,并录制视频记录。

准备

  1. 注册萤石云账户,配置好摄像头协议
  2. 安装ffmpeg 工具
  3. 安装依赖包cv2
  4. 接口文档

代码

# -*- coding: UTF-8 -*-
# Desc   :萤石云视频流对接,并录制视频
import subprocess
import os
import time
import cv2
import requests

# 视频配置
APP_KEY = "app_key"
APP_SECRET = "app_secret"
HEADERS = {'Host': 'open.ys7.com', 'Content-Type': 'application/x-www-form-urlencoded'}


def get_camera_token():
    # 获取camera token
    token_url = f'https://open.ys7.com/api/lapp/token/get?appKey={APP_KEY}&appSecret={APP_SECRET}'
    response = requests.post(token_url, headers=HEADERS)
    # result = response.json()
    # token = response.json()['data']['accessToken']
    token = 'at.7jrcjmna8qnqg8d3dgnzs87m4v2dme3l-32enpqgusd-1jvdfe4-uxo15ik0s'
    return token


def get_video_stream_url(accessToken, deviceSerial, protocol):
    """

    :param accessToken: 访问token
    :param deviceSerial: 设备序列号
    :param protocol: 协议编号
    :return:
    """
    # 获取视频流URL
    try:
        url = f"https://open.ys7.com/api/lapp/v2/live/address/get?accessToken={accessToken}&deviceSerial={deviceSerial}&protocol={protocol}&supportH265=0"
        response = requests.post(url, headers=HEADERS, verify=False)
        msg = response.json()['msg']
        if "Operation succeeded" not in msg:
            return False, msg
        video_url = response.json()['data']['url']
        return True, video_url
    except Exception as e:
        print(e)
        return False, ""


def record_video(deviceSerial, save_path, fps=24, seconds=10):
    """

    :param deviceSerial: 设备序列号
    :param save_path: 录制视频保存路径
    :param fps: 视频帧数
    :param seconds: 视频录制时长
    :return:
    """

    file_dir = os.path.join(save_path, deviceSerial)
    tmp_dir = os.path.join(save_path, 'tmp')
    if not os.path.exists(file_dir):
        os.makedirs(file_dir)
    if not os.path.exists(tmp_dir):
        os.makedirs(tmp_dir)

    accessToken = get_camera_token()

    status, stream_url = get_video_stream_url(accessToken, deviceSerial, "2")
    if not status:
        raise Exception("获取stream_url失败")
    # 初始化视频
    cap = cv2.VideoCapture(stream_url)
    # 经尝试,MP4其他的协议格式均不成功!
    fourcc = cv2.VideoWriter_fourcc('M', 'P', '4', 'v')

    # 设置要保存视频的像素大小 原值是1920*1080,按照原值保存,视频文件很大,
    # 可设置视频帧数,以及时间长度,保存像素大小来改变保存的视频文件大小
    size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH) / 3),
            int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT) / 3))

    start_time = time.time()
    title = f'{int(start_time)}'
    video_tmp = os.path.join(tmp_dir, f'{title}.mp4')
    video_result = os.path.join(file_dir, f'{title}.mp4')
    video = cv2.VideoWriter(video_tmp, fourcc, fps, size)

    while cap.isOpened():
        # 采集一帧一帧的图像数据
        is_success, frame = cap.read()
        if is_success:
            img = cv2.resize(frame, size, interpolation=cv2.INTER_LINEAR)
            video.write(img)
        # 实现按下“q”键退出程序
        # if cv2.waitKey(1) & 0xFF == ord('q'):
        #     break
        if time.time() - start_time >= seconds:
            break

    # 释放视频资源

    video.release()
    cap.release()
    cv2.destroyAllWindows()
    return video_tmp, video_result, title


def mp4_video_record(deviceSerial, save_path):
    video_tmp, video_path, title = record_video(
        deviceSerial=deviceSerial,
        save_path=save_path
    )
    # 还需要对录制下来的视频做处理,之后才能在前端显示,播放
    cmd = f'ffmpeg -i {video_tmp} -strict -2 {video_path}'
    res = subprocess.Popen(
        cmd, shell=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE)
    result = str(res.stderr.readlines()[-1], encoding='utf-8')
    if 'No such file or directory' in result:
        print("录制视频失败")
    elif not os.path.exists(video_path):
        print("录制视频失败")
    else:
        print("保存视频路径到数据库")



def back2():
   
    cap = cv2.VideoCapture(r['data']['url'])
    fps = cap.get(cv2.CAP_PROP_FPS)
    print(fps)
    # 获取cap视频流的每帧像素大小
    size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
        int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))

    # 定义编码格式mpge-4
    fourcc = cv2.VideoWriter_fourcc('M', 'P', '4', '2')
    # 定义视频文件输入对象
    outVideo = cv2.VideoWriter('saveDir.avi', fourcc, fps, size) #size必须和视频流的帧大   小一致,否则无法执行

    # 获取视频流打开状态
    if cap.isOpened():
        rval, frame = cap.read()
        print('ture')
    else:
        rval = False
        print('False')

    tot = 1
    c = 1
    # 循环使用cv2的read()方法读取视频帧
    while rval:
        rval, frame = cap.read()
        frame = cv2.resize(frame, (400, 300)) #调整画面大小
        cv2.imshow('test', frame)

        # 使用VideoWriter类中的write(frame)方法,将图像帧写入视频文件
        outVideo.write(frame)
        cv2.waitKey(25)

    cap.release()
    outVideo.release()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    # 对接萤石云摄像头
    mp4_video_record("123", "/")

### 海康威视摄像头接入萤石的配置方法 #### 准备工作 在开始之前,需确认以下条件已满足: - 确保海康威视摄像头能够正常联网并可以通过网络访问。 - 录像机或摄像头的 IPv4 地址应设置为 `192.168.0.xx` 的形式,其中 `xx` 可自行设定,但要确保不与其他设备 IP 冲突[^3]。 #### 设备连接与协议选择 萤石开放平台支持通过 Ehome 协议接入海康威视摄像头。此协议专为移动监控场景设计,提供高效的设备接入方式[^2]。因此,在准备阶段需要确保摄像头支持该协议,并在网络环境中正确配置。 #### 配置步骤详解 以下是具体的配置流程: ##### 1. 注册并登录萤石账户 前往萤石官网注册账号并完成验证过程。随后登录至萤石开放平台管理界面。 ##### 2. 添加国标设备 进入萤石开放平台后,找到 **“设备管理”** 页面中的 **“添加设备”** 功能选项。在此处输入海康威视摄像头的相关参数,包括但不限于设备序列号、IP 地址以及其他必要信息。 ##### 3. 设置Ehome协议 由于采用的是 Ehome 协议作为通信桥梁,所以需要进一步调整摄像装置内部设置来启用它。通常情况下可以在其Web管理界面上寻得对应项开启服务端口监听等功能以便于外部调用请求到达时能及时响应处理数据流传输等问题解决办法如下所示: ```bash # 假设默认EHOMEPORT为37777, 如果有防火墙则允许TCP/UDP流量通行 sudo ufw allow 37777/tcp sudo ufw allow 37777/udp ``` 以上命令适用于Linux环境下操作系统的防火墙规则修改情况;对于Windows或者其他操作系统可能略有差异,请参照各自官方文档执行相应指令集以达成相同效果即打开指定端口号供外界合法访问使用。 ##### 4. 绑定设备到端 当上述准备工作完成后返回至先前提到过的那个位置继续往下走就是绑定环节了——将本地局域网内的物理实体映射成为虚拟世界里的逻辑存在从而实现远程操控目的最终达到随时随地查看实时画面或者回放历史记录等等一系列便利之处尽收眼底一览无余矣乎哉! 此时应该能看到所添加成功的图标显示出来代表着整个流程接近尾声只差最后一步测试检验成果是否符合预期标准而已啦😊 --- ### 注意事项 在整个过程中可能会遇到各种各样的问题比如无法识别新增加进来的新成员又或者是虽然表面上看起来一切正常但实际上却始终得不到想要的结果等情况发生都是比较常见的现象不必太过担心只需耐心排查逐一排除潜在隐患直至彻底解决问题为止就可以了💪 另外值得注意的一点在于不同型号之间可能存在细微差别所以在实际动手实践的时候最好还是查阅一下产品说明书获取更加精准详实的信息指导行动方向更为稳妥可靠一些哦😉 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

**星光*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值