import shutil import os from datetime import timedelta import dateutil.parser from intelab_python_sdk.logger import log from intelab_python_sdk.ffmpeg import ffmpeg_capture from ils_common_video.utils.record_utils import get_video_duration, time_to_seconds class VideoFile: def __init__(self, full_path): """ full_path: 文件的全路径 """ self._duration = None self._is_opened = None self._frame = None self.full_path = full_path self.dir_path, self.file_path = os.path.split(full_path) self.file_name, self.postfix = self.file_path.rsplit('.', 1) name_info = self.file_name.split('_') if len(name_info) == 3: # 文件名格式如:G25597998_2021-08-03_11-01-52.mp4 self.sn, self.date, self.time = name_info self.prefix = '' # HD文件名处理 self.sn = self.sn[3:] if 'HDV' in self.sn else self.sn self.start_time = dateutil.parser.parse( ' '.join([self.date, self.time.replace('-', ':')])) elif len(name_info) == 4: # 文件名格式如: EVIZ_G25597998_20210803T110152_20210803T110334.mp4 self.prefix, self.sn, self.start_time_str, self.end_time_str = name_info self.start_time = dateutil.parser.parse(self.start_time_str) self.date, self.time = self.start_time.strftime('%Y-%m-%d'), self.start_time.strftime('%H-%M-%S') else: self.sn = self.date = self.time = None self._duration = self._bitrate = self._resolution = self._media_type = None self._end_time = None self._error_log = '' self.load = False self._picture_path = os.path.join(self.dir_path, self.file_name + '.jpg') self._device_name = '' self.rename = False self.network_quality = 1.0 # 网络质量得分 self._network_quality_grade = '' @property def error_log(self): if not self._error_log and not self.load: self._get_video_info() return self._error_log @property def duration(self): if not self._duration: self._get_video_info() return self._duration @property def bitrate(self): if not self._bitrate: self._get_video_info() return self._bitrate @property def resolution(self): if not self._resolution: self._get_video_info() return self._resolution @property def media_type(self): if not self._media_type: self._get_video_info() return self._media_type @property def end_time(self): if not self._end_time: self._get_video_info() return self._end_time def _get_video_info(self): video_info, self._error_log = get_video_duration(self.full_path) self._duration = time_to_seconds(video_info['duration']) self._bitrate = video_info['bitrate'] self._resolution = video_info['resolution'] self._media_type = video_info['media_type'] self._end_time = self.start_time + timedelta(seconds=self._duration) if self._duration == 7 \ and self._media_type == 'VideoHandler' \ and self._resolution == '512x288': # 时长为7秒且无音频且分辨率为512x288的视频文件为萤石云无效视频 self._error_log = '萤石云无效视频分辨率为512x288' self.load = True @property def network_quality_grade(self): if self.network_quality > 0.95: self._network_quality_grade = '优' elif self.network_quality > 0.20: self._network_quality_grade = '良' else: self._network_quality_grade = '差' return self._network_quality_grade def rename_by_start_time(self, start_time): new_file_name = '{}_{}'.format(self.sn, start_time.strftime('%Y-%m-%d_%H-%M-%S')) full_path = os.path.join(self.dir_path, '{}.{}'.format(new_file_name, self.postfix)) if os.path.isfile(self._picture_path): shutil.move(self._picture_path, os.path.join(self.dir_path, '{}.{}'.format(new_file_name, 'jpg'))) return full_path @property def picture_path(self): if not os.path.exists(self._picture_path): # 如果文件所略图不存在,则打开视频文件,保存一帧 ffmpeg_capture.capture(self.full_path, self._picture_path) return self._picture_path @property def device_name(self): return self._device_name @property def size(self): """ 获取文件大小(M: 兆) K = B / 1024, M = K / 1024, G = M / 1024 """ file_path = self.get_exists_file() size = 0 try: if os.path.isfile(file_path): size = os.path.getsize(file_path) / 1024.0 except Exception as e: log.warning('获取文件%s大小失败!', self.file_name) log.exception(e) return size def get_uploaded_name(self): new_file_file_name = os.path.join(self.dir_path, self.device_name + self.file_path.replace('-', '_')) return new_file_file_name def get_exists_file(self): if os.path.exists(self.full_path): file_path = self.full_path else: uploaded_name = self.get_uploaded_name() if os.path.exists(uploaded_name): file_path = uploaded_name else: file_path = '' log.warning('未获取到文件%s的有效的文件名', self.file_name) return file_path @staticmethod def gen_file_name(camera_code, start_time, end_time, prefix='ISC', part_num=None): elements = [ prefix, camera_code, start_time.strftime('%Y%m%dT%H%M%S'), end_time.strftime('%Y%m%dT%H%M%S') ] if part_num is not None: elements.append(str(part_num)) return '_'.join(elements) + '.mp4' if __name__ == '__main__': video_file = VideoFile('/Users/wen/Downloads/EVIZ_G25597998_20210803T110152_20210803T110334.mp4') # print(video_file.picture_path) print(video_file.duration) print(video_file.size) print(video_file.resolution)