diff --git a/短视频合成自动化/draft.py b/短视频合成自动化/draft.py index b9cb542..fbbaa84 100644 --- a/短视频合成自动化/draft.py +++ b/短视频合成自动化/draft.py @@ -21,8 +21,6 @@ class JianYingDraft: 6、将草稿保存至剪映草稿文件夹内 """ - # pylint: disable=too-many-arguments - # pylint: disable=too-many-positional-arguments def __init__( self, drafts_folder: pyJianYingDraft.DraftFolder, @@ -122,7 +120,6 @@ class JianYingDraft: text_segment.add_bubble(**bubble) # 添加花字 - # pylint: disable=line-too-long # 将花字保存预设后在C:/Users/admin/AppData/Local/JianyingPro/User Data/Presets/Text_V2/预设文本?.textpreset获取花字resource_id if effect: text_segment.add_effect(**effect) @@ -319,7 +316,6 @@ class JianYingDraft: ) # 构建贴纸 - # pylint: disable=line-too-long # 将贴纸保存为我的预设后在C:\Users\admin\AppData\Local\JianyingPro\User Data\Presets\Combination\Presets\我的预设?\preset_draft获取 sticker_segment = pyJianYingDraft.StickerSegment( resource_id=resource_id, @@ -350,7 +346,7 @@ class JianYingDraft: rate: str = "+25%", volume: str = "+0%", font: Optional[str] = None, - style: Optional[Dict[str, Any]] = None, + style: Optional[Dict[str, Any]] = {"size": 12.0, "align": "center"}, clip_settings: Optional[Dict[str, Any]] = None, effect: Optional[Dict[str, Any]] = None, ): @@ -402,7 +398,7 @@ class JianYingDraft: **(style or {}), }, clip_settings={ - "transform_y": -0.75, + "transform_y": -0.6, **(clip_settings or {}), }, effect=effect, diff --git a/短视频合成自动化/export.py b/短视频合成自动化/export.py index 2a802ae..f87acdb 100644 --- a/短视频合成自动化/export.py +++ b/短视频合成自动化/export.py @@ -3,15 +3,19 @@ 导出草稿模块 """ +from copy import deepcopy +import json +from pathlib import Path import random +import re import subprocess import time -from pathlib import Path from typing import Any, Dict, Optional import pyJianYingDraft import win32con import win32gui + from draft import JianYingDraft @@ -25,8 +29,6 @@ class JianYingExport: 3、导出草稿 """ - # pylint: disable=too-many-arguments - # pylint: disable=too-many-positional-arguments def __init__( self, materials_folder_path: str, @@ -72,7 +74,7 @@ class JianYingExport: self.exports_folder_path = Path( self.materials_folder_path.as_posix().replace("materials", "exports") ) - self.exports_folder_path.mkdir() # 若导出文件夹存在则抛出异常,需手动处理 + # self.exports_folder_path.mkdir() # 若导出文件夹存在则抛出异常,需手动处理 self.materials = {} # 初始化素材文件夹内所有素材 @@ -106,6 +108,9 @@ class JianYingExport: {"size": 10.0}, {"size": 11.0}, ], # 字体样式 + "keywords": [ + "瑞幸", + ], # 关键词 "effect": [ {"effect_id": "7127561998556089631"}, {"effect_id": "7166467215410187552"}, @@ -120,71 +125,13 @@ class JianYingExport: ], # 花字设置 }, # 添加字幕工作配置 "add_background_video": { - "track_name": ["background_video"], "material_path": self.materials["background_video_material_path"], "volume": [0.3, 0.4, 0.5], "clip_settings": [ None, - { - "transform_x": 0.1, - }, - { - "transform_x": 0.2, - }, - { - "transform_x": -0.1, - }, - { - "transform_x": -0.2, - }, - { - "transform_y": 0.1, - }, - { - "transform_y": 0.2, - }, - { - "transform_y": -0.1, - }, - { - "transform_y": -0.2, - }, - { - "transform_x": 0.1, - "transform_y": 0.1, - }, - { - "transform_x": 0.1, - "transform_y": -0.1, - }, - { - "transform_x": -0.1, - "transform_y": 0.1, - }, - { - "transform_x": -0.1, - "transform_y": -0.1, - }, - { - "transform_x": 0.2, - "transform_y": 0.2, - }, - { - "transform_x": 0.2, - "transform_y": -0.2, - }, - { - "transform_x": -0.2, - "transform_y": 0.2, - }, - { - "transform_x": -0.2, - "transform_y": -0.2, - }, ], # 图像调节设置 }, # 添加背景视频工作配置 "add_logo": { - "track_name": ["logo"], "material_path": self.materials["logo_material_path"], "clip_settings": [ { @@ -220,19 +167,18 @@ class JianYingExport: ], }, # 添加标识工作配置 "add_statement": { - "track_name": ["statement"], "text": self.materials["statement_text"], "style": [ + {"size": 5.0, "align": 1, "vertical": True}, {"size": 6.0, "align": 1, "vertical": True}, {"size": 7.0, "align": 1, "vertical": True}, - {"size": 8.0, "align": 1, "vertical": True}, ], # 文本样式 "border": [ + {"width": 35.0}, {"width": 40.0}, - {"width": 44.0}, + {"width": 45.0}, {"width": 50.0}, {"width": 55.0}, - {"width": 60.0}, ], # 描边宽度 "clip_settings": [ { @@ -247,7 +193,6 @@ class JianYingExport: ], # 图像调节设置 }, # 添加声明工作配置 "add_sticker1": { - "track_name": ["sticker1"], "resource_id": [ "7110124379568098568", "7019687632804334861", @@ -286,7 +231,6 @@ class JianYingExport: ], # 图像调节设置 }, # 添加贴纸工作配置1(不包含箭头类) "add_sticker2": { - "track_name": ["sticker2"], "resource_id": [ "7143078914989018379", "7142870400358255905", @@ -370,8 +314,9 @@ class JianYingExport: 导出草稿 :param batch_draft_counts: 每批次导出草稿数 """ - # 按照工作流和工作配置拼接素材,生成草稿 - self._generate() + # 按照工作流和工作配置拼接素材,批量生成草稿 + self._generate_drafts() + exit() # 批次导出 for batch_start in range(0, self.draft_counts, batch_draft_counts): @@ -409,11 +354,11 @@ class JianYingExport: self.drafts_folder.remove(draft_name=draft_name) time.sleep(2) - def _generate( + def _generate_drafts( self, ) -> None: """ - 按照工作流和工作配置拼接素材,生成草稿 + 按照工作流和工作配置拼接素材,批量生成草稿 :return: 无 """ for idx in range(self.draft_counts): @@ -434,27 +379,27 @@ class JianYingExport: match work: case "add_subtitles": print("-> 正在添加字幕...", end="") - draft.add_subtitles(**self._random(work=work)) + draft.add_subtitles(**self._get_parameters(work=work)) print("已完成") # 添加背景视频 case "add_background_video": print("-> 正在添加背景视频...", end="") - draft.add_video_segment(**self._random(work=work)) + draft.add_video_segment(**self._get_parameters(work=work)) print("已完成") # 添加标识 case "add_logo": print("-> 正在添加标识...", end="") - draft.add_video_segment(**self._random(work=work)) + draft.add_video_segment(**self._get_parameters(work=work)) print("已完成") # 添加声明 case "add_statement": print("-> 正在添加声明...", end="") - draft.add_text_segment(**self._random(work=work)) + draft.add_text_segment(**self._get_parameters(work=work)) print("已完成") # 添加贴纸 case _ if work.startswith("add_sticker"): print("-> 正在添加贴纸...", end="") - draft.add_sticker(**self._random(work=work)) + draft.add_sticker(**self._get_parameters(work=work)) print("已完成") # 将草稿保存至剪映草稿文件夹内 case "save": @@ -462,6 +407,10 @@ class JianYingExport: draft.save() print("已完成") + # 高亮关键词 + self._highlight_keywords(draft_name=draft_name) + exit() + self.draft_names.append(draft_name) print("已完成") @@ -470,18 +419,110 @@ class JianYingExport: # 就所有草稿名称倒叙排序排序 self.draft_names.sort(reverse=True) - def _random( + def _get_parameters( self, work: str, ) -> Dict[str, Any]: """ - 随机化工作配置项 + 获取工作配置项 :param work: 工作,包括添加字幕、添加背景视频、添加标识、添加声明和添加贴纸 :return: 工作配置 """ - return { + parameters = { key: random.choice(value) for key, value in self.configuration[work].items() - } + } # TODO: 考虑融合贝叶斯优化 + if work == "add_subtitles": + parameters.pop("keywords") + + # 就除添加字幕其它工作添加轨道名称 + if work != "add_subtitles" and ( + match := re.search(r"_(?P.+)", work) + ): + parameters["track_name"] = match.group("track_name") + + return parameters + + def _highlight_keywords( + self, + draft_name: str, + ) -> None: + """ + 高亮关键词 + :param draft_name: 草稿名称 + :return: 无 + """ + time.sleep(2) + + # 草稿内容路径 + draft_content_path = self.drafts_folder_path / draft_name / "draft_content.json" + + with open( + file=draft_content_path, + mode="r", + encoding="utf-8", + ) as file: + draft_content = json.load(file) + + # 字幕文本轨道所有文本片段的素材标识 + material_ids = [ + segment["material_id"] + for track in draft_content["tracks"] + if track["name"] == "subtitles(text)" + for segment in track["segments"] + ] + + # 遍历所有文本素材 + for idx, material in enumerate(draft_content["materials"]["texts"]): + if material["id"] in material_ids: + # 素材内容 + content = json.loads(s=material["content"]) + # 素材文本 + text = content["text"] + # 遍历关键词 + for keyword in self.configuration["add_subtitles"]["keywords"]: + if match := next(re.finditer(pattern=keyword, string=text), None): + assert len(styles := content["styles"]) == 1, "样式设置数不为1" + # 根据关键词将文本拆分为三段,分别为前段、中段和后段样式。其中前段和后段样式无花字设置,中段样式有花字设置 + middle_style = styles[0] + style = { + key: value + for key, value in middle_style.items() + if key != "effectStyle" + } + front_style = deepcopy(style) + rear_style = deepcopy(style) + + # 将前段样式中终止位置设置为关键词起始位置 + front_style["range"] = [0, match.start()] + + # 将中段样式中起始和终止位置设置为关键词起始和终止位置 + middle_style["range"] = [match.start(), match.end()] + # 调整字号 + middle_style["size"] += 3 + + if match.end() != len(text): + # 将后段样式中起始位置设置为关键词终止位置 + rear_style["range"] = [match.end(), len(text)] + styles = [front_style, middle_style, rear_style] + else: + styles = [front_style, middle_style] + + draft_content["materials"]["texts"][idx]["content"] = ( + json.dumps( + obj={ + "styles": [front_style, middle_style, rear_style], + "text": text, + }, + ensure_ascii=False, + ) + ) + + with open( + file=draft_content_path, + mode="w", + encoding="utf-8", + ) as file: + file.write(json.dumps(obj=draft_content, ensure_ascii=False, indent=4)) def _start_process(self, timeout: int = 60) -> None: """ @@ -527,12 +568,10 @@ class JianYingExport: window_handle = self._locate_window() if window_handle is not None: # 请求关闭剪映程序窗口 - # pylint: disable=c-extension-no-member win32gui.SendMessage(window_handle, win32con.WM_CLOSE, 0, 0) start_time = time.time() while time.time() - start_time < timeout: - # pylint: disable=c-extension-no-member if not win32gui.IsWindow(window_handle): print("已关闭剪映专业版进程") return @@ -559,16 +598,17 @@ class JianYingExport: # 初始化窗口句柄 nonlocal window_handle # 获取窗口标题 - # pylint: disable=c-extension-no-member window_text = win32gui.GetWindowText(handle) # 检查窗口是否可见且窗口标题为剪映专业版 - # pylint: disable=c-extension-no-member - if win32gui.IsWindowVisible(handle) and window_text == "剪映专业版": + if ( + win32gui.IsWindow(handle) + and win32gui.IsWindowVisible(handle) + and window_text == "剪映专业版" + ): window_handle = handle return False return True # 遍历所有顶层窗口 - # pylint: disable=c-extension-no-member win32gui.EnumWindows(callback, None) return window_handle diff --git a/票据理赔自动化/image.py b/票据理赔自动化/image.py index 93b904c..e54510f 100644 --- a/票据理赔自动化/image.py +++ b/票据理赔自动化/image.py @@ -123,6 +123,7 @@ def image_classify(image_index: int, image_path: Path, dossier: Dict[str, Any]) "image_guid": image_guid, # 影像件唯一标识 "image_base64": image_base64, # 影像件BASE64编码 "image_type": image_type, # 影像件类型 + "image_classified": "是", # 影像件是否已分类 } # 影像件编号作为键名 diff --git a/票据理赔自动化/template.html b/票据理赔自动化/template.html index f234778..5eb63b4 100644 --- a/票据理赔自动化/template.html +++ b/票据理赔自动化/template.html @@ -406,6 +406,7 @@ 影像件编号 影像件路径 影像件类型 + 已分类 已识别 @@ -415,6 +416,7 @@ {{ image_index }} {{ image["image_name"] }} {{ image["image_type"] }} + {{ image["image_classified"] }} {{ image["image_recognized"] }} {% endfor %} @@ -425,7 +427,7 @@

赔案层

-

出险人(即被保险人)信息

+

出险人(亦被保险人)信息

姓名