更新配置
This commit is contained in:
parent
a64819b66f
commit
ec12171542
|
|
@ -0,0 +1,25 @@
|
||||||
|
video:
|
||||||
|
pullUrl: "rtsp://127.0.0.1:8554/video"
|
||||||
|
pushUrl: ["rtmp://192.168.10.101:19350/rlive/stream_9?sign=f8a15b6n"]
|
||||||
|
# 日志设置
|
||||||
|
log:
|
||||||
|
# 是否开启文件输出 True:开启 False:关闭
|
||||||
|
enable_file_log: True
|
||||||
|
# 是否开启控制台日志输出 True:开启 False:关闭
|
||||||
|
enable_stderr: True
|
||||||
|
# 日志打印文件夹
|
||||||
|
base_path: ./logs/
|
||||||
|
# 日志文件名称
|
||||||
|
log_name: airport.log
|
||||||
|
# 日志打印格式
|
||||||
|
log_fmt: "{time:YYYY-MM-DD HH:mm:ss.SSS} [{level}][{process.name}-{process.id}-{thread.name}-{thread.id}][{line}] {module}-{function} - {message}"
|
||||||
|
# 日志隔离级别
|
||||||
|
level: INFO
|
||||||
|
# 日志每天0点创建新文件
|
||||||
|
rotation: 00:00
|
||||||
|
# 日志保存时间1天
|
||||||
|
retention: 1 days
|
||||||
|
# 线程安全
|
||||||
|
enqueue: True
|
||||||
|
# 编码格式
|
||||||
|
encoding: utf8
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from alg_airport_ffmpeg.service.PushStreamService import PushStreamService
|
||||||
|
|
||||||
|
"""
|
||||||
|
airport主程序入口
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print("(♥◠‿◠)ノ゙ AIRPORT【推流服务】开始启动 ლ(´ڡ`ლ)゙")
|
||||||
|
PushStreamService().start_service()
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
from enum import Enum, unique
|
||||||
|
|
||||||
|
|
||||||
|
# 常量枚举
|
||||||
|
@unique
|
||||||
|
class ConstantEnum(Enum):
|
||||||
|
APPLICATION_CONFIG = ("airport_application.yml", "配置文件名称")
|
||||||
|
|
||||||
|
UTF_8 = ("utf-8", "utf-8")
|
||||||
|
|
||||||
|
R = ("r", "可读")
|
||||||
|
|
||||||
|
START_LOG = ("""
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
""", "启动服务LOG")
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,22 @@
|
||||||
|
import time
|
||||||
|
from threading import Thread
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
|
||||||
|
class Common(Thread):
|
||||||
|
|
||||||
|
def __init__(self, timeout, func, args=()):
|
||||||
|
super(Common, self).__init__()
|
||||||
|
self.__timeout = timeout
|
||||||
|
self.__func = func
|
||||||
|
self.__args = args
|
||||||
|
self.__result = None
|
||||||
|
|
||||||
|
def get_result(self):
|
||||||
|
self.join(self.__timeout)
|
||||||
|
return self.__result
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
# logger.info("开始执行线程!")
|
||||||
|
self.__result = self.__func(self.__args)
|
||||||
|
# logger.info("线程停止完成!")
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,13 @@
|
||||||
|
from enum import Enum, unique
|
||||||
|
|
||||||
|
|
||||||
|
# 异常枚举
|
||||||
|
@unique
|
||||||
|
class ExceptionType(Enum):
|
||||||
|
|
||||||
|
PULL_STREAM_URL_EXCEPTION = ("AP000", "拉流地址不能为空!")
|
||||||
|
|
||||||
|
PUSH_STREAM_URL_EXCEPTION = ("AP001", "推流地址不能为空!")
|
||||||
|
|
||||||
|
SERVICE_INNER_EXCEPTION = ("AP999", "系统内部异常, 请联系工程师定位处理!")
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,19 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
自定义异常
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceException(Exception):
|
||||||
|
def __init__(self, code, msg):
|
||||||
|
self.code = code
|
||||||
|
self.msg = msg
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
logger.error("异常编码:{}, 异常描述:{}", self.code, self.msg)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,203 @@
|
||||||
|
2023-01-13 13:12:40.886 [INFO][MainProcess-10664-MainThread-19964][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 13:12:41.894 [INFO][MainProcess-10664-MainThread-19964][38] PushStreamService-start_service - 开始重新获取视频信息: 0次
|
||||||
|
2023-01-13 13:12:49.945 [INFO][MainProcess-10664-MainThread-19964][38] PushStreamService-start_service - 开始重新获取视频信息: 1次
|
||||||
|
2023-01-13 13:12:57.999 [INFO][MainProcess-10664-MainThread-19964][38] PushStreamService-start_service - 开始重新获取视频信息: 2次
|
||||||
|
2023-01-13 15:43:43.762 [INFO][MainProcess-11488-MainThread-5440][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 15:43:44.777 [INFO][MainProcess-11488-MainThread-5440][38] PushStreamService-start_service - 开始重新获取视频信息: 0次
|
||||||
|
2023-01-13 15:43:46.158 [INFO][MainProcess-11488-MainThread-5440][81] Cv2Utils-get_video_info - 视频信息, width:1920|height:1080|fps:25
|
||||||
|
2023-01-13 15:44:00.788 [INFO][MainProcess-11488-MainThread-5440][224] Cv2Utils-read - 关闭拉流管道完成!
|
||||||
|
2023-01-13 15:45:16.962 [INFO][MainProcess-716-MainThread-1284][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 15:45:20.152 [ERROR][MainProcess-716-MainThread-1284][66] PushStreamService-start_service - 推流异常: 'int' object has no attribute 'start_push_stream'
|
||||||
|
2023-01-13 15:45:22.158 [ERROR][MainProcess-716-MainThread-1284][66] PushStreamService-start_service - 推流异常: 'int' object has no attribute 'start_push_stream'
|
||||||
|
2023-01-13 15:45:24.148 [ERROR][MainProcess-716-MainThread-1284][66] PushStreamService-start_service - 推流异常: 'int' object has no attribute 'start_push_stream'
|
||||||
|
2023-01-13 15:45:26.148 [ERROR][MainProcess-716-MainThread-1284][66] PushStreamService-start_service - 推流异常: 'int' object has no attribute 'start_push_stream'
|
||||||
|
2023-01-13 15:45:28.152 [ERROR][MainProcess-716-MainThread-1284][66] PushStreamService-start_service - 推流异常: 'int' object has no attribute 'start_push_stream'
|
||||||
|
2023-01-13 15:46:51.659 [INFO][MainProcess-28372-MainThread-8996][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 15:47:24.687 [INFO][MainProcess-18692-MainThread-32432][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 15:49:25.276 [INFO][MainProcess-28924-MainThread-3700][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 15:49:58.770 [INFO][MainProcess-17768-MainThread-33684][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 15:51:11.366 [INFO][MainProcess-26664-MainThread-22888][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 15:53:22.401 [INFO][MainProcess-20940-MainThread-32656][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 15:56:59.924 [INFO][MainProcess-11316-MainThread-10624][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 15:58:51.358 [INFO][MainProcess-12808-MainThread-30060][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 16:00:13.184 [ERROR][MainProcess-12808-MainThread-30060][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:00:20.227 [ERROR][MainProcess-12808-MainThread-30060][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:00:27.282 [ERROR][MainProcess-12808-MainThread-30060][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:00:34.330 [ERROR][MainProcess-12808-MainThread-30060][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:00:41.379 [ERROR][MainProcess-12808-MainThread-30060][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:00:48.426 [ERROR][MainProcess-12808-MainThread-30060][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:00:55.477 [ERROR][MainProcess-12808-MainThread-30060][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:04:23.859 [ERROR][MainProcess-12808-MainThread-30060][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:07:51.939 [INFO][MainProcess-11556-MainThread-10732][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 16:07:58.992 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:08:06.046 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:08:13.100 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:08:35.323 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:08:42.366 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:08:49.417 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:08:56.464 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:09:54.054 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:10:01.103 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:10:08.159 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:10:15.207 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:10:22.259 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:10:29.304 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:10:36.349 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:10:43.406 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:10:50.448 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:10:57.489 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:11:04.534 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:11:11.586 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:11:18.630 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:11:25.679 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:11:32.727 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:11:39.772 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:11:46.822 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:11:53.870 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:12:00.915 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:12:07.973 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:12:15.023 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:12:22.065 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:12:29.120 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:12:36.174 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:12:43.226 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:12:50.270 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:12:57.321 [ERROR][MainProcess-11556-MainThread-10732][67] PushStreamService-start_service - 推流异常: Command '['ffprobe', '-show_format', '-show_streams', '-of', 'json', 'rtsp://127.0.0.1:8554/video']' timed out after 7 seconds
|
||||||
|
2023-01-13 16:13:04.146 [INFO][MainProcess-21980-MainThread-21248][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 16:13:11.200 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 0次
|
||||||
|
2023-01-13 16:13:19.269 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 1次
|
||||||
|
2023-01-13 16:13:27.331 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 2次
|
||||||
|
2023-01-13 16:13:35.365 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 3次
|
||||||
|
2023-01-13 16:13:43.424 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 4次
|
||||||
|
2023-01-13 16:13:51.475 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 5次
|
||||||
|
2023-01-13 16:13:59.527 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 6次
|
||||||
|
2023-01-13 16:14:07.583 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 7次
|
||||||
|
2023-01-13 16:14:15.629 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 8次
|
||||||
|
2023-01-13 16:14:23.684 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 9次
|
||||||
|
2023-01-13 16:14:31.743 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 10次
|
||||||
|
2023-01-13 16:14:39.801 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 11次
|
||||||
|
2023-01-13 16:14:47.855 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 12次
|
||||||
|
2023-01-13 16:14:55.915 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 13次
|
||||||
|
2023-01-13 16:15:03.975 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 14次
|
||||||
|
2023-01-13 16:15:12.030 [INFO][MainProcess-21980-MainThread-21248][39] PushStreamService-start_service - 开始重新获取视频信息: 15次
|
||||||
|
2023-01-13 16:15:18.469 [INFO][MainProcess-32128-MainThread-26468][27] PushStreamService-start_service -
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
|
||||||
|
2023-01-13 16:15:56.603 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 0次
|
||||||
|
2023-01-13 16:16:04.664 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 1次
|
||||||
|
2023-01-13 16:16:12.728 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 2次
|
||||||
|
2023-01-13 16:16:20.796 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 3次
|
||||||
|
2023-01-13 16:16:28.850 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 4次
|
||||||
|
2023-01-13 16:16:36.923 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 5次
|
||||||
|
2023-01-13 16:16:44.991 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 6次
|
||||||
|
2023-01-13 16:16:53.052 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 7次
|
||||||
|
2023-01-13 16:17:01.101 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 8次
|
||||||
|
2023-01-13 16:17:09.159 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 9次
|
||||||
|
2023-01-13 16:17:17.190 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 10次
|
||||||
|
2023-01-13 16:17:25.240 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 11次
|
||||||
|
2023-01-13 16:17:33.306 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 12次
|
||||||
|
2023-01-13 16:17:41.361 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 13次
|
||||||
|
2023-01-13 16:17:49.413 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 14次
|
||||||
|
2023-01-13 16:17:57.463 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 15次
|
||||||
|
2023-01-13 16:18:05.510 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 16次
|
||||||
|
2023-01-13 16:18:13.558 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 17次
|
||||||
|
2023-01-13 16:18:21.609 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 18次
|
||||||
|
2023-01-13 16:21:03.797 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 19次
|
||||||
|
2023-01-13 16:21:11.858 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 20次
|
||||||
|
2023-01-13 16:21:19.916 [INFO][MainProcess-32128-MainThread-26468][39] PushStreamService-start_service - 开始重新获取视频信息: 21次
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import time
|
||||||
|
|
||||||
|
from alg_airport_ffmpeg.common.Constant import ConstantEnum
|
||||||
|
from alg_airport_ffmpeg.exception.CustomerException import ServiceException
|
||||||
|
from alg_airport_ffmpeg.util import YmlUtils, LogUtils
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
from alg_airport_ffmpeg.util.Cv2Utils import Cv2Util
|
||||||
|
|
||||||
|
'''
|
||||||
|
推流服务
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
class PushStreamService:
|
||||||
|
|
||||||
|
# 初始化
|
||||||
|
def __init__(self):
|
||||||
|
# 获取airport环境所需要的配置
|
||||||
|
self.__content = YmlUtils.get_configs()
|
||||||
|
# 初始化日志
|
||||||
|
LogUtils.init_log(self.__content)
|
||||||
|
|
||||||
|
# 服务调用启动方法
|
||||||
|
def start_service(self):
|
||||||
|
logger.info(ConstantEnum.START_LOG.value[0])
|
||||||
|
# 循环消息处理
|
||||||
|
pull_url = self.__content["video"]["pullUrl"]
|
||||||
|
pushUrl = self.__content["video"]["pushUrl"]
|
||||||
|
cv2_tool = Cv2Util(pull_url, pushUrl)
|
||||||
|
cv2_init_num = 0
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
time1 = time.time()
|
||||||
|
#################################拉流推流一体###################################
|
||||||
|
# 1,检查拉流通道是否有流,没有流7秒后重试
|
||||||
|
if not cv2_tool.is_video_stream(pull_url):
|
||||||
|
logger.info("开始重新获取视频信息: {}次", cv2_init_num)
|
||||||
|
time.sleep(1)
|
||||||
|
cv2_init_num += 1
|
||||||
|
cv2_tool.close_push_stream()
|
||||||
|
continue
|
||||||
|
cv2_init_num = 0
|
||||||
|
# 2. 推流存在跳过,不存在初始化推流
|
||||||
|
cv2_tool.start_push_stream()
|
||||||
|
# 3. 判断推流通道是否有流,进程是否存在
|
||||||
|
if cv2_tool.is_push_stream_ok():
|
||||||
|
cv2_tool.close_push_stream()
|
||||||
|
#################################先拉流再推流###################################
|
||||||
|
# if cv2_tool.check_config():
|
||||||
|
# time.sleep(1)
|
||||||
|
# logger.info("开始重新获取视频信息: {}次", cv2_init_num)
|
||||||
|
# cv2_init_num += 1
|
||||||
|
# # cv2_tool.build_cv2() # 方式1 cv2
|
||||||
|
# cv2_tool.get_video_info() # 方式2 ffmpeg
|
||||||
|
# continue
|
||||||
|
# cv2_init_num = 0
|
||||||
|
# # frame = cv2_tool.cv2_read() # 方式1 cv2
|
||||||
|
# frame = cv2_tool.read() # 方式2 ffmpeg
|
||||||
|
# if frame is None:
|
||||||
|
# continue
|
||||||
|
# cv2_tool.push_stream_write(frame)
|
||||||
|
# print(time.time()- time1)
|
||||||
|
except ServiceException as s:
|
||||||
|
logger.error("推流异常: {}", s.msg)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("推流异常: {}", e)
|
||||||
|
cv2_tool.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,249 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import time
|
||||||
|
import cv2
|
||||||
|
import subprocess as sp
|
||||||
|
|
||||||
|
import ffmpeg
|
||||||
|
import numpy as np
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
获取视频信息
|
||||||
|
'''
|
||||||
|
def get_video_info(pullUrl):
|
||||||
|
try:
|
||||||
|
probe = ffmpeg.probe(pullUrl)
|
||||||
|
if probe is None or probe.get("streams") is None:
|
||||||
|
return
|
||||||
|
# 视频大小
|
||||||
|
# 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("根据拉流地址未获取到视频流")
|
||||||
|
return
|
||||||
|
width = video_stream.get('width')
|
||||||
|
height = video_stream.get('height')
|
||||||
|
nb_frames = video_stream.get('nb_frames')
|
||||||
|
fps = video_stream.get('r_frame_rate')
|
||||||
|
# duration = video_stream.get('duration')
|
||||||
|
bit_rate = video_stream.get('bit_rate')
|
||||||
|
if width:
|
||||||
|
width = int(width)
|
||||||
|
if height:
|
||||||
|
height = int(height)
|
||||||
|
if nb_frames:
|
||||||
|
all_frames = int(nb_frames)
|
||||||
|
if fps:
|
||||||
|
up, down = str(fps).split('/')
|
||||||
|
fps = int(eval(up) / eval(down))
|
||||||
|
# if duration:
|
||||||
|
# self.duration = float(video_stream['duration'])
|
||||||
|
if bit_rate:
|
||||||
|
bit_rate = int(bit_rate) / 1000
|
||||||
|
logger.info("视频信息, width:{}|height:{}|fps:{}|all_frames:{}|bit_rate:{}", width,
|
||||||
|
height, fps, all_frames, bit_rate)
|
||||||
|
except ffmpeg._run.Error as er:
|
||||||
|
logger.error("获取视频信息异常: {}", er.stderr.decode(encoding='utf-8'))
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("获取视频信息异常:{}", e)
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
拉取视频
|
||||||
|
'''
|
||||||
|
def build_pull_p(wh, pullUrl):
|
||||||
|
try:
|
||||||
|
command = [r'E:\liumeiti\ffmpeg\ffmpeg-master-latest-win64-gpl\bin\ffmpeg',
|
||||||
|
'-re',
|
||||||
|
'-y',
|
||||||
|
'-c:v', 'h264_cuvid',
|
||||||
|
'-resize', wh,
|
||||||
|
'-i', pullUrl,
|
||||||
|
'-f', 'rawvideo',
|
||||||
|
'-an',
|
||||||
|
'-']
|
||||||
|
return sp.Popen(command, stdout=sp.PIPE)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("构建拉流管道异常:{}", e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def read(whr, whrz, pullUrl, h, w):
|
||||||
|
result = None
|
||||||
|
try:
|
||||||
|
in_bytes = build_pull_p(whrz, pullUrl).stdout.read(whr)
|
||||||
|
if in_bytes is not None and len(in_bytes) > 0:
|
||||||
|
# result = (np.frombuffer(in_bytes, np.uint8).reshape([int(self.height), int(self.width), 3]))
|
||||||
|
try:
|
||||||
|
img = (np.frombuffer(in_bytes, np.uint8)).reshape((h, w))
|
||||||
|
except Exception as ei:
|
||||||
|
logger.exception("视频格式异常:{}", ei)
|
||||||
|
result = cv2.cvtColor(img, cv2.COLOR_YUV2BGR_NV12)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("读流异常:{}", e)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if self.pull_p:
|
||||||
|
if self.pull_p.stdout:
|
||||||
|
self.pull_p.stdout.close()
|
||||||
|
self.pull_p.terminate()
|
||||||
|
self.pull_p.wait()
|
||||||
|
logger.info("关闭拉流管道完成, requestId:{}", self.requestId)
|
||||||
|
if self.p:
|
||||||
|
if self.p.stdin:
|
||||||
|
self.p.stdin.close()
|
||||||
|
self.p.terminate()
|
||||||
|
self.p.wait()
|
||||||
|
# self.p.communicate()
|
||||||
|
# self.p.kill()
|
||||||
|
logger.info("关闭管道完成, requestId:{}", self.requestId)
|
||||||
|
if self.or_video_file:
|
||||||
|
self.or_video_file.release()
|
||||||
|
logger.info("关闭原视频写入流完成, requestId:{}", self.requestId)
|
||||||
|
if self.ai_video_file:
|
||||||
|
self.ai_video_file.release()
|
||||||
|
logger.info("关闭AI视频写入流完成, requestId:{}", self.requestId)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# async def push_stream_write(self, frame):
|
||||||
|
# self.p.stdin.write(frame.tostring())
|
||||||
|
#
|
||||||
|
# async def push_stream(self, frame):
|
||||||
|
# if self.p is None:
|
||||||
|
# self.build_p()
|
||||||
|
# try:
|
||||||
|
# await self.push_stream_write(frame)
|
||||||
|
# return True
|
||||||
|
# except Exception as ex:
|
||||||
|
# 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:
|
||||||
|
# return False
|
||||||
|
# self.build_p()
|
||||||
|
# await self.push_stream_write(frame)
|
||||||
|
# logger.info("构建p管道重试成功, 当前重试次数: {}, requestId: {}", current_retry_num,
|
||||||
|
# self.requestId)
|
||||||
|
# return True
|
||||||
|
# except Exception as e:
|
||||||
|
# logger.exception("构建p管道异常:{}, 开始重试, 当前重试次数:{}, requestId: {}", e,
|
||||||
|
# current_retry_num, self.requestId)
|
||||||
|
# return False
|
||||||
|
|
||||||
|
# async def video_frame_write(self, or_frame, ai_frame):
|
||||||
|
# if or_frame is not None:
|
||||||
|
# self.or_video_file.write(or_frame)
|
||||||
|
# if ai_frame is not None:
|
||||||
|
# self.ai_video_file.write(ai_frame)
|
||||||
|
|
||||||
|
# async def video_write(self, or_frame, ai_frame):
|
||||||
|
# try:
|
||||||
|
# self.build_write()
|
||||||
|
# if or_frame is not None and len(or_frame) > 0:
|
||||||
|
# await self.video_frame_write(or_frame, None)
|
||||||
|
# if ai_frame is not None and len(ai_frame) > 0:
|
||||||
|
# await self.video_frame_write(None, ai_frame)
|
||||||
|
# return True
|
||||||
|
# except Exception as ex:
|
||||||
|
# ai_retry_num = 0
|
||||||
|
# while True:
|
||||||
|
# try:
|
||||||
|
# ai_retry_num += 1
|
||||||
|
# if ai_retry_num > 3:
|
||||||
|
# logger.exception("重新写入离线分析后视频到本地,重试失败:{}, requestId: {}", e, self.requestId)
|
||||||
|
# return False
|
||||||
|
# if or_frame is not None and len(or_frame) > 0:
|
||||||
|
# await self.or_video_file.write(or_frame)
|
||||||
|
# if ai_frame is not None and len(ai_frame) > 0:
|
||||||
|
# await self.ai_video_file.write(ai_frame)
|
||||||
|
# logger.info("重新写入离线分析后视频到本地, 当前重试次数: {}, requestId: {}", ai_retry_num,
|
||||||
|
# self.requestId)
|
||||||
|
# return True
|
||||||
|
# except Exception as e:
|
||||||
|
# logger.exception("重新写入离线分析后视频到本地:{}, 开始重试, 当前重试次数:{}, requestId: {}", e,
|
||||||
|
# ai_retry_num, self.requestId)
|
||||||
|
|
||||||
|
# def build_write(self):
|
||||||
|
# try:
|
||||||
|
# if self.fps is None or self.width is None or self.height is None:
|
||||||
|
# raise ServiceException(ExceptionType.VIDEO_CONFIG_EXCEPTION.value[0],
|
||||||
|
# ExceptionType.VIDEO_CONFIG_EXCEPTION.value[1])
|
||||||
|
# if self.orFilePath is not None and self.or_video_file is None:
|
||||||
|
# self.or_video_file = cv2.VideoWriter(self.orFilePath, cv2.VideoWriter_fourcc(*'mp4v'), self.fps,
|
||||||
|
# (int(self.wn), int(self.hn)))
|
||||||
|
# if self.or_video_file is None:
|
||||||
|
# raise ServiceException(ExceptionType.OR_WRITE_OBJECT_EXCEPTION.value[0],
|
||||||
|
# ExceptionType.OR_WRITE_OBJECT_EXCEPTION.value[1])
|
||||||
|
# if self.aiFilePath is not None and self.ai_video_file is None:
|
||||||
|
# self.ai_video_file = cv2.VideoWriter(self.aiFilePath, cv2.VideoWriter_fourcc(*'mp4v'), self.fps,
|
||||||
|
# (int(self.width), int(self.hn)))
|
||||||
|
# if self.ai_video_file is None:
|
||||||
|
# raise ServiceException(ExceptionType.AI_WRITE_OBJECT_EXCEPTION.value[0],
|
||||||
|
# ExceptionType.AI_WRITE_OBJECT_EXCEPTION.value[1])
|
||||||
|
# except ServiceException as s:
|
||||||
|
# logger.exception("构建文件写对象异常: {}, requestId:{}", s, self.requestId)
|
||||||
|
# raise s
|
||||||
|
# except Exception as e:
|
||||||
|
# logger.exception("构建文件写对象异常: {}, requestId:{}", e, self.requestId)
|
||||||
|
# raise e
|
||||||
|
|
||||||
|
# def video_merge(self, frame1, frame2):
|
||||||
|
# # frameLeft = cv2.resize(frame1, (int(self.width / 2), int(self.height / 2)), interpolation=cv2.INTER_LINEAR)
|
||||||
|
# # frameRight = cv2.resize(frame2, (int(self.width / 2), int(self.height / 2)), interpolation=cv2.INTER_LINEAR)
|
||||||
|
# # frame_merge = np.hstack((frameLeft, frameRight))
|
||||||
|
# frame_merge = np.hstack((frame1, frame2))
|
||||||
|
# return frame_merge
|
||||||
|
#
|
||||||
|
# def getP(self):
|
||||||
|
# if self.p is None:
|
||||||
|
# logger.error("获取管道为空, requestId:{}", self.requestId)
|
||||||
|
# raise ServiceException(ExceptionType.PULL_PIPELINE_INIT_EXCEPTION.value[0],
|
||||||
|
# ExceptionType.PULL_PIPELINE_INIT_EXCEPTION.value[1])
|
||||||
|
# return self.p
|
||||||
|
#
|
||||||
|
# def getCap(self):
|
||||||
|
# if self.cap is None:
|
||||||
|
# logger.error("获取cv2为空, requestId:{}", self.requestId)
|
||||||
|
# raise ServiceException(ExceptionType.CV2_IS_NULL_EXCEPTION.value[0],
|
||||||
|
# ExceptionType.CV2_IS_NULL_EXCEPTION.value[1])
|
||||||
|
# return self.cap
|
||||||
|
#
|
||||||
|
# def getOrVideoFile(self):
|
||||||
|
# if self.or_video_file is None:
|
||||||
|
# logger.error("获取原视频写入对象为空, requestId:{}", self.requestId)
|
||||||
|
# raise ServiceException(ExceptionType.OR_WRITE_OBJECT_EXCEPTION.value[0],
|
||||||
|
# ExceptionType.OR_WRITE_OBJECT_EXCEPTION.value[1])
|
||||||
|
# return self.or_video_file
|
||||||
|
#
|
||||||
|
# def getAiVideoFile(self):
|
||||||
|
# if self.ai_video_file is None:
|
||||||
|
# logger.error("获取AI视频写入对象为空, requestId:{}", self.requestId)
|
||||||
|
# raise ServiceException(ExceptionType.AI_WRITE_OBJECT_EXCEPTION.value[0],
|
||||||
|
# ExceptionType.AI_WRITE_OBJECT_EXCEPTION.value[1])
|
||||||
|
# return self.ai_video_file
|
||||||
|
if __name__== "__main__":
|
||||||
|
command = ['ffmpeg',
|
||||||
|
'-rtsp_transport', 'tcp',
|
||||||
|
'-i', 'rtsp://127.0.0.1:8554/video', # 指定输入文件
|
||||||
|
'-c', 'copy',
|
||||||
|
'-f', 'flv',
|
||||||
|
"rtmp://192.168.10.101:19350/rlive/stream_9?sign=f8a15b6n"]
|
||||||
|
p = sp.Popen(command, shell=False)
|
||||||
|
while True:
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
print("pid", p.pid)
|
||||||
|
print("poll", p.poll())
|
||||||
|
print("returncode", p.returncode)
|
||||||
|
# p.terminate()
|
||||||
|
# p.wait()
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
|
||||||
|
print("""
|
||||||
|
_ ___ ____ ____ ___ ____ _____
|
||||||
|
/ \ |_ _| _ \| _ \ / _ \| _ \_ _|
|
||||||
|
/ _ \ | || |_) | |_) | | | | |_) || |
|
||||||
|
/ ___ \ | || _ <| __/| |_| | _ < | |
|
||||||
|
/_/ \_\___|_| \_\_| \___/|_| \_\|_|
|
||||||
|
:: AIRPORT SERVICE :: (1.0.0.RELEASE)
|
||||||
|
""")
|
||||||
|
|
@ -0,0 +1,394 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import json
|
||||||
|
import subprocess as sp
|
||||||
|
import time
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
from alg_airport_ffmpeg.enums.ExceptionEnum import ExceptionType
|
||||||
|
from alg_airport_ffmpeg.exception.CustomerException import ServiceException
|
||||||
|
from alg_airport_ffmpeg.concurrency.CommonThread import Common
|
||||||
|
|
||||||
|
"""
|
||||||
|
推流工具
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class Cv2Util:
|
||||||
|
|
||||||
|
def __init__(self, pullUrl=None, pushUrl=None):
|
||||||
|
self.__pullUrl = pullUrl
|
||||||
|
self.__pushUrl = pushUrl
|
||||||
|
self.__push_stream = None
|
||||||
|
self.__pull_stream = None
|
||||||
|
self.__width = None
|
||||||
|
self.__height = None
|
||||||
|
self.__wh = None
|
||||||
|
self.__fps = None
|
||||||
|
self.__cap = None
|
||||||
|
|
||||||
|
def probe(self):
|
||||||
|
p = None
|
||||||
|
try:
|
||||||
|
args = ['ffprobe', '-show_format', '-show_streams', '-of', 'json', self.__pullUrl]
|
||||||
|
p = sp.Popen(args, stdout=sp.PIPE, stderr=sp.PIPE, close_fds=True)
|
||||||
|
out, err = p.communicate(timeout=7)
|
||||||
|
if p.returncode != 0:
|
||||||
|
# logger.error("获取视频信息异常: {}", err.stderr.decode(encoding='utf-8'))
|
||||||
|
return None
|
||||||
|
return json.loads(out.decode('utf-8'))
|
||||||
|
except Exception as e:
|
||||||
|
# logger.error("获取视频信息异常: {}", e)
|
||||||
|
return None
|
||||||
|
finally:
|
||||||
|
if p:
|
||||||
|
# if p.stdout:
|
||||||
|
# p.stdout.flush()
|
||||||
|
# p.stdout.close()
|
||||||
|
# if p.stderr:
|
||||||
|
# p.stderr.close()
|
||||||
|
p.terminate()
|
||||||
|
# parent_proc = psutil.Process(p.pid)
|
||||||
|
# for child_proc in parent_proc.children(recursive=True):
|
||||||
|
# child_proc.kill()
|
||||||
|
# parent_proc.kill()
|
||||||
|
# p.kill()
|
||||||
|
p.wait()
|
||||||
|
# logger.info("关闭获取视频管道完成!")
|
||||||
|
|
||||||
|
# 获取视频信息
|
||||||
|
def get_video_info(self):
|
||||||
|
try:
|
||||||
|
if self.__pullUrl is None or len(self.__pullUrl) == 0:
|
||||||
|
raise ServiceException(ExceptionType.PULL_STREAM_URL_EXCEPTION.value[0],
|
||||||
|
ExceptionType.PULL_STREAM_URL_EXCEPTION.value[1])
|
||||||
|
probe = self.probe()
|
||||||
|
if probe is None or probe.get("streams") is None:
|
||||||
|
return
|
||||||
|
video_stream = next((stream for stream in probe['streams'] if stream.get('codec_type') == 'video'), None)
|
||||||
|
if video_stream is None:
|
||||||
|
return
|
||||||
|
width = video_stream.get('width')
|
||||||
|
height = video_stream.get('height')
|
||||||
|
fps = video_stream.get('r_frame_rate')
|
||||||
|
self.__width = int(width)
|
||||||
|
self.__height = int(height)
|
||||||
|
self.__wh = int(width * height * 3)
|
||||||
|
up, down = str(fps).split('/')
|
||||||
|
self.__fps = int(eval(up) / eval(down))
|
||||||
|
logger.info("视频信息, width:{}|height:{}|fps:{}", self.__width, self.__height, self.__fps)
|
||||||
|
except ServiceException as s:
|
||||||
|
# logger.error("获取视频信息异常: {}", s.msg)
|
||||||
|
raise s
|
||||||
|
except Exception as e:
|
||||||
|
# logger.error("获取视频信息异常:{}", e)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
def build_cap(self, args):
|
||||||
|
try:
|
||||||
|
pullUrl = args[0]
|
||||||
|
return cv2.VideoCapture(pullUrl)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("初始化cap异常: {}", e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 构建 cv2
|
||||||
|
def build_cv2(self):
|
||||||
|
try:
|
||||||
|
if self.__cap is not None:
|
||||||
|
# logger.info("重试, 关闭cap")
|
||||||
|
self.__cap.release()
|
||||||
|
self.__cap = None
|
||||||
|
self.__fps = None
|
||||||
|
self.__width = None
|
||||||
|
self.__height = None
|
||||||
|
if self.__pullUrl is None or len(self.__pullUrl) == 0:
|
||||||
|
raise ServiceException(ExceptionType.PULL_STREAM_URL_EXCEPTION.value[0],
|
||||||
|
ExceptionType.PULL_STREAM_URL_EXCEPTION.value[1])
|
||||||
|
cap_thread = Common(timeout=7, func=self.build_cap, args=(self.__pullUrl,))
|
||||||
|
cap_thread.setDaemon(True)
|
||||||
|
cap_thread.start()
|
||||||
|
self.__cap = cap_thread.get_result()
|
||||||
|
if self.__cap is None:
|
||||||
|
return
|
||||||
|
if self.__cap.isOpened():
|
||||||
|
if self.__fps is None or self.__fps == 0:
|
||||||
|
self.__fps = int(self.__cap.get(cv2.CAP_PROP_FPS))
|
||||||
|
if self.__width is None or self.__width == 0:
|
||||||
|
self.__width = int(self.__cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
||||||
|
if self.__height is None or self.__height == 0:
|
||||||
|
self.__height = int(self.__cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
||||||
|
logger.info("fps:{}|height:{}|width:{}", self.__fps, self.__height, self.__width)
|
||||||
|
except ServiceException as s:
|
||||||
|
logger.error("构建cv2异常: {}", s.msg)
|
||||||
|
raise s
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("初始化cv2异常:{}", e)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
def cv2_read(self):
|
||||||
|
result = None
|
||||||
|
try:
|
||||||
|
if self.__cap is None:
|
||||||
|
self.build_cv2()
|
||||||
|
if self.__cap.isOpened():
|
||||||
|
ret, frame = self.__cap.read()
|
||||||
|
if ret:
|
||||||
|
result = frame
|
||||||
|
del ret
|
||||||
|
del frame
|
||||||
|
except ServiceException as s:
|
||||||
|
raise s
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("读流异常:{}", e)
|
||||||
|
raise e
|
||||||
|
finally:
|
||||||
|
if result is None:
|
||||||
|
self.__fps = None
|
||||||
|
self.__height = None
|
||||||
|
self.__width = None
|
||||||
|
if self.__cap:
|
||||||
|
self.__cap.release()
|
||||||
|
self.__cap = None
|
||||||
|
logger.info("关闭cv2!")
|
||||||
|
return result
|
||||||
|
|
||||||
|
# 拉取视频
|
||||||
|
def build_pull_stream(self):
|
||||||
|
try:
|
||||||
|
if self.__pullUrl is None or len(self.__pullUrl) == 0:
|
||||||
|
logger.error("拉流地址不能为空!")
|
||||||
|
raise ServiceException(ExceptionType.PULL_STREAM_URL_EXCEPTION.value[0],
|
||||||
|
ExceptionType.PULL_STREAM_URL_EXCEPTION.value[1])
|
||||||
|
if self.__pull_stream:
|
||||||
|
logger.info("重试, 关闭拉流管道")
|
||||||
|
if self.__pull_stream.stdout:
|
||||||
|
self.__pull_stream.stdout.close()
|
||||||
|
self.__pull_stream.terminate()
|
||||||
|
self.__pull_stream.wait()
|
||||||
|
command = ['ffmpeg',
|
||||||
|
'-rtsp_transport', 'tcp',
|
||||||
|
'-i', self.__pullUrl,
|
||||||
|
'-f', 'rawvideo',
|
||||||
|
'-pix_fmt', 'bgr24',
|
||||||
|
'-an',
|
||||||
|
'-']
|
||||||
|
# command = ['ffmpeg',
|
||||||
|
# '-re',
|
||||||
|
# '-y',
|
||||||
|
# '-c:v', 'h264_cuvid',
|
||||||
|
# '-resize', self.wah,
|
||||||
|
# '-i', self.pullUrl,
|
||||||
|
# '-f', 'rawvideo',
|
||||||
|
# '-an',
|
||||||
|
# '-']
|
||||||
|
self.__pull_stream = sp.Popen(command, stdout=sp.PIPE)
|
||||||
|
except ServiceException as s:
|
||||||
|
logger.error("构建拉流管道异常: {}", s.msg)
|
||||||
|
raise s
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("构建拉流管道异常:{}", e)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
def check_config(self):
|
||||||
|
if self.__fps is None or self.__width is None or self.__height is None:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def read(self):
|
||||||
|
result = None
|
||||||
|
try:
|
||||||
|
if self.__pull_stream is None:
|
||||||
|
self.build_pull_stream()
|
||||||
|
in_bytes = self.__pull_stream.stdout.read(self.__wh)
|
||||||
|
if in_bytes is not None and len(in_bytes) > 0:
|
||||||
|
result = (np.frombuffer(in_bytes, np.uint8).reshape([int(self.__height), int(self.__width), 3]))
|
||||||
|
except ServiceException as s:
|
||||||
|
raise s
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("读流异常:{}", e)
|
||||||
|
raise e
|
||||||
|
finally:
|
||||||
|
if result is None:
|
||||||
|
self.__fps = None
|
||||||
|
self.__height = None
|
||||||
|
self.__width = None
|
||||||
|
if self.__pull_stream:
|
||||||
|
if self.__pull_stream.stdout:
|
||||||
|
self.__pull_stream.stdout.close()
|
||||||
|
self.__pull_stream.terminate()
|
||||||
|
self.__pull_stream.wait()
|
||||||
|
logger.info("关闭拉流管道完成!")
|
||||||
|
self.__pull_stream = None
|
||||||
|
return result
|
||||||
|
|
||||||
|
# 关闭管道
|
||||||
|
def close(self):
|
||||||
|
if self.__pull_stream:
|
||||||
|
if self.__pull_stream.stdout:
|
||||||
|
self.__pull_stream.stdout.close()
|
||||||
|
self.__pull_stream.terminate()
|
||||||
|
self.__pull_stream.wait()
|
||||||
|
logger.info("关闭拉流管道完成!")
|
||||||
|
if self.__push_stream:
|
||||||
|
if self.__push_stream.stdin:
|
||||||
|
self.__push_stream.stdin.close()
|
||||||
|
self.__push_stream.terminate()
|
||||||
|
self.__push_stream.wait()
|
||||||
|
logger.info("关闭推流管道完成!")
|
||||||
|
if self.__cap:
|
||||||
|
self.__cap.release()
|
||||||
|
|
||||||
|
# 开始推流
|
||||||
|
def build_push_stream(self):
|
||||||
|
try:
|
||||||
|
if self.__push_stream:
|
||||||
|
logger.info("重试, 关闭管道, 重新开启新管道")
|
||||||
|
if self.__push_stream.stdin:
|
||||||
|
self.__push_stream.stdin.close()
|
||||||
|
self.__push_stream.terminate()
|
||||||
|
self.__push_stream.wait()
|
||||||
|
if self.__pushUrl is None or len(self.__pushUrl) == 0:
|
||||||
|
logger.error("推流地址不能为空!")
|
||||||
|
raise ServiceException(ExceptionType.PUSH_STREAM_URL_EXCEPTION.value[0],
|
||||||
|
ExceptionType.PUSH_STREAM_URL_EXCEPTION.value[1])
|
||||||
|
command = ['ffmpeg',
|
||||||
|
# '-loglevel', 'debug',
|
||||||
|
'-f', 'rawvideo',
|
||||||
|
'-vcodec', 'rawvideo',
|
||||||
|
'-pix_fmt', 'bgr24',
|
||||||
|
'-s', "{}x{}".format(int(self.__width), int(self.__height)),
|
||||||
|
'-r', str(self.__fps),
|
||||||
|
'-i', '-',
|
||||||
|
# '-g', str(self.__fps),
|
||||||
|
# '-maxrate', '15000k',
|
||||||
|
# '-minrate', '3000k',
|
||||||
|
# '-profile:v', 'high',
|
||||||
|
# '-level', '5.1',
|
||||||
|
# '-b:v', '4000k',
|
||||||
|
# '-crf', '26',
|
||||||
|
# '-bufsize', '4000k',
|
||||||
|
# '-c:v', 'libx264',
|
||||||
|
# '-tune', 'zerolatency',
|
||||||
|
# '-sc_threshold', '0',
|
||||||
|
# '-pix_fmt', 'yuv420p',
|
||||||
|
# "-an",
|
||||||
|
# '-preset', 'medium', # 指定输出的视频质量,会影响文件的生成速度,有以下几个可用的值 ultrafast,
|
||||||
|
# superfast, veryfast, faster, fast, medium, slow, slower, veryslow。
|
||||||
|
]
|
||||||
|
for url in self.__pushUrl:
|
||||||
|
command.extend(['-f', 'flv',
|
||||||
|
'-g', str(self.__fps),
|
||||||
|
'-maxrate', '15000k',
|
||||||
|
'-minrate', '3000k',
|
||||||
|
'-b:v', '4000k',
|
||||||
|
'-bufsize', '4000k',
|
||||||
|
'-c:v', 'libx264',
|
||||||
|
'-tune', 'zerolatency',
|
||||||
|
'-sc_threshold', '0',
|
||||||
|
'-pix_fmt', 'yuv420p',
|
||||||
|
'-preset', 'fast',
|
||||||
|
"-an", "-y", url
|
||||||
|
])
|
||||||
|
self.__push_stream = sp.Popen(command, stdin=sp.PIPE, shell=False)
|
||||||
|
except ServiceException as s:
|
||||||
|
logger.error("构建推流管道异常: {}", s.msg)
|
||||||
|
raise s
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("初始化推流管道异常:{}", e)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
def push_stream_write(self, frame):
|
||||||
|
try:
|
||||||
|
if self.__push_stream is None:
|
||||||
|
self.build_push_stream()
|
||||||
|
self.__push_stream.stdin.write(frame.tostring())
|
||||||
|
except Exception as ex:
|
||||||
|
logger.error("推流异常:{}", ex)
|
||||||
|
current_retry_num = 0
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
self.build_push_stream()
|
||||||
|
self.__push_stream.stdin.write(frame.tostring())
|
||||||
|
logger.info("推流重试成功, 当前重试次数: {}", current_retry_num)
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
current_retry_num += 1
|
||||||
|
logger.error("推流异常:{}, 开始重试, 当前重试次数:{}", e, current_retry_num)
|
||||||
|
time.sleep(1)
|
||||||
|
if current_retry_num > 1:
|
||||||
|
raise Exception("推流异常,请检查通道是否被占用!")
|
||||||
|
|
||||||
|
def close_push_stream(self):
|
||||||
|
if self.__push_stream:
|
||||||
|
self.__push_stream.terminate()
|
||||||
|
self.__push_stream.wait()
|
||||||
|
self.__push_stream = None
|
||||||
|
|
||||||
|
def is_push_stream_ok(self):
|
||||||
|
if self.__push_stream:
|
||||||
|
if self.__push_stream.poll() is not None:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 开始推流
|
||||||
|
def start_push_stream(self):
|
||||||
|
try:
|
||||||
|
if self.__push_stream:
|
||||||
|
return
|
||||||
|
if self.__pullUrl is None or len(self.__pullUrl) == 0:
|
||||||
|
logger.error("拉流地址不能为空!")
|
||||||
|
raise ServiceException(ExceptionType.PUll_STREAM_URL_EXCEPTION.value[0],
|
||||||
|
ExceptionType.PUll_STREAM_URL_EXCEPTION.value[1])
|
||||||
|
if self.__pushUrl is None or len(self.__pushUrl) == 0:
|
||||||
|
logger.error("推流地址不能为空!")
|
||||||
|
raise ServiceException(ExceptionType.PUSH_STREAM_URL_EXCEPTION.value[0],
|
||||||
|
ExceptionType.PUSH_STREAM_URL_EXCEPTION.value[1])
|
||||||
|
command = ['ffmpeg',
|
||||||
|
'-re',
|
||||||
|
'-rtsp_transport', 'tcp',
|
||||||
|
'-i', self.__pullUrl,
|
||||||
|
]
|
||||||
|
for url in self.__pushUrl:
|
||||||
|
command.extend(['-f', 'flv',
|
||||||
|
'-g', str(25),
|
||||||
|
'-c:v', 'copy',
|
||||||
|
"-an", "-y", url
|
||||||
|
])
|
||||||
|
self.__push_stream = sp.Popen(command, shell=False)
|
||||||
|
except ServiceException as s:
|
||||||
|
logger.error("构建推流管道异常: {}", s.msg)
|
||||||
|
raise s
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("初始化推流管道异常:{}", e)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
def is_video_stream(self, url):
|
||||||
|
p = None
|
||||||
|
try:
|
||||||
|
if url is None or len(url) == 0:
|
||||||
|
raise Exception("流地址不能为空!")
|
||||||
|
args = ['ffprobe', '-show_format', '-show_streams', '-of', 'json', url]
|
||||||
|
p = sp.Popen(args, stdout=sp.PIPE, stderr=sp.PIPE, close_fds=True)
|
||||||
|
out, err = p.communicate(timeout=7)
|
||||||
|
if p.returncode != 0:
|
||||||
|
return False
|
||||||
|
probe = json.loads(out.decode('utf-8'))
|
||||||
|
if probe is None or probe.get("streams") is None:
|
||||||
|
return False
|
||||||
|
video_stream = next((stream for stream in probe['streams'] if stream.get('codec_type') == 'video'), None)
|
||||||
|
if video_stream is None:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
except ServiceException as s:
|
||||||
|
raise s
|
||||||
|
except Exception as e:
|
||||||
|
return False
|
||||||
|
finally:
|
||||||
|
if p:
|
||||||
|
p.terminate()
|
||||||
|
p.wait()
|
||||||
|
p = None
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
|
||||||
|
# 初始化日志配置
|
||||||
|
def init_log(content):
|
||||||
|
if not os.path.exists(content["log"]["base_path"]):
|
||||||
|
os.makedirs(content["log"]["base_path"])
|
||||||
|
# 移除日志设置
|
||||||
|
logger.remove(handler_id=None)
|
||||||
|
# 打印日志到文件
|
||||||
|
if content["log"]["enable_file_log"]:
|
||||||
|
logger.add(content["log"]["base_path"] + content["log"]["log_name"],
|
||||||
|
rotation=content["log"]["rotation"],
|
||||||
|
retention=content["log"]["retention"],
|
||||||
|
format=content["log"]["log_fmt"],
|
||||||
|
level=content["log"]["level"],
|
||||||
|
enqueue=content["log"]["enqueue"],
|
||||||
|
encoding=content["log"]["encoding"])
|
||||||
|
# 控制台输出
|
||||||
|
if content["log"]["enable_stderr"]:
|
||||||
|
logger.add(sys.stderr,
|
||||||
|
format=content["log"]["log_fmt"],
|
||||||
|
level=content["log"]["level"],
|
||||||
|
enqueue=True)
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
import time
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
YY_MM_DD_HH_MM_SS = "%Y-%m-%d %H:%M:%S"
|
||||||
|
YMDHMSF = "%Y%m%d%H%M%S%f"
|
||||||
|
|
||||||
|
|
||||||
|
def generate_timestamp():
|
||||||
|
"""根据当前时间获取时间戳,返回整数"""
|
||||||
|
return int(time.time())
|
||||||
|
|
||||||
|
|
||||||
|
def now_date_to_str(fmt=None):
|
||||||
|
if fmt is None:
|
||||||
|
fmt = YY_MM_DD_HH_MM_SS
|
||||||
|
return datetime.datetime.now().strftime(fmt)
|
||||||
|
|
||||||
|
if __name__=="__main__":
|
||||||
|
print(now_date_to_str(YMDHMSF))
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
from alg_airport_ffmpeg.common.Constant import ConstantEnum
|
||||||
|
|
||||||
|
"""
|
||||||
|
获取配置项信息
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def get_configs():
|
||||||
|
print("开始读取配置文件,获取配置信息:", ConstantEnum.APPLICATION_CONFIG.value[0])
|
||||||
|
config_path = os.path.abspath(ConstantEnum.APPLICATION_CONFIG.value[0])
|
||||||
|
if not os.path.exists(config_path):
|
||||||
|
raise Exception("未找到配置文件:{}".format(ConstantEnum.APPLICATION_CONFIG.value[0]))
|
||||||
|
with open(config_path, ConstantEnum.R.value[0], encoding=ConstantEnum.UTF_8.value[0]) as f:
|
||||||
|
file_content = f.read()
|
||||||
|
content = yaml.load(file_content, yaml.FullLoader)
|
||||||
|
if not content:
|
||||||
|
raise Exception("配置项不能为空:{}".format(ConstantEnum.APPLICATION_CONFIG.value[0]))
|
||||||
|
print("读取配置文件完成!")
|
||||||
|
return content
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue