|
@@ -8,17 +8,20 @@
|
|
|
"""
|
|
|
import datetime
|
|
|
import logging
|
|
|
+import os
|
|
|
import time
|
|
|
import traceback
|
|
|
|
|
|
+import cv2
|
|
|
+from django.db import transaction
|
|
|
from django.views import View
|
|
|
|
|
|
-from Ansjer.cn_config.config_formal import PUSH_CLOUD_PHOTO
|
|
|
-from Ansjer.config import ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME, PUSH_BUCKET
|
|
|
+from Ansjer.config import PUSH_CLOUD_PHOTO, ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME, PUSH_BUCKET
|
|
|
from Model.models import UidSetModel, DeviceCloudPhotoInfo, DevicePicturePushInfo
|
|
|
from Object.AWS.AmazonS3Util import AmazonS3Util
|
|
|
from Object.RedisObject import RedisObject
|
|
|
from Object.ResponseObject import ResponseObject
|
|
|
+from Object.utils import LocalDateTimeUtil
|
|
|
from Service.EquipmentInfoService import EquipmentInfoService
|
|
|
|
|
|
LOGGER = logging.getLogger('info')
|
|
@@ -43,13 +46,15 @@ class CloudPhotoView(View):
|
|
|
return self.get_photo(response)
|
|
|
elif operation == 'cache-uid-set':
|
|
|
return self.cache_photo_uid_set(response)
|
|
|
+ elif operation == 'generate-video':
|
|
|
+ return self.generate_video(response)
|
|
|
else:
|
|
|
return response.json(404)
|
|
|
|
|
|
@classmethod
|
|
|
def get_photo(cls, response):
|
|
|
"""
|
|
|
- 定时获取云存消息推送图
|
|
|
+ 定时获取设备消息推送图
|
|
|
"""
|
|
|
try:
|
|
|
redis = RedisObject().CONN
|
|
@@ -58,18 +63,15 @@ class CloudPhotoView(View):
|
|
|
return response.json(0)
|
|
|
uid_set_cache = list(uid_set_cache)
|
|
|
today = datetime.date.today()
|
|
|
- start_time = "{} 00:00:00".format(str(today))
|
|
|
- # 先转换为时间数组
|
|
|
- timeArray = time.strptime(start_time, "%Y-%m-%d %H:%M:%S")
|
|
|
- # 转换为时间戳
|
|
|
- timeStamp = int(time.mktime(timeArray))
|
|
|
+ time_stamp = cls.get_month_stamp()
|
|
|
now_time = int(time.time())
|
|
|
+ s3 = AmazonS3Util(ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME)
|
|
|
for item in uid_set_cache:
|
|
|
try:
|
|
|
eq_qs = EquipmentInfoService.get_equipment_info_model(str(today))
|
|
|
item = str(item, encoding="utf-8")
|
|
|
- eq_qs = eq_qs.filter(event_time__gt=timeStamp, is_st=1, device_uid=item) \
|
|
|
- .values('device_uid', 'channel', 'event_time')
|
|
|
+ eq_qs = eq_qs.filter(event_time__gt=time_stamp, is_st=1, device_uid=item) \
|
|
|
+ .values('device_uid', 'channel', 'event_time', 'device_nick_name')
|
|
|
count = eq_qs.count()
|
|
|
page = int(count / 2) if count > 1 else count
|
|
|
redis.lrem(UID_KEY, item, 0)
|
|
@@ -77,22 +79,17 @@ class CloudPhotoView(View):
|
|
|
continue
|
|
|
eq_qs = eq_qs[(page - 1) * 1:page * 1]
|
|
|
eq_vo = eq_qs[0]
|
|
|
- s3 = AmazonS3Util(
|
|
|
- aws_access_key_id=ACCESS_KEY_ID,
|
|
|
- secret_access_key=SECRET_ACCESS_KEY,
|
|
|
- region_name=REGION_NAME
|
|
|
- )
|
|
|
file_path = '{uid}/{channel}/{event_time}.jpeg'.format(uid=eq_vo['device_uid'],
|
|
|
channel=eq_vo['channel'],
|
|
|
event_time=eq_vo['event_time'])
|
|
|
s3.copy_obj(PUSH_BUCKET, PUSH_CLOUD_PHOTO, file_path)
|
|
|
- push_data = {'type': 1, 'uid': eq_vo['device_uid'], 'channel': eq_vo['channel'],
|
|
|
- 'event_time': eq_vo['event_time'], 'updated_time': now_time, 'created_time': now_time}
|
|
|
+ push_data = {'type': 0, 'uid': eq_vo['device_uid'], 'channel': eq_vo['channel'],
|
|
|
+ 'event_time': eq_vo['event_time'], 'updated_time': now_time, 'created_time': now_time,
|
|
|
+ 'device_nick_name': eq_vo['device_nick_name']}
|
|
|
DevicePicturePushInfo.objects.create(**push_data)
|
|
|
except Exception as e:
|
|
|
LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
|
|
|
continue
|
|
|
-
|
|
|
return response.json(0)
|
|
|
except Exception as e:
|
|
|
print(e)
|
|
@@ -102,8 +99,7 @@ class CloudPhotoView(View):
|
|
|
@classmethod
|
|
|
def cache_photo_uid_set(cls, response):
|
|
|
"""
|
|
|
- 缓存uid_set
|
|
|
- @return:
|
|
|
+ 缓存uid_set信息
|
|
|
"""
|
|
|
try:
|
|
|
photo_qs = DeviceCloudPhotoInfo.objects.filter(status=1).values('uid')
|
|
@@ -120,3 +116,97 @@ class CloudPhotoView(View):
|
|
|
print(e)
|
|
|
LOGGER.info('--->获取uid_set信息异常:{}'.format(traceback.format_exc()))
|
|
|
return response.json(177, repr(e))
|
|
|
+
|
|
|
+ @classmethod
|
|
|
+ def generate_video(cls, response):
|
|
|
+ """
|
|
|
+ 生成视频并存库
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ photo_qs = DeviceCloudPhotoInfo.objects.filter(status=1).values('uid', 'user_id')
|
|
|
+ if not photo_qs.exists():
|
|
|
+ return response.json(0)
|
|
|
+ # 获取当前项目路径
|
|
|
+ poj_path = os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
|
|
|
+ time_stamp = cls.get_month_stamp()
|
|
|
+ s3 = AmazonS3Util(ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME)
|
|
|
+ now_time = int(time.time())
|
|
|
+ for item in photo_qs:
|
|
|
+ try:
|
|
|
+ with transaction.atomic():
|
|
|
+ picture_qs = DevicePicturePushInfo.objects.filter(uid=item['uid'], event_time__gt=time_stamp,
|
|
|
+ type=0) \
|
|
|
+ .values('uid', 'channel', 'event_time', 'device_nick_name')
|
|
|
+ if not picture_qs.exists():
|
|
|
+ continue
|
|
|
+ device_nickname = picture_qs[0]['device_nick_name']
|
|
|
+ pic_list = cls.download_push_picture(s3, item['uid'], poj_path, picture_qs)
|
|
|
+ video_path = poj_path + r'\Ansjer\file\video.mp4' # 输出视频的保存路径
|
|
|
+ cls.picture_synthesis_video(video_path, poj_path, pic_list) # 图片合成视频
|
|
|
+ video_name = datetime.datetime.now().strftime('%Y%m')
|
|
|
+ data = open(video_path, 'rb')
|
|
|
+ key = '{}/video/{}.mp4'.format(item['uid'], video_name)
|
|
|
+ s3.upload_file_obj(PUSH_CLOUD_PHOTO, key, data) # 将视频资源上传至S3保存
|
|
|
+ os.remove(video_path) # 上传完成删除本地资源
|
|
|
+ push_data = {'type': 1, 'uid': item['uid'], 'channel': 1,
|
|
|
+ 'event_time': int(video_name), 'updated_time': now_time, 'created_time': now_time,
|
|
|
+ 'device_nick_name': device_nickname, 'user_id': item['user_id']}
|
|
|
+ DevicePicturePushInfo.objects.create(**push_data)
|
|
|
+ except Exception as e:
|
|
|
+ LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
|
|
|
+ continue
|
|
|
+ return response.json(0)
|
|
|
+ except Exception as e:
|
|
|
+ print(e)
|
|
|
+ LOGGER.info('--->图片合成视频异常:{}'.format(traceback.format_exc()))
|
|
|
+ return response.json(177)
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def download_push_picture(s3, uid, dir_url, picture_qs):
|
|
|
+ """
|
|
|
+ 下载推送图片,讲下载资源保存到项目本地
|
|
|
+ @param s3: s3对象
|
|
|
+ @param uid: 设备uid
|
|
|
+ @param dir_url: 项目文件路径
|
|
|
+ @param picture_qs: 消息推送图片对象
|
|
|
+ @return: pic_list 图片文件名集合
|
|
|
+ """
|
|
|
+ pic_list = []
|
|
|
+ for pic in picture_qs:
|
|
|
+ path = dir_url + r'\Ansjer\file\{}.jpeg'.format(pic['event_time'])
|
|
|
+ s3_key = '{}/{}/{}.jpeg'.format(uid, pic['channel'], pic['event_time'])
|
|
|
+ s3.download_object(PUSH_CLOUD_PHOTO, s3_key, path)
|
|
|
+ pic_list.append('{}.jpeg'.format(pic['event_time']))
|
|
|
+ return pic_list
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def picture_synthesis_video(video_path, poj_path, pic_list):
|
|
|
+ """
|
|
|
+ 图片合成视频
|
|
|
+ @param video_path: 输出视频的保存路径
|
|
|
+ @param poj_path: 项目路径
|
|
|
+ @param pic_list: 图片文件名集合
|
|
|
+ @return:
|
|
|
+ """
|
|
|
+ fps = 0.5 # 帧率
|
|
|
+ img_size = (1920, 1080) # 图片尺寸
|
|
|
+ fourcc = cv2.VideoWriter_fourcc(*"mp4v")
|
|
|
+ video_writer = cv2.VideoWriter(video_path, fourcc, fps, img_size)
|
|
|
+ for item in pic_list:
|
|
|
+ img_path = poj_path + r'\Ansjer\file\{}'.format(item)
|
|
|
+ frame = cv2.imread(img_path)
|
|
|
+ frame = cv2.resize(frame, img_size) # 生成视频 图片尺寸和设定尺寸相同
|
|
|
+ video_writer.write(frame) # 将图片写进视频里
|
|
|
+ os.remove(img_path)
|
|
|
+ video_writer.release() # 释放资源
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def get_month_stamp():
|
|
|
+ """
|
|
|
+ 获取当月开始时间戳
|
|
|
+ """
|
|
|
+ now_month = LocalDateTimeUtil.get_cur_month_start()
|
|
|
+ start_time = "{} 00:00:00".format(str(now_month))
|
|
|
+ time_array = time.strptime(start_time, "%Y-%m-%d %H:%M:%S")
|
|
|
+ # 转换为时间戳
|
|
|
+ return int(time.mktime(time_array))
|