Ver código fonte

完善云相册代码

zhangdongming 2 anos atrás
pai
commit
7087fda998
1 arquivos alterados com 110 adições e 20 exclusões
  1. 110 20
      Controller/Cron/CloudPhotoController.py

+ 110 - 20
Controller/Cron/CloudPhotoController.py

@@ -8,17 +8,20 @@
 """
 """
 import datetime
 import datetime
 import logging
 import logging
+import os
 import time
 import time
 import traceback
 import traceback
 
 
+import cv2
+from django.db import transaction
 from django.views import View
 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 Model.models import UidSetModel, DeviceCloudPhotoInfo, DevicePicturePushInfo
 from Object.AWS.AmazonS3Util import AmazonS3Util
 from Object.AWS.AmazonS3Util import AmazonS3Util
 from Object.RedisObject import RedisObject
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
+from Object.utils import LocalDateTimeUtil
 from Service.EquipmentInfoService import EquipmentInfoService
 from Service.EquipmentInfoService import EquipmentInfoService
 
 
 LOGGER = logging.getLogger('info')
 LOGGER = logging.getLogger('info')
@@ -43,13 +46,15 @@ class CloudPhotoView(View):
             return self.get_photo(response)
             return self.get_photo(response)
         elif operation == 'cache-uid-set':
         elif operation == 'cache-uid-set':
             return self.cache_photo_uid_set(response)
             return self.cache_photo_uid_set(response)
+        elif operation == 'generate-video':
+            return self.generate_video(response)
         else:
         else:
             return response.json(404)
             return response.json(404)
 
 
     @classmethod
     @classmethod
     def get_photo(cls, response):
     def get_photo(cls, response):
         """
         """
-        定时获取云存消息推送图
+        定时获取设备消息推送图
         """
         """
         try:
         try:
             redis = RedisObject().CONN
             redis = RedisObject().CONN
@@ -58,18 +63,15 @@ class CloudPhotoView(View):
                 return response.json(0)
                 return response.json(0)
             uid_set_cache = list(uid_set_cache)
             uid_set_cache = list(uid_set_cache)
             today = datetime.date.today()
             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())
             now_time = int(time.time())
+            s3 = AmazonS3Util(ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME)
             for item in uid_set_cache:
             for item in uid_set_cache:
                 try:
                 try:
                     eq_qs = EquipmentInfoService.get_equipment_info_model(str(today))
                     eq_qs = EquipmentInfoService.get_equipment_info_model(str(today))
                     item = str(item, encoding="utf-8")
                     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()
                     count = eq_qs.count()
                     page = int(count / 2) if count > 1 else count
                     page = int(count / 2) if count > 1 else count
                     redis.lrem(UID_KEY, item, 0)
                     redis.lrem(UID_KEY, item, 0)
@@ -77,22 +79,17 @@ class CloudPhotoView(View):
                         continue
                         continue
                     eq_qs = eq_qs[(page - 1) * 1:page * 1]
                     eq_qs = eq_qs[(page - 1) * 1:page * 1]
                     eq_vo = eq_qs[0]
                     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'],
                     file_path = '{uid}/{channel}/{event_time}.jpeg'.format(uid=eq_vo['device_uid'],
                                                                            channel=eq_vo['channel'],
                                                                            channel=eq_vo['channel'],
                                                                            event_time=eq_vo['event_time'])
                                                                            event_time=eq_vo['event_time'])
                     s3.copy_obj(PUSH_BUCKET, PUSH_CLOUD_PHOTO, file_path)
                     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)
                     DevicePicturePushInfo.objects.create(**push_data)
                 except Exception as e:
                 except Exception as e:
                     LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
                     LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
                     continue
                     continue
-
             return response.json(0)
             return response.json(0)
         except Exception as e:
         except Exception as e:
             print(e)
             print(e)
@@ -102,8 +99,7 @@ class CloudPhotoView(View):
     @classmethod
     @classmethod
     def cache_photo_uid_set(cls, response):
     def cache_photo_uid_set(cls, response):
         """
         """
-        缓存uid_set
-        @return:
+        缓存uid_set信息
         """
         """
         try:
         try:
             photo_qs = DeviceCloudPhotoInfo.objects.filter(status=1).values('uid')
             photo_qs = DeviceCloudPhotoInfo.objects.filter(status=1).values('uid')
@@ -120,3 +116,97 @@ class CloudPhotoView(View):
             print(e)
             print(e)
             LOGGER.info('--->获取uid_set信息异常:{}'.format(traceback.format_exc()))
             LOGGER.info('--->获取uid_set信息异常:{}'.format(traceback.format_exc()))
             return response.json(177, repr(e))
             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))