This commit is contained in:
parent
9781c8d7f2
commit
5ff511f898
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<track_name>.+)", 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
|
||||
|
|
|
|||
|
|
@ -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": "是", # 影像件是否已分类
|
||||
} # 影像件编号作为键名
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -406,6 +406,7 @@
|
|||
<th>影像件编号</th>
|
||||
<th>影像件路径</th>
|
||||
<th>影像件类型</th>
|
||||
<th>已分类</th>
|
||||
<th>已识别</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
@ -415,6 +416,7 @@
|
|||
<td>{{ image_index }}</td>
|
||||
<td>{{ image["image_name"] }}</td>
|
||||
<td>{{ image["image_type"] }}</td>
|
||||
<td>{{ image["image_classified"] }}</td>
|
||||
<td>{{ image["image_recognized"] }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
|
@ -425,7 +427,7 @@
|
|||
<h2>赔案层</h2>
|
||||
<div class="card-container">
|
||||
<div class="card">
|
||||
<h3>出险人(即被保险人)信息</h3>
|
||||
<h3>出险人(亦被保险人)信息</h3>
|
||||
<div class="info-grid">
|
||||
<div class="info-item">
|
||||
<div class="info-label">姓名</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue