使用python访问海康威视流媒体服务器

由于项目需要,需要访问海康威视的流媒体服务器获取视频流,对视频图象进行识别后,推送到网页进行视频实时监控,图像识别库使用的是yolov8,而yolov8是使用python语言进行开发的,所以决定使用python语言开发一个websocket 服务器,具体工作流程如下图所示:

由于本人使用python较少,因此代码写的比较乱,请大家原谅,以下是具体代码,供大家参考

import traceback
import WebSocketHandler
import Packets
from datetime import datetime
import logging
import json

import requests
from threading import Thread, Lock
from ctypes import *
import numpy as np
import cv2
from ultralytics import YOLO
import supervision as sv
from AbortableSleep import AbortableSleep

logger = logging.getLogger('WebChatSrv.Networking')

__author__ = 'wuhanzhongxintianqi'

FUNC_STREAM=WINFUNCTYPE(None,c_longlong, c_int, c_char_p, c_int, c_void_p)
FUNC_MSG=WINFUNCTYPE(None,c_longlong, c_int, c_void_p)
FUNC_DECODEDSTREAM=WINFUNCTYPE(None,c_longlong, POINTER(c_char), c_int, c_int, c_int, c_int, c_int, c_void_p)
class VIDEO_PLAY_REQ(Structure):
    _fields_=[
    ('iHardWareDecode',c_int),
    ('fnStream',FUNC_STREAM),
    ('fnMsg',FUNC_MSG),
    ('fnDecodedStream',FUNC_DECODEDSTREAM),
    ('pUserData',c_void_p),
    ('szReserve',c_char*64),
    ]

class hikplayer:
    def __init__(self, videosocket:videowebsocket):
        self.dll=WinDLL('F:/hkplayer/bin/VideoSDK.dll')
        self.dll.Video_Init.argtypes=[c_char_p]
        self.dll.Video_Init.restype=c_int
        self.dll.Video_Fini.argtypes=[]
        self.dll.Video_Fini.restype=c_int
        self.dll.Video_GetLastError.argtypes=[]
        self.dll.Video_GetLastError.restype=c_int
        self.dll.Video_StartAsynPreview.argtypes=[c_char_p,c_void_p,POINTER(VIDEO_PLAY_REQ)]
        self.dll.Video_StartAsynPreview.restype=c_longlong
        self.dll.Video_StartPreview.argtypes=[c_char_p,c_void_p,POINTER(VIDEO_PLAY_REQ)]
        self.dll.Video_StartPreview.restype=c_longlong
        self.dll.Video_StopPreview.argtypes=[c_longlong]
        self.dll.Video_StopPreview.restype=c_int
        self.videosocket=videosocket
        self.hikHandle=-1
        self.cb_msgCallback=FUNC_MSG(self.cb_msgCallback)
        self.cb_decodedDataCallback=FUNC_DECODEDSTREAM(self.cb_decodedDataCallback)
        self.dll.Video_Init(None)
        self.box_annotator = sv.BoxAnnotator(
            thickness=2,
            text_thickness=2,
            text_scale=1
        )
        self.queue_obj=[]
        self.abortable_sleep=AbortableSleep()
        self.isWebsocketServerRunning=False
        self.isSendStreamRunning=False
        self.bookLock = Lock()

    async def sendstream(self, webSocket):
        self.isSendStreamRunning=True
        while self.isSendStreamRunning:
            try:
                img=None
                self.bookLock.acquire()
                if (len(self.queue_obj)>0):
                    img=self.queue_obj.pop()
                self.bookLock.release();
                if (not img==None):
                    await webSocket.send(img)
            except Exception as e:
                print(e)
                self.isSendStreamRunning=False

    def stop(self):
        self.isSendStreamRunning=False
        self.abortable_sleep.abort()
        if (self.hikHandle>0):
            self.dll.Video_StopPreview(self.hikHandle)
            self.hikHandle=-1
        self.bookLock.acquire()
        self.queue_obj.clear()
        self.bookLock.release();

    def play(self,url:str):
        req=VIDEO_PLAY_REQ()
        req.iHardWareDecode=0
        req.pUserData=c_void_p(0)
        req.fnStream=FUNC_STREAM(0)
        #req.fnMsg=FUNC_MSG(0)
        #req.fnDecodedStream=FUNC_DECODEDSTREAM(0)

        req.fnMsg=self.cb_msgCallback
        req.fnDecodedStream=self.cb_decodedDataCallback
        self.hikHandle=self.dll.Video_StartAsynPreview(bytes(url,'ascii'),None,byref(req))

    def translate(self,name)->str:
        return name
        if (name=='person'):
            return '人员'
        elif (name=='tv'):
            return '显示屏'
        elif (name=='clock'):
            return '仪表'
        elif (name=='chair'):
            return '椅子'
        else:
            return name
    def cb_decodedDataCallback(self,i64PlayHandle:c_longlong, pDataArray:POINTER(c_char), iDataLen:c_int, iWidth:c_int, iHeight:c_int, iFrameType:c_int, iTimeStamp:c_int, pUserData:c_void_p):
        YUV = np.frombuffer(pDataArray[:iDataLen],dtype=np.uint8, count=iDataLen).reshape(iHeight*3//2,iWidth)
        bgr = cv2.cvtColor(YUV, cv2.COLOR_YUV420p2BGR)
        #bgr=cv2.cvtColor(YUV,cv2.COLOR_YUV2BGR)
        result = self.videosocket.model(bgr, agnostic_nms=True)[0]
        detections = sv.Detections.from_yolov8(result)
        labels = [
            f"{self.translate(self.videosocket.model.model.names[class_id])} {confidence:0.2f}"
            for _, _, confidence, class_id,_
            in detections
        ]
        bgr = self.box_annotator.annotate(
            scene=bgr,
            detections=detections,
            labels=labels
        )
        _,enc=cv2.imencode('.png', bgr)
        self.bookLock.acquire()
        self.queue_obj.append(enc.tobytes())
        if (len(self.queue_obj)>50):
            self.queue_obj.clear()
        self.bookLock.release();
        #cv2.imshow('t',bgr)
        #cv2.waitKey(5)

    def cb_msgCallback(self,i64PlayHandle:c_longlong, iMsg:c_int, pUserData:c_void_p):
        print(iMsg)

    def __del__(self):
        self.stop()


class Clients(object):
    def __init__(self, server):
        self._clients = []
        self._id = 0
        self.ipackets = Packets.IncomingPackets()
        self.server = server

    def __contains__(self, item):
        if isinstance(item, Clients.Client):
            return item in self._clients
        elif isinstance(item, int):
            return not self.get_client(item) is None
        else:
            return False

    def get_client(self, id):
        if not isinstance(id, int):
            raise ValueError('id is not instance of int')
        for c in self._clients:
            if c.id == id:
                return c
        return None

    def new_client(self, socket):
        if not isinstance(socket, WebSocketHandler.WebSocketHandler):
            raise ValueError('socket is not instance of WebSocketHandler')
        if socket not in self:
            cl = self.Client(self._id, socket, self)
            self._id += 1
            self._clients.append(cl)
            return cl
        else:
            raise ValueError('socket already has client')

    def remove_client(self, client):
        client.logger.info('Disconn
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值