<?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||
<project version="4"> | <project version="4"> | ||||
<component name="PublishConfigData" autoUpload="Always" serverName="192.168.11.8" remoteFilesAllowedToDisappearOnAutoupload="false"> | |||||
<component name="PublishConfigData" autoUpload="Always" serverName="192.168.11.7" remoteFilesAllowedToDisappearOnAutoupload="false"> | |||||
<serverData> | <serverData> | ||||
<paths name="10.21"> | <paths name="10.21"> | ||||
<serverdata> | <serverdata> | ||||
</mappings> | </mappings> | ||||
</serverdata> | </serverdata> | ||||
</paths> | </paths> | ||||
<paths name="192.168.11.7"> | |||||
<serverdata> | |||||
<mappings> | |||||
<mapping deploy="/home/th/tuo_heng/test/tuoheng_alg" local="$PROJECT_DIR$" web="/" /> | |||||
</mappings> | |||||
</serverdata> | |||||
</paths> | |||||
<paths name="192.168.11.8"> | <paths name="192.168.11.8"> | ||||
<serverdata> | <serverdata> | ||||
<mappings> | <mappings> |
<sshConfig authType="PASSWORD" host="192.168.10.22" id="ac18a75e-ff42-4875-a5da-ad98d2d695ea" port="22" nameFormat="DESCRIPTIVE" username="th" /> | <sshConfig authType="PASSWORD" host="192.168.10.22" id="ac18a75e-ff42-4875-a5da-ad98d2d695ea" port="22" nameFormat="DESCRIPTIVE" username="th" /> | ||||
<sshConfig authType="PASSWORD" connectionConfig="{"serverAliveInterval":300}" host="192.168.10.66" id="dcf03076-1bc5-4ce3-a4e4-38f7f00ea74a" port="32782" nameFormat="DESCRIPTIVE" username="root" /> | <sshConfig authType="PASSWORD" connectionConfig="{"serverAliveInterval":300}" host="192.168.10.66" id="dcf03076-1bc5-4ce3-a4e4-38f7f00ea74a" port="32782" nameFormat="DESCRIPTIVE" username="root" /> | ||||
<sshConfig authType="PASSWORD" host="192.168.11.8" id="34e9c3c2-edbc-42f0-8c89-cb75bfdf55e1" port="32178" nameFormat="DESCRIPTIVE" username="th" /> | <sshConfig authType="PASSWORD" host="192.168.11.8" id="34e9c3c2-edbc-42f0-8c89-cb75bfdf55e1" port="32178" nameFormat="DESCRIPTIVE" username="th" /> | ||||
<sshConfig authType="PASSWORD" host="192.168.11.7" id="5bb44c10-4e9c-4059-a0c0-9f2596b74bc0" port="22" nameFormat="DESCRIPTIVE" username="th" /> | |||||
</configs> | </configs> | ||||
</component> | </component> | ||||
</project> | </project> |
</advancedOptions> | </advancedOptions> | ||||
</fileTransfer> | </fileTransfer> | ||||
</webServer> | </webServer> | ||||
<webServer id="d52d4eb1-ad07-4dd6-adac-d5e84d4a0f0c" name="192.168.11.7"> | |||||
<fileTransfer accessType="SFTP" host="192.168.11.7" port="22" sshConfigId="5bb44c10-4e9c-4059-a0c0-9f2596b74bc0" sshConfig="th@192.168.11.7:22 password"> | |||||
<advancedOptions> | |||||
<advancedOptions dataProtectionLevel="Private" keepAliveTimeout="0" passiveMode="true" shareSSLContext="true" /> | |||||
</advancedOptions> | |||||
</fileTransfer> | |||||
</webServer> | |||||
</option> | </option> | ||||
</component> | </component> | ||||
</project> | </project> |
</component> | </component> | ||||
<component name="ChangeListManager"> | <component name="ChangeListManager"> | ||||
<list default="true" id="4f7dccd9-8f92-4a6e-90cc-33890d102263" name="Changes" comment="Changes"> | <list default="true" id="4f7dccd9-8f92-4a6e-90cc-33890d102263" name="Changes" comment="Changes"> | ||||
<change beforePath="$PROJECT_DIR$/.idea/deployment.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/deployment.xml" afterDir="false" /> | |||||
<change beforePath="$PROJECT_DIR$/.idea/sshConfigs.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/sshConfigs.xml" afterDir="false" /> | |||||
<change beforePath="$PROJECT_DIR$/.idea/webServers.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/webServers.xml" afterDir="false" /> | |||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> | <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> | ||||
<change beforePath="$PROJECT_DIR$/concurrency/IntelligentRecognitionProcess.py" beforeDir="false" afterPath="$PROJECT_DIR$/concurrency/IntelligentRecognitionProcess.py" afterDir="false" /> | |||||
<change beforePath="$PROJECT_DIR$/enums/ModelTypeEnum.py" beforeDir="false" afterPath="$PROJECT_DIR$/enums/ModelTypeEnum.py" afterDir="false" /> | |||||
<change beforePath="$PROJECT_DIR$/concurrency/PullVideoStreamProcess.py" beforeDir="false" afterPath="$PROJECT_DIR$/concurrency/PullVideoStreamProcess.py" afterDir="false" /> | |||||
<change beforePath="$PROJECT_DIR$/util/Cv2Utils.py" beforeDir="false" afterPath="$PROJECT_DIR$/util/Cv2Utils.py" afterDir="false" /> | |||||
<change beforePath="$PROJECT_DIR$/util/ModelUtils.py" beforeDir="false" afterPath="$PROJECT_DIR$/util/ModelUtils.py" afterDir="false" /> | |||||
</list> | </list> | ||||
<option name="SHOW_DIALOG" value="false" /> | <option name="SHOW_DIALOG" value="false" /> | ||||
<option name="HIGHLIGHT_CONFLICTS" value="true" /> | <option name="HIGHLIGHT_CONFLICTS" value="true" /> | ||||
<workItem from="1675298111671" duration="1710000" /> | <workItem from="1675298111671" duration="1710000" /> | ||||
<workItem from="1675388395566" duration="5304000" /> | <workItem from="1675388395566" duration="5304000" /> | ||||
<workItem from="1675643763842" duration="771000" /> | <workItem from="1675643763842" duration="771000" /> | ||||
<workItem from="1676269822235" duration="1871000" /> | |||||
<workItem from="1676269822235" duration="1954000" /> | |||||
<workItem from="1676362382024" duration="821000" /> | |||||
<workItem from="1676424351744" duration="4050000" /> | |||||
<workItem from="1676506502236" duration="585000" /> | |||||
<workItem from="1676871078953" duration="337000" /> | |||||
<workItem from="1676895744433" duration="4418000" /> | |||||
<workItem from="1676944131792" duration="515000" /> | |||||
<workItem from="1677036599171" duration="4605000" /> | |||||
<workItem from="1677112353743" duration="588000" /> | |||||
<workItem from="1677574708616" duration="34000" /> | |||||
<workItem from="1677632498068" duration="4279000" /> | |||||
<workItem from="1677654510460" duration="1688000" /> | |||||
</task> | </task> | ||||
<servers /> | <servers /> | ||||
</component> | </component> | ||||
</line-breakpoint> | </line-breakpoint> | ||||
<line-breakpoint enabled="true" suspend="THREAD" type="python-line"> | <line-breakpoint enabled="true" suspend="THREAD" type="python-line"> | ||||
<url>file://$PROJECT_DIR$/util/Cv2Utils.py</url> | <url>file://$PROJECT_DIR$/util/Cv2Utils.py</url> | ||||
<line>1</line> | |||||
<line>2</line> | |||||
<option name="timeStamp" value="2" /> | <option name="timeStamp" value="2" /> | ||||
</line-breakpoint> | </line-breakpoint> | ||||
</breakpoints> | </breakpoints> |
from enums.AnalysisTypeEnum import AnalysisType | from enums.AnalysisTypeEnum import AnalysisType | ||||
from enums.ExceptionEnum import ExceptionType | from enums.ExceptionEnum import ExceptionType | ||||
from exception.CustomerException import ServiceException | from exception.CustomerException import ServiceException | ||||
from util import LogUtils | |||||
from util.Cv2Utils import Cv2Util | from util.Cv2Utils import Cv2Util | ||||
class OnlinePullVideoStreamProcess(PullVideoStreamProcess): | class OnlinePullVideoStreamProcess(PullVideoStreamProcess): | ||||
def run(self): | def run(self): | ||||
LogUtils.init_log(self.content) | |||||
cv2tool = None | cv2tool = None | ||||
imageFileUpdate = None | imageFileUpdate = None | ||||
hb = None | hb = None | ||||
while True: | while True: | ||||
end_time = time.time() | end_time = time.time() | ||||
create_task_time = int(end_time - start_time) | create_task_time = int(end_time - start_time) | ||||
# 检测任务执行是否超时 | |||||
if create_task_time > self.service_timeout: | if create_task_time > self.service_timeout: | ||||
logger.error("分析超时, 超时时间:{}, requestId: {}", create_task_time, self.msg.get("request_id")) | logger.error("分析超时, 超时时间:{}, requestId: {}", create_task_time, self.msg.get("request_id")) | ||||
raise ServiceException(ExceptionType.ANALYSE_TIMEOUT_EXCEPTION.value[0], | raise ServiceException(ExceptionType.ANALYSE_TIMEOUT_EXCEPTION.value[0], | ||||
ExceptionType.ANALYSE_TIMEOUT_EXCEPTION.value[1]) | ExceptionType.ANALYSE_TIMEOUT_EXCEPTION.value[1]) | ||||
# 检测图片上传线程是否正常运行 | |||||
if not imageFileUpdate.is_alive(): | if not imageFileUpdate.is_alive(): | ||||
logger.error("未检测到图片上传线程活动,图片上传线程可能出现异常, reuqestId:{}", self.msg.get("request_id")) | logger.error("未检测到图片上传线程活动,图片上传线程可能出现异常, reuqestId:{}", self.msg.get("request_id")) | ||||
raise Exception("未检测到图片上传线程活动,图片上传线程可能出现异常!") | raise Exception("未检测到图片上传线程活动,图片上传线程可能出现异常!") | ||||
# 检测心跳线程是否正常运行 | |||||
if not hb.is_alive(): | if not hb.is_alive(): | ||||
logger.error("未检测到心跳线程活动,心跳线程可能出现异常, reuqestId:{}", self.msg.get("request_id")) | logger.error("未检测到心跳线程活动,心跳线程可能出现异常, reuqestId:{}", self.msg.get("request_id")) | ||||
raise Exception("未检测到心跳线程活动,心跳线程可能出现异常!") | raise Exception("未检测到心跳线程活动,心跳线程可能出现异常!") | ||||
if self.pullQueue.full(): | if self.pullQueue.full(): | ||||
time.sleep(0.1) | time.sleep(0.1) | ||||
continue | continue | ||||
# 检测视频信息是否存在或拉流对象是否存在 | |||||
if cv2tool.checkconfig() or cv2tool.pull_p is None: | if cv2tool.checkconfig() or cv2tool.pull_p is None: | ||||
logger.info("开始重新获取视频信息: {}次, requestId: {}", cv2_init_num, self.msg.get("request_id")) | logger.info("开始重新获取视频信息: {}次, requestId: {}", cv2_init_num, self.msg.get("request_id")) | ||||
pull_stream_init_timeout = time.time() - start_time_1 | pull_stream_init_timeout = time.time() - start_time_1 | ||||
raise ServiceException(ExceptionType.PULLSTREAM_TIMEOUT_EXCEPTION.value[0], | raise ServiceException(ExceptionType.PULLSTREAM_TIMEOUT_EXCEPTION.value[0], | ||||
ExceptionType.PULLSTREAM_TIMEOUT_EXCEPTION.value[1]) | ExceptionType.PULLSTREAM_TIMEOUT_EXCEPTION.value[1]) | ||||
cv2_init_num += 1 | cv2_init_num += 1 | ||||
time.sleep(2) | |||||
time.sleep(0.5) | |||||
cv2tool.get_video_info() | cv2tool.get_video_info() | ||||
cv2tool.build_pull_p() | cv2tool.build_pull_p() | ||||
continue | continue | ||||
cv2tool.close() | cv2tool.close() | ||||
continue | continue | ||||
init_pull_num += 1 | init_pull_num += 1 | ||||
time.sleep(1) | |||||
time.sleep(0.1) | |||||
cv2tool.build_pull_p() | cv2tool.build_pull_p() | ||||
continue | continue | ||||
init_pull_num = 1 | init_pull_num = 1 | ||||
class OfflinePullVideoStreamProcess(PullVideoStreamProcess): | class OfflinePullVideoStreamProcess(PullVideoStreamProcess): | ||||
def run(self): | def run(self): | ||||
LogUtils.init_log(self.content) | |||||
cv2tool = None | cv2tool = None | ||||
imageFileUpdate = None | imageFileUpdate = None | ||||
hb = None | hb = None | ||||
raise ServiceException(ExceptionType.OR_VIDEO_ADDRESS_EXCEPTION.value[0], | raise ServiceException(ExceptionType.OR_VIDEO_ADDRESS_EXCEPTION.value[0], | ||||
ExceptionType.OR_VIDEO_ADDRESS_EXCEPTION.value[1]) | ExceptionType.OR_VIDEO_ADDRESS_EXCEPTION.value[1]) | ||||
cv2_init_num += 1 | cv2_init_num += 1 | ||||
time.sleep(2) | |||||
time.sleep(1) | |||||
cv2tool.get_video_info() | cv2tool.get_video_info() | ||||
cv2tool.build_pull_p() | cv2tool.build_pull_p() | ||||
continue | continue |
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
import json | |||||
import time | import time | ||||
import cv2 | import cv2 | ||||
import subprocess as sp | import subprocess as sp | ||||
import ffmpeg | |||||
import numpy as np | import numpy as np | ||||
from loguru import logger | from loguru import logger | ||||
from exception.CustomerException import ServiceException | from exception.CustomerException import ServiceException | ||||
self.hn = int(self.height) | self.hn = int(self.height) | ||||
self.wn = int(self.width) | self.wn = int(self.width) | ||||
def clear_video_info(self): | |||||
self.fps = None | |||||
self.width = None | |||||
self.height = None | |||||
''' | ''' | ||||
获取视频信息 | 获取视频信息 | ||||
''' | ''' | ||||
logger.error("拉流地址不能为空, requestId:{}", self.requestId) | logger.error("拉流地址不能为空, requestId:{}", self.requestId) | ||||
raise ServiceException(ExceptionType.PULL_STREAM_URL_EXCEPTION.value[0], | raise ServiceException(ExceptionType.PULL_STREAM_URL_EXCEPTION.value[0], | ||||
ExceptionType.PULL_STREAM_URL_EXCEPTION.value[1]) | ExceptionType.PULL_STREAM_URL_EXCEPTION.value[1]) | ||||
probe = ffmpeg.probe(self.pullUrl) | |||||
args = ['ffprobe', '-show_format', '-show_streams', '-of', 'json', self.pullUrl] | |||||
p = sp.Popen(args, stdout=sp.PIPE, stderr=sp.PIPE) | |||||
out, err = p.communicate(timeout=20) | |||||
if p.returncode != 0: | |||||
raise Exception("未获取视频信息!!!!!requestId:" + self.requestId) | |||||
probe = json.loads(out.decode('utf-8')) | |||||
if probe is None or probe.get("streams") is None: | if probe is None or probe.get("streams") is None: | ||||
return | |||||
raise Exception("未获取视频信息!!!!!requestId:" + self.requestId) | |||||
# 视频大小 | # 视频大小 | ||||
# format = probe['format'] | # format = probe['format'] | ||||
# size = int(format['size'])/1024/1024 | # size = int(format['size'])/1024/1024 | ||||
video_stream = next((stream for stream in probe['streams'] if stream.get('codec_type') == 'video'), None) | video_stream = next((stream for stream in probe['streams'] if stream.get('codec_type') == 'video'), None) | ||||
if video_stream is None: | if video_stream is None: | ||||
logger.error("根据拉流地址未获取到视频流, requestId:{}", self.requestId) | |||||
return | |||||
raise Exception("未获取视频信息!!!!!requestId:" + self.requestId) | |||||
width = video_stream.get('width') | width = video_stream.get('width') | ||||
height = video_stream.get('height') | height = video_stream.get('height') | ||||
nb_frames = video_stream.get('nb_frames') | nb_frames = video_stream.get('nb_frames') | ||||
bit_rate = video_stream.get('bit_rate') | bit_rate = video_stream.get('bit_rate') | ||||
self.width = int(width) | self.width = int(width) | ||||
self.height = int(height) | self.height = int(height) | ||||
if width is not None and height is not None: | |||||
if width > 1600: | |||||
self.wh = int(width * height * 3 // 8) | |||||
self.wah = '%sx%s' % (int(self.width / 2), int(self.height / 2)) | |||||
self.h = int(self.height * 3 // 4) | |||||
self.w = int(self.width / 2) | |||||
self.hn = int(self.height / 2) | |||||
self.wn = int(self.width // 2) | |||||
w_f = self.wh != width * height * 3 / 8 | |||||
h_f = self.h != self.height * 3 / 4 | |||||
wd_f = self.w != self.width / 2 | |||||
if w_f or h_f or wd_f: | |||||
self.resize_status = True | |||||
self.wh = int(width * height * 3 // 2) | |||||
self.wah = '%sx%s' % (int(self.width), int(self.height)) | |||||
self.h = int(self.height * 3 // 2) | |||||
self.w = int(self.width) | |||||
else: | |||||
if width > 1600: | |||||
self.wh = int(width * height * 3 // 8) | |||||
self.wah = '%sx%s' % (int(self.width / 2), int(self.height / 2)) | |||||
self.h = int(self.height * 3 // 4) | |||||
self.w = int(self.width / 2) | |||||
self.hn = int(self.height / 2) | |||||
self.wn = int(self.width // 2) | |||||
w_f = self.wh != width * height * 3 / 8 | |||||
h_f = self.h != self.height * 3 / 4 | |||||
wd_f = self.w != self.width / 2 | |||||
if w_f or h_f or wd_f: | |||||
self.resize_status = True | |||||
self.wh = int(width * height * 3 // 2) | self.wh = int(width * height * 3 // 2) | ||||
self.wah = '%sx%s' % (int(self.width), int(self.height)) | self.wah = '%sx%s' % (int(self.width), int(self.height)) | ||||
self.h = int(self.height * 3 // 2) | self.h = int(self.height * 3 // 2) | ||||
self.w = int(self.width) | self.w = int(self.width) | ||||
self.hn = int(self.height) | |||||
self.wn = int(self.width) | |||||
else: | |||||
self.wh = int(width * height * 3 // 2) | |||||
self.wah = '%sx%s' % (int(self.width), int(self.height)) | |||||
self.h = int(self.height * 3 // 2) | |||||
self.w = int(self.width) | |||||
self.hn = int(self.height) | |||||
self.wn = int(self.width) | |||||
if nb_frames: | if nb_frames: | ||||
self.all_frames = int(nb_frames) | self.all_frames = int(nb_frames) | ||||
if fps: | |||||
up, down = str(fps).split('/') | |||||
self.fps = int(eval(up) / eval(down)) | |||||
up, down = str(fps).split('/') | |||||
self.fps = int(eval(up) / eval(down)) | |||||
# if duration: | # if duration: | ||||
# self.duration = float(video_stream['duration']) | # self.duration = float(video_stream['duration']) | ||||
if bit_rate: | |||||
self.bit_rate = int(bit_rate) / 1000 | |||||
self.bit_rate = int(bit_rate) / 1000 | |||||
logger.info("视频信息, width:{}|height:{}|fps:{}|all_frames:{}|bit_rate:{}, requestId:{}", self.width, | logger.info("视频信息, width:{}|height:{}|fps:{}|all_frames:{}|bit_rate:{}, requestId:{}", self.width, | ||||
self.height, self.fps, self.all_frames, self.bit_rate, self.requestId) | self.height, self.fps, self.all_frames, self.bit_rate, self.requestId) | ||||
except ServiceException as s: | except ServiceException as s: | ||||
logger.error("获取视频信息异常: {}, requestId:{}", s.msg, self.requestId) | logger.error("获取视频信息异常: {}, requestId:{}", s.msg, self.requestId) | ||||
self.clear_video_info() | |||||
raise s | raise s | ||||
except ffmpeg._run.Error as er: | |||||
logger.error("获取视频信息异常: {}, requestId:{}", er.stderr.decode(encoding='utf-8'), self.requestId) | |||||
except Exception as e: | except Exception as e: | ||||
logger.exception("获取视频信息异常:{}, requestId:{}", e, self.requestId) | logger.exception("获取视频信息异常:{}, requestId:{}", e, self.requestId) | ||||
self.clear_video_info() | |||||
''' | ''' | ||||
拉取视频 | 拉取视频 | ||||
# self.pull_p = process | # self.pull_p = process | ||||
except ServiceException as s: | except ServiceException as s: | ||||
logger.exception("构建拉流管道异常: {}, requestId:{}", s, self.requestId) | logger.exception("构建拉流管道异常: {}, requestId:{}", s, self.requestId) | ||||
if self.pull_p: | |||||
logger.info("重试, 关闭拉流管道, requestId:{}", self.requestId) | |||||
self.pull_p.stdout.close() | |||||
self.pull_p.terminate() | |||||
self.pull_p.wait() | |||||
self.pull_p = None | |||||
raise s | raise s | ||||
except Exception as e: | except Exception as e: | ||||
logger.exception("构建拉流管道异常:{}, requestId:{}", e, self.requestId) | logger.exception("构建拉流管道异常:{}, requestId:{}", e, self.requestId) | ||||
if self.pull_p: | |||||
logger.info("重试, 关闭拉流管道, requestId:{}", self.requestId) | |||||
self.pull_p.stdout.close() | |||||
self.pull_p.terminate() | |||||
self.pull_p.wait() | |||||
self.pull_p = None | |||||
def checkconfig(self): | def checkconfig(self): | ||||
if self.fps is None or self.width is None or self.height is None: | if self.fps is None or self.width is None or self.height is None: |
self.digitFont = None | self.digitFont = None | ||||
except Exception as ee: | except Exception as ee: | ||||
logger.exception("异常:{}, requestId:{}", ee, requestId) | logger.exception("异常:{}, requestId:{}", ee, requestId) | ||||
raise ee | |||||
def process(self, frame, width=1920): | def process(self, frame, width=1920): | ||||
if self.label_arraylist is None: | if self.label_arraylist is None: |