@@ -1,6 +1,6 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<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> | |||
<paths name="10.21"> | |||
<serverdata> | |||
@@ -16,6 +16,13 @@ | |||
</mappings> | |||
</serverdata> | |||
</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"> | |||
<serverdata> | |||
<mappings> |
@@ -7,6 +7,7 @@ | |||
<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" 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> | |||
</component> | |||
</project> |
@@ -37,6 +37,13 @@ | |||
</advancedOptions> | |||
</fileTransfer> | |||
</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> | |||
</component> | |||
</project> |
@@ -5,12 +5,10 @@ | |||
</component> | |||
<component name="ChangeListManager"> | |||
<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$/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> | |||
<option name="SHOW_DIALOG" value="false" /> | |||
<option name="HIGHLIGHT_CONFLICTS" value="true" /> | |||
@@ -400,7 +398,18 @@ | |||
<workItem from="1675298111671" duration="1710000" /> | |||
<workItem from="1675388395566" duration="5304000" /> | |||
<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> | |||
<servers /> | |||
</component> | |||
@@ -429,7 +438,7 @@ | |||
</line-breakpoint> | |||
<line-breakpoint enabled="true" suspend="THREAD" type="python-line"> | |||
<url>file://$PROJECT_DIR$/util/Cv2Utils.py</url> | |||
<line>1</line> | |||
<line>2</line> | |||
<option name="timeStamp" value="2" /> | |||
</line-breakpoint> | |||
</breakpoints> |
@@ -9,6 +9,7 @@ from concurrency.HeartbeatThread import Heartbeat | |||
from enums.AnalysisTypeEnum import AnalysisType | |||
from enums.ExceptionEnum import ExceptionType | |||
from exception.CustomerException import ServiceException | |||
from util import LogUtils | |||
from util.Cv2Utils import Cv2Util | |||
@@ -49,6 +50,7 @@ class PullVideoStreamProcess(Process): | |||
class OnlinePullVideoStreamProcess(PullVideoStreamProcess): | |||
def run(self): | |||
LogUtils.init_log(self.content) | |||
cv2tool = None | |||
imageFileUpdate = None | |||
hb = None | |||
@@ -71,13 +73,16 @@ class OnlinePullVideoStreamProcess(PullVideoStreamProcess): | |||
while True: | |||
end_time = time.time() | |||
create_task_time = int(end_time - start_time) | |||
# 检测任务执行是否超时 | |||
if create_task_time > self.service_timeout: | |||
logger.error("分析超时, 超时时间:{}, requestId: {}", create_task_time, self.msg.get("request_id")) | |||
raise ServiceException(ExceptionType.ANALYSE_TIMEOUT_EXCEPTION.value[0], | |||
ExceptionType.ANALYSE_TIMEOUT_EXCEPTION.value[1]) | |||
# 检测图片上传线程是否正常运行 | |||
if not imageFileUpdate.is_alive(): | |||
logger.error("未检测到图片上传线程活动,图片上传线程可能出现异常, reuqestId:{}", self.msg.get("request_id")) | |||
raise Exception("未检测到图片上传线程活动,图片上传线程可能出现异常!") | |||
# 检测心跳线程是否正常运行 | |||
if not hb.is_alive(): | |||
logger.error("未检测到心跳线程活动,心跳线程可能出现异常, reuqestId:{}", self.msg.get("request_id")) | |||
raise Exception("未检测到心跳线程活动,心跳线程可能出现异常!") | |||
@@ -111,6 +116,7 @@ class OnlinePullVideoStreamProcess(PullVideoStreamProcess): | |||
if self.pullQueue.full(): | |||
time.sleep(0.1) | |||
continue | |||
# 检测视频信息是否存在或拉流对象是否存在 | |||
if cv2tool.checkconfig() or cv2tool.pull_p is None: | |||
logger.info("开始重新获取视频信息: {}次, requestId: {}", cv2_init_num, self.msg.get("request_id")) | |||
pull_stream_init_timeout = time.time() - start_time_1 | |||
@@ -120,7 +126,7 @@ class OnlinePullVideoStreamProcess(PullVideoStreamProcess): | |||
raise ServiceException(ExceptionType.PULLSTREAM_TIMEOUT_EXCEPTION.value[0], | |||
ExceptionType.PULLSTREAM_TIMEOUT_EXCEPTION.value[1]) | |||
cv2_init_num += 1 | |||
time.sleep(2) | |||
time.sleep(0.5) | |||
cv2tool.get_video_info() | |||
cv2tool.build_pull_p() | |||
continue | |||
@@ -138,7 +144,7 @@ class OnlinePullVideoStreamProcess(PullVideoStreamProcess): | |||
cv2tool.close() | |||
continue | |||
init_pull_num += 1 | |||
time.sleep(1) | |||
time.sleep(0.1) | |||
cv2tool.build_pull_p() | |||
continue | |||
init_pull_num = 1 | |||
@@ -172,6 +178,7 @@ class OnlinePullVideoStreamProcess(PullVideoStreamProcess): | |||
class OfflinePullVideoStreamProcess(PullVideoStreamProcess): | |||
def run(self): | |||
LogUtils.init_log(self.content) | |||
cv2tool = None | |||
imageFileUpdate = None | |||
hb = None | |||
@@ -236,7 +243,7 @@ class OfflinePullVideoStreamProcess(PullVideoStreamProcess): | |||
raise ServiceException(ExceptionType.OR_VIDEO_ADDRESS_EXCEPTION.value[0], | |||
ExceptionType.OR_VIDEO_ADDRESS_EXCEPTION.value[1]) | |||
cv2_init_num += 1 | |||
time.sleep(2) | |||
time.sleep(1) | |||
cv2tool.get_video_info() | |||
cv2tool.build_pull_p() | |||
continue |
@@ -1,10 +1,10 @@ | |||
# -*- coding: utf-8 -*- | |||
import json | |||
import time | |||
import cv2 | |||
import subprocess as sp | |||
import ffmpeg | |||
import numpy as np | |||
from loguru import logger | |||
from exception.CustomerException import ServiceException | |||
@@ -67,6 +67,12 @@ class Cv2Util(): | |||
self.hn = int(self.height) | |||
self.wn = int(self.width) | |||
def clear_video_info(self): | |||
self.fps = None | |||
self.width = None | |||
self.height = None | |||
''' | |||
获取视频信息 | |||
''' | |||
@@ -77,16 +83,20 @@ class Cv2Util(): | |||
logger.error("拉流地址不能为空, requestId:{}", self.requestId) | |||
raise ServiceException(ExceptionType.PULL_STREAM_URL_EXCEPTION.value[0], | |||
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: | |||
return | |||
raise Exception("未获取视频信息!!!!!requestId:" + self.requestId) | |||
# 视频大小 | |||
# format = probe['format'] | |||
# size = int(format['size'])/1024/1024 | |||
video_stream = next((stream for stream in probe['streams'] if stream.get('codec_type') == 'video'), None) | |||
if video_stream is None: | |||
logger.error("根据拉流地址未获取到视频流, requestId:{}", self.requestId) | |||
return | |||
raise Exception("未获取视频信息!!!!!requestId:" + self.requestId) | |||
width = video_stream.get('width') | |||
height = video_stream.get('height') | |||
nb_frames = video_stream.get('nb_frames') | |||
@@ -95,48 +105,45 @@ class Cv2Util(): | |||
bit_rate = video_stream.get('bit_rate') | |||
self.width = int(width) | |||
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.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) | |||
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: | |||
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: | |||
# 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, | |||
self.height, self.fps, self.all_frames, self.bit_rate, self.requestId) | |||
except ServiceException as s: | |||
logger.error("获取视频信息异常: {}, requestId:{}", s.msg, self.requestId) | |||
self.clear_video_info() | |||
raise s | |||
except ffmpeg._run.Error as er: | |||
logger.error("获取视频信息异常: {}, requestId:{}", er.stderr.decode(encoding='utf-8'), self.requestId) | |||
except Exception as e: | |||
logger.exception("获取视频信息异常:{}, requestId:{}", e, self.requestId) | |||
self.clear_video_info() | |||
''' | |||
拉取视频 | |||
@@ -183,9 +190,21 @@ class Cv2Util(): | |||
# self.pull_p = process | |||
except ServiceException as s: | |||
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 | |||
except Exception as e: | |||
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): | |||
if self.fps is None or self.width is None or self.height is None: |
@@ -116,6 +116,8 @@ class Model: | |||
self.digitFont = None | |||
except Exception as ee: | |||
logger.exception("异常:{}, requestId:{}", ee, requestId) | |||
raise ee | |||
def process(self, frame, width=1920): | |||
if self.label_arraylist is None: |