提交 48089706 authored 作者: lc.zhou's avatar lc.zhou

ils-video-recorder:add redis to save camera callback

上级 0d5fecf0
LAST_CHECK_TIME_KEY = 'hk_isc:recorder:camera:{}' LAST_CHECK_TIME_KEY = 'hk_isc:recorder:camera:{}'
PROCESSING_CAMERA_KEY = 'hk_isc:processing:camera:{}' PROCESSING_CAMERA_KEY = 'hk_isc:processing:camera:{}'
CAMERA_CALLBACK_KEY = 'hk_isc:camera:callback:url:{}'
PROCESSING_TOTAL_KEY = 'hk_isc:recording:processing:total' PROCESSING_TOTAL_KEY = 'hk_isc:recording:processing:total'
ACCOUNT_TOKEN_KEY = 'eviz:account:app_key:{}:token' ACCOUNT_TOKEN_KEY = 'eviz:account:app_key:{}:token'
......
...@@ -13,7 +13,7 @@ from intelab_python_sdk.ffmpeg.ffmpeg_concat import concat ...@@ -13,7 +13,7 @@ from intelab_python_sdk.ffmpeg.ffmpeg_concat import concat
from intelab_python_sdk.ffmpeg.ffmpeg_prune import prune as ffmpeg_prune from intelab_python_sdk.ffmpeg.ffmpeg_prune import prune as ffmpeg_prune
from ils_common_video.db import rabbitmq_connect, redis_connect, influxdb from ils_common_video.db import rabbitmq_connect, redis_connect, influxdb
from ils_common_video.const import PROCESSING_CAMERA_KEY from ils_common_video.const import PROCESSING_CAMERA_KEY,CAMERA_CALLBACK_KEY
from ils_common_video.utils.api_helper import IntelabApiHelper, PlaybackUrlException from ils_common_video.utils.api_helper import IntelabApiHelper, PlaybackUrlException
from ils_common_video.utils.isc_client import HikVisionClient from ils_common_video.utils.isc_client import HikVisionClient
from ils_common_video.utils import aliyun_oss from ils_common_video.utils import aliyun_oss
...@@ -27,6 +27,7 @@ tz = pytz.timezone('Asia/Shanghai') ...@@ -27,6 +27,7 @@ tz = pytz.timezone('Asia/Shanghai')
video_path = '/tmp/videos/isc-record' video_path = '/tmp/videos/isc-record'
os.makedirs(video_path, exist_ok=True) os.makedirs(video_path, exist_ok=True)
# hk_config = dynaconf.settings.get('ISC') # hk_config = dynaconf.settings.get('ISC')
# hik_client = HikVisionClient(str(hk_config.get('KEY')), hk_config.get('SECRET'), # hik_client = HikVisionClient(str(hk_config.get('KEY')), hk_config.get('SECRET'),
# hk_config.get('HOST'), hk_config.get('PORT')) # hk_config.get('HOST'), hk_config.get('PORT'))
...@@ -371,17 +372,27 @@ class ProcessMessage: ...@@ -371,17 +372,27 @@ class ProcessMessage:
:param end_time: 结束时间,上海时区 :param end_time: 结束时间,上海时区
:param part_files_set: :param part_files_set:
""" """
playback_urls = []
res = {'file_name': file_name, 'is_completed': False, 'recovered_time': start_time} res = {'file_name': file_name, 'is_completed': False, 'recovered_time': start_time}
playback_stream = {}
try: try:
hik_client = HikVisionClient(body['hik_app_key'],body['hik_app_secret'], camera_callback_redis_key = CAMERA_CALLBACK_KEY.format(body['camera_code'])
with redis_connect() as pipe:
# 判断缓存中是否存在摄像头回调的信息
if pipe.exists(camera_callback_redis_key):
# 如果存在直接获取
playback_stream = json.loads(pipe.get(camera_callback_redis_key))
else:
# 不存在则调用海康平台接口获取
hik_client = HikVisionClient(body['hik_app_key'], body['hik_app_secret'],
body['hik_req_ip'], body['hik_req_port']) body['hik_req_ip'], body['hik_req_port'])
playback_urls = hik_client.get_cameras_playback_urls( playback_stream = hik_client.get_cameras_playback_urls(
body['camera_index'], body['camera_index'],
IntelabApiHelper.iso_format(start_time), IntelabApiHelper.iso_format(start_time),
IntelabApiHelper.iso_format(end_time) IntelabApiHelper.iso_format(end_time)
) )
if playback_stream:
pipe.set(camera_callback_redis_key, json.dumps(playback_stream), ex=3600 * 12)
except PlaybackUrlException as e: except PlaybackUrlException as e:
res.update({'except': True, 'offline': True, 'remark': e.msg}) res.update({'except': True, 'offline': True, 'remark': e.msg})
except Exception as e: except Exception as e:
...@@ -389,24 +400,18 @@ class ProcessMessage: ...@@ -389,24 +400,18 @@ class ProcessMessage:
res.update({'except': True, 'remark': e.__str__()}) res.update({'except': True, 'remark': e.__str__()})
send_alarm_to_developer('recorder-{}'.format(threading.get_ident()), e) send_alarm_to_developer('recorder-{}'.format(threading.get_ident()), e)
log.info('%s: playback: %s', body['camera_code'], playback_urls) log.info('%s: playback: %s', body['camera_code'], playback_stream)
if not playback_urls:
ProcessMessage.write_retry_info_to_influx(body['camera_code'], res.get('remark'))
playback_urls = []
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: if not playback_stream:
# (大概率情况)海康接口返回的回放视频开始时间是小于事件的开始时间,结束时间是大于事件的结束时间 ProcessMessage.write_retry_info_to_influx(body['camera_code'], res.get('remark'))
# 如果摄像头离线,开关机时 则有可能事件的时间范围在 回放视频的区间外面 else:
start_time = max(start_time, playback_stream['start_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:
log.info('摄像头%s在%s, %s录制未完成', body['camera_code'], start_time, end_time) log.info('摄像头%s在%s, %s录制未完成', body['camera_code'], start_time, end_time)
break
part_files = sorted(list(part_files_set)) part_files = sorted(list(part_files_set))
if len(part_files) > 1: if len(part_files) > 1:
......
...@@ -135,32 +135,41 @@ class HikVisionClient(object): ...@@ -135,32 +135,41 @@ class HikVisionClient(object):
log.info('requests body: {}'.format(body)) log.info('requests body: {}'.format(body))
expired_time = datetime.now() + timedelta(minutes=5) expired_time = datetime.now() + timedelta(minutes=5)
res = self._request(uri, body) res = self._request(uri, body)
events = [] if len(res.get('url')) == 0:
for pre_event in res.get('list') or []: return {}
if pre_event.get('online', 1) == '0': event = {
raise PlaybackUrlException({'message': 'offline', 'code': 404})
start_time = dateutil.parser.parse(pre_event['beginTime'])
end_time = dateutil.parser.parse(pre_event['endTime'])
# 此处有bug 理论上不能进行合并事件,会出现卡帧问题
if len(events) > 0 \
and start_time - events[-1]['end_time'] <= timedelta(seconds=2) \
and events[-1]['end_time'] - events[-1]['start_time'] <= timedelta(hours=0.5):
# 上一个回放视频和当前回放视频时间差<=2秒 且整个回放视频在半小时内 将上一个回放视频的结束时间延伸为当前结束时间
events[-1]['end_time'] = end_time
else:
events.append({
'start_time': start_time,
'end_time': end_time,
'expired_time': expired_time,
'stream_url': { 'stream_url': {
'url': res.get('url'), 'url': res.get('url'),
'extra_args': 'playBackMode=1', 'extra_args': 'playBackMode=1',
'protocol': protocol 'protocol': protocol
} }
}) }
return event
return events # events = []
# for pre_event in res.get('list') or []:
# if pre_event.get('online', 1) == '0':
# raise PlaybackUrlException({'message': 'offline', 'code': 404})
#
# start_time = dateutil.parser.parse(pre_event['beginTime'])
# end_time = dateutil.parser.parse(pre_event['endTime'])
# # 此处有bug 理论上不能进行合并事件,会出现卡帧问题
# if len(events) > 0 \
# and start_time - events[-1]['end_time'] <= timedelta(seconds=2) \
# and events[-1]['end_time'] - events[-1]['start_time'] <= timedelta(hours=0.5):
# # 上一个回放视频和当前回放视频时间差<=2秒 且整个回放视频在半小时内 将上一个回放视频的结束时间延伸为当前结束时间
# events[-1]['end_time'] = end_time
# else:
# events.append({
# 'start_time': start_time,
# 'end_time': end_time,
# 'expired_time': expired_time,
# 'stream_url': {
# 'url': res.get('url'),
# 'extra_args': 'playBackMode=1',
# 'protocol': protocol
# }
# })
# return events
def event_subscription(self, callback): def event_subscription(self, callback):
""" 事件订阅接口 """ 事件订阅接口
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论