@@ -5,27 +5,18 @@ | |||
</component> | |||
<component name="ChangeListManager"> | |||
<list default="true" id="4f7dccd9-8f92-4a6e-90cc-33890d102263" name="Changes" comment="Changes"> | |||
<change afterPath="$PROJECT_DIR$/vodsdk/AliyunVodUploader.py" afterDir="false" /> | |||
<change afterPath="$PROJECT_DIR$/vodsdk/AliyunVodUtils.py" afterDir="false" /> | |||
<change afterPath="$PROJECT_DIR$/vodsdk/UploadAttachedMediaRequest.py" afterDir="false" /> | |||
<change afterPath="$PROJECT_DIR$/vodsdk/UploadImageRequest.py" afterDir="false" /> | |||
<change afterPath="$PROJECT_DIR$/vodsdk/UploadVideoRequest.py" afterDir="false" /> | |||
<change afterPath="$PROJECT_DIR$/vodsdk/__init__.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/concurrency/CommonThread.py" beforeDir="false" afterPath="$PROJECT_DIR$/concurrency/CommonThread.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/concurrency/FileUploadThread.py" beforeDir="false" afterPath="$PROJECT_DIR$/concurrency/FileUploadThread.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/concurrency/IntelligentRecognitionProcess.py" beforeDir="false" afterPath="$PROJECT_DIR$/concurrency/IntelligentRecognitionProcess.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/enums/BaiduSdkEnum.py" beforeDir="false" afterPath="$PROJECT_DIR$/enums/BaiduSdkEnum.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/concurrency/PullVideoStreamProcess.py" beforeDir="false" afterPath="$PROJECT_DIR$/concurrency/PullVideoStreamProcess.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/dsp_master.py" beforeDir="false" afterPath="$PROJECT_DIR$/dsp_master.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/enums/ExceptionEnum.py" beforeDir="false" afterPath="$PROJECT_DIR$/enums/ExceptionEnum.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/test/aliyun/vod.py" beforeDir="false" afterPath="$PROJECT_DIR$/test/aliyun/vod.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/test/aliyun/vodTest.py" beforeDir="false" afterPath="$PROJECT_DIR$/test/aliyun/vodTest.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/test/aliyun/voddemo.py" beforeDir="false" afterPath="$PROJECT_DIR$/test/aliyun/voddemo.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/test/aliyun/vodtest2.py" beforeDir="false" afterPath="$PROJECT_DIR$/test/aliyun/vodtest2.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/test/序列化/Test.py" beforeDir="false" afterPath="$PROJECT_DIR$/test/序列化/Test.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/service/Dispatcher.py" beforeDir="false" afterPath="$PROJECT_DIR$/service/Dispatcher.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/test/ffmpeg11/aa.py" beforeDir="false" afterPath="$PROJECT_DIR$/test/ffmpeg11/aa.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/test/日志/test.py" beforeDir="false" afterPath="$PROJECT_DIR$/test/日志/test.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/test/线程/Test.py" beforeDir="false" afterPath="$PROJECT_DIR$/test/线程/Test.py" afterDir="false" /> | |||
<change beforePath="$PROJECT_DIR$/util/AliyunSdk.py" beforeDir="false" afterPath="$PROJECT_DIR$/util/AliyunSdk.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" /> | |||
@@ -154,11 +145,12 @@ | |||
"WebServerToolWindowPanel.toolwindow.show.date": "false", | |||
"WebServerToolWindowPanel.toolwindow.show.permissions": "false", | |||
"WebServerToolWindowPanel.toolwindow.show.size": "false", | |||
"last_opened_file_path": "D:/tuoheng/codenew/tuoheng_dsp", | |||
"last_opened_file_path": "D:/tuoheng/codenew/tuoheng_alg/test/元类", | |||
"node.js.detected.package.eslint": "true", | |||
"node.js.detected.package.tslint": "true", | |||
"node.js.selected.package.eslint": "(autodetect)", | |||
"node.js.selected.package.tslint": "(autodetect)", | |||
"nodejs_package_manager_path": "npm", | |||
"project.structure.last.edited": "SDK", | |||
"project.structure.proportion": "0.15", | |||
"project.structure.side.proportion": "0.2816092", | |||
@@ -168,21 +160,22 @@ | |||
}]]></component> | |||
<component name="RecentsManager"> | |||
<key name="CopyFile.RECENT_KEYS"> | |||
<recent name="D:\tuoheng\codenew\tuoheng_alg\test\元类" /> | |||
<recent name="D:\tuoheng\codenew\tuoheng_alg" /> | |||
<recent name="D:\tuoheng\codenew\tuoheng_alg\test\color" /> | |||
<recent name="D:\tuoheng\codenew\tuoheng_alg\test\cuda" /> | |||
<recent name="D:\tuoheng\codenew\tuoheng_alg\util" /> | |||
<recent name="D:\tuoheng\codenew\tuoheng_alg\test" /> | |||
</key> | |||
<key name="MoveFile.RECENT_KEYS"> | |||
<recent name="D:\tuoheng\codenew\tuoheng_alg\test\设计模式\单例" /> | |||
<recent name="D:\tuoheng\codenew\tuoheng_alg\font" /> | |||
<recent name="D:\work\alg_new\tuoheng_alg\test\image" /> | |||
<recent name="D:\work\alg\tuoheng_alg\test\水印" /> | |||
<recent name="D:\work\alg\tuoheng_alg\image" /> | |||
</key> | |||
</component> | |||
<component name="RunManager" selected="Python.Test (1)"> | |||
<configuration name="AliyunSdk" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> | |||
<component name="RunManager" selected="Python.demo1"> | |||
<configuration name="demo" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> | |||
<module name="tuoheng_alg" /> | |||
<option name="INTERPRETER_OPTIONS" value="" /> | |||
<option name="PARENT_ENVS" value="true" /> | |||
@@ -190,12 +183,12 @@ | |||
<env name="PYTHONUNBUFFERED" value="1" /> | |||
</envs> | |||
<option name="SDK_HOME" value="" /> | |||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> | |||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/test/设计模式/简单工厂模式" /> | |||
<option name="IS_MODULE_SDK" value="true" /> | |||
<option name="ADD_CONTENT_ROOTS" value="true" /> | |||
<option name="ADD_SOURCE_ROOTS" value="true" /> | |||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> | |||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/AliyunSdk.py" /> | |||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/test/设计模式/简单工厂模式/demo.py" /> | |||
<option name="PARAMETERS" value="" /> | |||
<option name="SHOW_COMMAND_LINE" value="false" /> | |||
<option name="EMULATE_TERMINAL" value="false" /> | |||
@@ -204,7 +197,7 @@ | |||
<option name="INPUT_FILE" value="" /> | |||
<method v="2" /> | |||
</configuration> | |||
<configuration name="Test (1)" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> | |||
<configuration name="demo1" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> | |||
<module name="tuoheng_alg" /> | |||
<option name="INTERPRETER_OPTIONS" value="" /> | |||
<option name="PARENT_ENVS" value="true" /> | |||
@@ -212,12 +205,12 @@ | |||
<env name="PYTHONUNBUFFERED" value="1" /> | |||
</envs> | |||
<option name="SDK_HOME" value="" /> | |||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/test/线程" /> | |||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/test/设计模式/简单工厂模式" /> | |||
<option name="IS_MODULE_SDK" value="true" /> | |||
<option name="ADD_CONTENT_ROOTS" value="true" /> | |||
<option name="ADD_SOURCE_ROOTS" value="true" /> | |||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> | |||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/test/线程/Test.py" /> | |||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/test/设计模式/简单工厂模式/demo1.py" /> | |||
<option name="PARAMETERS" value="" /> | |||
<option name="SHOW_COMMAND_LINE" value="false" /> | |||
<option name="EMULATE_TERMINAL" value="false" /> | |||
@@ -226,7 +219,7 @@ | |||
<option name="INPUT_FILE" value="" /> | |||
<method v="2" /> | |||
</configuration> | |||
<configuration name="Test" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> | |||
<configuration name="demo3" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> | |||
<module name="tuoheng_alg" /> | |||
<option name="INTERPRETER_OPTIONS" value="" /> | |||
<option name="PARENT_ENVS" value="true" /> | |||
@@ -234,12 +227,12 @@ | |||
<env name="PYTHONUNBUFFERED" value="1" /> | |||
</envs> | |||
<option name="SDK_HOME" value="" /> | |||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/test/序列化" /> | |||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/test/元类" /> | |||
<option name="IS_MODULE_SDK" value="true" /> | |||
<option name="ADD_CONTENT_ROOTS" value="true" /> | |||
<option name="ADD_SOURCE_ROOTS" value="true" /> | |||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> | |||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/test/序列化/Test.py" /> | |||
<option name="SCRIPT_NAME" value="D:\tuoheng\codenew\tuoheng_alg\test\设计模式\单例\demo3.py" /> | |||
<option name="PARAMETERS" value="" /> | |||
<option name="SHOW_COMMAND_LINE" value="false" /> | |||
<option name="EMULATE_TERMINAL" value="false" /> | |||
@@ -248,7 +241,7 @@ | |||
<option name="INPUT_FILE" value="" /> | |||
<method v="2" /> | |||
</configuration> | |||
<configuration name="color_test" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> | |||
<configuration name="demo4" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> | |||
<module name="tuoheng_alg" /> | |||
<option name="INTERPRETER_OPTIONS" value="" /> | |||
<option name="PARENT_ENVS" value="true" /> | |||
@@ -256,12 +249,34 @@ | |||
<env name="PYTHONUNBUFFERED" value="1" /> | |||
</envs> | |||
<option name="SDK_HOME" value="" /> | |||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/test/color" /> | |||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/test/元类" /> | |||
<option name="IS_MODULE_SDK" value="true" /> | |||
<option name="ADD_CONTENT_ROOTS" value="true" /> | |||
<option name="ADD_SOURCE_ROOTS" value="true" /> | |||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> | |||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/test/color/color_test.py" /> | |||
<option name="SCRIPT_NAME" value="D:\tuoheng\codenew\tuoheng_alg\test\设计模式\单例\demo4.py" /> | |||
<option name="PARAMETERS" value="" /> | |||
<option name="SHOW_COMMAND_LINE" value="false" /> | |||
<option name="EMULATE_TERMINAL" value="false" /> | |||
<option name="MODULE_MODE" value="false" /> | |||
<option name="REDIRECT_INPUT" value="false" /> | |||
<option name="INPUT_FILE" value="" /> | |||
<method v="2" /> | |||
</configuration> | |||
<configuration name="demo5" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> | |||
<module name="tuoheng_alg" /> | |||
<option name="INTERPRETER_OPTIONS" value="" /> | |||
<option name="PARENT_ENVS" value="true" /> | |||
<envs> | |||
<env name="PYTHONUNBUFFERED" value="1" /> | |||
</envs> | |||
<option name="SDK_HOME" value="" /> | |||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/test/元类" /> | |||
<option name="IS_MODULE_SDK" value="true" /> | |||
<option name="ADD_CONTENT_ROOTS" value="true" /> | |||
<option name="ADD_SOURCE_ROOTS" value="true" /> | |||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> | |||
<option name="SCRIPT_NAME" value="D:\tuoheng\codenew\tuoheng_alg\test\设计模式\单例\demo5.py" /> | |||
<option name="PARAMETERS" value="" /> | |||
<option name="SHOW_COMMAND_LINE" value="false" /> | |||
<option name="EMULATE_TERMINAL" value="false" /> | |||
@@ -314,20 +329,21 @@ | |||
<option name="INPUT_FILE" value="" /> | |||
<method v="2" /> | |||
</configuration> | |||
<configuration name="test (2)" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> | |||
<configuration name="test" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> | |||
<module name="tuoheng_alg" /> | |||
<option name="INTERPRETER_OPTIONS" value="" /> | |||
<option name="PARENT_ENVS" value="true" /> | |||
<envs> | |||
<env name="PYTHONUNBUFFERED" value="1" /> | |||
</envs> | |||
<option name="SDK_HOME" value="" /> | |||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/test/进程" /> | |||
<option name="IS_MODULE_SDK" value="true" /> | |||
<option name="SDK_HOME" value="B:\software\conda\envs\test\python.exe" /> | |||
<option name="SDK_NAME" value="Python 3.8 (test)" /> | |||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/test/类型标注" /> | |||
<option name="IS_MODULE_SDK" value="false" /> | |||
<option name="ADD_CONTENT_ROOTS" value="true" /> | |||
<option name="ADD_SOURCE_ROOTS" value="true" /> | |||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> | |||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/test/进程/test.py" /> | |||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/test/类型标注/test.py" /> | |||
<option name="PARAMETERS" value="" /> | |||
<option name="SHOW_COMMAND_LINE" value="false" /> | |||
<option name="EMULATE_TERMINAL" value="false" /> | |||
@@ -339,19 +355,19 @@ | |||
<list> | |||
<item itemvalue="Python.editImage" /> | |||
<item itemvalue="Python.mysqltest" /> | |||
<item itemvalue="Python.Test (1)" /> | |||
<item itemvalue="Python.AliyunSdk" /> | |||
<item itemvalue="Python.Test" /> | |||
<item itemvalue="Python.color_test" /> | |||
<item itemvalue="Python.test (2)" /> | |||
<item itemvalue="Python.demo" /> | |||
<item itemvalue="Python.demo1" /> | |||
<item itemvalue="Python.demo3" /> | |||
<item itemvalue="Python.demo4" /> | |||
<item itemvalue="Python.demo5" /> | |||
</list> | |||
<recent_temporary> | |||
<list> | |||
<item itemvalue="Python.Test (1)" /> | |||
<item itemvalue="Python.AliyunSdk" /> | |||
<item itemvalue="Python.Test" /> | |||
<item itemvalue="Python.color_test" /> | |||
<item itemvalue="Python.test (2)" /> | |||
<item itemvalue="Python.demo1" /> | |||
<item itemvalue="Python.demo" /> | |||
<item itemvalue="Python.demo5" /> | |||
<item itemvalue="Python.demo4" /> | |||
<item itemvalue="Python.demo3" /> | |||
</list> | |||
</recent_temporary> | |||
</component> | |||
@@ -511,7 +527,15 @@ | |||
<workItem from="1683762579964" duration="23871000" /> | |||
<workItem from="1683851036596" duration="51000" /> | |||
<workItem from="1683851900729" duration="83000" /> | |||
<workItem from="1683851995142" duration="23673000" /> | |||
<workItem from="1683851995142" duration="24789000" /> | |||
<workItem from="1684110880642" duration="5895000" /> | |||
<workItem from="1684197638479" duration="9103000" /> | |||
<workItem from="1684284520362" duration="13345000" /> | |||
<workItem from="1684379357818" duration="22600000" /> | |||
<workItem from="1684456296559" duration="11147000" /> | |||
<workItem from="1684653340859" duration="1199000" /> | |||
<workItem from="1684715657250" duration="6747000" /> | |||
<workItem from="1684801865053" duration="7552000" /> | |||
</task> | |||
<servers /> | |||
</component> | |||
@@ -561,38 +585,45 @@ | |||
</component> | |||
<component name="com.intellij.coverage.CoverageDataManagerImpl"> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$color_test.coverage" NAME="color_test 覆盖结果" MODIFIED="1683683775604" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/color" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$demo1.coverage" NAME="demo1 覆盖结果" MODIFIED="1680162882599" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/demo" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$demo1.coverage" NAME="demo1 覆盖结果" MODIFIED="1684807129961" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/元类" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$ffmpeg33.coverage" NAME="ffmpeg33 覆盖结果" MODIFIED="1670489109246" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/ffmpeg11" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$demo4.coverage" NAME="demo4 覆盖结果" MODIFIED="1684809818971" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/元类" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$minio.coverage" NAME="minio 覆盖结果" MODIFIED="1667465702864" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/minio1" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$3.coverage" NAME="视频添加文字水印3 Coverage Results" MODIFIED="1661906152928" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$ffmpeg12.coverage" NAME="ffmpeg12 覆盖结果" MODIFIED="1675391366890" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/ffmpeg11" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$Test__2_.coverage" NAME="Test (2) 覆盖结果" MODIFIED="1681796501563" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/路径" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$test1.coverage" NAME="test1 覆盖结果" MODIFIED="1681988279624" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/cuda" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$ossdemo.coverage" NAME="ossdemo 覆盖结果" MODIFIED="1681715255761" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/aliyun" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$test__1_.coverage" NAME="test (1) 覆盖结果" MODIFIED="1681969578447" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/cuda" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$test__1_.coverage" NAME="test (1) 覆盖结果" MODIFIED="1684480106837" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/日志" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$aa1.coverage" NAME="aa1 覆盖结果" MODIFIED="1667351136888" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/ffmpeg11" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg___$test.coverage" NAME="test 覆盖结果" MODIFIED="1668577200259" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/while" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$editImage.coverage" NAME="editImage 覆盖结果" MODIFIED="1678348350574" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/editimage" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$2.coverage" NAME="协程2 覆盖结果" MODIFIED="1668066168428" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="/opt/tuo_heng/algSch/test/协程/" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$ImgBaiduSdk.coverage" NAME="ImgBaiduSdk 覆盖结果" MODIFIED="1678355024003" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/util" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$ImageUtils.coverage" NAME="ImageUtils Coverage Results" MODIFIED="1663499421253" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/util" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$demo2.coverage" NAME="demo2 覆盖结果" MODIFIED="1684808407865" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/元类" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$dsp_master.coverage" NAME="dsp_master 覆盖结果" MODIFIED="1680503755624" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$test.coverage" NAME="test 覆盖结果" MODIFIED="1682582986112" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/集合" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$IntelligentRecognitionProcess.coverage" NAME="IntelligentRecognitionProcess 覆盖结果" MODIFIED="1682651444560" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/concurrency" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$test.coverage" NAME="test 覆盖结果" MODIFIED="1684742307978" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/opencv" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$demo3.coverage" NAME="demo3 覆盖结果" MODIFIED="1684809071819" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/元类" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$Test.coverage" NAME="Test 覆盖结果" MODIFIED="1683802532361" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/序列化" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$mysqltest.coverage" NAME="mysqltest Coverage Results" MODIFIED="1660868712851" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$asnyc__1_.coverage" NAME="asnyc (1) Coverage Results" MODIFIED="1663458917599" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$cv2test1.coverage" NAME="cv2test1 覆盖结果" MODIFIED="1665738045603" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="/home/DATA/chenyukun/algSch/test/" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$test2.coverage" NAME="test2 覆盖结果" MODIFIED="1669178077956" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/str" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$aa.coverage" NAME="aa 覆盖结果" MODIFIED="1670490313339" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="/home/chenyukun/algSch/test/ffmpeg11" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$ffmpeg22.coverage" NAME="aa 覆盖结果" MODIFIED="1667350492259" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="/opt/tuo_heng" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$aa.coverage" NAME="aa 覆盖结果" MODIFIED="1684461916527" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/ffmpeg11" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$KafkaUtils__1_.coverage" NAME="KafkaUtils (1) Coverage Results" MODIFIED="1663464961001" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/util" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$voddemo.coverage" NAME="voddemo 覆盖结果" MODIFIED="1681722102430" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/aliyun" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg___$producer_start.coverage" NAME="producer_start 覆盖结果" MODIFIED="1668522825199" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="/home/thsw/chenyukun/algSch" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg___$producer_start1.coverage" NAME="producer_start1 覆盖结果" MODIFIED="1668437822632" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="/home/thsw/chenyukun/algSch/test/kafka" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$re.coverage" NAME="re 覆盖结果" MODIFIED="1684221962919" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/正则" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$producer_start__1_.coverage" NAME="producer_start (1) 覆盖结果" MODIFIED="1665832569996" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg___$ffmpeg11.coverage" NAME="ffmpeg11 覆盖结果" MODIFIED="1668410004435" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/ffmpeg11" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$demo.coverage" NAME="demo 覆盖结果" MODIFIED="1684810722320" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/设计模式/简单工厂模式" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$producer_start.coverage" NAME="producer_start1 覆盖结果" MODIFIED="1670999187123" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/kafka" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$test__3_.coverage" NAME="test (3) 覆盖结果" MODIFIED="1684802056733" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/设计模式/单例" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$numpy_test.coverage" NAME="numpy_test 覆盖结果" MODIFIED="1684205019028" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/numpy" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$.coverage" NAME="协程笔记 覆盖结果" MODIFIED="1680926972744" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/协程" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$4.coverage" NAME="视频添加图片水印4 Coverage Results" MODIFIED="1661874731395" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$gputest.coverage" NAME="gputest 覆盖结果" MODIFIED="1681950938970" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/gpu" /> | |||
@@ -605,10 +636,12 @@ | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$cv2test1__1_.coverage" NAME="cv2test1 覆盖结果" MODIFIED="1665820653649" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$TimeUtils.coverage" NAME="TimeUtils Coverage Results" MODIFIED="1661222768678" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/util" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$producer_start1.coverage" NAME="producer_start1 覆盖结果" MODIFIED="1671428635702" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/kafka" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$demo5.coverage" NAME="demo5 覆盖结果" MODIFIED="1684810002359" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/元类" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg___$producer_stop.coverage" NAME="producer_stop 覆盖结果" MODIFIED="1668522920533" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="/home/thsw/chenyukun/algSch" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$Test__1_.coverage" NAME="Test (1) 覆盖结果" MODIFIED="1683865962957" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/线程" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$pa.coverage" NAME="pa 覆盖结果" MODIFIED="1684217734590" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/pachong" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$ffmpeg13.coverage" NAME="ffmpeg13 覆盖结果" MODIFIED="1675394160900" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/ffmpeg11" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$KafkaUtils.coverage" NAME="KafkaUtils Coverage Results" MODIFIED="1663465345491" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/util" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$test__2_.coverage" NAME="test (2) 覆盖结果" MODIFIED="1683355406740" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/进程" /> | |||
<SUITE FILE_PATH="coverage/tuoheng_alg$test__2_.coverage" NAME="test (2) 覆盖结果" MODIFIED="1684743889711" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/test/类型标注" /> | |||
</component> | |||
</project> |
@@ -1,4 +1,5 @@ | |||
import copy | |||
import time | |||
from concurrent.futures import ThreadPoolExecutor, as_completed | |||
from threading import Thread | |||
from loguru import logger | |||
@@ -165,8 +166,10 @@ class ImageFileUpload(FileUpload): | |||
thread_result.result() | |||
for msg in msg_list: | |||
self.sendResult(msg) | |||
else: | |||
time.sleep(1) | |||
except Exception as e: | |||
logger.exception("图片上传异常:{}, requestId:{}", e, self.msg.get("request_id")) | |||
logger.exception("图片上传异常:{}, requestId:{}", str(e), self.msg.get("request_id")) | |||
finally: | |||
high_score_image.clear() | |||
@@ -361,7 +361,7 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess): | |||
return pullProcess | |||
def checkPullProcess(self, pullProcess): | |||
if not pullProcess.is_alive(): | |||
if pullProcess is not None and not pullProcess.is_alive(): | |||
logger.info("拉流进程停止异常, requestId: {}", self.msg.get("request_id")) | |||
raise Exception("拉流进程异常停止") | |||
@@ -432,7 +432,7 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess): | |||
raise Exception("未知拉流状态异常!") | |||
logger.info("实时进程任务完成,requestId:{}", self.msg.get("request_id")) | |||
except ServiceException as s: | |||
logger.error("服务异常,异常编号:{}, 异常描述:{}, requestId: {}", s.code, s.msg, self.msg.get("request_id")) | |||
logger.exception("服务异常,异常编号:{}, 异常描述:{}, requestId: {}", s.code, s.msg, self.msg.get("request_id")) | |||
feedback = {"feedback": message_feedback(self.msg.get("request_id"), AnalysisStatus.FAILED.value, | |||
self.analyse_type, | |||
s.code, | |||
@@ -532,7 +532,7 @@ class OfflineIntelligentRecognitionProcess(IntelligentRecognitionProcess): | |||
with ThreadPoolExecutor(max_workers=3) as tt: | |||
with ThreadPoolExecutor(max_workers=10) as ttt: | |||
while True: | |||
if not pullProcess.is_alive(): | |||
if pullProcess is not None and not pullProcess.is_alive(): | |||
logger.info("拉流进程停止异常, requestId: {}", self.msg.get("request_id")) | |||
raise Exception("拉流进程异常停止") | |||
# 检查是否获取到视频信息 |
@@ -48,13 +48,41 @@ class PullVideoStreamProcess(Process): | |||
imageFileUpload = ImageFileUpload(self.fbQueue, self.content, self.msg, self.imageQueue, self.analyse_type) | |||
imageFileUpload.setDaemon(True) | |||
imageFileUpload.start() | |||
return imageFileUpload | |||
start_time = time.time() | |||
while True: | |||
if imageFileUpload.is_alive(): | |||
return imageFileUpload | |||
if not imageFileUpload.is_alive(): | |||
logger.warning("图片上传线程异常等待中, requestId:{}", self.msg.get("request_id")) | |||
if time.time() - start_time <= 3: | |||
continue | |||
elif int(time.time() - start_time) <= 5: | |||
logger.warning("图片上传线程异常重启中, requestId:{}", self.msg.get("request_id")) | |||
imageFileUpload.start() | |||
time.sleep(1) | |||
continue | |||
elif int(time.time() - start_time) > 5: | |||
raise Exception("图片上传线程启动异常") | |||
def start_heartbeat(self): | |||
hb = Heartbeat(self.fbQueue, self.hbQueue, self.msg.get("request_id"), self.analyse_type) | |||
hb.setDaemon(True) | |||
hb.start() | |||
return hb | |||
start_time = time.time() | |||
while True: | |||
if hb.is_alive(): | |||
return hb | |||
if not hb.is_alive(): | |||
logger.warning("心跳线程异常等待中, requestId:{}", self.msg.get("request_id")) | |||
if time.time() - start_time <= 3: | |||
continue | |||
elif int(time.time() - start_time) <= 5: | |||
logger.warning("心跳线程异常重启中, requestId:{}", self.msg.get("request_id")) | |||
hb.start() | |||
time.sleep(1) | |||
continue | |||
elif int(time.time() - start_time) > 5: | |||
raise Exception("心跳线程启动异常") | |||
def check(self, start_time, imageFileUpload, hb): | |||
create_task_time = time.time() - start_time | |||
@@ -63,11 +91,11 @@ class PullVideoStreamProcess(Process): | |||
raise ServiceException(ExceptionType.ANALYSE_TIMEOUT_EXCEPTION.value[0], | |||
ExceptionType.ANALYSE_TIMEOUT_EXCEPTION.value[1]) | |||
# 检测图片上传线程是否正常运行 | |||
if not imageFileUpload.is_alive(): | |||
if imageFileUpload is not None and not imageFileUpload.is_alive(): | |||
logger.error("未检测到图片上传线程活动,图片上传线程可能出现异常, reuqestId:{}", self.msg.get("request_id")) | |||
raise Exception("未检测到图片上传线程活动,图片上传线程可能出现异常!") | |||
# 检测心跳线程是否正常运行 | |||
if not hb.is_alive(): | |||
if hb is not None and not hb.is_alive(): | |||
logger.error("未检测到心跳线程活动,心跳线程可能出现异常, reuqestId:{}", self.msg.get("request_id")) | |||
raise Exception("未检测到心跳线程活动,心跳线程可能出现异常!") | |||
@@ -128,7 +156,7 @@ class OnlinePullVideoStreamProcess(PullVideoStreamProcess): | |||
raise ServiceException(ExceptionType.PULLSTREAM_TIMEOUT_EXCEPTION.value[0], | |||
ExceptionType.PULLSTREAM_TIMEOUT_EXCEPTION.value[1]) | |||
cv2_init_num += 1 | |||
time.sleep(0.5) | |||
time.sleep(1) | |||
cv2tool.get_video_info() | |||
continue | |||
pull_stream_start_time = time.time() | |||
@@ -144,8 +172,8 @@ class OnlinePullVideoStreamProcess(PullVideoStreamProcess): | |||
stop_pull_stream_step = True | |||
cv2tool.close() | |||
continue | |||
cv2tool.close() | |||
init_pull_num += 1 | |||
time.sleep(0.1) | |||
continue | |||
init_pull_num = 1 | |||
pull_stream_read_start_time = time.time() | |||
@@ -161,9 +189,10 @@ class OnlinePullVideoStreamProcess(PullVideoStreamProcess): | |||
"all_frame": cv2tool.all_frames}) | |||
concurrent_frame += 1 | |||
except ServiceException as s: | |||
logger.exception("实时拉流异常: {}, requestId:{}", s.msg, self.msg.get("request_id")) | |||
self.sendPullQueue({"status": "1", "error": {"code": s.code, "msg": s.msg}}) | |||
except Exception as e: | |||
logger.exception("实时拉流异常: {}, requestId:{}", e, self.msg.get("request_id")) | |||
logger.exception("实时拉流异常: {}, requestId:{}", str(e), self.msg.get("request_id")) | |||
self.sendPullQueue({"status": "1", "error": {"code": ExceptionType.SERVICE_INNER_EXCEPTION.value[0], | |||
"msg": ExceptionType.SERVICE_INNER_EXCEPTION.value[1]}}) | |||
finally: |
@@ -13,4 +13,4 @@ if __name__ == '__main__': | |||
# 获取主程序执行根路径 | |||
base_dir = os.path.dirname(os.path.realpath(sys.argv[0])) | |||
torch.multiprocessing.set_start_method('spawn') | |||
Dispatcher.DispatcherService(base_dir).start_service() | |||
Dispatcher.DispatcherService(base_dir).start_service() |
@@ -61,6 +61,8 @@ class ExceptionType(Enum): | |||
COORDINATE_ACQUISITION_FAILED = ("SP027", "飞行坐标识别异常!") | |||
PUSH_STREAM_EXCEPTION = ("SP028", "推流异常!") | |||
SERVICE_COMMON_EXCEPTION = ("SP997", "公共服务异常!") | |||
NO_GPU_RESOURCES = ("SP998", "暂无GPU资源可以使用,请稍后再试!") |
@@ -35,16 +35,16 @@ class DispatcherService: | |||
raise Exception("cuda不在活动状态, 请检测显卡驱动是否正常!!!!") | |||
# 初始化alg相关配置 ###################################################################### | |||
self.base_dir = base_dir # 根路径 | |||
self.context = YmlUtils.getConfigs(base_dir) # 获取alg需要使用的配置 | |||
self.context[YmlConstant.BASE_DIR] = base_dir # 将根路径设置到上下文中 | |||
self.feedbackThread = None # 初始化反馈线程对象 | |||
self.__base_dir = base_dir # 根路径 | |||
self.__context = YmlUtils.getConfigs(base_dir) # 获取alg需要使用的配置 | |||
self.__context[YmlConstant.BASE_DIR] = base_dir # 将根路径设置到上下文中 | |||
self.__feedbackThread = None # 初始化反馈线程对象 | |||
# 初始化日志框架 ######################################################################### | |||
LogUtils.init_log(self.context) # 初始化日志框架 | |||
LogUtils.init_log(self.__context) # 初始化日志框架 | |||
# 初始化视频保存文件夹 ##################################################################### | |||
FileUtils.create_dir_not_exist(YmlConstant.get_file_path(self.context)) # 创建文件夹 | |||
FileUtils.create_dir_not_exist(YmlConstant.get_file_path(self.__context)) # 创建文件夹 | |||
# 创建任务记录字典 ######################################################################## | |||
self.onlineProcesses = {} # 记录当前正在执行的实时流分析任务 | |||
@@ -58,10 +58,10 @@ class DispatcherService: | |||
self.fbQueue = Queue() | |||
# 监听topic信息 ########################################################################## | |||
self.online_topic = YmlConstant.get_online_tasks_topic(self.context) | |||
self.offline_topic = YmlConstant.get_offline_tasks_topic(self.context) | |||
self.image_topic = YmlConstant.get_image_tasks_topic(self.context) | |||
self.recording_task_topic = YmlConstant.get_recording_tasks_topic(self.context) | |||
self.online_topic = YmlConstant.get_online_tasks_topic(self.__context) | |||
self.offline_topic = YmlConstant.get_offline_tasks_topic(self.__context) | |||
self.image_topic = YmlConstant.get_image_tasks_topic(self.__context) | |||
self.recording_task_topic = YmlConstant.get_recording_tasks_topic(self.__context) | |||
self.topics = [self.online_topic, self.offline_topic, self.image_topic, self.recording_task_topic] | |||
self.analysisType = { | |||
self.online_topic: (AnalysisType.ONLINE.value, lambda x, y: self.online(x, y), | |||
@@ -79,16 +79,16 @@ class DispatcherService: | |||
gpu_codes = YmlConstant.GPU_CODES | |||
gpu_array = [g for g in gpu_codes if g in gpu_name] | |||
if len(gpu_array) > 0: | |||
self.context[YmlConstant.GPU_NAME] = gpu_array[0] | |||
self.__context[YmlConstant.GPU_NAME] = gpu_array[0] | |||
if gpu_array[0] == YmlConstant.GPU_2080: | |||
self.context[YmlConstant.GPU_NAME] = YmlConstant.GPU_2080_Ti | |||
self.__context[YmlConstant.GPU_NAME] = YmlConstant.GPU_2080_Ti | |||
else: | |||
raise Exception("GPU资源不在提供的模型所支持的范围内!请先提供对应的GPU模型!") | |||
# 服务调用启动方法 | |||
def start_service(self): | |||
# 初始化kafka监听者 | |||
customerKafkaConsumer = KafkaUtils.CustomerKafkaConsumer(self.context, topics=self.topics) | |||
customerKafkaConsumer = KafkaUtils.CustomerKafkaConsumer(self.__context, topics=self.topics) | |||
logger.info("(♥◠‿◠)ノ゙ DSP【算法调度服务】启动成功 ლ(´ڡ`ლ)゙") | |||
# 循环消息处理 | |||
while True: | |||
@@ -191,7 +191,7 @@ class DispatcherService: | |||
if self.onlineProcesses.get(msg.get(YmlConstant.REQUEST_ID)): | |||
logger.warning("重复任务,请稍后再试!requestId:{}", msg.get(YmlConstant.REQUEST_ID)) | |||
return | |||
cfg = {YmlConstant.FBQUEUE: self.fbQueue, YmlConstant.CONTEXT: self.context, YmlConstant.MSG: msg, | |||
cfg = {YmlConstant.FBQUEUE: self.fbQueue, YmlConstant.CONTEXT: self.__context, YmlConstant.MSG: msg, | |||
YmlConstant.GPU_IDS: gpu_ids, YmlConstant.ANALYSE_TYPE: analysisType} | |||
# 创建在线识别进程并启动 | |||
oirp = OnlineIntelligentRecognitionProcess(cfg) | |||
@@ -222,7 +222,7 @@ class DispatcherService: | |||
if self.offlineProcesses.get(msg.get(YmlConstant.REQUEST_ID)): | |||
logger.warning("重复任务,请稍后再试!requestId:{}", msg.get(YmlConstant.REQUEST_ID)) | |||
return | |||
cfg = {YmlConstant.FBQUEUE: self.fbQueue, YmlConstant.CONTEXT: self.context, YmlConstant.MSG: msg, | |||
cfg = {YmlConstant.FBQUEUE: self.fbQueue, YmlConstant.CONTEXT: self.__context, YmlConstant.MSG: msg, | |||
YmlConstant.GPU_IDS: gpu_ids, YmlConstant.ANALYSE_TYPE: analysisType} | |||
ofirp = OfflineIntelligentRecognitionProcess(cfg) | |||
ofirp.start() | |||
@@ -242,7 +242,7 @@ class DispatcherService: | |||
if pp is not None: | |||
logger.warning("重复任务,请稍后再试!requestId:{}", msg.get(YmlConstant.REQUEST_ID)) | |||
return | |||
cfg = {YmlConstant.FBQUEUE: self.fbQueue, YmlConstant.CONTEXT: self.context, YmlConstant.MSG: msg, | |||
cfg = {YmlConstant.FBQUEUE: self.fbQueue, YmlConstant.CONTEXT: self.__context, YmlConstant.MSG: msg, | |||
YmlConstant.GPU_IDS: gpu_ids, YmlConstant.ANALYSE_TYPE: analysisType} | |||
# 创建在线识别进程并启动 | |||
imagep = PhotosIntelligentRecognitionProcess(cfg) | |||
@@ -275,11 +275,44 @@ class DispatcherService: | |||
''' | |||
def start_feedback_thread(self): | |||
if self.__feedbackThread is None: | |||
self.__feedbackThread = FeedbackThread(self.fbQueue, self.__context) | |||
self.__feedbackThread.setDaemon(True) | |||
self.__feedbackThread.start() | |||
start_time = time.time() | |||
while True: | |||
if self.__feedbackThread.is_alive(): | |||
return | |||
if not self.__feedbackThread.is_alive(): | |||
logger.warning("反馈线程异常等待中") | |||
if time.time() - start_time <= 3: | |||
continue | |||
elif int(time.time() - start_time) <= 5: | |||
logger.warning("反馈线程异常重启中") | |||
self.__feedbackThread.start() | |||
time.sleep(2) | |||
continue | |||
elif int(time.time() - start_time) > 5: | |||
raise Exception("反馈线程程启动异常") | |||
# 如果反馈线程为空,启动反馈线程,如果反馈线程意外停止,再次启动反馈线程 | |||
if self.feedbackThread is None or not self.feedbackThread.is_alive(): | |||
self.feedbackThread = FeedbackThread(self.fbQueue, self.context) | |||
self.feedbackThread.setDaemon(True) | |||
self.feedbackThread.start() | |||
if self.__feedbackThread is not None and not self.__feedbackThread.is_alive(): | |||
start_time_1 = time.time() | |||
while True: | |||
if self.__feedbackThread.is_alive(): | |||
return | |||
if not self.__feedbackThread.is_alive(): | |||
logger.warning("反馈线程异常等待中") | |||
if time.time() - start_time_1 <= 3: | |||
continue | |||
elif time.time() - start_time_1 <= 5: | |||
logger.warning("反馈线程异常重启中") | |||
self.__feedbackThread.start() | |||
time.sleep(1) | |||
continue | |||
elif time.time() - start_time_1 > 5: | |||
raise Exception("反馈线程程启动异常") | |||
''' | |||
在线分析逻辑 | |||
@@ -287,7 +320,7 @@ class DispatcherService: | |||
def online(self, message, analysisType): | |||
if YmlConstant.START == message.get(YmlConstant.COMMAND): | |||
gpu_ids = GPUtils.check_gpu_resource(self.context) | |||
gpu_ids = GPUtils.check_gpu_resource(self.__context) | |||
self.startOnlineProcess(message, gpu_ids, analysisType) | |||
elif YmlConstant.STOP == message.get(YmlConstant.COMMAND): | |||
self.stopOnlineProcess(message) | |||
@@ -296,7 +329,7 @@ class DispatcherService: | |||
def offline(self, message, analysisType): | |||
if YmlConstant.START == message.get(YmlConstant.COMMAND): | |||
gpu_ids = GPUtils.check_gpu_resource(self.context) | |||
gpu_ids = GPUtils.check_gpu_resource(self.__context) | |||
self.startOfflineProcess(message, gpu_ids, analysisType) | |||
elif YmlConstant.STOP == message.get(YmlConstant.COMMAND): | |||
self.stopOfflineProcess(message) | |||
@@ -305,7 +338,7 @@ class DispatcherService: | |||
def image(self, message, analysisType): | |||
if YmlConstant.START == message.get(YmlConstant.COMMAND): | |||
gpu_ids = GPUtils.check_gpu_resource(self.context) | |||
gpu_ids = GPUtils.check_gpu_resource(self.__context) | |||
self.startImageProcess(message, gpu_ids, analysisType) | |||
else: | |||
pass | |||
@@ -324,7 +357,7 @@ class DispatcherService: | |||
if self.recordingProcesses.get(msg.get(YmlConstant.REQUEST_ID)): | |||
logger.warning("重复任务,请稍后再试!requestId:{}", msg.get(YmlConstant.REQUEST_ID)) | |||
return | |||
cfg = {YmlConstant.FBQUEUE: self.fbQueue, YmlConstant.CONTEXT: self.context, YmlConstant.MSG: msg, | |||
cfg = {YmlConstant.FBQUEUE: self.fbQueue, YmlConstant.CONTEXT: self.__context, YmlConstant.MSG: msg, | |||
YmlConstant.ANALYSE_TYPE: analysisType} | |||
srp = ScreenRecordingProcess(cfg) | |||
srp.start() |
@@ -49,9 +49,7 @@ def get_video_info(in_file): | |||
if __name__ == '__main__': | |||
file_path = 'https://vod.play.t-aaron.com/customerTrans/edc96ea2115a0723a003730956208134/55547af9-184f0827dae-0004-f90c-f2c-7ec68.mp4' | |||
#file_path = 'https://vod.play.t-aaron.com/customerTrans/edc96ea2115a0723a003730956208134/40b416f7-183b57f6be0-0004-f90c-f2c-7ec68.mp4' | |||
#file_path = 'https://vod.play.t-aaron.com/3301fc8e166f45be88f2214e7a8f4a9d/e29535365b54434d9ed2e8c3b0a175da-fba35541b31a1049ca05b145a283c33a-hd.mp4' | |||
file_path = r'D:\shipin\777.mp4' | |||
video_info = get_video_info(file_path) | |||
print(json.dumps(video_info)) | |||
# total_frames = int(video_info['nb_frames']) | |||
@@ -62,47 +60,32 @@ if __name__ == '__main__': | |||
# image_array = numpy.asarray(bytearray(out), dtype="uint8") | |||
# image = cv2.imdecode(image_array, cv2.IMREAD_COLOR) | |||
# kwargs={'fflags': 'nobuffer', 'flags': 'low_delay'} | |||
kwargs={ | |||
# "hwaccel": "nvdec", | |||
# "vcodec": "h264_cuvid", | |||
# "c:v": "h264_cuvid" | |||
} | |||
output_args = { | |||
# "vcodec": "hevc_nvenc", | |||
# "c:v": "hevc_nvenc", | |||
# "preset": "fast", | |||
} | |||
# i = 1 | |||
# process1 = ( | |||
# ffmpeg | |||
# .input(file_path, **kwargs) | |||
# .output('pipe:', format='rawvideo', pix_fmt='rgb24', **output_args) | |||
# # .global_args("-an") | |||
# .overwrite_output() | |||
# .run_async(pipe_stdout=True, pipe_stderr=True) | |||
# ) | |||
width = int(video_info['width']) | |||
height = int(video_info['height']) | |||
width_2_1 = int(width/2) | |||
height_2_1 = int(height/2) | |||
print("长:", width, "宽:", height) | |||
text = '' | |||
command = ['ffmpeg', | |||
# '-hwaccel', 'cuvid', | |||
'-c:v', 'h264_cuvid', | |||
# '-hwaccel_output_format', 'cuda', | |||
'-resize', '%sx%s' % (width_2_1, height_2_1), | |||
# '-resize', '%sx%s' % (width_2_1, height_2_1), | |||
'-i', file_path, | |||
# '-c:v', 'hevc_nvenc', | |||
# '-pix_fmt', 'yuv420p', | |||
'-f', 'rawvideo', | |||
# '-pix_fmt', 'bgr24', | |||
'-pix_fmt', 'bgr24', | |||
'-an', | |||
'-'] | |||
p = sp.Popen(command, stdout=sp.PIPE) | |||
# ai_video_file = cv2.VideoWriter(r"C:\Users\chenyukun\Desktop\shipin\aa.mp4", cv2.VideoWriter_fourcc(*'mp4v'), 30, | |||
# (width, height)) | |||
# for line in p.stderr: | |||
# # print(line.strip()) | |||
# for line in p.stdout: | |||
# print(text) | |||
command1 = ['ffmpeg', | |||
'-report', | |||
# '-loglevel', 'debug', | |||
'-y', # 不经过确认,输出时直接覆盖同名文件。 | |||
'-f', 'rawvideo', | |||
@@ -112,7 +95,7 @@ if __name__ == '__main__': | |||
# '-c:v', 'h264_cuvid', | |||
# '-hwaccel_output_format', 'cuda', | |||
# '-s', "{}x{}".format(self.width * 2, self.height), | |||
'-s', "{}x{}".format(width_2_1, height_2_1), | |||
'-s', "{}x{}".format(width, height), | |||
'-r', str(25), | |||
'-i', '-', # 指定输入文件 | |||
'-g', str(5), | |||
@@ -141,30 +124,37 @@ if __name__ == '__main__': | |||
'rtmp://live.push.t-aaron.com/live/THSAr'] | |||
# # 管道配置 | |||
p1 = sp.Popen(command1, stdin=sp.PIPE) | |||
p1 = sp.Popen(command1, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE, ) | |||
start1 = time.time() | |||
num = 0 | |||
while True: | |||
num += 1 | |||
# if num ==100: | |||
# print(time.time()-start1) | |||
# break | |||
start = time.time() | |||
in_bytes = p.stdout.read(int(width * height*3//8)) | |||
# print(type(in_bytes)) | |||
# img = (np.frombuffer(in_bytes, np.uint8)).reshape((height*3//4, width//2)) | |||
# result = cv2.cvtColor(img, cv2.COLOR_YUV2BGR_NV12) | |||
# result = cv2.resize(result, (int(width / 2), int(height / 2)), interpolation=cv2.INTER_LINEAR) | |||
# result = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) | |||
if not in_bytes: | |||
print(in_bytes) | |||
# ai_video_file.release() | |||
p.stdout.close() | |||
p.wait() | |||
break | |||
print(num) | |||
time.sleep(0.001) | |||
# p1.stdin.write(result.tostring()) | |||
# num += 1 | |||
# # if num ==100: | |||
# # print(time.time()-start1) | |||
# # break | |||
# start = time.time() | |||
in_bytes = p.stdout.read(int(width * height*3)) | |||
# # print(type(in_bytes)) | |||
img = (np.frombuffer(in_bytes, np.uint8)).reshape((height, width, 3)) | |||
# # result = cv2.cvtColor(img, cv2.COLOR_YUV2BGR_NV12) | |||
# # result = cv2.resize(result, (int(width / 2), int(height / 2)), interpolation=cv2.INTER_LINEAR) | |||
# # result = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) | |||
for line in iter(p1.stdout.readline, b''): | |||
print(line) | |||
# if in_bytes: | |||
# p1.stdin.write(img.tostring()) | |||
# print(p1.stderr.read().decode('utf-8')) | |||
# for line in iter(p1.std | |||
# | |||
# | |||
# out.readline, ''): | |||
# line = line.decode('utf-8') | |||
# print(line) | |||
# print(num) | |||
# time.sleep(0.001) | |||
# p1.stdin.write(in_frame.tostring()) | |||
# frame | |||
# .astype(np.uint8) | |||
@@ -182,4 +172,4 @@ if __name__ == '__main__': | |||
# break | |||
# cv2.imshow('frame', frame) | |||
# time.sleep(1111) | |||
p.kill() | |||
# p.kill() |
@@ -0,0 +1,108 @@ | |||
import numpy as np | |||
# # 使用标量类型 | |||
# dt = np.dtype(np.int32) | |||
# print(dt) | |||
# | |||
# # int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替 | |||
# dt = np.dtype('i4') | |||
# print(dt) | |||
# | |||
# # 字节顺序标注 | |||
# dt = np.dtype('<i4') | |||
# print(dt) | |||
# | |||
# dt = np.dtype([('age', np.int8)]) | |||
# print(dt) | |||
# | |||
# dt = np.dtype([('age', np.int8)]) | |||
# a = np.array([(10,), (20,), (30,)], dtype=dt) | |||
# print(a) | |||
# print(a['age']) | |||
# | |||
# student = np.dtype([('name', 'S20'), ('age', 'i1'), ('marks', 'f4')]) | |||
# print(student) | |||
# | |||
# a = np.array([('abc', 21, 50), ('xyz', 18, 75)], dtype=student) | |||
# print(a) | |||
# | |||
# a = np.arange(32) | |||
# b = a.reshape(2, 4, 4) | |||
# print(b.ndim) | |||
# print(b.shape) | |||
# | |||
# a = np.array([[1, 2, 3], [4, 5, 6]]) | |||
# a.shape = (3, 2) | |||
# print(a) | |||
# | |||
# a = np.array([[1, 2, 3], [4, 5, 6]]) | |||
# b = a.reshape(3, 2) | |||
# print(b) | |||
# x = np.array([1, 2, 3, 4, 5], dtype=np.int8) | |||
# print(x.itemsize) | |||
# y = np.array([1, 2, 3, 4, 5], dtype=np.float64) | |||
# print(y.itemsize) | |||
# x = np.empty([3, 2], dtype=int) | |||
# print(x) | |||
# | |||
# # 默认为浮点数 | |||
# x = np.zeros(5) | |||
# print(x) | |||
# # 设置类型为整数 | |||
# y = np.zeros((5,), dtype=int) | |||
# print(y) | |||
# | |||
# # 自定义类型 | |||
# z = np.zeros((2, 2), dtype=[('x', 'i4'), ('y', 'i4')]) | |||
# print(z) | |||
# | |||
# # 默认为浮点数 | |||
# x = np.ones(5) | |||
# print(x) | |||
# | |||
# x = np.ones([2, 2], dtype=int) | |||
# print(x) | |||
# | |||
# s = b'Hello World' | |||
# a = np.frombuffer(s, dtype='S1') | |||
# print(a) | |||
# | |||
# arr1 = np.array([1, 2, 3, 4, 5]) | |||
# arr2 = np.frombuffer(arr1, dtype=int) | |||
# print(arr2) # [1 2 3 4 5] | |||
# | |||
# | |||
# list=range(5) | |||
# it=iter(list) | |||
# a = [1,2,3,4,5] | |||
# # 使用迭代器创建 ndarray | |||
# x=np.fromiter(arr1, dtype=float) | |||
# print(x) | |||
# aa = [ | |||
# [1, 2, 3], | |||
# [4, 5, 6], | |||
# [7, 8, 9] | |||
# ] | |||
# a = np.array(aa) | |||
# # b = a[1:3, 1:3] | |||
# # c = a[1:3, [1, 2]] | |||
# d = a[...,1:] | |||
# # print(b) | |||
# # print(c) | |||
# print(d) | |||
# a = np.array([[0, 0, 0], | |||
# [10, 10, 10], | |||
# [20, 20, 20], | |||
# [30, 30, 30]]) | |||
# b = np.array([1, 2, 3]) | |||
# bb = np.tile(b, (4, 1)) # 重复 b 的各个维度 | |||
# print(bb) | |||
# # print(a + bb) | |||
a = np.arange(6).reshape(2, 3) | |||
print(a) | |||
print("========================") | |||
print(a.T) |
@@ -0,0 +1,198 @@ | |||
""" | |||
1.色彩空间:[BGR] | |||
(1) HSV: 更类似于人类感觉颜色的方式。H:色相(Hue) S: 饱和度(Saturation0) V: 亮度(Value) | |||
(2) YUV: Y: 亮度信号 U/V: 两个色彩信号 -> 色彩的饱和度 | |||
(3) Lab: 有国际照明委员会建立。 L: 整张图到的明亮度 a\b: 负责颜色的多少 | |||
""" | |||
import cv2 | |||
import numpy as np | |||
from matplotlib import pyplot as plt | |||
# img = cv2.imread(r'C:\Users\chenyukun\Pictures\R.png') | |||
# cv2.imshow("img", img) | |||
# HSV | |||
# hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) | |||
# cv2.imshow("hsv", hsv) | |||
# YUV | |||
# yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV) | |||
# cv2.imshow("yuv", yuv) | |||
# LAB | |||
# lab = cv2.cvtColor(img, cv2.COLOR_BGR2Lab) | |||
# cv2.imshow("lab", lab) | |||
# 分离颜色通道 | |||
# print(img) | |||
# b, g, r = cv2.split(img) | |||
# h, w = np.shape(b) | |||
# # 建立空白数组 | |||
# hest = np.zeros([256], dtype=np.int32) | |||
# print(hest) | |||
# # 遍历图片 | |||
# for i in [b, g, r]: | |||
# for row in range(h): | |||
# for col in range(w): | |||
# pv = i[row, col] | |||
# hest[pv] += 1 | |||
# plt.plot(hest, color='r') | |||
# plt.show() | |||
# cv2.waitKey(100000) | |||
# array1 = np.random.randint(0, 255, (300, 150, 3), dtype=np.uint8) | |||
# array2 = np.random.randint(200, 255, (300, 150, 3), dtype=np.uint8) | |||
# new_array = np.hstack([array1, array2]) | |||
# cv2.imshow("new_array", new_array) | |||
# cv2.waitKey(100000) | |||
# 彩色图片 -> BGR | |||
# 查看B | |||
# img_B = img.copy() | |||
# img_B[:, :, 1] = 0 | |||
# img_B[:, :, 2] = 0 | |||
# cv2.imshow("img_B", img_B) | |||
# cv2.waitKey(100000) | |||
# 查看G | |||
# img_G = img.copy() | |||
# img_G[:, :, 0] = 0 | |||
# img_G[:, :, 2] = 0 | |||
# cv2.imshow("img_G", img_G) | |||
# cv2.waitKey(100000) | |||
# 查看G | |||
# img_R = img.copy() | |||
# img_R[:, :, 0] = 0 | |||
# img_R[:, :, 1] = 0 | |||
# cv2.imshow("img_R", img_R) | |||
# cv2.waitKey(100000) | |||
# 深入研究图片的读取 | |||
""" | |||
cv2.imread(path, way) | |||
0: 读取灰度图片 | |||
1: 读取彩色图片 | |||
-1: 读取图片,加载Alpha通道 | |||
Alpha通道: | |||
指一张图片的透明与不透明度 | |||
""" | |||
img_color = cv2.imread(r'C:\Users\chenyukun\Pictures\R.png') | |||
img_gray = cv2.imread(r'C:\Users\chenyukun\Pictures\R.png', 0) | |||
img_transparent = cv2.imread(r'C:\Users\chenyukun\Pictures\R.png', -1) | |||
""" | |||
彩色图像:三维 B G R -> (373*490) | |||
灰度图像:二维:-> (373*490) | |||
推断出的公式: Y = (B+G+R)/3 | |||
官方给出的公式: Y = 0.299R + 0.587G + 0.114B | |||
cv.imshow() -> 不仅仅是array()必须是uint8这种类型的。 | |||
""" | |||
# 三通道分离 | |||
# b, g, r = cv2.split(img_color) | |||
# new_img = (b+g+r)/3 | |||
# new_img = 0.299*r + 0.587*g + 0.114*b | |||
# new_img = new_img.astype('uint8') | |||
# cv2.imshow('new_img', new_img) | |||
# 官方的填充方式: 以初始的灰度二维矩阵进行RGB通道的填充 | |||
# new_image = cv2.merge([img_gray,img_gray,img_gray]) | |||
# cv2.imshow('new_img', new_image) | |||
# cv2.waitKey(100000) | |||
# 图像的加法 -> 矩阵 | |||
# 加法 【前提:必须是一样大小的矩阵:对应的元素求和】 | |||
""" | |||
像素点: [0,255]超过255怎么办?【取余】 | |||
150+150=300 | |||
300%255 | |||
""" | |||
""" | |||
图片融合 | |||
addWeighted(src1, alpha, src2, beta, gamma) | |||
src1\src2: 第一张和第二张图片 | |||
alpha\beta: 第一张图片的权重、第二张图片的权重 | |||
gamma: 亮度的调节 | |||
""" | |||
# result = cv2.addWeighted(img_color, 0.6, img_color, 0.3, 0) | |||
# cv2.imshow('new_img', result) | |||
# cv2.waitKey(100000) | |||
# | |||
# # 图像的类型转换 | |||
# # 原始图片BGR -> RGB | |||
# cv2.cvtColor(img_color, cv2.COLOR_BGR2RGB) | |||
""" | |||
1.沿着x轴进行翻转 | |||
2.沿着y轴进行翻转 | |||
3.同时沿着x轴和y进行翻转 | |||
cv2.flip(src, flipCode) | |||
src: 源图像 | |||
flipCode: 翻转形式 | |||
0:沿着x轴进行翻转 | |||
1(大于等于1): 沿着y轴进行翻转 | |||
-1(小于等于-1): 同时沿着x轴和y进行翻转 | |||
""" | |||
""" | |||
图像阈值化处理 | |||
ret, dst = cv2.threshold(src, thresh, maxval, type) | |||
ret: 阈值返回值(阈值设定的是多少) | |||
dst: 输出的图像 | |||
src: 源图像 需要阈值化处理的图像 | |||
thresh: 人为指定的阈值 | |||
maxval: 当像素超过了阈值,(小于等于阈值)所赋予的值,否则取0 | |||
type: | |||
(1) cv2.THRESH_BINARY: 当像素点大于阈值时,取指定255,小于等于阈值时,取0 | |||
(2) cv2.THRESH_BINARY_INV: 当像素点大于阈值时,取0。小于等于阈值时,取255 | |||
(3) cv2.THRESH_TRUNC: 超过阈值取阈值,低于阈值取自身 | |||
(4) cv2.THRESH_TOZERO: 超过阈值不变,低于阈值取0 | |||
(5) cv2.THRESH_TOZERO_INV: 超过阈值变为0, 低于阈值不变 | |||
注意:当阈值处理彩色图像时,出现粉色等颜色的原因在于: BGR三通道的叠加 | |||
""" | |||
# ret, dst = cv2.threshold(img_color, 127, 255, cv2.THRESH_BINARY) | |||
# cv2.imshow('new_img', dst) | |||
# cv2.waitKey(100000) | |||
""" | |||
均值滤波 | |||
cv2.blur(src, kernel) | |||
src: 源图像 | |||
kernel: 大小(选择多大的矩阵进行平移[3*3最常见]) | |||
""" | |||
# new_img = cv2.blur(img_color, (3, 3)) | |||
# cv2.imshow('new_img', new_img) | |||
# cv2.waitKey(100000) | |||
""" | |||
方框滤波 | |||
cv2.boxFilter(src,depth, ksize, normalize) | |||
src: 源图像 | |||
depth: 图像的深度 填-1就ok, 表示与源图像深度相同 | |||
ksize: 核大小(3*3)(5*5) | |||
normalize: 是否进行归一化 | |||
0:false 不进行归一下(求和,像素点溢出,超过255取255) | |||
1:True 进行归一化,也就是均值滤波 | |||
""" | |||
""" | |||
高斯滤波【考虑了权重问题】 | |||
cv2.GaussianBlur(src, ksize, sigmaX, sigmaY) | |||
src:源图像 | |||
ksize: (3*3)(5*5) 必须为奇数 | |||
sigmaX, sigmaY: 高斯核函数在x或y方向上的标准偏差【控制权重】 | |||
sigmaX = 0, sigmaX = 0.3 * ((ksize -1) * 0.5 -1) + 0.8 | |||
""" | |||
''' | |||
中值滤波 | |||
cv2.medianBlur(src, ksize) | |||
src: 源图像 | |||
ksize:核大小, 只能传递int(1,3,5,7,9)【(3, 3)(5, 5)】 | |||
''' | |||
new_img = cv2.medianBlur(img_color, 5) | |||
cv2.imshow('new_img', new_img) | |||
cv2.waitKey(100000) |
@@ -0,0 +1,24 @@ | |||
import requests | |||
# url = 'https://www.baidu.com' | |||
# response = requests.get(url) | |||
# print(response) | |||
# print(type(response)) | |||
# # 返回的页面是requests库猜测的编码方式,有误 | |||
# print(response.text) | |||
# content = response.content.decode('utf-8') | |||
# print(content) | |||
url = 'https://www.baidu.com/s' | |||
kw = {"wd": "猫"} | |||
headers = { | |||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36" | |||
} | |||
response = requests.get(url, params=kw, headers=headers) | |||
# 打印requests库猜测的解码方式 | |||
print(response.encoding) | |||
content = response.content.decode('utf-8') | |||
print(content) | |||
# 查看状态码 | |||
print(response.status_code) | |||
@@ -0,0 +1,121 @@ | |||
# -*- coding: utf-8 -*- | |||
class Test: | |||
pass | |||
print(type(Test)) | |||
print(type(int)) | |||
# 结果都为<class 'type'>,type就是内置的元类,class关键字定义的所有的类以及内置的类都是由元类type实例化产生。 | |||
""" | |||
由于在python3中没有经典类和新式类的区别,因此python3中object是所有类的基类,那内置元类type又是什么? | |||
type是object类的类型,总结来说就是type是object的类型,同时,object又是type的基类,这句话看起来就有问题, | |||
到底是先有type还是先有object呢?这个问题有点类似于先有鸡还是先有蛋,我们可以通过代码简单分析一下 | |||
在python3中类和类型是同一种东西,因此对象.__class__和type(对象)得到的结果是一致的,object的基类为空, | |||
但是type的基类为object,但是object的类型又是type。 | |||
""" | |||
print(type(object)) | |||
print(object.__class__) | |||
print(type(type)) | |||
print(type.__class__) | |||
print(object.__bases__) | |||
print(type.__bases__) | |||
# python字符串 | |||
strs = """ | |||
global name | |||
global age | |||
name = 'py' | |||
age = 18 | |||
addr = 'xx' | |||
""" | |||
# 定义全局作用域中的名字和值 | |||
globals = { | |||
'a': '1', | |||
'b': '2' | |||
} | |||
# 定义局部作用域中的名字和值 | |||
locals = { | |||
'x': 3, | |||
'y': 4 | |||
} | |||
exec(strs, globals, locals) | |||
print(globals['name']) | |||
print(locals) | |||
# 了解了exec的作用之后,就可以分析class关键字如何借助type元类产生类的步骤: | |||
# 1 定义类名 | |||
class_name = 'Test' | |||
# 2 定义类的基类(父类) | |||
class_bases = (object,) | |||
# 3 执行类体代码拿到类的名称空间 | |||
class_dic = {} | |||
# 4 定义类体代码(本质是字符串) | |||
class_body = """ | |||
def __init__(self,name,age): | |||
self.name=name | |||
self.age=age | |||
def test(self): | |||
print('%s:%s' %(self.name,self.name)) | |||
""" | |||
# 5 将字符串转为python能识别的语法:将class_body运行时产生的名字存入class_dic中 | |||
exec(class_body, {}, class_dic) | |||
# 查看类的名称空间 | |||
print(class_dic) | |||
# 6 调用元类产生类 | |||
Test = type(class_name, class_bases, class_dic) | |||
# 7 调用类产生对象 | |||
t = Test('python', '12') | |||
t.test() | |||
# 自定义元类 | |||
class MyMeta(type): # 自定义元类必须继承type,否则就是普通的类 | |||
''' | |||
早于__init__方法执行,必须返回空对象,由于该方法是调用类后第一个运行的方法, | |||
此时并没有对象产生,因此该方法的第一个参数必须是类本身(MyMeta),*args, **kwargs | |||
用来接收调用元类产生对象所需的参数(类名 类的基类 名称空间) | |||
''' | |||
def __new__(cls, *args, **kwargs): | |||
return type.__new__(cls, *args, **kwargs) # 直接调用父类type中的__new__方法 | |||
''' | |||
通过__init__控制类的产生,调用自定义元类与调用内置元类type的方式相同, | |||
需要传入类名、类的父类们、类体代码的名称空间,__init__方法中第一个参数来自于__new__方法产生的空对象。 | |||
''' | |||
def __init__(self, class_name, class_bases, class_dict): | |||
''' | |||
在该方法内可以控制类的产生 | |||
''' | |||
if not class_name.istitle(): # 实现类名首字母必须大写,否则抛出异常 | |||
raise NameError('类名的首字母必须大写') | |||
if '__doc__' not in class_dict or len(class_dict['__doc__'].strip())==0: # 实现类必须有文档注释,否则抛出异常 | |||
raise TypeError('必须有文档注释') | |||
def __call__(self, *args, **kwargs): | |||
print(self) | |||
print(args) | |||
print(kwargs) | |||
return 'test' | |||
class Test(metaclass=MyMeta): | |||
''' | |||
我是文档注释 | |||
''' | |||
def __init__(self): | |||
self.name = 'python' | |||
def test(self): | |||
print('test') | |||
t = Test() |
@@ -0,0 +1,5 @@ | |||
from os import environ | |||
print("LOGURU_TRACE_NO" not in environ) |
@@ -0,0 +1,145 @@ | |||
import re | |||
''' | |||
1.匹配某个字符串 | |||
match():只能匹配某个 | |||
''' | |||
# text = 'python python' | |||
# result = re.match('py', text) | |||
# print(result) | |||
# print(result.group()) | |||
''' | |||
2.点 | |||
匹配任意的某个字符【无法匹配换行符】【必须从开头开始匹配】 | |||
''' | |||
# text = 'python' | |||
# result = re.match('.', text) | |||
# print(result) | |||
# print(result.group()) | |||
''' | |||
3.\d | |||
匹配任意的数字【除了数字外均无法匹配】 | |||
''' | |||
# text = '1python' | |||
# result = re.match('\d', text) | |||
# print(result) | |||
# print(result.group()) | |||
''' | |||
4.\D | |||
除了数字外均可匹配【数字均无法匹配】 | |||
''' | |||
# text = 'python' | |||
# result = re.match('\D', text) | |||
# print(result) | |||
# print(result.group()) | |||
''' | |||
5.\s | |||
匹配空白字符【\n、 \t、 \r 、空格】 | |||
''' | |||
# text = '\npython' | |||
# result = re.match('\s', text) | |||
# print(result) | |||
# print(result.group()) | |||
''' | |||
6.\w | |||
匹配小写的a-z,大写的A-Z,数字和下划线 | |||
''' | |||
# text = 'python' | |||
# result = re.match('\w', text) | |||
# print(result) | |||
# print(result.group()) | |||
''' | |||
7.\W | |||
匹配除小写\w之外的所有字符 | |||
''' | |||
# text = '\npython' | |||
# result = re.match('\W', text) | |||
# print(result) | |||
# print(result.group()) | |||
''' | |||
8.[] ->> 组合的方式 | |||
只要在中括号内的内容均可匹配 | |||
''' | |||
# text = '\npython' | |||
# result = re.match('[\n_]', text) | |||
# print(result) | |||
# print(result.group()) | |||
''' | |||
9.星号 * | |||
匹配零个或者多个字符 | |||
''' | |||
# text = '139-1234-5678' | |||
# result = re.match('[-\d]*', text) | |||
# print(result) | |||
# print(result.group()) | |||
''' | |||
10.加号 + | |||
匹配1个或者多个字符 | |||
''' | |||
# text = '139-1234-5678' | |||
# result = re.match('[-\d]+', text) | |||
# print(result) | |||
# print(result.group()) | |||
''' | |||
11.问号 ? | |||
匹配0个或者匹配1个 | |||
''' | |||
# text = '139-1234-5678' | |||
# result = re.match('[-\d]?', text) | |||
# print(result) | |||
# print(result.group()) | |||
''' | |||
12. {m,n} 匹配m到n个 | |||
匹配0个或者匹配1个 | |||
''' | |||
# text = '139-1234-5678' | |||
# result = re.match('[-\d]{1,5}', text) | |||
# print(result) | |||
# print(result.group()) | |||
''' | |||
13. 匹配所有的数字 | |||
''' | |||
# text = '139-1234-5678' | |||
# result = re.match('[-0-9]*', text) | |||
# print(result) | |||
# print(result.group()) | |||
''' | |||
14. 匹配所有的非数字 | |||
''' | |||
# text = '139-1234-5678' | |||
# result = re.match('[^0-9]*', text) | |||
# print(result) | |||
# print(result.group()) | |||
# re.match() 必须从字符串开头进行匹配 | |||
# re.search() 从左到右进行字符串的遍历,找到就返回 | |||
# text = 'aapython' | |||
# result = re.match('py', text) | |||
# print(result) | |||
# print(result.group()) | |||
# text = 'aapython' | |||
# result = re.search('py', text) | |||
# print(result) | |||
# print(result.group()) | |||
""" | |||
1. 贪婪模式: 正则表达式会尽可能多地匹配字符【默认就是贪婪模式】 | |||
2. 非贪婪模式: 正则表达式会尽可能少地匹配字符【?】 | |||
转义字符 \ | |||
""" | |||
@@ -0,0 +1,18 @@ | |||
from typing import Optional, Union, Any, Set | |||
a: int = 8 | |||
b: bool = True | |||
c: str = 'ok' | |||
d: Optional[Union[int, float]] = None | |||
e: float = 9.8 | |||
f: bytes = b'32' | |||
d = 5 | |||
d = 9.8 | |||
d = None | |||
s: Set[int] = {1, 2, '3'} | |||
for ss in s: | |||
print(ss) |
@@ -41,4 +41,8 @@ with ThreadPoolExecutor(max_workers=10) as t: | |||
if f.exception(): | |||
raise f.exception() | |||
else: | |||
print(f"Task {f.result()} succeeded") | |||
print(f"Task {f.result()} succeeded") | |||
dsp算法交互 V 2.7.4转测 | |||
1. 修复算法交互分析后上传大视频失败问题bug | |||
2. 修改百度图片子线程异常信息父级线程不打印问题bug |
@@ -0,0 +1,24 @@ | |||
# -*- coding: utf-8 -*- | |||
from threading import RLock | |||
class SingletonType(type): | |||
single_lock = RLock() | |||
def __call__(cls, *args, **kwargs): # 创建cls的对象时候调用 | |||
with SingletonType.single_lock: | |||
if not hasattr(cls, "_instance"): | |||
cls._instance = super(SingletonType, cls).__call__(*args, **kwargs) # 创建cls的对象 | |||
return cls._instance | |||
class Singleton(metaclass=SingletonType): | |||
def __init__(self, name): | |||
self.name = name | |||
single_1 = Singleton('第1次创建') | |||
single_2 = Singleton('第2次创建') | |||
print(single_1.name, single_2.name) # 第1次创建 第1次创建 | |||
print(single_1 is single_2) |
@@ -0,0 +1,28 @@ | |||
# -*- coding: utf-8 -*- | |||
from threading import RLock | |||
single_lock = RLock() | |||
def Singleton(cls): | |||
instance = {} | |||
def _singleton_wrapper(*args, **kargs): | |||
with single_lock: | |||
if cls not in instance: | |||
instance[cls] = cls(*args, **kargs) | |||
return instance[cls] | |||
return _singleton_wrapper | |||
@Singleton | |||
class SingletonTest(object): | |||
def __init__(self, name): | |||
self.name = name | |||
slt_1 = SingletonTest('第1次创建') | |||
print(slt_1.name) | |||
slt_2 = SingletonTest('第2次创建') | |||
print(slt_1.name, slt_2.name) | |||
print(slt_1 is slt_2) |
@@ -0,0 +1,18 @@ | |||
from threading import RLock | |||
class Singleton(object): | |||
single_lock = RLock() | |||
def __init__(self, name): | |||
self.name = name | |||
@classmethod | |||
def instance(cls, *args, **kwargs): | |||
with Singleton.single_lock: | |||
if not hasattr(Singleton, "_instance"): | |||
Singleton._instance = Singleton(*args, **kwargs) | |||
return Singleton._instance | |||
single_1 = Singleton.instance('第1次创建') | |||
single_2 = Singleton.instance('第2次创建') | |||
print(single_1 is single_2) # True |
@@ -0,0 +1,22 @@ | |||
from threading import RLock | |||
class Singleton(object): | |||
single_lock = RLock() | |||
def __init__(self, name): | |||
if hasattr(self, 'name'): | |||
return | |||
self.name = name | |||
def __new__(cls, *args, **kwargs): | |||
with Singleton.single_lock: | |||
if not hasattr(Singleton, "_instance"): | |||
Singleton._instance = object.__new__(cls) | |||
return Singleton._instance | |||
single_1 = Singleton('第1次创建') | |||
single_2 = Singleton('第2次创建') | |||
print(single_1.name, single_2.name) # 第2次创建 第2次创建 | |||
print(single_1 is single_2) # True |
@@ -0,0 +1,15 @@ | |||
class DbSingleton(): | |||
def __init__(self, host, port, username, password): | |||
self.host = host | |||
self.port = port | |||
self.username = username | |||
self.password = password | |||
self.pool = None # 连接池 | |||
def connect(self): | |||
print("建立连接") | |||
db_singleton = DbSingleton('host', 'port', 'username', 'password') |
@@ -0,0 +1,7 @@ | |||
from single import db_singleton | |||
if __name__ == '__main__': | |||
print(id(db_singleton)) | |||
print(id(db_singleton)) | |||
print(id(db_singleton)) |
@@ -0,0 +1,36 @@ | |||
from abc import ABC, abstractmethod | |||
class Fruit(ABC): | |||
def __init__(self, name): | |||
self.name = name | |||
@abstractmethod | |||
def make_juice(self): | |||
pass | |||
class Apple(Fruit): | |||
def make_juice(self): | |||
print(f"制作{self.name}汁") | |||
class Grape(Fruit): | |||
def make_juice(self): | |||
print(f"制作{self.name}酒") | |||
class FruitFactory(): | |||
@classmethod | |||
def create_fruit(cls, name): | |||
if name == 'apple': | |||
return Apple('苹果') | |||
elif name == 'grape': | |||
return Grape("葡萄") | |||
fruit1 = FruitFactory.create_fruit('apple') | |||
fruit1.make_juice() | |||
fruit2 = FruitFactory.create_fruit('grape') | |||
fruit2.make_juice() |
@@ -0,0 +1,44 @@ | |||
from abc import ABC, abstractmethod | |||
class Fruit(ABC): | |||
def __init__(self, name): | |||
self.name = name | |||
@abstractmethod | |||
def make_juice(self): | |||
pass | |||
class Apple(Fruit): | |||
def make_juice(self): | |||
print(f"制作{self.name}汁") | |||
class Grape(Fruit): | |||
def make_juice(self): | |||
print(f"制作{self.name}酒") | |||
class AbcFruitFactory(ABC): | |||
@abstractmethod | |||
def create_fruit(self): | |||
pass | |||
class AppleFactory(AbcFruitFactory): | |||
def create_fruit(self): | |||
return Apple('苹果') | |||
class OrangeFactory(AbcFruitFactory): | |||
def create_fruit(self): | |||
return Grape('葡萄') | |||
fruit1 = AppleFactory().create_fruit() | |||
fruit1.make_juice() # 制作苹果汁 | |||
fruit2 = OrangeFactory().create_fruit() | |||
fruit2.make_juice() |
@@ -16,10 +16,11 @@ from util import LogUtils | |||
from vodsdk.AliyunVodUploader import AliyunVodUploader | |||
from vodsdk.UploadVideoRequest import UploadVideoRequest | |||
class AliyunOssSdk: | |||
def __init__(self, context, requestId): | |||
LogUtils.init_log(context) | |||
# LogUtils.init_log(context) | |||
self.__context = context | |||
self.bucket = None | |||
self.__requestId = requestId | |||
@@ -55,7 +56,7 @@ class AliyunOssSdk: | |||
class ThAliyunVodSdk: | |||
def __init__(self, context, requestId): | |||
LogUtils.init_log(context) | |||
# LogUtils.init_log(context) | |||
self.__context = context | |||
self.__requestId = requestId | |||
@@ -93,7 +94,7 @@ class ThAliyunVodSdk: | |||
diff_time = current_time - start | |||
if diff_time > 60 * 60 * 5: | |||
logger.error("获取视频地址失败超时异常: {},超时时间:{}, requestId: {}", str(e), diff_time, | |||
self.__requestId) | |||
self.__requestId) | |||
raise ServiceException(ExceptionType.GET_VIDEO_URL_TIMEOUT_EXCEPTION.value[0], | |||
ExceptionType.GET_VIDEO_URL_TIMEOUT_EXCEPTION.value[1]) | |||
@@ -48,8 +48,8 @@ class Cv2Util(): | |||
self.width = width | |||
self.height = height | |||
if width > Constant.width: | |||
self.h = int(self.height//2) | |||
self.w = int(self.width//2) | |||
self.h = int(self.height // 2) | |||
self.w = int(self.width // 2) | |||
else: | |||
self.h = int(self.height) | |||
self.w = int(self.width) | |||
@@ -94,8 +94,8 @@ class Cv2Util(): | |||
self.height = int(height) | |||
self.wh = self.width * self.height * 3 | |||
if width > Constant.width: | |||
self.h = int(self.height//2) | |||
self.w = int(self.width//2) | |||
self.h = int(self.height // 2) | |||
self.w = int(self.width // 2) | |||
else: | |||
self.h = int(self.height) | |||
self.w = int(self.width) | |||
@@ -106,8 +106,9 @@ class Cv2Util(): | |||
# if duration: | |||
# self.duration = float(video_stream['duration']) | |||
# self.bit_rate = int(bit_rate) / 1000 | |||
self.__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.__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: | |||
self.__logger.error("获取视频信息异常: {}, requestId:{}", s.msg, self.requestId) | |||
self.clear_video_info() | |||
@@ -119,6 +120,7 @@ class Cv2Util(): | |||
''' | |||
录屏任务获取视频信息 | |||
''' | |||
def get_recording_video_info(self): | |||
try: | |||
video_info = 'ffprobe -show_format -show_streams -of json %s' % self.pullUrl | |||
@@ -149,7 +151,7 @@ class Cv2Util(): | |||
up, down = str(fps).split('/') | |||
self.fps = int(eval(up) / eval(down)) | |||
self.__logger.info("视频信息, width:{}|height:{}|fps:{}|all_frames:{}, requestId:{}", self.width, | |||
self.height, self.fps, self.all_frames, self.requestId) | |||
self.height, self.fps, self.all_frames, self.requestId) | |||
except ServiceException as s: | |||
self.__logger.error("获取视频信息异常: {}, requestId:{}", s.msg, self.requestId) | |||
self.clear_video_info() | |||
@@ -166,6 +168,7 @@ class Cv2Util(): | |||
''' | |||
录屏拉取视频 | |||
''' | |||
def recording_pull_p(self): | |||
try: | |||
# 如果视频信息不存在, 不初始化拉流 | |||
@@ -308,25 +311,30 @@ class Cv2Util(): | |||
return result | |||
def close(self): | |||
self.clear_video_info() | |||
if self.pull_p: | |||
if self.pull_p.stdout: | |||
self.pull_p.stdout.close() | |||
self.pull_p.terminate() | |||
self.pull_p.wait() | |||
self.pull_p = None | |||
self.__logger.info("关闭拉流管道完成, requestId:{}", self.requestId) | |||
if self.p: | |||
if self.p.stdin: | |||
self.p.stdin.close() | |||
self.p.terminate() | |||
self.p.wait() | |||
self.p = None | |||
# self.p.communicate() | |||
# self.p.kill() | |||
self.__logger.info("关闭管道完成, requestId:{}", self.requestId) | |||
if self.or_video_file: | |||
self.or_video_file.release() | |||
self.or_video_file = None | |||
self.__logger.info("关闭原视频写入流完成, requestId:{}", self.requestId) | |||
if self.ai_video_file: | |||
self.ai_video_file.release() | |||
self.ai_video_file = None | |||
self.__logger.info("关闭AI视频写入流完成, requestId:{}", self.requestId) | |||
# 构建 cv2 | |||
@@ -423,7 +431,8 @@ class Cv2Util(): | |||
'-tune', 'll', | |||
'-f', 'flv', | |||
self.pushUrl] | |||
self.__logger.info("fps:{}|height:{}|width:{}|requestId:{}", self.fps, self.height, self.width, self.requestId) | |||
self.__logger.info("fps:{}|height:{}|width:{}|requestId:{}", self.fps, self.height, self.width, | |||
self.requestId) | |||
self.p = sp.Popen(command, stdin=sp.PIPE, shell=False) | |||
except ServiceException as s: | |||
if self.p: | |||
@@ -442,32 +451,35 @@ class Cv2Util(): | |||
self.__logger.exception("初始化p管道异常:{}, requestId:{}", e, self.requestId) | |||
def push_stream(self, frame): | |||
try: | |||
if self.p is None: | |||
self.build_p() | |||
self.p.stdin.write(frame.tostring()) | |||
except ServiceException as s: | |||
raise s | |||
except Exception as ex: | |||
self.__logger.exception("推流进管道异常:{}, requestId: {}", ex, self.requestId) | |||
current_retry_num = 0 | |||
while True: | |||
try: | |||
time.sleep(1) | |||
self.p_push_retry_num += 1 | |||
current_retry_num += 1 | |||
if current_retry_num > 3 or self.p_push_retry_num > 600: | |||
raise ServiceException(ExceptionType.PUSH_STREAMING_CHANNEL_IS_OCCUPIED.value[0], | |||
ExceptionType.PUSH_STREAMING_CHANNEL_IS_OCCUPIED.value[1]) | |||
current_retry_num = 0 | |||
while True: | |||
try: | |||
if self.p is None: | |||
self.build_p() | |||
self.p.stdin.write(frame.tostring()) | |||
self.__logger.info("构建p管道重试成功, 当前重试次数: {}, requestId: {}", current_retry_num, | |||
self.requestId) | |||
except ServiceException as ss: | |||
raise ss | |||
except Exception as e: | |||
self.__logger.exception("构建p管道异常:{}, 开始重试, 当前重试次数:{}, requestId: {}", e, | |||
current_retry_num, self.requestId) | |||
self.p.stdin.write(frame.tostring()) | |||
self.p_push_retry_num == 0 | |||
break | |||
except ServiceException as s: | |||
raise s | |||
except Exception as ex: | |||
if self.p: | |||
if self.p.stdin: | |||
self.p.stdin.close() | |||
self.p.terminate() | |||
self.p.wait() | |||
self.p = None | |||
time.sleep(0.1) | |||
self.p_push_retry_num += 1 | |||
current_retry_num += 1 | |||
if self.p_push_retry_num > 500: | |||
self.__logger.exception("推流进管道异常:{}, requestId: {}", ex, self.requestId) | |||
raise ServiceException(ExceptionType.PUSH_STREAMING_CHANNEL_IS_OCCUPIED.value[0], | |||
ExceptionType.PUSH_STREAMING_CHANNEL_IS_OCCUPIED.value[1]) | |||
if current_retry_num > 3: | |||
self.__logger.exception("推流进管道异常:{}, requestId: {}", ex, self.requestId) | |||
raise ServiceException(ExceptionType.PUSH_STREAM_EXCEPTION.value[0], | |||
ExceptionType.PUSH_STREAM_EXCEPTION.value[1]) | |||
def build_or_write(self): | |||
try: | |||
@@ -498,7 +510,6 @@ class Cv2Util(): | |||
self.__logger.exception("构建OR文件写对象异常, requestId:{}", self.requestId) | |||
raise Exception("构建OR文件写对象异常") | |||
def build_ai_write(self): | |||
try: | |||
if self.aiFilePath is not None and self.ai_video_file is None: |