Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
I
ils-common-video
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
提交
议题看板
打开侧边栏
OpsTeam
ils-common-video
Commits
be452d94
提交
be452d94
authored
8月 27, 2021
作者:
lc.zhou
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ils-video-record:isc录制视频注释添加
上级
74168dce
显示空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
14 行增加
和
3 行删除
+14
-3
recorder.py
ils_common_video/isc_video/recorder.py
+12
-3
isc_client.py
ils_common_video/utils/isc_client.py
+2
-0
没有找到文件。
ils_common_video/isc_video/recorder.py
浏览文件 @
be452d94
...
@@ -64,6 +64,7 @@ class StreamRecorder:
...
@@ -64,6 +64,7 @@ class StreamRecorder:
try
:
try
:
if
pipe
.
set
(
camera_key
,
thread_id
,
nx
=
True
,
ex
=
100
):
if
pipe
.
set
(
camera_key
,
thread_id
,
nx
=
True
,
ex
=
100
):
log
.
info
(
'setnx:
%
s:ttl:100'
,
camera_key
)
log
.
info
(
'setnx:
%
s:ttl:100'
,
camera_key
)
# 针对当前摄像头开始录制
ack
=
ProcessMessage
.
process
(
body
,
camera_key
)
ack
=
ProcessMessage
.
process
(
body
,
camera_key
)
else
:
else
:
log
.
info
(
'camera_code[
%
s] processing, end.'
,
body
[
'camera_code'
])
log
.
info
(
'camera_code[
%
s] processing, end.'
,
body
[
'camera_code'
])
...
@@ -152,6 +153,7 @@ class ProcessMessage:
...
@@ -152,6 +153,7 @@ class ProcessMessage:
if
ProcessMessage
.
set_expired_time
(
camera_key
,
expired_time
,
thread_id
):
if
ProcessMessage
.
set_expired_time
(
camera_key
,
expired_time
,
thread_id
):
# 续约成功,本次任务继续
# 续约成功,本次任务继续
mysql
.
update_video_info
(
body
[
'db_table'
],
event
[
'video_id'
],
status
=
0
)
mysql
.
update_video_info
(
body
[
'db_table'
],
event
[
'video_id'
],
status
=
0
)
# 开始摄像头录制
ProcessMessage
.
recording
(
body
,
event
)
ProcessMessage
.
recording
(
body
,
event
)
else
:
else
:
log
.
info
(
'
%
s, expire failed'
,
camera_key
)
log
.
info
(
'
%
s, expire failed'
,
camera_key
)
...
@@ -180,6 +182,8 @@ class ProcessMessage:
...
@@ -180,6 +182,8 @@ class ProcessMessage:
def
recording
(
body
,
event
):
def
recording
(
body
,
event
):
part_files_set
=
set
()
part_files_set
=
set
()
if
event
[
'recovered_time'
]
and
event
[
'recovered_time'
]
!=
event
[
'start_time'
]:
if
event
[
'recovered_time'
]
and
event
[
'recovered_time'
]
!=
event
[
'start_time'
]:
# 如果恢复时间存在且不等于开始时间 那么说明该视频录制中断过
# 生成文件名称
part_file_name
=
ProcessMessage
.
gen_file_name
(
part_file_name
=
ProcessMessage
.
gen_file_name
(
body
[
'camera_code'
],
event
[
'start_time'
],
event
[
'recovered_time'
],
part_num
=
0
)
body
[
'camera_code'
],
event
[
'start_time'
],
event
[
'recovered_time'
],
part_num
=
0
)
...
@@ -239,7 +243,7 @@ class ProcessMessage:
...
@@ -239,7 +243,7 @@ class ProcessMessage:
remark
=
(
remark
or
'start'
)
+
'+offline'
remark
=
(
remark
or
'start'
)
+
'+offline'
elif
record_result
.
get
(
'is_completed'
):
elif
record_result
.
get
(
'is_completed'
):
log
.
info
(
'
%
s:
%
s is completed.'
,
event
[
'camera_code'
],
record_result
[
'file_name'
])
log
.
info
(
'
%
s:
%
s is completed.'
,
event
[
'camera_code'
],
record_result
[
'file_name'
])
status
=
5
# 录制完成的视频状态为5
status
=
5
# 录制完成的视频状态为5
(还未被filter分析)
else
:
else
:
next_retry_time
=
now
+
timedelta
(
minutes
=
10
)
next_retry_time
=
now
+
timedelta
(
minutes
=
10
)
retry_count
+=
1
retry_count
+=
1
...
@@ -327,7 +331,6 @@ class ProcessMessage:
...
@@ -327,7 +331,6 @@ class ProcessMessage:
# 重试六次
# 重试六次
retry_count
+=
1
retry_count
+=
1
complete_duration
=
(
end_time
-
start_time
)
.
total_seconds
()
complete_duration
=
(
end_time
-
start_time
)
.
total_seconds
()
file_info
,
error_log
=
ProcessMessage
.
stream_record
(
body
,
playback_stream
[
'stream_url'
],
file_info
,
error_log
=
ProcessMessage
.
stream_record
(
body
,
playback_stream
[
'stream_url'
],
start_time
,
end_time
)
start_time
,
end_time
)
if
error_log
:
if
error_log
:
...
@@ -392,8 +395,11 @@ class ProcessMessage:
...
@@ -392,8 +395,11 @@ class ProcessMessage:
is_completed
,
recovered_time
,
retry_info
=
False
,
start_time
,
{}
is_completed
,
recovered_time
,
retry_info
=
False
,
start_time
,
{}
part_files_set
=
part_files_set
or
set
()
part_files_set
=
part_files_set
or
set
()
for
playback_stream
in
playback_urls
:
for
playback_stream
in
playback_urls
:
# (大概率情况)海康接口返回的回放视频开始时间是小于事件的开始时间,结束时间是大于事件的结束时间
# 如果摄像头离线,开关机时 则有可能事件的时间范围在 回放视频的区间外面
start_time
=
max
(
start_time
,
playback_stream
[
'start_time'
])
start_time
=
max
(
start_time
,
playback_stream
[
'start_time'
])
end_time
=
min
(
end_time
,
playback_stream
[
'end_time'
])
end_time
=
min
(
end_time
,
playback_stream
[
'end_time'
])
# 视频流转为视频
recovered_time
,
is_completed
,
retry_info
=
ProcessMessage
.
stream_to_video
(
recovered_time
,
is_completed
,
retry_info
=
ProcessMessage
.
stream_to_video
(
body
,
playback_stream
,
start_time
,
end_time
,
part_files_set
)
body
,
playback_stream
,
start_time
,
end_time
,
part_files_set
)
if
not
is_completed
:
if
not
is_completed
:
...
@@ -422,7 +428,6 @@ class ProcessMessage:
...
@@ -422,7 +428,6 @@ class ProcessMessage:
@staticmethod
@staticmethod
def
stream_record
(
body
,
stream
,
start_time
,
end_time
):
def
stream_record
(
body
,
stream
,
start_time
,
end_time
):
if
stream
[
'protocol'
]
==
'rtsp'
:
if
stream
[
'protocol'
]
==
'rtsp'
:
stream_url
=
stream
[
'url'
]
stream_url
=
stream
[
'url'
]
else
:
else
:
...
@@ -432,13 +437,17 @@ class ProcessMessage:
...
@@ -432,13 +437,17 @@ class ProcessMessage:
file_name
=
ProcessMessage
.
gen_file_name
(
body
[
'camera_code'
],
start_time
,
end_time
,
prefix
=
'rtmp'
)
file_name
=
ProcessMessage
.
gen_file_name
(
body
[
'camera_code'
],
start_time
,
end_time
,
prefix
=
'rtmp'
)
log
.
info
(
'
%
s:stream_url:
%
s'
,
body
[
'camera_code'
],
stream_url
)
log
.
info
(
'
%
s:stream_url:
%
s'
,
body
[
'camera_code'
],
stream_url
)
# TODO 出现ffmpeg进程阻塞的情况
# TODO 出现ffmpeg进程阻塞的情况
# 1.开启视频的录制
_
,
error_log
=
record_thread
(
stream_url
,
file_name
,
thread_name
=
body
[
'camera_code'
])
_
,
error_log
=
record_thread
(
stream_url
,
file_name
,
thread_name
=
body
[
'camera_code'
])
# 2.判断视频是否损坏
video_info
,
video_error_log
=
judge_video_error
(
file_name
)
video_info
,
video_error_log
=
judge_video_error
(
file_name
)
# 3.裁剪视频或者删除文件
if
video_error_log
:
if
video_error_log
:
log
.
warning
(
'file:
%
s, error_log:
%
s'
,
file_name
,
video_error_log
)
log
.
warning
(
'file:
%
s, error_log:
%
s'
,
file_name
,
video_error_log
)
video_duration
=
time_to_seconds
(
video_info
[
'duration'
])
video_duration
=
time_to_seconds
(
video_info
[
'duration'
])
if
video_duration
>
5
:
if
video_duration
>
5
:
tmp_file_name
=
file_name
+
'.tmp.mp4'
tmp_file_name
=
file_name
+
'.tmp.mp4'
# 通过ffmpeg裁剪最后5秒的视频
ffmpeg_prune
(
file_name
,
file_name
,
duration
=
video_duration
-
5
)
ffmpeg_prune
(
file_name
,
file_name
,
duration
=
video_duration
-
5
)
if
os
.
path
.
isfile
(
tmp_file_name
):
if
os
.
path
.
isfile
(
tmp_file_name
):
shutil
.
move
(
tmp_file_name
,
file_name
)
shutil
.
move
(
tmp_file_name
,
file_name
)
...
...
ils_common_video/utils/isc_client.py
浏览文件 @
be452d94
...
@@ -142,9 +142,11 @@ class HikVisionClient(object):
...
@@ -142,9 +142,11 @@ class HikVisionClient(object):
start_time
=
dateutil
.
parser
.
parse
(
pre_event
[
'beginTime'
])
start_time
=
dateutil
.
parser
.
parse
(
pre_event
[
'beginTime'
])
end_time
=
dateutil
.
parser
.
parse
(
pre_event
[
'endTime'
])
end_time
=
dateutil
.
parser
.
parse
(
pre_event
[
'endTime'
])
# 此处有bug 理论上不能进行合并事件,会出现卡帧问题
if
len
(
events
)
>
0
\
if
len
(
events
)
>
0
\
and
start_time
-
events
[
-
1
][
'end_time'
]
<=
timedelta
(
seconds
=
2
)
\
and
start_time
-
events
[
-
1
][
'end_time'
]
<=
timedelta
(
seconds
=
2
)
\
and
events
[
-
1
][
'end_time'
]
-
events
[
-
1
][
'start_time'
]
<=
timedelta
(
hours
=
0.5
):
and
events
[
-
1
][
'end_time'
]
-
events
[
-
1
][
'start_time'
]
<=
timedelta
(
hours
=
0.5
):
# 上一个回放视频和当前回放视频时间差<=2秒 且整个回放视频在半小时内 将上一个回放视频的结束时间延伸为当前结束时间
events
[
-
1
][
'end_time'
]
=
end_time
events
[
-
1
][
'end_time'
]
=
end_time
else
:
else
:
events
.
append
({
events
.
append
({
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论