Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
I
ils-common-video
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
提交
议题看板
打开侧边栏
OpsTeam
ils-common-video
Commits
09c4d42d
提交
09c4d42d
authored
7月 07, 2021
作者:
zw.wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: [recorder] 检查录制的视频文件,文件存在问题时发送报警
上级
6c0044ef
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
63 行增加
和
49 行删除
+63
-49
recorder.py
isc_video_record/recorder.py
+9
-4
alarm_utils.py
isc_video_record/utils/alarm_utils.py
+8
-9
record_utils.py
isc_video_record/utils/record_utils.py
+45
-35
setup.py
setup.py
+1
-1
没有找到文件。
isc_video_record/recorder.py
浏览文件 @
09c4d42d
...
...
@@ -16,7 +16,7 @@ from isc_video_record.const import PROCESSING_CAMERA_KEY
from
isc_video_record.utils.api_helper
import
IntelabApiHelper
,
PlaybackUrlException
from
isc_video_record.utils.isc_client
import
HikVisionClient
from
isc_video_record.utils
import
aliyun_oss
from
isc_video_record.utils.record_utils
import
record_thread
,
get_video_duration
,
time_to_seconds
from
isc_video_record.utils.record_utils
import
record_thread
,
get_video_duration
,
time_to_seconds
,
judge_video_error
from
isc_video_record.utils.alarm_utils
import
send_alarm_to_developer
from
isc_video_record.db
import
mysql
...
...
@@ -307,7 +307,7 @@ class ProcessMessage:
retry_count
+=
1
complete_duration
=
(
end_time
-
start_time
)
.
total_seconds
()
(
file_info
,
_
)
,
error_log
=
self
.
stream_record
(
playback_stream
[
'stream_url'
],
file_info
,
error_log
=
self
.
stream_record
(
playback_stream
[
'stream_url'
],
start_time
,
end_time
)
if
error_log
:
remark
+=
' '
+
error_log
...
...
@@ -369,9 +369,14 @@ class ProcessMessage:
file_name
=
os
.
path
.
join
(
video_path
,
'rtmp_{}_{}_{}.mp4'
.
format
(
self
.
body
[
'camera_code'
],
start_time
,
end_time
))
log
.
info
(
'
%
s:stream_url:
%
s'
,
self
.
body
[
'camera_code'
],
stream_url
)
# TODO
多进程处理
# TODO
出现ffmpeg进程阻塞的情况
_
,
error_log
=
record_thread
(
stream_url
,
file_name
,
thread_name
=
self
.
body
[
'camera_code'
])
return
get_video_duration
(
file_name
),
error_log
video_info
,
video_error_log
=
judge_video_error
(
file_name
)
# TODO 查看出现损坏的视频发送报警
if
video_error_log
:
send_alarm_to_developer
(
'recorder'
,
'file_name: {}, error_log: {}'
.
format
(
file_name
,
video_error_log
),
mobiles
=
[
'15131601294'
])
return
video_info
,
error_log
@staticmethod
def
write_retry_info_to_influx
(
camera_code
,
error_log
):
...
...
isc_video_record/utils/alarm_utils.py
浏览文件 @
09c4d42d
...
...
@@ -3,20 +3,19 @@ from threading import Thread
from
intelab_python_sdk.dingtalk
import
DingTalkMessage
def
send_alarm_to_developer
(
service_name
,
e
):
def
send_alarm_to_developer
(
service_name
,
e
,
mobiles
=
None
):
config
=
settings
.
get
(
'DINGTALK'
)
mobiles
=
mobiles
or
config
.
get
(
'MOBILES'
)
dingtalk_config
=
settings
.
get
(
'DINGTALK'
)
dingtalk_mobiles
=
dingtalk_config
.
get
(
'MOBILES'
)
dingtalk
=
DingTalkMessage
(
dingtalk_config
.
get
(
'WEBHOOK'
),
dingtalk_config
.
get
(
'SECRET'
))
if
isinstance
(
e
,
Exception
):
import
traceback
content
=
'告警::
\n
{}服务模块出错:
\n
{}'
.
format
(
service_name
,
traceback
.
format_exc
())
else
:
content
=
e
t
=
Thread
(
target
=
dingtalk
.
send_text
,
args
=
(
content
,
dingtalk_mobiles
,
False
))
t
.
start
()
dt
=
DingTalkMessage
(
config
.
get
(
'WEBHOOK'
),
config
.
get
(
'SECRET'
))
Thread
(
target
=
dt
.
send_text
,
args
=
(
content
,
mobiles
,
False
))
.
start
()
def
send_markdown
(
title
,
text
,
mobiles
=
None
):
...
...
isc_video_record/utils/record_utils.py
浏览文件 @
09c4d42d
...
...
@@ -66,41 +66,6 @@ def record_thread(stream_url, out_file, thread_name='ffmpeg-log', protocol='rtmp
return
out_file
,
error_log
def
get_video_duration
(
file_name
):
"""
获取视频文件的持续时间、分辨率等信息
"""
error_log
=
''
duration
=
[
'00:00:00'
]
bitrate
=
[
'0'
]
resolution
=
[
'0x0'
]
media_type
=
'VideoHandler'
size
=
0
log_buffer
=
subprocess
.
getoutput
(
'ffmpeg -i {}'
.
format
(
file_name
))
if
'moov atom not found'
in
log_buffer
:
error_log
+=
log_buffer
duration
=
re
.
findall
(
r'Duration: (\d\d:\d\d:\d\d)\.\d\d'
,
log_buffer
)
or
duration
bitrate
=
re
.
findall
(
r'bitrate: (\d+) kb/s'
,
log_buffer
)
or
bitrate
resolution
=
re
.
findall
(
r'(\d{3,4}x\d{3,4})'
,
log_buffer
)
or
resolution
if
'SoundHandler'
in
log_buffer
:
media_type
+=
'+SoundHandler'
if
os
.
path
.
isfile
(
file_name
):
size
=
os
.
path
.
getsize
(
file_name
)
/
1024.0
/
1024.0
video_info
=
{
'duration'
:
duration
[
0
],
'bitrate'
:
bitrate
[
0
],
'resolution'
:
resolution
[
0
],
'media_type'
:
media_type
,
'file_name'
:
file_name
,
'size'
:
size
}
return
video_info
,
error_log
def
time_to_seconds
(
duration
):
"""
时间字符串转换成秒
...
...
@@ -135,3 +100,48 @@ def get_time_str(seconds):
s
+=
str
(
':
%02
d'
%
seconds
)
return
s
def
judge_video_error
(
file_name
):
"""
:param file_name: 文件路径
:return duration, bitrate, error_log
"""
# 通过ffmpeg打开文件两次判定文件是否花屏
video_info
,
error_log
=
get_video_duration
(
file_name
)
*
_
,
error_log
=
get_video_duration
(
file_name
,
video_info
[
'duration'
])
\
if
not
error_log
else
(
video_info
,
error_log
)
return
video_info
,
error_log
def
get_video_duration
(
file_name
,
start_time
=
'00:00:00'
,
key_word
=
'block unavailable'
):
resolution
,
duration
,
bitrate
,
media_type
=
[
'0x0'
],
[
'00:00:00'
],
[
'0'
],
'VideoHandler'
size
,
error_log
=
0
,
''
log_buffer
=
subprocess
.
getoutput
(
'ffmpeg -y -ss {} -i {} -t 1 -vframes 1 /tmp/tmp.jpg'
.
format
(
start_time
,
file_name
))
if
'moov atom not found'
in
log_buffer
:
error_log
+=
log_buffer
if
'Impossible to open'
in
log_buffer
:
error_log
=
log_buffer
if
key_word
in
log_buffer
:
error_log
=
log_buffer
if
'errors in I frame'
in
log_buffer
:
error_log
+=
log_buffer
duration
=
re
.
findall
(
r'Duration: (\d\d:\d\d:\d\d)\.\d\d'
,
log_buffer
)
or
duration
bitrate
=
re
.
findall
(
r'bitrate: (\d+) kb/s'
,
log_buffer
)
or
bitrate
resolution
=
re
.
findall
(
r'(\d{3,4}x\d{3,4})'
,
log_buffer
)
or
resolution
if
'SoundHandler'
in
log_buffer
:
media_type
+=
'+SoundHandler'
if
os
.
path
.
isfile
(
file_name
):
size
=
os
.
path
.
getsize
(
file_name
)
/
1024.0
/
1024.0
video_info
=
{
'duration'
:
duration
[
0
],
'bitrate'
:
bitrate
[
0
],
'resolution'
:
resolution
[
0
],
'media_type'
:
media_type
,
'file_name'
:
file_name
,
'size'
:
round
(
size
,
2
)
}
return
video_info
,
error_log
setup.py
浏览文件 @
09c4d42d
...
...
@@ -24,7 +24,7 @@ requires = [
setuptools
.
setup
(
name
=
'isc-video-record'
,
version
=
'1.0.0b1
3
'
,
version
=
'1.0.0b1
4
'
,
description
=
'ISC motion detection playback video stream recording service.'
,
long_description
=
long_description
,
long_description_content_type
=
'text/markdown'
,
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论